diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 0000000..e69de29 diff --git a/GitHub-Mark-32px.png b/GitHub-Mark-32px.png new file mode 100644 index 0000000..8b25551 Binary files /dev/null and b/GitHub-Mark-32px.png differ diff --git a/build..alpha..travis-ci.org/apidoc.html b/build..alpha..travis-ci.org/apidoc.html new file mode 100644 index 0000000..dd6be48 --- /dev/null +++ b/build..alpha..travis-ci.org/apidoc.html @@ -0,0 +1,78 @@ +
+ +

api documentation for + debowerify (v1.5.0) +

+

A browserify transform to enable the easy use of bower components in browserify client javascript projects. This can be used in conjunction with deamdify to require AMD components from bower as well.

+

table of contents

    + +
  1. module debowerify
      + +
  2. + +
+ +
+

module debowerify

+ +
+ +
+ [ this document was created with + utility2 + ] +
+
diff --git a/build..alpha..travis-ci.org/app/assets.app.js b/build..alpha..travis-ci.org/app/assets.app.js new file mode 100644 index 0000000..6375d1f --- /dev/null +++ b/build..alpha..travis-ci.org/app/assets.app.js @@ -0,0 +1,20728 @@ +/* this rollup was created with utility2 (https://github.com/kaizhu256/node-utility2) */ + + + +/* +assets.app.js + +#### basic api documentation for [debowerify (v1.5.0)](https://github.com/eugeneware/debowerify#readme) [![npm package](https://img.shields.io/npm/v/npmdoc-debowerify.svg?style=flat-square)](https://www.npmjs.org/package/npmdoc-debowerify) [![travis-ci.org build-status](https://api.travis-ci.org/npmdoc/node-npmdoc-debowerify.svg)](https://travis-ci.org/npmdoc/node-npmdoc-debowerify) + +instruction + 1. save this script as assets.app.js + 2. run the shell command: + $ PORT=8081 node assets.app.js + 3. play with the browser-demo on http://127.0.0.1:8081 +*/ + + + +/* script-begin /assets.utility2.rollup.js */ +/* this rollup was created with utility2 (https://github.com/kaizhu256/node-utility2) */ + + + +/* script-begin /assets.utility2.rollup.begin.js */ +/* utility2.rollup.js begin */ +/* istanbul ignore all */ +/*jslint + bitwise: true, + browser: true, + maxerr: 8, + maxlen: 96, + node: true, + nomen: true, + regexp: true, + stupid: true +*/ +(function () { + "use strict"; + var local; + local = {}; + local.modeJs = (function () { + try { + return typeof navigator.userAgent === "string" && + typeof document.querySelector("body") === "object" && + typeof XMLHttpRequest.prototype.open === "function" && + "browser"; + } catch (errorCaughtBrowser) { + return module.exports && + typeof process.versions.node === "string" && + typeof require("http").createServer === "function" && + "node"; + } + }()); + local.global = local.modeJs === "browser" + ? window + : global; + local.local = local.global.utility2_rollup = local.global.utility2_rollup_old || local; +}()); +/* script-end /assets.utility2.rollup.begin.js */ + + + +/* script-begin /assets.utility2.lib.apidoc.js */ +///usr/bin/env node +/* istanbul instrument in package apidoc */ +/*jslint + bitwise: true, + browser: true, + maxerr: 8, + maxlen: 96, + node: true, + nomen: true, + regexp: true, + stupid: true +*/ +(function () { + 'use strict'; + var local; + + + + // run shared js-env code - init-before + (function () { + // init local + local = {}; + // init modeJs + local.modeJs = (function () { + try { + return typeof navigator.userAgent === 'string' && + typeof document.querySelector('body') === 'object' && + typeof XMLHttpRequest.prototype.open === 'function' && + 'browser'; + } catch (errorCaughtBrowser) { + return module.exports && + typeof process.versions.node === 'string' && + typeof require('http').createServer === 'function' && + 'node'; + } + }()); + // init global + local.global = local.modeJs === 'browser' + ? window + : global; + // init utility2_rollup + local = local.global.utility2_rollup || local; + // init lib + local.local = local.apidoc = local; + // init exports + if (local.modeJs === 'browser') { + local.global.utility2_apidoc = local; + } else { + module.exports = local; + module.exports.__dirname = __dirname; + module.exports.module = module; + } + }()); + + + + // run shared js-env code - function-before + /* istanbul ignore next */ + (function () { + local.assert = function (passed, message) { + /* + * this function will throw the error message if passed is falsey + */ + var error; + if (passed) { + return; + } + error = message && message.message + // if message is an error-object, then leave it as is + ? message + : new Error(typeof message === 'string' + // if message is a string, then leave it as is + ? message + // else JSON.stringify message + : JSON.stringify(message)); + throw error; + }; + + local.moduleDirname = function (module, modulePathList) { + /* + * this function will search modulePathList for the module's __dirname + */ + var result, tmp; + // search process.cwd() + if (!module || module === '.' || module.indexOf('/') >= 0) { + return require('path').resolve(process.cwd(), module || ''); + } + // search modulePathList + ['node_modules'] + .concat(modulePathList) + .concat(require('module').globalPaths) + .concat([process.env.HOME + '/node_modules', '/usr/local/lib/node_modules']) + .some(function (modulePath) { + try { + tmp = require('path').resolve(process.cwd(), modulePath + '/' + module); + result = require('fs').statSync(tmp).isDirectory() && tmp; + return result; + } catch (ignore) { + } + }); + return result || ''; + }; + + local.nop = function () { + /* + * this function will do nothing + */ + return; + }; + + local.objectSetDefault = function (arg, defaults, depth) { + /* + * this function will recursively set defaults for undefined-items in the arg + */ + arg = arg || {}; + defaults = defaults || {}; + Object.keys(defaults).forEach(function (key) { + var arg2, defaults2; + arg2 = arg[key]; + // handle misbehaving getter + try { + defaults2 = defaults[key]; + } catch (ignore) { + } + if (defaults2 === undefined) { + return; + } + // init arg[key] to default value defaults[key] + if (!arg2) { + arg[key] = defaults2; + return; + } + // if arg2 and defaults2 are both non-null and non-array objects, + // then recurse with arg2 and defaults2 + if (depth > 1 && + // arg2 is a non-null and non-array object + arg2 && + typeof arg2 === 'object' && + !Array.isArray(arg2) && + // defaults2 is a non-null and non-array object + defaults2 && + typeof defaults2 === 'object' && + !Array.isArray(defaults2)) { + // recurse + local.objectSetDefault(arg2, defaults2, depth - 1); + } + }); + return arg; + }; + + local.stringHtmlSafe = function (text) { + /* + * this function will make the text html-safe + */ + // new RegExp('[' + '"&\'<>'.split('').sort().join('') + ']', 'g') + return text.replace((/["&'<>]/g), function (match0) { + return '&#x' + match0.charCodeAt(0).toString(16) + ';'; + }); + }; + + local.templateRender = function (template, dict) { + /* + * this function will render the template with the given dict + */ + var argList, getValue, match, renderPartial, rgx, value; + dict = dict || {}; + getValue = function (key) { + argList = key.split(' '); + value = dict; + // iteratively lookup nested values in the dict + argList[0].split('.').forEach(function (key) { + value = value && value[key]; + }); + return value; + }; + renderPartial = function (match0, helper, key, partial) { + switch (helper) { + case 'each': + value = getValue(key); + return Array.isArray(value) + ? value.map(function (dict) { + // recurse with partial + return local.templateRender(partial, dict); + }).join('') + : ''; + case 'if': + partial = partial.split('{{#unless ' + key + '}}'); + partial = getValue(key) + ? partial[0] + // handle 'unless' case + : partial.slice(1).join('{{#unless ' + key + '}}'); + // recurse with partial + return local.templateRender(partial, dict); + case 'unless': + return getValue(key) + ? '' + // recurse with partial + : local.templateRender(partial, dict); + default: + // recurse with partial + return match0[0] + local.templateRender(match0.slice(1), dict); + } + }; + // render partials + rgx = (/\{\{#(\w+) ([^}]+?)\}\}/g); + template = template || ''; + for (match = rgx.exec(template); match; match = rgx.exec(template)) { + rgx.lastIndex += 1 - match[0].length; + template = template.replace( + new RegExp('\\{\\{#(' + match[1] + ') (' + match[2] + + ')\\}\\}([\\S\\s]*?)\\{\\{/' + match[1] + ' ' + match[2] + + '\\}\\}'), + renderPartial + ); + } + // search for keys in the template + return template.replace((/\{\{[^}]+?\}\}/g), function (match0) { + getValue(match0.slice(2, -2)); + if (value === undefined) { + return match0; + } + argList.slice(1).forEach(function (arg) { + switch (arg) { + case 'alphanumeric': + value = value.replace((/\W/g), '_'); + break; + case 'decodeURIComponent': + value = decodeURIComponent(value); + break; + case 'encodeURIComponent': + value = encodeURIComponent(value); + break; + case 'htmlSafe': + value = value.replace((/["&'<>]/g), function (match0) { + return '&#x' + match0.charCodeAt(0).toString(16) + ';'; + }); + break; + case 'jsonStringify': + value = JSON.stringify(value); + break; + case 'jsonStringify4': + value = JSON.stringify(value, null, 4); + break; + case 'markdownCodeSafe': + value = value.replace((/`/g), '\''); + break; + default: + value = value[arg](); + break; + } + }); + return String(value); + }); + }; + + local.tryCatchOnError = function (fnc, onError) { + /* + * this function will try to run the fnc in a try-catch block, + * else call onError with the errorCaught + */ + // validate onError + local.assert(typeof onError === 'function', typeof onError); + try { + // reset errorCaught + local._debugTryCatchErrorCaught = null; + return fnc(); + } catch (errorCaught) { + // debug errorCaught + local._debugTryCatchErrorCaught = errorCaught; + return onError(errorCaught); + } + }; + }()); + + + + // run shared js-env code - init-before +/* jslint-ignore-begin */ +local.templateApidocHtml = '\ +
\n\ +\n\ +

api documentation for\n\ + {{env.npm_package_name}} (v{{env.npm_package_version}})\n\ +

\n\ +

{{env.npm_package_description}}

\n\ +

table of contents

    \n\ + {{#each moduleList}}\n\ +
  1. module {{name}}
      \n\ + {{#each elementList}}\n\ +
    1. \n\ + {{#if source}}\n\ + \n\ + {{name}}\n\ + {{signature}}\n\ + \n\ + {{#unless source}}\n\ + {{name}}\n\ + {{/if source}}\n\ +
    2. \n\ + {{/each elementList}}\n\ +
  2. \n\ + {{/each moduleList}}\n\ +
\n\ +{{#each moduleList}}\n\ +
\n\ +

module {{name}}

\n\ + {{#each elementList}}\n\ + {{#if source}}\n\ +

\n\ + \n\ + {{name}}\n\ + {{signature}}\n\ + \n\ +

\n\ + \n\ + {{/if source}}\n\ + {{/each elementList}}\n\ +
\n\ +{{/each moduleList}}\n\ +
\n\ + [ this document was created with\n\ + utility2\n\ + ]\n\ +
\n\ +
\n\ +'; +/* jslint-ignore-end */ + + + + // run shared js-env code - function + (function () { + local.apidocCreate = function (options) { + /* + * this function will create the apidoc from options.dir + */ + var elementCreate, module, moduleMain, readExample, tmp, toString, trimLeft; + elementCreate = function (module, prefix, key) { + /* + * this function will create the apidoc-element in the given module + */ + var element; + if (options.modeNoApidoc) { + return element; + } + element = {}; + element.moduleName = prefix.split('.'); + // handle case where module is a function + if (element.moduleName.slice(-1)[0] === key) { + element.moduleName.pop(); + } + element.moduleName = element.moduleName.join('.'); + element.id = encodeURIComponent('apidoc.element.' + prefix + '.' + key); + element.typeof = typeof module[key]; + element.name = (element.typeof + ' ' + + element.moduleName + '.' + key) + // handle case where module is a function + .replace('>.<', '><'); + if (element.typeof !== 'function') { + return element; + } + // init source + element.source = trimLeft(toString(module[key])) || 'n/a'; + if (element.source.length > 4096) { + element.source = element.source.slice(0, 4096).trimRight() + ' ...'; + } + element.source = local.stringHtmlSafe(element.source) + .replace((/\([\S\s]*?\)/), function (match0) { + // init signature + element.signature = match0 + .replace((/ *?\/\*[\S\s]*?\*\/ */g), '') + .replace((/,/g), ', ') + .replace((/\s+/g), ' '); + return element.signature; + }) + .replace( + (/( *?\/\*[\S\s]*?\*\/\n)/), + '$1' + ) + .replace((/^function \(/), key + ' = function ('); + // init example + options.exampleList.some(function (example) { + example.replace( + new RegExp('((?:\n.*?){8}\\.)(' + key + ')(\\((?:.*?\n){8})'), + function (match0, match1, match2, match3) { + // jslint-hack + local.nop(match0); + element.example = '...' + trimLeft(local.stringHtmlSafe(match1) + + '' + + local.stringHtmlSafe(match2) + + '' + + local.stringHtmlSafe(match3)).trimRight() + '\n...'; + } + ); + return element.example; + }); + element.example = element.example || 'n/a'; + return element; + }; + readExample = function (file) { + /* + * this function will read the example from the given file + */ + var result; + local.tryCatchOnError(function () { + file = local.path.resolve(options.dir, file); + console.error('apidocCreate - readExample - ' + file); + result = ''; + result = ('\n\n\n\n\n\n\n\n' + + local.fs.readFileSync(file, 'utf8').slice(0, 262144) + + '\n\n\n\n\n\n\n\n').replace((/\r\n*/g), '\n'); + }, console.error); + return result; + }; + toString = function (value) { + /* + * this function will try to return the string form of the value + */ + var result; + local.tryCatchOnError(function () { + result = ''; + result = String(value); + }, console.error); + return result; + }; + trimLeft = function (text) { + /* + * this function will normalize the whitespace around the text + */ + var whitespace; + whitespace = ''; + text.trim().replace((/^ */gm), function (match0) { + if (!whitespace || match0.length < whitespace.length) { + whitespace = match0; + } + }); + text = text.replace(new RegExp('^' + whitespace, 'gm'), ''); + // enforce 128 character column limit + text = text.replace((/^.{128}[^\\\n]+/gm), function (match0) { + return match0.replace((/(.{128}(?:\b|\w+))/g), '$1\n').trimRight(); + }); + return text; + }; + // init options + options.dir = local.moduleDirname( + options.dir, + options.modulePathList || local.module.paths + ); + local.objectSetDefault(options, { + env: { npm_package_description: '' }, + packageJson: JSON.parse(readExample('package.json')), + require: function (file) { + return local.tryCatchOnError(function () { + return require(file); + }, console.error); + } + }); + Object.keys(options.packageJson).forEach(function (key) { + tmp = options.packageJson[key]; + // strip email from npmdoc documentation + // https://github.com/npmdoc/node-npmdoc-hpp/issues/1 + if (tmp) { + if (tmp.email) { + delete tmp.email; + } + if (Array.isArray(tmp)) { + tmp.forEach(function (element) { + if (element && element.email) { + delete element.email; + } + }); + } + } + if (key[0] === '_' || key === 'readme') { + delete options.packageJson[key]; + } else if (typeof tmp === 'string') { + options.env['npm_package_' + key] = tmp; + } + }); + local.objectSetDefault(options, { + blacklistDict: { global: global }, + circularList: [global], + exampleDict: {}, + exampleList: [], + html: '', + libFileList: [], + moduleDict: {}, + moduleExtraDict: {}, + packageJson: { bin: {} }, + template: local.templateApidocHtml + }, 2); + // init exampleList + [1, 2, 3, 4].forEach(function (depth) { + options.exampleList = options.exampleList.concat( + // http://stackoverflow.com + // /questions/4509624/how-to-limit-depth-for-recursive-file-list + // find . -maxdepth 1 -mindepth 1 -name "*.js" -type f + local.child_process.execSync('find "' + options.dir + + '" -maxdepth ' + depth + ' -mindepth ' + depth + + ' -type f | sed -e "s|' + options.dir + + '/||" | grep -iv ' + +/* jslint-ignore-begin */ +'"\ +/\\.\\|\\(\\b\\|_\\)\\(\ +bower_component\\|\ +coverage\\|\ +git\\|\ +min\\|\ +node_module\\|\ +rollup\\|\ +tmp\\|\ +vendor\\)s\\{0,1\\}\\(\\b\\|_\\)\ +" ' + +/* jslint-ignore-end */ + ' | sort | head -n 256').toString() + .split('\n') + ); + }); + options.exampleList = options.exampleList.filter(function (file) { + if (!options.exampleDict[file]) { + options.exampleDict[file] = true; + return true; + } + }).slice(0, 256).map(readExample); + // init moduleMain + local.tryCatchOnError(function () { + console.error('apidocCreate - requiring ' + options.dir + ' ...'); + moduleMain = {}; + moduleMain = options.moduleDict[options.env.npm_package_name] || + options.require(options.dir) || + options.require(options.dir + '/' + (options.packageJson.bin)[ + Object.keys(options.packageJson.bin)[0] + ]) || {}; + console.error('apidocCreate - ... required ' + options.dir); + }, console.error); + tmp = {}; + // handle case where module is a function + if (typeof moduleMain === 'function') { + (function () { + var text; + text = toString(moduleMain); + tmp = function () { + return; + }; + // coverage-hack + tmp(); + Object.defineProperties(tmp, { toString: { get: function () { + return function () { + return text; + }; + } } }); + }()); + } + // normalize moduleMain + moduleMain = options.moduleDict[options.env.npm_package_name] = + local.objectSetDefault(tmp, moduleMain); + // init circularList - builtin + Object.keys(process.binding('natives')).forEach(function (key) { + if (!(/\/|_linklist|sys/).test(key)) { + options.blacklistDict[key] = options.blacklistDict[key] || require(key); + } + }); + // init circularList - blacklistDict + Object.keys(options.blacklistDict).forEach(function (key) { + options.circularList.push(options.blacklistDict[key]); + }); + // init circularList - moduleDict + Object.keys(options.moduleDict).forEach(function (key) { + options.circularList.push(options.moduleDict[key]); + }); + // init circularList - prototype + Object.keys(options.circularList).forEach(function (key) { + tmp = options.circularList[key]; + options.circularList.push(tmp && tmp.prototype); + }); + // deduplicate circularList + tmp = options.circularList; + options.circularList = []; + tmp.forEach(function (element) { + if (options.circularList.indexOf(element) < 0) { + options.circularList.push(element); + } + }); + // init moduleDict child + local.apidocModuleDictAdd(options, options.moduleDict); + // init moduleExtraDict + module = options.moduleExtraDict[options.env.npm_package_name] = + options.moduleExtraDict[options.env.npm_package_name] || {}; + [1, 2, 3, 4].forEach(function (depth) { + options.libFileList = options.libFileList.concat( + // http://stackoverflow.com + // /questions/4509624/how-to-limit-depth-for-recursive-file-list + // find . -maxdepth 1 -mindepth 1 -name "*.js" -type f + local.child_process.execSync('find "' + options.dir + + '" -maxdepth ' + depth + ' -mindepth ' + depth + + ' -name "*.js" -type f | sed -e "s|' + options.dir + + '/||" | grep -iv ' + +/* jslint-ignore-begin */ +'"\ +/\\.\\|\\(\\b\\|_\\)\\(\ +archive\\|artifact\\|asset\\|\ +bower_component\\|build\\|\ +coverage\\|\ +doc\\|dist\\|\ +example\\|external\\|\ +fixture\\|\ +git\\|\ +log\\|\ +min\\|mock\\|\ +node_module\\|\ +rollup\\|\ +spec\\|\ +test\\|tmp\\|\ +vendor\\)s\\{0,1\\}\\(\\b\\|_\\)\ +" ' + +/* jslint-ignore-end */ + ' | sort | head -n 256').toString() + .split('\n') + ); + }); + options.ii = 256; + options.libFileList.every(function (file) { + local.tryCatchOnError(function () { + tmp = {}; + tmp.name = local.path.basename(file) + .replace('lib.', '') + .replace((/\.[^.]*?$/), '') + .replace((/\W/g), '_'); + [ + tmp.name, + tmp.name.slice(0, 1).toUpperCase() + tmp.name.slice(1) + ].some(function (name) { + tmp.isFiltered = name && (!options.packageJson.main || + ('./' + file).indexOf(options.packageJson.main) < 0) && + !module[name]; + return !tmp.isFiltered; + }); + if (!tmp.isFiltered) { + return; + } + console.error('apidocCreate - libFile - ' + file); + tmp.module = options.require(options.dir + '/' + file); + if (!(tmp.module && options.circularList.indexOf(tmp.module) < 0)) { + return; + } + options.ii -= 1; + module[tmp.name] = tmp.module; + }, console.error); + return options.ii; + }); + local.apidocModuleDictAdd(options, options.moduleExtraDict); + Object.keys(options.moduleDict).forEach(function (key) { + if (key.indexOf(options.env.npm_package_name + '.') !== 0) { + return; + } + tmp = key.split('.').slice(1).join('.'); + moduleMain[tmp] = moduleMain[tmp] || options.moduleDict[key]; + }); + // init moduleList + options.moduleList = Object.keys(options.moduleDict) + .sort() + .map(function (prefix) { + module = options.moduleDict[prefix]; + // handle case where module is a function + if (typeof module === 'function') { + local.tryCatchOnError(function () { + module[prefix.split('.').slice(-1)[0]] = + module[prefix.split('.').slice(-1)[0]] || module; + }, console.error); + } + return { + elementList: Object.keys(module) + .filter(function (key) { + return local.tryCatchOnError(function () { + return key && + (/^\w[\w\-.]*?$/).test(key) && + key.indexOf('testCase_') !== 0 && + module[key] !== options.blacklistDict[key]; + }, console.error); + }) + .map(function (key) { + return elementCreate(module, prefix, key); + }) + .sort(function (aa, bb) { + return aa.name > bb.name + ? 1 + : -1; + }), + id: encodeURIComponent('apidoc.module.' + prefix), + name: prefix + }; + }); + // render apidoc + options.result = local.templateRender(options.template, options) + .trim() + .replace((/ +$/gm), '') + '\n'; + return options.result; + }; + + local.apidocModuleDictAdd = function (options, moduleDict) { + /* + * this function will add the modules in moduleDict to options.moduleDict + */ + var isModule, tmp; + ['child', 'prototype', 'grandchild', 'prototype'].forEach(function (element) { + Object.keys(moduleDict).sort().forEach(function (prefix) { + if (!(/^\w[\w\-.]*?$/).test(prefix)) { + return; + } + Object.keys(moduleDict[prefix]).forEach(function (key) { + // bug-workaround - buggy electron getter / setter + local.tryCatchOnError(function () { + if (!(/^\w[\w\-.]*?$/).test(key) || !moduleDict[prefix][key]) { + return; + } + tmp = element === 'prototype' + ? { + module: moduleDict[prefix][key].prototype, + name: prefix + '.' + key + '.prototype' + } + : { + module: moduleDict[prefix][key], + name: prefix + '.' + key + }; + if (!tmp.module || + !(typeof tmp.module === 'function' || + typeof tmp.module === 'object') || + options.moduleDict[tmp.name] || + options.circularList.indexOf(tmp.module) >= 0) { + return; + } + isModule = [ + tmp.module, + tmp.module.prototype + ].some(function (dict) { + return Object.keys(dict || {}).some(function (key) { + // bug-workaround - buggy electron getter / setter + return local.tryCatchOnError(function () { + return typeof dict[key] === 'function'; + }, console.error); + }); + }); + if (!isModule) { + return; + } + options.circularList.push(tmp.module); + options.moduleDict[tmp.name] = tmp.module; + }, console.error); + }); + }); + }); + }; + }()); + switch (local.modeJs) { + + + + // run node js-env code - init-after + /* istanbul ignore next */ + case 'node': + // require modules + local.child_process = require('child_process'); + local.fs = require('fs'); + local.path = require('path'); + // run the cli + if (module !== require.main || local.global.utility2_rollup) { + break; + } + // jslint files + process.stdout.write(local.apidocCreate({ + dir: process.argv[2], + modulePathList: module.paths + })); + break; + } +}()); +/* script-end /assets.utility2.lib.apidoc.js */ + + + +/* script-begin /assets.utility2.lib.db.js */ +/* + * assets.db-lite.js + * + * this zero-dependency package will provide a persistent, in-browser database + * + * browser example: + * + * + * + * node example: + * var db, dbTable1; + * utility2_db = require("./assets.db-lite.js"); + * dbTable1 = global.dbTable1 = utility2_db.dbTableCreateOne({ name: "dbTable1" }); + * dbTable1.idIndexCreate({ name: "field1" }); + * dbTable1.crudSetOneById({ field1: "hello", field2: "world" }); + * console.log(dbTable1.crudGetManyByQuery({ + * limit: Infinity, + * query: { field1: "hello" }, + * skip: 0, + * sort: [{ fieldName: 'field1', isDescending: false }] + * })); + */ + + + +/* istanbul instrument in package db */ +/*jslint + bitwise: true, + browser: true, + maxerr: 8, + maxlen: 96, + node: true, + nomen: true, + regexp: true, + stupid: true +*/ +(function () { + 'use strict'; + var local; + + + + // run shared js-env code - init-before + (function () { + // init local + local = {}; + // init modeJs + local.modeJs = (function () { + try { + return typeof navigator.userAgent === 'string' && + typeof document.querySelector('body') === 'object' && + typeof XMLHttpRequest.prototype.open === 'function' && + 'browser'; + } catch (errorCaughtBrowser) { + return module.exports && + typeof process.versions.node === 'string' && + typeof require('http').createServer === 'function' && + 'node'; + } + }()); + // init global + local.global = local.modeJs === 'browser' + ? window + : global; + // init utility2_rollup + local = local.global.utility2_rollup || local; + // init lib + local.local = local.db = local; + // init exports + if (local.modeJs === 'browser') { + local.global.utility2_db = local; + } else { + module.exports = local; + module.exports.__dirname = __dirname; + module.exports.module = module; + } + }()); + + + + /* istanbul ignore next */ + // run shared js-env code - function-before + (function () { + local.jsonCopy = function (arg) { + /* + * this function will return a deep-copy of the JSON-arg + */ + return arg === undefined + ? undefined + : JSON.parse(JSON.stringify(arg)); + }; + + local.jsonStringifyOrdered = function (element, replacer, space) { + /* + * this function will JSON.stringify the element, + * with object-keys sorted and circular-references removed + */ + var circularList, stringify, tmp; + stringify = function (element) { + /* + * this function will recursively JSON.stringify the element, + * with object-keys sorted and circular-references removed + */ + // if element is an object, then recurse its items with object-keys sorted + if (element && + typeof element === 'object' && + typeof element.toJSON !== 'function') { + // ignore circular-reference + if (circularList.indexOf(element) >= 0) { + return; + } + circularList.push(element); + // if element is an array, then recurse its elements + if (Array.isArray(element)) { + return '[' + element.map(function (element) { + // recurse + tmp = stringify(element); + return typeof tmp === 'string' + ? tmp + : 'null'; + }).join(',') + ']'; + } + return '{' + Object.keys(element) + // sort object-keys + .sort() + .map(function (key) { + // recurse + tmp = stringify(element[key]); + if (typeof tmp === 'string') { + return JSON.stringify(key) + ':' + tmp; + } + }) + .filter(function (element) { + return typeof element === 'string'; + }) + .join(',') + '}'; + } + // else JSON.stringify as normal + return JSON.stringify(element); + }; + circularList = []; + return JSON.stringify(element && typeof element === 'object' + // recurse + ? JSON.parse(stringify(element)) + : element, replacer, space); + }; + + local.listShuffle = function (list) { + /* + * https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle + * this function will inplace shuffle the list, via fisher-yates algorithm + */ + var ii, random, swap; + for (ii = list.length - 1; ii > 0; ii -= 1) { + // coerce to finite integer + random = (Math.random() * (ii + 1)) | 0; + swap = list[ii]; + list[ii] = list[random]; + list[random] = swap; + } + return list; + }; + + local.nop = function () { + /* + * this function will do nothing + */ + return; + }; + + local.normalizeDict = function (dict) { + /* + * this function will normalize the dict + */ + return dict && typeof dict === 'object' && !Array.isArray(dict) + ? dict + : {}; + }; + + local.normalizeList = function (list) { + /* + * this function will normalize the list + */ + return Array.isArray(list) + ? list + : []; + }; + + local.objectSetOverride = function (arg, overrides, depth, env) { + /* + * this function will recursively set overrides for items in the arg + */ + arg = arg || {}; + env = env || (typeof process === 'object' && process.env) || {}; + overrides = overrides || {}; + Object.keys(overrides).forEach(function (key) { + var arg2, overrides2; + arg2 = arg[key]; + overrides2 = overrides[key]; + if (overrides2 === undefined) { + return; + } + // if both arg2 and overrides2 are non-null and non-array objects, + // then recurse with arg2 and overrides2 + if (depth > 1 && + // arg2 is a non-null and non-array object + (arg2 && + typeof arg2 === 'object' && + !Array.isArray(arg2)) && + // overrides2 is a non-null and non-array object + (overrides2 && + typeof overrides2 === 'object' && + !Array.isArray(overrides2))) { + local.objectSetOverride(arg2, overrides2, depth - 1, env); + return; + } + // else set arg[key] with overrides[key] + arg[key] = arg === env + // if arg is env, then overrides falsey value with empty string + ? overrides2 || '' + : overrides2; + }); + return arg; + }; + + local.onErrorDefault = function (error) { + /* + * this function will if error exists, then print error.stack to stderr + */ + if (error && !local.global.__coverage__) { + console.error(error); + } + }; + + local.onErrorWithStack = function (onError) { + /* + * this function will create a new callback that will call onError, + * and append the current stack to any error + */ + var stack; + stack = new Error().stack.replace((/(.*?)\n.*?$/m), '$1'); + return function (error, data, meta) { + if (error && + error !== local.errorDefault && + String(error.stack).indexOf(stack.split('\n')[2]) < 0) { + // append the current stack to error.stack + error.stack += '\n' + stack; + } + onError(error, data, meta); + }; + }; + + local.onParallel = function (onError, onEach, onRetry) { + /* + * this function will create a function that will + * 1. run async tasks in parallel + * 2. if counter === 0 or error occurred, then call onError with error + */ + var onParallel; + onError = local.onErrorWithStack(onError); + onEach = onEach || local.nop; + onRetry = onRetry || local.nop; + onParallel = function (error, data) { + if (onRetry(error, data)) { + return; + } + // decrement counter + onParallel.counter -= 1; + // validate counter + console.assert(onParallel.counter >= 0 || error || onParallel.error); + // ensure onError is run only once + if (onParallel.counter < 0) { + return; + } + // handle error + if (error) { + onParallel.error = error; + // ensure counter <= 0 + onParallel.counter = -Math.abs(onParallel.counter); + } + // call onError when isDone + if (onParallel.counter <= 0) { + onError(error, data); + return; + } + onEach(); + }; + // init counter + onParallel.counter = 0; + // return callback + return onParallel; + }; + + local.setTimeoutOnError = function (onError, error, data) { + /* + * this function will async-call onError + */ + if (typeof onError === 'function') { + setTimeout(function () { + onError(error, data); + }); + } + return data; + }; + }()); + + + + // run shared js-env code - lib.storage.js + (function (local) { + var child_process, + clear, + defer, + deferList, + fs, + getItem, + init, + keys, + length, + modeJs, + os, + removeItem, + setItem, + storage, + storageDir; + + // init modeJs + modeJs = (function () { + try { + return typeof navigator.userAgent === 'string' && + typeof document.querySelector('body') === 'object' && + typeof XMLHttpRequest.prototype.open === 'function' && + 'browser'; + } catch (errorCaughtBrowser) { + return module.exports && + typeof process.versions.node === 'string' && + typeof require('http').createServer === 'function' && + 'node'; + } + }()); + storageDir = 'tmp/storage.' + (local.modeJs === 'browser' + ? 'undefined' + : process.env.NODE_ENV); + switch (modeJs) { + case 'node': + // require modules + child_process = require('child_process'); + fs = require('fs'); + os = require('os'); + break; + } + + clear = function (onError) { + /* + * this function will clear storage + */ + defer({ action: 'clear' }, onError); + }; + + defer = function (options, onError) { + /* + * this function will defer options.action until storage is ready + */ + var data, isDone, objectStore, onError2, request, tmp; + onError = onError || function (error) { + // validate no error occurred + console.assert(!error, error); + }; + if (!storage) { + deferList.push(function () { + defer(options, onError); + }); + init(); + return; + } + switch (modeJs) { + case 'browser': + onError2 = function () { + /* istanbul ignore next */ + if (isDone) { + return; + } + isDone = true; + onError( + request && (request.error || request.transaction.error), + data || request.result || '' + ); + }; + switch (options.action) { + case 'clear': + case 'removeItem': + case 'setItem': + objectStore = storage + .transaction(storageDir, 'readwrite') + .objectStore(storageDir); + break; + default: + objectStore = storage + .transaction(storageDir, 'readonly') + .objectStore(storageDir); + } + switch (options.action) { + case 'clear': + request = objectStore.clear(); + break; + case 'getItem': + request = objectStore.get(String(options.key)); + break; + case 'keys': + data = []; + request = objectStore.openCursor(); + request.onsuccess = function () { + if (!request.result) { + onError2(); + return; + } + data.push(request.result.key); + request.result.continue(); + }; + break; + case 'length': + request = objectStore.count(); + break; + case 'removeItem': + request = objectStore.delete(String(options.key)); + break; + case 'setItem': + request = objectStore.put(options.value, String(options.key)); + break; + } + ['onabort', 'onerror', 'onsuccess'].forEach(function (handler) { + request[handler] = request[handler] || onError2; + }); + // debug request + local._debugStorageRequest = request; + break; + case 'node': + switch (options.action) { + case 'clear': + child_process.spawnSync( + 'sh', + ['-c', 'rm -f ' + storage + '/*'], + { stdio: ['ignore', 1, 2] } + ); + setTimeout(onError); + break; + case 'getItem': + fs.readFile( + storage + '/' + encodeURIComponent(String(options.key)), + 'utf8', + // ignore error + function (error, data) { + onError(error && null, data || ''); + } + ); + break; + case 'keys': + fs.readdir(storage, function (error, data) { + onError(error, data && data.map(decodeURIComponent)); + }); + break; + case 'length': + fs.readdir(storage, function (error, data) { + onError(error, data && data.length); + }); + break; + case 'removeItem': + fs.unlink( + storage + '/' + encodeURIComponent(String(options.key)), + // ignore error + function () { + onError(); + } + ); + break; + case 'setItem': + tmp = os.tmpdir() + '/' + Date.now() + Math.random(); + // save to tmp + fs.writeFile(tmp, options.value, function (error) { + // validate no error occurred + console.assert(!error, error); + // rename tmp to key + fs.rename( + tmp, + storage + '/' + encodeURIComponent(String(options.key)), + onError + ); + }); + break; + } + break; + } + }; + + deferList = []; + + getItem = function (key, onError) { + /* + * this function will get the item with the given key from storage + */ + defer({ action: 'getItem', key: key }, onError); + }; + + init = function () { + /* + * this function will init storage + */ + var onError, request; + onError = function (error) { + // validate no error occurred + console.assert(!error, error); + if (modeJs === 'browser') { + storage = window[storageDir]; + } + while (deferList.length) { + deferList.shift()(); + } + }; + if (modeJs === 'browser') { + storage = window[storageDir]; + } + if (storage) { + onError(); + return; + } + switch (modeJs) { + case 'browser': + // init indexedDB + try { + request = window.indexedDB.open(storageDir); + // debug request + local._debugStorageRequestIndexedDB = request; + request.onerror = onError; + request.onsuccess = function () { + window[storageDir] = request.result; + onError(); + }; + request.onupgradeneeded = function () { + if (!request.result.objectStoreNames.contains(storageDir)) { + request.result.createObjectStore(storageDir); + } + }; + } catch (ignore) { + } + break; + case 'node': + // mkdirp storage + storage = storageDir; + child_process.spawnSync( + 'mkdir', + ['-p', storage], + { stdio: ['ignore', 1, 2] } + ); + onError(); + break; + } + }; + + keys = function (onError) { + /* + * this function will get all the keys in storage + */ + defer({ action: 'keys' }, onError); + }; + + length = function (onError) { + /* + * this function will get the number of items in storage + */ + defer({ action: 'length' }, onError); + }; + + removeItem = function (key, onError) { + /* + * this function will remove the item with the given key from storage + */ + defer({ action: 'removeItem', key: key }, onError); + }; + + setItem = function (key, value, onError) { + /* + * this function will set the item with the given key and value to storage + */ + defer({ action: 'setItem', key: key, value: value }, onError); + }; + + // init local + local.storage = storage; + local.storageClear = clear; + local.storageDefer = defer; + local.storageDeferList = deferList; + local.storageDir = storageDir; + local.storageGetItem = getItem; + local.storageInit = init; + local.storageKeys = keys; + local.storageLength = length; + local.storageRemoveItem = removeItem; + local.storageSetItem = setItem; + }(local)); + + + + // run shared js-env code - lib.dbTable.js + (function () { + local._DbTable = function (options) { + /* + * this function will create a dbTable + */ + options = local.normalizeDict(options); + this.name = String(options.name); + // register dbTable in dbTableDict + local.dbTableDict[this.name] = this; + this.dbRowList = []; + this.isDirty = null; + this.idIndexList = [{ name: '_id', dict: {} }]; + this.onSaveList = []; + this.sizeLimit = options.sizeLimit || 0; + }; + + local._DbTable.prototype._cleanup = function () { + /* + * this function will cleanup soft-deleted records from the dbTable + */ + var dbRow, ii, list; + if (!this.isDirty && this.dbRowList.length <= this.sizeLimit) { + return; + } + this.isDirty = null; + // cleanup dbRowList + list = this.dbRowList; + this.dbRowList = []; + // optimization - for-loop + for (ii = 0; ii < list.length; ii += 1) { + dbRow = list[ii]; + // cleanup isRemoved + if (!dbRow.$meta.isRemoved) { + this.dbRowList.push(dbRow); + } + } + if (this.sizeLimit && this.dbRowList.length >= 1.5 * this.sizeLimit) { + this.dbRowList = this._crudGetManyByQuery( + {}, + this.sortDefault, + 0, + this.sizeLimit + ); + } + }; + + local._DbTable.prototype._crudGetManyByQuery = function ( + query, + sort, + skip, + limit, + shuffle + ) { + /* + * this function will get the dbRow's in the dbTable, + * with the given query, sort, skip, and limit + */ + var ii, result; + result = this.dbRowList; + // get by query + if (result.length && query && Object.keys(query).length) { + result = local.dbRowListGetManyByQuery(this.dbRowList, query); + } + // sort + local.normalizeList(sort).forEach(function (element) { + // bug-workaround - v8 does not have stable-sort + // optimization - for-loop + for (ii = 0; ii < result.length; ii += 1) { + result[ii].$meta.ii = ii; + } + if (element.isDescending) { + result.sort(function (aa, bb) { + return -local.sortCompare( + local.dbRowGetItem(aa, element.fieldName), + local.dbRowGetItem(bb, element.fieldName), + aa.$meta.ii, + bb.$meta.ii + ); + }); + } else { + result.sort(function (aa, bb) { + return local.sortCompare( + local.dbRowGetItem(aa, element.fieldName), + local.dbRowGetItem(bb, element.fieldName), + aa.$meta.ii, + bb.$meta.ii + ); + }); + } + }); + // skip + result = result.slice(skip || 0); + // shuffle + ((shuffle && local.listShuffle) || local.nop)(result); + // limit + result = result.slice(0, limit || Infinity); + return result; + }; + + local._DbTable.prototype._crudGetOneById = function (idDict) { + /* + * this function will get the dbRow in the dbTable with the given idDict + */ + var id, result; + idDict = local.normalizeDict(idDict); + result = null; + this.idIndexList.some(function (idIndex) { + id = idDict[idIndex.name]; + // optimization - hasOwnProperty + if (idIndex.dict.hasOwnProperty(id)) { + result = idIndex.dict[id]; + return result; + } + }); + return result; + }; + + local._DbTable.prototype._crudRemoveOneById = function (idDict, circularList) { + /* + * this function will remove the dbRow from the dbTable with the given idDict + */ + var id, result, self; + if (!idDict) { + return null; + } + self = this; + circularList = circularList || [idDict]; + result = null; + self.idIndexList.forEach(function (idIndex) { + id = idDict[idIndex.name]; + // optimization - hasOwnProperty + if (!idIndex.dict.hasOwnProperty(id)) { + return; + } + result = idIndex.dict[id]; + delete idIndex.dict[id]; + // optimization - soft-delete + result.$meta.isRemoved = true; + self.isDirty = true; + if (circularList.indexOf(result) >= 0) { + return; + } + circularList.push(result); + // recurse + self._crudRemoveOneById(result, circularList); + }); + self.save(); + return result; + }; + + local._DbTable.prototype._crudSetOneById = function (dbRow) { + /* + * this function will set the dbRow into the dbTable with the given dbRow._id + * WARNING - existing dbRow with conflicting dbRow._id will be removed + */ + var existing, id, normalize, timeNow; + normalize = function (dbRow) { + /* + * this function will recursively normalize dbRow + */ + if (dbRow && typeof dbRow === 'object') { + Object.keys(dbRow).forEach(function (key) { + // remove invalid property + if (key[0] === '$' || key.indexOf('.') >= 0 || dbRow[key] === null) { + // optimization - soft-delete + dbRow[key] = undefined; + return; + } + // recurse + normalize(dbRow[key]); + }); + } + }; + dbRow = local.jsonCopy(dbRow && typeof dbRow === 'object' + ? dbRow + : {}); + // update timestamp + timeNow = new Date().toISOString(); + dbRow._timeCreated = dbRow._timeCreated || timeNow; + if (!local.modeImport) { + dbRow._timeUpdated = timeNow; + } + // normalize + normalize(dbRow); + dbRow = local.jsonCopy(dbRow); + // remove existing dbRow + existing = this._crudRemoveOneById(dbRow) || dbRow; + // init meta + dbRow.$meta = { isRemoved: null }; + this.idIndexList.forEach(function (idIndex) { + // auto-set id + id = local.dbRowSetId(existing, idIndex); + // copy id from existing to dbRow + dbRow[idIndex.name] = id; + // set dbRow + idIndex.dict[id] = dbRow; + }); + // update dbRowList + this.dbRowList.push(dbRow); + this.save(); + return dbRow; + }; + + local._DbTable.prototype._crudUpdateOneById = function (dbRow) { + /* + * this function will update the dbRow in the dbTable, + * if it exists with the given dbRow._id + * WARNING + * existing dbRow's with conflicting unique-keys (besides the one being updated) + * will be removed + */ + var id, result; + dbRow = local.jsonCopy(local.normalizeDict(dbRow)); + result = null; + this.idIndexList.some(function (idIndex) { + id = dbRow[idIndex.name]; + // optimization - hasOwnProperty + if (idIndex.dict.hasOwnProperty(id)) { + result = idIndex.dict[id]; + return true; + } + }); + result = result || {}; + // remove existing dbRow + this._crudRemoveOneById(result); + // update dbRow + dbRow._timeCreated = undefined; + local.objectSetOverride(result, dbRow, Infinity); + // replace dbRow + result = this._crudSetOneById(result); + return result; + }; + + local._DbTable.prototype.crudCountAll = function (onError) { + /* + * this function will count all of dbRow's in the dbTable + */ + this._cleanup(); + return local.setTimeoutOnError(onError, null, this.dbRowList.length); + }; + + local._DbTable.prototype.crudCountManyByQuery = function (query, onError) { + /* + * this function will count the number of dbRow's in the dbTable with the given query + */ + this._cleanup(); + return local.setTimeoutOnError( + onError, + null, + this._crudGetManyByQuery(query).length + ); + }; + + local._DbTable.prototype.crudGetManyById = function (idDictList, onError) { + /* + * this function will get the dbRow's in the dbTable with the given idDictList + */ + var self; + this._cleanup(); + self = this; + return local.setTimeoutOnError(onError, null, local.dbRowProject( + local.normalizeList(idDictList).map(function (idDict) { + return self._crudGetOneById(idDict); + }) + )); + }; + + local._DbTable.prototype.crudGetManyByQuery = function (options, onError) { + /* + * this function will get the dbRow's in the dbTable with the given options.query + */ + this._cleanup(); + options = local.normalizeDict(options); + return local.setTimeoutOnError(onError, null, local.dbRowProject( + this._crudGetManyByQuery( + options.query, + options.sort || this.sortDefault, + options.skip, + options.limit, + options.shuffle + ), + options.fieldList + )); + }; + + local._DbTable.prototype.crudGetOneById = function (idDict, onError) { + /* + * this function will get the dbRow in the dbTable with the given idDict + */ + this._cleanup(); + return local.setTimeoutOnError(onError, null, local.dbRowProject( + this._crudGetOneById(idDict) + )); + }; + + local._DbTable.prototype.crudGetOneByRandom = function (onError) { + /* + * this function will get a random dbRow in the dbTable + */ + this._cleanup(); + return local.setTimeoutOnError(onError, null, local.dbRowProject( + this.dbRowList[Math.floor(Math.random() * this.dbRowList.length)] + )); + }; + + local._DbTable.prototype.crudGetOneByQuery = function (query, onError) { + /* + * this function will get the dbRow in the dbTable with the given query + */ + var ii, result; + this._cleanup(); + // optimization - for-loop + for (ii = 0; ii < this.dbRowList.length; ii += 1) { + result = local.dbRowListGetManyByQuery([this.dbRowList[ii]], query)[0]; + if (result) { + break; + } + } + return local.setTimeoutOnError(onError, null, local.dbRowProject(result)); + }; + + local._DbTable.prototype.crudRemoveAll = function (onError) { + /* + * this function will remove all of the dbRow's from the dbTable + */ + var idIndexList; + // save idIndexList + idIndexList = this.idIndexList; + // reset dbTable + local._DbTable.call(this, this); + // restore idIndexList + local.dbTableCreateOne({ + name: this.name, + idIndexCreateList: idIndexList + }, onError); + }; + + local._DbTable.prototype.crudRemoveManyById = function (idDictList, onError) { + /* + * this function will remove the dbRow's from the dbTable with the given idDictList + */ + var self; + self = this; + return local.setTimeoutOnError(onError, null, local.dbRowProject( + local.normalizeList(idDictList).map(function (dbRow) { + return self._crudRemoveOneById(dbRow); + }) + )); + }; + + local._DbTable.prototype.crudRemoveManyByQuery = function (query, onError) { + /* + * this function will remove the dbRow's from the dbTable with the given query + */ + var self; + self = this; + return local.setTimeoutOnError(onError, null, local.dbRowProject( + self._crudGetManyByQuery(query).map(function (dbRow) { + return self._crudRemoveOneById(dbRow); + }) + )); + }; + + local._DbTable.prototype.crudRemoveOneById = function (idDict, onError) { + /* + * this function will remove the dbRow from the dbTable with the given idDict + */ + return local.setTimeoutOnError(onError, null, local.dbRowProject( + this._crudRemoveOneById(idDict) + )); + }; + + local._DbTable.prototype.crudSetManyById = function (dbRowList, onError) { + /* + * this function will set the dbRowList into the dbTable + */ + var self; + self = this; + return local.setTimeoutOnError(onError, null, local.dbRowProject( + local.normalizeList(dbRowList).map(function (dbRow) { + return self._crudSetOneById(dbRow); + }) + )); + }; + + local._DbTable.prototype.crudSetOneById = function (dbRow, onError) { + /* + * this function will set the dbRow into the dbTable with the given dbRow._id + */ + return local.setTimeoutOnError(onError, null, local.dbRowProject( + this._crudSetOneById(dbRow) + )); + }; + + local._DbTable.prototype.crudUpdateManyById = function (dbRowList, onError) { + /* + * this function will update the dbRowList in the dbTable, + * if they exist with the given dbRow._id's + */ + var self; + self = this; + return local.setTimeoutOnError(onError, null, local.dbRowProject( + local.normalizeList(dbRowList).map(function (dbRow) { + return self._crudUpdateOneById(dbRow); + }) + )); + }; + + local._DbTable.prototype.crudUpdateManyByQuery = function (query, dbRow, onError) { + /* + * this function will update the dbRow's in the dbTable with the given query + */ + var result, self, tmp; + self = this; + tmp = local.jsonCopy(local.normalizeDict(dbRow)); + result = self._crudGetManyByQuery(query).map(function (dbRow) { + tmp._id = dbRow._id; + return self._crudUpdateOneById(tmp); + }); + return local.setTimeoutOnError(onError, null, result); + }; + + local._DbTable.prototype.crudUpdateOneById = function (dbRow, onError) { + /* + * this function will update the dbRow in the dbTable, + * if it exists with the given dbRow._id + */ + return local.setTimeoutOnError(onError, null, local.dbRowProject( + this._crudUpdateOneById(dbRow) + )); + }; + + local._DbTable.prototype.drop = function (onError) { + /* + * this function will drop the dbTable + */ + console.error('dropping dbTable ' + this.name + ' ...'); + // cancel pending save + this.timerSave = null; + while (this.onSaveList.length) { + this.onSaveList.shift()(); + } + // reset dbTable + local._DbTable.call(this, this); + // clear persistence + local.storageRemoveItem('dbTable.' + this.name, onError); + }; + + local._DbTable.prototype.export = function (onError) { + /* + * this function will export the db + */ + var result, self; + this._cleanup(); + self = this; + result = ''; + self.idIndexList.forEach(function (idIndex) { + result += self.name + ' idIndexCreate ' + JSON.stringify({ + isInteger: idIndex.isInteger, + name: idIndex.name + }) + '\n'; + }); + result += self.name + ' sizeLimit ' + self.sizeLimit + '\n'; + result += self.name + ' sortDefault ' + JSON.stringify(self.sortDefault) + '\n'; + self.crudGetManyByQuery({}).forEach(function (dbRow) { + result += self.name + ' dbRowSet ' + JSON.stringify(dbRow) + '\n'; + }); + return local.setTimeoutOnError(onError, null, result.trim()); + }; + + local._DbTable.prototype.idIndexCreate = function (options, onError) { + /* + * this function will create an idIndex with the given options.name + */ + var dbRow, idIndex, ii, name; + options = local.normalizeDict(options); + name = String(options.name); + // disallow idIndex with dot-name + if (name.indexOf('.') >= 0 || name === '_id') { + return local.setTimeoutOnError(onError); + } + // remove existing idIndex + this.idIndexRemove(options); + // init idIndex + idIndex = { + dict: {}, + isInteger: options.isInteger, + name: options.name + }; + this.idIndexList.push(idIndex); + // populate idIndex with dbRowList + // optimization - for-loop + for (ii = 0; ii < this.dbRowList.length; ii += 1) { + dbRow = this.dbRowList[ii]; + // auto-set id + if (!dbRow.$meta.isRemoved) { + idIndex.dict[local.dbRowSetId(dbRow, idIndex)] = dbRow; + } + } + this.save(); + return local.setTimeoutOnError(onError); + }; + + local._DbTable.prototype.idIndexRemove = function (options, onError) { + /* + * this function will remove the idIndex with the given options.name + */ + var name; + options = local.normalizeDict(options); + name = String(options.name); + this.idIndexList = this.idIndexList.filter(function (idIndex) { + return idIndex.name !== name || idIndex.name === '_id'; + }); + this.save(); + return local.setTimeoutOnError(onError); + }; + + local._DbTable.prototype.save = function (onError) { + /* + * this function will save the dbTable to storage + */ + var self; + self = this; + if (local.modeImport) { + return; + } + if (onError) { + self.onSaveList.push(onError); + } + // throttle storage-writes to once every 1000 ms + self.timerSave = self.timerSave || setTimeout(function () { + self.timerSave = null; + local.storageSetItem('dbTable.' + self.name + '.json', self.export(), function ( + error + ) { + while (self.onSaveList.length) { + self.onSaveList.shift()(error); + } + }); + }, 1000); + }; + + local.dbCrudRemoveAll = function (onError) { + /* + * this function will remove all dbRow's from the db + */ + var onParallel; + onParallel = local.onParallel(function (error) { + local.setTimeoutOnError(onError, error); + }); + onParallel.counter += 1; + Object.keys(local.dbTableDict).forEach(function (key) { + onParallel.counter += 1; + local.dbTableDict[key].crudRemoveAll(onParallel); + }); + onParallel(); + }; + + local.dbDrop = function (onError) { + /* + * this function will drop the db + */ + var onParallel; + onParallel = local.onParallel(function (error) { + local.setTimeoutOnError(onError, error); + }); + onParallel.counter += 1; + onParallel.counter += 1; + local.storageClear(onParallel); + Object.keys(local.dbTableDict).forEach(function (key) { + onParallel.counter += 1; + local.dbTableDict[key].drop(onParallel); + }); + onParallel(); + }; + + local.dbExport = function (onError) { + /* + * this function will export the db as serialized text + */ + var result; + result = ''; + Object.keys(local.dbTableDict).forEach(function (key) { + result += local.dbTableDict[key].export(); + result += '\n\n'; + }); + return local.setTimeoutOnError(onError, null, result.trim()); + }; + + local.dbImport = function (text, onError) { + /* + * this function will import the serialized text into the db + */ + var dbTable; + local.modeImport = true; + setTimeout(function () { + local.modeImport = null; + }); + text.replace((/^(\w\S*?) (\S+?) (\S.*?)$/gm), function ( + match0, + match1, + match2, + match3 + ) { + // jslint-hack + local.nop(match0); + switch (match2) { + case 'dbRowSet': + dbTable = local.dbTableCreateOne({ isLoaded: true, name: match1 }); + dbTable.crudSetOneById(JSON.parse(match3)); + break; + case 'idIndexCreate': + dbTable = local.dbTableCreateOne({ isLoaded: true, name: match1 }); + dbTable.idIndexCreate(JSON.parse(match3)); + break; + case 'sizeLimit': + dbTable = local.dbTableCreateOne({ isLoaded: true, name: match1 }); + dbTable.sizeLimit = JSON.parse(match3); + break; + case 'sortDefault': + dbTable = local.dbTableCreateOne({ isLoaded: true, name: match1 }); + break; + default: + local.onErrorDefault(new Error('dbImport - invalid operation - ' + match0)); + } + }); + local.modeImport = null; + return local.setTimeoutOnError(onError); + }; + + local.dbLoad = function (onError) { + /* + * this function will load the db from storage + */ + var onParallel; + onParallel = local.onParallel(function (error) { + local.setTimeoutOnError(onError, error); + }); + local.storageKeys(function (error, data) { + onParallel.counter += 1; + onParallel.counter += 1; + onParallel(error); + local.normalizeList(data) + .filter(function (key) { + return key.indexOf('dbTable.') === 0; + }) + .forEach(function (key) { + onParallel.counter += 1; + local.storageGetItem(key, function (error, data) { + onParallel.counter += 1; + onParallel(error); + local.dbImport(data, onParallel); + }); + }); + onParallel(); + }); + }; + + local.dbRowGetItem = function (dbRow, key) { + /* + * this function will get the item with the given key from dbRow + */ + var ii, value; + value = dbRow; + key = String(key).split('.'); + // optimization - for-loop + for (ii = 0; ii < key.length && value && typeof value === 'object'; ii += 1) { + value = value[key[ii]]; + } + return value === undefined + ? null + : value; + }; + + local.dbRowListGetManyByOperator = function (dbRowList, fieldName, operator, bb, not) { + /* + * this function will get the dbRow's in dbRowList with the given operator + */ + var ii, jj, result, fieldValue, test, typeof2; + result = []; + typeof2 = typeof bb; + if (bb && typeof2 === 'object') { + switch (operator) { + case '$in': + case '$nin': + case '$regex': + break; + default: + return result; + } + } + switch (operator) { + case '$eq': + test = function (aa, bb) { + return aa === bb; + }; + break; + case '$exists': + bb = !bb; + test = function (aa, bb) { + return !((aa === null) ^ bb); + }; + break; + case '$gt': + test = function (aa, bb, typeof1, typeof2) { + return typeof1 === typeof2 && aa > bb; + }; + break; + case '$gte': + test = function (aa, bb, typeof1, typeof2) { + return typeof1 === typeof2 && aa >= bb; + }; + break; + case '$in': + if (bb && typeof bb.indexOf === 'function') { + if (typeof2 === 'string') { + test = function (aa, bb, typeof1, typeof2) { + return typeof1 === typeof2 && bb.indexOf(aa) >= 0; + }; + } else { + test = function (aa, bb) { + return bb.indexOf(aa) >= 0; + }; + } + } + break; + case '$lt': + test = function (aa, bb, typeof1, typeof2) { + return typeof1 === typeof2 && aa < bb; + }; + break; + case '$lte': + test = function (aa, bb, typeof1, typeof2) { + return typeof1 === typeof2 && aa <= bb; + }; + break; + case '$ne': + test = function (aa, bb) { + return aa !== bb; + }; + break; + case '$nin': + if (bb && typeof bb.indexOf === 'function') { + if (typeof2 === 'string') { + test = function (aa, bb, typeof1, typeof2) { + return typeof1 === typeof2 && bb.indexOf(aa) < 0; + }; + } else { + test = function (aa, bb) { + return bb.indexOf(aa) < 0; + }; + } + } + break; + case '$regex': + if (bb && typeof bb.test === 'function') { + test = function (aa, bb) { + return bb.test(aa); + }; + } + break; + case '$typeof': + test = function (aa, bb, typeof1) { + // jslint-hack + local.nop(aa); + return typeof1 === bb; + }; + break; + } + if (!test) { + return result; + } + // optimization - for-loop + for (ii = dbRowList.length - 1; ii >= 0; ii -= 1) { + fieldValue = local.dbRowGetItem(dbRowList[ii], fieldName); + // normalize to list + if (!Array.isArray(fieldValue)) { + fieldValue = [fieldValue]; + } + // optimization - for-loop + for (jj = fieldValue.length - 1; jj >= 0; jj -= 1) { + if (not ^ test(fieldValue[jj], bb, typeof fieldValue[jj], typeof2)) { + result.push(dbRowList[ii]); + break; + } + } + } + return result; + }; + + local.dbRowListGetManyByQuery = function (dbRowList, query, fieldName, not) { + /* + * this function will get the dbRow's in dbRowList with the given query + */ + var bb, dbRowDict, result; + // optimization - convert to boolean + not = !!not; + result = dbRowList; + if (!(query && typeof query === 'object')) { + result = local.dbRowListGetManyByOperator(result, fieldName, '$eq', query, not); + return result; + } + Object.keys(query).some(function (key) { + bb = query[key]; + switch (key) { + case '$not': + key = fieldName; + not = !not; + break; + case '$or': + if (!Array.isArray(bb)) { + break; + } + dbRowDict = {}; + bb.forEach(function (query) { + // recurse + local.dbRowListGetManyByQuery(result, query).forEach(function (dbRow) { + dbRowDict[dbRow._id] = dbRow; + }); + }); + result = Object.keys(dbRowDict).map(function (id) { + return dbRowDict[id]; + }); + return !result.length; + } + if (key[0] === '$') { + result = local.dbRowListGetManyByOperator(result, fieldName, key, bb, not); + return !result.length; + } + // recurse + result = local.dbRowListGetManyByQuery(result, bb, key, not); + return !result.length; + }); + return result; + }; + + local.dbRowProject = function (dbRow, fieldList) { + /* + * this function will deepcopy and project the dbRow with the given fieldList + */ + var result; + if (!dbRow) { + return null; + } + // handle list-case + if (Array.isArray(dbRow)) { + return dbRow.map(function (dbRow) { + // recurse + return local.dbRowProject(dbRow, fieldList); + }); + } + // normalize to list + if (!(Array.isArray(fieldList) && fieldList.length)) { + fieldList = Object.keys(dbRow); + } + result = {}; + fieldList.forEach(function (key) { + if (key[0] !== '$') { + result[key] = dbRow[key]; + } + }); + return JSON.parse(local.jsonStringifyOrdered(result)); + }; + + local.dbRowSetId = function (dbRow, idIndex) { + /* + * this function will set a random and unique id into dbRow for the given idIndex, + * if it does not exist + */ + var id; + id = dbRow[idIndex.name]; + if (typeof id !== 'number' && typeof id !== 'string') { + do { + id = idIndex.isInteger + ? (1 + Math.random()) * 0x10000000000000 + : 'a' + ((1 + Math.random()) * 0x10000000000000).toString(36).slice(1); + // optimization - hasOwnProperty + } while (idIndex.dict.hasOwnProperty(id)); + dbRow[idIndex.name] = id; + } + return id; + }; + + local.dbSave = function (onError) { + /* + * this function will save the db to storage + */ + var onParallel; + onParallel = local.onParallel(function (error) { + local.setTimeoutOnError(onError, error); + }); + onParallel.counter += 1; + Object.keys(local.dbTableDict).forEach(function (key) { + onParallel.counter += 1; + local.dbTableDict[key].save(onParallel); + }); + onParallel(); + }; + + local.dbTableCreateMany = function (optionsList, onError) { + /* + * this function will set the optionsList into the db + */ + var onParallel, result; + onParallel = local.onParallel(function (error) { + local.setTimeoutOnError(onError, error, result); + }); + onParallel.counter += 1; + result = local.normalizeList(optionsList).map(function (options) { + onParallel.counter += 1; + return local.dbTableCreateOne(options, onParallel); + }); + return local.setTimeoutOnError(onParallel, null, result); + }; + + local.dbTableCreateOne = function (options, onError) { + /* + * this function will create a dbTable with the given options + */ + var self; + options = local.normalizeDict(options); + // register dbTable + self = local.dbTableDict[options.name] = + local.dbTableDict[options.name] || new local._DbTable(options); + self.sortDefault = options.sortDefault || + self.sortDefault || + [{ fieldName: '_timeUpdated', isDescending: true }]; + // remove idIndex + local.normalizeList(options.idIndexRemoveList).forEach(function (index) { + self.idIndexRemove(index); + }); + // create idIndex + local.normalizeList(options.idIndexCreateList).forEach(function (index) { + self.idIndexCreate(index); + }); + // upsert dbRow + self.crudSetManyById(options.dbRowList); + self.isLoaded = self.isLoaded || options.isLoaded; + if (!self.isLoaded) { + local.storageGetItem('dbTable.' + self.name + '.json', function (error, data) { + // validate no error occurred + console.assert(!error, error); + if (!self.isLoaded) { + local.dbImport(data); + } + self.isLoaded = true; + local.setTimeoutOnError(onError, null, self); + }); + return self; + } + return local.setTimeoutOnError(onError, null, self); + }; + + local.dbTableDict = {}; + + local.sortCompare = function (aa, bb, ii, jj) { + /* + * this function will compare aa vs bb and return: + * -1 if aa < bb + * 0 if aa === bb + * 1 if aa > bb + * the priority for comparing different typeof's is: + * null < boolean < number < string < object < undefined + */ + var typeof1, typeof2; + if (aa === bb) { + return ii < jj + ? -1 + : 1; + } + if (aa === null) { + return -1; + } + if (bb === null) { + return 1; + } + typeof1 = typeof aa; + typeof2 = typeof bb; + if (typeof1 === typeof2) { + return typeof1 === 'object' + ? 0 + : aa > bb + ? 1 + : -1; + } + if (typeof1 === 'boolean') { + return -1; + } + if (typeof2 === 'boolean') { + return 1; + } + if (typeof1 === 'number') { + return -1; + } + if (typeof2 === 'number') { + return 1; + } + if (typeof1 === 'string') { + return -1; + } + if (typeof2 === 'string') { + return 1; + } + return 0; + }; + }()); + switch (local.modeJs) { + + + + // run node js-env code - init-after + case 'node': + // require modules + local.fs = require('fs'); + break; + } +}()); +/* script-end /assets.utility2.lib.db.js */ + + + +/* script-begin /assets.utility2.lib.github_crud.js */ +///usr/bin/env node +/* istanbul instrument in package github-crud */ +/*jslint + bitwise: true, + browser: true, + maxerr: 8, + maxlen: 96, + node: true, + nomen: true, + regexp: true, + stupid: true +*/ +(function () { + 'use strict'; + var local; + + + + // run shared js-env code - init-before + (function () { + // init local + local = {}; + // init modeJs + local.modeJs = (function () { + try { + return typeof navigator.userAgent === 'string' && + typeof document.querySelector('body') === 'object' && + typeof XMLHttpRequest.prototype.open === 'function' && + 'browser'; + } catch (errorCaughtBrowser) { + return module.exports && + typeof process.versions.node === 'string' && + typeof require('http').createServer === 'function' && + 'node'; + } + }()); + // init global + local.global = local.modeJs === 'browser' + ? window + : global; + // init utility2_rollup + local = local.global.utility2_rollup || local; + // init lib + local.local = local.github_crud = local; + // init exports + if (local.modeJs === 'browser') { + local.global.utility2_github_crud = local; + } else { + module.exports = local; + module.exports.__dirname = __dirname; + module.exports.module = module; + } + }()); + + + + /* istanbul ignore next */ + // run shared js-env code - function-before + (function () { + local.httpRequest = function (options, onError) { + /* + * this function will request the data from options.url + */ + var chunkList, isDone, onError2, timerTimeout, request, response, urlParsed; + // init onError2 + onError2 = function (error) { + if (isDone) { + return; + } + isDone = true; + // cleanup timerTimeout + clearTimeout(timerTimeout); + // cleanup request and response + [request, response].forEach(function (stream) { + // try to end the stream + try { + stream.end(); + // else try to destroy the stream + } catch (errorCaught) { + try { + stream.destroy(); + } catch (ignore) { + } + } + }); + if (response && (response.statusCode < 200 || response.statusCode >= 300)) { + error = error || new Error(response.statusCode); + console.error(String(response.data)); + } + // debug response + console.error(new Date().toISOString() + ' http-response ' + JSON.stringify({ + statusCode: (response && response.statusCode) || 0, + method: options.method, + url: options.url + })); + onError(error, response); + }; + // init timerTimeout + timerTimeout = setTimeout(function () { + onError2(new Error('http-request timeout')); + }, options.timeout || 30000); + urlParsed = require('url').parse(options.url); + urlParsed.headers = options.headers; + urlParsed.method = options.method; + // debug request + console.error(); + console.error(new Date().toISOString() + ' http-request ' + JSON.stringify({ + method: options.method, + url: options.url + })); + request = require( + urlParsed.protocol.slice(0, -1) + ).request(urlParsed, function (_response) { + response = _response; + chunkList = []; + response + .on('data', function (chunk) { + chunkList.push(chunk); + }) + .on('end', function () { + response.data = Buffer.concat(chunkList); + onError2(); + }) + .on('error', onError2); + }).on('error', onError2); + request.end(options.data); + }; + + local.nop = function () { + /* + * this function will do nothing + */ + return; + }; + + local.onErrorWithStack = function (onError) { + /* + * this function will create a new callback that will call onError, + * and append the current stack to any error + */ + var stack; + stack = new Error().stack.replace((/(.*?)\n.*?$/m), '$1'); + return function (error, data, meta) { + if (error && + error !== local.errorDefault && + String(error.stack).indexOf(stack.split('\n')[2]) < 0) { + // append the current stack to error.stack + error.stack += '\n' + stack; + } + onError(error, data, meta); + }; + }; + + local.onNext = function (options, onError) { + /* + * this function will wrap onError inside the recursive function options.onNext, + * and append the current stack to any error + */ + options.onNext = local.onErrorWithStack(function (error, data, meta) { + try { + options.modeNext = error && !options.modeErrorIgnore + ? Infinity + : options.modeNext + 1; + onError(error, data, meta); + } catch (errorCaught) { + // throw errorCaught to break infinite recursion-loop + if (options.errorCaught) { + throw options.errorCaught; + } + options.errorCaught = errorCaught; + options.onNext(errorCaught, data, meta); + } + }); + return options; + }; + + local.onParallel = function (onError, onEach, onRetry) { + /* + * this function will create a function that will + * 1. run async tasks in parallel + * 2. if counter === 0 or error occurred, then call onError with error + */ + var onParallel; + onError = local.onErrorWithStack(onError); + onEach = onEach || local.nop; + onRetry = onRetry || local.nop; + onParallel = function (error, data) { + if (onRetry(error, data)) { + return; + } + // decrement counter + onParallel.counter -= 1; + // validate counter + console.assert(onParallel.counter >= 0 || error || onParallel.error); + // ensure onError is run only once + if (onParallel.counter < 0) { + return; + } + // handle error + if (error) { + onParallel.error = error; + // ensure counter <= 0 + onParallel.counter = -Math.abs(onParallel.counter); + } + // call onError when isDone + if (onParallel.counter <= 0) { + onError(error, data); + return; + } + onEach(); + }; + // init counter + onParallel.counter = 0; + // return callback + return onParallel; + }; + + local.onParallelList = function (options, onEach, onError) { + /* + * this function will + * 1. async-run onEach in parallel, + * with the given options.rateLimit and options.retryLimit + * 2. call onError when isDone + */ + var ii, onEach2, onParallel; + onEach2 = function () { + while (ii + 1 < options.list.length && onParallel.counter < options.rateLimit) { + ii += 1; + onParallel.ii += 1; + onParallel.remaining -= 1; + onEach({ + element: options.list[ii], + ii: ii, + list: options.list, + retry: 0 + }, onParallel); + } + }; + onParallel = local.onParallel(onError, onEach2, function (error, data) { + if (error && data && data.retry < options.retryLimit) { + local.onErrorDefault(error); + data.retry += 1; + setTimeout(function () { + onParallel.counter -= 1; + onEach(data, onParallel); + }, 1000); + return true; + } + }); + onParallel.counter += 1; + ii = -1; + onParallel.ii = -1; + onParallel.remaining = options.list.length; + options.rateLimit = Number(options.rateLimit) || 4; + options.rateLimit = Math.max(options.rateLimit, 3); + options.retryLimit = Number(options.retryLimit) || 2; + onEach2(); + onParallel(); + }; + + local.onReadyAfter = function (onError) { + /* + * this function will call onError when onReadyBefore.counter === 0 + */ + local.onReadyBefore.counter += 1; + local.taskCreate({ key: 'utility2.onReadyAfter' }, null, onError); + local.onResetAfter(local.onReadyBefore); + return onError; + }; + }()); + switch (local.modeJs) { + + + + // run node js-env code - function + case 'node': + local.contentDelete = function (options, onError) { + /* + * this function will delete the github file + * https://developer.github.com/v3/repos/contents/#delete-a-file + */ + options = { message: options.message, url: options.url }; + local.onNext(options, function (error, data) { + switch (options.modeNext) { + case 1: + // get sha + local.contentRequest({ method: 'GET', url: options.url }, options.onNext); + break; + case 2: + // delete file with sha + if (!error && data.sha) { + local.contentRequest({ + message: options.message, + method: 'DELETE', + sha: data.sha, + url: options.url + }, options.onNext); + return; + } + // delete tree + local.onParallelList({ list: data }, function (data, onParallel) { + onParallel.counter += 1; + // recurse + local.contentDelete({ + message: options.message, + url: data.element.url + }, onParallel); + }, options.onNext); + break; + default: + onError(); + } + }); + options.modeNext = 0; + options.onNext(); + }; + + local.contentGet = function (options, onError) { + /* + * this function will get the github file + * https://developer.github.com/v3/repos/contents/#get-contents + */ + options = { url: options.url }; + local.onNext(options, function (error, data) { + switch (options.modeNext) { + case 1: + local.contentRequest({ method: 'GET', url: options.url }, options.onNext); + break; + case 2: + options.onNext(null, new Buffer(data.content, 'base64')); + break; + default: + onError(error, !error && data); + } + }); + options.modeNext = 0; + options.onNext(); + }; + + local.contentPut = function (options, onError) { + /* + * this function will put options.content into the github file + * https://developer.github.com/v3/repos/contents/#update-a-file + */ + options = { + content: options.content, + message: options.message, + modeErrorIgnore: true, + url: options.url + }; + local.onNext(options, function (error, data) { + switch (options.modeNext) { + case 1: + // get sha + local.contentRequest({ method: 'GET', url: options.url }, options.onNext); + break; + case 2: + // put file with sha + local.contentRequest({ + content: options.content, + message: options.message, + method: 'PUT', + sha: data.sha, + url: options.url + }, options.onNext); + break; + default: + onError(error); + } + }); + options.modeNext = 0; + options.onNext(); + }; + + local.contentPutFile = function (options, onError) { + /* + * this function will put options.file into the github file + * https://developer.github.com/v3/repos/contents/#update-a-file + */ + options = { file: options.file, message: options.message, url: options.url }; + local.onNext(options, function (error, data) { + switch (options.modeNext) { + case 1: + // get file from url + if ((/^(?:http|https):\/\//).test(options.file)) { + local.httpRequest({ + method: 'GET', + url: options.file + }, function (error, response) { + options.onNext(error, response && response.data); + }); + return; + } + // get file + local.fs.readFile( + local.path.resolve(process.cwd(), options.file), + options.onNext + ); + break; + case 2: + local.contentPut({ + content: data, + message: options.message, + // resolve file in url + url: (/\/$/).test(options.url) + ? options.url + local.path.basename(options.file) + : options.url + }, options.onNext); + break; + default: + onError(error); + } + }); + options.modeNext = 0; + options.onNext(); + }; + + local.contentRequest = function (options, onError) { + /* + * this function will request the content from github + */ + // init options + options = { + chunkList: [], + content: options.content, + headers: { + // github oauth authentication + Authorization: 'token ' + process.env.GITHUB_TOKEN, + // bug-workaround - https://developer.github.com/v3/#user-agent-required + 'User-Agent': 'undefined' + }, + message: options.message, + method: options.method, + responseJson: {}, + sha: options.sha, + url: options.url + }; + options.url = options.url +/* jslint-ignore-begin */ +// parse https://github.com/:owner/:repo/blob/:branch/:path +.replace( + (/^https:\/\/github.com\/([^\/]+?\/[^\/]+?)\/blob\/([^\/]+?)\/(.+)/), + 'https://api.github.com/repos/$1/contents/$3?branch=$2' +) +// parse https://github.com/:owner/:repo/tree/:branch/:path +.replace( + (/^https:\/\/github.com\/([^\/]+?\/[^\/]+?)\/tree\/([^\/]+?)\/(.+)/), + 'https://api.github.com/repos/$1/contents/$3?branch=$2' +) +// parse https://raw.githubusercontent.com/:owner/:repo/:branch/:path +.replace( +(/^https:\/\/raw.githubusercontent.com\/([^\/]+?\/[^\/]+?)\/([^\/]+?)\/(.+)/), + 'https://api.github.com/repos/$1/contents/$3?branch=$2' +) +// parse https://:owner.github.io/:repo/:path +.replace( + (/^https:\/\/([^\.]+?)\.github\.io\/([^\/]+?)\/(.+)/), + 'https://api.github.com/repos/$1/$2/contents/$3?branch=gh-pages' +) +/* jslint-ignore-end */ + .replace((/\?branch=(.*)/), function (match0, match1) { + options.branch = match1; + if (options.method === 'GET') { + match0 = match0.replace('branch', 'ref'); + } + return match0; + }); + if (options.url.indexOf('https://api.github.com/repos/') !== 0) { + onError(new Error('invalid url ' + options.url)); + return; + } + if (options.method !== 'GET') { + options.message = options.message || + '[ci skip] ' + options.method + ' file ' + options.url + .replace((/\?.*/), ''); + options.url += '&message=' + encodeURIComponent(options.message); + if (options.sha) { + options.url += '&sha=' + options.sha; + } + options.data = JSON.stringify({ + branch: options.branch, + content: new Buffer(options.content || '').toString('base64'), + message: options.message, + sha: options.sha + }); + } + local.httpRequest(options, function (error, response) { + try { + options.responseJson = JSON.parse(response.data.toString()); + } catch (ignore) { + } + onError(error, options.responseJson); + }); + }; + + local.contentTouch = function (options, onError) { + /* + * this function will touch options.url + * https://developer.github.com/v3/repos/contents/#update-a-file + */ + options = { + message: options.message, + modeErrorIgnore: true, + url: options.url + }; + local.onNext(options, function (error, data) { + switch (options.modeNext) { + case 1: + // get sha + local.contentRequest({ method: 'GET', url: options.url }, options.onNext); + break; + case 2: + // put file with sha + local.contentRequest({ + content: new Buffer(data.content || '', 'base64'), + message: options.message, + method: 'PUT', + sha: data.sha, + url: options.url + }, options.onNext); + break; + default: + onError(error); + } + }); + options.modeNext = 0; + options.onNext(); + }; + + local.contentTouchList = function (options, onError) { + /* + * this function will touch options.urlList in parallel + * https://developer.github.com/v3/repos/contents/#update-a-file + */ + local.onParallelList({ list: options.urlList }, function (data, onParallel) { + onParallel.counter += 1; + local.contentTouch({ + message: options.message, + modeErrorIgnore: true, + url: data.element + }, onParallel); + }, onError); + }; + break; + } + switch (local.modeJs) { + + + + /* istanbul ignore next */ + // run node js-env code - init-after + case 'node': + // require modules + local.fs = require('fs'); + local.path = require('path'); + // run the cli + if (module !== require.main || local.global.utility2_rollup) { + break; + } + switch (String(process.argv[2]).toLowerCase()) { + // delete file + case 'delete': + local.contentDelete({ + message: process.argv[4], + url: process.argv[3] + }, function (error) { + // validate no error occurred + console.assert(!error, error); + }); + break; + // get file + case 'get': + local.contentGet({ url: process.argv[3] }, function (error, data) { + // validate no error occurred + console.assert(!error, error); + try { + process.stdout.write(data); + } catch (ignore) { + } + }); + break; + // put file + case 'put': + local.contentPutFile({ + message: process.argv[5], + url: process.argv[3], + file: process.argv[4] + }, function (error) { + // validate no error occurred + console.assert(!error, error); + }); + break; + // touch file + case 'touch': + local.contentTouch({ + message: process.argv[4], + url: process.argv[3] + }, function (error) { + // validate no error occurred + console.assert(!error, error); + }); + break; + case 'touchlist': + local.contentTouchList({ + message: process.argv[4], + urlList: process.argv[3].split(' ').filter(function (element) { + return element; + }) + }, function (error) { + // validate no error occurred + console.assert(!error, error); + }); + break; + } + break; + } +}()); +/* script-end /assets.utility2.lib.github_crud.js */ + + + +/* script-begin /assets.utility2.lib.istanbul.js */ +///usr/bin/env node +/* istanbul instrument in package istanbul */ +/*jslint + bitwise: true, + browser: true, + maxerr: 8, + maxlen: 96, + node: true, + nomen: true, + regexp: true, + stupid: true +*/ +(function (local) { + 'use strict'; + var __dirname, process, require; + + + + // run shared js-env code - init-before + (function () { + // jslint-hack + local.nop(__dirname); + __dirname = ''; + /* istanbul ignore next */ + local.global.__coverageCodeDict__ = local.global.__coverageCodeDict__ || {}; + local['./package.json'] = {}; + process = local.modeJs === 'browser' + ? { + cwd: function () { + return ''; + }, + stdout: {} + } + : local.process; + require = function (key) { + try { + return local[key] || local.require(key); + } catch (ignore) { + } + }; + }()); + + + + // run shared js-env code - function + (function () { + local.coverageMerge = function (coverage1, coverage2) { + /* + * this function will merge coverage2 into coverage1 + */ + var dict1, dict2; + coverage1 = coverage1 || {}; + coverage2 = coverage2 || {}; + Object.keys(coverage2).forEach(function (file) { + if (!coverage2[file]) { + return; + } + // if file is undefined in coverage1, then add it + if (!coverage1[file]) { + coverage1[file] = coverage2[file]; + return; + } + // merge file from coverage2 into coverage1 + ['b', 'f', 's'].forEach(function (key) { + dict1 = coverage1[file][key]; + dict2 = coverage2[file][key]; + switch (key) { + // increment coverage for branch lines + case 'b': + Object.keys(dict2).forEach(function (key) { + dict2[key].forEach(function (count, ii) { + dict1[key][ii] += count; + }); + }); + break; + // increment coverage for function and statement lines + case 'f': + case 's': + Object.keys(dict2).forEach(function (key) { + dict1[key] += dict2[key]; + }); + break; + } + }); + }); + return coverage1; + }; + + local.coverageReportCreate = function () { + /* + * this function will + * 1. print coverage in text-format to stdout + * 2. write coverage in html-format to filesystem + * 3. return coverage in html-format as single document + */ + var options; + /* istanbul ignore next */ + if (!local.global.__coverage__) { + return ''; + } + options = {}; + options.dir = process.cwd() + '/tmp/build/coverage.html'; + // merge previous coverage + if (local.modeJs === 'node' && process.env.npm_config_mode_coverage_merge) { + console.log('merging file://' + options.dir + '/coverage.json to coverage'); + try { + local.coverageMerge( + local.global.__coverage__, + JSON.parse( + local._fs.readFileSync(options.dir + '/coverage.json', 'utf8') + ) + ); + } catch (ignore) { + } + try { + options.coverageCodeDict = JSON.parse(local._fs.readFileSync( + options.dir + '/coverage.code-dict.json', + 'utf8' + )); + Object.keys(options.coverageCodeDict).forEach(function (key) { + local.global.__coverageCodeDict__[key] = + local.global.__coverageCodeDict__[key] || + options.coverageCodeDict[key]; + }); + } catch (ignore) { + } + } + // init writer + local.coverageReportHtml = ''; + local.coverageReportHtml += '
\n' + + '

coverage-report

\n' + + '
\n'; + local.writerData = ''; + options.sourceStore = {}; + options.writer = local.writer; + // 1. print coverage in text-format to stdout + new local.TextReport(options).writeReport(local.collector); + // 2. write coverage in html-format to filesystem + new local.HtmlReport(options).writeReport(local.collector); + local.writer.writeFile('', local.nop); + // write coverage.json + local.fsWriteFileWithMkdirpSync2( + options.dir + '/coverage.json', + JSON.stringify(local.global.__coverage__) + ); + // write coverage.code-dict.json + local.fsWriteFileWithMkdirpSync2( + options.dir + '/coverage.code-dict.json', + JSON.stringify(local.global.__coverageCodeDict__) + ); + // write coverage.badge.svg + options.pct = local.coverageReportSummary.root.metrics.lines.pct; + local.fsWriteFileWithMkdirpSync2( + local.path.dirname(options.dir) + '/coverage.badge.svg', + local.templateCoverageBadgeSvg + // edit coverage badge percent + .replace((/100.0/g), options.pct) + // edit coverage badge color + .replace( + (/0d0/g), + ('0' + Math.round((100 - options.pct) * 2.21).toString(16)).slice(-2) + + ('0' + Math.round(options.pct * 2.21).toString(16)).slice(-2) + '00' + ) + ); + console.log('created coverage file://' + options.dir + '/index.html'); + // 3. return coverage in html-format as a single document + local.coverageReportHtml += '
\n
\n'; + // write coverage.rollup.html + local.fsWriteFileWithMkdirpSync2( + options.dir + '/coverage.rollup.html', + local.coverageReportHtml + ); + return local.coverageReportHtml; + }; + + local.fs = {}; + + local.fs.readFileSync = function (file) { + // return head.txt or foot.txt + file = local[file.slice(-8)]; + if (local.modeJs === 'browser') { + file = file + .replace((/\bhtml\b/g), 'x-istanbul-html') + .replace((/\n\ +\n\ +\n\ +
\n\ +

\n\ + {{env.npm_package_name}} (v{{env.npm_package_version}})\n\ +

\n\ +

Code coverage report for {{entity}}

\n\ +

\n\ + {{#with metrics.statements}}\n\ + Statements: {{pct}}% ({{covered}} / {{total}})     \n\ + {{/with}}\n\ + {{#with metrics.branches}}\n\ + Branches: {{pct}}% ({{covered}} / {{total}})     \n\ + {{/with}}\n\ + {{#with metrics.functions}}\n\ + Functions: {{pct}}% ({{covered}} / {{total}})     \n\ + {{/with}}\n\ + {{#with metrics.lines}}\n\ + Lines: {{pct}}% ({{covered}} / {{total}})     \n\ + {{/with}}\n\ + Ignored: {{#show_ignores metrics}}{{/show_ignores}}     \n\ +

\n\ + {{{pathHtml}}}\n\ +
\n\ +
\n\ +'; +/* jslint-ignore-end */ + + + + /* istanbul ignore next */ + // init lib istanbul.util.file-writer + (function () { + // https://github.com/gotwarlost/istanbul/blob/v0.2.16/lib/util/file-writer.js + local.writer = { + write: function (data) { + local.writerData += data; + }, + writeFile: function (file, onError) { + local.coverageReportHtml += local.writerData + '\n\n'; + if (local.writerFile) { + local.fsWriteFileWithMkdirpSync2(local.writerFile, local.writerData); + } + local.writerData = ''; + local.writerFile = file; + onError(local.writer); + } + }; + }()); + + + + /* istanbul ignore next */ + // init lib istanbul.util.tree-summarizer + (function () { + var module; + module = {}; +/* jslint-ignore-begin */ +// https://github.com/gotwarlost/istanbul/blob/v0.2.16/lib/util/tree-summarizer.js +// utility2-uglifyjs https://raw.githubusercontent.com/gotwarlost/istanbul/v0.2.16/lib/util/tree-summarizer.js +function commonArrayPrefix(e,t){var n=e.length0&&(t.pop(),s=i,o=s.children,s.children=[],i=new +Node(t.join(SEP)+SEP,"dir"),i.addChild(s),o.forEach(function(e){e.kind==="dir"?i +.addChild(e):s.addChild(e)})),this.fixupNodes(i,t.join(SEP)+SEP),this.calculateMetrics +(i),this.root=i,this.map={},this.indexAndSortTree(i,this.map)},fixupNodes:function( +e,t,n){var r=this;e.name.indexOf(t)===0&&(e.name=e.name.substring(t.length)),e.name +.charAt(0)===SEP&&(e.name=e.name.substring(1)),n?n.name!=="__root__/"?e.relativeName= +e.name.substring(n.name.length):e.relativeName=e.name:e.relativeName=e.name.substring +(t.length),e.children.forEach(function(n){r.fixupNodes(n,t,e)})},calculateMetrics +:function(e){var t=this,n;if(e.kind!=="dir")return;e.children.forEach(function(e +){t.calculateMetrics(e)}),e.metrics=utils.mergeSummaryObjects.apply(null,e.children +.map(function(e){return e.metrics})),n=e.children.filter(function(e){return e.kind!=="dir" +}),n.length>0?e.packageMetrics=utils.mergeSummaryObjects.apply(null,n.map(function( +e){return e.metrics})):e.packageMetrics=null},indexAndSortTree:function(e,t){var n= +this;t[e.name]=e,e.children.sort(function(e,t){return e=e.relativeName,t=t.relativeName +,et?1:0}),e.children.forEach(function(e){n.indexAndSortTree(e,t)})},toJSON +:function(){return{prefix:this.prefix,root:this.root.toJSON()}}},TreeSummarizer. +prototype={addFileCoverageSummary:function(e,t){this.summaryMap[e]=t},getTreeSummary +:function(){var e=findCommonArrayPrefix(Object.keys(this.summaryMap));return new +TreeSummary(this.summaryMap,e)}},module.exports=TreeSummarizer +/* jslint-ignore-end */ + local['../util/tree-summarizer'] = module.exports; + module.exports.prototype._getTreeSummary = module.exports.prototype.getTreeSummary; + module.exports.prototype.getTreeSummary = function () { + local.coverageReportSummary = this._getTreeSummary(); + return local.coverageReportSummary; + }; + }()); + + + +/* istanbul ignore next */ +// init lib istanbul.report.html +/* jslint-ignore-begin */ +// https://github.com/gotwarlost/istanbul/blob/v0.2.16/lib/report/html.js +// utility2-uglifyjs https://raw.githubusercontent.com/gotwarlost/istanbul/v0.2.16/lib/report/html.js +(function () { var module; module = {}; +function customEscape(e){return e=e.toString(),e.replace(RE_AMP,"&").replace +(RE_LT,"<").replace(RE_GT,">").replace(RE_lt,"<").replace(RE_gt,">")}function title +(e){return' title="'+e+'" '}function annotateLines(e,t){var n=e.l;if(!n)return;Object +.keys(n).forEach(function(e){var r=n[e];t[e].covered=r>0?"yes":"no"}),t.forEach( +function(e){e.covered===null&&(e.covered="neutral")})}function annotateStatements +(e,t){var n=e.s,r=e.statementMap;Object.keys(n).forEach(function(e){var i=n[e],s= +r[e],o=i>0?"yes":"no",u=s.start.column,a=s.end.column+1,f=s.start.line,l=s.end.line +,c=lt+'span class="'+(s.skip?"cstat-skip":"cstat-no")+'"'+title("statement not covered" +)+gt,h=lt+"/span"+gt,p;o==="no"&&(l!==f&&(l=f,a=t[f].text.originalLength()),p=t[ +f].text,p.wrap(u,c,f===l?a:p.originalLength(),h))})}function annotateFunctions(e +,t){var n=e.f,r=e.fnMap;if(!n)return;Object.keys(n).forEach(function(e){var i=n[ +e],s=r[e],o=i>0?"yes":"no",u=s.loc.start.column,a=s.loc.end.column+1,f=s.loc.start +.line,l=s.loc.end.line,c=lt+'span class="'+(s.skip?"fstat-skip":"fstat-no")+'"'+ +title("function not covered")+gt,h=lt+"/span"+gt,p;o==="no"&&(l!==f&&(l=f,a=t[f] +.text.originalLength()),p=t[f].text,p.wrap(u,c,f===l?a:p.originalLength(),h))})} +function annotateBranches(e,t){var n=e.b,r=e.branchMap;if(!n)return;Object.keys( +n).forEach(function(e){var i=n[e],s=i.reduce(function(e,t){return e+t},0),o=r[e] +.locations,u,a,f,l,c,h,p,d,v,m,g;if(s>0)for(u=0;u0?"yes":"no",c=f.start.column,h=f.end.column+1,p=f.start.line,d=f.end.line,v=lt+'span class="branch-'+ +u+" "+(f.skip?"cbranch-skip":"cbranch-no")+'"'+title("branch not covered")+gt,m= +lt+"/span"+gt,a===0&&(d!==p&&(d=p,h=t[p].text.originalLength()),g=t[p].text,r[e] +.type==="if"?g.insertAt(c,lt+'span class="'+(f.skip?"skip-if-branch":"missing-if-branch" +)+'"'+title((u===0?"if":"else")+" path not taken")+gt+(u===0?"I":"E")+lt+"/span"+ +gt,!0,!1):g.wrap(c,v,p===d?h:g.originalLength(),m))})}function getReportClass(e, +t){var n=e.pct,r=1;return n*r===n?n>=t[1]?"high":n>=t[0]?"medium":"low":""}function HtmlReport +(e){Report.call(this),this.opts=e||{},this.opts.dir=this.opts.dir||path.resolve( +process.cwd(),"html-report"),this.opts.sourceStore=this.opts.sourceStore||Store. +create("fslookup"),this.opts.linkMapper=this.opts.linkMapper||this.standardLinkMapper +(),this.opts.writer=this.opts.writer||null,this.opts.templateData={datetime:Date +()},this.opts.watermarks=this.opts.watermarks||defaults.watermarks()}var handlebars= +require("handlebars"),defaults=require("./common/defaults"),path=require("path") +,SEP=path.sep||"/",fs=require("fs"),util=require("util"),FileWriter=require("../util/file-writer" +),Report=require("./index"),Store=require("../store"),InsertionText=require("../util/insertion-text" +),TreeSummarizer=require("../util/tree-summarizer"),utils=require("../object-utils" +),templateFor=function(e){return handlebars.compile(fs.readFileSync(path.resolve +(__dirname,"templates",e+".txt"),"utf8"))},headerTemplate=templateFor("head"),footerTemplate= +templateFor("foot"),pathTemplate=handlebars.compile('
{{{html}}}
' +),detailTemplate=handlebars.compile(["",'{{#show_lines}}{{maxLines}}{{/show_lines}}' +,'{{#show_line_execution_counts fileCoverage}}{{maxLines}}{{/show_line_execution_counts}}' +,'
{{#show_code structured}}{{/show_code}}
' +,"\n"].join("")),summaryTableHeader=['
',"" +,"","",' ' +,' ' +,' ' +,' ' +,' ' +,' ' +,' ' +,' ' +,' ' +,' ' +,"","",""].join("\n"),summaryLineTemplate=handlebars.compile +(["",'' +,'' +,'' +,'' +,'' +,'' +,'' +,'' +,'' +,'' +,"\n"].join("\n ")),summaryTableFooter=["","
FileStatementsBranchesFunctionsLines
{{file}}{{#show_picture}}{{metrics.statements.pct}}{{/show_picture}}{{metrics.statements.pct}}%({{metrics.statements.covered}} / {{metrics.statements.total}}){{metrics.branches.pct}}%({{metrics.branches.covered}} / {{metrics.branches.total}}){{metrics.functions.pct}}%({{metrics.functions.covered}} / {{metrics.functions.total}}){{metrics.lines.pct}}%({{metrics.lines.covered}} / {{metrics.lines.total}})
","
"].join +("\n"),lt="",gt="",RE_LT=//g,RE_AMP=/&/g,RE_lt=/\u0001/g,RE_gt=/\u0002/g +;handlebars.registerHelper("show_picture",function(e){var t=Number(e.fn(this)),n +,r="";return isFinite(t)?(t===100&&(r=" cover-full"),t=Math.floor(t),n=100-t,''+''):""}),handlebars.registerHelper("show_ignores",function(e){var t= +e.statements.skipped,n=e.functions.skipped,r=e.branches.skipped,i;return t===0&& +n===0&&r===0?'none':(i=[],t>0&&i.push(t===1?"1 statement" +:t+" statements"),n>0&&i.push(n===1?"1 function":n+" functions"),r>0&&i.push(r===1?"1 branch" +:r+" branches"),i.join(", "))}),handlebars.registerHelper("show_lines",function( +e){var t=Number(e.fn(this)),n,r=[];for(n=0;n0?(u="yes",a=n[s]):u="no"),o.push(''+a+"");return o.join("\n")}),handlebars.registerHelper("show_code", +function(e){var t=[];return e.forEach(function(e){t.push(customEscape(e.text)||" " +)}),t.join("\n")}),HtmlReport.TYPE="html",util.inherits(HtmlReport,Report),Report +.mix(HtmlReport,{getPathHtml:function(e,t){var n=e.parent,r=[],i=[],s;while(n)r. +push(n),n=n.parent;for(s=0;s'+ +(r[s].relativeName||"All files")+"");return i.reverse(),i.length>0?i.join(" » " +)+" » "+e.displayShortName():""},fillTemplate:function(e,t){var n=this.opts +,r=n.linkMapper;t.entity=e.name||"All files",t.metrics=e.metrics,t.reportClass=getReportClass +(e.metrics.statements,n.watermarks.statements),t.pathHtml=pathTemplate({html:this +.getPathHtml(e,r)}),t.prettify={js:r.asset(e,"prettify.js"),css:r.asset(e,"prettify.css" +)}},writeDetailPage:function(e,t,n){var r=this.opts,i=r.sourceStore,s=r.templateData +,o=n.code&&Array.isArray(n.code)?n.code.join("\n")+"\n":i.get(n.path),u=o.split(/(?:\r?\n)|\r/ +),a=0,f=u.map(function(e){return a+=1,{line:a,covered:null,text:new InsertionText +(e,!0)}}),l;f.unshift({line:0,covered:null,text:new InsertionText("")}),this.fillTemplate +(t,s),e.write(headerTemplate(s)),e.write('
\n'),annotateLines
+(n,f),annotateBranches(n,f),annotateFunctions(n,f),annotateStatements(n,f),f.shift
+(),l={structured:f,maxLines:f.length,fileCoverage:n},e.write(detailTemplate(l)),
+e.write("
\n"),e.write(footerTemplate(s))},writeIndexPage:function( +e,t){var n=this.opts.linkMapper,r=this.opts.templateData,i=Array.prototype.slice +.apply(t.children),s=this.opts.watermarks;i.sort(function(e,t){return e.name0&&(o>=l?(f=padding(o-l),a=n?f+e: +e+f):(a=e.substring(l-o),a="... "+a.substring(4))),a=defaults.colorize(a,i),u+a} +function formatName(e,t,n,r){return fill(e,t,!1,n,r)}function formatPct(e,t){return fill +(e,PCT_COLS,!0,0,t)}function nodeName(e){return e.displayShortName()||"All files" +}function tableHeader(e){var t=[];return t.push(formatName("File",e,0)),t.push(formatPct +("% Stmts")),t.push(formatPct("% Branches")),t.push(formatPct("% Funcs")),t.push +(formatPct("% Lines")),t.join(" |")+" |"}function tableRow(e,t,n,r){var i=nodeName +(e),s=e.metrics.statements.pct,o=e.metrics.branches.pct,u=e.metrics.functions.pct +,a=e.metrics.lines.pct,f=[];return f.push(formatName(i,t,n,defaults.classFor("statements" +,e.metrics,r))),f.push(formatPct(s,defaults.classFor("statements",e.metrics,r))) +,f.push(formatPct(o,defaults.classFor("branches",e.metrics,r))),f.push(formatPct +(u,defaults.classFor("functions",e.metrics,r))),f.push(formatPct(a,defaults.classFor +("lines",e.metrics,r))),f.join(DELIM)+DELIM}function findNameWidth(e,t,n){n=n||0 +,t=t||0;var r=TAB_SIZE*t+nodeName(e).length;return r>n&&(n=r),e.children.forEach +(function(e){n=findNameWidth(e,t+1,n)}),n}function makeLine(e){var t=padding(e,"-" +),n=padding(PCT_COLS,"-"),r=[];return r.push(t),r.push(n),r.push(n),r.push(n),r. +push(n),r.join(COL_DELIM)+COL_DELIM}function walk(e,t,n,r,i){var s;r===0?(s=makeLine +(t),n.push(s),n.push(tableHeader(t)),n.push(s)):n.push(tableRow(e,t,r,i)),e.children +.forEach(function(e){walk(e,t,n,r+1,i)}),r===0&&(n.push(s),n.push(tableRow(e,t,r +,i)),n.push(s))}var path=require("path"),mkdirp=require("mkdirp"),fs=require("fs" +),defaults=require("./common/defaults"),Report=require("./index"),TreeSummarizer= +require("../util/tree-summarizer"),utils=require("../object-utils"),PCT_COLS=10, +TAB_SIZE=3,DELIM=" |",COL_DELIM="-|";TextReport.TYPE="text",Report.mix(TextReport +,{writeReport:function(e){var t=new TreeSummarizer,n,r,i,s=4*(PCT_COLS+2),o,u=[] +,a;e.files().forEach(function(n){t.addFileCoverageSummary(n,utils.summarizeFileCoverage +(e.fileCoverageFor(n)))}),n=t.getTreeSummary(),r=n.root,i=findNameWidth(r),this. +maxCols>0&&(o=this.maxCols-s-2,i>o&&(i=o)),walk(r,i,u,0,this.watermarks),a=u.join +("\n")+"\n",this.file?(mkdirp.sync(this.dir),fs.writeFileSync(path.join(this.dir +,this.file),a,"utf8")):console.log(a)}}),module.exports=TextReport +local.TextReport = module.exports; }()); +/* jslint-ignore-end */ + + + +/* jslint-ignore-begin */ +// https://img.shields.io/badge/coverage-100.0%-00dd00.svg?style=flat +local.templateCoverageBadgeSvg = +'coveragecoverage100.0%100.0%'; +/* jslint-ignore-end */ + switch (local.modeJs) { + + + + // run node js-env code - init-after + case 'node': + /* istanbul ignore next */ + // run the cli + local.cliRunIstanbul = function (options) { + /* + * this function will run the cli + */ + var tmp; + if ((module !== local.require.main || local.global.utility2_rollup) && + !(options && options.runMain)) { + return; + } + switch (process.argv[2]) { + // transparently adds coverage information to a node command + case 'cover': + try { + tmp = JSON.parse(local._fs.readFileSync('package.json', 'utf8')); + process.env.npm_package_nameAlias = process.env.npm_package_nameAlias || + tmp.nameAlias || + tmp.name.replace((/-/g), '_'); + } catch (ignore) { + } + process.env.npm_config_mode_coverage = process.env.npm_config_mode_coverage || + process.env.npm_package_nameAlias || + 'all'; + // add coverage hook to require + local._moduleExtensionsJs = local.module._extensions['.js']; + local.module._extensions['.js'] = function (module, file) { + if (typeof file === 'string' && + (file.indexOf(process.env.npm_config_mode_coverage_dir) === 0 || ( + file.indexOf(process.cwd()) === 0 && + file.indexOf(process.cwd() + '/node_modules/') !== 0 + ))) { + module._compile(local.instrumentInPackage( + local._fs.readFileSync(file, 'utf8'), + file + ), file); + return; + } + local._moduleExtensionsJs(module, file); + }; + // init process.argv + process.argv.splice(1, 2); + process.argv[1] = local.path.resolve(process.cwd(), process.argv[1]); + console.log('\ncovering $ ' + process.argv.join(' ')); + // create coverage on exit + process.on('exit', function () { + local.coverageReportCreate({ coverage: local.global.__coverage__ }); + }); + // re-run cli + local.module.runMain(); + break; + // instrument a file and print result to stdout + case 'instrument': + process.argv[3] = local.path.resolve(process.cwd(), process.argv[3]); + process.stdout.write(local.instrumentSync( + local._fs.readFileSync(process.argv[3], 'utf8'), + process.argv[3] + )); + break; + // cover a node command only when npm_config_mode_coverage is set + case 'test': + if (process.env.npm_config_mode_coverage) { + process.argv[2] = 'cover'; + // re-run cli + local.cliRunIstanbul(options); + return; + } + // init process.argv + process.argv.splice(1, 2); + process.argv[1] = local.path.resolve(process.cwd(), process.argv[1]); + // re-run cli + local.module.runMain(); + break; + } + }; + local.cliRunIstanbul(); + break; + } +}( + // run shared js-env code - init-before + (function () { + 'use strict'; + var local; + // init local + local = {}; + // init modeJs + local.modeJs = (function () { + try { + return typeof navigator.userAgent === 'string' && + typeof document.querySelector('body') === 'object' && + typeof XMLHttpRequest.prototype.open === 'function' && + 'browser'; + } catch (errorCaughtBrowser) { + return module.exports && + typeof process.versions.node === 'string' && + typeof require('http').createServer === 'function' && + 'node'; + } + }()); + // init global + local.global = local.modeJs === 'browser' + ? window + : global; + // init utility2_rollup + local = local.global.utility2_rollup || local; + // init lib + local.local = local.istanbul = local; + // init exports + if (local.modeJs === 'browser') { + local.global.utility2_istanbul = local; + } else { + module.exports = local; + module.exports.__dirname = __dirname; + } + local.fsWriteFileWithMkdirpSync = function (file, data) { + /* + * this function will synchronously 'mkdir -p' and write the data to file + */ + // try to write to file + try { + require('fs').writeFileSync(file, data); + } catch (errorCaught) { + // mkdir -p + require('child_process').spawnSync( + 'mkdir', + ['-p', require('path').dirname(file)], + { stdio: ['ignore', 1, 2] } + ); + // re-write to file + require('fs').writeFileSync(file, data); + } + }; + local.nop = function () { + /* + * this function will do nothing + */ + return; + }; + switch (local.modeJs) { + case 'browser': + local.fsWriteFileWithMkdirpSync2 = local.nop; + break; + case 'node': + local.fsWriteFileWithMkdirpSync2 = local.fsWriteFileWithMkdirpSync; + local.__dirname = __dirname; + local.process = process; + local.require = require; + break; + } + return local; + }()) +)); +/* script-end /assets.utility2.lib.istanbul.js */ + + + +/* script-begin /assets.utility2.lib.jslint.js */ +///usr/bin/env node +/* istanbul instrument in package jslint */ +/*jslint + bitwise: true, + browser: true, + maxerr: 8, + maxlen: 96, + node: true, + nomen: true, + regexp: true, + stupid: true +*/ +(function () { + 'use strict'; + var local; + + + + // run shared js-env code - init-before + (function () { + // init local + local = {}; + // init modeJs + local.modeJs = (function () { + try { + return typeof navigator.userAgent === 'string' && + typeof document.querySelector('body') === 'object' && + typeof XMLHttpRequest.prototype.open === 'function' && + 'browser'; + } catch (errorCaughtBrowser) { + return module.exports && + typeof process.versions.node === 'string' && + typeof require('http').createServer === 'function' && + 'node'; + } + }()); + // init global + local.global = local.modeJs === 'browser' + ? window + : global; + // init utility2_rollup + local = local.global.utility2_rollup || local; + // init lib + local.local = local.jslint = local; + // init exports + if (local.modeJs === 'browser') { + local.global.utility2_jslint = local; + } else { + module.exports = local; + module.exports.__dirname = __dirname; + module.exports.module = module; + } + }()); + + + +/* jslint-ignore-begin */ +/* istanbul ignore next */ +// init lib csslint +// https://github.com/CSSLint/csslint/blob/v0.10.0/release/csslint.js +// utility2-uglifyjs https://raw.githubusercontent.com/CSSLint/csslint/v0.10.0/release/csslint.js +(function () { +var exports=exports||{},CSSLint=function(){function Reporter(e,t){this.messages= +[],this.stats=[],this.lines=e,this.ruleset=t}var parserlib={};(function(){function e +(){this._listeners={}}function t(e){this._input=e.replace(/\n\r?/g,"\n"),this._line=1 +,this._col=1,this._cursor=0}function n(e,t,n){this.col=n,this.line=t,this.message= +e}function r(e,t,n,r){this.col=n,this.line=t,this.text=e,this.type=r}function i( +e,n){this._reader=e?new t(e.toString()):null,this._token=null,this._tokenData=n, +this._lt=[],this._ltIndex=0,this._ltIndexCache=[]}e.prototype={constructor:e,addListener +:function(e,t){this._listeners[e]||(this._listeners[e]=[]),this._listeners[e].push +(t)},fire:function(e){typeof e=="string"&&(e={type:e}),typeof e.target!="undefined"&& +(e.target=this);if(typeof e.type=="undefined")throw new Error("Event object missing 'type' property." +);if(this._listeners[e.type]){var t=this._listeners[e.type].concat();for(var n=0 +,r=t.length;n=0&& +this._ltIndex-1&&!t[u.type].hide&& +(u.channel=t[u.type].channel,this._token=u,this._lt.push(u),this._ltIndexCache.push +(this._lt.length-this._ltIndex+i),this._lt.length>5&&this._lt.shift(),this._ltIndexCache +.length>5&&this._ltIndexCache.shift(),this._ltIndex=this._lt.length),a=t[u.type] +,a&&(a.hide||a.channel!==undefined&&e!==a.channel)?this.get(e):u.type},LA:function( +e){var t=e,n;if(e>0){if(e>5)throw new Error("Too much lookahead.");while(t)n=this +.get(),t--;while(tthis._tokenData.length?"UNKNOWN_TOKEN":this._tokenData +[e].name},tokenType:function(e){return this._tokenData[e]||-1},unget:function(){ +if(!this._ltIndexCache.length)throw new Error("Too much lookahead.");this._ltIndex-= +this._ltIndexCache.pop(),this._token=this._lt[this._ltIndex-1]}},parserlib.util= +{StringReader:t,SyntaxError:n,SyntaxUnit:r,EventTarget:e,TokenStreamBase:i}})(), +function(){function Combinator(e,t,n){SyntaxUnit.call(this,e,t,n,Parser.COMBINATOR_TYPE +),this.type="unknown",/^\s+$/.test(e)?this.type="descendant":e==">"?this.type="child" +:e=="+"?this.type="adjacent-sibling":e=="~"&&(this.type="sibling")}function MediaFeature +(e,t){SyntaxUnit.call(this,"("+e+(t!==null?":"+t:"")+")",e.startLine,e.startCol, +Parser.MEDIA_FEATURE_TYPE),this.name=e,this.value=t}function MediaQuery(e,t,n,r, +i){SyntaxUnit.call(this,(e?e+" ":"")+(t?t:"")+(t&&n.length>0?" and ":"")+n.join(" and " +),r,i,Parser.MEDIA_QUERY_TYPE),this.modifier=e,this.mediaType=t,this.features=n} +function Parser(e){EventTarget.call(this),this.options=e||{},this._tokenStream=null +}function PropertyName(e,t,n,r){SyntaxUnit.call(this,e,n,r,Parser.PROPERTY_NAME_TYPE +),this.hack=t}function PropertyValue(e,t,n){SyntaxUnit.call(this,e.join(" "),t,n +,Parser.PROPERTY_VALUE_TYPE),this.parts=e}function PropertyValueIterator(e){this +._i=0,this._parts=e.parts,this._marks=[],this.value=e}function PropertyValuePart +(text,line,col){SyntaxUnit.call(this,text,line,col,Parser.PROPERTY_VALUE_PART_TYPE +),this.type="unknown";var temp;if(/^([+\-]?[\d\.]+)([a-z]+)$/i.test(text)){this. +type="dimension",this.value=+RegExp.$1,this.units=RegExp.$2;switch(this.units.toLowerCase +()){case"em":case"rem":case"ex":case"px":case"cm":case"mm":case"in":case"pt":case"pc" +:case"ch":case"vh":case"vw":case"vm":this.type="length";break;case"deg":case"rad" +:case"grad":this.type="angle";break;case"ms":case"s":this.type="time";break;case"hz" +:case"khz":this.type="frequency";break;case"dpi":case"dpcm":this.type="resolution" +}}else/^([+\-]?[\d\.]+)%$/i.test(text)?(this.type="percentage",this.value=+RegExp +.$1):/^([+\-]?[\d\.]+)%$/i.test(text)?(this.type="percentage",this.value=+RegExp +.$1):/^([+\-]?\d+)$/i.test(text)?(this.type="integer",this.value=+RegExp.$1):/^([+\-]?[\d\.]+)$/i +.test(text)?(this.type="number",this.value=+RegExp.$1):/^#([a-f0-9]{3,6})/i.test +(text)?(this.type="color",temp=RegExp.$1,temp.length==3?(this.red=parseInt(temp. +charAt(0)+temp.charAt(0),16),this.green=parseInt(temp.charAt(1)+temp.charAt(1),16 +),this.blue=parseInt(temp.charAt(2)+temp.charAt(2),16)):(this.red=parseInt(temp. +substring(0,2),16),this.green=parseInt(temp.substring(2,4),16),this.blue=parseInt +(temp.substring(4,6),16))):/^rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/i.test(text +)?(this.type="color",this.red=+RegExp.$1,this.green=+RegExp.$2,this.blue=+RegExp +.$3):/^rgb\(\s*(\d+)%\s*,\s*(\d+)%\s*,\s*(\d+)%\s*\)/i.test(text)?(this.type="color" +,this.red=+RegExp.$1*255/100,this.green=+RegExp.$2*255/100,this.blue=+RegExp.$3*255/100 +):/^rgba\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*([\d\.]+)\s*\)/i.test(text)?(this +.type="color",this.red=+RegExp.$1,this.green=+RegExp.$2,this.blue=+RegExp.$3,this +.alpha=+RegExp.$4):/^rgba\(\s*(\d+)%\s*,\s*(\d+)%\s*,\s*(\d+)%\s*,\s*([\d\.]+)\s*\)/i +.test(text)?(this.type="color",this.red=+RegExp.$1*255/100,this.green=+RegExp.$2*255/100 +,this.blue=+RegExp.$3*255/100,this.alpha=+RegExp.$4):/^hsl\(\s*(\d+)\s*,\s*(\d+)%\s*,\s*(\d+)%\s*\)/i +.test(text)?(this.type="color",this.hue=+RegExp.$1,this.saturation=+RegExp.$2/100 +,this.lightness=+RegExp.$3/100):/^hsla\(\s*(\d+)\s*,\s*(\d+)%\s*,\s*(\d+)%\s*,\s*([\d\.]+)\s*\)/i +.test(text)?(this.type="color",this.hue=+RegExp.$1,this.saturation=+RegExp.$2/100 +,this.lightness=+RegExp.$3/100,this.alpha=+RegExp.$4):/^url\(["']?([^\)"']+)["']?\)/i +.test(text)?(this.type="uri",this.uri=RegExp.$1):/^([^\(]+)\(/i.test(text)?(this +.type="function",this.name=RegExp.$1,this.value=text):/^["'][^"']*["']/.test(text +)?(this.type="string",this.value=eval(text)):Colors[text.toLowerCase()]?(this.type="color" +,temp=Colors[text.toLowerCase()].substring(1),this.red=parseInt(temp.substring(0 +,2),16),this.green=parseInt(temp.substring(2,4),16),this.blue=parseInt(temp.substring +(4,6),16)):/^[\,\/]$/.test(text)?(this.type="operator",this.value=text):/^[a-z\-\u0080-\uFFFF][a-z0-9\-\u0080-\uFFFF]*$/i +.test(text)&&(this.type="identifier",this.value=text)}function Selector(e,t,n){SyntaxUnit +.call(this,e.join(" "),t,n,Parser.SELECTOR_TYPE),this.parts=e,this.specificity=Specificity +.calculate(this)}function SelectorPart(e,t,n,r,i){SyntaxUnit.call(this,n,r,i,Parser +.SELECTOR_PART_TYPE),this.elementName=e,this.modifiers=t}function SelectorSubPart +(e,t,n,r){SyntaxUnit.call(this,e,n,r,Parser.SELECTOR_SUB_PART_TYPE),this.type=t, +this.args=[]}function Specificity(e,t,n,r){this.a=e,this.b=t,this.c=n,this.d=r}function isHexDigit +(e){return e!==null&&h.test(e)}function isDigit(e){return e!==null&&/\d/.test(e) +}function isWhitespace(e){return e!==null&&/\s/.test(e)}function isNewLine(e){return e!== +null&&nl.test(e)}function isNameStart(e){return e!==null&&/[a-z_\u0080-\uFFFF\\]/i +.test(e)}function isNameChar(e){return e!==null&&(isNameStart(e)||/[0-9\-\\]/.test +(e))}function isIdentStart(e){return e!==null&&(isNameStart(e)||/\-\\/.test(e))} +function mix(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);return e}function TokenStream +(e){TokenStreamBase.call(this,e,Tokens)}function ValidationError(e,t,n){this.col= +n,this.line=t,this.message=e}var EventTarget=parserlib.util.EventTarget,TokenStreamBase= +parserlib.util.TokenStreamBase,StringReader=parserlib.util.StringReader,SyntaxError= +parserlib.util.SyntaxError,SyntaxUnit=parserlib.util.SyntaxUnit,Colors={aliceblue +:"#f0f8ff",antiquewhite:"#faebd7",aqua:"#00ffff",aquamarine:"#7fffd4",azure:"#f0ffff" +,beige:"#f5f5dc",bisque:"#ffe4c4",black:"#000000",blanchedalmond:"#ffebcd",blue:"#0000ff" +,blueviolet:"#8a2be2",brown:"#a52a2a",burlywood:"#deb887",cadetblue:"#5f9ea0",chartreuse +:"#7fff00",chocolate:"#d2691e",coral:"#ff7f50",cornflowerblue:"#6495ed",cornsilk +:"#fff8dc",crimson:"#dc143c",cyan:"#00ffff",darkblue:"#00008b",darkcyan:"#008b8b" +,darkgoldenrod:"#b8860b",darkgray:"#a9a9a9",darkgreen:"#006400",darkkhaki:"#bdb76b" +,darkmagenta:"#8b008b",darkolivegreen:"#556b2f",darkorange:"#ff8c00",darkorchid:"#9932cc" +,darkred:"#8b0000",darksalmon:"#e9967a",darkseagreen:"#8fbc8f",darkslateblue:"#483d8b" +,darkslategray:"#2f4f4f",darkturquoise:"#00ced1",darkviolet:"#9400d3",deeppink:"#ff1493" +,deepskyblue:"#00bfff",dimgray:"#696969",dodgerblue:"#1e90ff",firebrick:"#b22222" +,floralwhite:"#fffaf0",forestgreen:"#228b22",fuchsia:"#ff00ff",gainsboro:"#dcdcdc" +,ghostwhite:"#f8f8ff",gold:"#ffd700",goldenrod:"#daa520",gray:"#808080",green:"#008000" +,greenyellow:"#adff2f",honeydew:"#f0fff0",hotpink:"#ff69b4",indianred:"#cd5c5c", +indigo:"#4b0082",ivory:"#fffff0",khaki:"#f0e68c",lavender:"#e6e6fa",lavenderblush +:"#fff0f5",lawngreen:"#7cfc00",lemonchiffon:"#fffacd",lightblue:"#add8e6",lightcoral +:"#f08080",lightcyan:"#e0ffff",lightgoldenrodyellow:"#fafad2",lightgray:"#d3d3d3" +,lightgreen:"#90ee90",lightpink:"#ffb6c1",lightsalmon:"#ffa07a",lightseagreen:"#20b2aa" +,lightskyblue:"#87cefa",lightslategray:"#778899",lightsteelblue:"#b0c4de",lightyellow +:"#ffffe0",lime:"#00ff00",limegreen:"#32cd32",linen:"#faf0e6",magenta:"#ff00ff", +maroon:"#800000",mediumaquamarine:"#66cdaa",mediumblue:"#0000cd",mediumorchid:"#ba55d3" +,mediumpurple:"#9370d8",mediumseagreen:"#3cb371",mediumslateblue:"#7b68ee",mediumspringgreen +:"#00fa9a",mediumturquoise:"#48d1cc",mediumvioletred:"#c71585",midnightblue:"#191970" +,mintcream:"#f5fffa",mistyrose:"#ffe4e1",moccasin:"#ffe4b5",navajowhite:"#ffdead" +,navy:"#000080",oldlace:"#fdf5e6",olive:"#808000",olivedrab:"#6b8e23",orange:"#ffa500" +,orangered:"#ff4500",orchid:"#da70d6",palegoldenrod:"#eee8aa",palegreen:"#98fb98" +,paleturquoise:"#afeeee",palevioletred:"#d87093",papayawhip:"#ffefd5",peachpuff:"#ffdab9" +,peru:"#cd853f",pink:"#ffc0cb",plum:"#dda0dd",powderblue:"#b0e0e6",purple:"#800080" +,red:"#ff0000",rosybrown:"#bc8f8f",royalblue:"#4169e1",saddlebrown:"#8b4513",salmon +:"#fa8072",sandybrown:"#f4a460",seagreen:"#2e8b57",seashell:"#fff5ee",sienna:"#a0522d" +,silver:"#c0c0c0",skyblue:"#87ceeb",slateblue:"#6a5acd",slategray:"#708090",snow +:"#fffafa",springgreen:"#00ff7f",steelblue:"#4682b4",tan:"#d2b48c",teal:"#008080" +,thistle:"#d8bfd8",tomato:"#ff6347",turquoise:"#40e0d0",violet:"#ee82ee",wheat:"#f5deb3" +,white:"#ffffff",whitesmoke:"#f5f5f5",yellow:"#ffff00",yellowgreen:"#9acd32",activeBorder +:"Active window border.",activecaption:"Active window caption.",appworkspace:"Background color of multiple document interface." +,background:"Desktop background.",buttonface:"The face background color for 3-D elements that appear 3-D due to one layer of surrounding border." +,buttonhighlight:"The color of the border facing the light source for 3-D elements that appear 3-D due to one layer of surrounding border." +,buttonshadow:"The color of the border away from the light source for 3-D elements that appear 3-D due to one layer of surrounding border." +,buttontext:"Text on push buttons.",captiontext:"Text in caption, size box, and scrollbar arrow box." +,graytext:"Grayed (disabled) text. This color is set to #000 if the current display driver does not support a solid gray color." +,highlight:"Item(s) selected in a control.",highlighttext:"Text of item(s) selected in a control." +,inactiveborder:"Inactive window border.",inactivecaption:"Inactive window caption." +,inactivecaptiontext:"Color of text in an inactive caption.",infobackground:"Background color for tooltip controls." +,infotext:"Text color for tooltip controls.",menu:"Menu background.",menutext:"Text in menus." +,scrollbar:"Scroll bar gray area.",threeddarkshadow:"The color of the darker (generally outer) of the two borders away from the light source for 3-D elements that appear 3-D due to two concentric layers of surrounding border." +,threedface:"The face background color for 3-D elements that appear 3-D due to two concentric layers of surrounding border." +,threedhighlight:"The color of the lighter (generally outer) of the two borders facing the light source for 3-D elements that appear 3-D due to two concentric layers of surrounding border." +,threedlightshadow:"The color of the darker (generally inner) of the two borders facing the light source for 3-D elements that appear 3-D due to two concentric layers of surrounding border." +,threedshadow:"The color of the lighter (generally inner) of the two borders away from the light source for 3-D elements that appear 3-D due to two concentric layers of surrounding border." +,window:"Window background.",windowframe:"Window frame.",windowtext:"Text in windows." +};Combinator.prototype=new SyntaxUnit,Combinator.prototype.constructor=Combinator +,MediaFeature.prototype=new SyntaxUnit,MediaFeature.prototype.constructor=MediaFeature +,MediaQuery.prototype=new SyntaxUnit,MediaQuery.prototype.constructor=MediaQuery +,Parser.DEFAULT_TYPE=0,Parser.COMBINATOR_TYPE=1,Parser.MEDIA_FEATURE_TYPE=2,Parser +.MEDIA_QUERY_TYPE=3,Parser.PROPERTY_NAME_TYPE=4,Parser.PROPERTY_VALUE_TYPE=5,Parser +.PROPERTY_VALUE_PART_TYPE=6,Parser.SELECTOR_TYPE=7,Parser.SELECTOR_PART_TYPE=8,Parser +.SELECTOR_SUB_PART_TYPE=9,Parser.prototype=function(){var e=new EventTarget,t,n= +{constructor:Parser,DEFAULT_TYPE:0,COMBINATOR_TYPE:1,MEDIA_FEATURE_TYPE:2,MEDIA_QUERY_TYPE +:3,PROPERTY_NAME_TYPE:4,PROPERTY_VALUE_TYPE:5,PROPERTY_VALUE_PART_TYPE:6,SELECTOR_TYPE +:7,SELECTOR_PART_TYPE:8,SELECTOR_SUB_PART_TYPE:9,_stylesheet:function(){var e=this +._tokenStream,t=null,n,r,i;this.fire("startstylesheet"),this._charset(),this._skipCruft +();while(e.peek()==Tokens.IMPORT_SYM)this._import(),this._skipCruft();while(e.peek +()==Tokens.NAMESPACE_SYM)this._namespace(),this._skipCruft();i=e.peek();while(i> +Tokens.EOF){try{switch(i){case Tokens.MEDIA_SYM:this._media(),this._skipCruft(); +break;case Tokens.PAGE_SYM:this._page(),this._skipCruft();break;case Tokens.FONT_FACE_SYM +:this._font_face(),this._skipCruft();break;case Tokens.KEYFRAMES_SYM:this._keyframes +(),this._skipCruft();break;case Tokens.VIEWPORT_SYM:this._viewport(),this._skipCruft +();break;case Tokens.UNKNOWN_SYM:e.get();if(!!this.options.strict)throw new SyntaxError +("Unknown @ rule.",e.LT(0).startLine,e.LT(0).startCol);this.fire({type:"error",error +:null,message:"Unknown @ rule: "+e.LT(0).value+".",line:e.LT(0).startLine,col:e. +LT(0).startCol}),n=0;while(e.advance([Tokens.LBRACE,Tokens.RBRACE])==Tokens.LBRACE +)n++;while(n)e.advance([Tokens.RBRACE]),n--;break;case Tokens.S:this._readWhitespace +();break;default:if(!this._ruleset())switch(i){case Tokens.CHARSET_SYM:throw r=e +.LT(1),this._charset(!1),new SyntaxError("@charset not allowed here.",r.startLine +,r.startCol);case Tokens.IMPORT_SYM:throw r=e.LT(1),this._import(!1),new SyntaxError +("@import not allowed here.",r.startLine,r.startCol);case Tokens.NAMESPACE_SYM:throw r= +e.LT(1),this._namespace(!1),new SyntaxError("@namespace not allowed here.",r.startLine +,r.startCol);default:e.get(),this._unexpectedToken(e.token())}}}catch(s){if(!(s instanceof +SyntaxError&&!this.options.strict))throw s;this.fire({type:"error",error:s,message +:s.message,line:s.line,col:s.col})}i=e.peek()}i!=Tokens.EOF&&this._unexpectedToken +(e.token()),this.fire("endstylesheet")},_charset:function(e){var t=this._tokenStream +,n,r,i,s;t.match(Tokens.CHARSET_SYM)&&(i=t.token().startLine,s=t.token().startCol +,this._readWhitespace(),t.mustMatch(Tokens.STRING),r=t.token(),n=r.value,this._readWhitespace +(),t.mustMatch(Tokens.SEMICOLON),e!==!1&&this.fire({type:"charset",charset:n,line +:i,col:s}))},_import:function(e){var t=this._tokenStream,n,r,i,s=[];t.mustMatch( +Tokens.IMPORT_SYM),i=t.token(),this._readWhitespace(),t.mustMatch([Tokens.STRING +,Tokens.URI]),r=t.token().value.replace(/(?:url\()?["']([^"']+)["']\)?/,"$1"),this +._readWhitespace(),s=this._media_query_list(),t.mustMatch(Tokens.SEMICOLON),this +._readWhitespace(),e!==!1&&this.fire({type:"import",uri:r,media:s,line:i.startLine +,col:i.startCol})},_namespace:function(e){var t=this._tokenStream,n,r,i,s;t.mustMatch +(Tokens.NAMESPACE_SYM),n=t.token().startLine,r=t.token().startCol,this._readWhitespace +(),t.match(Tokens.IDENT)&&(i=t.token().value,this._readWhitespace()),t.mustMatch +([Tokens.STRING,Tokens.URI]),s=t.token().value.replace(/(?:url\()?["']([^"']+)["']\)?/ +,"$1"),this._readWhitespace(),t.mustMatch(Tokens.SEMICOLON),this._readWhitespace +(),e!==!1&&this.fire({type:"namespace",prefix:i,uri:s,line:n,col:r})},_media:function( +){var e=this._tokenStream,t,n,r;e.mustMatch(Tokens.MEDIA_SYM),t=e.token().startLine +,n=e.token().startCol,this._readWhitespace(),r=this._media_query_list(),e.mustMatch +(Tokens.LBRACE),this._readWhitespace(),this.fire({type:"startmedia",media:r,line +:t,col:n});for(;;)if(e.peek()==Tokens.PAGE_SYM)this._page();else if(e.peek()==Tokens +.FONT_FACE_SYM)this._font_face();else if(!this._ruleset())break;e.mustMatch(Tokens +.RBRACE),this._readWhitespace(),this.fire({type:"endmedia",media:r,line:t,col:n} +)},_media_query_list:function(){var e=this._tokenStream,t=[];this._readWhitespace +(),(e.peek()==Tokens.IDENT||e.peek()==Tokens.LPAREN)&&t.push(this._media_query() +);while(e.match(Tokens.COMMA))this._readWhitespace(),t.push(this._media_query()) +;return t},_media_query:function(){var e=this._tokenStream,t=null,n=null,r=null, +i=[];e.match(Tokens.IDENT)&&(n=e.token().value.toLowerCase(),n!="only"&&n!="not"? +(e.unget(),n=null):r=e.token()),this._readWhitespace(),e.peek()==Tokens.IDENT?(t= +this._media_type(),r===null&&(r=e.token())):e.peek()==Tokens.LPAREN&&(r===null&& +(r=e.LT(1)),i.push(this._media_expression()));if(t===null&&i.length===0)return null +;this._readWhitespace();while(e.match(Tokens.IDENT))e.token().value.toLowerCase( +)!="and"&&this._unexpectedToken(e.token()),this._readWhitespace(),i.push(this._media_expression +());return new MediaQuery(n,t,i,r.startLine,r.startCol)},_media_type:function(){ +return this._media_feature()},_media_expression:function(){var e=this._tokenStream +,t=null,n,r=null;return e.mustMatch(Tokens.LPAREN),t=this._media_feature(),this. +_readWhitespace(),e.match(Tokens.COLON)&&(this._readWhitespace(),n=e.LT(1),r=this +._expression()),e.mustMatch(Tokens.RPAREN),this._readWhitespace(),new MediaFeature +(t,r?new SyntaxUnit(r,n.startLine,n.startCol):null)},_media_feature:function(){var e= +this._tokenStream;return e.mustMatch(Tokens.IDENT),SyntaxUnit.fromToken(e.token( +))},_page:function(){var e=this._tokenStream,t,n,r=null,i=null;e.mustMatch(Tokens +.PAGE_SYM),t=e.token().startLine,n=e.token().startCol,this._readWhitespace(),e.match +(Tokens.IDENT)&&(r=e.token().value,r.toLowerCase()==="auto"&&this._unexpectedToken +(e.token())),e.peek()==Tokens.COLON&&(i=this._pseudo_page()),this._readWhitespace +(),this.fire({type:"startpage",id:r,pseudo:i,line:t,col:n}),this._readDeclarations +(!0,!0),this.fire({type:"endpage",id:r,pseudo:i,line:t,col:n})},_margin:function( +){var e=this._tokenStream,t,n,r=this._margin_sym();return r?(t=e.token().startLine +,n=e.token().startCol,this.fire({type:"startpagemargin",margin:r,line:t,col:n}), +this._readDeclarations(!0),this.fire({type:"endpagemargin",margin:r,line:t,col:n +}),!0):!1},_margin_sym:function(){var e=this._tokenStream;return e.match([Tokens +.TOPLEFTCORNER_SYM,Tokens.TOPLEFT_SYM,Tokens.TOPCENTER_SYM,Tokens.TOPRIGHT_SYM,Tokens +.TOPRIGHTCORNER_SYM,Tokens.BOTTOMLEFTCORNER_SYM,Tokens.BOTTOMLEFT_SYM,Tokens.BOTTOMCENTER_SYM +,Tokens.BOTTOMRIGHT_SYM,Tokens.BOTTOMRIGHTCORNER_SYM,Tokens.LEFTTOP_SYM,Tokens.LEFTMIDDLE_SYM +,Tokens.LEFTBOTTOM_SYM,Tokens.RIGHTTOP_SYM,Tokens.RIGHTMIDDLE_SYM,Tokens.RIGHTBOTTOM_SYM +])?SyntaxUnit.fromToken(e.token()):null},_pseudo_page:function(){var e=this._tokenStream +;return e.mustMatch(Tokens.COLON),e.mustMatch(Tokens.IDENT),e.token().value},_font_face +:function(){var e=this._tokenStream,t,n;e.mustMatch(Tokens.FONT_FACE_SYM),t=e.token +().startLine,n=e.token().startCol,this._readWhitespace(),this.fire({type:"startfontface" +,line:t,col:n}),this._readDeclarations(!0),this.fire({type:"endfontface",line:t, +col:n})},_viewport:function(){var e=this._tokenStream,t,n;e.mustMatch(Tokens.VIEWPORT_SYM +),t=e.token().startLine,n=e.token().startCol,this._readWhitespace(),this.fire({type +:"startviewport",line:t,col:n}),this._readDeclarations(!0),this.fire({type:"endviewport" +,line:t,col:n})},_operator:function(e){var t=this._tokenStream,n=null;if(t.match +([Tokens.SLASH,Tokens.COMMA])||e&&t.match([Tokens.PLUS,Tokens.STAR,Tokens.MINUS] +))n=t.token(),this._readWhitespace();return n?PropertyValuePart.fromToken(n):null +},_combinator:function(){var e=this._tokenStream,t=null,n;return e.match([Tokens +.PLUS,Tokens.GREATER,Tokens.TILDE])&&(n=e.token(),t=new Combinator(n.value,n.startLine +,n.startCol),this._readWhitespace()),t},_unary_operator:function(){var e=this._tokenStream +;return e.match([Tokens.MINUS,Tokens.PLUS])?e.token().value:null},_property:function( +){var e=this._tokenStream,t=null,n=null,r,i,s,o;return e.peek()==Tokens.STAR&&this +.options.starHack&&(e.get(),i=e.token(),n=i.value,s=i.startLine,o=i.startCol),e. +match(Tokens.IDENT)&&(i=e.token(),r=i.value,r.charAt(0)=="_"&&this.options.underscoreHack&& +(n="_",r=r.substring(1)),t=new PropertyName(r,n,s||i.startLine,o||i.startCol),this +._readWhitespace()),t},_ruleset:function(){var e=this._tokenStream,t,n;try{n=this +._selectors_group()}catch(r){if(r instanceof SyntaxError&&!this.options.strict){ +this.fire({type:"error",error:r,message:r.message,line:r.line,col:r.col}),t=e.advance +([Tokens.RBRACE]);if(t!=Tokens.RBRACE)throw r;return!0}throw r}return n&&(this.fire +({type:"startrule",selectors:n,line:n[0].line,col:n[0].col}),this._readDeclarations +(!0),this.fire({type:"endrule",selectors:n,line:n[0].line,col:n[0].col})),n},_selectors_group +:function(){var e=this._tokenStream,t=[],n;n=this._selector();if(n!==null){t.push +(n);while(e.match(Tokens.COMMA))this._readWhitespace(),n=this._selector(),n!==null? +t.push(n):this._unexpectedToken(e.LT(1))}return t.length?t:null},_selector:function( +){var e=this._tokenStream,t=[],n=null,r=null,i=null;n=this._simple_selector_sequence +();if(n===null)return null;t.push(n);do{r=this._combinator();if(r!==null)t.push( +r),n=this._simple_selector_sequence(),n===null?this._unexpectedToken(e.LT(1)):t. +push(n);else{if(!this._readWhitespace())break;i=new Combinator(e.token().value,e +.token().startLine,e.token().startCol),r=this._combinator(),n=this._simple_selector_sequence +(),n===null?r!==null&&this._unexpectedToken(e.LT(1)):(r!==null?t.push(r):t.push( +i),t.push(n))}}while(!0);return new Selector(t,t[0].line,t[0].col)},_simple_selector_sequence +:function(){var e=this._tokenStream,t=null,n=[],r="",i=[function(){return e.match +(Tokens.HASH)?new SelectorSubPart(e.token().value,"id",e.token().startLine,e.token +().startCol):null},this._class,this._attrib,this._pseudo,this._negation],s=0,o=i +.length,u=null,a=!1,f,l;f=e.LT(1).startLine,l=e.LT(1).startCol,t=this._type_selector +(),t||(t=this._universal()),t!==null&&(r+=t);for(;;){if(e.peek()===Tokens.S)break; +while(s1&&e.unget()),null)},_class:function(){var e=this._tokenStream,t;return e +.match(Tokens.DOT)?(e.mustMatch(Tokens.IDENT),t=e.token(),new SelectorSubPart("."+ +t.value,"class",t.startLine,t.startCol-1)):null},_element_name:function(){var e= +this._tokenStream,t;return e.match(Tokens.IDENT)?(t=e.token(),new SelectorSubPart +(t.value,"elementName",t.startLine,t.startCol)):null},_namespace_prefix:function( +){var e=this._tokenStream,t="";if(e.LA(1)===Tokens.PIPE||e.LA(2)===Tokens.PIPE)e +.match([Tokens.IDENT,Tokens.STAR])&&(t+=e.token().value),e.mustMatch(Tokens.PIPE +),t+="|";return t.length?t:null},_universal:function(){var e=this._tokenStream,t="" +,n;return n=this._namespace_prefix(),n&&(t+=n),e.match(Tokens.STAR)&&(t+="*"),t. +length?t:null},_attrib:function(){var e=this._tokenStream,t=null,n,r;return e.match +(Tokens.LBRACKET)?(r=e.token(),t=r.value,t+=this._readWhitespace(),n=this._namespace_prefix +(),n&&(t+=n),e.mustMatch(Tokens.IDENT),t+=e.token().value,t+=this._readWhitespace +(),e.match([Tokens.PREFIXMATCH,Tokens.SUFFIXMATCH,Tokens.SUBSTRINGMATCH,Tokens.EQUALS +,Tokens.INCLUDES,Tokens.DASHMATCH])&&(t+=e.token().value,t+=this._readWhitespace +(),e.mustMatch([Tokens.IDENT,Tokens.STRING]),t+=e.token().value,t+=this._readWhitespace +()),e.mustMatch(Tokens.RBRACKET),new SelectorSubPart(t+"]","attribute",r.startLine +,r.startCol)):null},_pseudo:function(){var e=this._tokenStream,t=null,n=":",r,i; +return e.match(Tokens.COLON)&&(e.match(Tokens.COLON)&&(n+=":"),e.match(Tokens.IDENT +)?(t=e.token().value,r=e.token().startLine,i=e.token().startCol-n.length):e.peek +()==Tokens.FUNCTION&&(r=e.LT(1).startLine,i=e.LT(1).startCol-n.length,t=this._functional_pseudo +()),t&&(t=new SelectorSubPart(n+t,"pseudo",r,i))),t},_functional_pseudo:function( +){var e=this._tokenStream,t=null;return e.match(Tokens.FUNCTION)&&(t=e.token().value +,t+=this._readWhitespace(),t+=this._expression(),e.mustMatch(Tokens.RPAREN),t+=")" +),t},_expression:function(){var e=this._tokenStream,t="";while(e.match([Tokens.PLUS +,Tokens.MINUS,Tokens.DIMENSION,Tokens.NUMBER,Tokens.STRING,Tokens.IDENT,Tokens.LENGTH +,Tokens.FREQ,Tokens.ANGLE,Tokens.TIME,Tokens.RESOLUTION,Tokens.SLASH]))t+=e.token +().value,t+=this._readWhitespace();return t.length?t:null},_negation:function(){ +var e=this._tokenStream,t,n,r="",i,s=null;return e.match(Tokens.NOT)&&(r=e.token +().value,t=e.token().startLine,n=e.token().startCol,r+=this._readWhitespace(),i= +this._negation_arg(),r+=i,r+=this._readWhitespace(),e.match(Tokens.RPAREN),r+=e. +token().value,s=new SelectorSubPart(r,"not",t,n),s.args.push(i)),s},_negation_arg +:function(){var e=this._tokenStream,t=[this._type_selector,this._universal,function( +){return e.match(Tokens.HASH)?new SelectorSubPart(e.token().value,"id",e.token() +.startLine,e.token().startCol):null},this._class,this._attrib,this._pseudo],n=null +,r=0,i=t.length,s,o,u,a;o=e.LT(1).startLine,u=e.LT(1).startCol;while(r0?new PropertyValue(n,n[0].line,n[0].col):null},_term:function( +){var e=this._tokenStream,t=null,n=null,r,i,s;return t=this._unary_operator(),t!== +null&&(i=e.token().startLine,s=e.token().startCol),e.peek()==Tokens.IE_FUNCTION&& +this.options.ieFilters?(n=this._ie_function(),t===null&&(i=e.token().startLine,s= +e.token().startCol)):e.match([Tokens.NUMBER,Tokens.PERCENTAGE,Tokens.LENGTH,Tokens +.ANGLE,Tokens.TIME,Tokens.FREQ,Tokens.STRING,Tokens.IDENT,Tokens.URI,Tokens.UNICODE_RANGE +])?(n=e.token().value,t===null&&(i=e.token().startLine,s=e.token().startCol),this +._readWhitespace()):(r=this._hexcolor(),r===null?(t===null&&(i=e.LT(1).startLine +,s=e.LT(1).startCol),n===null&&(e.LA(3)==Tokens.EQUALS&&this.options.ieFilters?n= +this._ie_function():n=this._function())):(n=r.value,t===null&&(i=r.startLine,s=r +.startCol))),n!==null?new PropertyValuePart(t!==null?t+n:n,i,s):null},_function: +function(){var e=this._tokenStream,t=null,n=null,r;if(e.match(Tokens.FUNCTION)){ +t=e.token().value,this._readWhitespace(),n=this._expr(!0),t+=n;if(this.options.ieFilters&& +e.peek()==Tokens.EQUALS)do{this._readWhitespace()&&(t+=e.token().value),e.LA(0)== +Tokens.COMMA&&(t+=e.token().value),e.match(Tokens.IDENT),t+=e.token().value,e.match +(Tokens.EQUALS),t+=e.token().value,r=e.peek();while(r!=Tokens.COMMA&&r!=Tokens.S&& +r!=Tokens.RPAREN)e.get(),t+=e.token().value,r=e.peek()}while(e.match([Tokens.COMMA +,Tokens.S]));e.match(Tokens.RPAREN),t+=")",this._readWhitespace()}return t},_ie_function +:function(){var e=this._tokenStream,t=null,n=null,r;if(e.match([Tokens.IE_FUNCTION +,Tokens.FUNCTION])){t=e.token().value;do{this._readWhitespace()&&(t+=e.token().value +),e.LA(0)==Tokens.COMMA&&(t+=e.token().value),e.match(Tokens.IDENT),t+=e.token() +.value,e.match(Tokens.EQUALS),t+=e.token().value,r=e.peek();while(r!=Tokens.COMMA&& +r!=Tokens.S&&r!=Tokens.RPAREN)e.get(),t+=e.token().value,r=e.peek()}while(e.match +([Tokens.COMMA,Tokens.S]));e.match(Tokens.RPAREN),t+=")",this._readWhitespace()} +return t},_hexcolor:function(){var e=this._tokenStream,t=null,n;if(e.match(Tokens +.HASH)){t=e.token(),n=t.value;if(!/#[a-f0-9]{3,6}/i.test(n))throw new SyntaxError +("Expected a hex color but found '"+n+"' at line "+t.startLine+", col "+t.startCol+"." +,t.startLine,t.startCol);this._readWhitespace()}return t},_keyframes:function(){ +var e=this._tokenStream,t,n,r,i="";e.mustMatch(Tokens.KEYFRAMES_SYM),t=e.token() +,/^@\-([^\-]+)\-/.test(t.value)&&(i=RegExp.$1),this._readWhitespace(),r=this._keyframe_name +(),this._readWhitespace(),e.mustMatch(Tokens.LBRACE),this.fire({type:"startkeyframes" +,name:r,prefix:i,line:t.startLine,col:t.startCol}),this._readWhitespace(),n=e.peek +();while(n==Tokens.IDENT||n==Tokens.PERCENTAGE)this._keyframe_rule(),this._readWhitespace +(),n=e.peek();this.fire({type:"endkeyframes",name:r,prefix:i,line:t.startLine,col +:t.startCol}),this._readWhitespace(),e.mustMatch(Tokens.RBRACE)},_keyframe_name: +function(){var e=this._tokenStream,t;return e.mustMatch([Tokens.IDENT,Tokens.STRING +]),SyntaxUnit.fromToken(e.token())},_keyframe_rule:function(){var e=this._tokenStream +,t,n=this._key_list();this.fire({type:"startkeyframerule",keys:n,line:n[0].line, +col:n[0].col}),this._readDeclarations(!0),this.fire({type:"endkeyframerule",keys +:n,line:n[0].line,col:n[0].col})},_key_list:function(){var e=this._tokenStream,t +,n,r=[];r.push(this._key()),this._readWhitespace();while(e.match(Tokens.COMMA))this +._readWhitespace(),r.push(this._key()),this._readWhitespace();return r},_key:function( +){var e=this._tokenStream,t;if(e.match(Tokens.PERCENTAGE))return SyntaxUnit.fromToken +(e.token());if(e.match(Tokens.IDENT)){t=e.token();if(/from|to/i.test(t.value))return SyntaxUnit +.fromToken(t);e.unget()}this._unexpectedToken(e.LT(1))},_skipCruft:function(){while( +this._tokenStream.match([Tokens.S,Tokens.CDO,Tokens.CDC]));},_readDeclarations:function( +e,t){var n=this._tokenStream,r;this._readWhitespace(),e&&n.mustMatch(Tokens.LBRACE +),this._readWhitespace();try{for(;;){if(!(n.match(Tokens.SEMICOLON)||t&&this._margin +())){if(!this._declaration())break;if(!n.match(Tokens.SEMICOLON))break}this._readWhitespace +()}n.mustMatch(Tokens.RBRACE),this._readWhitespace()}catch(i){if(!(i instanceof +SyntaxError&&!this.options.strict))throw i;this.fire({type:"error",error:i,message +:i.message,line:i.line,col:i.col}),r=n.advance([Tokens.SEMICOLON,Tokens.RBRACE]) +;if(r==Tokens.SEMICOLON)this._readDeclarations(!1,t);else if(r!=Tokens.RBRACE)throw i +}},_readWhitespace:function(){var e=this._tokenStream,t="";while(e.match(Tokens. +S))t+=e.token().value;return t},_unexpectedToken:function(e){throw new SyntaxError +("Unexpected token '"+e.value+"' at line "+e.startLine+", col "+e.startCol+".",e +.startLine,e.startCol)},_verifyEnd:function(){this._tokenStream.LA(1)!=Tokens.EOF&& +this._unexpectedToken(this._tokenStream.LT(1))},_validateProperty:function(e,t){ +Validation.validate(e,t)},parse:function(e){this._tokenStream=new TokenStream(e, +Tokens),this._stylesheet()},parseStyleSheet:function(e){return this.parse(e)},parseMediaQuery +:function(e){this._tokenStream=new TokenStream(e,Tokens);var t=this._media_query +();return this._verifyEnd(),t},parsePropertyValue:function(e){this._tokenStream=new +TokenStream(e,Tokens),this._readWhitespace();var t=this._expr();return this._readWhitespace +(),this._verifyEnd(),t},parseRule:function(e){this._tokenStream=new TokenStream( +e,Tokens),this._readWhitespace();var t=this._ruleset();return this._readWhitespace +(),this._verifyEnd(),t},parseSelector:function(e){this._tokenStream=new TokenStream +(e,Tokens),this._readWhitespace();var t=this._selector();return this._readWhitespace +(),this._verifyEnd(),t},parseStyleAttribute:function(e){e+="}",this._tokenStream=new +TokenStream(e,Tokens),this._readDeclarations()}};for(t in n)n.hasOwnProperty(t)&& +(e[t]=n[t]);return e}();var Properties={"alignment-adjust":"auto | baseline | before-edge | text-before-edge | middle | central | after-edge | text-after-edge | ideographic | alphabetic | hanging | mathematical | | " +,"alignment-baseline":"baseline | use-script | before-edge | text-before-edge | after-edge | text-after-edge | central | middle | ideographic | alphabetic | hanging | mathematical" +,animation:1,"animation-delay":{multi:"
\n\ +'; + + + +// https://github.com/swagger-api/swagger-ui/blob/v2.1.3/src/main/template/param.handlebars +local.templateUiParam = '\ +\n\ + {{name}}\n\ + {{#if description}}\n\ +
{{description htmlSafe}}\n\ + {{/if description}}\n\ +
\n\ +{{type2}}{{#if format2}}
({{format2}}){{/if format2}}
\n\ +\n\ + {{#if isTextarea}}\n\ + \n\ + {{/if isTextarea}}\n\ + {{#if isFile}}\n\ + \n\ + {{/if isFile}}\n\ + {{#if isSelect}}\n\ + \n\ + {{/if isSelect}}\n\ + {{#if isInputText}}\n\ + \n\ + {{/if isInputText}}\n\ +\n\ +{{#if schemaText}}
{{schemaText}}
{{/if schemaText}}
\n\ +'; + + + +// https://github.com/swagger-api/swagger-ui/blob/v2.1.3/src/main/template/resource.handlebars +local.templateUiResource = '\ +\n\ +
\n\ + {{name}} :\n\ + {{#if description}}\n\ + {{description htmlSafe}}\n\ + {{/if description}}\n\ + \n\ + Show\n\ + Expand / Collapse Operations\n\ + Datatable\n\ +
\n\ + \n\ +\n\ +'; + + + +local.templateUiResponseAjax = '\ +

Curl Request

\n\ +{{#if errorValidate}}\n\ +
n/a
\n\ +{{#unless errorValidate}}\n\ +
{{curl htmlSafe}}
\n\ +{{/if errorValidate}}\n\ +

Response Code

\n\ +
{{statusCode}}
\n\ +

Response Headers

\n\ +{{#if errorValidate}}\n\ +
n/a
\n\ +{{#unless errorValidate}}\n\ +
{{responseHeaders htmlSafe}}
\n\ +{{/if errorValidate}}\n\ +

Response Body

\n\ +{{responseBody}}\n\ +'; +/* jslint-ignore-end */ + local.swaggerSchemaJson = local.jsonCopy(local.objectSetOverride( + JSON.parse(local.assetsDict['/assets.swgg.json-schema.json']), + JSON.parse(local.assetsDict['/assets.swgg.schema.json']), + 2 + )); + }()); + + + + // run shared js-env code - function + (function () { + local.apiAjax = function (self, options, onError) { + /* + * this function will send a swagger-api ajax-request with the pathObject self + */ + var isMultipartFormData, tmp; + isMultipartFormData = (self.consumes && self.consumes[0]) === 'multipart/form-data'; + local.objectSetDefault(options, { data: '', paramDict: {}, url: '' }); + // try to validate paramDict + local.tryCatchOnError(function () { + local.validateByParamDefList({ + // normalize paramDict + data: local.normalizeParamDictSwagger( + local.jsonCopy(options.paramDict), + self + ), + dataReadonlyRemove: options.paramDict, + key: self.operationId, + paramDefList: self.parameters + }); + }, function (error) { + options.errorValidate = error; + onError(error); + }); + if (options.errorValidate) { + return; + } + // init options-defaults + local.objectSetDefault(options, { + inForm: isMultipartFormData + ? new local.FormData() + : '', + inHeader: {}, + inPath: self._path, + inQuery: '', + headers: {}, + method: self._method, + responseType: self.produces && + self.produces[0].indexOf('application/octet-stream') === 0 + ? 'arraybuffer' + : '' + }); + // init paramDict + self.parameters.forEach(function (paramDef) { + tmp = options.paramDict[paramDef.name]; + if (tmp === undefined) { + return; + } + // serialize array + if (paramDef.type === 'array' && paramDef.in !== 'body') { + if (typeof tmp !== 'string') { + switch (paramDef.collectionFormat) { + case 'json': + tmp = JSON.stringify(tmp); + break; + case 'multi': + tmp.forEach(function (value) { + options[paramDef.in === 'formData' + ? 'inForm' + : 'inQuery'] += '&' + + encodeURIComponent(paramDef.name) + '=' + + encodeURIComponent(paramDef.items.type === 'string' + ? value + : JSON.stringify(value)); + }); + return; + case 'pipes': + tmp = tmp.join('|'); + break; + case 'ssv': + tmp = tmp.join(' '); + break; + case 'tsv': + tmp = tmp.join('\t'); + break; + // default to csv + default: + tmp = tmp.join(','); + } + } + } else if (!(paramDef.type === 'string' || tmp instanceof local.Blob)) { + tmp = JSON.stringify(tmp); + } + switch (paramDef.in) { + case 'body': + options.inBody = tmp; + break; + case 'formData': + if (isMultipartFormData) { + options.inForm.append(paramDef.name, tmp, tmp && tmp.name); + break; + } + options.inForm += '&' + encodeURIComponent(paramDef.name) + '=' + + encodeURIComponent(tmp); + break; + case 'header': + options.inHeader[encodeURIComponent(paramDef.name.toLowerCase())] = tmp; + break; + case 'query': + options.inQuery += '&' + encodeURIComponent(paramDef.name) + '=' + + encodeURIComponent(tmp); + break; + case 'path': + options.inPath = options.inPath + .replace('{' + paramDef.name + '}', encodeURIComponent(tmp)); + break; + } + }); + // init data + options.data = options.inBody || (isMultipartFormData + ? options.inForm + : options.inForm.slice(1)); + // init headers + local.objectSetOverride(options.headers, options.inHeader); + // init headers - Content-Type + if (options.inForm) { + options.headers['Content-Type'] = isMultipartFormData + ? 'multipart/form-data' + : 'application/x-www-form-urlencoded'; + } + // init headers - Authorization + options.jwtEncrypted = options.jwtEncrypted || local.userJwtEncrypted; + if (options.jwtEncrypted) { + options.headers.Authorization = options.headers.Authorization || + 'Bearer ' + options.jwtEncrypted; + } + // init url + options.url = (local.urlBaseGet() + options.inPath + '?' + options.inQuery.slice(1)) + .replace((/\?$/), ''); + if (!(options.headers['Content-Type'] || options.headers['content-type'])) { + options.headers['content-type'] = 'application/json; charset=UTF-8'; + } + // send ajax-request + return local.ajax(options, function (error, xhr) { + // try to init responseJson + local.tryCatchOnError(function () { + xhr.responseJson = JSON.parse(xhr.responseText); + }, local.nop); + // init userJwtEncrypted + if (xhr.getResponseHeader('swgg-jwt-encrypted')) { + local.userJwtEncrypted = xhr.getResponseHeader('swgg-jwt-encrypted'); + } + onError(error, xhr); + }); + }; + + local.apiDictUpdate = function (options) { + /* + * this function will update the swagger-api dict of api-calls + */ + var tmp; + options = options || {}; + // init apiDict + local.apiDict = local.apiDict || {}; + // init swaggerJson + local.swaggerJson = local.swaggerJson || { + "basePath": "/api/v0", + "definitions": { + "BuiltinFile": { + "properties": { + "_id": { + "readOnly": true, + "type": "string" + }, + "_timeCreated": { + "format": "date-time", + "readOnly": true, + "type": "string" + }, + "_timeUpdated": { + "format": "date-time", + "readOnly": true, + "type": "string" + }, + "fileBlob": { + "format": "byte", + "type": "string" + }, + "fileContentType": { + "type": "string" + }, + "fileDescription": { + "type": "string" + }, + "fileFilename": { + "type": "string" + }, + "fileInputName": { + "type": "string" + }, + "fileSize": { + "minimum": 0, + "type": "integer" + }, + "fileUrl": { + "type": "string" + }, + "id": { + "type": "string" + } + } + }, + "BuiltinJsonapiResponse": { + "properties": { + "data": { + "items": { + "type": "object" + }, + "type": "array" + }, + "errors": { + "items": { + "type": "object" + }, + "type": "array" + }, + "meta": { + "type": "object" + } + } + }, + "BuiltinUser": { + "properties": { + "_id": { + "readOnly": true, + "type": "string" + }, + "_timeCreated": { + "format": "date-time", + "readOnly": true, + "type": "string" + }, + "_timeUpdated": { + "format": "date-time", + "readOnly": true, + "type": "string" + }, + "id": { + "type": "string" + }, + "jwtEncrypted": { + "type": "string" + }, + "password": { + "format": "password", + "type": "string" + }, + "username": { + "type": "string" + } + } + } + }, + "info": { + "description": "demo of swagger-ui server", + "title": "swgg api", + "version": "0" + }, + "paths": {}, + "securityDefinitions": {}, + "swagger": "2.0", + "tags": [] + }; + // save tags + tmp = {}; + [local.swaggerJson.tags, options.tags || []].forEach(function (tagList) { + tagList.forEach(function (tag) { + local.objectSetOverride(tmp, local.objectLiteralize({ + '$[]': [tag.name, tag] + })); + }, 2); + }); + tmp = Object.keys(tmp).sort().map(function (key) { + return tmp[key]; + }); + // merge options into swaggerJson + options = local.objectSetOverride(local.swaggerJson, options, 10); + // restore tags + local.swaggerJson.tags = tmp; + Object.keys(options.definitions).forEach(function (schemaName) { + // normalize definition + options.definitions[schemaName] = + local.schemaNormalizeAndCopy(options.definitions[schemaName]); + }); + // init apiDict from paths + Object.keys(options.paths).forEach(function (path) { + Object.keys(options.paths[path]).forEach(function (method) { + var self; + self = options.paths[path][method]; + self._method = method; + self._path = path; + local.objectSetOverride(local.apiDict, local.objectLiteralize({ + '$[]': [self.tags[0] + ' ' + self.operationId, self] + }), 2); + }); + }); + // init apiDict from x-swgg-apiDict + Object.keys(options['x-swgg-apiDict'] || {}).forEach(function (key) { + // init self + local.objectSetOverride(local.apiDict, local.objectLiteralize({ + '$[]': [key, local.jsonCopy(options['x-swgg-apiDict'][key])] + }), Infinity); + }); + // init apiDict + Object.keys(local.apiDict).forEach(function (key) { + var self; + self = local.apiDict[key]; + if (key === self._keyPath) { + return; + } + // init _operationId + self._operationId = self._operationId || key.split(' ')[1]; + // init _fileUploadNumber + self._fileUploadNumber = 1; + self._operationId.replace( + (/^fileUploadManyByForm\.(\d+)/), + function (match0, match1) { + // jslint-hack - nop + local.nop(match0); + self._fileUploadNumber = Number(match1); + } + ); + // init _idAlias and _idField + tmp = local.idFieldInit({ operationId: self._operationId }); + self._idAlias = tmp.idAlias; + self._idField = tmp.idField; + // init _tags0 + self._tags0 = key.split(' ')[0]; + // init templateApiDict + if (local.templateApiDict[self._operationId.split('.')[0]]) { + local.objectSetDefault( + self, + JSON.parse(local.templateApiDict[self._operationId.split('.')[0]] + .replace((/\{\{_fileUploadNumber\}\}/g), self._fileUploadNumber) + .replace((/\{\{_idAlias\}\}/g), self._idAlias) + .replace((/\{\{_idField\}\}/g), self._idField) + .replace((/\{\{_schemaName\}\}/g), self._schemaName) + .replace((/\{\{_tags0\}\}/g), self._tags0) + .replace((/\{\{operationId\}\}/g), self._operationId)) + ); + } + // init default + local.objectSetDefault(self, { + _keyOperationId: key, + operationId: self._operationId, + parameters: [], + responses: { + 200: { + description: 'ok - ' + + 'http://jsonapi.org/format/#document-top-level', + schema: { $ref: '#/definitions/BuiltinJsonapiResponse' } + } + }, + tags: [self._tags0] + }); + // init _method + self._method = self._method.toUpperCase(); + // init _keyPath + self._keyPath = self._method + ' ' + self._path.replace((/\{.*?\}/g), ''); + // init _idField.format and _idField.type + if (self._schemaName) { + self.parameters.forEach(function (param) { + if (param.name === self._idField) { + param.format = options.definitions[self._schemaName] + .properties[self._idAlias].format; + param.type = options.definitions[self._schemaName] + .properties[self._idAlias].type; + } + }); + } + switch (self.operationId.split('.')[0]) { + // add extra file-upload forms + case 'fileUploadManyByForm': + for (tmp = 1; tmp <= self._fileUploadNumber; tmp += 1) { + self.parameters[tmp] = local.jsonCopy(self.parameters[1]); + self.parameters[tmp].name = 'file' + tmp; + } + break; + } + // update apiDict + self = local.apiDict[key] = local.apiDict[self._keyPath] = local.jsonCopy(self); + // init _ajax + self._ajax = function (options, onError) { + return local.apiAjax(self, options, onError); + }; + // remove underscored keys from self + tmp = local.jsonCopy(self); + Object.keys(tmp).forEach(function (key) { + if (key[0] === '_') { + delete tmp[key]; + } + }); + // update paths + local.objectSetOverride(options, local.objectLiteralize({ + paths: { '$[]': [self._path, { '$[]': [self._method.toLowerCase(), tmp] }] } + }), 3); + }); + // normalize swaggerJson + local.swaggerJson = JSON.parse(local.jsonStringifyOrdered(options)); + // update $npm_config_swagger_basePath + local.env.npm_config_swagger_basePath = local.swaggerJson.basePath; + // try to validate swaggerJson + local.tryCatchOnError(function () { + local.validateBySwagger(local.swaggerJson); + }, local.onErrorDefault); + }; + + local.dbFieldRandomCreate = function (options) { + /* + * this function will create a random dbField from options.propDef + */ + var ii, max, min, propDef, tmp; + propDef = options.propDef; + if (propDef.readOnly) { + return; + } + if (propDef.enum) { + tmp = options.modeNotRandom + ? propDef.enum[0] + : local.listGetElementRandom(propDef.enum); + return propDef.type === 'array' + ? [tmp] + : tmp; + } + // http://json-schema.org/latest/json-schema-validation.html#anchor13 + // 5.1. Validation keywords for numeric instances (number and integer) + max = isFinite(propDef.maximum) + ? propDef.maximum + : 999; + min = isFinite(propDef.maximum) + ? propDef.minimum + : 0; + switch (propDef.type) { + case 'array': + tmp = []; + // http://json-schema.org/latest/json-schema-validation.html#anchor36 + // 5.3. Validation keywords for arrays + for (ii = 0; ii < (propDef.minItems || 0); ii += 1) { + tmp.push(null); + } + break; + case 'boolean': + tmp = options.modeNotRandom + ? false + : Math.random() <= 0.5 + ? false + : true; + break; + case 'integer': + if (propDef.exclusiveMaximum) { + max -= 1; + } + if (propDef.exclusiveMinimum) { + min += 1; + } + min = Math.min(min, max); + tmp = options.modeNotRandom + ? 0 + : Math.random(); + tmp = Math.floor(min + tmp * (max - min)); + break; + case 'object': + tmp = {}; + // http://json-schema.org/latest/json-schema-validation.html#anchor53 + // 5.4. Validation keywords for objects + for (ii = 0; ii < (propDef.minProperties || 0); ii += 1) { + tmp['property' + ii] = null; + } + break; + case 'number': + if (propDef.exclusiveMinimum) { + min = min < 0 + ? min * 0.99999 + : min * 1.00001 + 0.00001; + } + if (propDef.exclusiveMaximum) { + max = max > 0 + ? max * 0.99999 + : max * 1.00001 - 0.00001; + } + min = Math.min(min, max); + tmp = options.modeNotRandom + ? 0 + : Math.random(); + tmp = min + tmp * (max - min); + break; + case 'string': + tmp = options.modeNotRandom + ? 'abcd1234' + : ((1 + Math.random()) * 0x10000000000000).toString(36).slice(1); + switch (propDef.format) { + case 'byte': + tmp = local.base64FromString(tmp); + break; + case 'date': + case 'date-time': + tmp = new Date().toISOString(); + break; + case 'email': + tmp = tmp + '@random.com'; + break; + case 'json': + tmp = JSON.stringify({ random: tmp }); + break; + case 'phone': + tmp = options.modeNotRandom + ? '+123 (1234) 1234-1234' + : '+' + Math.random().toString().slice(-3) + + ' (' + Math.random().toString().slice(-4) + ') ' + + Math.random().toString().slice(-4) + '-' + + Math.random().toString().slice(-4); + break; + } + // http://json-schema.org/latest/json-schema-validation.html#anchor25 + // 5.2. Validation keywords for strings + while (tmp.length < (propDef.minLength || 0)) { + tmp += tmp; + } + tmp = tmp.slice(0, propDef.maxLength || Infinity); + break; + } + // http://json-schema.org/latest/json-schema-validation.html#anchor13 + // 5.1. Validation keywords for numeric instances (number and integer) + if (propDef.multipleOf) { + tmp = propDef.multipleOf * Math.floor(tmp / propDef.multipleOf); + if (tmp < min) { + tmp += propDef.multipleOf; + } + } + return tmp; + }; + + local.dbRowListRandomCreate = function (options) { + /* + * this function will create a dbRowList of options.length random dbRow's + */ + local.objectSetDefault(options, { dbRowList: [] }); + for (options.ii = 0; options.ii < options.length; options.ii += 1) { + options.dbRowList.push(local.dbRowRandomCreate(options)); + } + return options.dbRowList; + }; + + local.dbRowRandomCreate = function (options) { + /* + * this function will create a random dbRow from options.properties + */ + var dbRow, tmp; + dbRow = {}; + Object.keys(options.properties).forEach(function (key) { + // try to validate data + local.tryCatchOnError(function () { + tmp = local.dbFieldRandomCreate({ + modeNotRandom: options.modeNotRandom, + propDef: options.properties[key] + }); + local.validateByPropDef({ + data: tmp, + key: options.properties[key].name, + schema: options.properties[key] + }); + dbRow[key] = tmp; + }, local.nop); + }); + return local.jsonCopy(local.objectSetOverride(dbRow, options.override(options))); + }; + + local.idDomElementCreate = function (seed) { + /* + * this function will create a unique dom-element id from the seed, + * that is both dom-selector and url friendly + */ + var id, ii; + id = encodeURIComponent(seed).replace((/\W/g), '_'); + for (ii = 2; local.idDomElementDict[id]; ii += 1) { + id = encodeURIComponent(seed + '_' + ii).replace((/\W/g), '_'); + } + local.idDomElementDict[id] = true; + return id; + }; + + local.idFieldInit = function (options) { + /* + * this function will init options.idAlias, options.idField, and options.queryById + */ + var idAlias, idField; + // init idField + options.idAlias = options.operationId.split('.'); + idField = options.idField = options.idAlias[1] || 'id'; + // init idAlias + idAlias = options.idAlias = options.idAlias[2] || options.idField; + // invert queryById + if (options.modeQueryByIdInvert) { + idAlias = options.idField; + idField = options.idAlias; + } + // init queryById + options.idValue = (options.data && options.data[idAlias]) || options.idValue; + options.queryById = {}; + options.queryById[idField] = options.idValue; + return options; + }; + + local.middlewareBodyParse = function (request, response, nextMiddleware) { + /* + * this function will run the middleware that will parse request.bodyRaw + */ + var ii, jj, options; + // jslint-hack + local.nop(response); + // if request is already parsed, then goto nextMiddleware + if (!local.isNullOrUndefined(request.swgg.bodyParsed)) { + nextMiddleware(); + return; + } + switch (String(request.headers['content-type']).split(';')[0]) { + // parse application/x-www-form-urlencoded, e.g. + // aa=hello%20world&bb=bye%20world + case 'application/x-www-form-urlencoded': + request.swgg.bodyParsed = local.bufferToString(request.bodyRaw); + request.swgg.bodyParsed = + local.urlParse('?' + request.swgg.bodyParsed, true).query; + break; + /* + * https://tools.ietf.org/html/rfc7578 + * parse multipart/form-data, e.g. + * --Boundary\r\n + * Content-Disposition: form-data; name="key"\r\n + * \r\n + * value\r\n + * --Boundary\r\n + * Content-Disposition: form-data; name="input1"; filename="file1.png"\r\n + * Content-Type: image/jpeg\r\n + * \r\n + * \r\n + * --Boundary\r\n + * Content-Disposition: form-data; name="input2"; filename="file2.png"\r\n + * Content-Type: image/jpeg\r\n + * \r\n + * \r\n + * --Boundary--\r\n + */ + case 'multipart/form-data': + request.swgg.isMultipartFormData = true; + request.swgg.bodyParsed = {}; + request.swgg.bodyMeta = {}; + options = {}; + options.crlf = local.bufferCreate([0x0d, 0x0a]); + // init boundary + ii = 0; + jj = local.bufferIndexOfSubBuffer(request.bodyRaw, options.crlf, ii); + if (jj <= 0) { + break; + } + options.boundary = local.bufferConcat([ + options.crlf, + request.bodyRaw.slice(ii, jj) + ]); + ii = jj + 2; + while (true) { + jj = local.bufferIndexOfSubBuffer( + request.bodyRaw, + options.boundary, + ii + ); + if (jj < 0) { + break; + } + options.header = local.bufferToString(request.bodyRaw.slice(ii, ii + 1024)) + .split('\r\n').slice(0, 2).join('\r\n'); + options.contentType = (/^content-type:(.*)/im).exec(options.header); + options.contentType = options.contentType && options.contentType[1].trim(); + options.filename = (/^content-disposition:.*?\bfilename="([^"]+)/im) + .exec(options.header); + options.filename = options.filename && options.filename[1]; + options.name = (/^content-disposition:.*?\bname="([^"]+)/im) + .exec(options.header); + options.name = options.name && options.name[1]; + ii = local.bufferIndexOfSubBuffer( + request.bodyRaw, + [0x0d, 0x0a, 0x0d, 0x0a], + ii + 2 + ) + 4; + options.data = request.bodyRaw.slice(ii, jj); + request.swgg.bodyParsed[options.name] = options.data; + request.swgg.bodyMeta[options.name] = { + contentType: options.contentType, + filename: options.filename, + name: options.name + }; + ii = jj + options.boundary.length + 2; + } + break; + default: + request.swgg.bodyParsed = local.bufferToString(request.bodyRaw); + // try to JSON.parse the string + local.tryCatchOnError(function () { + request.swgg.bodyParsed = JSON.parse(request.swgg.bodyParsed); + }, local.nop); + } + nextMiddleware(); + }; + + local.middlewareCrudBuiltin = function (request, response, nextMiddleware) { + /* + * this function will run the middleware that will + * run the builtin crud-operations backed by db-lite + */ + var crud, onParallel, options, tmp, user; + options = {}; + local.onNext(options, function (error, data, meta) { + switch (options.modeNext) { + case 1: + crud = request.swgg.crud; + user = request.swgg.user; + switch (crud.operationId.split('.')[0]) { + case 'crudCountManyByQuery': + crud.dbTable.crudCountManyByQuery(crud.queryWhere, options.onNext); + break; + case 'crudSetManyById': + crud.dbTable.crudSetManyById(crud.body, options.onNext); + break; + case 'crudSetOneById': + // replace idField with idAlias in body + delete crud.body.id; + delete crud.body[crud.idField]; + crud.body[crud.idAlias] = crud.data[crud.idField]; + crud.dbTable.crudSetOneById(crud.body, options.onNext); + break; + case 'crudUpdateOneById': + // replace idField with idAlias in body + delete crud.body.id; + delete crud.body[crud.idField]; + crud.body[crud.idAlias] = crud.data[crud.idField]; + crud.dbTable.crudUpdateOneById(crud.body, options.onNext); + break; + // coverage-hack - test error handling-behavior + case 'crudErrorDelete': + case 'crudErrorGet': + case 'crudErrorHead': + case 'crudErrorOptions': + case 'crudErrorPatch': + case 'crudErrorPost': + case 'crudErrorPut': + options.onNext(local.errorDefault); + break; + case 'crudGetManyByQuery': + onParallel = local.onParallel(options.onNext); + onParallel.counter += 1; + crud.dbTable.crudGetManyByQuery({ + fieldList: crud.queryFields, + limit: crud.queryLimit, + query: crud.queryWhere, + skip: crud.querySkip, + sort: crud.querySort + }, function (error, data) { + crud.queryData = data; + onParallel(error); + }); + onParallel.counter += 1; + crud.dbTable.crudCountAll(function (error, data) { + crud.paginationCountTotal = data; + onParallel(error); + }); + break; + case 'crudGetOneById': + crud.dbTable.crudGetOneById(crud.queryById, options.onNext); + break; + case 'crudGetOneByQuery': + crud.dbTable.crudGetOneByQuery({ + query: crud.queryWhere + }, options.onNext); + break; + case 'crudNullDelete': + case 'crudNullGet': + case 'crudNullHead': + case 'crudNullOptions': + case 'crudNullPatch': + case 'crudNullPost': + case 'crudNullPut': + options.onNext(); + break; + case 'crudRemoveManyByQuery': + crud.dbTable.crudRemoveManyByQuery(crud.queryWhere, options.onNext); + break; + case 'crudRemoveOneById': + crud.dbTable.crudRemoveOneById(crud.queryById, options.onNext); + break; + case 'fileGetOneById': + local.dbTableFile = local.db.dbTableCreateOne({ name: 'File' }); + crud.dbTable.crudGetOneById(crud.queryById, options.onNext); + break; + case 'fileUploadManyByForm': + local.dbTableFile = local.db.dbTableCreateOne({ name: 'File' }); + request.swgg.paramDict = {}; + Object.keys(request.swgg.bodyMeta).forEach(function (key) { + if (typeof request.swgg.bodyMeta[key].filename !== 'string') { + request.swgg.paramDict[key] = + local.bufferToString(request.swgg.bodyParsed[key]); + } + }); + crud.body = Object.keys(request.swgg.bodyMeta) + .filter(function (key) { + return typeof request.swgg.bodyMeta[key].filename === 'string'; + }) + .map(function (key) { + tmp = local.jsonCopy(request.swgg.paramDict); + local.objectSetOverride(tmp, { + fileBlob: + local.base64FromBuffer(request.swgg.bodyParsed[key]), + fileContentType: request.swgg.bodyMeta[key].contentType, + fileFilename: request.swgg.bodyMeta[key].filename, + fileInputName: request.swgg.bodyMeta[key].name, + fileSize: request.swgg.bodyParsed[key].length, + fileUrl: local.swaggerJson.basePath + + '/' + request.swgg.pathObject._tags0 + + '/fileGetOneById/' + tmp.id + }); + return tmp; + }); + local.dbTableFile.crudSetManyById(crud.body, options.onNext); + break; + case 'userLoginByPassword': + case 'userLogout': + // respond with 401 Unauthorized + if (!user.isAuthenticated) { + local.serverRespondHeadSet(request, response, 401, {}); + request.swgg.crud.endArgList = [request, response]; + options.modeNext = Infinity; + options.onNext(); + return; + } + options.onNext(); + break; + default: + options.modeNext = Infinity; + options.onNext(); + } + break; + case 2: + switch (crud.operationId.split('.')[0]) { + case 'crudSetOneById': + case 'crudUpdateOneById': + options.onNext(null, data); + break; + case 'crudGetManyByQuery': + options.onNext(null, crud.queryData, { + paginationCountTotal: crud.paginationCountTotal + }); + break; + case 'fileUploadManyByForm': + options.onNext(null, data.map(function (element) { + delete element.fileBlob; + return element; + })); + break; + case 'userLoginByPassword': + options.onNext(null, { jwtEncrypted: user.jwtEncrypted }); + break; + case 'userLogout': + crud.dbTable.crudUpdateOneById({ + jwtEncrypted: null, + username: user.username + }, options.onNext); + break; + default: + options.onNext(null, data, meta); + } + break; + case 3: + switch (crud.operationId.split('.')[0]) { + case 'fileGetOneById': + if (!data) { + local.serverRespondDefault(request, response, 404); + return; + } + local.serverRespondHeadSet(request, response, null, { + 'Content-Type': data.fileContentType + }); + response.end(local.base64ToBuffer(data.fileBlob)); + break; + case 'userLogout': + options.onNext(); + break; + default: + options.onNext(null, data, meta); + } + break; + case 4: + request.swgg.crud.endArgList = [request, response, null, data, meta]; + options.onNext(); + break; + default: + nextMiddleware(error); + } + }); + options.modeNext = 0; + options.onNext(); + }; + + local.middlewareCrudEnd = function (request, response, nextMiddleware) { + /* + * this function will run the middleware that will end the builtin crud-operations + */ + // jslint-hack + local.nop(response); + if (request.swgg.crud.endArgList) { + local.serverRespondJsonapi.apply(null, request.swgg.crud.endArgList); + return; + } + nextMiddleware(); + }; + + local.middlewareRouter = function (request, response, nextMiddleware) { + /* + * this function will run the middleware that will + * map the request's method-path to swagger's tags[0]-operationId + */ + var tmp; + // jslint-hack + local.nop(response); + // init swgg object + local.objectSetDefault( + request, + { swgg: { crud: { operationId: '' }, user: {} } }, + 2 + ); + // if request.url is not prefixed with swaggerJson.basePath, + // then default to nextMiddleware + if (request.urlParsed.pathname.indexOf(local.swaggerJson.basePath) !== 0) { + nextMiddleware(); + return; + } + // init pathname + request.swgg.pathname = request.method + ' ' + request.urlParsed.pathname + .replace(local.swaggerJson.basePath, ''); + // init pathObject + while (request.swgg.pathname !== tmp) { + request.swgg.pathObject = + local.apiDict[request.swgg.pathname] || + // handle /foo/{id}/bar case + local.apiDict[request.swgg.pathname + .replace((/\/[^\/]+\/([^\/]*?)$/), '//$1')]; + // if pathObject exists, then break + if (request.swgg.pathObject) { + request.swgg.pathObject = local.jsonCopy(request.swgg.pathObject); + request.swgg.pathname = request.swgg.pathObject._keyPath; + // init crud.operationId + request.swgg.crud.operationId = request.swgg.pathObject._operationId; + break; + } + tmp = request.swgg.pathname; + request.swgg.pathname = request.swgg.pathname + .replace((/\/[^\/]+?(\/*?)$/), '/$1'); + } + nextMiddleware(); + }; + + local.middlewareUserLogin = function (request, response, nextMiddleware) { + /* + * this function will run the middleware that will handle user login + */ + var crud, options, user; + options = {}; + local.onNext(options, function (error, data) { + switch (options.modeNext) { + case 1: + local.dbTableUser = local.db.dbTableCreateOne({ name: 'User' }); + crud = request.swgg.crud; + user = request.swgg.user = {}; + user.jwtEncrypted = request.headers.authorization && + request.headers.authorization.replace('Bearer ', ''); + user.jwtDecrypted = local.jwtA256GcmDecrypt(user.jwtEncrypted); + switch (crud.operationId.split('.')[0]) { + // coverage-hack - test error handling-behavior + case 'crudErrorLogin': + options.onNext(local.errorDefault); + return; + case 'userLoginByPassword': + user.password = request.urlParsed.query.password; + user.username = request.urlParsed.query.username; + if (user.password && user.username) { + local.dbTableUser.crudGetOneById({ + username: user.username + }, options.onNext); + return; + } + break; + default: + if (user.jwtDecrypted.sub) { + // init username + user.username = user.jwtDecrypted.sub; + local.dbTableUser.crudGetOneById({ + username: user.username + }, options.onNext); + return; + } + } + options.modeNext = Infinity; + options.onNext(); + break; + case 2: + switch (crud.operationId.split('.')[0]) { + case 'userLoginByPassword': + user.data = data; + if (!local.sjclHashScryptValidate( + user.password, + user.data && user.data.password + )) { + options.modeNext = Infinity; + options.onNext(); + return; + } + // init isAuthenticated + user.isAuthenticated = true; + // https://tools.ietf.org/html/rfc7519 + // create JSON Web Token (JWT) + user.jwtDecrypted = {}; + user.jwtDecrypted.sub = user.data.username; + // update jwtEncrypted in client + user.jwtEncrypted = local.jwtA256GcmEncrypt(user.jwtDecrypted); + local.serverRespondHeadSet(request, response, null, { + 'swgg-jwt-encrypted': user.jwtEncrypted + }); + // update jwtEncrypted in dbTableUser + local.dbTableUser.crudUpdateOneById({ + jwtEncrypted: user.jwtEncrypted, + username: user.jwtDecrypted.sub + }, options.onNext); + return; + default: + data = user.data = data || {}; + if (data.jwtEncrypted) { + // init isAuthenticated + user.isAuthenticated = true; + // update jwtEncrypted in client + if (data.jwtEncrypted !== user.jwtEncrypted) { + user.jwtEncrypted = data.jwtEncrypted; + user.jwtDecrypted = local.jwtA256GcmDecrypt(user.jwtEncrypted); + local.serverRespondHeadSet(request, response, null, { + 'swgg-jwt-encrypted': user.jwtEncrypted + }); + } + } + } + options.onNext(); + break; + default: + nextMiddleware(error); + } + }); + options.modeNext = 0; + options.onNext(); + }; + + local.middlewareValidate = function (request, response, nextMiddleware) { + /* + * this function will run the middleware that will validate the swagger-request + */ + var crud, modeNext, onNext, tmp; + modeNext = 0; + onNext = function () { + modeNext += 1; + switch (modeNext) { + case 1: + // serve swagger.json + if (request.method + ' ' + request.urlParsed.pathname === + 'GET ' + local.swaggerJson.basePath + '/swagger.json') { + response.end(JSON.stringify(local.swaggerJson)); + return; + } + if (!request.swgg.pathObject) { + modeNext = Infinity; + onNext(); + return; + } + // init paramDict + request.swgg.paramDict = {}; + // parse path param + tmp = request.urlParsed.pathname + .replace(local.swaggerJson.basePath, '').split('/'); + request.swgg.pathObject._path.split('/').forEach(function (key, ii) { + if ((/^\{\S*?\}$/).test(key)) { + request.swgg.paramDict[key.slice(1, -1)] = + decodeURIComponent(tmp[ii]); + } + }); + request.swgg.pathObject.parameters.forEach(function (paramDef) { + switch (paramDef.in) { + // parse body param + case 'body': + request.swgg.paramDict[paramDef.name] = request.swgg.bodyParsed || + undefined; + break; + // parse formData param + case 'formData': + switch (String(request.headers['content-type']).split(';')[0]) { + case 'application/x-www-form-urlencoded': + request.swgg.paramDict[paramDef.name] = + request.swgg.bodyParsed[paramDef.name]; + break; + } + break; + // parse header param + case 'header': + request.swgg.paramDict[paramDef.name] = + request.headers[paramDef.name.toLowerCase()]; + break; + // parse query param + case 'query': + request.swgg.paramDict[paramDef.name] = + request.urlParsed.query[paramDef.name]; + break; + } + // parse array-multi + if (request.swgg.paramDict[paramDef.name] && + paramDef.type === 'array' && + paramDef.collectionFormat === 'multi') { + tmp = ''; + request.swgg.paramDict[paramDef.name].forEach(function (value) { + tmp += '&' + encodeURIComponent(paramDef.name) + '=' + + encodeURIComponent(value); + }); + request.swgg.paramDict[paramDef.name] = tmp.slice(1); + } + // init default param + if (local.isNullOrUndefined(request.swgg.paramDict[paramDef.name]) && + paramDef.default !== undefined) { + request.swgg.paramDict[paramDef.name] = + local.jsonCopy(paramDef.default); + } + }); + // normalize paramDict + local.normalizeParamDictSwagger( + request.swgg.paramDict, + request.swgg.pathObject + ); + // validate paramDict + local.validateByParamDefList({ + data: request.swgg.paramDict, + key: request.swgg.pathname, + paramDefList: request.swgg.pathObject.parameters + }); + onNext(); + break; + case 2: + // init crud + crud = request.swgg.crud; + // init crud.dbTable + crud.dbTable = request.swgg.pathObject && + request.swgg.pathObject._schemaName && + local.db.dbTableCreateOne({ + name: request.swgg.pathObject._schemaName + }); + if (!crud.dbTable) { + nextMiddleware(); + return; + } + // init crud.body + if (!request.swgg.isMultipartFormData) { + crud.body = local.jsonCopy(request.swgg.bodyParsed); + } + // init crud.data + crud.data = local.jsonCopy(request.swgg.paramDict); + request.swgg.pathObject.parameters.forEach(function (param) { + // JSON.parse json-string + if (param.format === 'json' && + param.type === 'string' && + crud.data[param.name]) { + crud.data[param.name] = JSON.parse(crud.data[param.name]); + } + }); + // init crud.query* + [{ + key: 'queryFields', + value: {} + }, { + key: 'queryLimit', + value: 100 + }, { + key: 'querySkip', + value: 0 + }, { + key: 'querySort', + value: [{ fieldName: '_timeUpdated', isDescending: true }] + }, { + key: 'queryWhere', + value: {} + }].forEach(function (element) { + crud[element.key] = crud.data['_' + element.key] || JSON.parse( + local.templateRender( + request.swgg.pathObject['_' + element.key] || 'null', + request.swgg.paramDict + ) + ) || element.value; + }); + // init-before crud.idField + crud.modeQueryByIdInvert = true; + local.idFieldInit(crud); + // init crud.data.id + switch (crud.operationId.split('.')[0]) { + case 'crudSetOneById': + case 'crudUpdateOneById': + if (!local.isNullOrUndefined(crud.data[crud.idField])) { + break; + } + crud.data[crud.idField] = (crud.body && crud.body[crud.idAlias]); + break; + } + // init-after crud.idField + crud.modeQueryByIdInvert = true; + local.idFieldInit(crud); + nextMiddleware(); + break; + default: + nextMiddleware(); + } + }; + onNext(); + }; + + local.normalizeParamDictSwagger = function (data, pathObject) { + /* + * this function will parse the data according to pathObject.parameters + */ + var tmp; + pathObject.parameters.forEach(function (paramDef) { + tmp = data[paramDef.name]; + // init default value + if (local.isNullOrUndefined(tmp) && paramDef.default !== undefined) { + tmp = local.jsonCopy(paramDef.default); + } + // parse array + if (paramDef.type === 'array' && paramDef.in !== 'body') { + if (typeof tmp === 'string') { + switch (paramDef.collectionFormat) { + case 'json': + local.tryCatchOnError(function () { + tmp = JSON.parse(tmp); + }, local.nop); + data[paramDef.name] = tmp; + return; + case 'multi': + tmp = local.urlParse('?' + tmp, true).query[paramDef.name]; + break; + case 'pipes': + tmp = tmp.split('|'); + break; + case 'ssv': + tmp = tmp.split(' '); + break; + case 'tsv': + tmp = tmp.split('\t'); + break; + // default to csv + default: + tmp = tmp.split(','); + } + if (paramDef.items && paramDef.items.type !== 'string') { + // try to JSON.parse the string + local.tryCatchOnError(function () { + tmp = tmp.map(function (element) { + return JSON.parse(element); + }); + }, local.nop); + } + } + // JSON.parse paramDict + } else if (paramDef.type !== 'file' && + paramDef.type !== 'string' && + (typeof tmp === 'string' || tmp instanceof local.global.Uint8Array)) { + // try to JSON.parse the string + local.tryCatchOnError(function () { + tmp = JSON.parse(local.bufferToString(tmp)); + }, local.nop); + } + data[paramDef.name] = tmp; + }); + return data; + }; + + local.onErrorJsonapi = function (onError) { + /* + * http://jsonapi.org/format/#errors + * http://jsonapi.org/format/#document-structure-resource-objects + * this function will normalize the error and data to jsonapi format, + * and pass them to onError + */ + return function (error, data, meta) { + data = [error, data].map(function (data, ii) { + // if no error occurred, then return + if ((ii === 0 && !data) || + // if data is already normalized, then return it + (data && data.meta && data.meta.isJsonapiResponse)) { + return data; + } + // normalize data-list + if (!Array.isArray(data)) { + data = [data]; + } + // normalize error-list to contain non-null objects + if (ii === 0) { + // normalize error-list to be non-empty + if (!data.length) { + data.push(null); + } + data = data.map(function (element) { + if (!(element && typeof element === 'object')) { + element = { message: String(element) }; + } + // normalize error-object to plain json-object + error = local.jsonCopy(element); + error.message = element.message; + error.stack = element.stack; + error.statusCode = Number(error.statusCode) || 500; + return error; + }); + error = local.jsonCopy(data[0]); + error.errors = data; + return error; + } + return { data: data }; + }); + // init data.meta + data.forEach(function (data, ii) { + if (!data) { + return; + } + data.meta = local.jsonCopy(meta || {}); + data.meta.isJsonapiResponse = true; + if (ii === 0) { + data.meta.errorsLength = (data.errors && data.errors.length) | 0; + } else { + data.meta.dataLength = (data.data && data.data.length) | 0; + } + data.meta.statusCode = Number(data.meta.statusCode) || + Number(data.statusCode) || + 0; + }); + onError(data[0], data[1]); + }; + }; + + local.schemaNormalizeAndCopy = function (schema) { + /* + * this function will return a normalized copy the schema + */ + var tmp; + // dereference $ref + if (schema.$ref) { + [local.swaggerJson, local.swaggerSchemaJson].some(function (options) { + local.tryCatchOnError(function () { + schema.$ref.replace( + (/#\/(.*?)\/(.*?)$/), + function (match0, match1, match2) { + // jslint-hack - nop + local.nop(match0); + tmp = options[match1][match2]; + } + ); + }, local.nop); + return tmp; + }); + // validate schema + local.assert(tmp, schema.$ref); + // recurse + schema = local.schemaNormalizeAndCopy(tmp); + } + // inherit allOf + if (schema.allOf) { + tmp = local.jsonCopy(schema); + delete tmp.allOf; + schema.allOf.reverse().forEach(function (element) { + // recurse + local.objectSetDefault(tmp, local.schemaNormalizeAndCopy(element), 2); + }); + schema = tmp; + } + schema = local.jsonCopy(schema); + if (schema.type === 'object') { + schema.properties = local.normalizeDict(schema.properties); + } + return schema; + }; + + local.serverRespondJsonapi = function (request, response, error, data, meta) { + /* + * http://jsonapi.org/format/#errors + * http://jsonapi.org/format/#document-structure-resource-objects + * this function will respond in jsonapi format + */ + local.onErrorJsonapi(function (error, data) { + local.serverRespondHeadSet(request, response, error && error.statusCode, { + 'Content-Type': 'application/json; charset=UTF-8' + }); + if (error) { + // debug statusCode / method / url + local.errorMessagePrepend(error, response.statusCode + ' ' + + request.method + ' ' + request.url + '\n'); + // print error.stack to stderr + local.onErrorDefault(error); + } + data = error || data; + data.meta.statusCode = response.statusCode = + data.meta.statusCode || response.statusCode; + response.end(JSON.stringify(data)); + })(error, data, meta); + }; + + local.uiAnimateFadeIn = function (element) { + /* + * this function will fadeIn the element + */ + element.classList.add('swggAnimateFade'); + element.style.display = ''; + setTimeout(function () { + element.style.opacity = ''; + }, 20); + setTimeout(function () { + element.classList.remove('swggAnimateFade'); + }, 500); + }; + + local.uiAnimateFadeOut = function (element) { + /* + * this function will fadeOut the element + */ + element.classList.add('swggAnimateFade'); + element.style.opacity = '0'; + setTimeout(function () { + element.style.display = 'none'; + element.classList.remove('swggAnimateFade'); + }, 500); + }; + + local.uiAnimateScrollTo = function (element) { + /* + * this function will scrollTo the element + */ + var ii, timerInterval; + ii = 0; + timerInterval = setInterval(function () { + ii += 0.025; + local.global.scrollTo(0, document.body.scrollTop + + Math.min(ii, 1) * (element.offsetTop - document.body.scrollTop) + + -5); + }, 25); + setTimeout(function () { + clearInterval(timerInterval); + }, 1000); + }; + + local.uiAnimateShake = function (element) { + /* + * this function will shake the dom-element + */ + element.classList.add('swggAnimateShake'); + setTimeout(function () { + element.classList.remove('swggAnimateShake'); + }, 500); + }; + + local.uiAnimateSlideAccordian = function (element, elementList) { + /* + * this function will slideDown the element, + * but slideUp all other elements in elementList + */ + // hide elements in elementList + elementList.forEach(function (element2) { + if (element2 !== element) { + local.uiAnimateSlideUp(element2); + } + }); + // show element + local.uiAnimateSlideDown(element); + }; + + local.uiAnimateSlideDown = function (element) { + /* + * this function will slideDown the dom-element + */ + if (element.style.display !== 'none') { + return; + } + element.style.maxHeight = 0; + element.classList.add('swggAnimateSlide'); + element.style.display = ''; + setTimeout(function () { + element.style.maxHeight = 2 * local.global.innerHeight + 'px'; + }, 20); + setTimeout(function () { + element.style.maxHeight = ''; + element.classList.remove('swggAnimateSlide'); + }, 500); + }; + + local.uiAnimateSlideUp = function (element) { + /* + * this function will slideUp the dom-element + */ + if (element.style.display === 'none') { + return; + } + element.style.maxHeight = 2 * local.global.innerHeight + 'px'; + element.classList.add('swggAnimateSlide'); + setTimeout(function () { + element.style.maxHeight = '0px'; + }, 20); + setTimeout(function () { + element.style.display = 'none'; + }, 500); + setTimeout(function () { + element.style.maxHeight = ''; + element.classList.remove('swggAnimateSlide'); + }, 500); + }; + + local.uiDatatableRender = function (options) { + /* + * this function will render the datatable + */ + var tmp; + local.uiState.datatable = options; + options.schema = local.schemaNormalizeAndCopy(options.schema); + options.propDefList = Object.keys(options.schema.properties) + .sort(function (aa, bb) { + return aa === options._idAlias + ? -1 + : bb === options._idAlias + ? 1 + : aa < bb + ? -1 + : 1; + }) + .map(function (propDef) { + tmp = propDef; + propDef = options.schema.properties[tmp]; + propDef.name = tmp; + local.uiParamRender(propDef); + return propDef; + }); + options.iiPadding = 0; + options.dbRowList = options.responseJson.data.map(function (dbRow, ii) { + dbRow = { paramDict: dbRow }; + dbRow.colList = options.propDefList.map(function (propDef) { + propDef = local.jsonCopy(propDef); + propDef.valueEncoded = dbRow.paramDict[propDef.name]; + if (propDef.valueEncoded === undefined) { + propDef.valueEncoded = ''; + } + if (typeof propDef.valueEncoded !== 'string') { + propDef.valueEncoded = JSON.stringify(propDef.valueEncoded); + } + return propDef; + }); + dbRow.id = dbRow.paramDict[options._idAlias]; + dbRow.ii = options.querySkip + ii + 1; + options.iiPadding = Math.max( + 0.375 * String(dbRow.ii).length, + options.iiPadding + ); + return dbRow; + }); + // init pagination + options.pageCurrent = Math.floor(options.querySkip / options.queryLimit); + options.pageTotal = Math.ceil( + options.responseJson.meta.paginationCountTotal / options.queryLimit + ); + options.pageMin = Math.max( + Math.min(options.pageCurrent - 3, options.pageTotal - 7), + 0 + ); + options.pageMax = Math.min(options.pageMin + 7, options.pageTotal); + options.pageList = []; + // add first page + options.pageList.push({ + disabled: options.pageCurrent === 0, + pageNumber: 0, + valueEncoded: 'first page' + }); + for (tmp = options.pageMin; tmp < options.pageMax; tmp += 1) { + options.pageList.push({ + disabled: tmp === options.pageCurrent, + pageNumber: tmp, + valueEncoded: JSON.stringify(tmp + 1) + }); + } + // add last page + options.pageList.push({ + disabled: options.pageCurrent === options.pageTotal - 1, + pageNumber: options.pageTotal - 1, + valueEncoded: 'last page' + }); + options.pageCurrentIsFirst = options.pageCurrent === 0; + options.pageCurrentIsLast = options.pageCurrent + 1 === options.pageTotal; + // templateRender datatable + document.querySelector('.swggUiContainer .datatable').innerHTML = + local.templateRender(local.templateUiDatatable, options); + // init event-handling + local.uiEventInit(document.querySelector('.swggUiContainer .datatable')); + // show modal + if (document.querySelector('.swggUiContainer > .modal').style.display !== 'none') { + return; + } + document.body.style.overflow = 'hidden'; + local.uiAnimateFadeIn(document.querySelector('.swggUiContainer > .modal')); + }; + + local.uiEventDelegate = function (event) { + Object.keys(local.uiEventListenerDict).sort().some(function (key) { + if (!(event.currentTarget.matches(key) || event.target.matches(key))) { + return; + } + switch (event.target.tagName) { + case 'A': + case 'BUTTON': + case 'FORM': + event.preventDefault(); + break; + } + event.stopPropagation(); + local.uiEventListenerDict[key](event); + return true; + }); + }; + + local.uiEventInit = function (element) { + /* + * this function will init event-handling for the dom-element + */ + ['Click', 'Submit'].forEach(function (eventType) { + Array.from( + element.querySelectorAll('.eventDelegate' + eventType) + ).forEach(function (element) { + element.addEventListener(eventType.toLowerCase(), local.uiEventDelegate); + }); + }); + }; + + local.uiEventListenerDict = {}; + + local.uiEventListenerDict['.onEventDatatableReload'] = function (event) { + /* + * this function will show the modal + */ + var options; + options = {}; + if (event) { + options.name = event.target.dataset.resourceName; + options.pageNumber = event.target.dataset.pageNumber; + } else { + options.name = local.uiState.datatable.name; + options.pageNumber = local.uiState.datatable.pageNumber; + options.queryLimit = local.uiState.datatable.queryLimit; + options.querySort = local.uiState.datatable.querySort; + options.queryWhere = local.uiState.datatable.queryWhere; + } + local.objectSetDefault( + options, + local.jsonCopy(local.uiState['x-swgg-datatableDict'][options.name]) + ); + options._idAlias = local.apiDict[options.crudRemoveOneById]._idAlias; + options._idField = local.apiDict[options.crudRemoveOneById]._idField; + local.objectSetDefault(options, { pageNumber: 0, queryLimit: 20 }); + options.querySkip = options.pageNumber * options.queryLimit; + options.paramDict = { + _queryLimit: options.queryLimit, + _querySkip: options.querySkip, + _querySort: options.querySort, + _queryWhere: options.queryWhere + }; + // request data + local.apiDict[options.crudGetManyByQuery]._ajax(options, function (error, options) { + // validate no error occurred + local.assert(!error, error); + local.uiDatatableRender(options); + // emit event uiDatatableRendered + document.dispatchEvent(new local.global.Event('uiDatatableRendered', { + bubbles: true, + cancelable: true + })); + }); + }; + + local.uiEventListenerDict['.onEventDatatableSelectedRemove'] = function () { + var onParallel; + onParallel = local.onParallel(local.uiEventListenerDict['.onEventDatatableReload']); + onParallel.counter += 1; + Array.from( + document.querySelectorAll('.swggUiContainer .datatable tr.selected') + ).forEach(function (element) { + onParallel.counter += 1; + // remove data + local.apiDict[ + local.uiState.datatable.crudRemoveOneById + ]._ajax(local.objectLiteralize({ + paramDict: { '$[]': [ + local.uiState.datatable._idField, + JSON.parse(decodeURIComponent(element.dataset.id)) + ] } + }), onParallel); + }); + onParallel(); + }; + + local.uiEventListenerDict['.onEventDatatableTrSelect'] = function (event) { + if (event.target.tagName !== 'INPUT') { + event.currentTarget.querySelector('input').checked = + !event.currentTarget.querySelector('input').checked; + } + Array.from( + event.currentTarget.closest('tr').querySelectorAll('input') + ).forEach(function (element) { + element.checked = event.currentTarget.querySelector('input').checked; + }); + if (event.currentTarget.querySelector('input').checked) { + event.currentTarget.closest('tr').classList.add('selected'); + } else { + event.currentTarget.closest('tr').classList.remove('selected'); + } + }; + + local.uiEventListenerDict['.onEventModalHide'] = function (event) { + /* + * this function will hide the modal + */ + if (event && !event.target.classList.contains('onEventModalHide')) { + return; + } + if (document.querySelector('.swggUiContainer > .modal').style.display === 'none') { + return; + } + document.body.style.overflow = ''; + // hide modeal + local.uiAnimateFadeOut(document.querySelector('.swggUiContainer > .modal')); + }; + + local.uiEventListenerDict['.onEventOperationAjax'] = function (event) { + /* + * this function will return submit the operation to the backend + */ + var options, tmp; + options = {}; + local.onNext(options, function (error, data) { + switch (options.modeNext) { + case 1: + options.api = local.apiDict[event.currentTarget.dataset._keyOperationId]; + options.domOperationContent = event.target.closest('.operation > .content'); + options.headers = {}; + options.paramDict = {}; + options.api.parameters.forEach(function (paramDef) { + local.tryCatchOnError(function () { + tmp = options.domOperationContent.querySelector( + '.paramDef[name=' + paramDef.name + '] > .td3' + ).children[0]; + switch (tmp.tagName) { + case 'INPUT': + // parse file + if (tmp.type === 'file') { + tmp = tmp.files && tmp.files[0]; + break; + } + tmp = tmp.value; + if (!tmp) { + return; + } + // parse string + if (paramDef.type !== 'string') { + tmp = JSON.parse(tmp); + } + break; + case 'SELECT': + tmp = Array.from(tmp.options) + .filter(function (element) { + return element.selected; + }) + .map(function (element) { + return JSON.parse(decodeURIComponent( + element.dataset.valueDecoded + )); + }); + if (!tmp.length || tmp[0] === '$swggUndefined') { + return; + } + if (paramDef.type !== 'array') { + tmp = tmp[0]; + } + break; + case 'TEXTAREA': + tmp = tmp.value; + if (!tmp) { + return; + } + // parse schema + if (paramDef.in === 'body') { + tmp = JSON.parse(tmp); + break; + } + // parse array + tmp = tmp.split('\n').map(function (element) { + return paramDef.items.type === 'string' + ? element + : JSON.parse(element); + }); + break; + } + options.paramDict[paramDef.name] = tmp; + }, function (error) { + options.errorValidate = error; + options.errorValidate.options = { key: paramDef.name }; + options.onNext(error); + }); + }); + options.api._ajax(options, options.onNext); + break; + default: + // remove previous error + Array.from( + options.domOperationContent.querySelectorAll('.paramDef .input') + ).forEach(function (element) { + element.classList.remove('error'); + }); + if (options.errorValidate) { + // shake input on Error + Array.from(options.domOperationContent.querySelectorAll( + '.paramDef[name=' + options.errorValidate.options.key + '] .input' + )).forEach(function (element) { + element.classList.add('error'); + local.uiAnimateShake(element.closest('span')); + }); + data = { + errorValidate: options.errorValidate, + responseText: error.message, + statusCode: 400 + }; + } + // init responseHeaders + data.responseHeaders = {}; + ( + (data.getAllResponseHeaders && data.getAllResponseHeaders()) || '' + ).replace( + (/.+/g), + function (item) { + item = item.split(':'); + data.responseHeaders[item[0].trim().toLowerCase()] = + item.slice(1).join(':').trim(); + } + ); + // init contentType + data.contentType = + String(data.responseHeaders['content-type']).split(';')[0]; + // init responseBody + switch (data.contentType.split('/')[0]) { + case 'audio': + case 'video': + data.responseBody = '<' + data.contentType.split('/')[0] + + ' controls>'; + break; + case 'image': + data.responseBody = ''; + break; + default: + data.responseBody = '
' + local.stringHtmlSafe(
+                            data.responseJson
+                                ? JSON.stringify(data.responseJson, null, 4)
+                                : data.responseText
+                        ) + '
'; + } + // init curl + local.tryCatchOnError(function () { + options.data = JSON.stringify(JSON.parse(options.data), null, 4); + }, local.nop); + data.curl = 'curl \\\n' + + '--request ' + options.api._method.toUpperCase() + ' \\\n' + + Object.keys(options.headers).map(function (key) { + return "--header '" + key + ': ' + options.headers[key] + "' \\\n"; + }).join('') + '--data-binary ' + (typeof options.data === 'string' + ? "'" + options.data.replace(/'/g, "'\"'\"'") + "'" + : '') + ' \\\n"' + options.url + '"'; + data.responseHeaders = data.getAllResponseHeaders && + data.getAllResponseHeaders().trim(); + // templateRender response + options.domOperationContent.querySelector( + '.responseAjax' + ).innerHTML = local.templateRender(local.templateUiResponseAjax, data); + break; + } + }); + options.modeNext = 0; + options.onNext(); + }; + + local.uiEventListenerDict['.onEventOperationDisplayShow'] = function (event) { + /* + * this function will toggle the display of the operation + */ + var tmp; + location.hash = '!/' + event.target.closest('.resource').id + '/' + + event.target.closest('.operation').id; + tmp = event.target.closest('.operation').querySelector('.operation > .content'); + tmp.closest('.resource').classList.remove('expanded'); + // show the operation, but hide all other operations + local.uiAnimateSlideAccordian( + tmp, + Array.from( + tmp.closest('.operationList').querySelectorAll('.operation > .content') + ) + ); + }; + + local.uiEventListenerDict['.onEventResourceDisplayAction'] = function (event) { + /* + * this function will toggle the display of the resource + */ + location.hash = '!/' + event.currentTarget.id; + event.target.className.split(' ').some(function (className) { + switch (className) { + // show the resource, but hide all other resources + case 'td1': + case 'td2': + case 'td3': + local.uiAnimateSlideAccordian( + event.currentTarget.querySelector('.operationList'), + Array.from(document.querySelectorAll('.swggUiContainer .operationList')) + ); + break; + } + switch (className) { + case 'td1': + case 'td2': + return true; + case 'td3': + // collapse all operations in the resource + if (event.currentTarget.classList.contains('expanded')) { + event.currentTarget.classList.remove('expanded'); + Array.from( + event.currentTarget.querySelectorAll('.operation > .content') + ).forEach(function (element) { + local.uiAnimateSlideUp(element); + }); + // expand all operations in the resource + } else { + event.currentTarget.classList.add('expanded'); + Array.from( + event.currentTarget.querySelectorAll('.operation > .content') + ).forEach(function (element) { + local.uiAnimateSlideDown(element); + }); + } + return true; + } + }); + }; + + local.uiEventListenerDict['.onEventUiReload'] = function () { + /* + * this function will reload the ui + */ + // reset ui + Array.from( + document.querySelectorAll('.swggUiContainer > .reset') + ).forEach(function (element) { + element.remove(); + }); + // normalize url + document.querySelector('.swggUiContainer > .header > .td2').value = + local.urlParse( + document.querySelector('.swggUiContainer > .header > .td2').value + .replace((/^\//), '') + ).href; + // display .swggAjaxProgressDiv + document.querySelector('.swggAjaxProgressDiv').textContent = + 'fetching resource list: ' + + document.querySelector('.swggUiContainer > .header > .td2').value + + '; Please wait.'; + document.querySelector('.swggAjaxProgressDiv').style.display = 'block'; + local.ajax({ + url: document.querySelector('.swggUiContainer > .header > .td2').value + }, function (error, xhr) { + // hide .swggAjaxProgressDiv + document.querySelector('.swggAjaxProgressDiv').style.display = 'none'; + // validate no error occurred + local.assert(!error, error); + // reset state + local.apiDict = local.swaggerJson = null; + local.apiDictUpdate(local.objectSetDefault(JSON.parse(xhr.responseText), { + host: local.urlParse( + document.querySelector('.swggUiContainer > .header > .td2').value + ).host + })); + local.uiRender(); + }); + }; + + local.uiParamRender = function (paramDef) { + /* + * this function will render the param + */ + paramDef.placeholder = paramDef.required + ? '(required)' + : ''; + // init input - file + if (paramDef.type === 'file') { + paramDef.isFile = true; + // init input - textarea + } else if (paramDef.in === 'body') { + paramDef.isTextarea = true; + // init input - select + } else if (paramDef.enum || paramDef.type === 'boolean') { + paramDef.enumDefault = []; + if (paramDef.default !== undefined) { + paramDef.enumDefault = paramDef.type === 'array' + ? paramDef.default + : [paramDef.default]; + } + paramDef.isSelect = true; + paramDef.isSelectMultiple = paramDef.type === 'array'; + paramDef.selectOptionList = (paramDef.type === 'boolean' + ? [false, true] + : paramDef.enum).map(function (element) { + paramDef.hasDefault |= paramDef.enumDefault.indexOf(element) >= 0; + return { + id: local.idDomElementCreate('swgg_id_' + paramDef.name), + selected: paramDef.enumDefault.indexOf(element) >= 0 + ? 'selected' + : '', + type: (paramDef.items && paramDef.items.type) || paramDef.type, + valueDecoded: element, + valueEncoded: typeof element === 'string' + ? element + : JSON.stringify(element) + }; + }); + // init 'undefined' value + if (!(paramDef.hasDefault || + paramDef.isSelectMultiple || + paramDef.required)) { + paramDef.selectOptionList.unshift({ + id: local.idDomElementCreate('swgg_id_' + paramDef.name), + selected: 'selected', + type: paramDef.type, + valueDecoded: '$swggUndefined', + valueEncoded: '' + }); + } + // if required, then select at least one value + if (paramDef.required && paramDef.selectOptionList.length) { + paramDef.selected = paramDef.selectOptionList[0]; + paramDef.selectOptionList.some(function (element) { + if (element.selected) { + paramDef.selected = element.selected; + return true; + } + }); + paramDef.selected = 'selected'; + } + // init input - textarea + } else if (paramDef.type === 'array') { + paramDef.isTextarea = true; + paramDef.placeholder = 'provide multiple values in new lines' + + (paramDef.required + ? ' (at least one required)' + : ''); + // init input - text + } else { + paramDef.isInputText = true; + } + // init format2 / type2 + [ + paramDef, + paramDef.schema + ].some(function (element) { + local.tryCatchOnError(function () { + paramDef.format2 = paramDef.format2 || element.format; + }, local.nop); + local.tryCatchOnError(function () { + paramDef.type2 = paramDef.type2 || element.type; + }, local.nop); + return paramDef.type2; + }); + paramDef.type2 = paramDef.type2 || 'object'; + // init schema2 + [ + paramDef.items, + paramDef.schema, + paramDef.schema && paramDef.schema.items + ].some(function (element) { + paramDef.schema2 = local.schemaNormalizeAndCopy(element || {}).properties; + return paramDef.schema2; + }); + if (paramDef.schema2) { + paramDef.schemaText = JSON.stringify(paramDef.type2 === 'array' + ? [paramDef.schema2] + : paramDef.schema2, null, 4); + } + // init valueEncoded + paramDef.valueEncoded = paramDef.default; + if (paramDef.valueEncoded === undefined) { + paramDef.valueEncoded = local.dbFieldRandomCreate({ + modeNotRandom: true, + propDef: paramDef + }); + } + // init valueEncoded for array + if (paramDef.valueEncoded && paramDef.type2 === 'array' && paramDef.in !== 'body') { + paramDef.valueEncoded = paramDef.valueEncoded.map(function (element) { + return typeof element === 'string' + ? element + : JSON.stringify(element); + }).join('\n'); + } + // init valueEncoded for schema + if (paramDef.in === 'body' && paramDef.schema2) { + paramDef.valueEncoded = local.dbRowRandomCreate({ + modeNotRandom: true, + override: function () { + var override = {}; + // preserve default value + Object.keys(paramDef.schema2).forEach(function (key) { + if (paramDef.schema2[key].default !== undefined) { + override[key] = paramDef.schema2[key].default; + } + }); + return override; + }, + properties: paramDef.schema2 + }); + if (paramDef.type2 === 'array') { + paramDef.valueEncoded = [paramDef.valueEncoded]; + } + paramDef.valueEncoded = JSON.stringify(paramDef.valueEncoded, null, 4); + } + if (typeof paramDef.valueEncoded !== 'string') { + paramDef.valueEncoded = JSON.stringify(paramDef.valueEncoded) || ''; + } + // templateRender paramDef + paramDef.innerHTML = local.templateRender(local.templateUiParam, paramDef); + }; + + local.uiRender = function () { + /* + * this function will render swagger-ui + */ + var resource, self; + // reset state + local.idDomElementDict = {}; + self = local.uiState = local.jsonCopy(local.swaggerJson); + // init url + self.url = document.querySelector('.swggUiContainer > .header > .td2').value; + // templateRender main + self.uiFragment = local.domFragmentRender(local.templateUiMain, self); + local.objectSetDefault(self, { + resourceDict: {}, + operationDict: {}, + tagDict: {} + }); + // init tagDict + self.tags.forEach(function (tag) { + self.tagDict[tag.name] = tag; + }); + // init operationDict + Object.keys(local.apiDict).sort().forEach(function (operation) { + // init operation + operation = local.jsonCopy(local.apiDict[operation]); + operation.tags.forEach(function (tag) { + self.operationDict[operation._keyOperationId] = operation; + // init resource + resource = self.resourceDict[tag]; + if (!resource && self.tagDict[tag]) { + resource = self.resourceDict[tag] = self.tagDict[tag]; + local.objectSetDefault(resource, { + description: 'no description available', + id: local.idDomElementCreate('swgg_id_' + tag), + name: tag, + operationListInnerHtml: '' + }); + } + }); + }); + // init resourceDict + Object.keys(self.resourceDict).sort().forEach(function (key) { + // templateRender resource + self.uiFragment.querySelector('.resourceList').appendChild( + local.domFragmentRender(local.templateUiResource, self.resourceDict[key]) + ); + }); + Object.keys(self.operationDict).sort(function (aa, bb) { + aa = self.operationDict[aa]; + aa = aa._path + ' ' + aa._method; + bb = self.operationDict[bb]; + bb = bb._path + ' ' + bb._method; + return aa < bb + ? -1 + : 1; + }).forEach(function (operation) { + operation = self.operationDict[operation]; + operation.id = local.idDomElementCreate('swgg_id_' + operation.operationId); + operation.tags.forEach(function (tag) { + operation = local.jsonCopy(operation); + resource = self.resourceDict[tag]; + local.objectSetDefault(operation, { + description: '', + responseList: Object.keys(operation.responses).sort() + .map(function (key) { + return { key: key, value: operation.responses[key] }; + }), + summary: 'no summary available' + }); + operation.parameters.forEach(function (element) { + // init element.id + element.id = local.idDomElementCreate('swgg_id_' + element.name); + local.uiParamRender(element); + }); + // templateRender operation + self.uiFragment.querySelector('#' + resource.id + ' .operationList') + .appendChild( + local.domFragmentRender(local.templateUiOperation, operation) + ); + }); + }); + // overwrite swggUiContainer with uiFragment + document.querySelector('.swggUiContainer').innerHTML = ''; + document.querySelector('.swggUiContainer').appendChild(self.uiFragment); + /* istanbul ignore next */ + // bug-workaround - add keypress listener for + document.querySelector('form2').addEventListener('keypress', function (event) { + if (event.keyCode === 13) { + local.uiEventListenerDict['.onEventUiReload'](); + } + }); + // render valueEncoded + Array.from( + document.querySelectorAll('.swggUiContainer [data-value-encoded]') + ).forEach(function (element) { + element.value = decodeURIComponent(element.dataset.valueEncoded); + }); + // init event-handling + local.uiEventInit(document); + // scrollTo location.hash + local.uiScrollTo(location.hash); + }; + + local.uiScrollTo = function (locationHash) { + /* + * this function will scrollTo locationHash + */ + var operation, resource; + // init resource + resource = locationHash.split('/')[1]; + // list operations + resource = document.querySelector('.swggUiContainer #' + resource) || + document.querySelector('.swggUiContainer .resource'); + local.uiAnimateSlideDown(resource.querySelector('.operationList')); + // init operation + operation = locationHash.split('/')[2]; + operation = resource.querySelector('#' + operation); + // expand operation and scroll to it + if (operation) { + local.uiAnimateSlideDown(operation.querySelector('.content')); + // scroll to operation + local.uiAnimateScrollTo(operation); + } else { + // scroll to resource + local.uiAnimateScrollTo(resource); + } + }; + + local.urlBaseGet = function () { + /* + * this function will return the base swagger url + */ + return (local.swaggerJson.schemes || + local.urlParse('').protocol.slice(0, -1)) + '://' + + (local.swaggerJson.host || local.urlParse('').host) + + local.swaggerJson.basePath; + }; + + local.userLoginByPassword = function (options, onError) { + /* + * this function will send a login-by-password request + */ + local.apiDict["GET /user/userLoginByPassword"]._ajax({ + paramDict: { password: options.password, username: options.username } + }, onError); + }; + + local.userLogout = function (options, onError) { + /* + * this function will send a logout request + */ + local.apiDict["GET /user/userLogout"]._ajax(options, onError); + }; + + local.utility2._middlewareError = function (error, request, response) { + /* + * this function will run the middleware that will + * handle errors according to http://jsonapi.org/format/#errors + */ + if (!error) { + error = new Error('404 Not Found'); + error.statusCode = 404; + } + local.serverRespondJsonapi(request, response, error); + }; + + local.utility2._stateInit = function (options) { + /* + * this function will init the state-options + */ + local.objectSetOverride(local, options, 10); + // init api + local.apiDictUpdate(local.swaggerJson); + }; + + local.validateByParamDefList = function (options) { + /* + * this function will validate options.data against options.paramDefList + */ + var data, key; + local.tryCatchOnError(function () { + data = options.data; + // validate data + local.assert(data && typeof data === 'object', data); + (options.paramDefList || []).forEach(function (paramDef) { + key = paramDef.name; + // recurse - validateByPropDef + local.validateByPropDef({ + circularList: options.circularList, + data: data[key], + dataReadonlyRemove: (options.dataReadonlyRemove || {})[key], + key: key, + schema: paramDef, + required: paramDef.required, + 'x-swgg-notRequired': paramDef['x-swgg-notRequired'] + }); + }); + }, function (error) { + error.statusCode = error.statusCode || 400; + local.errorMessagePrepend(error, options.key + '.' + key + ' -> '); + throw error; + }); + }; + + local.validateByPropDef = function (options) { + /* + * this function will validate options.data against options.schema + */ + var data, prefix, propDef, tmp; + local.tryCatchOnError(function () { + data = options.data; + prefix = 'property ' + options.key; + propDef = options.schema; + // validate undefined data + if (local.isNullOrUndefined(data)) { + if (options.required && !options['x-swgg-notRequired']) { + tmp = new Error(prefix + ' cannot be null or undefined'); + tmp.options = options; + throw tmp; + } + return; + } + // handle $ref + tmp = propDef.$ref || (propDef.schema && propDef.schema.$ref); + if (tmp) { + // recurse - validateBySchema + local.validateBySchema({ + circularList: options.circularList, + data: data, + dataReadonlyRemove: options.dataReadonlyRemove, + key: tmp, + schema: local.schemaNormalizeAndCopy({ $ref: tmp }), + 'x-swgg-notRequired': options['x-swgg-notRequired'] + }); + return; + } + // handle anyOf + if (propDef.anyOf) { + tmp = propDef.anyOf.some(function (element) { + local.tryCatchOnError(function () { + // recurse - validateBySchema + local.validateBySchema({ + circularList: options.circularList, + data: data, + key: 'anyOf', + schema: local.schemaNormalizeAndCopy(element), + 'x-swgg-notRequired': options['x-swgg-notRequired'] + }); + }, local.nop); + return !local.utility2._debugTryCatchErrorCaught; + }); + local.assert(tmp, local.utility2._debugTryCatchErrorCaught); + return; + } + // normalize propDef + propDef = local.schemaNormalizeAndCopy(options.schema); + // init circularList + if (data && typeof data === 'object') { + options.circularList = options.circularList || []; + if (options.circularList.indexOf(data) >= 0) { + return; + } + options.circularList.push(data); + } + // validate propDef embedded in propDef.schema.type + if (!propDef.type && propDef.schema && propDef.schema.type) { + propDef = propDef.schema; + } + // http://json-schema.org/latest/json-schema-validation.html#anchor13 + // 5.1. Validation keywords for numeric instances (number and integer) + if (typeof data === 'number') { + if (typeof propDef.multipleOf === 'number') { + local.assert( + data % propDef.multipleOf === 0, + prefix + ' must be a multiple of ' + propDef.multipleOf + ); + } + if (typeof propDef.maximum === 'number') { + local.assert( + propDef.exclusiveMaximum + ? data < propDef.maximum + : data <= propDef.maximum, + prefix + ' must be ' + (propDef.exclusiveMaximum + ? '< ' + : '<= ') + propDef.maximum + ); + } + if (typeof propDef.minimum === 'number') { + local.assert( + propDef.exclusiveMinimum + ? data > propDef.minimum + : data >= propDef.minimum, + prefix + ' must be ' + (propDef.exclusiveMinimum + ? '> ' + : '>= ') + propDef.minimum + ); + } + // http://json-schema.org/latest/json-schema-validation.html#anchor25 + // 5.2. Validation keywords for strings + } else if (typeof data === 'string') { + if (propDef.maxLength) { + local.assert( + data.length <= propDef.maxLength, + prefix + ' must have <= ' + propDef.maxLength + ' characters' + ); + } + if (propDef.minLength) { + local.assert( + data.length >= propDef.minLength, + prefix + ' must have >= ' + propDef.minLength + ' characters' + ); + } + if (propDef.pattern) { + local.assert( + new RegExp(propDef.pattern).test(data), + prefix + ' must match regex pattern /' + propDef.pattern + '/' + ); + } + // http://json-schema.org/latest/json-schema-validation.html#anchor36 + // 5.3. Validation keywords for arrays + } else if (Array.isArray(data)) { + if (propDef.maxItems) { + local.assert( + data.length <= propDef.maxItems, + prefix + ' must have <= ' + propDef.maxItems + ' items' + ); + } + if (propDef.minItems) { + local.assert( + data.length >= propDef.minItems, + prefix + ' must have >= ' + propDef.minItems + ' items' + ); + } + if (propDef.uniqueItems) { + tmp = {}; + data.forEach(function (element) { + element = JSON.stringify(element); + local.assert( + !tmp[element], + prefix + ' must have only unique items' + ); + tmp[element] = true; + }); + } + // http://json-schema.org/latest/json-schema-validation.html#anchor53 + // 5.4. Validation keywords for objects + } else if (typeof data === 'object') { + if (propDef.maxProperties) { + local.assert( + Object.keys(data).length <= propDef.maxProperties, + prefix + ' must have <= ' + propDef.maxProperties + ' items' + ); + } + if (propDef.minProperties) { + local.assert( + Object.keys(data).length >= propDef.minProperties, + prefix + ' must have >= ' + propDef.minProperties + ' items' + ); + } + } + // http://json-schema.org/latest/json-schema-validation.html#anchor75 + // 5.5. Validation keywords for any instance type + if (propDef.enum) { + (Array.isArray(data) + ? data + : [data]).forEach(function (element) { + local.assert( + propDef.enum.indexOf(element) >= 0, + prefix + ' must only have items in the list ' + + JSON.stringify(propDef.enum) + ); + }); + } + // https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md + // #data-types + // validate schema.type + switch (propDef.type) { + case 'array': + local.assert(Array.isArray(data) && propDef.items); + data.forEach(function (element, ii) { + // recurse - validateByPropDef + local.validateByPropDef({ + circularList: options.circularList, + data: element, + dataReadonlyRemove: (options.dataReadonlyRemove || {})[ii], + key: ii, + schema: propDef.items, + 'x-swgg-notRequired': options['x-swgg-notRequired'] + }); + }); + switch (propDef.collectionFormat) { + case 'multi': + local.assert( + propDef.in === 'formData' || propDef.in === 'query', + prefix + ' with collectionFormat "multi" ' + + 'is valid only for parameters in "query" or "formData"' + ); + break; + } + break; + case 'boolean': + local.assert(typeof data === 'boolean'); + break; + case 'file': + break; + case 'integer': + local.assert(typeof data === 'number' && + isFinite(data) && + Math.floor(data) === data); + switch (propDef.format) { + case 'int32': + case 'int64': + break; + } + break; + case 'number': + local.assert(typeof data === 'number' && isFinite(data)); + switch (propDef.format) { + case 'double': + case 'float': + break; + } + break; + case 'object': + local.assert(typeof data === 'object'); + break; + case 'string': + local.assert(typeof data === 'string' || propDef.format === 'binary'); + switch (propDef.format) { + // https://github.com/swagger-api/swagger-spec/issues/50 + // Clarify 'byte' format #50 + case 'byte': + local.assert(!(/[^\n\r\+\/0-9\=A-Za-z]/).test(data)); + break; + case 'date': + case 'date-time': + local.assert(JSON.stringify(new Date(data)) !== 'null'); + break; + case 'email': + local.assert(local.regexpEmailValidate.test(data)); + break; + case 'phone': + local.assert(local.regexpPhoneValidate.test(data)); + break; + case 'json': + JSON.parse(data); + break; + } + break; + default: + local.assert( + propDef.type === undefined, + prefix + ' has invalid type ' + propDef.type + ); + } + }, function (error) { + error.message = error.message || prefix + ' is not a valid ' + propDef.type + + (propDef.format + ? ' (' + propDef.format + ')' + : ''); + error.options = options; + throw error; + }); + }; + + local.validateBySchema = function (options) { + /* + * this function will validate options.data against options.schema + */ + var data, key, prefix, propDefDict, schema, tmp, validateByPropDef; + // recurse - validateByPropDef + local.validateByPropDef(options); + local.tryCatchOnError(function () { + data = options.data; + prefix = 'schema ' + options.key; + schema = options.schema; + // validate schema + local.assert( + schema && typeof schema === 'object', + prefix + ' must be an object (not ' + typeof schema + ')' + ); + // init propDefDict + propDefDict = schema.properties || {}; + // validate data + local.assert( + (data && typeof data === 'object') || !Object.keys(propDefDict).length, + 'data for ' + prefix + ' must be an object (not ' + typeof data + ')' + ); + if (typeof data !== 'object') { + return; + } + validateByPropDef = function (propDef) { + // remove options.dataReadonlyRemove[key] + if (propDef.readOnly && + (options.dataReadonlyRemove || {}).hasOwnProperty(key)) { + delete options.dataReadonlyRemove[key]; + } + // recurse - validateByPropDef + local.validateByPropDef({ + circularList: options.circularList, + data: data[key], + dataReadonlyRemove: (options.dataReadonlyRemove || {})[key], + key: key, + schema: propDef, + required: schema.required && schema.required.indexOf(key) >= 0, + 'x-swgg-notRequired': options['x-swgg-notRequired'] + }); + }; + Object.keys(propDefDict).forEach(function (_) { + key = _; + validateByPropDef(propDefDict[key]); + }); + Object.keys(data).forEach(function (_) { + key = _; + if (propDefDict[key]) { + return; + } + tmp = Object.keys(schema.patternProperties || {}).some(function (_) { + if (new RegExp(_).test(key)) { + validateByPropDef(schema.patternProperties[_]); + return true; + } + }); + if (tmp) { + return; + } + // https://tools.ietf.org/html/draft-fge-json-schema-validation-00 + // #section-5.4.4 + // validate additionalProperties + local.assert( + schema.additionalProperties !== false, + prefix + ' must not have additionalProperties - ' + key + ); + if (schema.additionalProperties) { + validateByPropDef(schema.additionalProperties); + } + }); + }, function (error) { + local.errorMessagePrepend(error, options.key + '.' + key + ' -> '); + throw error; + }); + }; + + local.validateBySwagger = function (options) { + /* + * this function will validate the entire swagger json object + */ + var key, schema, tmp, validateDefault; + local.validateBySchema({ + data: options, + key: 'swaggerJson', + schema: local.swaggerSchemaJson + }); + // validate default + validateDefault = function () { + if (schema.default !== undefined) { + return; + } + local.validateByPropDef({ + data: schema.default, + key: key + '.default', + schema: schema + }); + }; + Object.keys(options.definitions).forEach(function (schemaName) { + schema = options.definitions[schemaName]; + key = schemaName; + validateDefault(); + Object.keys(options.definitions[schemaName].properties || { + }).forEach(function (propName) { + schema = options.definitions[schemaName].properties[propName]; + key = schemaName + '.' + propName; + validateDefault(); + }); + }); + Object.keys(options.paths).forEach(function (pathName) { + Object.keys(options.paths[pathName]).forEach(function (methodName) { + tmp = options.paths[pathName][methodName]; + Object.keys(tmp.parameters).forEach(function (paramName) { + schema = tmp.parameters[paramName]; + key = tmp.tags[0] + '.' + tmp.operationId + '.' + paramName; + validateDefault(); + }); + }); + }); + }; + }()); + switch (local.modeJs) { + + + + // run browser js-env code - init-after + case 'browser': + // init state + local.utility2._stateInit({}); + break; + + + + // run node js-env code - init-after + case 'node': + // init assets.lib.rollup.js + local.assetsDict['/assets.swgg.rollup.js'] = + local.assetsDict['/assets.utility2.rollup.js']; + // init state + local.utility2._stateInit({}); + break; + } + switch (local.modeJs) { + + + + /* istanbul ignore next */ + // run node js-env code - cli + case 'node': + /* istanbul ignore next */ + if (local.env.SWAGGER_JSON_URL) { + if (local.env.SWAGGER_JSON_URL === '127.0.0.1') { + local.env.SWAGGER_JSON_URL = '/assets.swgg.petstore.json'; + } + local.assetsDict['/assets.swgg.html'] = + local.assetsDict['/assets.swgg.html'].replace( + 'assets.swgg.petstore.json', + local.env.SWAGGER_JSON_URL + ); + } + // run the cli + switch (process.argv[2]) { + case 'swagger-ui': + local.replStart(); + local.global.local = local; + local.assetsDict['/'] = local.assetsDict['/assets.swgg.html']; + local.testRunServer({}); + break; + } + break; + } +}()); +/* script-end /assets.swgg.js */ + + + +/* script-begin /assets.utility2.rollup.end.js */ +(function () { + "use strict"; + var local; + local = {}; + local.modeJs = (function () { + try { + return typeof navigator.userAgent === "string" && + typeof document.querySelector("body") === "object" && + typeof XMLHttpRequest.prototype.open === "function" && + "browser"; + } catch (errorCaughtBrowser) { + return module.exports && + typeof process.versions.node === "string" && + typeof require("http").createServer === "function" && + "node"; + } + }()); + local.global = local.modeJs === "browser" + ? window + : global; + local.global.utility2_rollup_old = local.global.utility2_rollup; + local.global.utility2_rollup = null; +}()); +/* utility2.rollup.js end */ +/* script-end /assets.utility2.rollup.end.js */ +/* script-end /assets.utility2.rollup.js */ + + + +/* script-begin /assets.utility2.rollup.begin.js */ +/* utility2.rollup.js begin */ +/* istanbul ignore all */ +/*jslint + bitwise: true, + browser: true, + maxerr: 8, + maxlen: 96, + node: true, + nomen: true, + regexp: true, + stupid: true +*/ +(function () { + "use strict"; + var local; + local = {}; + local.modeJs = (function () { + try { + return typeof navigator.userAgent === "string" && + typeof document.querySelector("body") === "object" && + typeof XMLHttpRequest.prototype.open === "function" && + "browser"; + } catch (errorCaughtBrowser) { + return module.exports && + typeof process.versions.node === "string" && + typeof require("http").createServer === "function" && + "node"; + } + }()); + local.global = local.modeJs === "browser" + ? window + : global; + local.local = local.global.utility2_rollup = local.global.utility2_rollup_old || local; +}()); +/* script-end /assets.utility2.rollup.begin.js */ + + + +/* script-begin local._stateInit */ +(function () { + "use strict"; + var local; + local = (typeof window === "object" && window && window.utility2_rollup) || + global.utility2_rollup; + local.local = local; +/* jslint-ignore-begin */ +local._stateInit({"utility2":{"assetsDict":{"/assets.index.template.html":"\n\n\n\n\n{{env.npm_package_name}} (v{{env.npm_package_version}})\n\n\n\n\n\n

\n\n {{env.npm_package_name}} (v{{env.npm_package_version}})\n\n

\n

{{env.npm_package_description}}

\n\n\n\n\n\n\n\n\n\n\n\n\n\n
\n [ this app was created with\n utility2\n ]\n
\n\n\n"},"env":{"NODE_ENV":"test","npm_package_description":"#### basic api documentation for [debowerify (v1.5.0)](https://github.com/eugeneware/debowerify#readme) [![npm package](https://img.shields.io/npm/v/npmdoc-debowerify.svg?style=flat-square)](https://www.npmjs.org/package/npmdoc-debowerify) [![travis-ci.org build-status](https://api.travis-ci.org/npmdoc/node-npmdoc-debowerify.svg)](https://travis-ci.org/npmdoc/node-npmdoc-debowerify)","npm_package_homepage":"https://github.com/npmdoc/node-npmdoc-debowerify","npm_package_name":"npmdoc-debowerify","npm_package_nameAlias":"npmdoc_debowerify","npm_package_version":"0.0.2"}}}); +/* jslint-ignore-end */ +}()); +/* script-end local._stateInit */ + + + +/* script-begin /assets.lib.js */ +/* istanbul instrument in package npmdoc_debowerify */ +/*jslint + bitwise: true, + browser: true, + maxerr: 8, + maxlen: 96, + node: true, + nomen: true, + regexp: true, + stupid: true +*/ +(function () { + 'use strict'; + var local; + + + + // run shared js-env code - init-before + (function () { + // init local + local = {}; + // init modeJs + local.modeJs = (function () { + try { + return typeof navigator.userAgent === 'string' && + typeof document.querySelector('body') === 'object' && + typeof XMLHttpRequest.prototype.open === 'function' && + 'browser'; + } catch (errorCaughtBrowser) { + return module.exports && + typeof process.versions.node === 'string' && + typeof require('http').createServer === 'function' && + 'node'; + } + }()); + // init global + local.global = local.modeJs === 'browser' + ? window + : global; + // init utility2_rollup + local = local.global.utility2_rollup || local; + // init lib + local.local = local.npmdoc_debowerify = local; + // init exports + if (local.modeJs === 'browser') { + local.global.utility2_npmdoc_debowerify = local; + } else { + module.exports = local; + module.exports.__dirname = __dirname; + module.exports.module = module; + } + }()); +}()); +/* script-end /assets.lib.js */ + + + +/* script-begin /assets.example.js */ +/* +example.js + +quickstart example + +instruction + 1. save this script as example.js + 2. run the shell command: + $ npm install npmdoc-debowerify && PORT=8081 node example.js + 3. play with the browser-demo on http://127.0.0.1:8081 +*/ + + + +/* istanbul instrument in package npmdoc_debowerify */ +/*jslint + bitwise: true, + browser: true, + maxerr: 8, + maxlen: 96, + node: true, + nomen: true, + regexp: true, + stupid: true +*/ +(function () { + 'use strict'; + var local; + + + + // run shared js-env code - init-before + (function () { + // init local + local = {}; + // init modeJs + local.modeJs = (function () { + try { + return typeof navigator.userAgent === 'string' && + typeof document.querySelector('body') === 'object' && + typeof XMLHttpRequest.prototype.open === 'function' && + 'browser'; + } catch (errorCaughtBrowser) { + return module.exports && + typeof process.versions.node === 'string' && + typeof require('http').createServer === 'function' && + 'node'; + } + }()); + // init global + local.global = local.modeJs === 'browser' + ? window + : global; + // init utility2_rollup + local = local.global.utility2_rollup || (local.modeJs === 'browser' + ? local.global.utility2_npmdoc_debowerify + : global.utility2_moduleExports); + // export local + local.global.local = local; + }()); + switch (local.modeJs) { + + + + // init-after + // run browser js-env code - init-after + /* istanbul ignore next */ + case 'browser': + local.testRunBrowser = function (event) { + if (!event || (event && + event.currentTarget && + event.currentTarget.className && + event.currentTarget.className.includes && + event.currentTarget.className.includes('onreset'))) { + // reset output + Array.from( + document.querySelectorAll('body > .resettable') + ).forEach(function (element) { + switch (element.tagName) { + case 'INPUT': + case 'TEXTAREA': + element.value = ''; + break; + default: + element.textContent = ''; + } + }); + } + switch (event && event.currentTarget && event.currentTarget.id) { + case 'testRunButton1': + // show tests + if (document.querySelector('#testReportDiv1').style.display === 'none') { + document.querySelector('#testReportDiv1').style.display = 'block'; + document.querySelector('#testRunButton1').textContent = + 'hide internal test'; + local.modeTest = true; + local.testRunDefault(local); + // hide tests + } else { + document.querySelector('#testReportDiv1').style.display = 'none'; + document.querySelector('#testRunButton1').textContent = 'run internal test'; + } + break; + // custom-case + default: + break; + } + if (document.querySelector('#inputTextareaEval1') && (!event || (event && + event.currentTarget && + event.currentTarget.className && + event.currentTarget.className.includes && + event.currentTarget.className.includes('oneval')))) { + // try to eval input-code + try { + /*jslint evil: true*/ + eval(document.querySelector('#inputTextareaEval1').value); + } catch (errorCaught) { + console.error(errorCaught); + } + } + }; + // log stderr and stdout to #outputTextareaStdout1 + ['error', 'log'].forEach(function (key) { + console[key + '_original'] = console[key]; + console[key] = function () { + var element; + console[key + '_original'].apply(console, arguments); + element = document.querySelector('#outputTextareaStdout1'); + if (!element) { + return; + } + // append text to #outputTextareaStdout1 + element.value += Array.from(arguments).map(function (arg) { + return typeof arg === 'string' + ? arg + : JSON.stringify(arg, null, 4); + }).join(' ') + '\n'; + // scroll textarea to bottom + element.scrollTop = element.scrollHeight; + }; + }); + // init event-handling + ['change', 'click', 'keyup'].forEach(function (event) { + Array.from(document.querySelectorAll('.on' + event)).forEach(function (element) { + element.addEventListener(event, local.testRunBrowser); + }); + }); + // run tests + local.testRunBrowser(); + break; + + + + // run node js-env code - init-after + /* istanbul ignore next */ + case 'node': + // export local + module.exports = local; + // require modules + local.fs = require('fs'); + local.http = require('http'); + local.url = require('url'); + // init assets + local.assetsDict = local.assetsDict || {}; + /* jslint-ignore-begin */ + local.assetsDict['/assets.index.template.html'] = '\ +\n\ +\n\ +\n\ +\n\ +\n\ +{{env.npm_package_name}} (v{{env.npm_package_version}})\n\ +\n\ +\n\ +\n\ +\n\ +\n\ +

\n\ +\n\ + {{env.npm_package_name}} (v{{env.npm_package_version}})\n\ +\n\ +

\n\ +

{{env.npm_package_description}}

\n\ +\n\ +\n\ +\n\ +\n\ +\n\ +\n\ +\n\ +\n\ +\n\ +\n\ +\n\ +\n\ +\n\ +
\n\ + [ this app was created with\n\ + utility2\n\ + ]\n\ +
\n\ +\n\ +\n\ +'; + /* jslint-ignore-end */ + if (local.templateRender) { + local.assetsDict['/'] = local.templateRender( + local.assetsDict['/assets.index.template.html'], + { + env: local.objectSetDefault(local.env, { + npm_package_description: 'the greatest app in the world!', + npm_package_name: 'my-app', + npm_package_nameAlias: 'my_app', + npm_package_version: '0.0.1' + }) + } + ); + } else { + local.assetsDict['/'] = local.assetsDict['/assets.index.template.html'] + .replace((/\{\{env\.(\w+?)\}\}/g), function (match0, match1) { + // jslint-hack + String(match0); + switch (match1) { + case 'npm_package_description': + return 'the greatest app in the world!'; + case 'npm_package_name': + return 'my-app'; + case 'npm_package_nameAlias': + return 'my_app'; + case 'npm_package_version': + return '0.0.1'; + } + }); + } + // run the cli + if (local.global.utility2_rollup || module !== require.main) { + break; + } + local.assetsDict['/assets.example.js'] = + local.assetsDict['/assets.example.js'] || + local.fs.readFileSync(__filename, 'utf8'); + // bug-workaround - long $npm_package_buildCustomOrg + /* jslint-ignore-begin */ + local.assetsDict['/assets.npmdoc_debowerify.rollup.js'] = + local.assetsDict['/assets.npmdoc_debowerify.rollup.js'] || + local.fs.readFileSync( + local.npmdoc_debowerify.__dirname + '/lib.npmdoc_debowerify.js', + 'utf8' + ).replace((/^#!/), '//'); + /* jslint-ignore-end */ + local.assetsDict['/favicon.ico'] = local.assetsDict['/favicon.ico'] || ''; + // if $npm_config_timeout_exit exists, + // then exit this process after $npm_config_timeout_exit ms + if (Number(process.env.npm_config_timeout_exit)) { + setTimeout(process.exit, Number(process.env.npm_config_timeout_exit)); + } + // start server + if (local.global.utility2_serverHttp1) { + break; + } + process.env.PORT = process.env.PORT || '8081'; + console.error('server starting on port ' + process.env.PORT); + local.http.createServer(function (request, response) { + request.urlParsed = local.url.parse(request.url); + if (local.assetsDict[request.urlParsed.pathname] !== undefined) { + response.end(local.assetsDict[request.urlParsed.pathname]); + return; + } + response.statusCode = 404; + response.end(); + }).listen(process.env.PORT); + break; + } +}()); +/* script-end /assets.example.js */ + + + +/* script-begin /assets.test.js */ +/* istanbul instrument in package npmdoc_debowerify */ +/*jslint + bitwise: true, + browser: true, + maxerr: 8, + maxlen: 96, + node: true, + nomen: true, + regexp: true, + stupid: true +*/ +(function () { + 'use strict'; + var local; + + + + // run shared js-env code - init-before + (function () { + // init local + local = {}; + // init modeJs + local.modeJs = (function () { + try { + return typeof navigator.userAgent === 'string' && + typeof document.querySelector('body') === 'object' && + typeof XMLHttpRequest.prototype.open === 'function' && + 'browser'; + } catch (errorCaughtBrowser) { + return module.exports && + typeof process.versions.node === 'string' && + typeof require('http').createServer === 'function' && + 'node'; + } + }()); + // init global + local.global = local.modeJs === 'browser' + ? window + : global; + switch (local.modeJs) { + // re-init local from window.local + case 'browser': + local = local.global.utility2.objectSetDefault( + local.global.utility2_rollup || local.global.local, + local.global.utility2 + ); + break; + // re-init local from example.js + case 'node': + local = (local.global.utility2_rollup || require('utility2')) + .requireReadme(); + break; + } + // export local + local.global.local = local; + }()); + + + + // run shared js-env code - function + (function () { + return; + }()); + switch (local.modeJs) { + + + + // run browser js-env code - function + case 'browser': + break; + + + + // run node js-env code - function + case 'node': + break; + } + + + + // run shared js-env code - init-after + (function () { + return; + }()); + switch (local.modeJs) { + + + + // run browser js-env code - init-after + case 'browser': + local.testCase_browser_nullCase = local.testCase_browser_nullCase || function ( + options, + onError + ) { + /* + * this function will test browsers's null-case handling-behavior-behavior + */ + onError(null, options); + }; + + // run tests + local.nop(local.modeTest && + document.querySelector('#testRunButton1') && + document.querySelector('#testRunButton1').click()); + break; + + + + // run node js-env code - init-after + /* istanbul ignore next */ + case 'node': + local.testCase_buildApidoc_default = local.testCase_buildApidoc_default || function ( + options, + onError + ) { + /* + * this function will test buildApidoc's default handling-behavior-behavior + */ + options = { modulePathList: module.paths }; + local.buildApidoc(options, onError); + }; + + local.testCase_buildApp_default = local.testCase_buildApp_default || function ( + options, + onError + ) { + /* + * this function will test buildApp's default handling-behavior-behavior + */ + local.testCase_buildReadme_default(options, local.onErrorThrow); + local.testCase_buildLib_default(options, local.onErrorThrow); + local.testCase_buildTest_default(options, local.onErrorThrow); + local.testCase_buildCustomOrg_default(options, local.onErrorThrow); + options = []; + local.buildApp(options, onError); + }; + + local.testCase_buildCustomOrg_default = local.testCase_buildCustomOrg_default || + function (options, onError) { + /* + * this function will test buildCustomOrg's default handling-behavior + */ + options = {}; + local.buildCustomOrg(options, onError); + }; + + local.testCase_buildLib_default = local.testCase_buildLib_default || function ( + options, + onError + ) { + /* + * this function will test buildLib's default handling-behavior + */ + options = {}; + local.buildLib(options, onError); + }; + + local.testCase_buildReadme_default = local.testCase_buildReadme_default || function ( + options, + onError + ) { + /* + * this function will test buildReadme's default handling-behavior-behavior + */ + options = {}; + local.buildReadme(options, onError); + }; + + local.testCase_buildTest_default = local.testCase_buildTest_default || function ( + options, + onError + ) { + /* + * this function will test buildTest's default handling-behavior + */ + options = {}; + local.buildTest(options, onError); + }; + + local.testCase_webpage_default = local.testCase_webpage_default || function ( + options, + onError + ) { + /* + * this function will test webpage's default handling-behavior + */ + options = { modeCoverageMerge: true, url: local.serverLocalHost + '?modeTest=1' }; + local.browserTest(options, onError); + }; + + // run test-server + local.testRunServer(local); + break; + } +}()); +/* script-end /assets.test.js */ + + + +/* script-begin /assets.utility2.rollup.end.js */ +(function () { + "use strict"; + var local; + local = {}; + local.modeJs = (function () { + try { + return typeof navigator.userAgent === "string" && + typeof document.querySelector("body") === "object" && + typeof XMLHttpRequest.prototype.open === "function" && + "browser"; + } catch (errorCaughtBrowser) { + return module.exports && + typeof process.versions.node === "string" && + typeof require("http").createServer === "function" && + "node"; + } + }()); + local.global = local.modeJs === "browser" + ? window + : global; + local.global.utility2_rollup_old = local.global.utility2_rollup; + local.global.utility2_rollup = null; +}()); +/* utility2.rollup.js end */ +/* script-end /assets.utility2.rollup.end.js */ diff --git a/build..alpha..travis-ci.org/app/assets.example.js b/build..alpha..travis-ci.org/app/assets.example.js new file mode 100644 index 0000000..43b2257 --- /dev/null +++ b/build..alpha..travis-ci.org/app/assets.example.js @@ -0,0 +1,326 @@ +/* +example.js + +quickstart example + +instruction + 1. save this script as example.js + 2. run the shell command: + $ npm install npmdoc-debowerify && PORT=8081 node example.js + 3. play with the browser-demo on http://127.0.0.1:8081 +*/ + + + +/* istanbul instrument in package npmdoc_debowerify */ +/*jslint + bitwise: true, + browser: true, + maxerr: 8, + maxlen: 96, + node: true, + nomen: true, + regexp: true, + stupid: true +*/ +(function () { + 'use strict'; + var local; + + + + // run shared js-env code - init-before + (function () { + // init local + local = {}; + // init modeJs + local.modeJs = (function () { + try { + return typeof navigator.userAgent === 'string' && + typeof document.querySelector('body') === 'object' && + typeof XMLHttpRequest.prototype.open === 'function' && + 'browser'; + } catch (errorCaughtBrowser) { + return module.exports && + typeof process.versions.node === 'string' && + typeof require('http').createServer === 'function' && + 'node'; + } + }()); + // init global + local.global = local.modeJs === 'browser' + ? window + : global; + // init utility2_rollup + local = local.global.utility2_rollup || (local.modeJs === 'browser' + ? local.global.utility2_npmdoc_debowerify + : global.utility2_moduleExports); + // export local + local.global.local = local; + }()); + switch (local.modeJs) { + + + + // init-after + // run browser js-env code - init-after + /* istanbul ignore next */ + case 'browser': + local.testRunBrowser = function (event) { + if (!event || (event && + event.currentTarget && + event.currentTarget.className && + event.currentTarget.className.includes && + event.currentTarget.className.includes('onreset'))) { + // reset output + Array.from( + document.querySelectorAll('body > .resettable') + ).forEach(function (element) { + switch (element.tagName) { + case 'INPUT': + case 'TEXTAREA': + element.value = ''; + break; + default: + element.textContent = ''; + } + }); + } + switch (event && event.currentTarget && event.currentTarget.id) { + case 'testRunButton1': + // show tests + if (document.querySelector('#testReportDiv1').style.display === 'none') { + document.querySelector('#testReportDiv1').style.display = 'block'; + document.querySelector('#testRunButton1').textContent = + 'hide internal test'; + local.modeTest = true; + local.testRunDefault(local); + // hide tests + } else { + document.querySelector('#testReportDiv1').style.display = 'none'; + document.querySelector('#testRunButton1').textContent = 'run internal test'; + } + break; + // custom-case + default: + break; + } + if (document.querySelector('#inputTextareaEval1') && (!event || (event && + event.currentTarget && + event.currentTarget.className && + event.currentTarget.className.includes && + event.currentTarget.className.includes('oneval')))) { + // try to eval input-code + try { + /*jslint evil: true*/ + eval(document.querySelector('#inputTextareaEval1').value); + } catch (errorCaught) { + console.error(errorCaught); + } + } + }; + // log stderr and stdout to #outputTextareaStdout1 + ['error', 'log'].forEach(function (key) { + console[key + '_original'] = console[key]; + console[key] = function () { + var element; + console[key + '_original'].apply(console, arguments); + element = document.querySelector('#outputTextareaStdout1'); + if (!element) { + return; + } + // append text to #outputTextareaStdout1 + element.value += Array.from(arguments).map(function (arg) { + return typeof arg === 'string' + ? arg + : JSON.stringify(arg, null, 4); + }).join(' ') + '\n'; + // scroll textarea to bottom + element.scrollTop = element.scrollHeight; + }; + }); + // init event-handling + ['change', 'click', 'keyup'].forEach(function (event) { + Array.from(document.querySelectorAll('.on' + event)).forEach(function (element) { + element.addEventListener(event, local.testRunBrowser); + }); + }); + // run tests + local.testRunBrowser(); + break; + + + + // run node js-env code - init-after + /* istanbul ignore next */ + case 'node': + // export local + module.exports = local; + // require modules + local.fs = require('fs'); + local.http = require('http'); + local.url = require('url'); + // init assets + local.assetsDict = local.assetsDict || {}; + /* jslint-ignore-begin */ + local.assetsDict['/assets.index.template.html'] = '\ +\n\ +\n\ +\n\ +\n\ +\n\ +{{env.npm_package_name}} (v{{env.npm_package_version}})\n\ +\n\ +\n\ +\n\ +\n\ +\n\ +

\n\ +\n\ + {{env.npm_package_name}} (v{{env.npm_package_version}})\n\ +\n\ +

\n\ +

{{env.npm_package_description}}

\n\ +\n\ +\n\ +\n\ +\n\ +\n\ +\n\ +\n\ +\n\ +\n\ +\n\ +\n\ +\n\ +\n\ +
\n\ + [ this app was created with\n\ + utility2\n\ + ]\n\ +
\n\ +\n\ +\n\ +'; + /* jslint-ignore-end */ + if (local.templateRender) { + local.assetsDict['/'] = local.templateRender( + local.assetsDict['/assets.index.template.html'], + { + env: local.objectSetDefault(local.env, { + npm_package_description: 'the greatest app in the world!', + npm_package_name: 'my-app', + npm_package_nameAlias: 'my_app', + npm_package_version: '0.0.1' + }) + } + ); + } else { + local.assetsDict['/'] = local.assetsDict['/assets.index.template.html'] + .replace((/\{\{env\.(\w+?)\}\}/g), function (match0, match1) { + // jslint-hack + String(match0); + switch (match1) { + case 'npm_package_description': + return 'the greatest app in the world!'; + case 'npm_package_name': + return 'my-app'; + case 'npm_package_nameAlias': + return 'my_app'; + case 'npm_package_version': + return '0.0.1'; + } + }); + } + // run the cli + if (local.global.utility2_rollup || module !== require.main) { + break; + } + local.assetsDict['/assets.example.js'] = + local.assetsDict['/assets.example.js'] || + local.fs.readFileSync(__filename, 'utf8'); + // bug-workaround - long $npm_package_buildCustomOrg + /* jslint-ignore-begin */ + local.assetsDict['/assets.npmdoc_debowerify.rollup.js'] = + local.assetsDict['/assets.npmdoc_debowerify.rollup.js'] || + local.fs.readFileSync( + local.npmdoc_debowerify.__dirname + '/lib.npmdoc_debowerify.js', + 'utf8' + ).replace((/^#!/), '//'); + /* jslint-ignore-end */ + local.assetsDict['/favicon.ico'] = local.assetsDict['/favicon.ico'] || ''; + // if $npm_config_timeout_exit exists, + // then exit this process after $npm_config_timeout_exit ms + if (Number(process.env.npm_config_timeout_exit)) { + setTimeout(process.exit, Number(process.env.npm_config_timeout_exit)); + } + // start server + if (local.global.utility2_serverHttp1) { + break; + } + process.env.PORT = process.env.PORT || '8081'; + console.error('server starting on port ' + process.env.PORT); + local.http.createServer(function (request, response) { + request.urlParsed = local.url.parse(request.url); + if (local.assetsDict[request.urlParsed.pathname] !== undefined) { + response.end(local.assetsDict[request.urlParsed.pathname]); + return; + } + response.statusCode = 404; + response.end(); + }).listen(process.env.PORT); + break; + } +}()); diff --git a/build..alpha..travis-ci.org/app/assets.npmdoc_debowerify.js b/build..alpha..travis-ci.org/app/assets.npmdoc_debowerify.js new file mode 100644 index 0000000..0a480c2 --- /dev/null +++ b/build..alpha..travis-ci.org/app/assets.npmdoc_debowerify.js @@ -0,0 +1,53 @@ +/* istanbul instrument in package npmdoc_debowerify */ +/*jslint + bitwise: true, + browser: true, + maxerr: 8, + maxlen: 96, + node: true, + nomen: true, + regexp: true, + stupid: true +*/ +(function () { + 'use strict'; + var local; + + + + // run shared js-env code - init-before + (function () { + // init local + local = {}; + // init modeJs + local.modeJs = (function () { + try { + return typeof navigator.userAgent === 'string' && + typeof document.querySelector('body') === 'object' && + typeof XMLHttpRequest.prototype.open === 'function' && + 'browser'; + } catch (errorCaughtBrowser) { + return module.exports && + typeof process.versions.node === 'string' && + typeof require('http').createServer === 'function' && + 'node'; + } + }()); + // init global + local.global = local.modeJs === 'browser' + ? window + : global; + // init utility2_rollup + local = local.global.utility2_rollup || local; + // init lib + local.local = local.npmdoc_debowerify = local; + // init exports + if (local.modeJs === 'browser') { + local.global.utility2_npmdoc_debowerify = local; + } else { + module.exports = local; + module.exports.__dirname = __dirname; + module.exports.module = module; + } + }()); +}()); diff --git a/build..alpha..travis-ci.org/app/assets.npmdoc_debowerify.rollup.js b/build..alpha..travis-ci.org/app/assets.npmdoc_debowerify.rollup.js new file mode 100644 index 0000000..0a480c2 --- /dev/null +++ b/build..alpha..travis-ci.org/app/assets.npmdoc_debowerify.rollup.js @@ -0,0 +1,53 @@ +/* istanbul instrument in package npmdoc_debowerify */ +/*jslint + bitwise: true, + browser: true, + maxerr: 8, + maxlen: 96, + node: true, + nomen: true, + regexp: true, + stupid: true +*/ +(function () { + 'use strict'; + var local; + + + + // run shared js-env code - init-before + (function () { + // init local + local = {}; + // init modeJs + local.modeJs = (function () { + try { + return typeof navigator.userAgent === 'string' && + typeof document.querySelector('body') === 'object' && + typeof XMLHttpRequest.prototype.open === 'function' && + 'browser'; + } catch (errorCaughtBrowser) { + return module.exports && + typeof process.versions.node === 'string' && + typeof require('http').createServer === 'function' && + 'node'; + } + }()); + // init global + local.global = local.modeJs === 'browser' + ? window + : global; + // init utility2_rollup + local = local.global.utility2_rollup || local; + // init lib + local.local = local.npmdoc_debowerify = local; + // init exports + if (local.modeJs === 'browser') { + local.global.utility2_npmdoc_debowerify = local; + } else { + module.exports = local; + module.exports.__dirname = __dirname; + module.exports.module = module; + } + }()); +}()); diff --git a/build..alpha..travis-ci.org/app/assets.test.js b/build..alpha..travis-ci.org/app/assets.test.js new file mode 100644 index 0000000..2d915cd --- /dev/null +++ b/build..alpha..travis-ci.org/app/assets.test.js @@ -0,0 +1,195 @@ +/* istanbul instrument in package npmdoc_debowerify */ +/*jslint + bitwise: true, + browser: true, + maxerr: 8, + maxlen: 96, + node: true, + nomen: true, + regexp: true, + stupid: true +*/ +(function () { + 'use strict'; + var local; + + + + // run shared js-env code - init-before + (function () { + // init local + local = {}; + // init modeJs + local.modeJs = (function () { + try { + return typeof navigator.userAgent === 'string' && + typeof document.querySelector('body') === 'object' && + typeof XMLHttpRequest.prototype.open === 'function' && + 'browser'; + } catch (errorCaughtBrowser) { + return module.exports && + typeof process.versions.node === 'string' && + typeof require('http').createServer === 'function' && + 'node'; + } + }()); + // init global + local.global = local.modeJs === 'browser' + ? window + : global; + switch (local.modeJs) { + // re-init local from window.local + case 'browser': + local = local.global.utility2.objectSetDefault( + local.global.utility2_rollup || local.global.local, + local.global.utility2 + ); + break; + // re-init local from example.js + case 'node': + local = (local.global.utility2_rollup || require('utility2')) + .requireReadme(); + break; + } + // export local + local.global.local = local; + }()); + + + + // run shared js-env code - function + (function () { + return; + }()); + switch (local.modeJs) { + + + + // run browser js-env code - function + case 'browser': + break; + + + + // run node js-env code - function + case 'node': + break; + } + + + + // run shared js-env code - init-after + (function () { + return; + }()); + switch (local.modeJs) { + + + + // run browser js-env code - init-after + case 'browser': + local.testCase_browser_nullCase = local.testCase_browser_nullCase || function ( + options, + onError + ) { + /* + * this function will test browsers's null-case handling-behavior-behavior + */ + onError(null, options); + }; + + // run tests + local.nop(local.modeTest && + document.querySelector('#testRunButton1') && + document.querySelector('#testRunButton1').click()); + break; + + + + // run node js-env code - init-after + /* istanbul ignore next */ + case 'node': + local.testCase_buildApidoc_default = local.testCase_buildApidoc_default || function ( + options, + onError + ) { + /* + * this function will test buildApidoc's default handling-behavior-behavior + */ + options = { modulePathList: module.paths }; + local.buildApidoc(options, onError); + }; + + local.testCase_buildApp_default = local.testCase_buildApp_default || function ( + options, + onError + ) { + /* + * this function will test buildApp's default handling-behavior-behavior + */ + local.testCase_buildReadme_default(options, local.onErrorThrow); + local.testCase_buildLib_default(options, local.onErrorThrow); + local.testCase_buildTest_default(options, local.onErrorThrow); + local.testCase_buildCustomOrg_default(options, local.onErrorThrow); + options = []; + local.buildApp(options, onError); + }; + + local.testCase_buildCustomOrg_default = local.testCase_buildCustomOrg_default || + function (options, onError) { + /* + * this function will test buildCustomOrg's default handling-behavior + */ + options = {}; + local.buildCustomOrg(options, onError); + }; + + local.testCase_buildLib_default = local.testCase_buildLib_default || function ( + options, + onError + ) { + /* + * this function will test buildLib's default handling-behavior + */ + options = {}; + local.buildLib(options, onError); + }; + + local.testCase_buildReadme_default = local.testCase_buildReadme_default || function ( + options, + onError + ) { + /* + * this function will test buildReadme's default handling-behavior-behavior + */ + options = {}; + local.buildReadme(options, onError); + }; + + local.testCase_buildTest_default = local.testCase_buildTest_default || function ( + options, + onError + ) { + /* + * this function will test buildTest's default handling-behavior + */ + options = {}; + local.buildTest(options, onError); + }; + + local.testCase_webpage_default = local.testCase_webpage_default || function ( + options, + onError + ) { + /* + * this function will test webpage's default handling-behavior + */ + options = { modeCoverageMerge: true, url: local.serverLocalHost + '?modeTest=1' }; + local.browserTest(options, onError); + }; + + // run test-server + local.testRunServer(local); + break; + } +}()); diff --git a/build..alpha..travis-ci.org/app/assets.utility2.rollup.js b/build..alpha..travis-ci.org/app/assets.utility2.rollup.js new file mode 100644 index 0000000..97ac6c5 --- /dev/null +++ b/build..alpha..travis-ci.org/app/assets.utility2.rollup.js @@ -0,0 +1,20036 @@ +/* this rollup was created with utility2 (https://github.com/kaizhu256/node-utility2) */ + + + +/* script-begin /assets.utility2.rollup.begin.js */ +/* utility2.rollup.js begin */ +/* istanbul ignore all */ +/*jslint + bitwise: true, + browser: true, + maxerr: 8, + maxlen: 96, + node: true, + nomen: true, + regexp: true, + stupid: true +*/ +(function () { + "use strict"; + var local; + local = {}; + local.modeJs = (function () { + try { + return typeof navigator.userAgent === "string" && + typeof document.querySelector("body") === "object" && + typeof XMLHttpRequest.prototype.open === "function" && + "browser"; + } catch (errorCaughtBrowser) { + return module.exports && + typeof process.versions.node === "string" && + typeof require("http").createServer === "function" && + "node"; + } + }()); + local.global = local.modeJs === "browser" + ? window + : global; + local.local = local.global.utility2_rollup = local.global.utility2_rollup_old || local; +}()); +/* script-end /assets.utility2.rollup.begin.js */ + + + +/* script-begin /assets.utility2.lib.apidoc.js */ +///usr/bin/env node +/* istanbul instrument in package apidoc */ +/*jslint + bitwise: true, + browser: true, + maxerr: 8, + maxlen: 96, + node: true, + nomen: true, + regexp: true, + stupid: true +*/ +(function () { + 'use strict'; + var local; + + + + // run shared js-env code - init-before + (function () { + // init local + local = {}; + // init modeJs + local.modeJs = (function () { + try { + return typeof navigator.userAgent === 'string' && + typeof document.querySelector('body') === 'object' && + typeof XMLHttpRequest.prototype.open === 'function' && + 'browser'; + } catch (errorCaughtBrowser) { + return module.exports && + typeof process.versions.node === 'string' && + typeof require('http').createServer === 'function' && + 'node'; + } + }()); + // init global + local.global = local.modeJs === 'browser' + ? window + : global; + // init utility2_rollup + local = local.global.utility2_rollup || local; + // init lib + local.local = local.apidoc = local; + // init exports + if (local.modeJs === 'browser') { + local.global.utility2_apidoc = local; + } else { + module.exports = local; + module.exports.__dirname = __dirname; + module.exports.module = module; + } + }()); + + + + // run shared js-env code - function-before + /* istanbul ignore next */ + (function () { + local.assert = function (passed, message) { + /* + * this function will throw the error message if passed is falsey + */ + var error; + if (passed) { + return; + } + error = message && message.message + // if message is an error-object, then leave it as is + ? message + : new Error(typeof message === 'string' + // if message is a string, then leave it as is + ? message + // else JSON.stringify message + : JSON.stringify(message)); + throw error; + }; + + local.moduleDirname = function (module, modulePathList) { + /* + * this function will search modulePathList for the module's __dirname + */ + var result, tmp; + // search process.cwd() + if (!module || module === '.' || module.indexOf('/') >= 0) { + return require('path').resolve(process.cwd(), module || ''); + } + // search modulePathList + ['node_modules'] + .concat(modulePathList) + .concat(require('module').globalPaths) + .concat([process.env.HOME + '/node_modules', '/usr/local/lib/node_modules']) + .some(function (modulePath) { + try { + tmp = require('path').resolve(process.cwd(), modulePath + '/' + module); + result = require('fs').statSync(tmp).isDirectory() && tmp; + return result; + } catch (ignore) { + } + }); + return result || ''; + }; + + local.nop = function () { + /* + * this function will do nothing + */ + return; + }; + + local.objectSetDefault = function (arg, defaults, depth) { + /* + * this function will recursively set defaults for undefined-items in the arg + */ + arg = arg || {}; + defaults = defaults || {}; + Object.keys(defaults).forEach(function (key) { + var arg2, defaults2; + arg2 = arg[key]; + // handle misbehaving getter + try { + defaults2 = defaults[key]; + } catch (ignore) { + } + if (defaults2 === undefined) { + return; + } + // init arg[key] to default value defaults[key] + if (!arg2) { + arg[key] = defaults2; + return; + } + // if arg2 and defaults2 are both non-null and non-array objects, + // then recurse with arg2 and defaults2 + if (depth > 1 && + // arg2 is a non-null and non-array object + arg2 && + typeof arg2 === 'object' && + !Array.isArray(arg2) && + // defaults2 is a non-null and non-array object + defaults2 && + typeof defaults2 === 'object' && + !Array.isArray(defaults2)) { + // recurse + local.objectSetDefault(arg2, defaults2, depth - 1); + } + }); + return arg; + }; + + local.stringHtmlSafe = function (text) { + /* + * this function will make the text html-safe + */ + // new RegExp('[' + '"&\'<>'.split('').sort().join('') + ']', 'g') + return text.replace((/["&'<>]/g), function (match0) { + return '&#x' + match0.charCodeAt(0).toString(16) + ';'; + }); + }; + + local.templateRender = function (template, dict) { + /* + * this function will render the template with the given dict + */ + var argList, getValue, match, renderPartial, rgx, value; + dict = dict || {}; + getValue = function (key) { + argList = key.split(' '); + value = dict; + // iteratively lookup nested values in the dict + argList[0].split('.').forEach(function (key) { + value = value && value[key]; + }); + return value; + }; + renderPartial = function (match0, helper, key, partial) { + switch (helper) { + case 'each': + value = getValue(key); + return Array.isArray(value) + ? value.map(function (dict) { + // recurse with partial + return local.templateRender(partial, dict); + }).join('') + : ''; + case 'if': + partial = partial.split('{{#unless ' + key + '}}'); + partial = getValue(key) + ? partial[0] + // handle 'unless' case + : partial.slice(1).join('{{#unless ' + key + '}}'); + // recurse with partial + return local.templateRender(partial, dict); + case 'unless': + return getValue(key) + ? '' + // recurse with partial + : local.templateRender(partial, dict); + default: + // recurse with partial + return match0[0] + local.templateRender(match0.slice(1), dict); + } + }; + // render partials + rgx = (/\{\{#(\w+) ([^}]+?)\}\}/g); + template = template || ''; + for (match = rgx.exec(template); match; match = rgx.exec(template)) { + rgx.lastIndex += 1 - match[0].length; + template = template.replace( + new RegExp('\\{\\{#(' + match[1] + ') (' + match[2] + + ')\\}\\}([\\S\\s]*?)\\{\\{/' + match[1] + ' ' + match[2] + + '\\}\\}'), + renderPartial + ); + } + // search for keys in the template + return template.replace((/\{\{[^}]+?\}\}/g), function (match0) { + getValue(match0.slice(2, -2)); + if (value === undefined) { + return match0; + } + argList.slice(1).forEach(function (arg) { + switch (arg) { + case 'alphanumeric': + value = value.replace((/\W/g), '_'); + break; + case 'decodeURIComponent': + value = decodeURIComponent(value); + break; + case 'encodeURIComponent': + value = encodeURIComponent(value); + break; + case 'htmlSafe': + value = value.replace((/["&'<>]/g), function (match0) { + return '&#x' + match0.charCodeAt(0).toString(16) + ';'; + }); + break; + case 'jsonStringify': + value = JSON.stringify(value); + break; + case 'jsonStringify4': + value = JSON.stringify(value, null, 4); + break; + case 'markdownCodeSafe': + value = value.replace((/`/g), '\''); + break; + default: + value = value[arg](); + break; + } + }); + return String(value); + }); + }; + + local.tryCatchOnError = function (fnc, onError) { + /* + * this function will try to run the fnc in a try-catch block, + * else call onError with the errorCaught + */ + // validate onError + local.assert(typeof onError === 'function', typeof onError); + try { + // reset errorCaught + local._debugTryCatchErrorCaught = null; + return fnc(); + } catch (errorCaught) { + // debug errorCaught + local._debugTryCatchErrorCaught = errorCaught; + return onError(errorCaught); + } + }; + }()); + + + + // run shared js-env code - init-before +/* jslint-ignore-begin */ +local.templateApidocHtml = '\ +
\n\ +\n\ +

api documentation for\n\ + {{env.npm_package_name}} (v{{env.npm_package_version}})\n\ +

\n\ +

{{env.npm_package_description}}

\n\ +

table of contents

    \n\ + {{#each moduleList}}\n\ +
  1. module {{name}}
      \n\ + {{#each elementList}}\n\ +
    1. \n\ + {{#if source}}\n\ + \n\ + {{name}}\n\ + {{signature}}\n\ + \n\ + {{#unless source}}\n\ + {{name}}\n\ + {{/if source}}\n\ +
    2. \n\ + {{/each elementList}}\n\ +
  2. \n\ + {{/each moduleList}}\n\ +
\n\ +{{#each moduleList}}\n\ +
\n\ +

module {{name}}

\n\ + {{#each elementList}}\n\ + {{#if source}}\n\ +

\n\ + \n\ + {{name}}\n\ + {{signature}}\n\ + \n\ +

\n\ +
    \n\ +
  • description and source-code
    {{source}}
  • \n\ +
  • example usage
    {{example}}
  • \n\ +
\n\ + {{/if source}}\n\ + {{/each elementList}}\n\ +
\n\ +{{/each moduleList}}\n\ +
\n\ + [ this document was created with\n\ + utility2\n\ + ]\n\ +
\n\ +
\n\ +'; +/* jslint-ignore-end */ + + + + // run shared js-env code - function + (function () { + local.apidocCreate = function (options) { + /* + * this function will create the apidoc from options.dir + */ + var elementCreate, module, moduleMain, readExample, tmp, toString, trimLeft; + elementCreate = function (module, prefix, key) { + /* + * this function will create the apidoc-element in the given module + */ + var element; + if (options.modeNoApidoc) { + return element; + } + element = {}; + element.moduleName = prefix.split('.'); + // handle case where module is a function + if (element.moduleName.slice(-1)[0] === key) { + element.moduleName.pop(); + } + element.moduleName = element.moduleName.join('.'); + element.id = encodeURIComponent('apidoc.element.' + prefix + '.' + key); + element.typeof = typeof module[key]; + element.name = (element.typeof + ' ' + + element.moduleName + '.' + key) + // handle case where module is a function + .replace('>.<', '><'); + if (element.typeof !== 'function') { + return element; + } + // init source + element.source = trimLeft(toString(module[key])) || 'n/a'; + if (element.source.length > 4096) { + element.source = element.source.slice(0, 4096).trimRight() + ' ...'; + } + element.source = local.stringHtmlSafe(element.source) + .replace((/\([\S\s]*?\)/), function (match0) { + // init signature + element.signature = match0 + .replace((/ *?\/\*[\S\s]*?\*\/ */g), '') + .replace((/,/g), ', ') + .replace((/\s+/g), ' '); + return element.signature; + }) + .replace( + (/( *?\/\*[\S\s]*?\*\/\n)/), + '$1' + ) + .replace((/^function \(/), key + ' = function ('); + // init example + options.exampleList.some(function (example) { + example.replace( + new RegExp('((?:\n.*?){8}\\.)(' + key + ')(\\((?:.*?\n){8})'), + function (match0, match1, match2, match3) { + // jslint-hack + local.nop(match0); + element.example = '...' + trimLeft(local.stringHtmlSafe(match1) + + '' + + local.stringHtmlSafe(match2) + + '' + + local.stringHtmlSafe(match3)).trimRight() + '\n...'; + } + ); + return element.example; + }); + element.example = element.example || 'n/a'; + return element; + }; + readExample = function (file) { + /* + * this function will read the example from the given file + */ + var result; + local.tryCatchOnError(function () { + file = local.path.resolve(options.dir, file); + console.error('apidocCreate - readExample - ' + file); + result = ''; + result = ('\n\n\n\n\n\n\n\n' + + local.fs.readFileSync(file, 'utf8').slice(0, 262144) + + '\n\n\n\n\n\n\n\n').replace((/\r\n*/g), '\n'); + }, console.error); + return result; + }; + toString = function (value) { + /* + * this function will try to return the string form of the value + */ + var result; + local.tryCatchOnError(function () { + result = ''; + result = String(value); + }, console.error); + return result; + }; + trimLeft = function (text) { + /* + * this function will normalize the whitespace around the text + */ + var whitespace; + whitespace = ''; + text.trim().replace((/^ */gm), function (match0) { + if (!whitespace || match0.length < whitespace.length) { + whitespace = match0; + } + }); + text = text.replace(new RegExp('^' + whitespace, 'gm'), ''); + // enforce 128 character column limit + text = text.replace((/^.{128}[^\\\n]+/gm), function (match0) { + return match0.replace((/(.{128}(?:\b|\w+))/g), '$1\n').trimRight(); + }); + return text; + }; + // init options + options.dir = local.moduleDirname( + options.dir, + options.modulePathList || local.module.paths + ); + local.objectSetDefault(options, { + env: { npm_package_description: '' }, + packageJson: JSON.parse(readExample('package.json')), + require: function (file) { + return local.tryCatchOnError(function () { + return require(file); + }, console.error); + } + }); + Object.keys(options.packageJson).forEach(function (key) { + tmp = options.packageJson[key]; + // strip email from npmdoc documentation + // https://github.com/npmdoc/node-npmdoc-hpp/issues/1 + if (tmp) { + if (tmp.email) { + delete tmp.email; + } + if (Array.isArray(tmp)) { + tmp.forEach(function (element) { + if (element && element.email) { + delete element.email; + } + }); + } + } + if (key[0] === '_' || key === 'readme') { + delete options.packageJson[key]; + } else if (typeof tmp === 'string') { + options.env['npm_package_' + key] = tmp; + } + }); + local.objectSetDefault(options, { + blacklistDict: { global: global }, + circularList: [global], + exampleDict: {}, + exampleList: [], + html: '', + libFileList: [], + moduleDict: {}, + moduleExtraDict: {}, + packageJson: { bin: {} }, + template: local.templateApidocHtml + }, 2); + // init exampleList + [1, 2, 3, 4].forEach(function (depth) { + options.exampleList = options.exampleList.concat( + // http://stackoverflow.com + // /questions/4509624/how-to-limit-depth-for-recursive-file-list + // find . -maxdepth 1 -mindepth 1 -name "*.js" -type f + local.child_process.execSync('find "' + options.dir + + '" -maxdepth ' + depth + ' -mindepth ' + depth + + ' -type f | sed -e "s|' + options.dir + + '/||" | grep -iv ' + +/* jslint-ignore-begin */ +'"\ +/\\.\\|\\(\\b\\|_\\)\\(\ +bower_component\\|\ +coverage\\|\ +git\\|\ +min\\|\ +node_module\\|\ +rollup\\|\ +tmp\\|\ +vendor\\)s\\{0,1\\}\\(\\b\\|_\\)\ +" ' + +/* jslint-ignore-end */ + ' | sort | head -n 256').toString() + .split('\n') + ); + }); + options.exampleList = options.exampleList.filter(function (file) { + if (!options.exampleDict[file]) { + options.exampleDict[file] = true; + return true; + } + }).slice(0, 256).map(readExample); + // init moduleMain + local.tryCatchOnError(function () { + console.error('apidocCreate - requiring ' + options.dir + ' ...'); + moduleMain = {}; + moduleMain = options.moduleDict[options.env.npm_package_name] || + options.require(options.dir) || + options.require(options.dir + '/' + (options.packageJson.bin)[ + Object.keys(options.packageJson.bin)[0] + ]) || {}; + console.error('apidocCreate - ... required ' + options.dir); + }, console.error); + tmp = {}; + // handle case where module is a function + if (typeof moduleMain === 'function') { + (function () { + var text; + text = toString(moduleMain); + tmp = function () { + return; + }; + // coverage-hack + tmp(); + Object.defineProperties(tmp, { toString: { get: function () { + return function () { + return text; + }; + } } }); + }()); + } + // normalize moduleMain + moduleMain = options.moduleDict[options.env.npm_package_name] = + local.objectSetDefault(tmp, moduleMain); + // init circularList - builtin + Object.keys(process.binding('natives')).forEach(function (key) { + if (!(/\/|_linklist|sys/).test(key)) { + options.blacklistDict[key] = options.blacklistDict[key] || require(key); + } + }); + // init circularList - blacklistDict + Object.keys(options.blacklistDict).forEach(function (key) { + options.circularList.push(options.blacklistDict[key]); + }); + // init circularList - moduleDict + Object.keys(options.moduleDict).forEach(function (key) { + options.circularList.push(options.moduleDict[key]); + }); + // init circularList - prototype + Object.keys(options.circularList).forEach(function (key) { + tmp = options.circularList[key]; + options.circularList.push(tmp && tmp.prototype); + }); + // deduplicate circularList + tmp = options.circularList; + options.circularList = []; + tmp.forEach(function (element) { + if (options.circularList.indexOf(element) < 0) { + options.circularList.push(element); + } + }); + // init moduleDict child + local.apidocModuleDictAdd(options, options.moduleDict); + // init moduleExtraDict + module = options.moduleExtraDict[options.env.npm_package_name] = + options.moduleExtraDict[options.env.npm_package_name] || {}; + [1, 2, 3, 4].forEach(function (depth) { + options.libFileList = options.libFileList.concat( + // http://stackoverflow.com + // /questions/4509624/how-to-limit-depth-for-recursive-file-list + // find . -maxdepth 1 -mindepth 1 -name "*.js" -type f + local.child_process.execSync('find "' + options.dir + + '" -maxdepth ' + depth + ' -mindepth ' + depth + + ' -name "*.js" -type f | sed -e "s|' + options.dir + + '/||" | grep -iv ' + +/* jslint-ignore-begin */ +'"\ +/\\.\\|\\(\\b\\|_\\)\\(\ +archive\\|artifact\\|asset\\|\ +bower_component\\|build\\|\ +coverage\\|\ +doc\\|dist\\|\ +example\\|external\\|\ +fixture\\|\ +git\\|\ +log\\|\ +min\\|mock\\|\ +node_module\\|\ +rollup\\|\ +spec\\|\ +test\\|tmp\\|\ +vendor\\)s\\{0,1\\}\\(\\b\\|_\\)\ +" ' + +/* jslint-ignore-end */ + ' | sort | head -n 256').toString() + .split('\n') + ); + }); + options.ii = 256; + options.libFileList.every(function (file) { + local.tryCatchOnError(function () { + tmp = {}; + tmp.name = local.path.basename(file) + .replace('lib.', '') + .replace((/\.[^.]*?$/), '') + .replace((/\W/g), '_'); + [ + tmp.name, + tmp.name.slice(0, 1).toUpperCase() + tmp.name.slice(1) + ].some(function (name) { + tmp.isFiltered = name && (!options.packageJson.main || + ('./' + file).indexOf(options.packageJson.main) < 0) && + !module[name]; + return !tmp.isFiltered; + }); + if (!tmp.isFiltered) { + return; + } + console.error('apidocCreate - libFile - ' + file); + tmp.module = options.require(options.dir + '/' + file); + if (!(tmp.module && options.circularList.indexOf(tmp.module) < 0)) { + return; + } + options.ii -= 1; + module[tmp.name] = tmp.module; + }, console.error); + return options.ii; + }); + local.apidocModuleDictAdd(options, options.moduleExtraDict); + Object.keys(options.moduleDict).forEach(function (key) { + if (key.indexOf(options.env.npm_package_name + '.') !== 0) { + return; + } + tmp = key.split('.').slice(1).join('.'); + moduleMain[tmp] = moduleMain[tmp] || options.moduleDict[key]; + }); + // init moduleList + options.moduleList = Object.keys(options.moduleDict) + .sort() + .map(function (prefix) { + module = options.moduleDict[prefix]; + // handle case where module is a function + if (typeof module === 'function') { + local.tryCatchOnError(function () { + module[prefix.split('.').slice(-1)[0]] = + module[prefix.split('.').slice(-1)[0]] || module; + }, console.error); + } + return { + elementList: Object.keys(module) + .filter(function (key) { + return local.tryCatchOnError(function () { + return key && + (/^\w[\w\-.]*?$/).test(key) && + key.indexOf('testCase_') !== 0 && + module[key] !== options.blacklistDict[key]; + }, console.error); + }) + .map(function (key) { + return elementCreate(module, prefix, key); + }) + .sort(function (aa, bb) { + return aa.name > bb.name + ? 1 + : -1; + }), + id: encodeURIComponent('apidoc.module.' + prefix), + name: prefix + }; + }); + // render apidoc + options.result = local.templateRender(options.template, options) + .trim() + .replace((/ +$/gm), '') + '\n'; + return options.result; + }; + + local.apidocModuleDictAdd = function (options, moduleDict) { + /* + * this function will add the modules in moduleDict to options.moduleDict + */ + var isModule, tmp; + ['child', 'prototype', 'grandchild', 'prototype'].forEach(function (element) { + Object.keys(moduleDict).sort().forEach(function (prefix) { + if (!(/^\w[\w\-.]*?$/).test(prefix)) { + return; + } + Object.keys(moduleDict[prefix]).forEach(function (key) { + // bug-workaround - buggy electron getter / setter + local.tryCatchOnError(function () { + if (!(/^\w[\w\-.]*?$/).test(key) || !moduleDict[prefix][key]) { + return; + } + tmp = element === 'prototype' + ? { + module: moduleDict[prefix][key].prototype, + name: prefix + '.' + key + '.prototype' + } + : { + module: moduleDict[prefix][key], + name: prefix + '.' + key + }; + if (!tmp.module || + !(typeof tmp.module === 'function' || + typeof tmp.module === 'object') || + options.moduleDict[tmp.name] || + options.circularList.indexOf(tmp.module) >= 0) { + return; + } + isModule = [ + tmp.module, + tmp.module.prototype + ].some(function (dict) { + return Object.keys(dict || {}).some(function (key) { + // bug-workaround - buggy electron getter / setter + return local.tryCatchOnError(function () { + return typeof dict[key] === 'function'; + }, console.error); + }); + }); + if (!isModule) { + return; + } + options.circularList.push(tmp.module); + options.moduleDict[tmp.name] = tmp.module; + }, console.error); + }); + }); + }); + }; + }()); + switch (local.modeJs) { + + + + // run node js-env code - init-after + /* istanbul ignore next */ + case 'node': + // require modules + local.child_process = require('child_process'); + local.fs = require('fs'); + local.path = require('path'); + // run the cli + if (module !== require.main || local.global.utility2_rollup) { + break; + } + // jslint files + process.stdout.write(local.apidocCreate({ + dir: process.argv[2], + modulePathList: module.paths + })); + break; + } +}()); +/* script-end /assets.utility2.lib.apidoc.js */ + + + +/* script-begin /assets.utility2.lib.db.js */ +/* + * assets.db-lite.js + * + * this zero-dependency package will provide a persistent, in-browser database + * + * browser example: + * + * + * + * node example: + * var db, dbTable1; + * utility2_db = require("./assets.db-lite.js"); + * dbTable1 = global.dbTable1 = utility2_db.dbTableCreateOne({ name: "dbTable1" }); + * dbTable1.idIndexCreate({ name: "field1" }); + * dbTable1.crudSetOneById({ field1: "hello", field2: "world" }); + * console.log(dbTable1.crudGetManyByQuery({ + * limit: Infinity, + * query: { field1: "hello" }, + * skip: 0, + * sort: [{ fieldName: 'field1', isDescending: false }] + * })); + */ + + + +/* istanbul instrument in package db */ +/*jslint + bitwise: true, + browser: true, + maxerr: 8, + maxlen: 96, + node: true, + nomen: true, + regexp: true, + stupid: true +*/ +(function () { + 'use strict'; + var local; + + + + // run shared js-env code - init-before + (function () { + // init local + local = {}; + // init modeJs + local.modeJs = (function () { + try { + return typeof navigator.userAgent === 'string' && + typeof document.querySelector('body') === 'object' && + typeof XMLHttpRequest.prototype.open === 'function' && + 'browser'; + } catch (errorCaughtBrowser) { + return module.exports && + typeof process.versions.node === 'string' && + typeof require('http').createServer === 'function' && + 'node'; + } + }()); + // init global + local.global = local.modeJs === 'browser' + ? window + : global; + // init utility2_rollup + local = local.global.utility2_rollup || local; + // init lib + local.local = local.db = local; + // init exports + if (local.modeJs === 'browser') { + local.global.utility2_db = local; + } else { + module.exports = local; + module.exports.__dirname = __dirname; + module.exports.module = module; + } + }()); + + + + /* istanbul ignore next */ + // run shared js-env code - function-before + (function () { + local.jsonCopy = function (arg) { + /* + * this function will return a deep-copy of the JSON-arg + */ + return arg === undefined + ? undefined + : JSON.parse(JSON.stringify(arg)); + }; + + local.jsonStringifyOrdered = function (element, replacer, space) { + /* + * this function will JSON.stringify the element, + * with object-keys sorted and circular-references removed + */ + var circularList, stringify, tmp; + stringify = function (element) { + /* + * this function will recursively JSON.stringify the element, + * with object-keys sorted and circular-references removed + */ + // if element is an object, then recurse its items with object-keys sorted + if (element && + typeof element === 'object' && + typeof element.toJSON !== 'function') { + // ignore circular-reference + if (circularList.indexOf(element) >= 0) { + return; + } + circularList.push(element); + // if element is an array, then recurse its elements + if (Array.isArray(element)) { + return '[' + element.map(function (element) { + // recurse + tmp = stringify(element); + return typeof tmp === 'string' + ? tmp + : 'null'; + }).join(',') + ']'; + } + return '{' + Object.keys(element) + // sort object-keys + .sort() + .map(function (key) { + // recurse + tmp = stringify(element[key]); + if (typeof tmp === 'string') { + return JSON.stringify(key) + ':' + tmp; + } + }) + .filter(function (element) { + return typeof element === 'string'; + }) + .join(',') + '}'; + } + // else JSON.stringify as normal + return JSON.stringify(element); + }; + circularList = []; + return JSON.stringify(element && typeof element === 'object' + // recurse + ? JSON.parse(stringify(element)) + : element, replacer, space); + }; + + local.listShuffle = function (list) { + /* + * https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle + * this function will inplace shuffle the list, via fisher-yates algorithm + */ + var ii, random, swap; + for (ii = list.length - 1; ii > 0; ii -= 1) { + // coerce to finite integer + random = (Math.random() * (ii + 1)) | 0; + swap = list[ii]; + list[ii] = list[random]; + list[random] = swap; + } + return list; + }; + + local.nop = function () { + /* + * this function will do nothing + */ + return; + }; + + local.normalizeDict = function (dict) { + /* + * this function will normalize the dict + */ + return dict && typeof dict === 'object' && !Array.isArray(dict) + ? dict + : {}; + }; + + local.normalizeList = function (list) { + /* + * this function will normalize the list + */ + return Array.isArray(list) + ? list + : []; + }; + + local.objectSetOverride = function (arg, overrides, depth, env) { + /* + * this function will recursively set overrides for items in the arg + */ + arg = arg || {}; + env = env || (typeof process === 'object' && process.env) || {}; + overrides = overrides || {}; + Object.keys(overrides).forEach(function (key) { + var arg2, overrides2; + arg2 = arg[key]; + overrides2 = overrides[key]; + if (overrides2 === undefined) { + return; + } + // if both arg2 and overrides2 are non-null and non-array objects, + // then recurse with arg2 and overrides2 + if (depth > 1 && + // arg2 is a non-null and non-array object + (arg2 && + typeof arg2 === 'object' && + !Array.isArray(arg2)) && + // overrides2 is a non-null and non-array object + (overrides2 && + typeof overrides2 === 'object' && + !Array.isArray(overrides2))) { + local.objectSetOverride(arg2, overrides2, depth - 1, env); + return; + } + // else set arg[key] with overrides[key] + arg[key] = arg === env + // if arg is env, then overrides falsey value with empty string + ? overrides2 || '' + : overrides2; + }); + return arg; + }; + + local.onErrorDefault = function (error) { + /* + * this function will if error exists, then print error.stack to stderr + */ + if (error && !local.global.__coverage__) { + console.error(error); + } + }; + + local.onErrorWithStack = function (onError) { + /* + * this function will create a new callback that will call onError, + * and append the current stack to any error + */ + var stack; + stack = new Error().stack.replace((/(.*?)\n.*?$/m), '$1'); + return function (error, data, meta) { + if (error && + error !== local.errorDefault && + String(error.stack).indexOf(stack.split('\n')[2]) < 0) { + // append the current stack to error.stack + error.stack += '\n' + stack; + } + onError(error, data, meta); + }; + }; + + local.onParallel = function (onError, onEach, onRetry) { + /* + * this function will create a function that will + * 1. run async tasks in parallel + * 2. if counter === 0 or error occurred, then call onError with error + */ + var onParallel; + onError = local.onErrorWithStack(onError); + onEach = onEach || local.nop; + onRetry = onRetry || local.nop; + onParallel = function (error, data) { + if (onRetry(error, data)) { + return; + } + // decrement counter + onParallel.counter -= 1; + // validate counter + console.assert(onParallel.counter >= 0 || error || onParallel.error); + // ensure onError is run only once + if (onParallel.counter < 0) { + return; + } + // handle error + if (error) { + onParallel.error = error; + // ensure counter <= 0 + onParallel.counter = -Math.abs(onParallel.counter); + } + // call onError when isDone + if (onParallel.counter <= 0) { + onError(error, data); + return; + } + onEach(); + }; + // init counter + onParallel.counter = 0; + // return callback + return onParallel; + }; + + local.setTimeoutOnError = function (onError, error, data) { + /* + * this function will async-call onError + */ + if (typeof onError === 'function') { + setTimeout(function () { + onError(error, data); + }); + } + return data; + }; + }()); + + + + // run shared js-env code - lib.storage.js + (function (local) { + var child_process, + clear, + defer, + deferList, + fs, + getItem, + init, + keys, + length, + modeJs, + os, + removeItem, + setItem, + storage, + storageDir; + + // init modeJs + modeJs = (function () { + try { + return typeof navigator.userAgent === 'string' && + typeof document.querySelector('body') === 'object' && + typeof XMLHttpRequest.prototype.open === 'function' && + 'browser'; + } catch (errorCaughtBrowser) { + return module.exports && + typeof process.versions.node === 'string' && + typeof require('http').createServer === 'function' && + 'node'; + } + }()); + storageDir = 'tmp/storage.' + (local.modeJs === 'browser' + ? 'undefined' + : process.env.NODE_ENV); + switch (modeJs) { + case 'node': + // require modules + child_process = require('child_process'); + fs = require('fs'); + os = require('os'); + break; + } + + clear = function (onError) { + /* + * this function will clear storage + */ + defer({ action: 'clear' }, onError); + }; + + defer = function (options, onError) { + /* + * this function will defer options.action until storage is ready + */ + var data, isDone, objectStore, onError2, request, tmp; + onError = onError || function (error) { + // validate no error occurred + console.assert(!error, error); + }; + if (!storage) { + deferList.push(function () { + defer(options, onError); + }); + init(); + return; + } + switch (modeJs) { + case 'browser': + onError2 = function () { + /* istanbul ignore next */ + if (isDone) { + return; + } + isDone = true; + onError( + request && (request.error || request.transaction.error), + data || request.result || '' + ); + }; + switch (options.action) { + case 'clear': + case 'removeItem': + case 'setItem': + objectStore = storage + .transaction(storageDir, 'readwrite') + .objectStore(storageDir); + break; + default: + objectStore = storage + .transaction(storageDir, 'readonly') + .objectStore(storageDir); + } + switch (options.action) { + case 'clear': + request = objectStore.clear(); + break; + case 'getItem': + request = objectStore.get(String(options.key)); + break; + case 'keys': + data = []; + request = objectStore.openCursor(); + request.onsuccess = function () { + if (!request.result) { + onError2(); + return; + } + data.push(request.result.key); + request.result.continue(); + }; + break; + case 'length': + request = objectStore.count(); + break; + case 'removeItem': + request = objectStore.delete(String(options.key)); + break; + case 'setItem': + request = objectStore.put(options.value, String(options.key)); + break; + } + ['onabort', 'onerror', 'onsuccess'].forEach(function (handler) { + request[handler] = request[handler] || onError2; + }); + // debug request + local._debugStorageRequest = request; + break; + case 'node': + switch (options.action) { + case 'clear': + child_process.spawnSync( + 'sh', + ['-c', 'rm -f ' + storage + '/*'], + { stdio: ['ignore', 1, 2] } + ); + setTimeout(onError); + break; + case 'getItem': + fs.readFile( + storage + '/' + encodeURIComponent(String(options.key)), + 'utf8', + // ignore error + function (error, data) { + onError(error && null, data || ''); + } + ); + break; + case 'keys': + fs.readdir(storage, function (error, data) { + onError(error, data && data.map(decodeURIComponent)); + }); + break; + case 'length': + fs.readdir(storage, function (error, data) { + onError(error, data && data.length); + }); + break; + case 'removeItem': + fs.unlink( + storage + '/' + encodeURIComponent(String(options.key)), + // ignore error + function () { + onError(); + } + ); + break; + case 'setItem': + tmp = os.tmpdir() + '/' + Date.now() + Math.random(); + // save to tmp + fs.writeFile(tmp, options.value, function (error) { + // validate no error occurred + console.assert(!error, error); + // rename tmp to key + fs.rename( + tmp, + storage + '/' + encodeURIComponent(String(options.key)), + onError + ); + }); + break; + } + break; + } + }; + + deferList = []; + + getItem = function (key, onError) { + /* + * this function will get the item with the given key from storage + */ + defer({ action: 'getItem', key: key }, onError); + }; + + init = function () { + /* + * this function will init storage + */ + var onError, request; + onError = function (error) { + // validate no error occurred + console.assert(!error, error); + if (modeJs === 'browser') { + storage = window[storageDir]; + } + while (deferList.length) { + deferList.shift()(); + } + }; + if (modeJs === 'browser') { + storage = window[storageDir]; + } + if (storage) { + onError(); + return; + } + switch (modeJs) { + case 'browser': + // init indexedDB + try { + request = window.indexedDB.open(storageDir); + // debug request + local._debugStorageRequestIndexedDB = request; + request.onerror = onError; + request.onsuccess = function () { + window[storageDir] = request.result; + onError(); + }; + request.onupgradeneeded = function () { + if (!request.result.objectStoreNames.contains(storageDir)) { + request.result.createObjectStore(storageDir); + } + }; + } catch (ignore) { + } + break; + case 'node': + // mkdirp storage + storage = storageDir; + child_process.spawnSync( + 'mkdir', + ['-p', storage], + { stdio: ['ignore', 1, 2] } + ); + onError(); + break; + } + }; + + keys = function (onError) { + /* + * this function will get all the keys in storage + */ + defer({ action: 'keys' }, onError); + }; + + length = function (onError) { + /* + * this function will get the number of items in storage + */ + defer({ action: 'length' }, onError); + }; + + removeItem = function (key, onError) { + /* + * this function will remove the item with the given key from storage + */ + defer({ action: 'removeItem', key: key }, onError); + }; + + setItem = function (key, value, onError) { + /* + * this function will set the item with the given key and value to storage + */ + defer({ action: 'setItem', key: key, value: value }, onError); + }; + + // init local + local.storage = storage; + local.storageClear = clear; + local.storageDefer = defer; + local.storageDeferList = deferList; + local.storageDir = storageDir; + local.storageGetItem = getItem; + local.storageInit = init; + local.storageKeys = keys; + local.storageLength = length; + local.storageRemoveItem = removeItem; + local.storageSetItem = setItem; + }(local)); + + + + // run shared js-env code - lib.dbTable.js + (function () { + local._DbTable = function (options) { + /* + * this function will create a dbTable + */ + options = local.normalizeDict(options); + this.name = String(options.name); + // register dbTable in dbTableDict + local.dbTableDict[this.name] = this; + this.dbRowList = []; + this.isDirty = null; + this.idIndexList = [{ name: '_id', dict: {} }]; + this.onSaveList = []; + this.sizeLimit = options.sizeLimit || 0; + }; + + local._DbTable.prototype._cleanup = function () { + /* + * this function will cleanup soft-deleted records from the dbTable + */ + var dbRow, ii, list; + if (!this.isDirty && this.dbRowList.length <= this.sizeLimit) { + return; + } + this.isDirty = null; + // cleanup dbRowList + list = this.dbRowList; + this.dbRowList = []; + // optimization - for-loop + for (ii = 0; ii < list.length; ii += 1) { + dbRow = list[ii]; + // cleanup isRemoved + if (!dbRow.$meta.isRemoved) { + this.dbRowList.push(dbRow); + } + } + if (this.sizeLimit && this.dbRowList.length >= 1.5 * this.sizeLimit) { + this.dbRowList = this._crudGetManyByQuery( + {}, + this.sortDefault, + 0, + this.sizeLimit + ); + } + }; + + local._DbTable.prototype._crudGetManyByQuery = function ( + query, + sort, + skip, + limit, + shuffle + ) { + /* + * this function will get the dbRow's in the dbTable, + * with the given query, sort, skip, and limit + */ + var ii, result; + result = this.dbRowList; + // get by query + if (result.length && query && Object.keys(query).length) { + result = local.dbRowListGetManyByQuery(this.dbRowList, query); + } + // sort + local.normalizeList(sort).forEach(function (element) { + // bug-workaround - v8 does not have stable-sort + // optimization - for-loop + for (ii = 0; ii < result.length; ii += 1) { + result[ii].$meta.ii = ii; + } + if (element.isDescending) { + result.sort(function (aa, bb) { + return -local.sortCompare( + local.dbRowGetItem(aa, element.fieldName), + local.dbRowGetItem(bb, element.fieldName), + aa.$meta.ii, + bb.$meta.ii + ); + }); + } else { + result.sort(function (aa, bb) { + return local.sortCompare( + local.dbRowGetItem(aa, element.fieldName), + local.dbRowGetItem(bb, element.fieldName), + aa.$meta.ii, + bb.$meta.ii + ); + }); + } + }); + // skip + result = result.slice(skip || 0); + // shuffle + ((shuffle && local.listShuffle) || local.nop)(result); + // limit + result = result.slice(0, limit || Infinity); + return result; + }; + + local._DbTable.prototype._crudGetOneById = function (idDict) { + /* + * this function will get the dbRow in the dbTable with the given idDict + */ + var id, result; + idDict = local.normalizeDict(idDict); + result = null; + this.idIndexList.some(function (idIndex) { + id = idDict[idIndex.name]; + // optimization - hasOwnProperty + if (idIndex.dict.hasOwnProperty(id)) { + result = idIndex.dict[id]; + return result; + } + }); + return result; + }; + + local._DbTable.prototype._crudRemoveOneById = function (idDict, circularList) { + /* + * this function will remove the dbRow from the dbTable with the given idDict + */ + var id, result, self; + if (!idDict) { + return null; + } + self = this; + circularList = circularList || [idDict]; + result = null; + self.idIndexList.forEach(function (idIndex) { + id = idDict[idIndex.name]; + // optimization - hasOwnProperty + if (!idIndex.dict.hasOwnProperty(id)) { + return; + } + result = idIndex.dict[id]; + delete idIndex.dict[id]; + // optimization - soft-delete + result.$meta.isRemoved = true; + self.isDirty = true; + if (circularList.indexOf(result) >= 0) { + return; + } + circularList.push(result); + // recurse + self._crudRemoveOneById(result, circularList); + }); + self.save(); + return result; + }; + + local._DbTable.prototype._crudSetOneById = function (dbRow) { + /* + * this function will set the dbRow into the dbTable with the given dbRow._id + * WARNING - existing dbRow with conflicting dbRow._id will be removed + */ + var existing, id, normalize, timeNow; + normalize = function (dbRow) { + /* + * this function will recursively normalize dbRow + */ + if (dbRow && typeof dbRow === 'object') { + Object.keys(dbRow).forEach(function (key) { + // remove invalid property + if (key[0] === '$' || key.indexOf('.') >= 0 || dbRow[key] === null) { + // optimization - soft-delete + dbRow[key] = undefined; + return; + } + // recurse + normalize(dbRow[key]); + }); + } + }; + dbRow = local.jsonCopy(dbRow && typeof dbRow === 'object' + ? dbRow + : {}); + // update timestamp + timeNow = new Date().toISOString(); + dbRow._timeCreated = dbRow._timeCreated || timeNow; + if (!local.modeImport) { + dbRow._timeUpdated = timeNow; + } + // normalize + normalize(dbRow); + dbRow = local.jsonCopy(dbRow); + // remove existing dbRow + existing = this._crudRemoveOneById(dbRow) || dbRow; + // init meta + dbRow.$meta = { isRemoved: null }; + this.idIndexList.forEach(function (idIndex) { + // auto-set id + id = local.dbRowSetId(existing, idIndex); + // copy id from existing to dbRow + dbRow[idIndex.name] = id; + // set dbRow + idIndex.dict[id] = dbRow; + }); + // update dbRowList + this.dbRowList.push(dbRow); + this.save(); + return dbRow; + }; + + local._DbTable.prototype._crudUpdateOneById = function (dbRow) { + /* + * this function will update the dbRow in the dbTable, + * if it exists with the given dbRow._id + * WARNING + * existing dbRow's with conflicting unique-keys (besides the one being updated) + * will be removed + */ + var id, result; + dbRow = local.jsonCopy(local.normalizeDict(dbRow)); + result = null; + this.idIndexList.some(function (idIndex) { + id = dbRow[idIndex.name]; + // optimization - hasOwnProperty + if (idIndex.dict.hasOwnProperty(id)) { + result = idIndex.dict[id]; + return true; + } + }); + result = result || {}; + // remove existing dbRow + this._crudRemoveOneById(result); + // update dbRow + dbRow._timeCreated = undefined; + local.objectSetOverride(result, dbRow, Infinity); + // replace dbRow + result = this._crudSetOneById(result); + return result; + }; + + local._DbTable.prototype.crudCountAll = function (onError) { + /* + * this function will count all of dbRow's in the dbTable + */ + this._cleanup(); + return local.setTimeoutOnError(onError, null, this.dbRowList.length); + }; + + local._DbTable.prototype.crudCountManyByQuery = function (query, onError) { + /* + * this function will count the number of dbRow's in the dbTable with the given query + */ + this._cleanup(); + return local.setTimeoutOnError( + onError, + null, + this._crudGetManyByQuery(query).length + ); + }; + + local._DbTable.prototype.crudGetManyById = function (idDictList, onError) { + /* + * this function will get the dbRow's in the dbTable with the given idDictList + */ + var self; + this._cleanup(); + self = this; + return local.setTimeoutOnError(onError, null, local.dbRowProject( + local.normalizeList(idDictList).map(function (idDict) { + return self._crudGetOneById(idDict); + }) + )); + }; + + local._DbTable.prototype.crudGetManyByQuery = function (options, onError) { + /* + * this function will get the dbRow's in the dbTable with the given options.query + */ + this._cleanup(); + options = local.normalizeDict(options); + return local.setTimeoutOnError(onError, null, local.dbRowProject( + this._crudGetManyByQuery( + options.query, + options.sort || this.sortDefault, + options.skip, + options.limit, + options.shuffle + ), + options.fieldList + )); + }; + + local._DbTable.prototype.crudGetOneById = function (idDict, onError) { + /* + * this function will get the dbRow in the dbTable with the given idDict + */ + this._cleanup(); + return local.setTimeoutOnError(onError, null, local.dbRowProject( + this._crudGetOneById(idDict) + )); + }; + + local._DbTable.prototype.crudGetOneByRandom = function (onError) { + /* + * this function will get a random dbRow in the dbTable + */ + this._cleanup(); + return local.setTimeoutOnError(onError, null, local.dbRowProject( + this.dbRowList[Math.floor(Math.random() * this.dbRowList.length)] + )); + }; + + local._DbTable.prototype.crudGetOneByQuery = function (query, onError) { + /* + * this function will get the dbRow in the dbTable with the given query + */ + var ii, result; + this._cleanup(); + // optimization - for-loop + for (ii = 0; ii < this.dbRowList.length; ii += 1) { + result = local.dbRowListGetManyByQuery([this.dbRowList[ii]], query)[0]; + if (result) { + break; + } + } + return local.setTimeoutOnError(onError, null, local.dbRowProject(result)); + }; + + local._DbTable.prototype.crudRemoveAll = function (onError) { + /* + * this function will remove all of the dbRow's from the dbTable + */ + var idIndexList; + // save idIndexList + idIndexList = this.idIndexList; + // reset dbTable + local._DbTable.call(this, this); + // restore idIndexList + local.dbTableCreateOne({ + name: this.name, + idIndexCreateList: idIndexList + }, onError); + }; + + local._DbTable.prototype.crudRemoveManyById = function (idDictList, onError) { + /* + * this function will remove the dbRow's from the dbTable with the given idDictList + */ + var self; + self = this; + return local.setTimeoutOnError(onError, null, local.dbRowProject( + local.normalizeList(idDictList).map(function (dbRow) { + return self._crudRemoveOneById(dbRow); + }) + )); + }; + + local._DbTable.prototype.crudRemoveManyByQuery = function (query, onError) { + /* + * this function will remove the dbRow's from the dbTable with the given query + */ + var self; + self = this; + return local.setTimeoutOnError(onError, null, local.dbRowProject( + self._crudGetManyByQuery(query).map(function (dbRow) { + return self._crudRemoveOneById(dbRow); + }) + )); + }; + + local._DbTable.prototype.crudRemoveOneById = function (idDict, onError) { + /* + * this function will remove the dbRow from the dbTable with the given idDict + */ + return local.setTimeoutOnError(onError, null, local.dbRowProject( + this._crudRemoveOneById(idDict) + )); + }; + + local._DbTable.prototype.crudSetManyById = function (dbRowList, onError) { + /* + * this function will set the dbRowList into the dbTable + */ + var self; + self = this; + return local.setTimeoutOnError(onError, null, local.dbRowProject( + local.normalizeList(dbRowList).map(function (dbRow) { + return self._crudSetOneById(dbRow); + }) + )); + }; + + local._DbTable.prototype.crudSetOneById = function (dbRow, onError) { + /* + * this function will set the dbRow into the dbTable with the given dbRow._id + */ + return local.setTimeoutOnError(onError, null, local.dbRowProject( + this._crudSetOneById(dbRow) + )); + }; + + local._DbTable.prototype.crudUpdateManyById = function (dbRowList, onError) { + /* + * this function will update the dbRowList in the dbTable, + * if they exist with the given dbRow._id's + */ + var self; + self = this; + return local.setTimeoutOnError(onError, null, local.dbRowProject( + local.normalizeList(dbRowList).map(function (dbRow) { + return self._crudUpdateOneById(dbRow); + }) + )); + }; + + local._DbTable.prototype.crudUpdateManyByQuery = function (query, dbRow, onError) { + /* + * this function will update the dbRow's in the dbTable with the given query + */ + var result, self, tmp; + self = this; + tmp = local.jsonCopy(local.normalizeDict(dbRow)); + result = self._crudGetManyByQuery(query).map(function (dbRow) { + tmp._id = dbRow._id; + return self._crudUpdateOneById(tmp); + }); + return local.setTimeoutOnError(onError, null, result); + }; + + local._DbTable.prototype.crudUpdateOneById = function (dbRow, onError) { + /* + * this function will update the dbRow in the dbTable, + * if it exists with the given dbRow._id + */ + return local.setTimeoutOnError(onError, null, local.dbRowProject( + this._crudUpdateOneById(dbRow) + )); + }; + + local._DbTable.prototype.drop = function (onError) { + /* + * this function will drop the dbTable + */ + console.error('dropping dbTable ' + this.name + ' ...'); + // cancel pending save + this.timerSave = null; + while (this.onSaveList.length) { + this.onSaveList.shift()(); + } + // reset dbTable + local._DbTable.call(this, this); + // clear persistence + local.storageRemoveItem('dbTable.' + this.name, onError); + }; + + local._DbTable.prototype.export = function (onError) { + /* + * this function will export the db + */ + var result, self; + this._cleanup(); + self = this; + result = ''; + self.idIndexList.forEach(function (idIndex) { + result += self.name + ' idIndexCreate ' + JSON.stringify({ + isInteger: idIndex.isInteger, + name: idIndex.name + }) + '\n'; + }); + result += self.name + ' sizeLimit ' + self.sizeLimit + '\n'; + result += self.name + ' sortDefault ' + JSON.stringify(self.sortDefault) + '\n'; + self.crudGetManyByQuery({}).forEach(function (dbRow) { + result += self.name + ' dbRowSet ' + JSON.stringify(dbRow) + '\n'; + }); + return local.setTimeoutOnError(onError, null, result.trim()); + }; + + local._DbTable.prototype.idIndexCreate = function (options, onError) { + /* + * this function will create an idIndex with the given options.name + */ + var dbRow, idIndex, ii, name; + options = local.normalizeDict(options); + name = String(options.name); + // disallow idIndex with dot-name + if (name.indexOf('.') >= 0 || name === '_id') { + return local.setTimeoutOnError(onError); + } + // remove existing idIndex + this.idIndexRemove(options); + // init idIndex + idIndex = { + dict: {}, + isInteger: options.isInteger, + name: options.name + }; + this.idIndexList.push(idIndex); + // populate idIndex with dbRowList + // optimization - for-loop + for (ii = 0; ii < this.dbRowList.length; ii += 1) { + dbRow = this.dbRowList[ii]; + // auto-set id + if (!dbRow.$meta.isRemoved) { + idIndex.dict[local.dbRowSetId(dbRow, idIndex)] = dbRow; + } + } + this.save(); + return local.setTimeoutOnError(onError); + }; + + local._DbTable.prototype.idIndexRemove = function (options, onError) { + /* + * this function will remove the idIndex with the given options.name + */ + var name; + options = local.normalizeDict(options); + name = String(options.name); + this.idIndexList = this.idIndexList.filter(function (idIndex) { + return idIndex.name !== name || idIndex.name === '_id'; + }); + this.save(); + return local.setTimeoutOnError(onError); + }; + + local._DbTable.prototype.save = function (onError) { + /* + * this function will save the dbTable to storage + */ + var self; + self = this; + if (local.modeImport) { + return; + } + if (onError) { + self.onSaveList.push(onError); + } + // throttle storage-writes to once every 1000 ms + self.timerSave = self.timerSave || setTimeout(function () { + self.timerSave = null; + local.storageSetItem('dbTable.' + self.name + '.json', self.export(), function ( + error + ) { + while (self.onSaveList.length) { + self.onSaveList.shift()(error); + } + }); + }, 1000); + }; + + local.dbCrudRemoveAll = function (onError) { + /* + * this function will remove all dbRow's from the db + */ + var onParallel; + onParallel = local.onParallel(function (error) { + local.setTimeoutOnError(onError, error); + }); + onParallel.counter += 1; + Object.keys(local.dbTableDict).forEach(function (key) { + onParallel.counter += 1; + local.dbTableDict[key].crudRemoveAll(onParallel); + }); + onParallel(); + }; + + local.dbDrop = function (onError) { + /* + * this function will drop the db + */ + var onParallel; + onParallel = local.onParallel(function (error) { + local.setTimeoutOnError(onError, error); + }); + onParallel.counter += 1; + onParallel.counter += 1; + local.storageClear(onParallel); + Object.keys(local.dbTableDict).forEach(function (key) { + onParallel.counter += 1; + local.dbTableDict[key].drop(onParallel); + }); + onParallel(); + }; + + local.dbExport = function (onError) { + /* + * this function will export the db as serialized text + */ + var result; + result = ''; + Object.keys(local.dbTableDict).forEach(function (key) { + result += local.dbTableDict[key].export(); + result += '\n\n'; + }); + return local.setTimeoutOnError(onError, null, result.trim()); + }; + + local.dbImport = function (text, onError) { + /* + * this function will import the serialized text into the db + */ + var dbTable; + local.modeImport = true; + setTimeout(function () { + local.modeImport = null; + }); + text.replace((/^(\w\S*?) (\S+?) (\S.*?)$/gm), function ( + match0, + match1, + match2, + match3 + ) { + // jslint-hack + local.nop(match0); + switch (match2) { + case 'dbRowSet': + dbTable = local.dbTableCreateOne({ isLoaded: true, name: match1 }); + dbTable.crudSetOneById(JSON.parse(match3)); + break; + case 'idIndexCreate': + dbTable = local.dbTableCreateOne({ isLoaded: true, name: match1 }); + dbTable.idIndexCreate(JSON.parse(match3)); + break; + case 'sizeLimit': + dbTable = local.dbTableCreateOne({ isLoaded: true, name: match1 }); + dbTable.sizeLimit = JSON.parse(match3); + break; + case 'sortDefault': + dbTable = local.dbTableCreateOne({ isLoaded: true, name: match1 }); + break; + default: + local.onErrorDefault(new Error('dbImport - invalid operation - ' + match0)); + } + }); + local.modeImport = null; + return local.setTimeoutOnError(onError); + }; + + local.dbLoad = function (onError) { + /* + * this function will load the db from storage + */ + var onParallel; + onParallel = local.onParallel(function (error) { + local.setTimeoutOnError(onError, error); + }); + local.storageKeys(function (error, data) { + onParallel.counter += 1; + onParallel.counter += 1; + onParallel(error); + local.normalizeList(data) + .filter(function (key) { + return key.indexOf('dbTable.') === 0; + }) + .forEach(function (key) { + onParallel.counter += 1; + local.storageGetItem(key, function (error, data) { + onParallel.counter += 1; + onParallel(error); + local.dbImport(data, onParallel); + }); + }); + onParallel(); + }); + }; + + local.dbRowGetItem = function (dbRow, key) { + /* + * this function will get the item with the given key from dbRow + */ + var ii, value; + value = dbRow; + key = String(key).split('.'); + // optimization - for-loop + for (ii = 0; ii < key.length && value && typeof value === 'object'; ii += 1) { + value = value[key[ii]]; + } + return value === undefined + ? null + : value; + }; + + local.dbRowListGetManyByOperator = function (dbRowList, fieldName, operator, bb, not) { + /* + * this function will get the dbRow's in dbRowList with the given operator + */ + var ii, jj, result, fieldValue, test, typeof2; + result = []; + typeof2 = typeof bb; + if (bb && typeof2 === 'object') { + switch (operator) { + case '$in': + case '$nin': + case '$regex': + break; + default: + return result; + } + } + switch (operator) { + case '$eq': + test = function (aa, bb) { + return aa === bb; + }; + break; + case '$exists': + bb = !bb; + test = function (aa, bb) { + return !((aa === null) ^ bb); + }; + break; + case '$gt': + test = function (aa, bb, typeof1, typeof2) { + return typeof1 === typeof2 && aa > bb; + }; + break; + case '$gte': + test = function (aa, bb, typeof1, typeof2) { + return typeof1 === typeof2 && aa >= bb; + }; + break; + case '$in': + if (bb && typeof bb.indexOf === 'function') { + if (typeof2 === 'string') { + test = function (aa, bb, typeof1, typeof2) { + return typeof1 === typeof2 && bb.indexOf(aa) >= 0; + }; + } else { + test = function (aa, bb) { + return bb.indexOf(aa) >= 0; + }; + } + } + break; + case '$lt': + test = function (aa, bb, typeof1, typeof2) { + return typeof1 === typeof2 && aa < bb; + }; + break; + case '$lte': + test = function (aa, bb, typeof1, typeof2) { + return typeof1 === typeof2 && aa <= bb; + }; + break; + case '$ne': + test = function (aa, bb) { + return aa !== bb; + }; + break; + case '$nin': + if (bb && typeof bb.indexOf === 'function') { + if (typeof2 === 'string') { + test = function (aa, bb, typeof1, typeof2) { + return typeof1 === typeof2 && bb.indexOf(aa) < 0; + }; + } else { + test = function (aa, bb) { + return bb.indexOf(aa) < 0; + }; + } + } + break; + case '$regex': + if (bb && typeof bb.test === 'function') { + test = function (aa, bb) { + return bb.test(aa); + }; + } + break; + case '$typeof': + test = function (aa, bb, typeof1) { + // jslint-hack + local.nop(aa); + return typeof1 === bb; + }; + break; + } + if (!test) { + return result; + } + // optimization - for-loop + for (ii = dbRowList.length - 1; ii >= 0; ii -= 1) { + fieldValue = local.dbRowGetItem(dbRowList[ii], fieldName); + // normalize to list + if (!Array.isArray(fieldValue)) { + fieldValue = [fieldValue]; + } + // optimization - for-loop + for (jj = fieldValue.length - 1; jj >= 0; jj -= 1) { + if (not ^ test(fieldValue[jj], bb, typeof fieldValue[jj], typeof2)) { + result.push(dbRowList[ii]); + break; + } + } + } + return result; + }; + + local.dbRowListGetManyByQuery = function (dbRowList, query, fieldName, not) { + /* + * this function will get the dbRow's in dbRowList with the given query + */ + var bb, dbRowDict, result; + // optimization - convert to boolean + not = !!not; + result = dbRowList; + if (!(query && typeof query === 'object')) { + result = local.dbRowListGetManyByOperator(result, fieldName, '$eq', query, not); + return result; + } + Object.keys(query).some(function (key) { + bb = query[key]; + switch (key) { + case '$not': + key = fieldName; + not = !not; + break; + case '$or': + if (!Array.isArray(bb)) { + break; + } + dbRowDict = {}; + bb.forEach(function (query) { + // recurse + local.dbRowListGetManyByQuery(result, query).forEach(function (dbRow) { + dbRowDict[dbRow._id] = dbRow; + }); + }); + result = Object.keys(dbRowDict).map(function (id) { + return dbRowDict[id]; + }); + return !result.length; + } + if (key[0] === '$') { + result = local.dbRowListGetManyByOperator(result, fieldName, key, bb, not); + return !result.length; + } + // recurse + result = local.dbRowListGetManyByQuery(result, bb, key, not); + return !result.length; + }); + return result; + }; + + local.dbRowProject = function (dbRow, fieldList) { + /* + * this function will deepcopy and project the dbRow with the given fieldList + */ + var result; + if (!dbRow) { + return null; + } + // handle list-case + if (Array.isArray(dbRow)) { + return dbRow.map(function (dbRow) { + // recurse + return local.dbRowProject(dbRow, fieldList); + }); + } + // normalize to list + if (!(Array.isArray(fieldList) && fieldList.length)) { + fieldList = Object.keys(dbRow); + } + result = {}; + fieldList.forEach(function (key) { + if (key[0] !== '$') { + result[key] = dbRow[key]; + } + }); + return JSON.parse(local.jsonStringifyOrdered(result)); + }; + + local.dbRowSetId = function (dbRow, idIndex) { + /* + * this function will set a random and unique id into dbRow for the given idIndex, + * if it does not exist + */ + var id; + id = dbRow[idIndex.name]; + if (typeof id !== 'number' && typeof id !== 'string') { + do { + id = idIndex.isInteger + ? (1 + Math.random()) * 0x10000000000000 + : 'a' + ((1 + Math.random()) * 0x10000000000000).toString(36).slice(1); + // optimization - hasOwnProperty + } while (idIndex.dict.hasOwnProperty(id)); + dbRow[idIndex.name] = id; + } + return id; + }; + + local.dbSave = function (onError) { + /* + * this function will save the db to storage + */ + var onParallel; + onParallel = local.onParallel(function (error) { + local.setTimeoutOnError(onError, error); + }); + onParallel.counter += 1; + Object.keys(local.dbTableDict).forEach(function (key) { + onParallel.counter += 1; + local.dbTableDict[key].save(onParallel); + }); + onParallel(); + }; + + local.dbTableCreateMany = function (optionsList, onError) { + /* + * this function will set the optionsList into the db + */ + var onParallel, result; + onParallel = local.onParallel(function (error) { + local.setTimeoutOnError(onError, error, result); + }); + onParallel.counter += 1; + result = local.normalizeList(optionsList).map(function (options) { + onParallel.counter += 1; + return local.dbTableCreateOne(options, onParallel); + }); + return local.setTimeoutOnError(onParallel, null, result); + }; + + local.dbTableCreateOne = function (options, onError) { + /* + * this function will create a dbTable with the given options + */ + var self; + options = local.normalizeDict(options); + // register dbTable + self = local.dbTableDict[options.name] = + local.dbTableDict[options.name] || new local._DbTable(options); + self.sortDefault = options.sortDefault || + self.sortDefault || + [{ fieldName: '_timeUpdated', isDescending: true }]; + // remove idIndex + local.normalizeList(options.idIndexRemoveList).forEach(function (index) { + self.idIndexRemove(index); + }); + // create idIndex + local.normalizeList(options.idIndexCreateList).forEach(function (index) { + self.idIndexCreate(index); + }); + // upsert dbRow + self.crudSetManyById(options.dbRowList); + self.isLoaded = self.isLoaded || options.isLoaded; + if (!self.isLoaded) { + local.storageGetItem('dbTable.' + self.name + '.json', function (error, data) { + // validate no error occurred + console.assert(!error, error); + if (!self.isLoaded) { + local.dbImport(data); + } + self.isLoaded = true; + local.setTimeoutOnError(onError, null, self); + }); + return self; + } + return local.setTimeoutOnError(onError, null, self); + }; + + local.dbTableDict = {}; + + local.sortCompare = function (aa, bb, ii, jj) { + /* + * this function will compare aa vs bb and return: + * -1 if aa < bb + * 0 if aa === bb + * 1 if aa > bb + * the priority for comparing different typeof's is: + * null < boolean < number < string < object < undefined + */ + var typeof1, typeof2; + if (aa === bb) { + return ii < jj + ? -1 + : 1; + } + if (aa === null) { + return -1; + } + if (bb === null) { + return 1; + } + typeof1 = typeof aa; + typeof2 = typeof bb; + if (typeof1 === typeof2) { + return typeof1 === 'object' + ? 0 + : aa > bb + ? 1 + : -1; + } + if (typeof1 === 'boolean') { + return -1; + } + if (typeof2 === 'boolean') { + return 1; + } + if (typeof1 === 'number') { + return -1; + } + if (typeof2 === 'number') { + return 1; + } + if (typeof1 === 'string') { + return -1; + } + if (typeof2 === 'string') { + return 1; + } + return 0; + }; + }()); + switch (local.modeJs) { + + + + // run node js-env code - init-after + case 'node': + // require modules + local.fs = require('fs'); + break; + } +}()); +/* script-end /assets.utility2.lib.db.js */ + + + +/* script-begin /assets.utility2.lib.github_crud.js */ +///usr/bin/env node +/* istanbul instrument in package github-crud */ +/*jslint + bitwise: true, + browser: true, + maxerr: 8, + maxlen: 96, + node: true, + nomen: true, + regexp: true, + stupid: true +*/ +(function () { + 'use strict'; + var local; + + + + // run shared js-env code - init-before + (function () { + // init local + local = {}; + // init modeJs + local.modeJs = (function () { + try { + return typeof navigator.userAgent === 'string' && + typeof document.querySelector('body') === 'object' && + typeof XMLHttpRequest.prototype.open === 'function' && + 'browser'; + } catch (errorCaughtBrowser) { + return module.exports && + typeof process.versions.node === 'string' && + typeof require('http').createServer === 'function' && + 'node'; + } + }()); + // init global + local.global = local.modeJs === 'browser' + ? window + : global; + // init utility2_rollup + local = local.global.utility2_rollup || local; + // init lib + local.local = local.github_crud = local; + // init exports + if (local.modeJs === 'browser') { + local.global.utility2_github_crud = local; + } else { + module.exports = local; + module.exports.__dirname = __dirname; + module.exports.module = module; + } + }()); + + + + /* istanbul ignore next */ + // run shared js-env code - function-before + (function () { + local.httpRequest = function (options, onError) { + /* + * this function will request the data from options.url + */ + var chunkList, isDone, onError2, timerTimeout, request, response, urlParsed; + // init onError2 + onError2 = function (error) { + if (isDone) { + return; + } + isDone = true; + // cleanup timerTimeout + clearTimeout(timerTimeout); + // cleanup request and response + [request, response].forEach(function (stream) { + // try to end the stream + try { + stream.end(); + // else try to destroy the stream + } catch (errorCaught) { + try { + stream.destroy(); + } catch (ignore) { + } + } + }); + if (response && (response.statusCode < 200 || response.statusCode >= 300)) { + error = error || new Error(response.statusCode); + console.error(String(response.data)); + } + // debug response + console.error(new Date().toISOString() + ' http-response ' + JSON.stringify({ + statusCode: (response && response.statusCode) || 0, + method: options.method, + url: options.url + })); + onError(error, response); + }; + // init timerTimeout + timerTimeout = setTimeout(function () { + onError2(new Error('http-request timeout')); + }, options.timeout || 30000); + urlParsed = require('url').parse(options.url); + urlParsed.headers = options.headers; + urlParsed.method = options.method; + // debug request + console.error(); + console.error(new Date().toISOString() + ' http-request ' + JSON.stringify({ + method: options.method, + url: options.url + })); + request = require( + urlParsed.protocol.slice(0, -1) + ).request(urlParsed, function (_response) { + response = _response; + chunkList = []; + response + .on('data', function (chunk) { + chunkList.push(chunk); + }) + .on('end', function () { + response.data = Buffer.concat(chunkList); + onError2(); + }) + .on('error', onError2); + }).on('error', onError2); + request.end(options.data); + }; + + local.nop = function () { + /* + * this function will do nothing + */ + return; + }; + + local.onErrorWithStack = function (onError) { + /* + * this function will create a new callback that will call onError, + * and append the current stack to any error + */ + var stack; + stack = new Error().stack.replace((/(.*?)\n.*?$/m), '$1'); + return function (error, data, meta) { + if (error && + error !== local.errorDefault && + String(error.stack).indexOf(stack.split('\n')[2]) < 0) { + // append the current stack to error.stack + error.stack += '\n' + stack; + } + onError(error, data, meta); + }; + }; + + local.onNext = function (options, onError) { + /* + * this function will wrap onError inside the recursive function options.onNext, + * and append the current stack to any error + */ + options.onNext = local.onErrorWithStack(function (error, data, meta) { + try { + options.modeNext = error && !options.modeErrorIgnore + ? Infinity + : options.modeNext + 1; + onError(error, data, meta); + } catch (errorCaught) { + // throw errorCaught to break infinite recursion-loop + if (options.errorCaught) { + throw options.errorCaught; + } + options.errorCaught = errorCaught; + options.onNext(errorCaught, data, meta); + } + }); + return options; + }; + + local.onParallel = function (onError, onEach, onRetry) { + /* + * this function will create a function that will + * 1. run async tasks in parallel + * 2. if counter === 0 or error occurred, then call onError with error + */ + var onParallel; + onError = local.onErrorWithStack(onError); + onEach = onEach || local.nop; + onRetry = onRetry || local.nop; + onParallel = function (error, data) { + if (onRetry(error, data)) { + return; + } + // decrement counter + onParallel.counter -= 1; + // validate counter + console.assert(onParallel.counter >= 0 || error || onParallel.error); + // ensure onError is run only once + if (onParallel.counter < 0) { + return; + } + // handle error + if (error) { + onParallel.error = error; + // ensure counter <= 0 + onParallel.counter = -Math.abs(onParallel.counter); + } + // call onError when isDone + if (onParallel.counter <= 0) { + onError(error, data); + return; + } + onEach(); + }; + // init counter + onParallel.counter = 0; + // return callback + return onParallel; + }; + + local.onParallelList = function (options, onEach, onError) { + /* + * this function will + * 1. async-run onEach in parallel, + * with the given options.rateLimit and options.retryLimit + * 2. call onError when isDone + */ + var ii, onEach2, onParallel; + onEach2 = function () { + while (ii + 1 < options.list.length && onParallel.counter < options.rateLimit) { + ii += 1; + onParallel.ii += 1; + onParallel.remaining -= 1; + onEach({ + element: options.list[ii], + ii: ii, + list: options.list, + retry: 0 + }, onParallel); + } + }; + onParallel = local.onParallel(onError, onEach2, function (error, data) { + if (error && data && data.retry < options.retryLimit) { + local.onErrorDefault(error); + data.retry += 1; + setTimeout(function () { + onParallel.counter -= 1; + onEach(data, onParallel); + }, 1000); + return true; + } + }); + onParallel.counter += 1; + ii = -1; + onParallel.ii = -1; + onParallel.remaining = options.list.length; + options.rateLimit = Number(options.rateLimit) || 4; + options.rateLimit = Math.max(options.rateLimit, 3); + options.retryLimit = Number(options.retryLimit) || 2; + onEach2(); + onParallel(); + }; + + local.onReadyAfter = function (onError) { + /* + * this function will call onError when onReadyBefore.counter === 0 + */ + local.onReadyBefore.counter += 1; + local.taskCreate({ key: 'utility2.onReadyAfter' }, null, onError); + local.onResetAfter(local.onReadyBefore); + return onError; + }; + }()); + switch (local.modeJs) { + + + + // run node js-env code - function + case 'node': + local.contentDelete = function (options, onError) { + /* + * this function will delete the github file + * https://developer.github.com/v3/repos/contents/#delete-a-file + */ + options = { message: options.message, url: options.url }; + local.onNext(options, function (error, data) { + switch (options.modeNext) { + case 1: + // get sha + local.contentRequest({ method: 'GET', url: options.url }, options.onNext); + break; + case 2: + // delete file with sha + if (!error && data.sha) { + local.contentRequest({ + message: options.message, + method: 'DELETE', + sha: data.sha, + url: options.url + }, options.onNext); + return; + } + // delete tree + local.onParallelList({ list: data }, function (data, onParallel) { + onParallel.counter += 1; + // recurse + local.contentDelete({ + message: options.message, + url: data.element.url + }, onParallel); + }, options.onNext); + break; + default: + onError(); + } + }); + options.modeNext = 0; + options.onNext(); + }; + + local.contentGet = function (options, onError) { + /* + * this function will get the github file + * https://developer.github.com/v3/repos/contents/#get-contents + */ + options = { url: options.url }; + local.onNext(options, function (error, data) { + switch (options.modeNext) { + case 1: + local.contentRequest({ method: 'GET', url: options.url }, options.onNext); + break; + case 2: + options.onNext(null, new Buffer(data.content, 'base64')); + break; + default: + onError(error, !error && data); + } + }); + options.modeNext = 0; + options.onNext(); + }; + + local.contentPut = function (options, onError) { + /* + * this function will put options.content into the github file + * https://developer.github.com/v3/repos/contents/#update-a-file + */ + options = { + content: options.content, + message: options.message, + modeErrorIgnore: true, + url: options.url + }; + local.onNext(options, function (error, data) { + switch (options.modeNext) { + case 1: + // get sha + local.contentRequest({ method: 'GET', url: options.url }, options.onNext); + break; + case 2: + // put file with sha + local.contentRequest({ + content: options.content, + message: options.message, + method: 'PUT', + sha: data.sha, + url: options.url + }, options.onNext); + break; + default: + onError(error); + } + }); + options.modeNext = 0; + options.onNext(); + }; + + local.contentPutFile = function (options, onError) { + /* + * this function will put options.file into the github file + * https://developer.github.com/v3/repos/contents/#update-a-file + */ + options = { file: options.file, message: options.message, url: options.url }; + local.onNext(options, function (error, data) { + switch (options.modeNext) { + case 1: + // get file from url + if ((/^(?:http|https):\/\//).test(options.file)) { + local.httpRequest({ + method: 'GET', + url: options.file + }, function (error, response) { + options.onNext(error, response && response.data); + }); + return; + } + // get file + local.fs.readFile( + local.path.resolve(process.cwd(), options.file), + options.onNext + ); + break; + case 2: + local.contentPut({ + content: data, + message: options.message, + // resolve file in url + url: (/\/$/).test(options.url) + ? options.url + local.path.basename(options.file) + : options.url + }, options.onNext); + break; + default: + onError(error); + } + }); + options.modeNext = 0; + options.onNext(); + }; + + local.contentRequest = function (options, onError) { + /* + * this function will request the content from github + */ + // init options + options = { + chunkList: [], + content: options.content, + headers: { + // github oauth authentication + Authorization: 'token ' + process.env.GITHUB_TOKEN, + // bug-workaround - https://developer.github.com/v3/#user-agent-required + 'User-Agent': 'undefined' + }, + message: options.message, + method: options.method, + responseJson: {}, + sha: options.sha, + url: options.url + }; + options.url = options.url +/* jslint-ignore-begin */ +// parse https://github.com/:owner/:repo/blob/:branch/:path +.replace( + (/^https:\/\/github.com\/([^\/]+?\/[^\/]+?)\/blob\/([^\/]+?)\/(.+)/), + 'https://api.github.com/repos/$1/contents/$3?branch=$2' +) +// parse https://github.com/:owner/:repo/tree/:branch/:path +.replace( + (/^https:\/\/github.com\/([^\/]+?\/[^\/]+?)\/tree\/([^\/]+?)\/(.+)/), + 'https://api.github.com/repos/$1/contents/$3?branch=$2' +) +// parse https://raw.githubusercontent.com/:owner/:repo/:branch/:path +.replace( +(/^https:\/\/raw.githubusercontent.com\/([^\/]+?\/[^\/]+?)\/([^\/]+?)\/(.+)/), + 'https://api.github.com/repos/$1/contents/$3?branch=$2' +) +// parse https://:owner.github.io/:repo/:path +.replace( + (/^https:\/\/([^\.]+?)\.github\.io\/([^\/]+?)\/(.+)/), + 'https://api.github.com/repos/$1/$2/contents/$3?branch=gh-pages' +) +/* jslint-ignore-end */ + .replace((/\?branch=(.*)/), function (match0, match1) { + options.branch = match1; + if (options.method === 'GET') { + match0 = match0.replace('branch', 'ref'); + } + return match0; + }); + if (options.url.indexOf('https://api.github.com/repos/') !== 0) { + onError(new Error('invalid url ' + options.url)); + return; + } + if (options.method !== 'GET') { + options.message = options.message || + '[ci skip] ' + options.method + ' file ' + options.url + .replace((/\?.*/), ''); + options.url += '&message=' + encodeURIComponent(options.message); + if (options.sha) { + options.url += '&sha=' + options.sha; + } + options.data = JSON.stringify({ + branch: options.branch, + content: new Buffer(options.content || '').toString('base64'), + message: options.message, + sha: options.sha + }); + } + local.httpRequest(options, function (error, response) { + try { + options.responseJson = JSON.parse(response.data.toString()); + } catch (ignore) { + } + onError(error, options.responseJson); + }); + }; + + local.contentTouch = function (options, onError) { + /* + * this function will touch options.url + * https://developer.github.com/v3/repos/contents/#update-a-file + */ + options = { + message: options.message, + modeErrorIgnore: true, + url: options.url + }; + local.onNext(options, function (error, data) { + switch (options.modeNext) { + case 1: + // get sha + local.contentRequest({ method: 'GET', url: options.url }, options.onNext); + break; + case 2: + // put file with sha + local.contentRequest({ + content: new Buffer(data.content || '', 'base64'), + message: options.message, + method: 'PUT', + sha: data.sha, + url: options.url + }, options.onNext); + break; + default: + onError(error); + } + }); + options.modeNext = 0; + options.onNext(); + }; + + local.contentTouchList = function (options, onError) { + /* + * this function will touch options.urlList in parallel + * https://developer.github.com/v3/repos/contents/#update-a-file + */ + local.onParallelList({ list: options.urlList }, function (data, onParallel) { + onParallel.counter += 1; + local.contentTouch({ + message: options.message, + modeErrorIgnore: true, + url: data.element + }, onParallel); + }, onError); + }; + break; + } + switch (local.modeJs) { + + + + /* istanbul ignore next */ + // run node js-env code - init-after + case 'node': + // require modules + local.fs = require('fs'); + local.path = require('path'); + // run the cli + if (module !== require.main || local.global.utility2_rollup) { + break; + } + switch (String(process.argv[2]).toLowerCase()) { + // delete file + case 'delete': + local.contentDelete({ + message: process.argv[4], + url: process.argv[3] + }, function (error) { + // validate no error occurred + console.assert(!error, error); + }); + break; + // get file + case 'get': + local.contentGet({ url: process.argv[3] }, function (error, data) { + // validate no error occurred + console.assert(!error, error); + try { + process.stdout.write(data); + } catch (ignore) { + } + }); + break; + // put file + case 'put': + local.contentPutFile({ + message: process.argv[5], + url: process.argv[3], + file: process.argv[4] + }, function (error) { + // validate no error occurred + console.assert(!error, error); + }); + break; + // touch file + case 'touch': + local.contentTouch({ + message: process.argv[4], + url: process.argv[3] + }, function (error) { + // validate no error occurred + console.assert(!error, error); + }); + break; + case 'touchlist': + local.contentTouchList({ + message: process.argv[4], + urlList: process.argv[3].split(' ').filter(function (element) { + return element; + }) + }, function (error) { + // validate no error occurred + console.assert(!error, error); + }); + break; + } + break; + } +}()); +/* script-end /assets.utility2.lib.github_crud.js */ + + + +/* script-begin /assets.utility2.lib.istanbul.js */ +///usr/bin/env node +/* istanbul instrument in package istanbul */ +/*jslint + bitwise: true, + browser: true, + maxerr: 8, + maxlen: 96, + node: true, + nomen: true, + regexp: true, + stupid: true +*/ +(function (local) { + 'use strict'; + var __dirname, process, require; + + + + // run shared js-env code - init-before + (function () { + // jslint-hack + local.nop(__dirname); + __dirname = ''; + /* istanbul ignore next */ + local.global.__coverageCodeDict__ = local.global.__coverageCodeDict__ || {}; + local['./package.json'] = {}; + process = local.modeJs === 'browser' + ? { + cwd: function () { + return ''; + }, + stdout: {} + } + : local.process; + require = function (key) { + try { + return local[key] || local.require(key); + } catch (ignore) { + } + }; + }()); + + + + // run shared js-env code - function + (function () { + local.coverageMerge = function (coverage1, coverage2) { + /* + * this function will merge coverage2 into coverage1 + */ + var dict1, dict2; + coverage1 = coverage1 || {}; + coverage2 = coverage2 || {}; + Object.keys(coverage2).forEach(function (file) { + if (!coverage2[file]) { + return; + } + // if file is undefined in coverage1, then add it + if (!coverage1[file]) { + coverage1[file] = coverage2[file]; + return; + } + // merge file from coverage2 into coverage1 + ['b', 'f', 's'].forEach(function (key) { + dict1 = coverage1[file][key]; + dict2 = coverage2[file][key]; + switch (key) { + // increment coverage for branch lines + case 'b': + Object.keys(dict2).forEach(function (key) { + dict2[key].forEach(function (count, ii) { + dict1[key][ii] += count; + }); + }); + break; + // increment coverage for function and statement lines + case 'f': + case 's': + Object.keys(dict2).forEach(function (key) { + dict1[key] += dict2[key]; + }); + break; + } + }); + }); + return coverage1; + }; + + local.coverageReportCreate = function () { + /* + * this function will + * 1. print coverage in text-format to stdout + * 2. write coverage in html-format to filesystem + * 3. return coverage in html-format as single document + */ + var options; + /* istanbul ignore next */ + if (!local.global.__coverage__) { + return ''; + } + options = {}; + options.dir = process.cwd() + '/tmp/build/coverage.html'; + // merge previous coverage + if (local.modeJs === 'node' && process.env.npm_config_mode_coverage_merge) { + console.log('merging file://' + options.dir + '/coverage.json to coverage'); + try { + local.coverageMerge( + local.global.__coverage__, + JSON.parse( + local._fs.readFileSync(options.dir + '/coverage.json', 'utf8') + ) + ); + } catch (ignore) { + } + try { + options.coverageCodeDict = JSON.parse(local._fs.readFileSync( + options.dir + '/coverage.code-dict.json', + 'utf8' + )); + Object.keys(options.coverageCodeDict).forEach(function (key) { + local.global.__coverageCodeDict__[key] = + local.global.__coverageCodeDict__[key] || + options.coverageCodeDict[key]; + }); + } catch (ignore) { + } + } + // init writer + local.coverageReportHtml = ''; + local.coverageReportHtml += '
\n' + + '

coverage-report

\n' + + '
\n'; + local.writerData = ''; + options.sourceStore = {}; + options.writer = local.writer; + // 1. print coverage in text-format to stdout + new local.TextReport(options).writeReport(local.collector); + // 2. write coverage in html-format to filesystem + new local.HtmlReport(options).writeReport(local.collector); + local.writer.writeFile('', local.nop); + // write coverage.json + local.fsWriteFileWithMkdirpSync2( + options.dir + '/coverage.json', + JSON.stringify(local.global.__coverage__) + ); + // write coverage.code-dict.json + local.fsWriteFileWithMkdirpSync2( + options.dir + '/coverage.code-dict.json', + JSON.stringify(local.global.__coverageCodeDict__) + ); + // write coverage.badge.svg + options.pct = local.coverageReportSummary.root.metrics.lines.pct; + local.fsWriteFileWithMkdirpSync2( + local.path.dirname(options.dir) + '/coverage.badge.svg', + local.templateCoverageBadgeSvg + // edit coverage badge percent + .replace((/100.0/g), options.pct) + // edit coverage badge color + .replace( + (/0d0/g), + ('0' + Math.round((100 - options.pct) * 2.21).toString(16)).slice(-2) + + ('0' + Math.round(options.pct * 2.21).toString(16)).slice(-2) + '00' + ) + ); + console.log('created coverage file://' + options.dir + '/index.html'); + // 3. return coverage in html-format as a single document + local.coverageReportHtml += '
\n
\n'; + // write coverage.rollup.html + local.fsWriteFileWithMkdirpSync2( + options.dir + '/coverage.rollup.html', + local.coverageReportHtml + ); + return local.coverageReportHtml; + }; + + local.fs = {}; + + local.fs.readFileSync = function (file) { + // return head.txt or foot.txt + file = local[file.slice(-8)]; + if (local.modeJs === 'browser') { + file = file + .replace((/\bhtml\b/g), 'x-istanbul-html') + .replace((/\n\ +\n\ +\n\ +
\n\ +

\n\ + {{env.npm_package_name}} (v{{env.npm_package_version}})\n\ +

\n\ +

Code coverage report for {{entity}}

\n\ +

\n\ + {{#with metrics.statements}}\n\ + Statements: {{pct}}% ({{covered}} / {{total}})     \n\ + {{/with}}\n\ + {{#with metrics.branches}}\n\ + Branches: {{pct}}% ({{covered}} / {{total}})     \n\ + {{/with}}\n\ + {{#with metrics.functions}}\n\ + Functions: {{pct}}% ({{covered}} / {{total}})     \n\ + {{/with}}\n\ + {{#with metrics.lines}}\n\ + Lines: {{pct}}% ({{covered}} / {{total}})     \n\ + {{/with}}\n\ + Ignored: {{#show_ignores metrics}}{{/show_ignores}}     \n\ +

\n\ + {{{pathHtml}}}\n\ +
\n\ +
\n\ +'; +/* jslint-ignore-end */ + + + + /* istanbul ignore next */ + // init lib istanbul.util.file-writer + (function () { + // https://github.com/gotwarlost/istanbul/blob/v0.2.16/lib/util/file-writer.js + local.writer = { + write: function (data) { + local.writerData += data; + }, + writeFile: function (file, onError) { + local.coverageReportHtml += local.writerData + '\n\n'; + if (local.writerFile) { + local.fsWriteFileWithMkdirpSync2(local.writerFile, local.writerData); + } + local.writerData = ''; + local.writerFile = file; + onError(local.writer); + } + }; + }()); + + + + /* istanbul ignore next */ + // init lib istanbul.util.tree-summarizer + (function () { + var module; + module = {}; +/* jslint-ignore-begin */ +// https://github.com/gotwarlost/istanbul/blob/v0.2.16/lib/util/tree-summarizer.js +// utility2-uglifyjs https://raw.githubusercontent.com/gotwarlost/istanbul/v0.2.16/lib/util/tree-summarizer.js +function commonArrayPrefix(e,t){var n=e.length0&&(t.pop(),s=i,o=s.children,s.children=[],i=new +Node(t.join(SEP)+SEP,"dir"),i.addChild(s),o.forEach(function(e){e.kind==="dir"?i +.addChild(e):s.addChild(e)})),this.fixupNodes(i,t.join(SEP)+SEP),this.calculateMetrics +(i),this.root=i,this.map={},this.indexAndSortTree(i,this.map)},fixupNodes:function( +e,t,n){var r=this;e.name.indexOf(t)===0&&(e.name=e.name.substring(t.length)),e.name +.charAt(0)===SEP&&(e.name=e.name.substring(1)),n?n.name!=="__root__/"?e.relativeName= +e.name.substring(n.name.length):e.relativeName=e.name:e.relativeName=e.name.substring +(t.length),e.children.forEach(function(n){r.fixupNodes(n,t,e)})},calculateMetrics +:function(e){var t=this,n;if(e.kind!=="dir")return;e.children.forEach(function(e +){t.calculateMetrics(e)}),e.metrics=utils.mergeSummaryObjects.apply(null,e.children +.map(function(e){return e.metrics})),n=e.children.filter(function(e){return e.kind!=="dir" +}),n.length>0?e.packageMetrics=utils.mergeSummaryObjects.apply(null,n.map(function( +e){return e.metrics})):e.packageMetrics=null},indexAndSortTree:function(e,t){var n= +this;t[e.name]=e,e.children.sort(function(e,t){return e=e.relativeName,t=t.relativeName +,et?1:0}),e.children.forEach(function(e){n.indexAndSortTree(e,t)})},toJSON +:function(){return{prefix:this.prefix,root:this.root.toJSON()}}},TreeSummarizer. +prototype={addFileCoverageSummary:function(e,t){this.summaryMap[e]=t},getTreeSummary +:function(){var e=findCommonArrayPrefix(Object.keys(this.summaryMap));return new +TreeSummary(this.summaryMap,e)}},module.exports=TreeSummarizer +/* jslint-ignore-end */ + local['../util/tree-summarizer'] = module.exports; + module.exports.prototype._getTreeSummary = module.exports.prototype.getTreeSummary; + module.exports.prototype.getTreeSummary = function () { + local.coverageReportSummary = this._getTreeSummary(); + return local.coverageReportSummary; + }; + }()); + + + +/* istanbul ignore next */ +// init lib istanbul.report.html +/* jslint-ignore-begin */ +// https://github.com/gotwarlost/istanbul/blob/v0.2.16/lib/report/html.js +// utility2-uglifyjs https://raw.githubusercontent.com/gotwarlost/istanbul/v0.2.16/lib/report/html.js +(function () { var module; module = {}; +function customEscape(e){return e=e.toString(),e.replace(RE_AMP,"&").replace +(RE_LT,"<").replace(RE_GT,">").replace(RE_lt,"<").replace(RE_gt,">")}function title +(e){return' title="'+e+'" '}function annotateLines(e,t){var n=e.l;if(!n)return;Object +.keys(n).forEach(function(e){var r=n[e];t[e].covered=r>0?"yes":"no"}),t.forEach( +function(e){e.covered===null&&(e.covered="neutral")})}function annotateStatements +(e,t){var n=e.s,r=e.statementMap;Object.keys(n).forEach(function(e){var i=n[e],s= +r[e],o=i>0?"yes":"no",u=s.start.column,a=s.end.column+1,f=s.start.line,l=s.end.line +,c=lt+'span class="'+(s.skip?"cstat-skip":"cstat-no")+'"'+title("statement not covered" +)+gt,h=lt+"/span"+gt,p;o==="no"&&(l!==f&&(l=f,a=t[f].text.originalLength()),p=t[ +f].text,p.wrap(u,c,f===l?a:p.originalLength(),h))})}function annotateFunctions(e +,t){var n=e.f,r=e.fnMap;if(!n)return;Object.keys(n).forEach(function(e){var i=n[ +e],s=r[e],o=i>0?"yes":"no",u=s.loc.start.column,a=s.loc.end.column+1,f=s.loc.start +.line,l=s.loc.end.line,c=lt+'span class="'+(s.skip?"fstat-skip":"fstat-no")+'"'+ +title("function not covered")+gt,h=lt+"/span"+gt,p;o==="no"&&(l!==f&&(l=f,a=t[f] +.text.originalLength()),p=t[f].text,p.wrap(u,c,f===l?a:p.originalLength(),h))})} +function annotateBranches(e,t){var n=e.b,r=e.branchMap;if(!n)return;Object.keys( +n).forEach(function(e){var i=n[e],s=i.reduce(function(e,t){return e+t},0),o=r[e] +.locations,u,a,f,l,c,h,p,d,v,m,g;if(s>0)for(u=0;u0?"yes":"no",c=f.start.column,h=f.end.column+1,p=f.start.line,d=f.end.line,v=lt+'span class="branch-'+ +u+" "+(f.skip?"cbranch-skip":"cbranch-no")+'"'+title("branch not covered")+gt,m= +lt+"/span"+gt,a===0&&(d!==p&&(d=p,h=t[p].text.originalLength()),g=t[p].text,r[e] +.type==="if"?g.insertAt(c,lt+'span class="'+(f.skip?"skip-if-branch":"missing-if-branch" +)+'"'+title((u===0?"if":"else")+" path not taken")+gt+(u===0?"I":"E")+lt+"/span"+ +gt,!0,!1):g.wrap(c,v,p===d?h:g.originalLength(),m))})}function getReportClass(e, +t){var n=e.pct,r=1;return n*r===n?n>=t[1]?"high":n>=t[0]?"medium":"low":""}function HtmlReport +(e){Report.call(this),this.opts=e||{},this.opts.dir=this.opts.dir||path.resolve( +process.cwd(),"html-report"),this.opts.sourceStore=this.opts.sourceStore||Store. +create("fslookup"),this.opts.linkMapper=this.opts.linkMapper||this.standardLinkMapper +(),this.opts.writer=this.opts.writer||null,this.opts.templateData={datetime:Date +()},this.opts.watermarks=this.opts.watermarks||defaults.watermarks()}var handlebars= +require("handlebars"),defaults=require("./common/defaults"),path=require("path") +,SEP=path.sep||"/",fs=require("fs"),util=require("util"),FileWriter=require("../util/file-writer" +),Report=require("./index"),Store=require("../store"),InsertionText=require("../util/insertion-text" +),TreeSummarizer=require("../util/tree-summarizer"),utils=require("../object-utils" +),templateFor=function(e){return handlebars.compile(fs.readFileSync(path.resolve +(__dirname,"templates",e+".txt"),"utf8"))},headerTemplate=templateFor("head"),footerTemplate= +templateFor("foot"),pathTemplate=handlebars.compile('
{{{html}}}
' +),detailTemplate=handlebars.compile(["",'{{#show_lines}}{{maxLines}}{{/show_lines}}' +,'{{#show_line_execution_counts fileCoverage}}{{maxLines}}{{/show_line_execution_counts}}' +,'
{{#show_code structured}}{{/show_code}}
' +,"\n"].join("")),summaryTableHeader=['
',"" +,"","",' ' +,' ' +,' ' +,' ' +,' ' +,' ' +,' ' +,' ' +,' ' +,' ' +,"","",""].join("\n"),summaryLineTemplate=handlebars.compile +(["",'' +,'' +,'' +,'' +,'' +,'' +,'' +,'' +,'' +,'' +,"\n"].join("\n ")),summaryTableFooter=["","
FileStatementsBranchesFunctionsLines
{{file}}{{#show_picture}}{{metrics.statements.pct}}{{/show_picture}}{{metrics.statements.pct}}%({{metrics.statements.covered}} / {{metrics.statements.total}}){{metrics.branches.pct}}%({{metrics.branches.covered}} / {{metrics.branches.total}}){{metrics.functions.pct}}%({{metrics.functions.covered}} / {{metrics.functions.total}}){{metrics.lines.pct}}%({{metrics.lines.covered}} / {{metrics.lines.total}})
","
"].join +("\n"),lt="",gt="",RE_LT=//g,RE_AMP=/&/g,RE_lt=/\u0001/g,RE_gt=/\u0002/g +;handlebars.registerHelper("show_picture",function(e){var t=Number(e.fn(this)),n +,r="";return isFinite(t)?(t===100&&(r=" cover-full"),t=Math.floor(t),n=100-t,''+''):""}),handlebars.registerHelper("show_ignores",function(e){var t= +e.statements.skipped,n=e.functions.skipped,r=e.branches.skipped,i;return t===0&& +n===0&&r===0?'none':(i=[],t>0&&i.push(t===1?"1 statement" +:t+" statements"),n>0&&i.push(n===1?"1 function":n+" functions"),r>0&&i.push(r===1?"1 branch" +:r+" branches"),i.join(", "))}),handlebars.registerHelper("show_lines",function( +e){var t=Number(e.fn(this)),n,r=[];for(n=0;n0?(u="yes",a=n[s]):u="no"),o.push(''+a+"");return o.join("\n")}),handlebars.registerHelper("show_code", +function(e){var t=[];return e.forEach(function(e){t.push(customEscape(e.text)||" " +)}),t.join("\n")}),HtmlReport.TYPE="html",util.inherits(HtmlReport,Report),Report +.mix(HtmlReport,{getPathHtml:function(e,t){var n=e.parent,r=[],i=[],s;while(n)r. +push(n),n=n.parent;for(s=0;s'+ +(r[s].relativeName||"All files")+"");return i.reverse(),i.length>0?i.join(" » " +)+" » "+e.displayShortName():""},fillTemplate:function(e,t){var n=this.opts +,r=n.linkMapper;t.entity=e.name||"All files",t.metrics=e.metrics,t.reportClass=getReportClass +(e.metrics.statements,n.watermarks.statements),t.pathHtml=pathTemplate({html:this +.getPathHtml(e,r)}),t.prettify={js:r.asset(e,"prettify.js"),css:r.asset(e,"prettify.css" +)}},writeDetailPage:function(e,t,n){var r=this.opts,i=r.sourceStore,s=r.templateData +,o=n.code&&Array.isArray(n.code)?n.code.join("\n")+"\n":i.get(n.path),u=o.split(/(?:\r?\n)|\r/ +),a=0,f=u.map(function(e){return a+=1,{line:a,covered:null,text:new InsertionText +(e,!0)}}),l;f.unshift({line:0,covered:null,text:new InsertionText("")}),this.fillTemplate +(t,s),e.write(headerTemplate(s)),e.write('
\n'),annotateLines
+(n,f),annotateBranches(n,f),annotateFunctions(n,f),annotateStatements(n,f),f.shift
+(),l={structured:f,maxLines:f.length,fileCoverage:n},e.write(detailTemplate(l)),
+e.write("
\n"),e.write(footerTemplate(s))},writeIndexPage:function( +e,t){var n=this.opts.linkMapper,r=this.opts.templateData,i=Array.prototype.slice +.apply(t.children),s=this.opts.watermarks;i.sort(function(e,t){return e.name0&&(o>=l?(f=padding(o-l),a=n?f+e: +e+f):(a=e.substring(l-o),a="... "+a.substring(4))),a=defaults.colorize(a,i),u+a} +function formatName(e,t,n,r){return fill(e,t,!1,n,r)}function formatPct(e,t){return fill +(e,PCT_COLS,!0,0,t)}function nodeName(e){return e.displayShortName()||"All files" +}function tableHeader(e){var t=[];return t.push(formatName("File",e,0)),t.push(formatPct +("% Stmts")),t.push(formatPct("% Branches")),t.push(formatPct("% Funcs")),t.push +(formatPct("% Lines")),t.join(" |")+" |"}function tableRow(e,t,n,r){var i=nodeName +(e),s=e.metrics.statements.pct,o=e.metrics.branches.pct,u=e.metrics.functions.pct +,a=e.metrics.lines.pct,f=[];return f.push(formatName(i,t,n,defaults.classFor("statements" +,e.metrics,r))),f.push(formatPct(s,defaults.classFor("statements",e.metrics,r))) +,f.push(formatPct(o,defaults.classFor("branches",e.metrics,r))),f.push(formatPct +(u,defaults.classFor("functions",e.metrics,r))),f.push(formatPct(a,defaults.classFor +("lines",e.metrics,r))),f.join(DELIM)+DELIM}function findNameWidth(e,t,n){n=n||0 +,t=t||0;var r=TAB_SIZE*t+nodeName(e).length;return r>n&&(n=r),e.children.forEach +(function(e){n=findNameWidth(e,t+1,n)}),n}function makeLine(e){var t=padding(e,"-" +),n=padding(PCT_COLS,"-"),r=[];return r.push(t),r.push(n),r.push(n),r.push(n),r. +push(n),r.join(COL_DELIM)+COL_DELIM}function walk(e,t,n,r,i){var s;r===0?(s=makeLine +(t),n.push(s),n.push(tableHeader(t)),n.push(s)):n.push(tableRow(e,t,r,i)),e.children +.forEach(function(e){walk(e,t,n,r+1,i)}),r===0&&(n.push(s),n.push(tableRow(e,t,r +,i)),n.push(s))}var path=require("path"),mkdirp=require("mkdirp"),fs=require("fs" +),defaults=require("./common/defaults"),Report=require("./index"),TreeSummarizer= +require("../util/tree-summarizer"),utils=require("../object-utils"),PCT_COLS=10, +TAB_SIZE=3,DELIM=" |",COL_DELIM="-|";TextReport.TYPE="text",Report.mix(TextReport +,{writeReport:function(e){var t=new TreeSummarizer,n,r,i,s=4*(PCT_COLS+2),o,u=[] +,a;e.files().forEach(function(n){t.addFileCoverageSummary(n,utils.summarizeFileCoverage +(e.fileCoverageFor(n)))}),n=t.getTreeSummary(),r=n.root,i=findNameWidth(r),this. +maxCols>0&&(o=this.maxCols-s-2,i>o&&(i=o)),walk(r,i,u,0,this.watermarks),a=u.join +("\n")+"\n",this.file?(mkdirp.sync(this.dir),fs.writeFileSync(path.join(this.dir +,this.file),a,"utf8")):console.log(a)}}),module.exports=TextReport +local.TextReport = module.exports; }()); +/* jslint-ignore-end */ + + + +/* jslint-ignore-begin */ +// https://img.shields.io/badge/coverage-100.0%-00dd00.svg?style=flat +local.templateCoverageBadgeSvg = +'coveragecoverage100.0%100.0%'; +/* jslint-ignore-end */ + switch (local.modeJs) { + + + + // run node js-env code - init-after + case 'node': + /* istanbul ignore next */ + // run the cli + local.cliRunIstanbul = function (options) { + /* + * this function will run the cli + */ + var tmp; + if ((module !== local.require.main || local.global.utility2_rollup) && + !(options && options.runMain)) { + return; + } + switch (process.argv[2]) { + // transparently adds coverage information to a node command + case 'cover': + try { + tmp = JSON.parse(local._fs.readFileSync('package.json', 'utf8')); + process.env.npm_package_nameAlias = process.env.npm_package_nameAlias || + tmp.nameAlias || + tmp.name.replace((/-/g), '_'); + } catch (ignore) { + } + process.env.npm_config_mode_coverage = process.env.npm_config_mode_coverage || + process.env.npm_package_nameAlias || + 'all'; + // add coverage hook to require + local._moduleExtensionsJs = local.module._extensions['.js']; + local.module._extensions['.js'] = function (module, file) { + if (typeof file === 'string' && + (file.indexOf(process.env.npm_config_mode_coverage_dir) === 0 || ( + file.indexOf(process.cwd()) === 0 && + file.indexOf(process.cwd() + '/node_modules/') !== 0 + ))) { + module._compile(local.instrumentInPackage( + local._fs.readFileSync(file, 'utf8'), + file + ), file); + return; + } + local._moduleExtensionsJs(module, file); + }; + // init process.argv + process.argv.splice(1, 2); + process.argv[1] = local.path.resolve(process.cwd(), process.argv[1]); + console.log('\ncovering $ ' + process.argv.join(' ')); + // create coverage on exit + process.on('exit', function () { + local.coverageReportCreate({ coverage: local.global.__coverage__ }); + }); + // re-run cli + local.module.runMain(); + break; + // instrument a file and print result to stdout + case 'instrument': + process.argv[3] = local.path.resolve(process.cwd(), process.argv[3]); + process.stdout.write(local.instrumentSync( + local._fs.readFileSync(process.argv[3], 'utf8'), + process.argv[3] + )); + break; + // cover a node command only when npm_config_mode_coverage is set + case 'test': + if (process.env.npm_config_mode_coverage) { + process.argv[2] = 'cover'; + // re-run cli + local.cliRunIstanbul(options); + return; + } + // init process.argv + process.argv.splice(1, 2); + process.argv[1] = local.path.resolve(process.cwd(), process.argv[1]); + // re-run cli + local.module.runMain(); + break; + } + }; + local.cliRunIstanbul(); + break; + } +}( + // run shared js-env code - init-before + (function () { + 'use strict'; + var local; + // init local + local = {}; + // init modeJs + local.modeJs = (function () { + try { + return typeof navigator.userAgent === 'string' && + typeof document.querySelector('body') === 'object' && + typeof XMLHttpRequest.prototype.open === 'function' && + 'browser'; + } catch (errorCaughtBrowser) { + return module.exports && + typeof process.versions.node === 'string' && + typeof require('http').createServer === 'function' && + 'node'; + } + }()); + // init global + local.global = local.modeJs === 'browser' + ? window + : global; + // init utility2_rollup + local = local.global.utility2_rollup || local; + // init lib + local.local = local.istanbul = local; + // init exports + if (local.modeJs === 'browser') { + local.global.utility2_istanbul = local; + } else { + module.exports = local; + module.exports.__dirname = __dirname; + } + local.fsWriteFileWithMkdirpSync = function (file, data) { + /* + * this function will synchronously 'mkdir -p' and write the data to file + */ + // try to write to file + try { + require('fs').writeFileSync(file, data); + } catch (errorCaught) { + // mkdir -p + require('child_process').spawnSync( + 'mkdir', + ['-p', require('path').dirname(file)], + { stdio: ['ignore', 1, 2] } + ); + // re-write to file + require('fs').writeFileSync(file, data); + } + }; + local.nop = function () { + /* + * this function will do nothing + */ + return; + }; + switch (local.modeJs) { + case 'browser': + local.fsWriteFileWithMkdirpSync2 = local.nop; + break; + case 'node': + local.fsWriteFileWithMkdirpSync2 = local.fsWriteFileWithMkdirpSync; + local.__dirname = __dirname; + local.process = process; + local.require = require; + break; + } + return local; + }()) +)); +/* script-end /assets.utility2.lib.istanbul.js */ + + + +/* script-begin /assets.utility2.lib.jslint.js */ +///usr/bin/env node +/* istanbul instrument in package jslint */ +/*jslint + bitwise: true, + browser: true, + maxerr: 8, + maxlen: 96, + node: true, + nomen: true, + regexp: true, + stupid: true +*/ +(function () { + 'use strict'; + var local; + + + + // run shared js-env code - init-before + (function () { + // init local + local = {}; + // init modeJs + local.modeJs = (function () { + try { + return typeof navigator.userAgent === 'string' && + typeof document.querySelector('body') === 'object' && + typeof XMLHttpRequest.prototype.open === 'function' && + 'browser'; + } catch (errorCaughtBrowser) { + return module.exports && + typeof process.versions.node === 'string' && + typeof require('http').createServer === 'function' && + 'node'; + } + }()); + // init global + local.global = local.modeJs === 'browser' + ? window + : global; + // init utility2_rollup + local = local.global.utility2_rollup || local; + // init lib + local.local = local.jslint = local; + // init exports + if (local.modeJs === 'browser') { + local.global.utility2_jslint = local; + } else { + module.exports = local; + module.exports.__dirname = __dirname; + module.exports.module = module; + } + }()); + + + +/* jslint-ignore-begin */ +/* istanbul ignore next */ +// init lib csslint +// https://github.com/CSSLint/csslint/blob/v0.10.0/release/csslint.js +// utility2-uglifyjs https://raw.githubusercontent.com/CSSLint/csslint/v0.10.0/release/csslint.js +(function () { +var exports=exports||{},CSSLint=function(){function Reporter(e,t){this.messages= +[],this.stats=[],this.lines=e,this.ruleset=t}var parserlib={};(function(){function e +(){this._listeners={}}function t(e){this._input=e.replace(/\n\r?/g,"\n"),this._line=1 +,this._col=1,this._cursor=0}function n(e,t,n){this.col=n,this.line=t,this.message= +e}function r(e,t,n,r){this.col=n,this.line=t,this.text=e,this.type=r}function i( +e,n){this._reader=e?new t(e.toString()):null,this._token=null,this._tokenData=n, +this._lt=[],this._ltIndex=0,this._ltIndexCache=[]}e.prototype={constructor:e,addListener +:function(e,t){this._listeners[e]||(this._listeners[e]=[]),this._listeners[e].push +(t)},fire:function(e){typeof e=="string"&&(e={type:e}),typeof e.target!="undefined"&& +(e.target=this);if(typeof e.type=="undefined")throw new Error("Event object missing 'type' property." +);if(this._listeners[e.type]){var t=this._listeners[e.type].concat();for(var n=0 +,r=t.length;n=0&& +this._ltIndex-1&&!t[u.type].hide&& +(u.channel=t[u.type].channel,this._token=u,this._lt.push(u),this._ltIndexCache.push +(this._lt.length-this._ltIndex+i),this._lt.length>5&&this._lt.shift(),this._ltIndexCache +.length>5&&this._ltIndexCache.shift(),this._ltIndex=this._lt.length),a=t[u.type] +,a&&(a.hide||a.channel!==undefined&&e!==a.channel)?this.get(e):u.type},LA:function( +e){var t=e,n;if(e>0){if(e>5)throw new Error("Too much lookahead.");while(t)n=this +.get(),t--;while(tthis._tokenData.length?"UNKNOWN_TOKEN":this._tokenData +[e].name},tokenType:function(e){return this._tokenData[e]||-1},unget:function(){ +if(!this._ltIndexCache.length)throw new Error("Too much lookahead.");this._ltIndex-= +this._ltIndexCache.pop(),this._token=this._lt[this._ltIndex-1]}},parserlib.util= +{StringReader:t,SyntaxError:n,SyntaxUnit:r,EventTarget:e,TokenStreamBase:i}})(), +function(){function Combinator(e,t,n){SyntaxUnit.call(this,e,t,n,Parser.COMBINATOR_TYPE +),this.type="unknown",/^\s+$/.test(e)?this.type="descendant":e==">"?this.type="child" +:e=="+"?this.type="adjacent-sibling":e=="~"&&(this.type="sibling")}function MediaFeature +(e,t){SyntaxUnit.call(this,"("+e+(t!==null?":"+t:"")+")",e.startLine,e.startCol, +Parser.MEDIA_FEATURE_TYPE),this.name=e,this.value=t}function MediaQuery(e,t,n,r, +i){SyntaxUnit.call(this,(e?e+" ":"")+(t?t:"")+(t&&n.length>0?" and ":"")+n.join(" and " +),r,i,Parser.MEDIA_QUERY_TYPE),this.modifier=e,this.mediaType=t,this.features=n} +function Parser(e){EventTarget.call(this),this.options=e||{},this._tokenStream=null +}function PropertyName(e,t,n,r){SyntaxUnit.call(this,e,n,r,Parser.PROPERTY_NAME_TYPE +),this.hack=t}function PropertyValue(e,t,n){SyntaxUnit.call(this,e.join(" "),t,n +,Parser.PROPERTY_VALUE_TYPE),this.parts=e}function PropertyValueIterator(e){this +._i=0,this._parts=e.parts,this._marks=[],this.value=e}function PropertyValuePart +(text,line,col){SyntaxUnit.call(this,text,line,col,Parser.PROPERTY_VALUE_PART_TYPE +),this.type="unknown";var temp;if(/^([+\-]?[\d\.]+)([a-z]+)$/i.test(text)){this. +type="dimension",this.value=+RegExp.$1,this.units=RegExp.$2;switch(this.units.toLowerCase +()){case"em":case"rem":case"ex":case"px":case"cm":case"mm":case"in":case"pt":case"pc" +:case"ch":case"vh":case"vw":case"vm":this.type="length";break;case"deg":case"rad" +:case"grad":this.type="angle";break;case"ms":case"s":this.type="time";break;case"hz" +:case"khz":this.type="frequency";break;case"dpi":case"dpcm":this.type="resolution" +}}else/^([+\-]?[\d\.]+)%$/i.test(text)?(this.type="percentage",this.value=+RegExp +.$1):/^([+\-]?[\d\.]+)%$/i.test(text)?(this.type="percentage",this.value=+RegExp +.$1):/^([+\-]?\d+)$/i.test(text)?(this.type="integer",this.value=+RegExp.$1):/^([+\-]?[\d\.]+)$/i +.test(text)?(this.type="number",this.value=+RegExp.$1):/^#([a-f0-9]{3,6})/i.test +(text)?(this.type="color",temp=RegExp.$1,temp.length==3?(this.red=parseInt(temp. +charAt(0)+temp.charAt(0),16),this.green=parseInt(temp.charAt(1)+temp.charAt(1),16 +),this.blue=parseInt(temp.charAt(2)+temp.charAt(2),16)):(this.red=parseInt(temp. +substring(0,2),16),this.green=parseInt(temp.substring(2,4),16),this.blue=parseInt +(temp.substring(4,6),16))):/^rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/i.test(text +)?(this.type="color",this.red=+RegExp.$1,this.green=+RegExp.$2,this.blue=+RegExp +.$3):/^rgb\(\s*(\d+)%\s*,\s*(\d+)%\s*,\s*(\d+)%\s*\)/i.test(text)?(this.type="color" +,this.red=+RegExp.$1*255/100,this.green=+RegExp.$2*255/100,this.blue=+RegExp.$3*255/100 +):/^rgba\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*([\d\.]+)\s*\)/i.test(text)?(this +.type="color",this.red=+RegExp.$1,this.green=+RegExp.$2,this.blue=+RegExp.$3,this +.alpha=+RegExp.$4):/^rgba\(\s*(\d+)%\s*,\s*(\d+)%\s*,\s*(\d+)%\s*,\s*([\d\.]+)\s*\)/i +.test(text)?(this.type="color",this.red=+RegExp.$1*255/100,this.green=+RegExp.$2*255/100 +,this.blue=+RegExp.$3*255/100,this.alpha=+RegExp.$4):/^hsl\(\s*(\d+)\s*,\s*(\d+)%\s*,\s*(\d+)%\s*\)/i +.test(text)?(this.type="color",this.hue=+RegExp.$1,this.saturation=+RegExp.$2/100 +,this.lightness=+RegExp.$3/100):/^hsla\(\s*(\d+)\s*,\s*(\d+)%\s*,\s*(\d+)%\s*,\s*([\d\.]+)\s*\)/i +.test(text)?(this.type="color",this.hue=+RegExp.$1,this.saturation=+RegExp.$2/100 +,this.lightness=+RegExp.$3/100,this.alpha=+RegExp.$4):/^url\(["']?([^\)"']+)["']?\)/i +.test(text)?(this.type="uri",this.uri=RegExp.$1):/^([^\(]+)\(/i.test(text)?(this +.type="function",this.name=RegExp.$1,this.value=text):/^["'][^"']*["']/.test(text +)?(this.type="string",this.value=eval(text)):Colors[text.toLowerCase()]?(this.type="color" +,temp=Colors[text.toLowerCase()].substring(1),this.red=parseInt(temp.substring(0 +,2),16),this.green=parseInt(temp.substring(2,4),16),this.blue=parseInt(temp.substring +(4,6),16)):/^[\,\/]$/.test(text)?(this.type="operator",this.value=text):/^[a-z\-\u0080-\uFFFF][a-z0-9\-\u0080-\uFFFF]*$/i +.test(text)&&(this.type="identifier",this.value=text)}function Selector(e,t,n){SyntaxUnit +.call(this,e.join(" "),t,n,Parser.SELECTOR_TYPE),this.parts=e,this.specificity=Specificity +.calculate(this)}function SelectorPart(e,t,n,r,i){SyntaxUnit.call(this,n,r,i,Parser +.SELECTOR_PART_TYPE),this.elementName=e,this.modifiers=t}function SelectorSubPart +(e,t,n,r){SyntaxUnit.call(this,e,n,r,Parser.SELECTOR_SUB_PART_TYPE),this.type=t, +this.args=[]}function Specificity(e,t,n,r){this.a=e,this.b=t,this.c=n,this.d=r}function isHexDigit +(e){return e!==null&&h.test(e)}function isDigit(e){return e!==null&&/\d/.test(e) +}function isWhitespace(e){return e!==null&&/\s/.test(e)}function isNewLine(e){return e!== +null&&nl.test(e)}function isNameStart(e){return e!==null&&/[a-z_\u0080-\uFFFF\\]/i +.test(e)}function isNameChar(e){return e!==null&&(isNameStart(e)||/[0-9\-\\]/.test +(e))}function isIdentStart(e){return e!==null&&(isNameStart(e)||/\-\\/.test(e))} +function mix(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);return e}function TokenStream +(e){TokenStreamBase.call(this,e,Tokens)}function ValidationError(e,t,n){this.col= +n,this.line=t,this.message=e}var EventTarget=parserlib.util.EventTarget,TokenStreamBase= +parserlib.util.TokenStreamBase,StringReader=parserlib.util.StringReader,SyntaxError= +parserlib.util.SyntaxError,SyntaxUnit=parserlib.util.SyntaxUnit,Colors={aliceblue +:"#f0f8ff",antiquewhite:"#faebd7",aqua:"#00ffff",aquamarine:"#7fffd4",azure:"#f0ffff" +,beige:"#f5f5dc",bisque:"#ffe4c4",black:"#000000",blanchedalmond:"#ffebcd",blue:"#0000ff" +,blueviolet:"#8a2be2",brown:"#a52a2a",burlywood:"#deb887",cadetblue:"#5f9ea0",chartreuse +:"#7fff00",chocolate:"#d2691e",coral:"#ff7f50",cornflowerblue:"#6495ed",cornsilk +:"#fff8dc",crimson:"#dc143c",cyan:"#00ffff",darkblue:"#00008b",darkcyan:"#008b8b" +,darkgoldenrod:"#b8860b",darkgray:"#a9a9a9",darkgreen:"#006400",darkkhaki:"#bdb76b" +,darkmagenta:"#8b008b",darkolivegreen:"#556b2f",darkorange:"#ff8c00",darkorchid:"#9932cc" +,darkred:"#8b0000",darksalmon:"#e9967a",darkseagreen:"#8fbc8f",darkslateblue:"#483d8b" +,darkslategray:"#2f4f4f",darkturquoise:"#00ced1",darkviolet:"#9400d3",deeppink:"#ff1493" +,deepskyblue:"#00bfff",dimgray:"#696969",dodgerblue:"#1e90ff",firebrick:"#b22222" +,floralwhite:"#fffaf0",forestgreen:"#228b22",fuchsia:"#ff00ff",gainsboro:"#dcdcdc" +,ghostwhite:"#f8f8ff",gold:"#ffd700",goldenrod:"#daa520",gray:"#808080",green:"#008000" +,greenyellow:"#adff2f",honeydew:"#f0fff0",hotpink:"#ff69b4",indianred:"#cd5c5c", +indigo:"#4b0082",ivory:"#fffff0",khaki:"#f0e68c",lavender:"#e6e6fa",lavenderblush +:"#fff0f5",lawngreen:"#7cfc00",lemonchiffon:"#fffacd",lightblue:"#add8e6",lightcoral +:"#f08080",lightcyan:"#e0ffff",lightgoldenrodyellow:"#fafad2",lightgray:"#d3d3d3" +,lightgreen:"#90ee90",lightpink:"#ffb6c1",lightsalmon:"#ffa07a",lightseagreen:"#20b2aa" +,lightskyblue:"#87cefa",lightslategray:"#778899",lightsteelblue:"#b0c4de",lightyellow +:"#ffffe0",lime:"#00ff00",limegreen:"#32cd32",linen:"#faf0e6",magenta:"#ff00ff", +maroon:"#800000",mediumaquamarine:"#66cdaa",mediumblue:"#0000cd",mediumorchid:"#ba55d3" +,mediumpurple:"#9370d8",mediumseagreen:"#3cb371",mediumslateblue:"#7b68ee",mediumspringgreen +:"#00fa9a",mediumturquoise:"#48d1cc",mediumvioletred:"#c71585",midnightblue:"#191970" +,mintcream:"#f5fffa",mistyrose:"#ffe4e1",moccasin:"#ffe4b5",navajowhite:"#ffdead" +,navy:"#000080",oldlace:"#fdf5e6",olive:"#808000",olivedrab:"#6b8e23",orange:"#ffa500" +,orangered:"#ff4500",orchid:"#da70d6",palegoldenrod:"#eee8aa",palegreen:"#98fb98" +,paleturquoise:"#afeeee",palevioletred:"#d87093",papayawhip:"#ffefd5",peachpuff:"#ffdab9" +,peru:"#cd853f",pink:"#ffc0cb",plum:"#dda0dd",powderblue:"#b0e0e6",purple:"#800080" +,red:"#ff0000",rosybrown:"#bc8f8f",royalblue:"#4169e1",saddlebrown:"#8b4513",salmon +:"#fa8072",sandybrown:"#f4a460",seagreen:"#2e8b57",seashell:"#fff5ee",sienna:"#a0522d" +,silver:"#c0c0c0",skyblue:"#87ceeb",slateblue:"#6a5acd",slategray:"#708090",snow +:"#fffafa",springgreen:"#00ff7f",steelblue:"#4682b4",tan:"#d2b48c",teal:"#008080" +,thistle:"#d8bfd8",tomato:"#ff6347",turquoise:"#40e0d0",violet:"#ee82ee",wheat:"#f5deb3" +,white:"#ffffff",whitesmoke:"#f5f5f5",yellow:"#ffff00",yellowgreen:"#9acd32",activeBorder +:"Active window border.",activecaption:"Active window caption.",appworkspace:"Background color of multiple document interface." +,background:"Desktop background.",buttonface:"The face background color for 3-D elements that appear 3-D due to one layer of surrounding border." +,buttonhighlight:"The color of the border facing the light source for 3-D elements that appear 3-D due to one layer of surrounding border." +,buttonshadow:"The color of the border away from the light source for 3-D elements that appear 3-D due to one layer of surrounding border." +,buttontext:"Text on push buttons.",captiontext:"Text in caption, size box, and scrollbar arrow box." +,graytext:"Grayed (disabled) text. This color is set to #000 if the current display driver does not support a solid gray color." +,highlight:"Item(s) selected in a control.",highlighttext:"Text of item(s) selected in a control." +,inactiveborder:"Inactive window border.",inactivecaption:"Inactive window caption." +,inactivecaptiontext:"Color of text in an inactive caption.",infobackground:"Background color for tooltip controls." +,infotext:"Text color for tooltip controls.",menu:"Menu background.",menutext:"Text in menus." +,scrollbar:"Scroll bar gray area.",threeddarkshadow:"The color of the darker (generally outer) of the two borders away from the light source for 3-D elements that appear 3-D due to two concentric layers of surrounding border." +,threedface:"The face background color for 3-D elements that appear 3-D due to two concentric layers of surrounding border." +,threedhighlight:"The color of the lighter (generally outer) of the two borders facing the light source for 3-D elements that appear 3-D due to two concentric layers of surrounding border." +,threedlightshadow:"The color of the darker (generally inner) of the two borders facing the light source for 3-D elements that appear 3-D due to two concentric layers of surrounding border." +,threedshadow:"The color of the lighter (generally inner) of the two borders away from the light source for 3-D elements that appear 3-D due to two concentric layers of surrounding border." +,window:"Window background.",windowframe:"Window frame.",windowtext:"Text in windows." +};Combinator.prototype=new SyntaxUnit,Combinator.prototype.constructor=Combinator +,MediaFeature.prototype=new SyntaxUnit,MediaFeature.prototype.constructor=MediaFeature +,MediaQuery.prototype=new SyntaxUnit,MediaQuery.prototype.constructor=MediaQuery +,Parser.DEFAULT_TYPE=0,Parser.COMBINATOR_TYPE=1,Parser.MEDIA_FEATURE_TYPE=2,Parser +.MEDIA_QUERY_TYPE=3,Parser.PROPERTY_NAME_TYPE=4,Parser.PROPERTY_VALUE_TYPE=5,Parser +.PROPERTY_VALUE_PART_TYPE=6,Parser.SELECTOR_TYPE=7,Parser.SELECTOR_PART_TYPE=8,Parser +.SELECTOR_SUB_PART_TYPE=9,Parser.prototype=function(){var e=new EventTarget,t,n= +{constructor:Parser,DEFAULT_TYPE:0,COMBINATOR_TYPE:1,MEDIA_FEATURE_TYPE:2,MEDIA_QUERY_TYPE +:3,PROPERTY_NAME_TYPE:4,PROPERTY_VALUE_TYPE:5,PROPERTY_VALUE_PART_TYPE:6,SELECTOR_TYPE +:7,SELECTOR_PART_TYPE:8,SELECTOR_SUB_PART_TYPE:9,_stylesheet:function(){var e=this +._tokenStream,t=null,n,r,i;this.fire("startstylesheet"),this._charset(),this._skipCruft +();while(e.peek()==Tokens.IMPORT_SYM)this._import(),this._skipCruft();while(e.peek +()==Tokens.NAMESPACE_SYM)this._namespace(),this._skipCruft();i=e.peek();while(i> +Tokens.EOF){try{switch(i){case Tokens.MEDIA_SYM:this._media(),this._skipCruft(); +break;case Tokens.PAGE_SYM:this._page(),this._skipCruft();break;case Tokens.FONT_FACE_SYM +:this._font_face(),this._skipCruft();break;case Tokens.KEYFRAMES_SYM:this._keyframes +(),this._skipCruft();break;case Tokens.VIEWPORT_SYM:this._viewport(),this._skipCruft +();break;case Tokens.UNKNOWN_SYM:e.get();if(!!this.options.strict)throw new SyntaxError +("Unknown @ rule.",e.LT(0).startLine,e.LT(0).startCol);this.fire({type:"error",error +:null,message:"Unknown @ rule: "+e.LT(0).value+".",line:e.LT(0).startLine,col:e. +LT(0).startCol}),n=0;while(e.advance([Tokens.LBRACE,Tokens.RBRACE])==Tokens.LBRACE +)n++;while(n)e.advance([Tokens.RBRACE]),n--;break;case Tokens.S:this._readWhitespace +();break;default:if(!this._ruleset())switch(i){case Tokens.CHARSET_SYM:throw r=e +.LT(1),this._charset(!1),new SyntaxError("@charset not allowed here.",r.startLine +,r.startCol);case Tokens.IMPORT_SYM:throw r=e.LT(1),this._import(!1),new SyntaxError +("@import not allowed here.",r.startLine,r.startCol);case Tokens.NAMESPACE_SYM:throw r= +e.LT(1),this._namespace(!1),new SyntaxError("@namespace not allowed here.",r.startLine +,r.startCol);default:e.get(),this._unexpectedToken(e.token())}}}catch(s){if(!(s instanceof +SyntaxError&&!this.options.strict))throw s;this.fire({type:"error",error:s,message +:s.message,line:s.line,col:s.col})}i=e.peek()}i!=Tokens.EOF&&this._unexpectedToken +(e.token()),this.fire("endstylesheet")},_charset:function(e){var t=this._tokenStream +,n,r,i,s;t.match(Tokens.CHARSET_SYM)&&(i=t.token().startLine,s=t.token().startCol +,this._readWhitespace(),t.mustMatch(Tokens.STRING),r=t.token(),n=r.value,this._readWhitespace +(),t.mustMatch(Tokens.SEMICOLON),e!==!1&&this.fire({type:"charset",charset:n,line +:i,col:s}))},_import:function(e){var t=this._tokenStream,n,r,i,s=[];t.mustMatch( +Tokens.IMPORT_SYM),i=t.token(),this._readWhitespace(),t.mustMatch([Tokens.STRING +,Tokens.URI]),r=t.token().value.replace(/(?:url\()?["']([^"']+)["']\)?/,"$1"),this +._readWhitespace(),s=this._media_query_list(),t.mustMatch(Tokens.SEMICOLON),this +._readWhitespace(),e!==!1&&this.fire({type:"import",uri:r,media:s,line:i.startLine +,col:i.startCol})},_namespace:function(e){var t=this._tokenStream,n,r,i,s;t.mustMatch +(Tokens.NAMESPACE_SYM),n=t.token().startLine,r=t.token().startCol,this._readWhitespace +(),t.match(Tokens.IDENT)&&(i=t.token().value,this._readWhitespace()),t.mustMatch +([Tokens.STRING,Tokens.URI]),s=t.token().value.replace(/(?:url\()?["']([^"']+)["']\)?/ +,"$1"),this._readWhitespace(),t.mustMatch(Tokens.SEMICOLON),this._readWhitespace +(),e!==!1&&this.fire({type:"namespace",prefix:i,uri:s,line:n,col:r})},_media:function( +){var e=this._tokenStream,t,n,r;e.mustMatch(Tokens.MEDIA_SYM),t=e.token().startLine +,n=e.token().startCol,this._readWhitespace(),r=this._media_query_list(),e.mustMatch +(Tokens.LBRACE),this._readWhitespace(),this.fire({type:"startmedia",media:r,line +:t,col:n});for(;;)if(e.peek()==Tokens.PAGE_SYM)this._page();else if(e.peek()==Tokens +.FONT_FACE_SYM)this._font_face();else if(!this._ruleset())break;e.mustMatch(Tokens +.RBRACE),this._readWhitespace(),this.fire({type:"endmedia",media:r,line:t,col:n} +)},_media_query_list:function(){var e=this._tokenStream,t=[];this._readWhitespace +(),(e.peek()==Tokens.IDENT||e.peek()==Tokens.LPAREN)&&t.push(this._media_query() +);while(e.match(Tokens.COMMA))this._readWhitespace(),t.push(this._media_query()) +;return t},_media_query:function(){var e=this._tokenStream,t=null,n=null,r=null, +i=[];e.match(Tokens.IDENT)&&(n=e.token().value.toLowerCase(),n!="only"&&n!="not"? +(e.unget(),n=null):r=e.token()),this._readWhitespace(),e.peek()==Tokens.IDENT?(t= +this._media_type(),r===null&&(r=e.token())):e.peek()==Tokens.LPAREN&&(r===null&& +(r=e.LT(1)),i.push(this._media_expression()));if(t===null&&i.length===0)return null +;this._readWhitespace();while(e.match(Tokens.IDENT))e.token().value.toLowerCase( +)!="and"&&this._unexpectedToken(e.token()),this._readWhitespace(),i.push(this._media_expression +());return new MediaQuery(n,t,i,r.startLine,r.startCol)},_media_type:function(){ +return this._media_feature()},_media_expression:function(){var e=this._tokenStream +,t=null,n,r=null;return e.mustMatch(Tokens.LPAREN),t=this._media_feature(),this. +_readWhitespace(),e.match(Tokens.COLON)&&(this._readWhitespace(),n=e.LT(1),r=this +._expression()),e.mustMatch(Tokens.RPAREN),this._readWhitespace(),new MediaFeature +(t,r?new SyntaxUnit(r,n.startLine,n.startCol):null)},_media_feature:function(){var e= +this._tokenStream;return e.mustMatch(Tokens.IDENT),SyntaxUnit.fromToken(e.token( +))},_page:function(){var e=this._tokenStream,t,n,r=null,i=null;e.mustMatch(Tokens +.PAGE_SYM),t=e.token().startLine,n=e.token().startCol,this._readWhitespace(),e.match +(Tokens.IDENT)&&(r=e.token().value,r.toLowerCase()==="auto"&&this._unexpectedToken +(e.token())),e.peek()==Tokens.COLON&&(i=this._pseudo_page()),this._readWhitespace +(),this.fire({type:"startpage",id:r,pseudo:i,line:t,col:n}),this._readDeclarations +(!0,!0),this.fire({type:"endpage",id:r,pseudo:i,line:t,col:n})},_margin:function( +){var e=this._tokenStream,t,n,r=this._margin_sym();return r?(t=e.token().startLine +,n=e.token().startCol,this.fire({type:"startpagemargin",margin:r,line:t,col:n}), +this._readDeclarations(!0),this.fire({type:"endpagemargin",margin:r,line:t,col:n +}),!0):!1},_margin_sym:function(){var e=this._tokenStream;return e.match([Tokens +.TOPLEFTCORNER_SYM,Tokens.TOPLEFT_SYM,Tokens.TOPCENTER_SYM,Tokens.TOPRIGHT_SYM,Tokens +.TOPRIGHTCORNER_SYM,Tokens.BOTTOMLEFTCORNER_SYM,Tokens.BOTTOMLEFT_SYM,Tokens.BOTTOMCENTER_SYM +,Tokens.BOTTOMRIGHT_SYM,Tokens.BOTTOMRIGHTCORNER_SYM,Tokens.LEFTTOP_SYM,Tokens.LEFTMIDDLE_SYM +,Tokens.LEFTBOTTOM_SYM,Tokens.RIGHTTOP_SYM,Tokens.RIGHTMIDDLE_SYM,Tokens.RIGHTBOTTOM_SYM +])?SyntaxUnit.fromToken(e.token()):null},_pseudo_page:function(){var e=this._tokenStream +;return e.mustMatch(Tokens.COLON),e.mustMatch(Tokens.IDENT),e.token().value},_font_face +:function(){var e=this._tokenStream,t,n;e.mustMatch(Tokens.FONT_FACE_SYM),t=e.token +().startLine,n=e.token().startCol,this._readWhitespace(),this.fire({type:"startfontface" +,line:t,col:n}),this._readDeclarations(!0),this.fire({type:"endfontface",line:t, +col:n})},_viewport:function(){var e=this._tokenStream,t,n;e.mustMatch(Tokens.VIEWPORT_SYM +),t=e.token().startLine,n=e.token().startCol,this._readWhitespace(),this.fire({type +:"startviewport",line:t,col:n}),this._readDeclarations(!0),this.fire({type:"endviewport" +,line:t,col:n})},_operator:function(e){var t=this._tokenStream,n=null;if(t.match +([Tokens.SLASH,Tokens.COMMA])||e&&t.match([Tokens.PLUS,Tokens.STAR,Tokens.MINUS] +))n=t.token(),this._readWhitespace();return n?PropertyValuePart.fromToken(n):null +},_combinator:function(){var e=this._tokenStream,t=null,n;return e.match([Tokens +.PLUS,Tokens.GREATER,Tokens.TILDE])&&(n=e.token(),t=new Combinator(n.value,n.startLine +,n.startCol),this._readWhitespace()),t},_unary_operator:function(){var e=this._tokenStream +;return e.match([Tokens.MINUS,Tokens.PLUS])?e.token().value:null},_property:function( +){var e=this._tokenStream,t=null,n=null,r,i,s,o;return e.peek()==Tokens.STAR&&this +.options.starHack&&(e.get(),i=e.token(),n=i.value,s=i.startLine,o=i.startCol),e. +match(Tokens.IDENT)&&(i=e.token(),r=i.value,r.charAt(0)=="_"&&this.options.underscoreHack&& +(n="_",r=r.substring(1)),t=new PropertyName(r,n,s||i.startLine,o||i.startCol),this +._readWhitespace()),t},_ruleset:function(){var e=this._tokenStream,t,n;try{n=this +._selectors_group()}catch(r){if(r instanceof SyntaxError&&!this.options.strict){ +this.fire({type:"error",error:r,message:r.message,line:r.line,col:r.col}),t=e.advance +([Tokens.RBRACE]);if(t!=Tokens.RBRACE)throw r;return!0}throw r}return n&&(this.fire +({type:"startrule",selectors:n,line:n[0].line,col:n[0].col}),this._readDeclarations +(!0),this.fire({type:"endrule",selectors:n,line:n[0].line,col:n[0].col})),n},_selectors_group +:function(){var e=this._tokenStream,t=[],n;n=this._selector();if(n!==null){t.push +(n);while(e.match(Tokens.COMMA))this._readWhitespace(),n=this._selector(),n!==null? +t.push(n):this._unexpectedToken(e.LT(1))}return t.length?t:null},_selector:function( +){var e=this._tokenStream,t=[],n=null,r=null,i=null;n=this._simple_selector_sequence +();if(n===null)return null;t.push(n);do{r=this._combinator();if(r!==null)t.push( +r),n=this._simple_selector_sequence(),n===null?this._unexpectedToken(e.LT(1)):t. +push(n);else{if(!this._readWhitespace())break;i=new Combinator(e.token().value,e +.token().startLine,e.token().startCol),r=this._combinator(),n=this._simple_selector_sequence +(),n===null?r!==null&&this._unexpectedToken(e.LT(1)):(r!==null?t.push(r):t.push( +i),t.push(n))}}while(!0);return new Selector(t,t[0].line,t[0].col)},_simple_selector_sequence +:function(){var e=this._tokenStream,t=null,n=[],r="",i=[function(){return e.match +(Tokens.HASH)?new SelectorSubPart(e.token().value,"id",e.token().startLine,e.token +().startCol):null},this._class,this._attrib,this._pseudo,this._negation],s=0,o=i +.length,u=null,a=!1,f,l;f=e.LT(1).startLine,l=e.LT(1).startCol,t=this._type_selector +(),t||(t=this._universal()),t!==null&&(r+=t);for(;;){if(e.peek()===Tokens.S)break; +while(s1&&e.unget()),null)},_class:function(){var e=this._tokenStream,t;return e +.match(Tokens.DOT)?(e.mustMatch(Tokens.IDENT),t=e.token(),new SelectorSubPart("."+ +t.value,"class",t.startLine,t.startCol-1)):null},_element_name:function(){var e= +this._tokenStream,t;return e.match(Tokens.IDENT)?(t=e.token(),new SelectorSubPart +(t.value,"elementName",t.startLine,t.startCol)):null},_namespace_prefix:function( +){var e=this._tokenStream,t="";if(e.LA(1)===Tokens.PIPE||e.LA(2)===Tokens.PIPE)e +.match([Tokens.IDENT,Tokens.STAR])&&(t+=e.token().value),e.mustMatch(Tokens.PIPE +),t+="|";return t.length?t:null},_universal:function(){var e=this._tokenStream,t="" +,n;return n=this._namespace_prefix(),n&&(t+=n),e.match(Tokens.STAR)&&(t+="*"),t. +length?t:null},_attrib:function(){var e=this._tokenStream,t=null,n,r;return e.match +(Tokens.LBRACKET)?(r=e.token(),t=r.value,t+=this._readWhitespace(),n=this._namespace_prefix +(),n&&(t+=n),e.mustMatch(Tokens.IDENT),t+=e.token().value,t+=this._readWhitespace +(),e.match([Tokens.PREFIXMATCH,Tokens.SUFFIXMATCH,Tokens.SUBSTRINGMATCH,Tokens.EQUALS +,Tokens.INCLUDES,Tokens.DASHMATCH])&&(t+=e.token().value,t+=this._readWhitespace +(),e.mustMatch([Tokens.IDENT,Tokens.STRING]),t+=e.token().value,t+=this._readWhitespace +()),e.mustMatch(Tokens.RBRACKET),new SelectorSubPart(t+"]","attribute",r.startLine +,r.startCol)):null},_pseudo:function(){var e=this._tokenStream,t=null,n=":",r,i; +return e.match(Tokens.COLON)&&(e.match(Tokens.COLON)&&(n+=":"),e.match(Tokens.IDENT +)?(t=e.token().value,r=e.token().startLine,i=e.token().startCol-n.length):e.peek +()==Tokens.FUNCTION&&(r=e.LT(1).startLine,i=e.LT(1).startCol-n.length,t=this._functional_pseudo +()),t&&(t=new SelectorSubPart(n+t,"pseudo",r,i))),t},_functional_pseudo:function( +){var e=this._tokenStream,t=null;return e.match(Tokens.FUNCTION)&&(t=e.token().value +,t+=this._readWhitespace(),t+=this._expression(),e.mustMatch(Tokens.RPAREN),t+=")" +),t},_expression:function(){var e=this._tokenStream,t="";while(e.match([Tokens.PLUS +,Tokens.MINUS,Tokens.DIMENSION,Tokens.NUMBER,Tokens.STRING,Tokens.IDENT,Tokens.LENGTH +,Tokens.FREQ,Tokens.ANGLE,Tokens.TIME,Tokens.RESOLUTION,Tokens.SLASH]))t+=e.token +().value,t+=this._readWhitespace();return t.length?t:null},_negation:function(){ +var e=this._tokenStream,t,n,r="",i,s=null;return e.match(Tokens.NOT)&&(r=e.token +().value,t=e.token().startLine,n=e.token().startCol,r+=this._readWhitespace(),i= +this._negation_arg(),r+=i,r+=this._readWhitespace(),e.match(Tokens.RPAREN),r+=e. +token().value,s=new SelectorSubPart(r,"not",t,n),s.args.push(i)),s},_negation_arg +:function(){var e=this._tokenStream,t=[this._type_selector,this._universal,function( +){return e.match(Tokens.HASH)?new SelectorSubPart(e.token().value,"id",e.token() +.startLine,e.token().startCol):null},this._class,this._attrib,this._pseudo],n=null +,r=0,i=t.length,s,o,u,a;o=e.LT(1).startLine,u=e.LT(1).startCol;while(r0?new PropertyValue(n,n[0].line,n[0].col):null},_term:function( +){var e=this._tokenStream,t=null,n=null,r,i,s;return t=this._unary_operator(),t!== +null&&(i=e.token().startLine,s=e.token().startCol),e.peek()==Tokens.IE_FUNCTION&& +this.options.ieFilters?(n=this._ie_function(),t===null&&(i=e.token().startLine,s= +e.token().startCol)):e.match([Tokens.NUMBER,Tokens.PERCENTAGE,Tokens.LENGTH,Tokens +.ANGLE,Tokens.TIME,Tokens.FREQ,Tokens.STRING,Tokens.IDENT,Tokens.URI,Tokens.UNICODE_RANGE +])?(n=e.token().value,t===null&&(i=e.token().startLine,s=e.token().startCol),this +._readWhitespace()):(r=this._hexcolor(),r===null?(t===null&&(i=e.LT(1).startLine +,s=e.LT(1).startCol),n===null&&(e.LA(3)==Tokens.EQUALS&&this.options.ieFilters?n= +this._ie_function():n=this._function())):(n=r.value,t===null&&(i=r.startLine,s=r +.startCol))),n!==null?new PropertyValuePart(t!==null?t+n:n,i,s):null},_function: +function(){var e=this._tokenStream,t=null,n=null,r;if(e.match(Tokens.FUNCTION)){ +t=e.token().value,this._readWhitespace(),n=this._expr(!0),t+=n;if(this.options.ieFilters&& +e.peek()==Tokens.EQUALS)do{this._readWhitespace()&&(t+=e.token().value),e.LA(0)== +Tokens.COMMA&&(t+=e.token().value),e.match(Tokens.IDENT),t+=e.token().value,e.match +(Tokens.EQUALS),t+=e.token().value,r=e.peek();while(r!=Tokens.COMMA&&r!=Tokens.S&& +r!=Tokens.RPAREN)e.get(),t+=e.token().value,r=e.peek()}while(e.match([Tokens.COMMA +,Tokens.S]));e.match(Tokens.RPAREN),t+=")",this._readWhitespace()}return t},_ie_function +:function(){var e=this._tokenStream,t=null,n=null,r;if(e.match([Tokens.IE_FUNCTION +,Tokens.FUNCTION])){t=e.token().value;do{this._readWhitespace()&&(t+=e.token().value +),e.LA(0)==Tokens.COMMA&&(t+=e.token().value),e.match(Tokens.IDENT),t+=e.token() +.value,e.match(Tokens.EQUALS),t+=e.token().value,r=e.peek();while(r!=Tokens.COMMA&& +r!=Tokens.S&&r!=Tokens.RPAREN)e.get(),t+=e.token().value,r=e.peek()}while(e.match +([Tokens.COMMA,Tokens.S]));e.match(Tokens.RPAREN),t+=")",this._readWhitespace()} +return t},_hexcolor:function(){var e=this._tokenStream,t=null,n;if(e.match(Tokens +.HASH)){t=e.token(),n=t.value;if(!/#[a-f0-9]{3,6}/i.test(n))throw new SyntaxError +("Expected a hex color but found '"+n+"' at line "+t.startLine+", col "+t.startCol+"." +,t.startLine,t.startCol);this._readWhitespace()}return t},_keyframes:function(){ +var e=this._tokenStream,t,n,r,i="";e.mustMatch(Tokens.KEYFRAMES_SYM),t=e.token() +,/^@\-([^\-]+)\-/.test(t.value)&&(i=RegExp.$1),this._readWhitespace(),r=this._keyframe_name +(),this._readWhitespace(),e.mustMatch(Tokens.LBRACE),this.fire({type:"startkeyframes" +,name:r,prefix:i,line:t.startLine,col:t.startCol}),this._readWhitespace(),n=e.peek +();while(n==Tokens.IDENT||n==Tokens.PERCENTAGE)this._keyframe_rule(),this._readWhitespace +(),n=e.peek();this.fire({type:"endkeyframes",name:r,prefix:i,line:t.startLine,col +:t.startCol}),this._readWhitespace(),e.mustMatch(Tokens.RBRACE)},_keyframe_name: +function(){var e=this._tokenStream,t;return e.mustMatch([Tokens.IDENT,Tokens.STRING +]),SyntaxUnit.fromToken(e.token())},_keyframe_rule:function(){var e=this._tokenStream +,t,n=this._key_list();this.fire({type:"startkeyframerule",keys:n,line:n[0].line, +col:n[0].col}),this._readDeclarations(!0),this.fire({type:"endkeyframerule",keys +:n,line:n[0].line,col:n[0].col})},_key_list:function(){var e=this._tokenStream,t +,n,r=[];r.push(this._key()),this._readWhitespace();while(e.match(Tokens.COMMA))this +._readWhitespace(),r.push(this._key()),this._readWhitespace();return r},_key:function( +){var e=this._tokenStream,t;if(e.match(Tokens.PERCENTAGE))return SyntaxUnit.fromToken +(e.token());if(e.match(Tokens.IDENT)){t=e.token();if(/from|to/i.test(t.value))return SyntaxUnit +.fromToken(t);e.unget()}this._unexpectedToken(e.LT(1))},_skipCruft:function(){while( +this._tokenStream.match([Tokens.S,Tokens.CDO,Tokens.CDC]));},_readDeclarations:function( +e,t){var n=this._tokenStream,r;this._readWhitespace(),e&&n.mustMatch(Tokens.LBRACE +),this._readWhitespace();try{for(;;){if(!(n.match(Tokens.SEMICOLON)||t&&this._margin +())){if(!this._declaration())break;if(!n.match(Tokens.SEMICOLON))break}this._readWhitespace +()}n.mustMatch(Tokens.RBRACE),this._readWhitespace()}catch(i){if(!(i instanceof +SyntaxError&&!this.options.strict))throw i;this.fire({type:"error",error:i,message +:i.message,line:i.line,col:i.col}),r=n.advance([Tokens.SEMICOLON,Tokens.RBRACE]) +;if(r==Tokens.SEMICOLON)this._readDeclarations(!1,t);else if(r!=Tokens.RBRACE)throw i +}},_readWhitespace:function(){var e=this._tokenStream,t="";while(e.match(Tokens. +S))t+=e.token().value;return t},_unexpectedToken:function(e){throw new SyntaxError +("Unexpected token '"+e.value+"' at line "+e.startLine+", col "+e.startCol+".",e +.startLine,e.startCol)},_verifyEnd:function(){this._tokenStream.LA(1)!=Tokens.EOF&& +this._unexpectedToken(this._tokenStream.LT(1))},_validateProperty:function(e,t){ +Validation.validate(e,t)},parse:function(e){this._tokenStream=new TokenStream(e, +Tokens),this._stylesheet()},parseStyleSheet:function(e){return this.parse(e)},parseMediaQuery +:function(e){this._tokenStream=new TokenStream(e,Tokens);var t=this._media_query +();return this._verifyEnd(),t},parsePropertyValue:function(e){this._tokenStream=new +TokenStream(e,Tokens),this._readWhitespace();var t=this._expr();return this._readWhitespace +(),this._verifyEnd(),t},parseRule:function(e){this._tokenStream=new TokenStream( +e,Tokens),this._readWhitespace();var t=this._ruleset();return this._readWhitespace +(),this._verifyEnd(),t},parseSelector:function(e){this._tokenStream=new TokenStream +(e,Tokens),this._readWhitespace();var t=this._selector();return this._readWhitespace +(),this._verifyEnd(),t},parseStyleAttribute:function(e){e+="}",this._tokenStream=new +TokenStream(e,Tokens),this._readDeclarations()}};for(t in n)n.hasOwnProperty(t)&& +(e[t]=n[t]);return e}();var Properties={"alignment-adjust":"auto | baseline | before-edge | text-before-edge | middle | central | after-edge | text-after-edge | ideographic | alphabetic | hanging | mathematical | | " +,"alignment-baseline":"baseline | use-script | before-edge | text-before-edge | after-edge | text-after-edge | central | middle | ideographic | alphabetic | hanging | mathematical" +,animation:1,"animation-delay":{multi:"
\n\ +'; + + + +// https://github.com/swagger-api/swagger-ui/blob/v2.1.3/src/main/template/param.handlebars +local.templateUiParam = '\ +\n\ + {{name}}\n\ + {{#if description}}\n\ +
{{description htmlSafe}}\n\ + {{/if description}}\n\ +
\n\ +{{type2}}{{#if format2}}
({{format2}}){{/if format2}}
\n\ +\n\ + {{#if isTextarea}}\n\ + \n\ + {{/if isTextarea}}\n\ + {{#if isFile}}\n\ + \n\ + {{/if isFile}}\n\ + {{#if isSelect}}\n\ + \n\ + {{/if isSelect}}\n\ + {{#if isInputText}}\n\ + \n\ + {{/if isInputText}}\n\ +\n\ +{{#if schemaText}}
{{schemaText}}
{{/if schemaText}}
\n\ +'; + + + +// https://github.com/swagger-api/swagger-ui/blob/v2.1.3/src/main/template/resource.handlebars +local.templateUiResource = '\ +\n\ +
\n\ + {{name}} :\n\ + {{#if description}}\n\ + {{description htmlSafe}}\n\ + {{/if description}}\n\ + \n\ + Show\n\ + Expand / Collapse Operations\n\ + Datatable\n\ +
\n\ + \n\ +\n\ +'; + + + +local.templateUiResponseAjax = '\ +

Curl Request

\n\ +{{#if errorValidate}}\n\ +
n/a
\n\ +{{#unless errorValidate}}\n\ +
{{curl htmlSafe}}
\n\ +{{/if errorValidate}}\n\ +

Response Code

\n\ +
{{statusCode}}
\n\ +

Response Headers

\n\ +{{#if errorValidate}}\n\ +
n/a
\n\ +{{#unless errorValidate}}\n\ +
{{responseHeaders htmlSafe}}
\n\ +{{/if errorValidate}}\n\ +

Response Body

\n\ +{{responseBody}}\n\ +'; +/* jslint-ignore-end */ + local.swaggerSchemaJson = local.jsonCopy(local.objectSetOverride( + JSON.parse(local.assetsDict['/assets.swgg.json-schema.json']), + JSON.parse(local.assetsDict['/assets.swgg.schema.json']), + 2 + )); + }()); + + + + // run shared js-env code - function + (function () { + local.apiAjax = function (self, options, onError) { + /* + * this function will send a swagger-api ajax-request with the pathObject self + */ + var isMultipartFormData, tmp; + isMultipartFormData = (self.consumes && self.consumes[0]) === 'multipart/form-data'; + local.objectSetDefault(options, { data: '', paramDict: {}, url: '' }); + // try to validate paramDict + local.tryCatchOnError(function () { + local.validateByParamDefList({ + // normalize paramDict + data: local.normalizeParamDictSwagger( + local.jsonCopy(options.paramDict), + self + ), + dataReadonlyRemove: options.paramDict, + key: self.operationId, + paramDefList: self.parameters + }); + }, function (error) { + options.errorValidate = error; + onError(error); + }); + if (options.errorValidate) { + return; + } + // init options-defaults + local.objectSetDefault(options, { + inForm: isMultipartFormData + ? new local.FormData() + : '', + inHeader: {}, + inPath: self._path, + inQuery: '', + headers: {}, + method: self._method, + responseType: self.produces && + self.produces[0].indexOf('application/octet-stream') === 0 + ? 'arraybuffer' + : '' + }); + // init paramDict + self.parameters.forEach(function (paramDef) { + tmp = options.paramDict[paramDef.name]; + if (tmp === undefined) { + return; + } + // serialize array + if (paramDef.type === 'array' && paramDef.in !== 'body') { + if (typeof tmp !== 'string') { + switch (paramDef.collectionFormat) { + case 'json': + tmp = JSON.stringify(tmp); + break; + case 'multi': + tmp.forEach(function (value) { + options[paramDef.in === 'formData' + ? 'inForm' + : 'inQuery'] += '&' + + encodeURIComponent(paramDef.name) + '=' + + encodeURIComponent(paramDef.items.type === 'string' + ? value + : JSON.stringify(value)); + }); + return; + case 'pipes': + tmp = tmp.join('|'); + break; + case 'ssv': + tmp = tmp.join(' '); + break; + case 'tsv': + tmp = tmp.join('\t'); + break; + // default to csv + default: + tmp = tmp.join(','); + } + } + } else if (!(paramDef.type === 'string' || tmp instanceof local.Blob)) { + tmp = JSON.stringify(tmp); + } + switch (paramDef.in) { + case 'body': + options.inBody = tmp; + break; + case 'formData': + if (isMultipartFormData) { + options.inForm.append(paramDef.name, tmp, tmp && tmp.name); + break; + } + options.inForm += '&' + encodeURIComponent(paramDef.name) + '=' + + encodeURIComponent(tmp); + break; + case 'header': + options.inHeader[encodeURIComponent(paramDef.name.toLowerCase())] = tmp; + break; + case 'query': + options.inQuery += '&' + encodeURIComponent(paramDef.name) + '=' + + encodeURIComponent(tmp); + break; + case 'path': + options.inPath = options.inPath + .replace('{' + paramDef.name + '}', encodeURIComponent(tmp)); + break; + } + }); + // init data + options.data = options.inBody || (isMultipartFormData + ? options.inForm + : options.inForm.slice(1)); + // init headers + local.objectSetOverride(options.headers, options.inHeader); + // init headers - Content-Type + if (options.inForm) { + options.headers['Content-Type'] = isMultipartFormData + ? 'multipart/form-data' + : 'application/x-www-form-urlencoded'; + } + // init headers - Authorization + options.jwtEncrypted = options.jwtEncrypted || local.userJwtEncrypted; + if (options.jwtEncrypted) { + options.headers.Authorization = options.headers.Authorization || + 'Bearer ' + options.jwtEncrypted; + } + // init url + options.url = (local.urlBaseGet() + options.inPath + '?' + options.inQuery.slice(1)) + .replace((/\?$/), ''); + if (!(options.headers['Content-Type'] || options.headers['content-type'])) { + options.headers['content-type'] = 'application/json; charset=UTF-8'; + } + // send ajax-request + return local.ajax(options, function (error, xhr) { + // try to init responseJson + local.tryCatchOnError(function () { + xhr.responseJson = JSON.parse(xhr.responseText); + }, local.nop); + // init userJwtEncrypted + if (xhr.getResponseHeader('swgg-jwt-encrypted')) { + local.userJwtEncrypted = xhr.getResponseHeader('swgg-jwt-encrypted'); + } + onError(error, xhr); + }); + }; + + local.apiDictUpdate = function (options) { + /* + * this function will update the swagger-api dict of api-calls + */ + var tmp; + options = options || {}; + // init apiDict + local.apiDict = local.apiDict || {}; + // init swaggerJson + local.swaggerJson = local.swaggerJson || { + "basePath": "/api/v0", + "definitions": { + "BuiltinFile": { + "properties": { + "_id": { + "readOnly": true, + "type": "string" + }, + "_timeCreated": { + "format": "date-time", + "readOnly": true, + "type": "string" + }, + "_timeUpdated": { + "format": "date-time", + "readOnly": true, + "type": "string" + }, + "fileBlob": { + "format": "byte", + "type": "string" + }, + "fileContentType": { + "type": "string" + }, + "fileDescription": { + "type": "string" + }, + "fileFilename": { + "type": "string" + }, + "fileInputName": { + "type": "string" + }, + "fileSize": { + "minimum": 0, + "type": "integer" + }, + "fileUrl": { + "type": "string" + }, + "id": { + "type": "string" + } + } + }, + "BuiltinJsonapiResponse": { + "properties": { + "data": { + "items": { + "type": "object" + }, + "type": "array" + }, + "errors": { + "items": { + "type": "object" + }, + "type": "array" + }, + "meta": { + "type": "object" + } + } + }, + "BuiltinUser": { + "properties": { + "_id": { + "readOnly": true, + "type": "string" + }, + "_timeCreated": { + "format": "date-time", + "readOnly": true, + "type": "string" + }, + "_timeUpdated": { + "format": "date-time", + "readOnly": true, + "type": "string" + }, + "id": { + "type": "string" + }, + "jwtEncrypted": { + "type": "string" + }, + "password": { + "format": "password", + "type": "string" + }, + "username": { + "type": "string" + } + } + } + }, + "info": { + "description": "demo of swagger-ui server", + "title": "swgg api", + "version": "0" + }, + "paths": {}, + "securityDefinitions": {}, + "swagger": "2.0", + "tags": [] + }; + // save tags + tmp = {}; + [local.swaggerJson.tags, options.tags || []].forEach(function (tagList) { + tagList.forEach(function (tag) { + local.objectSetOverride(tmp, local.objectLiteralize({ + '$[]': [tag.name, tag] + })); + }, 2); + }); + tmp = Object.keys(tmp).sort().map(function (key) { + return tmp[key]; + }); + // merge options into swaggerJson + options = local.objectSetOverride(local.swaggerJson, options, 10); + // restore tags + local.swaggerJson.tags = tmp; + Object.keys(options.definitions).forEach(function (schemaName) { + // normalize definition + options.definitions[schemaName] = + local.schemaNormalizeAndCopy(options.definitions[schemaName]); + }); + // init apiDict from paths + Object.keys(options.paths).forEach(function (path) { + Object.keys(options.paths[path]).forEach(function (method) { + var self; + self = options.paths[path][method]; + self._method = method; + self._path = path; + local.objectSetOverride(local.apiDict, local.objectLiteralize({ + '$[]': [self.tags[0] + ' ' + self.operationId, self] + }), 2); + }); + }); + // init apiDict from x-swgg-apiDict + Object.keys(options['x-swgg-apiDict'] || {}).forEach(function (key) { + // init self + local.objectSetOverride(local.apiDict, local.objectLiteralize({ + '$[]': [key, local.jsonCopy(options['x-swgg-apiDict'][key])] + }), Infinity); + }); + // init apiDict + Object.keys(local.apiDict).forEach(function (key) { + var self; + self = local.apiDict[key]; + if (key === self._keyPath) { + return; + } + // init _operationId + self._operationId = self._operationId || key.split(' ')[1]; + // init _fileUploadNumber + self._fileUploadNumber = 1; + self._operationId.replace( + (/^fileUploadManyByForm\.(\d+)/), + function (match0, match1) { + // jslint-hack - nop + local.nop(match0); + self._fileUploadNumber = Number(match1); + } + ); + // init _idAlias and _idField + tmp = local.idFieldInit({ operationId: self._operationId }); + self._idAlias = tmp.idAlias; + self._idField = tmp.idField; + // init _tags0 + self._tags0 = key.split(' ')[0]; + // init templateApiDict + if (local.templateApiDict[self._operationId.split('.')[0]]) { + local.objectSetDefault( + self, + JSON.parse(local.templateApiDict[self._operationId.split('.')[0]] + .replace((/\{\{_fileUploadNumber\}\}/g), self._fileUploadNumber) + .replace((/\{\{_idAlias\}\}/g), self._idAlias) + .replace((/\{\{_idField\}\}/g), self._idField) + .replace((/\{\{_schemaName\}\}/g), self._schemaName) + .replace((/\{\{_tags0\}\}/g), self._tags0) + .replace((/\{\{operationId\}\}/g), self._operationId)) + ); + } + // init default + local.objectSetDefault(self, { + _keyOperationId: key, + operationId: self._operationId, + parameters: [], + responses: { + 200: { + description: 'ok - ' + + 'http://jsonapi.org/format/#document-top-level', + schema: { $ref: '#/definitions/BuiltinJsonapiResponse' } + } + }, + tags: [self._tags0] + }); + // init _method + self._method = self._method.toUpperCase(); + // init _keyPath + self._keyPath = self._method + ' ' + self._path.replace((/\{.*?\}/g), ''); + // init _idField.format and _idField.type + if (self._schemaName) { + self.parameters.forEach(function (param) { + if (param.name === self._idField) { + param.format = options.definitions[self._schemaName] + .properties[self._idAlias].format; + param.type = options.definitions[self._schemaName] + .properties[self._idAlias].type; + } + }); + } + switch (self.operationId.split('.')[0]) { + // add extra file-upload forms + case 'fileUploadManyByForm': + for (tmp = 1; tmp <= self._fileUploadNumber; tmp += 1) { + self.parameters[tmp] = local.jsonCopy(self.parameters[1]); + self.parameters[tmp].name = 'file' + tmp; + } + break; + } + // update apiDict + self = local.apiDict[key] = local.apiDict[self._keyPath] = local.jsonCopy(self); + // init _ajax + self._ajax = function (options, onError) { + return local.apiAjax(self, options, onError); + }; + // remove underscored keys from self + tmp = local.jsonCopy(self); + Object.keys(tmp).forEach(function (key) { + if (key[0] === '_') { + delete tmp[key]; + } + }); + // update paths + local.objectSetOverride(options, local.objectLiteralize({ + paths: { '$[]': [self._path, { '$[]': [self._method.toLowerCase(), tmp] }] } + }), 3); + }); + // normalize swaggerJson + local.swaggerJson = JSON.parse(local.jsonStringifyOrdered(options)); + // update $npm_config_swagger_basePath + local.env.npm_config_swagger_basePath = local.swaggerJson.basePath; + // try to validate swaggerJson + local.tryCatchOnError(function () { + local.validateBySwagger(local.swaggerJson); + }, local.onErrorDefault); + }; + + local.dbFieldRandomCreate = function (options) { + /* + * this function will create a random dbField from options.propDef + */ + var ii, max, min, propDef, tmp; + propDef = options.propDef; + if (propDef.readOnly) { + return; + } + if (propDef.enum) { + tmp = options.modeNotRandom + ? propDef.enum[0] + : local.listGetElementRandom(propDef.enum); + return propDef.type === 'array' + ? [tmp] + : tmp; + } + // http://json-schema.org/latest/json-schema-validation.html#anchor13 + // 5.1. Validation keywords for numeric instances (number and integer) + max = isFinite(propDef.maximum) + ? propDef.maximum + : 999; + min = isFinite(propDef.maximum) + ? propDef.minimum + : 0; + switch (propDef.type) { + case 'array': + tmp = []; + // http://json-schema.org/latest/json-schema-validation.html#anchor36 + // 5.3. Validation keywords for arrays + for (ii = 0; ii < (propDef.minItems || 0); ii += 1) { + tmp.push(null); + } + break; + case 'boolean': + tmp = options.modeNotRandom + ? false + : Math.random() <= 0.5 + ? false + : true; + break; + case 'integer': + if (propDef.exclusiveMaximum) { + max -= 1; + } + if (propDef.exclusiveMinimum) { + min += 1; + } + min = Math.min(min, max); + tmp = options.modeNotRandom + ? 0 + : Math.random(); + tmp = Math.floor(min + tmp * (max - min)); + break; + case 'object': + tmp = {}; + // http://json-schema.org/latest/json-schema-validation.html#anchor53 + // 5.4. Validation keywords for objects + for (ii = 0; ii < (propDef.minProperties || 0); ii += 1) { + tmp['property' + ii] = null; + } + break; + case 'number': + if (propDef.exclusiveMinimum) { + min = min < 0 + ? min * 0.99999 + : min * 1.00001 + 0.00001; + } + if (propDef.exclusiveMaximum) { + max = max > 0 + ? max * 0.99999 + : max * 1.00001 - 0.00001; + } + min = Math.min(min, max); + tmp = options.modeNotRandom + ? 0 + : Math.random(); + tmp = min + tmp * (max - min); + break; + case 'string': + tmp = options.modeNotRandom + ? 'abcd1234' + : ((1 + Math.random()) * 0x10000000000000).toString(36).slice(1); + switch (propDef.format) { + case 'byte': + tmp = local.base64FromString(tmp); + break; + case 'date': + case 'date-time': + tmp = new Date().toISOString(); + break; + case 'email': + tmp = tmp + '@random.com'; + break; + case 'json': + tmp = JSON.stringify({ random: tmp }); + break; + case 'phone': + tmp = options.modeNotRandom + ? '+123 (1234) 1234-1234' + : '+' + Math.random().toString().slice(-3) + + ' (' + Math.random().toString().slice(-4) + ') ' + + Math.random().toString().slice(-4) + '-' + + Math.random().toString().slice(-4); + break; + } + // http://json-schema.org/latest/json-schema-validation.html#anchor25 + // 5.2. Validation keywords for strings + while (tmp.length < (propDef.minLength || 0)) { + tmp += tmp; + } + tmp = tmp.slice(0, propDef.maxLength || Infinity); + break; + } + // http://json-schema.org/latest/json-schema-validation.html#anchor13 + // 5.1. Validation keywords for numeric instances (number and integer) + if (propDef.multipleOf) { + tmp = propDef.multipleOf * Math.floor(tmp / propDef.multipleOf); + if (tmp < min) { + tmp += propDef.multipleOf; + } + } + return tmp; + }; + + local.dbRowListRandomCreate = function (options) { + /* + * this function will create a dbRowList of options.length random dbRow's + */ + local.objectSetDefault(options, { dbRowList: [] }); + for (options.ii = 0; options.ii < options.length; options.ii += 1) { + options.dbRowList.push(local.dbRowRandomCreate(options)); + } + return options.dbRowList; + }; + + local.dbRowRandomCreate = function (options) { + /* + * this function will create a random dbRow from options.properties + */ + var dbRow, tmp; + dbRow = {}; + Object.keys(options.properties).forEach(function (key) { + // try to validate data + local.tryCatchOnError(function () { + tmp = local.dbFieldRandomCreate({ + modeNotRandom: options.modeNotRandom, + propDef: options.properties[key] + }); + local.validateByPropDef({ + data: tmp, + key: options.properties[key].name, + schema: options.properties[key] + }); + dbRow[key] = tmp; + }, local.nop); + }); + return local.jsonCopy(local.objectSetOverride(dbRow, options.override(options))); + }; + + local.idDomElementCreate = function (seed) { + /* + * this function will create a unique dom-element id from the seed, + * that is both dom-selector and url friendly + */ + var id, ii; + id = encodeURIComponent(seed).replace((/\W/g), '_'); + for (ii = 2; local.idDomElementDict[id]; ii += 1) { + id = encodeURIComponent(seed + '_' + ii).replace((/\W/g), '_'); + } + local.idDomElementDict[id] = true; + return id; + }; + + local.idFieldInit = function (options) { + /* + * this function will init options.idAlias, options.idField, and options.queryById + */ + var idAlias, idField; + // init idField + options.idAlias = options.operationId.split('.'); + idField = options.idField = options.idAlias[1] || 'id'; + // init idAlias + idAlias = options.idAlias = options.idAlias[2] || options.idField; + // invert queryById + if (options.modeQueryByIdInvert) { + idAlias = options.idField; + idField = options.idAlias; + } + // init queryById + options.idValue = (options.data && options.data[idAlias]) || options.idValue; + options.queryById = {}; + options.queryById[idField] = options.idValue; + return options; + }; + + local.middlewareBodyParse = function (request, response, nextMiddleware) { + /* + * this function will run the middleware that will parse request.bodyRaw + */ + var ii, jj, options; + // jslint-hack + local.nop(response); + // if request is already parsed, then goto nextMiddleware + if (!local.isNullOrUndefined(request.swgg.bodyParsed)) { + nextMiddleware(); + return; + } + switch (String(request.headers['content-type']).split(';')[0]) { + // parse application/x-www-form-urlencoded, e.g. + // aa=hello%20world&bb=bye%20world + case 'application/x-www-form-urlencoded': + request.swgg.bodyParsed = local.bufferToString(request.bodyRaw); + request.swgg.bodyParsed = + local.urlParse('?' + request.swgg.bodyParsed, true).query; + break; + /* + * https://tools.ietf.org/html/rfc7578 + * parse multipart/form-data, e.g. + * --Boundary\r\n + * Content-Disposition: form-data; name="key"\r\n + * \r\n + * value\r\n + * --Boundary\r\n + * Content-Disposition: form-data; name="input1"; filename="file1.png"\r\n + * Content-Type: image/jpeg\r\n + * \r\n + * \r\n + * --Boundary\r\n + * Content-Disposition: form-data; name="input2"; filename="file2.png"\r\n + * Content-Type: image/jpeg\r\n + * \r\n + * \r\n + * --Boundary--\r\n + */ + case 'multipart/form-data': + request.swgg.isMultipartFormData = true; + request.swgg.bodyParsed = {}; + request.swgg.bodyMeta = {}; + options = {}; + options.crlf = local.bufferCreate([0x0d, 0x0a]); + // init boundary + ii = 0; + jj = local.bufferIndexOfSubBuffer(request.bodyRaw, options.crlf, ii); + if (jj <= 0) { + break; + } + options.boundary = local.bufferConcat([ + options.crlf, + request.bodyRaw.slice(ii, jj) + ]); + ii = jj + 2; + while (true) { + jj = local.bufferIndexOfSubBuffer( + request.bodyRaw, + options.boundary, + ii + ); + if (jj < 0) { + break; + } + options.header = local.bufferToString(request.bodyRaw.slice(ii, ii + 1024)) + .split('\r\n').slice(0, 2).join('\r\n'); + options.contentType = (/^content-type:(.*)/im).exec(options.header); + options.contentType = options.contentType && options.contentType[1].trim(); + options.filename = (/^content-disposition:.*?\bfilename="([^"]+)/im) + .exec(options.header); + options.filename = options.filename && options.filename[1]; + options.name = (/^content-disposition:.*?\bname="([^"]+)/im) + .exec(options.header); + options.name = options.name && options.name[1]; + ii = local.bufferIndexOfSubBuffer( + request.bodyRaw, + [0x0d, 0x0a, 0x0d, 0x0a], + ii + 2 + ) + 4; + options.data = request.bodyRaw.slice(ii, jj); + request.swgg.bodyParsed[options.name] = options.data; + request.swgg.bodyMeta[options.name] = { + contentType: options.contentType, + filename: options.filename, + name: options.name + }; + ii = jj + options.boundary.length + 2; + } + break; + default: + request.swgg.bodyParsed = local.bufferToString(request.bodyRaw); + // try to JSON.parse the string + local.tryCatchOnError(function () { + request.swgg.bodyParsed = JSON.parse(request.swgg.bodyParsed); + }, local.nop); + } + nextMiddleware(); + }; + + local.middlewareCrudBuiltin = function (request, response, nextMiddleware) { + /* + * this function will run the middleware that will + * run the builtin crud-operations backed by db-lite + */ + var crud, onParallel, options, tmp, user; + options = {}; + local.onNext(options, function (error, data, meta) { + switch (options.modeNext) { + case 1: + crud = request.swgg.crud; + user = request.swgg.user; + switch (crud.operationId.split('.')[0]) { + case 'crudCountManyByQuery': + crud.dbTable.crudCountManyByQuery(crud.queryWhere, options.onNext); + break; + case 'crudSetManyById': + crud.dbTable.crudSetManyById(crud.body, options.onNext); + break; + case 'crudSetOneById': + // replace idField with idAlias in body + delete crud.body.id; + delete crud.body[crud.idField]; + crud.body[crud.idAlias] = crud.data[crud.idField]; + crud.dbTable.crudSetOneById(crud.body, options.onNext); + break; + case 'crudUpdateOneById': + // replace idField with idAlias in body + delete crud.body.id; + delete crud.body[crud.idField]; + crud.body[crud.idAlias] = crud.data[crud.idField]; + crud.dbTable.crudUpdateOneById(crud.body, options.onNext); + break; + // coverage-hack - test error handling-behavior + case 'crudErrorDelete': + case 'crudErrorGet': + case 'crudErrorHead': + case 'crudErrorOptions': + case 'crudErrorPatch': + case 'crudErrorPost': + case 'crudErrorPut': + options.onNext(local.errorDefault); + break; + case 'crudGetManyByQuery': + onParallel = local.onParallel(options.onNext); + onParallel.counter += 1; + crud.dbTable.crudGetManyByQuery({ + fieldList: crud.queryFields, + limit: crud.queryLimit, + query: crud.queryWhere, + skip: crud.querySkip, + sort: crud.querySort + }, function (error, data) { + crud.queryData = data; + onParallel(error); + }); + onParallel.counter += 1; + crud.dbTable.crudCountAll(function (error, data) { + crud.paginationCountTotal = data; + onParallel(error); + }); + break; + case 'crudGetOneById': + crud.dbTable.crudGetOneById(crud.queryById, options.onNext); + break; + case 'crudGetOneByQuery': + crud.dbTable.crudGetOneByQuery({ + query: crud.queryWhere + }, options.onNext); + break; + case 'crudNullDelete': + case 'crudNullGet': + case 'crudNullHead': + case 'crudNullOptions': + case 'crudNullPatch': + case 'crudNullPost': + case 'crudNullPut': + options.onNext(); + break; + case 'crudRemoveManyByQuery': + crud.dbTable.crudRemoveManyByQuery(crud.queryWhere, options.onNext); + break; + case 'crudRemoveOneById': + crud.dbTable.crudRemoveOneById(crud.queryById, options.onNext); + break; + case 'fileGetOneById': + local.dbTableFile = local.db.dbTableCreateOne({ name: 'File' }); + crud.dbTable.crudGetOneById(crud.queryById, options.onNext); + break; + case 'fileUploadManyByForm': + local.dbTableFile = local.db.dbTableCreateOne({ name: 'File' }); + request.swgg.paramDict = {}; + Object.keys(request.swgg.bodyMeta).forEach(function (key) { + if (typeof request.swgg.bodyMeta[key].filename !== 'string') { + request.swgg.paramDict[key] = + local.bufferToString(request.swgg.bodyParsed[key]); + } + }); + crud.body = Object.keys(request.swgg.bodyMeta) + .filter(function (key) { + return typeof request.swgg.bodyMeta[key].filename === 'string'; + }) + .map(function (key) { + tmp = local.jsonCopy(request.swgg.paramDict); + local.objectSetOverride(tmp, { + fileBlob: + local.base64FromBuffer(request.swgg.bodyParsed[key]), + fileContentType: request.swgg.bodyMeta[key].contentType, + fileFilename: request.swgg.bodyMeta[key].filename, + fileInputName: request.swgg.bodyMeta[key].name, + fileSize: request.swgg.bodyParsed[key].length, + fileUrl: local.swaggerJson.basePath + + '/' + request.swgg.pathObject._tags0 + + '/fileGetOneById/' + tmp.id + }); + return tmp; + }); + local.dbTableFile.crudSetManyById(crud.body, options.onNext); + break; + case 'userLoginByPassword': + case 'userLogout': + // respond with 401 Unauthorized + if (!user.isAuthenticated) { + local.serverRespondHeadSet(request, response, 401, {}); + request.swgg.crud.endArgList = [request, response]; + options.modeNext = Infinity; + options.onNext(); + return; + } + options.onNext(); + break; + default: + options.modeNext = Infinity; + options.onNext(); + } + break; + case 2: + switch (crud.operationId.split('.')[0]) { + case 'crudSetOneById': + case 'crudUpdateOneById': + options.onNext(null, data); + break; + case 'crudGetManyByQuery': + options.onNext(null, crud.queryData, { + paginationCountTotal: crud.paginationCountTotal + }); + break; + case 'fileUploadManyByForm': + options.onNext(null, data.map(function (element) { + delete element.fileBlob; + return element; + })); + break; + case 'userLoginByPassword': + options.onNext(null, { jwtEncrypted: user.jwtEncrypted }); + break; + case 'userLogout': + crud.dbTable.crudUpdateOneById({ + jwtEncrypted: null, + username: user.username + }, options.onNext); + break; + default: + options.onNext(null, data, meta); + } + break; + case 3: + switch (crud.operationId.split('.')[0]) { + case 'fileGetOneById': + if (!data) { + local.serverRespondDefault(request, response, 404); + return; + } + local.serverRespondHeadSet(request, response, null, { + 'Content-Type': data.fileContentType + }); + response.end(local.base64ToBuffer(data.fileBlob)); + break; + case 'userLogout': + options.onNext(); + break; + default: + options.onNext(null, data, meta); + } + break; + case 4: + request.swgg.crud.endArgList = [request, response, null, data, meta]; + options.onNext(); + break; + default: + nextMiddleware(error); + } + }); + options.modeNext = 0; + options.onNext(); + }; + + local.middlewareCrudEnd = function (request, response, nextMiddleware) { + /* + * this function will run the middleware that will end the builtin crud-operations + */ + // jslint-hack + local.nop(response); + if (request.swgg.crud.endArgList) { + local.serverRespondJsonapi.apply(null, request.swgg.crud.endArgList); + return; + } + nextMiddleware(); + }; + + local.middlewareRouter = function (request, response, nextMiddleware) { + /* + * this function will run the middleware that will + * map the request's method-path to swagger's tags[0]-operationId + */ + var tmp; + // jslint-hack + local.nop(response); + // init swgg object + local.objectSetDefault( + request, + { swgg: { crud: { operationId: '' }, user: {} } }, + 2 + ); + // if request.url is not prefixed with swaggerJson.basePath, + // then default to nextMiddleware + if (request.urlParsed.pathname.indexOf(local.swaggerJson.basePath) !== 0) { + nextMiddleware(); + return; + } + // init pathname + request.swgg.pathname = request.method + ' ' + request.urlParsed.pathname + .replace(local.swaggerJson.basePath, ''); + // init pathObject + while (request.swgg.pathname !== tmp) { + request.swgg.pathObject = + local.apiDict[request.swgg.pathname] || + // handle /foo/{id}/bar case + local.apiDict[request.swgg.pathname + .replace((/\/[^\/]+\/([^\/]*?)$/), '//$1')]; + // if pathObject exists, then break + if (request.swgg.pathObject) { + request.swgg.pathObject = local.jsonCopy(request.swgg.pathObject); + request.swgg.pathname = request.swgg.pathObject._keyPath; + // init crud.operationId + request.swgg.crud.operationId = request.swgg.pathObject._operationId; + break; + } + tmp = request.swgg.pathname; + request.swgg.pathname = request.swgg.pathname + .replace((/\/[^\/]+?(\/*?)$/), '/$1'); + } + nextMiddleware(); + }; + + local.middlewareUserLogin = function (request, response, nextMiddleware) { + /* + * this function will run the middleware that will handle user login + */ + var crud, options, user; + options = {}; + local.onNext(options, function (error, data) { + switch (options.modeNext) { + case 1: + local.dbTableUser = local.db.dbTableCreateOne({ name: 'User' }); + crud = request.swgg.crud; + user = request.swgg.user = {}; + user.jwtEncrypted = request.headers.authorization && + request.headers.authorization.replace('Bearer ', ''); + user.jwtDecrypted = local.jwtA256GcmDecrypt(user.jwtEncrypted); + switch (crud.operationId.split('.')[0]) { + // coverage-hack - test error handling-behavior + case 'crudErrorLogin': + options.onNext(local.errorDefault); + return; + case 'userLoginByPassword': + user.password = request.urlParsed.query.password; + user.username = request.urlParsed.query.username; + if (user.password && user.username) { + local.dbTableUser.crudGetOneById({ + username: user.username + }, options.onNext); + return; + } + break; + default: + if (user.jwtDecrypted.sub) { + // init username + user.username = user.jwtDecrypted.sub; + local.dbTableUser.crudGetOneById({ + username: user.username + }, options.onNext); + return; + } + } + options.modeNext = Infinity; + options.onNext(); + break; + case 2: + switch (crud.operationId.split('.')[0]) { + case 'userLoginByPassword': + user.data = data; + if (!local.sjclHashScryptValidate( + user.password, + user.data && user.data.password + )) { + options.modeNext = Infinity; + options.onNext(); + return; + } + // init isAuthenticated + user.isAuthenticated = true; + // https://tools.ietf.org/html/rfc7519 + // create JSON Web Token (JWT) + user.jwtDecrypted = {}; + user.jwtDecrypted.sub = user.data.username; + // update jwtEncrypted in client + user.jwtEncrypted = local.jwtA256GcmEncrypt(user.jwtDecrypted); + local.serverRespondHeadSet(request, response, null, { + 'swgg-jwt-encrypted': user.jwtEncrypted + }); + // update jwtEncrypted in dbTableUser + local.dbTableUser.crudUpdateOneById({ + jwtEncrypted: user.jwtEncrypted, + username: user.jwtDecrypted.sub + }, options.onNext); + return; + default: + data = user.data = data || {}; + if (data.jwtEncrypted) { + // init isAuthenticated + user.isAuthenticated = true; + // update jwtEncrypted in client + if (data.jwtEncrypted !== user.jwtEncrypted) { + user.jwtEncrypted = data.jwtEncrypted; + user.jwtDecrypted = local.jwtA256GcmDecrypt(user.jwtEncrypted); + local.serverRespondHeadSet(request, response, null, { + 'swgg-jwt-encrypted': user.jwtEncrypted + }); + } + } + } + options.onNext(); + break; + default: + nextMiddleware(error); + } + }); + options.modeNext = 0; + options.onNext(); + }; + + local.middlewareValidate = function (request, response, nextMiddleware) { + /* + * this function will run the middleware that will validate the swagger-request + */ + var crud, modeNext, onNext, tmp; + modeNext = 0; + onNext = function () { + modeNext += 1; + switch (modeNext) { + case 1: + // serve swagger.json + if (request.method + ' ' + request.urlParsed.pathname === + 'GET ' + local.swaggerJson.basePath + '/swagger.json') { + response.end(JSON.stringify(local.swaggerJson)); + return; + } + if (!request.swgg.pathObject) { + modeNext = Infinity; + onNext(); + return; + } + // init paramDict + request.swgg.paramDict = {}; + // parse path param + tmp = request.urlParsed.pathname + .replace(local.swaggerJson.basePath, '').split('/'); + request.swgg.pathObject._path.split('/').forEach(function (key, ii) { + if ((/^\{\S*?\}$/).test(key)) { + request.swgg.paramDict[key.slice(1, -1)] = + decodeURIComponent(tmp[ii]); + } + }); + request.swgg.pathObject.parameters.forEach(function (paramDef) { + switch (paramDef.in) { + // parse body param + case 'body': + request.swgg.paramDict[paramDef.name] = request.swgg.bodyParsed || + undefined; + break; + // parse formData param + case 'formData': + switch (String(request.headers['content-type']).split(';')[0]) { + case 'application/x-www-form-urlencoded': + request.swgg.paramDict[paramDef.name] = + request.swgg.bodyParsed[paramDef.name]; + break; + } + break; + // parse header param + case 'header': + request.swgg.paramDict[paramDef.name] = + request.headers[paramDef.name.toLowerCase()]; + break; + // parse query param + case 'query': + request.swgg.paramDict[paramDef.name] = + request.urlParsed.query[paramDef.name]; + break; + } + // parse array-multi + if (request.swgg.paramDict[paramDef.name] && + paramDef.type === 'array' && + paramDef.collectionFormat === 'multi') { + tmp = ''; + request.swgg.paramDict[paramDef.name].forEach(function (value) { + tmp += '&' + encodeURIComponent(paramDef.name) + '=' + + encodeURIComponent(value); + }); + request.swgg.paramDict[paramDef.name] = tmp.slice(1); + } + // init default param + if (local.isNullOrUndefined(request.swgg.paramDict[paramDef.name]) && + paramDef.default !== undefined) { + request.swgg.paramDict[paramDef.name] = + local.jsonCopy(paramDef.default); + } + }); + // normalize paramDict + local.normalizeParamDictSwagger( + request.swgg.paramDict, + request.swgg.pathObject + ); + // validate paramDict + local.validateByParamDefList({ + data: request.swgg.paramDict, + key: request.swgg.pathname, + paramDefList: request.swgg.pathObject.parameters + }); + onNext(); + break; + case 2: + // init crud + crud = request.swgg.crud; + // init crud.dbTable + crud.dbTable = request.swgg.pathObject && + request.swgg.pathObject._schemaName && + local.db.dbTableCreateOne({ + name: request.swgg.pathObject._schemaName + }); + if (!crud.dbTable) { + nextMiddleware(); + return; + } + // init crud.body + if (!request.swgg.isMultipartFormData) { + crud.body = local.jsonCopy(request.swgg.bodyParsed); + } + // init crud.data + crud.data = local.jsonCopy(request.swgg.paramDict); + request.swgg.pathObject.parameters.forEach(function (param) { + // JSON.parse json-string + if (param.format === 'json' && + param.type === 'string' && + crud.data[param.name]) { + crud.data[param.name] = JSON.parse(crud.data[param.name]); + } + }); + // init crud.query* + [{ + key: 'queryFields', + value: {} + }, { + key: 'queryLimit', + value: 100 + }, { + key: 'querySkip', + value: 0 + }, { + key: 'querySort', + value: [{ fieldName: '_timeUpdated', isDescending: true }] + }, { + key: 'queryWhere', + value: {} + }].forEach(function (element) { + crud[element.key] = crud.data['_' + element.key] || JSON.parse( + local.templateRender( + request.swgg.pathObject['_' + element.key] || 'null', + request.swgg.paramDict + ) + ) || element.value; + }); + // init-before crud.idField + crud.modeQueryByIdInvert = true; + local.idFieldInit(crud); + // init crud.data.id + switch (crud.operationId.split('.')[0]) { + case 'crudSetOneById': + case 'crudUpdateOneById': + if (!local.isNullOrUndefined(crud.data[crud.idField])) { + break; + } + crud.data[crud.idField] = (crud.body && crud.body[crud.idAlias]); + break; + } + // init-after crud.idField + crud.modeQueryByIdInvert = true; + local.idFieldInit(crud); + nextMiddleware(); + break; + default: + nextMiddleware(); + } + }; + onNext(); + }; + + local.normalizeParamDictSwagger = function (data, pathObject) { + /* + * this function will parse the data according to pathObject.parameters + */ + var tmp; + pathObject.parameters.forEach(function (paramDef) { + tmp = data[paramDef.name]; + // init default value + if (local.isNullOrUndefined(tmp) && paramDef.default !== undefined) { + tmp = local.jsonCopy(paramDef.default); + } + // parse array + if (paramDef.type === 'array' && paramDef.in !== 'body') { + if (typeof tmp === 'string') { + switch (paramDef.collectionFormat) { + case 'json': + local.tryCatchOnError(function () { + tmp = JSON.parse(tmp); + }, local.nop); + data[paramDef.name] = tmp; + return; + case 'multi': + tmp = local.urlParse('?' + tmp, true).query[paramDef.name]; + break; + case 'pipes': + tmp = tmp.split('|'); + break; + case 'ssv': + tmp = tmp.split(' '); + break; + case 'tsv': + tmp = tmp.split('\t'); + break; + // default to csv + default: + tmp = tmp.split(','); + } + if (paramDef.items && paramDef.items.type !== 'string') { + // try to JSON.parse the string + local.tryCatchOnError(function () { + tmp = tmp.map(function (element) { + return JSON.parse(element); + }); + }, local.nop); + } + } + // JSON.parse paramDict + } else if (paramDef.type !== 'file' && + paramDef.type !== 'string' && + (typeof tmp === 'string' || tmp instanceof local.global.Uint8Array)) { + // try to JSON.parse the string + local.tryCatchOnError(function () { + tmp = JSON.parse(local.bufferToString(tmp)); + }, local.nop); + } + data[paramDef.name] = tmp; + }); + return data; + }; + + local.onErrorJsonapi = function (onError) { + /* + * http://jsonapi.org/format/#errors + * http://jsonapi.org/format/#document-structure-resource-objects + * this function will normalize the error and data to jsonapi format, + * and pass them to onError + */ + return function (error, data, meta) { + data = [error, data].map(function (data, ii) { + // if no error occurred, then return + if ((ii === 0 && !data) || + // if data is already normalized, then return it + (data && data.meta && data.meta.isJsonapiResponse)) { + return data; + } + // normalize data-list + if (!Array.isArray(data)) { + data = [data]; + } + // normalize error-list to contain non-null objects + if (ii === 0) { + // normalize error-list to be non-empty + if (!data.length) { + data.push(null); + } + data = data.map(function (element) { + if (!(element && typeof element === 'object')) { + element = { message: String(element) }; + } + // normalize error-object to plain json-object + error = local.jsonCopy(element); + error.message = element.message; + error.stack = element.stack; + error.statusCode = Number(error.statusCode) || 500; + return error; + }); + error = local.jsonCopy(data[0]); + error.errors = data; + return error; + } + return { data: data }; + }); + // init data.meta + data.forEach(function (data, ii) { + if (!data) { + return; + } + data.meta = local.jsonCopy(meta || {}); + data.meta.isJsonapiResponse = true; + if (ii === 0) { + data.meta.errorsLength = (data.errors && data.errors.length) | 0; + } else { + data.meta.dataLength = (data.data && data.data.length) | 0; + } + data.meta.statusCode = Number(data.meta.statusCode) || + Number(data.statusCode) || + 0; + }); + onError(data[0], data[1]); + }; + }; + + local.schemaNormalizeAndCopy = function (schema) { + /* + * this function will return a normalized copy the schema + */ + var tmp; + // dereference $ref + if (schema.$ref) { + [local.swaggerJson, local.swaggerSchemaJson].some(function (options) { + local.tryCatchOnError(function () { + schema.$ref.replace( + (/#\/(.*?)\/(.*?)$/), + function (match0, match1, match2) { + // jslint-hack - nop + local.nop(match0); + tmp = options[match1][match2]; + } + ); + }, local.nop); + return tmp; + }); + // validate schema + local.assert(tmp, schema.$ref); + // recurse + schema = local.schemaNormalizeAndCopy(tmp); + } + // inherit allOf + if (schema.allOf) { + tmp = local.jsonCopy(schema); + delete tmp.allOf; + schema.allOf.reverse().forEach(function (element) { + // recurse + local.objectSetDefault(tmp, local.schemaNormalizeAndCopy(element), 2); + }); + schema = tmp; + } + schema = local.jsonCopy(schema); + if (schema.type === 'object') { + schema.properties = local.normalizeDict(schema.properties); + } + return schema; + }; + + local.serverRespondJsonapi = function (request, response, error, data, meta) { + /* + * http://jsonapi.org/format/#errors + * http://jsonapi.org/format/#document-structure-resource-objects + * this function will respond in jsonapi format + */ + local.onErrorJsonapi(function (error, data) { + local.serverRespondHeadSet(request, response, error && error.statusCode, { + 'Content-Type': 'application/json; charset=UTF-8' + }); + if (error) { + // debug statusCode / method / url + local.errorMessagePrepend(error, response.statusCode + ' ' + + request.method + ' ' + request.url + '\n'); + // print error.stack to stderr + local.onErrorDefault(error); + } + data = error || data; + data.meta.statusCode = response.statusCode = + data.meta.statusCode || response.statusCode; + response.end(JSON.stringify(data)); + })(error, data, meta); + }; + + local.uiAnimateFadeIn = function (element) { + /* + * this function will fadeIn the element + */ + element.classList.add('swggAnimateFade'); + element.style.display = ''; + setTimeout(function () { + element.style.opacity = ''; + }, 20); + setTimeout(function () { + element.classList.remove('swggAnimateFade'); + }, 500); + }; + + local.uiAnimateFadeOut = function (element) { + /* + * this function will fadeOut the element + */ + element.classList.add('swggAnimateFade'); + element.style.opacity = '0'; + setTimeout(function () { + element.style.display = 'none'; + element.classList.remove('swggAnimateFade'); + }, 500); + }; + + local.uiAnimateScrollTo = function (element) { + /* + * this function will scrollTo the element + */ + var ii, timerInterval; + ii = 0; + timerInterval = setInterval(function () { + ii += 0.025; + local.global.scrollTo(0, document.body.scrollTop + + Math.min(ii, 1) * (element.offsetTop - document.body.scrollTop) + + -5); + }, 25); + setTimeout(function () { + clearInterval(timerInterval); + }, 1000); + }; + + local.uiAnimateShake = function (element) { + /* + * this function will shake the dom-element + */ + element.classList.add('swggAnimateShake'); + setTimeout(function () { + element.classList.remove('swggAnimateShake'); + }, 500); + }; + + local.uiAnimateSlideAccordian = function (element, elementList) { + /* + * this function will slideDown the element, + * but slideUp all other elements in elementList + */ + // hide elements in elementList + elementList.forEach(function (element2) { + if (element2 !== element) { + local.uiAnimateSlideUp(element2); + } + }); + // show element + local.uiAnimateSlideDown(element); + }; + + local.uiAnimateSlideDown = function (element) { + /* + * this function will slideDown the dom-element + */ + if (element.style.display !== 'none') { + return; + } + element.style.maxHeight = 0; + element.classList.add('swggAnimateSlide'); + element.style.display = ''; + setTimeout(function () { + element.style.maxHeight = 2 * local.global.innerHeight + 'px'; + }, 20); + setTimeout(function () { + element.style.maxHeight = ''; + element.classList.remove('swggAnimateSlide'); + }, 500); + }; + + local.uiAnimateSlideUp = function (element) { + /* + * this function will slideUp the dom-element + */ + if (element.style.display === 'none') { + return; + } + element.style.maxHeight = 2 * local.global.innerHeight + 'px'; + element.classList.add('swggAnimateSlide'); + setTimeout(function () { + element.style.maxHeight = '0px'; + }, 20); + setTimeout(function () { + element.style.display = 'none'; + }, 500); + setTimeout(function () { + element.style.maxHeight = ''; + element.classList.remove('swggAnimateSlide'); + }, 500); + }; + + local.uiDatatableRender = function (options) { + /* + * this function will render the datatable + */ + var tmp; + local.uiState.datatable = options; + options.schema = local.schemaNormalizeAndCopy(options.schema); + options.propDefList = Object.keys(options.schema.properties) + .sort(function (aa, bb) { + return aa === options._idAlias + ? -1 + : bb === options._idAlias + ? 1 + : aa < bb + ? -1 + : 1; + }) + .map(function (propDef) { + tmp = propDef; + propDef = options.schema.properties[tmp]; + propDef.name = tmp; + local.uiParamRender(propDef); + return propDef; + }); + options.iiPadding = 0; + options.dbRowList = options.responseJson.data.map(function (dbRow, ii) { + dbRow = { paramDict: dbRow }; + dbRow.colList = options.propDefList.map(function (propDef) { + propDef = local.jsonCopy(propDef); + propDef.valueEncoded = dbRow.paramDict[propDef.name]; + if (propDef.valueEncoded === undefined) { + propDef.valueEncoded = ''; + } + if (typeof propDef.valueEncoded !== 'string') { + propDef.valueEncoded = JSON.stringify(propDef.valueEncoded); + } + return propDef; + }); + dbRow.id = dbRow.paramDict[options._idAlias]; + dbRow.ii = options.querySkip + ii + 1; + options.iiPadding = Math.max( + 0.375 * String(dbRow.ii).length, + options.iiPadding + ); + return dbRow; + }); + // init pagination + options.pageCurrent = Math.floor(options.querySkip / options.queryLimit); + options.pageTotal = Math.ceil( + options.responseJson.meta.paginationCountTotal / options.queryLimit + ); + options.pageMin = Math.max( + Math.min(options.pageCurrent - 3, options.pageTotal - 7), + 0 + ); + options.pageMax = Math.min(options.pageMin + 7, options.pageTotal); + options.pageList = []; + // add first page + options.pageList.push({ + disabled: options.pageCurrent === 0, + pageNumber: 0, + valueEncoded: 'first page' + }); + for (tmp = options.pageMin; tmp < options.pageMax; tmp += 1) { + options.pageList.push({ + disabled: tmp === options.pageCurrent, + pageNumber: tmp, + valueEncoded: JSON.stringify(tmp + 1) + }); + } + // add last page + options.pageList.push({ + disabled: options.pageCurrent === options.pageTotal - 1, + pageNumber: options.pageTotal - 1, + valueEncoded: 'last page' + }); + options.pageCurrentIsFirst = options.pageCurrent === 0; + options.pageCurrentIsLast = options.pageCurrent + 1 === options.pageTotal; + // templateRender datatable + document.querySelector('.swggUiContainer .datatable').innerHTML = + local.templateRender(local.templateUiDatatable, options); + // init event-handling + local.uiEventInit(document.querySelector('.swggUiContainer .datatable')); + // show modal + if (document.querySelector('.swggUiContainer > .modal').style.display !== 'none') { + return; + } + document.body.style.overflow = 'hidden'; + local.uiAnimateFadeIn(document.querySelector('.swggUiContainer > .modal')); + }; + + local.uiEventDelegate = function (event) { + Object.keys(local.uiEventListenerDict).sort().some(function (key) { + if (!(event.currentTarget.matches(key) || event.target.matches(key))) { + return; + } + switch (event.target.tagName) { + case 'A': + case 'BUTTON': + case 'FORM': + event.preventDefault(); + break; + } + event.stopPropagation(); + local.uiEventListenerDict[key](event); + return true; + }); + }; + + local.uiEventInit = function (element) { + /* + * this function will init event-handling for the dom-element + */ + ['Click', 'Submit'].forEach(function (eventType) { + Array.from( + element.querySelectorAll('.eventDelegate' + eventType) + ).forEach(function (element) { + element.addEventListener(eventType.toLowerCase(), local.uiEventDelegate); + }); + }); + }; + + local.uiEventListenerDict = {}; + + local.uiEventListenerDict['.onEventDatatableReload'] = function (event) { + /* + * this function will show the modal + */ + var options; + options = {}; + if (event) { + options.name = event.target.dataset.resourceName; + options.pageNumber = event.target.dataset.pageNumber; + } else { + options.name = local.uiState.datatable.name; + options.pageNumber = local.uiState.datatable.pageNumber; + options.queryLimit = local.uiState.datatable.queryLimit; + options.querySort = local.uiState.datatable.querySort; + options.queryWhere = local.uiState.datatable.queryWhere; + } + local.objectSetDefault( + options, + local.jsonCopy(local.uiState['x-swgg-datatableDict'][options.name]) + ); + options._idAlias = local.apiDict[options.crudRemoveOneById]._idAlias; + options._idField = local.apiDict[options.crudRemoveOneById]._idField; + local.objectSetDefault(options, { pageNumber: 0, queryLimit: 20 }); + options.querySkip = options.pageNumber * options.queryLimit; + options.paramDict = { + _queryLimit: options.queryLimit, + _querySkip: options.querySkip, + _querySort: options.querySort, + _queryWhere: options.queryWhere + }; + // request data + local.apiDict[options.crudGetManyByQuery]._ajax(options, function (error, options) { + // validate no error occurred + local.assert(!error, error); + local.uiDatatableRender(options); + // emit event uiDatatableRendered + document.dispatchEvent(new local.global.Event('uiDatatableRendered', { + bubbles: true, + cancelable: true + })); + }); + }; + + local.uiEventListenerDict['.onEventDatatableSelectedRemove'] = function () { + var onParallel; + onParallel = local.onParallel(local.uiEventListenerDict['.onEventDatatableReload']); + onParallel.counter += 1; + Array.from( + document.querySelectorAll('.swggUiContainer .datatable tr.selected') + ).forEach(function (element) { + onParallel.counter += 1; + // remove data + local.apiDict[ + local.uiState.datatable.crudRemoveOneById + ]._ajax(local.objectLiteralize({ + paramDict: { '$[]': [ + local.uiState.datatable._idField, + JSON.parse(decodeURIComponent(element.dataset.id)) + ] } + }), onParallel); + }); + onParallel(); + }; + + local.uiEventListenerDict['.onEventDatatableTrSelect'] = function (event) { + if (event.target.tagName !== 'INPUT') { + event.currentTarget.querySelector('input').checked = + !event.currentTarget.querySelector('input').checked; + } + Array.from( + event.currentTarget.closest('tr').querySelectorAll('input') + ).forEach(function (element) { + element.checked = event.currentTarget.querySelector('input').checked; + }); + if (event.currentTarget.querySelector('input').checked) { + event.currentTarget.closest('tr').classList.add('selected'); + } else { + event.currentTarget.closest('tr').classList.remove('selected'); + } + }; + + local.uiEventListenerDict['.onEventModalHide'] = function (event) { + /* + * this function will hide the modal + */ + if (event && !event.target.classList.contains('onEventModalHide')) { + return; + } + if (document.querySelector('.swggUiContainer > .modal').style.display === 'none') { + return; + } + document.body.style.overflow = ''; + // hide modeal + local.uiAnimateFadeOut(document.querySelector('.swggUiContainer > .modal')); + }; + + local.uiEventListenerDict['.onEventOperationAjax'] = function (event) { + /* + * this function will return submit the operation to the backend + */ + var options, tmp; + options = {}; + local.onNext(options, function (error, data) { + switch (options.modeNext) { + case 1: + options.api = local.apiDict[event.currentTarget.dataset._keyOperationId]; + options.domOperationContent = event.target.closest('.operation > .content'); + options.headers = {}; + options.paramDict = {}; + options.api.parameters.forEach(function (paramDef) { + local.tryCatchOnError(function () { + tmp = options.domOperationContent.querySelector( + '.paramDef[name=' + paramDef.name + '] > .td3' + ).children[0]; + switch (tmp.tagName) { + case 'INPUT': + // parse file + if (tmp.type === 'file') { + tmp = tmp.files && tmp.files[0]; + break; + } + tmp = tmp.value; + if (!tmp) { + return; + } + // parse string + if (paramDef.type !== 'string') { + tmp = JSON.parse(tmp); + } + break; + case 'SELECT': + tmp = Array.from(tmp.options) + .filter(function (element) { + return element.selected; + }) + .map(function (element) { + return JSON.parse(decodeURIComponent( + element.dataset.valueDecoded + )); + }); + if (!tmp.length || tmp[0] === '$swggUndefined') { + return; + } + if (paramDef.type !== 'array') { + tmp = tmp[0]; + } + break; + case 'TEXTAREA': + tmp = tmp.value; + if (!tmp) { + return; + } + // parse schema + if (paramDef.in === 'body') { + tmp = JSON.parse(tmp); + break; + } + // parse array + tmp = tmp.split('\n').map(function (element) { + return paramDef.items.type === 'string' + ? element + : JSON.parse(element); + }); + break; + } + options.paramDict[paramDef.name] = tmp; + }, function (error) { + options.errorValidate = error; + options.errorValidate.options = { key: paramDef.name }; + options.onNext(error); + }); + }); + options.api._ajax(options, options.onNext); + break; + default: + // remove previous error + Array.from( + options.domOperationContent.querySelectorAll('.paramDef .input') + ).forEach(function (element) { + element.classList.remove('error'); + }); + if (options.errorValidate) { + // shake input on Error + Array.from(options.domOperationContent.querySelectorAll( + '.paramDef[name=' + options.errorValidate.options.key + '] .input' + )).forEach(function (element) { + element.classList.add('error'); + local.uiAnimateShake(element.closest('span')); + }); + data = { + errorValidate: options.errorValidate, + responseText: error.message, + statusCode: 400 + }; + } + // init responseHeaders + data.responseHeaders = {}; + ( + (data.getAllResponseHeaders && data.getAllResponseHeaders()) || '' + ).replace( + (/.+/g), + function (item) { + item = item.split(':'); + data.responseHeaders[item[0].trim().toLowerCase()] = + item.slice(1).join(':').trim(); + } + ); + // init contentType + data.contentType = + String(data.responseHeaders['content-type']).split(';')[0]; + // init responseBody + switch (data.contentType.split('/')[0]) { + case 'audio': + case 'video': + data.responseBody = '<' + data.contentType.split('/')[0] + + ' controls>'; + break; + case 'image': + data.responseBody = ''; + break; + default: + data.responseBody = '
' + local.stringHtmlSafe(
+                            data.responseJson
+                                ? JSON.stringify(data.responseJson, null, 4)
+                                : data.responseText
+                        ) + '
'; + } + // init curl + local.tryCatchOnError(function () { + options.data = JSON.stringify(JSON.parse(options.data), null, 4); + }, local.nop); + data.curl = 'curl \\\n' + + '--request ' + options.api._method.toUpperCase() + ' \\\n' + + Object.keys(options.headers).map(function (key) { + return "--header '" + key + ': ' + options.headers[key] + "' \\\n"; + }).join('') + '--data-binary ' + (typeof options.data === 'string' + ? "'" + options.data.replace(/'/g, "'\"'\"'") + "'" + : '') + ' \\\n"' + options.url + '"'; + data.responseHeaders = data.getAllResponseHeaders && + data.getAllResponseHeaders().trim(); + // templateRender response + options.domOperationContent.querySelector( + '.responseAjax' + ).innerHTML = local.templateRender(local.templateUiResponseAjax, data); + break; + } + }); + options.modeNext = 0; + options.onNext(); + }; + + local.uiEventListenerDict['.onEventOperationDisplayShow'] = function (event) { + /* + * this function will toggle the display of the operation + */ + var tmp; + location.hash = '!/' + event.target.closest('.resource').id + '/' + + event.target.closest('.operation').id; + tmp = event.target.closest('.operation').querySelector('.operation > .content'); + tmp.closest('.resource').classList.remove('expanded'); + // show the operation, but hide all other operations + local.uiAnimateSlideAccordian( + tmp, + Array.from( + tmp.closest('.operationList').querySelectorAll('.operation > .content') + ) + ); + }; + + local.uiEventListenerDict['.onEventResourceDisplayAction'] = function (event) { + /* + * this function will toggle the display of the resource + */ + location.hash = '!/' + event.currentTarget.id; + event.target.className.split(' ').some(function (className) { + switch (className) { + // show the resource, but hide all other resources + case 'td1': + case 'td2': + case 'td3': + local.uiAnimateSlideAccordian( + event.currentTarget.querySelector('.operationList'), + Array.from(document.querySelectorAll('.swggUiContainer .operationList')) + ); + break; + } + switch (className) { + case 'td1': + case 'td2': + return true; + case 'td3': + // collapse all operations in the resource + if (event.currentTarget.classList.contains('expanded')) { + event.currentTarget.classList.remove('expanded'); + Array.from( + event.currentTarget.querySelectorAll('.operation > .content') + ).forEach(function (element) { + local.uiAnimateSlideUp(element); + }); + // expand all operations in the resource + } else { + event.currentTarget.classList.add('expanded'); + Array.from( + event.currentTarget.querySelectorAll('.operation > .content') + ).forEach(function (element) { + local.uiAnimateSlideDown(element); + }); + } + return true; + } + }); + }; + + local.uiEventListenerDict['.onEventUiReload'] = function () { + /* + * this function will reload the ui + */ + // reset ui + Array.from( + document.querySelectorAll('.swggUiContainer > .reset') + ).forEach(function (element) { + element.remove(); + }); + // normalize url + document.querySelector('.swggUiContainer > .header > .td2').value = + local.urlParse( + document.querySelector('.swggUiContainer > .header > .td2').value + .replace((/^\//), '') + ).href; + // display .swggAjaxProgressDiv + document.querySelector('.swggAjaxProgressDiv').textContent = + 'fetching resource list: ' + + document.querySelector('.swggUiContainer > .header > .td2').value + + '; Please wait.'; + document.querySelector('.swggAjaxProgressDiv').style.display = 'block'; + local.ajax({ + url: document.querySelector('.swggUiContainer > .header > .td2').value + }, function (error, xhr) { + // hide .swggAjaxProgressDiv + document.querySelector('.swggAjaxProgressDiv').style.display = 'none'; + // validate no error occurred + local.assert(!error, error); + // reset state + local.apiDict = local.swaggerJson = null; + local.apiDictUpdate(local.objectSetDefault(JSON.parse(xhr.responseText), { + host: local.urlParse( + document.querySelector('.swggUiContainer > .header > .td2').value + ).host + })); + local.uiRender(); + }); + }; + + local.uiParamRender = function (paramDef) { + /* + * this function will render the param + */ + paramDef.placeholder = paramDef.required + ? '(required)' + : ''; + // init input - file + if (paramDef.type === 'file') { + paramDef.isFile = true; + // init input - textarea + } else if (paramDef.in === 'body') { + paramDef.isTextarea = true; + // init input - select + } else if (paramDef.enum || paramDef.type === 'boolean') { + paramDef.enumDefault = []; + if (paramDef.default !== undefined) { + paramDef.enumDefault = paramDef.type === 'array' + ? paramDef.default + : [paramDef.default]; + } + paramDef.isSelect = true; + paramDef.isSelectMultiple = paramDef.type === 'array'; + paramDef.selectOptionList = (paramDef.type === 'boolean' + ? [false, true] + : paramDef.enum).map(function (element) { + paramDef.hasDefault |= paramDef.enumDefault.indexOf(element) >= 0; + return { + id: local.idDomElementCreate('swgg_id_' + paramDef.name), + selected: paramDef.enumDefault.indexOf(element) >= 0 + ? 'selected' + : '', + type: (paramDef.items && paramDef.items.type) || paramDef.type, + valueDecoded: element, + valueEncoded: typeof element === 'string' + ? element + : JSON.stringify(element) + }; + }); + // init 'undefined' value + if (!(paramDef.hasDefault || + paramDef.isSelectMultiple || + paramDef.required)) { + paramDef.selectOptionList.unshift({ + id: local.idDomElementCreate('swgg_id_' + paramDef.name), + selected: 'selected', + type: paramDef.type, + valueDecoded: '$swggUndefined', + valueEncoded: '' + }); + } + // if required, then select at least one value + if (paramDef.required && paramDef.selectOptionList.length) { + paramDef.selected = paramDef.selectOptionList[0]; + paramDef.selectOptionList.some(function (element) { + if (element.selected) { + paramDef.selected = element.selected; + return true; + } + }); + paramDef.selected = 'selected'; + } + // init input - textarea + } else if (paramDef.type === 'array') { + paramDef.isTextarea = true; + paramDef.placeholder = 'provide multiple values in new lines' + + (paramDef.required + ? ' (at least one required)' + : ''); + // init input - text + } else { + paramDef.isInputText = true; + } + // init format2 / type2 + [ + paramDef, + paramDef.schema + ].some(function (element) { + local.tryCatchOnError(function () { + paramDef.format2 = paramDef.format2 || element.format; + }, local.nop); + local.tryCatchOnError(function () { + paramDef.type2 = paramDef.type2 || element.type; + }, local.nop); + return paramDef.type2; + }); + paramDef.type2 = paramDef.type2 || 'object'; + // init schema2 + [ + paramDef.items, + paramDef.schema, + paramDef.schema && paramDef.schema.items + ].some(function (element) { + paramDef.schema2 = local.schemaNormalizeAndCopy(element || {}).properties; + return paramDef.schema2; + }); + if (paramDef.schema2) { + paramDef.schemaText = JSON.stringify(paramDef.type2 === 'array' + ? [paramDef.schema2] + : paramDef.schema2, null, 4); + } + // init valueEncoded + paramDef.valueEncoded = paramDef.default; + if (paramDef.valueEncoded === undefined) { + paramDef.valueEncoded = local.dbFieldRandomCreate({ + modeNotRandom: true, + propDef: paramDef + }); + } + // init valueEncoded for array + if (paramDef.valueEncoded && paramDef.type2 === 'array' && paramDef.in !== 'body') { + paramDef.valueEncoded = paramDef.valueEncoded.map(function (element) { + return typeof element === 'string' + ? element + : JSON.stringify(element); + }).join('\n'); + } + // init valueEncoded for schema + if (paramDef.in === 'body' && paramDef.schema2) { + paramDef.valueEncoded = local.dbRowRandomCreate({ + modeNotRandom: true, + override: function () { + var override = {}; + // preserve default value + Object.keys(paramDef.schema2).forEach(function (key) { + if (paramDef.schema2[key].default !== undefined) { + override[key] = paramDef.schema2[key].default; + } + }); + return override; + }, + properties: paramDef.schema2 + }); + if (paramDef.type2 === 'array') { + paramDef.valueEncoded = [paramDef.valueEncoded]; + } + paramDef.valueEncoded = JSON.stringify(paramDef.valueEncoded, null, 4); + } + if (typeof paramDef.valueEncoded !== 'string') { + paramDef.valueEncoded = JSON.stringify(paramDef.valueEncoded) || ''; + } + // templateRender paramDef + paramDef.innerHTML = local.templateRender(local.templateUiParam, paramDef); + }; + + local.uiRender = function () { + /* + * this function will render swagger-ui + */ + var resource, self; + // reset state + local.idDomElementDict = {}; + self = local.uiState = local.jsonCopy(local.swaggerJson); + // init url + self.url = document.querySelector('.swggUiContainer > .header > .td2').value; + // templateRender main + self.uiFragment = local.domFragmentRender(local.templateUiMain, self); + local.objectSetDefault(self, { + resourceDict: {}, + operationDict: {}, + tagDict: {} + }); + // init tagDict + self.tags.forEach(function (tag) { + self.tagDict[tag.name] = tag; + }); + // init operationDict + Object.keys(local.apiDict).sort().forEach(function (operation) { + // init operation + operation = local.jsonCopy(local.apiDict[operation]); + operation.tags.forEach(function (tag) { + self.operationDict[operation._keyOperationId] = operation; + // init resource + resource = self.resourceDict[tag]; + if (!resource && self.tagDict[tag]) { + resource = self.resourceDict[tag] = self.tagDict[tag]; + local.objectSetDefault(resource, { + description: 'no description available', + id: local.idDomElementCreate('swgg_id_' + tag), + name: tag, + operationListInnerHtml: '' + }); + } + }); + }); + // init resourceDict + Object.keys(self.resourceDict).sort().forEach(function (key) { + // templateRender resource + self.uiFragment.querySelector('.resourceList').appendChild( + local.domFragmentRender(local.templateUiResource, self.resourceDict[key]) + ); + }); + Object.keys(self.operationDict).sort(function (aa, bb) { + aa = self.operationDict[aa]; + aa = aa._path + ' ' + aa._method; + bb = self.operationDict[bb]; + bb = bb._path + ' ' + bb._method; + return aa < bb + ? -1 + : 1; + }).forEach(function (operation) { + operation = self.operationDict[operation]; + operation.id = local.idDomElementCreate('swgg_id_' + operation.operationId); + operation.tags.forEach(function (tag) { + operation = local.jsonCopy(operation); + resource = self.resourceDict[tag]; + local.objectSetDefault(operation, { + description: '', + responseList: Object.keys(operation.responses).sort() + .map(function (key) { + return { key: key, value: operation.responses[key] }; + }), + summary: 'no summary available' + }); + operation.parameters.forEach(function (element) { + // init element.id + element.id = local.idDomElementCreate('swgg_id_' + element.name); + local.uiParamRender(element); + }); + // templateRender operation + self.uiFragment.querySelector('#' + resource.id + ' .operationList') + .appendChild( + local.domFragmentRender(local.templateUiOperation, operation) + ); + }); + }); + // overwrite swggUiContainer with uiFragment + document.querySelector('.swggUiContainer').innerHTML = ''; + document.querySelector('.swggUiContainer').appendChild(self.uiFragment); + /* istanbul ignore next */ + // bug-workaround - add keypress listener for + document.querySelector('form2').addEventListener('keypress', function (event) { + if (event.keyCode === 13) { + local.uiEventListenerDict['.onEventUiReload'](); + } + }); + // render valueEncoded + Array.from( + document.querySelectorAll('.swggUiContainer [data-value-encoded]') + ).forEach(function (element) { + element.value = decodeURIComponent(element.dataset.valueEncoded); + }); + // init event-handling + local.uiEventInit(document); + // scrollTo location.hash + local.uiScrollTo(location.hash); + }; + + local.uiScrollTo = function (locationHash) { + /* + * this function will scrollTo locationHash + */ + var operation, resource; + // init resource + resource = locationHash.split('/')[1]; + // list operations + resource = document.querySelector('.swggUiContainer #' + resource) || + document.querySelector('.swggUiContainer .resource'); + local.uiAnimateSlideDown(resource.querySelector('.operationList')); + // init operation + operation = locationHash.split('/')[2]; + operation = resource.querySelector('#' + operation); + // expand operation and scroll to it + if (operation) { + local.uiAnimateSlideDown(operation.querySelector('.content')); + // scroll to operation + local.uiAnimateScrollTo(operation); + } else { + // scroll to resource + local.uiAnimateScrollTo(resource); + } + }; + + local.urlBaseGet = function () { + /* + * this function will return the base swagger url + */ + return (local.swaggerJson.schemes || + local.urlParse('').protocol.slice(0, -1)) + '://' + + (local.swaggerJson.host || local.urlParse('').host) + + local.swaggerJson.basePath; + }; + + local.userLoginByPassword = function (options, onError) { + /* + * this function will send a login-by-password request + */ + local.apiDict["GET /user/userLoginByPassword"]._ajax({ + paramDict: { password: options.password, username: options.username } + }, onError); + }; + + local.userLogout = function (options, onError) { + /* + * this function will send a logout request + */ + local.apiDict["GET /user/userLogout"]._ajax(options, onError); + }; + + local.utility2._middlewareError = function (error, request, response) { + /* + * this function will run the middleware that will + * handle errors according to http://jsonapi.org/format/#errors + */ + if (!error) { + error = new Error('404 Not Found'); + error.statusCode = 404; + } + local.serverRespondJsonapi(request, response, error); + }; + + local.utility2._stateInit = function (options) { + /* + * this function will init the state-options + */ + local.objectSetOverride(local, options, 10); + // init api + local.apiDictUpdate(local.swaggerJson); + }; + + local.validateByParamDefList = function (options) { + /* + * this function will validate options.data against options.paramDefList + */ + var data, key; + local.tryCatchOnError(function () { + data = options.data; + // validate data + local.assert(data && typeof data === 'object', data); + (options.paramDefList || []).forEach(function (paramDef) { + key = paramDef.name; + // recurse - validateByPropDef + local.validateByPropDef({ + circularList: options.circularList, + data: data[key], + dataReadonlyRemove: (options.dataReadonlyRemove || {})[key], + key: key, + schema: paramDef, + required: paramDef.required, + 'x-swgg-notRequired': paramDef['x-swgg-notRequired'] + }); + }); + }, function (error) { + error.statusCode = error.statusCode || 400; + local.errorMessagePrepend(error, options.key + '.' + key + ' -> '); + throw error; + }); + }; + + local.validateByPropDef = function (options) { + /* + * this function will validate options.data against options.schema + */ + var data, prefix, propDef, tmp; + local.tryCatchOnError(function () { + data = options.data; + prefix = 'property ' + options.key; + propDef = options.schema; + // validate undefined data + if (local.isNullOrUndefined(data)) { + if (options.required && !options['x-swgg-notRequired']) { + tmp = new Error(prefix + ' cannot be null or undefined'); + tmp.options = options; + throw tmp; + } + return; + } + // handle $ref + tmp = propDef.$ref || (propDef.schema && propDef.schema.$ref); + if (tmp) { + // recurse - validateBySchema + local.validateBySchema({ + circularList: options.circularList, + data: data, + dataReadonlyRemove: options.dataReadonlyRemove, + key: tmp, + schema: local.schemaNormalizeAndCopy({ $ref: tmp }), + 'x-swgg-notRequired': options['x-swgg-notRequired'] + }); + return; + } + // handle anyOf + if (propDef.anyOf) { + tmp = propDef.anyOf.some(function (element) { + local.tryCatchOnError(function () { + // recurse - validateBySchema + local.validateBySchema({ + circularList: options.circularList, + data: data, + key: 'anyOf', + schema: local.schemaNormalizeAndCopy(element), + 'x-swgg-notRequired': options['x-swgg-notRequired'] + }); + }, local.nop); + return !local.utility2._debugTryCatchErrorCaught; + }); + local.assert(tmp, local.utility2._debugTryCatchErrorCaught); + return; + } + // normalize propDef + propDef = local.schemaNormalizeAndCopy(options.schema); + // init circularList + if (data && typeof data === 'object') { + options.circularList = options.circularList || []; + if (options.circularList.indexOf(data) >= 0) { + return; + } + options.circularList.push(data); + } + // validate propDef embedded in propDef.schema.type + if (!propDef.type && propDef.schema && propDef.schema.type) { + propDef = propDef.schema; + } + // http://json-schema.org/latest/json-schema-validation.html#anchor13 + // 5.1. Validation keywords for numeric instances (number and integer) + if (typeof data === 'number') { + if (typeof propDef.multipleOf === 'number') { + local.assert( + data % propDef.multipleOf === 0, + prefix + ' must be a multiple of ' + propDef.multipleOf + ); + } + if (typeof propDef.maximum === 'number') { + local.assert( + propDef.exclusiveMaximum + ? data < propDef.maximum + : data <= propDef.maximum, + prefix + ' must be ' + (propDef.exclusiveMaximum + ? '< ' + : '<= ') + propDef.maximum + ); + } + if (typeof propDef.minimum === 'number') { + local.assert( + propDef.exclusiveMinimum + ? data > propDef.minimum + : data >= propDef.minimum, + prefix + ' must be ' + (propDef.exclusiveMinimum + ? '> ' + : '>= ') + propDef.minimum + ); + } + // http://json-schema.org/latest/json-schema-validation.html#anchor25 + // 5.2. Validation keywords for strings + } else if (typeof data === 'string') { + if (propDef.maxLength) { + local.assert( + data.length <= propDef.maxLength, + prefix + ' must have <= ' + propDef.maxLength + ' characters' + ); + } + if (propDef.minLength) { + local.assert( + data.length >= propDef.minLength, + prefix + ' must have >= ' + propDef.minLength + ' characters' + ); + } + if (propDef.pattern) { + local.assert( + new RegExp(propDef.pattern).test(data), + prefix + ' must match regex pattern /' + propDef.pattern + '/' + ); + } + // http://json-schema.org/latest/json-schema-validation.html#anchor36 + // 5.3. Validation keywords for arrays + } else if (Array.isArray(data)) { + if (propDef.maxItems) { + local.assert( + data.length <= propDef.maxItems, + prefix + ' must have <= ' + propDef.maxItems + ' items' + ); + } + if (propDef.minItems) { + local.assert( + data.length >= propDef.minItems, + prefix + ' must have >= ' + propDef.minItems + ' items' + ); + } + if (propDef.uniqueItems) { + tmp = {}; + data.forEach(function (element) { + element = JSON.stringify(element); + local.assert( + !tmp[element], + prefix + ' must have only unique items' + ); + tmp[element] = true; + }); + } + // http://json-schema.org/latest/json-schema-validation.html#anchor53 + // 5.4. Validation keywords for objects + } else if (typeof data === 'object') { + if (propDef.maxProperties) { + local.assert( + Object.keys(data).length <= propDef.maxProperties, + prefix + ' must have <= ' + propDef.maxProperties + ' items' + ); + } + if (propDef.minProperties) { + local.assert( + Object.keys(data).length >= propDef.minProperties, + prefix + ' must have >= ' + propDef.minProperties + ' items' + ); + } + } + // http://json-schema.org/latest/json-schema-validation.html#anchor75 + // 5.5. Validation keywords for any instance type + if (propDef.enum) { + (Array.isArray(data) + ? data + : [data]).forEach(function (element) { + local.assert( + propDef.enum.indexOf(element) >= 0, + prefix + ' must only have items in the list ' + + JSON.stringify(propDef.enum) + ); + }); + } + // https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md + // #data-types + // validate schema.type + switch (propDef.type) { + case 'array': + local.assert(Array.isArray(data) && propDef.items); + data.forEach(function (element, ii) { + // recurse - validateByPropDef + local.validateByPropDef({ + circularList: options.circularList, + data: element, + dataReadonlyRemove: (options.dataReadonlyRemove || {})[ii], + key: ii, + schema: propDef.items, + 'x-swgg-notRequired': options['x-swgg-notRequired'] + }); + }); + switch (propDef.collectionFormat) { + case 'multi': + local.assert( + propDef.in === 'formData' || propDef.in === 'query', + prefix + ' with collectionFormat "multi" ' + + 'is valid only for parameters in "query" or "formData"' + ); + break; + } + break; + case 'boolean': + local.assert(typeof data === 'boolean'); + break; + case 'file': + break; + case 'integer': + local.assert(typeof data === 'number' && + isFinite(data) && + Math.floor(data) === data); + switch (propDef.format) { + case 'int32': + case 'int64': + break; + } + break; + case 'number': + local.assert(typeof data === 'number' && isFinite(data)); + switch (propDef.format) { + case 'double': + case 'float': + break; + } + break; + case 'object': + local.assert(typeof data === 'object'); + break; + case 'string': + local.assert(typeof data === 'string' || propDef.format === 'binary'); + switch (propDef.format) { + // https://github.com/swagger-api/swagger-spec/issues/50 + // Clarify 'byte' format #50 + case 'byte': + local.assert(!(/[^\n\r\+\/0-9\=A-Za-z]/).test(data)); + break; + case 'date': + case 'date-time': + local.assert(JSON.stringify(new Date(data)) !== 'null'); + break; + case 'email': + local.assert(local.regexpEmailValidate.test(data)); + break; + case 'phone': + local.assert(local.regexpPhoneValidate.test(data)); + break; + case 'json': + JSON.parse(data); + break; + } + break; + default: + local.assert( + propDef.type === undefined, + prefix + ' has invalid type ' + propDef.type + ); + } + }, function (error) { + error.message = error.message || prefix + ' is not a valid ' + propDef.type + + (propDef.format + ? ' (' + propDef.format + ')' + : ''); + error.options = options; + throw error; + }); + }; + + local.validateBySchema = function (options) { + /* + * this function will validate options.data against options.schema + */ + var data, key, prefix, propDefDict, schema, tmp, validateByPropDef; + // recurse - validateByPropDef + local.validateByPropDef(options); + local.tryCatchOnError(function () { + data = options.data; + prefix = 'schema ' + options.key; + schema = options.schema; + // validate schema + local.assert( + schema && typeof schema === 'object', + prefix + ' must be an object (not ' + typeof schema + ')' + ); + // init propDefDict + propDefDict = schema.properties || {}; + // validate data + local.assert( + (data && typeof data === 'object') || !Object.keys(propDefDict).length, + 'data for ' + prefix + ' must be an object (not ' + typeof data + ')' + ); + if (typeof data !== 'object') { + return; + } + validateByPropDef = function (propDef) { + // remove options.dataReadonlyRemove[key] + if (propDef.readOnly && + (options.dataReadonlyRemove || {}).hasOwnProperty(key)) { + delete options.dataReadonlyRemove[key]; + } + // recurse - validateByPropDef + local.validateByPropDef({ + circularList: options.circularList, + data: data[key], + dataReadonlyRemove: (options.dataReadonlyRemove || {})[key], + key: key, + schema: propDef, + required: schema.required && schema.required.indexOf(key) >= 0, + 'x-swgg-notRequired': options['x-swgg-notRequired'] + }); + }; + Object.keys(propDefDict).forEach(function (_) { + key = _; + validateByPropDef(propDefDict[key]); + }); + Object.keys(data).forEach(function (_) { + key = _; + if (propDefDict[key]) { + return; + } + tmp = Object.keys(schema.patternProperties || {}).some(function (_) { + if (new RegExp(_).test(key)) { + validateByPropDef(schema.patternProperties[_]); + return true; + } + }); + if (tmp) { + return; + } + // https://tools.ietf.org/html/draft-fge-json-schema-validation-00 + // #section-5.4.4 + // validate additionalProperties + local.assert( + schema.additionalProperties !== false, + prefix + ' must not have additionalProperties - ' + key + ); + if (schema.additionalProperties) { + validateByPropDef(schema.additionalProperties); + } + }); + }, function (error) { + local.errorMessagePrepend(error, options.key + '.' + key + ' -> '); + throw error; + }); + }; + + local.validateBySwagger = function (options) { + /* + * this function will validate the entire swagger json object + */ + var key, schema, tmp, validateDefault; + local.validateBySchema({ + data: options, + key: 'swaggerJson', + schema: local.swaggerSchemaJson + }); + // validate default + validateDefault = function () { + if (schema.default !== undefined) { + return; + } + local.validateByPropDef({ + data: schema.default, + key: key + '.default', + schema: schema + }); + }; + Object.keys(options.definitions).forEach(function (schemaName) { + schema = options.definitions[schemaName]; + key = schemaName; + validateDefault(); + Object.keys(options.definitions[schemaName].properties || { + }).forEach(function (propName) { + schema = options.definitions[schemaName].properties[propName]; + key = schemaName + '.' + propName; + validateDefault(); + }); + }); + Object.keys(options.paths).forEach(function (pathName) { + Object.keys(options.paths[pathName]).forEach(function (methodName) { + tmp = options.paths[pathName][methodName]; + Object.keys(tmp.parameters).forEach(function (paramName) { + schema = tmp.parameters[paramName]; + key = tmp.tags[0] + '.' + tmp.operationId + '.' + paramName; + validateDefault(); + }); + }); + }); + }; + }()); + switch (local.modeJs) { + + + + // run browser js-env code - init-after + case 'browser': + // init state + local.utility2._stateInit({}); + break; + + + + // run node js-env code - init-after + case 'node': + // init assets.lib.rollup.js + local.assetsDict['/assets.swgg.rollup.js'] = + local.assetsDict['/assets.utility2.rollup.js']; + // init state + local.utility2._stateInit({}); + break; + } + switch (local.modeJs) { + + + + /* istanbul ignore next */ + // run node js-env code - cli + case 'node': + /* istanbul ignore next */ + if (local.env.SWAGGER_JSON_URL) { + if (local.env.SWAGGER_JSON_URL === '127.0.0.1') { + local.env.SWAGGER_JSON_URL = '/assets.swgg.petstore.json'; + } + local.assetsDict['/assets.swgg.html'] = + local.assetsDict['/assets.swgg.html'].replace( + 'assets.swgg.petstore.json', + local.env.SWAGGER_JSON_URL + ); + } + // run the cli + switch (process.argv[2]) { + case 'swagger-ui': + local.replStart(); + local.global.local = local; + local.assetsDict['/'] = local.assetsDict['/assets.swgg.html']; + local.testRunServer({}); + break; + } + break; + } +}()); +/* script-end /assets.swgg.js */ + + + +/* script-begin /assets.utility2.rollup.end.js */ +(function () { + "use strict"; + var local; + local = {}; + local.modeJs = (function () { + try { + return typeof navigator.userAgent === "string" && + typeof document.querySelector("body") === "object" && + typeof XMLHttpRequest.prototype.open === "function" && + "browser"; + } catch (errorCaughtBrowser) { + return module.exports && + typeof process.versions.node === "string" && + typeof require("http").createServer === "function" && + "node"; + } + }()); + local.global = local.modeJs === "browser" + ? window + : global; + local.global.utility2_rollup_old = local.global.utility2_rollup; + local.global.utility2_rollup = null; +}()); +/* utility2.rollup.js end */ +/* script-end /assets.utility2.rollup.end.js */ diff --git a/build..alpha..travis-ci.org/app/index.html b/build..alpha..travis-ci.org/app/index.html new file mode 100644 index 0000000..fa96ab4 --- /dev/null +++ b/build..alpha..travis-ci.org/app/index.html @@ -0,0 +1,87 @@ + + + + + +npmdoc-debowerify (v0.0.2) + + + + + +
+ +

+ + + + npmdoc-debowerify (v0.0.2) + + + +

+

#### basic api documentation for [debowerify (v1.5.0)](https://github.com/eugeneware/debowerify#readme) [![npm package](https://img.shields.io/npm/v/npmdoc-debowerify.svg?style=flat-square)](https://www.npmjs.org/package/npmdoc-debowerify) [![travis-ci.org build-status](https://api.travis-ci.org/npmdoc/node-npmdoc-debowerify.svg)](https://travis-ci.org/npmdoc/node-npmdoc-debowerify)

+ +

download standalone app

+
+ + + + + + + + + + + + + + + + + + +
+ [ this app was created with + utility2 + ] +
+ + diff --git a/build..alpha..travis-ci.org/app/jsonp.utility2._stateInit b/build..alpha..travis-ci.org/app/jsonp.utility2._stateInit new file mode 100644 index 0000000..7f5af19 --- /dev/null +++ b/build..alpha..travis-ci.org/app/jsonp.utility2._stateInit @@ -0,0 +1 @@ +window.utility2._stateInit({"utility2":{"assetsDict":{"/assets.index.template.html":"\n\n\n\n\n{{env.npm_package_name}} (v{{env.npm_package_version}})\n\n\n\n\n\n

\n\n {{env.npm_package_name}} (v{{env.npm_package_version}})\n\n

\n

{{env.npm_package_description}}

\n\n\n\n\n\n\n\n\n\n\n\n\n\n
\n [ this app was created with\n utility2\n ]\n
\n\n\n"},"env":{"NODE_ENV":"test","npm_package_description":"#### basic api documentation for [debowerify (v1.5.0)](https://github.com/eugeneware/debowerify#readme) [![npm package](https://img.shields.io/npm/v/npmdoc-debowerify.svg?style=flat-square)](https://www.npmjs.org/package/npmdoc-debowerify) [![travis-ci.org build-status](https://api.travis-ci.org/npmdoc/node-npmdoc-debowerify.svg)](https://travis-ci.org/npmdoc/node-npmdoc-debowerify)","npm_package_homepage":"https://github.com/npmdoc/node-npmdoc-debowerify","npm_package_name":"npmdoc-debowerify","npm_package_nameAlias":"npmdoc_debowerify","npm_package_version":"0.0.2"}}}); \ No newline at end of file diff --git a/build..alpha..travis-ci.org/build.badge.svg b/build..alpha..travis-ci.org/build.badge.svg new file mode 100644 index 0000000..97d696b --- /dev/null +++ b/build..alpha..travis-ci.org/build.badge.svg @@ -0,0 +1 @@ +last buildlast build2017-04-27 16:48:12 UTC | alpha | alpha2017-04-27 16:48:12 UTC | alpha | alpha \ No newline at end of file diff --git a/build..alpha..travis-ci.org/screenCapture.buildCi.browser.%2Ftmp%2Fbuild%2Fapidoc.html.html b/build..alpha..travis-ci.org/screenCapture.buildCi.browser.%2Ftmp%2Fbuild%2Fapidoc.html.html new file mode 100644 index 0000000..8b713d5 --- /dev/null +++ b/build..alpha..travis-ci.org/screenCapture.buildCi.browser.%2Ftmp%2Fbuild%2Fapidoc.html.html @@ -0,0 +1,72 @@ +
+ +

api documentation for + debowerify (v1.5.0) +

+

A browserify transform to enable the easy use of bower components in browserify client javascript projects. This can be used in conjunction with deamdify to require AMD components from bower as well.

+ + + + +
+ [ this document was created with + utility2 + ] +
+
+ \ No newline at end of file diff --git a/build..alpha..travis-ci.org/screenCapture.buildCi.browser.%2Ftmp%2Fbuild%2Fapidoc.html.png b/build..alpha..travis-ci.org/screenCapture.buildCi.browser.%2Ftmp%2Fbuild%2Fapidoc.html.png new file mode 100644 index 0000000..db0241f Binary files /dev/null and b/build..alpha..travis-ci.org/screenCapture.buildCi.browser.%2Ftmp%2Fbuild%2Fapidoc.html.png differ diff --git a/build..alpha..travis-ci.org/screenCapture.buildCi.browser.%2Ftmp%2Fbuild%2Ftest-report.html.html b/build..alpha..travis-ci.org/screenCapture.buildCi.browser.%2Ftmp%2Fbuild%2Ftest-report.html.html new file mode 100644 index 0000000..fd4f01a --- /dev/null +++ b/build..alpha..travis-ci.org/screenCapture.buildCi.browser.%2Ftmp%2Fbuild%2Ftest-report.html.html @@ -0,0 +1,236 @@ +
+ +

test-report for + npmdoc-debowerify (v0.0.2) +

+
+

summary

+

+ version- + 0.0.2
+ test date- 2017-04-27T16:48:09.775Z
+ commit info- + + alpha - [npm publishAfterCommitAfterBuild]
+ +

+ + + + + + + + + + + + + + + +
total time-elapsedtotal tests failedtotal tests passedtotal tests pending
27603 ms090
+
+ +
+

+ 1. buildApidoc - node - linux v6.10.2 - 2017-04-27T16:48:09.667Z
+ + time-elapsed- 1313 ms
+ tests failed- 0
+ tests passed- 1
+ tests pending- 0
+

+ + + + + + + + + + + + + + + + + +
#time-elapsedstatustest-case
11 mspassedtestCase_buildApidoc_default
+
+
+
+ +
+

+ 2. buildApp - node - linux v6.10.2 - 2017-04-27T16:47:43.368Z
+ + time-elapsed- 27603 ms
+ tests failed- 0
+ tests passed- 7
+ tests pending- 0
+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
#time-elapsedstatustest-case
21 mspassedtestCase_buildApidoc_default
36517 mspassedtestCase_buildApp_default
4164 mspassedtestCase_buildCustomOrg_default
51 mspassedtestCase_buildLib_default
60 mspassedtestCase_buildReadme_default
70 mspassedtestCase_buildTest_default
811979 mspassedtestCase_webpage_default
+
+
+
+ +
+

+ 3. npmTest - browser - / - Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Electron/1.4.16 Safari/537.36 - 2017-04-27T16:47:57.614Z
+ + + + +
+ + time-elapsed- 14809 ms
+ tests failed- 0
+ tests passed- 1
+ tests pending- 0
+

+ + + + + + + + + + + + + + + + + +
#time-elapsedstatustest-case
91 mspassedtestCase_browser_nullCase
+
+
+
+ +
+ [ this document was created with + utility2 + ] +
+
+ \ No newline at end of file diff --git a/build..alpha..travis-ci.org/screenCapture.buildCi.browser.%2Ftmp%2Fbuild%2Ftest-report.html.png b/build..alpha..travis-ci.org/screenCapture.buildCi.browser.%2Ftmp%2Fbuild%2Ftest-report.html.png new file mode 100644 index 0000000..49bf1af Binary files /dev/null and b/build..alpha..travis-ci.org/screenCapture.buildCi.browser.%2Ftmp%2Fbuild%2Ftest-report.html.png differ diff --git a/build..alpha..travis-ci.org/screenCapture.gitLog.svg b/build..alpha..travis-ci.org/screenCapture.gitLog.svg new file mode 100644 index 0000000..5ee4d16 --- /dev/null +++ b/build..alpha..travis-ci.org/screenCapture.gitLog.svg @@ -0,0 +1,20 @@ + + + +2017-04-28 00:39:08 +0800 +[npm publishAfterCommitAfterBuild] +2017-04-18 15:49:30 +0000 +[ci skip] npm published + +2017-04-18 17:03:22 +0800 +[npm publishAfterCommitAfterBuild] +2017-04-06 18:58:28 +0000 +[ci skip] npm published + +2017-04-06 17:22:27 +0000 +[npm publishAfterCommitAfterBuild] + +2014-03-26 02:31:50 +0700 +add blank README.md + + diff --git a/build..alpha..travis-ci.org/screenCapture.npmPackageDependencyTree.svg b/build..alpha..travis-ci.org/screenCapture.npmPackageDependencyTree.svg new file mode 100644 index 0000000..89ee935 --- /dev/null +++ b/build..alpha..travis-ci.org/screenCapture.npmPackageDependencyTree.svg @@ -0,0 +1,219 @@ + + + +32 megabytes installed + +node_modules +└─┬ debowerify@1.5.0 + ├─┬ bower@1.3.12 + │ ├── abbrev@1.0.9 + │ ├── archy@0.0.2 + │ ├─┬ bower-config@0.5.2 + │ │ ├── graceful-fs@2.0.3 + │ │ ├─┬ optimist@0.6.1 + │ │ │ ├── minimist@0.0.10 + │ │ │ └── wordwrap@0.0.3 + │ │ └── osenv@0.0.3 + │ ├── bower-endpoint-parser@0.2.2 + │ ├─┬ bower-json@0.4.0 + │ │ ├── deep-extend@0.2.11 + │ │ ├── graceful-fs@2.0.3 + │ │ └── intersect@0.0.3 + │ ├── bower-logger@0.2.2 + │ ├─┬ bower-registry-client@0.2.4 + │ │ ├── async@0.2.10 + │ │ ├── graceful-fs@2.0.3 + │ │ ├── lru-cache@2.3.1 + │ │ ├── mkdirp@0.3.5 + │ │ ├─┬ request@2.51.0 + │ │ │ ├── caseless@0.8.0 + │ │ │ ├─┬ combined-stream@0.0.7 + │ │ │ │ └── delayed-stream@0.0.5 + │ │ │ ├─┬ form-data@0.2.0 + │ │ │ │ ├── async@0.9.2 + │ │ │ │ └─┬ mime-types@2.0.14 + │ │ │ │ └── mime-db@1.12.0 + │ │ │ ├── oauth-sign@0.5.0 + │ │ │ └── qs@2.3.3 + │ │ └── request-replay@0.2.0 + │ ├─┬ cardinal@0.4.0 + │ │ └─┬ redeyed@0.4.4 + │ │ └── esprima@1.0.4 + │ ├─┬ chalk@0.5.0 + │ │ ├── ansi-styles@1.1.0 + │ │ ├── escape-string-regexp@1.0.5 + │ │ ├─┬ has-ansi@0.1.0 + │ │ │ └── ansi-regex@0.2.1 + │ │ ├── strip-ansi@0.3.0 + │ │ └── supports-color@0.2.0 + │ ├── chmodr@0.1.0 + │ ├─┬ decompress-zip@0.0.8 + │ │ ├─┬ binary@0.3.0 + │ │ │ ├── buffers@0.1.1 + │ │ │ └─┬ chainsaw@0.1.0 + │ │ │ └── traverse@0.3.9 + │ │ ├── mkpath@0.1.0 + │ │ ├── nopt@2.2.1 + │ │ ├─┬ readable-stream@1.1.14 + │ │ │ ├── core-util-is@1.0.2 + │ │ │ ├── isarray@0.0.1 + │ │ │ └── string_decoder@0.10.31 + │ │ └─┬ touch@0.0.2 + │ │ └── nopt@1.0.10 + │ ├─┬ fstream@1.0.11 + │ │ ├── graceful-fs@4.1.11 + │ │ └── inherits@2.0.3 + │ ├─┬ fstream-ignore@1.0.5 + │ │ └─┬ minimatch@3.0.3 + │ │ └─┬ brace-expansion@1.1.7 + │ │ ├── balanced-match@0.4.2 + │ │ └── concat-map@0.0.1 + │ ├─┬ glob@4.0.6 + │ │ ├─┬ minimatch@1.0.0 + │ │ │ └── sigmund@1.0.1 + │ │ └─┬ once@1.4.0 + │ │ └── wrappy@1.0.2 + │ ├─┬ graceful-fs@3.0.11 + │ │ └── natives@1.1.0 + │ ├─┬ handlebars@2.0.0 + │ │ ├── optimist@0.3.7 + │ │ └─┬ uglify-js@2.3.6 + │ │ ├── optimist@0.3.7 + │ │ └─┬ source-map@0.1.43 + │ │ └── amdefine@1.0.1 + │ ├─┬ inquirer@0.7.1 + │ │ ├─┬ cli-color@0.3.3 + │ │ │ ├── d@0.1.1 + │ │ │ ├─┬ es5-ext@0.10.15 + │ │ │ │ ├─┬ es6-iterator@2.0.1 + │ │ │ │ │ └── d@1.0.0 + │ │ │ │ └─┬ es6-symbol@3.1.1 + │ │ │ │ └── d@1.0.0 + │ │ │ ├─┬ memoizee@0.3.10 + │ │ │ │ ├─┬ es6-weak-map@0.1.4 + │ │ │ │ │ ├── es6-iterator@0.1.3 + │ │ │ │ │ └── es6-symbol@2.0.1 + │ │ │ │ ├─┬ event-emitter@0.3.5 + │ │ │ │ │ └── d@1.0.0 + │ │ │ │ ├── lru-queue@0.1.0 + │ │ │ │ └── next-tick@0.2.2 + │ │ │ └─┬ timers-ext@0.1.2 + │ │ │ └── next-tick@1.0.0 + │ │ ├─┬ figures@1.7.0 + │ │ │ └── object-assign@4.1.1 + │ │ ├── lodash@2.4.2 + │ │ ├── mute-stream@0.0.4 + │ │ ├─┬ readline2@0.1.1 + │ │ │ └─┬ strip-ansi@2.0.1 + │ │ │ └── ansi-regex@1.1.1 + │ │ └── rx@2.5.3 + │ ├─┬ insight@0.4.3 + │ │ ├── async@0.9.2 + │ │ ├── chalk@0.5.1 + │ │ ├─┬ configstore@0.3.2 + │ │ │ ├─┬ js-yaml@3.8.3 + │ │ │ │ ├─┬ argparse@1.0.9 + │ │ │ │ │ └── sprintf-js@1.0.3 + │ │ │ │ └── esprima@3.1.3 + │ │ │ ├── object-assign@2.1.1 + │ │ │ ├── user-home@1.1.1 + │ │ │ ├── uuid@2.0.3 + │ │ │ └── xdg-basedir@1.0.1 + │ │ ├── inquirer@0.6.0 + │ │ ├─┬ lodash.debounce@2.4.1 + │ │ │ ├── lodash.isfunction@2.4.1 + │ │ │ ├─┬ lodash.isobject@2.4.1 + │ │ │ │ └── lodash._objecttypes@2.4.1 + │ │ │ └─┬ lodash.now@2.4.1 + │ │ │ └── lodash._isnative@2.4.1 + │ │ ├── object-assign@1.0.0 + │ │ ├─┬ os-name@1.0.3 + │ │ │ ├─┬ osx-release@1.1.0 + │ │ │ │ └── minimist@1.2.0 + │ │ │ └─┬ win-release@1.1.1 + │ │ │ └── semver@5.3.0 + │ │ └─┬ tough-cookie@0.12.1 + │ │ └── punycode@1.4.1 + │ ├── is-root@1.0.0 + │ ├── junk@1.0.3 + │ ├── lockfile@1.0.3 + │ ├── lru-cache@2.5.2 + │ ├─┬ mkdirp@0.5.0 + │ │ └── minimist@0.0.8 + │ ├── mout@0.9.1 + │ ├── nopt@3.0.6 + │ ├── opn@1.0.2 + │ ├── osenv@0.1.0 + │ ├─┬ p-throttler@0.1.0 + │ │ └── q@0.9.7 + │ ├─┬ promptly@0.2.0 + │ │ └── read@1.0.7 + │ ├── q@1.0.1 + │ ├─┬ request@2.42.0 + │ │ ├── aws-sign2@0.5.0 + │ │ ├─┬ bl@0.9.5 + │ │ │ └── readable-stream@1.0.34 + │ │ ├── caseless@0.6.0 + │ │ ├── forever-agent@0.5.2 + │ │ ├─┬ form-data@0.1.4 + │ │ │ ├── async@0.9.2 + │ │ │ └── mime@1.2.11 + │ │ ├─┬ hawk@1.1.1 + │ │ │ ├── boom@0.4.2 + │ │ │ ├── cryptiles@0.2.2 + │ │ │ ├── hoek@0.9.1 + │ │ │ └── sntp@0.2.4 + │ │ ├─┬ http-signature@0.10.1 + │ │ │ ├── asn1@0.1.11 + │ │ │ ├── assert-plus@0.1.5 + │ │ │ └── ctype@0.5.3 + │ │ ├── json-stringify-safe@5.0.1 + │ │ ├── mime-types@1.0.2 + │ │ ├── node-uuid@1.4.8 + │ │ ├── oauth-sign@0.4.0 + │ │ ├── qs@1.2.2 + │ │ ├── stringstream@0.0.5 + │ │ ├── tough-cookie@2.3.2 + │ │ └── tunnel-agent@0.4.3 + │ ├─┬ request-progress@0.3.0 + │ │ └── throttleit@0.0.2 + │ ├── retry@0.6.0 + │ ├── rimraf@2.2.8 + │ ├── semver@2.3.2 + │ ├─┬ shell-quote@1.4.3 + │ │ ├── array-filter@0.0.1 + │ │ ├── array-map@0.0.0 + │ │ ├── array-reduce@0.0.0 + │ │ └── jsonify@0.0.0 + │ ├── stringify-object@1.0.1 + │ ├─┬ tar-fs@0.5.2 + │ │ ├─┬ pump@0.3.5 + │ │ │ ├─┬ end-of-stream@1.0.0 + │ │ │ │ └── once@1.3.3 + │ │ │ └── once@1.2.0 + │ │ └─┬ tar-stream@0.4.7 + │ │ └── xtend@4.0.1 + │ ├── tmp@0.0.23 + │ ├─┬ update-notifier@0.2.0 + │ │ ├─┬ latest-version@0.2.0 + │ │ │ └─┬ package-json@0.2.0 + │ │ │ ├─┬ got@0.3.0 + │ │ │ │ └── object-assign@0.3.1 + │ │ │ └─┬ registry-url@0.1.1 + │ │ │ └─┬ npmconf@2.1.2 + │ │ │ ├─┬ config-chain@1.1.11 + │ │ │ │ └── proto-list@1.2.4 + │ │ │ ├── ini@1.3.4 + │ │ │ ├── once@1.3.3 + │ │ │ └── uid-number@0.0.5 + │ │ ├── semver-diff@0.1.0 + │ │ └─┬ string-length@0.1.2 + │ │ └─┬ strip-ansi@0.2.2 + │ │ └── ansi-regex@0.1.0 + │ └── which@1.0.9 + ├── esprima@2.7.3 + ├─┬ ordered-ast-traverse@1.1.1 + │ └── ordered-esprima-props@1.1.0 + └── through@2.3.8 + + diff --git a/build..alpha..travis-ci.org/screenCapture.npmPackageListing.svg b/build..alpha..travis-ci.org/screenCapture.npmPackageListing.svg new file mode 100644 index 0000000..65fe561 --- /dev/null +++ b/build..alpha..travis-ci.org/screenCapture.npmPackageListing.svg @@ -0,0 +1,11 @@ + + + + 0. 2017-04-27 16:48:12 +0000 15566 bytes . + 1. 2017-04-27 16:48:12 +0000 1236 bytes CONTRIBUTING.md + 2. 2017-04-27 16:48:12 +0000 6156 bytes README.md + 3. 2017-04-27 16:48:12 +0000 269 bytes bower.json + 4. 2017-04-27 16:48:12 +0000 5109 bytes index.js + 5. 2017-04-27 16:48:12 +0000 2796 bytes package.json + + diff --git a/build..alpha..travis-ci.org/screenCapture.npmTest.browser.%2F.html b/build..alpha..travis-ci.org/screenCapture.npmTest.browser.%2F.html new file mode 100644 index 0000000..a98a78b --- /dev/null +++ b/build..alpha..travis-ci.org/screenCapture.npmTest.browser.%2F.html @@ -0,0 +1,207 @@ + + + +npmdoc-debowerify (v0.0.2) + + + + + +
+ +

+ + + + npmdoc-debowerify (v0.0.2) + + + +

+

#### basic api documentation for [debowerify (v1.5.0)](https://github.com/eugeneware/debowerify#readme) [![npm package](https://img.shields.io/npm/v/npmdoc-debowerify.svg?style=flat-square)](https://www.npmjs.org/package/npmdoc-debowerify) [![travis-ci.org build-status](https://api.travis-ci.org/npmdoc/node-npmdoc-debowerify.svg)](https://travis-ci.org/npmdoc/node-npmdoc-debowerify)

+ +

download standalone app

+
+
+ +

test-report for + npmdoc-debowerify (v0.0.2) +

+
+

summary

+

+ version- + 0.0.2
+ test date- 2017-04-27T16:47:57.723Z
+ commit info- + + undefined
+ +

+ + + + + + + + + + + + + + + +
total time-elapsedtotal tests failedtotal tests passedtotal tests pending
1011 ms010
+
+ +
+

+ 1. browser - / - Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Electron/1.4.16 Safari/537.36 - 2017-04-27T16:47:57.614Z
+ + time-elapsed- 1010 ms
+ tests failed- 0
+ tests passed- 1
+ tests pending- 0
+

+ + + + + + + + + + + + + + + + + +
#time-elapsedstatustest-case
11 mspassedtestCase_browser_nullCase
+
+
+
+ +
+ [ this document was created with + utility2 + ] +
+
+
+ + + + + + + + + + + + + + + + + +
+ [ this app was created with + utility2 + ] +
+ + + \ No newline at end of file diff --git a/build..alpha..travis-ci.org/screenCapture.npmTest.browser.%2F.png b/build..alpha..travis-ci.org/screenCapture.npmTest.browser.%2F.png new file mode 100644 index 0000000..ec85fad Binary files /dev/null and b/build..alpha..travis-ci.org/screenCapture.npmTest.browser.%2F.png differ diff --git a/build..alpha..travis-ci.org/test-report.badge.svg b/build..alpha..travis-ci.org/test-report.badge.svg new file mode 100644 index 0000000..8552400 --- /dev/null +++ b/build..alpha..travis-ci.org/test-report.badge.svg @@ -0,0 +1 @@ +tests failedtests failed00 \ No newline at end of file diff --git a/build..alpha..travis-ci.org/test-report.html b/build..alpha..travis-ci.org/test-report.html new file mode 100644 index 0000000..30a0a3b --- /dev/null +++ b/build..alpha..travis-ci.org/test-report.html @@ -0,0 +1,242 @@ +
+ +

test-report for + npmdoc-debowerify (v0.0.2) +

+
+

summary

+

+ version- + 0.0.2
+ test date- 2017-04-27T16:48:09.775Z
+ commit info- + + alpha - [npm publishAfterCommitAfterBuild]
+ +

+ + + + + + + + + + + + + + + +
total time-elapsedtotal tests failedtotal tests passedtotal tests pending
27603 ms090
+
+ +
+

+ 1. buildApidoc - node - linux v6.10.2 - 2017-04-27T16:48:09.667Z
+ + time-elapsed- 1313 ms
+ tests failed- 0
+ tests passed- 1
+ tests pending- 0
+

+ + + + + + + + + + + + + + + + + +
#time-elapsedstatustest-case
11 mspassedtestCase_buildApidoc_default
+
+
+
+
+ +
+

+ 2. buildApp - node - linux v6.10.2 - 2017-04-27T16:47:43.368Z
+ + time-elapsed- 27603 ms
+ tests failed- 0
+ tests passed- 7
+ tests pending- 0
+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
#time-elapsedstatustest-case
21 mspassedtestCase_buildApidoc_default
36517 mspassedtestCase_buildApp_default
4164 mspassedtestCase_buildCustomOrg_default
51 mspassedtestCase_buildLib_default
60 mspassedtestCase_buildReadme_default
70 mspassedtestCase_buildTest_default
811979 mspassedtestCase_webpage_default
+
+
+
+
+ +
+

+ 3. npmTest - browser - / - Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Electron/1.4.16 Safari/537.36 - 2017-04-27T16:47:57.614Z
+ + + + +
+ + time-elapsed- 14809 ms
+ tests failed- 0
+ tests passed- 1
+ tests pending- 0
+

+ + + + + + + + + + + + + + + + + +
#time-elapsedstatustest-case
91 mspassedtestCase_browser_nullCase
+
+
+
+
+ +
+ [ this document was created with + utility2 + ] +
+
diff --git a/build..alpha..travis-ci.org/test-report.json b/build..alpha..travis-ci.org/test-report.json new file mode 100644 index 0000000..24a69d0 --- /dev/null +++ b/build..alpha..travis-ci.org/test-report.json @@ -0,0 +1 @@ +{"testPlatformList":[{"name":"buildApidoc - node - linux v6.10.2 - 2017-04-27T16:48:09.667Z","testCaseList":[{"name":"testCase_buildApidoc_default","status":"passed","errorStack":"","timeElapsed":1,"timeStart":1493311691220,"isDone":true}],"timeElapsed":4,"testsFailed":0,"testsPassed":1,"testsPending":0,"status":"passed","timeStart":1493311691217},{"name":"buildApp - node - linux v6.10.2 - 2017-04-27T16:47:43.368Z","testCaseList":[{"name":"testCase_buildApidoc_default","status":"passed","errorStack":"","timeElapsed":1,"timeStart":1493311674796,"isDone":true},{"name":"testCase_buildApp_default","status":"passed","errorStack":"","timeElapsed":6517,"timeStart":1493311674798,"isDone":true},{"name":"testCase_buildCustomOrg_default","status":"passed","errorStack":"","timeElapsed":164,"timeStart":1493311675091,"isDone":true},{"name":"testCase_buildLib_default","status":"passed","errorStack":"","timeElapsed":1,"timeStart":1493311675231,"isDone":true},{"name":"testCase_buildReadme_default","status":"passed","errorStack":"","timeElapsed":0,"timeStart":1493311675232,"isDone":true},{"name":"testCase_buildTest_default","status":"passed","errorStack":"","timeElapsed":0,"timeStart":1493311675233,"isDone":true},{"name":"testCase_webpage_default","status":"passed","errorStack":"","timeElapsed":11979,"timeStart":1493311675233,"isDone":true}],"timeElapsed":22285,"testsFailed":0,"testsPassed":7,"testsPending":0,"status":"passed","timeStart":1493311664927},{"name":"npmTest - browser - / - Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Electron/1.4.16 Safari/537.36 - 2017-04-27T16:47:57.614Z","testCaseList":[{"name":"testCase_browser_nullCase","status":"passed","errorStack":"","timeElapsed":1,"timeStart":1493311677732,"isDone":true}],"timeStart":1493311677721,"timeElapsed":27,"testsFailed":0,"testsPassed":1,"testsPending":0,"status":"passed","screenCaptureImg":"screenCapture.npmTest.browser.%2F.png"},{"name":"npmTest - node - linux v6.10.2 - 2017-04-27T16:47:53.223Z","testCaseList":[],"timeElapsed":0,"testsFailed":0,"testsPassed":0,"testsPending":0,"status":"passed"}],"date":"2017-04-27T16:48:09.775Z","errorStackList":[],"timeElapsed":1445,"testsFailed":0,"testsPassed":9,"testsPending":0,"timeStart":1493311689777} \ No newline at end of file diff --git a/build/apidoc.html b/build/apidoc.html new file mode 100644 index 0000000..dd6be48 --- /dev/null +++ b/build/apidoc.html @@ -0,0 +1,78 @@ +
+ +

api documentation for + debowerify (v1.5.0) +

+

A browserify transform to enable the easy use of bower components in browserify client javascript projects. This can be used in conjunction with deamdify to require AMD components from bower as well.

+ + + + +
+ [ this document was created with + utility2 + ] +
+
diff --git a/build/app/assets.app.js b/build/app/assets.app.js new file mode 100644 index 0000000..6375d1f --- /dev/null +++ b/build/app/assets.app.js @@ -0,0 +1,20728 @@ +/* this rollup was created with utility2 (https://github.com/kaizhu256/node-utility2) */ + + + +/* +assets.app.js + +#### basic api documentation for [debowerify (v1.5.0)](https://github.com/eugeneware/debowerify#readme) [![npm package](https://img.shields.io/npm/v/npmdoc-debowerify.svg?style=flat-square)](https://www.npmjs.org/package/npmdoc-debowerify) [![travis-ci.org build-status](https://api.travis-ci.org/npmdoc/node-npmdoc-debowerify.svg)](https://travis-ci.org/npmdoc/node-npmdoc-debowerify) + +instruction + 1. save this script as assets.app.js + 2. run the shell command: + $ PORT=8081 node assets.app.js + 3. play with the browser-demo on http://127.0.0.1:8081 +*/ + + + +/* script-begin /assets.utility2.rollup.js */ +/* this rollup was created with utility2 (https://github.com/kaizhu256/node-utility2) */ + + + +/* script-begin /assets.utility2.rollup.begin.js */ +/* utility2.rollup.js begin */ +/* istanbul ignore all */ +/*jslint + bitwise: true, + browser: true, + maxerr: 8, + maxlen: 96, + node: true, + nomen: true, + regexp: true, + stupid: true +*/ +(function () { + "use strict"; + var local; + local = {}; + local.modeJs = (function () { + try { + return typeof navigator.userAgent === "string" && + typeof document.querySelector("body") === "object" && + typeof XMLHttpRequest.prototype.open === "function" && + "browser"; + } catch (errorCaughtBrowser) { + return module.exports && + typeof process.versions.node === "string" && + typeof require("http").createServer === "function" && + "node"; + } + }()); + local.global = local.modeJs === "browser" + ? window + : global; + local.local = local.global.utility2_rollup = local.global.utility2_rollup_old || local; +}()); +/* script-end /assets.utility2.rollup.begin.js */ + + + +/* script-begin /assets.utility2.lib.apidoc.js */ +///usr/bin/env node +/* istanbul instrument in package apidoc */ +/*jslint + bitwise: true, + browser: true, + maxerr: 8, + maxlen: 96, + node: true, + nomen: true, + regexp: true, + stupid: true +*/ +(function () { + 'use strict'; + var local; + + + + // run shared js-env code - init-before + (function () { + // init local + local = {}; + // init modeJs + local.modeJs = (function () { + try { + return typeof navigator.userAgent === 'string' && + typeof document.querySelector('body') === 'object' && + typeof XMLHttpRequest.prototype.open === 'function' && + 'browser'; + } catch (errorCaughtBrowser) { + return module.exports && + typeof process.versions.node === 'string' && + typeof require('http').createServer === 'function' && + 'node'; + } + }()); + // init global + local.global = local.modeJs === 'browser' + ? window + : global; + // init utility2_rollup + local = local.global.utility2_rollup || local; + // init lib + local.local = local.apidoc = local; + // init exports + if (local.modeJs === 'browser') { + local.global.utility2_apidoc = local; + } else { + module.exports = local; + module.exports.__dirname = __dirname; + module.exports.module = module; + } + }()); + + + + // run shared js-env code - function-before + /* istanbul ignore next */ + (function () { + local.assert = function (passed, message) { + /* + * this function will throw the error message if passed is falsey + */ + var error; + if (passed) { + return; + } + error = message && message.message + // if message is an error-object, then leave it as is + ? message + : new Error(typeof message === 'string' + // if message is a string, then leave it as is + ? message + // else JSON.stringify message + : JSON.stringify(message)); + throw error; + }; + + local.moduleDirname = function (module, modulePathList) { + /* + * this function will search modulePathList for the module's __dirname + */ + var result, tmp; + // search process.cwd() + if (!module || module === '.' || module.indexOf('/') >= 0) { + return require('path').resolve(process.cwd(), module || ''); + } + // search modulePathList + ['node_modules'] + .concat(modulePathList) + .concat(require('module').globalPaths) + .concat([process.env.HOME + '/node_modules', '/usr/local/lib/node_modules']) + .some(function (modulePath) { + try { + tmp = require('path').resolve(process.cwd(), modulePath + '/' + module); + result = require('fs').statSync(tmp).isDirectory() && tmp; + return result; + } catch (ignore) { + } + }); + return result || ''; + }; + + local.nop = function () { + /* + * this function will do nothing + */ + return; + }; + + local.objectSetDefault = function (arg, defaults, depth) { + /* + * this function will recursively set defaults for undefined-items in the arg + */ + arg = arg || {}; + defaults = defaults || {}; + Object.keys(defaults).forEach(function (key) { + var arg2, defaults2; + arg2 = arg[key]; + // handle misbehaving getter + try { + defaults2 = defaults[key]; + } catch (ignore) { + } + if (defaults2 === undefined) { + return; + } + // init arg[key] to default value defaults[key] + if (!arg2) { + arg[key] = defaults2; + return; + } + // if arg2 and defaults2 are both non-null and non-array objects, + // then recurse with arg2 and defaults2 + if (depth > 1 && + // arg2 is a non-null and non-array object + arg2 && + typeof arg2 === 'object' && + !Array.isArray(arg2) && + // defaults2 is a non-null and non-array object + defaults2 && + typeof defaults2 === 'object' && + !Array.isArray(defaults2)) { + // recurse + local.objectSetDefault(arg2, defaults2, depth - 1); + } + }); + return arg; + }; + + local.stringHtmlSafe = function (text) { + /* + * this function will make the text html-safe + */ + // new RegExp('[' + '"&\'<>'.split('').sort().join('') + ']', 'g') + return text.replace((/["&'<>]/g), function (match0) { + return '&#x' + match0.charCodeAt(0).toString(16) + ';'; + }); + }; + + local.templateRender = function (template, dict) { + /* + * this function will render the template with the given dict + */ + var argList, getValue, match, renderPartial, rgx, value; + dict = dict || {}; + getValue = function (key) { + argList = key.split(' '); + value = dict; + // iteratively lookup nested values in the dict + argList[0].split('.').forEach(function (key) { + value = value && value[key]; + }); + return value; + }; + renderPartial = function (match0, helper, key, partial) { + switch (helper) { + case 'each': + value = getValue(key); + return Array.isArray(value) + ? value.map(function (dict) { + // recurse with partial + return local.templateRender(partial, dict); + }).join('') + : ''; + case 'if': + partial = partial.split('{{#unless ' + key + '}}'); + partial = getValue(key) + ? partial[0] + // handle 'unless' case + : partial.slice(1).join('{{#unless ' + key + '}}'); + // recurse with partial + return local.templateRender(partial, dict); + case 'unless': + return getValue(key) + ? '' + // recurse with partial + : local.templateRender(partial, dict); + default: + // recurse with partial + return match0[0] + local.templateRender(match0.slice(1), dict); + } + }; + // render partials + rgx = (/\{\{#(\w+) ([^}]+?)\}\}/g); + template = template || ''; + for (match = rgx.exec(template); match; match = rgx.exec(template)) { + rgx.lastIndex += 1 - match[0].length; + template = template.replace( + new RegExp('\\{\\{#(' + match[1] + ') (' + match[2] + + ')\\}\\}([\\S\\s]*?)\\{\\{/' + match[1] + ' ' + match[2] + + '\\}\\}'), + renderPartial + ); + } + // search for keys in the template + return template.replace((/\{\{[^}]+?\}\}/g), function (match0) { + getValue(match0.slice(2, -2)); + if (value === undefined) { + return match0; + } + argList.slice(1).forEach(function (arg) { + switch (arg) { + case 'alphanumeric': + value = value.replace((/\W/g), '_'); + break; + case 'decodeURIComponent': + value = decodeURIComponent(value); + break; + case 'encodeURIComponent': + value = encodeURIComponent(value); + break; + case 'htmlSafe': + value = value.replace((/["&'<>]/g), function (match0) { + return '&#x' + match0.charCodeAt(0).toString(16) + ';'; + }); + break; + case 'jsonStringify': + value = JSON.stringify(value); + break; + case 'jsonStringify4': + value = JSON.stringify(value, null, 4); + break; + case 'markdownCodeSafe': + value = value.replace((/`/g), '\''); + break; + default: + value = value[arg](); + break; + } + }); + return String(value); + }); + }; + + local.tryCatchOnError = function (fnc, onError) { + /* + * this function will try to run the fnc in a try-catch block, + * else call onError with the errorCaught + */ + // validate onError + local.assert(typeof onError === 'function', typeof onError); + try { + // reset errorCaught + local._debugTryCatchErrorCaught = null; + return fnc(); + } catch (errorCaught) { + // debug errorCaught + local._debugTryCatchErrorCaught = errorCaught; + return onError(errorCaught); + } + }; + }()); + + + + // run shared js-env code - init-before +/* jslint-ignore-begin */ +local.templateApidocHtml = '\ +
\n\ +\n\ +

api documentation for\n\ + {{env.npm_package_name}} (v{{env.npm_package_version}})\n\ +

\n\ +

{{env.npm_package_description}}

\n\ +

table of contents

    \n\ + {{#each moduleList}}\n\ +
  1. module {{name}}
      \n\ + {{#each elementList}}\n\ +
    1. \n\ + {{#if source}}\n\ + \n\ + {{name}}\n\ + {{signature}}\n\ + \n\ + {{#unless source}}\n\ + {{name}}\n\ + {{/if source}}\n\ +
    2. \n\ + {{/each elementList}}\n\ +
  2. \n\ + {{/each moduleList}}\n\ +
\n\ +{{#each moduleList}}\n\ +
\n\ +

module {{name}}

\n\ + {{#each elementList}}\n\ + {{#if source}}\n\ +

\n\ + \n\ + {{name}}\n\ + {{signature}}\n\ + \n\ +

\n\ +
    \n\ +
  • description and source-code
    {{source}}
  • \n\ +
  • example usage
    {{example}}
  • \n\ +
\n\ + {{/if source}}\n\ + {{/each elementList}}\n\ +
\n\ +{{/each moduleList}}\n\ +
\n\ + [ this document was created with\n\ + utility2\n\ + ]\n\ +
\n\ +
\n\ +'; +/* jslint-ignore-end */ + + + + // run shared js-env code - function + (function () { + local.apidocCreate = function (options) { + /* + * this function will create the apidoc from options.dir + */ + var elementCreate, module, moduleMain, readExample, tmp, toString, trimLeft; + elementCreate = function (module, prefix, key) { + /* + * this function will create the apidoc-element in the given module + */ + var element; + if (options.modeNoApidoc) { + return element; + } + element = {}; + element.moduleName = prefix.split('.'); + // handle case where module is a function + if (element.moduleName.slice(-1)[0] === key) { + element.moduleName.pop(); + } + element.moduleName = element.moduleName.join('.'); + element.id = encodeURIComponent('apidoc.element.' + prefix + '.' + key); + element.typeof = typeof module[key]; + element.name = (element.typeof + ' ' + + element.moduleName + '.' + key) + // handle case where module is a function + .replace('>.<', '><'); + if (element.typeof !== 'function') { + return element; + } + // init source + element.source = trimLeft(toString(module[key])) || 'n/a'; + if (element.source.length > 4096) { + element.source = element.source.slice(0, 4096).trimRight() + ' ...'; + } + element.source = local.stringHtmlSafe(element.source) + .replace((/\([\S\s]*?\)/), function (match0) { + // init signature + element.signature = match0 + .replace((/ *?\/\*[\S\s]*?\*\/ */g), '') + .replace((/,/g), ', ') + .replace((/\s+/g), ' '); + return element.signature; + }) + .replace( + (/( *?\/\*[\S\s]*?\*\/\n)/), + '$1' + ) + .replace((/^function \(/), key + ' = function ('); + // init example + options.exampleList.some(function (example) { + example.replace( + new RegExp('((?:\n.*?){8}\\.)(' + key + ')(\\((?:.*?\n){8})'), + function (match0, match1, match2, match3) { + // jslint-hack + local.nop(match0); + element.example = '...' + trimLeft(local.stringHtmlSafe(match1) + + '' + + local.stringHtmlSafe(match2) + + '' + + local.stringHtmlSafe(match3)).trimRight() + '\n...'; + } + ); + return element.example; + }); + element.example = element.example || 'n/a'; + return element; + }; + readExample = function (file) { + /* + * this function will read the example from the given file + */ + var result; + local.tryCatchOnError(function () { + file = local.path.resolve(options.dir, file); + console.error('apidocCreate - readExample - ' + file); + result = ''; + result = ('\n\n\n\n\n\n\n\n' + + local.fs.readFileSync(file, 'utf8').slice(0, 262144) + + '\n\n\n\n\n\n\n\n').replace((/\r\n*/g), '\n'); + }, console.error); + return result; + }; + toString = function (value) { + /* + * this function will try to return the string form of the value + */ + var result; + local.tryCatchOnError(function () { + result = ''; + result = String(value); + }, console.error); + return result; + }; + trimLeft = function (text) { + /* + * this function will normalize the whitespace around the text + */ + var whitespace; + whitespace = ''; + text.trim().replace((/^ */gm), function (match0) { + if (!whitespace || match0.length < whitespace.length) { + whitespace = match0; + } + }); + text = text.replace(new RegExp('^' + whitespace, 'gm'), ''); + // enforce 128 character column limit + text = text.replace((/^.{128}[^\\\n]+/gm), function (match0) { + return match0.replace((/(.{128}(?:\b|\w+))/g), '$1\n').trimRight(); + }); + return text; + }; + // init options + options.dir = local.moduleDirname( + options.dir, + options.modulePathList || local.module.paths + ); + local.objectSetDefault(options, { + env: { npm_package_description: '' }, + packageJson: JSON.parse(readExample('package.json')), + require: function (file) { + return local.tryCatchOnError(function () { + return require(file); + }, console.error); + } + }); + Object.keys(options.packageJson).forEach(function (key) { + tmp = options.packageJson[key]; + // strip email from npmdoc documentation + // https://github.com/npmdoc/node-npmdoc-hpp/issues/1 + if (tmp) { + if (tmp.email) { + delete tmp.email; + } + if (Array.isArray(tmp)) { + tmp.forEach(function (element) { + if (element && element.email) { + delete element.email; + } + }); + } + } + if (key[0] === '_' || key === 'readme') { + delete options.packageJson[key]; + } else if (typeof tmp === 'string') { + options.env['npm_package_' + key] = tmp; + } + }); + local.objectSetDefault(options, { + blacklistDict: { global: global }, + circularList: [global], + exampleDict: {}, + exampleList: [], + html: '', + libFileList: [], + moduleDict: {}, + moduleExtraDict: {}, + packageJson: { bin: {} }, + template: local.templateApidocHtml + }, 2); + // init exampleList + [1, 2, 3, 4].forEach(function (depth) { + options.exampleList = options.exampleList.concat( + // http://stackoverflow.com + // /questions/4509624/how-to-limit-depth-for-recursive-file-list + // find . -maxdepth 1 -mindepth 1 -name "*.js" -type f + local.child_process.execSync('find "' + options.dir + + '" -maxdepth ' + depth + ' -mindepth ' + depth + + ' -type f | sed -e "s|' + options.dir + + '/||" | grep -iv ' + +/* jslint-ignore-begin */ +'"\ +/\\.\\|\\(\\b\\|_\\)\\(\ +bower_component\\|\ +coverage\\|\ +git\\|\ +min\\|\ +node_module\\|\ +rollup\\|\ +tmp\\|\ +vendor\\)s\\{0,1\\}\\(\\b\\|_\\)\ +" ' + +/* jslint-ignore-end */ + ' | sort | head -n 256').toString() + .split('\n') + ); + }); + options.exampleList = options.exampleList.filter(function (file) { + if (!options.exampleDict[file]) { + options.exampleDict[file] = true; + return true; + } + }).slice(0, 256).map(readExample); + // init moduleMain + local.tryCatchOnError(function () { + console.error('apidocCreate - requiring ' + options.dir + ' ...'); + moduleMain = {}; + moduleMain = options.moduleDict[options.env.npm_package_name] || + options.require(options.dir) || + options.require(options.dir + '/' + (options.packageJson.bin)[ + Object.keys(options.packageJson.bin)[0] + ]) || {}; + console.error('apidocCreate - ... required ' + options.dir); + }, console.error); + tmp = {}; + // handle case where module is a function + if (typeof moduleMain === 'function') { + (function () { + var text; + text = toString(moduleMain); + tmp = function () { + return; + }; + // coverage-hack + tmp(); + Object.defineProperties(tmp, { toString: { get: function () { + return function () { + return text; + }; + } } }); + }()); + } + // normalize moduleMain + moduleMain = options.moduleDict[options.env.npm_package_name] = + local.objectSetDefault(tmp, moduleMain); + // init circularList - builtin + Object.keys(process.binding('natives')).forEach(function (key) { + if (!(/\/|_linklist|sys/).test(key)) { + options.blacklistDict[key] = options.blacklistDict[key] || require(key); + } + }); + // init circularList - blacklistDict + Object.keys(options.blacklistDict).forEach(function (key) { + options.circularList.push(options.blacklistDict[key]); + }); + // init circularList - moduleDict + Object.keys(options.moduleDict).forEach(function (key) { + options.circularList.push(options.moduleDict[key]); + }); + // init circularList - prototype + Object.keys(options.circularList).forEach(function (key) { + tmp = options.circularList[key]; + options.circularList.push(tmp && tmp.prototype); + }); + // deduplicate circularList + tmp = options.circularList; + options.circularList = []; + tmp.forEach(function (element) { + if (options.circularList.indexOf(element) < 0) { + options.circularList.push(element); + } + }); + // init moduleDict child + local.apidocModuleDictAdd(options, options.moduleDict); + // init moduleExtraDict + module = options.moduleExtraDict[options.env.npm_package_name] = + options.moduleExtraDict[options.env.npm_package_name] || {}; + [1, 2, 3, 4].forEach(function (depth) { + options.libFileList = options.libFileList.concat( + // http://stackoverflow.com + // /questions/4509624/how-to-limit-depth-for-recursive-file-list + // find . -maxdepth 1 -mindepth 1 -name "*.js" -type f + local.child_process.execSync('find "' + options.dir + + '" -maxdepth ' + depth + ' -mindepth ' + depth + + ' -name "*.js" -type f | sed -e "s|' + options.dir + + '/||" | grep -iv ' + +/* jslint-ignore-begin */ +'"\ +/\\.\\|\\(\\b\\|_\\)\\(\ +archive\\|artifact\\|asset\\|\ +bower_component\\|build\\|\ +coverage\\|\ +doc\\|dist\\|\ +example\\|external\\|\ +fixture\\|\ +git\\|\ +log\\|\ +min\\|mock\\|\ +node_module\\|\ +rollup\\|\ +spec\\|\ +test\\|tmp\\|\ +vendor\\)s\\{0,1\\}\\(\\b\\|_\\)\ +" ' + +/* jslint-ignore-end */ + ' | sort | head -n 256').toString() + .split('\n') + ); + }); + options.ii = 256; + options.libFileList.every(function (file) { + local.tryCatchOnError(function () { + tmp = {}; + tmp.name = local.path.basename(file) + .replace('lib.', '') + .replace((/\.[^.]*?$/), '') + .replace((/\W/g), '_'); + [ + tmp.name, + tmp.name.slice(0, 1).toUpperCase() + tmp.name.slice(1) + ].some(function (name) { + tmp.isFiltered = name && (!options.packageJson.main || + ('./' + file).indexOf(options.packageJson.main) < 0) && + !module[name]; + return !tmp.isFiltered; + }); + if (!tmp.isFiltered) { + return; + } + console.error('apidocCreate - libFile - ' + file); + tmp.module = options.require(options.dir + '/' + file); + if (!(tmp.module && options.circularList.indexOf(tmp.module) < 0)) { + return; + } + options.ii -= 1; + module[tmp.name] = tmp.module; + }, console.error); + return options.ii; + }); + local.apidocModuleDictAdd(options, options.moduleExtraDict); + Object.keys(options.moduleDict).forEach(function (key) { + if (key.indexOf(options.env.npm_package_name + '.') !== 0) { + return; + } + tmp = key.split('.').slice(1).join('.'); + moduleMain[tmp] = moduleMain[tmp] || options.moduleDict[key]; + }); + // init moduleList + options.moduleList = Object.keys(options.moduleDict) + .sort() + .map(function (prefix) { + module = options.moduleDict[prefix]; + // handle case where module is a function + if (typeof module === 'function') { + local.tryCatchOnError(function () { + module[prefix.split('.').slice(-1)[0]] = + module[prefix.split('.').slice(-1)[0]] || module; + }, console.error); + } + return { + elementList: Object.keys(module) + .filter(function (key) { + return local.tryCatchOnError(function () { + return key && + (/^\w[\w\-.]*?$/).test(key) && + key.indexOf('testCase_') !== 0 && + module[key] !== options.blacklistDict[key]; + }, console.error); + }) + .map(function (key) { + return elementCreate(module, prefix, key); + }) + .sort(function (aa, bb) { + return aa.name > bb.name + ? 1 + : -1; + }), + id: encodeURIComponent('apidoc.module.' + prefix), + name: prefix + }; + }); + // render apidoc + options.result = local.templateRender(options.template, options) + .trim() + .replace((/ +$/gm), '') + '\n'; + return options.result; + }; + + local.apidocModuleDictAdd = function (options, moduleDict) { + /* + * this function will add the modules in moduleDict to options.moduleDict + */ + var isModule, tmp; + ['child', 'prototype', 'grandchild', 'prototype'].forEach(function (element) { + Object.keys(moduleDict).sort().forEach(function (prefix) { + if (!(/^\w[\w\-.]*?$/).test(prefix)) { + return; + } + Object.keys(moduleDict[prefix]).forEach(function (key) { + // bug-workaround - buggy electron getter / setter + local.tryCatchOnError(function () { + if (!(/^\w[\w\-.]*?$/).test(key) || !moduleDict[prefix][key]) { + return; + } + tmp = element === 'prototype' + ? { + module: moduleDict[prefix][key].prototype, + name: prefix + '.' + key + '.prototype' + } + : { + module: moduleDict[prefix][key], + name: prefix + '.' + key + }; + if (!tmp.module || + !(typeof tmp.module === 'function' || + typeof tmp.module === 'object') || + options.moduleDict[tmp.name] || + options.circularList.indexOf(tmp.module) >= 0) { + return; + } + isModule = [ + tmp.module, + tmp.module.prototype + ].some(function (dict) { + return Object.keys(dict || {}).some(function (key) { + // bug-workaround - buggy electron getter / setter + return local.tryCatchOnError(function () { + return typeof dict[key] === 'function'; + }, console.error); + }); + }); + if (!isModule) { + return; + } + options.circularList.push(tmp.module); + options.moduleDict[tmp.name] = tmp.module; + }, console.error); + }); + }); + }); + }; + }()); + switch (local.modeJs) { + + + + // run node js-env code - init-after + /* istanbul ignore next */ + case 'node': + // require modules + local.child_process = require('child_process'); + local.fs = require('fs'); + local.path = require('path'); + // run the cli + if (module !== require.main || local.global.utility2_rollup) { + break; + } + // jslint files + process.stdout.write(local.apidocCreate({ + dir: process.argv[2], + modulePathList: module.paths + })); + break; + } +}()); +/* script-end /assets.utility2.lib.apidoc.js */ + + + +/* script-begin /assets.utility2.lib.db.js */ +/* + * assets.db-lite.js + * + * this zero-dependency package will provide a persistent, in-browser database + * + * browser example: + * + * + * + * node example: + * var db, dbTable1; + * utility2_db = require("./assets.db-lite.js"); + * dbTable1 = global.dbTable1 = utility2_db.dbTableCreateOne({ name: "dbTable1" }); + * dbTable1.idIndexCreate({ name: "field1" }); + * dbTable1.crudSetOneById({ field1: "hello", field2: "world" }); + * console.log(dbTable1.crudGetManyByQuery({ + * limit: Infinity, + * query: { field1: "hello" }, + * skip: 0, + * sort: [{ fieldName: 'field1', isDescending: false }] + * })); + */ + + + +/* istanbul instrument in package db */ +/*jslint + bitwise: true, + browser: true, + maxerr: 8, + maxlen: 96, + node: true, + nomen: true, + regexp: true, + stupid: true +*/ +(function () { + 'use strict'; + var local; + + + + // run shared js-env code - init-before + (function () { + // init local + local = {}; + // init modeJs + local.modeJs = (function () { + try { + return typeof navigator.userAgent === 'string' && + typeof document.querySelector('body') === 'object' && + typeof XMLHttpRequest.prototype.open === 'function' && + 'browser'; + } catch (errorCaughtBrowser) { + return module.exports && + typeof process.versions.node === 'string' && + typeof require('http').createServer === 'function' && + 'node'; + } + }()); + // init global + local.global = local.modeJs === 'browser' + ? window + : global; + // init utility2_rollup + local = local.global.utility2_rollup || local; + // init lib + local.local = local.db = local; + // init exports + if (local.modeJs === 'browser') { + local.global.utility2_db = local; + } else { + module.exports = local; + module.exports.__dirname = __dirname; + module.exports.module = module; + } + }()); + + + + /* istanbul ignore next */ + // run shared js-env code - function-before + (function () { + local.jsonCopy = function (arg) { + /* + * this function will return a deep-copy of the JSON-arg + */ + return arg === undefined + ? undefined + : JSON.parse(JSON.stringify(arg)); + }; + + local.jsonStringifyOrdered = function (element, replacer, space) { + /* + * this function will JSON.stringify the element, + * with object-keys sorted and circular-references removed + */ + var circularList, stringify, tmp; + stringify = function (element) { + /* + * this function will recursively JSON.stringify the element, + * with object-keys sorted and circular-references removed + */ + // if element is an object, then recurse its items with object-keys sorted + if (element && + typeof element === 'object' && + typeof element.toJSON !== 'function') { + // ignore circular-reference + if (circularList.indexOf(element) >= 0) { + return; + } + circularList.push(element); + // if element is an array, then recurse its elements + if (Array.isArray(element)) { + return '[' + element.map(function (element) { + // recurse + tmp = stringify(element); + return typeof tmp === 'string' + ? tmp + : 'null'; + }).join(',') + ']'; + } + return '{' + Object.keys(element) + // sort object-keys + .sort() + .map(function (key) { + // recurse + tmp = stringify(element[key]); + if (typeof tmp === 'string') { + return JSON.stringify(key) + ':' + tmp; + } + }) + .filter(function (element) { + return typeof element === 'string'; + }) + .join(',') + '}'; + } + // else JSON.stringify as normal + return JSON.stringify(element); + }; + circularList = []; + return JSON.stringify(element && typeof element === 'object' + // recurse + ? JSON.parse(stringify(element)) + : element, replacer, space); + }; + + local.listShuffle = function (list) { + /* + * https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle + * this function will inplace shuffle the list, via fisher-yates algorithm + */ + var ii, random, swap; + for (ii = list.length - 1; ii > 0; ii -= 1) { + // coerce to finite integer + random = (Math.random() * (ii + 1)) | 0; + swap = list[ii]; + list[ii] = list[random]; + list[random] = swap; + } + return list; + }; + + local.nop = function () { + /* + * this function will do nothing + */ + return; + }; + + local.normalizeDict = function (dict) { + /* + * this function will normalize the dict + */ + return dict && typeof dict === 'object' && !Array.isArray(dict) + ? dict + : {}; + }; + + local.normalizeList = function (list) { + /* + * this function will normalize the list + */ + return Array.isArray(list) + ? list + : []; + }; + + local.objectSetOverride = function (arg, overrides, depth, env) { + /* + * this function will recursively set overrides for items in the arg + */ + arg = arg || {}; + env = env || (typeof process === 'object' && process.env) || {}; + overrides = overrides || {}; + Object.keys(overrides).forEach(function (key) { + var arg2, overrides2; + arg2 = arg[key]; + overrides2 = overrides[key]; + if (overrides2 === undefined) { + return; + } + // if both arg2 and overrides2 are non-null and non-array objects, + // then recurse with arg2 and overrides2 + if (depth > 1 && + // arg2 is a non-null and non-array object + (arg2 && + typeof arg2 === 'object' && + !Array.isArray(arg2)) && + // overrides2 is a non-null and non-array object + (overrides2 && + typeof overrides2 === 'object' && + !Array.isArray(overrides2))) { + local.objectSetOverride(arg2, overrides2, depth - 1, env); + return; + } + // else set arg[key] with overrides[key] + arg[key] = arg === env + // if arg is env, then overrides falsey value with empty string + ? overrides2 || '' + : overrides2; + }); + return arg; + }; + + local.onErrorDefault = function (error) { + /* + * this function will if error exists, then print error.stack to stderr + */ + if (error && !local.global.__coverage__) { + console.error(error); + } + }; + + local.onErrorWithStack = function (onError) { + /* + * this function will create a new callback that will call onError, + * and append the current stack to any error + */ + var stack; + stack = new Error().stack.replace((/(.*?)\n.*?$/m), '$1'); + return function (error, data, meta) { + if (error && + error !== local.errorDefault && + String(error.stack).indexOf(stack.split('\n')[2]) < 0) { + // append the current stack to error.stack + error.stack += '\n' + stack; + } + onError(error, data, meta); + }; + }; + + local.onParallel = function (onError, onEach, onRetry) { + /* + * this function will create a function that will + * 1. run async tasks in parallel + * 2. if counter === 0 or error occurred, then call onError with error + */ + var onParallel; + onError = local.onErrorWithStack(onError); + onEach = onEach || local.nop; + onRetry = onRetry || local.nop; + onParallel = function (error, data) { + if (onRetry(error, data)) { + return; + } + // decrement counter + onParallel.counter -= 1; + // validate counter + console.assert(onParallel.counter >= 0 || error || onParallel.error); + // ensure onError is run only once + if (onParallel.counter < 0) { + return; + } + // handle error + if (error) { + onParallel.error = error; + // ensure counter <= 0 + onParallel.counter = -Math.abs(onParallel.counter); + } + // call onError when isDone + if (onParallel.counter <= 0) { + onError(error, data); + return; + } + onEach(); + }; + // init counter + onParallel.counter = 0; + // return callback + return onParallel; + }; + + local.setTimeoutOnError = function (onError, error, data) { + /* + * this function will async-call onError + */ + if (typeof onError === 'function') { + setTimeout(function () { + onError(error, data); + }); + } + return data; + }; + }()); + + + + // run shared js-env code - lib.storage.js + (function (local) { + var child_process, + clear, + defer, + deferList, + fs, + getItem, + init, + keys, + length, + modeJs, + os, + removeItem, + setItem, + storage, + storageDir; + + // init modeJs + modeJs = (function () { + try { + return typeof navigator.userAgent === 'string' && + typeof document.querySelector('body') === 'object' && + typeof XMLHttpRequest.prototype.open === 'function' && + 'browser'; + } catch (errorCaughtBrowser) { + return module.exports && + typeof process.versions.node === 'string' && + typeof require('http').createServer === 'function' && + 'node'; + } + }()); + storageDir = 'tmp/storage.' + (local.modeJs === 'browser' + ? 'undefined' + : process.env.NODE_ENV); + switch (modeJs) { + case 'node': + // require modules + child_process = require('child_process'); + fs = require('fs'); + os = require('os'); + break; + } + + clear = function (onError) { + /* + * this function will clear storage + */ + defer({ action: 'clear' }, onError); + }; + + defer = function (options, onError) { + /* + * this function will defer options.action until storage is ready + */ + var data, isDone, objectStore, onError2, request, tmp; + onError = onError || function (error) { + // validate no error occurred + console.assert(!error, error); + }; + if (!storage) { + deferList.push(function () { + defer(options, onError); + }); + init(); + return; + } + switch (modeJs) { + case 'browser': + onError2 = function () { + /* istanbul ignore next */ + if (isDone) { + return; + } + isDone = true; + onError( + request && (request.error || request.transaction.error), + data || request.result || '' + ); + }; + switch (options.action) { + case 'clear': + case 'removeItem': + case 'setItem': + objectStore = storage + .transaction(storageDir, 'readwrite') + .objectStore(storageDir); + break; + default: + objectStore = storage + .transaction(storageDir, 'readonly') + .objectStore(storageDir); + } + switch (options.action) { + case 'clear': + request = objectStore.clear(); + break; + case 'getItem': + request = objectStore.get(String(options.key)); + break; + case 'keys': + data = []; + request = objectStore.openCursor(); + request.onsuccess = function () { + if (!request.result) { + onError2(); + return; + } + data.push(request.result.key); + request.result.continue(); + }; + break; + case 'length': + request = objectStore.count(); + break; + case 'removeItem': + request = objectStore.delete(String(options.key)); + break; + case 'setItem': + request = objectStore.put(options.value, String(options.key)); + break; + } + ['onabort', 'onerror', 'onsuccess'].forEach(function (handler) { + request[handler] = request[handler] || onError2; + }); + // debug request + local._debugStorageRequest = request; + break; + case 'node': + switch (options.action) { + case 'clear': + child_process.spawnSync( + 'sh', + ['-c', 'rm -f ' + storage + '/*'], + { stdio: ['ignore', 1, 2] } + ); + setTimeout(onError); + break; + case 'getItem': + fs.readFile( + storage + '/' + encodeURIComponent(String(options.key)), + 'utf8', + // ignore error + function (error, data) { + onError(error && null, data || ''); + } + ); + break; + case 'keys': + fs.readdir(storage, function (error, data) { + onError(error, data && data.map(decodeURIComponent)); + }); + break; + case 'length': + fs.readdir(storage, function (error, data) { + onError(error, data && data.length); + }); + break; + case 'removeItem': + fs.unlink( + storage + '/' + encodeURIComponent(String(options.key)), + // ignore error + function () { + onError(); + } + ); + break; + case 'setItem': + tmp = os.tmpdir() + '/' + Date.now() + Math.random(); + // save to tmp + fs.writeFile(tmp, options.value, function (error) { + // validate no error occurred + console.assert(!error, error); + // rename tmp to key + fs.rename( + tmp, + storage + '/' + encodeURIComponent(String(options.key)), + onError + ); + }); + break; + } + break; + } + }; + + deferList = []; + + getItem = function (key, onError) { + /* + * this function will get the item with the given key from storage + */ + defer({ action: 'getItem', key: key }, onError); + }; + + init = function () { + /* + * this function will init storage + */ + var onError, request; + onError = function (error) { + // validate no error occurred + console.assert(!error, error); + if (modeJs === 'browser') { + storage = window[storageDir]; + } + while (deferList.length) { + deferList.shift()(); + } + }; + if (modeJs === 'browser') { + storage = window[storageDir]; + } + if (storage) { + onError(); + return; + } + switch (modeJs) { + case 'browser': + // init indexedDB + try { + request = window.indexedDB.open(storageDir); + // debug request + local._debugStorageRequestIndexedDB = request; + request.onerror = onError; + request.onsuccess = function () { + window[storageDir] = request.result; + onError(); + }; + request.onupgradeneeded = function () { + if (!request.result.objectStoreNames.contains(storageDir)) { + request.result.createObjectStore(storageDir); + } + }; + } catch (ignore) { + } + break; + case 'node': + // mkdirp storage + storage = storageDir; + child_process.spawnSync( + 'mkdir', + ['-p', storage], + { stdio: ['ignore', 1, 2] } + ); + onError(); + break; + } + }; + + keys = function (onError) { + /* + * this function will get all the keys in storage + */ + defer({ action: 'keys' }, onError); + }; + + length = function (onError) { + /* + * this function will get the number of items in storage + */ + defer({ action: 'length' }, onError); + }; + + removeItem = function (key, onError) { + /* + * this function will remove the item with the given key from storage + */ + defer({ action: 'removeItem', key: key }, onError); + }; + + setItem = function (key, value, onError) { + /* + * this function will set the item with the given key and value to storage + */ + defer({ action: 'setItem', key: key, value: value }, onError); + }; + + // init local + local.storage = storage; + local.storageClear = clear; + local.storageDefer = defer; + local.storageDeferList = deferList; + local.storageDir = storageDir; + local.storageGetItem = getItem; + local.storageInit = init; + local.storageKeys = keys; + local.storageLength = length; + local.storageRemoveItem = removeItem; + local.storageSetItem = setItem; + }(local)); + + + + // run shared js-env code - lib.dbTable.js + (function () { + local._DbTable = function (options) { + /* + * this function will create a dbTable + */ + options = local.normalizeDict(options); + this.name = String(options.name); + // register dbTable in dbTableDict + local.dbTableDict[this.name] = this; + this.dbRowList = []; + this.isDirty = null; + this.idIndexList = [{ name: '_id', dict: {} }]; + this.onSaveList = []; + this.sizeLimit = options.sizeLimit || 0; + }; + + local._DbTable.prototype._cleanup = function () { + /* + * this function will cleanup soft-deleted records from the dbTable + */ + var dbRow, ii, list; + if (!this.isDirty && this.dbRowList.length <= this.sizeLimit) { + return; + } + this.isDirty = null; + // cleanup dbRowList + list = this.dbRowList; + this.dbRowList = []; + // optimization - for-loop + for (ii = 0; ii < list.length; ii += 1) { + dbRow = list[ii]; + // cleanup isRemoved + if (!dbRow.$meta.isRemoved) { + this.dbRowList.push(dbRow); + } + } + if (this.sizeLimit && this.dbRowList.length >= 1.5 * this.sizeLimit) { + this.dbRowList = this._crudGetManyByQuery( + {}, + this.sortDefault, + 0, + this.sizeLimit + ); + } + }; + + local._DbTable.prototype._crudGetManyByQuery = function ( + query, + sort, + skip, + limit, + shuffle + ) { + /* + * this function will get the dbRow's in the dbTable, + * with the given query, sort, skip, and limit + */ + var ii, result; + result = this.dbRowList; + // get by query + if (result.length && query && Object.keys(query).length) { + result = local.dbRowListGetManyByQuery(this.dbRowList, query); + } + // sort + local.normalizeList(sort).forEach(function (element) { + // bug-workaround - v8 does not have stable-sort + // optimization - for-loop + for (ii = 0; ii < result.length; ii += 1) { + result[ii].$meta.ii = ii; + } + if (element.isDescending) { + result.sort(function (aa, bb) { + return -local.sortCompare( + local.dbRowGetItem(aa, element.fieldName), + local.dbRowGetItem(bb, element.fieldName), + aa.$meta.ii, + bb.$meta.ii + ); + }); + } else { + result.sort(function (aa, bb) { + return local.sortCompare( + local.dbRowGetItem(aa, element.fieldName), + local.dbRowGetItem(bb, element.fieldName), + aa.$meta.ii, + bb.$meta.ii + ); + }); + } + }); + // skip + result = result.slice(skip || 0); + // shuffle + ((shuffle && local.listShuffle) || local.nop)(result); + // limit + result = result.slice(0, limit || Infinity); + return result; + }; + + local._DbTable.prototype._crudGetOneById = function (idDict) { + /* + * this function will get the dbRow in the dbTable with the given idDict + */ + var id, result; + idDict = local.normalizeDict(idDict); + result = null; + this.idIndexList.some(function (idIndex) { + id = idDict[idIndex.name]; + // optimization - hasOwnProperty + if (idIndex.dict.hasOwnProperty(id)) { + result = idIndex.dict[id]; + return result; + } + }); + return result; + }; + + local._DbTable.prototype._crudRemoveOneById = function (idDict, circularList) { + /* + * this function will remove the dbRow from the dbTable with the given idDict + */ + var id, result, self; + if (!idDict) { + return null; + } + self = this; + circularList = circularList || [idDict]; + result = null; + self.idIndexList.forEach(function (idIndex) { + id = idDict[idIndex.name]; + // optimization - hasOwnProperty + if (!idIndex.dict.hasOwnProperty(id)) { + return; + } + result = idIndex.dict[id]; + delete idIndex.dict[id]; + // optimization - soft-delete + result.$meta.isRemoved = true; + self.isDirty = true; + if (circularList.indexOf(result) >= 0) { + return; + } + circularList.push(result); + // recurse + self._crudRemoveOneById(result, circularList); + }); + self.save(); + return result; + }; + + local._DbTable.prototype._crudSetOneById = function (dbRow) { + /* + * this function will set the dbRow into the dbTable with the given dbRow._id + * WARNING - existing dbRow with conflicting dbRow._id will be removed + */ + var existing, id, normalize, timeNow; + normalize = function (dbRow) { + /* + * this function will recursively normalize dbRow + */ + if (dbRow && typeof dbRow === 'object') { + Object.keys(dbRow).forEach(function (key) { + // remove invalid property + if (key[0] === '$' || key.indexOf('.') >= 0 || dbRow[key] === null) { + // optimization - soft-delete + dbRow[key] = undefined; + return; + } + // recurse + normalize(dbRow[key]); + }); + } + }; + dbRow = local.jsonCopy(dbRow && typeof dbRow === 'object' + ? dbRow + : {}); + // update timestamp + timeNow = new Date().toISOString(); + dbRow._timeCreated = dbRow._timeCreated || timeNow; + if (!local.modeImport) { + dbRow._timeUpdated = timeNow; + } + // normalize + normalize(dbRow); + dbRow = local.jsonCopy(dbRow); + // remove existing dbRow + existing = this._crudRemoveOneById(dbRow) || dbRow; + // init meta + dbRow.$meta = { isRemoved: null }; + this.idIndexList.forEach(function (idIndex) { + // auto-set id + id = local.dbRowSetId(existing, idIndex); + // copy id from existing to dbRow + dbRow[idIndex.name] = id; + // set dbRow + idIndex.dict[id] = dbRow; + }); + // update dbRowList + this.dbRowList.push(dbRow); + this.save(); + return dbRow; + }; + + local._DbTable.prototype._crudUpdateOneById = function (dbRow) { + /* + * this function will update the dbRow in the dbTable, + * if it exists with the given dbRow._id + * WARNING + * existing dbRow's with conflicting unique-keys (besides the one being updated) + * will be removed + */ + var id, result; + dbRow = local.jsonCopy(local.normalizeDict(dbRow)); + result = null; + this.idIndexList.some(function (idIndex) { + id = dbRow[idIndex.name]; + // optimization - hasOwnProperty + if (idIndex.dict.hasOwnProperty(id)) { + result = idIndex.dict[id]; + return true; + } + }); + result = result || {}; + // remove existing dbRow + this._crudRemoveOneById(result); + // update dbRow + dbRow._timeCreated = undefined; + local.objectSetOverride(result, dbRow, Infinity); + // replace dbRow + result = this._crudSetOneById(result); + return result; + }; + + local._DbTable.prototype.crudCountAll = function (onError) { + /* + * this function will count all of dbRow's in the dbTable + */ + this._cleanup(); + return local.setTimeoutOnError(onError, null, this.dbRowList.length); + }; + + local._DbTable.prototype.crudCountManyByQuery = function (query, onError) { + /* + * this function will count the number of dbRow's in the dbTable with the given query + */ + this._cleanup(); + return local.setTimeoutOnError( + onError, + null, + this._crudGetManyByQuery(query).length + ); + }; + + local._DbTable.prototype.crudGetManyById = function (idDictList, onError) { + /* + * this function will get the dbRow's in the dbTable with the given idDictList + */ + var self; + this._cleanup(); + self = this; + return local.setTimeoutOnError(onError, null, local.dbRowProject( + local.normalizeList(idDictList).map(function (idDict) { + return self._crudGetOneById(idDict); + }) + )); + }; + + local._DbTable.prototype.crudGetManyByQuery = function (options, onError) { + /* + * this function will get the dbRow's in the dbTable with the given options.query + */ + this._cleanup(); + options = local.normalizeDict(options); + return local.setTimeoutOnError(onError, null, local.dbRowProject( + this._crudGetManyByQuery( + options.query, + options.sort || this.sortDefault, + options.skip, + options.limit, + options.shuffle + ), + options.fieldList + )); + }; + + local._DbTable.prototype.crudGetOneById = function (idDict, onError) { + /* + * this function will get the dbRow in the dbTable with the given idDict + */ + this._cleanup(); + return local.setTimeoutOnError(onError, null, local.dbRowProject( + this._crudGetOneById(idDict) + )); + }; + + local._DbTable.prototype.crudGetOneByRandom = function (onError) { + /* + * this function will get a random dbRow in the dbTable + */ + this._cleanup(); + return local.setTimeoutOnError(onError, null, local.dbRowProject( + this.dbRowList[Math.floor(Math.random() * this.dbRowList.length)] + )); + }; + + local._DbTable.prototype.crudGetOneByQuery = function (query, onError) { + /* + * this function will get the dbRow in the dbTable with the given query + */ + var ii, result; + this._cleanup(); + // optimization - for-loop + for (ii = 0; ii < this.dbRowList.length; ii += 1) { + result = local.dbRowListGetManyByQuery([this.dbRowList[ii]], query)[0]; + if (result) { + break; + } + } + return local.setTimeoutOnError(onError, null, local.dbRowProject(result)); + }; + + local._DbTable.prototype.crudRemoveAll = function (onError) { + /* + * this function will remove all of the dbRow's from the dbTable + */ + var idIndexList; + // save idIndexList + idIndexList = this.idIndexList; + // reset dbTable + local._DbTable.call(this, this); + // restore idIndexList + local.dbTableCreateOne({ + name: this.name, + idIndexCreateList: idIndexList + }, onError); + }; + + local._DbTable.prototype.crudRemoveManyById = function (idDictList, onError) { + /* + * this function will remove the dbRow's from the dbTable with the given idDictList + */ + var self; + self = this; + return local.setTimeoutOnError(onError, null, local.dbRowProject( + local.normalizeList(idDictList).map(function (dbRow) { + return self._crudRemoveOneById(dbRow); + }) + )); + }; + + local._DbTable.prototype.crudRemoveManyByQuery = function (query, onError) { + /* + * this function will remove the dbRow's from the dbTable with the given query + */ + var self; + self = this; + return local.setTimeoutOnError(onError, null, local.dbRowProject( + self._crudGetManyByQuery(query).map(function (dbRow) { + return self._crudRemoveOneById(dbRow); + }) + )); + }; + + local._DbTable.prototype.crudRemoveOneById = function (idDict, onError) { + /* + * this function will remove the dbRow from the dbTable with the given idDict + */ + return local.setTimeoutOnError(onError, null, local.dbRowProject( + this._crudRemoveOneById(idDict) + )); + }; + + local._DbTable.prototype.crudSetManyById = function (dbRowList, onError) { + /* + * this function will set the dbRowList into the dbTable + */ + var self; + self = this; + return local.setTimeoutOnError(onError, null, local.dbRowProject( + local.normalizeList(dbRowList).map(function (dbRow) { + return self._crudSetOneById(dbRow); + }) + )); + }; + + local._DbTable.prototype.crudSetOneById = function (dbRow, onError) { + /* + * this function will set the dbRow into the dbTable with the given dbRow._id + */ + return local.setTimeoutOnError(onError, null, local.dbRowProject( + this._crudSetOneById(dbRow) + )); + }; + + local._DbTable.prototype.crudUpdateManyById = function (dbRowList, onError) { + /* + * this function will update the dbRowList in the dbTable, + * if they exist with the given dbRow._id's + */ + var self; + self = this; + return local.setTimeoutOnError(onError, null, local.dbRowProject( + local.normalizeList(dbRowList).map(function (dbRow) { + return self._crudUpdateOneById(dbRow); + }) + )); + }; + + local._DbTable.prototype.crudUpdateManyByQuery = function (query, dbRow, onError) { + /* + * this function will update the dbRow's in the dbTable with the given query + */ + var result, self, tmp; + self = this; + tmp = local.jsonCopy(local.normalizeDict(dbRow)); + result = self._crudGetManyByQuery(query).map(function (dbRow) { + tmp._id = dbRow._id; + return self._crudUpdateOneById(tmp); + }); + return local.setTimeoutOnError(onError, null, result); + }; + + local._DbTable.prototype.crudUpdateOneById = function (dbRow, onError) { + /* + * this function will update the dbRow in the dbTable, + * if it exists with the given dbRow._id + */ + return local.setTimeoutOnError(onError, null, local.dbRowProject( + this._crudUpdateOneById(dbRow) + )); + }; + + local._DbTable.prototype.drop = function (onError) { + /* + * this function will drop the dbTable + */ + console.error('dropping dbTable ' + this.name + ' ...'); + // cancel pending save + this.timerSave = null; + while (this.onSaveList.length) { + this.onSaveList.shift()(); + } + // reset dbTable + local._DbTable.call(this, this); + // clear persistence + local.storageRemoveItem('dbTable.' + this.name, onError); + }; + + local._DbTable.prototype.export = function (onError) { + /* + * this function will export the db + */ + var result, self; + this._cleanup(); + self = this; + result = ''; + self.idIndexList.forEach(function (idIndex) { + result += self.name + ' idIndexCreate ' + JSON.stringify({ + isInteger: idIndex.isInteger, + name: idIndex.name + }) + '\n'; + }); + result += self.name + ' sizeLimit ' + self.sizeLimit + '\n'; + result += self.name + ' sortDefault ' + JSON.stringify(self.sortDefault) + '\n'; + self.crudGetManyByQuery({}).forEach(function (dbRow) { + result += self.name + ' dbRowSet ' + JSON.stringify(dbRow) + '\n'; + }); + return local.setTimeoutOnError(onError, null, result.trim()); + }; + + local._DbTable.prototype.idIndexCreate = function (options, onError) { + /* + * this function will create an idIndex with the given options.name + */ + var dbRow, idIndex, ii, name; + options = local.normalizeDict(options); + name = String(options.name); + // disallow idIndex with dot-name + if (name.indexOf('.') >= 0 || name === '_id') { + return local.setTimeoutOnError(onError); + } + // remove existing idIndex + this.idIndexRemove(options); + // init idIndex + idIndex = { + dict: {}, + isInteger: options.isInteger, + name: options.name + }; + this.idIndexList.push(idIndex); + // populate idIndex with dbRowList + // optimization - for-loop + for (ii = 0; ii < this.dbRowList.length; ii += 1) { + dbRow = this.dbRowList[ii]; + // auto-set id + if (!dbRow.$meta.isRemoved) { + idIndex.dict[local.dbRowSetId(dbRow, idIndex)] = dbRow; + } + } + this.save(); + return local.setTimeoutOnError(onError); + }; + + local._DbTable.prototype.idIndexRemove = function (options, onError) { + /* + * this function will remove the idIndex with the given options.name + */ + var name; + options = local.normalizeDict(options); + name = String(options.name); + this.idIndexList = this.idIndexList.filter(function (idIndex) { + return idIndex.name !== name || idIndex.name === '_id'; + }); + this.save(); + return local.setTimeoutOnError(onError); + }; + + local._DbTable.prototype.save = function (onError) { + /* + * this function will save the dbTable to storage + */ + var self; + self = this; + if (local.modeImport) { + return; + } + if (onError) { + self.onSaveList.push(onError); + } + // throttle storage-writes to once every 1000 ms + self.timerSave = self.timerSave || setTimeout(function () { + self.timerSave = null; + local.storageSetItem('dbTable.' + self.name + '.json', self.export(), function ( + error + ) { + while (self.onSaveList.length) { + self.onSaveList.shift()(error); + } + }); + }, 1000); + }; + + local.dbCrudRemoveAll = function (onError) { + /* + * this function will remove all dbRow's from the db + */ + var onParallel; + onParallel = local.onParallel(function (error) { + local.setTimeoutOnError(onError, error); + }); + onParallel.counter += 1; + Object.keys(local.dbTableDict).forEach(function (key) { + onParallel.counter += 1; + local.dbTableDict[key].crudRemoveAll(onParallel); + }); + onParallel(); + }; + + local.dbDrop = function (onError) { + /* + * this function will drop the db + */ + var onParallel; + onParallel = local.onParallel(function (error) { + local.setTimeoutOnError(onError, error); + }); + onParallel.counter += 1; + onParallel.counter += 1; + local.storageClear(onParallel); + Object.keys(local.dbTableDict).forEach(function (key) { + onParallel.counter += 1; + local.dbTableDict[key].drop(onParallel); + }); + onParallel(); + }; + + local.dbExport = function (onError) { + /* + * this function will export the db as serialized text + */ + var result; + result = ''; + Object.keys(local.dbTableDict).forEach(function (key) { + result += local.dbTableDict[key].export(); + result += '\n\n'; + }); + return local.setTimeoutOnError(onError, null, result.trim()); + }; + + local.dbImport = function (text, onError) { + /* + * this function will import the serialized text into the db + */ + var dbTable; + local.modeImport = true; + setTimeout(function () { + local.modeImport = null; + }); + text.replace((/^(\w\S*?) (\S+?) (\S.*?)$/gm), function ( + match0, + match1, + match2, + match3 + ) { + // jslint-hack + local.nop(match0); + switch (match2) { + case 'dbRowSet': + dbTable = local.dbTableCreateOne({ isLoaded: true, name: match1 }); + dbTable.crudSetOneById(JSON.parse(match3)); + break; + case 'idIndexCreate': + dbTable = local.dbTableCreateOne({ isLoaded: true, name: match1 }); + dbTable.idIndexCreate(JSON.parse(match3)); + break; + case 'sizeLimit': + dbTable = local.dbTableCreateOne({ isLoaded: true, name: match1 }); + dbTable.sizeLimit = JSON.parse(match3); + break; + case 'sortDefault': + dbTable = local.dbTableCreateOne({ isLoaded: true, name: match1 }); + break; + default: + local.onErrorDefault(new Error('dbImport - invalid operation - ' + match0)); + } + }); + local.modeImport = null; + return local.setTimeoutOnError(onError); + }; + + local.dbLoad = function (onError) { + /* + * this function will load the db from storage + */ + var onParallel; + onParallel = local.onParallel(function (error) { + local.setTimeoutOnError(onError, error); + }); + local.storageKeys(function (error, data) { + onParallel.counter += 1; + onParallel.counter += 1; + onParallel(error); + local.normalizeList(data) + .filter(function (key) { + return key.indexOf('dbTable.') === 0; + }) + .forEach(function (key) { + onParallel.counter += 1; + local.storageGetItem(key, function (error, data) { + onParallel.counter += 1; + onParallel(error); + local.dbImport(data, onParallel); + }); + }); + onParallel(); + }); + }; + + local.dbRowGetItem = function (dbRow, key) { + /* + * this function will get the item with the given key from dbRow + */ + var ii, value; + value = dbRow; + key = String(key).split('.'); + // optimization - for-loop + for (ii = 0; ii < key.length && value && typeof value === 'object'; ii += 1) { + value = value[key[ii]]; + } + return value === undefined + ? null + : value; + }; + + local.dbRowListGetManyByOperator = function (dbRowList, fieldName, operator, bb, not) { + /* + * this function will get the dbRow's in dbRowList with the given operator + */ + var ii, jj, result, fieldValue, test, typeof2; + result = []; + typeof2 = typeof bb; + if (bb && typeof2 === 'object') { + switch (operator) { + case '$in': + case '$nin': + case '$regex': + break; + default: + return result; + } + } + switch (operator) { + case '$eq': + test = function (aa, bb) { + return aa === bb; + }; + break; + case '$exists': + bb = !bb; + test = function (aa, bb) { + return !((aa === null) ^ bb); + }; + break; + case '$gt': + test = function (aa, bb, typeof1, typeof2) { + return typeof1 === typeof2 && aa > bb; + }; + break; + case '$gte': + test = function (aa, bb, typeof1, typeof2) { + return typeof1 === typeof2 && aa >= bb; + }; + break; + case '$in': + if (bb && typeof bb.indexOf === 'function') { + if (typeof2 === 'string') { + test = function (aa, bb, typeof1, typeof2) { + return typeof1 === typeof2 && bb.indexOf(aa) >= 0; + }; + } else { + test = function (aa, bb) { + return bb.indexOf(aa) >= 0; + }; + } + } + break; + case '$lt': + test = function (aa, bb, typeof1, typeof2) { + return typeof1 === typeof2 && aa < bb; + }; + break; + case '$lte': + test = function (aa, bb, typeof1, typeof2) { + return typeof1 === typeof2 && aa <= bb; + }; + break; + case '$ne': + test = function (aa, bb) { + return aa !== bb; + }; + break; + case '$nin': + if (bb && typeof bb.indexOf === 'function') { + if (typeof2 === 'string') { + test = function (aa, bb, typeof1, typeof2) { + return typeof1 === typeof2 && bb.indexOf(aa) < 0; + }; + } else { + test = function (aa, bb) { + return bb.indexOf(aa) < 0; + }; + } + } + break; + case '$regex': + if (bb && typeof bb.test === 'function') { + test = function (aa, bb) { + return bb.test(aa); + }; + } + break; + case '$typeof': + test = function (aa, bb, typeof1) { + // jslint-hack + local.nop(aa); + return typeof1 === bb; + }; + break; + } + if (!test) { + return result; + } + // optimization - for-loop + for (ii = dbRowList.length - 1; ii >= 0; ii -= 1) { + fieldValue = local.dbRowGetItem(dbRowList[ii], fieldName); + // normalize to list + if (!Array.isArray(fieldValue)) { + fieldValue = [fieldValue]; + } + // optimization - for-loop + for (jj = fieldValue.length - 1; jj >= 0; jj -= 1) { + if (not ^ test(fieldValue[jj], bb, typeof fieldValue[jj], typeof2)) { + result.push(dbRowList[ii]); + break; + } + } + } + return result; + }; + + local.dbRowListGetManyByQuery = function (dbRowList, query, fieldName, not) { + /* + * this function will get the dbRow's in dbRowList with the given query + */ + var bb, dbRowDict, result; + // optimization - convert to boolean + not = !!not; + result = dbRowList; + if (!(query && typeof query === 'object')) { + result = local.dbRowListGetManyByOperator(result, fieldName, '$eq', query, not); + return result; + } + Object.keys(query).some(function (key) { + bb = query[key]; + switch (key) { + case '$not': + key = fieldName; + not = !not; + break; + case '$or': + if (!Array.isArray(bb)) { + break; + } + dbRowDict = {}; + bb.forEach(function (query) { + // recurse + local.dbRowListGetManyByQuery(result, query).forEach(function (dbRow) { + dbRowDict[dbRow._id] = dbRow; + }); + }); + result = Object.keys(dbRowDict).map(function (id) { + return dbRowDict[id]; + }); + return !result.length; + } + if (key[0] === '$') { + result = local.dbRowListGetManyByOperator(result, fieldName, key, bb, not); + return !result.length; + } + // recurse + result = local.dbRowListGetManyByQuery(result, bb, key, not); + return !result.length; + }); + return result; + }; + + local.dbRowProject = function (dbRow, fieldList) { + /* + * this function will deepcopy and project the dbRow with the given fieldList + */ + var result; + if (!dbRow) { + return null; + } + // handle list-case + if (Array.isArray(dbRow)) { + return dbRow.map(function (dbRow) { + // recurse + return local.dbRowProject(dbRow, fieldList); + }); + } + // normalize to list + if (!(Array.isArray(fieldList) && fieldList.length)) { + fieldList = Object.keys(dbRow); + } + result = {}; + fieldList.forEach(function (key) { + if (key[0] !== '$') { + result[key] = dbRow[key]; + } + }); + return JSON.parse(local.jsonStringifyOrdered(result)); + }; + + local.dbRowSetId = function (dbRow, idIndex) { + /* + * this function will set a random and unique id into dbRow for the given idIndex, + * if it does not exist + */ + var id; + id = dbRow[idIndex.name]; + if (typeof id !== 'number' && typeof id !== 'string') { + do { + id = idIndex.isInteger + ? (1 + Math.random()) * 0x10000000000000 + : 'a' + ((1 + Math.random()) * 0x10000000000000).toString(36).slice(1); + // optimization - hasOwnProperty + } while (idIndex.dict.hasOwnProperty(id)); + dbRow[idIndex.name] = id; + } + return id; + }; + + local.dbSave = function (onError) { + /* + * this function will save the db to storage + */ + var onParallel; + onParallel = local.onParallel(function (error) { + local.setTimeoutOnError(onError, error); + }); + onParallel.counter += 1; + Object.keys(local.dbTableDict).forEach(function (key) { + onParallel.counter += 1; + local.dbTableDict[key].save(onParallel); + }); + onParallel(); + }; + + local.dbTableCreateMany = function (optionsList, onError) { + /* + * this function will set the optionsList into the db + */ + var onParallel, result; + onParallel = local.onParallel(function (error) { + local.setTimeoutOnError(onError, error, result); + }); + onParallel.counter += 1; + result = local.normalizeList(optionsList).map(function (options) { + onParallel.counter += 1; + return local.dbTableCreateOne(options, onParallel); + }); + return local.setTimeoutOnError(onParallel, null, result); + }; + + local.dbTableCreateOne = function (options, onError) { + /* + * this function will create a dbTable with the given options + */ + var self; + options = local.normalizeDict(options); + // register dbTable + self = local.dbTableDict[options.name] = + local.dbTableDict[options.name] || new local._DbTable(options); + self.sortDefault = options.sortDefault || + self.sortDefault || + [{ fieldName: '_timeUpdated', isDescending: true }]; + // remove idIndex + local.normalizeList(options.idIndexRemoveList).forEach(function (index) { + self.idIndexRemove(index); + }); + // create idIndex + local.normalizeList(options.idIndexCreateList).forEach(function (index) { + self.idIndexCreate(index); + }); + // upsert dbRow + self.crudSetManyById(options.dbRowList); + self.isLoaded = self.isLoaded || options.isLoaded; + if (!self.isLoaded) { + local.storageGetItem('dbTable.' + self.name + '.json', function (error, data) { + // validate no error occurred + console.assert(!error, error); + if (!self.isLoaded) { + local.dbImport(data); + } + self.isLoaded = true; + local.setTimeoutOnError(onError, null, self); + }); + return self; + } + return local.setTimeoutOnError(onError, null, self); + }; + + local.dbTableDict = {}; + + local.sortCompare = function (aa, bb, ii, jj) { + /* + * this function will compare aa vs bb and return: + * -1 if aa < bb + * 0 if aa === bb + * 1 if aa > bb + * the priority for comparing different typeof's is: + * null < boolean < number < string < object < undefined + */ + var typeof1, typeof2; + if (aa === bb) { + return ii < jj + ? -1 + : 1; + } + if (aa === null) { + return -1; + } + if (bb === null) { + return 1; + } + typeof1 = typeof aa; + typeof2 = typeof bb; + if (typeof1 === typeof2) { + return typeof1 === 'object' + ? 0 + : aa > bb + ? 1 + : -1; + } + if (typeof1 === 'boolean') { + return -1; + } + if (typeof2 === 'boolean') { + return 1; + } + if (typeof1 === 'number') { + return -1; + } + if (typeof2 === 'number') { + return 1; + } + if (typeof1 === 'string') { + return -1; + } + if (typeof2 === 'string') { + return 1; + } + return 0; + }; + }()); + switch (local.modeJs) { + + + + // run node js-env code - init-after + case 'node': + // require modules + local.fs = require('fs'); + break; + } +}()); +/* script-end /assets.utility2.lib.db.js */ + + + +/* script-begin /assets.utility2.lib.github_crud.js */ +///usr/bin/env node +/* istanbul instrument in package github-crud */ +/*jslint + bitwise: true, + browser: true, + maxerr: 8, + maxlen: 96, + node: true, + nomen: true, + regexp: true, + stupid: true +*/ +(function () { + 'use strict'; + var local; + + + + // run shared js-env code - init-before + (function () { + // init local + local = {}; + // init modeJs + local.modeJs = (function () { + try { + return typeof navigator.userAgent === 'string' && + typeof document.querySelector('body') === 'object' && + typeof XMLHttpRequest.prototype.open === 'function' && + 'browser'; + } catch (errorCaughtBrowser) { + return module.exports && + typeof process.versions.node === 'string' && + typeof require('http').createServer === 'function' && + 'node'; + } + }()); + // init global + local.global = local.modeJs === 'browser' + ? window + : global; + // init utility2_rollup + local = local.global.utility2_rollup || local; + // init lib + local.local = local.github_crud = local; + // init exports + if (local.modeJs === 'browser') { + local.global.utility2_github_crud = local; + } else { + module.exports = local; + module.exports.__dirname = __dirname; + module.exports.module = module; + } + }()); + + + + /* istanbul ignore next */ + // run shared js-env code - function-before + (function () { + local.httpRequest = function (options, onError) { + /* + * this function will request the data from options.url + */ + var chunkList, isDone, onError2, timerTimeout, request, response, urlParsed; + // init onError2 + onError2 = function (error) { + if (isDone) { + return; + } + isDone = true; + // cleanup timerTimeout + clearTimeout(timerTimeout); + // cleanup request and response + [request, response].forEach(function (stream) { + // try to end the stream + try { + stream.end(); + // else try to destroy the stream + } catch (errorCaught) { + try { + stream.destroy(); + } catch (ignore) { + } + } + }); + if (response && (response.statusCode < 200 || response.statusCode >= 300)) { + error = error || new Error(response.statusCode); + console.error(String(response.data)); + } + // debug response + console.error(new Date().toISOString() + ' http-response ' + JSON.stringify({ + statusCode: (response && response.statusCode) || 0, + method: options.method, + url: options.url + })); + onError(error, response); + }; + // init timerTimeout + timerTimeout = setTimeout(function () { + onError2(new Error('http-request timeout')); + }, options.timeout || 30000); + urlParsed = require('url').parse(options.url); + urlParsed.headers = options.headers; + urlParsed.method = options.method; + // debug request + console.error(); + console.error(new Date().toISOString() + ' http-request ' + JSON.stringify({ + method: options.method, + url: options.url + })); + request = require( + urlParsed.protocol.slice(0, -1) + ).request(urlParsed, function (_response) { + response = _response; + chunkList = []; + response + .on('data', function (chunk) { + chunkList.push(chunk); + }) + .on('end', function () { + response.data = Buffer.concat(chunkList); + onError2(); + }) + .on('error', onError2); + }).on('error', onError2); + request.end(options.data); + }; + + local.nop = function () { + /* + * this function will do nothing + */ + return; + }; + + local.onErrorWithStack = function (onError) { + /* + * this function will create a new callback that will call onError, + * and append the current stack to any error + */ + var stack; + stack = new Error().stack.replace((/(.*?)\n.*?$/m), '$1'); + return function (error, data, meta) { + if (error && + error !== local.errorDefault && + String(error.stack).indexOf(stack.split('\n')[2]) < 0) { + // append the current stack to error.stack + error.stack += '\n' + stack; + } + onError(error, data, meta); + }; + }; + + local.onNext = function (options, onError) { + /* + * this function will wrap onError inside the recursive function options.onNext, + * and append the current stack to any error + */ + options.onNext = local.onErrorWithStack(function (error, data, meta) { + try { + options.modeNext = error && !options.modeErrorIgnore + ? Infinity + : options.modeNext + 1; + onError(error, data, meta); + } catch (errorCaught) { + // throw errorCaught to break infinite recursion-loop + if (options.errorCaught) { + throw options.errorCaught; + } + options.errorCaught = errorCaught; + options.onNext(errorCaught, data, meta); + } + }); + return options; + }; + + local.onParallel = function (onError, onEach, onRetry) { + /* + * this function will create a function that will + * 1. run async tasks in parallel + * 2. if counter === 0 or error occurred, then call onError with error + */ + var onParallel; + onError = local.onErrorWithStack(onError); + onEach = onEach || local.nop; + onRetry = onRetry || local.nop; + onParallel = function (error, data) { + if (onRetry(error, data)) { + return; + } + // decrement counter + onParallel.counter -= 1; + // validate counter + console.assert(onParallel.counter >= 0 || error || onParallel.error); + // ensure onError is run only once + if (onParallel.counter < 0) { + return; + } + // handle error + if (error) { + onParallel.error = error; + // ensure counter <= 0 + onParallel.counter = -Math.abs(onParallel.counter); + } + // call onError when isDone + if (onParallel.counter <= 0) { + onError(error, data); + return; + } + onEach(); + }; + // init counter + onParallel.counter = 0; + // return callback + return onParallel; + }; + + local.onParallelList = function (options, onEach, onError) { + /* + * this function will + * 1. async-run onEach in parallel, + * with the given options.rateLimit and options.retryLimit + * 2. call onError when isDone + */ + var ii, onEach2, onParallel; + onEach2 = function () { + while (ii + 1 < options.list.length && onParallel.counter < options.rateLimit) { + ii += 1; + onParallel.ii += 1; + onParallel.remaining -= 1; + onEach({ + element: options.list[ii], + ii: ii, + list: options.list, + retry: 0 + }, onParallel); + } + }; + onParallel = local.onParallel(onError, onEach2, function (error, data) { + if (error && data && data.retry < options.retryLimit) { + local.onErrorDefault(error); + data.retry += 1; + setTimeout(function () { + onParallel.counter -= 1; + onEach(data, onParallel); + }, 1000); + return true; + } + }); + onParallel.counter += 1; + ii = -1; + onParallel.ii = -1; + onParallel.remaining = options.list.length; + options.rateLimit = Number(options.rateLimit) || 4; + options.rateLimit = Math.max(options.rateLimit, 3); + options.retryLimit = Number(options.retryLimit) || 2; + onEach2(); + onParallel(); + }; + + local.onReadyAfter = function (onError) { + /* + * this function will call onError when onReadyBefore.counter === 0 + */ + local.onReadyBefore.counter += 1; + local.taskCreate({ key: 'utility2.onReadyAfter' }, null, onError); + local.onResetAfter(local.onReadyBefore); + return onError; + }; + }()); + switch (local.modeJs) { + + + + // run node js-env code - function + case 'node': + local.contentDelete = function (options, onError) { + /* + * this function will delete the github file + * https://developer.github.com/v3/repos/contents/#delete-a-file + */ + options = { message: options.message, url: options.url }; + local.onNext(options, function (error, data) { + switch (options.modeNext) { + case 1: + // get sha + local.contentRequest({ method: 'GET', url: options.url }, options.onNext); + break; + case 2: + // delete file with sha + if (!error && data.sha) { + local.contentRequest({ + message: options.message, + method: 'DELETE', + sha: data.sha, + url: options.url + }, options.onNext); + return; + } + // delete tree + local.onParallelList({ list: data }, function (data, onParallel) { + onParallel.counter += 1; + // recurse + local.contentDelete({ + message: options.message, + url: data.element.url + }, onParallel); + }, options.onNext); + break; + default: + onError(); + } + }); + options.modeNext = 0; + options.onNext(); + }; + + local.contentGet = function (options, onError) { + /* + * this function will get the github file + * https://developer.github.com/v3/repos/contents/#get-contents + */ + options = { url: options.url }; + local.onNext(options, function (error, data) { + switch (options.modeNext) { + case 1: + local.contentRequest({ method: 'GET', url: options.url }, options.onNext); + break; + case 2: + options.onNext(null, new Buffer(data.content, 'base64')); + break; + default: + onError(error, !error && data); + } + }); + options.modeNext = 0; + options.onNext(); + }; + + local.contentPut = function (options, onError) { + /* + * this function will put options.content into the github file + * https://developer.github.com/v3/repos/contents/#update-a-file + */ + options = { + content: options.content, + message: options.message, + modeErrorIgnore: true, + url: options.url + }; + local.onNext(options, function (error, data) { + switch (options.modeNext) { + case 1: + // get sha + local.contentRequest({ method: 'GET', url: options.url }, options.onNext); + break; + case 2: + // put file with sha + local.contentRequest({ + content: options.content, + message: options.message, + method: 'PUT', + sha: data.sha, + url: options.url + }, options.onNext); + break; + default: + onError(error); + } + }); + options.modeNext = 0; + options.onNext(); + }; + + local.contentPutFile = function (options, onError) { + /* + * this function will put options.file into the github file + * https://developer.github.com/v3/repos/contents/#update-a-file + */ + options = { file: options.file, message: options.message, url: options.url }; + local.onNext(options, function (error, data) { + switch (options.modeNext) { + case 1: + // get file from url + if ((/^(?:http|https):\/\//).test(options.file)) { + local.httpRequest({ + method: 'GET', + url: options.file + }, function (error, response) { + options.onNext(error, response && response.data); + }); + return; + } + // get file + local.fs.readFile( + local.path.resolve(process.cwd(), options.file), + options.onNext + ); + break; + case 2: + local.contentPut({ + content: data, + message: options.message, + // resolve file in url + url: (/\/$/).test(options.url) + ? options.url + local.path.basename(options.file) + : options.url + }, options.onNext); + break; + default: + onError(error); + } + }); + options.modeNext = 0; + options.onNext(); + }; + + local.contentRequest = function (options, onError) { + /* + * this function will request the content from github + */ + // init options + options = { + chunkList: [], + content: options.content, + headers: { + // github oauth authentication + Authorization: 'token ' + process.env.GITHUB_TOKEN, + // bug-workaround - https://developer.github.com/v3/#user-agent-required + 'User-Agent': 'undefined' + }, + message: options.message, + method: options.method, + responseJson: {}, + sha: options.sha, + url: options.url + }; + options.url = options.url +/* jslint-ignore-begin */ +// parse https://github.com/:owner/:repo/blob/:branch/:path +.replace( + (/^https:\/\/github.com\/([^\/]+?\/[^\/]+?)\/blob\/([^\/]+?)\/(.+)/), + 'https://api.github.com/repos/$1/contents/$3?branch=$2' +) +// parse https://github.com/:owner/:repo/tree/:branch/:path +.replace( + (/^https:\/\/github.com\/([^\/]+?\/[^\/]+?)\/tree\/([^\/]+?)\/(.+)/), + 'https://api.github.com/repos/$1/contents/$3?branch=$2' +) +// parse https://raw.githubusercontent.com/:owner/:repo/:branch/:path +.replace( +(/^https:\/\/raw.githubusercontent.com\/([^\/]+?\/[^\/]+?)\/([^\/]+?)\/(.+)/), + 'https://api.github.com/repos/$1/contents/$3?branch=$2' +) +// parse https://:owner.github.io/:repo/:path +.replace( + (/^https:\/\/([^\.]+?)\.github\.io\/([^\/]+?)\/(.+)/), + 'https://api.github.com/repos/$1/$2/contents/$3?branch=gh-pages' +) +/* jslint-ignore-end */ + .replace((/\?branch=(.*)/), function (match0, match1) { + options.branch = match1; + if (options.method === 'GET') { + match0 = match0.replace('branch', 'ref'); + } + return match0; + }); + if (options.url.indexOf('https://api.github.com/repos/') !== 0) { + onError(new Error('invalid url ' + options.url)); + return; + } + if (options.method !== 'GET') { + options.message = options.message || + '[ci skip] ' + options.method + ' file ' + options.url + .replace((/\?.*/), ''); + options.url += '&message=' + encodeURIComponent(options.message); + if (options.sha) { + options.url += '&sha=' + options.sha; + } + options.data = JSON.stringify({ + branch: options.branch, + content: new Buffer(options.content || '').toString('base64'), + message: options.message, + sha: options.sha + }); + } + local.httpRequest(options, function (error, response) { + try { + options.responseJson = JSON.parse(response.data.toString()); + } catch (ignore) { + } + onError(error, options.responseJson); + }); + }; + + local.contentTouch = function (options, onError) { + /* + * this function will touch options.url + * https://developer.github.com/v3/repos/contents/#update-a-file + */ + options = { + message: options.message, + modeErrorIgnore: true, + url: options.url + }; + local.onNext(options, function (error, data) { + switch (options.modeNext) { + case 1: + // get sha + local.contentRequest({ method: 'GET', url: options.url }, options.onNext); + break; + case 2: + // put file with sha + local.contentRequest({ + content: new Buffer(data.content || '', 'base64'), + message: options.message, + method: 'PUT', + sha: data.sha, + url: options.url + }, options.onNext); + break; + default: + onError(error); + } + }); + options.modeNext = 0; + options.onNext(); + }; + + local.contentTouchList = function (options, onError) { + /* + * this function will touch options.urlList in parallel + * https://developer.github.com/v3/repos/contents/#update-a-file + */ + local.onParallelList({ list: options.urlList }, function (data, onParallel) { + onParallel.counter += 1; + local.contentTouch({ + message: options.message, + modeErrorIgnore: true, + url: data.element + }, onParallel); + }, onError); + }; + break; + } + switch (local.modeJs) { + + + + /* istanbul ignore next */ + // run node js-env code - init-after + case 'node': + // require modules + local.fs = require('fs'); + local.path = require('path'); + // run the cli + if (module !== require.main || local.global.utility2_rollup) { + break; + } + switch (String(process.argv[2]).toLowerCase()) { + // delete file + case 'delete': + local.contentDelete({ + message: process.argv[4], + url: process.argv[3] + }, function (error) { + // validate no error occurred + console.assert(!error, error); + }); + break; + // get file + case 'get': + local.contentGet({ url: process.argv[3] }, function (error, data) { + // validate no error occurred + console.assert(!error, error); + try { + process.stdout.write(data); + } catch (ignore) { + } + }); + break; + // put file + case 'put': + local.contentPutFile({ + message: process.argv[5], + url: process.argv[3], + file: process.argv[4] + }, function (error) { + // validate no error occurred + console.assert(!error, error); + }); + break; + // touch file + case 'touch': + local.contentTouch({ + message: process.argv[4], + url: process.argv[3] + }, function (error) { + // validate no error occurred + console.assert(!error, error); + }); + break; + case 'touchlist': + local.contentTouchList({ + message: process.argv[4], + urlList: process.argv[3].split(' ').filter(function (element) { + return element; + }) + }, function (error) { + // validate no error occurred + console.assert(!error, error); + }); + break; + } + break; + } +}()); +/* script-end /assets.utility2.lib.github_crud.js */ + + + +/* script-begin /assets.utility2.lib.istanbul.js */ +///usr/bin/env node +/* istanbul instrument in package istanbul */ +/*jslint + bitwise: true, + browser: true, + maxerr: 8, + maxlen: 96, + node: true, + nomen: true, + regexp: true, + stupid: true +*/ +(function (local) { + 'use strict'; + var __dirname, process, require; + + + + // run shared js-env code - init-before + (function () { + // jslint-hack + local.nop(__dirname); + __dirname = ''; + /* istanbul ignore next */ + local.global.__coverageCodeDict__ = local.global.__coverageCodeDict__ || {}; + local['./package.json'] = {}; + process = local.modeJs === 'browser' + ? { + cwd: function () { + return ''; + }, + stdout: {} + } + : local.process; + require = function (key) { + try { + return local[key] || local.require(key); + } catch (ignore) { + } + }; + }()); + + + + // run shared js-env code - function + (function () { + local.coverageMerge = function (coverage1, coverage2) { + /* + * this function will merge coverage2 into coverage1 + */ + var dict1, dict2; + coverage1 = coverage1 || {}; + coverage2 = coverage2 || {}; + Object.keys(coverage2).forEach(function (file) { + if (!coverage2[file]) { + return; + } + // if file is undefined in coverage1, then add it + if (!coverage1[file]) { + coverage1[file] = coverage2[file]; + return; + } + // merge file from coverage2 into coverage1 + ['b', 'f', 's'].forEach(function (key) { + dict1 = coverage1[file][key]; + dict2 = coverage2[file][key]; + switch (key) { + // increment coverage for branch lines + case 'b': + Object.keys(dict2).forEach(function (key) { + dict2[key].forEach(function (count, ii) { + dict1[key][ii] += count; + }); + }); + break; + // increment coverage for function and statement lines + case 'f': + case 's': + Object.keys(dict2).forEach(function (key) { + dict1[key] += dict2[key]; + }); + break; + } + }); + }); + return coverage1; + }; + + local.coverageReportCreate = function () { + /* + * this function will + * 1. print coverage in text-format to stdout + * 2. write coverage in html-format to filesystem + * 3. return coverage in html-format as single document + */ + var options; + /* istanbul ignore next */ + if (!local.global.__coverage__) { + return ''; + } + options = {}; + options.dir = process.cwd() + '/tmp/build/coverage.html'; + // merge previous coverage + if (local.modeJs === 'node' && process.env.npm_config_mode_coverage_merge) { + console.log('merging file://' + options.dir + '/coverage.json to coverage'); + try { + local.coverageMerge( + local.global.__coverage__, + JSON.parse( + local._fs.readFileSync(options.dir + '/coverage.json', 'utf8') + ) + ); + } catch (ignore) { + } + try { + options.coverageCodeDict = JSON.parse(local._fs.readFileSync( + options.dir + '/coverage.code-dict.json', + 'utf8' + )); + Object.keys(options.coverageCodeDict).forEach(function (key) { + local.global.__coverageCodeDict__[key] = + local.global.__coverageCodeDict__[key] || + options.coverageCodeDict[key]; + }); + } catch (ignore) { + } + } + // init writer + local.coverageReportHtml = ''; + local.coverageReportHtml += '
\n' + + '

coverage-report

\n' + + '
\n'; + local.writerData = ''; + options.sourceStore = {}; + options.writer = local.writer; + // 1. print coverage in text-format to stdout + new local.TextReport(options).writeReport(local.collector); + // 2. write coverage in html-format to filesystem + new local.HtmlReport(options).writeReport(local.collector); + local.writer.writeFile('', local.nop); + // write coverage.json + local.fsWriteFileWithMkdirpSync2( + options.dir + '/coverage.json', + JSON.stringify(local.global.__coverage__) + ); + // write coverage.code-dict.json + local.fsWriteFileWithMkdirpSync2( + options.dir + '/coverage.code-dict.json', + JSON.stringify(local.global.__coverageCodeDict__) + ); + // write coverage.badge.svg + options.pct = local.coverageReportSummary.root.metrics.lines.pct; + local.fsWriteFileWithMkdirpSync2( + local.path.dirname(options.dir) + '/coverage.badge.svg', + local.templateCoverageBadgeSvg + // edit coverage badge percent + .replace((/100.0/g), options.pct) + // edit coverage badge color + .replace( + (/0d0/g), + ('0' + Math.round((100 - options.pct) * 2.21).toString(16)).slice(-2) + + ('0' + Math.round(options.pct * 2.21).toString(16)).slice(-2) + '00' + ) + ); + console.log('created coverage file://' + options.dir + '/index.html'); + // 3. return coverage in html-format as a single document + local.coverageReportHtml += '
\n
\n'; + // write coverage.rollup.html + local.fsWriteFileWithMkdirpSync2( + options.dir + '/coverage.rollup.html', + local.coverageReportHtml + ); + return local.coverageReportHtml; + }; + + local.fs = {}; + + local.fs.readFileSync = function (file) { + // return head.txt or foot.txt + file = local[file.slice(-8)]; + if (local.modeJs === 'browser') { + file = file + .replace((/\bhtml\b/g), 'x-istanbul-html') + .replace((/\n\ +\n\ +\n\ +
\n\ +

\n\ + {{env.npm_package_name}} (v{{env.npm_package_version}})\n\ +

\n\ +

Code coverage report for {{entity}}

\n\ +

\n\ + {{#with metrics.statements}}\n\ + Statements: {{pct}}% ({{covered}} / {{total}})     \n\ + {{/with}}\n\ + {{#with metrics.branches}}\n\ + Branches: {{pct}}% ({{covered}} / {{total}})     \n\ + {{/with}}\n\ + {{#with metrics.functions}}\n\ + Functions: {{pct}}% ({{covered}} / {{total}})     \n\ + {{/with}}\n\ + {{#with metrics.lines}}\n\ + Lines: {{pct}}% ({{covered}} / {{total}})     \n\ + {{/with}}\n\ + Ignored: {{#show_ignores metrics}}{{/show_ignores}}     \n\ +

\n\ + {{{pathHtml}}}\n\ +
\n\ +
\n\ +'; +/* jslint-ignore-end */ + + + + /* istanbul ignore next */ + // init lib istanbul.util.file-writer + (function () { + // https://github.com/gotwarlost/istanbul/blob/v0.2.16/lib/util/file-writer.js + local.writer = { + write: function (data) { + local.writerData += data; + }, + writeFile: function (file, onError) { + local.coverageReportHtml += local.writerData + '\n\n'; + if (local.writerFile) { + local.fsWriteFileWithMkdirpSync2(local.writerFile, local.writerData); + } + local.writerData = ''; + local.writerFile = file; + onError(local.writer); + } + }; + }()); + + + + /* istanbul ignore next */ + // init lib istanbul.util.tree-summarizer + (function () { + var module; + module = {}; +/* jslint-ignore-begin */ +// https://github.com/gotwarlost/istanbul/blob/v0.2.16/lib/util/tree-summarizer.js +// utility2-uglifyjs https://raw.githubusercontent.com/gotwarlost/istanbul/v0.2.16/lib/util/tree-summarizer.js +function commonArrayPrefix(e,t){var n=e.length0&&(t.pop(),s=i,o=s.children,s.children=[],i=new +Node(t.join(SEP)+SEP,"dir"),i.addChild(s),o.forEach(function(e){e.kind==="dir"?i +.addChild(e):s.addChild(e)})),this.fixupNodes(i,t.join(SEP)+SEP),this.calculateMetrics +(i),this.root=i,this.map={},this.indexAndSortTree(i,this.map)},fixupNodes:function( +e,t,n){var r=this;e.name.indexOf(t)===0&&(e.name=e.name.substring(t.length)),e.name +.charAt(0)===SEP&&(e.name=e.name.substring(1)),n?n.name!=="__root__/"?e.relativeName= +e.name.substring(n.name.length):e.relativeName=e.name:e.relativeName=e.name.substring +(t.length),e.children.forEach(function(n){r.fixupNodes(n,t,e)})},calculateMetrics +:function(e){var t=this,n;if(e.kind!=="dir")return;e.children.forEach(function(e +){t.calculateMetrics(e)}),e.metrics=utils.mergeSummaryObjects.apply(null,e.children +.map(function(e){return e.metrics})),n=e.children.filter(function(e){return e.kind!=="dir" +}),n.length>0?e.packageMetrics=utils.mergeSummaryObjects.apply(null,n.map(function( +e){return e.metrics})):e.packageMetrics=null},indexAndSortTree:function(e,t){var n= +this;t[e.name]=e,e.children.sort(function(e,t){return e=e.relativeName,t=t.relativeName +,et?1:0}),e.children.forEach(function(e){n.indexAndSortTree(e,t)})},toJSON +:function(){return{prefix:this.prefix,root:this.root.toJSON()}}},TreeSummarizer. +prototype={addFileCoverageSummary:function(e,t){this.summaryMap[e]=t},getTreeSummary +:function(){var e=findCommonArrayPrefix(Object.keys(this.summaryMap));return new +TreeSummary(this.summaryMap,e)}},module.exports=TreeSummarizer +/* jslint-ignore-end */ + local['../util/tree-summarizer'] = module.exports; + module.exports.prototype._getTreeSummary = module.exports.prototype.getTreeSummary; + module.exports.prototype.getTreeSummary = function () { + local.coverageReportSummary = this._getTreeSummary(); + return local.coverageReportSummary; + }; + }()); + + + +/* istanbul ignore next */ +// init lib istanbul.report.html +/* jslint-ignore-begin */ +// https://github.com/gotwarlost/istanbul/blob/v0.2.16/lib/report/html.js +// utility2-uglifyjs https://raw.githubusercontent.com/gotwarlost/istanbul/v0.2.16/lib/report/html.js +(function () { var module; module = {}; +function customEscape(e){return e=e.toString(),e.replace(RE_AMP,"&").replace +(RE_LT,"<").replace(RE_GT,">").replace(RE_lt,"<").replace(RE_gt,">")}function title +(e){return' title="'+e+'" '}function annotateLines(e,t){var n=e.l;if(!n)return;Object +.keys(n).forEach(function(e){var r=n[e];t[e].covered=r>0?"yes":"no"}),t.forEach( +function(e){e.covered===null&&(e.covered="neutral")})}function annotateStatements +(e,t){var n=e.s,r=e.statementMap;Object.keys(n).forEach(function(e){var i=n[e],s= +r[e],o=i>0?"yes":"no",u=s.start.column,a=s.end.column+1,f=s.start.line,l=s.end.line +,c=lt+'span class="'+(s.skip?"cstat-skip":"cstat-no")+'"'+title("statement not covered" +)+gt,h=lt+"/span"+gt,p;o==="no"&&(l!==f&&(l=f,a=t[f].text.originalLength()),p=t[ +f].text,p.wrap(u,c,f===l?a:p.originalLength(),h))})}function annotateFunctions(e +,t){var n=e.f,r=e.fnMap;if(!n)return;Object.keys(n).forEach(function(e){var i=n[ +e],s=r[e],o=i>0?"yes":"no",u=s.loc.start.column,a=s.loc.end.column+1,f=s.loc.start +.line,l=s.loc.end.line,c=lt+'span class="'+(s.skip?"fstat-skip":"fstat-no")+'"'+ +title("function not covered")+gt,h=lt+"/span"+gt,p;o==="no"&&(l!==f&&(l=f,a=t[f] +.text.originalLength()),p=t[f].text,p.wrap(u,c,f===l?a:p.originalLength(),h))})} +function annotateBranches(e,t){var n=e.b,r=e.branchMap;if(!n)return;Object.keys( +n).forEach(function(e){var i=n[e],s=i.reduce(function(e,t){return e+t},0),o=r[e] +.locations,u,a,f,l,c,h,p,d,v,m,g;if(s>0)for(u=0;u0?"yes":"no",c=f.start.column,h=f.end.column+1,p=f.start.line,d=f.end.line,v=lt+'span class="branch-'+ +u+" "+(f.skip?"cbranch-skip":"cbranch-no")+'"'+title("branch not covered")+gt,m= +lt+"/span"+gt,a===0&&(d!==p&&(d=p,h=t[p].text.originalLength()),g=t[p].text,r[e] +.type==="if"?g.insertAt(c,lt+'span class="'+(f.skip?"skip-if-branch":"missing-if-branch" +)+'"'+title((u===0?"if":"else")+" path not taken")+gt+(u===0?"I":"E")+lt+"/span"+ +gt,!0,!1):g.wrap(c,v,p===d?h:g.originalLength(),m))})}function getReportClass(e, +t){var n=e.pct,r=1;return n*r===n?n>=t[1]?"high":n>=t[0]?"medium":"low":""}function HtmlReport +(e){Report.call(this),this.opts=e||{},this.opts.dir=this.opts.dir||path.resolve( +process.cwd(),"html-report"),this.opts.sourceStore=this.opts.sourceStore||Store. +create("fslookup"),this.opts.linkMapper=this.opts.linkMapper||this.standardLinkMapper +(),this.opts.writer=this.opts.writer||null,this.opts.templateData={datetime:Date +()},this.opts.watermarks=this.opts.watermarks||defaults.watermarks()}var handlebars= +require("handlebars"),defaults=require("./common/defaults"),path=require("path") +,SEP=path.sep||"/",fs=require("fs"),util=require("util"),FileWriter=require("../util/file-writer" +),Report=require("./index"),Store=require("../store"),InsertionText=require("../util/insertion-text" +),TreeSummarizer=require("../util/tree-summarizer"),utils=require("../object-utils" +),templateFor=function(e){return handlebars.compile(fs.readFileSync(path.resolve +(__dirname,"templates",e+".txt"),"utf8"))},headerTemplate=templateFor("head"),footerTemplate= +templateFor("foot"),pathTemplate=handlebars.compile('
{{{html}}}
' +),detailTemplate=handlebars.compile(["",'{{#show_lines}}{{maxLines}}{{/show_lines}}' +,'{{#show_line_execution_counts fileCoverage}}{{maxLines}}{{/show_line_execution_counts}}' +,'
{{#show_code structured}}{{/show_code}}
' +,"\n"].join("")),summaryTableHeader=['
',"" +,"","",' ' +,' ' +,' ' +,' ' +,' ' +,' ' +,' ' +,' ' +,' ' +,' ' +,"","",""].join("\n"),summaryLineTemplate=handlebars.compile +(["",'' +,'' +,'' +,'' +,'' +,'' +,'' +,'' +,'' +,'' +,"\n"].join("\n ")),summaryTableFooter=["","
FileStatementsBranchesFunctionsLines
{{file}}{{#show_picture}}{{metrics.statements.pct}}{{/show_picture}}{{metrics.statements.pct}}%({{metrics.statements.covered}} / {{metrics.statements.total}}){{metrics.branches.pct}}%({{metrics.branches.covered}} / {{metrics.branches.total}}){{metrics.functions.pct}}%({{metrics.functions.covered}} / {{metrics.functions.total}}){{metrics.lines.pct}}%({{metrics.lines.covered}} / {{metrics.lines.total}})
","
"].join +("\n"),lt="",gt="",RE_LT=//g,RE_AMP=/&/g,RE_lt=/\u0001/g,RE_gt=/\u0002/g +;handlebars.registerHelper("show_picture",function(e){var t=Number(e.fn(this)),n +,r="";return isFinite(t)?(t===100&&(r=" cover-full"),t=Math.floor(t),n=100-t,''+''):""}),handlebars.registerHelper("show_ignores",function(e){var t= +e.statements.skipped,n=e.functions.skipped,r=e.branches.skipped,i;return t===0&& +n===0&&r===0?'none':(i=[],t>0&&i.push(t===1?"1 statement" +:t+" statements"),n>0&&i.push(n===1?"1 function":n+" functions"),r>0&&i.push(r===1?"1 branch" +:r+" branches"),i.join(", "))}),handlebars.registerHelper("show_lines",function( +e){var t=Number(e.fn(this)),n,r=[];for(n=0;n0?(u="yes",a=n[s]):u="no"),o.push(''+a+"");return o.join("\n")}),handlebars.registerHelper("show_code", +function(e){var t=[];return e.forEach(function(e){t.push(customEscape(e.text)||" " +)}),t.join("\n")}),HtmlReport.TYPE="html",util.inherits(HtmlReport,Report),Report +.mix(HtmlReport,{getPathHtml:function(e,t){var n=e.parent,r=[],i=[],s;while(n)r. +push(n),n=n.parent;for(s=0;s'+ +(r[s].relativeName||"All files")+"");return i.reverse(),i.length>0?i.join(" » " +)+" » "+e.displayShortName():""},fillTemplate:function(e,t){var n=this.opts +,r=n.linkMapper;t.entity=e.name||"All files",t.metrics=e.metrics,t.reportClass=getReportClass +(e.metrics.statements,n.watermarks.statements),t.pathHtml=pathTemplate({html:this +.getPathHtml(e,r)}),t.prettify={js:r.asset(e,"prettify.js"),css:r.asset(e,"prettify.css" +)}},writeDetailPage:function(e,t,n){var r=this.opts,i=r.sourceStore,s=r.templateData +,o=n.code&&Array.isArray(n.code)?n.code.join("\n")+"\n":i.get(n.path),u=o.split(/(?:\r?\n)|\r/ +),a=0,f=u.map(function(e){return a+=1,{line:a,covered:null,text:new InsertionText +(e,!0)}}),l;f.unshift({line:0,covered:null,text:new InsertionText("")}),this.fillTemplate +(t,s),e.write(headerTemplate(s)),e.write('
\n'),annotateLines
+(n,f),annotateBranches(n,f),annotateFunctions(n,f),annotateStatements(n,f),f.shift
+(),l={structured:f,maxLines:f.length,fileCoverage:n},e.write(detailTemplate(l)),
+e.write("
\n"),e.write(footerTemplate(s))},writeIndexPage:function( +e,t){var n=this.opts.linkMapper,r=this.opts.templateData,i=Array.prototype.slice +.apply(t.children),s=this.opts.watermarks;i.sort(function(e,t){return e.name0&&(o>=l?(f=padding(o-l),a=n?f+e: +e+f):(a=e.substring(l-o),a="... "+a.substring(4))),a=defaults.colorize(a,i),u+a} +function formatName(e,t,n,r){return fill(e,t,!1,n,r)}function formatPct(e,t){return fill +(e,PCT_COLS,!0,0,t)}function nodeName(e){return e.displayShortName()||"All files" +}function tableHeader(e){var t=[];return t.push(formatName("File",e,0)),t.push(formatPct +("% Stmts")),t.push(formatPct("% Branches")),t.push(formatPct("% Funcs")),t.push +(formatPct("% Lines")),t.join(" |")+" |"}function tableRow(e,t,n,r){var i=nodeName +(e),s=e.metrics.statements.pct,o=e.metrics.branches.pct,u=e.metrics.functions.pct +,a=e.metrics.lines.pct,f=[];return f.push(formatName(i,t,n,defaults.classFor("statements" +,e.metrics,r))),f.push(formatPct(s,defaults.classFor("statements",e.metrics,r))) +,f.push(formatPct(o,defaults.classFor("branches",e.metrics,r))),f.push(formatPct +(u,defaults.classFor("functions",e.metrics,r))),f.push(formatPct(a,defaults.classFor +("lines",e.metrics,r))),f.join(DELIM)+DELIM}function findNameWidth(e,t,n){n=n||0 +,t=t||0;var r=TAB_SIZE*t+nodeName(e).length;return r>n&&(n=r),e.children.forEach +(function(e){n=findNameWidth(e,t+1,n)}),n}function makeLine(e){var t=padding(e,"-" +),n=padding(PCT_COLS,"-"),r=[];return r.push(t),r.push(n),r.push(n),r.push(n),r. +push(n),r.join(COL_DELIM)+COL_DELIM}function walk(e,t,n,r,i){var s;r===0?(s=makeLine +(t),n.push(s),n.push(tableHeader(t)),n.push(s)):n.push(tableRow(e,t,r,i)),e.children +.forEach(function(e){walk(e,t,n,r+1,i)}),r===0&&(n.push(s),n.push(tableRow(e,t,r +,i)),n.push(s))}var path=require("path"),mkdirp=require("mkdirp"),fs=require("fs" +),defaults=require("./common/defaults"),Report=require("./index"),TreeSummarizer= +require("../util/tree-summarizer"),utils=require("../object-utils"),PCT_COLS=10, +TAB_SIZE=3,DELIM=" |",COL_DELIM="-|";TextReport.TYPE="text",Report.mix(TextReport +,{writeReport:function(e){var t=new TreeSummarizer,n,r,i,s=4*(PCT_COLS+2),o,u=[] +,a;e.files().forEach(function(n){t.addFileCoverageSummary(n,utils.summarizeFileCoverage +(e.fileCoverageFor(n)))}),n=t.getTreeSummary(),r=n.root,i=findNameWidth(r),this. +maxCols>0&&(o=this.maxCols-s-2,i>o&&(i=o)),walk(r,i,u,0,this.watermarks),a=u.join +("\n")+"\n",this.file?(mkdirp.sync(this.dir),fs.writeFileSync(path.join(this.dir +,this.file),a,"utf8")):console.log(a)}}),module.exports=TextReport +local.TextReport = module.exports; }()); +/* jslint-ignore-end */ + + + +/* jslint-ignore-begin */ +// https://img.shields.io/badge/coverage-100.0%-00dd00.svg?style=flat +local.templateCoverageBadgeSvg = +'coveragecoverage100.0%100.0%'; +/* jslint-ignore-end */ + switch (local.modeJs) { + + + + // run node js-env code - init-after + case 'node': + /* istanbul ignore next */ + // run the cli + local.cliRunIstanbul = function (options) { + /* + * this function will run the cli + */ + var tmp; + if ((module !== local.require.main || local.global.utility2_rollup) && + !(options && options.runMain)) { + return; + } + switch (process.argv[2]) { + // transparently adds coverage information to a node command + case 'cover': + try { + tmp = JSON.parse(local._fs.readFileSync('package.json', 'utf8')); + process.env.npm_package_nameAlias = process.env.npm_package_nameAlias || + tmp.nameAlias || + tmp.name.replace((/-/g), '_'); + } catch (ignore) { + } + process.env.npm_config_mode_coverage = process.env.npm_config_mode_coverage || + process.env.npm_package_nameAlias || + 'all'; + // add coverage hook to require + local._moduleExtensionsJs = local.module._extensions['.js']; + local.module._extensions['.js'] = function (module, file) { + if (typeof file === 'string' && + (file.indexOf(process.env.npm_config_mode_coverage_dir) === 0 || ( + file.indexOf(process.cwd()) === 0 && + file.indexOf(process.cwd() + '/node_modules/') !== 0 + ))) { + module._compile(local.instrumentInPackage( + local._fs.readFileSync(file, 'utf8'), + file + ), file); + return; + } + local._moduleExtensionsJs(module, file); + }; + // init process.argv + process.argv.splice(1, 2); + process.argv[1] = local.path.resolve(process.cwd(), process.argv[1]); + console.log('\ncovering $ ' + process.argv.join(' ')); + // create coverage on exit + process.on('exit', function () { + local.coverageReportCreate({ coverage: local.global.__coverage__ }); + }); + // re-run cli + local.module.runMain(); + break; + // instrument a file and print result to stdout + case 'instrument': + process.argv[3] = local.path.resolve(process.cwd(), process.argv[3]); + process.stdout.write(local.instrumentSync( + local._fs.readFileSync(process.argv[3], 'utf8'), + process.argv[3] + )); + break; + // cover a node command only when npm_config_mode_coverage is set + case 'test': + if (process.env.npm_config_mode_coverage) { + process.argv[2] = 'cover'; + // re-run cli + local.cliRunIstanbul(options); + return; + } + // init process.argv + process.argv.splice(1, 2); + process.argv[1] = local.path.resolve(process.cwd(), process.argv[1]); + // re-run cli + local.module.runMain(); + break; + } + }; + local.cliRunIstanbul(); + break; + } +}( + // run shared js-env code - init-before + (function () { + 'use strict'; + var local; + // init local + local = {}; + // init modeJs + local.modeJs = (function () { + try { + return typeof navigator.userAgent === 'string' && + typeof document.querySelector('body') === 'object' && + typeof XMLHttpRequest.prototype.open === 'function' && + 'browser'; + } catch (errorCaughtBrowser) { + return module.exports && + typeof process.versions.node === 'string' && + typeof require('http').createServer === 'function' && + 'node'; + } + }()); + // init global + local.global = local.modeJs === 'browser' + ? window + : global; + // init utility2_rollup + local = local.global.utility2_rollup || local; + // init lib + local.local = local.istanbul = local; + // init exports + if (local.modeJs === 'browser') { + local.global.utility2_istanbul = local; + } else { + module.exports = local; + module.exports.__dirname = __dirname; + } + local.fsWriteFileWithMkdirpSync = function (file, data) { + /* + * this function will synchronously 'mkdir -p' and write the data to file + */ + // try to write to file + try { + require('fs').writeFileSync(file, data); + } catch (errorCaught) { + // mkdir -p + require('child_process').spawnSync( + 'mkdir', + ['-p', require('path').dirname(file)], + { stdio: ['ignore', 1, 2] } + ); + // re-write to file + require('fs').writeFileSync(file, data); + } + }; + local.nop = function () { + /* + * this function will do nothing + */ + return; + }; + switch (local.modeJs) { + case 'browser': + local.fsWriteFileWithMkdirpSync2 = local.nop; + break; + case 'node': + local.fsWriteFileWithMkdirpSync2 = local.fsWriteFileWithMkdirpSync; + local.__dirname = __dirname; + local.process = process; + local.require = require; + break; + } + return local; + }()) +)); +/* script-end /assets.utility2.lib.istanbul.js */ + + + +/* script-begin /assets.utility2.lib.jslint.js */ +///usr/bin/env node +/* istanbul instrument in package jslint */ +/*jslint + bitwise: true, + browser: true, + maxerr: 8, + maxlen: 96, + node: true, + nomen: true, + regexp: true, + stupid: true +*/ +(function () { + 'use strict'; + var local; + + + + // run shared js-env code - init-before + (function () { + // init local + local = {}; + // init modeJs + local.modeJs = (function () { + try { + return typeof navigator.userAgent === 'string' && + typeof document.querySelector('body') === 'object' && + typeof XMLHttpRequest.prototype.open === 'function' && + 'browser'; + } catch (errorCaughtBrowser) { + return module.exports && + typeof process.versions.node === 'string' && + typeof require('http').createServer === 'function' && + 'node'; + } + }()); + // init global + local.global = local.modeJs === 'browser' + ? window + : global; + // init utility2_rollup + local = local.global.utility2_rollup || local; + // init lib + local.local = local.jslint = local; + // init exports + if (local.modeJs === 'browser') { + local.global.utility2_jslint = local; + } else { + module.exports = local; + module.exports.__dirname = __dirname; + module.exports.module = module; + } + }()); + + + +/* jslint-ignore-begin */ +/* istanbul ignore next */ +// init lib csslint +// https://github.com/CSSLint/csslint/blob/v0.10.0/release/csslint.js +// utility2-uglifyjs https://raw.githubusercontent.com/CSSLint/csslint/v0.10.0/release/csslint.js +(function () { +var exports=exports||{},CSSLint=function(){function Reporter(e,t){this.messages= +[],this.stats=[],this.lines=e,this.ruleset=t}var parserlib={};(function(){function e +(){this._listeners={}}function t(e){this._input=e.replace(/\n\r?/g,"\n"),this._line=1 +,this._col=1,this._cursor=0}function n(e,t,n){this.col=n,this.line=t,this.message= +e}function r(e,t,n,r){this.col=n,this.line=t,this.text=e,this.type=r}function i( +e,n){this._reader=e?new t(e.toString()):null,this._token=null,this._tokenData=n, +this._lt=[],this._ltIndex=0,this._ltIndexCache=[]}e.prototype={constructor:e,addListener +:function(e,t){this._listeners[e]||(this._listeners[e]=[]),this._listeners[e].push +(t)},fire:function(e){typeof e=="string"&&(e={type:e}),typeof e.target!="undefined"&& +(e.target=this);if(typeof e.type=="undefined")throw new Error("Event object missing 'type' property." +);if(this._listeners[e.type]){var t=this._listeners[e.type].concat();for(var n=0 +,r=t.length;n=0&& +this._ltIndex-1&&!t[u.type].hide&& +(u.channel=t[u.type].channel,this._token=u,this._lt.push(u),this._ltIndexCache.push +(this._lt.length-this._ltIndex+i),this._lt.length>5&&this._lt.shift(),this._ltIndexCache +.length>5&&this._ltIndexCache.shift(),this._ltIndex=this._lt.length),a=t[u.type] +,a&&(a.hide||a.channel!==undefined&&e!==a.channel)?this.get(e):u.type},LA:function( +e){var t=e,n;if(e>0){if(e>5)throw new Error("Too much lookahead.");while(t)n=this +.get(),t--;while(tthis._tokenData.length?"UNKNOWN_TOKEN":this._tokenData +[e].name},tokenType:function(e){return this._tokenData[e]||-1},unget:function(){ +if(!this._ltIndexCache.length)throw new Error("Too much lookahead.");this._ltIndex-= +this._ltIndexCache.pop(),this._token=this._lt[this._ltIndex-1]}},parserlib.util= +{StringReader:t,SyntaxError:n,SyntaxUnit:r,EventTarget:e,TokenStreamBase:i}})(), +function(){function Combinator(e,t,n){SyntaxUnit.call(this,e,t,n,Parser.COMBINATOR_TYPE +),this.type="unknown",/^\s+$/.test(e)?this.type="descendant":e==">"?this.type="child" +:e=="+"?this.type="adjacent-sibling":e=="~"&&(this.type="sibling")}function MediaFeature +(e,t){SyntaxUnit.call(this,"("+e+(t!==null?":"+t:"")+")",e.startLine,e.startCol, +Parser.MEDIA_FEATURE_TYPE),this.name=e,this.value=t}function MediaQuery(e,t,n,r, +i){SyntaxUnit.call(this,(e?e+" ":"")+(t?t:"")+(t&&n.length>0?" and ":"")+n.join(" and " +),r,i,Parser.MEDIA_QUERY_TYPE),this.modifier=e,this.mediaType=t,this.features=n} +function Parser(e){EventTarget.call(this),this.options=e||{},this._tokenStream=null +}function PropertyName(e,t,n,r){SyntaxUnit.call(this,e,n,r,Parser.PROPERTY_NAME_TYPE +),this.hack=t}function PropertyValue(e,t,n){SyntaxUnit.call(this,e.join(" "),t,n +,Parser.PROPERTY_VALUE_TYPE),this.parts=e}function PropertyValueIterator(e){this +._i=0,this._parts=e.parts,this._marks=[],this.value=e}function PropertyValuePart +(text,line,col){SyntaxUnit.call(this,text,line,col,Parser.PROPERTY_VALUE_PART_TYPE +),this.type="unknown";var temp;if(/^([+\-]?[\d\.]+)([a-z]+)$/i.test(text)){this. +type="dimension",this.value=+RegExp.$1,this.units=RegExp.$2;switch(this.units.toLowerCase +()){case"em":case"rem":case"ex":case"px":case"cm":case"mm":case"in":case"pt":case"pc" +:case"ch":case"vh":case"vw":case"vm":this.type="length";break;case"deg":case"rad" +:case"grad":this.type="angle";break;case"ms":case"s":this.type="time";break;case"hz" +:case"khz":this.type="frequency";break;case"dpi":case"dpcm":this.type="resolution" +}}else/^([+\-]?[\d\.]+)%$/i.test(text)?(this.type="percentage",this.value=+RegExp +.$1):/^([+\-]?[\d\.]+)%$/i.test(text)?(this.type="percentage",this.value=+RegExp +.$1):/^([+\-]?\d+)$/i.test(text)?(this.type="integer",this.value=+RegExp.$1):/^([+\-]?[\d\.]+)$/i +.test(text)?(this.type="number",this.value=+RegExp.$1):/^#([a-f0-9]{3,6})/i.test +(text)?(this.type="color",temp=RegExp.$1,temp.length==3?(this.red=parseInt(temp. +charAt(0)+temp.charAt(0),16),this.green=parseInt(temp.charAt(1)+temp.charAt(1),16 +),this.blue=parseInt(temp.charAt(2)+temp.charAt(2),16)):(this.red=parseInt(temp. +substring(0,2),16),this.green=parseInt(temp.substring(2,4),16),this.blue=parseInt +(temp.substring(4,6),16))):/^rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/i.test(text +)?(this.type="color",this.red=+RegExp.$1,this.green=+RegExp.$2,this.blue=+RegExp +.$3):/^rgb\(\s*(\d+)%\s*,\s*(\d+)%\s*,\s*(\d+)%\s*\)/i.test(text)?(this.type="color" +,this.red=+RegExp.$1*255/100,this.green=+RegExp.$2*255/100,this.blue=+RegExp.$3*255/100 +):/^rgba\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*([\d\.]+)\s*\)/i.test(text)?(this +.type="color",this.red=+RegExp.$1,this.green=+RegExp.$2,this.blue=+RegExp.$3,this +.alpha=+RegExp.$4):/^rgba\(\s*(\d+)%\s*,\s*(\d+)%\s*,\s*(\d+)%\s*,\s*([\d\.]+)\s*\)/i +.test(text)?(this.type="color",this.red=+RegExp.$1*255/100,this.green=+RegExp.$2*255/100 +,this.blue=+RegExp.$3*255/100,this.alpha=+RegExp.$4):/^hsl\(\s*(\d+)\s*,\s*(\d+)%\s*,\s*(\d+)%\s*\)/i +.test(text)?(this.type="color",this.hue=+RegExp.$1,this.saturation=+RegExp.$2/100 +,this.lightness=+RegExp.$3/100):/^hsla\(\s*(\d+)\s*,\s*(\d+)%\s*,\s*(\d+)%\s*,\s*([\d\.]+)\s*\)/i +.test(text)?(this.type="color",this.hue=+RegExp.$1,this.saturation=+RegExp.$2/100 +,this.lightness=+RegExp.$3/100,this.alpha=+RegExp.$4):/^url\(["']?([^\)"']+)["']?\)/i +.test(text)?(this.type="uri",this.uri=RegExp.$1):/^([^\(]+)\(/i.test(text)?(this +.type="function",this.name=RegExp.$1,this.value=text):/^["'][^"']*["']/.test(text +)?(this.type="string",this.value=eval(text)):Colors[text.toLowerCase()]?(this.type="color" +,temp=Colors[text.toLowerCase()].substring(1),this.red=parseInt(temp.substring(0 +,2),16),this.green=parseInt(temp.substring(2,4),16),this.blue=parseInt(temp.substring +(4,6),16)):/^[\,\/]$/.test(text)?(this.type="operator",this.value=text):/^[a-z\-\u0080-\uFFFF][a-z0-9\-\u0080-\uFFFF]*$/i +.test(text)&&(this.type="identifier",this.value=text)}function Selector(e,t,n){SyntaxUnit +.call(this,e.join(" "),t,n,Parser.SELECTOR_TYPE),this.parts=e,this.specificity=Specificity +.calculate(this)}function SelectorPart(e,t,n,r,i){SyntaxUnit.call(this,n,r,i,Parser +.SELECTOR_PART_TYPE),this.elementName=e,this.modifiers=t}function SelectorSubPart +(e,t,n,r){SyntaxUnit.call(this,e,n,r,Parser.SELECTOR_SUB_PART_TYPE),this.type=t, +this.args=[]}function Specificity(e,t,n,r){this.a=e,this.b=t,this.c=n,this.d=r}function isHexDigit +(e){return e!==null&&h.test(e)}function isDigit(e){return e!==null&&/\d/.test(e) +}function isWhitespace(e){return e!==null&&/\s/.test(e)}function isNewLine(e){return e!== +null&&nl.test(e)}function isNameStart(e){return e!==null&&/[a-z_\u0080-\uFFFF\\]/i +.test(e)}function isNameChar(e){return e!==null&&(isNameStart(e)||/[0-9\-\\]/.test +(e))}function isIdentStart(e){return e!==null&&(isNameStart(e)||/\-\\/.test(e))} +function mix(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);return e}function TokenStream +(e){TokenStreamBase.call(this,e,Tokens)}function ValidationError(e,t,n){this.col= +n,this.line=t,this.message=e}var EventTarget=parserlib.util.EventTarget,TokenStreamBase= +parserlib.util.TokenStreamBase,StringReader=parserlib.util.StringReader,SyntaxError= +parserlib.util.SyntaxError,SyntaxUnit=parserlib.util.SyntaxUnit,Colors={aliceblue +:"#f0f8ff",antiquewhite:"#faebd7",aqua:"#00ffff",aquamarine:"#7fffd4",azure:"#f0ffff" +,beige:"#f5f5dc",bisque:"#ffe4c4",black:"#000000",blanchedalmond:"#ffebcd",blue:"#0000ff" +,blueviolet:"#8a2be2",brown:"#a52a2a",burlywood:"#deb887",cadetblue:"#5f9ea0",chartreuse +:"#7fff00",chocolate:"#d2691e",coral:"#ff7f50",cornflowerblue:"#6495ed",cornsilk +:"#fff8dc",crimson:"#dc143c",cyan:"#00ffff",darkblue:"#00008b",darkcyan:"#008b8b" +,darkgoldenrod:"#b8860b",darkgray:"#a9a9a9",darkgreen:"#006400",darkkhaki:"#bdb76b" +,darkmagenta:"#8b008b",darkolivegreen:"#556b2f",darkorange:"#ff8c00",darkorchid:"#9932cc" +,darkred:"#8b0000",darksalmon:"#e9967a",darkseagreen:"#8fbc8f",darkslateblue:"#483d8b" +,darkslategray:"#2f4f4f",darkturquoise:"#00ced1",darkviolet:"#9400d3",deeppink:"#ff1493" +,deepskyblue:"#00bfff",dimgray:"#696969",dodgerblue:"#1e90ff",firebrick:"#b22222" +,floralwhite:"#fffaf0",forestgreen:"#228b22",fuchsia:"#ff00ff",gainsboro:"#dcdcdc" +,ghostwhite:"#f8f8ff",gold:"#ffd700",goldenrod:"#daa520",gray:"#808080",green:"#008000" +,greenyellow:"#adff2f",honeydew:"#f0fff0",hotpink:"#ff69b4",indianred:"#cd5c5c", +indigo:"#4b0082",ivory:"#fffff0",khaki:"#f0e68c",lavender:"#e6e6fa",lavenderblush +:"#fff0f5",lawngreen:"#7cfc00",lemonchiffon:"#fffacd",lightblue:"#add8e6",lightcoral +:"#f08080",lightcyan:"#e0ffff",lightgoldenrodyellow:"#fafad2",lightgray:"#d3d3d3" +,lightgreen:"#90ee90",lightpink:"#ffb6c1",lightsalmon:"#ffa07a",lightseagreen:"#20b2aa" +,lightskyblue:"#87cefa",lightslategray:"#778899",lightsteelblue:"#b0c4de",lightyellow +:"#ffffe0",lime:"#00ff00",limegreen:"#32cd32",linen:"#faf0e6",magenta:"#ff00ff", +maroon:"#800000",mediumaquamarine:"#66cdaa",mediumblue:"#0000cd",mediumorchid:"#ba55d3" +,mediumpurple:"#9370d8",mediumseagreen:"#3cb371",mediumslateblue:"#7b68ee",mediumspringgreen +:"#00fa9a",mediumturquoise:"#48d1cc",mediumvioletred:"#c71585",midnightblue:"#191970" +,mintcream:"#f5fffa",mistyrose:"#ffe4e1",moccasin:"#ffe4b5",navajowhite:"#ffdead" +,navy:"#000080",oldlace:"#fdf5e6",olive:"#808000",olivedrab:"#6b8e23",orange:"#ffa500" +,orangered:"#ff4500",orchid:"#da70d6",palegoldenrod:"#eee8aa",palegreen:"#98fb98" +,paleturquoise:"#afeeee",palevioletred:"#d87093",papayawhip:"#ffefd5",peachpuff:"#ffdab9" +,peru:"#cd853f",pink:"#ffc0cb",plum:"#dda0dd",powderblue:"#b0e0e6",purple:"#800080" +,red:"#ff0000",rosybrown:"#bc8f8f",royalblue:"#4169e1",saddlebrown:"#8b4513",salmon +:"#fa8072",sandybrown:"#f4a460",seagreen:"#2e8b57",seashell:"#fff5ee",sienna:"#a0522d" +,silver:"#c0c0c0",skyblue:"#87ceeb",slateblue:"#6a5acd",slategray:"#708090",snow +:"#fffafa",springgreen:"#00ff7f",steelblue:"#4682b4",tan:"#d2b48c",teal:"#008080" +,thistle:"#d8bfd8",tomato:"#ff6347",turquoise:"#40e0d0",violet:"#ee82ee",wheat:"#f5deb3" +,white:"#ffffff",whitesmoke:"#f5f5f5",yellow:"#ffff00",yellowgreen:"#9acd32",activeBorder +:"Active window border.",activecaption:"Active window caption.",appworkspace:"Background color of multiple document interface." +,background:"Desktop background.",buttonface:"The face background color for 3-D elements that appear 3-D due to one layer of surrounding border." +,buttonhighlight:"The color of the border facing the light source for 3-D elements that appear 3-D due to one layer of surrounding border." +,buttonshadow:"The color of the border away from the light source for 3-D elements that appear 3-D due to one layer of surrounding border." +,buttontext:"Text on push buttons.",captiontext:"Text in caption, size box, and scrollbar arrow box." +,graytext:"Grayed (disabled) text. This color is set to #000 if the current display driver does not support a solid gray color." +,highlight:"Item(s) selected in a control.",highlighttext:"Text of item(s) selected in a control." +,inactiveborder:"Inactive window border.",inactivecaption:"Inactive window caption." +,inactivecaptiontext:"Color of text in an inactive caption.",infobackground:"Background color for tooltip controls." +,infotext:"Text color for tooltip controls.",menu:"Menu background.",menutext:"Text in menus." +,scrollbar:"Scroll bar gray area.",threeddarkshadow:"The color of the darker (generally outer) of the two borders away from the light source for 3-D elements that appear 3-D due to two concentric layers of surrounding border." +,threedface:"The face background color for 3-D elements that appear 3-D due to two concentric layers of surrounding border." +,threedhighlight:"The color of the lighter (generally outer) of the two borders facing the light source for 3-D elements that appear 3-D due to two concentric layers of surrounding border." +,threedlightshadow:"The color of the darker (generally inner) of the two borders facing the light source for 3-D elements that appear 3-D due to two concentric layers of surrounding border." +,threedshadow:"The color of the lighter (generally inner) of the two borders away from the light source for 3-D elements that appear 3-D due to two concentric layers of surrounding border." +,window:"Window background.",windowframe:"Window frame.",windowtext:"Text in windows." +};Combinator.prototype=new SyntaxUnit,Combinator.prototype.constructor=Combinator +,MediaFeature.prototype=new SyntaxUnit,MediaFeature.prototype.constructor=MediaFeature +,MediaQuery.prototype=new SyntaxUnit,MediaQuery.prototype.constructor=MediaQuery +,Parser.DEFAULT_TYPE=0,Parser.COMBINATOR_TYPE=1,Parser.MEDIA_FEATURE_TYPE=2,Parser +.MEDIA_QUERY_TYPE=3,Parser.PROPERTY_NAME_TYPE=4,Parser.PROPERTY_VALUE_TYPE=5,Parser +.PROPERTY_VALUE_PART_TYPE=6,Parser.SELECTOR_TYPE=7,Parser.SELECTOR_PART_TYPE=8,Parser +.SELECTOR_SUB_PART_TYPE=9,Parser.prototype=function(){var e=new EventTarget,t,n= +{constructor:Parser,DEFAULT_TYPE:0,COMBINATOR_TYPE:1,MEDIA_FEATURE_TYPE:2,MEDIA_QUERY_TYPE +:3,PROPERTY_NAME_TYPE:4,PROPERTY_VALUE_TYPE:5,PROPERTY_VALUE_PART_TYPE:6,SELECTOR_TYPE +:7,SELECTOR_PART_TYPE:8,SELECTOR_SUB_PART_TYPE:9,_stylesheet:function(){var e=this +._tokenStream,t=null,n,r,i;this.fire("startstylesheet"),this._charset(),this._skipCruft +();while(e.peek()==Tokens.IMPORT_SYM)this._import(),this._skipCruft();while(e.peek +()==Tokens.NAMESPACE_SYM)this._namespace(),this._skipCruft();i=e.peek();while(i> +Tokens.EOF){try{switch(i){case Tokens.MEDIA_SYM:this._media(),this._skipCruft(); +break;case Tokens.PAGE_SYM:this._page(),this._skipCruft();break;case Tokens.FONT_FACE_SYM +:this._font_face(),this._skipCruft();break;case Tokens.KEYFRAMES_SYM:this._keyframes +(),this._skipCruft();break;case Tokens.VIEWPORT_SYM:this._viewport(),this._skipCruft +();break;case Tokens.UNKNOWN_SYM:e.get();if(!!this.options.strict)throw new SyntaxError +("Unknown @ rule.",e.LT(0).startLine,e.LT(0).startCol);this.fire({type:"error",error +:null,message:"Unknown @ rule: "+e.LT(0).value+".",line:e.LT(0).startLine,col:e. +LT(0).startCol}),n=0;while(e.advance([Tokens.LBRACE,Tokens.RBRACE])==Tokens.LBRACE +)n++;while(n)e.advance([Tokens.RBRACE]),n--;break;case Tokens.S:this._readWhitespace +();break;default:if(!this._ruleset())switch(i){case Tokens.CHARSET_SYM:throw r=e +.LT(1),this._charset(!1),new SyntaxError("@charset not allowed here.",r.startLine +,r.startCol);case Tokens.IMPORT_SYM:throw r=e.LT(1),this._import(!1),new SyntaxError +("@import not allowed here.",r.startLine,r.startCol);case Tokens.NAMESPACE_SYM:throw r= +e.LT(1),this._namespace(!1),new SyntaxError("@namespace not allowed here.",r.startLine +,r.startCol);default:e.get(),this._unexpectedToken(e.token())}}}catch(s){if(!(s instanceof +SyntaxError&&!this.options.strict))throw s;this.fire({type:"error",error:s,message +:s.message,line:s.line,col:s.col})}i=e.peek()}i!=Tokens.EOF&&this._unexpectedToken +(e.token()),this.fire("endstylesheet")},_charset:function(e){var t=this._tokenStream +,n,r,i,s;t.match(Tokens.CHARSET_SYM)&&(i=t.token().startLine,s=t.token().startCol +,this._readWhitespace(),t.mustMatch(Tokens.STRING),r=t.token(),n=r.value,this._readWhitespace +(),t.mustMatch(Tokens.SEMICOLON),e!==!1&&this.fire({type:"charset",charset:n,line +:i,col:s}))},_import:function(e){var t=this._tokenStream,n,r,i,s=[];t.mustMatch( +Tokens.IMPORT_SYM),i=t.token(),this._readWhitespace(),t.mustMatch([Tokens.STRING +,Tokens.URI]),r=t.token().value.replace(/(?:url\()?["']([^"']+)["']\)?/,"$1"),this +._readWhitespace(),s=this._media_query_list(),t.mustMatch(Tokens.SEMICOLON),this +._readWhitespace(),e!==!1&&this.fire({type:"import",uri:r,media:s,line:i.startLine +,col:i.startCol})},_namespace:function(e){var t=this._tokenStream,n,r,i,s;t.mustMatch +(Tokens.NAMESPACE_SYM),n=t.token().startLine,r=t.token().startCol,this._readWhitespace +(),t.match(Tokens.IDENT)&&(i=t.token().value,this._readWhitespace()),t.mustMatch +([Tokens.STRING,Tokens.URI]),s=t.token().value.replace(/(?:url\()?["']([^"']+)["']\)?/ +,"$1"),this._readWhitespace(),t.mustMatch(Tokens.SEMICOLON),this._readWhitespace +(),e!==!1&&this.fire({type:"namespace",prefix:i,uri:s,line:n,col:r})},_media:function( +){var e=this._tokenStream,t,n,r;e.mustMatch(Tokens.MEDIA_SYM),t=e.token().startLine +,n=e.token().startCol,this._readWhitespace(),r=this._media_query_list(),e.mustMatch +(Tokens.LBRACE),this._readWhitespace(),this.fire({type:"startmedia",media:r,line +:t,col:n});for(;;)if(e.peek()==Tokens.PAGE_SYM)this._page();else if(e.peek()==Tokens +.FONT_FACE_SYM)this._font_face();else if(!this._ruleset())break;e.mustMatch(Tokens +.RBRACE),this._readWhitespace(),this.fire({type:"endmedia",media:r,line:t,col:n} +)},_media_query_list:function(){var e=this._tokenStream,t=[];this._readWhitespace +(),(e.peek()==Tokens.IDENT||e.peek()==Tokens.LPAREN)&&t.push(this._media_query() +);while(e.match(Tokens.COMMA))this._readWhitespace(),t.push(this._media_query()) +;return t},_media_query:function(){var e=this._tokenStream,t=null,n=null,r=null, +i=[];e.match(Tokens.IDENT)&&(n=e.token().value.toLowerCase(),n!="only"&&n!="not"? +(e.unget(),n=null):r=e.token()),this._readWhitespace(),e.peek()==Tokens.IDENT?(t= +this._media_type(),r===null&&(r=e.token())):e.peek()==Tokens.LPAREN&&(r===null&& +(r=e.LT(1)),i.push(this._media_expression()));if(t===null&&i.length===0)return null +;this._readWhitespace();while(e.match(Tokens.IDENT))e.token().value.toLowerCase( +)!="and"&&this._unexpectedToken(e.token()),this._readWhitespace(),i.push(this._media_expression +());return new MediaQuery(n,t,i,r.startLine,r.startCol)},_media_type:function(){ +return this._media_feature()},_media_expression:function(){var e=this._tokenStream +,t=null,n,r=null;return e.mustMatch(Tokens.LPAREN),t=this._media_feature(),this. +_readWhitespace(),e.match(Tokens.COLON)&&(this._readWhitespace(),n=e.LT(1),r=this +._expression()),e.mustMatch(Tokens.RPAREN),this._readWhitespace(),new MediaFeature +(t,r?new SyntaxUnit(r,n.startLine,n.startCol):null)},_media_feature:function(){var e= +this._tokenStream;return e.mustMatch(Tokens.IDENT),SyntaxUnit.fromToken(e.token( +))},_page:function(){var e=this._tokenStream,t,n,r=null,i=null;e.mustMatch(Tokens +.PAGE_SYM),t=e.token().startLine,n=e.token().startCol,this._readWhitespace(),e.match +(Tokens.IDENT)&&(r=e.token().value,r.toLowerCase()==="auto"&&this._unexpectedToken +(e.token())),e.peek()==Tokens.COLON&&(i=this._pseudo_page()),this._readWhitespace +(),this.fire({type:"startpage",id:r,pseudo:i,line:t,col:n}),this._readDeclarations +(!0,!0),this.fire({type:"endpage",id:r,pseudo:i,line:t,col:n})},_margin:function( +){var e=this._tokenStream,t,n,r=this._margin_sym();return r?(t=e.token().startLine +,n=e.token().startCol,this.fire({type:"startpagemargin",margin:r,line:t,col:n}), +this._readDeclarations(!0),this.fire({type:"endpagemargin",margin:r,line:t,col:n +}),!0):!1},_margin_sym:function(){var e=this._tokenStream;return e.match([Tokens +.TOPLEFTCORNER_SYM,Tokens.TOPLEFT_SYM,Tokens.TOPCENTER_SYM,Tokens.TOPRIGHT_SYM,Tokens +.TOPRIGHTCORNER_SYM,Tokens.BOTTOMLEFTCORNER_SYM,Tokens.BOTTOMLEFT_SYM,Tokens.BOTTOMCENTER_SYM +,Tokens.BOTTOMRIGHT_SYM,Tokens.BOTTOMRIGHTCORNER_SYM,Tokens.LEFTTOP_SYM,Tokens.LEFTMIDDLE_SYM +,Tokens.LEFTBOTTOM_SYM,Tokens.RIGHTTOP_SYM,Tokens.RIGHTMIDDLE_SYM,Tokens.RIGHTBOTTOM_SYM +])?SyntaxUnit.fromToken(e.token()):null},_pseudo_page:function(){var e=this._tokenStream +;return e.mustMatch(Tokens.COLON),e.mustMatch(Tokens.IDENT),e.token().value},_font_face +:function(){var e=this._tokenStream,t,n;e.mustMatch(Tokens.FONT_FACE_SYM),t=e.token +().startLine,n=e.token().startCol,this._readWhitespace(),this.fire({type:"startfontface" +,line:t,col:n}),this._readDeclarations(!0),this.fire({type:"endfontface",line:t, +col:n})},_viewport:function(){var e=this._tokenStream,t,n;e.mustMatch(Tokens.VIEWPORT_SYM +),t=e.token().startLine,n=e.token().startCol,this._readWhitespace(),this.fire({type +:"startviewport",line:t,col:n}),this._readDeclarations(!0),this.fire({type:"endviewport" +,line:t,col:n})},_operator:function(e){var t=this._tokenStream,n=null;if(t.match +([Tokens.SLASH,Tokens.COMMA])||e&&t.match([Tokens.PLUS,Tokens.STAR,Tokens.MINUS] +))n=t.token(),this._readWhitespace();return n?PropertyValuePart.fromToken(n):null +},_combinator:function(){var e=this._tokenStream,t=null,n;return e.match([Tokens +.PLUS,Tokens.GREATER,Tokens.TILDE])&&(n=e.token(),t=new Combinator(n.value,n.startLine +,n.startCol),this._readWhitespace()),t},_unary_operator:function(){var e=this._tokenStream +;return e.match([Tokens.MINUS,Tokens.PLUS])?e.token().value:null},_property:function( +){var e=this._tokenStream,t=null,n=null,r,i,s,o;return e.peek()==Tokens.STAR&&this +.options.starHack&&(e.get(),i=e.token(),n=i.value,s=i.startLine,o=i.startCol),e. +match(Tokens.IDENT)&&(i=e.token(),r=i.value,r.charAt(0)=="_"&&this.options.underscoreHack&& +(n="_",r=r.substring(1)),t=new PropertyName(r,n,s||i.startLine,o||i.startCol),this +._readWhitespace()),t},_ruleset:function(){var e=this._tokenStream,t,n;try{n=this +._selectors_group()}catch(r){if(r instanceof SyntaxError&&!this.options.strict){ +this.fire({type:"error",error:r,message:r.message,line:r.line,col:r.col}),t=e.advance +([Tokens.RBRACE]);if(t!=Tokens.RBRACE)throw r;return!0}throw r}return n&&(this.fire +({type:"startrule",selectors:n,line:n[0].line,col:n[0].col}),this._readDeclarations +(!0),this.fire({type:"endrule",selectors:n,line:n[0].line,col:n[0].col})),n},_selectors_group +:function(){var e=this._tokenStream,t=[],n;n=this._selector();if(n!==null){t.push +(n);while(e.match(Tokens.COMMA))this._readWhitespace(),n=this._selector(),n!==null? +t.push(n):this._unexpectedToken(e.LT(1))}return t.length?t:null},_selector:function( +){var e=this._tokenStream,t=[],n=null,r=null,i=null;n=this._simple_selector_sequence +();if(n===null)return null;t.push(n);do{r=this._combinator();if(r!==null)t.push( +r),n=this._simple_selector_sequence(),n===null?this._unexpectedToken(e.LT(1)):t. +push(n);else{if(!this._readWhitespace())break;i=new Combinator(e.token().value,e +.token().startLine,e.token().startCol),r=this._combinator(),n=this._simple_selector_sequence +(),n===null?r!==null&&this._unexpectedToken(e.LT(1)):(r!==null?t.push(r):t.push( +i),t.push(n))}}while(!0);return new Selector(t,t[0].line,t[0].col)},_simple_selector_sequence +:function(){var e=this._tokenStream,t=null,n=[],r="",i=[function(){return e.match +(Tokens.HASH)?new SelectorSubPart(e.token().value,"id",e.token().startLine,e.token +().startCol):null},this._class,this._attrib,this._pseudo,this._negation],s=0,o=i +.length,u=null,a=!1,f,l;f=e.LT(1).startLine,l=e.LT(1).startCol,t=this._type_selector +(),t||(t=this._universal()),t!==null&&(r+=t);for(;;){if(e.peek()===Tokens.S)break; +while(s1&&e.unget()),null)},_class:function(){var e=this._tokenStream,t;return e +.match(Tokens.DOT)?(e.mustMatch(Tokens.IDENT),t=e.token(),new SelectorSubPart("."+ +t.value,"class",t.startLine,t.startCol-1)):null},_element_name:function(){var e= +this._tokenStream,t;return e.match(Tokens.IDENT)?(t=e.token(),new SelectorSubPart +(t.value,"elementName",t.startLine,t.startCol)):null},_namespace_prefix:function( +){var e=this._tokenStream,t="";if(e.LA(1)===Tokens.PIPE||e.LA(2)===Tokens.PIPE)e +.match([Tokens.IDENT,Tokens.STAR])&&(t+=e.token().value),e.mustMatch(Tokens.PIPE +),t+="|";return t.length?t:null},_universal:function(){var e=this._tokenStream,t="" +,n;return n=this._namespace_prefix(),n&&(t+=n),e.match(Tokens.STAR)&&(t+="*"),t. +length?t:null},_attrib:function(){var e=this._tokenStream,t=null,n,r;return e.match +(Tokens.LBRACKET)?(r=e.token(),t=r.value,t+=this._readWhitespace(),n=this._namespace_prefix +(),n&&(t+=n),e.mustMatch(Tokens.IDENT),t+=e.token().value,t+=this._readWhitespace +(),e.match([Tokens.PREFIXMATCH,Tokens.SUFFIXMATCH,Tokens.SUBSTRINGMATCH,Tokens.EQUALS +,Tokens.INCLUDES,Tokens.DASHMATCH])&&(t+=e.token().value,t+=this._readWhitespace +(),e.mustMatch([Tokens.IDENT,Tokens.STRING]),t+=e.token().value,t+=this._readWhitespace +()),e.mustMatch(Tokens.RBRACKET),new SelectorSubPart(t+"]","attribute",r.startLine +,r.startCol)):null},_pseudo:function(){var e=this._tokenStream,t=null,n=":",r,i; +return e.match(Tokens.COLON)&&(e.match(Tokens.COLON)&&(n+=":"),e.match(Tokens.IDENT +)?(t=e.token().value,r=e.token().startLine,i=e.token().startCol-n.length):e.peek +()==Tokens.FUNCTION&&(r=e.LT(1).startLine,i=e.LT(1).startCol-n.length,t=this._functional_pseudo +()),t&&(t=new SelectorSubPart(n+t,"pseudo",r,i))),t},_functional_pseudo:function( +){var e=this._tokenStream,t=null;return e.match(Tokens.FUNCTION)&&(t=e.token().value +,t+=this._readWhitespace(),t+=this._expression(),e.mustMatch(Tokens.RPAREN),t+=")" +),t},_expression:function(){var e=this._tokenStream,t="";while(e.match([Tokens.PLUS +,Tokens.MINUS,Tokens.DIMENSION,Tokens.NUMBER,Tokens.STRING,Tokens.IDENT,Tokens.LENGTH +,Tokens.FREQ,Tokens.ANGLE,Tokens.TIME,Tokens.RESOLUTION,Tokens.SLASH]))t+=e.token +().value,t+=this._readWhitespace();return t.length?t:null},_negation:function(){ +var e=this._tokenStream,t,n,r="",i,s=null;return e.match(Tokens.NOT)&&(r=e.token +().value,t=e.token().startLine,n=e.token().startCol,r+=this._readWhitespace(),i= +this._negation_arg(),r+=i,r+=this._readWhitespace(),e.match(Tokens.RPAREN),r+=e. +token().value,s=new SelectorSubPart(r,"not",t,n),s.args.push(i)),s},_negation_arg +:function(){var e=this._tokenStream,t=[this._type_selector,this._universal,function( +){return e.match(Tokens.HASH)?new SelectorSubPart(e.token().value,"id",e.token() +.startLine,e.token().startCol):null},this._class,this._attrib,this._pseudo],n=null +,r=0,i=t.length,s,o,u,a;o=e.LT(1).startLine,u=e.LT(1).startCol;while(r0?new PropertyValue(n,n[0].line,n[0].col):null},_term:function( +){var e=this._tokenStream,t=null,n=null,r,i,s;return t=this._unary_operator(),t!== +null&&(i=e.token().startLine,s=e.token().startCol),e.peek()==Tokens.IE_FUNCTION&& +this.options.ieFilters?(n=this._ie_function(),t===null&&(i=e.token().startLine,s= +e.token().startCol)):e.match([Tokens.NUMBER,Tokens.PERCENTAGE,Tokens.LENGTH,Tokens +.ANGLE,Tokens.TIME,Tokens.FREQ,Tokens.STRING,Tokens.IDENT,Tokens.URI,Tokens.UNICODE_RANGE +])?(n=e.token().value,t===null&&(i=e.token().startLine,s=e.token().startCol),this +._readWhitespace()):(r=this._hexcolor(),r===null?(t===null&&(i=e.LT(1).startLine +,s=e.LT(1).startCol),n===null&&(e.LA(3)==Tokens.EQUALS&&this.options.ieFilters?n= +this._ie_function():n=this._function())):(n=r.value,t===null&&(i=r.startLine,s=r +.startCol))),n!==null?new PropertyValuePart(t!==null?t+n:n,i,s):null},_function: +function(){var e=this._tokenStream,t=null,n=null,r;if(e.match(Tokens.FUNCTION)){ +t=e.token().value,this._readWhitespace(),n=this._expr(!0),t+=n;if(this.options.ieFilters&& +e.peek()==Tokens.EQUALS)do{this._readWhitespace()&&(t+=e.token().value),e.LA(0)== +Tokens.COMMA&&(t+=e.token().value),e.match(Tokens.IDENT),t+=e.token().value,e.match +(Tokens.EQUALS),t+=e.token().value,r=e.peek();while(r!=Tokens.COMMA&&r!=Tokens.S&& +r!=Tokens.RPAREN)e.get(),t+=e.token().value,r=e.peek()}while(e.match([Tokens.COMMA +,Tokens.S]));e.match(Tokens.RPAREN),t+=")",this._readWhitespace()}return t},_ie_function +:function(){var e=this._tokenStream,t=null,n=null,r;if(e.match([Tokens.IE_FUNCTION +,Tokens.FUNCTION])){t=e.token().value;do{this._readWhitespace()&&(t+=e.token().value +),e.LA(0)==Tokens.COMMA&&(t+=e.token().value),e.match(Tokens.IDENT),t+=e.token() +.value,e.match(Tokens.EQUALS),t+=e.token().value,r=e.peek();while(r!=Tokens.COMMA&& +r!=Tokens.S&&r!=Tokens.RPAREN)e.get(),t+=e.token().value,r=e.peek()}while(e.match +([Tokens.COMMA,Tokens.S]));e.match(Tokens.RPAREN),t+=")",this._readWhitespace()} +return t},_hexcolor:function(){var e=this._tokenStream,t=null,n;if(e.match(Tokens +.HASH)){t=e.token(),n=t.value;if(!/#[a-f0-9]{3,6}/i.test(n))throw new SyntaxError +("Expected a hex color but found '"+n+"' at line "+t.startLine+", col "+t.startCol+"." +,t.startLine,t.startCol);this._readWhitespace()}return t},_keyframes:function(){ +var e=this._tokenStream,t,n,r,i="";e.mustMatch(Tokens.KEYFRAMES_SYM),t=e.token() +,/^@\-([^\-]+)\-/.test(t.value)&&(i=RegExp.$1),this._readWhitespace(),r=this._keyframe_name +(),this._readWhitespace(),e.mustMatch(Tokens.LBRACE),this.fire({type:"startkeyframes" +,name:r,prefix:i,line:t.startLine,col:t.startCol}),this._readWhitespace(),n=e.peek +();while(n==Tokens.IDENT||n==Tokens.PERCENTAGE)this._keyframe_rule(),this._readWhitespace +(),n=e.peek();this.fire({type:"endkeyframes",name:r,prefix:i,line:t.startLine,col +:t.startCol}),this._readWhitespace(),e.mustMatch(Tokens.RBRACE)},_keyframe_name: +function(){var e=this._tokenStream,t;return e.mustMatch([Tokens.IDENT,Tokens.STRING +]),SyntaxUnit.fromToken(e.token())},_keyframe_rule:function(){var e=this._tokenStream +,t,n=this._key_list();this.fire({type:"startkeyframerule",keys:n,line:n[0].line, +col:n[0].col}),this._readDeclarations(!0),this.fire({type:"endkeyframerule",keys +:n,line:n[0].line,col:n[0].col})},_key_list:function(){var e=this._tokenStream,t +,n,r=[];r.push(this._key()),this._readWhitespace();while(e.match(Tokens.COMMA))this +._readWhitespace(),r.push(this._key()),this._readWhitespace();return r},_key:function( +){var e=this._tokenStream,t;if(e.match(Tokens.PERCENTAGE))return SyntaxUnit.fromToken +(e.token());if(e.match(Tokens.IDENT)){t=e.token();if(/from|to/i.test(t.value))return SyntaxUnit +.fromToken(t);e.unget()}this._unexpectedToken(e.LT(1))},_skipCruft:function(){while( +this._tokenStream.match([Tokens.S,Tokens.CDO,Tokens.CDC]));},_readDeclarations:function( +e,t){var n=this._tokenStream,r;this._readWhitespace(),e&&n.mustMatch(Tokens.LBRACE +),this._readWhitespace();try{for(;;){if(!(n.match(Tokens.SEMICOLON)||t&&this._margin +())){if(!this._declaration())break;if(!n.match(Tokens.SEMICOLON))break}this._readWhitespace +()}n.mustMatch(Tokens.RBRACE),this._readWhitespace()}catch(i){if(!(i instanceof +SyntaxError&&!this.options.strict))throw i;this.fire({type:"error",error:i,message +:i.message,line:i.line,col:i.col}),r=n.advance([Tokens.SEMICOLON,Tokens.RBRACE]) +;if(r==Tokens.SEMICOLON)this._readDeclarations(!1,t);else if(r!=Tokens.RBRACE)throw i +}},_readWhitespace:function(){var e=this._tokenStream,t="";while(e.match(Tokens. +S))t+=e.token().value;return t},_unexpectedToken:function(e){throw new SyntaxError +("Unexpected token '"+e.value+"' at line "+e.startLine+", col "+e.startCol+".",e +.startLine,e.startCol)},_verifyEnd:function(){this._tokenStream.LA(1)!=Tokens.EOF&& +this._unexpectedToken(this._tokenStream.LT(1))},_validateProperty:function(e,t){ +Validation.validate(e,t)},parse:function(e){this._tokenStream=new TokenStream(e, +Tokens),this._stylesheet()},parseStyleSheet:function(e){return this.parse(e)},parseMediaQuery +:function(e){this._tokenStream=new TokenStream(e,Tokens);var t=this._media_query +();return this._verifyEnd(),t},parsePropertyValue:function(e){this._tokenStream=new +TokenStream(e,Tokens),this._readWhitespace();var t=this._expr();return this._readWhitespace +(),this._verifyEnd(),t},parseRule:function(e){this._tokenStream=new TokenStream( +e,Tokens),this._readWhitespace();var t=this._ruleset();return this._readWhitespace +(),this._verifyEnd(),t},parseSelector:function(e){this._tokenStream=new TokenStream +(e,Tokens),this._readWhitespace();var t=this._selector();return this._readWhitespace +(),this._verifyEnd(),t},parseStyleAttribute:function(e){e+="}",this._tokenStream=new +TokenStream(e,Tokens),this._readDeclarations()}};for(t in n)n.hasOwnProperty(t)&& +(e[t]=n[t]);return e}();var Properties={"alignment-adjust":"auto | baseline | before-edge | text-before-edge | middle | central | after-edge | text-after-edge | ideographic | alphabetic | hanging | mathematical | | " +,"alignment-baseline":"baseline | use-script | before-edge | text-before-edge | after-edge | text-after-edge | central | middle | ideographic | alphabetic | hanging | mathematical" +,animation:1,"animation-delay":{multi:"
\n\ +'; + + + +// https://github.com/swagger-api/swagger-ui/blob/v2.1.3/src/main/template/param.handlebars +local.templateUiParam = '\ +\n\ + {{name}}\n\ + {{#if description}}\n\ +
{{description htmlSafe}}\n\ + {{/if description}}\n\ +
\n\ +{{type2}}{{#if format2}}
({{format2}}){{/if format2}}
\n\ +\n\ + {{#if isTextarea}}\n\ + \n\ + {{/if isTextarea}}\n\ + {{#if isFile}}\n\ + \n\ + {{/if isFile}}\n\ + {{#if isSelect}}\n\ + \n\ + {{/if isSelect}}\n\ + {{#if isInputText}}\n\ + \n\ + {{/if isInputText}}\n\ +\n\ +{{#if schemaText}}
{{schemaText}}
{{/if schemaText}}
\n\ +'; + + + +// https://github.com/swagger-api/swagger-ui/blob/v2.1.3/src/main/template/resource.handlebars +local.templateUiResource = '\ +\n\ +
\n\ + {{name}} :\n\ + {{#if description}}\n\ + {{description htmlSafe}}\n\ + {{/if description}}\n\ + \n\ + Show\n\ + Expand / Collapse Operations\n\ + Datatable\n\ +
\n\ + \n\ +\n\ +'; + + + +local.templateUiResponseAjax = '\ +

Curl Request

\n\ +{{#if errorValidate}}\n\ +
n/a
\n\ +{{#unless errorValidate}}\n\ +
{{curl htmlSafe}}
\n\ +{{/if errorValidate}}\n\ +

Response Code

\n\ +
{{statusCode}}
\n\ +

Response Headers

\n\ +{{#if errorValidate}}\n\ +
n/a
\n\ +{{#unless errorValidate}}\n\ +
{{responseHeaders htmlSafe}}
\n\ +{{/if errorValidate}}\n\ +

Response Body

\n\ +{{responseBody}}\n\ +'; +/* jslint-ignore-end */ + local.swaggerSchemaJson = local.jsonCopy(local.objectSetOverride( + JSON.parse(local.assetsDict['/assets.swgg.json-schema.json']), + JSON.parse(local.assetsDict['/assets.swgg.schema.json']), + 2 + )); + }()); + + + + // run shared js-env code - function + (function () { + local.apiAjax = function (self, options, onError) { + /* + * this function will send a swagger-api ajax-request with the pathObject self + */ + var isMultipartFormData, tmp; + isMultipartFormData = (self.consumes && self.consumes[0]) === 'multipart/form-data'; + local.objectSetDefault(options, { data: '', paramDict: {}, url: '' }); + // try to validate paramDict + local.tryCatchOnError(function () { + local.validateByParamDefList({ + // normalize paramDict + data: local.normalizeParamDictSwagger( + local.jsonCopy(options.paramDict), + self + ), + dataReadonlyRemove: options.paramDict, + key: self.operationId, + paramDefList: self.parameters + }); + }, function (error) { + options.errorValidate = error; + onError(error); + }); + if (options.errorValidate) { + return; + } + // init options-defaults + local.objectSetDefault(options, { + inForm: isMultipartFormData + ? new local.FormData() + : '', + inHeader: {}, + inPath: self._path, + inQuery: '', + headers: {}, + method: self._method, + responseType: self.produces && + self.produces[0].indexOf('application/octet-stream') === 0 + ? 'arraybuffer' + : '' + }); + // init paramDict + self.parameters.forEach(function (paramDef) { + tmp = options.paramDict[paramDef.name]; + if (tmp === undefined) { + return; + } + // serialize array + if (paramDef.type === 'array' && paramDef.in !== 'body') { + if (typeof tmp !== 'string') { + switch (paramDef.collectionFormat) { + case 'json': + tmp = JSON.stringify(tmp); + break; + case 'multi': + tmp.forEach(function (value) { + options[paramDef.in === 'formData' + ? 'inForm' + : 'inQuery'] += '&' + + encodeURIComponent(paramDef.name) + '=' + + encodeURIComponent(paramDef.items.type === 'string' + ? value + : JSON.stringify(value)); + }); + return; + case 'pipes': + tmp = tmp.join('|'); + break; + case 'ssv': + tmp = tmp.join(' '); + break; + case 'tsv': + tmp = tmp.join('\t'); + break; + // default to csv + default: + tmp = tmp.join(','); + } + } + } else if (!(paramDef.type === 'string' || tmp instanceof local.Blob)) { + tmp = JSON.stringify(tmp); + } + switch (paramDef.in) { + case 'body': + options.inBody = tmp; + break; + case 'formData': + if (isMultipartFormData) { + options.inForm.append(paramDef.name, tmp, tmp && tmp.name); + break; + } + options.inForm += '&' + encodeURIComponent(paramDef.name) + '=' + + encodeURIComponent(tmp); + break; + case 'header': + options.inHeader[encodeURIComponent(paramDef.name.toLowerCase())] = tmp; + break; + case 'query': + options.inQuery += '&' + encodeURIComponent(paramDef.name) + '=' + + encodeURIComponent(tmp); + break; + case 'path': + options.inPath = options.inPath + .replace('{' + paramDef.name + '}', encodeURIComponent(tmp)); + break; + } + }); + // init data + options.data = options.inBody || (isMultipartFormData + ? options.inForm + : options.inForm.slice(1)); + // init headers + local.objectSetOverride(options.headers, options.inHeader); + // init headers - Content-Type + if (options.inForm) { + options.headers['Content-Type'] = isMultipartFormData + ? 'multipart/form-data' + : 'application/x-www-form-urlencoded'; + } + // init headers - Authorization + options.jwtEncrypted = options.jwtEncrypted || local.userJwtEncrypted; + if (options.jwtEncrypted) { + options.headers.Authorization = options.headers.Authorization || + 'Bearer ' + options.jwtEncrypted; + } + // init url + options.url = (local.urlBaseGet() + options.inPath + '?' + options.inQuery.slice(1)) + .replace((/\?$/), ''); + if (!(options.headers['Content-Type'] || options.headers['content-type'])) { + options.headers['content-type'] = 'application/json; charset=UTF-8'; + } + // send ajax-request + return local.ajax(options, function (error, xhr) { + // try to init responseJson + local.tryCatchOnError(function () { + xhr.responseJson = JSON.parse(xhr.responseText); + }, local.nop); + // init userJwtEncrypted + if (xhr.getResponseHeader('swgg-jwt-encrypted')) { + local.userJwtEncrypted = xhr.getResponseHeader('swgg-jwt-encrypted'); + } + onError(error, xhr); + }); + }; + + local.apiDictUpdate = function (options) { + /* + * this function will update the swagger-api dict of api-calls + */ + var tmp; + options = options || {}; + // init apiDict + local.apiDict = local.apiDict || {}; + // init swaggerJson + local.swaggerJson = local.swaggerJson || { + "basePath": "/api/v0", + "definitions": { + "BuiltinFile": { + "properties": { + "_id": { + "readOnly": true, + "type": "string" + }, + "_timeCreated": { + "format": "date-time", + "readOnly": true, + "type": "string" + }, + "_timeUpdated": { + "format": "date-time", + "readOnly": true, + "type": "string" + }, + "fileBlob": { + "format": "byte", + "type": "string" + }, + "fileContentType": { + "type": "string" + }, + "fileDescription": { + "type": "string" + }, + "fileFilename": { + "type": "string" + }, + "fileInputName": { + "type": "string" + }, + "fileSize": { + "minimum": 0, + "type": "integer" + }, + "fileUrl": { + "type": "string" + }, + "id": { + "type": "string" + } + } + }, + "BuiltinJsonapiResponse": { + "properties": { + "data": { + "items": { + "type": "object" + }, + "type": "array" + }, + "errors": { + "items": { + "type": "object" + }, + "type": "array" + }, + "meta": { + "type": "object" + } + } + }, + "BuiltinUser": { + "properties": { + "_id": { + "readOnly": true, + "type": "string" + }, + "_timeCreated": { + "format": "date-time", + "readOnly": true, + "type": "string" + }, + "_timeUpdated": { + "format": "date-time", + "readOnly": true, + "type": "string" + }, + "id": { + "type": "string" + }, + "jwtEncrypted": { + "type": "string" + }, + "password": { + "format": "password", + "type": "string" + }, + "username": { + "type": "string" + } + } + } + }, + "info": { + "description": "demo of swagger-ui server", + "title": "swgg api", + "version": "0" + }, + "paths": {}, + "securityDefinitions": {}, + "swagger": "2.0", + "tags": [] + }; + // save tags + tmp = {}; + [local.swaggerJson.tags, options.tags || []].forEach(function (tagList) { + tagList.forEach(function (tag) { + local.objectSetOverride(tmp, local.objectLiteralize({ + '$[]': [tag.name, tag] + })); + }, 2); + }); + tmp = Object.keys(tmp).sort().map(function (key) { + return tmp[key]; + }); + // merge options into swaggerJson + options = local.objectSetOverride(local.swaggerJson, options, 10); + // restore tags + local.swaggerJson.tags = tmp; + Object.keys(options.definitions).forEach(function (schemaName) { + // normalize definition + options.definitions[schemaName] = + local.schemaNormalizeAndCopy(options.definitions[schemaName]); + }); + // init apiDict from paths + Object.keys(options.paths).forEach(function (path) { + Object.keys(options.paths[path]).forEach(function (method) { + var self; + self = options.paths[path][method]; + self._method = method; + self._path = path; + local.objectSetOverride(local.apiDict, local.objectLiteralize({ + '$[]': [self.tags[0] + ' ' + self.operationId, self] + }), 2); + }); + }); + // init apiDict from x-swgg-apiDict + Object.keys(options['x-swgg-apiDict'] || {}).forEach(function (key) { + // init self + local.objectSetOverride(local.apiDict, local.objectLiteralize({ + '$[]': [key, local.jsonCopy(options['x-swgg-apiDict'][key])] + }), Infinity); + }); + // init apiDict + Object.keys(local.apiDict).forEach(function (key) { + var self; + self = local.apiDict[key]; + if (key === self._keyPath) { + return; + } + // init _operationId + self._operationId = self._operationId || key.split(' ')[1]; + // init _fileUploadNumber + self._fileUploadNumber = 1; + self._operationId.replace( + (/^fileUploadManyByForm\.(\d+)/), + function (match0, match1) { + // jslint-hack - nop + local.nop(match0); + self._fileUploadNumber = Number(match1); + } + ); + // init _idAlias and _idField + tmp = local.idFieldInit({ operationId: self._operationId }); + self._idAlias = tmp.idAlias; + self._idField = tmp.idField; + // init _tags0 + self._tags0 = key.split(' ')[0]; + // init templateApiDict + if (local.templateApiDict[self._operationId.split('.')[0]]) { + local.objectSetDefault( + self, + JSON.parse(local.templateApiDict[self._operationId.split('.')[0]] + .replace((/\{\{_fileUploadNumber\}\}/g), self._fileUploadNumber) + .replace((/\{\{_idAlias\}\}/g), self._idAlias) + .replace((/\{\{_idField\}\}/g), self._idField) + .replace((/\{\{_schemaName\}\}/g), self._schemaName) + .replace((/\{\{_tags0\}\}/g), self._tags0) + .replace((/\{\{operationId\}\}/g), self._operationId)) + ); + } + // init default + local.objectSetDefault(self, { + _keyOperationId: key, + operationId: self._operationId, + parameters: [], + responses: { + 200: { + description: 'ok - ' + + 'http://jsonapi.org/format/#document-top-level', + schema: { $ref: '#/definitions/BuiltinJsonapiResponse' } + } + }, + tags: [self._tags0] + }); + // init _method + self._method = self._method.toUpperCase(); + // init _keyPath + self._keyPath = self._method + ' ' + self._path.replace((/\{.*?\}/g), ''); + // init _idField.format and _idField.type + if (self._schemaName) { + self.parameters.forEach(function (param) { + if (param.name === self._idField) { + param.format = options.definitions[self._schemaName] + .properties[self._idAlias].format; + param.type = options.definitions[self._schemaName] + .properties[self._idAlias].type; + } + }); + } + switch (self.operationId.split('.')[0]) { + // add extra file-upload forms + case 'fileUploadManyByForm': + for (tmp = 1; tmp <= self._fileUploadNumber; tmp += 1) { + self.parameters[tmp] = local.jsonCopy(self.parameters[1]); + self.parameters[tmp].name = 'file' + tmp; + } + break; + } + // update apiDict + self = local.apiDict[key] = local.apiDict[self._keyPath] = local.jsonCopy(self); + // init _ajax + self._ajax = function (options, onError) { + return local.apiAjax(self, options, onError); + }; + // remove underscored keys from self + tmp = local.jsonCopy(self); + Object.keys(tmp).forEach(function (key) { + if (key[0] === '_') { + delete tmp[key]; + } + }); + // update paths + local.objectSetOverride(options, local.objectLiteralize({ + paths: { '$[]': [self._path, { '$[]': [self._method.toLowerCase(), tmp] }] } + }), 3); + }); + // normalize swaggerJson + local.swaggerJson = JSON.parse(local.jsonStringifyOrdered(options)); + // update $npm_config_swagger_basePath + local.env.npm_config_swagger_basePath = local.swaggerJson.basePath; + // try to validate swaggerJson + local.tryCatchOnError(function () { + local.validateBySwagger(local.swaggerJson); + }, local.onErrorDefault); + }; + + local.dbFieldRandomCreate = function (options) { + /* + * this function will create a random dbField from options.propDef + */ + var ii, max, min, propDef, tmp; + propDef = options.propDef; + if (propDef.readOnly) { + return; + } + if (propDef.enum) { + tmp = options.modeNotRandom + ? propDef.enum[0] + : local.listGetElementRandom(propDef.enum); + return propDef.type === 'array' + ? [tmp] + : tmp; + } + // http://json-schema.org/latest/json-schema-validation.html#anchor13 + // 5.1. Validation keywords for numeric instances (number and integer) + max = isFinite(propDef.maximum) + ? propDef.maximum + : 999; + min = isFinite(propDef.maximum) + ? propDef.minimum + : 0; + switch (propDef.type) { + case 'array': + tmp = []; + // http://json-schema.org/latest/json-schema-validation.html#anchor36 + // 5.3. Validation keywords for arrays + for (ii = 0; ii < (propDef.minItems || 0); ii += 1) { + tmp.push(null); + } + break; + case 'boolean': + tmp = options.modeNotRandom + ? false + : Math.random() <= 0.5 + ? false + : true; + break; + case 'integer': + if (propDef.exclusiveMaximum) { + max -= 1; + } + if (propDef.exclusiveMinimum) { + min += 1; + } + min = Math.min(min, max); + tmp = options.modeNotRandom + ? 0 + : Math.random(); + tmp = Math.floor(min + tmp * (max - min)); + break; + case 'object': + tmp = {}; + // http://json-schema.org/latest/json-schema-validation.html#anchor53 + // 5.4. Validation keywords for objects + for (ii = 0; ii < (propDef.minProperties || 0); ii += 1) { + tmp['property' + ii] = null; + } + break; + case 'number': + if (propDef.exclusiveMinimum) { + min = min < 0 + ? min * 0.99999 + : min * 1.00001 + 0.00001; + } + if (propDef.exclusiveMaximum) { + max = max > 0 + ? max * 0.99999 + : max * 1.00001 - 0.00001; + } + min = Math.min(min, max); + tmp = options.modeNotRandom + ? 0 + : Math.random(); + tmp = min + tmp * (max - min); + break; + case 'string': + tmp = options.modeNotRandom + ? 'abcd1234' + : ((1 + Math.random()) * 0x10000000000000).toString(36).slice(1); + switch (propDef.format) { + case 'byte': + tmp = local.base64FromString(tmp); + break; + case 'date': + case 'date-time': + tmp = new Date().toISOString(); + break; + case 'email': + tmp = tmp + '@random.com'; + break; + case 'json': + tmp = JSON.stringify({ random: tmp }); + break; + case 'phone': + tmp = options.modeNotRandom + ? '+123 (1234) 1234-1234' + : '+' + Math.random().toString().slice(-3) + + ' (' + Math.random().toString().slice(-4) + ') ' + + Math.random().toString().slice(-4) + '-' + + Math.random().toString().slice(-4); + break; + } + // http://json-schema.org/latest/json-schema-validation.html#anchor25 + // 5.2. Validation keywords for strings + while (tmp.length < (propDef.minLength || 0)) { + tmp += tmp; + } + tmp = tmp.slice(0, propDef.maxLength || Infinity); + break; + } + // http://json-schema.org/latest/json-schema-validation.html#anchor13 + // 5.1. Validation keywords for numeric instances (number and integer) + if (propDef.multipleOf) { + tmp = propDef.multipleOf * Math.floor(tmp / propDef.multipleOf); + if (tmp < min) { + tmp += propDef.multipleOf; + } + } + return tmp; + }; + + local.dbRowListRandomCreate = function (options) { + /* + * this function will create a dbRowList of options.length random dbRow's + */ + local.objectSetDefault(options, { dbRowList: [] }); + for (options.ii = 0; options.ii < options.length; options.ii += 1) { + options.dbRowList.push(local.dbRowRandomCreate(options)); + } + return options.dbRowList; + }; + + local.dbRowRandomCreate = function (options) { + /* + * this function will create a random dbRow from options.properties + */ + var dbRow, tmp; + dbRow = {}; + Object.keys(options.properties).forEach(function (key) { + // try to validate data + local.tryCatchOnError(function () { + tmp = local.dbFieldRandomCreate({ + modeNotRandom: options.modeNotRandom, + propDef: options.properties[key] + }); + local.validateByPropDef({ + data: tmp, + key: options.properties[key].name, + schema: options.properties[key] + }); + dbRow[key] = tmp; + }, local.nop); + }); + return local.jsonCopy(local.objectSetOverride(dbRow, options.override(options))); + }; + + local.idDomElementCreate = function (seed) { + /* + * this function will create a unique dom-element id from the seed, + * that is both dom-selector and url friendly + */ + var id, ii; + id = encodeURIComponent(seed).replace((/\W/g), '_'); + for (ii = 2; local.idDomElementDict[id]; ii += 1) { + id = encodeURIComponent(seed + '_' + ii).replace((/\W/g), '_'); + } + local.idDomElementDict[id] = true; + return id; + }; + + local.idFieldInit = function (options) { + /* + * this function will init options.idAlias, options.idField, and options.queryById + */ + var idAlias, idField; + // init idField + options.idAlias = options.operationId.split('.'); + idField = options.idField = options.idAlias[1] || 'id'; + // init idAlias + idAlias = options.idAlias = options.idAlias[2] || options.idField; + // invert queryById + if (options.modeQueryByIdInvert) { + idAlias = options.idField; + idField = options.idAlias; + } + // init queryById + options.idValue = (options.data && options.data[idAlias]) || options.idValue; + options.queryById = {}; + options.queryById[idField] = options.idValue; + return options; + }; + + local.middlewareBodyParse = function (request, response, nextMiddleware) { + /* + * this function will run the middleware that will parse request.bodyRaw + */ + var ii, jj, options; + // jslint-hack + local.nop(response); + // if request is already parsed, then goto nextMiddleware + if (!local.isNullOrUndefined(request.swgg.bodyParsed)) { + nextMiddleware(); + return; + } + switch (String(request.headers['content-type']).split(';')[0]) { + // parse application/x-www-form-urlencoded, e.g. + // aa=hello%20world&bb=bye%20world + case 'application/x-www-form-urlencoded': + request.swgg.bodyParsed = local.bufferToString(request.bodyRaw); + request.swgg.bodyParsed = + local.urlParse('?' + request.swgg.bodyParsed, true).query; + break; + /* + * https://tools.ietf.org/html/rfc7578 + * parse multipart/form-data, e.g. + * --Boundary\r\n + * Content-Disposition: form-data; name="key"\r\n + * \r\n + * value\r\n + * --Boundary\r\n + * Content-Disposition: form-data; name="input1"; filename="file1.png"\r\n + * Content-Type: image/jpeg\r\n + * \r\n + * \r\n + * --Boundary\r\n + * Content-Disposition: form-data; name="input2"; filename="file2.png"\r\n + * Content-Type: image/jpeg\r\n + * \r\n + * \r\n + * --Boundary--\r\n + */ + case 'multipart/form-data': + request.swgg.isMultipartFormData = true; + request.swgg.bodyParsed = {}; + request.swgg.bodyMeta = {}; + options = {}; + options.crlf = local.bufferCreate([0x0d, 0x0a]); + // init boundary + ii = 0; + jj = local.bufferIndexOfSubBuffer(request.bodyRaw, options.crlf, ii); + if (jj <= 0) { + break; + } + options.boundary = local.bufferConcat([ + options.crlf, + request.bodyRaw.slice(ii, jj) + ]); + ii = jj + 2; + while (true) { + jj = local.bufferIndexOfSubBuffer( + request.bodyRaw, + options.boundary, + ii + ); + if (jj < 0) { + break; + } + options.header = local.bufferToString(request.bodyRaw.slice(ii, ii + 1024)) + .split('\r\n').slice(0, 2).join('\r\n'); + options.contentType = (/^content-type:(.*)/im).exec(options.header); + options.contentType = options.contentType && options.contentType[1].trim(); + options.filename = (/^content-disposition:.*?\bfilename="([^"]+)/im) + .exec(options.header); + options.filename = options.filename && options.filename[1]; + options.name = (/^content-disposition:.*?\bname="([^"]+)/im) + .exec(options.header); + options.name = options.name && options.name[1]; + ii = local.bufferIndexOfSubBuffer( + request.bodyRaw, + [0x0d, 0x0a, 0x0d, 0x0a], + ii + 2 + ) + 4; + options.data = request.bodyRaw.slice(ii, jj); + request.swgg.bodyParsed[options.name] = options.data; + request.swgg.bodyMeta[options.name] = { + contentType: options.contentType, + filename: options.filename, + name: options.name + }; + ii = jj + options.boundary.length + 2; + } + break; + default: + request.swgg.bodyParsed = local.bufferToString(request.bodyRaw); + // try to JSON.parse the string + local.tryCatchOnError(function () { + request.swgg.bodyParsed = JSON.parse(request.swgg.bodyParsed); + }, local.nop); + } + nextMiddleware(); + }; + + local.middlewareCrudBuiltin = function (request, response, nextMiddleware) { + /* + * this function will run the middleware that will + * run the builtin crud-operations backed by db-lite + */ + var crud, onParallel, options, tmp, user; + options = {}; + local.onNext(options, function (error, data, meta) { + switch (options.modeNext) { + case 1: + crud = request.swgg.crud; + user = request.swgg.user; + switch (crud.operationId.split('.')[0]) { + case 'crudCountManyByQuery': + crud.dbTable.crudCountManyByQuery(crud.queryWhere, options.onNext); + break; + case 'crudSetManyById': + crud.dbTable.crudSetManyById(crud.body, options.onNext); + break; + case 'crudSetOneById': + // replace idField with idAlias in body + delete crud.body.id; + delete crud.body[crud.idField]; + crud.body[crud.idAlias] = crud.data[crud.idField]; + crud.dbTable.crudSetOneById(crud.body, options.onNext); + break; + case 'crudUpdateOneById': + // replace idField with idAlias in body + delete crud.body.id; + delete crud.body[crud.idField]; + crud.body[crud.idAlias] = crud.data[crud.idField]; + crud.dbTable.crudUpdateOneById(crud.body, options.onNext); + break; + // coverage-hack - test error handling-behavior + case 'crudErrorDelete': + case 'crudErrorGet': + case 'crudErrorHead': + case 'crudErrorOptions': + case 'crudErrorPatch': + case 'crudErrorPost': + case 'crudErrorPut': + options.onNext(local.errorDefault); + break; + case 'crudGetManyByQuery': + onParallel = local.onParallel(options.onNext); + onParallel.counter += 1; + crud.dbTable.crudGetManyByQuery({ + fieldList: crud.queryFields, + limit: crud.queryLimit, + query: crud.queryWhere, + skip: crud.querySkip, + sort: crud.querySort + }, function (error, data) { + crud.queryData = data; + onParallel(error); + }); + onParallel.counter += 1; + crud.dbTable.crudCountAll(function (error, data) { + crud.paginationCountTotal = data; + onParallel(error); + }); + break; + case 'crudGetOneById': + crud.dbTable.crudGetOneById(crud.queryById, options.onNext); + break; + case 'crudGetOneByQuery': + crud.dbTable.crudGetOneByQuery({ + query: crud.queryWhere + }, options.onNext); + break; + case 'crudNullDelete': + case 'crudNullGet': + case 'crudNullHead': + case 'crudNullOptions': + case 'crudNullPatch': + case 'crudNullPost': + case 'crudNullPut': + options.onNext(); + break; + case 'crudRemoveManyByQuery': + crud.dbTable.crudRemoveManyByQuery(crud.queryWhere, options.onNext); + break; + case 'crudRemoveOneById': + crud.dbTable.crudRemoveOneById(crud.queryById, options.onNext); + break; + case 'fileGetOneById': + local.dbTableFile = local.db.dbTableCreateOne({ name: 'File' }); + crud.dbTable.crudGetOneById(crud.queryById, options.onNext); + break; + case 'fileUploadManyByForm': + local.dbTableFile = local.db.dbTableCreateOne({ name: 'File' }); + request.swgg.paramDict = {}; + Object.keys(request.swgg.bodyMeta).forEach(function (key) { + if (typeof request.swgg.bodyMeta[key].filename !== 'string') { + request.swgg.paramDict[key] = + local.bufferToString(request.swgg.bodyParsed[key]); + } + }); + crud.body = Object.keys(request.swgg.bodyMeta) + .filter(function (key) { + return typeof request.swgg.bodyMeta[key].filename === 'string'; + }) + .map(function (key) { + tmp = local.jsonCopy(request.swgg.paramDict); + local.objectSetOverride(tmp, { + fileBlob: + local.base64FromBuffer(request.swgg.bodyParsed[key]), + fileContentType: request.swgg.bodyMeta[key].contentType, + fileFilename: request.swgg.bodyMeta[key].filename, + fileInputName: request.swgg.bodyMeta[key].name, + fileSize: request.swgg.bodyParsed[key].length, + fileUrl: local.swaggerJson.basePath + + '/' + request.swgg.pathObject._tags0 + + '/fileGetOneById/' + tmp.id + }); + return tmp; + }); + local.dbTableFile.crudSetManyById(crud.body, options.onNext); + break; + case 'userLoginByPassword': + case 'userLogout': + // respond with 401 Unauthorized + if (!user.isAuthenticated) { + local.serverRespondHeadSet(request, response, 401, {}); + request.swgg.crud.endArgList = [request, response]; + options.modeNext = Infinity; + options.onNext(); + return; + } + options.onNext(); + break; + default: + options.modeNext = Infinity; + options.onNext(); + } + break; + case 2: + switch (crud.operationId.split('.')[0]) { + case 'crudSetOneById': + case 'crudUpdateOneById': + options.onNext(null, data); + break; + case 'crudGetManyByQuery': + options.onNext(null, crud.queryData, { + paginationCountTotal: crud.paginationCountTotal + }); + break; + case 'fileUploadManyByForm': + options.onNext(null, data.map(function (element) { + delete element.fileBlob; + return element; + })); + break; + case 'userLoginByPassword': + options.onNext(null, { jwtEncrypted: user.jwtEncrypted }); + break; + case 'userLogout': + crud.dbTable.crudUpdateOneById({ + jwtEncrypted: null, + username: user.username + }, options.onNext); + break; + default: + options.onNext(null, data, meta); + } + break; + case 3: + switch (crud.operationId.split('.')[0]) { + case 'fileGetOneById': + if (!data) { + local.serverRespondDefault(request, response, 404); + return; + } + local.serverRespondHeadSet(request, response, null, { + 'Content-Type': data.fileContentType + }); + response.end(local.base64ToBuffer(data.fileBlob)); + break; + case 'userLogout': + options.onNext(); + break; + default: + options.onNext(null, data, meta); + } + break; + case 4: + request.swgg.crud.endArgList = [request, response, null, data, meta]; + options.onNext(); + break; + default: + nextMiddleware(error); + } + }); + options.modeNext = 0; + options.onNext(); + }; + + local.middlewareCrudEnd = function (request, response, nextMiddleware) { + /* + * this function will run the middleware that will end the builtin crud-operations + */ + // jslint-hack + local.nop(response); + if (request.swgg.crud.endArgList) { + local.serverRespondJsonapi.apply(null, request.swgg.crud.endArgList); + return; + } + nextMiddleware(); + }; + + local.middlewareRouter = function (request, response, nextMiddleware) { + /* + * this function will run the middleware that will + * map the request's method-path to swagger's tags[0]-operationId + */ + var tmp; + // jslint-hack + local.nop(response); + // init swgg object + local.objectSetDefault( + request, + { swgg: { crud: { operationId: '' }, user: {} } }, + 2 + ); + // if request.url is not prefixed with swaggerJson.basePath, + // then default to nextMiddleware + if (request.urlParsed.pathname.indexOf(local.swaggerJson.basePath) !== 0) { + nextMiddleware(); + return; + } + // init pathname + request.swgg.pathname = request.method + ' ' + request.urlParsed.pathname + .replace(local.swaggerJson.basePath, ''); + // init pathObject + while (request.swgg.pathname !== tmp) { + request.swgg.pathObject = + local.apiDict[request.swgg.pathname] || + // handle /foo/{id}/bar case + local.apiDict[request.swgg.pathname + .replace((/\/[^\/]+\/([^\/]*?)$/), '//$1')]; + // if pathObject exists, then break + if (request.swgg.pathObject) { + request.swgg.pathObject = local.jsonCopy(request.swgg.pathObject); + request.swgg.pathname = request.swgg.pathObject._keyPath; + // init crud.operationId + request.swgg.crud.operationId = request.swgg.pathObject._operationId; + break; + } + tmp = request.swgg.pathname; + request.swgg.pathname = request.swgg.pathname + .replace((/\/[^\/]+?(\/*?)$/), '/$1'); + } + nextMiddleware(); + }; + + local.middlewareUserLogin = function (request, response, nextMiddleware) { + /* + * this function will run the middleware that will handle user login + */ + var crud, options, user; + options = {}; + local.onNext(options, function (error, data) { + switch (options.modeNext) { + case 1: + local.dbTableUser = local.db.dbTableCreateOne({ name: 'User' }); + crud = request.swgg.crud; + user = request.swgg.user = {}; + user.jwtEncrypted = request.headers.authorization && + request.headers.authorization.replace('Bearer ', ''); + user.jwtDecrypted = local.jwtA256GcmDecrypt(user.jwtEncrypted); + switch (crud.operationId.split('.')[0]) { + // coverage-hack - test error handling-behavior + case 'crudErrorLogin': + options.onNext(local.errorDefault); + return; + case 'userLoginByPassword': + user.password = request.urlParsed.query.password; + user.username = request.urlParsed.query.username; + if (user.password && user.username) { + local.dbTableUser.crudGetOneById({ + username: user.username + }, options.onNext); + return; + } + break; + default: + if (user.jwtDecrypted.sub) { + // init username + user.username = user.jwtDecrypted.sub; + local.dbTableUser.crudGetOneById({ + username: user.username + }, options.onNext); + return; + } + } + options.modeNext = Infinity; + options.onNext(); + break; + case 2: + switch (crud.operationId.split('.')[0]) { + case 'userLoginByPassword': + user.data = data; + if (!local.sjclHashScryptValidate( + user.password, + user.data && user.data.password + )) { + options.modeNext = Infinity; + options.onNext(); + return; + } + // init isAuthenticated + user.isAuthenticated = true; + // https://tools.ietf.org/html/rfc7519 + // create JSON Web Token (JWT) + user.jwtDecrypted = {}; + user.jwtDecrypted.sub = user.data.username; + // update jwtEncrypted in client + user.jwtEncrypted = local.jwtA256GcmEncrypt(user.jwtDecrypted); + local.serverRespondHeadSet(request, response, null, { + 'swgg-jwt-encrypted': user.jwtEncrypted + }); + // update jwtEncrypted in dbTableUser + local.dbTableUser.crudUpdateOneById({ + jwtEncrypted: user.jwtEncrypted, + username: user.jwtDecrypted.sub + }, options.onNext); + return; + default: + data = user.data = data || {}; + if (data.jwtEncrypted) { + // init isAuthenticated + user.isAuthenticated = true; + // update jwtEncrypted in client + if (data.jwtEncrypted !== user.jwtEncrypted) { + user.jwtEncrypted = data.jwtEncrypted; + user.jwtDecrypted = local.jwtA256GcmDecrypt(user.jwtEncrypted); + local.serverRespondHeadSet(request, response, null, { + 'swgg-jwt-encrypted': user.jwtEncrypted + }); + } + } + } + options.onNext(); + break; + default: + nextMiddleware(error); + } + }); + options.modeNext = 0; + options.onNext(); + }; + + local.middlewareValidate = function (request, response, nextMiddleware) { + /* + * this function will run the middleware that will validate the swagger-request + */ + var crud, modeNext, onNext, tmp; + modeNext = 0; + onNext = function () { + modeNext += 1; + switch (modeNext) { + case 1: + // serve swagger.json + if (request.method + ' ' + request.urlParsed.pathname === + 'GET ' + local.swaggerJson.basePath + '/swagger.json') { + response.end(JSON.stringify(local.swaggerJson)); + return; + } + if (!request.swgg.pathObject) { + modeNext = Infinity; + onNext(); + return; + } + // init paramDict + request.swgg.paramDict = {}; + // parse path param + tmp = request.urlParsed.pathname + .replace(local.swaggerJson.basePath, '').split('/'); + request.swgg.pathObject._path.split('/').forEach(function (key, ii) { + if ((/^\{\S*?\}$/).test(key)) { + request.swgg.paramDict[key.slice(1, -1)] = + decodeURIComponent(tmp[ii]); + } + }); + request.swgg.pathObject.parameters.forEach(function (paramDef) { + switch (paramDef.in) { + // parse body param + case 'body': + request.swgg.paramDict[paramDef.name] = request.swgg.bodyParsed || + undefined; + break; + // parse formData param + case 'formData': + switch (String(request.headers['content-type']).split(';')[0]) { + case 'application/x-www-form-urlencoded': + request.swgg.paramDict[paramDef.name] = + request.swgg.bodyParsed[paramDef.name]; + break; + } + break; + // parse header param + case 'header': + request.swgg.paramDict[paramDef.name] = + request.headers[paramDef.name.toLowerCase()]; + break; + // parse query param + case 'query': + request.swgg.paramDict[paramDef.name] = + request.urlParsed.query[paramDef.name]; + break; + } + // parse array-multi + if (request.swgg.paramDict[paramDef.name] && + paramDef.type === 'array' && + paramDef.collectionFormat === 'multi') { + tmp = ''; + request.swgg.paramDict[paramDef.name].forEach(function (value) { + tmp += '&' + encodeURIComponent(paramDef.name) + '=' + + encodeURIComponent(value); + }); + request.swgg.paramDict[paramDef.name] = tmp.slice(1); + } + // init default param + if (local.isNullOrUndefined(request.swgg.paramDict[paramDef.name]) && + paramDef.default !== undefined) { + request.swgg.paramDict[paramDef.name] = + local.jsonCopy(paramDef.default); + } + }); + // normalize paramDict + local.normalizeParamDictSwagger( + request.swgg.paramDict, + request.swgg.pathObject + ); + // validate paramDict + local.validateByParamDefList({ + data: request.swgg.paramDict, + key: request.swgg.pathname, + paramDefList: request.swgg.pathObject.parameters + }); + onNext(); + break; + case 2: + // init crud + crud = request.swgg.crud; + // init crud.dbTable + crud.dbTable = request.swgg.pathObject && + request.swgg.pathObject._schemaName && + local.db.dbTableCreateOne({ + name: request.swgg.pathObject._schemaName + }); + if (!crud.dbTable) { + nextMiddleware(); + return; + } + // init crud.body + if (!request.swgg.isMultipartFormData) { + crud.body = local.jsonCopy(request.swgg.bodyParsed); + } + // init crud.data + crud.data = local.jsonCopy(request.swgg.paramDict); + request.swgg.pathObject.parameters.forEach(function (param) { + // JSON.parse json-string + if (param.format === 'json' && + param.type === 'string' && + crud.data[param.name]) { + crud.data[param.name] = JSON.parse(crud.data[param.name]); + } + }); + // init crud.query* + [{ + key: 'queryFields', + value: {} + }, { + key: 'queryLimit', + value: 100 + }, { + key: 'querySkip', + value: 0 + }, { + key: 'querySort', + value: [{ fieldName: '_timeUpdated', isDescending: true }] + }, { + key: 'queryWhere', + value: {} + }].forEach(function (element) { + crud[element.key] = crud.data['_' + element.key] || JSON.parse( + local.templateRender( + request.swgg.pathObject['_' + element.key] || 'null', + request.swgg.paramDict + ) + ) || element.value; + }); + // init-before crud.idField + crud.modeQueryByIdInvert = true; + local.idFieldInit(crud); + // init crud.data.id + switch (crud.operationId.split('.')[0]) { + case 'crudSetOneById': + case 'crudUpdateOneById': + if (!local.isNullOrUndefined(crud.data[crud.idField])) { + break; + } + crud.data[crud.idField] = (crud.body && crud.body[crud.idAlias]); + break; + } + // init-after crud.idField + crud.modeQueryByIdInvert = true; + local.idFieldInit(crud); + nextMiddleware(); + break; + default: + nextMiddleware(); + } + }; + onNext(); + }; + + local.normalizeParamDictSwagger = function (data, pathObject) { + /* + * this function will parse the data according to pathObject.parameters + */ + var tmp; + pathObject.parameters.forEach(function (paramDef) { + tmp = data[paramDef.name]; + // init default value + if (local.isNullOrUndefined(tmp) && paramDef.default !== undefined) { + tmp = local.jsonCopy(paramDef.default); + } + // parse array + if (paramDef.type === 'array' && paramDef.in !== 'body') { + if (typeof tmp === 'string') { + switch (paramDef.collectionFormat) { + case 'json': + local.tryCatchOnError(function () { + tmp = JSON.parse(tmp); + }, local.nop); + data[paramDef.name] = tmp; + return; + case 'multi': + tmp = local.urlParse('?' + tmp, true).query[paramDef.name]; + break; + case 'pipes': + tmp = tmp.split('|'); + break; + case 'ssv': + tmp = tmp.split(' '); + break; + case 'tsv': + tmp = tmp.split('\t'); + break; + // default to csv + default: + tmp = tmp.split(','); + } + if (paramDef.items && paramDef.items.type !== 'string') { + // try to JSON.parse the string + local.tryCatchOnError(function () { + tmp = tmp.map(function (element) { + return JSON.parse(element); + }); + }, local.nop); + } + } + // JSON.parse paramDict + } else if (paramDef.type !== 'file' && + paramDef.type !== 'string' && + (typeof tmp === 'string' || tmp instanceof local.global.Uint8Array)) { + // try to JSON.parse the string + local.tryCatchOnError(function () { + tmp = JSON.parse(local.bufferToString(tmp)); + }, local.nop); + } + data[paramDef.name] = tmp; + }); + return data; + }; + + local.onErrorJsonapi = function (onError) { + /* + * http://jsonapi.org/format/#errors + * http://jsonapi.org/format/#document-structure-resource-objects + * this function will normalize the error and data to jsonapi format, + * and pass them to onError + */ + return function (error, data, meta) { + data = [error, data].map(function (data, ii) { + // if no error occurred, then return + if ((ii === 0 && !data) || + // if data is already normalized, then return it + (data && data.meta && data.meta.isJsonapiResponse)) { + return data; + } + // normalize data-list + if (!Array.isArray(data)) { + data = [data]; + } + // normalize error-list to contain non-null objects + if (ii === 0) { + // normalize error-list to be non-empty + if (!data.length) { + data.push(null); + } + data = data.map(function (element) { + if (!(element && typeof element === 'object')) { + element = { message: String(element) }; + } + // normalize error-object to plain json-object + error = local.jsonCopy(element); + error.message = element.message; + error.stack = element.stack; + error.statusCode = Number(error.statusCode) || 500; + return error; + }); + error = local.jsonCopy(data[0]); + error.errors = data; + return error; + } + return { data: data }; + }); + // init data.meta + data.forEach(function (data, ii) { + if (!data) { + return; + } + data.meta = local.jsonCopy(meta || {}); + data.meta.isJsonapiResponse = true; + if (ii === 0) { + data.meta.errorsLength = (data.errors && data.errors.length) | 0; + } else { + data.meta.dataLength = (data.data && data.data.length) | 0; + } + data.meta.statusCode = Number(data.meta.statusCode) || + Number(data.statusCode) || + 0; + }); + onError(data[0], data[1]); + }; + }; + + local.schemaNormalizeAndCopy = function (schema) { + /* + * this function will return a normalized copy the schema + */ + var tmp; + // dereference $ref + if (schema.$ref) { + [local.swaggerJson, local.swaggerSchemaJson].some(function (options) { + local.tryCatchOnError(function () { + schema.$ref.replace( + (/#\/(.*?)\/(.*?)$/), + function (match0, match1, match2) { + // jslint-hack - nop + local.nop(match0); + tmp = options[match1][match2]; + } + ); + }, local.nop); + return tmp; + }); + // validate schema + local.assert(tmp, schema.$ref); + // recurse + schema = local.schemaNormalizeAndCopy(tmp); + } + // inherit allOf + if (schema.allOf) { + tmp = local.jsonCopy(schema); + delete tmp.allOf; + schema.allOf.reverse().forEach(function (element) { + // recurse + local.objectSetDefault(tmp, local.schemaNormalizeAndCopy(element), 2); + }); + schema = tmp; + } + schema = local.jsonCopy(schema); + if (schema.type === 'object') { + schema.properties = local.normalizeDict(schema.properties); + } + return schema; + }; + + local.serverRespondJsonapi = function (request, response, error, data, meta) { + /* + * http://jsonapi.org/format/#errors + * http://jsonapi.org/format/#document-structure-resource-objects + * this function will respond in jsonapi format + */ + local.onErrorJsonapi(function (error, data) { + local.serverRespondHeadSet(request, response, error && error.statusCode, { + 'Content-Type': 'application/json; charset=UTF-8' + }); + if (error) { + // debug statusCode / method / url + local.errorMessagePrepend(error, response.statusCode + ' ' + + request.method + ' ' + request.url + '\n'); + // print error.stack to stderr + local.onErrorDefault(error); + } + data = error || data; + data.meta.statusCode = response.statusCode = + data.meta.statusCode || response.statusCode; + response.end(JSON.stringify(data)); + })(error, data, meta); + }; + + local.uiAnimateFadeIn = function (element) { + /* + * this function will fadeIn the element + */ + element.classList.add('swggAnimateFade'); + element.style.display = ''; + setTimeout(function () { + element.style.opacity = ''; + }, 20); + setTimeout(function () { + element.classList.remove('swggAnimateFade'); + }, 500); + }; + + local.uiAnimateFadeOut = function (element) { + /* + * this function will fadeOut the element + */ + element.classList.add('swggAnimateFade'); + element.style.opacity = '0'; + setTimeout(function () { + element.style.display = 'none'; + element.classList.remove('swggAnimateFade'); + }, 500); + }; + + local.uiAnimateScrollTo = function (element) { + /* + * this function will scrollTo the element + */ + var ii, timerInterval; + ii = 0; + timerInterval = setInterval(function () { + ii += 0.025; + local.global.scrollTo(0, document.body.scrollTop + + Math.min(ii, 1) * (element.offsetTop - document.body.scrollTop) + + -5); + }, 25); + setTimeout(function () { + clearInterval(timerInterval); + }, 1000); + }; + + local.uiAnimateShake = function (element) { + /* + * this function will shake the dom-element + */ + element.classList.add('swggAnimateShake'); + setTimeout(function () { + element.classList.remove('swggAnimateShake'); + }, 500); + }; + + local.uiAnimateSlideAccordian = function (element, elementList) { + /* + * this function will slideDown the element, + * but slideUp all other elements in elementList + */ + // hide elements in elementList + elementList.forEach(function (element2) { + if (element2 !== element) { + local.uiAnimateSlideUp(element2); + } + }); + // show element + local.uiAnimateSlideDown(element); + }; + + local.uiAnimateSlideDown = function (element) { + /* + * this function will slideDown the dom-element + */ + if (element.style.display !== 'none') { + return; + } + element.style.maxHeight = 0; + element.classList.add('swggAnimateSlide'); + element.style.display = ''; + setTimeout(function () { + element.style.maxHeight = 2 * local.global.innerHeight + 'px'; + }, 20); + setTimeout(function () { + element.style.maxHeight = ''; + element.classList.remove('swggAnimateSlide'); + }, 500); + }; + + local.uiAnimateSlideUp = function (element) { + /* + * this function will slideUp the dom-element + */ + if (element.style.display === 'none') { + return; + } + element.style.maxHeight = 2 * local.global.innerHeight + 'px'; + element.classList.add('swggAnimateSlide'); + setTimeout(function () { + element.style.maxHeight = '0px'; + }, 20); + setTimeout(function () { + element.style.display = 'none'; + }, 500); + setTimeout(function () { + element.style.maxHeight = ''; + element.classList.remove('swggAnimateSlide'); + }, 500); + }; + + local.uiDatatableRender = function (options) { + /* + * this function will render the datatable + */ + var tmp; + local.uiState.datatable = options; + options.schema = local.schemaNormalizeAndCopy(options.schema); + options.propDefList = Object.keys(options.schema.properties) + .sort(function (aa, bb) { + return aa === options._idAlias + ? -1 + : bb === options._idAlias + ? 1 + : aa < bb + ? -1 + : 1; + }) + .map(function (propDef) { + tmp = propDef; + propDef = options.schema.properties[tmp]; + propDef.name = tmp; + local.uiParamRender(propDef); + return propDef; + }); + options.iiPadding = 0; + options.dbRowList = options.responseJson.data.map(function (dbRow, ii) { + dbRow = { paramDict: dbRow }; + dbRow.colList = options.propDefList.map(function (propDef) { + propDef = local.jsonCopy(propDef); + propDef.valueEncoded = dbRow.paramDict[propDef.name]; + if (propDef.valueEncoded === undefined) { + propDef.valueEncoded = ''; + } + if (typeof propDef.valueEncoded !== 'string') { + propDef.valueEncoded = JSON.stringify(propDef.valueEncoded); + } + return propDef; + }); + dbRow.id = dbRow.paramDict[options._idAlias]; + dbRow.ii = options.querySkip + ii + 1; + options.iiPadding = Math.max( + 0.375 * String(dbRow.ii).length, + options.iiPadding + ); + return dbRow; + }); + // init pagination + options.pageCurrent = Math.floor(options.querySkip / options.queryLimit); + options.pageTotal = Math.ceil( + options.responseJson.meta.paginationCountTotal / options.queryLimit + ); + options.pageMin = Math.max( + Math.min(options.pageCurrent - 3, options.pageTotal - 7), + 0 + ); + options.pageMax = Math.min(options.pageMin + 7, options.pageTotal); + options.pageList = []; + // add first page + options.pageList.push({ + disabled: options.pageCurrent === 0, + pageNumber: 0, + valueEncoded: 'first page' + }); + for (tmp = options.pageMin; tmp < options.pageMax; tmp += 1) { + options.pageList.push({ + disabled: tmp === options.pageCurrent, + pageNumber: tmp, + valueEncoded: JSON.stringify(tmp + 1) + }); + } + // add last page + options.pageList.push({ + disabled: options.pageCurrent === options.pageTotal - 1, + pageNumber: options.pageTotal - 1, + valueEncoded: 'last page' + }); + options.pageCurrentIsFirst = options.pageCurrent === 0; + options.pageCurrentIsLast = options.pageCurrent + 1 === options.pageTotal; + // templateRender datatable + document.querySelector('.swggUiContainer .datatable').innerHTML = + local.templateRender(local.templateUiDatatable, options); + // init event-handling + local.uiEventInit(document.querySelector('.swggUiContainer .datatable')); + // show modal + if (document.querySelector('.swggUiContainer > .modal').style.display !== 'none') { + return; + } + document.body.style.overflow = 'hidden'; + local.uiAnimateFadeIn(document.querySelector('.swggUiContainer > .modal')); + }; + + local.uiEventDelegate = function (event) { + Object.keys(local.uiEventListenerDict).sort().some(function (key) { + if (!(event.currentTarget.matches(key) || event.target.matches(key))) { + return; + } + switch (event.target.tagName) { + case 'A': + case 'BUTTON': + case 'FORM': + event.preventDefault(); + break; + } + event.stopPropagation(); + local.uiEventListenerDict[key](event); + return true; + }); + }; + + local.uiEventInit = function (element) { + /* + * this function will init event-handling for the dom-element + */ + ['Click', 'Submit'].forEach(function (eventType) { + Array.from( + element.querySelectorAll('.eventDelegate' + eventType) + ).forEach(function (element) { + element.addEventListener(eventType.toLowerCase(), local.uiEventDelegate); + }); + }); + }; + + local.uiEventListenerDict = {}; + + local.uiEventListenerDict['.onEventDatatableReload'] = function (event) { + /* + * this function will show the modal + */ + var options; + options = {}; + if (event) { + options.name = event.target.dataset.resourceName; + options.pageNumber = event.target.dataset.pageNumber; + } else { + options.name = local.uiState.datatable.name; + options.pageNumber = local.uiState.datatable.pageNumber; + options.queryLimit = local.uiState.datatable.queryLimit; + options.querySort = local.uiState.datatable.querySort; + options.queryWhere = local.uiState.datatable.queryWhere; + } + local.objectSetDefault( + options, + local.jsonCopy(local.uiState['x-swgg-datatableDict'][options.name]) + ); + options._idAlias = local.apiDict[options.crudRemoveOneById]._idAlias; + options._idField = local.apiDict[options.crudRemoveOneById]._idField; + local.objectSetDefault(options, { pageNumber: 0, queryLimit: 20 }); + options.querySkip = options.pageNumber * options.queryLimit; + options.paramDict = { + _queryLimit: options.queryLimit, + _querySkip: options.querySkip, + _querySort: options.querySort, + _queryWhere: options.queryWhere + }; + // request data + local.apiDict[options.crudGetManyByQuery]._ajax(options, function (error, options) { + // validate no error occurred + local.assert(!error, error); + local.uiDatatableRender(options); + // emit event uiDatatableRendered + document.dispatchEvent(new local.global.Event('uiDatatableRendered', { + bubbles: true, + cancelable: true + })); + }); + }; + + local.uiEventListenerDict['.onEventDatatableSelectedRemove'] = function () { + var onParallel; + onParallel = local.onParallel(local.uiEventListenerDict['.onEventDatatableReload']); + onParallel.counter += 1; + Array.from( + document.querySelectorAll('.swggUiContainer .datatable tr.selected') + ).forEach(function (element) { + onParallel.counter += 1; + // remove data + local.apiDict[ + local.uiState.datatable.crudRemoveOneById + ]._ajax(local.objectLiteralize({ + paramDict: { '$[]': [ + local.uiState.datatable._idField, + JSON.parse(decodeURIComponent(element.dataset.id)) + ] } + }), onParallel); + }); + onParallel(); + }; + + local.uiEventListenerDict['.onEventDatatableTrSelect'] = function (event) { + if (event.target.tagName !== 'INPUT') { + event.currentTarget.querySelector('input').checked = + !event.currentTarget.querySelector('input').checked; + } + Array.from( + event.currentTarget.closest('tr').querySelectorAll('input') + ).forEach(function (element) { + element.checked = event.currentTarget.querySelector('input').checked; + }); + if (event.currentTarget.querySelector('input').checked) { + event.currentTarget.closest('tr').classList.add('selected'); + } else { + event.currentTarget.closest('tr').classList.remove('selected'); + } + }; + + local.uiEventListenerDict['.onEventModalHide'] = function (event) { + /* + * this function will hide the modal + */ + if (event && !event.target.classList.contains('onEventModalHide')) { + return; + } + if (document.querySelector('.swggUiContainer > .modal').style.display === 'none') { + return; + } + document.body.style.overflow = ''; + // hide modeal + local.uiAnimateFadeOut(document.querySelector('.swggUiContainer > .modal')); + }; + + local.uiEventListenerDict['.onEventOperationAjax'] = function (event) { + /* + * this function will return submit the operation to the backend + */ + var options, tmp; + options = {}; + local.onNext(options, function (error, data) { + switch (options.modeNext) { + case 1: + options.api = local.apiDict[event.currentTarget.dataset._keyOperationId]; + options.domOperationContent = event.target.closest('.operation > .content'); + options.headers = {}; + options.paramDict = {}; + options.api.parameters.forEach(function (paramDef) { + local.tryCatchOnError(function () { + tmp = options.domOperationContent.querySelector( + '.paramDef[name=' + paramDef.name + '] > .td3' + ).children[0]; + switch (tmp.tagName) { + case 'INPUT': + // parse file + if (tmp.type === 'file') { + tmp = tmp.files && tmp.files[0]; + break; + } + tmp = tmp.value; + if (!tmp) { + return; + } + // parse string + if (paramDef.type !== 'string') { + tmp = JSON.parse(tmp); + } + break; + case 'SELECT': + tmp = Array.from(tmp.options) + .filter(function (element) { + return element.selected; + }) + .map(function (element) { + return JSON.parse(decodeURIComponent( + element.dataset.valueDecoded + )); + }); + if (!tmp.length || tmp[0] === '$swggUndefined') { + return; + } + if (paramDef.type !== 'array') { + tmp = tmp[0]; + } + break; + case 'TEXTAREA': + tmp = tmp.value; + if (!tmp) { + return; + } + // parse schema + if (paramDef.in === 'body') { + tmp = JSON.parse(tmp); + break; + } + // parse array + tmp = tmp.split('\n').map(function (element) { + return paramDef.items.type === 'string' + ? element + : JSON.parse(element); + }); + break; + } + options.paramDict[paramDef.name] = tmp; + }, function (error) { + options.errorValidate = error; + options.errorValidate.options = { key: paramDef.name }; + options.onNext(error); + }); + }); + options.api._ajax(options, options.onNext); + break; + default: + // remove previous error + Array.from( + options.domOperationContent.querySelectorAll('.paramDef .input') + ).forEach(function (element) { + element.classList.remove('error'); + }); + if (options.errorValidate) { + // shake input on Error + Array.from(options.domOperationContent.querySelectorAll( + '.paramDef[name=' + options.errorValidate.options.key + '] .input' + )).forEach(function (element) { + element.classList.add('error'); + local.uiAnimateShake(element.closest('span')); + }); + data = { + errorValidate: options.errorValidate, + responseText: error.message, + statusCode: 400 + }; + } + // init responseHeaders + data.responseHeaders = {}; + ( + (data.getAllResponseHeaders && data.getAllResponseHeaders()) || '' + ).replace( + (/.+/g), + function (item) { + item = item.split(':'); + data.responseHeaders[item[0].trim().toLowerCase()] = + item.slice(1).join(':').trim(); + } + ); + // init contentType + data.contentType = + String(data.responseHeaders['content-type']).split(';')[0]; + // init responseBody + switch (data.contentType.split('/')[0]) { + case 'audio': + case 'video': + data.responseBody = '<' + data.contentType.split('/')[0] + + ' controls>'; + break; + case 'image': + data.responseBody = ''; + break; + default: + data.responseBody = '
' + local.stringHtmlSafe(
+                            data.responseJson
+                                ? JSON.stringify(data.responseJson, null, 4)
+                                : data.responseText
+                        ) + '
'; + } + // init curl + local.tryCatchOnError(function () { + options.data = JSON.stringify(JSON.parse(options.data), null, 4); + }, local.nop); + data.curl = 'curl \\\n' + + '--request ' + options.api._method.toUpperCase() + ' \\\n' + + Object.keys(options.headers).map(function (key) { + return "--header '" + key + ': ' + options.headers[key] + "' \\\n"; + }).join('') + '--data-binary ' + (typeof options.data === 'string' + ? "'" + options.data.replace(/'/g, "'\"'\"'") + "'" + : '') + ' \\\n"' + options.url + '"'; + data.responseHeaders = data.getAllResponseHeaders && + data.getAllResponseHeaders().trim(); + // templateRender response + options.domOperationContent.querySelector( + '.responseAjax' + ).innerHTML = local.templateRender(local.templateUiResponseAjax, data); + break; + } + }); + options.modeNext = 0; + options.onNext(); + }; + + local.uiEventListenerDict['.onEventOperationDisplayShow'] = function (event) { + /* + * this function will toggle the display of the operation + */ + var tmp; + location.hash = '!/' + event.target.closest('.resource').id + '/' + + event.target.closest('.operation').id; + tmp = event.target.closest('.operation').querySelector('.operation > .content'); + tmp.closest('.resource').classList.remove('expanded'); + // show the operation, but hide all other operations + local.uiAnimateSlideAccordian( + tmp, + Array.from( + tmp.closest('.operationList').querySelectorAll('.operation > .content') + ) + ); + }; + + local.uiEventListenerDict['.onEventResourceDisplayAction'] = function (event) { + /* + * this function will toggle the display of the resource + */ + location.hash = '!/' + event.currentTarget.id; + event.target.className.split(' ').some(function (className) { + switch (className) { + // show the resource, but hide all other resources + case 'td1': + case 'td2': + case 'td3': + local.uiAnimateSlideAccordian( + event.currentTarget.querySelector('.operationList'), + Array.from(document.querySelectorAll('.swggUiContainer .operationList')) + ); + break; + } + switch (className) { + case 'td1': + case 'td2': + return true; + case 'td3': + // collapse all operations in the resource + if (event.currentTarget.classList.contains('expanded')) { + event.currentTarget.classList.remove('expanded'); + Array.from( + event.currentTarget.querySelectorAll('.operation > .content') + ).forEach(function (element) { + local.uiAnimateSlideUp(element); + }); + // expand all operations in the resource + } else { + event.currentTarget.classList.add('expanded'); + Array.from( + event.currentTarget.querySelectorAll('.operation > .content') + ).forEach(function (element) { + local.uiAnimateSlideDown(element); + }); + } + return true; + } + }); + }; + + local.uiEventListenerDict['.onEventUiReload'] = function () { + /* + * this function will reload the ui + */ + // reset ui + Array.from( + document.querySelectorAll('.swggUiContainer > .reset') + ).forEach(function (element) { + element.remove(); + }); + // normalize url + document.querySelector('.swggUiContainer > .header > .td2').value = + local.urlParse( + document.querySelector('.swggUiContainer > .header > .td2').value + .replace((/^\//), '') + ).href; + // display .swggAjaxProgressDiv + document.querySelector('.swggAjaxProgressDiv').textContent = + 'fetching resource list: ' + + document.querySelector('.swggUiContainer > .header > .td2').value + + '; Please wait.'; + document.querySelector('.swggAjaxProgressDiv').style.display = 'block'; + local.ajax({ + url: document.querySelector('.swggUiContainer > .header > .td2').value + }, function (error, xhr) { + // hide .swggAjaxProgressDiv + document.querySelector('.swggAjaxProgressDiv').style.display = 'none'; + // validate no error occurred + local.assert(!error, error); + // reset state + local.apiDict = local.swaggerJson = null; + local.apiDictUpdate(local.objectSetDefault(JSON.parse(xhr.responseText), { + host: local.urlParse( + document.querySelector('.swggUiContainer > .header > .td2').value + ).host + })); + local.uiRender(); + }); + }; + + local.uiParamRender = function (paramDef) { + /* + * this function will render the param + */ + paramDef.placeholder = paramDef.required + ? '(required)' + : ''; + // init input - file + if (paramDef.type === 'file') { + paramDef.isFile = true; + // init input - textarea + } else if (paramDef.in === 'body') { + paramDef.isTextarea = true; + // init input - select + } else if (paramDef.enum || paramDef.type === 'boolean') { + paramDef.enumDefault = []; + if (paramDef.default !== undefined) { + paramDef.enumDefault = paramDef.type === 'array' + ? paramDef.default + : [paramDef.default]; + } + paramDef.isSelect = true; + paramDef.isSelectMultiple = paramDef.type === 'array'; + paramDef.selectOptionList = (paramDef.type === 'boolean' + ? [false, true] + : paramDef.enum).map(function (element) { + paramDef.hasDefault |= paramDef.enumDefault.indexOf(element) >= 0; + return { + id: local.idDomElementCreate('swgg_id_' + paramDef.name), + selected: paramDef.enumDefault.indexOf(element) >= 0 + ? 'selected' + : '', + type: (paramDef.items && paramDef.items.type) || paramDef.type, + valueDecoded: element, + valueEncoded: typeof element === 'string' + ? element + : JSON.stringify(element) + }; + }); + // init 'undefined' value + if (!(paramDef.hasDefault || + paramDef.isSelectMultiple || + paramDef.required)) { + paramDef.selectOptionList.unshift({ + id: local.idDomElementCreate('swgg_id_' + paramDef.name), + selected: 'selected', + type: paramDef.type, + valueDecoded: '$swggUndefined', + valueEncoded: '' + }); + } + // if required, then select at least one value + if (paramDef.required && paramDef.selectOptionList.length) { + paramDef.selected = paramDef.selectOptionList[0]; + paramDef.selectOptionList.some(function (element) { + if (element.selected) { + paramDef.selected = element.selected; + return true; + } + }); + paramDef.selected = 'selected'; + } + // init input - textarea + } else if (paramDef.type === 'array') { + paramDef.isTextarea = true; + paramDef.placeholder = 'provide multiple values in new lines' + + (paramDef.required + ? ' (at least one required)' + : ''); + // init input - text + } else { + paramDef.isInputText = true; + } + // init format2 / type2 + [ + paramDef, + paramDef.schema + ].some(function (element) { + local.tryCatchOnError(function () { + paramDef.format2 = paramDef.format2 || element.format; + }, local.nop); + local.tryCatchOnError(function () { + paramDef.type2 = paramDef.type2 || element.type; + }, local.nop); + return paramDef.type2; + }); + paramDef.type2 = paramDef.type2 || 'object'; + // init schema2 + [ + paramDef.items, + paramDef.schema, + paramDef.schema && paramDef.schema.items + ].some(function (element) { + paramDef.schema2 = local.schemaNormalizeAndCopy(element || {}).properties; + return paramDef.schema2; + }); + if (paramDef.schema2) { + paramDef.schemaText = JSON.stringify(paramDef.type2 === 'array' + ? [paramDef.schema2] + : paramDef.schema2, null, 4); + } + // init valueEncoded + paramDef.valueEncoded = paramDef.default; + if (paramDef.valueEncoded === undefined) { + paramDef.valueEncoded = local.dbFieldRandomCreate({ + modeNotRandom: true, + propDef: paramDef + }); + } + // init valueEncoded for array + if (paramDef.valueEncoded && paramDef.type2 === 'array' && paramDef.in !== 'body') { + paramDef.valueEncoded = paramDef.valueEncoded.map(function (element) { + return typeof element === 'string' + ? element + : JSON.stringify(element); + }).join('\n'); + } + // init valueEncoded for schema + if (paramDef.in === 'body' && paramDef.schema2) { + paramDef.valueEncoded = local.dbRowRandomCreate({ + modeNotRandom: true, + override: function () { + var override = {}; + // preserve default value + Object.keys(paramDef.schema2).forEach(function (key) { + if (paramDef.schema2[key].default !== undefined) { + override[key] = paramDef.schema2[key].default; + } + }); + return override; + }, + properties: paramDef.schema2 + }); + if (paramDef.type2 === 'array') { + paramDef.valueEncoded = [paramDef.valueEncoded]; + } + paramDef.valueEncoded = JSON.stringify(paramDef.valueEncoded, null, 4); + } + if (typeof paramDef.valueEncoded !== 'string') { + paramDef.valueEncoded = JSON.stringify(paramDef.valueEncoded) || ''; + } + // templateRender paramDef + paramDef.innerHTML = local.templateRender(local.templateUiParam, paramDef); + }; + + local.uiRender = function () { + /* + * this function will render swagger-ui + */ + var resource, self; + // reset state + local.idDomElementDict = {}; + self = local.uiState = local.jsonCopy(local.swaggerJson); + // init url + self.url = document.querySelector('.swggUiContainer > .header > .td2').value; + // templateRender main + self.uiFragment = local.domFragmentRender(local.templateUiMain, self); + local.objectSetDefault(self, { + resourceDict: {}, + operationDict: {}, + tagDict: {} + }); + // init tagDict + self.tags.forEach(function (tag) { + self.tagDict[tag.name] = tag; + }); + // init operationDict + Object.keys(local.apiDict).sort().forEach(function (operation) { + // init operation + operation = local.jsonCopy(local.apiDict[operation]); + operation.tags.forEach(function (tag) { + self.operationDict[operation._keyOperationId] = operation; + // init resource + resource = self.resourceDict[tag]; + if (!resource && self.tagDict[tag]) { + resource = self.resourceDict[tag] = self.tagDict[tag]; + local.objectSetDefault(resource, { + description: 'no description available', + id: local.idDomElementCreate('swgg_id_' + tag), + name: tag, + operationListInnerHtml: '' + }); + } + }); + }); + // init resourceDict + Object.keys(self.resourceDict).sort().forEach(function (key) { + // templateRender resource + self.uiFragment.querySelector('.resourceList').appendChild( + local.domFragmentRender(local.templateUiResource, self.resourceDict[key]) + ); + }); + Object.keys(self.operationDict).sort(function (aa, bb) { + aa = self.operationDict[aa]; + aa = aa._path + ' ' + aa._method; + bb = self.operationDict[bb]; + bb = bb._path + ' ' + bb._method; + return aa < bb + ? -1 + : 1; + }).forEach(function (operation) { + operation = self.operationDict[operation]; + operation.id = local.idDomElementCreate('swgg_id_' + operation.operationId); + operation.tags.forEach(function (tag) { + operation = local.jsonCopy(operation); + resource = self.resourceDict[tag]; + local.objectSetDefault(operation, { + description: '', + responseList: Object.keys(operation.responses).sort() + .map(function (key) { + return { key: key, value: operation.responses[key] }; + }), + summary: 'no summary available' + }); + operation.parameters.forEach(function (element) { + // init element.id + element.id = local.idDomElementCreate('swgg_id_' + element.name); + local.uiParamRender(element); + }); + // templateRender operation + self.uiFragment.querySelector('#' + resource.id + ' .operationList') + .appendChild( + local.domFragmentRender(local.templateUiOperation, operation) + ); + }); + }); + // overwrite swggUiContainer with uiFragment + document.querySelector('.swggUiContainer').innerHTML = ''; + document.querySelector('.swggUiContainer').appendChild(self.uiFragment); + /* istanbul ignore next */ + // bug-workaround - add keypress listener for + document.querySelector('form2').addEventListener('keypress', function (event) { + if (event.keyCode === 13) { + local.uiEventListenerDict['.onEventUiReload'](); + } + }); + // render valueEncoded + Array.from( + document.querySelectorAll('.swggUiContainer [data-value-encoded]') + ).forEach(function (element) { + element.value = decodeURIComponent(element.dataset.valueEncoded); + }); + // init event-handling + local.uiEventInit(document); + // scrollTo location.hash + local.uiScrollTo(location.hash); + }; + + local.uiScrollTo = function (locationHash) { + /* + * this function will scrollTo locationHash + */ + var operation, resource; + // init resource + resource = locationHash.split('/')[1]; + // list operations + resource = document.querySelector('.swggUiContainer #' + resource) || + document.querySelector('.swggUiContainer .resource'); + local.uiAnimateSlideDown(resource.querySelector('.operationList')); + // init operation + operation = locationHash.split('/')[2]; + operation = resource.querySelector('#' + operation); + // expand operation and scroll to it + if (operation) { + local.uiAnimateSlideDown(operation.querySelector('.content')); + // scroll to operation + local.uiAnimateScrollTo(operation); + } else { + // scroll to resource + local.uiAnimateScrollTo(resource); + } + }; + + local.urlBaseGet = function () { + /* + * this function will return the base swagger url + */ + return (local.swaggerJson.schemes || + local.urlParse('').protocol.slice(0, -1)) + '://' + + (local.swaggerJson.host || local.urlParse('').host) + + local.swaggerJson.basePath; + }; + + local.userLoginByPassword = function (options, onError) { + /* + * this function will send a login-by-password request + */ + local.apiDict["GET /user/userLoginByPassword"]._ajax({ + paramDict: { password: options.password, username: options.username } + }, onError); + }; + + local.userLogout = function (options, onError) { + /* + * this function will send a logout request + */ + local.apiDict["GET /user/userLogout"]._ajax(options, onError); + }; + + local.utility2._middlewareError = function (error, request, response) { + /* + * this function will run the middleware that will + * handle errors according to http://jsonapi.org/format/#errors + */ + if (!error) { + error = new Error('404 Not Found'); + error.statusCode = 404; + } + local.serverRespondJsonapi(request, response, error); + }; + + local.utility2._stateInit = function (options) { + /* + * this function will init the state-options + */ + local.objectSetOverride(local, options, 10); + // init api + local.apiDictUpdate(local.swaggerJson); + }; + + local.validateByParamDefList = function (options) { + /* + * this function will validate options.data against options.paramDefList + */ + var data, key; + local.tryCatchOnError(function () { + data = options.data; + // validate data + local.assert(data && typeof data === 'object', data); + (options.paramDefList || []).forEach(function (paramDef) { + key = paramDef.name; + // recurse - validateByPropDef + local.validateByPropDef({ + circularList: options.circularList, + data: data[key], + dataReadonlyRemove: (options.dataReadonlyRemove || {})[key], + key: key, + schema: paramDef, + required: paramDef.required, + 'x-swgg-notRequired': paramDef['x-swgg-notRequired'] + }); + }); + }, function (error) { + error.statusCode = error.statusCode || 400; + local.errorMessagePrepend(error, options.key + '.' + key + ' -> '); + throw error; + }); + }; + + local.validateByPropDef = function (options) { + /* + * this function will validate options.data against options.schema + */ + var data, prefix, propDef, tmp; + local.tryCatchOnError(function () { + data = options.data; + prefix = 'property ' + options.key; + propDef = options.schema; + // validate undefined data + if (local.isNullOrUndefined(data)) { + if (options.required && !options['x-swgg-notRequired']) { + tmp = new Error(prefix + ' cannot be null or undefined'); + tmp.options = options; + throw tmp; + } + return; + } + // handle $ref + tmp = propDef.$ref || (propDef.schema && propDef.schema.$ref); + if (tmp) { + // recurse - validateBySchema + local.validateBySchema({ + circularList: options.circularList, + data: data, + dataReadonlyRemove: options.dataReadonlyRemove, + key: tmp, + schema: local.schemaNormalizeAndCopy({ $ref: tmp }), + 'x-swgg-notRequired': options['x-swgg-notRequired'] + }); + return; + } + // handle anyOf + if (propDef.anyOf) { + tmp = propDef.anyOf.some(function (element) { + local.tryCatchOnError(function () { + // recurse - validateBySchema + local.validateBySchema({ + circularList: options.circularList, + data: data, + key: 'anyOf', + schema: local.schemaNormalizeAndCopy(element), + 'x-swgg-notRequired': options['x-swgg-notRequired'] + }); + }, local.nop); + return !local.utility2._debugTryCatchErrorCaught; + }); + local.assert(tmp, local.utility2._debugTryCatchErrorCaught); + return; + } + // normalize propDef + propDef = local.schemaNormalizeAndCopy(options.schema); + // init circularList + if (data && typeof data === 'object') { + options.circularList = options.circularList || []; + if (options.circularList.indexOf(data) >= 0) { + return; + } + options.circularList.push(data); + } + // validate propDef embedded in propDef.schema.type + if (!propDef.type && propDef.schema && propDef.schema.type) { + propDef = propDef.schema; + } + // http://json-schema.org/latest/json-schema-validation.html#anchor13 + // 5.1. Validation keywords for numeric instances (number and integer) + if (typeof data === 'number') { + if (typeof propDef.multipleOf === 'number') { + local.assert( + data % propDef.multipleOf === 0, + prefix + ' must be a multiple of ' + propDef.multipleOf + ); + } + if (typeof propDef.maximum === 'number') { + local.assert( + propDef.exclusiveMaximum + ? data < propDef.maximum + : data <= propDef.maximum, + prefix + ' must be ' + (propDef.exclusiveMaximum + ? '< ' + : '<= ') + propDef.maximum + ); + } + if (typeof propDef.minimum === 'number') { + local.assert( + propDef.exclusiveMinimum + ? data > propDef.minimum + : data >= propDef.minimum, + prefix + ' must be ' + (propDef.exclusiveMinimum + ? '> ' + : '>= ') + propDef.minimum + ); + } + // http://json-schema.org/latest/json-schema-validation.html#anchor25 + // 5.2. Validation keywords for strings + } else if (typeof data === 'string') { + if (propDef.maxLength) { + local.assert( + data.length <= propDef.maxLength, + prefix + ' must have <= ' + propDef.maxLength + ' characters' + ); + } + if (propDef.minLength) { + local.assert( + data.length >= propDef.minLength, + prefix + ' must have >= ' + propDef.minLength + ' characters' + ); + } + if (propDef.pattern) { + local.assert( + new RegExp(propDef.pattern).test(data), + prefix + ' must match regex pattern /' + propDef.pattern + '/' + ); + } + // http://json-schema.org/latest/json-schema-validation.html#anchor36 + // 5.3. Validation keywords for arrays + } else if (Array.isArray(data)) { + if (propDef.maxItems) { + local.assert( + data.length <= propDef.maxItems, + prefix + ' must have <= ' + propDef.maxItems + ' items' + ); + } + if (propDef.minItems) { + local.assert( + data.length >= propDef.minItems, + prefix + ' must have >= ' + propDef.minItems + ' items' + ); + } + if (propDef.uniqueItems) { + tmp = {}; + data.forEach(function (element) { + element = JSON.stringify(element); + local.assert( + !tmp[element], + prefix + ' must have only unique items' + ); + tmp[element] = true; + }); + } + // http://json-schema.org/latest/json-schema-validation.html#anchor53 + // 5.4. Validation keywords for objects + } else if (typeof data === 'object') { + if (propDef.maxProperties) { + local.assert( + Object.keys(data).length <= propDef.maxProperties, + prefix + ' must have <= ' + propDef.maxProperties + ' items' + ); + } + if (propDef.minProperties) { + local.assert( + Object.keys(data).length >= propDef.minProperties, + prefix + ' must have >= ' + propDef.minProperties + ' items' + ); + } + } + // http://json-schema.org/latest/json-schema-validation.html#anchor75 + // 5.5. Validation keywords for any instance type + if (propDef.enum) { + (Array.isArray(data) + ? data + : [data]).forEach(function (element) { + local.assert( + propDef.enum.indexOf(element) >= 0, + prefix + ' must only have items in the list ' + + JSON.stringify(propDef.enum) + ); + }); + } + // https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md + // #data-types + // validate schema.type + switch (propDef.type) { + case 'array': + local.assert(Array.isArray(data) && propDef.items); + data.forEach(function (element, ii) { + // recurse - validateByPropDef + local.validateByPropDef({ + circularList: options.circularList, + data: element, + dataReadonlyRemove: (options.dataReadonlyRemove || {})[ii], + key: ii, + schema: propDef.items, + 'x-swgg-notRequired': options['x-swgg-notRequired'] + }); + }); + switch (propDef.collectionFormat) { + case 'multi': + local.assert( + propDef.in === 'formData' || propDef.in === 'query', + prefix + ' with collectionFormat "multi" ' + + 'is valid only for parameters in "query" or "formData"' + ); + break; + } + break; + case 'boolean': + local.assert(typeof data === 'boolean'); + break; + case 'file': + break; + case 'integer': + local.assert(typeof data === 'number' && + isFinite(data) && + Math.floor(data) === data); + switch (propDef.format) { + case 'int32': + case 'int64': + break; + } + break; + case 'number': + local.assert(typeof data === 'number' && isFinite(data)); + switch (propDef.format) { + case 'double': + case 'float': + break; + } + break; + case 'object': + local.assert(typeof data === 'object'); + break; + case 'string': + local.assert(typeof data === 'string' || propDef.format === 'binary'); + switch (propDef.format) { + // https://github.com/swagger-api/swagger-spec/issues/50 + // Clarify 'byte' format #50 + case 'byte': + local.assert(!(/[^\n\r\+\/0-9\=A-Za-z]/).test(data)); + break; + case 'date': + case 'date-time': + local.assert(JSON.stringify(new Date(data)) !== 'null'); + break; + case 'email': + local.assert(local.regexpEmailValidate.test(data)); + break; + case 'phone': + local.assert(local.regexpPhoneValidate.test(data)); + break; + case 'json': + JSON.parse(data); + break; + } + break; + default: + local.assert( + propDef.type === undefined, + prefix + ' has invalid type ' + propDef.type + ); + } + }, function (error) { + error.message = error.message || prefix + ' is not a valid ' + propDef.type + + (propDef.format + ? ' (' + propDef.format + ')' + : ''); + error.options = options; + throw error; + }); + }; + + local.validateBySchema = function (options) { + /* + * this function will validate options.data against options.schema + */ + var data, key, prefix, propDefDict, schema, tmp, validateByPropDef; + // recurse - validateByPropDef + local.validateByPropDef(options); + local.tryCatchOnError(function () { + data = options.data; + prefix = 'schema ' + options.key; + schema = options.schema; + // validate schema + local.assert( + schema && typeof schema === 'object', + prefix + ' must be an object (not ' + typeof schema + ')' + ); + // init propDefDict + propDefDict = schema.properties || {}; + // validate data + local.assert( + (data && typeof data === 'object') || !Object.keys(propDefDict).length, + 'data for ' + prefix + ' must be an object (not ' + typeof data + ')' + ); + if (typeof data !== 'object') { + return; + } + validateByPropDef = function (propDef) { + // remove options.dataReadonlyRemove[key] + if (propDef.readOnly && + (options.dataReadonlyRemove || {}).hasOwnProperty(key)) { + delete options.dataReadonlyRemove[key]; + } + // recurse - validateByPropDef + local.validateByPropDef({ + circularList: options.circularList, + data: data[key], + dataReadonlyRemove: (options.dataReadonlyRemove || {})[key], + key: key, + schema: propDef, + required: schema.required && schema.required.indexOf(key) >= 0, + 'x-swgg-notRequired': options['x-swgg-notRequired'] + }); + }; + Object.keys(propDefDict).forEach(function (_) { + key = _; + validateByPropDef(propDefDict[key]); + }); + Object.keys(data).forEach(function (_) { + key = _; + if (propDefDict[key]) { + return; + } + tmp = Object.keys(schema.patternProperties || {}).some(function (_) { + if (new RegExp(_).test(key)) { + validateByPropDef(schema.patternProperties[_]); + return true; + } + }); + if (tmp) { + return; + } + // https://tools.ietf.org/html/draft-fge-json-schema-validation-00 + // #section-5.4.4 + // validate additionalProperties + local.assert( + schema.additionalProperties !== false, + prefix + ' must not have additionalProperties - ' + key + ); + if (schema.additionalProperties) { + validateByPropDef(schema.additionalProperties); + } + }); + }, function (error) { + local.errorMessagePrepend(error, options.key + '.' + key + ' -> '); + throw error; + }); + }; + + local.validateBySwagger = function (options) { + /* + * this function will validate the entire swagger json object + */ + var key, schema, tmp, validateDefault; + local.validateBySchema({ + data: options, + key: 'swaggerJson', + schema: local.swaggerSchemaJson + }); + // validate default + validateDefault = function () { + if (schema.default !== undefined) { + return; + } + local.validateByPropDef({ + data: schema.default, + key: key + '.default', + schema: schema + }); + }; + Object.keys(options.definitions).forEach(function (schemaName) { + schema = options.definitions[schemaName]; + key = schemaName; + validateDefault(); + Object.keys(options.definitions[schemaName].properties || { + }).forEach(function (propName) { + schema = options.definitions[schemaName].properties[propName]; + key = schemaName + '.' + propName; + validateDefault(); + }); + }); + Object.keys(options.paths).forEach(function (pathName) { + Object.keys(options.paths[pathName]).forEach(function (methodName) { + tmp = options.paths[pathName][methodName]; + Object.keys(tmp.parameters).forEach(function (paramName) { + schema = tmp.parameters[paramName]; + key = tmp.tags[0] + '.' + tmp.operationId + '.' + paramName; + validateDefault(); + }); + }); + }); + }; + }()); + switch (local.modeJs) { + + + + // run browser js-env code - init-after + case 'browser': + // init state + local.utility2._stateInit({}); + break; + + + + // run node js-env code - init-after + case 'node': + // init assets.lib.rollup.js + local.assetsDict['/assets.swgg.rollup.js'] = + local.assetsDict['/assets.utility2.rollup.js']; + // init state + local.utility2._stateInit({}); + break; + } + switch (local.modeJs) { + + + + /* istanbul ignore next */ + // run node js-env code - cli + case 'node': + /* istanbul ignore next */ + if (local.env.SWAGGER_JSON_URL) { + if (local.env.SWAGGER_JSON_URL === '127.0.0.1') { + local.env.SWAGGER_JSON_URL = '/assets.swgg.petstore.json'; + } + local.assetsDict['/assets.swgg.html'] = + local.assetsDict['/assets.swgg.html'].replace( + 'assets.swgg.petstore.json', + local.env.SWAGGER_JSON_URL + ); + } + // run the cli + switch (process.argv[2]) { + case 'swagger-ui': + local.replStart(); + local.global.local = local; + local.assetsDict['/'] = local.assetsDict['/assets.swgg.html']; + local.testRunServer({}); + break; + } + break; + } +}()); +/* script-end /assets.swgg.js */ + + + +/* script-begin /assets.utility2.rollup.end.js */ +(function () { + "use strict"; + var local; + local = {}; + local.modeJs = (function () { + try { + return typeof navigator.userAgent === "string" && + typeof document.querySelector("body") === "object" && + typeof XMLHttpRequest.prototype.open === "function" && + "browser"; + } catch (errorCaughtBrowser) { + return module.exports && + typeof process.versions.node === "string" && + typeof require("http").createServer === "function" && + "node"; + } + }()); + local.global = local.modeJs === "browser" + ? window + : global; + local.global.utility2_rollup_old = local.global.utility2_rollup; + local.global.utility2_rollup = null; +}()); +/* utility2.rollup.js end */ +/* script-end /assets.utility2.rollup.end.js */ +/* script-end /assets.utility2.rollup.js */ + + + +/* script-begin /assets.utility2.rollup.begin.js */ +/* utility2.rollup.js begin */ +/* istanbul ignore all */ +/*jslint + bitwise: true, + browser: true, + maxerr: 8, + maxlen: 96, + node: true, + nomen: true, + regexp: true, + stupid: true +*/ +(function () { + "use strict"; + var local; + local = {}; + local.modeJs = (function () { + try { + return typeof navigator.userAgent === "string" && + typeof document.querySelector("body") === "object" && + typeof XMLHttpRequest.prototype.open === "function" && + "browser"; + } catch (errorCaughtBrowser) { + return module.exports && + typeof process.versions.node === "string" && + typeof require("http").createServer === "function" && + "node"; + } + }()); + local.global = local.modeJs === "browser" + ? window + : global; + local.local = local.global.utility2_rollup = local.global.utility2_rollup_old || local; +}()); +/* script-end /assets.utility2.rollup.begin.js */ + + + +/* script-begin local._stateInit */ +(function () { + "use strict"; + var local; + local = (typeof window === "object" && window && window.utility2_rollup) || + global.utility2_rollup; + local.local = local; +/* jslint-ignore-begin */ +local._stateInit({"utility2":{"assetsDict":{"/assets.index.template.html":"\n\n\n\n\n{{env.npm_package_name}} (v{{env.npm_package_version}})\n\n\n\n\n\n

\n\n {{env.npm_package_name}} (v{{env.npm_package_version}})\n\n

\n

{{env.npm_package_description}}

\n\n\n\n\n\n\n\n\n\n\n\n\n\n
\n [ this app was created with\n utility2\n ]\n
\n\n\n"},"env":{"NODE_ENV":"test","npm_package_description":"#### basic api documentation for [debowerify (v1.5.0)](https://github.com/eugeneware/debowerify#readme) [![npm package](https://img.shields.io/npm/v/npmdoc-debowerify.svg?style=flat-square)](https://www.npmjs.org/package/npmdoc-debowerify) [![travis-ci.org build-status](https://api.travis-ci.org/npmdoc/node-npmdoc-debowerify.svg)](https://travis-ci.org/npmdoc/node-npmdoc-debowerify)","npm_package_homepage":"https://github.com/npmdoc/node-npmdoc-debowerify","npm_package_name":"npmdoc-debowerify","npm_package_nameAlias":"npmdoc_debowerify","npm_package_version":"0.0.2"}}}); +/* jslint-ignore-end */ +}()); +/* script-end local._stateInit */ + + + +/* script-begin /assets.lib.js */ +/* istanbul instrument in package npmdoc_debowerify */ +/*jslint + bitwise: true, + browser: true, + maxerr: 8, + maxlen: 96, + node: true, + nomen: true, + regexp: true, + stupid: true +*/ +(function () { + 'use strict'; + var local; + + + + // run shared js-env code - init-before + (function () { + // init local + local = {}; + // init modeJs + local.modeJs = (function () { + try { + return typeof navigator.userAgent === 'string' && + typeof document.querySelector('body') === 'object' && + typeof XMLHttpRequest.prototype.open === 'function' && + 'browser'; + } catch (errorCaughtBrowser) { + return module.exports && + typeof process.versions.node === 'string' && + typeof require('http').createServer === 'function' && + 'node'; + } + }()); + // init global + local.global = local.modeJs === 'browser' + ? window + : global; + // init utility2_rollup + local = local.global.utility2_rollup || local; + // init lib + local.local = local.npmdoc_debowerify = local; + // init exports + if (local.modeJs === 'browser') { + local.global.utility2_npmdoc_debowerify = local; + } else { + module.exports = local; + module.exports.__dirname = __dirname; + module.exports.module = module; + } + }()); +}()); +/* script-end /assets.lib.js */ + + + +/* script-begin /assets.example.js */ +/* +example.js + +quickstart example + +instruction + 1. save this script as example.js + 2. run the shell command: + $ npm install npmdoc-debowerify && PORT=8081 node example.js + 3. play with the browser-demo on http://127.0.0.1:8081 +*/ + + + +/* istanbul instrument in package npmdoc_debowerify */ +/*jslint + bitwise: true, + browser: true, + maxerr: 8, + maxlen: 96, + node: true, + nomen: true, + regexp: true, + stupid: true +*/ +(function () { + 'use strict'; + var local; + + + + // run shared js-env code - init-before + (function () { + // init local + local = {}; + // init modeJs + local.modeJs = (function () { + try { + return typeof navigator.userAgent === 'string' && + typeof document.querySelector('body') === 'object' && + typeof XMLHttpRequest.prototype.open === 'function' && + 'browser'; + } catch (errorCaughtBrowser) { + return module.exports && + typeof process.versions.node === 'string' && + typeof require('http').createServer === 'function' && + 'node'; + } + }()); + // init global + local.global = local.modeJs === 'browser' + ? window + : global; + // init utility2_rollup + local = local.global.utility2_rollup || (local.modeJs === 'browser' + ? local.global.utility2_npmdoc_debowerify + : global.utility2_moduleExports); + // export local + local.global.local = local; + }()); + switch (local.modeJs) { + + + + // init-after + // run browser js-env code - init-after + /* istanbul ignore next */ + case 'browser': + local.testRunBrowser = function (event) { + if (!event || (event && + event.currentTarget && + event.currentTarget.className && + event.currentTarget.className.includes && + event.currentTarget.className.includes('onreset'))) { + // reset output + Array.from( + document.querySelectorAll('body > .resettable') + ).forEach(function (element) { + switch (element.tagName) { + case 'INPUT': + case 'TEXTAREA': + element.value = ''; + break; + default: + element.textContent = ''; + } + }); + } + switch (event && event.currentTarget && event.currentTarget.id) { + case 'testRunButton1': + // show tests + if (document.querySelector('#testReportDiv1').style.display === 'none') { + document.querySelector('#testReportDiv1').style.display = 'block'; + document.querySelector('#testRunButton1').textContent = + 'hide internal test'; + local.modeTest = true; + local.testRunDefault(local); + // hide tests + } else { + document.querySelector('#testReportDiv1').style.display = 'none'; + document.querySelector('#testRunButton1').textContent = 'run internal test'; + } + break; + // custom-case + default: + break; + } + if (document.querySelector('#inputTextareaEval1') && (!event || (event && + event.currentTarget && + event.currentTarget.className && + event.currentTarget.className.includes && + event.currentTarget.className.includes('oneval')))) { + // try to eval input-code + try { + /*jslint evil: true*/ + eval(document.querySelector('#inputTextareaEval1').value); + } catch (errorCaught) { + console.error(errorCaught); + } + } + }; + // log stderr and stdout to #outputTextareaStdout1 + ['error', 'log'].forEach(function (key) { + console[key + '_original'] = console[key]; + console[key] = function () { + var element; + console[key + '_original'].apply(console, arguments); + element = document.querySelector('#outputTextareaStdout1'); + if (!element) { + return; + } + // append text to #outputTextareaStdout1 + element.value += Array.from(arguments).map(function (arg) { + return typeof arg === 'string' + ? arg + : JSON.stringify(arg, null, 4); + }).join(' ') + '\n'; + // scroll textarea to bottom + element.scrollTop = element.scrollHeight; + }; + }); + // init event-handling + ['change', 'click', 'keyup'].forEach(function (event) { + Array.from(document.querySelectorAll('.on' + event)).forEach(function (element) { + element.addEventListener(event, local.testRunBrowser); + }); + }); + // run tests + local.testRunBrowser(); + break; + + + + // run node js-env code - init-after + /* istanbul ignore next */ + case 'node': + // export local + module.exports = local; + // require modules + local.fs = require('fs'); + local.http = require('http'); + local.url = require('url'); + // init assets + local.assetsDict = local.assetsDict || {}; + /* jslint-ignore-begin */ + local.assetsDict['/assets.index.template.html'] = '\ +\n\ +\n\ +\n\ +\n\ +\n\ +{{env.npm_package_name}} (v{{env.npm_package_version}})\n\ +\n\ +\n\ +\n\ +\n\ +\n\ +

\n\ +\n\ + {{env.npm_package_name}} (v{{env.npm_package_version}})\n\ +\n\ +

\n\ +

{{env.npm_package_description}}

\n\ +\n\ +\n\ +\n\ +\n\ +\n\ +\n\ +\n\ +\n\ +\n\ +\n\ +\n\ +\n\ +\n\ +
\n\ + [ this app was created with\n\ + utility2\n\ + ]\n\ +
\n\ +\n\ +\n\ +'; + /* jslint-ignore-end */ + if (local.templateRender) { + local.assetsDict['/'] = local.templateRender( + local.assetsDict['/assets.index.template.html'], + { + env: local.objectSetDefault(local.env, { + npm_package_description: 'the greatest app in the world!', + npm_package_name: 'my-app', + npm_package_nameAlias: 'my_app', + npm_package_version: '0.0.1' + }) + } + ); + } else { + local.assetsDict['/'] = local.assetsDict['/assets.index.template.html'] + .replace((/\{\{env\.(\w+?)\}\}/g), function (match0, match1) { + // jslint-hack + String(match0); + switch (match1) { + case 'npm_package_description': + return 'the greatest app in the world!'; + case 'npm_package_name': + return 'my-app'; + case 'npm_package_nameAlias': + return 'my_app'; + case 'npm_package_version': + return '0.0.1'; + } + }); + } + // run the cli + if (local.global.utility2_rollup || module !== require.main) { + break; + } + local.assetsDict['/assets.example.js'] = + local.assetsDict['/assets.example.js'] || + local.fs.readFileSync(__filename, 'utf8'); + // bug-workaround - long $npm_package_buildCustomOrg + /* jslint-ignore-begin */ + local.assetsDict['/assets.npmdoc_debowerify.rollup.js'] = + local.assetsDict['/assets.npmdoc_debowerify.rollup.js'] || + local.fs.readFileSync( + local.npmdoc_debowerify.__dirname + '/lib.npmdoc_debowerify.js', + 'utf8' + ).replace((/^#!/), '//'); + /* jslint-ignore-end */ + local.assetsDict['/favicon.ico'] = local.assetsDict['/favicon.ico'] || ''; + // if $npm_config_timeout_exit exists, + // then exit this process after $npm_config_timeout_exit ms + if (Number(process.env.npm_config_timeout_exit)) { + setTimeout(process.exit, Number(process.env.npm_config_timeout_exit)); + } + // start server + if (local.global.utility2_serverHttp1) { + break; + } + process.env.PORT = process.env.PORT || '8081'; + console.error('server starting on port ' + process.env.PORT); + local.http.createServer(function (request, response) { + request.urlParsed = local.url.parse(request.url); + if (local.assetsDict[request.urlParsed.pathname] !== undefined) { + response.end(local.assetsDict[request.urlParsed.pathname]); + return; + } + response.statusCode = 404; + response.end(); + }).listen(process.env.PORT); + break; + } +}()); +/* script-end /assets.example.js */ + + + +/* script-begin /assets.test.js */ +/* istanbul instrument in package npmdoc_debowerify */ +/*jslint + bitwise: true, + browser: true, + maxerr: 8, + maxlen: 96, + node: true, + nomen: true, + regexp: true, + stupid: true +*/ +(function () { + 'use strict'; + var local; + + + + // run shared js-env code - init-before + (function () { + // init local + local = {}; + // init modeJs + local.modeJs = (function () { + try { + return typeof navigator.userAgent === 'string' && + typeof document.querySelector('body') === 'object' && + typeof XMLHttpRequest.prototype.open === 'function' && + 'browser'; + } catch (errorCaughtBrowser) { + return module.exports && + typeof process.versions.node === 'string' && + typeof require('http').createServer === 'function' && + 'node'; + } + }()); + // init global + local.global = local.modeJs === 'browser' + ? window + : global; + switch (local.modeJs) { + // re-init local from window.local + case 'browser': + local = local.global.utility2.objectSetDefault( + local.global.utility2_rollup || local.global.local, + local.global.utility2 + ); + break; + // re-init local from example.js + case 'node': + local = (local.global.utility2_rollup || require('utility2')) + .requireReadme(); + break; + } + // export local + local.global.local = local; + }()); + + + + // run shared js-env code - function + (function () { + return; + }()); + switch (local.modeJs) { + + + + // run browser js-env code - function + case 'browser': + break; + + + + // run node js-env code - function + case 'node': + break; + } + + + + // run shared js-env code - init-after + (function () { + return; + }()); + switch (local.modeJs) { + + + + // run browser js-env code - init-after + case 'browser': + local.testCase_browser_nullCase = local.testCase_browser_nullCase || function ( + options, + onError + ) { + /* + * this function will test browsers's null-case handling-behavior-behavior + */ + onError(null, options); + }; + + // run tests + local.nop(local.modeTest && + document.querySelector('#testRunButton1') && + document.querySelector('#testRunButton1').click()); + break; + + + + // run node js-env code - init-after + /* istanbul ignore next */ + case 'node': + local.testCase_buildApidoc_default = local.testCase_buildApidoc_default || function ( + options, + onError + ) { + /* + * this function will test buildApidoc's default handling-behavior-behavior + */ + options = { modulePathList: module.paths }; + local.buildApidoc(options, onError); + }; + + local.testCase_buildApp_default = local.testCase_buildApp_default || function ( + options, + onError + ) { + /* + * this function will test buildApp's default handling-behavior-behavior + */ + local.testCase_buildReadme_default(options, local.onErrorThrow); + local.testCase_buildLib_default(options, local.onErrorThrow); + local.testCase_buildTest_default(options, local.onErrorThrow); + local.testCase_buildCustomOrg_default(options, local.onErrorThrow); + options = []; + local.buildApp(options, onError); + }; + + local.testCase_buildCustomOrg_default = local.testCase_buildCustomOrg_default || + function (options, onError) { + /* + * this function will test buildCustomOrg's default handling-behavior + */ + options = {}; + local.buildCustomOrg(options, onError); + }; + + local.testCase_buildLib_default = local.testCase_buildLib_default || function ( + options, + onError + ) { + /* + * this function will test buildLib's default handling-behavior + */ + options = {}; + local.buildLib(options, onError); + }; + + local.testCase_buildReadme_default = local.testCase_buildReadme_default || function ( + options, + onError + ) { + /* + * this function will test buildReadme's default handling-behavior-behavior + */ + options = {}; + local.buildReadme(options, onError); + }; + + local.testCase_buildTest_default = local.testCase_buildTest_default || function ( + options, + onError + ) { + /* + * this function will test buildTest's default handling-behavior + */ + options = {}; + local.buildTest(options, onError); + }; + + local.testCase_webpage_default = local.testCase_webpage_default || function ( + options, + onError + ) { + /* + * this function will test webpage's default handling-behavior + */ + options = { modeCoverageMerge: true, url: local.serverLocalHost + '?modeTest=1' }; + local.browserTest(options, onError); + }; + + // run test-server + local.testRunServer(local); + break; + } +}()); +/* script-end /assets.test.js */ + + + +/* script-begin /assets.utility2.rollup.end.js */ +(function () { + "use strict"; + var local; + local = {}; + local.modeJs = (function () { + try { + return typeof navigator.userAgent === "string" && + typeof document.querySelector("body") === "object" && + typeof XMLHttpRequest.prototype.open === "function" && + "browser"; + } catch (errorCaughtBrowser) { + return module.exports && + typeof process.versions.node === "string" && + typeof require("http").createServer === "function" && + "node"; + } + }()); + local.global = local.modeJs === "browser" + ? window + : global; + local.global.utility2_rollup_old = local.global.utility2_rollup; + local.global.utility2_rollup = null; +}()); +/* utility2.rollup.js end */ +/* script-end /assets.utility2.rollup.end.js */ diff --git a/build/app/assets.example.js b/build/app/assets.example.js new file mode 100644 index 0000000..43b2257 --- /dev/null +++ b/build/app/assets.example.js @@ -0,0 +1,326 @@ +/* +example.js + +quickstart example + +instruction + 1. save this script as example.js + 2. run the shell command: + $ npm install npmdoc-debowerify && PORT=8081 node example.js + 3. play with the browser-demo on http://127.0.0.1:8081 +*/ + + + +/* istanbul instrument in package npmdoc_debowerify */ +/*jslint + bitwise: true, + browser: true, + maxerr: 8, + maxlen: 96, + node: true, + nomen: true, + regexp: true, + stupid: true +*/ +(function () { + 'use strict'; + var local; + + + + // run shared js-env code - init-before + (function () { + // init local + local = {}; + // init modeJs + local.modeJs = (function () { + try { + return typeof navigator.userAgent === 'string' && + typeof document.querySelector('body') === 'object' && + typeof XMLHttpRequest.prototype.open === 'function' && + 'browser'; + } catch (errorCaughtBrowser) { + return module.exports && + typeof process.versions.node === 'string' && + typeof require('http').createServer === 'function' && + 'node'; + } + }()); + // init global + local.global = local.modeJs === 'browser' + ? window + : global; + // init utility2_rollup + local = local.global.utility2_rollup || (local.modeJs === 'browser' + ? local.global.utility2_npmdoc_debowerify + : global.utility2_moduleExports); + // export local + local.global.local = local; + }()); + switch (local.modeJs) { + + + + // init-after + // run browser js-env code - init-after + /* istanbul ignore next */ + case 'browser': + local.testRunBrowser = function (event) { + if (!event || (event && + event.currentTarget && + event.currentTarget.className && + event.currentTarget.className.includes && + event.currentTarget.className.includes('onreset'))) { + // reset output + Array.from( + document.querySelectorAll('body > .resettable') + ).forEach(function (element) { + switch (element.tagName) { + case 'INPUT': + case 'TEXTAREA': + element.value = ''; + break; + default: + element.textContent = ''; + } + }); + } + switch (event && event.currentTarget && event.currentTarget.id) { + case 'testRunButton1': + // show tests + if (document.querySelector('#testReportDiv1').style.display === 'none') { + document.querySelector('#testReportDiv1').style.display = 'block'; + document.querySelector('#testRunButton1').textContent = + 'hide internal test'; + local.modeTest = true; + local.testRunDefault(local); + // hide tests + } else { + document.querySelector('#testReportDiv1').style.display = 'none'; + document.querySelector('#testRunButton1').textContent = 'run internal test'; + } + break; + // custom-case + default: + break; + } + if (document.querySelector('#inputTextareaEval1') && (!event || (event && + event.currentTarget && + event.currentTarget.className && + event.currentTarget.className.includes && + event.currentTarget.className.includes('oneval')))) { + // try to eval input-code + try { + /*jslint evil: true*/ + eval(document.querySelector('#inputTextareaEval1').value); + } catch (errorCaught) { + console.error(errorCaught); + } + } + }; + // log stderr and stdout to #outputTextareaStdout1 + ['error', 'log'].forEach(function (key) { + console[key + '_original'] = console[key]; + console[key] = function () { + var element; + console[key + '_original'].apply(console, arguments); + element = document.querySelector('#outputTextareaStdout1'); + if (!element) { + return; + } + // append text to #outputTextareaStdout1 + element.value += Array.from(arguments).map(function (arg) { + return typeof arg === 'string' + ? arg + : JSON.stringify(arg, null, 4); + }).join(' ') + '\n'; + // scroll textarea to bottom + element.scrollTop = element.scrollHeight; + }; + }); + // init event-handling + ['change', 'click', 'keyup'].forEach(function (event) { + Array.from(document.querySelectorAll('.on' + event)).forEach(function (element) { + element.addEventListener(event, local.testRunBrowser); + }); + }); + // run tests + local.testRunBrowser(); + break; + + + + // run node js-env code - init-after + /* istanbul ignore next */ + case 'node': + // export local + module.exports = local; + // require modules + local.fs = require('fs'); + local.http = require('http'); + local.url = require('url'); + // init assets + local.assetsDict = local.assetsDict || {}; + /* jslint-ignore-begin */ + local.assetsDict['/assets.index.template.html'] = '\ +\n\ +\n\ +\n\ +\n\ +\n\ +{{env.npm_package_name}} (v{{env.npm_package_version}})\n\ +\n\ +\n\ +\n\ +\n\ +\n\ +

\n\ +\n\ + {{env.npm_package_name}} (v{{env.npm_package_version}})\n\ +\n\ +

\n\ +

{{env.npm_package_description}}

\n\ +\n\ +\n\ +\n\ +\n\ +\n\ +\n\ +\n\ +\n\ +\n\ +\n\ +\n\ +\n\ +\n\ +
\n\ + [ this app was created with\n\ + utility2\n\ + ]\n\ +
\n\ +\n\ +\n\ +'; + /* jslint-ignore-end */ + if (local.templateRender) { + local.assetsDict['/'] = local.templateRender( + local.assetsDict['/assets.index.template.html'], + { + env: local.objectSetDefault(local.env, { + npm_package_description: 'the greatest app in the world!', + npm_package_name: 'my-app', + npm_package_nameAlias: 'my_app', + npm_package_version: '0.0.1' + }) + } + ); + } else { + local.assetsDict['/'] = local.assetsDict['/assets.index.template.html'] + .replace((/\{\{env\.(\w+?)\}\}/g), function (match0, match1) { + // jslint-hack + String(match0); + switch (match1) { + case 'npm_package_description': + return 'the greatest app in the world!'; + case 'npm_package_name': + return 'my-app'; + case 'npm_package_nameAlias': + return 'my_app'; + case 'npm_package_version': + return '0.0.1'; + } + }); + } + // run the cli + if (local.global.utility2_rollup || module !== require.main) { + break; + } + local.assetsDict['/assets.example.js'] = + local.assetsDict['/assets.example.js'] || + local.fs.readFileSync(__filename, 'utf8'); + // bug-workaround - long $npm_package_buildCustomOrg + /* jslint-ignore-begin */ + local.assetsDict['/assets.npmdoc_debowerify.rollup.js'] = + local.assetsDict['/assets.npmdoc_debowerify.rollup.js'] || + local.fs.readFileSync( + local.npmdoc_debowerify.__dirname + '/lib.npmdoc_debowerify.js', + 'utf8' + ).replace((/^#!/), '//'); + /* jslint-ignore-end */ + local.assetsDict['/favicon.ico'] = local.assetsDict['/favicon.ico'] || ''; + // if $npm_config_timeout_exit exists, + // then exit this process after $npm_config_timeout_exit ms + if (Number(process.env.npm_config_timeout_exit)) { + setTimeout(process.exit, Number(process.env.npm_config_timeout_exit)); + } + // start server + if (local.global.utility2_serverHttp1) { + break; + } + process.env.PORT = process.env.PORT || '8081'; + console.error('server starting on port ' + process.env.PORT); + local.http.createServer(function (request, response) { + request.urlParsed = local.url.parse(request.url); + if (local.assetsDict[request.urlParsed.pathname] !== undefined) { + response.end(local.assetsDict[request.urlParsed.pathname]); + return; + } + response.statusCode = 404; + response.end(); + }).listen(process.env.PORT); + break; + } +}()); diff --git a/build/app/assets.npmdoc_debowerify.js b/build/app/assets.npmdoc_debowerify.js new file mode 100644 index 0000000..0a480c2 --- /dev/null +++ b/build/app/assets.npmdoc_debowerify.js @@ -0,0 +1,53 @@ +/* istanbul instrument in package npmdoc_debowerify */ +/*jslint + bitwise: true, + browser: true, + maxerr: 8, + maxlen: 96, + node: true, + nomen: true, + regexp: true, + stupid: true +*/ +(function () { + 'use strict'; + var local; + + + + // run shared js-env code - init-before + (function () { + // init local + local = {}; + // init modeJs + local.modeJs = (function () { + try { + return typeof navigator.userAgent === 'string' && + typeof document.querySelector('body') === 'object' && + typeof XMLHttpRequest.prototype.open === 'function' && + 'browser'; + } catch (errorCaughtBrowser) { + return module.exports && + typeof process.versions.node === 'string' && + typeof require('http').createServer === 'function' && + 'node'; + } + }()); + // init global + local.global = local.modeJs === 'browser' + ? window + : global; + // init utility2_rollup + local = local.global.utility2_rollup || local; + // init lib + local.local = local.npmdoc_debowerify = local; + // init exports + if (local.modeJs === 'browser') { + local.global.utility2_npmdoc_debowerify = local; + } else { + module.exports = local; + module.exports.__dirname = __dirname; + module.exports.module = module; + } + }()); +}()); diff --git a/build/app/assets.npmdoc_debowerify.rollup.js b/build/app/assets.npmdoc_debowerify.rollup.js new file mode 100644 index 0000000..0a480c2 --- /dev/null +++ b/build/app/assets.npmdoc_debowerify.rollup.js @@ -0,0 +1,53 @@ +/* istanbul instrument in package npmdoc_debowerify */ +/*jslint + bitwise: true, + browser: true, + maxerr: 8, + maxlen: 96, + node: true, + nomen: true, + regexp: true, + stupid: true +*/ +(function () { + 'use strict'; + var local; + + + + // run shared js-env code - init-before + (function () { + // init local + local = {}; + // init modeJs + local.modeJs = (function () { + try { + return typeof navigator.userAgent === 'string' && + typeof document.querySelector('body') === 'object' && + typeof XMLHttpRequest.prototype.open === 'function' && + 'browser'; + } catch (errorCaughtBrowser) { + return module.exports && + typeof process.versions.node === 'string' && + typeof require('http').createServer === 'function' && + 'node'; + } + }()); + // init global + local.global = local.modeJs === 'browser' + ? window + : global; + // init utility2_rollup + local = local.global.utility2_rollup || local; + // init lib + local.local = local.npmdoc_debowerify = local; + // init exports + if (local.modeJs === 'browser') { + local.global.utility2_npmdoc_debowerify = local; + } else { + module.exports = local; + module.exports.__dirname = __dirname; + module.exports.module = module; + } + }()); +}()); diff --git a/build/app/assets.test.js b/build/app/assets.test.js new file mode 100644 index 0000000..2d915cd --- /dev/null +++ b/build/app/assets.test.js @@ -0,0 +1,195 @@ +/* istanbul instrument in package npmdoc_debowerify */ +/*jslint + bitwise: true, + browser: true, + maxerr: 8, + maxlen: 96, + node: true, + nomen: true, + regexp: true, + stupid: true +*/ +(function () { + 'use strict'; + var local; + + + + // run shared js-env code - init-before + (function () { + // init local + local = {}; + // init modeJs + local.modeJs = (function () { + try { + return typeof navigator.userAgent === 'string' && + typeof document.querySelector('body') === 'object' && + typeof XMLHttpRequest.prototype.open === 'function' && + 'browser'; + } catch (errorCaughtBrowser) { + return module.exports && + typeof process.versions.node === 'string' && + typeof require('http').createServer === 'function' && + 'node'; + } + }()); + // init global + local.global = local.modeJs === 'browser' + ? window + : global; + switch (local.modeJs) { + // re-init local from window.local + case 'browser': + local = local.global.utility2.objectSetDefault( + local.global.utility2_rollup || local.global.local, + local.global.utility2 + ); + break; + // re-init local from example.js + case 'node': + local = (local.global.utility2_rollup || require('utility2')) + .requireReadme(); + break; + } + // export local + local.global.local = local; + }()); + + + + // run shared js-env code - function + (function () { + return; + }()); + switch (local.modeJs) { + + + + // run browser js-env code - function + case 'browser': + break; + + + + // run node js-env code - function + case 'node': + break; + } + + + + // run shared js-env code - init-after + (function () { + return; + }()); + switch (local.modeJs) { + + + + // run browser js-env code - init-after + case 'browser': + local.testCase_browser_nullCase = local.testCase_browser_nullCase || function ( + options, + onError + ) { + /* + * this function will test browsers's null-case handling-behavior-behavior + */ + onError(null, options); + }; + + // run tests + local.nop(local.modeTest && + document.querySelector('#testRunButton1') && + document.querySelector('#testRunButton1').click()); + break; + + + + // run node js-env code - init-after + /* istanbul ignore next */ + case 'node': + local.testCase_buildApidoc_default = local.testCase_buildApidoc_default || function ( + options, + onError + ) { + /* + * this function will test buildApidoc's default handling-behavior-behavior + */ + options = { modulePathList: module.paths }; + local.buildApidoc(options, onError); + }; + + local.testCase_buildApp_default = local.testCase_buildApp_default || function ( + options, + onError + ) { + /* + * this function will test buildApp's default handling-behavior-behavior + */ + local.testCase_buildReadme_default(options, local.onErrorThrow); + local.testCase_buildLib_default(options, local.onErrorThrow); + local.testCase_buildTest_default(options, local.onErrorThrow); + local.testCase_buildCustomOrg_default(options, local.onErrorThrow); + options = []; + local.buildApp(options, onError); + }; + + local.testCase_buildCustomOrg_default = local.testCase_buildCustomOrg_default || + function (options, onError) { + /* + * this function will test buildCustomOrg's default handling-behavior + */ + options = {}; + local.buildCustomOrg(options, onError); + }; + + local.testCase_buildLib_default = local.testCase_buildLib_default || function ( + options, + onError + ) { + /* + * this function will test buildLib's default handling-behavior + */ + options = {}; + local.buildLib(options, onError); + }; + + local.testCase_buildReadme_default = local.testCase_buildReadme_default || function ( + options, + onError + ) { + /* + * this function will test buildReadme's default handling-behavior-behavior + */ + options = {}; + local.buildReadme(options, onError); + }; + + local.testCase_buildTest_default = local.testCase_buildTest_default || function ( + options, + onError + ) { + /* + * this function will test buildTest's default handling-behavior + */ + options = {}; + local.buildTest(options, onError); + }; + + local.testCase_webpage_default = local.testCase_webpage_default || function ( + options, + onError + ) { + /* + * this function will test webpage's default handling-behavior + */ + options = { modeCoverageMerge: true, url: local.serverLocalHost + '?modeTest=1' }; + local.browserTest(options, onError); + }; + + // run test-server + local.testRunServer(local); + break; + } +}()); diff --git a/build/app/assets.utility2.rollup.js b/build/app/assets.utility2.rollup.js new file mode 100644 index 0000000..97ac6c5 --- /dev/null +++ b/build/app/assets.utility2.rollup.js @@ -0,0 +1,20036 @@ +/* this rollup was created with utility2 (https://github.com/kaizhu256/node-utility2) */ + + + +/* script-begin /assets.utility2.rollup.begin.js */ +/* utility2.rollup.js begin */ +/* istanbul ignore all */ +/*jslint + bitwise: true, + browser: true, + maxerr: 8, + maxlen: 96, + node: true, + nomen: true, + regexp: true, + stupid: true +*/ +(function () { + "use strict"; + var local; + local = {}; + local.modeJs = (function () { + try { + return typeof navigator.userAgent === "string" && + typeof document.querySelector("body") === "object" && + typeof XMLHttpRequest.prototype.open === "function" && + "browser"; + } catch (errorCaughtBrowser) { + return module.exports && + typeof process.versions.node === "string" && + typeof require("http").createServer === "function" && + "node"; + } + }()); + local.global = local.modeJs === "browser" + ? window + : global; + local.local = local.global.utility2_rollup = local.global.utility2_rollup_old || local; +}()); +/* script-end /assets.utility2.rollup.begin.js */ + + + +/* script-begin /assets.utility2.lib.apidoc.js */ +///usr/bin/env node +/* istanbul instrument in package apidoc */ +/*jslint + bitwise: true, + browser: true, + maxerr: 8, + maxlen: 96, + node: true, + nomen: true, + regexp: true, + stupid: true +*/ +(function () { + 'use strict'; + var local; + + + + // run shared js-env code - init-before + (function () { + // init local + local = {}; + // init modeJs + local.modeJs = (function () { + try { + return typeof navigator.userAgent === 'string' && + typeof document.querySelector('body') === 'object' && + typeof XMLHttpRequest.prototype.open === 'function' && + 'browser'; + } catch (errorCaughtBrowser) { + return module.exports && + typeof process.versions.node === 'string' && + typeof require('http').createServer === 'function' && + 'node'; + } + }()); + // init global + local.global = local.modeJs === 'browser' + ? window + : global; + // init utility2_rollup + local = local.global.utility2_rollup || local; + // init lib + local.local = local.apidoc = local; + // init exports + if (local.modeJs === 'browser') { + local.global.utility2_apidoc = local; + } else { + module.exports = local; + module.exports.__dirname = __dirname; + module.exports.module = module; + } + }()); + + + + // run shared js-env code - function-before + /* istanbul ignore next */ + (function () { + local.assert = function (passed, message) { + /* + * this function will throw the error message if passed is falsey + */ + var error; + if (passed) { + return; + } + error = message && message.message + // if message is an error-object, then leave it as is + ? message + : new Error(typeof message === 'string' + // if message is a string, then leave it as is + ? message + // else JSON.stringify message + : JSON.stringify(message)); + throw error; + }; + + local.moduleDirname = function (module, modulePathList) { + /* + * this function will search modulePathList for the module's __dirname + */ + var result, tmp; + // search process.cwd() + if (!module || module === '.' || module.indexOf('/') >= 0) { + return require('path').resolve(process.cwd(), module || ''); + } + // search modulePathList + ['node_modules'] + .concat(modulePathList) + .concat(require('module').globalPaths) + .concat([process.env.HOME + '/node_modules', '/usr/local/lib/node_modules']) + .some(function (modulePath) { + try { + tmp = require('path').resolve(process.cwd(), modulePath + '/' + module); + result = require('fs').statSync(tmp).isDirectory() && tmp; + return result; + } catch (ignore) { + } + }); + return result || ''; + }; + + local.nop = function () { + /* + * this function will do nothing + */ + return; + }; + + local.objectSetDefault = function (arg, defaults, depth) { + /* + * this function will recursively set defaults for undefined-items in the arg + */ + arg = arg || {}; + defaults = defaults || {}; + Object.keys(defaults).forEach(function (key) { + var arg2, defaults2; + arg2 = arg[key]; + // handle misbehaving getter + try { + defaults2 = defaults[key]; + } catch (ignore) { + } + if (defaults2 === undefined) { + return; + } + // init arg[key] to default value defaults[key] + if (!arg2) { + arg[key] = defaults2; + return; + } + // if arg2 and defaults2 are both non-null and non-array objects, + // then recurse with arg2 and defaults2 + if (depth > 1 && + // arg2 is a non-null and non-array object + arg2 && + typeof arg2 === 'object' && + !Array.isArray(arg2) && + // defaults2 is a non-null and non-array object + defaults2 && + typeof defaults2 === 'object' && + !Array.isArray(defaults2)) { + // recurse + local.objectSetDefault(arg2, defaults2, depth - 1); + } + }); + return arg; + }; + + local.stringHtmlSafe = function (text) { + /* + * this function will make the text html-safe + */ + // new RegExp('[' + '"&\'<>'.split('').sort().join('') + ']', 'g') + return text.replace((/["&'<>]/g), function (match0) { + return '&#x' + match0.charCodeAt(0).toString(16) + ';'; + }); + }; + + local.templateRender = function (template, dict) { + /* + * this function will render the template with the given dict + */ + var argList, getValue, match, renderPartial, rgx, value; + dict = dict || {}; + getValue = function (key) { + argList = key.split(' '); + value = dict; + // iteratively lookup nested values in the dict + argList[0].split('.').forEach(function (key) { + value = value && value[key]; + }); + return value; + }; + renderPartial = function (match0, helper, key, partial) { + switch (helper) { + case 'each': + value = getValue(key); + return Array.isArray(value) + ? value.map(function (dict) { + // recurse with partial + return local.templateRender(partial, dict); + }).join('') + : ''; + case 'if': + partial = partial.split('{{#unless ' + key + '}}'); + partial = getValue(key) + ? partial[0] + // handle 'unless' case + : partial.slice(1).join('{{#unless ' + key + '}}'); + // recurse with partial + return local.templateRender(partial, dict); + case 'unless': + return getValue(key) + ? '' + // recurse with partial + : local.templateRender(partial, dict); + default: + // recurse with partial + return match0[0] + local.templateRender(match0.slice(1), dict); + } + }; + // render partials + rgx = (/\{\{#(\w+) ([^}]+?)\}\}/g); + template = template || ''; + for (match = rgx.exec(template); match; match = rgx.exec(template)) { + rgx.lastIndex += 1 - match[0].length; + template = template.replace( + new RegExp('\\{\\{#(' + match[1] + ') (' + match[2] + + ')\\}\\}([\\S\\s]*?)\\{\\{/' + match[1] + ' ' + match[2] + + '\\}\\}'), + renderPartial + ); + } + // search for keys in the template + return template.replace((/\{\{[^}]+?\}\}/g), function (match0) { + getValue(match0.slice(2, -2)); + if (value === undefined) { + return match0; + } + argList.slice(1).forEach(function (arg) { + switch (arg) { + case 'alphanumeric': + value = value.replace((/\W/g), '_'); + break; + case 'decodeURIComponent': + value = decodeURIComponent(value); + break; + case 'encodeURIComponent': + value = encodeURIComponent(value); + break; + case 'htmlSafe': + value = value.replace((/["&'<>]/g), function (match0) { + return '&#x' + match0.charCodeAt(0).toString(16) + ';'; + }); + break; + case 'jsonStringify': + value = JSON.stringify(value); + break; + case 'jsonStringify4': + value = JSON.stringify(value, null, 4); + break; + case 'markdownCodeSafe': + value = value.replace((/`/g), '\''); + break; + default: + value = value[arg](); + break; + } + }); + return String(value); + }); + }; + + local.tryCatchOnError = function (fnc, onError) { + /* + * this function will try to run the fnc in a try-catch block, + * else call onError with the errorCaught + */ + // validate onError + local.assert(typeof onError === 'function', typeof onError); + try { + // reset errorCaught + local._debugTryCatchErrorCaught = null; + return fnc(); + } catch (errorCaught) { + // debug errorCaught + local._debugTryCatchErrorCaught = errorCaught; + return onError(errorCaught); + } + }; + }()); + + + + // run shared js-env code - init-before +/* jslint-ignore-begin */ +local.templateApidocHtml = '\ +
\n\ +\n\ +

api documentation for\n\ + {{env.npm_package_name}} (v{{env.npm_package_version}})\n\ +

\n\ +

{{env.npm_package_description}}

\n\ +

table of contents

    \n\ + {{#each moduleList}}\n\ +
  1. module {{name}}
      \n\ + {{#each elementList}}\n\ +
    1. \n\ + {{#if source}}\n\ + \n\ + {{name}}\n\ + {{signature}}\n\ + \n\ + {{#unless source}}\n\ + {{name}}\n\ + {{/if source}}\n\ +
    2. \n\ + {{/each elementList}}\n\ +
  2. \n\ + {{/each moduleList}}\n\ +
\n\ +{{#each moduleList}}\n\ +
\n\ +

module {{name}}

\n\ + {{#each elementList}}\n\ + {{#if source}}\n\ +

\n\ + \n\ + {{name}}\n\ + {{signature}}\n\ + \n\ +

\n\ +
    \n\ +
  • description and source-code
    {{source}}
  • \n\ +
  • example usage
    {{example}}
  • \n\ +
\n\ + {{/if source}}\n\ + {{/each elementList}}\n\ +
\n\ +{{/each moduleList}}\n\ +
\n\ + [ this document was created with\n\ + utility2\n\ + ]\n\ +
\n\ +
\n\ +'; +/* jslint-ignore-end */ + + + + // run shared js-env code - function + (function () { + local.apidocCreate = function (options) { + /* + * this function will create the apidoc from options.dir + */ + var elementCreate, module, moduleMain, readExample, tmp, toString, trimLeft; + elementCreate = function (module, prefix, key) { + /* + * this function will create the apidoc-element in the given module + */ + var element; + if (options.modeNoApidoc) { + return element; + } + element = {}; + element.moduleName = prefix.split('.'); + // handle case where module is a function + if (element.moduleName.slice(-1)[0] === key) { + element.moduleName.pop(); + } + element.moduleName = element.moduleName.join('.'); + element.id = encodeURIComponent('apidoc.element.' + prefix + '.' + key); + element.typeof = typeof module[key]; + element.name = (element.typeof + ' ' + + element.moduleName + '.' + key) + // handle case where module is a function + .replace('>.<', '><'); + if (element.typeof !== 'function') { + return element; + } + // init source + element.source = trimLeft(toString(module[key])) || 'n/a'; + if (element.source.length > 4096) { + element.source = element.source.slice(0, 4096).trimRight() + ' ...'; + } + element.source = local.stringHtmlSafe(element.source) + .replace((/\([\S\s]*?\)/), function (match0) { + // init signature + element.signature = match0 + .replace((/ *?\/\*[\S\s]*?\*\/ */g), '') + .replace((/,/g), ', ') + .replace((/\s+/g), ' '); + return element.signature; + }) + .replace( + (/( *?\/\*[\S\s]*?\*\/\n)/), + '$1' + ) + .replace((/^function \(/), key + ' = function ('); + // init example + options.exampleList.some(function (example) { + example.replace( + new RegExp('((?:\n.*?){8}\\.)(' + key + ')(\\((?:.*?\n){8})'), + function (match0, match1, match2, match3) { + // jslint-hack + local.nop(match0); + element.example = '...' + trimLeft(local.stringHtmlSafe(match1) + + '' + + local.stringHtmlSafe(match2) + + '' + + local.stringHtmlSafe(match3)).trimRight() + '\n...'; + } + ); + return element.example; + }); + element.example = element.example || 'n/a'; + return element; + }; + readExample = function (file) { + /* + * this function will read the example from the given file + */ + var result; + local.tryCatchOnError(function () { + file = local.path.resolve(options.dir, file); + console.error('apidocCreate - readExample - ' + file); + result = ''; + result = ('\n\n\n\n\n\n\n\n' + + local.fs.readFileSync(file, 'utf8').slice(0, 262144) + + '\n\n\n\n\n\n\n\n').replace((/\r\n*/g), '\n'); + }, console.error); + return result; + }; + toString = function (value) { + /* + * this function will try to return the string form of the value + */ + var result; + local.tryCatchOnError(function () { + result = ''; + result = String(value); + }, console.error); + return result; + }; + trimLeft = function (text) { + /* + * this function will normalize the whitespace around the text + */ + var whitespace; + whitespace = ''; + text.trim().replace((/^ */gm), function (match0) { + if (!whitespace || match0.length < whitespace.length) { + whitespace = match0; + } + }); + text = text.replace(new RegExp('^' + whitespace, 'gm'), ''); + // enforce 128 character column limit + text = text.replace((/^.{128}[^\\\n]+/gm), function (match0) { + return match0.replace((/(.{128}(?:\b|\w+))/g), '$1\n').trimRight(); + }); + return text; + }; + // init options + options.dir = local.moduleDirname( + options.dir, + options.modulePathList || local.module.paths + ); + local.objectSetDefault(options, { + env: { npm_package_description: '' }, + packageJson: JSON.parse(readExample('package.json')), + require: function (file) { + return local.tryCatchOnError(function () { + return require(file); + }, console.error); + } + }); + Object.keys(options.packageJson).forEach(function (key) { + tmp = options.packageJson[key]; + // strip email from npmdoc documentation + // https://github.com/npmdoc/node-npmdoc-hpp/issues/1 + if (tmp) { + if (tmp.email) { + delete tmp.email; + } + if (Array.isArray(tmp)) { + tmp.forEach(function (element) { + if (element && element.email) { + delete element.email; + } + }); + } + } + if (key[0] === '_' || key === 'readme') { + delete options.packageJson[key]; + } else if (typeof tmp === 'string') { + options.env['npm_package_' + key] = tmp; + } + }); + local.objectSetDefault(options, { + blacklistDict: { global: global }, + circularList: [global], + exampleDict: {}, + exampleList: [], + html: '', + libFileList: [], + moduleDict: {}, + moduleExtraDict: {}, + packageJson: { bin: {} }, + template: local.templateApidocHtml + }, 2); + // init exampleList + [1, 2, 3, 4].forEach(function (depth) { + options.exampleList = options.exampleList.concat( + // http://stackoverflow.com + // /questions/4509624/how-to-limit-depth-for-recursive-file-list + // find . -maxdepth 1 -mindepth 1 -name "*.js" -type f + local.child_process.execSync('find "' + options.dir + + '" -maxdepth ' + depth + ' -mindepth ' + depth + + ' -type f | sed -e "s|' + options.dir + + '/||" | grep -iv ' + +/* jslint-ignore-begin */ +'"\ +/\\.\\|\\(\\b\\|_\\)\\(\ +bower_component\\|\ +coverage\\|\ +git\\|\ +min\\|\ +node_module\\|\ +rollup\\|\ +tmp\\|\ +vendor\\)s\\{0,1\\}\\(\\b\\|_\\)\ +" ' + +/* jslint-ignore-end */ + ' | sort | head -n 256').toString() + .split('\n') + ); + }); + options.exampleList = options.exampleList.filter(function (file) { + if (!options.exampleDict[file]) { + options.exampleDict[file] = true; + return true; + } + }).slice(0, 256).map(readExample); + // init moduleMain + local.tryCatchOnError(function () { + console.error('apidocCreate - requiring ' + options.dir + ' ...'); + moduleMain = {}; + moduleMain = options.moduleDict[options.env.npm_package_name] || + options.require(options.dir) || + options.require(options.dir + '/' + (options.packageJson.bin)[ + Object.keys(options.packageJson.bin)[0] + ]) || {}; + console.error('apidocCreate - ... required ' + options.dir); + }, console.error); + tmp = {}; + // handle case where module is a function + if (typeof moduleMain === 'function') { + (function () { + var text; + text = toString(moduleMain); + tmp = function () { + return; + }; + // coverage-hack + tmp(); + Object.defineProperties(tmp, { toString: { get: function () { + return function () { + return text; + }; + } } }); + }()); + } + // normalize moduleMain + moduleMain = options.moduleDict[options.env.npm_package_name] = + local.objectSetDefault(tmp, moduleMain); + // init circularList - builtin + Object.keys(process.binding('natives')).forEach(function (key) { + if (!(/\/|_linklist|sys/).test(key)) { + options.blacklistDict[key] = options.blacklistDict[key] || require(key); + } + }); + // init circularList - blacklistDict + Object.keys(options.blacklistDict).forEach(function (key) { + options.circularList.push(options.blacklistDict[key]); + }); + // init circularList - moduleDict + Object.keys(options.moduleDict).forEach(function (key) { + options.circularList.push(options.moduleDict[key]); + }); + // init circularList - prototype + Object.keys(options.circularList).forEach(function (key) { + tmp = options.circularList[key]; + options.circularList.push(tmp && tmp.prototype); + }); + // deduplicate circularList + tmp = options.circularList; + options.circularList = []; + tmp.forEach(function (element) { + if (options.circularList.indexOf(element) < 0) { + options.circularList.push(element); + } + }); + // init moduleDict child + local.apidocModuleDictAdd(options, options.moduleDict); + // init moduleExtraDict + module = options.moduleExtraDict[options.env.npm_package_name] = + options.moduleExtraDict[options.env.npm_package_name] || {}; + [1, 2, 3, 4].forEach(function (depth) { + options.libFileList = options.libFileList.concat( + // http://stackoverflow.com + // /questions/4509624/how-to-limit-depth-for-recursive-file-list + // find . -maxdepth 1 -mindepth 1 -name "*.js" -type f + local.child_process.execSync('find "' + options.dir + + '" -maxdepth ' + depth + ' -mindepth ' + depth + + ' -name "*.js" -type f | sed -e "s|' + options.dir + + '/||" | grep -iv ' + +/* jslint-ignore-begin */ +'"\ +/\\.\\|\\(\\b\\|_\\)\\(\ +archive\\|artifact\\|asset\\|\ +bower_component\\|build\\|\ +coverage\\|\ +doc\\|dist\\|\ +example\\|external\\|\ +fixture\\|\ +git\\|\ +log\\|\ +min\\|mock\\|\ +node_module\\|\ +rollup\\|\ +spec\\|\ +test\\|tmp\\|\ +vendor\\)s\\{0,1\\}\\(\\b\\|_\\)\ +" ' + +/* jslint-ignore-end */ + ' | sort | head -n 256').toString() + .split('\n') + ); + }); + options.ii = 256; + options.libFileList.every(function (file) { + local.tryCatchOnError(function () { + tmp = {}; + tmp.name = local.path.basename(file) + .replace('lib.', '') + .replace((/\.[^.]*?$/), '') + .replace((/\W/g), '_'); + [ + tmp.name, + tmp.name.slice(0, 1).toUpperCase() + tmp.name.slice(1) + ].some(function (name) { + tmp.isFiltered = name && (!options.packageJson.main || + ('./' + file).indexOf(options.packageJson.main) < 0) && + !module[name]; + return !tmp.isFiltered; + }); + if (!tmp.isFiltered) { + return; + } + console.error('apidocCreate - libFile - ' + file); + tmp.module = options.require(options.dir + '/' + file); + if (!(tmp.module && options.circularList.indexOf(tmp.module) < 0)) { + return; + } + options.ii -= 1; + module[tmp.name] = tmp.module; + }, console.error); + return options.ii; + }); + local.apidocModuleDictAdd(options, options.moduleExtraDict); + Object.keys(options.moduleDict).forEach(function (key) { + if (key.indexOf(options.env.npm_package_name + '.') !== 0) { + return; + } + tmp = key.split('.').slice(1).join('.'); + moduleMain[tmp] = moduleMain[tmp] || options.moduleDict[key]; + }); + // init moduleList + options.moduleList = Object.keys(options.moduleDict) + .sort() + .map(function (prefix) { + module = options.moduleDict[prefix]; + // handle case where module is a function + if (typeof module === 'function') { + local.tryCatchOnError(function () { + module[prefix.split('.').slice(-1)[0]] = + module[prefix.split('.').slice(-1)[0]] || module; + }, console.error); + } + return { + elementList: Object.keys(module) + .filter(function (key) { + return local.tryCatchOnError(function () { + return key && + (/^\w[\w\-.]*?$/).test(key) && + key.indexOf('testCase_') !== 0 && + module[key] !== options.blacklistDict[key]; + }, console.error); + }) + .map(function (key) { + return elementCreate(module, prefix, key); + }) + .sort(function (aa, bb) { + return aa.name > bb.name + ? 1 + : -1; + }), + id: encodeURIComponent('apidoc.module.' + prefix), + name: prefix + }; + }); + // render apidoc + options.result = local.templateRender(options.template, options) + .trim() + .replace((/ +$/gm), '') + '\n'; + return options.result; + }; + + local.apidocModuleDictAdd = function (options, moduleDict) { + /* + * this function will add the modules in moduleDict to options.moduleDict + */ + var isModule, tmp; + ['child', 'prototype', 'grandchild', 'prototype'].forEach(function (element) { + Object.keys(moduleDict).sort().forEach(function (prefix) { + if (!(/^\w[\w\-.]*?$/).test(prefix)) { + return; + } + Object.keys(moduleDict[prefix]).forEach(function (key) { + // bug-workaround - buggy electron getter / setter + local.tryCatchOnError(function () { + if (!(/^\w[\w\-.]*?$/).test(key) || !moduleDict[prefix][key]) { + return; + } + tmp = element === 'prototype' + ? { + module: moduleDict[prefix][key].prototype, + name: prefix + '.' + key + '.prototype' + } + : { + module: moduleDict[prefix][key], + name: prefix + '.' + key + }; + if (!tmp.module || + !(typeof tmp.module === 'function' || + typeof tmp.module === 'object') || + options.moduleDict[tmp.name] || + options.circularList.indexOf(tmp.module) >= 0) { + return; + } + isModule = [ + tmp.module, + tmp.module.prototype + ].some(function (dict) { + return Object.keys(dict || {}).some(function (key) { + // bug-workaround - buggy electron getter / setter + return local.tryCatchOnError(function () { + return typeof dict[key] === 'function'; + }, console.error); + }); + }); + if (!isModule) { + return; + } + options.circularList.push(tmp.module); + options.moduleDict[tmp.name] = tmp.module; + }, console.error); + }); + }); + }); + }; + }()); + switch (local.modeJs) { + + + + // run node js-env code - init-after + /* istanbul ignore next */ + case 'node': + // require modules + local.child_process = require('child_process'); + local.fs = require('fs'); + local.path = require('path'); + // run the cli + if (module !== require.main || local.global.utility2_rollup) { + break; + } + // jslint files + process.stdout.write(local.apidocCreate({ + dir: process.argv[2], + modulePathList: module.paths + })); + break; + } +}()); +/* script-end /assets.utility2.lib.apidoc.js */ + + + +/* script-begin /assets.utility2.lib.db.js */ +/* + * assets.db-lite.js + * + * this zero-dependency package will provide a persistent, in-browser database + * + * browser example: + * + * + * + * node example: + * var db, dbTable1; + * utility2_db = require("./assets.db-lite.js"); + * dbTable1 = global.dbTable1 = utility2_db.dbTableCreateOne({ name: "dbTable1" }); + * dbTable1.idIndexCreate({ name: "field1" }); + * dbTable1.crudSetOneById({ field1: "hello", field2: "world" }); + * console.log(dbTable1.crudGetManyByQuery({ + * limit: Infinity, + * query: { field1: "hello" }, + * skip: 0, + * sort: [{ fieldName: 'field1', isDescending: false }] + * })); + */ + + + +/* istanbul instrument in package db */ +/*jslint + bitwise: true, + browser: true, + maxerr: 8, + maxlen: 96, + node: true, + nomen: true, + regexp: true, + stupid: true +*/ +(function () { + 'use strict'; + var local; + + + + // run shared js-env code - init-before + (function () { + // init local + local = {}; + // init modeJs + local.modeJs = (function () { + try { + return typeof navigator.userAgent === 'string' && + typeof document.querySelector('body') === 'object' && + typeof XMLHttpRequest.prototype.open === 'function' && + 'browser'; + } catch (errorCaughtBrowser) { + return module.exports && + typeof process.versions.node === 'string' && + typeof require('http').createServer === 'function' && + 'node'; + } + }()); + // init global + local.global = local.modeJs === 'browser' + ? window + : global; + // init utility2_rollup + local = local.global.utility2_rollup || local; + // init lib + local.local = local.db = local; + // init exports + if (local.modeJs === 'browser') { + local.global.utility2_db = local; + } else { + module.exports = local; + module.exports.__dirname = __dirname; + module.exports.module = module; + } + }()); + + + + /* istanbul ignore next */ + // run shared js-env code - function-before + (function () { + local.jsonCopy = function (arg) { + /* + * this function will return a deep-copy of the JSON-arg + */ + return arg === undefined + ? undefined + : JSON.parse(JSON.stringify(arg)); + }; + + local.jsonStringifyOrdered = function (element, replacer, space) { + /* + * this function will JSON.stringify the element, + * with object-keys sorted and circular-references removed + */ + var circularList, stringify, tmp; + stringify = function (element) { + /* + * this function will recursively JSON.stringify the element, + * with object-keys sorted and circular-references removed + */ + // if element is an object, then recurse its items with object-keys sorted + if (element && + typeof element === 'object' && + typeof element.toJSON !== 'function') { + // ignore circular-reference + if (circularList.indexOf(element) >= 0) { + return; + } + circularList.push(element); + // if element is an array, then recurse its elements + if (Array.isArray(element)) { + return '[' + element.map(function (element) { + // recurse + tmp = stringify(element); + return typeof tmp === 'string' + ? tmp + : 'null'; + }).join(',') + ']'; + } + return '{' + Object.keys(element) + // sort object-keys + .sort() + .map(function (key) { + // recurse + tmp = stringify(element[key]); + if (typeof tmp === 'string') { + return JSON.stringify(key) + ':' + tmp; + } + }) + .filter(function (element) { + return typeof element === 'string'; + }) + .join(',') + '}'; + } + // else JSON.stringify as normal + return JSON.stringify(element); + }; + circularList = []; + return JSON.stringify(element && typeof element === 'object' + // recurse + ? JSON.parse(stringify(element)) + : element, replacer, space); + }; + + local.listShuffle = function (list) { + /* + * https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle + * this function will inplace shuffle the list, via fisher-yates algorithm + */ + var ii, random, swap; + for (ii = list.length - 1; ii > 0; ii -= 1) { + // coerce to finite integer + random = (Math.random() * (ii + 1)) | 0; + swap = list[ii]; + list[ii] = list[random]; + list[random] = swap; + } + return list; + }; + + local.nop = function () { + /* + * this function will do nothing + */ + return; + }; + + local.normalizeDict = function (dict) { + /* + * this function will normalize the dict + */ + return dict && typeof dict === 'object' && !Array.isArray(dict) + ? dict + : {}; + }; + + local.normalizeList = function (list) { + /* + * this function will normalize the list + */ + return Array.isArray(list) + ? list + : []; + }; + + local.objectSetOverride = function (arg, overrides, depth, env) { + /* + * this function will recursively set overrides for items in the arg + */ + arg = arg || {}; + env = env || (typeof process === 'object' && process.env) || {}; + overrides = overrides || {}; + Object.keys(overrides).forEach(function (key) { + var arg2, overrides2; + arg2 = arg[key]; + overrides2 = overrides[key]; + if (overrides2 === undefined) { + return; + } + // if both arg2 and overrides2 are non-null and non-array objects, + // then recurse with arg2 and overrides2 + if (depth > 1 && + // arg2 is a non-null and non-array object + (arg2 && + typeof arg2 === 'object' && + !Array.isArray(arg2)) && + // overrides2 is a non-null and non-array object + (overrides2 && + typeof overrides2 === 'object' && + !Array.isArray(overrides2))) { + local.objectSetOverride(arg2, overrides2, depth - 1, env); + return; + } + // else set arg[key] with overrides[key] + arg[key] = arg === env + // if arg is env, then overrides falsey value with empty string + ? overrides2 || '' + : overrides2; + }); + return arg; + }; + + local.onErrorDefault = function (error) { + /* + * this function will if error exists, then print error.stack to stderr + */ + if (error && !local.global.__coverage__) { + console.error(error); + } + }; + + local.onErrorWithStack = function (onError) { + /* + * this function will create a new callback that will call onError, + * and append the current stack to any error + */ + var stack; + stack = new Error().stack.replace((/(.*?)\n.*?$/m), '$1'); + return function (error, data, meta) { + if (error && + error !== local.errorDefault && + String(error.stack).indexOf(stack.split('\n')[2]) < 0) { + // append the current stack to error.stack + error.stack += '\n' + stack; + } + onError(error, data, meta); + }; + }; + + local.onParallel = function (onError, onEach, onRetry) { + /* + * this function will create a function that will + * 1. run async tasks in parallel + * 2. if counter === 0 or error occurred, then call onError with error + */ + var onParallel; + onError = local.onErrorWithStack(onError); + onEach = onEach || local.nop; + onRetry = onRetry || local.nop; + onParallel = function (error, data) { + if (onRetry(error, data)) { + return; + } + // decrement counter + onParallel.counter -= 1; + // validate counter + console.assert(onParallel.counter >= 0 || error || onParallel.error); + // ensure onError is run only once + if (onParallel.counter < 0) { + return; + } + // handle error + if (error) { + onParallel.error = error; + // ensure counter <= 0 + onParallel.counter = -Math.abs(onParallel.counter); + } + // call onError when isDone + if (onParallel.counter <= 0) { + onError(error, data); + return; + } + onEach(); + }; + // init counter + onParallel.counter = 0; + // return callback + return onParallel; + }; + + local.setTimeoutOnError = function (onError, error, data) { + /* + * this function will async-call onError + */ + if (typeof onError === 'function') { + setTimeout(function () { + onError(error, data); + }); + } + return data; + }; + }()); + + + + // run shared js-env code - lib.storage.js + (function (local) { + var child_process, + clear, + defer, + deferList, + fs, + getItem, + init, + keys, + length, + modeJs, + os, + removeItem, + setItem, + storage, + storageDir; + + // init modeJs + modeJs = (function () { + try { + return typeof navigator.userAgent === 'string' && + typeof document.querySelector('body') === 'object' && + typeof XMLHttpRequest.prototype.open === 'function' && + 'browser'; + } catch (errorCaughtBrowser) { + return module.exports && + typeof process.versions.node === 'string' && + typeof require('http').createServer === 'function' && + 'node'; + } + }()); + storageDir = 'tmp/storage.' + (local.modeJs === 'browser' + ? 'undefined' + : process.env.NODE_ENV); + switch (modeJs) { + case 'node': + // require modules + child_process = require('child_process'); + fs = require('fs'); + os = require('os'); + break; + } + + clear = function (onError) { + /* + * this function will clear storage + */ + defer({ action: 'clear' }, onError); + }; + + defer = function (options, onError) { + /* + * this function will defer options.action until storage is ready + */ + var data, isDone, objectStore, onError2, request, tmp; + onError = onError || function (error) { + // validate no error occurred + console.assert(!error, error); + }; + if (!storage) { + deferList.push(function () { + defer(options, onError); + }); + init(); + return; + } + switch (modeJs) { + case 'browser': + onError2 = function () { + /* istanbul ignore next */ + if (isDone) { + return; + } + isDone = true; + onError( + request && (request.error || request.transaction.error), + data || request.result || '' + ); + }; + switch (options.action) { + case 'clear': + case 'removeItem': + case 'setItem': + objectStore = storage + .transaction(storageDir, 'readwrite') + .objectStore(storageDir); + break; + default: + objectStore = storage + .transaction(storageDir, 'readonly') + .objectStore(storageDir); + } + switch (options.action) { + case 'clear': + request = objectStore.clear(); + break; + case 'getItem': + request = objectStore.get(String(options.key)); + break; + case 'keys': + data = []; + request = objectStore.openCursor(); + request.onsuccess = function () { + if (!request.result) { + onError2(); + return; + } + data.push(request.result.key); + request.result.continue(); + }; + break; + case 'length': + request = objectStore.count(); + break; + case 'removeItem': + request = objectStore.delete(String(options.key)); + break; + case 'setItem': + request = objectStore.put(options.value, String(options.key)); + break; + } + ['onabort', 'onerror', 'onsuccess'].forEach(function (handler) { + request[handler] = request[handler] || onError2; + }); + // debug request + local._debugStorageRequest = request; + break; + case 'node': + switch (options.action) { + case 'clear': + child_process.spawnSync( + 'sh', + ['-c', 'rm -f ' + storage + '/*'], + { stdio: ['ignore', 1, 2] } + ); + setTimeout(onError); + break; + case 'getItem': + fs.readFile( + storage + '/' + encodeURIComponent(String(options.key)), + 'utf8', + // ignore error + function (error, data) { + onError(error && null, data || ''); + } + ); + break; + case 'keys': + fs.readdir(storage, function (error, data) { + onError(error, data && data.map(decodeURIComponent)); + }); + break; + case 'length': + fs.readdir(storage, function (error, data) { + onError(error, data && data.length); + }); + break; + case 'removeItem': + fs.unlink( + storage + '/' + encodeURIComponent(String(options.key)), + // ignore error + function () { + onError(); + } + ); + break; + case 'setItem': + tmp = os.tmpdir() + '/' + Date.now() + Math.random(); + // save to tmp + fs.writeFile(tmp, options.value, function (error) { + // validate no error occurred + console.assert(!error, error); + // rename tmp to key + fs.rename( + tmp, + storage + '/' + encodeURIComponent(String(options.key)), + onError + ); + }); + break; + } + break; + } + }; + + deferList = []; + + getItem = function (key, onError) { + /* + * this function will get the item with the given key from storage + */ + defer({ action: 'getItem', key: key }, onError); + }; + + init = function () { + /* + * this function will init storage + */ + var onError, request; + onError = function (error) { + // validate no error occurred + console.assert(!error, error); + if (modeJs === 'browser') { + storage = window[storageDir]; + } + while (deferList.length) { + deferList.shift()(); + } + }; + if (modeJs === 'browser') { + storage = window[storageDir]; + } + if (storage) { + onError(); + return; + } + switch (modeJs) { + case 'browser': + // init indexedDB + try { + request = window.indexedDB.open(storageDir); + // debug request + local._debugStorageRequestIndexedDB = request; + request.onerror = onError; + request.onsuccess = function () { + window[storageDir] = request.result; + onError(); + }; + request.onupgradeneeded = function () { + if (!request.result.objectStoreNames.contains(storageDir)) { + request.result.createObjectStore(storageDir); + } + }; + } catch (ignore) { + } + break; + case 'node': + // mkdirp storage + storage = storageDir; + child_process.spawnSync( + 'mkdir', + ['-p', storage], + { stdio: ['ignore', 1, 2] } + ); + onError(); + break; + } + }; + + keys = function (onError) { + /* + * this function will get all the keys in storage + */ + defer({ action: 'keys' }, onError); + }; + + length = function (onError) { + /* + * this function will get the number of items in storage + */ + defer({ action: 'length' }, onError); + }; + + removeItem = function (key, onError) { + /* + * this function will remove the item with the given key from storage + */ + defer({ action: 'removeItem', key: key }, onError); + }; + + setItem = function (key, value, onError) { + /* + * this function will set the item with the given key and value to storage + */ + defer({ action: 'setItem', key: key, value: value }, onError); + }; + + // init local + local.storage = storage; + local.storageClear = clear; + local.storageDefer = defer; + local.storageDeferList = deferList; + local.storageDir = storageDir; + local.storageGetItem = getItem; + local.storageInit = init; + local.storageKeys = keys; + local.storageLength = length; + local.storageRemoveItem = removeItem; + local.storageSetItem = setItem; + }(local)); + + + + // run shared js-env code - lib.dbTable.js + (function () { + local._DbTable = function (options) { + /* + * this function will create a dbTable + */ + options = local.normalizeDict(options); + this.name = String(options.name); + // register dbTable in dbTableDict + local.dbTableDict[this.name] = this; + this.dbRowList = []; + this.isDirty = null; + this.idIndexList = [{ name: '_id', dict: {} }]; + this.onSaveList = []; + this.sizeLimit = options.sizeLimit || 0; + }; + + local._DbTable.prototype._cleanup = function () { + /* + * this function will cleanup soft-deleted records from the dbTable + */ + var dbRow, ii, list; + if (!this.isDirty && this.dbRowList.length <= this.sizeLimit) { + return; + } + this.isDirty = null; + // cleanup dbRowList + list = this.dbRowList; + this.dbRowList = []; + // optimization - for-loop + for (ii = 0; ii < list.length; ii += 1) { + dbRow = list[ii]; + // cleanup isRemoved + if (!dbRow.$meta.isRemoved) { + this.dbRowList.push(dbRow); + } + } + if (this.sizeLimit && this.dbRowList.length >= 1.5 * this.sizeLimit) { + this.dbRowList = this._crudGetManyByQuery( + {}, + this.sortDefault, + 0, + this.sizeLimit + ); + } + }; + + local._DbTable.prototype._crudGetManyByQuery = function ( + query, + sort, + skip, + limit, + shuffle + ) { + /* + * this function will get the dbRow's in the dbTable, + * with the given query, sort, skip, and limit + */ + var ii, result; + result = this.dbRowList; + // get by query + if (result.length && query && Object.keys(query).length) { + result = local.dbRowListGetManyByQuery(this.dbRowList, query); + } + // sort + local.normalizeList(sort).forEach(function (element) { + // bug-workaround - v8 does not have stable-sort + // optimization - for-loop + for (ii = 0; ii < result.length; ii += 1) { + result[ii].$meta.ii = ii; + } + if (element.isDescending) { + result.sort(function (aa, bb) { + return -local.sortCompare( + local.dbRowGetItem(aa, element.fieldName), + local.dbRowGetItem(bb, element.fieldName), + aa.$meta.ii, + bb.$meta.ii + ); + }); + } else { + result.sort(function (aa, bb) { + return local.sortCompare( + local.dbRowGetItem(aa, element.fieldName), + local.dbRowGetItem(bb, element.fieldName), + aa.$meta.ii, + bb.$meta.ii + ); + }); + } + }); + // skip + result = result.slice(skip || 0); + // shuffle + ((shuffle && local.listShuffle) || local.nop)(result); + // limit + result = result.slice(0, limit || Infinity); + return result; + }; + + local._DbTable.prototype._crudGetOneById = function (idDict) { + /* + * this function will get the dbRow in the dbTable with the given idDict + */ + var id, result; + idDict = local.normalizeDict(idDict); + result = null; + this.idIndexList.some(function (idIndex) { + id = idDict[idIndex.name]; + // optimization - hasOwnProperty + if (idIndex.dict.hasOwnProperty(id)) { + result = idIndex.dict[id]; + return result; + } + }); + return result; + }; + + local._DbTable.prototype._crudRemoveOneById = function (idDict, circularList) { + /* + * this function will remove the dbRow from the dbTable with the given idDict + */ + var id, result, self; + if (!idDict) { + return null; + } + self = this; + circularList = circularList || [idDict]; + result = null; + self.idIndexList.forEach(function (idIndex) { + id = idDict[idIndex.name]; + // optimization - hasOwnProperty + if (!idIndex.dict.hasOwnProperty(id)) { + return; + } + result = idIndex.dict[id]; + delete idIndex.dict[id]; + // optimization - soft-delete + result.$meta.isRemoved = true; + self.isDirty = true; + if (circularList.indexOf(result) >= 0) { + return; + } + circularList.push(result); + // recurse + self._crudRemoveOneById(result, circularList); + }); + self.save(); + return result; + }; + + local._DbTable.prototype._crudSetOneById = function (dbRow) { + /* + * this function will set the dbRow into the dbTable with the given dbRow._id + * WARNING - existing dbRow with conflicting dbRow._id will be removed + */ + var existing, id, normalize, timeNow; + normalize = function (dbRow) { + /* + * this function will recursively normalize dbRow + */ + if (dbRow && typeof dbRow === 'object') { + Object.keys(dbRow).forEach(function (key) { + // remove invalid property + if (key[0] === '$' || key.indexOf('.') >= 0 || dbRow[key] === null) { + // optimization - soft-delete + dbRow[key] = undefined; + return; + } + // recurse + normalize(dbRow[key]); + }); + } + }; + dbRow = local.jsonCopy(dbRow && typeof dbRow === 'object' + ? dbRow + : {}); + // update timestamp + timeNow = new Date().toISOString(); + dbRow._timeCreated = dbRow._timeCreated || timeNow; + if (!local.modeImport) { + dbRow._timeUpdated = timeNow; + } + // normalize + normalize(dbRow); + dbRow = local.jsonCopy(dbRow); + // remove existing dbRow + existing = this._crudRemoveOneById(dbRow) || dbRow; + // init meta + dbRow.$meta = { isRemoved: null }; + this.idIndexList.forEach(function (idIndex) { + // auto-set id + id = local.dbRowSetId(existing, idIndex); + // copy id from existing to dbRow + dbRow[idIndex.name] = id; + // set dbRow + idIndex.dict[id] = dbRow; + }); + // update dbRowList + this.dbRowList.push(dbRow); + this.save(); + return dbRow; + }; + + local._DbTable.prototype._crudUpdateOneById = function (dbRow) { + /* + * this function will update the dbRow in the dbTable, + * if it exists with the given dbRow._id + * WARNING + * existing dbRow's with conflicting unique-keys (besides the one being updated) + * will be removed + */ + var id, result; + dbRow = local.jsonCopy(local.normalizeDict(dbRow)); + result = null; + this.idIndexList.some(function (idIndex) { + id = dbRow[idIndex.name]; + // optimization - hasOwnProperty + if (idIndex.dict.hasOwnProperty(id)) { + result = idIndex.dict[id]; + return true; + } + }); + result = result || {}; + // remove existing dbRow + this._crudRemoveOneById(result); + // update dbRow + dbRow._timeCreated = undefined; + local.objectSetOverride(result, dbRow, Infinity); + // replace dbRow + result = this._crudSetOneById(result); + return result; + }; + + local._DbTable.prototype.crudCountAll = function (onError) { + /* + * this function will count all of dbRow's in the dbTable + */ + this._cleanup(); + return local.setTimeoutOnError(onError, null, this.dbRowList.length); + }; + + local._DbTable.prototype.crudCountManyByQuery = function (query, onError) { + /* + * this function will count the number of dbRow's in the dbTable with the given query + */ + this._cleanup(); + return local.setTimeoutOnError( + onError, + null, + this._crudGetManyByQuery(query).length + ); + }; + + local._DbTable.prototype.crudGetManyById = function (idDictList, onError) { + /* + * this function will get the dbRow's in the dbTable with the given idDictList + */ + var self; + this._cleanup(); + self = this; + return local.setTimeoutOnError(onError, null, local.dbRowProject( + local.normalizeList(idDictList).map(function (idDict) { + return self._crudGetOneById(idDict); + }) + )); + }; + + local._DbTable.prototype.crudGetManyByQuery = function (options, onError) { + /* + * this function will get the dbRow's in the dbTable with the given options.query + */ + this._cleanup(); + options = local.normalizeDict(options); + return local.setTimeoutOnError(onError, null, local.dbRowProject( + this._crudGetManyByQuery( + options.query, + options.sort || this.sortDefault, + options.skip, + options.limit, + options.shuffle + ), + options.fieldList + )); + }; + + local._DbTable.prototype.crudGetOneById = function (idDict, onError) { + /* + * this function will get the dbRow in the dbTable with the given idDict + */ + this._cleanup(); + return local.setTimeoutOnError(onError, null, local.dbRowProject( + this._crudGetOneById(idDict) + )); + }; + + local._DbTable.prototype.crudGetOneByRandom = function (onError) { + /* + * this function will get a random dbRow in the dbTable + */ + this._cleanup(); + return local.setTimeoutOnError(onError, null, local.dbRowProject( + this.dbRowList[Math.floor(Math.random() * this.dbRowList.length)] + )); + }; + + local._DbTable.prototype.crudGetOneByQuery = function (query, onError) { + /* + * this function will get the dbRow in the dbTable with the given query + */ + var ii, result; + this._cleanup(); + // optimization - for-loop + for (ii = 0; ii < this.dbRowList.length; ii += 1) { + result = local.dbRowListGetManyByQuery([this.dbRowList[ii]], query)[0]; + if (result) { + break; + } + } + return local.setTimeoutOnError(onError, null, local.dbRowProject(result)); + }; + + local._DbTable.prototype.crudRemoveAll = function (onError) { + /* + * this function will remove all of the dbRow's from the dbTable + */ + var idIndexList; + // save idIndexList + idIndexList = this.idIndexList; + // reset dbTable + local._DbTable.call(this, this); + // restore idIndexList + local.dbTableCreateOne({ + name: this.name, + idIndexCreateList: idIndexList + }, onError); + }; + + local._DbTable.prototype.crudRemoveManyById = function (idDictList, onError) { + /* + * this function will remove the dbRow's from the dbTable with the given idDictList + */ + var self; + self = this; + return local.setTimeoutOnError(onError, null, local.dbRowProject( + local.normalizeList(idDictList).map(function (dbRow) { + return self._crudRemoveOneById(dbRow); + }) + )); + }; + + local._DbTable.prototype.crudRemoveManyByQuery = function (query, onError) { + /* + * this function will remove the dbRow's from the dbTable with the given query + */ + var self; + self = this; + return local.setTimeoutOnError(onError, null, local.dbRowProject( + self._crudGetManyByQuery(query).map(function (dbRow) { + return self._crudRemoveOneById(dbRow); + }) + )); + }; + + local._DbTable.prototype.crudRemoveOneById = function (idDict, onError) { + /* + * this function will remove the dbRow from the dbTable with the given idDict + */ + return local.setTimeoutOnError(onError, null, local.dbRowProject( + this._crudRemoveOneById(idDict) + )); + }; + + local._DbTable.prototype.crudSetManyById = function (dbRowList, onError) { + /* + * this function will set the dbRowList into the dbTable + */ + var self; + self = this; + return local.setTimeoutOnError(onError, null, local.dbRowProject( + local.normalizeList(dbRowList).map(function (dbRow) { + return self._crudSetOneById(dbRow); + }) + )); + }; + + local._DbTable.prototype.crudSetOneById = function (dbRow, onError) { + /* + * this function will set the dbRow into the dbTable with the given dbRow._id + */ + return local.setTimeoutOnError(onError, null, local.dbRowProject( + this._crudSetOneById(dbRow) + )); + }; + + local._DbTable.prototype.crudUpdateManyById = function (dbRowList, onError) { + /* + * this function will update the dbRowList in the dbTable, + * if they exist with the given dbRow._id's + */ + var self; + self = this; + return local.setTimeoutOnError(onError, null, local.dbRowProject( + local.normalizeList(dbRowList).map(function (dbRow) { + return self._crudUpdateOneById(dbRow); + }) + )); + }; + + local._DbTable.prototype.crudUpdateManyByQuery = function (query, dbRow, onError) { + /* + * this function will update the dbRow's in the dbTable with the given query + */ + var result, self, tmp; + self = this; + tmp = local.jsonCopy(local.normalizeDict(dbRow)); + result = self._crudGetManyByQuery(query).map(function (dbRow) { + tmp._id = dbRow._id; + return self._crudUpdateOneById(tmp); + }); + return local.setTimeoutOnError(onError, null, result); + }; + + local._DbTable.prototype.crudUpdateOneById = function (dbRow, onError) { + /* + * this function will update the dbRow in the dbTable, + * if it exists with the given dbRow._id + */ + return local.setTimeoutOnError(onError, null, local.dbRowProject( + this._crudUpdateOneById(dbRow) + )); + }; + + local._DbTable.prototype.drop = function (onError) { + /* + * this function will drop the dbTable + */ + console.error('dropping dbTable ' + this.name + ' ...'); + // cancel pending save + this.timerSave = null; + while (this.onSaveList.length) { + this.onSaveList.shift()(); + } + // reset dbTable + local._DbTable.call(this, this); + // clear persistence + local.storageRemoveItem('dbTable.' + this.name, onError); + }; + + local._DbTable.prototype.export = function (onError) { + /* + * this function will export the db + */ + var result, self; + this._cleanup(); + self = this; + result = ''; + self.idIndexList.forEach(function (idIndex) { + result += self.name + ' idIndexCreate ' + JSON.stringify({ + isInteger: idIndex.isInteger, + name: idIndex.name + }) + '\n'; + }); + result += self.name + ' sizeLimit ' + self.sizeLimit + '\n'; + result += self.name + ' sortDefault ' + JSON.stringify(self.sortDefault) + '\n'; + self.crudGetManyByQuery({}).forEach(function (dbRow) { + result += self.name + ' dbRowSet ' + JSON.stringify(dbRow) + '\n'; + }); + return local.setTimeoutOnError(onError, null, result.trim()); + }; + + local._DbTable.prototype.idIndexCreate = function (options, onError) { + /* + * this function will create an idIndex with the given options.name + */ + var dbRow, idIndex, ii, name; + options = local.normalizeDict(options); + name = String(options.name); + // disallow idIndex with dot-name + if (name.indexOf('.') >= 0 || name === '_id') { + return local.setTimeoutOnError(onError); + } + // remove existing idIndex + this.idIndexRemove(options); + // init idIndex + idIndex = { + dict: {}, + isInteger: options.isInteger, + name: options.name + }; + this.idIndexList.push(idIndex); + // populate idIndex with dbRowList + // optimization - for-loop + for (ii = 0; ii < this.dbRowList.length; ii += 1) { + dbRow = this.dbRowList[ii]; + // auto-set id + if (!dbRow.$meta.isRemoved) { + idIndex.dict[local.dbRowSetId(dbRow, idIndex)] = dbRow; + } + } + this.save(); + return local.setTimeoutOnError(onError); + }; + + local._DbTable.prototype.idIndexRemove = function (options, onError) { + /* + * this function will remove the idIndex with the given options.name + */ + var name; + options = local.normalizeDict(options); + name = String(options.name); + this.idIndexList = this.idIndexList.filter(function (idIndex) { + return idIndex.name !== name || idIndex.name === '_id'; + }); + this.save(); + return local.setTimeoutOnError(onError); + }; + + local._DbTable.prototype.save = function (onError) { + /* + * this function will save the dbTable to storage + */ + var self; + self = this; + if (local.modeImport) { + return; + } + if (onError) { + self.onSaveList.push(onError); + } + // throttle storage-writes to once every 1000 ms + self.timerSave = self.timerSave || setTimeout(function () { + self.timerSave = null; + local.storageSetItem('dbTable.' + self.name + '.json', self.export(), function ( + error + ) { + while (self.onSaveList.length) { + self.onSaveList.shift()(error); + } + }); + }, 1000); + }; + + local.dbCrudRemoveAll = function (onError) { + /* + * this function will remove all dbRow's from the db + */ + var onParallel; + onParallel = local.onParallel(function (error) { + local.setTimeoutOnError(onError, error); + }); + onParallel.counter += 1; + Object.keys(local.dbTableDict).forEach(function (key) { + onParallel.counter += 1; + local.dbTableDict[key].crudRemoveAll(onParallel); + }); + onParallel(); + }; + + local.dbDrop = function (onError) { + /* + * this function will drop the db + */ + var onParallel; + onParallel = local.onParallel(function (error) { + local.setTimeoutOnError(onError, error); + }); + onParallel.counter += 1; + onParallel.counter += 1; + local.storageClear(onParallel); + Object.keys(local.dbTableDict).forEach(function (key) { + onParallel.counter += 1; + local.dbTableDict[key].drop(onParallel); + }); + onParallel(); + }; + + local.dbExport = function (onError) { + /* + * this function will export the db as serialized text + */ + var result; + result = ''; + Object.keys(local.dbTableDict).forEach(function (key) { + result += local.dbTableDict[key].export(); + result += '\n\n'; + }); + return local.setTimeoutOnError(onError, null, result.trim()); + }; + + local.dbImport = function (text, onError) { + /* + * this function will import the serialized text into the db + */ + var dbTable; + local.modeImport = true; + setTimeout(function () { + local.modeImport = null; + }); + text.replace((/^(\w\S*?) (\S+?) (\S.*?)$/gm), function ( + match0, + match1, + match2, + match3 + ) { + // jslint-hack + local.nop(match0); + switch (match2) { + case 'dbRowSet': + dbTable = local.dbTableCreateOne({ isLoaded: true, name: match1 }); + dbTable.crudSetOneById(JSON.parse(match3)); + break; + case 'idIndexCreate': + dbTable = local.dbTableCreateOne({ isLoaded: true, name: match1 }); + dbTable.idIndexCreate(JSON.parse(match3)); + break; + case 'sizeLimit': + dbTable = local.dbTableCreateOne({ isLoaded: true, name: match1 }); + dbTable.sizeLimit = JSON.parse(match3); + break; + case 'sortDefault': + dbTable = local.dbTableCreateOne({ isLoaded: true, name: match1 }); + break; + default: + local.onErrorDefault(new Error('dbImport - invalid operation - ' + match0)); + } + }); + local.modeImport = null; + return local.setTimeoutOnError(onError); + }; + + local.dbLoad = function (onError) { + /* + * this function will load the db from storage + */ + var onParallel; + onParallel = local.onParallel(function (error) { + local.setTimeoutOnError(onError, error); + }); + local.storageKeys(function (error, data) { + onParallel.counter += 1; + onParallel.counter += 1; + onParallel(error); + local.normalizeList(data) + .filter(function (key) { + return key.indexOf('dbTable.') === 0; + }) + .forEach(function (key) { + onParallel.counter += 1; + local.storageGetItem(key, function (error, data) { + onParallel.counter += 1; + onParallel(error); + local.dbImport(data, onParallel); + }); + }); + onParallel(); + }); + }; + + local.dbRowGetItem = function (dbRow, key) { + /* + * this function will get the item with the given key from dbRow + */ + var ii, value; + value = dbRow; + key = String(key).split('.'); + // optimization - for-loop + for (ii = 0; ii < key.length && value && typeof value === 'object'; ii += 1) { + value = value[key[ii]]; + } + return value === undefined + ? null + : value; + }; + + local.dbRowListGetManyByOperator = function (dbRowList, fieldName, operator, bb, not) { + /* + * this function will get the dbRow's in dbRowList with the given operator + */ + var ii, jj, result, fieldValue, test, typeof2; + result = []; + typeof2 = typeof bb; + if (bb && typeof2 === 'object') { + switch (operator) { + case '$in': + case '$nin': + case '$regex': + break; + default: + return result; + } + } + switch (operator) { + case '$eq': + test = function (aa, bb) { + return aa === bb; + }; + break; + case '$exists': + bb = !bb; + test = function (aa, bb) { + return !((aa === null) ^ bb); + }; + break; + case '$gt': + test = function (aa, bb, typeof1, typeof2) { + return typeof1 === typeof2 && aa > bb; + }; + break; + case '$gte': + test = function (aa, bb, typeof1, typeof2) { + return typeof1 === typeof2 && aa >= bb; + }; + break; + case '$in': + if (bb && typeof bb.indexOf === 'function') { + if (typeof2 === 'string') { + test = function (aa, bb, typeof1, typeof2) { + return typeof1 === typeof2 && bb.indexOf(aa) >= 0; + }; + } else { + test = function (aa, bb) { + return bb.indexOf(aa) >= 0; + }; + } + } + break; + case '$lt': + test = function (aa, bb, typeof1, typeof2) { + return typeof1 === typeof2 && aa < bb; + }; + break; + case '$lte': + test = function (aa, bb, typeof1, typeof2) { + return typeof1 === typeof2 && aa <= bb; + }; + break; + case '$ne': + test = function (aa, bb) { + return aa !== bb; + }; + break; + case '$nin': + if (bb && typeof bb.indexOf === 'function') { + if (typeof2 === 'string') { + test = function (aa, bb, typeof1, typeof2) { + return typeof1 === typeof2 && bb.indexOf(aa) < 0; + }; + } else { + test = function (aa, bb) { + return bb.indexOf(aa) < 0; + }; + } + } + break; + case '$regex': + if (bb && typeof bb.test === 'function') { + test = function (aa, bb) { + return bb.test(aa); + }; + } + break; + case '$typeof': + test = function (aa, bb, typeof1) { + // jslint-hack + local.nop(aa); + return typeof1 === bb; + }; + break; + } + if (!test) { + return result; + } + // optimization - for-loop + for (ii = dbRowList.length - 1; ii >= 0; ii -= 1) { + fieldValue = local.dbRowGetItem(dbRowList[ii], fieldName); + // normalize to list + if (!Array.isArray(fieldValue)) { + fieldValue = [fieldValue]; + } + // optimization - for-loop + for (jj = fieldValue.length - 1; jj >= 0; jj -= 1) { + if (not ^ test(fieldValue[jj], bb, typeof fieldValue[jj], typeof2)) { + result.push(dbRowList[ii]); + break; + } + } + } + return result; + }; + + local.dbRowListGetManyByQuery = function (dbRowList, query, fieldName, not) { + /* + * this function will get the dbRow's in dbRowList with the given query + */ + var bb, dbRowDict, result; + // optimization - convert to boolean + not = !!not; + result = dbRowList; + if (!(query && typeof query === 'object')) { + result = local.dbRowListGetManyByOperator(result, fieldName, '$eq', query, not); + return result; + } + Object.keys(query).some(function (key) { + bb = query[key]; + switch (key) { + case '$not': + key = fieldName; + not = !not; + break; + case '$or': + if (!Array.isArray(bb)) { + break; + } + dbRowDict = {}; + bb.forEach(function (query) { + // recurse + local.dbRowListGetManyByQuery(result, query).forEach(function (dbRow) { + dbRowDict[dbRow._id] = dbRow; + }); + }); + result = Object.keys(dbRowDict).map(function (id) { + return dbRowDict[id]; + }); + return !result.length; + } + if (key[0] === '$') { + result = local.dbRowListGetManyByOperator(result, fieldName, key, bb, not); + return !result.length; + } + // recurse + result = local.dbRowListGetManyByQuery(result, bb, key, not); + return !result.length; + }); + return result; + }; + + local.dbRowProject = function (dbRow, fieldList) { + /* + * this function will deepcopy and project the dbRow with the given fieldList + */ + var result; + if (!dbRow) { + return null; + } + // handle list-case + if (Array.isArray(dbRow)) { + return dbRow.map(function (dbRow) { + // recurse + return local.dbRowProject(dbRow, fieldList); + }); + } + // normalize to list + if (!(Array.isArray(fieldList) && fieldList.length)) { + fieldList = Object.keys(dbRow); + } + result = {}; + fieldList.forEach(function (key) { + if (key[0] !== '$') { + result[key] = dbRow[key]; + } + }); + return JSON.parse(local.jsonStringifyOrdered(result)); + }; + + local.dbRowSetId = function (dbRow, idIndex) { + /* + * this function will set a random and unique id into dbRow for the given idIndex, + * if it does not exist + */ + var id; + id = dbRow[idIndex.name]; + if (typeof id !== 'number' && typeof id !== 'string') { + do { + id = idIndex.isInteger + ? (1 + Math.random()) * 0x10000000000000 + : 'a' + ((1 + Math.random()) * 0x10000000000000).toString(36).slice(1); + // optimization - hasOwnProperty + } while (idIndex.dict.hasOwnProperty(id)); + dbRow[idIndex.name] = id; + } + return id; + }; + + local.dbSave = function (onError) { + /* + * this function will save the db to storage + */ + var onParallel; + onParallel = local.onParallel(function (error) { + local.setTimeoutOnError(onError, error); + }); + onParallel.counter += 1; + Object.keys(local.dbTableDict).forEach(function (key) { + onParallel.counter += 1; + local.dbTableDict[key].save(onParallel); + }); + onParallel(); + }; + + local.dbTableCreateMany = function (optionsList, onError) { + /* + * this function will set the optionsList into the db + */ + var onParallel, result; + onParallel = local.onParallel(function (error) { + local.setTimeoutOnError(onError, error, result); + }); + onParallel.counter += 1; + result = local.normalizeList(optionsList).map(function (options) { + onParallel.counter += 1; + return local.dbTableCreateOne(options, onParallel); + }); + return local.setTimeoutOnError(onParallel, null, result); + }; + + local.dbTableCreateOne = function (options, onError) { + /* + * this function will create a dbTable with the given options + */ + var self; + options = local.normalizeDict(options); + // register dbTable + self = local.dbTableDict[options.name] = + local.dbTableDict[options.name] || new local._DbTable(options); + self.sortDefault = options.sortDefault || + self.sortDefault || + [{ fieldName: '_timeUpdated', isDescending: true }]; + // remove idIndex + local.normalizeList(options.idIndexRemoveList).forEach(function (index) { + self.idIndexRemove(index); + }); + // create idIndex + local.normalizeList(options.idIndexCreateList).forEach(function (index) { + self.idIndexCreate(index); + }); + // upsert dbRow + self.crudSetManyById(options.dbRowList); + self.isLoaded = self.isLoaded || options.isLoaded; + if (!self.isLoaded) { + local.storageGetItem('dbTable.' + self.name + '.json', function (error, data) { + // validate no error occurred + console.assert(!error, error); + if (!self.isLoaded) { + local.dbImport(data); + } + self.isLoaded = true; + local.setTimeoutOnError(onError, null, self); + }); + return self; + } + return local.setTimeoutOnError(onError, null, self); + }; + + local.dbTableDict = {}; + + local.sortCompare = function (aa, bb, ii, jj) { + /* + * this function will compare aa vs bb and return: + * -1 if aa < bb + * 0 if aa === bb + * 1 if aa > bb + * the priority for comparing different typeof's is: + * null < boolean < number < string < object < undefined + */ + var typeof1, typeof2; + if (aa === bb) { + return ii < jj + ? -1 + : 1; + } + if (aa === null) { + return -1; + } + if (bb === null) { + return 1; + } + typeof1 = typeof aa; + typeof2 = typeof bb; + if (typeof1 === typeof2) { + return typeof1 === 'object' + ? 0 + : aa > bb + ? 1 + : -1; + } + if (typeof1 === 'boolean') { + return -1; + } + if (typeof2 === 'boolean') { + return 1; + } + if (typeof1 === 'number') { + return -1; + } + if (typeof2 === 'number') { + return 1; + } + if (typeof1 === 'string') { + return -1; + } + if (typeof2 === 'string') { + return 1; + } + return 0; + }; + }()); + switch (local.modeJs) { + + + + // run node js-env code - init-after + case 'node': + // require modules + local.fs = require('fs'); + break; + } +}()); +/* script-end /assets.utility2.lib.db.js */ + + + +/* script-begin /assets.utility2.lib.github_crud.js */ +///usr/bin/env node +/* istanbul instrument in package github-crud */ +/*jslint + bitwise: true, + browser: true, + maxerr: 8, + maxlen: 96, + node: true, + nomen: true, + regexp: true, + stupid: true +*/ +(function () { + 'use strict'; + var local; + + + + // run shared js-env code - init-before + (function () { + // init local + local = {}; + // init modeJs + local.modeJs = (function () { + try { + return typeof navigator.userAgent === 'string' && + typeof document.querySelector('body') === 'object' && + typeof XMLHttpRequest.prototype.open === 'function' && + 'browser'; + } catch (errorCaughtBrowser) { + return module.exports && + typeof process.versions.node === 'string' && + typeof require('http').createServer === 'function' && + 'node'; + } + }()); + // init global + local.global = local.modeJs === 'browser' + ? window + : global; + // init utility2_rollup + local = local.global.utility2_rollup || local; + // init lib + local.local = local.github_crud = local; + // init exports + if (local.modeJs === 'browser') { + local.global.utility2_github_crud = local; + } else { + module.exports = local; + module.exports.__dirname = __dirname; + module.exports.module = module; + } + }()); + + + + /* istanbul ignore next */ + // run shared js-env code - function-before + (function () { + local.httpRequest = function (options, onError) { + /* + * this function will request the data from options.url + */ + var chunkList, isDone, onError2, timerTimeout, request, response, urlParsed; + // init onError2 + onError2 = function (error) { + if (isDone) { + return; + } + isDone = true; + // cleanup timerTimeout + clearTimeout(timerTimeout); + // cleanup request and response + [request, response].forEach(function (stream) { + // try to end the stream + try { + stream.end(); + // else try to destroy the stream + } catch (errorCaught) { + try { + stream.destroy(); + } catch (ignore) { + } + } + }); + if (response && (response.statusCode < 200 || response.statusCode >= 300)) { + error = error || new Error(response.statusCode); + console.error(String(response.data)); + } + // debug response + console.error(new Date().toISOString() + ' http-response ' + JSON.stringify({ + statusCode: (response && response.statusCode) || 0, + method: options.method, + url: options.url + })); + onError(error, response); + }; + // init timerTimeout + timerTimeout = setTimeout(function () { + onError2(new Error('http-request timeout')); + }, options.timeout || 30000); + urlParsed = require('url').parse(options.url); + urlParsed.headers = options.headers; + urlParsed.method = options.method; + // debug request + console.error(); + console.error(new Date().toISOString() + ' http-request ' + JSON.stringify({ + method: options.method, + url: options.url + })); + request = require( + urlParsed.protocol.slice(0, -1) + ).request(urlParsed, function (_response) { + response = _response; + chunkList = []; + response + .on('data', function (chunk) { + chunkList.push(chunk); + }) + .on('end', function () { + response.data = Buffer.concat(chunkList); + onError2(); + }) + .on('error', onError2); + }).on('error', onError2); + request.end(options.data); + }; + + local.nop = function () { + /* + * this function will do nothing + */ + return; + }; + + local.onErrorWithStack = function (onError) { + /* + * this function will create a new callback that will call onError, + * and append the current stack to any error + */ + var stack; + stack = new Error().stack.replace((/(.*?)\n.*?$/m), '$1'); + return function (error, data, meta) { + if (error && + error !== local.errorDefault && + String(error.stack).indexOf(stack.split('\n')[2]) < 0) { + // append the current stack to error.stack + error.stack += '\n' + stack; + } + onError(error, data, meta); + }; + }; + + local.onNext = function (options, onError) { + /* + * this function will wrap onError inside the recursive function options.onNext, + * and append the current stack to any error + */ + options.onNext = local.onErrorWithStack(function (error, data, meta) { + try { + options.modeNext = error && !options.modeErrorIgnore + ? Infinity + : options.modeNext + 1; + onError(error, data, meta); + } catch (errorCaught) { + // throw errorCaught to break infinite recursion-loop + if (options.errorCaught) { + throw options.errorCaught; + } + options.errorCaught = errorCaught; + options.onNext(errorCaught, data, meta); + } + }); + return options; + }; + + local.onParallel = function (onError, onEach, onRetry) { + /* + * this function will create a function that will + * 1. run async tasks in parallel + * 2. if counter === 0 or error occurred, then call onError with error + */ + var onParallel; + onError = local.onErrorWithStack(onError); + onEach = onEach || local.nop; + onRetry = onRetry || local.nop; + onParallel = function (error, data) { + if (onRetry(error, data)) { + return; + } + // decrement counter + onParallel.counter -= 1; + // validate counter + console.assert(onParallel.counter >= 0 || error || onParallel.error); + // ensure onError is run only once + if (onParallel.counter < 0) { + return; + } + // handle error + if (error) { + onParallel.error = error; + // ensure counter <= 0 + onParallel.counter = -Math.abs(onParallel.counter); + } + // call onError when isDone + if (onParallel.counter <= 0) { + onError(error, data); + return; + } + onEach(); + }; + // init counter + onParallel.counter = 0; + // return callback + return onParallel; + }; + + local.onParallelList = function (options, onEach, onError) { + /* + * this function will + * 1. async-run onEach in parallel, + * with the given options.rateLimit and options.retryLimit + * 2. call onError when isDone + */ + var ii, onEach2, onParallel; + onEach2 = function () { + while (ii + 1 < options.list.length && onParallel.counter < options.rateLimit) { + ii += 1; + onParallel.ii += 1; + onParallel.remaining -= 1; + onEach({ + element: options.list[ii], + ii: ii, + list: options.list, + retry: 0 + }, onParallel); + } + }; + onParallel = local.onParallel(onError, onEach2, function (error, data) { + if (error && data && data.retry < options.retryLimit) { + local.onErrorDefault(error); + data.retry += 1; + setTimeout(function () { + onParallel.counter -= 1; + onEach(data, onParallel); + }, 1000); + return true; + } + }); + onParallel.counter += 1; + ii = -1; + onParallel.ii = -1; + onParallel.remaining = options.list.length; + options.rateLimit = Number(options.rateLimit) || 4; + options.rateLimit = Math.max(options.rateLimit, 3); + options.retryLimit = Number(options.retryLimit) || 2; + onEach2(); + onParallel(); + }; + + local.onReadyAfter = function (onError) { + /* + * this function will call onError when onReadyBefore.counter === 0 + */ + local.onReadyBefore.counter += 1; + local.taskCreate({ key: 'utility2.onReadyAfter' }, null, onError); + local.onResetAfter(local.onReadyBefore); + return onError; + }; + }()); + switch (local.modeJs) { + + + + // run node js-env code - function + case 'node': + local.contentDelete = function (options, onError) { + /* + * this function will delete the github file + * https://developer.github.com/v3/repos/contents/#delete-a-file + */ + options = { message: options.message, url: options.url }; + local.onNext(options, function (error, data) { + switch (options.modeNext) { + case 1: + // get sha + local.contentRequest({ method: 'GET', url: options.url }, options.onNext); + break; + case 2: + // delete file with sha + if (!error && data.sha) { + local.contentRequest({ + message: options.message, + method: 'DELETE', + sha: data.sha, + url: options.url + }, options.onNext); + return; + } + // delete tree + local.onParallelList({ list: data }, function (data, onParallel) { + onParallel.counter += 1; + // recurse + local.contentDelete({ + message: options.message, + url: data.element.url + }, onParallel); + }, options.onNext); + break; + default: + onError(); + } + }); + options.modeNext = 0; + options.onNext(); + }; + + local.contentGet = function (options, onError) { + /* + * this function will get the github file + * https://developer.github.com/v3/repos/contents/#get-contents + */ + options = { url: options.url }; + local.onNext(options, function (error, data) { + switch (options.modeNext) { + case 1: + local.contentRequest({ method: 'GET', url: options.url }, options.onNext); + break; + case 2: + options.onNext(null, new Buffer(data.content, 'base64')); + break; + default: + onError(error, !error && data); + } + }); + options.modeNext = 0; + options.onNext(); + }; + + local.contentPut = function (options, onError) { + /* + * this function will put options.content into the github file + * https://developer.github.com/v3/repos/contents/#update-a-file + */ + options = { + content: options.content, + message: options.message, + modeErrorIgnore: true, + url: options.url + }; + local.onNext(options, function (error, data) { + switch (options.modeNext) { + case 1: + // get sha + local.contentRequest({ method: 'GET', url: options.url }, options.onNext); + break; + case 2: + // put file with sha + local.contentRequest({ + content: options.content, + message: options.message, + method: 'PUT', + sha: data.sha, + url: options.url + }, options.onNext); + break; + default: + onError(error); + } + }); + options.modeNext = 0; + options.onNext(); + }; + + local.contentPutFile = function (options, onError) { + /* + * this function will put options.file into the github file + * https://developer.github.com/v3/repos/contents/#update-a-file + */ + options = { file: options.file, message: options.message, url: options.url }; + local.onNext(options, function (error, data) { + switch (options.modeNext) { + case 1: + // get file from url + if ((/^(?:http|https):\/\//).test(options.file)) { + local.httpRequest({ + method: 'GET', + url: options.file + }, function (error, response) { + options.onNext(error, response && response.data); + }); + return; + } + // get file + local.fs.readFile( + local.path.resolve(process.cwd(), options.file), + options.onNext + ); + break; + case 2: + local.contentPut({ + content: data, + message: options.message, + // resolve file in url + url: (/\/$/).test(options.url) + ? options.url + local.path.basename(options.file) + : options.url + }, options.onNext); + break; + default: + onError(error); + } + }); + options.modeNext = 0; + options.onNext(); + }; + + local.contentRequest = function (options, onError) { + /* + * this function will request the content from github + */ + // init options + options = { + chunkList: [], + content: options.content, + headers: { + // github oauth authentication + Authorization: 'token ' + process.env.GITHUB_TOKEN, + // bug-workaround - https://developer.github.com/v3/#user-agent-required + 'User-Agent': 'undefined' + }, + message: options.message, + method: options.method, + responseJson: {}, + sha: options.sha, + url: options.url + }; + options.url = options.url +/* jslint-ignore-begin */ +// parse https://github.com/:owner/:repo/blob/:branch/:path +.replace( + (/^https:\/\/github.com\/([^\/]+?\/[^\/]+?)\/blob\/([^\/]+?)\/(.+)/), + 'https://api.github.com/repos/$1/contents/$3?branch=$2' +) +// parse https://github.com/:owner/:repo/tree/:branch/:path +.replace( + (/^https:\/\/github.com\/([^\/]+?\/[^\/]+?)\/tree\/([^\/]+?)\/(.+)/), + 'https://api.github.com/repos/$1/contents/$3?branch=$2' +) +// parse https://raw.githubusercontent.com/:owner/:repo/:branch/:path +.replace( +(/^https:\/\/raw.githubusercontent.com\/([^\/]+?\/[^\/]+?)\/([^\/]+?)\/(.+)/), + 'https://api.github.com/repos/$1/contents/$3?branch=$2' +) +// parse https://:owner.github.io/:repo/:path +.replace( + (/^https:\/\/([^\.]+?)\.github\.io\/([^\/]+?)\/(.+)/), + 'https://api.github.com/repos/$1/$2/contents/$3?branch=gh-pages' +) +/* jslint-ignore-end */ + .replace((/\?branch=(.*)/), function (match0, match1) { + options.branch = match1; + if (options.method === 'GET') { + match0 = match0.replace('branch', 'ref'); + } + return match0; + }); + if (options.url.indexOf('https://api.github.com/repos/') !== 0) { + onError(new Error('invalid url ' + options.url)); + return; + } + if (options.method !== 'GET') { + options.message = options.message || + '[ci skip] ' + options.method + ' file ' + options.url + .replace((/\?.*/), ''); + options.url += '&message=' + encodeURIComponent(options.message); + if (options.sha) { + options.url += '&sha=' + options.sha; + } + options.data = JSON.stringify({ + branch: options.branch, + content: new Buffer(options.content || '').toString('base64'), + message: options.message, + sha: options.sha + }); + } + local.httpRequest(options, function (error, response) { + try { + options.responseJson = JSON.parse(response.data.toString()); + } catch (ignore) { + } + onError(error, options.responseJson); + }); + }; + + local.contentTouch = function (options, onError) { + /* + * this function will touch options.url + * https://developer.github.com/v3/repos/contents/#update-a-file + */ + options = { + message: options.message, + modeErrorIgnore: true, + url: options.url + }; + local.onNext(options, function (error, data) { + switch (options.modeNext) { + case 1: + // get sha + local.contentRequest({ method: 'GET', url: options.url }, options.onNext); + break; + case 2: + // put file with sha + local.contentRequest({ + content: new Buffer(data.content || '', 'base64'), + message: options.message, + method: 'PUT', + sha: data.sha, + url: options.url + }, options.onNext); + break; + default: + onError(error); + } + }); + options.modeNext = 0; + options.onNext(); + }; + + local.contentTouchList = function (options, onError) { + /* + * this function will touch options.urlList in parallel + * https://developer.github.com/v3/repos/contents/#update-a-file + */ + local.onParallelList({ list: options.urlList }, function (data, onParallel) { + onParallel.counter += 1; + local.contentTouch({ + message: options.message, + modeErrorIgnore: true, + url: data.element + }, onParallel); + }, onError); + }; + break; + } + switch (local.modeJs) { + + + + /* istanbul ignore next */ + // run node js-env code - init-after + case 'node': + // require modules + local.fs = require('fs'); + local.path = require('path'); + // run the cli + if (module !== require.main || local.global.utility2_rollup) { + break; + } + switch (String(process.argv[2]).toLowerCase()) { + // delete file + case 'delete': + local.contentDelete({ + message: process.argv[4], + url: process.argv[3] + }, function (error) { + // validate no error occurred + console.assert(!error, error); + }); + break; + // get file + case 'get': + local.contentGet({ url: process.argv[3] }, function (error, data) { + // validate no error occurred + console.assert(!error, error); + try { + process.stdout.write(data); + } catch (ignore) { + } + }); + break; + // put file + case 'put': + local.contentPutFile({ + message: process.argv[5], + url: process.argv[3], + file: process.argv[4] + }, function (error) { + // validate no error occurred + console.assert(!error, error); + }); + break; + // touch file + case 'touch': + local.contentTouch({ + message: process.argv[4], + url: process.argv[3] + }, function (error) { + // validate no error occurred + console.assert(!error, error); + }); + break; + case 'touchlist': + local.contentTouchList({ + message: process.argv[4], + urlList: process.argv[3].split(' ').filter(function (element) { + return element; + }) + }, function (error) { + // validate no error occurred + console.assert(!error, error); + }); + break; + } + break; + } +}()); +/* script-end /assets.utility2.lib.github_crud.js */ + + + +/* script-begin /assets.utility2.lib.istanbul.js */ +///usr/bin/env node +/* istanbul instrument in package istanbul */ +/*jslint + bitwise: true, + browser: true, + maxerr: 8, + maxlen: 96, + node: true, + nomen: true, + regexp: true, + stupid: true +*/ +(function (local) { + 'use strict'; + var __dirname, process, require; + + + + // run shared js-env code - init-before + (function () { + // jslint-hack + local.nop(__dirname); + __dirname = ''; + /* istanbul ignore next */ + local.global.__coverageCodeDict__ = local.global.__coverageCodeDict__ || {}; + local['./package.json'] = {}; + process = local.modeJs === 'browser' + ? { + cwd: function () { + return ''; + }, + stdout: {} + } + : local.process; + require = function (key) { + try { + return local[key] || local.require(key); + } catch (ignore) { + } + }; + }()); + + + + // run shared js-env code - function + (function () { + local.coverageMerge = function (coverage1, coverage2) { + /* + * this function will merge coverage2 into coverage1 + */ + var dict1, dict2; + coverage1 = coverage1 || {}; + coverage2 = coverage2 || {}; + Object.keys(coverage2).forEach(function (file) { + if (!coverage2[file]) { + return; + } + // if file is undefined in coverage1, then add it + if (!coverage1[file]) { + coverage1[file] = coverage2[file]; + return; + } + // merge file from coverage2 into coverage1 + ['b', 'f', 's'].forEach(function (key) { + dict1 = coverage1[file][key]; + dict2 = coverage2[file][key]; + switch (key) { + // increment coverage for branch lines + case 'b': + Object.keys(dict2).forEach(function (key) { + dict2[key].forEach(function (count, ii) { + dict1[key][ii] += count; + }); + }); + break; + // increment coverage for function and statement lines + case 'f': + case 's': + Object.keys(dict2).forEach(function (key) { + dict1[key] += dict2[key]; + }); + break; + } + }); + }); + return coverage1; + }; + + local.coverageReportCreate = function () { + /* + * this function will + * 1. print coverage in text-format to stdout + * 2. write coverage in html-format to filesystem + * 3. return coverage in html-format as single document + */ + var options; + /* istanbul ignore next */ + if (!local.global.__coverage__) { + return ''; + } + options = {}; + options.dir = process.cwd() + '/tmp/build/coverage.html'; + // merge previous coverage + if (local.modeJs === 'node' && process.env.npm_config_mode_coverage_merge) { + console.log('merging file://' + options.dir + '/coverage.json to coverage'); + try { + local.coverageMerge( + local.global.__coverage__, + JSON.parse( + local._fs.readFileSync(options.dir + '/coverage.json', 'utf8') + ) + ); + } catch (ignore) { + } + try { + options.coverageCodeDict = JSON.parse(local._fs.readFileSync( + options.dir + '/coverage.code-dict.json', + 'utf8' + )); + Object.keys(options.coverageCodeDict).forEach(function (key) { + local.global.__coverageCodeDict__[key] = + local.global.__coverageCodeDict__[key] || + options.coverageCodeDict[key]; + }); + } catch (ignore) { + } + } + // init writer + local.coverageReportHtml = ''; + local.coverageReportHtml += '
\n' + + '

coverage-report

\n' + + '
\n'; + local.writerData = ''; + options.sourceStore = {}; + options.writer = local.writer; + // 1. print coverage in text-format to stdout + new local.TextReport(options).writeReport(local.collector); + // 2. write coverage in html-format to filesystem + new local.HtmlReport(options).writeReport(local.collector); + local.writer.writeFile('', local.nop); + // write coverage.json + local.fsWriteFileWithMkdirpSync2( + options.dir + '/coverage.json', + JSON.stringify(local.global.__coverage__) + ); + // write coverage.code-dict.json + local.fsWriteFileWithMkdirpSync2( + options.dir + '/coverage.code-dict.json', + JSON.stringify(local.global.__coverageCodeDict__) + ); + // write coverage.badge.svg + options.pct = local.coverageReportSummary.root.metrics.lines.pct; + local.fsWriteFileWithMkdirpSync2( + local.path.dirname(options.dir) + '/coverage.badge.svg', + local.templateCoverageBadgeSvg + // edit coverage badge percent + .replace((/100.0/g), options.pct) + // edit coverage badge color + .replace( + (/0d0/g), + ('0' + Math.round((100 - options.pct) * 2.21).toString(16)).slice(-2) + + ('0' + Math.round(options.pct * 2.21).toString(16)).slice(-2) + '00' + ) + ); + console.log('created coverage file://' + options.dir + '/index.html'); + // 3. return coverage in html-format as a single document + local.coverageReportHtml += '
\n
\n'; + // write coverage.rollup.html + local.fsWriteFileWithMkdirpSync2( + options.dir + '/coverage.rollup.html', + local.coverageReportHtml + ); + return local.coverageReportHtml; + }; + + local.fs = {}; + + local.fs.readFileSync = function (file) { + // return head.txt or foot.txt + file = local[file.slice(-8)]; + if (local.modeJs === 'browser') { + file = file + .replace((/\bhtml\b/g), 'x-istanbul-html') + .replace((/\n\ +\n\ +\n\ +
\n\ +

\n\ + {{env.npm_package_name}} (v{{env.npm_package_version}})\n\ +

\n\ +

Code coverage report for {{entity}}

\n\ +

\n\ + {{#with metrics.statements}}\n\ + Statements: {{pct}}% ({{covered}} / {{total}})     \n\ + {{/with}}\n\ + {{#with metrics.branches}}\n\ + Branches: {{pct}}% ({{covered}} / {{total}})     \n\ + {{/with}}\n\ + {{#with metrics.functions}}\n\ + Functions: {{pct}}% ({{covered}} / {{total}})     \n\ + {{/with}}\n\ + {{#with metrics.lines}}\n\ + Lines: {{pct}}% ({{covered}} / {{total}})     \n\ + {{/with}}\n\ + Ignored: {{#show_ignores metrics}}{{/show_ignores}}     \n\ +

\n\ + {{{pathHtml}}}\n\ +
\n\ +
\n\ +'; +/* jslint-ignore-end */ + + + + /* istanbul ignore next */ + // init lib istanbul.util.file-writer + (function () { + // https://github.com/gotwarlost/istanbul/blob/v0.2.16/lib/util/file-writer.js + local.writer = { + write: function (data) { + local.writerData += data; + }, + writeFile: function (file, onError) { + local.coverageReportHtml += local.writerData + '\n\n'; + if (local.writerFile) { + local.fsWriteFileWithMkdirpSync2(local.writerFile, local.writerData); + } + local.writerData = ''; + local.writerFile = file; + onError(local.writer); + } + }; + }()); + + + + /* istanbul ignore next */ + // init lib istanbul.util.tree-summarizer + (function () { + var module; + module = {}; +/* jslint-ignore-begin */ +// https://github.com/gotwarlost/istanbul/blob/v0.2.16/lib/util/tree-summarizer.js +// utility2-uglifyjs https://raw.githubusercontent.com/gotwarlost/istanbul/v0.2.16/lib/util/tree-summarizer.js +function commonArrayPrefix(e,t){var n=e.length0&&(t.pop(),s=i,o=s.children,s.children=[],i=new +Node(t.join(SEP)+SEP,"dir"),i.addChild(s),o.forEach(function(e){e.kind==="dir"?i +.addChild(e):s.addChild(e)})),this.fixupNodes(i,t.join(SEP)+SEP),this.calculateMetrics +(i),this.root=i,this.map={},this.indexAndSortTree(i,this.map)},fixupNodes:function( +e,t,n){var r=this;e.name.indexOf(t)===0&&(e.name=e.name.substring(t.length)),e.name +.charAt(0)===SEP&&(e.name=e.name.substring(1)),n?n.name!=="__root__/"?e.relativeName= +e.name.substring(n.name.length):e.relativeName=e.name:e.relativeName=e.name.substring +(t.length),e.children.forEach(function(n){r.fixupNodes(n,t,e)})},calculateMetrics +:function(e){var t=this,n;if(e.kind!=="dir")return;e.children.forEach(function(e +){t.calculateMetrics(e)}),e.metrics=utils.mergeSummaryObjects.apply(null,e.children +.map(function(e){return e.metrics})),n=e.children.filter(function(e){return e.kind!=="dir" +}),n.length>0?e.packageMetrics=utils.mergeSummaryObjects.apply(null,n.map(function( +e){return e.metrics})):e.packageMetrics=null},indexAndSortTree:function(e,t){var n= +this;t[e.name]=e,e.children.sort(function(e,t){return e=e.relativeName,t=t.relativeName +,et?1:0}),e.children.forEach(function(e){n.indexAndSortTree(e,t)})},toJSON +:function(){return{prefix:this.prefix,root:this.root.toJSON()}}},TreeSummarizer. +prototype={addFileCoverageSummary:function(e,t){this.summaryMap[e]=t},getTreeSummary +:function(){var e=findCommonArrayPrefix(Object.keys(this.summaryMap));return new +TreeSummary(this.summaryMap,e)}},module.exports=TreeSummarizer +/* jslint-ignore-end */ + local['../util/tree-summarizer'] = module.exports; + module.exports.prototype._getTreeSummary = module.exports.prototype.getTreeSummary; + module.exports.prototype.getTreeSummary = function () { + local.coverageReportSummary = this._getTreeSummary(); + return local.coverageReportSummary; + }; + }()); + + + +/* istanbul ignore next */ +// init lib istanbul.report.html +/* jslint-ignore-begin */ +// https://github.com/gotwarlost/istanbul/blob/v0.2.16/lib/report/html.js +// utility2-uglifyjs https://raw.githubusercontent.com/gotwarlost/istanbul/v0.2.16/lib/report/html.js +(function () { var module; module = {}; +function customEscape(e){return e=e.toString(),e.replace(RE_AMP,"&").replace +(RE_LT,"<").replace(RE_GT,">").replace(RE_lt,"<").replace(RE_gt,">")}function title +(e){return' title="'+e+'" '}function annotateLines(e,t){var n=e.l;if(!n)return;Object +.keys(n).forEach(function(e){var r=n[e];t[e].covered=r>0?"yes":"no"}),t.forEach( +function(e){e.covered===null&&(e.covered="neutral")})}function annotateStatements +(e,t){var n=e.s,r=e.statementMap;Object.keys(n).forEach(function(e){var i=n[e],s= +r[e],o=i>0?"yes":"no",u=s.start.column,a=s.end.column+1,f=s.start.line,l=s.end.line +,c=lt+'span class="'+(s.skip?"cstat-skip":"cstat-no")+'"'+title("statement not covered" +)+gt,h=lt+"/span"+gt,p;o==="no"&&(l!==f&&(l=f,a=t[f].text.originalLength()),p=t[ +f].text,p.wrap(u,c,f===l?a:p.originalLength(),h))})}function annotateFunctions(e +,t){var n=e.f,r=e.fnMap;if(!n)return;Object.keys(n).forEach(function(e){var i=n[ +e],s=r[e],o=i>0?"yes":"no",u=s.loc.start.column,a=s.loc.end.column+1,f=s.loc.start +.line,l=s.loc.end.line,c=lt+'span class="'+(s.skip?"fstat-skip":"fstat-no")+'"'+ +title("function not covered")+gt,h=lt+"/span"+gt,p;o==="no"&&(l!==f&&(l=f,a=t[f] +.text.originalLength()),p=t[f].text,p.wrap(u,c,f===l?a:p.originalLength(),h))})} +function annotateBranches(e,t){var n=e.b,r=e.branchMap;if(!n)return;Object.keys( +n).forEach(function(e){var i=n[e],s=i.reduce(function(e,t){return e+t},0),o=r[e] +.locations,u,a,f,l,c,h,p,d,v,m,g;if(s>0)for(u=0;u0?"yes":"no",c=f.start.column,h=f.end.column+1,p=f.start.line,d=f.end.line,v=lt+'span class="branch-'+ +u+" "+(f.skip?"cbranch-skip":"cbranch-no")+'"'+title("branch not covered")+gt,m= +lt+"/span"+gt,a===0&&(d!==p&&(d=p,h=t[p].text.originalLength()),g=t[p].text,r[e] +.type==="if"?g.insertAt(c,lt+'span class="'+(f.skip?"skip-if-branch":"missing-if-branch" +)+'"'+title((u===0?"if":"else")+" path not taken")+gt+(u===0?"I":"E")+lt+"/span"+ +gt,!0,!1):g.wrap(c,v,p===d?h:g.originalLength(),m))})}function getReportClass(e, +t){var n=e.pct,r=1;return n*r===n?n>=t[1]?"high":n>=t[0]?"medium":"low":""}function HtmlReport +(e){Report.call(this),this.opts=e||{},this.opts.dir=this.opts.dir||path.resolve( +process.cwd(),"html-report"),this.opts.sourceStore=this.opts.sourceStore||Store. +create("fslookup"),this.opts.linkMapper=this.opts.linkMapper||this.standardLinkMapper +(),this.opts.writer=this.opts.writer||null,this.opts.templateData={datetime:Date +()},this.opts.watermarks=this.opts.watermarks||defaults.watermarks()}var handlebars= +require("handlebars"),defaults=require("./common/defaults"),path=require("path") +,SEP=path.sep||"/",fs=require("fs"),util=require("util"),FileWriter=require("../util/file-writer" +),Report=require("./index"),Store=require("../store"),InsertionText=require("../util/insertion-text" +),TreeSummarizer=require("../util/tree-summarizer"),utils=require("../object-utils" +),templateFor=function(e){return handlebars.compile(fs.readFileSync(path.resolve +(__dirname,"templates",e+".txt"),"utf8"))},headerTemplate=templateFor("head"),footerTemplate= +templateFor("foot"),pathTemplate=handlebars.compile('
{{{html}}}
' +),detailTemplate=handlebars.compile(["",'{{#show_lines}}{{maxLines}}{{/show_lines}}' +,'{{#show_line_execution_counts fileCoverage}}{{maxLines}}{{/show_line_execution_counts}}' +,'
{{#show_code structured}}{{/show_code}}
' +,"\n"].join("")),summaryTableHeader=['
',"" +,"","",' ' +,' ' +,' ' +,' ' +,' ' +,' ' +,' ' +,' ' +,' ' +,' ' +,"","",""].join("\n"),summaryLineTemplate=handlebars.compile +(["",'' +,'' +,'' +,'' +,'' +,'' +,'' +,'' +,'' +,'' +,"\n"].join("\n ")),summaryTableFooter=["","
FileStatementsBranchesFunctionsLines
{{file}}{{#show_picture}}{{metrics.statements.pct}}{{/show_picture}}{{metrics.statements.pct}}%({{metrics.statements.covered}} / {{metrics.statements.total}}){{metrics.branches.pct}}%({{metrics.branches.covered}} / {{metrics.branches.total}}){{metrics.functions.pct}}%({{metrics.functions.covered}} / {{metrics.functions.total}}){{metrics.lines.pct}}%({{metrics.lines.covered}} / {{metrics.lines.total}})
","
"].join +("\n"),lt="",gt="",RE_LT=//g,RE_AMP=/&/g,RE_lt=/\u0001/g,RE_gt=/\u0002/g +;handlebars.registerHelper("show_picture",function(e){var t=Number(e.fn(this)),n +,r="";return isFinite(t)?(t===100&&(r=" cover-full"),t=Math.floor(t),n=100-t,''+''):""}),handlebars.registerHelper("show_ignores",function(e){var t= +e.statements.skipped,n=e.functions.skipped,r=e.branches.skipped,i;return t===0&& +n===0&&r===0?'none':(i=[],t>0&&i.push(t===1?"1 statement" +:t+" statements"),n>0&&i.push(n===1?"1 function":n+" functions"),r>0&&i.push(r===1?"1 branch" +:r+" branches"),i.join(", "))}),handlebars.registerHelper("show_lines",function( +e){var t=Number(e.fn(this)),n,r=[];for(n=0;n0?(u="yes",a=n[s]):u="no"),o.push(''+a+"");return o.join("\n")}),handlebars.registerHelper("show_code", +function(e){var t=[];return e.forEach(function(e){t.push(customEscape(e.text)||" " +)}),t.join("\n")}),HtmlReport.TYPE="html",util.inherits(HtmlReport,Report),Report +.mix(HtmlReport,{getPathHtml:function(e,t){var n=e.parent,r=[],i=[],s;while(n)r. +push(n),n=n.parent;for(s=0;s'+ +(r[s].relativeName||"All files")+"");return i.reverse(),i.length>0?i.join(" » " +)+" » "+e.displayShortName():""},fillTemplate:function(e,t){var n=this.opts +,r=n.linkMapper;t.entity=e.name||"All files",t.metrics=e.metrics,t.reportClass=getReportClass +(e.metrics.statements,n.watermarks.statements),t.pathHtml=pathTemplate({html:this +.getPathHtml(e,r)}),t.prettify={js:r.asset(e,"prettify.js"),css:r.asset(e,"prettify.css" +)}},writeDetailPage:function(e,t,n){var r=this.opts,i=r.sourceStore,s=r.templateData +,o=n.code&&Array.isArray(n.code)?n.code.join("\n")+"\n":i.get(n.path),u=o.split(/(?:\r?\n)|\r/ +),a=0,f=u.map(function(e){return a+=1,{line:a,covered:null,text:new InsertionText +(e,!0)}}),l;f.unshift({line:0,covered:null,text:new InsertionText("")}),this.fillTemplate +(t,s),e.write(headerTemplate(s)),e.write('
\n'),annotateLines
+(n,f),annotateBranches(n,f),annotateFunctions(n,f),annotateStatements(n,f),f.shift
+(),l={structured:f,maxLines:f.length,fileCoverage:n},e.write(detailTemplate(l)),
+e.write("
\n"),e.write(footerTemplate(s))},writeIndexPage:function( +e,t){var n=this.opts.linkMapper,r=this.opts.templateData,i=Array.prototype.slice +.apply(t.children),s=this.opts.watermarks;i.sort(function(e,t){return e.name0&&(o>=l?(f=padding(o-l),a=n?f+e: +e+f):(a=e.substring(l-o),a="... "+a.substring(4))),a=defaults.colorize(a,i),u+a} +function formatName(e,t,n,r){return fill(e,t,!1,n,r)}function formatPct(e,t){return fill +(e,PCT_COLS,!0,0,t)}function nodeName(e){return e.displayShortName()||"All files" +}function tableHeader(e){var t=[];return t.push(formatName("File",e,0)),t.push(formatPct +("% Stmts")),t.push(formatPct("% Branches")),t.push(formatPct("% Funcs")),t.push +(formatPct("% Lines")),t.join(" |")+" |"}function tableRow(e,t,n,r){var i=nodeName +(e),s=e.metrics.statements.pct,o=e.metrics.branches.pct,u=e.metrics.functions.pct +,a=e.metrics.lines.pct,f=[];return f.push(formatName(i,t,n,defaults.classFor("statements" +,e.metrics,r))),f.push(formatPct(s,defaults.classFor("statements",e.metrics,r))) +,f.push(formatPct(o,defaults.classFor("branches",e.metrics,r))),f.push(formatPct +(u,defaults.classFor("functions",e.metrics,r))),f.push(formatPct(a,defaults.classFor +("lines",e.metrics,r))),f.join(DELIM)+DELIM}function findNameWidth(e,t,n){n=n||0 +,t=t||0;var r=TAB_SIZE*t+nodeName(e).length;return r>n&&(n=r),e.children.forEach +(function(e){n=findNameWidth(e,t+1,n)}),n}function makeLine(e){var t=padding(e,"-" +),n=padding(PCT_COLS,"-"),r=[];return r.push(t),r.push(n),r.push(n),r.push(n),r. +push(n),r.join(COL_DELIM)+COL_DELIM}function walk(e,t,n,r,i){var s;r===0?(s=makeLine +(t),n.push(s),n.push(tableHeader(t)),n.push(s)):n.push(tableRow(e,t,r,i)),e.children +.forEach(function(e){walk(e,t,n,r+1,i)}),r===0&&(n.push(s),n.push(tableRow(e,t,r +,i)),n.push(s))}var path=require("path"),mkdirp=require("mkdirp"),fs=require("fs" +),defaults=require("./common/defaults"),Report=require("./index"),TreeSummarizer= +require("../util/tree-summarizer"),utils=require("../object-utils"),PCT_COLS=10, +TAB_SIZE=3,DELIM=" |",COL_DELIM="-|";TextReport.TYPE="text",Report.mix(TextReport +,{writeReport:function(e){var t=new TreeSummarizer,n,r,i,s=4*(PCT_COLS+2),o,u=[] +,a;e.files().forEach(function(n){t.addFileCoverageSummary(n,utils.summarizeFileCoverage +(e.fileCoverageFor(n)))}),n=t.getTreeSummary(),r=n.root,i=findNameWidth(r),this. +maxCols>0&&(o=this.maxCols-s-2,i>o&&(i=o)),walk(r,i,u,0,this.watermarks),a=u.join +("\n")+"\n",this.file?(mkdirp.sync(this.dir),fs.writeFileSync(path.join(this.dir +,this.file),a,"utf8")):console.log(a)}}),module.exports=TextReport +local.TextReport = module.exports; }()); +/* jslint-ignore-end */ + + + +/* jslint-ignore-begin */ +// https://img.shields.io/badge/coverage-100.0%-00dd00.svg?style=flat +local.templateCoverageBadgeSvg = +'coveragecoverage100.0%100.0%'; +/* jslint-ignore-end */ + switch (local.modeJs) { + + + + // run node js-env code - init-after + case 'node': + /* istanbul ignore next */ + // run the cli + local.cliRunIstanbul = function (options) { + /* + * this function will run the cli + */ + var tmp; + if ((module !== local.require.main || local.global.utility2_rollup) && + !(options && options.runMain)) { + return; + } + switch (process.argv[2]) { + // transparently adds coverage information to a node command + case 'cover': + try { + tmp = JSON.parse(local._fs.readFileSync('package.json', 'utf8')); + process.env.npm_package_nameAlias = process.env.npm_package_nameAlias || + tmp.nameAlias || + tmp.name.replace((/-/g), '_'); + } catch (ignore) { + } + process.env.npm_config_mode_coverage = process.env.npm_config_mode_coverage || + process.env.npm_package_nameAlias || + 'all'; + // add coverage hook to require + local._moduleExtensionsJs = local.module._extensions['.js']; + local.module._extensions['.js'] = function (module, file) { + if (typeof file === 'string' && + (file.indexOf(process.env.npm_config_mode_coverage_dir) === 0 || ( + file.indexOf(process.cwd()) === 0 && + file.indexOf(process.cwd() + '/node_modules/') !== 0 + ))) { + module._compile(local.instrumentInPackage( + local._fs.readFileSync(file, 'utf8'), + file + ), file); + return; + } + local._moduleExtensionsJs(module, file); + }; + // init process.argv + process.argv.splice(1, 2); + process.argv[1] = local.path.resolve(process.cwd(), process.argv[1]); + console.log('\ncovering $ ' + process.argv.join(' ')); + // create coverage on exit + process.on('exit', function () { + local.coverageReportCreate({ coverage: local.global.__coverage__ }); + }); + // re-run cli + local.module.runMain(); + break; + // instrument a file and print result to stdout + case 'instrument': + process.argv[3] = local.path.resolve(process.cwd(), process.argv[3]); + process.stdout.write(local.instrumentSync( + local._fs.readFileSync(process.argv[3], 'utf8'), + process.argv[3] + )); + break; + // cover a node command only when npm_config_mode_coverage is set + case 'test': + if (process.env.npm_config_mode_coverage) { + process.argv[2] = 'cover'; + // re-run cli + local.cliRunIstanbul(options); + return; + } + // init process.argv + process.argv.splice(1, 2); + process.argv[1] = local.path.resolve(process.cwd(), process.argv[1]); + // re-run cli + local.module.runMain(); + break; + } + }; + local.cliRunIstanbul(); + break; + } +}( + // run shared js-env code - init-before + (function () { + 'use strict'; + var local; + // init local + local = {}; + // init modeJs + local.modeJs = (function () { + try { + return typeof navigator.userAgent === 'string' && + typeof document.querySelector('body') === 'object' && + typeof XMLHttpRequest.prototype.open === 'function' && + 'browser'; + } catch (errorCaughtBrowser) { + return module.exports && + typeof process.versions.node === 'string' && + typeof require('http').createServer === 'function' && + 'node'; + } + }()); + // init global + local.global = local.modeJs === 'browser' + ? window + : global; + // init utility2_rollup + local = local.global.utility2_rollup || local; + // init lib + local.local = local.istanbul = local; + // init exports + if (local.modeJs === 'browser') { + local.global.utility2_istanbul = local; + } else { + module.exports = local; + module.exports.__dirname = __dirname; + } + local.fsWriteFileWithMkdirpSync = function (file, data) { + /* + * this function will synchronously 'mkdir -p' and write the data to file + */ + // try to write to file + try { + require('fs').writeFileSync(file, data); + } catch (errorCaught) { + // mkdir -p + require('child_process').spawnSync( + 'mkdir', + ['-p', require('path').dirname(file)], + { stdio: ['ignore', 1, 2] } + ); + // re-write to file + require('fs').writeFileSync(file, data); + } + }; + local.nop = function () { + /* + * this function will do nothing + */ + return; + }; + switch (local.modeJs) { + case 'browser': + local.fsWriteFileWithMkdirpSync2 = local.nop; + break; + case 'node': + local.fsWriteFileWithMkdirpSync2 = local.fsWriteFileWithMkdirpSync; + local.__dirname = __dirname; + local.process = process; + local.require = require; + break; + } + return local; + }()) +)); +/* script-end /assets.utility2.lib.istanbul.js */ + + + +/* script-begin /assets.utility2.lib.jslint.js */ +///usr/bin/env node +/* istanbul instrument in package jslint */ +/*jslint + bitwise: true, + browser: true, + maxerr: 8, + maxlen: 96, + node: true, + nomen: true, + regexp: true, + stupid: true +*/ +(function () { + 'use strict'; + var local; + + + + // run shared js-env code - init-before + (function () { + // init local + local = {}; + // init modeJs + local.modeJs = (function () { + try { + return typeof navigator.userAgent === 'string' && + typeof document.querySelector('body') === 'object' && + typeof XMLHttpRequest.prototype.open === 'function' && + 'browser'; + } catch (errorCaughtBrowser) { + return module.exports && + typeof process.versions.node === 'string' && + typeof require('http').createServer === 'function' && + 'node'; + } + }()); + // init global + local.global = local.modeJs === 'browser' + ? window + : global; + // init utility2_rollup + local = local.global.utility2_rollup || local; + // init lib + local.local = local.jslint = local; + // init exports + if (local.modeJs === 'browser') { + local.global.utility2_jslint = local; + } else { + module.exports = local; + module.exports.__dirname = __dirname; + module.exports.module = module; + } + }()); + + + +/* jslint-ignore-begin */ +/* istanbul ignore next */ +// init lib csslint +// https://github.com/CSSLint/csslint/blob/v0.10.0/release/csslint.js +// utility2-uglifyjs https://raw.githubusercontent.com/CSSLint/csslint/v0.10.0/release/csslint.js +(function () { +var exports=exports||{},CSSLint=function(){function Reporter(e,t){this.messages= +[],this.stats=[],this.lines=e,this.ruleset=t}var parserlib={};(function(){function e +(){this._listeners={}}function t(e){this._input=e.replace(/\n\r?/g,"\n"),this._line=1 +,this._col=1,this._cursor=0}function n(e,t,n){this.col=n,this.line=t,this.message= +e}function r(e,t,n,r){this.col=n,this.line=t,this.text=e,this.type=r}function i( +e,n){this._reader=e?new t(e.toString()):null,this._token=null,this._tokenData=n, +this._lt=[],this._ltIndex=0,this._ltIndexCache=[]}e.prototype={constructor:e,addListener +:function(e,t){this._listeners[e]||(this._listeners[e]=[]),this._listeners[e].push +(t)},fire:function(e){typeof e=="string"&&(e={type:e}),typeof e.target!="undefined"&& +(e.target=this);if(typeof e.type=="undefined")throw new Error("Event object missing 'type' property." +);if(this._listeners[e.type]){var t=this._listeners[e.type].concat();for(var n=0 +,r=t.length;n=0&& +this._ltIndex-1&&!t[u.type].hide&& +(u.channel=t[u.type].channel,this._token=u,this._lt.push(u),this._ltIndexCache.push +(this._lt.length-this._ltIndex+i),this._lt.length>5&&this._lt.shift(),this._ltIndexCache +.length>5&&this._ltIndexCache.shift(),this._ltIndex=this._lt.length),a=t[u.type] +,a&&(a.hide||a.channel!==undefined&&e!==a.channel)?this.get(e):u.type},LA:function( +e){var t=e,n;if(e>0){if(e>5)throw new Error("Too much lookahead.");while(t)n=this +.get(),t--;while(tthis._tokenData.length?"UNKNOWN_TOKEN":this._tokenData +[e].name},tokenType:function(e){return this._tokenData[e]||-1},unget:function(){ +if(!this._ltIndexCache.length)throw new Error("Too much lookahead.");this._ltIndex-= +this._ltIndexCache.pop(),this._token=this._lt[this._ltIndex-1]}},parserlib.util= +{StringReader:t,SyntaxError:n,SyntaxUnit:r,EventTarget:e,TokenStreamBase:i}})(), +function(){function Combinator(e,t,n){SyntaxUnit.call(this,e,t,n,Parser.COMBINATOR_TYPE +),this.type="unknown",/^\s+$/.test(e)?this.type="descendant":e==">"?this.type="child" +:e=="+"?this.type="adjacent-sibling":e=="~"&&(this.type="sibling")}function MediaFeature +(e,t){SyntaxUnit.call(this,"("+e+(t!==null?":"+t:"")+")",e.startLine,e.startCol, +Parser.MEDIA_FEATURE_TYPE),this.name=e,this.value=t}function MediaQuery(e,t,n,r, +i){SyntaxUnit.call(this,(e?e+" ":"")+(t?t:"")+(t&&n.length>0?" and ":"")+n.join(" and " +),r,i,Parser.MEDIA_QUERY_TYPE),this.modifier=e,this.mediaType=t,this.features=n} +function Parser(e){EventTarget.call(this),this.options=e||{},this._tokenStream=null +}function PropertyName(e,t,n,r){SyntaxUnit.call(this,e,n,r,Parser.PROPERTY_NAME_TYPE +),this.hack=t}function PropertyValue(e,t,n){SyntaxUnit.call(this,e.join(" "),t,n +,Parser.PROPERTY_VALUE_TYPE),this.parts=e}function PropertyValueIterator(e){this +._i=0,this._parts=e.parts,this._marks=[],this.value=e}function PropertyValuePart +(text,line,col){SyntaxUnit.call(this,text,line,col,Parser.PROPERTY_VALUE_PART_TYPE +),this.type="unknown";var temp;if(/^([+\-]?[\d\.]+)([a-z]+)$/i.test(text)){this. +type="dimension",this.value=+RegExp.$1,this.units=RegExp.$2;switch(this.units.toLowerCase +()){case"em":case"rem":case"ex":case"px":case"cm":case"mm":case"in":case"pt":case"pc" +:case"ch":case"vh":case"vw":case"vm":this.type="length";break;case"deg":case"rad" +:case"grad":this.type="angle";break;case"ms":case"s":this.type="time";break;case"hz" +:case"khz":this.type="frequency";break;case"dpi":case"dpcm":this.type="resolution" +}}else/^([+\-]?[\d\.]+)%$/i.test(text)?(this.type="percentage",this.value=+RegExp +.$1):/^([+\-]?[\d\.]+)%$/i.test(text)?(this.type="percentage",this.value=+RegExp +.$1):/^([+\-]?\d+)$/i.test(text)?(this.type="integer",this.value=+RegExp.$1):/^([+\-]?[\d\.]+)$/i +.test(text)?(this.type="number",this.value=+RegExp.$1):/^#([a-f0-9]{3,6})/i.test +(text)?(this.type="color",temp=RegExp.$1,temp.length==3?(this.red=parseInt(temp. +charAt(0)+temp.charAt(0),16),this.green=parseInt(temp.charAt(1)+temp.charAt(1),16 +),this.blue=parseInt(temp.charAt(2)+temp.charAt(2),16)):(this.red=parseInt(temp. +substring(0,2),16),this.green=parseInt(temp.substring(2,4),16),this.blue=parseInt +(temp.substring(4,6),16))):/^rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/i.test(text +)?(this.type="color",this.red=+RegExp.$1,this.green=+RegExp.$2,this.blue=+RegExp +.$3):/^rgb\(\s*(\d+)%\s*,\s*(\d+)%\s*,\s*(\d+)%\s*\)/i.test(text)?(this.type="color" +,this.red=+RegExp.$1*255/100,this.green=+RegExp.$2*255/100,this.blue=+RegExp.$3*255/100 +):/^rgba\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*([\d\.]+)\s*\)/i.test(text)?(this +.type="color",this.red=+RegExp.$1,this.green=+RegExp.$2,this.blue=+RegExp.$3,this +.alpha=+RegExp.$4):/^rgba\(\s*(\d+)%\s*,\s*(\d+)%\s*,\s*(\d+)%\s*,\s*([\d\.]+)\s*\)/i +.test(text)?(this.type="color",this.red=+RegExp.$1*255/100,this.green=+RegExp.$2*255/100 +,this.blue=+RegExp.$3*255/100,this.alpha=+RegExp.$4):/^hsl\(\s*(\d+)\s*,\s*(\d+)%\s*,\s*(\d+)%\s*\)/i +.test(text)?(this.type="color",this.hue=+RegExp.$1,this.saturation=+RegExp.$2/100 +,this.lightness=+RegExp.$3/100):/^hsla\(\s*(\d+)\s*,\s*(\d+)%\s*,\s*(\d+)%\s*,\s*([\d\.]+)\s*\)/i +.test(text)?(this.type="color",this.hue=+RegExp.$1,this.saturation=+RegExp.$2/100 +,this.lightness=+RegExp.$3/100,this.alpha=+RegExp.$4):/^url\(["']?([^\)"']+)["']?\)/i +.test(text)?(this.type="uri",this.uri=RegExp.$1):/^([^\(]+)\(/i.test(text)?(this +.type="function",this.name=RegExp.$1,this.value=text):/^["'][^"']*["']/.test(text +)?(this.type="string",this.value=eval(text)):Colors[text.toLowerCase()]?(this.type="color" +,temp=Colors[text.toLowerCase()].substring(1),this.red=parseInt(temp.substring(0 +,2),16),this.green=parseInt(temp.substring(2,4),16),this.blue=parseInt(temp.substring +(4,6),16)):/^[\,\/]$/.test(text)?(this.type="operator",this.value=text):/^[a-z\-\u0080-\uFFFF][a-z0-9\-\u0080-\uFFFF]*$/i +.test(text)&&(this.type="identifier",this.value=text)}function Selector(e,t,n){SyntaxUnit +.call(this,e.join(" "),t,n,Parser.SELECTOR_TYPE),this.parts=e,this.specificity=Specificity +.calculate(this)}function SelectorPart(e,t,n,r,i){SyntaxUnit.call(this,n,r,i,Parser +.SELECTOR_PART_TYPE),this.elementName=e,this.modifiers=t}function SelectorSubPart +(e,t,n,r){SyntaxUnit.call(this,e,n,r,Parser.SELECTOR_SUB_PART_TYPE),this.type=t, +this.args=[]}function Specificity(e,t,n,r){this.a=e,this.b=t,this.c=n,this.d=r}function isHexDigit +(e){return e!==null&&h.test(e)}function isDigit(e){return e!==null&&/\d/.test(e) +}function isWhitespace(e){return e!==null&&/\s/.test(e)}function isNewLine(e){return e!== +null&&nl.test(e)}function isNameStart(e){return e!==null&&/[a-z_\u0080-\uFFFF\\]/i +.test(e)}function isNameChar(e){return e!==null&&(isNameStart(e)||/[0-9\-\\]/.test +(e))}function isIdentStart(e){return e!==null&&(isNameStart(e)||/\-\\/.test(e))} +function mix(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);return e}function TokenStream +(e){TokenStreamBase.call(this,e,Tokens)}function ValidationError(e,t,n){this.col= +n,this.line=t,this.message=e}var EventTarget=parserlib.util.EventTarget,TokenStreamBase= +parserlib.util.TokenStreamBase,StringReader=parserlib.util.StringReader,SyntaxError= +parserlib.util.SyntaxError,SyntaxUnit=parserlib.util.SyntaxUnit,Colors={aliceblue +:"#f0f8ff",antiquewhite:"#faebd7",aqua:"#00ffff",aquamarine:"#7fffd4",azure:"#f0ffff" +,beige:"#f5f5dc",bisque:"#ffe4c4",black:"#000000",blanchedalmond:"#ffebcd",blue:"#0000ff" +,blueviolet:"#8a2be2",brown:"#a52a2a",burlywood:"#deb887",cadetblue:"#5f9ea0",chartreuse +:"#7fff00",chocolate:"#d2691e",coral:"#ff7f50",cornflowerblue:"#6495ed",cornsilk +:"#fff8dc",crimson:"#dc143c",cyan:"#00ffff",darkblue:"#00008b",darkcyan:"#008b8b" +,darkgoldenrod:"#b8860b",darkgray:"#a9a9a9",darkgreen:"#006400",darkkhaki:"#bdb76b" +,darkmagenta:"#8b008b",darkolivegreen:"#556b2f",darkorange:"#ff8c00",darkorchid:"#9932cc" +,darkred:"#8b0000",darksalmon:"#e9967a",darkseagreen:"#8fbc8f",darkslateblue:"#483d8b" +,darkslategray:"#2f4f4f",darkturquoise:"#00ced1",darkviolet:"#9400d3",deeppink:"#ff1493" +,deepskyblue:"#00bfff",dimgray:"#696969",dodgerblue:"#1e90ff",firebrick:"#b22222" +,floralwhite:"#fffaf0",forestgreen:"#228b22",fuchsia:"#ff00ff",gainsboro:"#dcdcdc" +,ghostwhite:"#f8f8ff",gold:"#ffd700",goldenrod:"#daa520",gray:"#808080",green:"#008000" +,greenyellow:"#adff2f",honeydew:"#f0fff0",hotpink:"#ff69b4",indianred:"#cd5c5c", +indigo:"#4b0082",ivory:"#fffff0",khaki:"#f0e68c",lavender:"#e6e6fa",lavenderblush +:"#fff0f5",lawngreen:"#7cfc00",lemonchiffon:"#fffacd",lightblue:"#add8e6",lightcoral +:"#f08080",lightcyan:"#e0ffff",lightgoldenrodyellow:"#fafad2",lightgray:"#d3d3d3" +,lightgreen:"#90ee90",lightpink:"#ffb6c1",lightsalmon:"#ffa07a",lightseagreen:"#20b2aa" +,lightskyblue:"#87cefa",lightslategray:"#778899",lightsteelblue:"#b0c4de",lightyellow +:"#ffffe0",lime:"#00ff00",limegreen:"#32cd32",linen:"#faf0e6",magenta:"#ff00ff", +maroon:"#800000",mediumaquamarine:"#66cdaa",mediumblue:"#0000cd",mediumorchid:"#ba55d3" +,mediumpurple:"#9370d8",mediumseagreen:"#3cb371",mediumslateblue:"#7b68ee",mediumspringgreen +:"#00fa9a",mediumturquoise:"#48d1cc",mediumvioletred:"#c71585",midnightblue:"#191970" +,mintcream:"#f5fffa",mistyrose:"#ffe4e1",moccasin:"#ffe4b5",navajowhite:"#ffdead" +,navy:"#000080",oldlace:"#fdf5e6",olive:"#808000",olivedrab:"#6b8e23",orange:"#ffa500" +,orangered:"#ff4500",orchid:"#da70d6",palegoldenrod:"#eee8aa",palegreen:"#98fb98" +,paleturquoise:"#afeeee",palevioletred:"#d87093",papayawhip:"#ffefd5",peachpuff:"#ffdab9" +,peru:"#cd853f",pink:"#ffc0cb",plum:"#dda0dd",powderblue:"#b0e0e6",purple:"#800080" +,red:"#ff0000",rosybrown:"#bc8f8f",royalblue:"#4169e1",saddlebrown:"#8b4513",salmon +:"#fa8072",sandybrown:"#f4a460",seagreen:"#2e8b57",seashell:"#fff5ee",sienna:"#a0522d" +,silver:"#c0c0c0",skyblue:"#87ceeb",slateblue:"#6a5acd",slategray:"#708090",snow +:"#fffafa",springgreen:"#00ff7f",steelblue:"#4682b4",tan:"#d2b48c",teal:"#008080" +,thistle:"#d8bfd8",tomato:"#ff6347",turquoise:"#40e0d0",violet:"#ee82ee",wheat:"#f5deb3" +,white:"#ffffff",whitesmoke:"#f5f5f5",yellow:"#ffff00",yellowgreen:"#9acd32",activeBorder +:"Active window border.",activecaption:"Active window caption.",appworkspace:"Background color of multiple document interface." +,background:"Desktop background.",buttonface:"The face background color for 3-D elements that appear 3-D due to one layer of surrounding border." +,buttonhighlight:"The color of the border facing the light source for 3-D elements that appear 3-D due to one layer of surrounding border." +,buttonshadow:"The color of the border away from the light source for 3-D elements that appear 3-D due to one layer of surrounding border." +,buttontext:"Text on push buttons.",captiontext:"Text in caption, size box, and scrollbar arrow box." +,graytext:"Grayed (disabled) text. This color is set to #000 if the current display driver does not support a solid gray color." +,highlight:"Item(s) selected in a control.",highlighttext:"Text of item(s) selected in a control." +,inactiveborder:"Inactive window border.",inactivecaption:"Inactive window caption." +,inactivecaptiontext:"Color of text in an inactive caption.",infobackground:"Background color for tooltip controls." +,infotext:"Text color for tooltip controls.",menu:"Menu background.",menutext:"Text in menus." +,scrollbar:"Scroll bar gray area.",threeddarkshadow:"The color of the darker (generally outer) of the two borders away from the light source for 3-D elements that appear 3-D due to two concentric layers of surrounding border." +,threedface:"The face background color for 3-D elements that appear 3-D due to two concentric layers of surrounding border." +,threedhighlight:"The color of the lighter (generally outer) of the two borders facing the light source for 3-D elements that appear 3-D due to two concentric layers of surrounding border." +,threedlightshadow:"The color of the darker (generally inner) of the two borders facing the light source for 3-D elements that appear 3-D due to two concentric layers of surrounding border." +,threedshadow:"The color of the lighter (generally inner) of the two borders away from the light source for 3-D elements that appear 3-D due to two concentric layers of surrounding border." +,window:"Window background.",windowframe:"Window frame.",windowtext:"Text in windows." +};Combinator.prototype=new SyntaxUnit,Combinator.prototype.constructor=Combinator +,MediaFeature.prototype=new SyntaxUnit,MediaFeature.prototype.constructor=MediaFeature +,MediaQuery.prototype=new SyntaxUnit,MediaQuery.prototype.constructor=MediaQuery +,Parser.DEFAULT_TYPE=0,Parser.COMBINATOR_TYPE=1,Parser.MEDIA_FEATURE_TYPE=2,Parser +.MEDIA_QUERY_TYPE=3,Parser.PROPERTY_NAME_TYPE=4,Parser.PROPERTY_VALUE_TYPE=5,Parser +.PROPERTY_VALUE_PART_TYPE=6,Parser.SELECTOR_TYPE=7,Parser.SELECTOR_PART_TYPE=8,Parser +.SELECTOR_SUB_PART_TYPE=9,Parser.prototype=function(){var e=new EventTarget,t,n= +{constructor:Parser,DEFAULT_TYPE:0,COMBINATOR_TYPE:1,MEDIA_FEATURE_TYPE:2,MEDIA_QUERY_TYPE +:3,PROPERTY_NAME_TYPE:4,PROPERTY_VALUE_TYPE:5,PROPERTY_VALUE_PART_TYPE:6,SELECTOR_TYPE +:7,SELECTOR_PART_TYPE:8,SELECTOR_SUB_PART_TYPE:9,_stylesheet:function(){var e=this +._tokenStream,t=null,n,r,i;this.fire("startstylesheet"),this._charset(),this._skipCruft +();while(e.peek()==Tokens.IMPORT_SYM)this._import(),this._skipCruft();while(e.peek +()==Tokens.NAMESPACE_SYM)this._namespace(),this._skipCruft();i=e.peek();while(i> +Tokens.EOF){try{switch(i){case Tokens.MEDIA_SYM:this._media(),this._skipCruft(); +break;case Tokens.PAGE_SYM:this._page(),this._skipCruft();break;case Tokens.FONT_FACE_SYM +:this._font_face(),this._skipCruft();break;case Tokens.KEYFRAMES_SYM:this._keyframes +(),this._skipCruft();break;case Tokens.VIEWPORT_SYM:this._viewport(),this._skipCruft +();break;case Tokens.UNKNOWN_SYM:e.get();if(!!this.options.strict)throw new SyntaxError +("Unknown @ rule.",e.LT(0).startLine,e.LT(0).startCol);this.fire({type:"error",error +:null,message:"Unknown @ rule: "+e.LT(0).value+".",line:e.LT(0).startLine,col:e. +LT(0).startCol}),n=0;while(e.advance([Tokens.LBRACE,Tokens.RBRACE])==Tokens.LBRACE +)n++;while(n)e.advance([Tokens.RBRACE]),n--;break;case Tokens.S:this._readWhitespace +();break;default:if(!this._ruleset())switch(i){case Tokens.CHARSET_SYM:throw r=e +.LT(1),this._charset(!1),new SyntaxError("@charset not allowed here.",r.startLine +,r.startCol);case Tokens.IMPORT_SYM:throw r=e.LT(1),this._import(!1),new SyntaxError +("@import not allowed here.",r.startLine,r.startCol);case Tokens.NAMESPACE_SYM:throw r= +e.LT(1),this._namespace(!1),new SyntaxError("@namespace not allowed here.",r.startLine +,r.startCol);default:e.get(),this._unexpectedToken(e.token())}}}catch(s){if(!(s instanceof +SyntaxError&&!this.options.strict))throw s;this.fire({type:"error",error:s,message +:s.message,line:s.line,col:s.col})}i=e.peek()}i!=Tokens.EOF&&this._unexpectedToken +(e.token()),this.fire("endstylesheet")},_charset:function(e){var t=this._tokenStream +,n,r,i,s;t.match(Tokens.CHARSET_SYM)&&(i=t.token().startLine,s=t.token().startCol +,this._readWhitespace(),t.mustMatch(Tokens.STRING),r=t.token(),n=r.value,this._readWhitespace +(),t.mustMatch(Tokens.SEMICOLON),e!==!1&&this.fire({type:"charset",charset:n,line +:i,col:s}))},_import:function(e){var t=this._tokenStream,n,r,i,s=[];t.mustMatch( +Tokens.IMPORT_SYM),i=t.token(),this._readWhitespace(),t.mustMatch([Tokens.STRING +,Tokens.URI]),r=t.token().value.replace(/(?:url\()?["']([^"']+)["']\)?/,"$1"),this +._readWhitespace(),s=this._media_query_list(),t.mustMatch(Tokens.SEMICOLON),this +._readWhitespace(),e!==!1&&this.fire({type:"import",uri:r,media:s,line:i.startLine +,col:i.startCol})},_namespace:function(e){var t=this._tokenStream,n,r,i,s;t.mustMatch +(Tokens.NAMESPACE_SYM),n=t.token().startLine,r=t.token().startCol,this._readWhitespace +(),t.match(Tokens.IDENT)&&(i=t.token().value,this._readWhitespace()),t.mustMatch +([Tokens.STRING,Tokens.URI]),s=t.token().value.replace(/(?:url\()?["']([^"']+)["']\)?/ +,"$1"),this._readWhitespace(),t.mustMatch(Tokens.SEMICOLON),this._readWhitespace +(),e!==!1&&this.fire({type:"namespace",prefix:i,uri:s,line:n,col:r})},_media:function( +){var e=this._tokenStream,t,n,r;e.mustMatch(Tokens.MEDIA_SYM),t=e.token().startLine +,n=e.token().startCol,this._readWhitespace(),r=this._media_query_list(),e.mustMatch +(Tokens.LBRACE),this._readWhitespace(),this.fire({type:"startmedia",media:r,line +:t,col:n});for(;;)if(e.peek()==Tokens.PAGE_SYM)this._page();else if(e.peek()==Tokens +.FONT_FACE_SYM)this._font_face();else if(!this._ruleset())break;e.mustMatch(Tokens +.RBRACE),this._readWhitespace(),this.fire({type:"endmedia",media:r,line:t,col:n} +)},_media_query_list:function(){var e=this._tokenStream,t=[];this._readWhitespace +(),(e.peek()==Tokens.IDENT||e.peek()==Tokens.LPAREN)&&t.push(this._media_query() +);while(e.match(Tokens.COMMA))this._readWhitespace(),t.push(this._media_query()) +;return t},_media_query:function(){var e=this._tokenStream,t=null,n=null,r=null, +i=[];e.match(Tokens.IDENT)&&(n=e.token().value.toLowerCase(),n!="only"&&n!="not"? +(e.unget(),n=null):r=e.token()),this._readWhitespace(),e.peek()==Tokens.IDENT?(t= +this._media_type(),r===null&&(r=e.token())):e.peek()==Tokens.LPAREN&&(r===null&& +(r=e.LT(1)),i.push(this._media_expression()));if(t===null&&i.length===0)return null +;this._readWhitespace();while(e.match(Tokens.IDENT))e.token().value.toLowerCase( +)!="and"&&this._unexpectedToken(e.token()),this._readWhitespace(),i.push(this._media_expression +());return new MediaQuery(n,t,i,r.startLine,r.startCol)},_media_type:function(){ +return this._media_feature()},_media_expression:function(){var e=this._tokenStream +,t=null,n,r=null;return e.mustMatch(Tokens.LPAREN),t=this._media_feature(),this. +_readWhitespace(),e.match(Tokens.COLON)&&(this._readWhitespace(),n=e.LT(1),r=this +._expression()),e.mustMatch(Tokens.RPAREN),this._readWhitespace(),new MediaFeature +(t,r?new SyntaxUnit(r,n.startLine,n.startCol):null)},_media_feature:function(){var e= +this._tokenStream;return e.mustMatch(Tokens.IDENT),SyntaxUnit.fromToken(e.token( +))},_page:function(){var e=this._tokenStream,t,n,r=null,i=null;e.mustMatch(Tokens +.PAGE_SYM),t=e.token().startLine,n=e.token().startCol,this._readWhitespace(),e.match +(Tokens.IDENT)&&(r=e.token().value,r.toLowerCase()==="auto"&&this._unexpectedToken +(e.token())),e.peek()==Tokens.COLON&&(i=this._pseudo_page()),this._readWhitespace +(),this.fire({type:"startpage",id:r,pseudo:i,line:t,col:n}),this._readDeclarations +(!0,!0),this.fire({type:"endpage",id:r,pseudo:i,line:t,col:n})},_margin:function( +){var e=this._tokenStream,t,n,r=this._margin_sym();return r?(t=e.token().startLine +,n=e.token().startCol,this.fire({type:"startpagemargin",margin:r,line:t,col:n}), +this._readDeclarations(!0),this.fire({type:"endpagemargin",margin:r,line:t,col:n +}),!0):!1},_margin_sym:function(){var e=this._tokenStream;return e.match([Tokens +.TOPLEFTCORNER_SYM,Tokens.TOPLEFT_SYM,Tokens.TOPCENTER_SYM,Tokens.TOPRIGHT_SYM,Tokens +.TOPRIGHTCORNER_SYM,Tokens.BOTTOMLEFTCORNER_SYM,Tokens.BOTTOMLEFT_SYM,Tokens.BOTTOMCENTER_SYM +,Tokens.BOTTOMRIGHT_SYM,Tokens.BOTTOMRIGHTCORNER_SYM,Tokens.LEFTTOP_SYM,Tokens.LEFTMIDDLE_SYM +,Tokens.LEFTBOTTOM_SYM,Tokens.RIGHTTOP_SYM,Tokens.RIGHTMIDDLE_SYM,Tokens.RIGHTBOTTOM_SYM +])?SyntaxUnit.fromToken(e.token()):null},_pseudo_page:function(){var e=this._tokenStream +;return e.mustMatch(Tokens.COLON),e.mustMatch(Tokens.IDENT),e.token().value},_font_face +:function(){var e=this._tokenStream,t,n;e.mustMatch(Tokens.FONT_FACE_SYM),t=e.token +().startLine,n=e.token().startCol,this._readWhitespace(),this.fire({type:"startfontface" +,line:t,col:n}),this._readDeclarations(!0),this.fire({type:"endfontface",line:t, +col:n})},_viewport:function(){var e=this._tokenStream,t,n;e.mustMatch(Tokens.VIEWPORT_SYM +),t=e.token().startLine,n=e.token().startCol,this._readWhitespace(),this.fire({type +:"startviewport",line:t,col:n}),this._readDeclarations(!0),this.fire({type:"endviewport" +,line:t,col:n})},_operator:function(e){var t=this._tokenStream,n=null;if(t.match +([Tokens.SLASH,Tokens.COMMA])||e&&t.match([Tokens.PLUS,Tokens.STAR,Tokens.MINUS] +))n=t.token(),this._readWhitespace();return n?PropertyValuePart.fromToken(n):null +},_combinator:function(){var e=this._tokenStream,t=null,n;return e.match([Tokens +.PLUS,Tokens.GREATER,Tokens.TILDE])&&(n=e.token(),t=new Combinator(n.value,n.startLine +,n.startCol),this._readWhitespace()),t},_unary_operator:function(){var e=this._tokenStream +;return e.match([Tokens.MINUS,Tokens.PLUS])?e.token().value:null},_property:function( +){var e=this._tokenStream,t=null,n=null,r,i,s,o;return e.peek()==Tokens.STAR&&this +.options.starHack&&(e.get(),i=e.token(),n=i.value,s=i.startLine,o=i.startCol),e. +match(Tokens.IDENT)&&(i=e.token(),r=i.value,r.charAt(0)=="_"&&this.options.underscoreHack&& +(n="_",r=r.substring(1)),t=new PropertyName(r,n,s||i.startLine,o||i.startCol),this +._readWhitespace()),t},_ruleset:function(){var e=this._tokenStream,t,n;try{n=this +._selectors_group()}catch(r){if(r instanceof SyntaxError&&!this.options.strict){ +this.fire({type:"error",error:r,message:r.message,line:r.line,col:r.col}),t=e.advance +([Tokens.RBRACE]);if(t!=Tokens.RBRACE)throw r;return!0}throw r}return n&&(this.fire +({type:"startrule",selectors:n,line:n[0].line,col:n[0].col}),this._readDeclarations +(!0),this.fire({type:"endrule",selectors:n,line:n[0].line,col:n[0].col})),n},_selectors_group +:function(){var e=this._tokenStream,t=[],n;n=this._selector();if(n!==null){t.push +(n);while(e.match(Tokens.COMMA))this._readWhitespace(),n=this._selector(),n!==null? +t.push(n):this._unexpectedToken(e.LT(1))}return t.length?t:null},_selector:function( +){var e=this._tokenStream,t=[],n=null,r=null,i=null;n=this._simple_selector_sequence +();if(n===null)return null;t.push(n);do{r=this._combinator();if(r!==null)t.push( +r),n=this._simple_selector_sequence(),n===null?this._unexpectedToken(e.LT(1)):t. +push(n);else{if(!this._readWhitespace())break;i=new Combinator(e.token().value,e +.token().startLine,e.token().startCol),r=this._combinator(),n=this._simple_selector_sequence +(),n===null?r!==null&&this._unexpectedToken(e.LT(1)):(r!==null?t.push(r):t.push( +i),t.push(n))}}while(!0);return new Selector(t,t[0].line,t[0].col)},_simple_selector_sequence +:function(){var e=this._tokenStream,t=null,n=[],r="",i=[function(){return e.match +(Tokens.HASH)?new SelectorSubPart(e.token().value,"id",e.token().startLine,e.token +().startCol):null},this._class,this._attrib,this._pseudo,this._negation],s=0,o=i +.length,u=null,a=!1,f,l;f=e.LT(1).startLine,l=e.LT(1).startCol,t=this._type_selector +(),t||(t=this._universal()),t!==null&&(r+=t);for(;;){if(e.peek()===Tokens.S)break; +while(s1&&e.unget()),null)},_class:function(){var e=this._tokenStream,t;return e +.match(Tokens.DOT)?(e.mustMatch(Tokens.IDENT),t=e.token(),new SelectorSubPart("."+ +t.value,"class",t.startLine,t.startCol-1)):null},_element_name:function(){var e= +this._tokenStream,t;return e.match(Tokens.IDENT)?(t=e.token(),new SelectorSubPart +(t.value,"elementName",t.startLine,t.startCol)):null},_namespace_prefix:function( +){var e=this._tokenStream,t="";if(e.LA(1)===Tokens.PIPE||e.LA(2)===Tokens.PIPE)e +.match([Tokens.IDENT,Tokens.STAR])&&(t+=e.token().value),e.mustMatch(Tokens.PIPE +),t+="|";return t.length?t:null},_universal:function(){var e=this._tokenStream,t="" +,n;return n=this._namespace_prefix(),n&&(t+=n),e.match(Tokens.STAR)&&(t+="*"),t. +length?t:null},_attrib:function(){var e=this._tokenStream,t=null,n,r;return e.match +(Tokens.LBRACKET)?(r=e.token(),t=r.value,t+=this._readWhitespace(),n=this._namespace_prefix +(),n&&(t+=n),e.mustMatch(Tokens.IDENT),t+=e.token().value,t+=this._readWhitespace +(),e.match([Tokens.PREFIXMATCH,Tokens.SUFFIXMATCH,Tokens.SUBSTRINGMATCH,Tokens.EQUALS +,Tokens.INCLUDES,Tokens.DASHMATCH])&&(t+=e.token().value,t+=this._readWhitespace +(),e.mustMatch([Tokens.IDENT,Tokens.STRING]),t+=e.token().value,t+=this._readWhitespace +()),e.mustMatch(Tokens.RBRACKET),new SelectorSubPart(t+"]","attribute",r.startLine +,r.startCol)):null},_pseudo:function(){var e=this._tokenStream,t=null,n=":",r,i; +return e.match(Tokens.COLON)&&(e.match(Tokens.COLON)&&(n+=":"),e.match(Tokens.IDENT +)?(t=e.token().value,r=e.token().startLine,i=e.token().startCol-n.length):e.peek +()==Tokens.FUNCTION&&(r=e.LT(1).startLine,i=e.LT(1).startCol-n.length,t=this._functional_pseudo +()),t&&(t=new SelectorSubPart(n+t,"pseudo",r,i))),t},_functional_pseudo:function( +){var e=this._tokenStream,t=null;return e.match(Tokens.FUNCTION)&&(t=e.token().value +,t+=this._readWhitespace(),t+=this._expression(),e.mustMatch(Tokens.RPAREN),t+=")" +),t},_expression:function(){var e=this._tokenStream,t="";while(e.match([Tokens.PLUS +,Tokens.MINUS,Tokens.DIMENSION,Tokens.NUMBER,Tokens.STRING,Tokens.IDENT,Tokens.LENGTH +,Tokens.FREQ,Tokens.ANGLE,Tokens.TIME,Tokens.RESOLUTION,Tokens.SLASH]))t+=e.token +().value,t+=this._readWhitespace();return t.length?t:null},_negation:function(){ +var e=this._tokenStream,t,n,r="",i,s=null;return e.match(Tokens.NOT)&&(r=e.token +().value,t=e.token().startLine,n=e.token().startCol,r+=this._readWhitespace(),i= +this._negation_arg(),r+=i,r+=this._readWhitespace(),e.match(Tokens.RPAREN),r+=e. +token().value,s=new SelectorSubPart(r,"not",t,n),s.args.push(i)),s},_negation_arg +:function(){var e=this._tokenStream,t=[this._type_selector,this._universal,function( +){return e.match(Tokens.HASH)?new SelectorSubPart(e.token().value,"id",e.token() +.startLine,e.token().startCol):null},this._class,this._attrib,this._pseudo],n=null +,r=0,i=t.length,s,o,u,a;o=e.LT(1).startLine,u=e.LT(1).startCol;while(r0?new PropertyValue(n,n[0].line,n[0].col):null},_term:function( +){var e=this._tokenStream,t=null,n=null,r,i,s;return t=this._unary_operator(),t!== +null&&(i=e.token().startLine,s=e.token().startCol),e.peek()==Tokens.IE_FUNCTION&& +this.options.ieFilters?(n=this._ie_function(),t===null&&(i=e.token().startLine,s= +e.token().startCol)):e.match([Tokens.NUMBER,Tokens.PERCENTAGE,Tokens.LENGTH,Tokens +.ANGLE,Tokens.TIME,Tokens.FREQ,Tokens.STRING,Tokens.IDENT,Tokens.URI,Tokens.UNICODE_RANGE +])?(n=e.token().value,t===null&&(i=e.token().startLine,s=e.token().startCol),this +._readWhitespace()):(r=this._hexcolor(),r===null?(t===null&&(i=e.LT(1).startLine +,s=e.LT(1).startCol),n===null&&(e.LA(3)==Tokens.EQUALS&&this.options.ieFilters?n= +this._ie_function():n=this._function())):(n=r.value,t===null&&(i=r.startLine,s=r +.startCol))),n!==null?new PropertyValuePart(t!==null?t+n:n,i,s):null},_function: +function(){var e=this._tokenStream,t=null,n=null,r;if(e.match(Tokens.FUNCTION)){ +t=e.token().value,this._readWhitespace(),n=this._expr(!0),t+=n;if(this.options.ieFilters&& +e.peek()==Tokens.EQUALS)do{this._readWhitespace()&&(t+=e.token().value),e.LA(0)== +Tokens.COMMA&&(t+=e.token().value),e.match(Tokens.IDENT),t+=e.token().value,e.match +(Tokens.EQUALS),t+=e.token().value,r=e.peek();while(r!=Tokens.COMMA&&r!=Tokens.S&& +r!=Tokens.RPAREN)e.get(),t+=e.token().value,r=e.peek()}while(e.match([Tokens.COMMA +,Tokens.S]));e.match(Tokens.RPAREN),t+=")",this._readWhitespace()}return t},_ie_function +:function(){var e=this._tokenStream,t=null,n=null,r;if(e.match([Tokens.IE_FUNCTION +,Tokens.FUNCTION])){t=e.token().value;do{this._readWhitespace()&&(t+=e.token().value +),e.LA(0)==Tokens.COMMA&&(t+=e.token().value),e.match(Tokens.IDENT),t+=e.token() +.value,e.match(Tokens.EQUALS),t+=e.token().value,r=e.peek();while(r!=Tokens.COMMA&& +r!=Tokens.S&&r!=Tokens.RPAREN)e.get(),t+=e.token().value,r=e.peek()}while(e.match +([Tokens.COMMA,Tokens.S]));e.match(Tokens.RPAREN),t+=")",this._readWhitespace()} +return t},_hexcolor:function(){var e=this._tokenStream,t=null,n;if(e.match(Tokens +.HASH)){t=e.token(),n=t.value;if(!/#[a-f0-9]{3,6}/i.test(n))throw new SyntaxError +("Expected a hex color but found '"+n+"' at line "+t.startLine+", col "+t.startCol+"." +,t.startLine,t.startCol);this._readWhitespace()}return t},_keyframes:function(){ +var e=this._tokenStream,t,n,r,i="";e.mustMatch(Tokens.KEYFRAMES_SYM),t=e.token() +,/^@\-([^\-]+)\-/.test(t.value)&&(i=RegExp.$1),this._readWhitespace(),r=this._keyframe_name +(),this._readWhitespace(),e.mustMatch(Tokens.LBRACE),this.fire({type:"startkeyframes" +,name:r,prefix:i,line:t.startLine,col:t.startCol}),this._readWhitespace(),n=e.peek +();while(n==Tokens.IDENT||n==Tokens.PERCENTAGE)this._keyframe_rule(),this._readWhitespace +(),n=e.peek();this.fire({type:"endkeyframes",name:r,prefix:i,line:t.startLine,col +:t.startCol}),this._readWhitespace(),e.mustMatch(Tokens.RBRACE)},_keyframe_name: +function(){var e=this._tokenStream,t;return e.mustMatch([Tokens.IDENT,Tokens.STRING +]),SyntaxUnit.fromToken(e.token())},_keyframe_rule:function(){var e=this._tokenStream +,t,n=this._key_list();this.fire({type:"startkeyframerule",keys:n,line:n[0].line, +col:n[0].col}),this._readDeclarations(!0),this.fire({type:"endkeyframerule",keys +:n,line:n[0].line,col:n[0].col})},_key_list:function(){var e=this._tokenStream,t +,n,r=[];r.push(this._key()),this._readWhitespace();while(e.match(Tokens.COMMA))this +._readWhitespace(),r.push(this._key()),this._readWhitespace();return r},_key:function( +){var e=this._tokenStream,t;if(e.match(Tokens.PERCENTAGE))return SyntaxUnit.fromToken +(e.token());if(e.match(Tokens.IDENT)){t=e.token();if(/from|to/i.test(t.value))return SyntaxUnit +.fromToken(t);e.unget()}this._unexpectedToken(e.LT(1))},_skipCruft:function(){while( +this._tokenStream.match([Tokens.S,Tokens.CDO,Tokens.CDC]));},_readDeclarations:function( +e,t){var n=this._tokenStream,r;this._readWhitespace(),e&&n.mustMatch(Tokens.LBRACE +),this._readWhitespace();try{for(;;){if(!(n.match(Tokens.SEMICOLON)||t&&this._margin +())){if(!this._declaration())break;if(!n.match(Tokens.SEMICOLON))break}this._readWhitespace +()}n.mustMatch(Tokens.RBRACE),this._readWhitespace()}catch(i){if(!(i instanceof +SyntaxError&&!this.options.strict))throw i;this.fire({type:"error",error:i,message +:i.message,line:i.line,col:i.col}),r=n.advance([Tokens.SEMICOLON,Tokens.RBRACE]) +;if(r==Tokens.SEMICOLON)this._readDeclarations(!1,t);else if(r!=Tokens.RBRACE)throw i +}},_readWhitespace:function(){var e=this._tokenStream,t="";while(e.match(Tokens. +S))t+=e.token().value;return t},_unexpectedToken:function(e){throw new SyntaxError +("Unexpected token '"+e.value+"' at line "+e.startLine+", col "+e.startCol+".",e +.startLine,e.startCol)},_verifyEnd:function(){this._tokenStream.LA(1)!=Tokens.EOF&& +this._unexpectedToken(this._tokenStream.LT(1))},_validateProperty:function(e,t){ +Validation.validate(e,t)},parse:function(e){this._tokenStream=new TokenStream(e, +Tokens),this._stylesheet()},parseStyleSheet:function(e){return this.parse(e)},parseMediaQuery +:function(e){this._tokenStream=new TokenStream(e,Tokens);var t=this._media_query +();return this._verifyEnd(),t},parsePropertyValue:function(e){this._tokenStream=new +TokenStream(e,Tokens),this._readWhitespace();var t=this._expr();return this._readWhitespace +(),this._verifyEnd(),t},parseRule:function(e){this._tokenStream=new TokenStream( +e,Tokens),this._readWhitespace();var t=this._ruleset();return this._readWhitespace +(),this._verifyEnd(),t},parseSelector:function(e){this._tokenStream=new TokenStream +(e,Tokens),this._readWhitespace();var t=this._selector();return this._readWhitespace +(),this._verifyEnd(),t},parseStyleAttribute:function(e){e+="}",this._tokenStream=new +TokenStream(e,Tokens),this._readDeclarations()}};for(t in n)n.hasOwnProperty(t)&& +(e[t]=n[t]);return e}();var Properties={"alignment-adjust":"auto | baseline | before-edge | text-before-edge | middle | central | after-edge | text-after-edge | ideographic | alphabetic | hanging | mathematical | | " +,"alignment-baseline":"baseline | use-script | before-edge | text-before-edge | after-edge | text-after-edge | central | middle | ideographic | alphabetic | hanging | mathematical" +,animation:1,"animation-delay":{multi:"
\n\ +'; + + + +// https://github.com/swagger-api/swagger-ui/blob/v2.1.3/src/main/template/param.handlebars +local.templateUiParam = '\ +\n\ + {{name}}\n\ + {{#if description}}\n\ +
{{description htmlSafe}}\n\ + {{/if description}}\n\ +
\n\ +{{type2}}{{#if format2}}
({{format2}}){{/if format2}}
\n\ +\n\ + {{#if isTextarea}}\n\ + \n\ + {{/if isTextarea}}\n\ + {{#if isFile}}\n\ + \n\ + {{/if isFile}}\n\ + {{#if isSelect}}\n\ + \n\ + {{/if isSelect}}\n\ + {{#if isInputText}}\n\ + \n\ + {{/if isInputText}}\n\ +\n\ +{{#if schemaText}}
{{schemaText}}
{{/if schemaText}}
\n\ +'; + + + +// https://github.com/swagger-api/swagger-ui/blob/v2.1.3/src/main/template/resource.handlebars +local.templateUiResource = '\ +\n\ +
\n\ + {{name}} :\n\ + {{#if description}}\n\ + {{description htmlSafe}}\n\ + {{/if description}}\n\ + \n\ + Show\n\ + Expand / Collapse Operations\n\ + Datatable\n\ +
\n\ + \n\ +\n\ +'; + + + +local.templateUiResponseAjax = '\ +

Curl Request

\n\ +{{#if errorValidate}}\n\ +
n/a
\n\ +{{#unless errorValidate}}\n\ +
{{curl htmlSafe}}
\n\ +{{/if errorValidate}}\n\ +

Response Code

\n\ +
{{statusCode}}
\n\ +

Response Headers

\n\ +{{#if errorValidate}}\n\ +
n/a
\n\ +{{#unless errorValidate}}\n\ +
{{responseHeaders htmlSafe}}
\n\ +{{/if errorValidate}}\n\ +

Response Body

\n\ +{{responseBody}}\n\ +'; +/* jslint-ignore-end */ + local.swaggerSchemaJson = local.jsonCopy(local.objectSetOverride( + JSON.parse(local.assetsDict['/assets.swgg.json-schema.json']), + JSON.parse(local.assetsDict['/assets.swgg.schema.json']), + 2 + )); + }()); + + + + // run shared js-env code - function + (function () { + local.apiAjax = function (self, options, onError) { + /* + * this function will send a swagger-api ajax-request with the pathObject self + */ + var isMultipartFormData, tmp; + isMultipartFormData = (self.consumes && self.consumes[0]) === 'multipart/form-data'; + local.objectSetDefault(options, { data: '', paramDict: {}, url: '' }); + // try to validate paramDict + local.tryCatchOnError(function () { + local.validateByParamDefList({ + // normalize paramDict + data: local.normalizeParamDictSwagger( + local.jsonCopy(options.paramDict), + self + ), + dataReadonlyRemove: options.paramDict, + key: self.operationId, + paramDefList: self.parameters + }); + }, function (error) { + options.errorValidate = error; + onError(error); + }); + if (options.errorValidate) { + return; + } + // init options-defaults + local.objectSetDefault(options, { + inForm: isMultipartFormData + ? new local.FormData() + : '', + inHeader: {}, + inPath: self._path, + inQuery: '', + headers: {}, + method: self._method, + responseType: self.produces && + self.produces[0].indexOf('application/octet-stream') === 0 + ? 'arraybuffer' + : '' + }); + // init paramDict + self.parameters.forEach(function (paramDef) { + tmp = options.paramDict[paramDef.name]; + if (tmp === undefined) { + return; + } + // serialize array + if (paramDef.type === 'array' && paramDef.in !== 'body') { + if (typeof tmp !== 'string') { + switch (paramDef.collectionFormat) { + case 'json': + tmp = JSON.stringify(tmp); + break; + case 'multi': + tmp.forEach(function (value) { + options[paramDef.in === 'formData' + ? 'inForm' + : 'inQuery'] += '&' + + encodeURIComponent(paramDef.name) + '=' + + encodeURIComponent(paramDef.items.type === 'string' + ? value + : JSON.stringify(value)); + }); + return; + case 'pipes': + tmp = tmp.join('|'); + break; + case 'ssv': + tmp = tmp.join(' '); + break; + case 'tsv': + tmp = tmp.join('\t'); + break; + // default to csv + default: + tmp = tmp.join(','); + } + } + } else if (!(paramDef.type === 'string' || tmp instanceof local.Blob)) { + tmp = JSON.stringify(tmp); + } + switch (paramDef.in) { + case 'body': + options.inBody = tmp; + break; + case 'formData': + if (isMultipartFormData) { + options.inForm.append(paramDef.name, tmp, tmp && tmp.name); + break; + } + options.inForm += '&' + encodeURIComponent(paramDef.name) + '=' + + encodeURIComponent(tmp); + break; + case 'header': + options.inHeader[encodeURIComponent(paramDef.name.toLowerCase())] = tmp; + break; + case 'query': + options.inQuery += '&' + encodeURIComponent(paramDef.name) + '=' + + encodeURIComponent(tmp); + break; + case 'path': + options.inPath = options.inPath + .replace('{' + paramDef.name + '}', encodeURIComponent(tmp)); + break; + } + }); + // init data + options.data = options.inBody || (isMultipartFormData + ? options.inForm + : options.inForm.slice(1)); + // init headers + local.objectSetOverride(options.headers, options.inHeader); + // init headers - Content-Type + if (options.inForm) { + options.headers['Content-Type'] = isMultipartFormData + ? 'multipart/form-data' + : 'application/x-www-form-urlencoded'; + } + // init headers - Authorization + options.jwtEncrypted = options.jwtEncrypted || local.userJwtEncrypted; + if (options.jwtEncrypted) { + options.headers.Authorization = options.headers.Authorization || + 'Bearer ' + options.jwtEncrypted; + } + // init url + options.url = (local.urlBaseGet() + options.inPath + '?' + options.inQuery.slice(1)) + .replace((/\?$/), ''); + if (!(options.headers['Content-Type'] || options.headers['content-type'])) { + options.headers['content-type'] = 'application/json; charset=UTF-8'; + } + // send ajax-request + return local.ajax(options, function (error, xhr) { + // try to init responseJson + local.tryCatchOnError(function () { + xhr.responseJson = JSON.parse(xhr.responseText); + }, local.nop); + // init userJwtEncrypted + if (xhr.getResponseHeader('swgg-jwt-encrypted')) { + local.userJwtEncrypted = xhr.getResponseHeader('swgg-jwt-encrypted'); + } + onError(error, xhr); + }); + }; + + local.apiDictUpdate = function (options) { + /* + * this function will update the swagger-api dict of api-calls + */ + var tmp; + options = options || {}; + // init apiDict + local.apiDict = local.apiDict || {}; + // init swaggerJson + local.swaggerJson = local.swaggerJson || { + "basePath": "/api/v0", + "definitions": { + "BuiltinFile": { + "properties": { + "_id": { + "readOnly": true, + "type": "string" + }, + "_timeCreated": { + "format": "date-time", + "readOnly": true, + "type": "string" + }, + "_timeUpdated": { + "format": "date-time", + "readOnly": true, + "type": "string" + }, + "fileBlob": { + "format": "byte", + "type": "string" + }, + "fileContentType": { + "type": "string" + }, + "fileDescription": { + "type": "string" + }, + "fileFilename": { + "type": "string" + }, + "fileInputName": { + "type": "string" + }, + "fileSize": { + "minimum": 0, + "type": "integer" + }, + "fileUrl": { + "type": "string" + }, + "id": { + "type": "string" + } + } + }, + "BuiltinJsonapiResponse": { + "properties": { + "data": { + "items": { + "type": "object" + }, + "type": "array" + }, + "errors": { + "items": { + "type": "object" + }, + "type": "array" + }, + "meta": { + "type": "object" + } + } + }, + "BuiltinUser": { + "properties": { + "_id": { + "readOnly": true, + "type": "string" + }, + "_timeCreated": { + "format": "date-time", + "readOnly": true, + "type": "string" + }, + "_timeUpdated": { + "format": "date-time", + "readOnly": true, + "type": "string" + }, + "id": { + "type": "string" + }, + "jwtEncrypted": { + "type": "string" + }, + "password": { + "format": "password", + "type": "string" + }, + "username": { + "type": "string" + } + } + } + }, + "info": { + "description": "demo of swagger-ui server", + "title": "swgg api", + "version": "0" + }, + "paths": {}, + "securityDefinitions": {}, + "swagger": "2.0", + "tags": [] + }; + // save tags + tmp = {}; + [local.swaggerJson.tags, options.tags || []].forEach(function (tagList) { + tagList.forEach(function (tag) { + local.objectSetOverride(tmp, local.objectLiteralize({ + '$[]': [tag.name, tag] + })); + }, 2); + }); + tmp = Object.keys(tmp).sort().map(function (key) { + return tmp[key]; + }); + // merge options into swaggerJson + options = local.objectSetOverride(local.swaggerJson, options, 10); + // restore tags + local.swaggerJson.tags = tmp; + Object.keys(options.definitions).forEach(function (schemaName) { + // normalize definition + options.definitions[schemaName] = + local.schemaNormalizeAndCopy(options.definitions[schemaName]); + }); + // init apiDict from paths + Object.keys(options.paths).forEach(function (path) { + Object.keys(options.paths[path]).forEach(function (method) { + var self; + self = options.paths[path][method]; + self._method = method; + self._path = path; + local.objectSetOverride(local.apiDict, local.objectLiteralize({ + '$[]': [self.tags[0] + ' ' + self.operationId, self] + }), 2); + }); + }); + // init apiDict from x-swgg-apiDict + Object.keys(options['x-swgg-apiDict'] || {}).forEach(function (key) { + // init self + local.objectSetOverride(local.apiDict, local.objectLiteralize({ + '$[]': [key, local.jsonCopy(options['x-swgg-apiDict'][key])] + }), Infinity); + }); + // init apiDict + Object.keys(local.apiDict).forEach(function (key) { + var self; + self = local.apiDict[key]; + if (key === self._keyPath) { + return; + } + // init _operationId + self._operationId = self._operationId || key.split(' ')[1]; + // init _fileUploadNumber + self._fileUploadNumber = 1; + self._operationId.replace( + (/^fileUploadManyByForm\.(\d+)/), + function (match0, match1) { + // jslint-hack - nop + local.nop(match0); + self._fileUploadNumber = Number(match1); + } + ); + // init _idAlias and _idField + tmp = local.idFieldInit({ operationId: self._operationId }); + self._idAlias = tmp.idAlias; + self._idField = tmp.idField; + // init _tags0 + self._tags0 = key.split(' ')[0]; + // init templateApiDict + if (local.templateApiDict[self._operationId.split('.')[0]]) { + local.objectSetDefault( + self, + JSON.parse(local.templateApiDict[self._operationId.split('.')[0]] + .replace((/\{\{_fileUploadNumber\}\}/g), self._fileUploadNumber) + .replace((/\{\{_idAlias\}\}/g), self._idAlias) + .replace((/\{\{_idField\}\}/g), self._idField) + .replace((/\{\{_schemaName\}\}/g), self._schemaName) + .replace((/\{\{_tags0\}\}/g), self._tags0) + .replace((/\{\{operationId\}\}/g), self._operationId)) + ); + } + // init default + local.objectSetDefault(self, { + _keyOperationId: key, + operationId: self._operationId, + parameters: [], + responses: { + 200: { + description: 'ok - ' + + 'http://jsonapi.org/format/#document-top-level', + schema: { $ref: '#/definitions/BuiltinJsonapiResponse' } + } + }, + tags: [self._tags0] + }); + // init _method + self._method = self._method.toUpperCase(); + // init _keyPath + self._keyPath = self._method + ' ' + self._path.replace((/\{.*?\}/g), ''); + // init _idField.format and _idField.type + if (self._schemaName) { + self.parameters.forEach(function (param) { + if (param.name === self._idField) { + param.format = options.definitions[self._schemaName] + .properties[self._idAlias].format; + param.type = options.definitions[self._schemaName] + .properties[self._idAlias].type; + } + }); + } + switch (self.operationId.split('.')[0]) { + // add extra file-upload forms + case 'fileUploadManyByForm': + for (tmp = 1; tmp <= self._fileUploadNumber; tmp += 1) { + self.parameters[tmp] = local.jsonCopy(self.parameters[1]); + self.parameters[tmp].name = 'file' + tmp; + } + break; + } + // update apiDict + self = local.apiDict[key] = local.apiDict[self._keyPath] = local.jsonCopy(self); + // init _ajax + self._ajax = function (options, onError) { + return local.apiAjax(self, options, onError); + }; + // remove underscored keys from self + tmp = local.jsonCopy(self); + Object.keys(tmp).forEach(function (key) { + if (key[0] === '_') { + delete tmp[key]; + } + }); + // update paths + local.objectSetOverride(options, local.objectLiteralize({ + paths: { '$[]': [self._path, { '$[]': [self._method.toLowerCase(), tmp] }] } + }), 3); + }); + // normalize swaggerJson + local.swaggerJson = JSON.parse(local.jsonStringifyOrdered(options)); + // update $npm_config_swagger_basePath + local.env.npm_config_swagger_basePath = local.swaggerJson.basePath; + // try to validate swaggerJson + local.tryCatchOnError(function () { + local.validateBySwagger(local.swaggerJson); + }, local.onErrorDefault); + }; + + local.dbFieldRandomCreate = function (options) { + /* + * this function will create a random dbField from options.propDef + */ + var ii, max, min, propDef, tmp; + propDef = options.propDef; + if (propDef.readOnly) { + return; + } + if (propDef.enum) { + tmp = options.modeNotRandom + ? propDef.enum[0] + : local.listGetElementRandom(propDef.enum); + return propDef.type === 'array' + ? [tmp] + : tmp; + } + // http://json-schema.org/latest/json-schema-validation.html#anchor13 + // 5.1. Validation keywords for numeric instances (number and integer) + max = isFinite(propDef.maximum) + ? propDef.maximum + : 999; + min = isFinite(propDef.maximum) + ? propDef.minimum + : 0; + switch (propDef.type) { + case 'array': + tmp = []; + // http://json-schema.org/latest/json-schema-validation.html#anchor36 + // 5.3. Validation keywords for arrays + for (ii = 0; ii < (propDef.minItems || 0); ii += 1) { + tmp.push(null); + } + break; + case 'boolean': + tmp = options.modeNotRandom + ? false + : Math.random() <= 0.5 + ? false + : true; + break; + case 'integer': + if (propDef.exclusiveMaximum) { + max -= 1; + } + if (propDef.exclusiveMinimum) { + min += 1; + } + min = Math.min(min, max); + tmp = options.modeNotRandom + ? 0 + : Math.random(); + tmp = Math.floor(min + tmp * (max - min)); + break; + case 'object': + tmp = {}; + // http://json-schema.org/latest/json-schema-validation.html#anchor53 + // 5.4. Validation keywords for objects + for (ii = 0; ii < (propDef.minProperties || 0); ii += 1) { + tmp['property' + ii] = null; + } + break; + case 'number': + if (propDef.exclusiveMinimum) { + min = min < 0 + ? min * 0.99999 + : min * 1.00001 + 0.00001; + } + if (propDef.exclusiveMaximum) { + max = max > 0 + ? max * 0.99999 + : max * 1.00001 - 0.00001; + } + min = Math.min(min, max); + tmp = options.modeNotRandom + ? 0 + : Math.random(); + tmp = min + tmp * (max - min); + break; + case 'string': + tmp = options.modeNotRandom + ? 'abcd1234' + : ((1 + Math.random()) * 0x10000000000000).toString(36).slice(1); + switch (propDef.format) { + case 'byte': + tmp = local.base64FromString(tmp); + break; + case 'date': + case 'date-time': + tmp = new Date().toISOString(); + break; + case 'email': + tmp = tmp + '@random.com'; + break; + case 'json': + tmp = JSON.stringify({ random: tmp }); + break; + case 'phone': + tmp = options.modeNotRandom + ? '+123 (1234) 1234-1234' + : '+' + Math.random().toString().slice(-3) + + ' (' + Math.random().toString().slice(-4) + ') ' + + Math.random().toString().slice(-4) + '-' + + Math.random().toString().slice(-4); + break; + } + // http://json-schema.org/latest/json-schema-validation.html#anchor25 + // 5.2. Validation keywords for strings + while (tmp.length < (propDef.minLength || 0)) { + tmp += tmp; + } + tmp = tmp.slice(0, propDef.maxLength || Infinity); + break; + } + // http://json-schema.org/latest/json-schema-validation.html#anchor13 + // 5.1. Validation keywords for numeric instances (number and integer) + if (propDef.multipleOf) { + tmp = propDef.multipleOf * Math.floor(tmp / propDef.multipleOf); + if (tmp < min) { + tmp += propDef.multipleOf; + } + } + return tmp; + }; + + local.dbRowListRandomCreate = function (options) { + /* + * this function will create a dbRowList of options.length random dbRow's + */ + local.objectSetDefault(options, { dbRowList: [] }); + for (options.ii = 0; options.ii < options.length; options.ii += 1) { + options.dbRowList.push(local.dbRowRandomCreate(options)); + } + return options.dbRowList; + }; + + local.dbRowRandomCreate = function (options) { + /* + * this function will create a random dbRow from options.properties + */ + var dbRow, tmp; + dbRow = {}; + Object.keys(options.properties).forEach(function (key) { + // try to validate data + local.tryCatchOnError(function () { + tmp = local.dbFieldRandomCreate({ + modeNotRandom: options.modeNotRandom, + propDef: options.properties[key] + }); + local.validateByPropDef({ + data: tmp, + key: options.properties[key].name, + schema: options.properties[key] + }); + dbRow[key] = tmp; + }, local.nop); + }); + return local.jsonCopy(local.objectSetOverride(dbRow, options.override(options))); + }; + + local.idDomElementCreate = function (seed) { + /* + * this function will create a unique dom-element id from the seed, + * that is both dom-selector and url friendly + */ + var id, ii; + id = encodeURIComponent(seed).replace((/\W/g), '_'); + for (ii = 2; local.idDomElementDict[id]; ii += 1) { + id = encodeURIComponent(seed + '_' + ii).replace((/\W/g), '_'); + } + local.idDomElementDict[id] = true; + return id; + }; + + local.idFieldInit = function (options) { + /* + * this function will init options.idAlias, options.idField, and options.queryById + */ + var idAlias, idField; + // init idField + options.idAlias = options.operationId.split('.'); + idField = options.idField = options.idAlias[1] || 'id'; + // init idAlias + idAlias = options.idAlias = options.idAlias[2] || options.idField; + // invert queryById + if (options.modeQueryByIdInvert) { + idAlias = options.idField; + idField = options.idAlias; + } + // init queryById + options.idValue = (options.data && options.data[idAlias]) || options.idValue; + options.queryById = {}; + options.queryById[idField] = options.idValue; + return options; + }; + + local.middlewareBodyParse = function (request, response, nextMiddleware) { + /* + * this function will run the middleware that will parse request.bodyRaw + */ + var ii, jj, options; + // jslint-hack + local.nop(response); + // if request is already parsed, then goto nextMiddleware + if (!local.isNullOrUndefined(request.swgg.bodyParsed)) { + nextMiddleware(); + return; + } + switch (String(request.headers['content-type']).split(';')[0]) { + // parse application/x-www-form-urlencoded, e.g. + // aa=hello%20world&bb=bye%20world + case 'application/x-www-form-urlencoded': + request.swgg.bodyParsed = local.bufferToString(request.bodyRaw); + request.swgg.bodyParsed = + local.urlParse('?' + request.swgg.bodyParsed, true).query; + break; + /* + * https://tools.ietf.org/html/rfc7578 + * parse multipart/form-data, e.g. + * --Boundary\r\n + * Content-Disposition: form-data; name="key"\r\n + * \r\n + * value\r\n + * --Boundary\r\n + * Content-Disposition: form-data; name="input1"; filename="file1.png"\r\n + * Content-Type: image/jpeg\r\n + * \r\n + * \r\n + * --Boundary\r\n + * Content-Disposition: form-data; name="input2"; filename="file2.png"\r\n + * Content-Type: image/jpeg\r\n + * \r\n + * \r\n + * --Boundary--\r\n + */ + case 'multipart/form-data': + request.swgg.isMultipartFormData = true; + request.swgg.bodyParsed = {}; + request.swgg.bodyMeta = {}; + options = {}; + options.crlf = local.bufferCreate([0x0d, 0x0a]); + // init boundary + ii = 0; + jj = local.bufferIndexOfSubBuffer(request.bodyRaw, options.crlf, ii); + if (jj <= 0) { + break; + } + options.boundary = local.bufferConcat([ + options.crlf, + request.bodyRaw.slice(ii, jj) + ]); + ii = jj + 2; + while (true) { + jj = local.bufferIndexOfSubBuffer( + request.bodyRaw, + options.boundary, + ii + ); + if (jj < 0) { + break; + } + options.header = local.bufferToString(request.bodyRaw.slice(ii, ii + 1024)) + .split('\r\n').slice(0, 2).join('\r\n'); + options.contentType = (/^content-type:(.*)/im).exec(options.header); + options.contentType = options.contentType && options.contentType[1].trim(); + options.filename = (/^content-disposition:.*?\bfilename="([^"]+)/im) + .exec(options.header); + options.filename = options.filename && options.filename[1]; + options.name = (/^content-disposition:.*?\bname="([^"]+)/im) + .exec(options.header); + options.name = options.name && options.name[1]; + ii = local.bufferIndexOfSubBuffer( + request.bodyRaw, + [0x0d, 0x0a, 0x0d, 0x0a], + ii + 2 + ) + 4; + options.data = request.bodyRaw.slice(ii, jj); + request.swgg.bodyParsed[options.name] = options.data; + request.swgg.bodyMeta[options.name] = { + contentType: options.contentType, + filename: options.filename, + name: options.name + }; + ii = jj + options.boundary.length + 2; + } + break; + default: + request.swgg.bodyParsed = local.bufferToString(request.bodyRaw); + // try to JSON.parse the string + local.tryCatchOnError(function () { + request.swgg.bodyParsed = JSON.parse(request.swgg.bodyParsed); + }, local.nop); + } + nextMiddleware(); + }; + + local.middlewareCrudBuiltin = function (request, response, nextMiddleware) { + /* + * this function will run the middleware that will + * run the builtin crud-operations backed by db-lite + */ + var crud, onParallel, options, tmp, user; + options = {}; + local.onNext(options, function (error, data, meta) { + switch (options.modeNext) { + case 1: + crud = request.swgg.crud; + user = request.swgg.user; + switch (crud.operationId.split('.')[0]) { + case 'crudCountManyByQuery': + crud.dbTable.crudCountManyByQuery(crud.queryWhere, options.onNext); + break; + case 'crudSetManyById': + crud.dbTable.crudSetManyById(crud.body, options.onNext); + break; + case 'crudSetOneById': + // replace idField with idAlias in body + delete crud.body.id; + delete crud.body[crud.idField]; + crud.body[crud.idAlias] = crud.data[crud.idField]; + crud.dbTable.crudSetOneById(crud.body, options.onNext); + break; + case 'crudUpdateOneById': + // replace idField with idAlias in body + delete crud.body.id; + delete crud.body[crud.idField]; + crud.body[crud.idAlias] = crud.data[crud.idField]; + crud.dbTable.crudUpdateOneById(crud.body, options.onNext); + break; + // coverage-hack - test error handling-behavior + case 'crudErrorDelete': + case 'crudErrorGet': + case 'crudErrorHead': + case 'crudErrorOptions': + case 'crudErrorPatch': + case 'crudErrorPost': + case 'crudErrorPut': + options.onNext(local.errorDefault); + break; + case 'crudGetManyByQuery': + onParallel = local.onParallel(options.onNext); + onParallel.counter += 1; + crud.dbTable.crudGetManyByQuery({ + fieldList: crud.queryFields, + limit: crud.queryLimit, + query: crud.queryWhere, + skip: crud.querySkip, + sort: crud.querySort + }, function (error, data) { + crud.queryData = data; + onParallel(error); + }); + onParallel.counter += 1; + crud.dbTable.crudCountAll(function (error, data) { + crud.paginationCountTotal = data; + onParallel(error); + }); + break; + case 'crudGetOneById': + crud.dbTable.crudGetOneById(crud.queryById, options.onNext); + break; + case 'crudGetOneByQuery': + crud.dbTable.crudGetOneByQuery({ + query: crud.queryWhere + }, options.onNext); + break; + case 'crudNullDelete': + case 'crudNullGet': + case 'crudNullHead': + case 'crudNullOptions': + case 'crudNullPatch': + case 'crudNullPost': + case 'crudNullPut': + options.onNext(); + break; + case 'crudRemoveManyByQuery': + crud.dbTable.crudRemoveManyByQuery(crud.queryWhere, options.onNext); + break; + case 'crudRemoveOneById': + crud.dbTable.crudRemoveOneById(crud.queryById, options.onNext); + break; + case 'fileGetOneById': + local.dbTableFile = local.db.dbTableCreateOne({ name: 'File' }); + crud.dbTable.crudGetOneById(crud.queryById, options.onNext); + break; + case 'fileUploadManyByForm': + local.dbTableFile = local.db.dbTableCreateOne({ name: 'File' }); + request.swgg.paramDict = {}; + Object.keys(request.swgg.bodyMeta).forEach(function (key) { + if (typeof request.swgg.bodyMeta[key].filename !== 'string') { + request.swgg.paramDict[key] = + local.bufferToString(request.swgg.bodyParsed[key]); + } + }); + crud.body = Object.keys(request.swgg.bodyMeta) + .filter(function (key) { + return typeof request.swgg.bodyMeta[key].filename === 'string'; + }) + .map(function (key) { + tmp = local.jsonCopy(request.swgg.paramDict); + local.objectSetOverride(tmp, { + fileBlob: + local.base64FromBuffer(request.swgg.bodyParsed[key]), + fileContentType: request.swgg.bodyMeta[key].contentType, + fileFilename: request.swgg.bodyMeta[key].filename, + fileInputName: request.swgg.bodyMeta[key].name, + fileSize: request.swgg.bodyParsed[key].length, + fileUrl: local.swaggerJson.basePath + + '/' + request.swgg.pathObject._tags0 + + '/fileGetOneById/' + tmp.id + }); + return tmp; + }); + local.dbTableFile.crudSetManyById(crud.body, options.onNext); + break; + case 'userLoginByPassword': + case 'userLogout': + // respond with 401 Unauthorized + if (!user.isAuthenticated) { + local.serverRespondHeadSet(request, response, 401, {}); + request.swgg.crud.endArgList = [request, response]; + options.modeNext = Infinity; + options.onNext(); + return; + } + options.onNext(); + break; + default: + options.modeNext = Infinity; + options.onNext(); + } + break; + case 2: + switch (crud.operationId.split('.')[0]) { + case 'crudSetOneById': + case 'crudUpdateOneById': + options.onNext(null, data); + break; + case 'crudGetManyByQuery': + options.onNext(null, crud.queryData, { + paginationCountTotal: crud.paginationCountTotal + }); + break; + case 'fileUploadManyByForm': + options.onNext(null, data.map(function (element) { + delete element.fileBlob; + return element; + })); + break; + case 'userLoginByPassword': + options.onNext(null, { jwtEncrypted: user.jwtEncrypted }); + break; + case 'userLogout': + crud.dbTable.crudUpdateOneById({ + jwtEncrypted: null, + username: user.username + }, options.onNext); + break; + default: + options.onNext(null, data, meta); + } + break; + case 3: + switch (crud.operationId.split('.')[0]) { + case 'fileGetOneById': + if (!data) { + local.serverRespondDefault(request, response, 404); + return; + } + local.serverRespondHeadSet(request, response, null, { + 'Content-Type': data.fileContentType + }); + response.end(local.base64ToBuffer(data.fileBlob)); + break; + case 'userLogout': + options.onNext(); + break; + default: + options.onNext(null, data, meta); + } + break; + case 4: + request.swgg.crud.endArgList = [request, response, null, data, meta]; + options.onNext(); + break; + default: + nextMiddleware(error); + } + }); + options.modeNext = 0; + options.onNext(); + }; + + local.middlewareCrudEnd = function (request, response, nextMiddleware) { + /* + * this function will run the middleware that will end the builtin crud-operations + */ + // jslint-hack + local.nop(response); + if (request.swgg.crud.endArgList) { + local.serverRespondJsonapi.apply(null, request.swgg.crud.endArgList); + return; + } + nextMiddleware(); + }; + + local.middlewareRouter = function (request, response, nextMiddleware) { + /* + * this function will run the middleware that will + * map the request's method-path to swagger's tags[0]-operationId + */ + var tmp; + // jslint-hack + local.nop(response); + // init swgg object + local.objectSetDefault( + request, + { swgg: { crud: { operationId: '' }, user: {} } }, + 2 + ); + // if request.url is not prefixed with swaggerJson.basePath, + // then default to nextMiddleware + if (request.urlParsed.pathname.indexOf(local.swaggerJson.basePath) !== 0) { + nextMiddleware(); + return; + } + // init pathname + request.swgg.pathname = request.method + ' ' + request.urlParsed.pathname + .replace(local.swaggerJson.basePath, ''); + // init pathObject + while (request.swgg.pathname !== tmp) { + request.swgg.pathObject = + local.apiDict[request.swgg.pathname] || + // handle /foo/{id}/bar case + local.apiDict[request.swgg.pathname + .replace((/\/[^\/]+\/([^\/]*?)$/), '//$1')]; + // if pathObject exists, then break + if (request.swgg.pathObject) { + request.swgg.pathObject = local.jsonCopy(request.swgg.pathObject); + request.swgg.pathname = request.swgg.pathObject._keyPath; + // init crud.operationId + request.swgg.crud.operationId = request.swgg.pathObject._operationId; + break; + } + tmp = request.swgg.pathname; + request.swgg.pathname = request.swgg.pathname + .replace((/\/[^\/]+?(\/*?)$/), '/$1'); + } + nextMiddleware(); + }; + + local.middlewareUserLogin = function (request, response, nextMiddleware) { + /* + * this function will run the middleware that will handle user login + */ + var crud, options, user; + options = {}; + local.onNext(options, function (error, data) { + switch (options.modeNext) { + case 1: + local.dbTableUser = local.db.dbTableCreateOne({ name: 'User' }); + crud = request.swgg.crud; + user = request.swgg.user = {}; + user.jwtEncrypted = request.headers.authorization && + request.headers.authorization.replace('Bearer ', ''); + user.jwtDecrypted = local.jwtA256GcmDecrypt(user.jwtEncrypted); + switch (crud.operationId.split('.')[0]) { + // coverage-hack - test error handling-behavior + case 'crudErrorLogin': + options.onNext(local.errorDefault); + return; + case 'userLoginByPassword': + user.password = request.urlParsed.query.password; + user.username = request.urlParsed.query.username; + if (user.password && user.username) { + local.dbTableUser.crudGetOneById({ + username: user.username + }, options.onNext); + return; + } + break; + default: + if (user.jwtDecrypted.sub) { + // init username + user.username = user.jwtDecrypted.sub; + local.dbTableUser.crudGetOneById({ + username: user.username + }, options.onNext); + return; + } + } + options.modeNext = Infinity; + options.onNext(); + break; + case 2: + switch (crud.operationId.split('.')[0]) { + case 'userLoginByPassword': + user.data = data; + if (!local.sjclHashScryptValidate( + user.password, + user.data && user.data.password + )) { + options.modeNext = Infinity; + options.onNext(); + return; + } + // init isAuthenticated + user.isAuthenticated = true; + // https://tools.ietf.org/html/rfc7519 + // create JSON Web Token (JWT) + user.jwtDecrypted = {}; + user.jwtDecrypted.sub = user.data.username; + // update jwtEncrypted in client + user.jwtEncrypted = local.jwtA256GcmEncrypt(user.jwtDecrypted); + local.serverRespondHeadSet(request, response, null, { + 'swgg-jwt-encrypted': user.jwtEncrypted + }); + // update jwtEncrypted in dbTableUser + local.dbTableUser.crudUpdateOneById({ + jwtEncrypted: user.jwtEncrypted, + username: user.jwtDecrypted.sub + }, options.onNext); + return; + default: + data = user.data = data || {}; + if (data.jwtEncrypted) { + // init isAuthenticated + user.isAuthenticated = true; + // update jwtEncrypted in client + if (data.jwtEncrypted !== user.jwtEncrypted) { + user.jwtEncrypted = data.jwtEncrypted; + user.jwtDecrypted = local.jwtA256GcmDecrypt(user.jwtEncrypted); + local.serverRespondHeadSet(request, response, null, { + 'swgg-jwt-encrypted': user.jwtEncrypted + }); + } + } + } + options.onNext(); + break; + default: + nextMiddleware(error); + } + }); + options.modeNext = 0; + options.onNext(); + }; + + local.middlewareValidate = function (request, response, nextMiddleware) { + /* + * this function will run the middleware that will validate the swagger-request + */ + var crud, modeNext, onNext, tmp; + modeNext = 0; + onNext = function () { + modeNext += 1; + switch (modeNext) { + case 1: + // serve swagger.json + if (request.method + ' ' + request.urlParsed.pathname === + 'GET ' + local.swaggerJson.basePath + '/swagger.json') { + response.end(JSON.stringify(local.swaggerJson)); + return; + } + if (!request.swgg.pathObject) { + modeNext = Infinity; + onNext(); + return; + } + // init paramDict + request.swgg.paramDict = {}; + // parse path param + tmp = request.urlParsed.pathname + .replace(local.swaggerJson.basePath, '').split('/'); + request.swgg.pathObject._path.split('/').forEach(function (key, ii) { + if ((/^\{\S*?\}$/).test(key)) { + request.swgg.paramDict[key.slice(1, -1)] = + decodeURIComponent(tmp[ii]); + } + }); + request.swgg.pathObject.parameters.forEach(function (paramDef) { + switch (paramDef.in) { + // parse body param + case 'body': + request.swgg.paramDict[paramDef.name] = request.swgg.bodyParsed || + undefined; + break; + // parse formData param + case 'formData': + switch (String(request.headers['content-type']).split(';')[0]) { + case 'application/x-www-form-urlencoded': + request.swgg.paramDict[paramDef.name] = + request.swgg.bodyParsed[paramDef.name]; + break; + } + break; + // parse header param + case 'header': + request.swgg.paramDict[paramDef.name] = + request.headers[paramDef.name.toLowerCase()]; + break; + // parse query param + case 'query': + request.swgg.paramDict[paramDef.name] = + request.urlParsed.query[paramDef.name]; + break; + } + // parse array-multi + if (request.swgg.paramDict[paramDef.name] && + paramDef.type === 'array' && + paramDef.collectionFormat === 'multi') { + tmp = ''; + request.swgg.paramDict[paramDef.name].forEach(function (value) { + tmp += '&' + encodeURIComponent(paramDef.name) + '=' + + encodeURIComponent(value); + }); + request.swgg.paramDict[paramDef.name] = tmp.slice(1); + } + // init default param + if (local.isNullOrUndefined(request.swgg.paramDict[paramDef.name]) && + paramDef.default !== undefined) { + request.swgg.paramDict[paramDef.name] = + local.jsonCopy(paramDef.default); + } + }); + // normalize paramDict + local.normalizeParamDictSwagger( + request.swgg.paramDict, + request.swgg.pathObject + ); + // validate paramDict + local.validateByParamDefList({ + data: request.swgg.paramDict, + key: request.swgg.pathname, + paramDefList: request.swgg.pathObject.parameters + }); + onNext(); + break; + case 2: + // init crud + crud = request.swgg.crud; + // init crud.dbTable + crud.dbTable = request.swgg.pathObject && + request.swgg.pathObject._schemaName && + local.db.dbTableCreateOne({ + name: request.swgg.pathObject._schemaName + }); + if (!crud.dbTable) { + nextMiddleware(); + return; + } + // init crud.body + if (!request.swgg.isMultipartFormData) { + crud.body = local.jsonCopy(request.swgg.bodyParsed); + } + // init crud.data + crud.data = local.jsonCopy(request.swgg.paramDict); + request.swgg.pathObject.parameters.forEach(function (param) { + // JSON.parse json-string + if (param.format === 'json' && + param.type === 'string' && + crud.data[param.name]) { + crud.data[param.name] = JSON.parse(crud.data[param.name]); + } + }); + // init crud.query* + [{ + key: 'queryFields', + value: {} + }, { + key: 'queryLimit', + value: 100 + }, { + key: 'querySkip', + value: 0 + }, { + key: 'querySort', + value: [{ fieldName: '_timeUpdated', isDescending: true }] + }, { + key: 'queryWhere', + value: {} + }].forEach(function (element) { + crud[element.key] = crud.data['_' + element.key] || JSON.parse( + local.templateRender( + request.swgg.pathObject['_' + element.key] || 'null', + request.swgg.paramDict + ) + ) || element.value; + }); + // init-before crud.idField + crud.modeQueryByIdInvert = true; + local.idFieldInit(crud); + // init crud.data.id + switch (crud.operationId.split('.')[0]) { + case 'crudSetOneById': + case 'crudUpdateOneById': + if (!local.isNullOrUndefined(crud.data[crud.idField])) { + break; + } + crud.data[crud.idField] = (crud.body && crud.body[crud.idAlias]); + break; + } + // init-after crud.idField + crud.modeQueryByIdInvert = true; + local.idFieldInit(crud); + nextMiddleware(); + break; + default: + nextMiddleware(); + } + }; + onNext(); + }; + + local.normalizeParamDictSwagger = function (data, pathObject) { + /* + * this function will parse the data according to pathObject.parameters + */ + var tmp; + pathObject.parameters.forEach(function (paramDef) { + tmp = data[paramDef.name]; + // init default value + if (local.isNullOrUndefined(tmp) && paramDef.default !== undefined) { + tmp = local.jsonCopy(paramDef.default); + } + // parse array + if (paramDef.type === 'array' && paramDef.in !== 'body') { + if (typeof tmp === 'string') { + switch (paramDef.collectionFormat) { + case 'json': + local.tryCatchOnError(function () { + tmp = JSON.parse(tmp); + }, local.nop); + data[paramDef.name] = tmp; + return; + case 'multi': + tmp = local.urlParse('?' + tmp, true).query[paramDef.name]; + break; + case 'pipes': + tmp = tmp.split('|'); + break; + case 'ssv': + tmp = tmp.split(' '); + break; + case 'tsv': + tmp = tmp.split('\t'); + break; + // default to csv + default: + tmp = tmp.split(','); + } + if (paramDef.items && paramDef.items.type !== 'string') { + // try to JSON.parse the string + local.tryCatchOnError(function () { + tmp = tmp.map(function (element) { + return JSON.parse(element); + }); + }, local.nop); + } + } + // JSON.parse paramDict + } else if (paramDef.type !== 'file' && + paramDef.type !== 'string' && + (typeof tmp === 'string' || tmp instanceof local.global.Uint8Array)) { + // try to JSON.parse the string + local.tryCatchOnError(function () { + tmp = JSON.parse(local.bufferToString(tmp)); + }, local.nop); + } + data[paramDef.name] = tmp; + }); + return data; + }; + + local.onErrorJsonapi = function (onError) { + /* + * http://jsonapi.org/format/#errors + * http://jsonapi.org/format/#document-structure-resource-objects + * this function will normalize the error and data to jsonapi format, + * and pass them to onError + */ + return function (error, data, meta) { + data = [error, data].map(function (data, ii) { + // if no error occurred, then return + if ((ii === 0 && !data) || + // if data is already normalized, then return it + (data && data.meta && data.meta.isJsonapiResponse)) { + return data; + } + // normalize data-list + if (!Array.isArray(data)) { + data = [data]; + } + // normalize error-list to contain non-null objects + if (ii === 0) { + // normalize error-list to be non-empty + if (!data.length) { + data.push(null); + } + data = data.map(function (element) { + if (!(element && typeof element === 'object')) { + element = { message: String(element) }; + } + // normalize error-object to plain json-object + error = local.jsonCopy(element); + error.message = element.message; + error.stack = element.stack; + error.statusCode = Number(error.statusCode) || 500; + return error; + }); + error = local.jsonCopy(data[0]); + error.errors = data; + return error; + } + return { data: data }; + }); + // init data.meta + data.forEach(function (data, ii) { + if (!data) { + return; + } + data.meta = local.jsonCopy(meta || {}); + data.meta.isJsonapiResponse = true; + if (ii === 0) { + data.meta.errorsLength = (data.errors && data.errors.length) | 0; + } else { + data.meta.dataLength = (data.data && data.data.length) | 0; + } + data.meta.statusCode = Number(data.meta.statusCode) || + Number(data.statusCode) || + 0; + }); + onError(data[0], data[1]); + }; + }; + + local.schemaNormalizeAndCopy = function (schema) { + /* + * this function will return a normalized copy the schema + */ + var tmp; + // dereference $ref + if (schema.$ref) { + [local.swaggerJson, local.swaggerSchemaJson].some(function (options) { + local.tryCatchOnError(function () { + schema.$ref.replace( + (/#\/(.*?)\/(.*?)$/), + function (match0, match1, match2) { + // jslint-hack - nop + local.nop(match0); + tmp = options[match1][match2]; + } + ); + }, local.nop); + return tmp; + }); + // validate schema + local.assert(tmp, schema.$ref); + // recurse + schema = local.schemaNormalizeAndCopy(tmp); + } + // inherit allOf + if (schema.allOf) { + tmp = local.jsonCopy(schema); + delete tmp.allOf; + schema.allOf.reverse().forEach(function (element) { + // recurse + local.objectSetDefault(tmp, local.schemaNormalizeAndCopy(element), 2); + }); + schema = tmp; + } + schema = local.jsonCopy(schema); + if (schema.type === 'object') { + schema.properties = local.normalizeDict(schema.properties); + } + return schema; + }; + + local.serverRespondJsonapi = function (request, response, error, data, meta) { + /* + * http://jsonapi.org/format/#errors + * http://jsonapi.org/format/#document-structure-resource-objects + * this function will respond in jsonapi format + */ + local.onErrorJsonapi(function (error, data) { + local.serverRespondHeadSet(request, response, error && error.statusCode, { + 'Content-Type': 'application/json; charset=UTF-8' + }); + if (error) { + // debug statusCode / method / url + local.errorMessagePrepend(error, response.statusCode + ' ' + + request.method + ' ' + request.url + '\n'); + // print error.stack to stderr + local.onErrorDefault(error); + } + data = error || data; + data.meta.statusCode = response.statusCode = + data.meta.statusCode || response.statusCode; + response.end(JSON.stringify(data)); + })(error, data, meta); + }; + + local.uiAnimateFadeIn = function (element) { + /* + * this function will fadeIn the element + */ + element.classList.add('swggAnimateFade'); + element.style.display = ''; + setTimeout(function () { + element.style.opacity = ''; + }, 20); + setTimeout(function () { + element.classList.remove('swggAnimateFade'); + }, 500); + }; + + local.uiAnimateFadeOut = function (element) { + /* + * this function will fadeOut the element + */ + element.classList.add('swggAnimateFade'); + element.style.opacity = '0'; + setTimeout(function () { + element.style.display = 'none'; + element.classList.remove('swggAnimateFade'); + }, 500); + }; + + local.uiAnimateScrollTo = function (element) { + /* + * this function will scrollTo the element + */ + var ii, timerInterval; + ii = 0; + timerInterval = setInterval(function () { + ii += 0.025; + local.global.scrollTo(0, document.body.scrollTop + + Math.min(ii, 1) * (element.offsetTop - document.body.scrollTop) + + -5); + }, 25); + setTimeout(function () { + clearInterval(timerInterval); + }, 1000); + }; + + local.uiAnimateShake = function (element) { + /* + * this function will shake the dom-element + */ + element.classList.add('swggAnimateShake'); + setTimeout(function () { + element.classList.remove('swggAnimateShake'); + }, 500); + }; + + local.uiAnimateSlideAccordian = function (element, elementList) { + /* + * this function will slideDown the element, + * but slideUp all other elements in elementList + */ + // hide elements in elementList + elementList.forEach(function (element2) { + if (element2 !== element) { + local.uiAnimateSlideUp(element2); + } + }); + // show element + local.uiAnimateSlideDown(element); + }; + + local.uiAnimateSlideDown = function (element) { + /* + * this function will slideDown the dom-element + */ + if (element.style.display !== 'none') { + return; + } + element.style.maxHeight = 0; + element.classList.add('swggAnimateSlide'); + element.style.display = ''; + setTimeout(function () { + element.style.maxHeight = 2 * local.global.innerHeight + 'px'; + }, 20); + setTimeout(function () { + element.style.maxHeight = ''; + element.classList.remove('swggAnimateSlide'); + }, 500); + }; + + local.uiAnimateSlideUp = function (element) { + /* + * this function will slideUp the dom-element + */ + if (element.style.display === 'none') { + return; + } + element.style.maxHeight = 2 * local.global.innerHeight + 'px'; + element.classList.add('swggAnimateSlide'); + setTimeout(function () { + element.style.maxHeight = '0px'; + }, 20); + setTimeout(function () { + element.style.display = 'none'; + }, 500); + setTimeout(function () { + element.style.maxHeight = ''; + element.classList.remove('swggAnimateSlide'); + }, 500); + }; + + local.uiDatatableRender = function (options) { + /* + * this function will render the datatable + */ + var tmp; + local.uiState.datatable = options; + options.schema = local.schemaNormalizeAndCopy(options.schema); + options.propDefList = Object.keys(options.schema.properties) + .sort(function (aa, bb) { + return aa === options._idAlias + ? -1 + : bb === options._idAlias + ? 1 + : aa < bb + ? -1 + : 1; + }) + .map(function (propDef) { + tmp = propDef; + propDef = options.schema.properties[tmp]; + propDef.name = tmp; + local.uiParamRender(propDef); + return propDef; + }); + options.iiPadding = 0; + options.dbRowList = options.responseJson.data.map(function (dbRow, ii) { + dbRow = { paramDict: dbRow }; + dbRow.colList = options.propDefList.map(function (propDef) { + propDef = local.jsonCopy(propDef); + propDef.valueEncoded = dbRow.paramDict[propDef.name]; + if (propDef.valueEncoded === undefined) { + propDef.valueEncoded = ''; + } + if (typeof propDef.valueEncoded !== 'string') { + propDef.valueEncoded = JSON.stringify(propDef.valueEncoded); + } + return propDef; + }); + dbRow.id = dbRow.paramDict[options._idAlias]; + dbRow.ii = options.querySkip + ii + 1; + options.iiPadding = Math.max( + 0.375 * String(dbRow.ii).length, + options.iiPadding + ); + return dbRow; + }); + // init pagination + options.pageCurrent = Math.floor(options.querySkip / options.queryLimit); + options.pageTotal = Math.ceil( + options.responseJson.meta.paginationCountTotal / options.queryLimit + ); + options.pageMin = Math.max( + Math.min(options.pageCurrent - 3, options.pageTotal - 7), + 0 + ); + options.pageMax = Math.min(options.pageMin + 7, options.pageTotal); + options.pageList = []; + // add first page + options.pageList.push({ + disabled: options.pageCurrent === 0, + pageNumber: 0, + valueEncoded: 'first page' + }); + for (tmp = options.pageMin; tmp < options.pageMax; tmp += 1) { + options.pageList.push({ + disabled: tmp === options.pageCurrent, + pageNumber: tmp, + valueEncoded: JSON.stringify(tmp + 1) + }); + } + // add last page + options.pageList.push({ + disabled: options.pageCurrent === options.pageTotal - 1, + pageNumber: options.pageTotal - 1, + valueEncoded: 'last page' + }); + options.pageCurrentIsFirst = options.pageCurrent === 0; + options.pageCurrentIsLast = options.pageCurrent + 1 === options.pageTotal; + // templateRender datatable + document.querySelector('.swggUiContainer .datatable').innerHTML = + local.templateRender(local.templateUiDatatable, options); + // init event-handling + local.uiEventInit(document.querySelector('.swggUiContainer .datatable')); + // show modal + if (document.querySelector('.swggUiContainer > .modal').style.display !== 'none') { + return; + } + document.body.style.overflow = 'hidden'; + local.uiAnimateFadeIn(document.querySelector('.swggUiContainer > .modal')); + }; + + local.uiEventDelegate = function (event) { + Object.keys(local.uiEventListenerDict).sort().some(function (key) { + if (!(event.currentTarget.matches(key) || event.target.matches(key))) { + return; + } + switch (event.target.tagName) { + case 'A': + case 'BUTTON': + case 'FORM': + event.preventDefault(); + break; + } + event.stopPropagation(); + local.uiEventListenerDict[key](event); + return true; + }); + }; + + local.uiEventInit = function (element) { + /* + * this function will init event-handling for the dom-element + */ + ['Click', 'Submit'].forEach(function (eventType) { + Array.from( + element.querySelectorAll('.eventDelegate' + eventType) + ).forEach(function (element) { + element.addEventListener(eventType.toLowerCase(), local.uiEventDelegate); + }); + }); + }; + + local.uiEventListenerDict = {}; + + local.uiEventListenerDict['.onEventDatatableReload'] = function (event) { + /* + * this function will show the modal + */ + var options; + options = {}; + if (event) { + options.name = event.target.dataset.resourceName; + options.pageNumber = event.target.dataset.pageNumber; + } else { + options.name = local.uiState.datatable.name; + options.pageNumber = local.uiState.datatable.pageNumber; + options.queryLimit = local.uiState.datatable.queryLimit; + options.querySort = local.uiState.datatable.querySort; + options.queryWhere = local.uiState.datatable.queryWhere; + } + local.objectSetDefault( + options, + local.jsonCopy(local.uiState['x-swgg-datatableDict'][options.name]) + ); + options._idAlias = local.apiDict[options.crudRemoveOneById]._idAlias; + options._idField = local.apiDict[options.crudRemoveOneById]._idField; + local.objectSetDefault(options, { pageNumber: 0, queryLimit: 20 }); + options.querySkip = options.pageNumber * options.queryLimit; + options.paramDict = { + _queryLimit: options.queryLimit, + _querySkip: options.querySkip, + _querySort: options.querySort, + _queryWhere: options.queryWhere + }; + // request data + local.apiDict[options.crudGetManyByQuery]._ajax(options, function (error, options) { + // validate no error occurred + local.assert(!error, error); + local.uiDatatableRender(options); + // emit event uiDatatableRendered + document.dispatchEvent(new local.global.Event('uiDatatableRendered', { + bubbles: true, + cancelable: true + })); + }); + }; + + local.uiEventListenerDict['.onEventDatatableSelectedRemove'] = function () { + var onParallel; + onParallel = local.onParallel(local.uiEventListenerDict['.onEventDatatableReload']); + onParallel.counter += 1; + Array.from( + document.querySelectorAll('.swggUiContainer .datatable tr.selected') + ).forEach(function (element) { + onParallel.counter += 1; + // remove data + local.apiDict[ + local.uiState.datatable.crudRemoveOneById + ]._ajax(local.objectLiteralize({ + paramDict: { '$[]': [ + local.uiState.datatable._idField, + JSON.parse(decodeURIComponent(element.dataset.id)) + ] } + }), onParallel); + }); + onParallel(); + }; + + local.uiEventListenerDict['.onEventDatatableTrSelect'] = function (event) { + if (event.target.tagName !== 'INPUT') { + event.currentTarget.querySelector('input').checked = + !event.currentTarget.querySelector('input').checked; + } + Array.from( + event.currentTarget.closest('tr').querySelectorAll('input') + ).forEach(function (element) { + element.checked = event.currentTarget.querySelector('input').checked; + }); + if (event.currentTarget.querySelector('input').checked) { + event.currentTarget.closest('tr').classList.add('selected'); + } else { + event.currentTarget.closest('tr').classList.remove('selected'); + } + }; + + local.uiEventListenerDict['.onEventModalHide'] = function (event) { + /* + * this function will hide the modal + */ + if (event && !event.target.classList.contains('onEventModalHide')) { + return; + } + if (document.querySelector('.swggUiContainer > .modal').style.display === 'none') { + return; + } + document.body.style.overflow = ''; + // hide modeal + local.uiAnimateFadeOut(document.querySelector('.swggUiContainer > .modal')); + }; + + local.uiEventListenerDict['.onEventOperationAjax'] = function (event) { + /* + * this function will return submit the operation to the backend + */ + var options, tmp; + options = {}; + local.onNext(options, function (error, data) { + switch (options.modeNext) { + case 1: + options.api = local.apiDict[event.currentTarget.dataset._keyOperationId]; + options.domOperationContent = event.target.closest('.operation > .content'); + options.headers = {}; + options.paramDict = {}; + options.api.parameters.forEach(function (paramDef) { + local.tryCatchOnError(function () { + tmp = options.domOperationContent.querySelector( + '.paramDef[name=' + paramDef.name + '] > .td3' + ).children[0]; + switch (tmp.tagName) { + case 'INPUT': + // parse file + if (tmp.type === 'file') { + tmp = tmp.files && tmp.files[0]; + break; + } + tmp = tmp.value; + if (!tmp) { + return; + } + // parse string + if (paramDef.type !== 'string') { + tmp = JSON.parse(tmp); + } + break; + case 'SELECT': + tmp = Array.from(tmp.options) + .filter(function (element) { + return element.selected; + }) + .map(function (element) { + return JSON.parse(decodeURIComponent( + element.dataset.valueDecoded + )); + }); + if (!tmp.length || tmp[0] === '$swggUndefined') { + return; + } + if (paramDef.type !== 'array') { + tmp = tmp[0]; + } + break; + case 'TEXTAREA': + tmp = tmp.value; + if (!tmp) { + return; + } + // parse schema + if (paramDef.in === 'body') { + tmp = JSON.parse(tmp); + break; + } + // parse array + tmp = tmp.split('\n').map(function (element) { + return paramDef.items.type === 'string' + ? element + : JSON.parse(element); + }); + break; + } + options.paramDict[paramDef.name] = tmp; + }, function (error) { + options.errorValidate = error; + options.errorValidate.options = { key: paramDef.name }; + options.onNext(error); + }); + }); + options.api._ajax(options, options.onNext); + break; + default: + // remove previous error + Array.from( + options.domOperationContent.querySelectorAll('.paramDef .input') + ).forEach(function (element) { + element.classList.remove('error'); + }); + if (options.errorValidate) { + // shake input on Error + Array.from(options.domOperationContent.querySelectorAll( + '.paramDef[name=' + options.errorValidate.options.key + '] .input' + )).forEach(function (element) { + element.classList.add('error'); + local.uiAnimateShake(element.closest('span')); + }); + data = { + errorValidate: options.errorValidate, + responseText: error.message, + statusCode: 400 + }; + } + // init responseHeaders + data.responseHeaders = {}; + ( + (data.getAllResponseHeaders && data.getAllResponseHeaders()) || '' + ).replace( + (/.+/g), + function (item) { + item = item.split(':'); + data.responseHeaders[item[0].trim().toLowerCase()] = + item.slice(1).join(':').trim(); + } + ); + // init contentType + data.contentType = + String(data.responseHeaders['content-type']).split(';')[0]; + // init responseBody + switch (data.contentType.split('/')[0]) { + case 'audio': + case 'video': + data.responseBody = '<' + data.contentType.split('/')[0] + + ' controls>'; + break; + case 'image': + data.responseBody = ''; + break; + default: + data.responseBody = '
' + local.stringHtmlSafe(
+                            data.responseJson
+                                ? JSON.stringify(data.responseJson, null, 4)
+                                : data.responseText
+                        ) + '
'; + } + // init curl + local.tryCatchOnError(function () { + options.data = JSON.stringify(JSON.parse(options.data), null, 4); + }, local.nop); + data.curl = 'curl \\\n' + + '--request ' + options.api._method.toUpperCase() + ' \\\n' + + Object.keys(options.headers).map(function (key) { + return "--header '" + key + ': ' + options.headers[key] + "' \\\n"; + }).join('') + '--data-binary ' + (typeof options.data === 'string' + ? "'" + options.data.replace(/'/g, "'\"'\"'") + "'" + : '') + ' \\\n"' + options.url + '"'; + data.responseHeaders = data.getAllResponseHeaders && + data.getAllResponseHeaders().trim(); + // templateRender response + options.domOperationContent.querySelector( + '.responseAjax' + ).innerHTML = local.templateRender(local.templateUiResponseAjax, data); + break; + } + }); + options.modeNext = 0; + options.onNext(); + }; + + local.uiEventListenerDict['.onEventOperationDisplayShow'] = function (event) { + /* + * this function will toggle the display of the operation + */ + var tmp; + location.hash = '!/' + event.target.closest('.resource').id + '/' + + event.target.closest('.operation').id; + tmp = event.target.closest('.operation').querySelector('.operation > .content'); + tmp.closest('.resource').classList.remove('expanded'); + // show the operation, but hide all other operations + local.uiAnimateSlideAccordian( + tmp, + Array.from( + tmp.closest('.operationList').querySelectorAll('.operation > .content') + ) + ); + }; + + local.uiEventListenerDict['.onEventResourceDisplayAction'] = function (event) { + /* + * this function will toggle the display of the resource + */ + location.hash = '!/' + event.currentTarget.id; + event.target.className.split(' ').some(function (className) { + switch (className) { + // show the resource, but hide all other resources + case 'td1': + case 'td2': + case 'td3': + local.uiAnimateSlideAccordian( + event.currentTarget.querySelector('.operationList'), + Array.from(document.querySelectorAll('.swggUiContainer .operationList')) + ); + break; + } + switch (className) { + case 'td1': + case 'td2': + return true; + case 'td3': + // collapse all operations in the resource + if (event.currentTarget.classList.contains('expanded')) { + event.currentTarget.classList.remove('expanded'); + Array.from( + event.currentTarget.querySelectorAll('.operation > .content') + ).forEach(function (element) { + local.uiAnimateSlideUp(element); + }); + // expand all operations in the resource + } else { + event.currentTarget.classList.add('expanded'); + Array.from( + event.currentTarget.querySelectorAll('.operation > .content') + ).forEach(function (element) { + local.uiAnimateSlideDown(element); + }); + } + return true; + } + }); + }; + + local.uiEventListenerDict['.onEventUiReload'] = function () { + /* + * this function will reload the ui + */ + // reset ui + Array.from( + document.querySelectorAll('.swggUiContainer > .reset') + ).forEach(function (element) { + element.remove(); + }); + // normalize url + document.querySelector('.swggUiContainer > .header > .td2').value = + local.urlParse( + document.querySelector('.swggUiContainer > .header > .td2').value + .replace((/^\//), '') + ).href; + // display .swggAjaxProgressDiv + document.querySelector('.swggAjaxProgressDiv').textContent = + 'fetching resource list: ' + + document.querySelector('.swggUiContainer > .header > .td2').value + + '; Please wait.'; + document.querySelector('.swggAjaxProgressDiv').style.display = 'block'; + local.ajax({ + url: document.querySelector('.swggUiContainer > .header > .td2').value + }, function (error, xhr) { + // hide .swggAjaxProgressDiv + document.querySelector('.swggAjaxProgressDiv').style.display = 'none'; + // validate no error occurred + local.assert(!error, error); + // reset state + local.apiDict = local.swaggerJson = null; + local.apiDictUpdate(local.objectSetDefault(JSON.parse(xhr.responseText), { + host: local.urlParse( + document.querySelector('.swggUiContainer > .header > .td2').value + ).host + })); + local.uiRender(); + }); + }; + + local.uiParamRender = function (paramDef) { + /* + * this function will render the param + */ + paramDef.placeholder = paramDef.required + ? '(required)' + : ''; + // init input - file + if (paramDef.type === 'file') { + paramDef.isFile = true; + // init input - textarea + } else if (paramDef.in === 'body') { + paramDef.isTextarea = true; + // init input - select + } else if (paramDef.enum || paramDef.type === 'boolean') { + paramDef.enumDefault = []; + if (paramDef.default !== undefined) { + paramDef.enumDefault = paramDef.type === 'array' + ? paramDef.default + : [paramDef.default]; + } + paramDef.isSelect = true; + paramDef.isSelectMultiple = paramDef.type === 'array'; + paramDef.selectOptionList = (paramDef.type === 'boolean' + ? [false, true] + : paramDef.enum).map(function (element) { + paramDef.hasDefault |= paramDef.enumDefault.indexOf(element) >= 0; + return { + id: local.idDomElementCreate('swgg_id_' + paramDef.name), + selected: paramDef.enumDefault.indexOf(element) >= 0 + ? 'selected' + : '', + type: (paramDef.items && paramDef.items.type) || paramDef.type, + valueDecoded: element, + valueEncoded: typeof element === 'string' + ? element + : JSON.stringify(element) + }; + }); + // init 'undefined' value + if (!(paramDef.hasDefault || + paramDef.isSelectMultiple || + paramDef.required)) { + paramDef.selectOptionList.unshift({ + id: local.idDomElementCreate('swgg_id_' + paramDef.name), + selected: 'selected', + type: paramDef.type, + valueDecoded: '$swggUndefined', + valueEncoded: '' + }); + } + // if required, then select at least one value + if (paramDef.required && paramDef.selectOptionList.length) { + paramDef.selected = paramDef.selectOptionList[0]; + paramDef.selectOptionList.some(function (element) { + if (element.selected) { + paramDef.selected = element.selected; + return true; + } + }); + paramDef.selected = 'selected'; + } + // init input - textarea + } else if (paramDef.type === 'array') { + paramDef.isTextarea = true; + paramDef.placeholder = 'provide multiple values in new lines' + + (paramDef.required + ? ' (at least one required)' + : ''); + // init input - text + } else { + paramDef.isInputText = true; + } + // init format2 / type2 + [ + paramDef, + paramDef.schema + ].some(function (element) { + local.tryCatchOnError(function () { + paramDef.format2 = paramDef.format2 || element.format; + }, local.nop); + local.tryCatchOnError(function () { + paramDef.type2 = paramDef.type2 || element.type; + }, local.nop); + return paramDef.type2; + }); + paramDef.type2 = paramDef.type2 || 'object'; + // init schema2 + [ + paramDef.items, + paramDef.schema, + paramDef.schema && paramDef.schema.items + ].some(function (element) { + paramDef.schema2 = local.schemaNormalizeAndCopy(element || {}).properties; + return paramDef.schema2; + }); + if (paramDef.schema2) { + paramDef.schemaText = JSON.stringify(paramDef.type2 === 'array' + ? [paramDef.schema2] + : paramDef.schema2, null, 4); + } + // init valueEncoded + paramDef.valueEncoded = paramDef.default; + if (paramDef.valueEncoded === undefined) { + paramDef.valueEncoded = local.dbFieldRandomCreate({ + modeNotRandom: true, + propDef: paramDef + }); + } + // init valueEncoded for array + if (paramDef.valueEncoded && paramDef.type2 === 'array' && paramDef.in !== 'body') { + paramDef.valueEncoded = paramDef.valueEncoded.map(function (element) { + return typeof element === 'string' + ? element + : JSON.stringify(element); + }).join('\n'); + } + // init valueEncoded for schema + if (paramDef.in === 'body' && paramDef.schema2) { + paramDef.valueEncoded = local.dbRowRandomCreate({ + modeNotRandom: true, + override: function () { + var override = {}; + // preserve default value + Object.keys(paramDef.schema2).forEach(function (key) { + if (paramDef.schema2[key].default !== undefined) { + override[key] = paramDef.schema2[key].default; + } + }); + return override; + }, + properties: paramDef.schema2 + }); + if (paramDef.type2 === 'array') { + paramDef.valueEncoded = [paramDef.valueEncoded]; + } + paramDef.valueEncoded = JSON.stringify(paramDef.valueEncoded, null, 4); + } + if (typeof paramDef.valueEncoded !== 'string') { + paramDef.valueEncoded = JSON.stringify(paramDef.valueEncoded) || ''; + } + // templateRender paramDef + paramDef.innerHTML = local.templateRender(local.templateUiParam, paramDef); + }; + + local.uiRender = function () { + /* + * this function will render swagger-ui + */ + var resource, self; + // reset state + local.idDomElementDict = {}; + self = local.uiState = local.jsonCopy(local.swaggerJson); + // init url + self.url = document.querySelector('.swggUiContainer > .header > .td2').value; + // templateRender main + self.uiFragment = local.domFragmentRender(local.templateUiMain, self); + local.objectSetDefault(self, { + resourceDict: {}, + operationDict: {}, + tagDict: {} + }); + // init tagDict + self.tags.forEach(function (tag) { + self.tagDict[tag.name] = tag; + }); + // init operationDict + Object.keys(local.apiDict).sort().forEach(function (operation) { + // init operation + operation = local.jsonCopy(local.apiDict[operation]); + operation.tags.forEach(function (tag) { + self.operationDict[operation._keyOperationId] = operation; + // init resource + resource = self.resourceDict[tag]; + if (!resource && self.tagDict[tag]) { + resource = self.resourceDict[tag] = self.tagDict[tag]; + local.objectSetDefault(resource, { + description: 'no description available', + id: local.idDomElementCreate('swgg_id_' + tag), + name: tag, + operationListInnerHtml: '' + }); + } + }); + }); + // init resourceDict + Object.keys(self.resourceDict).sort().forEach(function (key) { + // templateRender resource + self.uiFragment.querySelector('.resourceList').appendChild( + local.domFragmentRender(local.templateUiResource, self.resourceDict[key]) + ); + }); + Object.keys(self.operationDict).sort(function (aa, bb) { + aa = self.operationDict[aa]; + aa = aa._path + ' ' + aa._method; + bb = self.operationDict[bb]; + bb = bb._path + ' ' + bb._method; + return aa < bb + ? -1 + : 1; + }).forEach(function (operation) { + operation = self.operationDict[operation]; + operation.id = local.idDomElementCreate('swgg_id_' + operation.operationId); + operation.tags.forEach(function (tag) { + operation = local.jsonCopy(operation); + resource = self.resourceDict[tag]; + local.objectSetDefault(operation, { + description: '', + responseList: Object.keys(operation.responses).sort() + .map(function (key) { + return { key: key, value: operation.responses[key] }; + }), + summary: 'no summary available' + }); + operation.parameters.forEach(function (element) { + // init element.id + element.id = local.idDomElementCreate('swgg_id_' + element.name); + local.uiParamRender(element); + }); + // templateRender operation + self.uiFragment.querySelector('#' + resource.id + ' .operationList') + .appendChild( + local.domFragmentRender(local.templateUiOperation, operation) + ); + }); + }); + // overwrite swggUiContainer with uiFragment + document.querySelector('.swggUiContainer').innerHTML = ''; + document.querySelector('.swggUiContainer').appendChild(self.uiFragment); + /* istanbul ignore next */ + // bug-workaround - add keypress listener for + document.querySelector('form2').addEventListener('keypress', function (event) { + if (event.keyCode === 13) { + local.uiEventListenerDict['.onEventUiReload'](); + } + }); + // render valueEncoded + Array.from( + document.querySelectorAll('.swggUiContainer [data-value-encoded]') + ).forEach(function (element) { + element.value = decodeURIComponent(element.dataset.valueEncoded); + }); + // init event-handling + local.uiEventInit(document); + // scrollTo location.hash + local.uiScrollTo(location.hash); + }; + + local.uiScrollTo = function (locationHash) { + /* + * this function will scrollTo locationHash + */ + var operation, resource; + // init resource + resource = locationHash.split('/')[1]; + // list operations + resource = document.querySelector('.swggUiContainer #' + resource) || + document.querySelector('.swggUiContainer .resource'); + local.uiAnimateSlideDown(resource.querySelector('.operationList')); + // init operation + operation = locationHash.split('/')[2]; + operation = resource.querySelector('#' + operation); + // expand operation and scroll to it + if (operation) { + local.uiAnimateSlideDown(operation.querySelector('.content')); + // scroll to operation + local.uiAnimateScrollTo(operation); + } else { + // scroll to resource + local.uiAnimateScrollTo(resource); + } + }; + + local.urlBaseGet = function () { + /* + * this function will return the base swagger url + */ + return (local.swaggerJson.schemes || + local.urlParse('').protocol.slice(0, -1)) + '://' + + (local.swaggerJson.host || local.urlParse('').host) + + local.swaggerJson.basePath; + }; + + local.userLoginByPassword = function (options, onError) { + /* + * this function will send a login-by-password request + */ + local.apiDict["GET /user/userLoginByPassword"]._ajax({ + paramDict: { password: options.password, username: options.username } + }, onError); + }; + + local.userLogout = function (options, onError) { + /* + * this function will send a logout request + */ + local.apiDict["GET /user/userLogout"]._ajax(options, onError); + }; + + local.utility2._middlewareError = function (error, request, response) { + /* + * this function will run the middleware that will + * handle errors according to http://jsonapi.org/format/#errors + */ + if (!error) { + error = new Error('404 Not Found'); + error.statusCode = 404; + } + local.serverRespondJsonapi(request, response, error); + }; + + local.utility2._stateInit = function (options) { + /* + * this function will init the state-options + */ + local.objectSetOverride(local, options, 10); + // init api + local.apiDictUpdate(local.swaggerJson); + }; + + local.validateByParamDefList = function (options) { + /* + * this function will validate options.data against options.paramDefList + */ + var data, key; + local.tryCatchOnError(function () { + data = options.data; + // validate data + local.assert(data && typeof data === 'object', data); + (options.paramDefList || []).forEach(function (paramDef) { + key = paramDef.name; + // recurse - validateByPropDef + local.validateByPropDef({ + circularList: options.circularList, + data: data[key], + dataReadonlyRemove: (options.dataReadonlyRemove || {})[key], + key: key, + schema: paramDef, + required: paramDef.required, + 'x-swgg-notRequired': paramDef['x-swgg-notRequired'] + }); + }); + }, function (error) { + error.statusCode = error.statusCode || 400; + local.errorMessagePrepend(error, options.key + '.' + key + ' -> '); + throw error; + }); + }; + + local.validateByPropDef = function (options) { + /* + * this function will validate options.data against options.schema + */ + var data, prefix, propDef, tmp; + local.tryCatchOnError(function () { + data = options.data; + prefix = 'property ' + options.key; + propDef = options.schema; + // validate undefined data + if (local.isNullOrUndefined(data)) { + if (options.required && !options['x-swgg-notRequired']) { + tmp = new Error(prefix + ' cannot be null or undefined'); + tmp.options = options; + throw tmp; + } + return; + } + // handle $ref + tmp = propDef.$ref || (propDef.schema && propDef.schema.$ref); + if (tmp) { + // recurse - validateBySchema + local.validateBySchema({ + circularList: options.circularList, + data: data, + dataReadonlyRemove: options.dataReadonlyRemove, + key: tmp, + schema: local.schemaNormalizeAndCopy({ $ref: tmp }), + 'x-swgg-notRequired': options['x-swgg-notRequired'] + }); + return; + } + // handle anyOf + if (propDef.anyOf) { + tmp = propDef.anyOf.some(function (element) { + local.tryCatchOnError(function () { + // recurse - validateBySchema + local.validateBySchema({ + circularList: options.circularList, + data: data, + key: 'anyOf', + schema: local.schemaNormalizeAndCopy(element), + 'x-swgg-notRequired': options['x-swgg-notRequired'] + }); + }, local.nop); + return !local.utility2._debugTryCatchErrorCaught; + }); + local.assert(tmp, local.utility2._debugTryCatchErrorCaught); + return; + } + // normalize propDef + propDef = local.schemaNormalizeAndCopy(options.schema); + // init circularList + if (data && typeof data === 'object') { + options.circularList = options.circularList || []; + if (options.circularList.indexOf(data) >= 0) { + return; + } + options.circularList.push(data); + } + // validate propDef embedded in propDef.schema.type + if (!propDef.type && propDef.schema && propDef.schema.type) { + propDef = propDef.schema; + } + // http://json-schema.org/latest/json-schema-validation.html#anchor13 + // 5.1. Validation keywords for numeric instances (number and integer) + if (typeof data === 'number') { + if (typeof propDef.multipleOf === 'number') { + local.assert( + data % propDef.multipleOf === 0, + prefix + ' must be a multiple of ' + propDef.multipleOf + ); + } + if (typeof propDef.maximum === 'number') { + local.assert( + propDef.exclusiveMaximum + ? data < propDef.maximum + : data <= propDef.maximum, + prefix + ' must be ' + (propDef.exclusiveMaximum + ? '< ' + : '<= ') + propDef.maximum + ); + } + if (typeof propDef.minimum === 'number') { + local.assert( + propDef.exclusiveMinimum + ? data > propDef.minimum + : data >= propDef.minimum, + prefix + ' must be ' + (propDef.exclusiveMinimum + ? '> ' + : '>= ') + propDef.minimum + ); + } + // http://json-schema.org/latest/json-schema-validation.html#anchor25 + // 5.2. Validation keywords for strings + } else if (typeof data === 'string') { + if (propDef.maxLength) { + local.assert( + data.length <= propDef.maxLength, + prefix + ' must have <= ' + propDef.maxLength + ' characters' + ); + } + if (propDef.minLength) { + local.assert( + data.length >= propDef.minLength, + prefix + ' must have >= ' + propDef.minLength + ' characters' + ); + } + if (propDef.pattern) { + local.assert( + new RegExp(propDef.pattern).test(data), + prefix + ' must match regex pattern /' + propDef.pattern + '/' + ); + } + // http://json-schema.org/latest/json-schema-validation.html#anchor36 + // 5.3. Validation keywords for arrays + } else if (Array.isArray(data)) { + if (propDef.maxItems) { + local.assert( + data.length <= propDef.maxItems, + prefix + ' must have <= ' + propDef.maxItems + ' items' + ); + } + if (propDef.minItems) { + local.assert( + data.length >= propDef.minItems, + prefix + ' must have >= ' + propDef.minItems + ' items' + ); + } + if (propDef.uniqueItems) { + tmp = {}; + data.forEach(function (element) { + element = JSON.stringify(element); + local.assert( + !tmp[element], + prefix + ' must have only unique items' + ); + tmp[element] = true; + }); + } + // http://json-schema.org/latest/json-schema-validation.html#anchor53 + // 5.4. Validation keywords for objects + } else if (typeof data === 'object') { + if (propDef.maxProperties) { + local.assert( + Object.keys(data).length <= propDef.maxProperties, + prefix + ' must have <= ' + propDef.maxProperties + ' items' + ); + } + if (propDef.minProperties) { + local.assert( + Object.keys(data).length >= propDef.minProperties, + prefix + ' must have >= ' + propDef.minProperties + ' items' + ); + } + } + // http://json-schema.org/latest/json-schema-validation.html#anchor75 + // 5.5. Validation keywords for any instance type + if (propDef.enum) { + (Array.isArray(data) + ? data + : [data]).forEach(function (element) { + local.assert( + propDef.enum.indexOf(element) >= 0, + prefix + ' must only have items in the list ' + + JSON.stringify(propDef.enum) + ); + }); + } + // https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md + // #data-types + // validate schema.type + switch (propDef.type) { + case 'array': + local.assert(Array.isArray(data) && propDef.items); + data.forEach(function (element, ii) { + // recurse - validateByPropDef + local.validateByPropDef({ + circularList: options.circularList, + data: element, + dataReadonlyRemove: (options.dataReadonlyRemove || {})[ii], + key: ii, + schema: propDef.items, + 'x-swgg-notRequired': options['x-swgg-notRequired'] + }); + }); + switch (propDef.collectionFormat) { + case 'multi': + local.assert( + propDef.in === 'formData' || propDef.in === 'query', + prefix + ' with collectionFormat "multi" ' + + 'is valid only for parameters in "query" or "formData"' + ); + break; + } + break; + case 'boolean': + local.assert(typeof data === 'boolean'); + break; + case 'file': + break; + case 'integer': + local.assert(typeof data === 'number' && + isFinite(data) && + Math.floor(data) === data); + switch (propDef.format) { + case 'int32': + case 'int64': + break; + } + break; + case 'number': + local.assert(typeof data === 'number' && isFinite(data)); + switch (propDef.format) { + case 'double': + case 'float': + break; + } + break; + case 'object': + local.assert(typeof data === 'object'); + break; + case 'string': + local.assert(typeof data === 'string' || propDef.format === 'binary'); + switch (propDef.format) { + // https://github.com/swagger-api/swagger-spec/issues/50 + // Clarify 'byte' format #50 + case 'byte': + local.assert(!(/[^\n\r\+\/0-9\=A-Za-z]/).test(data)); + break; + case 'date': + case 'date-time': + local.assert(JSON.stringify(new Date(data)) !== 'null'); + break; + case 'email': + local.assert(local.regexpEmailValidate.test(data)); + break; + case 'phone': + local.assert(local.regexpPhoneValidate.test(data)); + break; + case 'json': + JSON.parse(data); + break; + } + break; + default: + local.assert( + propDef.type === undefined, + prefix + ' has invalid type ' + propDef.type + ); + } + }, function (error) { + error.message = error.message || prefix + ' is not a valid ' + propDef.type + + (propDef.format + ? ' (' + propDef.format + ')' + : ''); + error.options = options; + throw error; + }); + }; + + local.validateBySchema = function (options) { + /* + * this function will validate options.data against options.schema + */ + var data, key, prefix, propDefDict, schema, tmp, validateByPropDef; + // recurse - validateByPropDef + local.validateByPropDef(options); + local.tryCatchOnError(function () { + data = options.data; + prefix = 'schema ' + options.key; + schema = options.schema; + // validate schema + local.assert( + schema && typeof schema === 'object', + prefix + ' must be an object (not ' + typeof schema + ')' + ); + // init propDefDict + propDefDict = schema.properties || {}; + // validate data + local.assert( + (data && typeof data === 'object') || !Object.keys(propDefDict).length, + 'data for ' + prefix + ' must be an object (not ' + typeof data + ')' + ); + if (typeof data !== 'object') { + return; + } + validateByPropDef = function (propDef) { + // remove options.dataReadonlyRemove[key] + if (propDef.readOnly && + (options.dataReadonlyRemove || {}).hasOwnProperty(key)) { + delete options.dataReadonlyRemove[key]; + } + // recurse - validateByPropDef + local.validateByPropDef({ + circularList: options.circularList, + data: data[key], + dataReadonlyRemove: (options.dataReadonlyRemove || {})[key], + key: key, + schema: propDef, + required: schema.required && schema.required.indexOf(key) >= 0, + 'x-swgg-notRequired': options['x-swgg-notRequired'] + }); + }; + Object.keys(propDefDict).forEach(function (_) { + key = _; + validateByPropDef(propDefDict[key]); + }); + Object.keys(data).forEach(function (_) { + key = _; + if (propDefDict[key]) { + return; + } + tmp = Object.keys(schema.patternProperties || {}).some(function (_) { + if (new RegExp(_).test(key)) { + validateByPropDef(schema.patternProperties[_]); + return true; + } + }); + if (tmp) { + return; + } + // https://tools.ietf.org/html/draft-fge-json-schema-validation-00 + // #section-5.4.4 + // validate additionalProperties + local.assert( + schema.additionalProperties !== false, + prefix + ' must not have additionalProperties - ' + key + ); + if (schema.additionalProperties) { + validateByPropDef(schema.additionalProperties); + } + }); + }, function (error) { + local.errorMessagePrepend(error, options.key + '.' + key + ' -> '); + throw error; + }); + }; + + local.validateBySwagger = function (options) { + /* + * this function will validate the entire swagger json object + */ + var key, schema, tmp, validateDefault; + local.validateBySchema({ + data: options, + key: 'swaggerJson', + schema: local.swaggerSchemaJson + }); + // validate default + validateDefault = function () { + if (schema.default !== undefined) { + return; + } + local.validateByPropDef({ + data: schema.default, + key: key + '.default', + schema: schema + }); + }; + Object.keys(options.definitions).forEach(function (schemaName) { + schema = options.definitions[schemaName]; + key = schemaName; + validateDefault(); + Object.keys(options.definitions[schemaName].properties || { + }).forEach(function (propName) { + schema = options.definitions[schemaName].properties[propName]; + key = schemaName + '.' + propName; + validateDefault(); + }); + }); + Object.keys(options.paths).forEach(function (pathName) { + Object.keys(options.paths[pathName]).forEach(function (methodName) { + tmp = options.paths[pathName][methodName]; + Object.keys(tmp.parameters).forEach(function (paramName) { + schema = tmp.parameters[paramName]; + key = tmp.tags[0] + '.' + tmp.operationId + '.' + paramName; + validateDefault(); + }); + }); + }); + }; + }()); + switch (local.modeJs) { + + + + // run browser js-env code - init-after + case 'browser': + // init state + local.utility2._stateInit({}); + break; + + + + // run node js-env code - init-after + case 'node': + // init assets.lib.rollup.js + local.assetsDict['/assets.swgg.rollup.js'] = + local.assetsDict['/assets.utility2.rollup.js']; + // init state + local.utility2._stateInit({}); + break; + } + switch (local.modeJs) { + + + + /* istanbul ignore next */ + // run node js-env code - cli + case 'node': + /* istanbul ignore next */ + if (local.env.SWAGGER_JSON_URL) { + if (local.env.SWAGGER_JSON_URL === '127.0.0.1') { + local.env.SWAGGER_JSON_URL = '/assets.swgg.petstore.json'; + } + local.assetsDict['/assets.swgg.html'] = + local.assetsDict['/assets.swgg.html'].replace( + 'assets.swgg.petstore.json', + local.env.SWAGGER_JSON_URL + ); + } + // run the cli + switch (process.argv[2]) { + case 'swagger-ui': + local.replStart(); + local.global.local = local; + local.assetsDict['/'] = local.assetsDict['/assets.swgg.html']; + local.testRunServer({}); + break; + } + break; + } +}()); +/* script-end /assets.swgg.js */ + + + +/* script-begin /assets.utility2.rollup.end.js */ +(function () { + "use strict"; + var local; + local = {}; + local.modeJs = (function () { + try { + return typeof navigator.userAgent === "string" && + typeof document.querySelector("body") === "object" && + typeof XMLHttpRequest.prototype.open === "function" && + "browser"; + } catch (errorCaughtBrowser) { + return module.exports && + typeof process.versions.node === "string" && + typeof require("http").createServer === "function" && + "node"; + } + }()); + local.global = local.modeJs === "browser" + ? window + : global; + local.global.utility2_rollup_old = local.global.utility2_rollup; + local.global.utility2_rollup = null; +}()); +/* utility2.rollup.js end */ +/* script-end /assets.utility2.rollup.end.js */ diff --git a/build/app/index.html b/build/app/index.html new file mode 100644 index 0000000..fa96ab4 --- /dev/null +++ b/build/app/index.html @@ -0,0 +1,87 @@ + + + + + +npmdoc-debowerify (v0.0.2) + + + + + +
+ +

+ + + + npmdoc-debowerify (v0.0.2) + + + +

+

#### basic api documentation for [debowerify (v1.5.0)](https://github.com/eugeneware/debowerify#readme) [![npm package](https://img.shields.io/npm/v/npmdoc-debowerify.svg?style=flat-square)](https://www.npmjs.org/package/npmdoc-debowerify) [![travis-ci.org build-status](https://api.travis-ci.org/npmdoc/node-npmdoc-debowerify.svg)](https://travis-ci.org/npmdoc/node-npmdoc-debowerify)

+ +

download standalone app

+
+ + + + + + + + + + + + + + + + + + +
+ [ this app was created with + utility2 + ] +
+ + diff --git a/build/app/jsonp.utility2._stateInit b/build/app/jsonp.utility2._stateInit new file mode 100644 index 0000000..7f5af19 --- /dev/null +++ b/build/app/jsonp.utility2._stateInit @@ -0,0 +1 @@ +window.utility2._stateInit({"utility2":{"assetsDict":{"/assets.index.template.html":"\n\n\n\n\n{{env.npm_package_name}} (v{{env.npm_package_version}})\n\n\n\n\n\n

\n\n {{env.npm_package_name}} (v{{env.npm_package_version}})\n\n

\n

{{env.npm_package_description}}

\n\n\n\n\n\n\n\n\n\n\n\n\n\n
\n [ this app was created with\n utility2\n ]\n
\n\n\n"},"env":{"NODE_ENV":"test","npm_package_description":"#### basic api documentation for [debowerify (v1.5.0)](https://github.com/eugeneware/debowerify#readme) [![npm package](https://img.shields.io/npm/v/npmdoc-debowerify.svg?style=flat-square)](https://www.npmjs.org/package/npmdoc-debowerify) [![travis-ci.org build-status](https://api.travis-ci.org/npmdoc/node-npmdoc-debowerify.svg)](https://travis-ci.org/npmdoc/node-npmdoc-debowerify)","npm_package_homepage":"https://github.com/npmdoc/node-npmdoc-debowerify","npm_package_name":"npmdoc-debowerify","npm_package_nameAlias":"npmdoc_debowerify","npm_package_version":"0.0.2"}}}); \ No newline at end of file diff --git a/build/build.badge.svg b/build/build.badge.svg new file mode 100644 index 0000000..97d696b --- /dev/null +++ b/build/build.badge.svg @@ -0,0 +1 @@ +last buildlast build2017-04-27 16:48:12 UTC | alpha | alpha2017-04-27 16:48:12 UTC | alpha | alpha \ No newline at end of file diff --git a/build/coverage.badge.svg b/build/coverage.badge.svg new file mode 100644 index 0000000..1382aa2 --- /dev/null +++ b/build/coverage.badge.svg @@ -0,0 +1 @@ +coveragecoverage100%100% \ No newline at end of file diff --git a/build/coverage.html/coverage.code-dict.json b/build/coverage.html/coverage.code-dict.json new file mode 100644 index 0000000..a127f0d --- /dev/null +++ b/build/coverage.html/coverage.code-dict.json @@ -0,0 +1 @@ +{"/home/travis/build/npmdoc/node-npmdoc-debowerify/test.js":"/* istanbul instrument in package npmdoc_debowerify */\n/*jslint\n bitwise: true,\n browser: true,\n maxerr: 8,\n maxlen: 96,\n node: true,\n nomen: true,\n regexp: true,\n stupid: true\n*/\n(function () {\n 'use strict';\n var local;\n\n\n\n // run shared js-env code - pre-init\n (function () {\n // init local\n local = {};\n // init modeJs\n local.modeJs = (function () {\n try {\n return typeof navigator.userAgent === 'string' &&\n typeof document.querySelector('body') === 'object' &&\n typeof XMLHttpRequest.prototype.open === 'function' &&\n 'browser';\n } catch (errorCaughtBrowser) {\n return module.exports &&\n typeof process.versions.node === 'string' &&\n typeof require('http').createServer === 'function' &&\n 'node';\n }\n }());\n // init global\n local.global = local.modeJs === 'browser'\n ? window\n : global;\n switch (local.modeJs) {\n // re-init local from window.local\n case 'browser':\n local = local.global.utility2.objectSetDefault(\n local.global.utility2_rollup || local.global.local,\n local.global.utility2\n );\n break;\n // re-init local from example.js\n case 'node':\n local = (local.global.utility2_rollup || require('utility2'))\n .requireExampleJsFromReadme();\n break;\n }\n // export local\n local.global.local = local;\n }());\n\n\n\n // run shared js-env code - function\n (function () {\n return;\n }());\n switch (local.modeJs) {\n\n\n\n // run browser js-env code - function\n case 'browser':\n break;\n\n\n\n // run node js-env code - function\n case 'node':\n break;\n }\n\n\n\n // run shared js-env code - post-init\n (function () {\n return;\n }());\n switch (local.modeJs) {\n\n\n\n // run browser js-env code - post-init\n case 'browser':\n // run tests\n local.nop(local.modeTest &&\n document.querySelector('#testRunButton1') &&\n document.querySelector('#testRunButton1').click());\n break;\n\n\n\n // run node js-env code - post-init\n /* istanbul ignore next */\n case 'node':\n local.testCase_buildApidoc_default = local.testCase_buildApidoc_default || function (\n options,\n onError\n ) {\n /*\n * this function will test buildApidoc's default handling-behavior-behavior\n */\n options = { modulePathList: module.paths };\n if (local.env.npm_package_buildNpmdoc) {\n local.buildNpmdoc(options, onError);\n return;\n }\n local.buildApidoc(options, onError);\n };\n\n local.testCase_buildApp_default = local.testCase_buildApp_default || function (\n options,\n onError\n ) {\n /*\n * this function will test buildApp's default handling-behavior-behavior\n */\n local.testCase_buildReadme_default(options, local.onErrorThrow);\n local.testCase_buildLib_default(options, local.onErrorThrow);\n local.testCase_buildTest_default(options, local.onErrorThrow);\n options = [];\n local.buildApp(options, onError);\n };\n\n local.testCase_buildLib_default = local.testCase_buildLib_default || function (\n options,\n onError\n ) {\n /*\n * this function will test buildLib's default handling-behavior\n */\n options = {};\n local.buildLib(options, onError);\n };\n\n local.testCase_buildReadme_default = local.testCase_buildReadme_default || function (\n options,\n onError\n ) {\n /*\n * this function will test buildReadme's default handling-behavior-behavior\n */\n if (local.env.npm_package_buildNpmdoc) {\n onError();\n return;\n }\n options = {};\n local.buildReadme(options, onError);\n };\n\n local.testCase_buildTest_default = local.testCase_buildTest_default || function (\n options,\n onError\n ) {\n /*\n * this function will test buildTest's default handling-behavior\n */\n options = {};\n local.buildTest(options, onError);\n };\n\n local.testCase_webpage_default = local.testCase_webpage_default || function (\n options,\n onError\n ) {\n /*\n * this function will test webpage's default handling-behavior\n */\n options = { modeCoverageMerge: true, url: local.serverLocalHost + '?modeTest=1' };\n local.browserTest(options, onError);\n };\n\n // run test-server\n local.testRunServer(local);\n break;\n }\n}());\n","/home/travis/build/npmdoc/node-npmdoc-debowerify/lib.npmdoc_debowerify.js":"/* istanbul instrument in package npmdoc_debowerify */\n/*jslint\n bitwise: true,\n browser: true,\n maxerr: 8,\n maxlen: 96,\n node: true,\n nomen: true,\n regexp: true,\n stupid: true\n*/\n(function () {\n 'use strict';\n var local;\n\n\n\n // run shared js-env code - pre-init\n (function () {\n // init local\n local = {};\n // init modeJs\n local.modeJs = (function () {\n try {\n return typeof navigator.userAgent === 'string' &&\n typeof document.querySelector('body') === 'object' &&\n typeof XMLHttpRequest.prototype.open === 'function' &&\n 'browser';\n } catch (errorCaughtBrowser) {\n return module.exports &&\n typeof process.versions.node === 'string' &&\n typeof require('http').createServer === 'function' &&\n 'node';\n }\n }());\n // init global\n local.global = local.modeJs === 'browser'\n ? window\n : global;\n // init utility2_rollup\n local = local.global.utility2_rollup || local;\n // init lib\n local.local = local.npmdoc_debowerify = local;\n // init exports\n if (local.modeJs === 'browser') {\n local.global.utility2_npmdoc_debowerify = local;\n } else {\n module.exports = local;\n module.exports.__dirname = __dirname;\n module.exports.module = module;\n }\n }());\n}());\n","/home/travis/build/npmdoc/node-npmdoc-debowerify/example.js":"/*\nexample.js\n\nquickstart example\n\ninstruction\n 1. save this script as example.js\n 2. run the shell command:\n $ npm install npmdoc-debowerify && PORT=8081 node example.js\n 3. play with the browser-demo on http://127.0.0.1:8081\n*/\n\n\n\n/* istanbul instrument in package npmdoc_debowerify */\n/*jslint\n bitwise: true,\n browser: true,\n maxerr: 8,\n maxlen: 96,\n node: true,\n nomen: true,\n regexp: true,\n stupid: true\n*/\n(function () {\n 'use strict';\n var local;\n\n\n\n // run shared js-env code - pre-init\n (function () {\n // init local\n local = {};\n // init modeJs\n local.modeJs = (function () {\n try {\n return typeof navigator.userAgent === 'string' &&\n typeof document.querySelector('body') === 'object' &&\n typeof XMLHttpRequest.prototype.open === 'function' &&\n 'browser';\n } catch (errorCaughtBrowser) {\n return module.exports &&\n typeof process.versions.node === 'string' &&\n typeof require('http').createServer === 'function' &&\n 'node';\n }\n }());\n // init global\n local.global = local.modeJs === 'browser'\n ? window\n : global;\n // init utility2_rollup\n local = local.global.utility2_rollup || (local.modeJs === 'browser'\n ? local.global.utility2_npmdoc_debowerify\n : global.utility2_moduleExports);\n // export local\n local.global.local = local;\n }());\n switch (local.modeJs) {\n\n\n\n // post-init\n // run browser js-env code - post-init\n /* istanbul ignore next */\n case 'browser':\n local.testRunBrowser = function (event) {\n if (!event || (event &&\n event.currentTarget &&\n event.currentTarget.className &&\n event.currentTarget.className.includes &&\n event.currentTarget.className.includes('onreset'))) {\n // reset output\n Array.from(\n document.querySelectorAll('body > .resettable')\n ).forEach(function (element) {\n switch (element.tagName) {\n case 'INPUT':\n case 'TEXTAREA':\n element.value = '';\n break;\n default:\n element.textContent = '';\n }\n });\n }\n switch (event && event.currentTarget && event.currentTarget.id) {\n case 'testRunButton1':\n // show tests\n if (document.querySelector('#testReportDiv1').style.display === 'none') {\n document.querySelector('#testReportDiv1').style.display = 'block';\n document.querySelector('#testRunButton1').textContent =\n 'hide internal test';\n local.modeTest = true;\n local.testRunDefault(local);\n // hide tests\n } else {\n document.querySelector('#testReportDiv1').style.display = 'none';\n document.querySelector('#testRunButton1').textContent = 'run internal test';\n }\n break;\n // custom-case\n default:\n break;\n }\n if (document.querySelector('#inputTextareaEval1') && (!event || (event &&\n event.currentTarget &&\n event.currentTarget.className &&\n event.currentTarget.className.includes &&\n event.currentTarget.className.includes('oneval')))) {\n // try to eval input-code\n try {\n /*jslint evil: true*/\n eval(document.querySelector('#inputTextareaEval1').value);\n } catch (errorCaught) {\n console.error(errorCaught.stack);\n }\n }\n };\n // log stderr and stdout to #outputTextareaStdout1\n ['error', 'log'].forEach(function (key) {\n console[key + '_original'] = console[key];\n console[key] = function () {\n var element;\n console[key + '_original'].apply(console, arguments);\n element = document.querySelector('#outputTextareaStdout1');\n if (!element) {\n return;\n }\n // append text to #outputTextareaStdout1\n element.value += Array.from(arguments).map(function (arg) {\n return typeof arg === 'string'\n ? arg\n : JSON.stringify(arg, null, 4);\n }).join(' ') + '\\n';\n // scroll textarea to bottom\n element.scrollTop = element.scrollHeight;\n };\n });\n // init event-handling\n ['change', 'click', 'keyup'].forEach(function (event) {\n Array.from(document.querySelectorAll('.on' + event)).forEach(function (element) {\n element.addEventListener(event, local.testRunBrowser);\n });\n });\n // run tests\n local.testRunBrowser();\n break;\n\n\n\n // run node js-env code - post-init\n /* istanbul ignore next */\n case 'node':\n // export local\n module.exports = local;\n // require modules\n local.fs = require('fs');\n local.http = require('http');\n local.url = require('url');\n // init assets\n local.assetsDict = local.assetsDict || {};\n /* jslint-ignore-begin */\n local.assetsDict['/assets.index.template.html'] = '\\\n\\n\\\n\\n\\\n\\n\\\n\\n\\\n\\n\\\n{{env.npm_package_name}} (v{{env.npm_package_version}})\\n\\\n\\n\\\n\\n\\\n\\n\\\n\\n\\\n\\n\\\n

\\n\\\n\\n\\\n {{env.npm_package_name}} (v{{env.npm_package_version}})\\n\\\n\\n\\\n

\\n\\\n

{{env.npm_package_description}}

\\n\\\n\\n\\\n\\n\\\n\\n\\\n\\n\\\n\\n\\\n\\n\\\n\\n\\\n\\n\\\n\\n\\\n\\n\\\n\\n\\\n\\n\\\n\\n\\\n
\\n\\\n [ this app was created with\\n\\\n utility2\\n\\\n ]\\n\\\n
\\n\\\n\\n\\\n\\n\\\n';\n /* jslint-ignore-end */\n if (local.templateRender) {\n local.assetsDict['/'] = local.templateRender(\n local.assetsDict['/assets.index.template.html'],\n {\n env: local.objectSetDefault(local.env, {\n npm_package_description: 'example module',\n npm_package_name: 'example',\n npm_package_nameAlias: 'example',\n npm_package_version: '0.0.1'\n })\n }\n );\n } else {\n local.assetsDict['/'] = local.assetsDict['/assets.index.template.html']\n .replace((/\\{\\{env\\.(\\w+?)\\}\\}/g), function (match0, match1) {\n // jslint-hack\n String(match0);\n switch (match1) {\n case 'npm_package_description':\n return 'example module';\n case 'npm_package_name':\n return 'example';\n case 'npm_package_nameAlias':\n return 'example';\n case 'npm_package_version':\n return '0.0.1';\n }\n });\n }\n // run the cli\n if (local.global.utility2_rollup || module !== require.main) {\n break;\n }\n local.assetsDict['/assets.example.js'] =\n local.assetsDict['/assets.example.js'] ||\n local.fs.readFileSync(__filename, 'utf8');\n local.assetsDict['/assets.npmdoc_debowerify.rollup.js'] =\n local.assetsDict['/assets.npmdoc_debowerify.rollup.js'] ||\n local.fs.readFileSync(\n // npmdoc-hack\n local.npmdoc_debowerify.__dirname +\n '/lib.npmdoc_debowerify.js',\n 'utf8'\n ).replace((/^#!/), '//');\n local.assetsDict['/favicon.ico'] = local.assetsDict['/favicon.ico'] || '';\n // if $npm_config_timeout_exit exists,\n // then exit this process after $npm_config_timeout_exit ms\n if (Number(process.env.npm_config_timeout_exit)) {\n setTimeout(process.exit, Number(process.env.npm_config_timeout_exit));\n }\n // start server\n if (local.global.utility2_serverHttp1) {\n break;\n }\n process.env.PORT = process.env.PORT || '8081';\n console.error('server starting on port ' + process.env.PORT);\n local.http.createServer(function (request, response) {\n request.urlParsed = local.url.parse(request.url);\n if (local.assetsDict[request.urlParsed.pathname] !== undefined) {\n response.end(local.assetsDict[request.urlParsed.pathname]);\n return;\n }\n response.statusCode = 404;\n response.end();\n }).listen(process.env.PORT);\n break;\n }\n}());\n"} \ No newline at end of file diff --git a/build/coverage.html/coverage.json b/build/coverage.html/coverage.json new file mode 100644 index 0000000..f7aab8d --- /dev/null +++ b/build/coverage.html/coverage.json @@ -0,0 +1 @@ +{"/home/travis/build/npmdoc/node-npmdoc-debowerify/test.js":{"path":"/home/travis/build/npmdoc/node-npmdoc-debowerify/test.js","s":{"1":2,"2":2,"3":2,"4":2,"5":2,"6":2,"7":2,"8":1,"9":2,"10":2,"11":1,"12":1,"13":1,"14":1,"15":2,"16":2,"17":2,"18":2,"19":1,"20":1,"21":2,"22":2,"23":2,"24":1,"25":1,"26":1,"27":1,"28":1,"29":1,"30":1,"31":0,"32":1,"33":1,"34":1,"35":1,"36":1,"37":1,"38":1,"39":2,"40":2,"41":1,"42":2,"43":2,"44":2,"45":0,"46":0,"47":1,"48":2,"49":2,"50":1,"51":1,"52":1,"53":1,"54":1},"b":{"1":[2,1,1,1],"2":[1,1,1,1],"3":[1,1],"4":[1,1],"5":[1,1],"6":[1,1],"7":[1,1],"8":[1,1],"9":[1,1,1],"10":[1,1],"11":[1,0],"12":[1,1],"13":[1,1],"14":[1,1],"15":[2,0],"16":[1,1],"17":[1,1]},"f":{"1":2,"2":2,"3":2,"4":2,"5":2,"6":1,"7":1,"8":2,"9":2,"10":2,"11":1},"fnMap":{"1":{"name":"(anonymous_1)","line":12,"loc":{"start":{"line":12,"column":1},"end":{"line":12,"column":13}}},"2":{"name":"(anonymous_2)","line":19,"loc":{"start":{"line":19,"column":5},"end":{"line":19,"column":17}}},"3":{"name":"(anonymous_3)","line":23,"loc":{"start":{"line":23,"column":24},"end":{"line":23,"column":36}}},"4":{"name":"(anonymous_4)","line":61,"loc":{"start":{"line":61,"column":5},"end":{"line":61,"column":17}}},"5":{"name":"(anonymous_5)","line":82,"loc":{"start":{"line":82,"column":5},"end":{"line":82,"column":17}}},"6":{"name":"(anonymous_6)","line":102,"loc":{"start":{"line":102,"column":83},"end":{"line":105,"column":10}},"skip":true},"7":{"name":"(anonymous_7)","line":117,"loc":{"start":{"line":117,"column":77},"end":{"line":120,"column":10}},"skip":true},"8":{"name":"(anonymous_8)","line":131,"loc":{"start":{"line":131,"column":77},"end":{"line":134,"column":10}},"skip":true},"9":{"name":"(anonymous_9)","line":142,"loc":{"start":{"line":142,"column":83},"end":{"line":145,"column":10}},"skip":true},"10":{"name":"(anonymous_10)","line":157,"loc":{"start":{"line":157,"column":79},"end":{"line":160,"column":10}},"skip":true},"11":{"name":"(anonymous_11)","line":168,"loc":{"start":{"line":168,"column":75},"end":{"line":171,"column":10}},"skip":true}},"statementMap":{"1":{"start":{"line":12,"column":0},"end":{"line":183,"column":5}},"2":{"start":{"line":14,"column":4},"end":{"line":14,"column":14}},"3":{"start":{"line":19,"column":4},"end":{"line":56,"column":9}},"4":{"start":{"line":21,"column":8},"end":{"line":21,"column":19}},"5":{"start":{"line":23,"column":8},"end":{"line":35,"column":13}},"6":{"start":{"line":24,"column":12},"end":{"line":34,"column":13}},"7":{"start":{"line":25,"column":16},"end":{"line":28,"column":30}},"8":{"start":{"line":30,"column":16},"end":{"line":33,"column":27}},"9":{"start":{"line":37,"column":8},"end":{"line":39,"column":21}},"10":{"start":{"line":40,"column":8},"end":{"line":53,"column":9}},"11":{"start":{"line":43,"column":12},"end":{"line":46,"column":14}},"12":{"start":{"line":47,"column":12},"end":{"line":47,"column":18}},"13":{"start":{"line":50,"column":12},"end":{"line":51,"column":46}},"14":{"start":{"line":52,"column":12},"end":{"line":52,"column":18}},"15":{"start":{"line":55,"column":8},"end":{"line":55,"column":35}},"16":{"start":{"line":61,"column":4},"end":{"line":63,"column":9}},"17":{"start":{"line":62,"column":8},"end":{"line":62,"column":15}},"18":{"start":{"line":64,"column":4},"end":{"line":77,"column":5}},"19":{"start":{"line":70,"column":8},"end":{"line":70,"column":14}},"20":{"start":{"line":76,"column":8},"end":{"line":76,"column":14}},"21":{"start":{"line":82,"column":4},"end":{"line":84,"column":9}},"22":{"start":{"line":83,"column":8},"end":{"line":83,"column":15}},"23":{"start":{"line":85,"column":4},"end":{"line":182,"column":5}},"24":{"start":{"line":92,"column":8},"end":{"line":94,"column":63}},"25":{"start":{"line":95,"column":8},"end":{"line":95,"column":14}},"26":{"start":{"line":102,"column":8},"end":{"line":115,"column":10},"skip":true},"27":{"start":{"line":109,"column":12},"end":{"line":109,"column":55},"skip":true},"28":{"start":{"line":110,"column":12},"end":{"line":113,"column":13},"skip":true},"29":{"start":{"line":111,"column":16},"end":{"line":111,"column":52},"skip":true},"30":{"start":{"line":112,"column":16},"end":{"line":112,"column":23},"skip":true},"31":{"start":{"line":114,"column":12},"end":{"line":114,"column":48},"skip":true},"32":{"start":{"line":117,"column":8},"end":{"line":129,"column":10},"skip":true},"33":{"start":{"line":124,"column":12},"end":{"line":124,"column":76},"skip":true},"34":{"start":{"line":125,"column":12},"end":{"line":125,"column":73},"skip":true},"35":{"start":{"line":126,"column":12},"end":{"line":126,"column":74},"skip":true},"36":{"start":{"line":127,"column":12},"end":{"line":127,"column":25},"skip":true},"37":{"start":{"line":128,"column":12},"end":{"line":128,"column":45},"skip":true},"38":{"start":{"line":131,"column":8},"end":{"line":140,"column":10},"skip":true},"39":{"start":{"line":138,"column":12},"end":{"line":138,"column":25},"skip":true},"40":{"start":{"line":139,"column":12},"end":{"line":139,"column":45},"skip":true},"41":{"start":{"line":142,"column":8},"end":{"line":155,"column":10},"skip":true},"42":{"start":{"line":149,"column":12},"end":{"line":152,"column":13},"skip":true},"43":{"start":{"line":150,"column":16},"end":{"line":150,"column":26},"skip":true},"44":{"start":{"line":151,"column":16},"end":{"line":151,"column":23},"skip":true},"45":{"start":{"line":153,"column":12},"end":{"line":153,"column":25},"skip":true},"46":{"start":{"line":154,"column":12},"end":{"line":154,"column":48},"skip":true},"47":{"start":{"line":157,"column":8},"end":{"line":166,"column":10},"skip":true},"48":{"start":{"line":164,"column":12},"end":{"line":164,"column":25},"skip":true},"49":{"start":{"line":165,"column":12},"end":{"line":165,"column":46},"skip":true},"50":{"start":{"line":168,"column":8},"end":{"line":177,"column":10},"skip":true},"51":{"start":{"line":175,"column":12},"end":{"line":175,"column":94},"skip":true},"52":{"start":{"line":176,"column":12},"end":{"line":176,"column":48},"skip":true},"53":{"start":{"line":180,"column":8},"end":{"line":180,"column":35},"skip":true},"54":{"start":{"line":181,"column":8},"end":{"line":181,"column":14},"skip":true}},"branchMap":{"1":{"line":25,"type":"binary-expr","locations":[{"start":{"line":25,"column":23},"end":{"line":25,"column":62}},{"start":{"line":26,"column":20},"end":{"line":26,"column":70}},{"start":{"line":27,"column":20},"end":{"line":27,"column":71}},{"start":{"line":28,"column":20},"end":{"line":28,"column":29}}]},"2":{"line":30,"type":"binary-expr","locations":[{"start":{"line":30,"column":23},"end":{"line":30,"column":37}},{"start":{"line":31,"column":20},"end":{"line":31,"column":61}},{"start":{"line":32,"column":20},"end":{"line":32,"column":70}},{"start":{"line":33,"column":20},"end":{"line":33,"column":26}}]},"3":{"line":37,"type":"cond-expr","locations":[{"start":{"line":38,"column":14},"end":{"line":38,"column":20}},{"start":{"line":39,"column":14},"end":{"line":39,"column":20}}]},"4":{"line":40,"type":"switch","locations":[{"start":{"line":42,"column":8},"end":{"line":47,"column":18}},{"start":{"line":49,"column":8},"end":{"line":52,"column":18}}]},"5":{"line":44,"type":"binary-expr","locations":[{"start":{"line":44,"column":16},"end":{"line":44,"column":44}},{"start":{"line":44,"column":48},"end":{"line":44,"column":66}}]},"6":{"line":50,"type":"binary-expr","locations":[{"start":{"line":50,"column":21},"end":{"line":50,"column":49}},{"start":{"line":50,"column":53},"end":{"line":50,"column":72}}]},"7":{"line":64,"type":"switch","locations":[{"start":{"line":69,"column":4},"end":{"line":70,"column":14}},{"start":{"line":75,"column":4},"end":{"line":76,"column":14}}]},"8":{"line":85,"type":"switch","locations":[{"start":{"line":90,"column":4},"end":{"line":95,"column":14}},{"start":{"line":101,"column":4},"end":{"line":181,"column":14},"skip":true}]},"9":{"line":92,"type":"binary-expr","locations":[{"start":{"line":92,"column":18},"end":{"line":92,"column":32}},{"start":{"line":93,"column":12},"end":{"line":93,"column":53}},{"start":{"line":94,"column":12},"end":{"line":94,"column":61}}]},"10":{"line":102,"type":"binary-expr","locations":[{"start":{"line":102,"column":45},"end":{"line":102,"column":79},"skip":true},{"start":{"line":102,"column":83},"end":{"line":115,"column":9},"skip":true}]},"11":{"line":110,"type":"if","locations":[{"start":{"line":110,"column":12},"end":{"line":110,"column":12},"skip":true},{"start":{"line":110,"column":12},"end":{"line":110,"column":12},"skip":true}]},"12":{"line":117,"type":"binary-expr","locations":[{"start":{"line":117,"column":42},"end":{"line":117,"column":73},"skip":true},{"start":{"line":117,"column":77},"end":{"line":129,"column":9},"skip":true}]},"13":{"line":131,"type":"binary-expr","locations":[{"start":{"line":131,"column":42},"end":{"line":131,"column":73},"skip":true},{"start":{"line":131,"column":77},"end":{"line":140,"column":9},"skip":true}]},"14":{"line":142,"type":"binary-expr","locations":[{"start":{"line":142,"column":45},"end":{"line":142,"column":79},"skip":true},{"start":{"line":142,"column":83},"end":{"line":155,"column":9},"skip":true}]},"15":{"line":149,"type":"if","locations":[{"start":{"line":149,"column":12},"end":{"line":149,"column":12},"skip":true},{"start":{"line":149,"column":12},"end":{"line":149,"column":12},"skip":true}]},"16":{"line":157,"type":"binary-expr","locations":[{"start":{"line":157,"column":43},"end":{"line":157,"column":75},"skip":true},{"start":{"line":157,"column":79},"end":{"line":166,"column":9},"skip":true}]},"17":{"line":168,"type":"binary-expr","locations":[{"start":{"line":168,"column":41},"end":{"line":168,"column":71},"skip":true},{"start":{"line":168,"column":75},"end":{"line":177,"column":9},"skip":true}]}},"code":["/* istanbul instrument in package npmdoc_debowerify */","/*jslint"," bitwise: true,"," browser: true,"," maxerr: 8,"," maxlen: 96,"," node: true,"," nomen: true,"," regexp: true,"," stupid: true","*/","(function () {"," 'use strict';"," var local;","","",""," // run shared js-env code - pre-init"," (function () {"," // init local"," local = {};"," // init modeJs"," local.modeJs = (function () {"," try {"," return typeof navigator.userAgent === 'string' &&"," typeof document.querySelector('body') === 'object' &&"," typeof XMLHttpRequest.prototype.open === 'function' &&"," 'browser';"," } catch (errorCaughtBrowser) {"," return module.exports &&"," typeof process.versions.node === 'string' &&"," typeof require('http').createServer === 'function' &&"," 'node';"," }"," }());"," // init global"," local.global = local.modeJs === 'browser'"," ? window"," : global;"," switch (local.modeJs) {"," // re-init local from window.local"," case 'browser':"," local = local.global.utility2.objectSetDefault("," local.global.utility2_rollup || local.global.local,"," local.global.utility2"," );"," break;"," // re-init local from example.js"," case 'node':"," local = (local.global.utility2_rollup || require('utility2'))"," .requireExampleJsFromReadme();"," break;"," }"," // export local"," local.global.local = local;"," }());","","",""," // run shared js-env code - function"," (function () {"," return;"," }());"," switch (local.modeJs) {","","",""," // run browser js-env code - function"," case 'browser':"," break;","","",""," // run node js-env code - function"," case 'node':"," break;"," }","","",""," // run shared js-env code - post-init"," (function () {"," return;"," }());"," switch (local.modeJs) {","","",""," // run browser js-env code - post-init"," case 'browser':"," // run tests"," local.nop(local.modeTest &&"," document.querySelector('#testRunButton1') &&"," document.querySelector('#testRunButton1').click());"," break;","","",""," // run node js-env code - post-init"," /* istanbul ignore next */"," case 'node':"," local.testCase_buildApidoc_default = local.testCase_buildApidoc_default || function ("," options,"," onError"," ) {"," /*"," * this function will test buildApidoc's default handling-behavior-behavior"," */"," options = { modulePathList: module.paths };"," if (local.env.npm_package_buildNpmdoc) {"," local.buildNpmdoc(options, onError);"," return;"," }"," local.buildApidoc(options, onError);"," };",""," local.testCase_buildApp_default = local.testCase_buildApp_default || function ("," options,"," onError"," ) {"," /*"," * this function will test buildApp's default handling-behavior-behavior"," */"," local.testCase_buildReadme_default(options, local.onErrorThrow);"," local.testCase_buildLib_default(options, local.onErrorThrow);"," local.testCase_buildTest_default(options, local.onErrorThrow);"," options = [];"," local.buildApp(options, onError);"," };",""," local.testCase_buildLib_default = local.testCase_buildLib_default || function ("," options,"," onError"," ) {"," /*"," * this function will test buildLib's default handling-behavior"," */"," options = {};"," local.buildLib(options, onError);"," };",""," local.testCase_buildReadme_default = local.testCase_buildReadme_default || function ("," options,"," onError"," ) {"," /*"," * this function will test buildReadme's default handling-behavior-behavior"," */"," if (local.env.npm_package_buildNpmdoc) {"," onError();"," return;"," }"," options = {};"," local.buildReadme(options, onError);"," };",""," local.testCase_buildTest_default = local.testCase_buildTest_default || function ("," options,"," onError"," ) {"," /*"," * this function will test buildTest's default handling-behavior"," */"," options = {};"," local.buildTest(options, onError);"," };",""," local.testCase_webpage_default = local.testCase_webpage_default || function ("," options,"," onError"," ) {"," /*"," * this function will test webpage's default handling-behavior"," */"," options = { modeCoverageMerge: true, url: local.serverLocalHost + '?modeTest=1' };"," local.browserTest(options, onError);"," };",""," // run test-server"," local.testRunServer(local);"," break;"," }","}());",""],"l":{"12":2,"14":2,"19":2,"21":2,"23":2,"24":2,"25":2,"30":1,"37":2,"40":2,"43":1,"47":1,"50":1,"52":1,"55":2,"61":2,"62":2,"64":2,"70":1,"76":1,"82":2,"83":2,"85":2,"92":1,"95":1,"102":1,"109":1,"110":1,"111":1,"112":1,"114":1,"117":1,"124":1,"125":1,"126":1,"127":1,"128":1,"131":1,"138":2,"139":2,"142":1,"149":2,"150":2,"151":2,"153":1,"154":1,"157":1,"164":2,"165":2,"168":1,"175":1,"176":1,"180":1,"181":1}},"/home/travis/build/npmdoc/node-npmdoc-debowerify/lib.npmdoc_debowerify.js":{"path":"/home/travis/build/npmdoc/node-npmdoc-debowerify/lib.npmdoc_debowerify.js","s":{"1":2,"2":2,"3":2,"4":2,"5":2,"6":2,"7":2,"8":1,"9":2,"10":2,"11":2,"12":2,"13":1,"14":1,"15":1,"16":1},"b":{"1":[2,1,1,1],"2":[1,1,1,1],"3":[1,1],"4":[2,2],"5":[1,1]},"f":{"1":2,"2":2,"3":2},"fnMap":{"1":{"name":"(anonymous_1)","line":12,"loc":{"start":{"line":12,"column":1},"end":{"line":12,"column":13}}},"2":{"name":"(anonymous_2)","line":19,"loc":{"start":{"line":19,"column":5},"end":{"line":19,"column":17}}},"3":{"name":"(anonymous_3)","line":23,"loc":{"start":{"line":23,"column":24},"end":{"line":23,"column":36}}}},"statementMap":{"1":{"start":{"line":12,"column":0},"end":{"line":53,"column":5}},"2":{"start":{"line":14,"column":4},"end":{"line":14,"column":14}},"3":{"start":{"line":19,"column":4},"end":{"line":52,"column":9}},"4":{"start":{"line":21,"column":8},"end":{"line":21,"column":19}},"5":{"start":{"line":23,"column":8},"end":{"line":35,"column":13}},"6":{"start":{"line":24,"column":12},"end":{"line":34,"column":13}},"7":{"start":{"line":25,"column":16},"end":{"line":28,"column":30}},"8":{"start":{"line":30,"column":16},"end":{"line":33,"column":27}},"9":{"start":{"line":37,"column":8},"end":{"line":39,"column":21}},"10":{"start":{"line":41,"column":8},"end":{"line":41,"column":54}},"11":{"start":{"line":43,"column":8},"end":{"line":43,"column":54}},"12":{"start":{"line":45,"column":8},"end":{"line":51,"column":9}},"13":{"start":{"line":46,"column":12},"end":{"line":46,"column":60}},"14":{"start":{"line":48,"column":12},"end":{"line":48,"column":35}},"15":{"start":{"line":49,"column":12},"end":{"line":49,"column":49}},"16":{"start":{"line":50,"column":12},"end":{"line":50,"column":43}}},"branchMap":{"1":{"line":25,"type":"binary-expr","locations":[{"start":{"line":25,"column":23},"end":{"line":25,"column":62}},{"start":{"line":26,"column":20},"end":{"line":26,"column":70}},{"start":{"line":27,"column":20},"end":{"line":27,"column":71}},{"start":{"line":28,"column":20},"end":{"line":28,"column":29}}]},"2":{"line":30,"type":"binary-expr","locations":[{"start":{"line":30,"column":23},"end":{"line":30,"column":37}},{"start":{"line":31,"column":20},"end":{"line":31,"column":61}},{"start":{"line":32,"column":20},"end":{"line":32,"column":70}},{"start":{"line":33,"column":20},"end":{"line":33,"column":26}}]},"3":{"line":37,"type":"cond-expr","locations":[{"start":{"line":38,"column":14},"end":{"line":38,"column":20}},{"start":{"line":39,"column":14},"end":{"line":39,"column":20}}]},"4":{"line":41,"type":"binary-expr","locations":[{"start":{"line":41,"column":16},"end":{"line":41,"column":44}},{"start":{"line":41,"column":48},"end":{"line":41,"column":53}}]},"5":{"line":45,"type":"if","locations":[{"start":{"line":45,"column":8},"end":{"line":45,"column":8}},{"start":{"line":45,"column":8},"end":{"line":45,"column":8}}]}},"code":["/* istanbul instrument in package npmdoc_debowerify */","/*jslint"," bitwise: true,"," browser: true,"," maxerr: 8,"," maxlen: 96,"," node: true,"," nomen: true,"," regexp: true,"," stupid: true","*/","(function () {"," 'use strict';"," var local;","","",""," // run shared js-env code - pre-init"," (function () {"," // init local"," local = {};"," // init modeJs"," local.modeJs = (function () {"," try {"," return typeof navigator.userAgent === 'string' &&"," typeof document.querySelector('body') === 'object' &&"," typeof XMLHttpRequest.prototype.open === 'function' &&"," 'browser';"," } catch (errorCaughtBrowser) {"," return module.exports &&"," typeof process.versions.node === 'string' &&"," typeof require('http').createServer === 'function' &&"," 'node';"," }"," }());"," // init global"," local.global = local.modeJs === 'browser'"," ? window"," : global;"," // init utility2_rollup"," local = local.global.utility2_rollup || local;"," // init lib"," local.local = local.npmdoc_debowerify = local;"," // init exports"," if (local.modeJs === 'browser') {"," local.global.utility2_npmdoc_debowerify = local;"," } else {"," module.exports = local;"," module.exports.__dirname = __dirname;"," module.exports.module = module;"," }"," }());","}());",""],"l":{"12":2,"14":2,"19":2,"21":2,"23":2,"24":2,"25":2,"30":1,"37":2,"41":2,"43":2,"45":2,"46":1,"48":1,"49":1,"50":1}},"/home/travis/build/npmdoc/node-npmdoc-debowerify/example.js":{"path":"/home/travis/build/npmdoc/node-npmdoc-debowerify/example.js","s":{"1":2,"2":2,"3":2,"4":2,"5":2,"6":2,"7":2,"8":1,"9":2,"10":2,"11":2,"12":2,"13":1,"14":2,"15":2,"16":2,"17":2,"18":2,"19":0,"20":2,"21":1,"22":1,"23":1,"24":1,"25":1,"26":0,"27":0,"28":1,"29":1,"30":2,"31":0,"32":0,"33":0,"34":1,"35":2,"36":2,"37":2,"38":2,"39":2,"40":2,"41":0,"42":2,"43":2,"44":2,"45":1,"46":3,"47":1,"48":1,"49":1,"50":1,"51":1,"52":1,"53":1,"54":1,"55":1,"56":1,"57":0,"58":1,"59":6,"60":6,"61":1,"62":2,"63":0,"64":2,"65":1,"66":1,"67":0,"68":0,"69":0,"70":0,"71":0,"72":0,"73":0,"74":0,"75":0,"76":0,"77":0,"78":0,"79":0,"80":0,"81":0,"82":0,"83":0},"b":{"1":[2,1,1,1],"2":[1,1,1,1],"3":[1,1],"4":[2,2],"5":[1,1],"6":[1,1],"7":[2,0],"8":[2,1,1,1,1,1],"9":[0,2,0],"10":[1,1],"11":[2,1,1],"12":[1,0],"13":[0,2],"14":[2,0,0,0,0,0,0],"15":[0,2],"16":[2,0],"17":[1,1],"18":[0,1],"19":[1,2,0,2],"20":[1,0],"21":[1,1],"22":[0,0],"23":[0,0],"24":[0,0],"25":[0,0],"26":[0,0],"27":[0,0],"28":[0,0]},"f":{"1":2,"2":2,"3":2,"4":2,"5":2,"6":2,"7":2,"8":2,"9":3,"10":1,"11":6,"12":0},"fnMap":{"1":{"name":"(anonymous_1)","line":26,"loc":{"start":{"line":26,"column":1},"end":{"line":26,"column":13}}},"2":{"name":"(anonymous_2)","line":33,"loc":{"start":{"line":33,"column":5},"end":{"line":33,"column":17}}},"3":{"name":"(anonymous_3)","line":37,"loc":{"start":{"line":37,"column":24},"end":{"line":37,"column":36}}},"4":{"name":"(anonymous_4)","line":69,"loc":{"start":{"line":69,"column":31},"end":{"line":69,"column":48}},"skip":true},"5":{"name":"(anonymous_5)","line":78,"loc":{"start":{"line":78,"column":26},"end":{"line":78,"column":45}},"skip":true},"6":{"name":"(anonymous_6)","line":123,"loc":{"start":{"line":123,"column":33},"end":{"line":123,"column":48}},"skip":true},"7":{"name":"(anonymous_7)","line":125,"loc":{"start":{"line":125,"column":27},"end":{"line":125,"column":39}},"skip":true},"8":{"name":"(anonymous_8)","line":133,"loc":{"start":{"line":133,"column":59},"end":{"line":133,"column":74}},"skip":true},"9":{"name":"(anonymous_9)","line":143,"loc":{"start":{"line":143,"column":45},"end":{"line":143,"column":62}},"skip":true},"10":{"name":"(anonymous_10)","line":144,"loc":{"start":{"line":144,"column":73},"end":{"line":144,"column":92}},"skip":true},"11":{"name":"(anonymous_11)","line":272,"loc":{"start":{"line":272,"column":51},"end":{"line":272,"column":77}},"skip":true},"12":{"name":"(anonymous_12)","line":314,"loc":{"start":{"line":314,"column":32},"end":{"line":314,"column":61}},"skip":true}},"statementMap":{"1":{"start":{"line":26,"column":0},"end":{"line":325,"column":5}},"2":{"start":{"line":28,"column":4},"end":{"line":28,"column":14}},"3":{"start":{"line":33,"column":4},"end":{"line":60,"column":9}},"4":{"start":{"line":35,"column":8},"end":{"line":35,"column":19}},"5":{"start":{"line":37,"column":8},"end":{"line":49,"column":13}},"6":{"start":{"line":38,"column":12},"end":{"line":48,"column":13}},"7":{"start":{"line":39,"column":16},"end":{"line":42,"column":30}},"8":{"start":{"line":44,"column":16},"end":{"line":47,"column":27}},"9":{"start":{"line":51,"column":8},"end":{"line":53,"column":21}},"10":{"start":{"line":55,"column":8},"end":{"line":57,"column":45}},"11":{"start":{"line":59,"column":8},"end":{"line":59,"column":35}},"12":{"start":{"line":61,"column":4},"end":{"line":324,"column":5}},"13":{"start":{"line":69,"column":8},"end":{"line":121,"column":10},"skip":true},"14":{"start":{"line":70,"column":12},"end":{"line":88,"column":13},"skip":true},"15":{"start":{"line":76,"column":16},"end":{"line":87,"column":19},"skip":true},"16":{"start":{"line":79,"column":20},"end":{"line":86,"column":21},"skip":true},"17":{"start":{"line":82,"column":24},"end":{"line":82,"column":43},"skip":true},"18":{"start":{"line":83,"column":24},"end":{"line":83,"column":30},"skip":true},"19":{"start":{"line":85,"column":24},"end":{"line":85,"column":49},"skip":true},"20":{"start":{"line":89,"column":12},"end":{"line":107,"column":13},"skip":true},"21":{"start":{"line":92,"column":16},"end":{"line":102,"column":17},"skip":true},"22":{"start":{"line":93,"column":20},"end":{"line":93,"column":86},"skip":true},"23":{"start":{"line":94,"column":20},"end":{"line":95,"column":45},"skip":true},"24":{"start":{"line":96,"column":20},"end":{"line":96,"column":42},"skip":true},"25":{"start":{"line":97,"column":20},"end":{"line":97,"column":48},"skip":true},"26":{"start":{"line":100,"column":20},"end":{"line":100,"column":85},"skip":true},"27":{"start":{"line":101,"column":20},"end":{"line":101,"column":96},"skip":true},"28":{"start":{"line":103,"column":16},"end":{"line":103,"column":22},"skip":true},"29":{"start":{"line":106,"column":16},"end":{"line":106,"column":22},"skip":true},"30":{"start":{"line":108,"column":12},"end":{"line":120,"column":13},"skip":true},"31":{"start":{"line":114,"column":16},"end":{"line":119,"column":17},"skip":true},"32":{"start":{"line":116,"column":20},"end":{"line":116,"column":78},"skip":true},"33":{"start":{"line":118,"column":20},"end":{"line":118,"column":53},"skip":true},"34":{"start":{"line":123,"column":8},"end":{"line":141,"column":11},"skip":true},"35":{"start":{"line":124,"column":12},"end":{"line":124,"column":54},"skip":true},"36":{"start":{"line":125,"column":12},"end":{"line":140,"column":14},"skip":true},"37":{"start":{"line":126,"column":16},"end":{"line":126,"column":28},"skip":true},"38":{"start":{"line":127,"column":16},"end":{"line":127,"column":69},"skip":true},"39":{"start":{"line":128,"column":16},"end":{"line":128,"column":75},"skip":true},"40":{"start":{"line":129,"column":16},"end":{"line":131,"column":17},"skip":true},"41":{"start":{"line":130,"column":20},"end":{"line":130,"column":27},"skip":true},"42":{"start":{"line":133,"column":16},"end":{"line":137,"column":36},"skip":true},"43":{"start":{"line":134,"column":20},"end":{"line":136,"column":55},"skip":true},"44":{"start":{"line":139,"column":16},"end":{"line":139,"column":57},"skip":true},"45":{"start":{"line":143,"column":8},"end":{"line":147,"column":11},"skip":true},"46":{"start":{"line":144,"column":12},"end":{"line":146,"column":15},"skip":true},"47":{"start":{"line":145,"column":16},"end":{"line":145,"column":70},"skip":true},"48":{"start":{"line":149,"column":8},"end":{"line":149,"column":31},"skip":true},"49":{"start":{"line":150,"column":8},"end":{"line":150,"column":14},"skip":true},"50":{"start":{"line":158,"column":8},"end":{"line":158,"column":31},"skip":true},"51":{"start":{"line":160,"column":8},"end":{"line":160,"column":33},"skip":true},"52":{"start":{"line":161,"column":8},"end":{"line":161,"column":37},"skip":true},"53":{"start":{"line":162,"column":8},"end":{"line":162,"column":35},"skip":true},"54":{"start":{"line":164,"column":8},"end":{"line":164,"column":50},"skip":true},"55":{"start":{"line":166,"column":8},"end":{"line":256,"column":2},"skip":true},"56":{"start":{"line":258,"column":8},"end":{"line":286,"column":9},"skip":true},"57":{"start":{"line":259,"column":12},"end":{"line":269,"column":14},"skip":true},"58":{"start":{"line":271,"column":12},"end":{"line":285,"column":19},"skip":true},"59":{"start":{"line":274,"column":20},"end":{"line":274,"column":35},"skip":true},"60":{"start":{"line":275,"column":20},"end":{"line":284,"column":21},"skip":true},"61":{"start":{"line":277,"column":24},"end":{"line":277,"column":48},"skip":true},"62":{"start":{"line":279,"column":24},"end":{"line":279,"column":41},"skip":true},"63":{"start":{"line":281,"column":24},"end":{"line":281,"column":41},"skip":true},"64":{"start":{"line":283,"column":24},"end":{"line":283,"column":39},"skip":true},"65":{"start":{"line":288,"column":8},"end":{"line":290,"column":9},"skip":true},"66":{"start":{"line":289,"column":12},"end":{"line":289,"column":18},"skip":true},"67":{"start":{"line":291,"column":8},"end":{"line":293,"column":54},"skip":true},"68":{"start":{"line":294,"column":8},"end":{"line":301,"column":37},"skip":true},"69":{"start":{"line":302,"column":8},"end":{"line":302,"column":82},"skip":true},"70":{"start":{"line":305,"column":8},"end":{"line":307,"column":9},"skip":true},"71":{"start":{"line":306,"column":12},"end":{"line":306,"column":82},"skip":true},"72":{"start":{"line":309,"column":8},"end":{"line":311,"column":9},"skip":true},"73":{"start":{"line":310,"column":12},"end":{"line":310,"column":18},"skip":true},"74":{"start":{"line":312,"column":8},"end":{"line":312,"column":54},"skip":true},"75":{"start":{"line":313,"column":8},"end":{"line":313,"column":69},"skip":true},"76":{"start":{"line":314,"column":8},"end":{"line":322,"column":36},"skip":true},"77":{"start":{"line":315,"column":12},"end":{"line":315,"column":61},"skip":true},"78":{"start":{"line":316,"column":12},"end":{"line":319,"column":13},"skip":true},"79":{"start":{"line":317,"column":16},"end":{"line":317,"column":75},"skip":true},"80":{"start":{"line":318,"column":16},"end":{"line":318,"column":23},"skip":true},"81":{"start":{"line":320,"column":12},"end":{"line":320,"column":38},"skip":true},"82":{"start":{"line":321,"column":12},"end":{"line":321,"column":27},"skip":true},"83":{"start":{"line":323,"column":8},"end":{"line":323,"column":14},"skip":true}},"branchMap":{"1":{"line":39,"type":"binary-expr","locations":[{"start":{"line":39,"column":23},"end":{"line":39,"column":62}},{"start":{"line":40,"column":20},"end":{"line":40,"column":70}},{"start":{"line":41,"column":20},"end":{"line":41,"column":71}},{"start":{"line":42,"column":20},"end":{"line":42,"column":29}}]},"2":{"line":44,"type":"binary-expr","locations":[{"start":{"line":44,"column":23},"end":{"line":44,"column":37}},{"start":{"line":45,"column":20},"end":{"line":45,"column":61}},{"start":{"line":46,"column":20},"end":{"line":46,"column":70}},{"start":{"line":47,"column":20},"end":{"line":47,"column":26}}]},"3":{"line":51,"type":"cond-expr","locations":[{"start":{"line":52,"column":14},"end":{"line":52,"column":20}},{"start":{"line":53,"column":14},"end":{"line":53,"column":20}}]},"4":{"line":55,"type":"binary-expr","locations":[{"start":{"line":55,"column":16},"end":{"line":55,"column":44}},{"start":{"line":55,"column":49},"end":{"line":57,"column":43}}]},"5":{"line":55,"type":"cond-expr","locations":[{"start":{"line":56,"column":14},"end":{"line":56,"column":53}},{"start":{"line":57,"column":14},"end":{"line":57,"column":43}}]},"6":{"line":61,"type":"switch","locations":[{"start":{"line":68,"column":4},"end":{"line":150,"column":14},"skip":true},{"start":{"line":156,"column":4},"end":{"line":323,"column":14},"skip":true}]},"7":{"line":70,"type":"if","locations":[{"start":{"line":70,"column":12},"end":{"line":70,"column":12},"skip":true},{"start":{"line":70,"column":12},"end":{"line":70,"column":12},"skip":true}]},"8":{"line":70,"type":"binary-expr","locations":[{"start":{"line":70,"column":16},"end":{"line":70,"column":22},"skip":true},{"start":{"line":70,"column":27},"end":{"line":70,"column":32},"skip":true},{"start":{"line":71,"column":20},"end":{"line":71,"column":39},"skip":true},{"start":{"line":72,"column":20},"end":{"line":72,"column":49},"skip":true},{"start":{"line":73,"column":20},"end":{"line":73,"column":58},"skip":true},{"start":{"line":74,"column":20},"end":{"line":74,"column":69},"skip":true}]},"9":{"line":79,"type":"switch","locations":[{"start":{"line":80,"column":20},"end":{"line":80,"column":33},"skip":true},{"start":{"line":81,"column":20},"end":{"line":83,"column":30},"skip":true},{"start":{"line":84,"column":20},"end":{"line":85,"column":49},"skip":true}]},"10":{"line":89,"type":"switch","locations":[{"start":{"line":90,"column":12},"end":{"line":103,"column":22},"skip":true},{"start":{"line":105,"column":12},"end":{"line":106,"column":22},"skip":true}]},"11":{"line":89,"type":"binary-expr","locations":[{"start":{"line":89,"column":20},"end":{"line":89,"column":25},"skip":true},{"start":{"line":89,"column":29},"end":{"line":89,"column":48},"skip":true},{"start":{"line":89,"column":52},"end":{"line":89,"column":74},"skip":true}]},"12":{"line":92,"type":"if","locations":[{"start":{"line":92,"column":16},"end":{"line":92,"column":16},"skip":true},{"start":{"line":92,"column":16},"end":{"line":92,"column":16},"skip":true}]},"13":{"line":108,"type":"if","locations":[{"start":{"line":108,"column":12},"end":{"line":108,"column":12},"skip":true},{"start":{"line":108,"column":12},"end":{"line":108,"column":12},"skip":true}]},"14":{"line":108,"type":"binary-expr","locations":[{"start":{"line":108,"column":16},"end":{"line":108,"column":61},"skip":true},{"start":{"line":108,"column":66},"end":{"line":108,"column":72},"skip":true},{"start":{"line":108,"column":77},"end":{"line":108,"column":82},"skip":true},{"start":{"line":109,"column":20},"end":{"line":109,"column":39},"skip":true},{"start":{"line":110,"column":20},"end":{"line":110,"column":49},"skip":true},{"start":{"line":111,"column":20},"end":{"line":111,"column":58},"skip":true},{"start":{"line":112,"column":20},"end":{"line":112,"column":68},"skip":true}]},"15":{"line":129,"type":"if","locations":[{"start":{"line":129,"column":16},"end":{"line":129,"column":16},"skip":true},{"start":{"line":129,"column":16},"end":{"line":129,"column":16},"skip":true}]},"16":{"line":134,"type":"cond-expr","locations":[{"start":{"line":135,"column":26},"end":{"line":135,"column":29},"skip":true},{"start":{"line":136,"column":26},"end":{"line":136,"column":54},"skip":true}]},"17":{"line":164,"type":"binary-expr","locations":[{"start":{"line":164,"column":27},"end":{"line":164,"column":43},"skip":true},{"start":{"line":164,"column":47},"end":{"line":164,"column":49},"skip":true}]},"18":{"line":258,"type":"if","locations":[{"start":{"line":258,"column":8},"end":{"line":258,"column":8},"skip":true},{"start":{"line":258,"column":8},"end":{"line":258,"column":8},"skip":true}]},"19":{"line":275,"type":"switch","locations":[{"start":{"line":276,"column":20},"end":{"line":277,"column":48},"skip":true},{"start":{"line":278,"column":20},"end":{"line":279,"column":41},"skip":true},{"start":{"line":280,"column":20},"end":{"line":281,"column":41},"skip":true},{"start":{"line":282,"column":20},"end":{"line":283,"column":39},"skip":true}]},"20":{"line":288,"type":"if","locations":[{"start":{"line":288,"column":8},"end":{"line":288,"column":8},"skip":true},{"start":{"line":288,"column":8},"end":{"line":288,"column":8},"skip":true}]},"21":{"line":288,"type":"binary-expr","locations":[{"start":{"line":288,"column":12},"end":{"line":288,"column":40},"skip":true},{"start":{"line":288,"column":44},"end":{"line":288,"column":67},"skip":true}]},"22":{"line":292,"type":"binary-expr","locations":[{"start":{"line":292,"column":12},"end":{"line":292,"column":50},"skip":true},{"start":{"line":293,"column":12},"end":{"line":293,"column":53},"skip":true}]},"23":{"line":295,"type":"binary-expr","locations":[{"start":{"line":295,"column":12},"end":{"line":295,"column":67},"skip":true},{"start":{"line":296,"column":12},"end":{"line":301,"column":36},"skip":true}]},"24":{"line":302,"type":"binary-expr","locations":[{"start":{"line":302,"column":43},"end":{"line":302,"column":75},"skip":true},{"start":{"line":302,"column":79},"end":{"line":302,"column":81},"skip":true}]},"25":{"line":305,"type":"if","locations":[{"start":{"line":305,"column":8},"end":{"line":305,"column":8},"skip":true},{"start":{"line":305,"column":8},"end":{"line":305,"column":8},"skip":true}]},"26":{"line":309,"type":"if","locations":[{"start":{"line":309,"column":8},"end":{"line":309,"column":8},"skip":true},{"start":{"line":309,"column":8},"end":{"line":309,"column":8},"skip":true}]},"27":{"line":312,"type":"binary-expr","locations":[{"start":{"line":312,"column":27},"end":{"line":312,"column":43},"skip":true},{"start":{"line":312,"column":47},"end":{"line":312,"column":53},"skip":true}]},"28":{"line":316,"type":"if","locations":[{"start":{"line":316,"column":12},"end":{"line":316,"column":12},"skip":true},{"start":{"line":316,"column":12},"end":{"line":316,"column":12},"skip":true}]}},"code":["/*","example.js","","quickstart example","","instruction"," 1. save this script as example.js"," 2. run the shell command:"," $ npm install npmdoc-debowerify && PORT=8081 node example.js"," 3. play with the browser-demo on http://127.0.0.1:8081","*/","","","","/* istanbul instrument in package npmdoc_debowerify */","/*jslint"," bitwise: true,"," browser: true,"," maxerr: 8,"," maxlen: 96,"," node: true,"," nomen: true,"," regexp: true,"," stupid: true","*/","(function () {"," 'use strict';"," var local;","","",""," // run shared js-env code - pre-init"," (function () {"," // init local"," local = {};"," // init modeJs"," local.modeJs = (function () {"," try {"," return typeof navigator.userAgent === 'string' &&"," typeof document.querySelector('body') === 'object' &&"," typeof XMLHttpRequest.prototype.open === 'function' &&"," 'browser';"," } catch (errorCaughtBrowser) {"," return module.exports &&"," typeof process.versions.node === 'string' &&"," typeof require('http').createServer === 'function' &&"," 'node';"," }"," }());"," // init global"," local.global = local.modeJs === 'browser'"," ? window"," : global;"," // init utility2_rollup"," local = local.global.utility2_rollup || (local.modeJs === 'browser'"," ? local.global.utility2_npmdoc_debowerify"," : global.utility2_moduleExports);"," // export local"," local.global.local = local;"," }());"," switch (local.modeJs) {","","",""," // post-init"," // run browser js-env code - post-init"," /* istanbul ignore next */"," case 'browser':"," local.testRunBrowser = function (event) {"," if (!event || (event &&"," event.currentTarget &&"," event.currentTarget.className &&"," event.currentTarget.className.includes &&"," event.currentTarget.className.includes('onreset'))) {"," // reset output"," Array.from("," document.querySelectorAll('body > .resettable')"," ).forEach(function (element) {"," switch (element.tagName) {"," case 'INPUT':"," case 'TEXTAREA':"," element.value = '';"," break;"," default:"," element.textContent = '';"," }"," });"," }"," switch (event && event.currentTarget && event.currentTarget.id) {"," case 'testRunButton1':"," // show tests"," if (document.querySelector('#testReportDiv1').style.display === 'none') {"," document.querySelector('#testReportDiv1').style.display = 'block';"," document.querySelector('#testRunButton1').textContent ="," 'hide internal test';"," local.modeTest = true;"," local.testRunDefault(local);"," // hide tests"," } else {"," document.querySelector('#testReportDiv1').style.display = 'none';"," document.querySelector('#testRunButton1').textContent = 'run internal test';"," }"," break;"," // custom-case"," default:"," break;"," }"," if (document.querySelector('#inputTextareaEval1') && (!event || (event &&"," event.currentTarget &&"," event.currentTarget.className &&"," event.currentTarget.className.includes &&"," event.currentTarget.className.includes('oneval')))) {"," // try to eval input-code"," try {"," /*jslint evil: true*/"," eval(document.querySelector('#inputTextareaEval1').value);"," } catch (errorCaught) {"," console.error(errorCaught.stack);"," }"," }"," };"," // log stderr and stdout to #outputTextareaStdout1"," ['error', 'log'].forEach(function (key) {"," console[key + '_original'] = console[key];"," console[key] = function () {"," var element;"," console[key + '_original'].apply(console, arguments);"," element = document.querySelector('#outputTextareaStdout1');"," if (!element) {"," return;"," }"," // append text to #outputTextareaStdout1"," element.value += Array.from(arguments).map(function (arg) {"," return typeof arg === 'string'"," ? arg"," : JSON.stringify(arg, null, 4);"," }).join(' ') + '\\n';"," // scroll textarea to bottom"," element.scrollTop = element.scrollHeight;"," };"," });"," // init event-handling"," ['change', 'click', 'keyup'].forEach(function (event) {"," Array.from(document.querySelectorAll('.on' + event)).forEach(function (element) {"," element.addEventListener(event, local.testRunBrowser);"," });"," });"," // run tests"," local.testRunBrowser();"," break;","","",""," // run node js-env code - post-init"," /* istanbul ignore next */"," case 'node':"," // export local"," module.exports = local;"," // require modules"," local.fs = require('fs');"," local.http = require('http');"," local.url = require('url');"," // init assets"," local.assetsDict = local.assetsDict || {};"," /* jslint-ignore-begin */"," local.assetsDict['/assets.index.template.html'] = '\\","\\n\\","\\n\\","\\n\\","\\n\\","\\n\\","{{env.npm_package_name}} (v{{env.npm_package_version}})\\n\\","\\n\\","\\n\\","\\n\\","\\n\\","\\n\\","

\\n\\","\\n\\"," {{env.npm_package_name}} (v{{env.npm_package_version}})\\n\\","\\n\\","

\\n\\","

{{env.npm_package_description}}

\\n\\","\\n\\","\\n\\","\\n\\","\\n\\","\\n\\","\\n\\","\\n\\","\\n\\","\\n\\","\\n\\","\\n\\","\\n\\","\\n\\","
\\n\\"," [ this app was created with\\n\\"," utility2\\n\\"," ]\\n\\","
\\n\\","\\n\\","\\n\\","';"," /* jslint-ignore-end */"," if (local.templateRender) {"," local.assetsDict['/'] = local.templateRender("," local.assetsDict['/assets.index.template.html'],"," {"," env: local.objectSetDefault(local.env, {"," npm_package_description: 'example module',"," npm_package_name: 'example',"," npm_package_nameAlias: 'example',"," npm_package_version: '0.0.1'"," })"," }"," );"," } else {"," local.assetsDict['/'] = local.assetsDict['/assets.index.template.html']"," .replace((/\\{\\{env\\.(\\w+?)\\}\\}/g), function (match0, match1) {"," // jslint-hack"," String(match0);"," switch (match1) {"," case 'npm_package_description':"," return 'example module';"," case 'npm_package_name':"," return 'example';"," case 'npm_package_nameAlias':"," return 'example';"," case 'npm_package_version':"," return '0.0.1';"," }"," });"," }"," // run the cli"," if (local.global.utility2_rollup || module !== require.main) {"," break;"," }"," local.assetsDict['/assets.example.js'] ="," local.assetsDict['/assets.example.js'] ||"," local.fs.readFileSync(__filename, 'utf8');"," local.assetsDict['/assets.npmdoc_debowerify.rollup.js'] ="," local.assetsDict['/assets.npmdoc_debowerify.rollup.js'] ||"," local.fs.readFileSync("," // npmdoc-hack"," local.npmdoc_debowerify.__dirname +"," '/lib.npmdoc_debowerify.js',"," 'utf8'"," ).replace((/^#!/), '//');"," local.assetsDict['/favicon.ico'] = local.assetsDict['/favicon.ico'] || '';"," // if $npm_config_timeout_exit exists,"," // then exit this process after $npm_config_timeout_exit ms"," if (Number(process.env.npm_config_timeout_exit)) {"," setTimeout(process.exit, Number(process.env.npm_config_timeout_exit));"," }"," // start server"," if (local.global.utility2_serverHttp1) {"," break;"," }"," process.env.PORT = process.env.PORT || '8081';"," console.error('server starting on port ' + process.env.PORT);"," local.http.createServer(function (request, response) {"," request.urlParsed = local.url.parse(request.url);"," if (local.assetsDict[request.urlParsed.pathname] !== undefined) {"," response.end(local.assetsDict[request.urlParsed.pathname]);"," return;"," }"," response.statusCode = 404;"," response.end();"," }).listen(process.env.PORT);"," break;"," }","}());",""],"l":{"26":2,"28":2,"33":2,"35":2,"37":2,"38":2,"39":2,"44":1,"51":2,"55":2,"59":2,"61":2,"69":1,"70":2,"76":2,"79":2,"82":2,"83":2,"85":1,"89":2,"92":1,"93":1,"94":1,"96":1,"97":1,"100":1,"101":1,"103":1,"106":1,"108":2,"114":1,"116":1,"118":1,"123":1,"124":2,"125":2,"126":2,"127":2,"128":2,"129":2,"130":1,"133":2,"134":2,"139":2,"143":1,"144":3,"145":1,"149":1,"150":1,"158":1,"160":1,"161":1,"162":1,"164":1,"166":1,"258":1,"259":1,"271":1,"274":6,"275":6,"277":1,"279":2,"281":1,"283":2,"288":1,"289":1,"291":1,"294":1,"302":1,"305":1,"306":1,"309":1,"310":1,"312":1,"313":1,"314":1,"315":1,"316":1,"317":1,"318":1,"320":1,"321":1,"323":1}}} \ No newline at end of file diff --git a/build/coverage.html/coverage.rollup.html b/build/coverage.html/coverage.rollup.html new file mode 100644 index 0000000..c13cda7 --- /dev/null +++ b/build/coverage.html/coverage.rollup.html @@ -0,0 +1,2911 @@ +
+

coverage-report

+
+ + + + + + Code coverage report for All files + + + + +
+

+ npmdoc-debowerify (v0.0.1) +

+

Code coverage report for All files

+

+ + Statements: 100% (153 / 153)      + + + Branches: 100% (126 / 126)      + + + Functions: 100% (26 / 26)      + + + Lines: 100% (153 / 153)      + + Ignored: 29 statements, 1 function, 32 branches      +

+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FileStatementsBranchesFunctionsLines
node-npmdoc-debowerify/100%(153 / 153)100%(126 / 126)100%(26 / 26)100%(153 / 153)
+
+ + + + + + + + + Code coverage report for node-npmdoc-debowerify/ + + + + +
+

+ npmdoc-debowerify (v0.0.1) +

+

Code coverage report for node-npmdoc-debowerify/

+

+ + Statements: 100% (153 / 153)      + + + Branches: 100% (126 / 126)      + + + Functions: 100% (26 / 26)      + + + Lines: 100% (153 / 153)      + + Ignored: 29 statements, 1 function, 32 branches      +

+
All files » node-npmdoc-debowerify/
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FileStatementsBranchesFunctionsLines
example.js100%(83 / 83)100%(73 / 73)100%(12 / 12)100%(83 / 83)
lib.npmdoc_debowerify.js100%(16 / 16)100%(14 / 14)100%(3 / 3)100%(16 / 16)
test.js100%(54 / 54)100%(39 / 39)100%(11 / 11)100%(54 / 54)
+
+ + + + + + + + + Code coverage report for node-npmdoc-debowerify/example.js + + + + +
+

+ npmdoc-debowerify (v0.0.1) +

+

Code coverage report for node-npmdoc-debowerify/example.js

+

+ + Statements: 100% (83 / 83)      + + + Branches: 100% (73 / 73)      + + + Functions: 100% (12 / 12)      + + + Lines: 100% (83 / 83)      + + Ignored: 26 statements, 1 function, 30 branches      +

+ +
+
+

+
+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196 +197 +198 +199 +200 +201 +202 +203 +204 +205 +206 +207 +208 +209 +210 +211 +212 +213 +214 +215 +216 +217 +218 +219 +220 +221 +222 +223 +224 +225 +226 +227 +228 +229 +230 +231 +232 +233 +234 +235 +236 +237 +238 +239 +240 +241 +242 +243 +244 +245 +246 +247 +248 +249 +250 +251 +252 +253 +254 +255 +256 +257 +258 +259 +260 +261 +262 +263 +264 +265 +266 +267 +268 +269 +270 +271 +272 +273 +274 +275 +276 +277 +278 +279 +280 +281 +282 +283 +284 +285 +286 +287 +288 +289 +290 +291 +292 +293 +294 +295 +296 +297 +298 +299 +300 +301 +302 +303 +304 +305 +306 +307 +308 +309 +310 +311 +312 +313 +314 +315 +316 +317 +318 +319 +320 +321 +322 +323 +324 +325 +326 +327  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +2 +  +2 +  +  +  +  +2 +  +2 +  +2 +2 +2 +  +  +  +  +1 +  +  +  +  +  +  +2 +  +  +  +2 +  +  +  +2 +  +2 +  +  +  +  +  +  +  +1 +2 +  +  +  +  +  +2 +  +  +2 +  +  +2 +2 +  +1 +  +  +  +2 +  +  +1 +1 +1 +  +1 +1 +  +  +1 +1 +  +1 +  +  +1 +  +2 +  +  +  +  +  +1 +  +1 +  +1 +  +  +  +  +1 +2 +2 +2 +2 +2 +2 +1 +  +  +2 +2 +  +  +  +  +2 +  +  +  +1 +3 +1 +  +  +  +1 +1 +  +  +  +  +  +  +  +1 +  +1 +1 +1 +  +1 +  +1 +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1 +1 +  +  +  +  +  +  +  +  +  +  +  +1 +  +  +6 +6 +  +1 +  +2 +  +1 +  +2 +  +  +  +  +1 +1 +  +1 +  +  +1 +  +  +  +  +  +  +  +1 +  +  +1 +1 +  +  +1 +1 +  +1 +1 +1 +1 +1 +1 +1 +  +1 +1 +  +1 +  +  +  + 
/*
+example.js
+ 
+quickstart example
+ 
+instruction
+    1. save this script as example.js
+    2. run the shell command:
+        $ npm install npmdoc-debowerify && PORT=8081 node example.js
+    3. play with the browser-demo on http://127.0.0.1:8081
+*/
+ 
+ 
+ 
+/* istanbul instrument in package npmdoc_debowerify */
+/*jslint
+    bitwise: true,
+    browser: true,
+    maxerr: 8,
+    maxlen: 96,
+    node: true,
+    nomen: true,
+    regexp: true,
+    stupid: true
+*/
+(function () {
+    'use strict';
+    var local;
+ 
+ 
+ 
+    // run shared js-env code - pre-init
+    (function () {
+        // init local
+        local = {};
+        // init modeJs
+        local.modeJs = (function () {
+            try {
+                return typeof navigator.userAgent === 'string' &&
+                    typeof document.querySelector('body') === 'object' &&
+                    typeof XMLHttpRequest.prototype.open === 'function' &&
+                    'browser';
+            } catch (errorCaughtBrowser) {
+                return module.exports &&
+                    typeof process.versions.node === 'string' &&
+                    typeof require('http').createServer === 'function' &&
+                    'node';
+            }
+        }());
+        // init global
+        local.global = local.modeJs === 'browser'
+            ? window
+            : global;
+        // init utility2_rollup
+        local = local.global.utility2_rollup || (local.modeJs === 'browser'
+            ? local.global.utility2_npmdoc_debowerify
+            : global.utility2_moduleExports);
+        // export local
+        local.global.local = local;
+    }());
+    switch (local.modeJs) {
+ 
+ 
+ 
+    // post-init
+    // run browser js-env code - post-init
+    /* istanbul ignore next */
+    case 'browser':
+        local.testRunBrowser = function (event) {
+            Eif (!event || (event &&
+                    event.currentTarget &&
+                    event.currentTarget.className &&
+                    event.currentTarget.className.includes &&
+                    event.currentTarget.className.includes('onreset'))) {
+                // reset output
+                Array.from(
+                    document.querySelectorAll('body > .resettable')
+                ).forEach(function (element) {
+                    switch (element.tagName) {
+                    case 'INPUT':
+                    case 'TEXTAREA':
+                        element.value = '';
+                        break;
+                    default:
+                        element.textContent = '';
+                    }
+                });
+            }
+            switch (event && event.currentTarget && event.currentTarget.id) {
+            case 'testRunButton1':
+                // show tests
+                Eif (document.querySelector('#testReportDiv1').style.display === 'none') {
+                    document.querySelector('#testReportDiv1').style.display = 'block';
+                    document.querySelector('#testRunButton1').textContent =
+                        'hide internal test';
+                    local.modeTest = true;
+                    local.testRunDefault(local);
+                // hide tests
+                } else {
+                    document.querySelector('#testReportDiv1').style.display = 'none';
+                    document.querySelector('#testRunButton1').textContent = 'run internal test';
+                }
+                break;
+            // custom-case
+            default:
+                break;
+            }
+            Iif (document.querySelector('#inputTextareaEval1') && (!event || (event &&
+                    event.currentTarget &&
+                    event.currentTarget.className &&
+                    event.currentTarget.className.includes &&
+                    event.currentTarget.className.includes('oneval')))) {
+                // try to eval input-code
+                try {
+                    /*jslint evil: true*/
+                    eval(document.querySelector('#inputTextareaEval1').value);
+                } catch (errorCaught) {
+                    console.error(errorCaught.stack);
+                }
+            }
+        };
+        // log stderr and stdout to #outputTextareaStdout1
+        ['error', 'log'].forEach(function (key) {
+            console[key + '_original'] = console[key];
+            console[key] = function () {
+                var element;
+                console[key + '_original'].apply(console, arguments);
+                element = document.querySelector('#outputTextareaStdout1');
+                Iif (!element) {
+                    return;
+                }
+                // append text to #outputTextareaStdout1
+                element.value += Array.from(arguments).map(function (arg) {
+                    return typeof arg === 'string'
+                        ? arg
+                        : JSON.stringify(arg, null, 4);
+                }).join(' ') + '\n';
+                // scroll textarea to bottom
+                element.scrollTop = element.scrollHeight;
+            };
+        });
+        // init event-handling
+        ['change', 'click', 'keyup'].forEach(function (event) {
+            Array.from(document.querySelectorAll('.on' + event)).forEach(function (element) {
+                element.addEventListener(event, local.testRunBrowser);
+            });
+        });
+        // run tests
+        local.testRunBrowser();
+        break;
+ 
+ 
+ 
+    // run node js-env code - post-init
+    /* istanbul ignore next */
+    case 'node':
+        // export local
+        module.exports = local;
+        // require modules
+        local.fs = require('fs');
+        local.http = require('http');
+        local.url = require('url');
+        // init assets
+        local.assetsDict = local.assetsDict || {};
+        /* jslint-ignore-begin */
+        local.assetsDict['/assets.index.template.html'] = '\
+<!doctype html>\n\
+<html lang="en">\n\
+<head>\n\
+<meta charset="UTF-8">\n\
+<meta name="viewport" content="width=device-width, initial-scale=1">\n\
+<title>{{env.npm_package_name}} (v{{env.npm_package_version}})</title>\n\
+<style>\n\
+/*csslint\n\
+    box-sizing: false,\n\
+    universal-selector: false\n\
+*/\n\
+* {\n\
+    box-sizing: border-box;\n\
+}\n\
+body {\n\
+    background: #dde;\n\
+    font-family: Arial, Helvetica, sans-serif;\n\
+    margin: 2rem;\n\
+}\n\
+body > * {\n\
+    margin-bottom: 1rem;\n\
+}\n\
+.utility2FooterDiv {\n\
+    margin-top: 20px;\n\
+    text-align: center;\n\
+}\n\
+</style>\n\
+<style>\n\
+/*csslint\n\
+*/\n\
+textarea {\n\
+    font-family: monospace;\n\
+    height: 10rem;\n\
+    width: 100%;\n\
+}\n\
+textarea[readonly] {\n\
+    background: #ddd;\n\
+}\n\
+</style>\n\
+</head>\n\
+<body>\n\
+<!-- utility2-comment\n\
+<div id="ajaxProgressDiv1" style="background: #d00; height: 2px; left: 0; margin: 0; padding: 0; position: fixed; top: 0; transition: background 0.5s, width 1.5s; width: 25%;"></div>\n\
+utility2-comment -->\n\
+<h1>\n\
+<!-- utility2-comment\n\
+    <a\n\
+        {{#if env.npm_package_homepage}}\n\
+        href="http://github.com/%7B%7Benv.npm_package_homepage%7D%7D"\n\
+        {{/if env.npm_package_homepage}}\n\
+        target="_blank"\n\
+    >\n\
+utility2-comment -->\n\
+        {{env.npm_package_name}} (v{{env.npm_package_version}})\n\
+<!-- utility2-comment\n\
+    </a>\n\
+utility2-comment -->\n\
+</h1>\n\
+<h3>{{env.npm_package_description}}</h3>\n\
+<!-- utility2-comment\n\
+<h4><a download href="http://github.com/assets.app.js">download standalone app</a></h4>\n\
+<button class="onclick onreset" id="testRunButton1">run internal test</button><br>\n\
+<div id="testReportDiv1" style="display: none;"></div>\n\
+utility2-comment -->\n\
+\n\
+\n\
+\n\
+<label>stderr and stdout</label>\n\
+<textarea class="resettable" id="outputTextareaStdout1" readonly></textarea>\n\
+<!-- utility2-comment\n\
+{{#if isRollup}}\n\
+<script src="http://github.com/assets.app.js"></script>\n\
+{{#unless isRollup}}\n\
+utility2-comment -->\n\
+<script src="http://github.com/assets.utility2.rollup.js"></script>\n\
+<script src="http://github.com/jsonp.utility2._stateInit?callback=window.utility2._stateInit"></script>\n\
+<script src="http://github.com/assets.npmdoc_debowerify.rollup.js"></script>\n\
+<script src="http://github.com/assets.example.js"></script>\n\
+<script src="http://github.com/assets.test.js"></script>\n\
+<!-- utility2-comment\n\
+{{/if isRollup}}\n\
+utility2-comment -->\n\
+<div class="utility2FooterDiv">\n\
+    [ this app was created with\n\
+    <a href="https://github.com/kaizhu256/node-utility2" target="_blank">utility2</a>\n\
+    ]\n\
+</div>\n\
+</body>\n\
+</html>\n\
+';
+        /* jslint-ignore-end */
+        Iif (local.templateRender) {
+            local.assetsDict['/'] = local.templateRender(
+                local.assetsDict['/assets.index.template.html'],
+                {
+                    env: local.objectSetDefault(local.env, {
+                        npm_package_description: 'example module',
+                        npm_package_name: 'example',
+                        npm_package_nameAlias: 'example',
+                        npm_package_version: '0.0.1'
+                    })
+                }
+            );
+        } else {
+            local.assetsDict['/'] = local.assetsDict['/assets.index.template.html']
+                .replace((/\{\{env\.(\w+?)\}\}/g), function (match0, match1) {
+                    // jslint-hack
+                    String(match0);
+                    switch (match1) {
+                    case 'npm_package_description':
+                        return 'example module';
+                    case 'npm_package_name':
+                        return 'example';
+                    case 'npm_package_nameAlias':
+                        return 'example';
+                    case 'npm_package_version':
+                        return '0.0.1';
+                    }
+                });
+        }
+        // run the cli
+        Eif (local.global.utility2_rollup || module !== require.main) {
+            break;
+        }
+        local.assetsDict['/assets.example.js'] =
+            local.assetsDict['/assets.example.js'] ||
+            local.fs.readFileSync(__filename, 'utf8');
+        local.assetsDict['/assets.npmdoc_debowerify.rollup.js'] =
+            local.assetsDict['/assets.npmdoc_debowerify.rollup.js'] ||
+            local.fs.readFileSync(
+                // npmdoc-hack
+                local.npmdoc_debowerify.__dirname +
+                    '/lib.npmdoc_debowerify.js',
+                'utf8'
+            ).replace((/^#!/), '//');
+        local.assetsDict['/favicon.ico'] = local.assetsDict['/favicon.ico'] || '';
+        // if $npm_config_timeout_exit exists,
+        // then exit this process after $npm_config_timeout_exit ms
+        if (Number(process.env.npm_config_timeout_exit)) {
+            setTimeout(process.exit, Number(process.env.npm_config_timeout_exit));
+        }
+        // start server
+        if (local.global.utility2_serverHttp1) {
+            break;
+        }
+        process.env.PORT = process.env.PORT || '8081';
+        console.error('server starting on port ' + process.env.PORT);
+        local.http.createServer(function (request, response) {
+            request.urlParsed = local.url.parse(request.url);
+            if (local.assetsDict[request.urlParsed.pathname] !== undefined) {
+                response.end(local.assetsDict[request.urlParsed.pathname]);
+                return;
+            }
+            response.statusCode = 404;
+            response.end();
+        }).listen(process.env.PORT);
+        break;
+    }
+}());
+ 
+ 
+
+ + + + + + + + + Code coverage report for node-npmdoc-debowerify/lib.npmdoc_debowerify.js + + + + +
+

+ npmdoc-debowerify (v0.0.1) +

+

Code coverage report for node-npmdoc-debowerify/lib.npmdoc_debowerify.js

+

+ + Statements: 100% (16 / 16)      + + + Branches: 100% (14 / 14)      + + + Functions: 100% (3 / 3)      + + + Lines: 100% (16 / 16)      + + Ignored: none      +

+
All files » node-npmdoc-debowerify/ » lib.npmdoc_debowerify.js
+
+
+

+
+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55  +  +  +  +  +  +  +  +  +  +  +2 +  +2 +  +  +  +  +2 +  +2 +  +2 +2 +2 +  +  +  +  +1 +  +  +  +  +  +  +2 +  +  +  +2 +  +2 +  +2 +1 +  +1 +1 +1 +  +  +  +  + 
/* istanbul instrument in package npmdoc_debowerify */
+/*jslint
+    bitwise: true,
+    browser: true,
+    maxerr: 8,
+    maxlen: 96,
+    node: true,
+    nomen: true,
+    regexp: true,
+    stupid: true
+*/
+(function () {
+    'use strict';
+    var local;
+ 
+ 
+ 
+    // run shared js-env code - pre-init
+    (function () {
+        // init local
+        local = {};
+        // init modeJs
+        local.modeJs = (function () {
+            try {
+                return typeof navigator.userAgent === 'string' &&
+                    typeof document.querySelector('body') === 'object' &&
+                    typeof XMLHttpRequest.prototype.open === 'function' &&
+                    'browser';
+            } catch (errorCaughtBrowser) {
+                return module.exports &&
+                    typeof process.versions.node === 'string' &&
+                    typeof require('http').createServer === 'function' &&
+                    'node';
+            }
+        }());
+        // init global
+        local.global = local.modeJs === 'browser'
+            ? window
+            : global;
+        // init utility2_rollup
+        local = local.global.utility2_rollup || local;
+        // init lib
+        local.local = local.npmdoc_debowerify = local;
+        // init exports
+        if (local.modeJs === 'browser') {
+            local.global.utility2_npmdoc_debowerify = local;
+        } else {
+            module.exports = local;
+            module.exports.__dirname = __dirname;
+            module.exports.module = module;
+        }
+    }());
+}());
+ 
+ 
+
+ + + + + + + + + Code coverage report for node-npmdoc-debowerify/test.js + + + + +
+

+ npmdoc-debowerify (v0.0.1) +

+

Code coverage report for node-npmdoc-debowerify/test.js

+

+ + Statements: 100% (54 / 54)      + + + Branches: 100% (39 / 39)      + + + Functions: 100% (11 / 11)      + + + Lines: 100% (54 / 54)      + + Ignored: 3 statements, 2 branches      +

+ +
+
+

+
+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185  +  +  +  +  +  +  +  +  +  +  +2 +  +2 +  +  +  +  +2 +  +2 +  +2 +2 +2 +  +  +  +  +1 +  +  +  +  +  +  +2 +  +  +2 +  +  +1 +  +  +  +1 +  +  +1 +  +1 +  +  +2 +  +  +  +  +  +2 +2 +  +2 +  +  +  +  +  +1 +  +  +  +  +  +1 +  +  +  +  +  +2 +2 +  +2 +  +  +  +  +  +  +1 +  +  +1 +  +  +  +  +  +  +1 +  +  +  +  +  +  +1 +1 +1 +1 +  +1 +  +  +1 +  +  +  +  +  +  +1 +1 +1 +1 +1 +  +  +1 +  +  +  +  +  +  +2 +2 +  +  +1 +  +  +  +  +  +  +2 +2 +2 +  +1 +1 +  +  +1 +  +  +  +  +  +  +2 +2 +  +  +1 +  +  +  +  +  +  +1 +1 +  +  +  +1 +1 +  +  +  + 
/* istanbul instrument in package npmdoc_debowerify */
+/*jslint
+    bitwise: true,
+    browser: true,
+    maxerr: 8,
+    maxlen: 96,
+    node: true,
+    nomen: true,
+    regexp: true,
+    stupid: true
+*/
+(function () {
+    'use strict';
+    var local;
+ 
+ 
+ 
+    // run shared js-env code - pre-init
+    (function () {
+        // init local
+        local = {};
+        // init modeJs
+        local.modeJs = (function () {
+            try {
+                return typeof navigator.userAgent === 'string' &&
+                    typeof document.querySelector('body') === 'object' &&
+                    typeof XMLHttpRequest.prototype.open === 'function' &&
+                    'browser';
+            } catch (errorCaughtBrowser) {
+                return module.exports &&
+                    typeof process.versions.node === 'string' &&
+                    typeof require('http').createServer === 'function' &&
+                    'node';
+            }
+        }());
+        // init global
+        local.global = local.modeJs === 'browser'
+            ? window
+            : global;
+        switch (local.modeJs) {
+        // re-init local from window.local
+        case 'browser':
+            local = local.global.utility2.objectSetDefault(
+                local.global.utility2_rollup || local.global.local,
+                local.global.utility2
+            );
+            break;
+        // re-init local from example.js
+        case 'node':
+            local = (local.global.utility2_rollup || require('utility2'))
+                .requireExampleJsFromReadme();
+            break;
+        }
+        // export local
+        local.global.local = local;
+    }());
+ 
+ 
+ 
+    // run shared js-env code - function
+    (function () {
+        return;
+    }());
+    switch (local.modeJs) {
+ 
+ 
+ 
+    // run browser js-env code - function
+    case 'browser':
+        break;
+ 
+ 
+ 
+    // run node js-env code - function
+    case 'node':
+        break;
+    }
+ 
+ 
+ 
+    // run shared js-env code - post-init
+    (function () {
+        return;
+    }());
+    switch (local.modeJs) {
+ 
+ 
+ 
+    // run browser js-env code - post-init
+    case 'browser':
+        // run tests
+        local.nop(local.modeTest &&
+            document.querySelector('#testRunButton1') &&
+            document.querySelector('#testRunButton1').click());
+        break;
+ 
+ 
+ 
+    // run node js-env code - post-init
+    /* istanbul ignore next */
+    case 'node':
+        local.testCase_buildApidoc_default = local.testCase_buildApidoc_default || function (
+            options,
+            onError
+        ) {
+        /*
+         * this function will test buildApidoc's default handling-behavior-behavior
+         */
+            options = { modulePathList: module.paths };
+            Eif (local.env.npm_package_buildNpmdoc) {
+                local.buildNpmdoc(options, onError);
+                return;
+            }
+            local.buildApidoc(options, onError);
+        };
+ 
+        local.testCase_buildApp_default = local.testCase_buildApp_default || function (
+            options,
+            onError
+        ) {
+        /*
+         * this function will test buildApp's default handling-behavior-behavior
+         */
+            local.testCase_buildReadme_default(options, local.onErrorThrow);
+            local.testCase_buildLib_default(options, local.onErrorThrow);
+            local.testCase_buildTest_default(options, local.onErrorThrow);
+            options = [];
+            local.buildApp(options, onError);
+        };
+ 
+        local.testCase_buildLib_default = local.testCase_buildLib_default || function (
+            options,
+            onError
+        ) {
+        /*
+         * this function will test buildLib's default handling-behavior
+         */
+            options = {};
+            local.buildLib(options, onError);
+        };
+ 
+        local.testCase_buildReadme_default = local.testCase_buildReadme_default || function (
+            options,
+            onError
+        ) {
+        /*
+         * this function will test buildReadme's default handling-behavior-behavior
+         */
+            Eif (local.env.npm_package_buildNpmdoc) {
+                onError();
+                return;
+            }
+            options = {};
+            local.buildReadme(options, onError);
+        };
+ 
+        local.testCase_buildTest_default = local.testCase_buildTest_default || function (
+            options,
+            onError
+        ) {
+        /*
+         * this function will test buildTest's default handling-behavior
+         */
+            options = {};
+            local.buildTest(options, onError);
+        };
+ 
+        local.testCase_webpage_default = local.testCase_webpage_default || function (
+            options,
+            onError
+        ) {
+        /*
+         * this function will test webpage's default handling-behavior
+         */
+            options = { modeCoverageMerge: true, url: local.serverLocalHost + '?modeTest=1' };
+            local.browserTest(options, onError);
+        };
+ 
+        // run test-server
+        local.testRunServer(local);
+        break;
+    }
+}());
+ 
+ 
+
+ + + + + +
+
diff --git a/build/coverage.html/index.html b/build/coverage.html/index.html new file mode 100644 index 0000000..5cf120b --- /dev/null +++ b/build/coverage.html/index.html @@ -0,0 +1,252 @@ + + + + Code coverage report for All files + + + + +
+

+ npmdoc-debowerify (v0.0.1) +

+

Code coverage report for All files

+

+ + Statements: 100% (153 / 153)      + + + Branches: 100% (126 / 126)      + + + Functions: 100% (26 / 26)      + + + Lines: 100% (153 / 153)      + + Ignored: 29 statements, 1 function, 32 branches      +

+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FileStatementsBranchesFunctionsLines
node-npmdoc-debowerify/100%(153 / 153)100%(126 / 126)100%(26 / 26)100%(153 / 153)
+
+ + + diff --git a/build/coverage.html/node-npmdoc-debowerify/example.js.html b/build/coverage.html/node-npmdoc-debowerify/example.js.html new file mode 100644 index 0000000..9c6c577 --- /dev/null +++ b/build/coverage.html/node-npmdoc-debowerify/example.js.html @@ -0,0 +1,1202 @@ + + + + Code coverage report for node-npmdoc-debowerify/example.js + + + + +
+

+ npmdoc-debowerify (v0.0.1) +

+

Code coverage report for node-npmdoc-debowerify/example.js

+

+ + Statements: 100% (83 / 83)      + + + Branches: 100% (73 / 73)      + + + Functions: 100% (12 / 12)      + + + Lines: 100% (83 / 83)      + + Ignored: 26 statements, 1 function, 30 branches      +

+ +
+
+

+
+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185 +186 +187 +188 +189 +190 +191 +192 +193 +194 +195 +196 +197 +198 +199 +200 +201 +202 +203 +204 +205 +206 +207 +208 +209 +210 +211 +212 +213 +214 +215 +216 +217 +218 +219 +220 +221 +222 +223 +224 +225 +226 +227 +228 +229 +230 +231 +232 +233 +234 +235 +236 +237 +238 +239 +240 +241 +242 +243 +244 +245 +246 +247 +248 +249 +250 +251 +252 +253 +254 +255 +256 +257 +258 +259 +260 +261 +262 +263 +264 +265 +266 +267 +268 +269 +270 +271 +272 +273 +274 +275 +276 +277 +278 +279 +280 +281 +282 +283 +284 +285 +286 +287 +288 +289 +290 +291 +292 +293 +294 +295 +296 +297 +298 +299 +300 +301 +302 +303 +304 +305 +306 +307 +308 +309 +310 +311 +312 +313 +314 +315 +316 +317 +318 +319 +320 +321 +322 +323 +324 +325 +326 +327  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +2 +  +2 +  +  +  +  +2 +  +2 +  +2 +2 +2 +  +  +  +  +1 +  +  +  +  +  +  +2 +  +  +  +2 +  +  +  +2 +  +2 +  +  +  +  +  +  +  +1 +2 +  +  +  +  +  +2 +  +  +2 +  +  +2 +2 +  +1 +  +  +  +2 +  +  +1 +1 +1 +  +1 +1 +  +  +1 +1 +  +1 +  +  +1 +  +2 +  +  +  +  +  +1 +  +1 +  +1 +  +  +  +  +1 +2 +2 +2 +2 +2 +2 +1 +  +  +2 +2 +  +  +  +  +2 +  +  +  +1 +3 +1 +  +  +  +1 +1 +  +  +  +  +  +  +  +1 +  +1 +1 +1 +  +1 +  +1 +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +  +1 +1 +  +  +  +  +  +  +  +  +  +  +  +1 +  +  +6 +6 +  +1 +  +2 +  +1 +  +2 +  +  +  +  +1 +1 +  +1 +  +  +1 +  +  +  +  +  +  +  +1 +  +  +1 +1 +  +  +1 +1 +  +1 +1 +1 +1 +1 +1 +1 +  +1 +1 +  +1 +  +  +  + 
/*
+example.js
+ 
+quickstart example
+ 
+instruction
+    1. save this script as example.js
+    2. run the shell command:
+        $ npm install npmdoc-debowerify && PORT=8081 node example.js
+    3. play with the browser-demo on http://127.0.0.1:8081
+*/
+ 
+ 
+ 
+/* istanbul instrument in package npmdoc_debowerify */
+/*jslint
+    bitwise: true,
+    browser: true,
+    maxerr: 8,
+    maxlen: 96,
+    node: true,
+    nomen: true,
+    regexp: true,
+    stupid: true
+*/
+(function () {
+    'use strict';
+    var local;
+ 
+ 
+ 
+    // run shared js-env code - pre-init
+    (function () {
+        // init local
+        local = {};
+        // init modeJs
+        local.modeJs = (function () {
+            try {
+                return typeof navigator.userAgent === 'string' &&
+                    typeof document.querySelector('body') === 'object' &&
+                    typeof XMLHttpRequest.prototype.open === 'function' &&
+                    'browser';
+            } catch (errorCaughtBrowser) {
+                return module.exports &&
+                    typeof process.versions.node === 'string' &&
+                    typeof require('http').createServer === 'function' &&
+                    'node';
+            }
+        }());
+        // init global
+        local.global = local.modeJs === 'browser'
+            ? window
+            : global;
+        // init utility2_rollup
+        local = local.global.utility2_rollup || (local.modeJs === 'browser'
+            ? local.global.utility2_npmdoc_debowerify
+            : global.utility2_moduleExports);
+        // export local
+        local.global.local = local;
+    }());
+    switch (local.modeJs) {
+ 
+ 
+ 
+    // post-init
+    // run browser js-env code - post-init
+    /* istanbul ignore next */
+    case 'browser':
+        local.testRunBrowser = function (event) {
+            Eif (!event || (event &&
+                    event.currentTarget &&
+                    event.currentTarget.className &&
+                    event.currentTarget.className.includes &&
+                    event.currentTarget.className.includes('onreset'))) {
+                // reset output
+                Array.from(
+                    document.querySelectorAll('body > .resettable')
+                ).forEach(function (element) {
+                    switch (element.tagName) {
+                    case 'INPUT':
+                    case 'TEXTAREA':
+                        element.value = '';
+                        break;
+                    default:
+                        element.textContent = '';
+                    }
+                });
+            }
+            switch (event && event.currentTarget && event.currentTarget.id) {
+            case 'testRunButton1':
+                // show tests
+                Eif (document.querySelector('#testReportDiv1').style.display === 'none') {
+                    document.querySelector('#testReportDiv1').style.display = 'block';
+                    document.querySelector('#testRunButton1').textContent =
+                        'hide internal test';
+                    local.modeTest = true;
+                    local.testRunDefault(local);
+                // hide tests
+                } else {
+                    document.querySelector('#testReportDiv1').style.display = 'none';
+                    document.querySelector('#testRunButton1').textContent = 'run internal test';
+                }
+                break;
+            // custom-case
+            default:
+                break;
+            }
+            Iif (document.querySelector('#inputTextareaEval1') && (!event || (event &&
+                    event.currentTarget &&
+                    event.currentTarget.className &&
+                    event.currentTarget.className.includes &&
+                    event.currentTarget.className.includes('oneval')))) {
+                // try to eval input-code
+                try {
+                    /*jslint evil: true*/
+                    eval(document.querySelector('#inputTextareaEval1').value);
+                } catch (errorCaught) {
+                    console.error(errorCaught.stack);
+                }
+            }
+        };
+        // log stderr and stdout to #outputTextareaStdout1
+        ['error', 'log'].forEach(function (key) {
+            console[key + '_original'] = console[key];
+            console[key] = function () {
+                var element;
+                console[key + '_original'].apply(console, arguments);
+                element = document.querySelector('#outputTextareaStdout1');
+                Iif (!element) {
+                    return;
+                }
+                // append text to #outputTextareaStdout1
+                element.value += Array.from(arguments).map(function (arg) {
+                    return typeof arg === 'string'
+                        ? arg
+                        : JSON.stringify(arg, null, 4);
+                }).join(' ') + '\n';
+                // scroll textarea to bottom
+                element.scrollTop = element.scrollHeight;
+            };
+        });
+        // init event-handling
+        ['change', 'click', 'keyup'].forEach(function (event) {
+            Array.from(document.querySelectorAll('.on' + event)).forEach(function (element) {
+                element.addEventListener(event, local.testRunBrowser);
+            });
+        });
+        // run tests
+        local.testRunBrowser();
+        break;
+ 
+ 
+ 
+    // run node js-env code - post-init
+    /* istanbul ignore next */
+    case 'node':
+        // export local
+        module.exports = local;
+        // require modules
+        local.fs = require('fs');
+        local.http = require('http');
+        local.url = require('url');
+        // init assets
+        local.assetsDict = local.assetsDict || {};
+        /* jslint-ignore-begin */
+        local.assetsDict['/assets.index.template.html'] = '\
+<!doctype html>\n\
+<html lang="en">\n\
+<head>\n\
+<meta charset="UTF-8">\n\
+<meta name="viewport" content="width=device-width, initial-scale=1">\n\
+<title>{{env.npm_package_name}} (v{{env.npm_package_version}})</title>\n\
+<style>\n\
+/*csslint\n\
+    box-sizing: false,\n\
+    universal-selector: false\n\
+*/\n\
+* {\n\
+    box-sizing: border-box;\n\
+}\n\
+body {\n\
+    background: #dde;\n\
+    font-family: Arial, Helvetica, sans-serif;\n\
+    margin: 2rem;\n\
+}\n\
+body > * {\n\
+    margin-bottom: 1rem;\n\
+}\n\
+.utility2FooterDiv {\n\
+    margin-top: 20px;\n\
+    text-align: center;\n\
+}\n\
+</style>\n\
+<style>\n\
+/*csslint\n\
+*/\n\
+textarea {\n\
+    font-family: monospace;\n\
+    height: 10rem;\n\
+    width: 100%;\n\
+}\n\
+textarea[readonly] {\n\
+    background: #ddd;\n\
+}\n\
+</style>\n\
+</head>\n\
+<body>\n\
+<!-- utility2-comment\n\
+<div id="ajaxProgressDiv1" style="background: #d00; height: 2px; left: 0; margin: 0; padding: 0; position: fixed; top: 0; transition: background 0.5s, width 1.5s; width: 25%;"></div>\n\
+utility2-comment -->\n\
+<h1>\n\
+<!-- utility2-comment\n\
+    <a\n\
+        {{#if env.npm_package_homepage}}\n\
+        href="http://github.com/%7B%7Benv.npm_package_homepage%7D%7D"\n\
+        {{/if env.npm_package_homepage}}\n\
+        target="_blank"\n\
+    >\n\
+utility2-comment -->\n\
+        {{env.npm_package_name}} (v{{env.npm_package_version}})\n\
+<!-- utility2-comment\n\
+    </a>\n\
+utility2-comment -->\n\
+</h1>\n\
+<h3>{{env.npm_package_description}}</h3>\n\
+<!-- utility2-comment\n\
+<h4><a download href="http://github.com/assets.app.js">download standalone app</a></h4>\n\
+<button class="onclick onreset" id="testRunButton1">run internal test</button><br>\n\
+<div id="testReportDiv1" style="display: none;"></div>\n\
+utility2-comment -->\n\
+\n\
+\n\
+\n\
+<label>stderr and stdout</label>\n\
+<textarea class="resettable" id="outputTextareaStdout1" readonly></textarea>\n\
+<!-- utility2-comment\n\
+{{#if isRollup}}\n\
+<script src="http://github.com/assets.app.js"></script>\n\
+{{#unless isRollup}}\n\
+utility2-comment -->\n\
+<script src="http://github.com/assets.utility2.rollup.js"></script>\n\
+<script src="http://github.com/jsonp.utility2._stateInit?callback=window.utility2._stateInit"></script>\n\
+<script src="http://github.com/assets.npmdoc_debowerify.rollup.js"></script>\n\
+<script src="http://github.com/assets.example.js"></script>\n\
+<script src="http://github.com/assets.test.js"></script>\n\
+<!-- utility2-comment\n\
+{{/if isRollup}}\n\
+utility2-comment -->\n\
+<div class="utility2FooterDiv">\n\
+    [ this app was created with\n\
+    <a href="https://github.com/kaizhu256/node-utility2" target="_blank">utility2</a>\n\
+    ]\n\
+</div>\n\
+</body>\n\
+</html>\n\
+';
+        /* jslint-ignore-end */
+        Iif (local.templateRender) {
+            local.assetsDict['/'] = local.templateRender(
+                local.assetsDict['/assets.index.template.html'],
+                {
+                    env: local.objectSetDefault(local.env, {
+                        npm_package_description: 'example module',
+                        npm_package_name: 'example',
+                        npm_package_nameAlias: 'example',
+                        npm_package_version: '0.0.1'
+                    })
+                }
+            );
+        } else {
+            local.assetsDict['/'] = local.assetsDict['/assets.index.template.html']
+                .replace((/\{\{env\.(\w+?)\}\}/g), function (match0, match1) {
+                    // jslint-hack
+                    String(match0);
+                    switch (match1) {
+                    case 'npm_package_description':
+                        return 'example module';
+                    case 'npm_package_name':
+                        return 'example';
+                    case 'npm_package_nameAlias':
+                        return 'example';
+                    case 'npm_package_version':
+                        return '0.0.1';
+                    }
+                });
+        }
+        // run the cli
+        Eif (local.global.utility2_rollup || module !== require.main) {
+            break;
+        }
+        local.assetsDict['/assets.example.js'] =
+            local.assetsDict['/assets.example.js'] ||
+            local.fs.readFileSync(__filename, 'utf8');
+        local.assetsDict['/assets.npmdoc_debowerify.rollup.js'] =
+            local.assetsDict['/assets.npmdoc_debowerify.rollup.js'] ||
+            local.fs.readFileSync(
+                // npmdoc-hack
+                local.npmdoc_debowerify.__dirname +
+                    '/lib.npmdoc_debowerify.js',
+                'utf8'
+            ).replace((/^#!/), '//');
+        local.assetsDict['/favicon.ico'] = local.assetsDict['/favicon.ico'] || '';
+        // if $npm_config_timeout_exit exists,
+        // then exit this process after $npm_config_timeout_exit ms
+        if (Number(process.env.npm_config_timeout_exit)) {
+            setTimeout(process.exit, Number(process.env.npm_config_timeout_exit));
+        }
+        // start server
+        if (local.global.utility2_serverHttp1) {
+            break;
+        }
+        process.env.PORT = process.env.PORT || '8081';
+        console.error('server starting on port ' + process.env.PORT);
+        local.http.createServer(function (request, response) {
+            request.urlParsed = local.url.parse(request.url);
+            if (local.assetsDict[request.urlParsed.pathname] !== undefined) {
+                response.end(local.assetsDict[request.urlParsed.pathname]);
+                return;
+            }
+            response.statusCode = 404;
+            response.end();
+        }).listen(process.env.PORT);
+        break;
+    }
+}());
+ 
+ 
+
+ + + diff --git a/build/coverage.html/node-npmdoc-debowerify/index.html b/build/coverage.html/node-npmdoc-debowerify/index.html new file mode 100644 index 0000000..efd792c --- /dev/null +++ b/build/coverage.html/node-npmdoc-debowerify/index.html @@ -0,0 +1,278 @@ + + + + Code coverage report for node-npmdoc-debowerify/ + + + + +
+

+ npmdoc-debowerify (v0.0.1) +

+

Code coverage report for node-npmdoc-debowerify/

+

+ + Statements: 100% (153 / 153)      + + + Branches: 100% (126 / 126)      + + + Functions: 100% (26 / 26)      + + + Lines: 100% (153 / 153)      + + Ignored: 29 statements, 1 function, 32 branches      +

+
All files » node-npmdoc-debowerify/
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
FileStatementsBranchesFunctionsLines
example.js100%(83 / 83)100%(73 / 73)100%(12 / 12)100%(83 / 83)
lib.npmdoc_debowerify.js100%(16 / 16)100%(14 / 14)100%(3 / 3)100%(16 / 16)
test.js100%(54 / 54)100%(39 / 39)100%(11 / 11)100%(54 / 54)
+
+ + + diff --git a/build/coverage.html/node-npmdoc-debowerify/lib.npmdoc_debowerify.js.html b/build/coverage.html/node-npmdoc-debowerify/lib.npmdoc_debowerify.js.html new file mode 100644 index 0000000..4f6fcbf --- /dev/null +++ b/build/coverage.html/node-npmdoc-debowerify/lib.npmdoc_debowerify.js.html @@ -0,0 +1,386 @@ + + + + Code coverage report for node-npmdoc-debowerify/lib.npmdoc_debowerify.js + + + + +
+

+ npmdoc-debowerify (v0.0.1) +

+

Code coverage report for node-npmdoc-debowerify/lib.npmdoc_debowerify.js

+

+ + Statements: 100% (16 / 16)      + + + Branches: 100% (14 / 14)      + + + Functions: 100% (3 / 3)      + + + Lines: 100% (16 / 16)      + + Ignored: none      +

+
All files » node-npmdoc-debowerify/ » lib.npmdoc_debowerify.js
+
+
+

+
+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55  +  +  +  +  +  +  +  +  +  +  +2 +  +2 +  +  +  +  +2 +  +2 +  +2 +2 +2 +  +  +  +  +1 +  +  +  +  +  +  +2 +  +  +  +2 +  +2 +  +2 +1 +  +1 +1 +1 +  +  +  +  + 
/* istanbul instrument in package npmdoc_debowerify */
+/*jslint
+    bitwise: true,
+    browser: true,
+    maxerr: 8,
+    maxlen: 96,
+    node: true,
+    nomen: true,
+    regexp: true,
+    stupid: true
+*/
+(function () {
+    'use strict';
+    var local;
+ 
+ 
+ 
+    // run shared js-env code - pre-init
+    (function () {
+        // init local
+        local = {};
+        // init modeJs
+        local.modeJs = (function () {
+            try {
+                return typeof navigator.userAgent === 'string' &&
+                    typeof document.querySelector('body') === 'object' &&
+                    typeof XMLHttpRequest.prototype.open === 'function' &&
+                    'browser';
+            } catch (errorCaughtBrowser) {
+                return module.exports &&
+                    typeof process.versions.node === 'string' &&
+                    typeof require('http').createServer === 'function' &&
+                    'node';
+            }
+        }());
+        // init global
+        local.global = local.modeJs === 'browser'
+            ? window
+            : global;
+        // init utility2_rollup
+        local = local.global.utility2_rollup || local;
+        // init lib
+        local.local = local.npmdoc_debowerify = local;
+        // init exports
+        if (local.modeJs === 'browser') {
+            local.global.utility2_npmdoc_debowerify = local;
+        } else {
+            module.exports = local;
+            module.exports.__dirname = __dirname;
+            module.exports.module = module;
+        }
+    }());
+}());
+ 
+ 
+
+ + + diff --git a/build/coverage.html/node-npmdoc-debowerify/test.js.html b/build/coverage.html/node-npmdoc-debowerify/test.js.html new file mode 100644 index 0000000..9de2162 --- /dev/null +++ b/build/coverage.html/node-npmdoc-debowerify/test.js.html @@ -0,0 +1,776 @@ + + + + Code coverage report for node-npmdoc-debowerify/test.js + + + + +
+

+ npmdoc-debowerify (v0.0.1) +

+

Code coverage report for node-npmdoc-debowerify/test.js

+

+ + Statements: 100% (54 / 54)      + + + Branches: 100% (39 / 39)      + + + Functions: 100% (11 / 11)      + + + Lines: 100% (54 / 54)      + + Ignored: 3 statements, 2 branches      +

+ +
+
+

+
+
1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 +30 +31 +32 +33 +34 +35 +36 +37 +38 +39 +40 +41 +42 +43 +44 +45 +46 +47 +48 +49 +50 +51 +52 +53 +54 +55 +56 +57 +58 +59 +60 +61 +62 +63 +64 +65 +66 +67 +68 +69 +70 +71 +72 +73 +74 +75 +76 +77 +78 +79 +80 +81 +82 +83 +84 +85 +86 +87 +88 +89 +90 +91 +92 +93 +94 +95 +96 +97 +98 +99 +100 +101 +102 +103 +104 +105 +106 +107 +108 +109 +110 +111 +112 +113 +114 +115 +116 +117 +118 +119 +120 +121 +122 +123 +124 +125 +126 +127 +128 +129 +130 +131 +132 +133 +134 +135 +136 +137 +138 +139 +140 +141 +142 +143 +144 +145 +146 +147 +148 +149 +150 +151 +152 +153 +154 +155 +156 +157 +158 +159 +160 +161 +162 +163 +164 +165 +166 +167 +168 +169 +170 +171 +172 +173 +174 +175 +176 +177 +178 +179 +180 +181 +182 +183 +184 +185  +  +  +  +  +  +  +  +  +  +  +2 +  +2 +  +  +  +  +2 +  +2 +  +2 +2 +2 +  +  +  +  +1 +  +  +  +  +  +  +2 +  +  +2 +  +  +1 +  +  +  +1 +  +  +1 +  +1 +  +  +2 +  +  +  +  +  +2 +2 +  +2 +  +  +  +  +  +1 +  +  +  +  +  +1 +  +  +  +  +  +2 +2 +  +2 +  +  +  +  +  +  +1 +  +  +1 +  +  +  +  +  +  +1 +  +  +  +  +  +  +1 +1 +1 +1 +  +1 +  +  +1 +  +  +  +  +  +  +1 +1 +1 +1 +1 +  +  +1 +  +  +  +  +  +  +2 +2 +  +  +1 +  +  +  +  +  +  +2 +2 +2 +  +1 +1 +  +  +1 +  +  +  +  +  +  +2 +2 +  +  +1 +  +  +  +  +  +  +1 +1 +  +  +  +1 +1 +  +  +  + 
/* istanbul instrument in package npmdoc_debowerify */
+/*jslint
+    bitwise: true,
+    browser: true,
+    maxerr: 8,
+    maxlen: 96,
+    node: true,
+    nomen: true,
+    regexp: true,
+    stupid: true
+*/
+(function () {
+    'use strict';
+    var local;
+ 
+ 
+ 
+    // run shared js-env code - pre-init
+    (function () {
+        // init local
+        local = {};
+        // init modeJs
+        local.modeJs = (function () {
+            try {
+                return typeof navigator.userAgent === 'string' &&
+                    typeof document.querySelector('body') === 'object' &&
+                    typeof XMLHttpRequest.prototype.open === 'function' &&
+                    'browser';
+            } catch (errorCaughtBrowser) {
+                return module.exports &&
+                    typeof process.versions.node === 'string' &&
+                    typeof require('http').createServer === 'function' &&
+                    'node';
+            }
+        }());
+        // init global
+        local.global = local.modeJs === 'browser'
+            ? window
+            : global;
+        switch (local.modeJs) {
+        // re-init local from window.local
+        case 'browser':
+            local = local.global.utility2.objectSetDefault(
+                local.global.utility2_rollup || local.global.local,
+                local.global.utility2
+            );
+            break;
+        // re-init local from example.js
+        case 'node':
+            local = (local.global.utility2_rollup || require('utility2'))
+                .requireExampleJsFromReadme();
+            break;
+        }
+        // export local
+        local.global.local = local;
+    }());
+ 
+ 
+ 
+    // run shared js-env code - function
+    (function () {
+        return;
+    }());
+    switch (local.modeJs) {
+ 
+ 
+ 
+    // run browser js-env code - function
+    case 'browser':
+        break;
+ 
+ 
+ 
+    // run node js-env code - function
+    case 'node':
+        break;
+    }
+ 
+ 
+ 
+    // run shared js-env code - post-init
+    (function () {
+        return;
+    }());
+    switch (local.modeJs) {
+ 
+ 
+ 
+    // run browser js-env code - post-init
+    case 'browser':
+        // run tests
+        local.nop(local.modeTest &&
+            document.querySelector('#testRunButton1') &&
+            document.querySelector('#testRunButton1').click());
+        break;
+ 
+ 
+ 
+    // run node js-env code - post-init
+    /* istanbul ignore next */
+    case 'node':
+        local.testCase_buildApidoc_default = local.testCase_buildApidoc_default || function (
+            options,
+            onError
+        ) {
+        /*
+         * this function will test buildApidoc's default handling-behavior-behavior
+         */
+            options = { modulePathList: module.paths };
+            Eif (local.env.npm_package_buildNpmdoc) {
+                local.buildNpmdoc(options, onError);
+                return;
+            }
+            local.buildApidoc(options, onError);
+        };
+ 
+        local.testCase_buildApp_default = local.testCase_buildApp_default || function (
+            options,
+            onError
+        ) {
+        /*
+         * this function will test buildApp's default handling-behavior-behavior
+         */
+            local.testCase_buildReadme_default(options, local.onErrorThrow);
+            local.testCase_buildLib_default(options, local.onErrorThrow);
+            local.testCase_buildTest_default(options, local.onErrorThrow);
+            options = [];
+            local.buildApp(options, onError);
+        };
+ 
+        local.testCase_buildLib_default = local.testCase_buildLib_default || function (
+            options,
+            onError
+        ) {
+        /*
+         * this function will test buildLib's default handling-behavior
+         */
+            options = {};
+            local.buildLib(options, onError);
+        };
+ 
+        local.testCase_buildReadme_default = local.testCase_buildReadme_default || function (
+            options,
+            onError
+        ) {
+        /*
+         * this function will test buildReadme's default handling-behavior-behavior
+         */
+            Eif (local.env.npm_package_buildNpmdoc) {
+                onError();
+                return;
+            }
+            options = {};
+            local.buildReadme(options, onError);
+        };
+ 
+        local.testCase_buildTest_default = local.testCase_buildTest_default || function (
+            options,
+            onError
+        ) {
+        /*
+         * this function will test buildTest's default handling-behavior
+         */
+            options = {};
+            local.buildTest(options, onError);
+        };
+ 
+        local.testCase_webpage_default = local.testCase_webpage_default || function (
+            options,
+            onError
+        ) {
+        /*
+         * this function will test webpage's default handling-behavior
+         */
+            options = { modeCoverageMerge: true, url: local.serverLocalHost + '?modeTest=1' };
+            local.browserTest(options, onError);
+        };
+ 
+        // run test-server
+        local.testRunServer(local);
+        break;
+    }
+}());
+ 
+ 
+
+ + + diff --git a/build/screenCapture.buildApidoc.browser._2Fhome_2Ftravis_2Fbuild_2Fnpmdoc_2Fnode-npmdoc-debowerify_2Ftmp_2Fbuild_2Fapidoc.html.html b/build/screenCapture.buildApidoc.browser._2Fhome_2Ftravis_2Fbuild_2Fnpmdoc_2Fnode-npmdoc-debowerify_2Ftmp_2Fbuild_2Fapidoc.html.html new file mode 100644 index 0000000..8b713d5 --- /dev/null +++ b/build/screenCapture.buildApidoc.browser._2Fhome_2Ftravis_2Fbuild_2Fnpmdoc_2Fnode-npmdoc-debowerify_2Ftmp_2Fbuild_2Fapidoc.html.html @@ -0,0 +1,72 @@ +
+ +

api documentation for + debowerify (v1.5.0) +

+

A browserify transform to enable the easy use of bower components in browserify client javascript projects. This can be used in conjunction with deamdify to require AMD components from bower as well.

+ + + + +
+ [ this document was created with + utility2 + ] +
+
+ \ No newline at end of file diff --git a/build/screenCapture.buildApidoc.browser._2Fhome_2Ftravis_2Fbuild_2Fnpmdoc_2Fnode-npmdoc-debowerify_2Ftmp_2Fbuild_2Fapidoc.html.png b/build/screenCapture.buildApidoc.browser._2Fhome_2Ftravis_2Fbuild_2Fnpmdoc_2Fnode-npmdoc-debowerify_2Ftmp_2Fbuild_2Fapidoc.html.png new file mode 100644 index 0000000..db0241f Binary files /dev/null and b/build/screenCapture.buildApidoc.browser._2Fhome_2Ftravis_2Fbuild_2Fnpmdoc_2Fnode-npmdoc-debowerify_2Ftmp_2Fbuild_2Fapidoc.html.png differ diff --git a/build/screenCapture.buildCi.browser.%2Ftmp%2Fbuild%2Fapidoc.html.html b/build/screenCapture.buildCi.browser.%2Ftmp%2Fbuild%2Fapidoc.html.html new file mode 100644 index 0000000..8b713d5 --- /dev/null +++ b/build/screenCapture.buildCi.browser.%2Ftmp%2Fbuild%2Fapidoc.html.html @@ -0,0 +1,72 @@ +
+ +

api documentation for + debowerify (v1.5.0) +

+

A browserify transform to enable the easy use of bower components in browserify client javascript projects. This can be used in conjunction with deamdify to require AMD components from bower as well.

+ + + + +
+ [ this document was created with + utility2 + ] +
+
+ \ No newline at end of file diff --git a/build/screenCapture.buildCi.browser.%2Ftmp%2Fbuild%2Fapidoc.html.png b/build/screenCapture.buildCi.browser.%2Ftmp%2Fbuild%2Fapidoc.html.png new file mode 100644 index 0000000..db0241f Binary files /dev/null and b/build/screenCapture.buildCi.browser.%2Ftmp%2Fbuild%2Fapidoc.html.png differ diff --git a/build/screenCapture.buildCi.browser.%2Ftmp%2Fbuild%2Ftest-report.html.html b/build/screenCapture.buildCi.browser.%2Ftmp%2Fbuild%2Ftest-report.html.html new file mode 100644 index 0000000..fd4f01a --- /dev/null +++ b/build/screenCapture.buildCi.browser.%2Ftmp%2Fbuild%2Ftest-report.html.html @@ -0,0 +1,236 @@ +
+ +

test-report for + npmdoc-debowerify (v0.0.2) +

+
+

summary

+

+ version- + 0.0.2
+ test date- 2017-04-27T16:48:09.775Z
+ commit info- + + alpha - [npm publishAfterCommitAfterBuild]
+ +

+ + + + + + + + + + + + + + + +
total time-elapsedtotal tests failedtotal tests passedtotal tests pending
27603 ms090
+
+ +
+

+ 1. buildApidoc - node - linux v6.10.2 - 2017-04-27T16:48:09.667Z
+ + time-elapsed- 1313 ms
+ tests failed- 0
+ tests passed- 1
+ tests pending- 0
+

+ + + + + + + + + + + + + + + + + +
#time-elapsedstatustest-case
11 mspassedtestCase_buildApidoc_default
+
+
+
+ +
+

+ 2. buildApp - node - linux v6.10.2 - 2017-04-27T16:47:43.368Z
+ + time-elapsed- 27603 ms
+ tests failed- 0
+ tests passed- 7
+ tests pending- 0
+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
#time-elapsedstatustest-case
21 mspassedtestCase_buildApidoc_default
36517 mspassedtestCase_buildApp_default
4164 mspassedtestCase_buildCustomOrg_default
51 mspassedtestCase_buildLib_default
60 mspassedtestCase_buildReadme_default
70 mspassedtestCase_buildTest_default
811979 mspassedtestCase_webpage_default
+
+
+
+ +
+

+ 3. npmTest - browser - / - Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Electron/1.4.16 Safari/537.36 - 2017-04-27T16:47:57.614Z
+ + + + +
+ + time-elapsed- 14809 ms
+ tests failed- 0
+ tests passed- 1
+ tests pending- 0
+

+ + + + + + + + + + + + + + + + + +
#time-elapsedstatustest-case
91 mspassedtestCase_browser_nullCase
+
+
+
+ +
+ [ this document was created with + utility2 + ] +
+
+ \ No newline at end of file diff --git a/build/screenCapture.buildCi.browser.%2Ftmp%2Fbuild%2Ftest-report.html.png b/build/screenCapture.buildCi.browser.%2Ftmp%2Fbuild%2Ftest-report.html.png new file mode 100644 index 0000000..49bf1af Binary files /dev/null and b/build/screenCapture.buildCi.browser.%2Ftmp%2Fbuild%2Ftest-report.html.png differ diff --git a/build/screenCapture.buildNpmdoc.browser._2Fhome_2Ftravis_2Fbuild_2Fnpmdoc_2Fnode-npmdoc-debowerify_2Ftmp_2Fbuild_2Fapidoc.html.html b/build/screenCapture.buildNpmdoc.browser._2Fhome_2Ftravis_2Fbuild_2Fnpmdoc_2Fnode-npmdoc-debowerify_2Ftmp_2Fbuild_2Fapidoc.html.html new file mode 100644 index 0000000..8b713d5 --- /dev/null +++ b/build/screenCapture.buildNpmdoc.browser._2Fhome_2Ftravis_2Fbuild_2Fnpmdoc_2Fnode-npmdoc-debowerify_2Ftmp_2Fbuild_2Fapidoc.html.html @@ -0,0 +1,72 @@ +
+ +

api documentation for + debowerify (v1.5.0) +

+

A browserify transform to enable the easy use of bower components in browserify client javascript projects. This can be used in conjunction with deamdify to require AMD components from bower as well.

+ + + + +
+ [ this document was created with + utility2 + ] +
+
+ \ No newline at end of file diff --git a/build/screenCapture.buildNpmdoc.browser._2Fhome_2Ftravis_2Fbuild_2Fnpmdoc_2Fnode-npmdoc-debowerify_2Ftmp_2Fbuild_2Fapidoc.html.png b/build/screenCapture.buildNpmdoc.browser._2Fhome_2Ftravis_2Fbuild_2Fnpmdoc_2Fnode-npmdoc-debowerify_2Ftmp_2Fbuild_2Fapidoc.html.png new file mode 100644 index 0000000..db0241f Binary files /dev/null and b/build/screenCapture.buildNpmdoc.browser._2Fhome_2Ftravis_2Fbuild_2Fnpmdoc_2Fnode-npmdoc-debowerify_2Ftmp_2Fbuild_2Fapidoc.html.png differ diff --git a/build/screenCapture.gitLog.svg b/build/screenCapture.gitLog.svg new file mode 100644 index 0000000..5ee4d16 --- /dev/null +++ b/build/screenCapture.gitLog.svg @@ -0,0 +1,20 @@ + + + +2017-04-28 00:39:08 +0800 +[npm publishAfterCommitAfterBuild] +2017-04-18 15:49:30 +0000 +[ci skip] npm published + +2017-04-18 17:03:22 +0800 +[npm publishAfterCommitAfterBuild] +2017-04-06 18:58:28 +0000 +[ci skip] npm published + +2017-04-06 17:22:27 +0000 +[npm publishAfterCommitAfterBuild] + +2014-03-26 02:31:50 +0700 +add blank README.md + + diff --git a/build/screenCapture.npmPackageDependencyTree.svg b/build/screenCapture.npmPackageDependencyTree.svg new file mode 100644 index 0000000..89ee935 --- /dev/null +++ b/build/screenCapture.npmPackageDependencyTree.svg @@ -0,0 +1,219 @@ + + + +32 megabytes installed + +node_modules +└─┬ debowerify@1.5.0 + ├─┬ bower@1.3.12 + │ ├── abbrev@1.0.9 + │ ├── archy@0.0.2 + │ ├─┬ bower-config@0.5.2 + │ │ ├── graceful-fs@2.0.3 + │ │ ├─┬ optimist@0.6.1 + │ │ │ ├── minimist@0.0.10 + │ │ │ └── wordwrap@0.0.3 + │ │ └── osenv@0.0.3 + │ ├── bower-endpoint-parser@0.2.2 + │ ├─┬ bower-json@0.4.0 + │ │ ├── deep-extend@0.2.11 + │ │ ├── graceful-fs@2.0.3 + │ │ └── intersect@0.0.3 + │ ├── bower-logger@0.2.2 + │ ├─┬ bower-registry-client@0.2.4 + │ │ ├── async@0.2.10 + │ │ ├── graceful-fs@2.0.3 + │ │ ├── lru-cache@2.3.1 + │ │ ├── mkdirp@0.3.5 + │ │ ├─┬ request@2.51.0 + │ │ │ ├── caseless@0.8.0 + │ │ │ ├─┬ combined-stream@0.0.7 + │ │ │ │ └── delayed-stream@0.0.5 + │ │ │ ├─┬ form-data@0.2.0 + │ │ │ │ ├── async@0.9.2 + │ │ │ │ └─┬ mime-types@2.0.14 + │ │ │ │ └── mime-db@1.12.0 + │ │ │ ├── oauth-sign@0.5.0 + │ │ │ └── qs@2.3.3 + │ │ └── request-replay@0.2.0 + │ ├─┬ cardinal@0.4.0 + │ │ └─┬ redeyed@0.4.4 + │ │ └── esprima@1.0.4 + │ ├─┬ chalk@0.5.0 + │ │ ├── ansi-styles@1.1.0 + │ │ ├── escape-string-regexp@1.0.5 + │ │ ├─┬ has-ansi@0.1.0 + │ │ │ └── ansi-regex@0.2.1 + │ │ ├── strip-ansi@0.3.0 + │ │ └── supports-color@0.2.0 + │ ├── chmodr@0.1.0 + │ ├─┬ decompress-zip@0.0.8 + │ │ ├─┬ binary@0.3.0 + │ │ │ ├── buffers@0.1.1 + │ │ │ └─┬ chainsaw@0.1.0 + │ │ │ └── traverse@0.3.9 + │ │ ├── mkpath@0.1.0 + │ │ ├── nopt@2.2.1 + │ │ ├─┬ readable-stream@1.1.14 + │ │ │ ├── core-util-is@1.0.2 + │ │ │ ├── isarray@0.0.1 + │ │ │ └── string_decoder@0.10.31 + │ │ └─┬ touch@0.0.2 + │ │ └── nopt@1.0.10 + │ ├─┬ fstream@1.0.11 + │ │ ├── graceful-fs@4.1.11 + │ │ └── inherits@2.0.3 + │ ├─┬ fstream-ignore@1.0.5 + │ │ └─┬ minimatch@3.0.3 + │ │ └─┬ brace-expansion@1.1.7 + │ │ ├── balanced-match@0.4.2 + │ │ └── concat-map@0.0.1 + │ ├─┬ glob@4.0.6 + │ │ ├─┬ minimatch@1.0.0 + │ │ │ └── sigmund@1.0.1 + │ │ └─┬ once@1.4.0 + │ │ └── wrappy@1.0.2 + │ ├─┬ graceful-fs@3.0.11 + │ │ └── natives@1.1.0 + │ ├─┬ handlebars@2.0.0 + │ │ ├── optimist@0.3.7 + │ │ └─┬ uglify-js@2.3.6 + │ │ ├── optimist@0.3.7 + │ │ └─┬ source-map@0.1.43 + │ │ └── amdefine@1.0.1 + │ ├─┬ inquirer@0.7.1 + │ │ ├─┬ cli-color@0.3.3 + │ │ │ ├── d@0.1.1 + │ │ │ ├─┬ es5-ext@0.10.15 + │ │ │ │ ├─┬ es6-iterator@2.0.1 + │ │ │ │ │ └── d@1.0.0 + │ │ │ │ └─┬ es6-symbol@3.1.1 + │ │ │ │ └── d@1.0.0 + │ │ │ ├─┬ memoizee@0.3.10 + │ │ │ │ ├─┬ es6-weak-map@0.1.4 + │ │ │ │ │ ├── es6-iterator@0.1.3 + │ │ │ │ │ └── es6-symbol@2.0.1 + │ │ │ │ ├─┬ event-emitter@0.3.5 + │ │ │ │ │ └── d@1.0.0 + │ │ │ │ ├── lru-queue@0.1.0 + │ │ │ │ └── next-tick@0.2.2 + │ │ │ └─┬ timers-ext@0.1.2 + │ │ │ └── next-tick@1.0.0 + │ │ ├─┬ figures@1.7.0 + │ │ │ └── object-assign@4.1.1 + │ │ ├── lodash@2.4.2 + │ │ ├── mute-stream@0.0.4 + │ │ ├─┬ readline2@0.1.1 + │ │ │ └─┬ strip-ansi@2.0.1 + │ │ │ └── ansi-regex@1.1.1 + │ │ └── rx@2.5.3 + │ ├─┬ insight@0.4.3 + │ │ ├── async@0.9.2 + │ │ ├── chalk@0.5.1 + │ │ ├─┬ configstore@0.3.2 + │ │ │ ├─┬ js-yaml@3.8.3 + │ │ │ │ ├─┬ argparse@1.0.9 + │ │ │ │ │ └── sprintf-js@1.0.3 + │ │ │ │ └── esprima@3.1.3 + │ │ │ ├── object-assign@2.1.1 + │ │ │ ├── user-home@1.1.1 + │ │ │ ├── uuid@2.0.3 + │ │ │ └── xdg-basedir@1.0.1 + │ │ ├── inquirer@0.6.0 + │ │ ├─┬ lodash.debounce@2.4.1 + │ │ │ ├── lodash.isfunction@2.4.1 + │ │ │ ├─┬ lodash.isobject@2.4.1 + │ │ │ │ └── lodash._objecttypes@2.4.1 + │ │ │ └─┬ lodash.now@2.4.1 + │ │ │ └── lodash._isnative@2.4.1 + │ │ ├── object-assign@1.0.0 + │ │ ├─┬ os-name@1.0.3 + │ │ │ ├─┬ osx-release@1.1.0 + │ │ │ │ └── minimist@1.2.0 + │ │ │ └─┬ win-release@1.1.1 + │ │ │ └── semver@5.3.0 + │ │ └─┬ tough-cookie@0.12.1 + │ │ └── punycode@1.4.1 + │ ├── is-root@1.0.0 + │ ├── junk@1.0.3 + │ ├── lockfile@1.0.3 + │ ├── lru-cache@2.5.2 + │ ├─┬ mkdirp@0.5.0 + │ │ └── minimist@0.0.8 + │ ├── mout@0.9.1 + │ ├── nopt@3.0.6 + │ ├── opn@1.0.2 + │ ├── osenv@0.1.0 + │ ├─┬ p-throttler@0.1.0 + │ │ └── q@0.9.7 + │ ├─┬ promptly@0.2.0 + │ │ └── read@1.0.7 + │ ├── q@1.0.1 + │ ├─┬ request@2.42.0 + │ │ ├── aws-sign2@0.5.0 + │ │ ├─┬ bl@0.9.5 + │ │ │ └── readable-stream@1.0.34 + │ │ ├── caseless@0.6.0 + │ │ ├── forever-agent@0.5.2 + │ │ ├─┬ form-data@0.1.4 + │ │ │ ├── async@0.9.2 + │ │ │ └── mime@1.2.11 + │ │ ├─┬ hawk@1.1.1 + │ │ │ ├── boom@0.4.2 + │ │ │ ├── cryptiles@0.2.2 + │ │ │ ├── hoek@0.9.1 + │ │ │ └── sntp@0.2.4 + │ │ ├─┬ http-signature@0.10.1 + │ │ │ ├── asn1@0.1.11 + │ │ │ ├── assert-plus@0.1.5 + │ │ │ └── ctype@0.5.3 + │ │ ├── json-stringify-safe@5.0.1 + │ │ ├── mime-types@1.0.2 + │ │ ├── node-uuid@1.4.8 + │ │ ├── oauth-sign@0.4.0 + │ │ ├── qs@1.2.2 + │ │ ├── stringstream@0.0.5 + │ │ ├── tough-cookie@2.3.2 + │ │ └── tunnel-agent@0.4.3 + │ ├─┬ request-progress@0.3.0 + │ │ └── throttleit@0.0.2 + │ ├── retry@0.6.0 + │ ├── rimraf@2.2.8 + │ ├── semver@2.3.2 + │ ├─┬ shell-quote@1.4.3 + │ │ ├── array-filter@0.0.1 + │ │ ├── array-map@0.0.0 + │ │ ├── array-reduce@0.0.0 + │ │ └── jsonify@0.0.0 + │ ├── stringify-object@1.0.1 + │ ├─┬ tar-fs@0.5.2 + │ │ ├─┬ pump@0.3.5 + │ │ │ ├─┬ end-of-stream@1.0.0 + │ │ │ │ └── once@1.3.3 + │ │ │ └── once@1.2.0 + │ │ └─┬ tar-stream@0.4.7 + │ │ └── xtend@4.0.1 + │ ├── tmp@0.0.23 + │ ├─┬ update-notifier@0.2.0 + │ │ ├─┬ latest-version@0.2.0 + │ │ │ └─┬ package-json@0.2.0 + │ │ │ ├─┬ got@0.3.0 + │ │ │ │ └── object-assign@0.3.1 + │ │ │ └─┬ registry-url@0.1.1 + │ │ │ └─┬ npmconf@2.1.2 + │ │ │ ├─┬ config-chain@1.1.11 + │ │ │ │ └── proto-list@1.2.4 + │ │ │ ├── ini@1.3.4 + │ │ │ ├── once@1.3.3 + │ │ │ └── uid-number@0.0.5 + │ │ ├── semver-diff@0.1.0 + │ │ └─┬ string-length@0.1.2 + │ │ └─┬ strip-ansi@0.2.2 + │ │ └── ansi-regex@0.1.0 + │ └── which@1.0.9 + ├── esprima@2.7.3 + ├─┬ ordered-ast-traverse@1.1.1 + │ └── ordered-esprima-props@1.1.0 + └── through@2.3.8 + + diff --git a/build/screenCapture.npmPackageListing.svg b/build/screenCapture.npmPackageListing.svg new file mode 100644 index 0000000..65fe561 --- /dev/null +++ b/build/screenCapture.npmPackageListing.svg @@ -0,0 +1,11 @@ + + + + 0. 2017-04-27 16:48:12 +0000 15566 bytes . + 1. 2017-04-27 16:48:12 +0000 1236 bytes CONTRIBUTING.md + 2. 2017-04-27 16:48:12 +0000 6156 bytes README.md + 3. 2017-04-27 16:48:12 +0000 269 bytes bower.json + 4. 2017-04-27 16:48:12 +0000 5109 bytes index.js + 5. 2017-04-27 16:48:12 +0000 2796 bytes package.json + + diff --git a/build/screenCapture.npmTest.browser.%2F.html b/build/screenCapture.npmTest.browser.%2F.html new file mode 100644 index 0000000..a98a78b --- /dev/null +++ b/build/screenCapture.npmTest.browser.%2F.html @@ -0,0 +1,207 @@ + + + +npmdoc-debowerify (v0.0.2) + + + + + +
+ +

+ + + + npmdoc-debowerify (v0.0.2) + + + +

+

#### basic api documentation for [debowerify (v1.5.0)](https://github.com/eugeneware/debowerify#readme) [![npm package](https://img.shields.io/npm/v/npmdoc-debowerify.svg?style=flat-square)](https://www.npmjs.org/package/npmdoc-debowerify) [![travis-ci.org build-status](https://api.travis-ci.org/npmdoc/node-npmdoc-debowerify.svg)](https://travis-ci.org/npmdoc/node-npmdoc-debowerify)

+ +

download standalone app

+
+
+ +

test-report for + npmdoc-debowerify (v0.0.2) +

+
+

summary

+

+ version- + 0.0.2
+ test date- 2017-04-27T16:47:57.723Z
+ commit info- + + undefined
+ +

+ + + + + + + + + + + + + + + +
total time-elapsedtotal tests failedtotal tests passedtotal tests pending
1011 ms010
+
+ +
+

+ 1. browser - / - Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Electron/1.4.16 Safari/537.36 - 2017-04-27T16:47:57.614Z
+ + time-elapsed- 1010 ms
+ tests failed- 0
+ tests passed- 1
+ tests pending- 0
+

+ + + + + + + + + + + + + + + + + +
#time-elapsedstatustest-case
11 mspassedtestCase_browser_nullCase
+
+
+
+ +
+ [ this document was created with + utility2 + ] +
+
+
+ + + + + + + + + + + + + + + + + +
+ [ this app was created with + utility2 + ] +
+ + + \ No newline at end of file diff --git a/build/screenCapture.npmTest.browser.%2F.png b/build/screenCapture.npmTest.browser.%2F.png new file mode 100644 index 0000000..ec85fad Binary files /dev/null and b/build/screenCapture.npmTest.browser.%2F.png differ diff --git a/build/screenCapture.npmTest.browser..html b/build/screenCapture.npmTest.browser..html new file mode 100644 index 0000000..6cf1521 --- /dev/null +++ b/build/screenCapture.npmTest.browser..html @@ -0,0 +1,176 @@ + + + +npmdoc-debowerify (v0.0.1) + + + + + +
+ +

+ + + + npmdoc-debowerify (v0.0.1) + + + +

+

api documentation for [debowerify (v1.5.0)](https://github.com/eugeneware/debowerify#readme) [![npm package](https://img.shields.io/npm/v/npmdoc-debowerify.svg?style=flat-square)](https://www.npmjs.org/package/npmdoc-debowerify) [![travis-ci.org build-status](https://api.travis-ci.org/npmdoc/node-npmdoc-debowerify.svg)](https://travis-ci.org/npmdoc/node-npmdoc-debowerify)

+ +

download standalone app

+
+
+ +

test-report for + npmdoc-debowerify (v0.0.1) +

+
+

summary

+

+ version- + 0.0.1
+ test date- 2017-04-06T18:57:06.116Z
+ commit info- + + undefined
+ +

+ + + + + + + + + + + + + + + +
total time-elapsedtotal tests failedtotal tests passedtotal tests pending
1008 ms000
+
+ +
+ [ this document was created with + utility2 + ] +
+
+
+ + + + + + + + + + + + + + + + + +
+ [ this app was created with + utility2 + ] +
+ + + \ No newline at end of file diff --git a/build/screenCapture.npmTest.browser..png b/build/screenCapture.npmTest.browser..png new file mode 100644 index 0000000..19b958e Binary files /dev/null and b/build/screenCapture.npmTest.browser..png differ diff --git a/build/screenCapture.npmTest.browser._2Fhome_2Ftravis_2Fbuild_2Fnpmdoc_2Fnode-npmdoc-debowerify_2Ftmp_2Fbuild_2Fapidoc.html.html b/build/screenCapture.npmTest.browser._2Fhome_2Ftravis_2Fbuild_2Fnpmdoc_2Fnode-npmdoc-debowerify_2Ftmp_2Fbuild_2Fapidoc.html.html new file mode 100644 index 0000000..8b713d5 --- /dev/null +++ b/build/screenCapture.npmTest.browser._2Fhome_2Ftravis_2Fbuild_2Fnpmdoc_2Fnode-npmdoc-debowerify_2Ftmp_2Fbuild_2Fapidoc.html.html @@ -0,0 +1,72 @@ +
+ +

api documentation for + debowerify (v1.5.0) +

+

A browserify transform to enable the easy use of bower components in browserify client javascript projects. This can be used in conjunction with deamdify to require AMD components from bower as well.

+ + + + +
+ [ this document was created with + utility2 + ] +
+
+ \ No newline at end of file diff --git a/build/screenCapture.npmTest.browser._2Fhome_2Ftravis_2Fbuild_2Fnpmdoc_2Fnode-npmdoc-debowerify_2Ftmp_2Fbuild_2Fapidoc.html.png b/build/screenCapture.npmTest.browser._2Fhome_2Ftravis_2Fbuild_2Fnpmdoc_2Fnode-npmdoc-debowerify_2Ftmp_2Fbuild_2Fapidoc.html.png new file mode 100644 index 0000000..db0241f Binary files /dev/null and b/build/screenCapture.npmTest.browser._2Fhome_2Ftravis_2Fbuild_2Fnpmdoc_2Fnode-npmdoc-debowerify_2Ftmp_2Fbuild_2Fapidoc.html.png differ diff --git a/build/screenCapture.npmTest.svg b/build/screenCapture.npmTest.svg new file mode 100644 index 0000000..c3b17e6 --- /dev/null +++ b/build/screenCapture.npmTest.svg @@ -0,0 +1,129 @@ + + + + +> npmdoc-debowerify@0.0.1 test /home/travis/build/npmdoc/node-npmdoc-debowerify +> (set -e; export PORT=$(utility2 shServerPortRandom); utility2 test test.js) + + +[MODE_BUILD=npmTest] - 2017-04-06T18:57:03Z - npm-testing /home/travis/build/npmdoc/node-npmdoc-\ +debowerify + + +covering $ /home/travis/.nvm/versions/node/v6.10.2/bin/node /home/travis/build/npmdoc/node-npmdo\ +c-debowerify/test.js +merging file:///home/travis/build/npmdoc/node-npmdoc-debowerify/tmp/build/test-report.json to te\ +st-report +> server listening on http-port 37285 +created apidoc file:///home/travis/build/npmdoc/node-npmdoc-debowerify/tmp/build/apidoc.html + + +browserTest - created electron entry-page /home/travis/build/npmdoc/node-npmdoc-debowerify/tmp/e\ +lectron.15b44a08d1b0.c85c4769596d8.html + +[node test-case 1 of 6 passed] - testCase_buildLib_default +[node test-case 2 of 6 passed] - testCase_buildReadme_default +[node test-case 3 of 6 passed] - testCase_buildTest_default + +browserTest - created electron entry-page /home/travis/build/npmdoc/node-npmdoc-debowerify/tmp/e\ +lectron.15b44a08d410.178c1b370aa27.html + +Xlib: extension "RANDR" missing on display ":99.0". +Xlib: extension "RANDR" missing on display ":99.0". +> server listening on http-port 34266 +merging file:///home/travis/build/npmdoc/node-npmdoc-debowerify/tmp/build/test-report.json to te\ +st-report +Xlib: extension "RANDR" missing on display ":99.0". +[5983:0406/185705:WARNING:audio_manager.cc(314)] Multiple instances of AudioManager detected +[5983:0406/185705:WARNING:audio_manager.cc(275)] Multiple instances of AudioManager detected +merging file:///home/travis/build/npmdoc/node-npmdoc-debowerify/tmp/build/test-report.json to te\ +st-report +[6020:0406/185705:ERROR:sandbox_linux.cc(343)] InitializeSandbox() called with multiple threads \ +in process gpu-process. +Xlib: extension "RANDR" missing on display ":99.0". +[5981:0406/185705:WARNING:audio_manager.cc(314)] Multiple instances of AudioManager detected +[5981:0406/185705:WARNING:audio_manager.cc(275)] Multiple instances of AudioManager detected +[6046:0406/185705:ERROR:sandbox_linux.cc(343)] InitializeSandbox() called with multiple threads \ +in process gpu-process. +[5981:0406/185705:ERROR:browser_gpu_channel_host_factory.cc(131)] Failed to create channel. + +browserTest - opened url http://127.0.0.1:37285?modeTest=1 + + +browserTest - opened url /home/travis/build/npmdoc/node-npmdoc-debowerify/tmp/build/apidoc.html + +[5983:0406/185707:INFO:CONSOLE(250)] "----------|-----------|-----------|-----------|-----------\ +| +File | % Stmts |% Branches | % Funcs | % Lines | +----------|-----------|-----------|-----------|-----------| +----------|-----------|-----------|-----------|-----------| +All files | 100 | 100 | 100 | 100 | +----------|-----------|-----------|-----------|-----------| +", source: file:///home/travis/build/npmdoc/node-npmdoc-debowerify/tmp/electron.15b44a08d410.178\ +c1b370aa27.html (250) +[5983:0406/185707:INFO:CONSOLE(250)] "created coverage file:///tmp/build/coverage.html/index.htm\ +l", source: file:///home/travis/build/npmdoc/node-npmdoc-debowerify/tmp/electron.15b44a08d410.17\ +8c1b370aa27.html (250) +[node test-case 4 of 6 passed] - testCase_buildApp_default + +browserTest - created screenCapture file:///home/travis/build/npmdoc/node-npmdoc-debowerify/tmp/\ +build/screenCapture.npmTest.browser..png + +browserTest - created screenCapture file:///home/travis/build/npmdoc/node-npmdoc-debowerify/tmp/\ +build/screenCapture.npmTest.browser..html + +browserTest - created screenCapture file:///home/travis/build/npmdoc/node-npmdoc-debowerify/tmp/\ +build/screenCapture.npmTest.browser._2Fhome_2Ftravis_2Fbuild_2Fnpmdoc_2Fnode-npmdoc-debowerify_2\ +Ftmp_2Fbuild_2Fapidoc.html.png + + +browserTest - exit-code 0 - http://127.0.0.1:37285?modeTest=1 + + +browserTest - merged coverage from /home/travis/build/npmdoc/node-npmdoc-debowerify/tmp/coverage\ +.npmTest.browser.%2F.json + + +browserTest - merging test-report from /home/travis/build/npmdoc/node-npmdoc-debowerify/tmp/test\ +-report.npmTest.browser.%2F.json + +[node test-case 5 of 6 passed] - testCase_webpage_default +browserTest - created screenCapture file:///home/travis/build/npmdoc/node-npmdoc-debowerify/tmp/\ +build/screenCapture.npmTest.browser._2Fhome_2Ftravis_2Fbuild_2Fnpmdoc_2Fnode-npmdoc-debowerify_2\ +Ftmp_2Fbuild_2Fapidoc.html.html + +browserTest - exit-code 0 - /home/travis/build/npmdoc/node-npmdoc-debowerify/tmp/build/apidoc.ht\ +ml + +[node test-case 6 of 6 passed] - testCase_buildApidoc_default +-------------------------------|-----------|-----------|-----------|-----------| +File | % Stmts |% Branches | % Funcs | % Lines | +-------------------------------|-----------|-----------|-----------|-----------| + node-npmdoc-debowerify/ | 100 | 100 | 100 | 100 | + example.js | 100 | 100 | 100 | 100 | + lib.npmdoc_debowerify.js | 100 | 100 | 100 | 100 | + test.js | 100 | 100 | 100 | 100 | +-------------------------------|-----------|-----------|-----------|-----------| +All files | 100 | 100 | 100 | 100 | +-------------------------------|-----------|-----------|-----------|-----------| + +created coverage file:///home/travis/build/npmdoc/node-npmdoc-debowerify/tmp/build/coverage.html\ +/index.html +merging file:///home/travis/build/npmdoc/node-npmdoc-debowerify/tmp/build/test-report.json to te\ +st-report + +------------------------------------------------------- +| test-report - buildNpmdoc - node - linux v6.10.2 - 2017-04-06T18:56:25.892Z +| 53455 ms 0 failed 6 passed | +------------------------------------------------------- + +created test-report file:///home/travis/build/npmdoc/node-npmdoc-debowerify/tmp/build/test-repor\ +t.html + + +npmTest - 0 failed tests + + +[MODE_BUILD=npmTest] - 2017-04-06T18:57:22Z - EXIT_CODE - 0 + + diff --git a/build/test-report.badge.svg b/build/test-report.badge.svg new file mode 100644 index 0000000..8552400 --- /dev/null +++ b/build/test-report.badge.svg @@ -0,0 +1 @@ +tests failedtests failed00 \ No newline at end of file diff --git a/build/test-report.html b/build/test-report.html new file mode 100644 index 0000000..30a0a3b --- /dev/null +++ b/build/test-report.html @@ -0,0 +1,242 @@ +
+ +

test-report for + npmdoc-debowerify (v0.0.2) +

+
+

summary

+

+ version- + 0.0.2
+ test date- 2017-04-27T16:48:09.775Z
+ commit info- + + alpha - [npm publishAfterCommitAfterBuild]
+ +

+ + + + + + + + + + + + + + + +
total time-elapsedtotal tests failedtotal tests passedtotal tests pending
27603 ms090
+
+ +
+

+ 1. buildApidoc - node - linux v6.10.2 - 2017-04-27T16:48:09.667Z
+ + time-elapsed- 1313 ms
+ tests failed- 0
+ tests passed- 1
+ tests pending- 0
+

+ + + + + + + + + + + + + + + + + +
#time-elapsedstatustest-case
11 mspassedtestCase_buildApidoc_default
+
+
+
+
+ +
+

+ 2. buildApp - node - linux v6.10.2 - 2017-04-27T16:47:43.368Z
+ + time-elapsed- 27603 ms
+ tests failed- 0
+ tests passed- 7
+ tests pending- 0
+

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
#time-elapsedstatustest-case
21 mspassedtestCase_buildApidoc_default
36517 mspassedtestCase_buildApp_default
4164 mspassedtestCase_buildCustomOrg_default
51 mspassedtestCase_buildLib_default
60 mspassedtestCase_buildReadme_default
70 mspassedtestCase_buildTest_default
811979 mspassedtestCase_webpage_default
+
+
+
+
+ +
+

+ 3. npmTest - browser - / - Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Electron/1.4.16 Safari/537.36 - 2017-04-27T16:47:57.614Z
+ + + + +
+ + time-elapsed- 14809 ms
+ tests failed- 0
+ tests passed- 1
+ tests pending- 0
+

+ + + + + + + + + + + + + + + + + +
#time-elapsedstatustest-case
91 mspassedtestCase_browser_nullCase
+
+
+
+
+ +
+ [ this document was created with + utility2 + ] +
+
diff --git a/build/test-report.json b/build/test-report.json new file mode 100644 index 0000000..24a69d0 --- /dev/null +++ b/build/test-report.json @@ -0,0 +1 @@ +{"testPlatformList":[{"name":"buildApidoc - node - linux v6.10.2 - 2017-04-27T16:48:09.667Z","testCaseList":[{"name":"testCase_buildApidoc_default","status":"passed","errorStack":"","timeElapsed":1,"timeStart":1493311691220,"isDone":true}],"timeElapsed":4,"testsFailed":0,"testsPassed":1,"testsPending":0,"status":"passed","timeStart":1493311691217},{"name":"buildApp - node - linux v6.10.2 - 2017-04-27T16:47:43.368Z","testCaseList":[{"name":"testCase_buildApidoc_default","status":"passed","errorStack":"","timeElapsed":1,"timeStart":1493311674796,"isDone":true},{"name":"testCase_buildApp_default","status":"passed","errorStack":"","timeElapsed":6517,"timeStart":1493311674798,"isDone":true},{"name":"testCase_buildCustomOrg_default","status":"passed","errorStack":"","timeElapsed":164,"timeStart":1493311675091,"isDone":true},{"name":"testCase_buildLib_default","status":"passed","errorStack":"","timeElapsed":1,"timeStart":1493311675231,"isDone":true},{"name":"testCase_buildReadme_default","status":"passed","errorStack":"","timeElapsed":0,"timeStart":1493311675232,"isDone":true},{"name":"testCase_buildTest_default","status":"passed","errorStack":"","timeElapsed":0,"timeStart":1493311675233,"isDone":true},{"name":"testCase_webpage_default","status":"passed","errorStack":"","timeElapsed":11979,"timeStart":1493311675233,"isDone":true}],"timeElapsed":22285,"testsFailed":0,"testsPassed":7,"testsPending":0,"status":"passed","timeStart":1493311664927},{"name":"npmTest - browser - / - Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Electron/1.4.16 Safari/537.36 - 2017-04-27T16:47:57.614Z","testCaseList":[{"name":"testCase_browser_nullCase","status":"passed","errorStack":"","timeElapsed":1,"timeStart":1493311677732,"isDone":true}],"timeStart":1493311677721,"timeElapsed":27,"testsFailed":0,"testsPassed":1,"testsPending":0,"status":"passed","screenCaptureImg":"screenCapture.npmTest.browser.%2F.png"},{"name":"npmTest - node - linux v6.10.2 - 2017-04-27T16:47:53.223Z","testCaseList":[],"timeElapsed":0,"testsFailed":0,"testsPassed":0,"testsPending":0,"status":"passed"}],"date":"2017-04-27T16:48:09.775Z","errorStackList":[],"timeElapsed":1445,"testsFailed":0,"testsPassed":9,"testsPending":0,"timeStart":1493311689777} \ No newline at end of file diff --git a/glyphicons_144_folder_open.png b/glyphicons_144_folder_open.png new file mode 100644 index 0000000..2834d37 Binary files /dev/null and b/glyphicons_144_folder_open.png differ diff --git a/heroku-logo.75x25.png b/heroku-logo.75x25.png new file mode 100644 index 0000000..981f0dc Binary files /dev/null and b/heroku-logo.75x25.png differ