diff --git a/Gruntfile.js b/Gruntfile.js new file mode 100644 index 0000000..57cd540 --- /dev/null +++ b/Gruntfile.js @@ -0,0 +1,151 @@ +const requirejs = require('requirejs'); +const amdclean = require('./build/amdclean'); +const fs = require("fs"); +const Jasmine = require('jasmine'); + +module.exports = function (grunt) { + function getHeaderText() { + let packageJson = JSON.parse(fs.readFileSync('./package.json', 'utf8')), + licenseText = '\n\n/*' + fs.readFileSync('./LICENSE.txt', 'utf8') + '\n*/\n\n', + currentDate = (function () { + var today = new Date(), + dd = today.getDate(), + mm = today.getMonth() + 1, + yyyy = today.getFullYear(); + + if (dd < 10) { + dd = '0' + dd + } + + if (mm < 10) { + mm = '0' + mm + } + + today = yyyy + '-' + mm + '-' + dd; + return today; + }()), + currentYear = (function () { + var today = new Date(), + yyyy = today.getFullYear(); + + return yyyy; + }()); + return '/*! amdclean - v' + packageJson.version + ' - ' + currentDate + + '\n* https://github.com/gfranko/amdclean' + + '\n* Copyright (c) ' + currentYear + ' Greg Franko */\n' + licenseText; + } + const header = getHeaderText(); + // Project configuration. + grunt.initConfig({ + pkg: grunt.file.readJSON('package.json'), + uglify: { + options: { + banner: header, + }, + build: { + src: 'src/amdclean.js', + dest: 'build/amdclean.min.js' + } + }, + jshint: { + amdclean: { + options: { + "loopfunc": true, + "evil": true, + }, + src: ['src/amdclean.js'], + }, + }, + requirejs: { + "./build/amdclean.optimized.js": { + 'findNestedDependencies': false, + 'baseUrl': './src/modules/', + 'optimize': 'none', + 'paths': { + 'amdclean': 'index' + }, + 'include': ['amdclean'], + } + }, + amdclean: { + "./build/amdclean.optimized.cleaned.js": { + 'filePath': "./build/amdclean.optimized.js", + 'transformAMDChecks': false, + 'aggressiveOptimizations': true, + 'ignoreModules': ['esprima', 'estraverse', 'escodegen', 'lodash', 'fs', 'sourcemap_to_ast'], // wtf? parsed name here? + 'removeUseStricts': false, + 'wrap': { + // All of the third party dependencies are hoisted here + // It's a hack, but it's not too painful + 'start': ';(function(esprima, estraverse, escodegen, _, sourcemapToAst) {\n', + 'end': '}(typeof esprima !== "undefined" ? esprima: null, typeof estraverse !== "undefined" ? estraverse: null, typeof escodegen !== "undefined" ? escodegen: null, typeof _ !== "undefined" ? _ : null, typeof sourcemapToAst !== "undefined" ? sourcemapToAst : null));' + }, + 'createAnonymousAMDModule': true + } + }, + prepend: { + "./src/amdclean.js": { + header: getHeaderText, + src: "./build/amdclean.optimized.cleaned.js", + } + } + }); + + // Load the plugin that provides the "uglify" task. + grunt.loadNpmTasks('grunt-contrib-uglify'); + grunt.loadNpmTasks('grunt-contrib-jshint'); + // Default task(s). + grunt.registerTask('build', ['requirejs', 'amdclean', 'prepend:./src/amdclean.js']); + grunt.registerTask('default', ['build', 'jshint:amdclean', 'test']); + + grunt.registerTask('lint', ['build', 'jshint:amdclean']); + grunt.registerTask('minify', ['build', 'jshint:amdclean', 'test', 'uglify']); + + + grunt.registerTask('test', 'Runs Jasmine on the Spec File', function() { + const cb = this.async(); + const jasmine = new Jasmine(); + jasmine.loadConfig({ + spec_dir: 'test/specs', + spec_files: [ + 'convert.js' + ] + }); + jasmine.exitOnCompletion = false; + jasmine.execute().then((data)=>{ + cb(data.overallStatus === "passed"); + }); + }); + + grunt.registerMultiTask('requirejs', 'Uses RequireJS to optimize a file', function () { + const target = this.target; + const data = this.data; + const cb = this.async(); + requirejs.optimize({ + ...data, + out: target, + 'onModuleBundleComplete': function (data) { + cb(); + } + }); + }); + + grunt.registerMultiTask('amdclean', "Uses AMDClean on a file", function () { + const target = this.target; + const data = this.data; + const code = amdclean.clean({ + ...data, + }); + fs.writeFileSync(target, code); + }); + grunt.registerMultiTask('prepend', 'Prepends some text to a file', function() { + const target = this.target; + const data = this.data; + let header = data.header; + if(typeof header === "function") { + header = header(); + } + const file = header + fs.readFileSync(data.src); + fs.writeFileSync(target, file); + }) +}; \ No newline at end of file diff --git a/build/amdclean.js b/build/amdclean.js index e81d779..8e5c09a 100644 --- a/build/amdclean.js +++ b/build/amdclean.js @@ -586,14 +586,14 @@ convertToFunctionExpression = function convertToFunctionExpression(obj) { }); callbackFunc.body.body = body; // Returns an array of all return statements - returnStatements = _.where(body, { 'type': 'ReturnStatement' }); - exportsExpressions = _.where(body, { + returnStatements = _.filter(body, { 'type': 'ReturnStatement' }); + exportsExpressions = _.filter(body, { 'left': { 'type': 'Identifier', 'name': 'exports' } }); - moduleExportsExpressions = _.where(body, { + moduleExportsExpressions = _.filter(body, { 'left': { 'type': 'MemberExpression', 'object': { @@ -647,7 +647,7 @@ convertToFunctionExpression = function convertToFunctionExpression(obj) { }(), hasReturnStatement = function () { var returns = []; if (callbackFunc && callbackFunc.body && _.isArray(callbackFunc.body.body)) { - returns = _.where(callbackFunc.body.body, { 'type': 'ReturnStatement' }); + returns = _.filter(callbackFunc.body.body, { 'type': 'ReturnStatement' }); if (returns.length) { return true; } @@ -655,10 +655,10 @@ convertToFunctionExpression = function convertToFunctionExpression(obj) { return false; }(), originalCallbackFuncParams, hasExportsParam = function () { var cbParams = callbackFunc.params || []; - return _.where(cbParams, { 'name': 'exports' }).length; + return _.filter(cbParams, { 'name': 'exports' }).length; }(), hasModuleParam = function () { var cbParams = callbackFunc.params || []; - return _.where(cbParams, { 'name': 'module' }).length; + return _.filter(cbParams, { 'name': 'module' }).length; }(), normalizeDependencyNames = {}, dependencyNames = function () { var deps = [], currentName; _.each(dependencies, function (currentDependency) { @@ -709,7 +709,7 @@ convertToFunctionExpression = function convertToFunctionExpression(obj) { if (node.id && node.id.name && node.init && node.init['arguments'] && node.init['arguments'][0] && node.init['arguments'][0].value) { variableName = node.id.name; expressionName = normalizeModuleName.call(amdclean, utils.normalizeDependencyName(moduleId, node.init['arguments'][0].value, moduleId)); - if (!_.contains(ignoreModules, expressionName) && variableName === expressionName) { + if (!_.includes(ignoreModules, expressionName) && variableName === expressionName) { matchingNames.push({ 'originalName': expressionName, 'newName': findNewParamName(expressionName), @@ -792,7 +792,7 @@ convertToFunctionExpression = function convertToFunctionExpression(obj) { 'count': 1 }]; } else { - mappedParameter = _.where(amdclean.callbackParameterMap[dependencyNames[iterator].name], { 'name': currentName }); + mappedParameter = _.filter(amdclean.callbackParameterMap[dependencyNames[iterator].name], { 'name': currentName }); if (mappedParameter.length) { mappedParameter = mappedParameter[0]; mappedParameter.count += 1; @@ -852,11 +852,11 @@ convertToFunctionExpression = function convertToFunctionExpression(obj) { if (utils.isRequireExpression(node)) { if (node['arguments'] && node['arguments'][0] && node['arguments'][0].value) { normalizedModuleName = normalizeModuleName.call(amdclean, utils.normalizeDependencyName(moduleId, node['arguments'][0].value, moduleId)); - if (_.contains(ignoreModules, normalizedModuleName)) { + if (_.includes(ignoreModules, normalizedModuleName)) { return node; } - if (_.where(matchingRequireExpressionNames, { 'originalName': normalizedModuleName }).length) { - newName = _.where(matchingRequireExpressionNames, { 'originalName': normalizedModuleName })[0].newName; + if (_.filter(matchingRequireExpressionNames, { 'originalName': normalizedModuleName }).length) { + newName = _.filter(matchingRequireExpressionNames, { 'originalName': normalizedModuleName })[0].newName; } return { 'type': 'Identifier', @@ -898,13 +898,13 @@ convertToObjectDeclaration = function (obj, type) { modReturnValue = obj.moduleReturnValue; callee = modReturnValue.callee; params = callee.params; - if (params && params.length && _.isArray(params) && _.where(params, { 'name': 'global' })) { + if (params && params.length && _.isArray(params) && _.filter(params, { 'name': 'global' })) { if (_.isObject(callee.body) && _.isArray(callee.body.body)) { - returnStatement = _.where(callee.body.body, { 'type': 'ReturnStatement' })[0]; + returnStatement = _.filter(callee.body.body, { 'type': 'ReturnStatement' })[0]; if (_.isObject(returnStatement) && _.isObject(returnStatement.argument) && returnStatement.argument.type === 'FunctionExpression') { internalFunctionExpression = returnStatement.argument; if (_.isObject(internalFunctionExpression.body) && _.isArray(internalFunctionExpression.body.body)) { - nestedReturnStatement = _.where(internalFunctionExpression.body.body, { 'type': 'ReturnStatement' })[0]; + nestedReturnStatement = _.filter(internalFunctionExpression.body.body, { 'type': 'ReturnStatement' })[0]; if (_.isObject(nestedReturnStatement.argument) && _.isObject(nestedReturnStatement.argument.right) && _.isObject(nestedReturnStatement.argument.right.property)) { if (nestedReturnStatement.argument.right.property.name) { modReturnValue = { @@ -1032,7 +1032,7 @@ convertDefinesAndRequires = function convertDefinesAndRequires(node, parent) { } else { deps = []; } - hasExportsParam = _.where(deps, { 'value': 'exports' }).length; + hasExportsParam = _.filter(deps, { 'value': 'exports' }).length; if (_.isArray(deps) && deps.length) { _.each(deps, function (currentDependency) { if (dependencyBlacklist[currentDependency.value] && !shouldOptimize) { @@ -1072,7 +1072,7 @@ convertDefinesAndRequires = function convertDefinesAndRequires(node, parent) { amdclean.options.ignoreModules.push(moduleName); return node; } - if (_.contains(options.removeModules, moduleName)) { + if (_.includes(options.removeModules, moduleName)) { // Remove the current module from the source return { 'type': 'EmptyStatement' }; } @@ -1089,7 +1089,7 @@ convertDefinesAndRequires = function convertDefinesAndRequires(node, parent) { } else if (params.moduleReturnValue && params.moduleReturnValue.type === 'Identifier') { type = 'functionExpression'; } - if (_.contains(options.ignoreModules, moduleName)) { + if (_.includes(options.ignoreModules, moduleName)) { return node; } else if (utils.isFunctionExpression(moduleReturnValue) || type === 'functionExpression') { return convertToFunctionExpression.call(amdclean, params); @@ -1116,16 +1116,16 @@ convertDefinesAndRequires = function convertDefinesAndRequires(node, parent) { } } else { // If the node is a function expression that has an exports parameter and does not return anything, return exports - if (node.type === 'FunctionExpression' && _.isArray(node.params) && _.where(node.params, { + if (node.type === 'FunctionExpression' && _.isArray(node.params) && _.filter(node.params, { 'type': 'Identifier', 'name': 'exports' - }).length && _.isObject(node.body) && _.isArray(node.body.body) && !_.where(node.body.body, { 'type': 'ReturnStatement' }).length) { + }).length && _.isObject(node.body) && _.isArray(node.body.body) && !_.filter(node.body.body, { 'type': 'ReturnStatement' }).length) { parentHasFunctionExpressionArgument = function () { if (!parent || !parent.arguments) { return false; } if (parent && parent.arguments && parent.arguments.length) { - return _.where(parent.arguments, { 'type': 'FunctionExpression' }).length; + return _.filter(parent.arguments, { 'type': 'FunctionExpression' }).length; } return false; }(); @@ -1432,7 +1432,7 @@ clean = function clean() { }, {})), hoistedCallbackParameters); // Creates variable declarations for each AMD module/callback parameter that needs to be hoisted _.each(hoistedVariables, function (moduleValue, moduleName) { - if (!_.contains(options.ignoreModules, moduleName)) { + if (!_.includes(options.ignoreModules, moduleName)) { var _initValue = amdclean.exportsModules[moduleName] !== true ? null : { type: 'ObjectExpression', properties: [] diff --git a/build/amdclean.min.js b/build/amdclean.min.js index d31b656..f209db6 100644 --- a/build/amdclean.min.js +++ b/build/amdclean.min.js @@ -1,6 +1,7 @@ -/*! amdclean - v2.7.0 - 2015-12-05 -* http://gregfranko.com/amdclean -* Copyright (c) 2015 Greg Franko */ +/*! amdclean - v2.7.0 - 2022-04-11 +* Modified work: https://github.com/6si/amdclean +* Original work: https://github.com/gfranko/amdclean +* Original Copyright (c) 2022 Greg Franko */ /*The MIT License (MIT) @@ -25,5 +26,4 @@ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -!function(esprima,estraverse,escodegen,_,sourcemapToAst){var defaultOptions,errorMsgs,defaultValues,utils,convertToIIFE,convertToIIFEDeclaration,normalizeModuleName,convertToFunctionExpression,convertToObjectDeclaration,createAst,convertDefinesAndRequires,traverseAndUpdateAst,getNormalizedModuleName,findAndStoreAllModuleIds,generateCode,clean;defaultOptions={code:"",sourceMap:null,filePath:"",globalModules:[],esprima:{comment:!0,loc:!0,range:!0,tokens:!0},escodegen:{comment:!0,format:{indent:{style:" ",adjustMultilineComment:!0}}},commentCleanName:"amdclean",ignoreModules:[],removeModules:[],removeAllRequires:!1,removeUseStricts:!0,transformAMDChecks:!0,createAnonymousAMDModule:!1,shimOverrides:{},prefixMode:"standard",prefixTransform:function(e,t){return e},wrap:{start:";(function() {\n",end:"\n}());"},aggressiveOptimizations:!1,config:{}},errorMsgs={emptyCode:"There is no code to generate the AST with",emptyAst:function(e){return"An AST is not being passed to the "+e+"() method"},invalidObject:function(e){return"An object is not being passed as the first parameter to the "+e+"() method"},lodash:"Make sure you have included lodash (https://github.com/lodash/lodash).",esprima:"Make sure you have included esprima (https://github.com/ariya/esprima).",estraverse:"Make sure you have included estraverse (https://github.com/Constellation/estraverse).",escodegen:"Make sure you have included escodegen (https://github.com/Constellation/escodegen).",sourcemapToAst:"Make sure you have included sourcemapToAst (https://github.com/tarruda/sourcemap-to-ast)."},defaultValues={dependencyBlacklist:{require:"remove",exports:!0,module:"remove"},defaultLOC:{start:{line:0,column:0}},defaultRange:[0,0]},utils=function(){var Utils={isDefine:function(e){var t=e.expression||{},n=t.callee;return _.isObject(e)&&"ExpressionStatement"===e.type&&t&&"CallExpression"===t.type&&"Identifier"===n.type&&"define"===n.name},isRequire:function(e){var t=e.expression||{},n=t.callee;return e&&"ExpressionStatement"===e.type&&t&&"CallExpression"===t.type&&"Identifier"===n.type&&"require"===n.name},isModuleExports:function(e){return e?"AssignmentExpression"===e.type&&e.left&&"MemberExpression"===e.left.type&&e.left.object&&"Identifier"===e.left.object.type&&"module"===e.left.object.name&&e.left.property&&"Identifier"===e.left.property.type&&"exports"===e.left.property.name:!1},isRequireExpression:function(e){return e&&"CallExpression"===e.type&&e.callee&&"require"===e.callee.name},isObjectExpression:function(e){return e&&e&&"ObjectExpression"===e.type},isFunctionExpression:function(e){return e&&e&&"FunctionExpression"===e.type},isFunctionCallExpression:function(e){return e&&e&&"CallExpression"===e.type&&e.callee&&"FunctionExpression"===e.callee.type},isUseStrict:function(e){return e&&e&&"use strict"===e.value&&"Literal"===e.type},isIfStatement:function(e){return e&&"IfStatement"===e.type&&e.test},isAMDConditional:function(e){if(!Utils.isIfStatement(e))return!1;var t={left:{operator:"typeof",argument:{type:"Identifier",name:"define"}},right:{type:"Literal",value:"function"}},n={left:t.right,right:t.left};try{return _.find(e.test,t)||_.find([e.test],t)||_.find(e.test,n)||_.find([e.test],n)||_.find(e.test.left||{},t)||_.find([e.test.left||{}],t)||_.find(e.test.left||{},n)||_.find([e.test.left||{}],n)}catch(r){return!1}},returnExpressionIdentifier:function(e){return{type:"ExpressionStatement",expression:{type:"Identifier",name:e,range:defaultValues.defaultRange,loc:defaultValues.defaultLOC},range:defaultValues.defaultRange,loc:defaultValues.defaultLOC}},readFile:function(e){if("undefined"!=typeof exports){var t=require("fs");return t.readFileSync(e,"utf8")}return""},isRelativeFilePath:function(e){var t=e.split("/");return-1!==t.length&&("."===t[0]||".."===t[0])},convertToCamelCase:function(e,t){return t=t||"_",e.replace(new RegExp(t+"(.)","g"),function(e,t){return t.toUpperCase()})},prefixReservedWords:function(name){var reservedWord=!1;try{name.length&&eval("var "+name+" = 1;")}catch(e){reservedWord=!0}return reservedWord===!0?"_"+name:name},normalizeDependencyName:function(e,t){if(!e||!t)return t;var n=function(){if(!t||-1===t.indexOf("!"))return"";var e=t.split("!");return t=e[1],e[0]+"!"}(),r=function(e){var t,n=e.split("/");return t=_.reduce(n,function(e,t){switch(t){case".":break;case"..":e.pop();break;default:e.push(t)}return e},[]),t.join("/")},a=function(e){var t=e.split("/");return t.pop(),t.join("/")};return Utils.isRelativeFilePath(t)?n+r([a(e),t].join("/")):n+t}};return Utils}(),convertToIIFE=function(e){var t=e.callbackFuncParams,n=e.callbackFunc,r=e.dependencyNames,a=e.node,o=a.range||defaultValues.defaultRange,s=a.loc||defaultValues.defaultLOC;return{type:"ExpressionStatement",expression:{type:"CallExpression",callee:{type:"FunctionExpression",id:null,params:t,defaults:[],body:n.body,rest:n.rest,generator:n.generator,expression:n.expression,range:o,loc:s},arguments:r,range:o,loc:s},range:o,loc:s}},convertToIIFEDeclaration=function(e){var t=this,n=t.options,r=e.moduleId,a=e.moduleName,o=e.hasModuleParam,s=e.hasExportsParam,i=e.callbackFuncParams,l=e.isOptimized,u=e.callbackFunc,c=e.node,p=u.name,d=u.type,m=c.range||defaultValues.defaultRange,f=c.loc||defaultValues.defaultLOC,g=function(){var t=e.callbackFunc;return"Identifier"===d&&"undefined"!==p&&(t={type:"FunctionExpression",id:null,params:[],defaults:[],body:{type:"BlockStatement",body:[{type:"ReturnStatement",argument:{type:"ConditionalExpression",test:{type:"BinaryExpression",operator:"===",left:{type:"UnaryExpression",operator:"typeof",argument:{type:"Identifier",name:p,range:m,loc:f},prefix:!0,range:m,loc:f},right:{type:"Literal",value:"function",raw:"'function'",range:m,loc:f},range:m,loc:f},consequent:{type:"CallExpression",callee:{type:"Identifier",name:p,range:m,loc:f},arguments:i,range:m,loc:f},alternate:{type:"Identifier",name:p,range:m,loc:f},range:m,loc:f},range:m,loc:f}],range:m,loc:f},rest:null,generator:!1,expression:!1,range:m,loc:f}),t}(),y=function(){var t,a=e.dependencyNames,i={type:"ObjectExpression",properties:[],range:m,loc:f},l={type:"MemberExpression",computed:!0,object:{type:"Identifier",name:"modules"},property:{type:"Literal",value:r}};if(n.config&&n.config[r]){if(s&&o)return[i,i,l];o&&(t=_.findIndex(a,function(e){return"{}"===e.name}),a[t]=l)}return a}(),h=function(){return"Literal"===g.type||"Identifier"===g.type&&"undefined"===g.name||l===!0?g:{type:"CallExpression",callee:{type:"FunctionExpression",id:{type:"Identifier",name:"",range:m,loc:f},params:i,defaults:[],body:g.body,rest:g.rest,generator:g.generator,expression:g.expression,range:m,loc:f},arguments:y,range:m,loc:f}}(),v={type:"ExpressionStatement",expression:{type:"AssignmentExpression",operator:"=",left:{type:"Identifier",name:n.IIFEVariableNameTransform?n.IIFEVariableNameTransform(a,r):a,range:m,loc:f},right:h,range:m,loc:f},range:m,loc:f};return estraverse.replace(g,{enter:function(e){return utils.isModuleExports(e)?{type:"AssignmentExpression",operator:"=",left:{type:"Identifier",name:"exports"},right:e.right}:e}}),v},normalizeModuleName=function(e,t){var n,r,a,o=this,s=o.options,i=s.prefixMode,l=s.prefixTransform,u=defaultValues.dependencyBlacklist;return e=e||"","{}"===e?"remove"===u[e]?"":e:(r=utils.prefixReservedWords(e.replace(/\./g,"").replace(/[^A-Za-z0-9_$]/g,"_").replace(/^_+/,"")),a="camelCase"===i?utils.convertToCamelCase(r):r,_.isFunction(l)&&(n=l(a,e),_.isString(n)&&n.length)?n:a)},convertToFunctionExpression=function(e){var t,n,r,a=this,o=a.options,s=o.ignoreModules,i=e.node,l=e.isDefine,u=e.isRequire,c=!1,p=e.moduleName,d=e.moduleId,m=e.dependencies,f=m.length,g=o.aggressiveOptimizations,y=[],h=[],v=defaultValues.defaultRange,b=defaultValues.defaultLOC,x=e.range||v,E=e.loc||b,M=e.shouldOptimize,A=defaultValues.dependencyBlacklist,I=!1,O=function(){var t,n,r,s,i=e.moduleReturnValue;if(i&&"FunctionExpression"===i.type&&i.body&&_.isArray(i.body.body)&&i.body.body.length){if(t=_.filter(i.body.body,function(e){return o.removeUseStricts===!0?!utils.isUseStrict(e.expression):e}),i.body.body=t,n=_.where(t,{type:"ReturnStatement"}),y=_.where(t,{left:{type:"Identifier",name:"exports"}}),h=_.where(t,{left:{type:"MemberExpression",object:{type:"Identifier",name:"module"},property:{type:"Identifier",name:"exports"}}}),n.length){if(r=n[0],s=r.argument,I=function(){var e=!1;return _.each(i.params,function(t){var n=t.name;a.storedModules[n]||A[n]||(e=!0)}),e}(),I||!M||!utils.isFunctionExpression(r)&&t.length>1||s&&"Identifier"===s.type)return i;i=s,c=!0,i.params&&(f=i.params.length)}}else i&&"FunctionExpression"===i.type&&i.body&&_.isArray(i.body.body)&&0===i.body.body.length&&(i={type:"Identifier",name:"undefined",range:x,loc:E},f=0);return i}(),w=function(){var e=[];return O&&O.body&&_.isArray(O.body.body)&&(e=_.where(O.body.body,{type:"ReturnStatement"}),e.length)?!0:!1}(),j=function(){var e=O.params||[];return _.where(e,{name:"exports"}).length}(),R=function(){var e=O.params||[];return _.where(e,{name:"module"}).length}(),N={},F=function(){var e,t=[];return _.each(m,function(n){e=normalizeModuleName.call(a,utils.normalizeDependencyName(d,n),d),N[e]=!0,t.push({type:"Identifier",name:e,range:v,loc:b})}),t}(),C=function P(e){e="_"+e+"_";var t=function(){var t=!1;return N[e]?t=!0:estraverse.traverse(O,{enter:function(n){"VariableDeclarator"===n.type&&n.id&&"Identifier"===n.id.type&&n.id.name===e&&(t=!0)}}),t}();return t?P(e):e},S=function(){var e=[];return j&&estraverse.traverse(O,{enter:function(t){var n,r;"VariableDeclarator"===t.type&&utils.isRequireExpression(t.init)&&t.id&&t.id.name&&t.init&&t.init.arguments&&t.init.arguments[0]&&t.init.arguments[0].value&&(n=t.id.name,r=normalizeModuleName.call(a,utils.normalizeDependencyName(d,t.init.arguments[0].value,d)),_.contains(s,r)||n!==r||e.push({originalName:r,newName:C(r),range:t.range||v,loc:t.loc||b}))}}),e}(),T=function(){var e=[];return _.each(S,function(t){e.push({type:"Identifier",name:t.newName?t.newName:t,range:t.range,loc:t.loc})}),e}(),V=function(){var e,n,r=[],o=_.union(O.params&&O.params.length?O.params:!M&&F&&F.length?F:[],T),s={},i=[];if(O.body){if(estraverse.traverse(O.body,{enter:function(e,t){("FunctionExpression"==e.type||"FunctionDeclaration"==e.type)&&i.push(e)}}),i.length)for(var l=O.body.range[0];l=e.range[1])&&(n+=a.options.code[l])});else n=a.options.code.substring(O.body.range[0],O.body.range[1]);/[^\w0-9_]arguments[^\w0-9_]/.test(n)&&(o=o.concat(F.slice(o.length)))}return _.each(o,function(t,n){e=t?t.name:F[n].name,M||"{}"===e?"{}"===e||j&&"remove"===defaultValues.dependencyBlacklist[e]||(r.push({type:"Identifier",name:e,range:v,loc:b}),c||g!==!0||a.storedModules[e]||!F[n]||(a.callbackParameterMap[F[n].name]?(s=_.where(a.callbackParameterMap[F[n].name],{name:e}),s.length?(s=s[0],s.count+=1):a.callbackParameterMap[F[n].name].push({name:e,count:1})):a.callbackParameterMap[F[n].name]=[{name:e,count:1}])):r.push({type:"Identifier",name:e,range:v,loc:b})}),t=r,_.filter(r||[],function(e){return g===!0&&M?!a.storedModules[e.name]:!0})}(),k=!w&&j,D=y.length||h.length;return F=_.filter(F||[],function(e,n){var r=t[n],o=e.name;return g===!0&&M?!r||a.storedModules[r.name]&&r.name===o?!a.storedModules[o]:!a.storedModules[r.name]:!0}),F=_.map(F||[],function(e,t){return A[e.name]&&(e.name="{}"),e}),n=F.length,r=V.length,n>r&&F.splice(r,n-r),k&&D&&O.body.body.push({type:"ReturnStatement",argument:{type:"Identifier",name:"exports",range:v,loc:b},range:v,loc:b}),estraverse.replace(O,{enter:function(e){var t,n;return utils.isRequireExpression(e)?e.arguments&&e.arguments[0]&&e.arguments[0].value?(t=normalizeModuleName.call(a,utils.normalizeDependencyName(d,e.arguments[0].value,d)),_.contains(s,t)?e:(_.where(S,{originalName:t}).length&&(n=_.where(S,{originalName:t})[0].newName),{type:"Identifier",name:n?n:t,range:e.range||v,loc:e.loc||b})):e:void 0}}),l?convertToIIFEDeclaration.call(a,{moduleId:d,moduleName:p,dependencyNames:F,callbackFuncParams:V,hasModuleParam:R,hasExportsParam:j,callbackFunc:O,isOptimized:c,node:i}):u?convertToIIFE.call(a,{dependencyNames:F,callbackFuncParams:V,callbackFunc:O,node:i}):void 0},convertToObjectDeclaration=function(e,t){var n=e.node,r=defaultValues.defaultRange,a=defaultValues.defaultLOC,o=n.range||r,s=n.loc||a,i=e.moduleName,l=function(){var n,r,a,i,l,u;return"functionCallExpression"===t&&(n=e.moduleReturnValue,r=n.callee,a=r.params,a&&a.length&&_.isArray(a)&&_.where(a,{name:"global"})&&_.isObject(r.body)&&_.isArray(r.body.body)&&(i=_.where(r.body.body,{type:"ReturnStatement"})[0],_.isObject(i)&&_.isObject(i.argument)&&"FunctionExpression"===i.argument.type&&(u=i.argument,_.isObject(u.body)&&_.isArray(u.body.body)&&(l=_.where(u.body.body,{type:"ReturnStatement"})[0],_.isObject(l.argument)&&_.isObject(l.argument.right)&&_.isObject(l.argument.right.property)&&l.argument.right.property.name&&(n={type:"MemberExpression",computed:!1,object:{type:"Identifier",name:"window",range:o,loc:s},property:{type:"Identifier",name:l.argument.right.property.name,range:o,loc:s},range:o,loc:s}))))),n=n||e.moduleReturnValue}(),u={type:"ExpressionStatement",expression:{type:"AssignmentExpression",operator:"=",left:{type:"Identifier",name:i,range:o,loc:s},right:l,range:o,loc:s},range:o,loc:s};return u},createAst=function(e){var t=this,n=t.options,r=n.filePath,a=e||n.code||(r?utils.readFile(r):""),o=n.esprima,s=n.escodegen;if(a){if(!_.isPlainObject(esprima)||!_.isFunction(esprima.parse))throw new Error(errorMsgs.esprima);var i=esprima.parse(a,o);if(n.sourceMap&&sourcemapToAst(i,n.sourceMap),o.comment===!0&&s.comment===!0)try{i=escodegen.attachComments(i,i.comments,i.tokens)}catch(l){}return i}throw new Error(errorMsgs.emptyCode)},convertDefinesAndRequires=function(e,t){var n,r,a,o,s,i,l,u,c,p,d=this,m=d.options,f=utils.isDefine(e),g=utils.isRequire(e),y=!1,h="",v=defaultValues.defaultRange,b=defaultValues.defaultLOC,x=e.range||v,E=e.loc||b,M=defaultValues.dependencyBlacklist;if(l=f||g?e.expression.loc.start.line:e&&e.loc&&e.loc.start?e.loc.start.line:null,u=d.matchingCommentLineNumbers[l]||d.matchingCommentLineNumbers[l-1],utils.isAMDConditional(e)&&(estraverse.traverse(e,{enter:function(e){var t;utils.isDefine(e)&&e.expression&&e.expression.arguments&&e.expression.arguments.length&&"Literal"===e.expression.arguments[0].type&&e.expression.arguments[0].value&&(t=normalizeModuleName.call(d,e.expression.arguments[0].value),m.transformAMDChecks!==!0?d.conditionalModulesToIgnore[t]=!0:d.conditionalModulesToNotOptimize[t]=!0,m.createAnonymousAMDModule===!0&&(d.storedModules[t]=!1,e.expression.arguments.shift()))}}),!u&&m.transformAMDChecks===!0))return e.test={type:"Literal",value:!0,raw:"true",range:x,loc:E},e;if(!f&&!g)return"FunctionExpression"===e.type&&_.isArray(e.params)&&_.where(e.params,{type:"Identifier",name:"exports"}).length&&_.isObject(e.body)&&_.isArray(e.body.body)&&!_.where(e.body.body,{type:"ReturnStatement"}).length&&(c=function(){return t&&t.arguments&&t&&t.arguments&&t.arguments.length?_.where(t.arguments,{type:"FunctionExpression"}).length:!1}(),c&&e.body.body.unshift({type:"ExpressionStatement",expression:{type:"AssignmentExpression",operator:"=",left:{type:"Identifier",name:"exports",range:v,loc:b},right:{type:"LogicalExpression",operator:"||",left:{type:"Identifier",name:"exports",range:v,loc:b},right:{type:"ObjectExpression",properties:[],range:v,loc:b},range:v,loc:b},range:v,loc:b},range:v,loc:b}),e.body.body.push({type:"ReturnStatement",argument:{type:"Identifier",name:"exports",range:v,loc:b},range:v,loc:b})),e;if(r=Array.prototype.slice.call(e.expression.arguments,0),o=g?r[1]:r[r.length-1],s=e.expression.arguments[0].value,n=normalizeModuleName.call(d,s),p=!d.conditionalModulesToNotOptimize[n],a=function(){var e,t=g?r[0]:r[r.length-2],a=[];return t=_.isPlainObject(t)?t.elements||[]:[],e=_.where(t,{value:"exports"}).length,_.isArray(t)&&t.length&&_.each(t,function(t){M[t.value]&&!p?a.push(t.value):"remove"!==M[t.value]?"exports"===t.value?(a.push(n),d.exportsModules[n]=!0):M[t.value]?a.push("{}"):a.push(t.value):e||a.push("{}")}),a}(),i={node:e,moduleName:n,moduleId:s,dependencies:a,moduleReturnValue:o,isDefine:f,isRequire:g,range:x,loc:E,shouldOptimize:p},f){if(u||!n||d.conditionalModulesToIgnore[n]===!0)return d.options.ignoreModules.push(n),e;if(_.contains(m.removeModules,n))return{type:"EmptyStatement"};if(_.isObject(m.shimOverrides)&&m.shimOverrides[s]?(i.moduleReturnValue=createAst.call(d,m.shimOverrides[s]),_.isArray(i.moduleReturnValue.body)&&_.isObject(i.moduleReturnValue.body[0])?_.isObject(i.moduleReturnValue.body[0].expression)&&(i.moduleReturnValue=i.moduleReturnValue.body[0].expression,h="objectExpression"):i.moduleReturnValue=o):i.moduleReturnValue&&"Identifier"===i.moduleReturnValue.type&&(h="functionExpression"),_.contains(m.ignoreModules,n))return e;if(utils.isFunctionExpression(o)||"functionExpression"===h)return convertToFunctionExpression.call(d,i);if(utils.isObjectExpression(o)||"objectExpression"===h)return convertToObjectDeclaration.call(d,i);if(utils.isFunctionCallExpression(o))return convertToObjectDeclaration.call(d,i,"functionCallExpression")}else if(g)return u?e:(y=_.isArray(e.expression.arguments)&&e.expression.arguments.length?e.expression.arguments[1]&&e.expression.arguments[1].body&&e.expression.arguments[1].body.body&&e.expression.arguments[1].body.body.length:!1,m.removeAllRequires!==!0&&y?convertToFunctionExpression.call(d,i):{type:"EmptyStatement",range:x,loc:E})},traverseAndUpdateAst=function(e){var t=this,n=t.options,r=e.ast;if(!_.isPlainObject(e))throw new Error(errorMsgs.invalidObject("traverseAndUpdateAst"));if(!r)throw new Error(errorMsgs.emptyAst("traverseAndUpdateAst"));if(!_.isPlainObject(estraverse)||!_.isFunction(estraverse.replace))throw new Error(errorMsgs.estraverse);return estraverse.replace(r,{enter:function(e,r){var a;return"Program"===e.type?(a=function(){var r=[];return t.comments=e.comments,_.each(e.comments,function(e){var t=e.value.trim();t===n.commentCleanName&&r.push(e)}),r}(),_.each(a,function(e){currentLineNumber=e.loc.start.line,t.matchingCommentLineNumbers[currentLineNumber]=!0}),e):convertDefinesAndRequires.call(t,e,r)},leave:function(e){return e}}),r},getNormalizedModuleName=function(e){if(utils.isDefine(e)){var t=this,n=e.expression.arguments[0].value,r=normalizeModuleName.call(t,n);return r}},findAndStoreAllModuleIds=function(e){var t=this;if(!e)throw new Error(errorMsgs.emptyAst("findAndStoreAllModuleIds"));if(!_.isPlainObject(estraverse)||!_.isFunction(estraverse.traverse))throw new Error(errorMsgs.estraverse);estraverse.traverse(e,{enter:function(e,n){var r=getNormalizedModuleName.call(t,e,n);r&&!t.storedModules[r]&&(t.storedModules[r]=!0),"ReturnStatement"===e.type&&e.argument&&e.argument.callee&&"define"===e.argument.callee.name&&(e.type="ExpressionStatement",e.expression=e.argument,delete e.argument)}})},generateCode=function(e){var t=this,n=t.options,r=n.escodegen||{};if(!_.isPlainObject(escodegen)||!_.isFunction(escodegen.generate))throw new Error(errorMsgs.escodegen);return escodegen.generate(e,r)},clean=function(){var e,t=this,n=t.options,r=n.ignoreModules,a={},o={},s={},i=[],l={},u={},c=defaultValues.defaultRange,p=defaultValues.defaultLOC;return a=createAst.call(t),findAndStoreAllModuleIds.call(t,a),o=traverseAndUpdateAst.call(t,{ast:a}),o&&_.isArray(o.body)&&estraverse.replace(o,{enter:function(e,a){var o,s,i,l=e&&e.left&&e.left.name?e.left.name:"",u=e.right,d=[],m={},f=_.filter(t.callbackParameterMap[l],function(e){return e&&e.count>1}),g=[];if(void 0===e||"EmptyStatement"===e.type)_.each(a.body,function(e,t){(void 0===e||"EmptyStatement"===e.type)&&a.body.splice(t,1)});else{if(utils.isRequireExpression(e))return e.arguments&&e.arguments[0]&&e.arguments[0].value?(o=normalizeModuleName.call(t,e.arguments[0].value),-1===r.indexOf(o)?{type:"Identifier",name:o,range:e.range||c,loc:e.loc||p}:e):e;if(n.aggressiveOptimizations===!0&&"AssignmentExpression"===e.type&&l&&(i=_.map(u&&u.callee&&u.callee.params?u.callee.params:[],function(e){return e.name}),s=_.map(u.arguments,function(e){return e.name}),_.each(s,function(e){_.each(t.callbackParameterMap[e],function(e){var t=e.name,n=e.count;_.each(i,function(e,r){n>1&&t===e&&g.push(r)})})}),_.each(g,function(e){u.arguments.splice(e,e+1),u.callee.params.splice(e,e+1)}),t.callbackParameterMap[l]))return e.right=function(){return n.aggressiveOptimizations===!0&&f.length?(d=_.map(f,function(e,t){return{type:"AssignmentExpression",operator:"=",left:{type:"Identifier",name:e.name,range:c,loc:p},right:t1&&(e=t.name,n[e]=!0)})}),n}(),l=_.merge(_.cloneDeep(_.reduce(t.storedModules,function(e,t,n){return t!==!1&&(e[n]=!0),e},{})),u),_.each(l,function(e,r){if(!_.contains(n.ignoreModules,r)){var a=t.exportsModules[r]!==!0?null:{type:"ObjectExpression",properties:[]};i.push({type:"VariableDeclarator",id:{type:"Identifier",name:r,range:c,loc:p},init:a,range:c,loc:p})}}),_.isObject(n.config)&&!_.isEmpty(n.config)&&(s=function(){var e=[];return _.each(n.config,function(r,a){var o=n.config[a];e.push({type:"Property",key:{type:"Literal",value:a},value:{type:"ObjectExpression",properties:[{type:"Property",key:{type:"Literal",value:"config"},value:{type:"FunctionExpression",id:null,params:[],defaults:[],body:{type:"BlockStatement",body:[{type:"ReturnStatement",argument:createAst.call(t,"var x ="+JSON.stringify(o)).body[0].declarations[0].init}]}},kind:"init"}]}})}),{type:"VariableDeclarator",id:{type:"Identifier",name:"modules"},init:{type:"ObjectExpression",properties:e}}}(),i.push(s)),i.length&&o.body.unshift({type:"VariableDeclaration",declarations:i,kind:"var",range:c,loc:p}),e=generateCode.call(t,o),_.isObject(n.wrap)&&(_.isString(n.wrap.start)&&n.wrap.start.length&&(e=n.wrap.start+e),_.isString(n.wrap.end)&&n.wrap.end.length&&(e+=n.wrap.end)),e},function(){!function(e,t,n){"use strict";"function"==typeof define&&define.amd?(t.amd=!0,define(["esprima","estraverse","escodegen","underscore","sourcemap-to-ast"],function(n,r,a,o,s){return t({esprima:n,estraverse:r,escodegen:a,underscore:o,sourcemapToAst:s},e)})):"undefined"!=typeof exports?(t.commonjs=!0,module.exports=t(null,e)):e.amdclean=t(null,e)}(this,function e(t,n){"use strict";sourcemapToAst=function(){return e.amd&&t&&t.sourcemapToAst?t.sourcemapToAst:e.commonjs?require("sourcemap-to-ast"):n&&n.sourcemapToAst?n.sourcemapToAst:void 0}(),esprima=function(){return e.amd&&t&&t.esprima&&t.esprima.parse?t.esprima:e.commonjs?require("esprima"):n&&n.esprima&&n.esprima.parse?n.esprima:void 0}(),estraverse=function(){return e.amd&&t&&t.estraverse&&t.estraverse.traverse?t.estraverse:e.commonjs?require("estraverse"):n&&n.estraverse&&n.estraverse.traverse?n.estraverse:void 0}(),escodegen=function(){return e.amd&&t&&t.escodegen&&t.escodegen.generate?t.escodegen:e.commonjs?require("escodegen"):n&&n.escodegen&&n.escodegen.generate?n.escodegen:void 0}(),_=function(){return e.amd&&t&&(t.underscore||t.lodash||t._)?t.underscore||t.lodash||t._:e.commonjs?require("lodash"):n&&n._?n._:void 0}();var r=function(e,t){if(!esprima)throw new Error(errorMsgs.esprima);if(!estraverse)throw new Error(errorMsgs.estraverse);if(!escodegen)throw new Error(errorMsgs.escodegen);if(!_)throw new Error(errorMsgs.lodash);if(!sourcemapToAst&&"undefined"==typeof window)throw new Error(errorMsgs.sourcemapToAst);var n=_.cloneDeep(this.defaultOptions||{}),r=e||t||{};!_.isPlainObject(e)&&_.isString(e)&&(r=_.merge({code:e},_.isObject(t)?t:{})),this.storedModules={},this.originalAst={},this.callbackParameterMap={},this.conditionalModulesToIgnore={},this.conditionalModulesToNotOptimize={},this.matchingCommentLineNumbers={},this.comments=[],this.exportsModules={},this.options=_.merge(n,r)},a={VERSION:"2.7.0",clean:function(e,t){var n=new r(e,t),a=n.clean();return a}};return r.prototype={clean:clean,defaultOptions:defaultOptions},a})}()}("undefined"!=typeof esprima?esprima:null,"undefined"!=typeof estraverse?estraverse:null,"undefined"!=typeof escodegen?escodegen:null,"undefined"!=typeof _?_:null,"undefined"!=typeof sourcemapToAst?sourcemapToAst:null); \ No newline at end of file +!function(esprima,estraverse,escodegen,_,sourcemapToAst){var defaultOptions,errorMsgs,defaultValues,utils,convertToIIFE,convertToIIFEDeclaration,normalizeModuleName,convertToFunctionExpression,convertToObjectDeclaration,createAst,convertDefinesAndRequires,traverseAndUpdateAst,getNormalizedModuleName,findAndStoreAllModuleIds,generateCode,clean,defaultOptions={code:"",sourceMap:null,filePath:"",globalModules:[],esprima:{comment:!0,loc:!0,range:!0,tokens:!0},escodegen:{comment:!0,format:{indent:{style:" ",adjustMultilineComment:!0}}},commentCleanName:"amdclean",ignoreModules:[],removeModules:[],removeAllRequires:!1,removeUseStricts:!0,transformAMDChecks:!0,createAnonymousAMDModule:!1,shimOverrides:{},prefixMode:"standard",prefixTransform:function(e,t){return e},wrap:{start:";(function() {\n",end:"\n}());"},aggressiveOptimizations:!1,config:{}},errorMsgs={emptyCode:"There is no code to generate the AST with",emptyAst:function(e){return"An AST is not being passed to the "+e+"() method"},invalidObject:function(e){return"An object is not being passed as the first parameter to the "+e+"() method"},lodash:"Make sure you have included lodash (https://github.com/lodash/lodash).",esprima:"Make sure you have included esprima (https://github.com/ariya/esprima).",estraverse:"Make sure you have included estraverse (https://github.com/Constellation/estraverse).",escodegen:"Make sure you have included escodegen (https://github.com/Constellation/escodegen).",sourcemapToAst:"Make sure you have included sourcemapToAst (https://github.com/tarruda/sourcemap-to-ast)."},defaultValues={dependencyBlacklist:{require:"remove",exports:!0,module:"remove"},defaultLOC:{start:{line:0,column:0}},defaultRange:[0,0]},utils=function(){var Utils={isDefine:function(e){var t=e.expression||{},n=t.callee;return _.isObject(e)&&"ExpressionStatement"===e.type&&t&&"CallExpression"===t.type&&"Identifier"===n.type&&"define"===n.name},isRequire:function(e){var t=e.expression||{},n=t.callee;return e&&"ExpressionStatement"===e.type&&t&&"CallExpression"===t.type&&"Identifier"===n.type&&"require"===n.name},isModuleExports:function(e){return!!e&&("AssignmentExpression"===e.type&&e.left&&"MemberExpression"===e.left.type&&e.left.object&&"Identifier"===e.left.object.type&&"module"===e.left.object.name&&e.left.property&&"Identifier"===e.left.property.type&&"exports"===e.left.property.name)},isRequireExpression:function(e){return e&&"CallExpression"===e.type&&e.callee&&"require"===e.callee.name},isObjectExpression:function(e){return e&&"ObjectExpression"===e.type},isFunctionExpression:function(e){return e&&"FunctionExpression"===e.type},isFunctionCallExpression:function(e){return e&&"CallExpression"===e.type&&e.callee&&"FunctionExpression"===e.callee.type},isUseStrict:function(e){return e&&"use strict"===e.value&&"Literal"===e.type},isIfStatement:function(e){return e&&"IfStatement"===e.type&&e.test},isAMDConditional:function(e){if(!Utils.isIfStatement(e))return!1;var t={left:{operator:"typeof",argument:{type:"Identifier",name:"define"}},right:{type:"Literal",value:"function"}},n={left:t.right,right:t.left};try{return _.find(e.test,t)||_.find([e.test],t)||_.find(e.test,n)||_.find([e.test],n)||_.find(e.test.left||{},t)||_.find([e.test.left||{}],t)||_.find(e.test.left||{},n)||_.find([e.test.left||{}],n)}catch(e){return!1}},returnExpressionIdentifier:function(e){return{type:"ExpressionStatement",expression:{type:"Identifier",name:e,range:defaultValues.defaultRange,loc:defaultValues.defaultLOC},range:defaultValues.defaultRange,loc:defaultValues.defaultLOC}},readFile:function(e){return"undefined"!=typeof exports?require("fs").readFileSync(e,"utf8"):""},isRelativeFilePath:function(e){e=e.split("/");return-1!==e.length&&("."===e[0]||".."===e[0])},convertToCamelCase:function(e,t){return t=t||"_",e.replace(new RegExp(t+"(.)","g"),function(e,t){return t.toUpperCase()})},prefixReservedWords:function(name){var reservedWord=!1;try{name.length&&eval("var "+name+" = 1;")}catch(e){reservedWord=!0}return!0===reservedWord?"_"+name:name},normalizeDependencyName:function(e,t){if(!e||!t)return t;var n=function(){if(!t||-1===t.indexOf("!"))return"";var e=t.split("!");return t=e[1],e[0]+"!"}();return Utils.isRelativeFilePath(t)?n+function(e){e=e.split("/");return _.reduce(e,function(e,t){switch(t){case".":break;case"..":e.pop();break;default:e.push(t)}return e},[]).join("/")}([function(e){e=e.split("/");return e.pop(),e.join("/")}(e),t].join("/")):n+t}};return Utils}(),convertToIIFE=function(e){var t=e.callbackFuncParams,n=e.callbackFunc,r=e.dependencyNames,e=e.node,a=e.range||defaultValues.defaultRange,e=e.loc||defaultValues.defaultLOC;return{type:"ExpressionStatement",expression:{type:"CallExpression",callee:{type:"FunctionExpression",id:null,params:t,defaults:[],body:n.body,rest:n.rest,generator:n.generator,expression:n.expression,range:a,loc:e},arguments:r,range:a,loc:e},range:a,loc:e}},convertToIIFEDeclaration=function(r){var a=this.options,o=r.moduleId,e=r.moduleName,s=r.hasModuleParam,i=r.hasExportsParam,t=r.callbackFuncParams,n=r.isOptimized,l=r.callbackFunc,u=r.node,c=l.name,l=l.type,p=u.range||defaultValues.defaultRange,d=u.loc||defaultValues.defaultLOC,l=(u=r.callbackFunc,u="Identifier"===l&&"undefined"!==c?{type:"FunctionExpression",id:null,params:[],defaults:[],body:{type:"BlockStatement",body:[{type:"ReturnStatement",argument:{type:"ConditionalExpression",test:{type:"BinaryExpression",operator:"===",left:{type:"UnaryExpression",operator:"typeof",argument:{type:"Identifier",name:c,range:p,loc:d},prefix:!0,range:p,loc:d},right:{type:"Literal",value:"function",raw:"'function'",range:p,loc:d},range:p,loc:d},consequent:{type:"CallExpression",callee:{type:"Identifier",name:c,range:p,loc:d},arguments:t,range:p,loc:d},alternate:{type:"Identifier",name:c,range:p,loc:d},range:p,loc:d},range:p,loc:d}],range:p,loc:d},rest:null,generator:!1,expression:!1,range:p,loc:d}:u),c=function(){var e=r.dependencyNames,t={type:"ObjectExpression",properties:[],range:p,loc:d},n={type:"MemberExpression",computed:!0,object:{type:"Identifier",name:"modules"},property:{type:"Literal",value:o}};if(a.config&&a.config[o]){if(i&&s)return[t,t,n];s&&(e[_.findIndex(e,function(e){return"{}"===e.name})]=n)}return e}(),u="Literal"===l.type||"Identifier"===l.type&&"undefined"===l.name||!0===n?l:{type:"CallExpression",callee:{type:"FunctionExpression",id:{type:"Identifier",name:"",range:p,loc:d},params:t,defaults:[],body:l.body,rest:l.rest,generator:l.generator,expression:l.expression,range:p,loc:d},arguments:c,range:p,loc:d},n={type:"ExpressionStatement",expression:{type:"AssignmentExpression",operator:"=",left:{type:"Identifier",name:a.IIFEVariableNameTransform?a.IIFEVariableNameTransform(e,o):e,range:p,loc:d},right:u,range:p,loc:d},range:p,loc:d};return estraverse.replace(l,{enter:function(e){return utils.isModuleExports(e)?{type:"AssignmentExpression",operator:"=",left:{type:"Identifier",name:"exports"},right:e.right}:e}}),n},normalizeModuleName=function(e,t){var n=this.options,r=n.prefixMode,n=n.prefixTransform,a=defaultValues.dependencyBlacklist;return"{}"===(e=e||"")?"remove"===a[e]?"":e:(a=utils.prefixReservedWords(e.replace(/\./g,"").replace(/[^A-Za-z0-9_$]/g,"_").replace(/^_+/,"")),r="camelCase"===r?utils.convertToCamelCase(a):a,_.isFunction(n)&&(a=n(r,e),_.isString(a)&&a.length)?a:r)},convertToFunctionExpression=function(o){function r(t){var n;return n=!1,C[t="_"+t+"_"]?n=!0:estraverse.traverse(w,{enter:function(e){"VariableDeclarator"===e.type&&e.id&&"Identifier"===e.id.type&&e.id.name===t&&(n=!0)}}),n?r(t):t}var i,e,t,a,n,s,l=this,u=l.options,c=u.ignoreModules,p=o.node,d=o.isDefine,m=o.isRequire,f=!1,g=o.moduleName,y=o.moduleId,h=o.dependencies,v=(h.length,u.aggressiveOptimizations),b=[],x=[],E=defaultValues.defaultRange,M=defaultValues.defaultLOC,A=o.range||E,I=o.loc||M,O=o.shouldOptimize,j=defaultValues.dependencyBlacklist,w=function(){var e,t,n,r,a=o.moduleReturnValue;if(a&&"FunctionExpression"===a.type&&a.body&&_.isArray(a.body.body)&&a.body.body.length){if(e=_.filter(a.body.body,function(e){return!0===u.removeUseStricts?!utils.isUseStrict(e.expression):e}),a.body.body=e,t=_.filter(e,{type:"ReturnStatement"}),b=_.filter(e,{left:{type:"Identifier",name:"exports"}}),x=_.filter(e,{left:{type:"MemberExpression",object:{type:"Identifier",name:"module"},property:{type:"Identifier",name:"exports"}}}),t.length){if(n=(t=t[0]).argument,r=!1,_.each(a.params,function(e){e=e.name;l.storedModules[e]||j[e]||(r=!0)}),r||!O||!utils.isFunctionExpression(t)&&1=e.range[1])&&(t+=l.options.code[s])});else t=l.options.code.substring(w.body.range[0],w.body.range[1]);/[^\w0-9_]arguments[^\w0-9_]/.test(t)&&(e=e.concat(S.slice(e.length)))}return _.each(e,function(e,t){n=(e||S[t]).name,O||"{}"===n?"{}"===n||F&&"remove"===defaultValues.dependencyBlacklist[n]||(r.push({type:"Identifier",name:n,range:E,loc:M}),f||!0!==v||l.storedModules[n]||!S[t]||(l.callbackParameterMap[S[t].name]?(a=_.filter(l.callbackParameterMap[S[t].name],{name:n})).length?(a=a[0]).count+=1:l.callbackParameterMap[S[t].name].push({name:n,count:1}):l.callbackParameterMap[S[t].name]=[{name:n,count:1}])):r.push({type:"Identifier",name:n,range:E,loc:M})}),i=r,_.filter(r||[],function(e){return!0!==v||!O||!l.storedModules[e.name]})}(),R=!R&&F,D=b.length||x.length,S=_.filter(S||[],function(e,t){t=i[t],e=e.name;return!0!==v||!O||(!t||l.storedModules[t.name]&&t.name===e?!l.storedModules[e]:!l.storedModules[t.name])}),k=(S=_.map(S||[],function(e,t){return j[e.name]&&(e.name="{}"),e})).length;return(e=h.length) if(true) {} + 'transformAMDChecks': true, + // Determines if a named or anonymous AMD module will be created inside of your conditional AMD check + // Note: This is only applicable to JavaScript libraries, do not change this for web apps + // If set to true: e.g. define('example', [], function() {}) -> define([], function() {}) + 'createAnonymousAMDModule': false, + // Allows you to pass an expression that will override shimmed modules return values + // e.g. { 'backbone': 'window.Backbone' } + 'shimOverrides': {}, + // Determines how to prefix a module name with when a non-JavaScript compatible character is found + // 'standard' or 'camelCase' + // 'standard' example: 'utils/example' -> 'utils_example' + // 'camelCase' example: 'utils/example' -> 'utilsExample' + 'prefixMode': 'standard', + // A function hook that allows you add your own custom logic to how each module name is prefixed/normalized + 'prefixTransform': function (postNormalizedModuleName, preNormalizedModuleName) { + return postNormalizedModuleName; + }, + // Wrap any build bundle in a start and end text specified by wrap + // This should only be used when using the onModuleBundleComplete RequireJS Optimizer build hook + // If it is used with the onBuildWrite RequireJS Optimizer build hook, each module will get wrapped + 'wrap': { + 'start': ';(function() {\n', + 'end': '\n}());' + }, + // Determines if certain aggressive file size optimization techniques will be used to transform the soure code + 'aggressiveOptimizations': false, + // Configuration info for modules + // Note: Further info can be found here - http://requirejs.org/docs/api.html#config-moduleconfig + 'config': {} +}; +errorMsgs = { + // The user has not supplied the cliean method with any code + 'emptyCode': 'There is no code to generate the AST with', + // An AST has not been correctly returned by Esprima + 'emptyAst': function (methodName) { + return 'An AST is not being passed to the ' + methodName + '() method'; + }, + // A parameter is not an object literal (which is expected) + 'invalidObject': function (methodName) { + return 'An object is not being passed as the first parameter to the ' + methodName + '() method'; + }, + // Third-party dependencies have not been included on the page + 'lodash': 'Make sure you have included lodash (https://github.com/lodash/lodash).', + 'esprima': 'Make sure you have included esprima (https://github.com/ariya/esprima).', + 'estraverse': 'Make sure you have included estraverse (https://github.com/Constellation/estraverse).', + 'escodegen': 'Make sure you have included escodegen (https://github.com/Constellation/escodegen).', + 'sourcemapToAst': 'Make sure you have included sourcemapToAst (https://github.com/tarruda/sourcemap-to-ast).' +}; +defaultValues = { + // dependencyBlacklist + // ------------------- + // Variable names that are not allowed as dependencies to functions + 'dependencyBlacklist': { + 'require': 'remove', + 'exports': true, + 'module': 'remove' + }, + // defaultLOC + // ---------- + // Default line of code property + 'defaultLOC': { + 'start': { + 'line': 0, + 'column': 0 + } + }, + // defaultRange + // ------------ + // Default range property + 'defaultRange': [ + 0, + 0 + ] +}; +utils = function () { + var Utils = { + // isDefine + // -------- + // Returns if the current AST node is a define() method call + 'isDefine': function (node) { + var expression = node.expression || {}, callee = expression.callee; + return _.isObject(node) && node.type === 'ExpressionStatement' && expression && expression.type === 'CallExpression' && callee.type === 'Identifier' && callee.name === 'define'; + }, + // isRequire + // --------- + // Returns if the current AST node is a require() method call + 'isRequire': function (node) { + var expression = node.expression || {}, callee = expression.callee; + return node && node.type === 'ExpressionStatement' && expression && expression.type === 'CallExpression' && callee.type === 'Identifier' && callee.name === 'require'; + }, + // isModuleExports + // --------------- + // Is a module.exports member expression + 'isModuleExports': function (node) { + if (!node) { + return false; + } + return node.type === 'AssignmentExpression' && node.left && node.left.type === 'MemberExpression' && node.left.object && node.left.object.type === 'Identifier' && node.left.object.name === 'module' && node.left.property && node.left.property.type === 'Identifier' && node.left.property.name === 'exports'; + }, + // isRequireExpression + // ------------------- + // Returns if the current AST node is a require() call expression + // e.g. var example = require('someModule'); + 'isRequireExpression': function (node) { + return node && node.type === 'CallExpression' && node.callee && node.callee.name === 'require'; + }, + // isObjectExpression + // ------------------ + // Returns if the current AST node is an object literal + 'isObjectExpression': function (expression) { + return expression && expression && expression.type === 'ObjectExpression'; + }, + // isFunctionExpression + // -------------------- + // Returns if the current AST node is a function + 'isFunctionExpression': function (expression) { + return expression && expression && expression.type === 'FunctionExpression'; + }, + // isFunctionCallExpression + // ------------------------ + // Returns if the current AST node is a function call expression + 'isFunctionCallExpression': function (expression) { + return expression && expression && expression.type === 'CallExpression' && expression.callee && expression.callee.type === 'FunctionExpression'; + }, + // isUseStrict + // ----------- + // Returns if the current AST node is a 'use strict' expression + // e.g. 'use strict' + 'isUseStrict': function (expression) { + return expression && expression && expression.value === 'use strict' && expression.type === 'Literal'; + }, + // isIfStatement + // ------------- + // Returns if the current AST node is an if statement + // e.g. if(true) {} + 'isIfStatement': function (node) { + return node && node.type === 'IfStatement' && node.test; + }, + // isAMDConditional + // ---------------- + // Returns if the current AST node is an if statement AMD check + // e.g. if(typeof define === 'function') {} + 'isAMDConditional': function (node) { + if (!Utils.isIfStatement(node)) { + return false; + } + var matchObject = { + 'left': { + 'operator': 'typeof', + 'argument': { + 'type': 'Identifier', + 'name': 'define' + } + }, + 'right': { + 'type': 'Literal', + 'value': 'function' + } + }, reversedMatchObject = { + 'left': matchObject.right, + 'right': matchObject.left + }; + try { + return _.find(node.test, matchObject) || _.find([node.test], matchObject) || _.find(node.test, reversedMatchObject) || _.find([node.test], reversedMatchObject) || _.find(node.test.left || {}, matchObject) || _.find([node.test.left || {}], matchObject) || _.find(node.test.left || {}, reversedMatchObject) || _.find([node.test.left || {}], reversedMatchObject); + } catch (e) { + return false; + } + }, + // returnExpressionIdentifier + // -------------------------- + // Returns a single identifier + // e.g. module + 'returnExpressionIdentifier': function (name) { + return { + 'type': 'ExpressionStatement', + 'expression': { + 'type': 'Identifier', + 'name': name, + 'range': defaultValues.defaultRange, + 'loc': defaultValues.defaultLOC + }, + 'range': defaultValues.defaultRange, + 'loc': defaultValues.defaultLOC + }; + }, + // readFile + // -------- + // Synchronous file reading for node + 'readFile': function (path) { + if (typeof exports !== 'undefined') { + var fs = require('fs'); + return fs.readFileSync(path, 'utf8'); + } else { + return ''; + } + }, + // isRelativeFilePath + // ------------------ + // Returns a boolean that determines if the file path provided is a relative file path + // e.g. ../exampleModule -> true + 'isRelativeFilePath': function (path) { + var segments = path.split('/'); + return segments.length !== -1 && (segments[0] === '.' || segments[0] === '..'); + }, + // convertToCamelCase + // ------------------ + // Converts a delimited string to camel case + // e.g. some_str -> someStr + convertToCamelCase: function (input, delimiter) { + delimiter = delimiter || '_'; + return input.replace(new RegExp(delimiter + '(.)', 'g'), function (match, group1) { + return group1.toUpperCase(); + }); + }, + // prefixReservedWords + // ------------------- + // Converts a reserved word in JavaScript with an underscore + // e.g. class -> _class + 'prefixReservedWords': function (name) { + var reservedWord = false; + try { + if (name.length) { + eval('var ' + name + ' = 1;'); + } + } catch (e) { + reservedWord = true; + } + if (reservedWord === true) { + return '_' + name; + } else { + return name; + } + }, + // normalizeDependencyName + // ----------------------- + // Returns a normalized dependency name that handles relative file paths + 'normalizeDependencyName': function (moduleId, dep) { + if (!moduleId || !dep) { + return dep; + } + var pluginName = function () { + if (!dep || dep.indexOf('!') === -1) { + return ''; + } + var split = dep.split('!'); + dep = split[1]; + return split[0] + '!'; + }(), normalizePath = function (path) { + var segments = path.split('/'), normalizedSegments; + normalizedSegments = _.reduce(segments, function (memo, segment) { + switch (segment) { + case '.': + break; + case '..': + memo.pop(); + break; + default: + memo.push(segment); + } + return memo; + }, []); + return normalizedSegments.join('/'); + }, baseName = function (path) { + var segments = path.split('/'); + segments.pop(); + return segments.join('/'); + }; + if (!Utils.isRelativeFilePath(dep)) { + return pluginName + dep; + } + return pluginName + normalizePath([ + baseName(moduleId), + dep + ].join('/')); + } + }; + return Utils; +}(); +convertToIIFE = function convertToIIFE(obj) { + var callbackFuncParams = obj.callbackFuncParams, callbackFunc = obj.callbackFunc, dependencyNames = obj.dependencyNames, node = obj.node, range = node.range || defaultValues.defaultRange, loc = node.loc || defaultValues.defaultLOC; + return { + 'type': 'ExpressionStatement', + 'expression': { + 'type': 'CallExpression', + 'callee': { + 'type': 'FunctionExpression', + 'id': null, + 'params': callbackFuncParams, + 'defaults': [], + 'body': callbackFunc.body, + 'rest': callbackFunc.rest, + 'generator': callbackFunc.generator, + 'expression': callbackFunc.expression, + 'range': range, + 'loc': loc + }, + 'arguments': dependencyNames, + 'range': range, + 'loc': loc + }, + 'range': range, + 'loc': loc + }; +}; +convertToIIFEDeclaration = function convertToIIFEDeclaration(obj) { + var amdclean = this, options = amdclean.options, moduleId = obj.moduleId, moduleName = obj.moduleName, hasModuleParam = obj.hasModuleParam, hasExportsParam = obj.hasExportsParam, callbackFuncParams = obj.callbackFuncParams, isOptimized = obj.isOptimized, callback = obj.callbackFunc, node = obj.node, name = callback.name, type = callback.type, range = node.range || defaultValues.defaultRange, loc = node.loc || defaultValues.defaultLOC, callbackFunc = function () { + var cbFunc = obj.callbackFunc; + if (type === 'Identifier' && name !== 'undefined') { + cbFunc = { + 'type': 'FunctionExpression', + 'id': null, + 'params': [], + 'defaults': [], + 'body': { + 'type': 'BlockStatement', + 'body': [{ + 'type': 'ReturnStatement', + 'argument': { + 'type': 'ConditionalExpression', + 'test': { + 'type': 'BinaryExpression', + 'operator': '===', + 'left': { + 'type': 'UnaryExpression', + 'operator': 'typeof', + 'argument': { + 'type': 'Identifier', + 'name': name, + 'range': range, + 'loc': loc + }, + 'prefix': true, + 'range': range, + 'loc': loc + }, + 'right': { + 'type': 'Literal', + 'value': 'function', + 'raw': '\'function\'', + 'range': range, + 'loc': loc + }, + 'range': range, + 'loc': loc + }, + 'consequent': { + 'type': 'CallExpression', + 'callee': { + 'type': 'Identifier', + 'name': name, + 'range': range, + 'loc': loc + }, + 'arguments': callbackFuncParams, + 'range': range, + 'loc': loc + }, + 'alternate': { + 'type': 'Identifier', + 'name': name, + 'range': range, + 'loc': loc + }, + 'range': range, + 'loc': loc + }, + 'range': range, + 'loc': loc + }], + 'range': range, + 'loc': loc + }, + 'rest': null, + 'generator': false, + 'expression': false, + 'range': range, + 'loc': loc + }; + } + return cbFunc; + }(), dependencyNames = function () { + var depNames = obj.dependencyNames, objExpression = { + 'type': 'ObjectExpression', + 'properties': [], + 'range': range, + 'loc': loc + }, configMemberExpression = { + 'type': 'MemberExpression', + 'computed': true, + 'object': { + 'type': 'Identifier', + 'name': 'modules' + }, + 'property': { + 'type': 'Literal', + 'value': moduleId + } + }, moduleDepIndex; + if (options.config && options.config[moduleId]) { + if (hasExportsParam && hasModuleParam) { + return [ + objExpression, + objExpression, + configMemberExpression + ]; + } else if (hasModuleParam) { + moduleDepIndex = _.findIndex(depNames, function (currentDep) { + return currentDep.name === '{}'; + }); + depNames[moduleDepIndex] = configMemberExpression; + } + } + return depNames; + }(), cb = function () { + if (callbackFunc.type === 'Literal' || callbackFunc.type === 'Identifier' && callbackFunc.name === 'undefined' || isOptimized === true) { + return callbackFunc; + } else { + return { + 'type': 'CallExpression', + 'callee': { + 'type': 'FunctionExpression', + 'id': { + 'type': 'Identifier', + 'name': '', + 'range': range, + 'loc': loc + }, + 'params': callbackFuncParams, + 'defaults': [], + 'body': callbackFunc.body, + 'rest': callbackFunc.rest, + 'generator': callbackFunc.generator, + 'expression': callbackFunc.expression, + 'range': range, + 'loc': loc + }, + 'arguments': dependencyNames, + 'range': range, + 'loc': loc + }; + } + }(), updatedNode = { + 'type': 'ExpressionStatement', + 'expression': { + 'type': 'AssignmentExpression', + 'operator': '=', + 'left': { + 'type': 'Identifier', + 'name': options.IIFEVariableNameTransform ? options.IIFEVariableNameTransform(moduleName, moduleId) : moduleName, + 'range': range, + 'loc': loc + }, + 'right': cb, + 'range': range, + 'loc': loc + }, + 'range': range, + 'loc': loc + }; + estraverse.replace(callbackFunc, { + 'enter': function (node) { + if (utils.isModuleExports(node)) { + return { + 'type': 'AssignmentExpression', + 'operator': '=', + 'left': { + 'type': 'Identifier', + 'name': 'exports' + }, + 'right': node.right + }; + } else { + return node; + } + } + }); + return updatedNode; +}; +normalizeModuleName = function normalizeModuleName(name, moduleId) { + var amdclean = this, options = amdclean.options, prefixMode = options.prefixMode, prefixTransform = options.prefixTransform, dependencyBlacklist = defaultValues.dependencyBlacklist, prefixTransformValue, preNormalized, postNormalized; + name = name || ''; + if (name === '{}') { + if (dependencyBlacklist[name] === 'remove') { + return ''; + } else { + return name; + } + } + preNormalized = utils.prefixReservedWords(name.replace(/\./g, '').replace(/[^A-Za-z0-9_$]/g, '_').replace(/^_+/, '')); + postNormalized = prefixMode === 'camelCase' ? utils.convertToCamelCase(preNormalized) : preNormalized; + if (_.isFunction(prefixTransform)) { + prefixTransformValue = prefixTransform(postNormalized, name); + if (_.isString(prefixTransformValue) && prefixTransformValue.length) { + return prefixTransformValue; + } + } + return postNormalized; +}; +convertToFunctionExpression = function convertToFunctionExpression(obj) { + var amdclean = this, options = amdclean.options, ignoreModules = options.ignoreModules, node = obj.node, isDefine = obj.isDefine, isRequire = obj.isRequire, isOptimized = false, moduleName = obj.moduleName, moduleId = obj.moduleId, dependencies = obj.dependencies, depLength = dependencies.length, aggressiveOptimizations = options.aggressiveOptimizations, exportsExpressions = [], moduleExportsExpressions = [], defaultRange = defaultValues.defaultRange, defaultLOC = defaultValues.defaultLOC, range = obj.range || defaultRange, loc = obj.loc || defaultLOC, shouldOptimize = obj.shouldOptimize, dependencyBlacklist = defaultValues.dependencyBlacklist, hasNonMatchingParameter = false, callbackFunc = function () { + var callbackFunc = obj.moduleReturnValue, body, returnStatements, firstReturnStatement, returnStatementArg; + // If the module callback function is not empty + if (callbackFunc && callbackFunc.type === 'FunctionExpression' && callbackFunc.body && _.isArray(callbackFunc.body.body) && callbackFunc.body.body.length) { + // Filter 'use strict' statements + body = _.filter(callbackFunc.body.body, function (node) { + if (options.removeUseStricts === true) { + return !utils.isUseStrict(node.expression); + } else { + return node; + } + }); + callbackFunc.body.body = body; + // Returns an array of all return statements + returnStatements = _.filter(body, { 'type': 'ReturnStatement' }); + exportsExpressions = _.filter(body, { + 'left': { + 'type': 'Identifier', + 'name': 'exports' + } + }); + moduleExportsExpressions = _.filter(body, { + 'left': { + 'type': 'MemberExpression', + 'object': { + 'type': 'Identifier', + 'name': 'module' + }, + 'property': { + 'type': 'Identifier', + 'name': 'exports' + } + } + }); + // If there is a return statement + if (returnStatements.length) { + firstReturnStatement = returnStatements[0]; + returnStatementArg = firstReturnStatement.argument; + hasNonMatchingParameter = function () { + var nonMatchingParameter = false; + _.each(callbackFunc.params, function (currentParam) { + var currentParamName = currentParam.name; + if (!amdclean.storedModules[currentParamName] && !dependencyBlacklist[currentParamName]) { + nonMatchingParameter = true; + } + }); + return nonMatchingParameter; + }(); + // If something other than a function expression is getting returned + // and there is more than one AST child node in the factory function + // return early + if (hasNonMatchingParameter || !shouldOptimize || !utils.isFunctionExpression(firstReturnStatement) && body.length > 1 || returnStatementArg && returnStatementArg.type === 'Identifier') { + return callbackFunc; + } else { + // Optimize the AMD module by setting the callback function to the return statement argument + callbackFunc = returnStatementArg; + isOptimized = true; + if (callbackFunc.params) { + depLength = callbackFunc.params.length; + } + } + } + } else if (callbackFunc && callbackFunc.type === 'FunctionExpression' && callbackFunc.body && _.isArray(callbackFunc.body.body) && callbackFunc.body.body.length === 0) { + callbackFunc = { + 'type': 'Identifier', + 'name': 'undefined', + 'range': range, + 'loc': loc + }; + depLength = 0; + } + return callbackFunc; + }(), hasReturnStatement = function () { + var returns = []; + if (callbackFunc && callbackFunc.body && _.isArray(callbackFunc.body.body)) { + returns = _.filter(callbackFunc.body.body, { 'type': 'ReturnStatement' }); + if (returns.length) { + return true; + } + } + return false; + }(), originalCallbackFuncParams, hasExportsParam = function () { + var cbParams = callbackFunc.params || []; + return _.filter(cbParams, { 'name': 'exports' }).length; + }(), hasModuleParam = function () { + var cbParams = callbackFunc.params || []; + return _.filter(cbParams, { 'name': 'module' }).length; + }(), normalizeDependencyNames = {}, dependencyNames = function () { + var deps = [], currentName; + _.each(dependencies, function (currentDependency) { + currentName = normalizeModuleName.call(amdclean, utils.normalizeDependencyName(moduleId, currentDependency), moduleId); + normalizeDependencyNames[currentName] = true; + deps.push({ + 'type': 'Identifier', + 'name': currentName, + 'range': defaultRange, + 'loc': defaultLOC + }); + }); + return deps; + }(), + // Makes sure the new name is not an existing callback function dependency and/or existing local variable + findNewParamName = function findNewParamName(name) { + name = '_' + name + '_'; + var containsLocalVariable = function () { + var containsVariable = false; + if (normalizeDependencyNames[name]) { + containsVariable = true; + } else { + estraverse.traverse(callbackFunc, { + 'enter': function (node) { + if (node.type === 'VariableDeclarator' && node.id && node.id.type === 'Identifier' && node.id.name === name) { + containsVariable = true; + } + } + }); + } + return containsVariable; + }(); + // If there is not a local variable declaration with the passed name, return the name and surround it with underscores + // Else if there is already a local variable declaration with the passed name, recursively add more underscores surrounding it + if (!containsLocalVariable) { + return name; + } else { + return findNewParamName(name); + } + }, matchingRequireExpressionNames = function () { + var matchingNames = []; + if (hasExportsParam) { + estraverse.traverse(callbackFunc, { + 'enter': function (node) { + var variableName, expressionName; + if (node.type === 'VariableDeclarator' && utils.isRequireExpression(node.init)) { + // If both variable name and expression names are there + if (node.id && node.id.name && node.init && node.init['arguments'] && node.init['arguments'][0] && node.init['arguments'][0].value) { + variableName = node.id.name; + expressionName = normalizeModuleName.call(amdclean, utils.normalizeDependencyName(moduleId, node.init['arguments'][0].value, moduleId)); + if (!_.includes(ignoreModules, expressionName) && variableName === expressionName) { + matchingNames.push({ + 'originalName': expressionName, + 'newName': findNewParamName(expressionName), + 'range': node.range || defaultRange, + 'loc': node.loc || defaultLOC + }); + } + } + } + } + }); + } + return matchingNames; + }(), matchingRequireExpressionParams = function () { + var params = []; + _.each(matchingRequireExpressionNames, function (currentParam) { + params.push({ + 'type': 'Identifier', + 'name': currentParam.newName ? currentParam.newName : currentParam, + 'range': currentParam.range, + 'loc': currentParam.loc + }); + }); + return params; + }(), callbackFuncParams = function () { + var deps = [], currentName, cbParams = _.union(callbackFunc.params && callbackFunc.params.length ? callbackFunc.params : !shouldOptimize && dependencyNames && dependencyNames.length ? dependencyNames : [], matchingRequireExpressionParams), mappedParameter = {}, + // For calculating cbParams we'll optimize by removing not referenced names in the callback parameters. + // If the callback body contains a reference to 'arguments' then we cannot perform this optimization. + // but at the same time if only inner functions body contains arguments WE DO optimize. + // What we do is find inner function declarations and then remove their text from the callback body. Then we look for 'arguments' references + innerFunctions = [], lookForArgumentsCode; + if (callbackFunc.body) { + estraverse.traverse(callbackFunc.body, { + enter: function (node, parent) { + if (node.type == 'FunctionExpression' || node.type == 'FunctionDeclaration') + innerFunctions.push(node); + } + }); + if (innerFunctions.length) { + for (var i = callbackFunc.body.range[0]; i < callbackFunc.body.range[1]; i++) { + _.each(innerFunctions, function (innerFunction) { + if (i < innerFunction.range[0] || i >= innerFunction.range[1]) { + lookForArgumentsCode += amdclean.options.code[i]; + } + }); + } + } else { + lookForArgumentsCode = amdclean.options.code.substring(callbackFunc.body.range[0], callbackFunc.body.range[1]); + } + if (/[^\w0-9_]arguments[^\w0-9_]/.test(lookForArgumentsCode)) { + cbParams = cbParams.concat(dependencyNames.slice(cbParams.length)); + } + } + _.each(cbParams, function (currentParam, iterator) { + if (currentParam) { + currentName = currentParam.name; + } else { + currentName = dependencyNames[iterator].name; + } + if (!shouldOptimize && currentName !== '{}') { + deps.push({ + 'type': 'Identifier', + 'name': currentName, + 'range': defaultRange, + 'loc': defaultLOC + }); + } else if (currentName !== '{}' && (!hasExportsParam || defaultValues.dependencyBlacklist[currentName] !== 'remove')) { + deps.push({ + 'type': 'Identifier', + 'name': currentName, + 'range': defaultRange, + 'loc': defaultLOC + }); + // If a callback parameter is not the exact name of a stored module and there is a dependency that matches the current callback parameter + if (!isOptimized && aggressiveOptimizations === true && !amdclean.storedModules[currentName] && dependencyNames[iterator]) { + // If the current dependency has not been stored + if (!amdclean.callbackParameterMap[dependencyNames[iterator].name]) { + amdclean.callbackParameterMap[dependencyNames[iterator].name] = [{ + 'name': currentName, + 'count': 1 + }]; + } else { + mappedParameter = _.filter(amdclean.callbackParameterMap[dependencyNames[iterator].name], { 'name': currentName }); + if (mappedParameter.length) { + mappedParameter = mappedParameter[0]; + mappedParameter.count += 1; + } else { + amdclean.callbackParameterMap[dependencyNames[iterator].name].push({ + 'name': currentName, + 'count': 1 + }); + } + } + } + } + }); + originalCallbackFuncParams = deps; + // Only return callback function parameters that do not directly match the name of existing stored modules + return _.filter(deps || [], function (currentParam) { + return aggressiveOptimizations === true && shouldOptimize ? !amdclean.storedModules[currentParam.name] : true; + }); + }(), isCommonJS = !hasReturnStatement && hasExportsParam, hasExportsAssignment = exportsExpressions.length || moduleExportsExpressions.length, dependencyNameLength, callbackFuncParamsLength; + // Only return dependency names that do not directly match the name of existing stored modules + dependencyNames = _.filter(dependencyNames || [], function (currentDep, iterator) { + var mappedCallbackParameter = originalCallbackFuncParams[iterator], currentDepName = currentDep.name; + // If the matching callback parameter matches the name of a stored module, then do not return it + // Else if the matching callback parameter does not match the name of a stored module, return the dependency + return aggressiveOptimizations === true && shouldOptimize ? !mappedCallbackParameter || amdclean.storedModules[mappedCallbackParameter.name] && mappedCallbackParameter.name === currentDepName ? !amdclean.storedModules[currentDepName] : !amdclean.storedModules[mappedCallbackParameter.name] : true; + }); + dependencyNames = _.map(dependencyNames || [], function (currentDep, iterator) { + if (dependencyBlacklist[currentDep.name]) { + currentDep.name = '{}'; + } + return currentDep; + }); + dependencyNameLength = dependencyNames.length; + callbackFuncParamsLength = callbackFuncParams.length; + // If the module dependencies passed into the current module are greater than the used callback function parameters, do not pass the dependencies + if (dependencyNameLength > callbackFuncParamsLength) { + dependencyNames.splice(callbackFuncParamsLength, dependencyNameLength - callbackFuncParamsLength); + } + // If it is a CommonJS module and there is an exports assignment, make sure to return the exports object + if (isCommonJS && hasExportsAssignment) { + callbackFunc.body.body.push({ + 'type': 'ReturnStatement', + 'argument': { + 'type': 'Identifier', + 'name': 'exports', + 'range': defaultRange, + 'loc': defaultLOC + }, + 'range': defaultRange, + 'loc': defaultLOC + }); + } + // Makes sure to update all the local variable require expressions to any updated names + estraverse.replace(callbackFunc, { + 'enter': function (node) { + var normalizedModuleName, newName; + if (utils.isRequireExpression(node)) { + if (node['arguments'] && node['arguments'][0] && node['arguments'][0].value) { + normalizedModuleName = normalizeModuleName.call(amdclean, utils.normalizeDependencyName(moduleId, node['arguments'][0].value, moduleId)); + if (_.includes(ignoreModules, normalizedModuleName)) { + return node; + } + if (_.filter(matchingRequireExpressionNames, { 'originalName': normalizedModuleName }).length) { + newName = _.filter(matchingRequireExpressionNames, { 'originalName': normalizedModuleName })[0].newName; + } + return { + 'type': 'Identifier', + 'name': newName ? newName : normalizedModuleName, + 'range': node.range || defaultRange, + 'loc': node.loc || defaultLOC + }; + } else { + return node; + } + } + } + }); + if (isDefine) { + return convertToIIFEDeclaration.call(amdclean, { + 'moduleId': moduleId, + 'moduleName': moduleName, + 'dependencyNames': dependencyNames, + 'callbackFuncParams': callbackFuncParams, + 'hasModuleParam': hasModuleParam, + 'hasExportsParam': hasExportsParam, + 'callbackFunc': callbackFunc, + 'isOptimized': isOptimized, + 'node': node + }); + } else if (isRequire) { + return convertToIIFE.call(amdclean, { + 'dependencyNames': dependencyNames, + 'callbackFuncParams': callbackFuncParams, + 'callbackFunc': callbackFunc, + 'node': node + }); + } +}; +convertToObjectDeclaration = function (obj, type) { + var node = obj.node, defaultRange = defaultValues.defaultRange, defaultLOC = defaultValues.defaultLOC, range = node.range || defaultRange, loc = node.loc || defaultLOC, moduleName = obj.moduleName, moduleReturnValue = function () { + var modReturnValue, callee, params, returnStatement, nestedReturnStatement, internalFunctionExpression; + if (type === 'functionCallExpression') { + modReturnValue = obj.moduleReturnValue; + callee = modReturnValue.callee; + params = callee.params; + if (params && params.length && _.isArray(params) && _.filter(params, { 'name': 'global' })) { + if (_.isObject(callee.body) && _.isArray(callee.body.body)) { + returnStatement = _.filter(callee.body.body, { 'type': 'ReturnStatement' })[0]; + if (_.isObject(returnStatement) && _.isObject(returnStatement.argument) && returnStatement.argument.type === 'FunctionExpression') { + internalFunctionExpression = returnStatement.argument; + if (_.isObject(internalFunctionExpression.body) && _.isArray(internalFunctionExpression.body.body)) { + nestedReturnStatement = _.filter(internalFunctionExpression.body.body, { 'type': 'ReturnStatement' })[0]; + if (_.isObject(nestedReturnStatement.argument) && _.isObject(nestedReturnStatement.argument.right) && _.isObject(nestedReturnStatement.argument.right.property)) { + if (nestedReturnStatement.argument.right.property.name) { + modReturnValue = { + 'type': 'MemberExpression', + 'computed': false, + 'object': { + 'type': 'Identifier', + 'name': 'window', + 'range': range, + 'loc': loc + }, + 'property': { + 'type': 'Identifier', + 'name': nestedReturnStatement.argument.right.property.name, + 'range': range, + 'loc': loc + }, + 'range': range, + 'loc': loc + }; + } + } + } + } + } + } + } + modReturnValue = modReturnValue || obj.moduleReturnValue; + return modReturnValue; + }(), updatedNode = { + 'type': 'ExpressionStatement', + 'expression': { + 'type': 'AssignmentExpression', + 'operator': '=', + 'left': { + 'type': 'Identifier', + 'name': moduleName, + 'range': range, + 'loc': loc + }, + 'right': moduleReturnValue, + 'range': range, + 'loc': loc + }, + 'range': range, + 'loc': loc + }; + return updatedNode; +}; +createAst = function createAst(providedCode) { + var amdclean = this, options = amdclean.options, filePath = options.filePath, code = providedCode || options.code || (filePath ? utils.readFile(filePath) : ''), esprimaOptions = options.esprima, escodegenOptions = options.escodegen; + if (!code) { + throw new Error(errorMsgs.emptyCode); + } else { + if (!_.isPlainObject(esprima) || !_.isFunction(esprima.parse)) { + throw new Error(errorMsgs.esprima); + } + var ast = esprima.parse(code, esprimaOptions); + if (options.sourceMap) + sourcemapToAst(ast, options.sourceMap); + // Check if both the esprima and escodegen comment options are set to true + if (esprimaOptions.comment === true && escodegenOptions.comment === true) { + try { + // Needed to keep source code comments when generating the code with escodegen + ast = escodegen.attachComments(ast, ast.comments, ast.tokens); + } catch (e) { + } + } + return ast; + } +}; +convertDefinesAndRequires = function convertDefinesAndRequires(node, parent) { + var amdclean = this, options = amdclean.options, moduleName, args, dependencies, moduleReturnValue, moduleId, params, isDefine = utils.isDefine(node), isRequire = utils.isRequire(node), startLineNumber, callbackFuncArg = false, type = '', shouldBeIgnored, moduleToBeIgnored, parentHasFunctionExpressionArgument, defaultRange = defaultValues.defaultRange, defaultLOC = defaultValues.defaultLOC, range = node.range || defaultRange, loc = node.loc || defaultLOC, dependencyBlacklist = defaultValues.dependencyBlacklist, shouldOptimize; + startLineNumber = isDefine || isRequire ? node.expression.loc.start.line : node && node.loc && node.loc.start ? node.loc.start.line : null; + shouldBeIgnored = amdclean.matchingCommentLineNumbers[startLineNumber] || amdclean.matchingCommentLineNumbers[startLineNumber - 1]; + // If it is an AMD conditional statement + // e.g. if(typeof define === 'function') {} + if (utils.isAMDConditional(node)) { + estraverse.traverse(node, { + 'enter': function (node) { + var normalizedModuleName; + if (utils.isDefine(node)) { + if (node.expression && node.expression.arguments && node.expression.arguments.length) { + // Add the module name to the ignore list + if (node.expression.arguments[0].type === 'Literal' && node.expression.arguments[0].value) { + normalizedModuleName = normalizeModuleName.call(amdclean, node.expression.arguments[0].value); + if (options.transformAMDChecks !== true) { + amdclean.conditionalModulesToIgnore[normalizedModuleName] = true; + } else { + amdclean.conditionalModulesToNotOptimize[normalizedModuleName] = true; + } + if (options.createAnonymousAMDModule === true) { + amdclean.storedModules[normalizedModuleName] = false; + node.expression.arguments.shift(); + } + } + } + } + } + }); + // If the AMD conditional statement should be transformed and not ignored + if (!shouldBeIgnored && options.transformAMDChecks === true) { + // Transform the AMD conditional statement + // e.g. if(typeof define === 'function') {} -> if(true) {} + node.test = { + 'type': 'Literal', + 'value': true, + 'raw': 'true', + 'range': range, + 'loc': loc + }; + return node; + } + } + if (isDefine || isRequire) { + args = Array.prototype.slice.call(node.expression['arguments'], 0); + moduleReturnValue = isRequire ? args[1] : args[args.length - 1]; + moduleId = node.expression['arguments'][0].value; + moduleName = normalizeModuleName.call(amdclean, moduleId); + shouldOptimize = !amdclean.conditionalModulesToNotOptimize[moduleName]; + dependencies = function () { + var deps = isRequire ? args[0] : args[args.length - 2], depNames = [], hasExportsParam; + if (_.isPlainObject(deps)) { + deps = deps.elements || []; + } else { + deps = []; + } + hasExportsParam = _.filter(deps, { 'value': 'exports' }).length; + if (_.isArray(deps) && deps.length) { + _.each(deps, function (currentDependency) { + if (dependencyBlacklist[currentDependency.value] && !shouldOptimize) { + depNames.push(currentDependency.value); + } else if (dependencyBlacklist[currentDependency.value] !== 'remove') { + if (currentDependency.value === 'exports') { + depNames.push(moduleName); + amdclean.exportsModules[moduleName] = true; + } else if (dependencyBlacklist[currentDependency.value]) { + depNames.push('{}'); + } else { + depNames.push(currentDependency.value); + } + } else { + if (!hasExportsParam) { + depNames.push('{}'); + } + } + }); + } + return depNames; + }(); + params = { + 'node': node, + 'moduleName': moduleName, + 'moduleId': moduleId, + 'dependencies': dependencies, + 'moduleReturnValue': moduleReturnValue, + 'isDefine': isDefine, + 'isRequire': isRequire, + 'range': range, + 'loc': loc, + 'shouldOptimize': shouldOptimize + }; + if (isDefine) { + if (shouldBeIgnored || !moduleName || amdclean.conditionalModulesToIgnore[moduleName] === true) { + amdclean.options.ignoreModules.push(moduleName); + return node; + } + if (_.includes(options.removeModules, moduleName)) { + // Remove the current module from the source + return { 'type': 'EmptyStatement' }; + } + if (_.isObject(options.shimOverrides) && options.shimOverrides[moduleId]) { + params.moduleReturnValue = createAst.call(amdclean, options.shimOverrides[moduleId]); + if (_.isArray(params.moduleReturnValue.body) && _.isObject(params.moduleReturnValue.body[0])) { + if (_.isObject(params.moduleReturnValue.body[0].expression)) { + params.moduleReturnValue = params.moduleReturnValue.body[0].expression; + type = 'objectExpression'; + } + } else { + params.moduleReturnValue = moduleReturnValue; + } + } else if (params.moduleReturnValue && params.moduleReturnValue.type === 'Identifier') { + type = 'functionExpression'; + } + if (_.includes(options.ignoreModules, moduleName)) { + return node; + } else if (utils.isFunctionExpression(moduleReturnValue) || type === 'functionExpression') { + return convertToFunctionExpression.call(amdclean, params); + } else if (utils.isObjectExpression(moduleReturnValue) || type === 'objectExpression') { + return convertToObjectDeclaration.call(amdclean, params); + } else if (utils.isFunctionCallExpression(moduleReturnValue)) { + return convertToObjectDeclaration.call(amdclean, params, 'functionCallExpression'); + } + } else if (isRequire) { + if (shouldBeIgnored) { + return node; + } + callbackFuncArg = _.isArray(node.expression['arguments']) && node.expression['arguments'].length ? node.expression['arguments'][1] && node.expression['arguments'][1].body && node.expression['arguments'][1].body.body && node.expression['arguments'][1].body.body.length : false; + if (options.removeAllRequires !== true && callbackFuncArg) { + return convertToFunctionExpression.call(amdclean, params); + } else { + // Remove the require include statement from the source + return { + 'type': 'EmptyStatement', + 'range': range, + 'loc': loc + }; + } + } + } else { + // If the node is a function expression that has an exports parameter and does not return anything, return exports + if (node.type === 'FunctionExpression' && _.isArray(node.params) && _.filter(node.params, { + 'type': 'Identifier', + 'name': 'exports' + }).length && _.isObject(node.body) && _.isArray(node.body.body) && !_.filter(node.body.body, { 'type': 'ReturnStatement' }).length) { + parentHasFunctionExpressionArgument = function () { + if (!parent || !parent.arguments) { + return false; + } + if (parent && parent.arguments && parent.arguments.length) { + return _.filter(parent.arguments, { 'type': 'FunctionExpression' }).length; + } + return false; + }(); + if (parentHasFunctionExpressionArgument) { + // Adds the logical expression, 'exports = exports || {}', to the beginning of the function expression + node.body.body.unshift({ + 'type': 'ExpressionStatement', + 'expression': { + 'type': 'AssignmentExpression', + 'operator': '=', + 'left': { + 'type': 'Identifier', + 'name': 'exports', + 'range': defaultRange, + 'loc': defaultLOC + }, + 'right': { + 'type': 'LogicalExpression', + 'operator': '||', + 'left': { + 'type': 'Identifier', + 'name': 'exports', + 'range': defaultRange, + 'loc': defaultLOC + }, + 'right': { + 'type': 'ObjectExpression', + 'properties': [], + 'range': defaultRange, + 'loc': defaultLOC + }, + 'range': defaultRange, + 'loc': defaultLOC + }, + 'range': defaultRange, + 'loc': defaultLOC + }, + 'range': defaultRange, + 'loc': defaultLOC + }); + } + // Adds the return statement, 'return exports', to the end of the function expression + node.body.body.push({ + 'type': 'ReturnStatement', + 'argument': { + 'type': 'Identifier', + 'name': 'exports', + 'range': defaultRange, + 'loc': defaultLOC + }, + 'range': defaultRange, + 'loc': defaultLOC + }); + } + return node; + } +}; +traverseAndUpdateAst = function traverseAndUpdateAst(obj) { + var amdclean = this, options = amdclean.options, ast = obj.ast; + if (!_.isPlainObject(obj)) { + throw new Error(errorMsgs.invalidObject('traverseAndUpdateAst')); + } + if (!ast) { + throw new Error(errorMsgs.emptyAst('traverseAndUpdateAst')); + } + if (!_.isPlainObject(estraverse) || !_.isFunction(estraverse.replace)) { + throw new Error(errorMsgs.estraverse); + } + estraverse.replace(ast, { + 'enter': function (node, parent) { + var ignoreComments; + if (node.type === 'Program') { + ignoreComments = function () { + var arr = [], currentLineNumber; + amdclean.comments = node.comments; + _.each(node.comments, function (currentComment) { + var currentCommentValue = currentComment.value.trim(); + if (currentCommentValue === options.commentCleanName) { + arr.push(currentComment); + } + }); + return arr; + }(); + _.each(ignoreComments, function (currentComment) { + currentLineNumber = currentComment.loc.start.line; + amdclean.matchingCommentLineNumbers[currentLineNumber] = true; + }); + return node; + } + return convertDefinesAndRequires.call(amdclean, node, parent); + }, + 'leave': function (node) { + return node; + } + }); + return ast; +}; +getNormalizedModuleName = function getNormalizedModuleName(node) { + if (!utils.isDefine(node)) { + return; + } + var amdclean = this, moduleId = node.expression['arguments'][0].value, moduleName = normalizeModuleName.call(amdclean, moduleId); + return moduleName; +}; +findAndStoreAllModuleIds = function findAndStoreAllModuleIds(ast) { + var amdclean = this; + if (!ast) { + throw new Error(errorMsgs.emptyAst('findAndStoreAllModuleIds')); + } + if (!_.isPlainObject(estraverse) || !_.isFunction(estraverse.traverse)) { + throw new Error(errorMsgs.estraverse); + } + estraverse.traverse(ast, { + 'enter': function (node, parent) { + var moduleName = getNormalizedModuleName.call(amdclean, node, parent); + // If the current module has not been stored, store it + if (moduleName && !amdclean.storedModules[moduleName]) { + amdclean.storedModules[moduleName] = true; + } + // If it is a return statement that returns a define() method call, strip the return statement + if (node.type === 'ReturnStatement' && node.argument && node.argument.callee && node.argument.callee.name === 'define') { + node.type = 'ExpressionStatement'; + node.expression = node.argument; + delete node.argument; + } + } + }); +}; +generateCode = function generateCode(ast) { + var amdclean = this, options = amdclean.options, escodegenOptions = options.escodegen || {}; + if (!_.isPlainObject(escodegen) || !_.isFunction(escodegen.generate)) { + throw new Error(errorMsgs.escodegen); + } + return escodegen.generate(ast, escodegenOptions); +}; +clean = function clean() { + var amdclean = this, options = amdclean.options, ignoreModules = options.ignoreModules, originalAst = {}, ast = {}, configAst = {}, generatedCode, declarations = [], hoistedVariables = {}, hoistedCallbackParameters = {}, defaultRange = defaultValues.defaultRange, defaultLOC = defaultValues.defaultLOC; + // Creates and stores an AST representation of the code + originalAst = createAst.call(amdclean); + // Loops through the AST, finds all module ids, and stores them in the current instance storedModules property + findAndStoreAllModuleIds.call(amdclean, originalAst); + // Traverses the AST and removes any AMD trace + ast = traverseAndUpdateAst.call(amdclean, { ast: originalAst }); + // Post Clean Up + // Removes all empty statements from the source so that there are no single semicolons and + // Makes sure that all require() CommonJS calls are converted + // And all aggressive optimizations (if the option is turned on) are handled + if (ast && _.isArray(ast.body)) { + estraverse.replace(ast, { + enter: function (node, parent) { + var normalizedModuleName, assignmentName = node && node.left && node.left.name ? node.left.name : '', cb = node.right, assignmentNodes = [], assignments = {}, mappedParameters = _.filter(amdclean.callbackParameterMap[assignmentName], function (currentParameter) { + return currentParameter && currentParameter.count > 1; + }), mappedCbDependencyNames, mappedCbParameterNames, paramsToRemove = []; + if (node === undefined || node.type === 'EmptyStatement') { + _.each(parent.body, function (currentNode, iterator) { + if (currentNode === undefined || currentNode.type === 'EmptyStatement') { + parent.body.splice(iterator, 1); + } + }); + } else if (utils.isRequireExpression(node)) { + if (node['arguments'] && node['arguments'][0] && node['arguments'][0].value) { + normalizedModuleName = normalizeModuleName.call(amdclean, node['arguments'][0].value); + if (ignoreModules.indexOf(normalizedModuleName) === -1) { + return { + 'type': 'Identifier', + 'name': normalizedModuleName, + 'range': node.range || defaultRange, + 'loc': node.loc || defaultLOC + }; + } else { + return node; + } + } else { + return node; + } + } else if (options.aggressiveOptimizations === true && node.type === 'AssignmentExpression' && assignmentName) { + // The names of all of the current callback function parameters + mappedCbParameterNames = _.map(cb && cb.callee && cb.callee.params ? cb.callee.params : [], function (currentParam) { + return currentParam.name; + }); + // The names of all of the current callback function dependencies + mappedCbDependencyNames = _.map(cb.arguments, function (currentArg) { + return currentArg.name; + }); + // Loop through the dependency names + _.each(mappedCbDependencyNames, function (currentDependencyName) { + // Nested loop to see if any of the dependency names map to a callback parameter + _.each(amdclean.callbackParameterMap[currentDependencyName], function (currentMapping) { + var mappedName = currentMapping.name, mappedCount = currentMapping.count; + // Loops through all of the callback function parameter names to see if any of the parameters should be removed + _.each(mappedCbParameterNames, function (currentParameterName, iterator) { + if (mappedCount > 1 && mappedName === currentParameterName) { + paramsToRemove.push(iterator); + } + }); + }); + }); + _.each(paramsToRemove, function (currentParam) { + cb.arguments.splice(currentParam, currentParam + 1); + cb.callee.params.splice(currentParam, currentParam + 1); + }); + // If the current Assignment Expression is a mapped callback parameter + if (amdclean.callbackParameterMap[assignmentName]) { + node.right = function () { + // If aggressive optimizations are turned on, the mapped parameter is used more than once, and there are mapped dependencies to be removed + if (options.aggressiveOptimizations === true && mappedParameters.length) { + // All of the necessary assignment nodes + assignmentNodes = _.map(mappedParameters, function (currentDependency, iterator) { + return { + 'type': 'AssignmentExpression', + 'operator': '=', + 'left': { + 'type': 'Identifier', + 'name': currentDependency.name, + 'range': defaultRange, + 'loc': defaultLOC + }, + 'right': iterator < mappedParameters.length - 1 ? { + 'range': defaultRange, + 'loc': defaultLOC + } : cb, + 'range': defaultRange, + 'loc': defaultLOC + }; + }); + // Creates an object containing all of the assignment expressions + assignments = _.reduce(assignmentNodes, function (result, assignment) { + result.right = assignment; + return result; + }); + // The constructed assignment object node + return assignmentNodes.length ? assignments : cb; + } else { + return cb; + } + }(); + return node; + } + } + } + }); + } + // Makes any necessary modules global by appending a global instantiation to the code + // eg: window.exampleModule = exampleModule; + if (_.isArray(options.globalModules)) { + _.each(options.globalModules, function (currentModule) { + if (_.isString(currentModule) && currentModule.length) { + ast.body.push({ + 'type': 'ExpressionStatement', + 'expression': { + 'type': 'AssignmentExpression', + 'operator': '=', + 'left': { + 'type': 'MemberExpression', + 'computed': false, + 'object': { + 'type': 'Identifier', + 'name': 'window', + 'range': defaultRange, + 'loc': defaultLOC + }, + 'property': { + 'type': 'Identifier', + 'name': currentModule, + 'range': defaultRange, + 'loc': defaultLOC + }, + 'range': defaultRange, + 'loc': defaultLOC + }, + 'right': { + 'type': 'Identifier', + 'name': currentModule, + 'range': defaultRange, + 'loc': defaultLOC + }, + 'range': defaultRange, + 'loc': defaultLOC + }, + 'range': defaultRange, + 'loc': defaultLOC + }); + } + }); + } + hoistedCallbackParameters = function () { + var obj = {}, callbackParameterMap = amdclean.callbackParameterMap, currentParameterName; + _.each(callbackParameterMap, function (mappedParameters) { + _.each(mappedParameters, function (currentParameter) { + if (currentParameter.count > 1) { + currentParameterName = currentParameter.name; + obj[currentParameterName] = true; + } + }); + }); + return obj; + }(); + // Hoists all modules and necessary callback parameters + hoistedVariables = _.merge(_.cloneDeep(_.reduce(amdclean.storedModules, function (storedModules, key, val) { + if (key !== false) { + storedModules[val] = true; + } + return storedModules; + }, {})), hoistedCallbackParameters); + // Creates variable declarations for each AMD module/callback parameter that needs to be hoisted + _.each(hoistedVariables, function (moduleValue, moduleName) { + if (!_.includes(options.ignoreModules, moduleName)) { + var _initValue = amdclean.exportsModules[moduleName] !== true ? null : { + type: 'ObjectExpression', + properties: [] + }; + declarations.push({ + 'type': 'VariableDeclarator', + 'id': { + 'type': 'Identifier', + 'name': moduleName, + 'range': defaultRange, + 'loc': defaultLOC + }, + 'init': _initValue, + 'range': defaultRange, + 'loc': defaultLOC + }); + } + }); + // Adds a local modules variable if a user wants local module information available to them + if (_.isObject(options.config) && !_.isEmpty(options.config)) { + configAst = function () { + var props = []; + _.each(options.config, function (val, key) { + var currentModuleConfig = options.config[key]; + props.push({ + 'type': 'Property', + 'key': { + 'type': 'Literal', + 'value': key + }, + 'value': { + 'type': 'ObjectExpression', + 'properties': [{ + 'type': 'Property', + 'key': { + 'type': 'Literal', + 'value': 'config' + }, + 'value': { + 'type': 'FunctionExpression', + 'id': null, + 'params': [], + 'defaults': [], + 'body': { + 'type': 'BlockStatement', + 'body': [{ + 'type': 'ReturnStatement', + 'argument': createAst.call(amdclean, 'var x =' + JSON.stringify(currentModuleConfig)).body[0].declarations[0].init + }] + } + }, + 'kind': 'init' + }] + } + }); + }); + return { + 'type': 'VariableDeclarator', + 'id': { + 'type': 'Identifier', + 'name': 'modules' + }, + 'init': { + 'type': 'ObjectExpression', + 'properties': props + } + }; + }(); + declarations.push(configAst); + } + // If there are declarations, the declarations are preprended to the beginning of the code block + if (declarations.length) { + ast.body.unshift({ + 'type': 'VariableDeclaration', + 'declarations': declarations, + 'kind': 'var', + 'range': defaultRange, + 'loc': defaultLOC + }); + } + // Converts the updated AST to a string of code + generatedCode = generateCode.call(amdclean, ast); + // If there is a wrap option specified + if (_.isObject(options.wrap)) { + if (_.isString(options.wrap.start) && options.wrap.start.length) { + generatedCode = options.wrap.start + generatedCode; + } + if (_.isString(options.wrap.end) && options.wrap.end.length) { + generatedCode = generatedCode + options.wrap.end; + } + } + return generatedCode; +}; +(function () { + (function (root, factory, undefined) { + 'use strict'; + // Universal Module Definition (UMD) to support AMD, CommonJS/Node.js, and plain browser loading + if (typeof define === 'function' && define.amd) { + factory.amd = true; + define([ + 'esprima', + 'estraverse', + 'escodegen', + 'underscore', + 'sourcemap-to-ast' + ], function (esprima, estraverse, escodegen, underscore, sourcemapToAst) { + return factory({ + 'esprima': esprima, + 'estraverse': estraverse, + 'escodegen': escodegen, + 'underscore': underscore, + 'sourcemapToAst': sourcemapToAst + }, root); + }); + } else if (typeof exports !== 'undefined') { + factory.commonjs = true; + module.exports = factory(null, root); + } else { + root.amdclean = factory(null, root); + } + }(this, function cleanamd(amdDependencies, context) { + 'use strict'; + // Third-Party Dependencies + // Note: These dependencies are hoisted to the top (as local variables) at build time (Look in the gulpfile.js file and the AMDclean wrap option for more details) + sourcemapToAst = function () { + if (cleanamd.amd && amdDependencies && amdDependencies.sourcemapToAst) { + return amdDependencies.sourcemapToAst; + } else if (cleanamd.commonjs) { + return require('sourcemap-to-ast'); + } else if (context && context.sourcemapToAst) { + return context.sourcemapToAst; + } + }(); + // Third-Party Dependencies + // Note: These dependencies are hoisted to the top (as local variables) at build time (Look in the gulpfile.js file and the AMDclean wrap option for more details) + esprima = function () { + if (cleanamd.amd && amdDependencies && amdDependencies.esprima && amdDependencies.esprima.parse) { + return amdDependencies.esprima; + } else if (cleanamd.commonjs) { + return require('esprima'); + } else if (context && context.esprima && context.esprima.parse) { + return context.esprima; + } + }(); + estraverse = function () { + if (cleanamd.amd && amdDependencies && amdDependencies.estraverse && amdDependencies.estraverse.traverse) { + return amdDependencies.estraverse; + } else if (cleanamd.commonjs) { + return require('estraverse'); + } else if (context && context.estraverse && context.estraverse.traverse) { + return context.estraverse; + } + }(); + escodegen = function () { + if (cleanamd.amd && amdDependencies && amdDependencies.escodegen && amdDependencies.escodegen.generate) { + return amdDependencies.escodegen; + } else if (cleanamd.commonjs) { + return require('escodegen'); + } else if (context && context.escodegen && context.escodegen.generate) { + return context.escodegen; + } + }(); + _ = function () { + if (cleanamd.amd && amdDependencies && (amdDependencies.underscore || amdDependencies.lodash || amdDependencies._)) { + return amdDependencies.underscore || amdDependencies.lodash || amdDependencies._; + } else if (cleanamd.commonjs) { + return require('lodash'); + } else if (context && context._) { + return context._; + } + }(); + // AMDclean constructor function + var AMDclean = function (options, overloadedOptions) { + if (!esprima) { + throw new Error(errorMsgs.esprima); + } else if (!estraverse) { + throw new Error(errorMsgs.estraverse); + } else if (!escodegen) { + throw new Error(errorMsgs.escodegen); + } else if (!_) { + throw new Error(errorMsgs.lodash); + } else if (!sourcemapToAst && typeof window === 'undefined') { + throw new Error(errorMsgs.sourcemapToAst); + } + var defaultOptions = _.cloneDeep(this.defaultOptions || {}), userOptions = options || overloadedOptions || {}; + if (!_.isPlainObject(options) && _.isString(options)) { + userOptions = _.merge({ 'code': options }, _.isObject(overloadedOptions) ? overloadedOptions : {}); + } + // storedModules + // ------------- + // An object that will store all of the user module names + this.storedModules = {}; + // originalAst + // ----------- + // The original AST (Abstract Syntax Tree) before it is transformed + this.originalAst = {}; + // callbackParameterMap + // -------------------- + // An object that will store all of the user module callback parameters (that are used and also do not match the exact name of the dependencies they are representing) and the dependencies that they map to + this.callbackParameterMap = {}; + // conditionalModulesToIgnore + // -------------------------- + // An object that will store any modules that should be ignored (not cleaned) + this.conditionalModulesToIgnore = {}; + // conditionalModulesToNotOptimize + // ------------------------------- + // An object that will store any modules that should not be optimized (but still cleaned) + this.conditionalModulesToNotOptimize = {}; + // matchingCommentLineNumbers + // -------------------------- + // An object that stores any comments that match the commentCleanName option + this.matchingCommentLineNumbers = {}; + // comments + // -------- + // All of the stored program comments + this.comments = []; + // exportsModules + // -------- + // An object that stores a map of all modules that makes use of the exports parameter in define. Useful when declaring variables and making sure circular dependencies work correctly. + this.exportsModules = {}; + // options + // ------- + // Merged user options and default options + this.options = _.merge(defaultOptions, userOptions); + }, + // The object that is publicly accessible + publicAPI = { + // Current project version number + 'VERSION': '2.7.0', + 'clean': function (options, overloadedOptions) { + // Creates a new AMDclean instance + var amdclean = new AMDclean(options, overloadedOptions), cleanedCode = amdclean.clean(); + // returns the cleaned code + return cleanedCode; + } + }; + // AMDclean prototype object + AMDclean.prototype = { + // clean + // ----- + // Creates an AST using Esprima, traverse and updates the AST using Estraverse, and generates standard JavaScript using Escodegen. + 'clean': clean, + // defaultOptions + // -------------- + // Environment - either node or web + 'defaultOptions': defaultOptions + }; + return publicAPI; + })); +}());}(typeof esprima !== "undefined" ? esprima: null, typeof estraverse !== "undefined" ? estraverse: null, typeof escodegen !== "undefined" ? escodegen: null, typeof _ !== "undefined" ? _ : null, typeof sourcemapToAst !== "undefined" ? sourcemapToAst : null)); \ No newline at end of file diff --git a/build/amdclean.optimized.js b/build/amdclean.optimized.js new file mode 100644 index 0000000..1c36f43 --- /dev/null +++ b/build/amdclean.optimized.js @@ -0,0 +1,2302 @@ +// defaultOptions.js +// ================= +// AMDclean default options + +define('defaultOptions',{ + // The source code you would like to be 'cleaned' + 'code': '', + // Provide a source map for the code you'd like to 'clean' + // Output will change from plain code to a hash: {code: ..., map: ...} + // Where code is 'cleaned' code and map is the new source map + 'sourceMap': null, + // The relative file path of the file to be cleaned. Use this option if you are not using the code option. + // Hint: Use the __dirname trick + 'filePath': '', + // The modules that you would like to set as window properties + // An array of strings (module names) + 'globalModules': [], + // All esprima API options are supported: http://esprima.org/doc/ + 'esprima': { + 'comment': true, + 'loc': true, + 'range': true, + 'tokens': true + }, + // All escodegen API options are supported: https://github.com/Constellation/escodegen/wiki/API + 'escodegen': { + 'comment': true, + 'format': { + 'indent': { + 'style': ' ', + 'adjustMultilineComment': true + } + } + }, + // If there is a comment (that contains the following text) on the same line or one line above a specific module, the module will not be removed + 'commentCleanName': 'amdclean', + // The ids of all of the modules that you would not like to be 'cleaned' + 'ignoreModules': [], + // Determines which modules will be removed from the cleaned code + 'removeModules': [], + // Determines if all of the require() method calls will be removed + 'removeAllRequires': false, + // Determines if all of the 'use strict' statements will be removed + 'removeUseStricts': true, + // Determines if conditional AMD checks are transformed + // e.g. if(typeof define == 'function') {} -> if(true) {} + 'transformAMDChecks': true, + // Determines if a named or anonymous AMD module will be created inside of your conditional AMD check + // Note: This is only applicable to JavaScript libraries, do not change this for web apps + // If set to true: e.g. define('example', [], function() {}) -> define([], function() {}) + 'createAnonymousAMDModule': false, + // Allows you to pass an expression that will override shimmed modules return values + // e.g. { 'backbone': 'window.Backbone' } + 'shimOverrides': {}, + // Determines how to prefix a module name with when a non-JavaScript compatible character is found + // 'standard' or 'camelCase' + // 'standard' example: 'utils/example' -> 'utils_example' + // 'camelCase' example: 'utils/example' -> 'utilsExample' + 'prefixMode': 'standard', + // A function hook that allows you add your own custom logic to how each module name is prefixed/normalized + 'prefixTransform': function(postNormalizedModuleName, preNormalizedModuleName) { + return postNormalizedModuleName; + }, + // Wrap any build bundle in a start and end text specified by wrap + // This should only be used when using the onModuleBundleComplete RequireJS Optimizer build hook + // If it is used with the onBuildWrite RequireJS Optimizer build hook, each module will get wrapped + 'wrap': { + 'start': ';(function() {\n', + 'end': '\n}());' + }, + // Determines if certain aggressive file size optimization techniques will be used to transform the soure code + 'aggressiveOptimizations': false, + // Configuration info for modules + // Note: Further info can be found here - http://requirejs.org/docs/api.html#config-moduleconfig + 'config': {} +}); +// errorMsgs.js +// ============ +// AMDclean error messages + +define('errorMsgs',{ + // The user has not supplied the cliean method with any code + 'emptyCode': 'There is no code to generate the AST with', + + // An AST has not been correctly returned by Esprima + 'emptyAst': function(methodName) { + return 'An AST is not being passed to the ' + methodName + '() method'; + }, + + // A parameter is not an object literal (which is expected) + 'invalidObject': function(methodName) { + return 'An object is not being passed as the first parameter to the ' + methodName + '() method'; + }, + + // Third-party dependencies have not been included on the page + 'lodash': 'Make sure you have included lodash (https://github.com/lodash/lodash).', + + 'esprima': 'Make sure you have included esprima (https://github.com/ariya/esprima).', + + 'estraverse': 'Make sure you have included estraverse (https://github.com/Constellation/estraverse).', + + 'escodegen': 'Make sure you have included escodegen (https://github.com/Constellation/escodegen).', + + 'sourcemapToAst': 'Make sure you have included sourcemapToAst (https://github.com/tarruda/sourcemap-to-ast).' +}); +// defaultValues.js +// ================ +// Stores static default values + +define('defaultValues',{ + // dependencyBlacklist + // ------------------- + // Variable names that are not allowed as dependencies to functions + 'dependencyBlacklist': { + 'require': 'remove', + 'exports': true, + 'module': 'remove' + }, + + // defaultLOC + // ---------- + // Default line of code property + 'defaultLOC': { + 'start': { + 'line': 0, + 'column': 0 + } + }, + + // defaultRange + // ------------ + // Default range property + 'defaultRange': [0, 0] +}); +// Utils.js +// ======== +// Abstract Syntax Tree (AST) and other helper utility methods + +define('utils',[ + 'errorMsgs', + 'defaultValues' +], function( + errorMsgs, + defaultValues +) { + var Utils = { + + // isDefine + // -------- + // Returns if the current AST node is a define() method call + 'isDefine': function(node) { + var expression = node.expression || {}, + callee = expression.callee; + + return (_.isObject(node) && + node.type === 'ExpressionStatement' && + expression && + expression.type === 'CallExpression' && + callee.type === 'Identifier' && + callee.name === 'define'); + }, + + // isRequire + // --------- + // Returns if the current AST node is a require() method call + 'isRequire': function(node) { + var expression = node.expression || {}, + callee = expression.callee; + + return (node && + node.type === 'ExpressionStatement' && + expression && + expression.type === 'CallExpression' && + callee.type === 'Identifier' && + callee.name === 'require'); + }, + + // isModuleExports + // --------------- + // Is a module.exports member expression + 'isModuleExports': function(node) { + if (!node) { + return false; + } + + return (node.type === 'AssignmentExpression' && + node.left && + node.left.type === 'MemberExpression' && + node.left.object && + node.left.object.type === 'Identifier' && + node.left.object.name === 'module' && + node.left.property && + node.left.property.type === 'Identifier' && + node.left.property.name === 'exports'); + }, + + // isRequireExpression + // ------------------- + // Returns if the current AST node is a require() call expression + // e.g. var example = require('someModule'); + 'isRequireExpression': function(node) { + return (node && + node.type === 'CallExpression' && + node.callee && + node.callee.name === 'require'); + }, + + // isObjectExpression + // ------------------ + // Returns if the current AST node is an object literal + 'isObjectExpression': function(expression) { + return (expression && + expression && + expression.type === 'ObjectExpression'); + }, + + // isFunctionExpression + // -------------------- + // Returns if the current AST node is a function + 'isFunctionExpression': function(expression) { + return (expression && + expression && + expression.type === 'FunctionExpression'); + }, + + // isFunctionCallExpression + // ------------------------ + // Returns if the current AST node is a function call expression + 'isFunctionCallExpression': function(expression) { + return (expression && + expression && + expression.type === 'CallExpression' && + expression.callee && + expression.callee.type === 'FunctionExpression'); + }, + + // isUseStrict + // ----------- + // Returns if the current AST node is a 'use strict' expression + // e.g. 'use strict' + 'isUseStrict': function(expression) { + return (expression && + expression && + expression.value === 'use strict' && + expression.type === 'Literal'); + }, + + // isIfStatement + // ------------- + // Returns if the current AST node is an if statement + // e.g. if(true) {} + 'isIfStatement': function(node) { + return (node && + node.type === 'IfStatement' && + node.test); + }, + + // isAMDConditional + // ---------------- + // Returns if the current AST node is an if statement AMD check + // e.g. if(typeof define === 'function') {} + 'isAMDConditional': function(node) { + if (!Utils.isIfStatement(node)) { + return false; + } + + var matchObject = { + 'left': { + 'operator': 'typeof', + 'argument': { + 'type': 'Identifier', + 'name': 'define' + } + }, + 'right': { + 'type': 'Literal', + 'value': 'function' + } + }, + reversedMatchObject = { + 'left': matchObject.right, + 'right': matchObject.left + }; + + try { + return (_.find(node.test, matchObject) || + _.find([node.test], matchObject) || + _.find(node.test, reversedMatchObject) || + _.find([node.test], reversedMatchObject) || + _.find(node.test.left || {}, matchObject) || + _.find([node.test.left || {}], matchObject) || + _.find(node.test.left || {}, reversedMatchObject) || + _.find([node.test.left || {}], reversedMatchObject)); + } catch (e) { + return false; + } + }, + + // returnExpressionIdentifier + // -------------------------- + // Returns a single identifier + // e.g. module + 'returnExpressionIdentifier': function(name) { + return { + 'type': 'ExpressionStatement', + 'expression': { + 'type': 'Identifier', + 'name': name, + 'range': defaultValues.defaultRange, + 'loc': defaultValues.defaultLOC + }, + 'range': defaultValues.defaultRange, + 'loc': defaultValues.defaultLOC + }; + }, + + // readFile + // -------- + // Synchronous file reading for node + 'readFile': function(path) { + if (typeof exports !== 'undefined') { + var fs = require('fs'); + + return fs.readFileSync(path, 'utf8'); + } else { + return ''; + } + }, + + // isRelativeFilePath + // ------------------ + // Returns a boolean that determines if the file path provided is a relative file path + // e.g. ../exampleModule -> true + 'isRelativeFilePath': function(path) { + var segments = path.split('/'); + + return segments.length !== -1 && (segments[0] === '.' || segments[0] === '..'); + }, + + // convertToCamelCase + // ------------------ + // Converts a delimited string to camel case + // e.g. some_str -> someStr + convertToCamelCase: function(input, delimiter) { + delimiter = delimiter || '_'; + + return input.replace(new RegExp(delimiter + '(.)', 'g'), function(match, group1) { + return group1.toUpperCase(); + }); + }, + + // prefixReservedWords + // ------------------- + // Converts a reserved word in JavaScript with an underscore + // e.g. class -> _class + 'prefixReservedWords': function(name) { + var reservedWord = false; + + try { + if (name.length) { + eval('var ' + name + ' = 1;'); + } + } catch (e) { + reservedWord = true; + } + + if (reservedWord === true) { + return '_' + name; + } else { + return name; + } + }, + + // normalizeDependencyName + // ----------------------- + // Returns a normalized dependency name that handles relative file paths + 'normalizeDependencyName': function(moduleId, dep) { + if (!moduleId || !dep) { + return dep; + } + + var pluginName = (function(){ + if (!dep || dep.indexOf("!") === -1) { + return ""; + } + + var split = dep.split("!"); + dep = split[1]; + + return split[0] + "!"; + + }()), + normalizePath = function(path) { + var segments = path.split('/'), + normalizedSegments; + + normalizedSegments = _.reduce(segments, function(memo, segment) { + switch (segment) { + case '.': + break; + case '..': + memo.pop(); + break; + default: + memo.push(segment); + } + + return memo; + }, []); + return normalizedSegments.join('/'); + }, + baseName = function(path) { + var segments = path.split('/'); + + segments.pop(); + return segments.join('/'); + }; + + if (!Utils.isRelativeFilePath(dep)) { + return pluginName + dep; + } + + return pluginName + normalizePath([baseName(moduleId), dep].join('/')); + } + }; + + return Utils; +}); +// convertToIIFE.js +// ================ +// Returns an IIFE +// e.g. (function() { }()) + +define('convertToIIFE',[ + 'defaultValues' +], function( + defaultValues +) { + return function convertToIIFE(obj) { + var callbackFuncParams = obj.callbackFuncParams, + callbackFunc = obj.callbackFunc, + dependencyNames = obj.dependencyNames, + node = obj.node, + range = (node.range || defaultValues.defaultRange), + loc = (node.loc || defaultValues.defaultLOC); + + return { + 'type': 'ExpressionStatement', + 'expression': { + 'type': 'CallExpression', + 'callee': { + 'type': 'FunctionExpression', + 'id': null, + 'params': callbackFuncParams, + 'defaults': [], + 'body': callbackFunc.body, + 'rest': callbackFunc.rest, + 'generator': callbackFunc.generator, + 'expression': callbackFunc.expression, + 'range': range, + 'loc': loc + }, + 'arguments': dependencyNames, + 'range': range, + 'loc': loc + }, + 'range': range, + 'loc': loc + }; + }; +}); +// convertToIIFEDeclaration.js +// =========================== +// Returns a function expression that is executed immediately +// e.g. var example = function(){}() + +define('convertToIIFEDeclaration',[ + 'utils', + 'defaultValues' +], function( + utils, + defaultValues +) { + return function convertToIIFEDeclaration(obj) { + var amdclean = this, + options = amdclean.options, + moduleId = obj.moduleId, + moduleName = obj.moduleName, + hasModuleParam = obj.hasModuleParam, + hasExportsParam = obj.hasExportsParam, + callbackFuncParams = obj.callbackFuncParams, + isOptimized = obj.isOptimized, + callback = obj.callbackFunc, + node = obj.node, + name = callback.name, + type = callback.type, + range = (node.range || defaultValues.defaultRange), + loc = (node.loc || defaultValues.defaultLOC), + callbackFunc = (function() { + var cbFunc = obj.callbackFunc; + + if (type === 'Identifier' && name !== 'undefined') { + cbFunc = { + 'type': 'FunctionExpression', + 'id': null, + 'params': [], + 'defaults': [], + 'body': { + 'type': 'BlockStatement', + 'body': [{ + 'type': 'ReturnStatement', + 'argument': { + 'type': 'ConditionalExpression', + 'test': { + 'type': 'BinaryExpression', + 'operator': '===', + 'left': { + 'type': 'UnaryExpression', + 'operator': 'typeof', + 'argument': { + 'type': 'Identifier', + 'name': name, + 'range': range, + 'loc': loc + }, + 'prefix': true, + 'range': range, + 'loc': loc + }, + 'right': { + 'type': 'Literal', + 'value': 'function', + 'raw': "'function'", + 'range': range, + 'loc': loc + }, + 'range': range, + 'loc': loc + }, + 'consequent': { + 'type': 'CallExpression', + 'callee': { + 'type': 'Identifier', + 'name': name, + 'range': range, + 'loc': loc + }, + 'arguments': callbackFuncParams, + 'range': range, + 'loc': loc + }, + 'alternate': { + 'type': 'Identifier', + 'name': name, + 'range': range, + 'loc': loc + }, + 'range': range, + 'loc': loc + }, + 'range': range, + 'loc': loc + }], + 'range': range, + 'loc': loc + }, + 'rest': null, + 'generator': false, + 'expression': false, + 'range': range, + 'loc': loc + }; + } + return cbFunc; + }()), + dependencyNames = (function() { + var depNames = obj.dependencyNames, + objExpression = { + 'type': 'ObjectExpression', + 'properties': [], + 'range': range, + 'loc': loc + }, + configMemberExpression = { + 'type': 'MemberExpression', + 'computed': true, + 'object': { + 'type': 'Identifier', + 'name': 'modules' + }, + 'property': { + 'type': 'Literal', + 'value': moduleId + } + }, + moduleDepIndex; + + if (options.config && options.config[moduleId]) { + if (hasExportsParam && hasModuleParam) { + return [objExpression, objExpression, configMemberExpression]; + } else if (hasModuleParam) { + moduleDepIndex = _.findIndex(depNames, function(currentDep) { + return currentDep.name === '{}'; + }); + depNames[moduleDepIndex] = configMemberExpression; + } + } + + return depNames; + }()), + cb = (function() { + if (callbackFunc.type === 'Literal' || (callbackFunc.type === 'Identifier' && callbackFunc.name === 'undefined') || isOptimized === true) { + return callbackFunc; + } else { + return { + 'type': 'CallExpression', + 'callee': { + 'type': 'FunctionExpression', + 'id': { + 'type': 'Identifier', + 'name': '', + 'range': range, + 'loc': loc + }, + 'params': callbackFuncParams, + 'defaults': [], + 'body': callbackFunc.body, + 'rest': callbackFunc.rest, + 'generator': callbackFunc.generator, + 'expression': callbackFunc.expression, + 'range': range, + 'loc': loc + }, + 'arguments': dependencyNames, + 'range': range, + 'loc': loc + }; + } + }()), + updatedNode = { + 'type': 'ExpressionStatement', + 'expression': { + 'type': 'AssignmentExpression', + 'operator': '=', + 'left': { + 'type': 'Identifier', + 'name': options.IIFEVariableNameTransform ? options.IIFEVariableNameTransform(moduleName, moduleId) : moduleName, + 'range': range, + 'loc': loc + }, + 'right': cb, + 'range': range, + 'loc': loc + }, + 'range': range, + 'loc': loc + }; + + estraverse.replace(callbackFunc, { + 'enter': function(node) { + if (utils.isModuleExports(node)) { + return { + 'type': 'AssignmentExpression', + 'operator': '=', + 'left': { + 'type': 'Identifier', + 'name': 'exports' + }, + 'right': node.right + }; + } else { + return node; + } + } + }); + + return updatedNode; + }; +}); + +// normalizeModuleName.js +// ====================== +// Returns a normalized module name (removes relative file path urls) + +define('normalizeModuleName',[ + 'utils', + 'defaultValues' +], function( + utils, + defaultValues +) { + return function normalizeModuleName(name, moduleId) { + var amdclean = this, + options = amdclean.options, + prefixMode = options.prefixMode, + prefixTransform = options.prefixTransform, + dependencyBlacklist = defaultValues.dependencyBlacklist, + prefixTransformValue, + preNormalized, + postNormalized; + + name = name || ''; + + if (name === '{}') { + if (dependencyBlacklist[name] === 'remove') { + return ''; + } else { + return name; + } + } + + preNormalized = utils.prefixReservedWords(name.replace(/\./g, '').replace(/[^A-Za-z0-9_$]/g, '_').replace(/^_+/, '')); + + postNormalized = prefixMode === 'camelCase' ? utils.convertToCamelCase(preNormalized) : preNormalized; + + if (_.isFunction(prefixTransform)) { + prefixTransformValue = prefixTransform(postNormalized, name); + if (_.isString(prefixTransformValue) && prefixTransformValue.length) { + return prefixTransformValue; + } + } + + return postNormalized; + }; +}); +// convertToFunctionExpression.js +// ============================== +// Returns either an IIFE or variable declaration. +// Internally calls either convertToIIFE() or convertToIIFEDeclaration() + +define('convertToFunctionExpression',[ + 'utils', + 'convertToIIFE', + 'convertToIIFEDeclaration', + 'defaultValues', + 'normalizeModuleName', + 'defaultValues' +], function( + utils, + convertToIIFE, + convertToIIFEDeclaration, + defaultValues, + normalizeModuleName, + defaultValues +) { + return function convertToFunctionExpression(obj) { + var amdclean = this, + options = amdclean.options, + ignoreModules = options.ignoreModules, + node = obj.node, + isDefine = obj.isDefine, + isRequire = obj.isRequire, + isOptimized = false, + moduleName = obj.moduleName, + moduleId = obj.moduleId, + dependencies = obj.dependencies, + depLength = dependencies.length, + aggressiveOptimizations = options.aggressiveOptimizations, + exportsExpressions = [], + moduleExportsExpressions = [], + defaultRange = defaultValues.defaultRange, + defaultLOC = defaultValues.defaultLOC, + range = obj.range || defaultRange, + loc = obj.loc || defaultLOC, + shouldOptimize = obj.shouldOptimize, + dependencyBlacklist = defaultValues.dependencyBlacklist, + hasNonMatchingParameter = false, + callbackFunc = (function() { + var callbackFunc = obj.moduleReturnValue, + body, + returnStatements, + firstReturnStatement, + returnStatementArg; + + // If the module callback function is not empty + if (callbackFunc && callbackFunc.type === 'FunctionExpression' && callbackFunc.body && _.isArray(callbackFunc.body.body) && callbackFunc.body.body.length) { + + // Filter 'use strict' statements + body = _.filter(callbackFunc.body.body, function(node) { + if (options.removeUseStricts === true) { + return !utils.isUseStrict(node.expression); + } else { + return node; + } + }); + callbackFunc.body.body = body; + + // Returns an array of all return statements + returnStatements = _.filter(body, { + 'type': 'ReturnStatement' + }); + + exportsExpressions = _.filter(body, { + 'left': { + 'type': 'Identifier', + 'name': 'exports' + } + }); + + moduleExportsExpressions = _.filter(body, { + 'left': { + 'type': 'MemberExpression', + 'object': { + 'type': 'Identifier', + 'name': 'module' + }, + 'property': { + 'type': 'Identifier', + 'name': 'exports' + } + } + }); + + // If there is a return statement + if (returnStatements.length) { + firstReturnStatement = returnStatements[0]; + returnStatementArg = firstReturnStatement.argument; + + hasNonMatchingParameter = function() { + var nonMatchingParameter = false; + _.each(callbackFunc.params, function(currentParam) { + var currentParamName = currentParam.name; + if (!amdclean.storedModules[currentParamName] && !dependencyBlacklist[currentParamName]) { + nonMatchingParameter = true; + } + }); + return nonMatchingParameter; + }(); + + // If something other than a function expression is getting returned + // and there is more than one AST child node in the factory function + // return early + if (hasNonMatchingParameter || !shouldOptimize || (!utils.isFunctionExpression(firstReturnStatement) && body.length > 1) || (returnStatementArg && returnStatementArg.type === 'Identifier')) { + return callbackFunc; + } else { + // Optimize the AMD module by setting the callback function to the return statement argument + callbackFunc = returnStatementArg; + isOptimized = true; + + if (callbackFunc.params) { + depLength = callbackFunc.params.length; + } + } + } + } else if (callbackFunc && callbackFunc.type === 'FunctionExpression' && callbackFunc.body && _.isArray(callbackFunc.body.body) && callbackFunc.body.body.length === 0) { + callbackFunc = { + 'type': 'Identifier', + 'name': 'undefined', + 'range': range, + 'loc': loc + }; + depLength = 0; + } + return callbackFunc; + }()), + hasReturnStatement = (function() { + var returns = []; + + if (callbackFunc && callbackFunc.body && _.isArray(callbackFunc.body.body)) { + returns = _.filter(callbackFunc.body.body, { + 'type': 'ReturnStatement' + }); + if (returns.length) { + return true; + } + } + return false; + }()), + originalCallbackFuncParams, + hasExportsParam = (function() { + var cbParams = callbackFunc.params || []; + + return _.filter(cbParams, { + 'name': 'exports' + }).length; + }()), + hasModuleParam = (function() { + var cbParams = callbackFunc.params || []; + + return _.filter(cbParams, { + 'name': 'module' + }).length; + }()), + normalizeDependencyNames = {}, + dependencyNames = (function() { + var deps = [], + currentName; + + _.each(dependencies, function(currentDependency) { + currentName = normalizeModuleName.call(amdclean, utils.normalizeDependencyName(moduleId, currentDependency), moduleId); + normalizeDependencyNames[currentName] = true; + deps.push({ + 'type': 'Identifier', + 'name': currentName, + 'range': defaultRange, + 'loc': defaultLOC + }); + }); + return deps; + }()), + // Makes sure the new name is not an existing callback function dependency and/or existing local variable + findNewParamName = function findNewParamName(name) { + name = '_' + name + '_'; + var containsLocalVariable = (function() { + var containsVariable = false; + + if (normalizeDependencyNames[name]) { + containsVariable = true; + } else { + estraverse.traverse(callbackFunc, { + 'enter': function(node) { + if (node.type === 'VariableDeclarator' && + node.id && + node.id.type === 'Identifier' && + node.id.name === name) { + containsVariable = true; + } + } + }); + } + return containsVariable; + }()); + // If there is not a local variable declaration with the passed name, return the name and surround it with underscores + // Else if there is already a local variable declaration with the passed name, recursively add more underscores surrounding it + if (!containsLocalVariable) { + return name; + } else { + return findNewParamName(name); + } + }, + matchingRequireExpressionNames = (function() { + var matchingNames = []; + + if (hasExportsParam) { + estraverse.traverse(callbackFunc, { + 'enter': function(node) { + var variableName, + expressionName; + + if (node.type === 'VariableDeclarator' && utils.isRequireExpression(node.init)) { + + // If both variable name and expression names are there + if (node.id && node.id.name && node.init && node.init['arguments'] && node.init['arguments'][0] && node.init['arguments'][0].value) { + variableName = node.id.name; + expressionName = normalizeModuleName.call(amdclean, utils.normalizeDependencyName(moduleId, node.init['arguments'][0].value, moduleId)); + + if (!_.includes(ignoreModules, expressionName) && (variableName === expressionName)) { + matchingNames.push({ + 'originalName': expressionName, + 'newName': findNewParamName(expressionName), + 'range': (node.range || defaultRange), + 'loc': (node.loc || defaultLOC) + }); + } + } + } + } + }); + } + return matchingNames; + }()), + matchingRequireExpressionParams = (function() { + var params = []; + + _.each(matchingRequireExpressionNames, function(currentParam) { + params.push({ + 'type': 'Identifier', + 'name': currentParam.newName ? currentParam.newName : currentParam, + 'range': currentParam.range, + 'loc': currentParam.loc + }); + }); + + return params; + }()), + callbackFuncParams = (function() { + var deps = [], + currentName, + cbParams = _.union((callbackFunc.params && callbackFunc.params.length ? callbackFunc.params : !shouldOptimize && dependencyNames && dependencyNames.length ? dependencyNames : []), matchingRequireExpressionParams), + mappedParameter = {}, + // For calculating cbParams we'll optimize by removing not referenced names in the callback parameters. + // If the callback body contains a reference to 'arguments' then we cannot perform this optimization. + // but at the same time if only inner functions body contains arguments WE DO optimize. + // What we do is find inner function declarations and then remove their text from the callback body. Then we look for 'arguments' references + innerFunctions = [], + lookForArgumentsCode; + + if (callbackFunc.body) { + estraverse.traverse(callbackFunc.body, { + enter: function (node, parent) { + if (node.type == 'FunctionExpression' || node.type == 'FunctionDeclaration') + innerFunctions.push(node); + } + }); + if (innerFunctions.length) { + for (var i = callbackFunc.body.range[0]; i < callbackFunc.body.range[1]; i++) { + _.each(innerFunctions, function (innerFunction) { + if (i=innerFunction.range[1]) { + lookForArgumentsCode += amdclean.options.code[i]; + } + }); + } + } else { + lookForArgumentsCode = amdclean.options.code.substring(callbackFunc.body.range[0], callbackFunc.body.range[1]); + } + + if (/[^\w0-9_]arguments[^\w0-9_]/.test(lookForArgumentsCode)) { + cbParams = cbParams.concat(dependencyNames.slice(cbParams.length)); + } + } + + _.each(cbParams, function(currentParam, iterator) { + if (currentParam) { + currentName = currentParam.name; + } else { + currentName = dependencyNames[iterator].name; + } + + if (!shouldOptimize && currentName !== '{}') { + deps.push({ + 'type': 'Identifier', + 'name': currentName, + 'range': defaultRange, + 'loc': defaultLOC + }); + } else if (currentName !== '{}' && (!hasExportsParam || defaultValues.dependencyBlacklist[currentName] !== 'remove')) { + deps.push({ + 'type': 'Identifier', + 'name': currentName, + 'range': defaultRange, + 'loc': defaultLOC + }); + + // If a callback parameter is not the exact name of a stored module and there is a dependency that matches the current callback parameter + if (!isOptimized && aggressiveOptimizations === true && !amdclean.storedModules[currentName] && dependencyNames[iterator]) { + + // If the current dependency has not been stored + if (!amdclean.callbackParameterMap[dependencyNames[iterator].name]) { + amdclean.callbackParameterMap[dependencyNames[iterator].name] = [{ + 'name': currentName, + 'count': 1 + }]; + } else { + mappedParameter = _.filter(amdclean.callbackParameterMap[dependencyNames[iterator].name], { + 'name': currentName + }); + + if (mappedParameter.length) { + mappedParameter = mappedParameter[0]; + mappedParameter.count += 1; + } else { + amdclean.callbackParameterMap[dependencyNames[iterator].name].push({ + 'name': currentName, + 'count': 1 + }); + } + } + } + } + }); + + originalCallbackFuncParams = deps; + + // Only return callback function parameters that do not directly match the name of existing stored modules + return _.filter(deps || [], function(currentParam) { + return aggressiveOptimizations === true && shouldOptimize ? !amdclean.storedModules[currentParam.name] : true; + }); + }()), + isCommonJS = !hasReturnStatement && hasExportsParam, + hasExportsAssignment = exportsExpressions.length || moduleExportsExpressions.length, + dependencyNameLength, + callbackFuncParamsLength; + + // Only return dependency names that do not directly match the name of existing stored modules + dependencyNames = _.filter(dependencyNames || [], function(currentDep, iterator) { + var mappedCallbackParameter = originalCallbackFuncParams[iterator], + currentDepName = currentDep.name; + + // If the matching callback parameter matches the name of a stored module, then do not return it + // Else if the matching callback parameter does not match the name of a stored module, return the dependency + return aggressiveOptimizations === true && shouldOptimize ? (!mappedCallbackParameter || amdclean.storedModules[mappedCallbackParameter.name] && mappedCallbackParameter.name === currentDepName ? !amdclean.storedModules[currentDepName] : !amdclean.storedModules[mappedCallbackParameter.name]) : true; + }); + + dependencyNames = _.map(dependencyNames || [], function(currentDep, iterator) { + if (dependencyBlacklist[currentDep.name]) { + currentDep.name = '{}'; + } + return currentDep; + }); + + dependencyNameLength = dependencyNames.length; + callbackFuncParamsLength = callbackFuncParams.length; + + // If the module dependencies passed into the current module are greater than the used callback function parameters, do not pass the dependencies + if (dependencyNameLength > callbackFuncParamsLength) { + dependencyNames.splice(callbackFuncParamsLength, dependencyNameLength - callbackFuncParamsLength); + } + + // If it is a CommonJS module and there is an exports assignment, make sure to return the exports object + if (isCommonJS && hasExportsAssignment) { + callbackFunc.body.body.push({ + 'type': 'ReturnStatement', + 'argument': { + 'type': 'Identifier', + 'name': 'exports', + 'range': defaultRange, + 'loc': defaultLOC + }, + 'range': defaultRange, + 'loc': defaultLOC + }); + } + + // Makes sure to update all the local variable require expressions to any updated names + estraverse.replace(callbackFunc, { + 'enter': function(node) { + var normalizedModuleName, + newName; + + if (utils.isRequireExpression(node)) { + + if (node['arguments'] && node['arguments'][0] && node['arguments'][0].value) { + + normalizedModuleName = normalizeModuleName.call(amdclean, utils.normalizeDependencyName(moduleId, node['arguments'][0].value, moduleId)); + + if (_.includes(ignoreModules, normalizedModuleName)) { + return node; + } + + if (_.filter(matchingRequireExpressionNames, { + 'originalName': normalizedModuleName + }).length) { + newName = _.filter(matchingRequireExpressionNames, { + 'originalName': normalizedModuleName + })[0].newName; + } + return { + 'type': 'Identifier', + 'name': newName ? newName : normalizedModuleName, + 'range': (node.range || defaultRange), + 'loc': (node.loc || defaultLOC) + }; + } else { + return node; + } + } + } + }); + + if (isDefine) { + return convertToIIFEDeclaration.call(amdclean, { + 'moduleId': moduleId, + 'moduleName': moduleName, + 'dependencyNames': dependencyNames, + 'callbackFuncParams': callbackFuncParams, + 'hasModuleParam': hasModuleParam, + 'hasExportsParam': hasExportsParam, + 'callbackFunc': callbackFunc, + 'isOptimized': isOptimized, + 'node': node + }); + } else if (isRequire) { + return convertToIIFE.call(amdclean, { + 'dependencyNames': dependencyNames, + 'callbackFuncParams': callbackFuncParams, + 'callbackFunc': callbackFunc, + 'node': node + }); + } + }; +}); +// convertToObjectDeclaration.js +// ============================= +// Returns an object variable declaration +// e.g. var example = { exampleProp: true } + +define('convertToObjectDeclaration',[ + 'defaultValues' +], function( + defaultValues +) { + return function(obj, type) { + var node = obj.node, + defaultRange = defaultValues.defaultRange, + defaultLOC = defaultValues.defaultLOC, + range = (node.range || defaultRange), + loc = (node.loc || defaultLOC), + moduleName = obj.moduleName, + moduleReturnValue = (function() { + var modReturnValue, + callee, + params, + returnStatement, + nestedReturnStatement, + internalFunctionExpression; + + if (type === 'functionCallExpression') { + modReturnValue = obj.moduleReturnValue; + callee = modReturnValue.callee; + params = callee.params; + + if (params && params.length && _.isArray(params) && _.filter(params, { + 'name': 'global' + })) { + + if (_.isObject(callee.body) && _.isArray(callee.body.body)) { + returnStatement = _.filter(callee.body.body, { + 'type': 'ReturnStatement' + })[0]; + + if (_.isObject(returnStatement) && _.isObject(returnStatement.argument) && returnStatement.argument.type === 'FunctionExpression') { + internalFunctionExpression = returnStatement.argument; + + if (_.isObject(internalFunctionExpression.body) && _.isArray(internalFunctionExpression.body.body)) { + nestedReturnStatement = _.filter(internalFunctionExpression.body.body, { + 'type': 'ReturnStatement' + })[0]; + + if (_.isObject(nestedReturnStatement.argument) && _.isObject(nestedReturnStatement.argument.right) && _.isObject(nestedReturnStatement.argument.right.property)) { + + if (nestedReturnStatement.argument.right.property.name) { + modReturnValue = { + 'type': 'MemberExpression', + 'computed': false, + 'object': { + 'type': 'Identifier', + 'name': 'window', + 'range': range, + 'loc': loc + }, + 'property': { + 'type': 'Identifier', + 'name': nestedReturnStatement.argument.right.property.name, + 'range': range, + 'loc': loc + }, + 'range': range, + 'loc': loc + }; + } + } + } + } + } + } + } + modReturnValue = modReturnValue || obj.moduleReturnValue; + return modReturnValue; + }()), + updatedNode = { + 'type': 'ExpressionStatement', + 'expression': { + 'type': 'AssignmentExpression', + 'operator': '=', + 'left': { + 'type': 'Identifier', + 'name': moduleName, + 'range': range, + 'loc': loc + }, + 'right': moduleReturnValue, + 'range': range, + 'loc': loc + }, + 'range': range, + 'loc': loc + }; + return updatedNode; + }; +}); +// createAst.js +// ============ +// Returns an AST (Abstract Syntax Tree) that is generated by Esprima + +define('createAst',[ + 'errorMsgs', + 'utils', +], function( + errorMsgs, + utils +) { + return function createAst(providedCode) { + var amdclean = this, + options = amdclean.options, + filePath = options.filePath, + code = providedCode || options.code || (filePath ? utils.readFile(filePath) : ''), + esprimaOptions = options.esprima, + escodegenOptions = options.escodegen; + + if (!code) { + throw new Error(errorMsgs.emptyCode); + } else { + if (!_.isPlainObject(esprima) || !_.isFunction(esprima.parse)) { + throw new Error(errorMsgs.esprima); + } + var ast = esprima.parse(code, esprimaOptions); + if (options.sourceMap) sourcemapToAst(ast, options.sourceMap); + // Check if both the esprima and escodegen comment options are set to true + if (esprimaOptions.comment === true && escodegenOptions.comment === true) { + try { + // Needed to keep source code comments when generating the code with escodegen + ast = escodegen.attachComments(ast, ast.comments, ast.tokens); + } catch (e) {} + } + return ast; + } + }; +}); +// convertDefinesAndRequires.js +// ============================ +// Replaces define() and require() methods to standard JavaScript + +define('convertDefinesAndRequires',[ + 'utils', + 'convertToFunctionExpression', + 'convertToObjectDeclaration', + 'defaultValues', + 'normalizeModuleName', + 'createAst' +], function( + utils, + convertToFunctionExpression, + convertToObjectDeclaration, + defaultValues, + normalizeModuleName, + createAst +) { + return function convertDefinesAndRequires(node, parent) { + var amdclean = this, + options = amdclean.options, + moduleName, + args, + dependencies, + moduleReturnValue, + moduleId, + params, + isDefine = utils.isDefine(node), + isRequire = utils.isRequire(node), + startLineNumber, + callbackFuncArg = false, + type = '', + shouldBeIgnored, + moduleToBeIgnored, + parentHasFunctionExpressionArgument, + defaultRange = defaultValues.defaultRange, + defaultLOC = defaultValues.defaultLOC, + range = node.range || defaultRange, + loc = node.loc || defaultLOC, + dependencyBlacklist = defaultValues.dependencyBlacklist, + shouldOptimize; + + + startLineNumber = isDefine || isRequire ? node.expression.loc.start.line : node && node.loc && node.loc.start ? node.loc.start.line : null; + shouldBeIgnored = (amdclean.matchingCommentLineNumbers[startLineNumber] || amdclean.matchingCommentLineNumbers[startLineNumber - 1]); + + // If it is an AMD conditional statement + // e.g. if(typeof define === 'function') {} + if (utils.isAMDConditional(node)) { + estraverse.traverse(node, { + 'enter': function(node) { + var normalizedModuleName; + if (utils.isDefine(node)) { + if (node.expression && node.expression.arguments && node.expression.arguments.length) { + // Add the module name to the ignore list + if (node.expression.arguments[0].type === 'Literal' && node.expression.arguments[0].value) { + normalizedModuleName = normalizeModuleName.call(amdclean, node.expression.arguments[0].value); + if (options.transformAMDChecks !== true) { + amdclean.conditionalModulesToIgnore[normalizedModuleName] = true; + } else { + amdclean.conditionalModulesToNotOptimize[normalizedModuleName] = true; + } + if (options.createAnonymousAMDModule === true) { + amdclean.storedModules[normalizedModuleName] = false; + node.expression.arguments.shift(); + } + } + } + } + } + }); + + // If the AMD conditional statement should be transformed and not ignored + if (!shouldBeIgnored && options.transformAMDChecks === true) { + + // Transform the AMD conditional statement + // e.g. if(typeof define === 'function') {} -> if(true) {} + node.test = { + 'type': 'Literal', + 'value': true, + 'raw': 'true', + 'range': range, + 'loc': loc + }; + + return node; + } + + } + + if (isDefine || isRequire) { + args = Array.prototype.slice.call(node.expression['arguments'], 0); + + moduleReturnValue = isRequire ? args[1] : args[args.length - 1]; + + moduleId = node.expression['arguments'][0].value; + + moduleName = normalizeModuleName.call(amdclean, moduleId); + + shouldOptimize = !amdclean.conditionalModulesToNotOptimize[moduleName]; + + dependencies = (function() { + var deps = isRequire ? args[0] : args[args.length - 2], + depNames = [], + hasExportsParam; + + if (_.isPlainObject(deps)) { + deps = deps.elements || []; + } else { + deps = []; + } + + hasExportsParam = _.filter(deps, { + 'value': 'exports' + }).length; + + if (_.isArray(deps) && deps.length) { + + _.each(deps, function(currentDependency) { + if (dependencyBlacklist[currentDependency.value] && !shouldOptimize) { + depNames.push(currentDependency.value); + } else if (dependencyBlacklist[currentDependency.value] !== 'remove') { + if (currentDependency.value === "exports") { + depNames.push(moduleName); + amdclean.exportsModules[moduleName] = true; + } else if (dependencyBlacklist[currentDependency.value]) { + depNames.push('{}'); + } else { + depNames.push(currentDependency.value); + } + } else { + if (!hasExportsParam) { + depNames.push('{}'); + } + } + }); + } + return depNames; + }()); + + params = { + 'node': node, + 'moduleName': moduleName, + 'moduleId': moduleId, + 'dependencies': dependencies, + 'moduleReturnValue': moduleReturnValue, + 'isDefine': isDefine, + 'isRequire': isRequire, + 'range': range, + 'loc': loc, + 'shouldOptimize': shouldOptimize + }; + + if (isDefine) { + + if (shouldBeIgnored || !moduleName || amdclean.conditionalModulesToIgnore[moduleName] === true) { + amdclean.options.ignoreModules.push(moduleName); + return node; + } + + if (_.includes(options.removeModules, moduleName)) { + + // Remove the current module from the source + return { + 'type': 'EmptyStatement' + }; + } + + if (_.isObject(options.shimOverrides) && options.shimOverrides[moduleId]) { + params.moduleReturnValue = createAst.call(amdclean, options.shimOverrides[moduleId]); + + if (_.isArray(params.moduleReturnValue.body) && _.isObject(params.moduleReturnValue.body[0])) { + + if (_.isObject(params.moduleReturnValue.body[0].expression)) { + params.moduleReturnValue = params.moduleReturnValue.body[0].expression; + type = 'objectExpression'; + } + } else { + params.moduleReturnValue = moduleReturnValue; + } + } else if (params.moduleReturnValue && params.moduleReturnValue.type === 'Identifier') { + type = 'functionExpression'; + } + + if (_.includes(options.ignoreModules, moduleName)) { + return node; + } else if (utils.isFunctionExpression(moduleReturnValue) || type === 'functionExpression') { + return convertToFunctionExpression.call(amdclean, params); + } else if (utils.isObjectExpression(moduleReturnValue) || type === 'objectExpression') { + return convertToObjectDeclaration.call(amdclean, params); + } else if (utils.isFunctionCallExpression(moduleReturnValue)) { + return convertToObjectDeclaration.call(amdclean, params, 'functionCallExpression'); + } + + } else if (isRequire) { + + if (shouldBeIgnored) { + return node; + } + + callbackFuncArg = _.isArray(node.expression['arguments']) && node.expression['arguments'].length ? node.expression['arguments'][1] && node.expression['arguments'][1].body && node.expression['arguments'][1].body.body && node.expression['arguments'][1].body.body.length : false; + + if (options.removeAllRequires !== true && callbackFuncArg) { + return convertToFunctionExpression.call(amdclean, params); + } else { + // Remove the require include statement from the source + return { + 'type': 'EmptyStatement', + 'range': range, + 'loc': loc + }; + } + } + } else { + + // If the node is a function expression that has an exports parameter and does not return anything, return exports + if (node.type === 'FunctionExpression' && + _.isArray(node.params) && + _.filter(node.params, { + 'type': 'Identifier', + 'name': 'exports' + }).length && + _.isObject(node.body) && + _.isArray(node.body.body) && + !_.filter(node.body.body, { + 'type': 'ReturnStatement' + }).length) { + + parentHasFunctionExpressionArgument = (function() { + + if (!parent || !parent.arguments) { + return false; + } + + if (parent && parent.arguments && parent.arguments.length) { + return _.filter(parent.arguments, { + 'type': 'FunctionExpression' + }).length; + } + + return false; + }()); + + if (parentHasFunctionExpressionArgument) { + + // Adds the logical expression, 'exports = exports || {}', to the beginning of the function expression + node.body.body.unshift({ + 'type': 'ExpressionStatement', + 'expression': { + 'type': 'AssignmentExpression', + 'operator': '=', + 'left': { + 'type': 'Identifier', + 'name': 'exports', + 'range': defaultRange, + 'loc': defaultLOC + }, + 'right': { + 'type': 'LogicalExpression', + 'operator': '||', + 'left': { + 'type': 'Identifier', + 'name': 'exports', + 'range': defaultRange, + 'loc': defaultLOC + }, + 'right': { + 'type': 'ObjectExpression', + 'properties': [], + 'range': defaultRange, + 'loc': defaultLOC + }, + 'range': defaultRange, + 'loc': defaultLOC + }, + 'range': defaultRange, + 'loc': defaultLOC + }, + 'range': defaultRange, + 'loc': defaultLOC + }); + } + + // Adds the return statement, 'return exports', to the end of the function expression + node.body.body.push({ + 'type': 'ReturnStatement', + 'argument': { + 'type': 'Identifier', + 'name': 'exports', + 'range': defaultRange, + 'loc': defaultLOC + }, + 'range': defaultRange, + 'loc': defaultLOC + }); + } + return node; + } + }; +}); + +// traverseAndUpdateAst.js +// ======================= +// Uses Estraverse to traverse the AST and convert all define() and require() methods to standard JavaScript + +define('traverseAndUpdateAst',[ + 'errorMsgs', + 'convertDefinesAndRequires' +], function( + errorMsgs, + convertDefinesAndRequires +) { + return function traverseAndUpdateAst(obj) { + var amdclean = this, + options = amdclean.options, + ast = obj.ast; + + if (!_.isPlainObject(obj)) { + throw new Error(errorMsgs.invalidObject('traverseAndUpdateAst')); + } + + if (!ast) { + throw new Error(errorMsgs.emptyAst('traverseAndUpdateAst')); + } + + if (!_.isPlainObject(estraverse) || !_.isFunction(estraverse.replace)) { + throw new Error(errorMsgs.estraverse); + } + + estraverse.replace(ast, { + 'enter': function(node, parent) { + var ignoreComments; + + if (node.type === 'Program') { + ignoreComments = (function() { + var arr = [], + currentLineNumber; + + amdclean.comments = node.comments; + + _.each(node.comments, function(currentComment) { + var currentCommentValue = (currentComment.value).trim(); + + if (currentCommentValue === options.commentCleanName) { + arr.push(currentComment); + } + }); + return arr; + }()); + + _.each(ignoreComments, function(currentComment) { + currentLineNumber = currentComment.loc.start.line; + amdclean.matchingCommentLineNumbers[currentLineNumber] = true; + }); + + return node; + } + + return convertDefinesAndRequires.call(amdclean, node, parent); + }, + 'leave': function(node) { + return node; + } + }); + + return ast; + }; +}); +// getNormalizedModuleName.js +// ========================== +// Retrieves the module id if the current node is a define() method + +define('getNormalizedModuleName',[ + 'utils', + 'normalizeModuleName' +], function( + utils, + normalizeModuleName +) { + return function getNormalizedModuleName(node) { + if (!utils.isDefine(node)) { + return; + } + + var amdclean = this, + moduleId = node.expression['arguments'][0].value, + moduleName = normalizeModuleName.call(amdclean, moduleId); + + return moduleName; + }; +}); +// findAndStoreAllModuleIds.js +// =========================== +// Uses Estraverse to traverse the AST so that all of the module ids can be found and stored in an object + +define('findAndStoreAllModuleIds',[ + 'errorMsgs', + 'getNormalizedModuleName' +], function( + errorMsgs, + getNormalizedModuleName +) { + return function findAndStoreAllModuleIds(ast) { + var amdclean = this; + + if (!ast) { + throw new Error(errorMsgs.emptyAst('findAndStoreAllModuleIds')); + } + + if (!_.isPlainObject(estraverse) || !_.isFunction(estraverse.traverse)) { + throw new Error(errorMsgs.estraverse); + } + + estraverse.traverse(ast, { + 'enter': function(node, parent) { + var moduleName = getNormalizedModuleName.call(amdclean, node, parent); + + // If the current module has not been stored, store it + if (moduleName && !amdclean.storedModules[moduleName]) { + amdclean.storedModules[moduleName] = true; + } + + // If it is a return statement that returns a define() method call, strip the return statement + if (node.type === 'ReturnStatement' && node.argument && node.argument.callee && node.argument.callee.name === 'define') { + node.type = 'ExpressionStatement'; + node.expression = node.argument; + delete node.argument; + } + } + }); + }; +}); +// generateCode.js +// =============== +// Returns standard JavaScript generated by Escodegen + +define('generateCode',[ + 'errorMsgs' +], function( + errorMsgs +) { + return function generateCode(ast) { + var amdclean = this, + options = amdclean.options, + escodegenOptions = options.escodegen || {}; + + if (!_.isPlainObject(escodegen) || !_.isFunction(escodegen.generate)) { + throw new Error(errorMsgs.escodegen); + } + + return escodegen.generate(ast, escodegenOptions); + }; +}); +// clean.js +// ======== +// Removes any AMD and/or CommonJS trace from the provided source code + +define('clean',[ + 'utils', + 'defaultValues', + 'traverseAndUpdateAst', + 'findAndStoreAllModuleIds', + 'createAst', + 'generateCode', + 'normalizeModuleName' +], function( + utils, + defaultValues, + traverseAndUpdateAst, + findAndStoreAllModuleIds, + createAst, + generateCode, + normalizeModuleName +) { + // clean + // ----- + // Creates an AST using Esprima, traverse and updates the AST using Estraverse, and generates standard JavaScript using Escodegen. + return function clean() { + var amdclean = this, + options = amdclean.options, + ignoreModules = options.ignoreModules, + originalAst = {}, + ast = {}, + configAst = {}, + generatedCode, + declarations = [], + hoistedVariables = {}, + hoistedCallbackParameters = {}, + defaultRange = defaultValues.defaultRange, + defaultLOC = defaultValues.defaultLOC; + + // Creates and stores an AST representation of the code + originalAst = createAst.call(amdclean); + + // Loops through the AST, finds all module ids, and stores them in the current instance storedModules property + findAndStoreAllModuleIds.call(amdclean, originalAst); + + // Traverses the AST and removes any AMD trace + ast = traverseAndUpdateAst.call(amdclean, { + ast: originalAst + }); + + // Post Clean Up + // Removes all empty statements from the source so that there are no single semicolons and + // Makes sure that all require() CommonJS calls are converted + // And all aggressive optimizations (if the option is turned on) are handled + if (ast && _.isArray(ast.body)) { + estraverse.replace(ast, { + enter: function(node, parent) { + var normalizedModuleName, + assignmentName = node && node.left && node.left.name ? node.left.name : '', + cb = node.right, + assignmentNodes = [], + assignments = {}, + mappedParameters = _.filter(amdclean.callbackParameterMap[assignmentName], function(currentParameter) { + return currentParameter && currentParameter.count > 1; + }), + mappedCbDependencyNames, + mappedCbParameterNames, + paramsToRemove = []; + + if (node === undefined || node.type === 'EmptyStatement') { + _.each(parent.body, function(currentNode, iterator) { + if (currentNode === undefined || currentNode.type === 'EmptyStatement') { + parent.body.splice(iterator, 1); + } + }); + } else if (utils.isRequireExpression(node)) { + + if (node['arguments'] && node['arguments'][0] && node['arguments'][0].value) { + normalizedModuleName = normalizeModuleName.call(amdclean, node['arguments'][0].value); + + if (ignoreModules.indexOf(normalizedModuleName) === -1) { + return { + 'type': 'Identifier', + 'name': normalizedModuleName, + 'range': (node.range || defaultRange), + 'loc': (node.loc || defaultLOC) + }; + } else { + return node; + } + } else { + return node; + } + } else if (options.aggressiveOptimizations === true && node.type === 'AssignmentExpression' && assignmentName) { + + // The names of all of the current callback function parameters + mappedCbParameterNames = _.map((cb && cb.callee && cb.callee.params ? cb.callee.params : []), function(currentParam) { + return currentParam.name; + }); + + // The names of all of the current callback function dependencies + mappedCbDependencyNames = _.map(cb.arguments, function(currentArg) { + return currentArg.name; + }); + + // Loop through the dependency names + _.each(mappedCbDependencyNames, function(currentDependencyName) { + + // Nested loop to see if any of the dependency names map to a callback parameter + _.each(amdclean.callbackParameterMap[currentDependencyName], function(currentMapping) { + var mappedName = currentMapping.name, + mappedCount = currentMapping.count; + + // Loops through all of the callback function parameter names to see if any of the parameters should be removed + _.each(mappedCbParameterNames, function(currentParameterName, iterator) { + if (mappedCount > 1 && mappedName === currentParameterName) { + paramsToRemove.push(iterator); + } + }); + }); + }); + + _.each(paramsToRemove, function(currentParam) { + cb.arguments.splice(currentParam, currentParam + 1); + cb.callee.params.splice(currentParam, currentParam + 1); + }); + + // If the current Assignment Expression is a mapped callback parameter + if (amdclean.callbackParameterMap[assignmentName]) { + node.right = (function() { + + // If aggressive optimizations are turned on, the mapped parameter is used more than once, and there are mapped dependencies to be removed + if (options.aggressiveOptimizations === true && mappedParameters.length) { + + // All of the necessary assignment nodes + assignmentNodes = _.map(mappedParameters, function(currentDependency, iterator) { + return { + 'type': 'AssignmentExpression', + 'operator': '=', + 'left': { + 'type': 'Identifier', + 'name': currentDependency.name, + 'range': defaultRange, + 'loc': defaultLOC + }, + 'right': (iterator < mappedParameters.length - 1) ? { + 'range': defaultRange, + 'loc': defaultLOC + } : cb, + 'range': defaultRange, + 'loc': defaultLOC + }; + }); + + // Creates an object containing all of the assignment expressions + assignments = _.reduce(assignmentNodes, function(result, assignment) { + result.right = assignment; + return result; + }); + + // The constructed assignment object node + return assignmentNodes.length ? assignments : cb; + } else { + return cb; + } + }()); + return node; + } + } + } + }); + } + + // Makes any necessary modules global by appending a global instantiation to the code + // eg: window.exampleModule = exampleModule; + if (_.isArray(options.globalModules)) { + + _.each(options.globalModules, function(currentModule) { + + if (_.isString(currentModule) && currentModule.length) { + ast.body.push({ + 'type': 'ExpressionStatement', + 'expression': { + 'type': 'AssignmentExpression', + 'operator': '=', + 'left': { + 'type': 'MemberExpression', + 'computed': false, + 'object': { + 'type': 'Identifier', + 'name': 'window', + 'range': defaultRange, + 'loc': defaultLOC + }, + 'property': { + 'type': 'Identifier', + 'name': currentModule, + 'range': defaultRange, + 'loc': defaultLOC + }, + 'range': defaultRange, + 'loc': defaultLOC + }, + 'right': { + 'type': 'Identifier', + 'name': currentModule, + 'range': defaultRange, + 'loc': defaultLOC + }, + 'range': defaultRange, + 'loc': defaultLOC + }, + 'range': defaultRange, + 'loc': defaultLOC + }); + } + }); + } + + hoistedCallbackParameters = (function() { + var obj = {}, + callbackParameterMap = amdclean.callbackParameterMap, + currentParameterName; + + _.each(callbackParameterMap, function(mappedParameters) { + + _.each(mappedParameters, function(currentParameter) { + if (currentParameter.count > 1) { + currentParameterName = currentParameter.name; + obj[currentParameterName] = true; + } + }); + }); + return obj; + }()); + + // Hoists all modules and necessary callback parameters + hoistedVariables = _.merge(_.cloneDeep(_.reduce(amdclean.storedModules, function(storedModules, key, val) { + if (key !== false) { + storedModules[val] = true; + } + return storedModules; + }, {})), hoistedCallbackParameters); + + // Creates variable declarations for each AMD module/callback parameter that needs to be hoisted + _.each(hoistedVariables, function(moduleValue, moduleName) { + if (!_.includes(options.ignoreModules, moduleName)) { + var _initValue = amdclean.exportsModules[moduleName] !== true ? null : { type: 'ObjectExpression', properties: [] }; + + declarations.push({ + 'type': 'VariableDeclarator', + 'id': { + 'type': 'Identifier', + 'name': moduleName, + 'range': defaultRange, + 'loc': defaultLOC + }, + 'init': _initValue, + 'range': defaultRange, + 'loc': defaultLOC + }); + } + }); + + // Adds a local modules variable if a user wants local module information available to them + if (_.isObject(options.config) && !_.isEmpty(options.config)) { + configAst = (function() { + var props = []; + + _.each(options.config, function(val, key) { + var currentModuleConfig = options.config[key]; + + props.push({ + 'type': 'Property', + 'key': { + 'type': 'Literal', + 'value': key + }, + 'value': { + 'type': 'ObjectExpression', + 'properties': [{ + 'type': 'Property', + 'key': { + 'type': 'Literal', + 'value': 'config' + }, + 'value': { + 'type': 'FunctionExpression', + 'id': null, + 'params': [], + 'defaults': [], + 'body': { + 'type': 'BlockStatement', + 'body': [{ + 'type': 'ReturnStatement', + 'argument': createAst.call(amdclean, 'var x =' + JSON.stringify(currentModuleConfig)).body[0].declarations[0].init + }] + } + }, + 'kind': 'init' + }] + } + }); + }); + + return { + 'type': 'VariableDeclarator', + 'id': { + 'type': 'Identifier', + 'name': 'modules' + }, + 'init': { + 'type': 'ObjectExpression', + 'properties': props + } + }; + }()); + + declarations.push(configAst); + } + + // If there are declarations, the declarations are preprended to the beginning of the code block + if (declarations.length) { + ast.body.unshift({ + 'type': 'VariableDeclaration', + 'declarations': declarations, + 'kind': 'var', + 'range': defaultRange, + 'loc': defaultLOC + }); + } + + // Converts the updated AST to a string of code + generatedCode = generateCode.call(amdclean, ast); + + // If there is a wrap option specified + if (_.isObject(options.wrap)) { + if (_.isString(options.wrap.start) && options.wrap.start.length) { + generatedCode = options.wrap.start + generatedCode; + } + if (_.isString(options.wrap.end) && options.wrap.end.length) { + generatedCode = generatedCode + options.wrap.end; + } + } + + return generatedCode; + }; +}); + +// index.js +// ======== +// Wraps AMDclean in the UMD pattern to support being loaded in multiple environments, +// Sets all of the third-party dependencies +// And exposes the public API + +require([ + 'defaultOptions', + 'errorMsgs', + 'clean' +], function( + defaultOptions, + errorMsgs, + clean +) { + (function(root, factory, undefined) { + 'use strict'; + // Universal Module Definition (UMD) to support AMD, CommonJS/Node.js, and plain browser loading + if (typeof define === 'function' && define.amd) { + factory.amd = true; + define('amdclean',['esprima', 'estraverse', 'escodegen', 'underscore', 'sourcemap-to-ast'], function(esprima, estraverse, escodegen, underscore, sourcemapToAst) { + return factory({ + 'esprima': esprima, + 'estraverse': estraverse, + 'escodegen': escodegen, + 'underscore': underscore, + 'sourcemapToAst': sourcemapToAst + }, root); + }); + } else if (typeof exports !== 'undefined') { + factory.commonjs = true; + module.exports = factory(null, root); + } else { + root.amdclean = factory(null, root); + } + }(this, function cleanamd(amdDependencies, context) { + 'use strict'; + + // Third-Party Dependencies + // Note: These dependencies are hoisted to the top (as local variables) at build time (Look in the gulpfile.js file and the AMDclean wrap option for more details) + sourcemapToAst = (function() { + if (cleanamd.amd && amdDependencies && amdDependencies.sourcemapToAst) { + return amdDependencies.sourcemapToAst; + } else if (cleanamd.commonjs) { + return require('sourcemap-to-ast'); + } else if (context && context.sourcemapToAst) { + return context.sourcemapToAst; + } + }()); + + // Third-Party Dependencies + // Note: These dependencies are hoisted to the top (as local variables) at build time (Look in the gulpfile.js file and the AMDclean wrap option for more details) + esprima = (function() { + if (cleanamd.amd && amdDependencies && amdDependencies.esprima && amdDependencies.esprima.parse) { + return amdDependencies.esprima; + } else if (cleanamd.commonjs) { + return require('esprima'); + } else if (context && context.esprima && context.esprima.parse) { + return context.esprima; + } + }()); + + estraverse = (function() { + if (cleanamd.amd && amdDependencies && amdDependencies.estraverse && amdDependencies.estraverse.traverse) { + return amdDependencies.estraverse; + } else if (cleanamd.commonjs) { + return require('estraverse'); + } else if (context && context.estraverse && context.estraverse.traverse) { + return context.estraverse; + } + }()); + + escodegen = (function() { + if (cleanamd.amd && amdDependencies && amdDependencies.escodegen && amdDependencies.escodegen.generate) { + return amdDependencies.escodegen; + } else if (cleanamd.commonjs) { + return require('escodegen'); + } else if (context && context.escodegen && context.escodegen.generate) { + return context.escodegen; + } + }()); + + _ = (function() { + if (cleanamd.amd && amdDependencies && (amdDependencies.underscore || amdDependencies.lodash || amdDependencies._)) { + return amdDependencies.underscore || amdDependencies.lodash || amdDependencies._; + } else if (cleanamd.commonjs) { + return require('lodash'); + } else if (context && context._) { + return context._; + } + }()); + + // AMDclean constructor function + var AMDclean = function(options, overloadedOptions) { + if (!esprima) { + throw new Error(errorMsgs.esprima); + } else if (!estraverse) { + throw new Error(errorMsgs.estraverse); + } else if (!escodegen) { + throw new Error(errorMsgs.escodegen); + } else if (!_) { + throw new Error(errorMsgs.lodash); + } else if (!sourcemapToAst && typeof window === 'undefined') { + throw new Error(errorMsgs.sourcemapToAst); + } + + var defaultOptions = _.cloneDeep(this.defaultOptions || {}), + userOptions = options || overloadedOptions || {}; + + + if (!_.isPlainObject(options) && _.isString(options)) { + userOptions = _.merge({ + 'code': options + }, _.isObject(overloadedOptions) ? overloadedOptions : {}); + } + + // storedModules + // ------------- + // An object that will store all of the user module names + this.storedModules = {}; + + // originalAst + // ----------- + // The original AST (Abstract Syntax Tree) before it is transformed + this.originalAst = {}; + + // callbackParameterMap + // -------------------- + // An object that will store all of the user module callback parameters (that are used and also do not match the exact name of the dependencies they are representing) and the dependencies that they map to + this.callbackParameterMap = {}; + + // conditionalModulesToIgnore + // -------------------------- + // An object that will store any modules that should be ignored (not cleaned) + this.conditionalModulesToIgnore = {}; + + // conditionalModulesToNotOptimize + // ------------------------------- + // An object that will store any modules that should not be optimized (but still cleaned) + this.conditionalModulesToNotOptimize = {}; + + // matchingCommentLineNumbers + // -------------------------- + // An object that stores any comments that match the commentCleanName option + this.matchingCommentLineNumbers = {}; + + // comments + // -------- + // All of the stored program comments + this.comments = []; + + // exportsModules + // -------- + // An object that stores a map of all modules that makes use of the exports parameter in define. Useful when declaring variables and making sure circular dependencies work correctly. + this.exportsModules = {}; + + // options + // ------- + // Merged user options and default options + this.options = _.merge(defaultOptions, userOptions); + }, + // The object that is publicly accessible + publicAPI = { + // Current project version number + 'VERSION': '2.7.0', + 'clean': function(options, overloadedOptions) { + // Creates a new AMDclean instance + var amdclean = new AMDclean(options, overloadedOptions), + cleanedCode = amdclean.clean(); + + // returns the cleaned code + return cleanedCode; + } + }; + + // AMDclean prototype object + AMDclean.prototype = { + // clean + // ----- + // Creates an AST using Esprima, traverse and updates the AST using Estraverse, and generates standard JavaScript using Escodegen. + 'clean': clean, + + // defaultOptions + // -------------- + // Environment - either node or web + 'defaultOptions': defaultOptions + }; + + return publicAPI; + })); +}); + diff --git a/gulpfile.js b/gulpfile.js deleted file mode 100644 index cdf09c5..0000000 --- a/gulpfile.js +++ /dev/null @@ -1,139 +0,0 @@ -/* - AMDClean Build File -*/ -var gulp = require('gulp'), - uglify = require('gulp-uglify'), - jshint = require('gulp-jshint'), - jasmine = require('gulp-jasmine'), - rename = require('gulp-rename'), - insert = require('gulp-insert'), - requirejs = require('requirejs'), - fs = require('fs'), - amdclean = require('./build/amdclean'), - packageJson = JSON.parse(fs.readFileSync('./package.json', 'utf8')), - licenseText = '\n\n/*' + fs.readFileSync('./LICENSE.txt', 'utf8') + '\n*/\n\n', - currentDate = (function() { - var today = new Date(), - dd = today.getDate(), - mm = today.getMonth() + 1, - yyyy = today.getFullYear(); - - if (dd < 10) { - dd = '0' + dd - } - - if (mm < 10) { - mm = '0' + mm - } - - today = yyyy + '-' + mm + '-' + dd; - return today; - }()), - currentYear = (function() { - var today = new Date(), - yyyy = today.getFullYear(); - - return yyyy; - }()), - headerText = '/*! amdclean - v' + packageJson.version + ' - ' + currentDate + - '\n* http://gregfranko.com/amdclean' + - '\n* Copyright (c) ' + currentYear + ' Greg Franko */\n', - error = false, - cachedBuiltLibText = fs.readFileSync('./src/amdclean.js', 'utf8'); - revertFile = function() { - fs.writeFileSync('./src/amdclean.js', cachedBuiltLibText); - }; - -gulp.task('build', function(cb) { - requirejs.optimize({ - 'findNestedDependencies': false, - 'baseUrl': './src/modules/', - 'optimize': 'none', - 'paths': { - 'amdclean': 'index' - }, - 'include': ['amdclean'], - 'out': './src/amdclean.js', - 'onModuleBundleComplete': function(data) { - var outputFile = data.path, - cleanedCode = (function() { - try { - return amdclean.clean({ - 'filePath': outputFile, - 'transformAMDChecks': false, - 'aggressiveOptimizations': true, - 'ignoreModules': ['esprima', 'estraverse', 'escodegen', 'lodash', 'fs', 'sourcemap_to_ast'], // wtf? parsed name here? - 'removeUseStricts': false, - 'wrap': { - // All of the third party dependencies are hoisted here - // It's a hack, but it's not too painful - 'start': ';(function(esprima, estraverse, escodegen, _, sourcemapToAst) {\n', - 'end': '}(typeof esprima !== "undefined" ? esprima: null, typeof estraverse !== "undefined" ? estraverse: null, typeof escodegen !== "undefined" ? escodegen: null, typeof _ !== "undefined" ? _ : null, typeof sourcemapToAst !== "undefined" ? sourcemapToAst : null));' - }, - 'createAnonymousAMDModule': true - }); - } catch (e) { - error = true; - revertFile(); - return '' + e; - } - }()), - fullCode = headerText + licenseText + cleanedCode; - - if (error) { - revertFile(); - console.log('Looks like there was an error building, stopping the build... ' + cleanedCode); - return; - } - fs.writeFileSync(outputFile, fullCode); - } - }, function() { - if (!error) { - cb(); - } - }, function(err) { - revertFile(); - console.log('Looks like there was an error building, stopping the build... '); - return cb(err); // return error - }); -}); - -gulp.task('lint', ['build'], function() { - gulp.src('src/amdclean.js') - .pipe(jshint({ - 'evil': true, - 'loopfunc': true - })) - .pipe(jshint.reporter('default')); -}); - -gulp.task('test', ['build', 'lint'], function() { - gulp.src('test/specs/convert.js') - .pipe(jasmine()); -}); - -gulp.task('test-only', function() { - gulp.src('test/specs/convert.js') - .pipe(jasmine()); -}); - -gulp.task('minify', ['build', 'lint', 'test'], function() { - gulp.src(['src/amdclean.js']) - .pipe(gulp.dest('build/')) - .pipe(uglify()) - .pipe(insert.prepend(headerText + licenseText)) - .pipe(rename('amdclean.min.js')) - .pipe(gulp.dest('build/')); -}); - -// The default task (called when you run `gulp`) -gulp.task('default', ['build', 'lint', 'test', 'minify']); - -// The watch task that runs the default task on any AMDclean module file changes -gulp.task('watch', function() { - var watcher = gulp.watch('src/modules/*.js', ['default']); - - watcher.on('change', function(event) { - console.log('File ' + event.path + ' was ' + event.type + ', running tasks...'); - }); -}); diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..fd3219e --- /dev/null +++ b/package-lock.json @@ -0,0 +1,1405 @@ +{ + "name": "amdclean", + "version": "2.7.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true + }, + "amdefine": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", + "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=" + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + }, + "dependencies": { + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + } + } + }, + "array-each": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz", + "integrity": "sha1-p5SvDAWrF1KEbudTofIRoFugxE8=", + "dev": true + }, + "array-slice": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz", + "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==", + "dev": true + }, + "async": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.3.tgz", + "integrity": "sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g==", + "dev": true + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "cli": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cli/-/cli-1.0.1.tgz", + "integrity": "sha1-IoF1NPJL+klQw01TLUjsvGIbjBQ=", + "dev": true, + "requires": { + "exit": "0.1.2", + "glob": "^7.1.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "colors": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", + "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "console-browserify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz", + "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=", + "dev": true, + "requires": { + "date-now": "^0.1.4" + } + }, + "core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true + }, + "date-now": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz", + "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=", + "dev": true + }, + "dateformat": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", + "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==", + "dev": true + }, + "deep-is": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==" + }, + "detect-file": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", + "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=", + "dev": true + }, + "dom-serializer": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", + "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==", + "dev": true, + "requires": { + "domelementtype": "^2.0.1", + "entities": "^2.0.0" + }, + "dependencies": { + "domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "dev": true + }, + "entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "dev": true + } + } + }, + "domelementtype": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", + "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", + "dev": true + }, + "domhandler": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.3.0.tgz", + "integrity": "sha1-LeWaCCLVAn+r/28DLCsloqir5zg=", + "dev": true, + "requires": { + "domelementtype": "1" + } + }, + "domutils": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", + "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", + "dev": true, + "requires": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "duplexer": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", + "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", + "dev": true + }, + "entities": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.0.0.tgz", + "integrity": "sha1-sph6o4ITR/zeZCsk/fyeT7cSvyY=", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "escodegen": { + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.14.3.tgz", + "integrity": "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw==", + "requires": { + "esprima": "^4.0.1", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.6.1" + }, + "dependencies": { + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==" + } + } + }, + "esprima": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-1.2.5.tgz", + "integrity": "sha1-CZNQL+r2aBODJXVvMPmlH+7sEek=" + }, + "estraverse": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz", + "integrity": "sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q=" + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" + }, + "eventemitter2": { + "version": "0.4.14", + "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.14.tgz", + "integrity": "sha1-j2G3XN4BKy6esoTUVFWDtWQ7Yas=", + "dev": true + }, + "exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", + "dev": true + }, + "expand-tilde": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", + "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", + "dev": true, + "requires": { + "homedir-polyfill": "^1.0.1" + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" + }, + "figures": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", + "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5", + "object-assign": "^4.1.0" + } + }, + "fined": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fined/-/fined-1.2.0.tgz", + "integrity": "sha512-ZYDqPLGxDkDhDZBjZBb+oD1+j0rA4E0pXY50eplAAOPg2N/gUBSSk5IM1/QhPfyVo19lJ+CvXpqfvk+b2p/8Ng==", + "dev": true, + "requires": { + "expand-tilde": "^2.0.2", + "is-plain-object": "^2.0.3", + "object.defaults": "^1.1.0", + "object.pick": "^1.2.0", + "parse-filepath": "^1.0.1" + } + }, + "flagged-respawn": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.1.tgz", + "integrity": "sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q==", + "dev": true + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true + }, + "for-own": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", + "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", + "dev": true, + "requires": { + "for-in": "^1.0.1" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "getobject": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/getobject/-/getobject-1.0.2.tgz", + "integrity": "sha512-2zblDBaFcb3rB4rF77XVnuINOE2h2k/OnqXAiy0IrTxUfV1iFp3la33oAQVY9pCpWU268WFYVt2t71hlMuLsOg==", + "dev": true + }, + "glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "global-modules": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", + "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", + "dev": true, + "requires": { + "global-prefix": "^1.0.1", + "is-windows": "^1.0.1", + "resolve-dir": "^1.0.0" + } + }, + "global-prefix": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", + "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", + "dev": true, + "requires": { + "expand-tilde": "^2.0.2", + "homedir-polyfill": "^1.0.1", + "ini": "^1.3.4", + "is-windows": "^1.0.1", + "which": "^1.2.14" + } + }, + "grunt": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/grunt/-/grunt-1.5.1.tgz", + "integrity": "sha512-Nli2Cu1rSUJOCVypMIY3SHuwUQ7LdyoDJJ9ig7NUSM8jGOdC/BcrjW5i/1/pEaYqn8P4RLpeDmiqEwQ/uVQbOQ==", + "dev": true, + "requires": { + "dateformat": "~3.0.3", + "eventemitter2": "~0.4.13", + "exit": "~0.1.2", + "findup-sync": "~0.3.0", + "glob": "~7.1.6", + "grunt-cli": "~1.4.3", + "grunt-known-options": "~2.0.0", + "grunt-legacy-log": "~3.0.0", + "grunt-legacy-util": "~2.0.1", + "iconv-lite": "~0.4.13", + "js-yaml": "~3.14.0", + "minimatch": "~3.0.4", + "mkdirp": "~1.0.4", + "nopt": "~3.0.6", + "rimraf": "~3.0.2" + }, + "dependencies": { + "findup-sync": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.3.0.tgz", + "integrity": "sha1-N5MKpdgWt3fANEXhlmzGeQpMCxY=", + "dev": true, + "requires": { + "glob": "~5.0.0" + }, + "dependencies": { + "glob": { + "version": "5.0.15", + "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", + "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", + "dev": true, + "requires": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + } + } + }, + "glob": { + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", + "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "grunt-cli": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/grunt-cli/-/grunt-cli-1.4.3.tgz", + "integrity": "sha512-9Dtx/AhVeB4LYzsViCjUQkd0Kw0McN2gYpdmGYKtE2a5Yt7v1Q+HYZVWhqXc/kGnxlMtqKDxSwotiGeFmkrCoQ==", + "dev": true, + "requires": { + "grunt-known-options": "~2.0.0", + "interpret": "~1.1.0", + "liftup": "~3.0.1", + "nopt": "~4.0.1", + "v8flags": "~3.2.0" + }, + "dependencies": { + "nopt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz", + "integrity": "sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==", + "dev": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + } + } + }, + "interpret": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz", + "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=", + "dev": true + }, + "minimatch": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz", + "integrity": "sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + } + } + }, + "grunt-contrib-jshint": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/grunt-contrib-jshint/-/grunt-contrib-jshint-3.2.0.tgz", + "integrity": "sha512-pcXWCSZWfoMSvcV4BwH21TUtLtcX0Ms8IGuOPIcLeXK3fud9KclY7iqMKY94jFx8TxZzh028YYtpR+io8DiEaQ==", + "dev": true, + "requires": { + "chalk": "~4.1.2", + "hooker": "^0.2.3", + "jshint": "~2.13.4" + } + }, + "grunt-contrib-uglify": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/grunt-contrib-uglify/-/grunt-contrib-uglify-5.1.0.tgz", + "integrity": "sha512-czoxpIWCwDCUy4oKUVz7Nb9aQknBPMsIq4uu4Fz5UX7UTdmU4GwBbefE6yAcgo1bT40Lhciijh8hFd4aqfb3Jg==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "maxmin": "^2.1.0", + "uglify-js": "^3.15.2", + "uri-path": "^1.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "grunt-known-options": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/grunt-known-options/-/grunt-known-options-2.0.0.tgz", + "integrity": "sha512-GD7cTz0I4SAede1/+pAbmJRG44zFLPipVtdL9o3vqx9IEyb7b4/Y3s7r6ofI3CchR5GvYJ+8buCSioDv5dQLiA==", + "dev": true + }, + "grunt-legacy-log": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/grunt-legacy-log/-/grunt-legacy-log-3.0.0.tgz", + "integrity": "sha512-GHZQzZmhyq0u3hr7aHW4qUH0xDzwp2YXldLPZTCjlOeGscAOWWPftZG3XioW8MasGp+OBRIu39LFx14SLjXRcA==", + "dev": true, + "requires": { + "colors": "~1.1.2", + "grunt-legacy-log-utils": "~2.1.0", + "hooker": "~0.2.3", + "lodash": "~4.17.19" + } + }, + "grunt-legacy-log-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/grunt-legacy-log-utils/-/grunt-legacy-log-utils-2.1.0.tgz", + "integrity": "sha512-lwquaPXJtKQk0rUM1IQAop5noEpwFqOXasVoedLeNzaibf/OPWjKYvvdqnEHNmU+0T0CaReAXIbGo747ZD+Aaw==", + "dev": true, + "requires": { + "chalk": "~4.1.0", + "lodash": "~4.17.19" + } + }, + "grunt-legacy-util": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/grunt-legacy-util/-/grunt-legacy-util-2.0.1.tgz", + "integrity": "sha512-2bQiD4fzXqX8rhNdXkAywCadeqiPiay0oQny77wA2F3WF4grPJXCvAcyoWUJV+po/b15glGkxuSiQCK299UC2w==", + "dev": true, + "requires": { + "async": "~3.2.0", + "exit": "~0.1.2", + "getobject": "~1.0.0", + "hooker": "~0.2.3", + "lodash": "~4.17.21", + "underscore.string": "~3.3.5", + "which": "~2.0.2" + }, + "dependencies": { + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "gzip-size": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-3.0.0.tgz", + "integrity": "sha1-VGGI6b3DN/Zzdy+BZgRks4nc5SA=", + "dev": true, + "requires": { + "duplexer": "^0.1.1" + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "homedir-polyfill": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", + "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", + "dev": true, + "requires": { + "parse-passwd": "^1.0.0" + } + }, + "hooker": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/hooker/-/hooker-0.2.3.tgz", + "integrity": "sha1-uDT3I8xKJCqmWWNFnfbZhMXT2Vk=", + "dev": true + }, + "htmlparser2": { + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.8.3.tgz", + "integrity": "sha1-mWwosZFRaovoZQGn15dX5ccMEGg=", + "dev": true, + "requires": { + "domelementtype": "1", + "domhandler": "2.3", + "domutils": "1.5", + "entities": "1.0", + "readable-stream": "1.1" + } + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + }, + "is-absolute": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", + "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", + "dev": true, + "requires": { + "is-relative": "^1.0.0", + "is-windows": "^1.0.1" + } + }, + "is-core-module": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.1.tgz", + "integrity": "sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "is-relative": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", + "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", + "dev": true, + "requires": { + "is-unc-path": "^1.0.0" + } + }, + "is-unc-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", + "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", + "dev": true, + "requires": { + "unc-path-regex": "^0.1.2" + } + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "jasmine": { + "version": "3.99.0", + "resolved": "https://registry.npmjs.org/jasmine/-/jasmine-3.99.0.tgz", + "integrity": "sha512-YIThBuHzaIIcjxeuLmPD40SjxkEcc8i//sGMDKCgkRMVgIwRJf5qyExtlJpQeh7pkeoBSOe6lQEdg+/9uKg9mw==", + "dev": true, + "requires": { + "glob": "^7.1.6", + "jasmine-core": "~3.99.0" + } + }, + "jasmine-core": { + "version": "3.99.1", + "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-3.99.1.tgz", + "integrity": "sha512-Hu1dmuoGcZ7AfyynN3LsfruwMbxMALMka+YtZeGoLuDEySVmVAPaonkNoBRIw/ectu8b9tVQCJNgp4a4knp+tg==", + "dev": true + }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "dependencies": { + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + } + } + }, + "jshint": { + "version": "2.13.4", + "resolved": "https://registry.npmjs.org/jshint/-/jshint-2.13.4.tgz", + "integrity": "sha512-HO3bosL84b2qWqI0q+kpT/OpRJwo0R4ivgmxaO848+bo10rc50SkPnrtwSFXttW0ym4np8jbJvLwk5NziB7jIw==", + "dev": true, + "requires": { + "cli": "~1.0.0", + "console-browserify": "1.1.x", + "exit": "0.1.x", + "htmlparser2": "3.8.x", + "lodash": "~4.17.21", + "minimatch": "~3.0.2", + "strip-json-comments": "1.0.x" + }, + "dependencies": { + "minimatch": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz", + "integrity": "sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + } + } + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "liftup": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/liftup/-/liftup-3.0.1.tgz", + "integrity": "sha512-yRHaiQDizWSzoXk3APcA71eOI/UuhEkNN9DiW2Tt44mhYzX4joFoCZlxsSOF7RyeLlfqzFLQI1ngFq3ggMPhOw==", + "dev": true, + "requires": { + "extend": "^3.0.2", + "findup-sync": "^4.0.0", + "fined": "^1.2.0", + "flagged-respawn": "^1.0.1", + "is-plain-object": "^2.0.4", + "object.map": "^1.0.1", + "rechoir": "^0.7.0", + "resolve": "^1.19.0" + }, + "dependencies": { + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "findup-sync": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-4.0.0.tgz", + "integrity": "sha512-6jvvn/12IC4quLBL1KNokxC7wWTvYncaVUYSoxWw7YykPLuRrnv4qdHcSOywOI5RpkOVGeQRtWM8/q+G6W6qfQ==", + "dev": true, + "requires": { + "detect-file": "^1.0.0", + "is-glob": "^4.0.0", + "micromatch": "^4.0.2", + "resolve-dir": "^1.0.1" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "requires": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + } + }, + "rechoir": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.1.tgz", + "integrity": "sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg==", + "dev": true, + "requires": { + "resolve": "^1.9.0" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + } + } + }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "make-iterator": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz", + "integrity": "sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw==", + "dev": true, + "requires": { + "kind-of": "^6.0.2" + } + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "dev": true + }, + "maxmin": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/maxmin/-/maxmin-2.1.0.tgz", + "integrity": "sha1-TTsiCQPZXu5+t6x/qGTnLcCaMWY=", + "dev": true, + "requires": { + "chalk": "^1.0.0", + "figures": "^1.0.1", + "gzip-size": "^3.0.0", + "pretty-bytes": "^3.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true + }, + "nopt": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", + "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", + "dev": true, + "requires": { + "abbrev": "1" + } + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + }, + "object.defaults": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz", + "integrity": "sha1-On+GgzS0B96gbaFtiNXNKeQ1/s8=", + "dev": true, + "requires": { + "array-each": "^1.0.1", + "array-slice": "^1.0.0", + "for-own": "^1.0.0", + "isobject": "^3.0.0" + } + }, + "object.map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz", + "integrity": "sha1-z4Plncj8wK1fQlDh94s7gb2AHTc=", + "dev": true, + "requires": { + "for-own": "^1.0.0", + "make-iterator": "^1.0.0" + } + }, + "object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "once": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/once/-/once-1.3.3.tgz", + "integrity": "sha1-suJhVXzkwxTsgwTz+oJmPkKXyiA=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + } + }, + "os-homedir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", + "dev": true + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true + }, + "osenv": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", + "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "dev": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "parse-filepath": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", + "integrity": "sha1-pjISf1Oq89FYdvWHLz/6x2PWyJE=", + "dev": true, + "requires": { + "is-absolute": "^1.0.0", + "map-cache": "^0.2.0", + "path-root": "^0.1.1" + } + }, + "parse-passwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", + "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "path-root": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz", + "integrity": "sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc=", + "dev": true, + "requires": { + "path-root-regex": "^0.1.0" + } + }, + "path-root-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", + "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=", + "dev": true + }, + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=" + }, + "pretty-bytes": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-3.0.1.tgz", + "integrity": "sha1-J9AAjXeAY6C0gRuzXHnxvV1fvM8=", + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "readable-stream": { + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "requirejs": { + "version": "2.1.22", + "resolved": "https://registry.npmjs.org/requirejs/-/requirejs-2.1.22.tgz", + "integrity": "sha1-3Xj9LTQYDA1ixyS1uK68BmTgNm8=", + "dev": true + }, + "resolve": { + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", + "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==", + "dev": true, + "requires": { + "is-core-module": "^2.8.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, + "resolve-dir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", + "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", + "dev": true, + "requires": { + "expand-tilde": "^2.0.0", + "global-modules": "^1.0.0" + } + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "optional": true + }, + "sourcemap-to-ast": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/sourcemap-to-ast/-/sourcemap-to-ast-0.0.2.tgz", + "integrity": "sha1-a+dQispBUvwIwbMvMrDyW8iJ/Uk=", + "requires": { + "estraverse": "~1.3.1", + "source-map": "~0.1.30" + }, + "dependencies": { + "estraverse": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.3.2.tgz", + "integrity": "sha1-N8K4k+8T1yPydth41g2FNRUqbEI=" + }, + "source-map": { + "version": "0.1.43", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz", + "integrity": "sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y=", + "requires": { + "amdefine": ">=0.0.4" + } + } + } + }, + "sprintf-js": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", + "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==", + "dev": true + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-json-comments": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-1.0.4.tgz", + "integrity": "sha1-HhX7ysl9Pumb8tc7TGVrCCu6+5E=", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "requires": { + "prelude-ls": "~1.1.2" + } + }, + "uglify-js": { + "version": "3.15.4", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.15.4.tgz", + "integrity": "sha512-vMOPGDuvXecPs34V74qDKk4iJ/SN4vL3Ow/23ixafENYvtrNvtbcgUeugTcUGRGsOF/5fU8/NYSL5Hyb3l1OJA==", + "dev": true + }, + "unc-path-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", + "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=", + "dev": true + }, + "underscore.string": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-3.3.6.tgz", + "integrity": "sha512-VoC83HWXmCrF6rgkyxS9GHv8W9Q5nhMKho+OadDJGzL2oDYbYEppBaCMH6pFlwLeqj2QS+hhkw2kpXkSdD1JxQ==", + "dev": true, + "requires": { + "sprintf-js": "^1.1.1", + "util-deprecate": "^1.0.2" + } + }, + "uri-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/uri-path/-/uri-path-1.0.0.tgz", + "integrity": "sha1-l0fwGDWJM8Md4PzP2C0TjmcmLjI=", + "dev": true + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "v8flags": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.2.0.tgz", + "integrity": "sha512-mH8etigqMfiGWdeXpaaqGfs6BndypxusHHcv2qSHyZkGEznCd/qAXCWWRzeowtL54147cktFOC4P5y+kl8d8Jg==", + "dev": true, + "requires": { + "homedir-polyfill": "^1.0.1" + } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==" + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + } + } +} diff --git a/package.json b/package.json index 421d04e..94269a6 100644 --- a/package.json +++ b/package.json @@ -21,22 +21,18 @@ "test": "jasmine-node test/specs/ --matchall" }, "dependencies": { + "escodegen": "1.x", "esprima": "1.x", - "lodash": "2.x", "estraverse": "1.x", - "escodegen": "1.x", + "lodash": "^4.17.21", "sourcemap-to-ast": "0.0.2" }, "devDependencies": { - "jasmine-node": "~1.14.3", - "gulp": "~3.8.8", - "gulp-uglify": "~0.1.0", - "gulp-jshint": "~1.3.2", - "gulp-jasmine": "~0.1.1", - "gulp-rename": "~0.2.1", - "jasmine-only": "~0.1.0", - "requirejs": "~2.1.11", - "gulp-insert": "~0.3.0" + "grunt": "^1.5.1", + "grunt-contrib-jshint": "^3.2.0", + "grunt-contrib-uglify": "^5.1.0", + "jasmine": "^3.99.0", + "requirejs": "~2.1.11" }, "engine": { "node": ">= 0.8" diff --git a/src/amdclean.js b/src/amdclean.js index e81d779..9b379a5 100644 --- a/src/amdclean.js +++ b/src/amdclean.js @@ -1,6 +1,7 @@ -/*! amdclean - v2.7.0 - 2015-12-05 -* http://gregfranko.com/amdclean -* Copyright (c) 2015 Greg Franko */ +/*! amdclean - v2.7.0 - 2022-04-11 +* Modified work: https://github.com/6si/amdclean +* Original work: https://github.com/gfranko/amdclean +* Original Copyright (c) 2022 Greg Franko */ /*The MIT License (MIT) @@ -586,14 +587,14 @@ convertToFunctionExpression = function convertToFunctionExpression(obj) { }); callbackFunc.body.body = body; // Returns an array of all return statements - returnStatements = _.where(body, { 'type': 'ReturnStatement' }); - exportsExpressions = _.where(body, { + returnStatements = _.filter(body, { 'type': 'ReturnStatement' }); + exportsExpressions = _.filter(body, { 'left': { 'type': 'Identifier', 'name': 'exports' } }); - moduleExportsExpressions = _.where(body, { + moduleExportsExpressions = _.filter(body, { 'left': { 'type': 'MemberExpression', 'object': { @@ -647,7 +648,7 @@ convertToFunctionExpression = function convertToFunctionExpression(obj) { }(), hasReturnStatement = function () { var returns = []; if (callbackFunc && callbackFunc.body && _.isArray(callbackFunc.body.body)) { - returns = _.where(callbackFunc.body.body, { 'type': 'ReturnStatement' }); + returns = _.filter(callbackFunc.body.body, { 'type': 'ReturnStatement' }); if (returns.length) { return true; } @@ -655,10 +656,10 @@ convertToFunctionExpression = function convertToFunctionExpression(obj) { return false; }(), originalCallbackFuncParams, hasExportsParam = function () { var cbParams = callbackFunc.params || []; - return _.where(cbParams, { 'name': 'exports' }).length; + return _.filter(cbParams, { 'name': 'exports' }).length; }(), hasModuleParam = function () { var cbParams = callbackFunc.params || []; - return _.where(cbParams, { 'name': 'module' }).length; + return _.filter(cbParams, { 'name': 'module' }).length; }(), normalizeDependencyNames = {}, dependencyNames = function () { var deps = [], currentName; _.each(dependencies, function (currentDependency) { @@ -709,7 +710,7 @@ convertToFunctionExpression = function convertToFunctionExpression(obj) { if (node.id && node.id.name && node.init && node.init['arguments'] && node.init['arguments'][0] && node.init['arguments'][0].value) { variableName = node.id.name; expressionName = normalizeModuleName.call(amdclean, utils.normalizeDependencyName(moduleId, node.init['arguments'][0].value, moduleId)); - if (!_.contains(ignoreModules, expressionName) && variableName === expressionName) { + if (!_.includes(ignoreModules, expressionName) && variableName === expressionName) { matchingNames.push({ 'originalName': expressionName, 'newName': findNewParamName(expressionName), @@ -792,7 +793,7 @@ convertToFunctionExpression = function convertToFunctionExpression(obj) { 'count': 1 }]; } else { - mappedParameter = _.where(amdclean.callbackParameterMap[dependencyNames[iterator].name], { 'name': currentName }); + mappedParameter = _.filter(amdclean.callbackParameterMap[dependencyNames[iterator].name], { 'name': currentName }); if (mappedParameter.length) { mappedParameter = mappedParameter[0]; mappedParameter.count += 1; @@ -852,11 +853,11 @@ convertToFunctionExpression = function convertToFunctionExpression(obj) { if (utils.isRequireExpression(node)) { if (node['arguments'] && node['arguments'][0] && node['arguments'][0].value) { normalizedModuleName = normalizeModuleName.call(amdclean, utils.normalizeDependencyName(moduleId, node['arguments'][0].value, moduleId)); - if (_.contains(ignoreModules, normalizedModuleName)) { + if (_.includes(ignoreModules, normalizedModuleName)) { return node; } - if (_.where(matchingRequireExpressionNames, { 'originalName': normalizedModuleName }).length) { - newName = _.where(matchingRequireExpressionNames, { 'originalName': normalizedModuleName })[0].newName; + if (_.filter(matchingRequireExpressionNames, { 'originalName': normalizedModuleName }).length) { + newName = _.filter(matchingRequireExpressionNames, { 'originalName': normalizedModuleName })[0].newName; } return { 'type': 'Identifier', @@ -898,13 +899,13 @@ convertToObjectDeclaration = function (obj, type) { modReturnValue = obj.moduleReturnValue; callee = modReturnValue.callee; params = callee.params; - if (params && params.length && _.isArray(params) && _.where(params, { 'name': 'global' })) { + if (params && params.length && _.isArray(params) && _.filter(params, { 'name': 'global' })) { if (_.isObject(callee.body) && _.isArray(callee.body.body)) { - returnStatement = _.where(callee.body.body, { 'type': 'ReturnStatement' })[0]; + returnStatement = _.filter(callee.body.body, { 'type': 'ReturnStatement' })[0]; if (_.isObject(returnStatement) && _.isObject(returnStatement.argument) && returnStatement.argument.type === 'FunctionExpression') { internalFunctionExpression = returnStatement.argument; if (_.isObject(internalFunctionExpression.body) && _.isArray(internalFunctionExpression.body.body)) { - nestedReturnStatement = _.where(internalFunctionExpression.body.body, { 'type': 'ReturnStatement' })[0]; + nestedReturnStatement = _.filter(internalFunctionExpression.body.body, { 'type': 'ReturnStatement' })[0]; if (_.isObject(nestedReturnStatement.argument) && _.isObject(nestedReturnStatement.argument.right) && _.isObject(nestedReturnStatement.argument.right.property)) { if (nestedReturnStatement.argument.right.property.name) { modReturnValue = { @@ -1032,7 +1033,7 @@ convertDefinesAndRequires = function convertDefinesAndRequires(node, parent) { } else { deps = []; } - hasExportsParam = _.where(deps, { 'value': 'exports' }).length; + hasExportsParam = _.filter(deps, { 'value': 'exports' }).length; if (_.isArray(deps) && deps.length) { _.each(deps, function (currentDependency) { if (dependencyBlacklist[currentDependency.value] && !shouldOptimize) { @@ -1072,7 +1073,7 @@ convertDefinesAndRequires = function convertDefinesAndRequires(node, parent) { amdclean.options.ignoreModules.push(moduleName); return node; } - if (_.contains(options.removeModules, moduleName)) { + if (_.includes(options.removeModules, moduleName)) { // Remove the current module from the source return { 'type': 'EmptyStatement' }; } @@ -1089,7 +1090,7 @@ convertDefinesAndRequires = function convertDefinesAndRequires(node, parent) { } else if (params.moduleReturnValue && params.moduleReturnValue.type === 'Identifier') { type = 'functionExpression'; } - if (_.contains(options.ignoreModules, moduleName)) { + if (_.includes(options.ignoreModules, moduleName)) { return node; } else if (utils.isFunctionExpression(moduleReturnValue) || type === 'functionExpression') { return convertToFunctionExpression.call(amdclean, params); @@ -1116,16 +1117,16 @@ convertDefinesAndRequires = function convertDefinesAndRequires(node, parent) { } } else { // If the node is a function expression that has an exports parameter and does not return anything, return exports - if (node.type === 'FunctionExpression' && _.isArray(node.params) && _.where(node.params, { + if (node.type === 'FunctionExpression' && _.isArray(node.params) && _.filter(node.params, { 'type': 'Identifier', 'name': 'exports' - }).length && _.isObject(node.body) && _.isArray(node.body.body) && !_.where(node.body.body, { 'type': 'ReturnStatement' }).length) { + }).length && _.isObject(node.body) && _.isArray(node.body.body) && !_.filter(node.body.body, { 'type': 'ReturnStatement' }).length) { parentHasFunctionExpressionArgument = function () { if (!parent || !parent.arguments) { return false; } if (parent && parent.arguments && parent.arguments.length) { - return _.where(parent.arguments, { 'type': 'FunctionExpression' }).length; + return _.filter(parent.arguments, { 'type': 'FunctionExpression' }).length; } return false; }(); @@ -1432,7 +1433,7 @@ clean = function clean() { }, {})), hoistedCallbackParameters); // Creates variable declarations for each AMD module/callback parameter that needs to be hoisted _.each(hoistedVariables, function (moduleValue, moduleName) { - if (!_.contains(options.ignoreModules, moduleName)) { + if (!_.includes(options.ignoreModules, moduleName)) { var _initValue = amdclean.exportsModules[moduleName] !== true ? null : { type: 'ObjectExpression', properties: [] diff --git a/src/modules/clean.js b/src/modules/clean.js index 9210079..5ac3f87 100644 --- a/src/modules/clean.js +++ b/src/modules/clean.js @@ -243,7 +243,7 @@ define([ // Creates variable declarations for each AMD module/callback parameter that needs to be hoisted _.each(hoistedVariables, function(moduleValue, moduleName) { - if (!_.contains(options.ignoreModules, moduleName)) { + if (!_.includes(options.ignoreModules, moduleName)) { var _initValue = amdclean.exportsModules[moduleName] !== true ? null : { type: 'ObjectExpression', properties: [] }; declarations.push({ diff --git a/src/modules/convertDefinesAndRequires.js b/src/modules/convertDefinesAndRequires.js index 39598b2..15b7046 100644 --- a/src/modules/convertDefinesAndRequires.js +++ b/src/modules/convertDefinesAndRequires.js @@ -111,7 +111,7 @@ define([ deps = []; } - hasExportsParam = _.where(deps, { + hasExportsParam = _.filter(deps, { 'value': 'exports' }).length; @@ -159,7 +159,7 @@ define([ return node; } - if (_.contains(options.removeModules, moduleName)) { + if (_.includes(options.removeModules, moduleName)) { // Remove the current module from the source return { @@ -183,7 +183,7 @@ define([ type = 'functionExpression'; } - if (_.contains(options.ignoreModules, moduleName)) { + if (_.includes(options.ignoreModules, moduleName)) { return node; } else if (utils.isFunctionExpression(moduleReturnValue) || type === 'functionExpression') { return convertToFunctionExpression.call(amdclean, params); @@ -217,13 +217,13 @@ define([ // If the node is a function expression that has an exports parameter and does not return anything, return exports if (node.type === 'FunctionExpression' && _.isArray(node.params) && - _.where(node.params, { + _.filter(node.params, { 'type': 'Identifier', 'name': 'exports' }).length && _.isObject(node.body) && _.isArray(node.body.body) && - !_.where(node.body.body, { + !_.filter(node.body.body, { 'type': 'ReturnStatement' }).length) { @@ -234,7 +234,7 @@ define([ } if (parent && parent.arguments && parent.arguments.length) { - return _.where(parent.arguments, { + return _.filter(parent.arguments, { 'type': 'FunctionExpression' }).length; } diff --git a/src/modules/convertToFunctionExpression.js b/src/modules/convertToFunctionExpression.js index a21d10b..06bfd54 100644 --- a/src/modules/convertToFunctionExpression.js +++ b/src/modules/convertToFunctionExpression.js @@ -61,18 +61,18 @@ define([ callbackFunc.body.body = body; // Returns an array of all return statements - returnStatements = _.where(body, { + returnStatements = _.filter(body, { 'type': 'ReturnStatement' }); - exportsExpressions = _.where(body, { + exportsExpressions = _.filter(body, { 'left': { 'type': 'Identifier', 'name': 'exports' } }); - moduleExportsExpressions = _.where(body, { + moduleExportsExpressions = _.filter(body, { 'left': { 'type': 'MemberExpression', 'object': { @@ -132,7 +132,7 @@ define([ var returns = []; if (callbackFunc && callbackFunc.body && _.isArray(callbackFunc.body.body)) { - returns = _.where(callbackFunc.body.body, { + returns = _.filter(callbackFunc.body.body, { 'type': 'ReturnStatement' }); if (returns.length) { @@ -145,14 +145,14 @@ define([ hasExportsParam = (function() { var cbParams = callbackFunc.params || []; - return _.where(cbParams, { + return _.filter(cbParams, { 'name': 'exports' }).length; }()), hasModuleParam = (function() { var cbParams = callbackFunc.params || []; - return _.where(cbParams, { + return _.filter(cbParams, { 'name': 'module' }).length; }()), @@ -219,7 +219,7 @@ define([ variableName = node.id.name; expressionName = normalizeModuleName.call(amdclean, utils.normalizeDependencyName(moduleId, node.init['arguments'][0].value, moduleId)); - if (!_.contains(ignoreModules, expressionName) && (variableName === expressionName)) { + if (!_.includes(ignoreModules, expressionName) && (variableName === expressionName)) { matchingNames.push({ 'originalName': expressionName, 'newName': findNewParamName(expressionName), @@ -316,7 +316,7 @@ define([ 'count': 1 }]; } else { - mappedParameter = _.where(amdclean.callbackParameterMap[dependencyNames[iterator].name], { + mappedParameter = _.filter(amdclean.callbackParameterMap[dependencyNames[iterator].name], { 'name': currentName }); @@ -398,14 +398,14 @@ define([ normalizedModuleName = normalizeModuleName.call(amdclean, utils.normalizeDependencyName(moduleId, node['arguments'][0].value, moduleId)); - if (_.contains(ignoreModules, normalizedModuleName)) { + if (_.includes(ignoreModules, normalizedModuleName)) { return node; } - if (_.where(matchingRequireExpressionNames, { + if (_.filter(matchingRequireExpressionNames, { 'originalName': normalizedModuleName }).length) { - newName = _.where(matchingRequireExpressionNames, { + newName = _.filter(matchingRequireExpressionNames, { 'originalName': normalizedModuleName })[0].newName; } diff --git a/src/modules/convertToObjectDeclaration.js b/src/modules/convertToObjectDeclaration.js index f7a73e5..c673bf5 100644 --- a/src/modules/convertToObjectDeclaration.js +++ b/src/modules/convertToObjectDeclaration.js @@ -28,12 +28,12 @@ define([ callee = modReturnValue.callee; params = callee.params; - if (params && params.length && _.isArray(params) && _.where(params, { + if (params && params.length && _.isArray(params) && _.filter(params, { 'name': 'global' })) { if (_.isObject(callee.body) && _.isArray(callee.body.body)) { - returnStatement = _.where(callee.body.body, { + returnStatement = _.filter(callee.body.body, { 'type': 'ReturnStatement' })[0]; @@ -41,7 +41,7 @@ define([ internalFunctionExpression = returnStatement.argument; if (_.isObject(internalFunctionExpression.body) && _.isArray(internalFunctionExpression.body.body)) { - nestedReturnStatement = _.where(internalFunctionExpression.body.body, { + nestedReturnStatement = _.filter(internalFunctionExpression.body.body, { 'type': 'ReturnStatement' })[0]; diff --git a/test/specs/convert.js b/test/specs/convert.js index ce7c9f6..298df4e 100644 --- a/test/specs/convert.js +++ b/test/specs/convert.js @@ -1,4 +1,3 @@ -require('jasmine-only'); describe('amdclean specs', function() { var amdclean = require('../../src/amdclean'), requirejs = require('requirejs'), @@ -26,7 +25,6 @@ describe('amdclean specs', function() { var AMDcode = "define('example', [], function() {});", cleanedCode = amdclean.clean(AMDcode, defaultOptions); standardJavaScript = "var example;example=undefined;"; - expect(cleanedCode).toBe(standardJavaScript); });