diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 00000000..dd84ea78 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,38 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: '' +assignees: '' + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Desktop (please complete the following information):** + - OS: [e.g. iOS] + - Browser [e.g. chrome, safari] + - Version [e.g. 22] + +**Smartphone (please complete the following information):** + - Device: [e.g. iPhone6] + - OS: [e.g. iOS8.1] + - Browser [e.g. stock browser, safari] + - Version [e.g. 22] + +**Additional context** +Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 00000000..4cd65b22 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,20 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: '' +labels: '' +assignees: '' + +--- + +**Story:** +A clear and concise description of the feature from the perspective of the main user. + +**Implementation** +A clear and concise description of the feature from the developers point of view. + +**Client/Server/Compile/Database** +Choose one of the above and break goals down into individual tasks with checkboxes next to them. One issue may include multiple tasks for multiple of the above categories + +**Additional context** +Add any other context or screenshots about the feature request here. diff --git a/README.md b/README.md index 6a318bfc..81eec894 100644 --- a/README.md +++ b/README.md @@ -35,9 +35,15 @@ Cloud-based programming interface The development environment is composed of five servers. The first one is run with the [Create React App](https://create-react-app.dev/docs/getting-started/) dev server. The later four are containerized with docker and run with [docker compose](https://docs.docker.com/compose/). * `casmm-client-dev` - localhost:3000 + * `casmm-server-dev` - localhost:1337 + * `casmm-compile-dev` + * `casmm-db-dev` - localhost:5432 + + > The first time the db is started, the [init_db.sh](/scripts/init_db.sh) script will run and seed the database with an environment specific dump. Read about Postgres initialization scripts [here](https://github.com/docker-library/docs/blob/master/postgres/README.md#initialization-scripts) + * `casmm-compile_queue-dev` #### Running @@ -56,6 +62,7 @@ The development environment is composed of five servers. The first one is run wi 3. Run `docker-compose up` from `/` > Grant permission to the **scripts** and **server** directories if you are prompted + ### Staging @@ -87,6 +94,22 @@ The production environment is a Heroku app. It is composed of a web dyno, compil
+## Maintenance + +All three components of the application have their own dependencies managed in their respective `package.json` files. Run `npm outdated` in each folder to see what packages have new releases. Before updating a package (especially new major versions), ensure that there are no breaking changes. Avoid updating all of the packages at once by running `npm update` because it could lead to breaking changes. + +### Strapi + +This is by far the largest and most important dependency we have. Staying up to date with its [releases](https://github.com/strapi/strapi/releases) is important for bug/security fixes and new features. When it comes to actually upgrading Strapi make sure to follow the [migration guides](https://strapi.io/documentation/developer-docs/latest/migration-guide/#instructions)! + +
+ +## CI/CD + +All of the deployments and releases are handled automatically with [GitHub Actions](https://docs.github.com/en/actions). The workflows implement custom [Actions](https://github.com/STEM-C/CaSMM/actions) that live in the [auto](https://github.com/STEM-C/auto) repo. + +
+ ## Contributing ### Git Flow @@ -120,4 +143,3 @@ Before submitting a pull request, merge the target branch into the working branc - PRs to **master** should squash and merge - PRs to all other branches should create a merge commit - diff --git a/client/.gitignore b/client/.gitignore new file mode 100644 index 00000000..483a9c42 --- /dev/null +++ b/client/.gitignore @@ -0,0 +1 @@ +package-lock.json \ No newline at end of file diff --git a/client/package.json b/client/package.json index 1a3eb4b8..5e7cf017 100644 --- a/client/package.json +++ b/client/package.json @@ -10,7 +10,7 @@ "@testing-library/react": "^9.3.2", "@testing-library/user-event": "^7.1.2", "antd": "^4.3.5", - "axios": "^0.19.2", + "axios": "^0.21.1", "craco-less": "^1.17.0", "cross-env": "^7.0.2", "emoji-picker-react": "^3.2.1", @@ -19,7 +19,8 @@ "react-dom": "^16.13.1", "react-papaparse": "^3.7.0", "react-router-dom": "^5.1.2", - "react-scripts": "3.4.1" + "react-scripts": "3.4.1", + "yarn": "^1.22.10" }, "scripts": { "start": "craco start", diff --git a/client/public/lib/arduino_compressed.js b/client/public/lib/arduino_compressed.js index 5a5088a4..6e5f2a3a 100644 --- a/client/public/lib/arduino_compressed.js +++ b/client/public/lib/arduino_compressed.js @@ -5,101 +5,1232 @@ Licensed under the Apache License, Version 2.0 (the "License"): http://www.apache.org/licenses/LICENSE-2.0 */ -Blockly.Arduino=new Blockly.Generator("Arduino");Blockly.Arduino.StaticTyping=new Blockly.StaticTyping;Blockly.Arduino.addReservedWords("Blockly,setup,loop,if,else,for,switch,case,while,do,break,continue,return,goto,define,include,HIGH,LOW,INPUT,OUTPUT,INPUT_PULLUP,true,false,integer,constants,floating,point,void,boolean,char,unsigned,byte,int,word,long,float,double,string,String,array,static,volatile,const,sizeof,pinMode,digitalWrite,digitalRead,analogReference,analogRead,analogWrite,tone,noTone,shiftOut,shitIn,pulseIn,millis,micros,delay,delayMicroseconds,min,max,abs,constrain,map,pow,sqrt,sin,cos,tan,randomSeed,random,lowByte,highByte,bitRead,bitWrite,bitSet,bitClear,bit,attachInterrupt,detachInterrupt,interrupts,noInterrupts"); -Blockly.Arduino.ORDER_ATOMIC=0;Blockly.Arduino.ORDER_UNARY_POSTFIX=1;Blockly.Arduino.ORDER_UNARY_PREFIX=2;Blockly.Arduino.ORDER_MULTIPLICATIVE=3;Blockly.Arduino.ORDER_ADDITIVE=4;Blockly.Arduino.ORDER_SHIFT=5;Blockly.Arduino.ORDER_RELATIONAL=6;Blockly.Arduino.ORDER_EQUALITY=7;Blockly.Arduino.ORDER_BITWISE_AND=8;Blockly.Arduino.ORDER_BITWISE_XOR=9;Blockly.Arduino.ORDER_BITWISE_OR=10;Blockly.Arduino.ORDER_LOGICAL_AND=11;Blockly.Arduino.ORDER_LOGICAL_OR=12;Blockly.Arduino.ORDER_CONDITIONAL=13; -Blockly.Arduino.ORDER_ASSIGNMENT=14;Blockly.Arduino.ORDER_NONE=99;Blockly.Arduino.PinTypes={INPUT:"INPUT",OUTPUT:"OUTPUT",PWM:"PWM",SERVO:"SERVO",STEPPER:"STEPPER",SERIAL:"SERIAL",I2C:"I2C/TWI",SPI:"SPI"};Blockly.Arduino.DEF_FUNC_NAME=Blockly.Arduino.FUNCTION_NAME_PLACEHOLDER_; -Blockly.Arduino.init=function(a){Blockly.Arduino.includes_=Object.create(null);Blockly.Arduino.definitions_=Object.create(null);Blockly.Arduino.variables_=Object.create(null);Blockly.Arduino.codeFunctions_=Object.create(null);Blockly.Arduino.userFunctions_=Object.create(null);Blockly.Arduino.functionNames_=Object.create(null);Blockly.Arduino.setups_=Object.create(null);Blockly.Arduino.pins_=Object.create(null);Blockly.Arduino.variableDB_?Blockly.Arduino.variableDB_.reset():Blockly.Arduino.variableDB_= -new Blockly.Names(Blockly.Arduino.RESERVED_WORDS_);var b=Blockly.Arduino.StaticTyping.collectVarsWithTypes(a);Blockly.Arduino.StaticTyping.setProcedureArgs(a,b);for(var c in b)Blockly.Arduino.addVariable(c,Blockly.Arduino.getArduinoType_(b[c])+" "+Blockly.Arduino.variableDB_.getName(c,Blockly.Variables.NAME_TYPE)+";")}; -Blockly.Arduino.finish=function(a){var b=[],c=[],d=[],e=[],f;for(f in Blockly.Arduino.includes_)b.push(Blockly.Arduino.includes_[f]);b.length&&b.push("\n");for(f in Blockly.Arduino.variables_)d.push(Blockly.Arduino.variables_[f]);d.length&&d.push("\n");for(f in Blockly.Arduino.definitions_)c.push(Blockly.Arduino.definitions_[f]);c.length&&c.push("\n");for(f in Blockly.Arduino.codeFunctions_)e.push(Blockly.Arduino.codeFunctions_[f]);for(f in Blockly.Arduino.userFunctions_)e.push(Blockly.Arduino.userFunctions_[f]); -e.length&&e.push("\n");var g=[""],h="";void 0!==Blockly.Arduino.setups_.userSetupCode&&(h="\n"+Blockly.Arduino.setups_.userSetupCode,delete Blockly.Arduino.setups_.userSetupCode);for(f in Blockly.Arduino.setups_)g.push(Blockly.Arduino.setups_[f]);h&&g.push(h);delete Blockly.Arduino.includes_;delete Blockly.Arduino.definitions_;delete Blockly.Arduino.codeFunctions_;delete Blockly.Arduino.userFunctions_;delete Blockly.Arduino.functionNames_;delete Blockly.Arduino.setups_;delete Blockly.Arduino.pins_; -Blockly.Arduino.variableDB_.reset();b=b.join("\n")+d.join("\n")+c.join("\n")+e.join("\n\n");g="void setup() {"+g.join("\n ")+"\n}\n\n";a="void loop() {\n "+a.replace(/\n/g,"\n ")+"\n}";return b+g+a};Blockly.Arduino.addInclude=function(a,b){void 0===Blockly.Arduino.includes_[a]&&(Blockly.Arduino.includes_[a]=b)};Blockly.Arduino.addDeclaration=function(a,b){void 0===Blockly.Arduino.definitions_[a]&&(Blockly.Arduino.definitions_[a]=b)}; -Blockly.Arduino.addVariable=function(a,b,c){var d=!1;if(c||void 0===Blockly.Arduino.variables_[a])Blockly.Arduino.variables_[a]=b,d=!0;return d};Blockly.Arduino.addSetup=function(a,b,c){var d=!1;if(c||void 0===Blockly.Arduino.setups_[a])Blockly.Arduino.setups_[a]=b,d=!0;return d}; -Blockly.Arduino.addFunction=function(a,b){if(void 0===Blockly.Arduino.codeFunctions_[a]){var c=Blockly.Arduino.variableDB_.getDistinctName(a,Blockly.Generator.NAME_TYPE);Blockly.Arduino.codeFunctions_[a]=b.replace(Blockly.Arduino.DEF_FUNC_NAME,c);Blockly.Arduino.functionNames_[a]=c}return Blockly.Arduino.functionNames_[a]}; -Blockly.Arduino.reservePin=function(a,b,c,d){void 0!==Blockly.Arduino.pins_[b]?Blockly.Arduino.pins_[b]!=c?a.setWarningText(Blockly.Msg.ARD_PIN_WARN1.replace("%1",b).replace("%2",d).replace("%3",c).replace("%4",Blockly.Arduino.pins_[b]),d):a.setWarningText(null,d):(Blockly.Arduino.pins_[b]=c,a.setWarningText(null,d))};Blockly.Arduino.scrubNakedValue=function(a){return a+";\n"}; -Blockly.Arduino.quote_=function(a){a=a.replace(/\\/g,"\\\\").replace(/\n/g,"\\\n").replace(/\$/g,"\\$").replace(/'/g,"\\'");return'"'+a+'"'}; -Blockly.Arduino.scrub_=function(a,b){if(null===b)return"";var c="";if(!a.outputConnection||!a.outputConnection.targetConnection){var d=a.getCommentText();d&&(c+=this.prefixLines(d,"// ")+"\n");for(var e=0;ec||255",GTE:">="}[a.getFieldValue("OP")],c="=="==b||"!="==b?Blockly.Arduino.ORDER_EQUALITY:Blockly.Arduino.ORDER_RELATIONAL,d=Blockly.Arduino.valueToCode(a,"A",c)||"0";a=Blockly.Arduino.valueToCode(a,"B",c)||"0";return[d+" "+b+" "+a,c]}; -Blockly.Arduino.logic_operation=function(a){var b="AND"==a.getFieldValue("OP")?"&&":"||",c="&&"==b?Blockly.Arduino.ORDER_LOGICAL_AND:Blockly.Arduino.ORDER_LOGICAL_OR,d=Blockly.Arduino.valueToCode(a,"A",c)||"false";a=Blockly.Arduino.valueToCode(a,"B",c)||"false";if(d||a){var e="&&"==b?"true":"false";d||(d=e);a||(a=e)}else a=d="false";return[d+" "+b+" "+a,c]}; -Blockly.Arduino.logic_negate=function(a){var b=Blockly.Arduino.ORDER_UNARY_PREFIX;return["!"+(Blockly.Arduino.valueToCode(a,"BOOL",b)||"false"),b]};Blockly.Arduino.logic_boolean=function(a){return["TRUE"==a.getFieldValue("BOOL")?"true":"false",Blockly.Arduino.ORDER_ATOMIC]};Blockly.Arduino.logic_null=function(a){return["NULL",Blockly.Arduino.ORDER_ATOMIC]}; -Blockly.Arduino.logic_ternary=function(a){var b=Blockly.Arduino.valueToCode(a,"IF",Blockly.Arduino.ORDER_CONDITIONAL)||"false",c=Blockly.Arduino.valueToCode(a,"THEN",Blockly.Arduino.ORDER_CONDITIONAL)||"null";a=Blockly.Arduino.valueToCode(a,"ELSE",Blockly.Arduino.ORDER_CONDITIONAL)||"null";return[b+" ? "+c+" : "+a,Blockly.Arduino.ORDER_CONDITIONAL]};Blockly.Arduino.loops={};Blockly.Arduino.controls_repeat=function(a){var b=Number(a.getFieldValue("TIMES")),c=Blockly.Arduino.statementToCode(a,"DO"),c=Blockly.Arduino.addLoopTrap(c,a.id);a=Blockly.Arduino.variableDB_.getDistinctName("count",Blockly.Variables.NAME_TYPE);return"for (int "+a+" = 0; "+a+" < "+b+"; "+a+"++) {\n"+c+"}\n"}; -Blockly.Arduino.controls_repeat_ext=function(a){var b=Blockly.Arduino.valueToCode(a,"TIMES",Blockly.Arduino.ORDER_ADDITIVE)||"0",c=Blockly.Arduino.statementToCode(a,"DO"),c=Blockly.Arduino.addLoopTrap(c,a.id);a="";var d=Blockly.Arduino.variableDB_.getDistinctName("count",Blockly.Variables.NAME_TYPE),e=b;b.match(/^\w+$/)||Blockly.isNumber(b)||(e=Blockly.Arduino.variableDB_.getDistinctName("repeat_end",Blockly.Variables.NAME_TYPE),a+="int "+e+" = "+b+";\n");return a+("for (int "+d+" = 0; "+d+" < "+ -e+"; "+d+"++) {\n"+c+"}\n")};Blockly.Arduino.controls_whileUntil=function(a){var b="UNTIL"==a.getFieldValue("MODE"),c=Blockly.Arduino.valueToCode(a,"BOOL",b?Blockly.Arduino.ORDER_LOGICAL_OR:Blockly.Arduino.ORDER_NONE)||"false",d=Blockly.Arduino.statementToCode(a,"DO"),d=Blockly.Arduino.addLoopTrap(d,a.id);b&&(c.match(/^\w+$/)||(c="("+c+")"),c="!"+c);return"while ("+c+") {\n"+d+"}\n"}; -Blockly.Arduino.controls_for=function(a){var b=Blockly.Arduino.variableDB_.getName(a.getFieldValue("VAR"),Blockly.Variables.NAME_TYPE),c=Blockly.Arduino.valueToCode(a,"FROM",Blockly.Arduino.ORDER_ASSIGNMENT)||"0",d=Blockly.Arduino.valueToCode(a,"TO",Blockly.Arduino.ORDER_ASSIGNMENT)||"0",e=Blockly.Arduino.valueToCode(a,"BY",Blockly.Arduino.ORDER_ASSIGNMENT)||"1",f=Blockly.Arduino.statementToCode(a,"DO"),f=Blockly.Arduino.addLoopTrap(f,a.id);if(Blockly.isNumber(c)&&Blockly.isNumber(d)&&Blockly.isNumber(e)){var g= -parseFloat(c)<=parseFloat(d);a="for ("+b+" = "+c+"; "+b+(g?" <= ":" >= ")+d+"; "+b;b=Math.abs(parseFloat(e));a=(1==b?a+(g?"++":"--"):a+((g?" += ":" -= ")+b))+(") {\n"+f+"}\n")}else a="",g=c,c.match(/^\w+$/)||Blockly.isNumber(c)||(g=Blockly.Arduino.variableDB_.getDistinctName(b+"_start",Blockly.Variables.NAME_TYPE),a+="int "+g+" = "+c+";\n"),c=d,d.match(/^\w+$/)||Blockly.isNumber(d)||(c=Blockly.Arduino.variableDB_.getDistinctName(b+"_end",Blockly.Variables.NAME_TYPE),a+="int "+c+" = "+d+";\n"),d=Blockly.Arduino.variableDB_.getDistinctName(b+ -"_inc",Blockly.Variables.NAME_TYPE),a+="int "+d+" = ",a=Blockly.isNumber(e)?a+(Math.abs(e)+";\n"):a+("abs("+e+");\n"),a=a+("if ("+g+" > "+c+") {\n")+(Blockly.Arduino.INDENT+d+" = -"+d+";\n"),a+="}\n",a+="for ("+b+" = "+g+";\n "+d+" >= 0 ? "+b+" <= "+c+" : "+b+" >= "+c+";\n "+b+" += "+d+") {\n"+f+"}\n";return a};Blockly.Arduino.controls_forEach=Blockly.Arduino.noGeneratorCodeLine; -Blockly.Arduino.controls_flow_statements=function(a){switch(a.getFieldValue("FLOW")){case "BREAK":return"break;\n";case "CONTINUE":return"continue;\n"}throw"Unknown flow statement.";};Blockly.Arduino.map={};Blockly.Arduino.base_map=function(a){var b=Blockly.Arduino.valueToCode(a,"NUM",Blockly.Arduino.ORDER_NONE)||"0";a=Blockly.Arduino.valueToCode(a,"DMAX",Blockly.Arduino.ORDER_ATOMIC)||"0";return["map("+b+", 0, 1024, 0, "+a+")",Blockly.Arduino.ORDER_NONE]};Blockly.Arduino.math={};Blockly.Arduino.math_number=function(a){a=parseFloat(a.getFieldValue("NUM"));Infinity==a?a="INFINITY":-Infinity==a&&(a="-INFINITY");return[a,Blockly.Arduino.ORDER_ATOMIC]}; -Blockly.Arduino.math_arithmetic=function(a){var b={ADD:[" + ",Blockly.Arduino.ORDER_ADDITIVE],MINUS:[" - ",Blockly.Arduino.ORDER_ADDITIVE],MULTIPLY:[" * ",Blockly.Arduino.ORDER_MULTIPLICATIVE],DIVIDE:[" / ",Blockly.Arduino.ORDER_MULTIPLICATIVE],POWER:[null,Blockly.Arduino.ORDER_NONE]}[a.getFieldValue("OP")],c=b[0],b=b[1],d=Blockly.Arduino.valueToCode(a,"A",b)||"0";a=Blockly.Arduino.valueToCode(a,"B",b)||"0";return c?[d+c+a,b]:["Math.pow("+d+", "+a+")",Blockly.Arduino.ORDER_UNARY_POSTFIX]}; -Blockly.Arduino.math_single=function(a){var b=a.getFieldValue("OP"),c;if("NEG"==b)return a=Blockly.Arduino.valueToCode(a,"NUM",Blockly.Arduino.ORDER_UNARY_PREFIX)||"0","-"==a[0]&&(a=" "+a),["-"+a,Blockly.Arduino.ORDER_UNARY_PREFIX];a="ABS"==b||"ROUND"==b.substring(0,5)?Blockly.Arduino.valueToCode(a,"NUM",Blockly.Arduino.ORDER_UNARY_POSTFIX)||"0":"SIN"==b||"COS"==b||"TAN"==b?Blockly.Arduino.valueToCode(a,"NUM",Blockly.Arduino.ORDER_MULTIPLICATIVE)||"0":Blockly.Arduino.valueToCode(a,"NUM",Blockly.Arduino.ORDER_NONE)|| -"0";switch(b){case "ABS":c="abs("+a+")";break;case "ROOT":c="sqrt("+a+")";break;case "LN":c="log("+a+")";break;case "EXP":c="exp("+a+")";break;case "POW10":c="pow(10,"+a+")";break;case "ROUND":c="round("+a+")";break;case "ROUNDUP":c="ceil("+a+")";break;case "ROUNDDOWN":c="floor("+a+")";break;case "SIN":c="sin("+a+" / 180 * Math.PI)";break;case "COS":c="cos("+a+" / 180 * Math.PI)";break;case "TAN":c="tan("+a+" / 180 * Math.PI)"}if(c)return[c,Blockly.Arduino.ORDER_UNARY_POSTFIX];switch(b){case "LOG10":c= -"log("+a+") / log(10)";break;case "ASIN":c="asin("+a+") / M_PI * 180";break;case "ACOS":c="acos("+a+") / M_PI * 180";break;case "ATAN":c="atan("+a+") / M_PI * 180";break;default:throw"Unknown math operator: "+b;}return[c,Blockly.Arduino.ORDER_MULTIPLICATIVE]}; -Blockly.Arduino.math_constant=function(a){return{PI:["M_PI",Blockly.Arduino.ORDER_UNARY_POSTFIX],E:["M_E",Blockly.Arduino.ORDER_UNARY_POSTFIX],GOLDEN_RATIO:["(1 + sqrt(5)) / 2",Blockly.Arduino.ORDER_MULTIPLICATIVE],SQRT2:["M_SQRT2",Blockly.Arduino.ORDER_UNARY_POSTFIX],SQRT1_2:["M_SQRT1_2",Blockly.Arduino.ORDER_UNARY_POSTFIX],INFINITY:["INFINITY",Blockly.Arduino.ORDER_ATOMIC]}[a.getFieldValue("CONSTANT")]}; -Blockly.Arduino.math_number_property=function(a){var b=Blockly.Arduino.valueToCode(a,"NUMBER_TO_CHECK",Blockly.Arduino.ORDER_MULTIPLICATIVE)||"0",c=a.getFieldValue("PROPERTY"),d;if("PRIME"==c)return a=Blockly.Arduino.addFunction("mathIsPrime",["boolean "+Blockly.Arduino.DEF_FUNC_NAME+"(int n) {"," // https://en.wikipedia.org/wiki/Primality_test#Naive_methods\n if (n == 2 || n == 3) {\n return true;\n }\n // False if n is NaN, negative, is 1.\n // And false if n is divisible by 2 or 3.\n if (isnan(n) || (n <= 1) || (n == 1) || (n % 2 == 0) || (n % 3 == 0)) {\n return false;\n }\n // Check all the numbers of form 6k +/- 1, up to sqrt(n).\n for (int x = 6; x <= sqrt(n) + 1; x += 6) {\n if (n % (x - 1) == 0 || n % (x + 1) == 0) {\n return false;\n }\n }\n return true;\n}"].join("\n")), -Blockly.Arduino.addInclude("math","#include "),[a+"("+b+")",Blockly.Arduino.ORDER_UNARY_POSTFIX];switch(c){case "EVEN":d=b+" % 2 == 0";break;case "ODD":d=b+" % 2 == 1";break;case "WHOLE":Blockly.Arduino.addInclude("math","#include ");d="(floor("+b+") == "+b+")";break;case "POSITIVE":d=b+" > 0";break;case "NEGATIVE":d=b+" < 0";break;case "DIVISIBLE_BY":a=Blockly.Arduino.valueToCode(a,"DIVISOR",Blockly.Arduino.ORDER_MULTIPLICATIVE)||"0",d=b+" % "+a+" == 0"}return[d,Blockly.Arduino.ORDER_EQUALITY]}; -Blockly.Arduino.math_change=function(a){var b=Blockly.Arduino.valueToCode(a,"DELTA",Blockly.Arduino.ORDER_ADDITIVE)||"0";return Blockly.Arduino.variableDB_.getName(a.getFieldValue("VAR"),Blockly.Variables.NAME_TYPE)+" += "+b+";\n"};Blockly.Arduino.math_round=Blockly.Arduino.math_single;Blockly.Arduino.math_trig=Blockly.Arduino.math_single;Blockly.Arduino.math_on_list=Blockly.Arduino.noGeneratorCodeInline; -Blockly.Arduino.math_modulo=function(a){var b=Blockly.Arduino.valueToCode(a,"DIVIDEND",Blockly.Arduino.ORDER_MULTIPLICATIVE)||"0";a=Blockly.Arduino.valueToCode(a,"DIVISOR",Blockly.Arduino.ORDER_MULTIPLICATIVE)||"0";return[b+" % "+a,Blockly.Arduino.ORDER_MULTIPLICATIVE]}; -Blockly.Arduino.math_constrain=function(a){var b=Blockly.Arduino.valueToCode(a,"VALUE",Blockly.Arduino.ORDER_NONE)||"0",c=Blockly.Arduino.valueToCode(a,"LOW",Blockly.Arduino.ORDER_NONE)||"0";a=Blockly.Arduino.valueToCode(a,"HIGH",Blockly.Arduino.ORDER_NONE)||"0";return["("+b+" < "+c+" ? "+c+" : ( "+b+" > "+a+" ? "+a+" : "+b+"))",Blockly.Arduino.ORDER_UNARY_POSTFIX]}; -Blockly.Arduino.math_random_int=function(a){var b=Blockly.Arduino.valueToCode(a,"FROM",Blockly.Arduino.ORDER_NONE)||"0";a=Blockly.Arduino.valueToCode(a,"TO",Blockly.Arduino.ORDER_NONE)||"0";var c=Blockly.Arduino.variableDB_.getDistinctName("math_random_int",Blockly.Generator.NAME_TYPE);Blockly.Arduino.math_random_int.random_function=c;return[Blockly.Arduino.addFunction("mathRandomInt",["int "+Blockly.Arduino.DEF_FUNC_NAME+"(int min, int max) {"," if (min > max) {\n // Swap min and max to ensure min is smaller.\n int temp = min;\n min = max;\n max = temp;\n }\n return min + (rand() % (max - min + 1));\n}"].join("\n"))+ -"("+b+", "+a+")",Blockly.Arduino.ORDER_UNARY_POSTFIX]};Blockly.Arduino.math_random_float=function(a){return["(rand() / RAND_MAX)",Blockly.Arduino.ORDER_UNARY_POSTFIX]};Blockly.Arduino.procedures={}; -Blockly.Arduino.procedures_defreturn=function(a){var b=Blockly.Arduino.variableDB_.getName(a.getFieldValue("NAME"),Blockly.Procedures.NAME_TYPE),c=Blockly.Arduino.statementToCode(a,"STACK");Blockly.Arduino.STATEMENT_PREFIX&&(c=Blockly.Arduino.prefixLines(Blockly.Arduino.STATEMENT_PREFIX.replace(/%1/g,"'"+a.id+"'"),Blockly.Arduino.INDENT)+c);Blockly.Arduino.INFINITE_LOOP_TRAP&&(c=Blockly.Arduino.INFINITE_LOOP_TRAP.replace(/%1/g,"'"+a.id+"'")+c);var d=Blockly.Arduino.valueToCode(a,"RETURN",Blockly.Arduino.ORDER_NONE)|| -"";d&&(d=" return "+d+";\n");for(var e=[],f=0;f");Blockly.Arduino.addDeclaration("servo_"+b,"Servo "+d+";");Blockly.Arduino.addSetup("servo_"+b,d+".attach("+b+");",!0);return d+".write("+c+");\n"}; -Blockly.Arduino.servo_read=function(a){var b=a.getFieldValue("SERVO_PIN"),c="myServo"+b;Blockly.Arduino.reservePin(a,b,Blockly.Arduino.PinTypes.SERVO,"Servo Read");Blockly.Arduino.addInclude("servo","#include ");Blockly.Arduino.addDeclaration("servo_"+b,"Servo "+c+";");Blockly.Arduino.addSetup("servo_"+b,c+".attach("+b+");",!0);return[c+".read()",Blockly.Arduino.ORDER_ATOMIC]};Blockly.Arduino.spi={}; -Blockly.Arduino.spi_setup=function(a){var b=a.getFieldValue("SPI_ID"),c=a.getFieldValue("SPI_SHIFT_ORDER"),d=a.getFieldValue("SPI_CLOCK_DIVIDE");a=a.getFieldValue("SPI_MODE");Blockly.Arduino.addInclude("spi","#include ");Blockly.Arduino.addSetup("spi_order",b+".setBitOrder("+c+");",!0);Blockly.Arduino.addSetup("spi_mode",b+".setDataMode("+a+");",!0);Blockly.Arduino.addSetup("spi_div",b+".setClockDivider("+d+");",!0);Blockly.Arduino.addSetup("spi_begin",b+".begin();",!0);return""}; -Blockly.Arduino.spi_transfer=function(a){var b=a.getFieldValue("SPI_ID"),c=a.getFieldValue("SPI_SS"),d=Blockly.Arduino.valueToCode(a,"SPI_DATA",Blockly.Arduino.ORDER_ATOMIC)||"0";Blockly.Arduino.addInclude("spi","#include ");Blockly.Arduino.addSetup("spi_begin",b+".begin();",!1);for(var e=Blockly.Arduino.Boards.selected.spiPins[b],f=0;f");Blockly.Arduino.addDeclaration(c,e);Blockly.Arduino.addSetup(c,c+".setSpeed("+f+");",!0);return""}; -Blockly.Arduino.stepper_step=function(a){var b="stepper_"+a.getFieldValue("STEPPER_NAME");a=Blockly.Arduino.valueToCode(a,"STEPPER_STEPS",Blockly.Arduino.ORDER_ATOMIC)||"0";return b+".step("+a+");\n"};Blockly.Arduino.text={};Blockly.Arduino.text=function(a){return[Blockly.Arduino.quote_(a.getFieldValue("TEXT")),Blockly.Arduino.ORDER_ATOMIC]}; -Blockly.Arduino.text_join=function(a){var b;if(0==a.itemCount_)return['""',Blockly.Arduino.ORDER_ATOMIC];if(1==a.itemCount_)return["String("+(Blockly.Arduino.valueToCode(a,"ADD0",Blockly.Arduino.ORDER_UNARY_POSTFIX)||'""')+")",Blockly.Arduino.ORDER_UNARY_POSTFIX];var c;b=[];for(var d=0;d c || 255 < c ? a.setWarningText("The analogue value set must be between 0 and 255", "pwm_value") : a.setWarningText(null, "pwm_value"); + return "analogWrite(" + b + ", " + c + ");\n" +}; +Blockly.Arduino.io_analogread = function(a) { + var b = a.getFieldValue("PIN"); + Blockly.Arduino.reservePin(a, b, Blockly.Arduino.PinTypes.INPUT, "Analogue Read"); + Blockly.Arduino.addSetup("io_" + b, "pinMode(" + b + ", INPUT);", !1); + return ["analogRead(" + b + ")", Blockly.Arduino.ORDER_ATOMIC] +}; +Blockly.Arduino.io_highlow = function(a) { + return [a.getFieldValue("STATE"), Blockly.Arduino.ORDER_ATOMIC] +}; +Blockly.Arduino.io_pulsein = function(a) { + var b = a.getFieldValue("PULSEPIN"), + c = Blockly.Arduino.valueToCode(a, "PULSETYPE", Blockly.Arduino.ORDER_ATOMIC); + Blockly.Arduino.reservePin(a, b, Blockly.Arduino.PinTypes.INPUT, "Pulse Pin"); + Blockly.Arduino.addSetup("io_" + b, "pinMode(" + b + ", INPUT);\n", !1); + return ["pulseIn(" + b + ", " + c + ")", Blockly.Arduino.ORDER_ATOMIC] +}; +Blockly.Arduino.io_pulsetimeout = function(a) { + var b = a.getFieldValue("PULSEPIN"), + c = Blockly.Arduino.valueToCode(a, "PULSETYPE", Blockly.Arduino.ORDER_ATOMIC), + d = Blockly.Arduino.valueToCode(a, "TIMEOUT", Blockly.Arduino.ORDER_ATOMIC); + Blockly.Arduino.reservePin(a, b, Blockly.Arduino.PinTypes.INPUT, "Pulse Pin"); + Blockly.Arduino.addSetup("io_" + b, "pinMode(" + b + ", INPUT);\n", !1); + return ["pulseIn(" + b + ", " + c + ", " + d + ")", Blockly.Arduino.ORDER_ATOMIC] +}; +Blockly.Arduino.lists = {}; +Blockly.Arduino.lists_create_empty = Blockly.Arduino.noGeneratorCodeInline; +Blockly.Arduino.lists_create_with = Blockly.Arduino.noGeneratorCodeInline; +Blockly.Arduino.lists_repeat = Blockly.Arduino.noGeneratorCodeInline; +Blockly.Arduino.lists_length = Blockly.Arduino.noGeneratorCodeInline; +Blockly.Arduino.lists_isEmpty = Blockly.Arduino.noGeneratorCodeInline; +Blockly.Arduino.lists_indexOf = Blockly.Arduino.noGeneratorCodeInline; +Blockly.Arduino.lists_getIndex = Blockly.Arduino.noGeneratorCodeInline; +Blockly.Arduino.lists_setIndex = Blockly.Arduino.noGeneratorCodeLine; +Blockly.Arduino.logic = {}; +Blockly.Arduino.controls_if = function(a) { + for (var b = 0, c = Blockly.Arduino.valueToCode(a, "IF" + b, Blockly.Arduino.ORDER_NONE) || "false", d = Blockly.Arduino.statementToCode(a, "DO" + b), e = "if (" + c + ") {\n" + d + "}", b = 1; b <= a.elseifCount_; b++) c = Blockly.Arduino.valueToCode(a, "IF" + b, Blockly.Arduino.ORDER_NONE) || "false", d = Blockly.Arduino.statementToCode(a, "DO" + b), e += " else if (" + c + ") {\n" + d + "}"; + a.elseCount_ && (d = Blockly.Arduino.statementToCode(a, "ELSE"), e += " else {\n" + d + "}"); + return e + "\n" +}; +Blockly.Arduino.logic_compare = function(a) { + var b = { + EQ: "==", + NEQ: "!=", + LT: "<", + LTE: "<=", + GT: ">", + GTE: ">=" + } [a.getFieldValue("OP")], + c = "==" == b || "!=" == b ? Blockly.Arduino.ORDER_EQUALITY : Blockly.Arduino.ORDER_RELATIONAL, + d = Blockly.Arduino.valueToCode(a, "A", c) || "0"; + a = Blockly.Arduino.valueToCode(a, "B", c) || "0"; + return [d + " " + b + " " + a, c] +}; +Blockly.Arduino.logic_operation = function(a) { + var b = "AND" == a.getFieldValue("OP") ? "&&" : "||", + c = "&&" == b ? Blockly.Arduino.ORDER_LOGICAL_AND : Blockly.Arduino.ORDER_LOGICAL_OR, + d = Blockly.Arduino.valueToCode(a, "A", c) || "false"; + a = Blockly.Arduino.valueToCode(a, "B", c) || "false"; + if (d || a) { + var e = "&&" == b ? "true" : "false"; + d || (d = e); + a || (a = e) + } else a = d = "false"; + return [d + " " + b + " " + a, c] +}; +Blockly.Arduino.logic_negate = function(a) { + var b = Blockly.Arduino.ORDER_UNARY_PREFIX; + return ["!" + (Blockly.Arduino.valueToCode(a, "BOOL", b) || "false"), b] +}; +Blockly.Arduino.logic_boolean = function(a) { + return ["TRUE" == a.getFieldValue("BOOL") ? "true" : "false", Blockly.Arduino.ORDER_ATOMIC] +}; +Blockly.Arduino.logic_null = function(a) { + return ["NULL", Blockly.Arduino.ORDER_ATOMIC] +}; +Blockly.Arduino.logic_ternary = function(a) { + var b = Blockly.Arduino.valueToCode(a, "IF", Blockly.Arduino.ORDER_CONDITIONAL) || "false", + c = Blockly.Arduino.valueToCode(a, "THEN", Blockly.Arduino.ORDER_CONDITIONAL) || "null"; + a = Blockly.Arduino.valueToCode(a, "ELSE", Blockly.Arduino.ORDER_CONDITIONAL) || "null"; + return [b + " ? " + c + " : " + a, Blockly.Arduino.ORDER_CONDITIONAL] +}; +Blockly.Arduino.loops = {}; +Blockly.Arduino.controls_repeat = function(a) { + var b = Number(a.getFieldValue("TIMES")), + c = Blockly.Arduino.statementToCode(a, "DO"), + c = Blockly.Arduino.addLoopTrap(c, a.id); + a = Blockly.Arduino.variableDB_.getDistinctName("count", Blockly.Variables.NAME_TYPE); + return "for (int " + a + " = 0; " + a + " < " + b + "; " + a + "++) {\n" + c + "}\n" +}; +Blockly.Arduino.controls_repeat_ext = function(a) { + var b = Blockly.Arduino.valueToCode(a, "TIMES", Blockly.Arduino.ORDER_ADDITIVE) || "0", + c = Blockly.Arduino.statementToCode(a, "DO"), + c = Blockly.Arduino.addLoopTrap(c, a.id); + a = ""; + var d = Blockly.Arduino.variableDB_.getDistinctName("count", Blockly.Variables.NAME_TYPE), + e = b; + b.match(/^\w+$/) || Blockly.isNumber(b) || (e = Blockly.Arduino.variableDB_.getDistinctName("repeat_end", Blockly.Variables.NAME_TYPE), a += "int " + e + " = " + b + ";\n"); + return a + ("for (int " + d + " = 0; " + d + " < " + + e + "; " + d + "++) {\n" + c + "}\n") +}; +Blockly.Arduino.controls_whileUntil = function(a) { + var b = "UNTIL" == a.getFieldValue("MODE"), + c = Blockly.Arduino.valueToCode(a, "BOOL", b ? Blockly.Arduino.ORDER_LOGICAL_OR : Blockly.Arduino.ORDER_NONE) || "false", + d = Blockly.Arduino.statementToCode(a, "DO"), + d = Blockly.Arduino.addLoopTrap(d, a.id); + b && (c.match(/^\w+$/) || (c = "(" + c + ")"), c = "!" + c); + return "while (" + c + ") {\n" + d + "}\n" +}; +Blockly.Arduino.controls_for = function(a) { + var b = Blockly.Arduino.variableDB_.getName(a.getFieldValue("VAR"), Blockly.Variables.NAME_TYPE), + c = Blockly.Arduino.valueToCode(a, "FROM", Blockly.Arduino.ORDER_ASSIGNMENT) || "0", + d = Blockly.Arduino.valueToCode(a, "TO", Blockly.Arduino.ORDER_ASSIGNMENT) || "0", + e = Blockly.Arduino.valueToCode(a, "BY", Blockly.Arduino.ORDER_ASSIGNMENT) || "1", + f = Blockly.Arduino.statementToCode(a, "DO"), + f = Blockly.Arduino.addLoopTrap(f, a.id); + if (Blockly.isNumber(c) && Blockly.isNumber(d) && Blockly.isNumber(e)) { + var g = + parseFloat(c) <= parseFloat(d); + a = "for (" + b + " = " + c + "; " + b + (g ? " <= " : " >= ") + d + "; " + b; + b = Math.abs(parseFloat(e)); + a = (1 == b ? a + (g ? "++" : "--") : a + ((g ? " += " : " -= ") + b)) + (") {\n" + f + "}\n") + } else a = "", g = c, c.match(/^\w+$/) || Blockly.isNumber(c) || (g = Blockly.Arduino.variableDB_.getDistinctName(b + "_start", Blockly.Variables.NAME_TYPE), a += "int " + g + " = " + c + ";\n"), c = d, d.match(/^\w+$/) || Blockly.isNumber(d) || (c = Blockly.Arduino.variableDB_.getDistinctName(b + "_end", Blockly.Variables.NAME_TYPE), a += "int " + c + " = " + d + ";\n"), d = Blockly.Arduino.variableDB_.getDistinctName(b + + "_inc", Blockly.Variables.NAME_TYPE), a += "int " + d + " = ", a = Blockly.isNumber(e) ? a + (Math.abs(e) + ";\n") : a + ("abs(" + e + ");\n"), a = a + ("if (" + g + " > " + c + ") {\n") + (Blockly.Arduino.INDENT + d + " = -" + d + ";\n"), a += "}\n", a += "for (" + b + " = " + g + ";\n " + d + " >= 0 ? " + b + " <= " + c + " : " + b + " >= " + c + ";\n " + b + " += " + d + ") {\n" + f + "}\n"; + return a +}; + +Blockly.Arduino.controls_forEach = Blockly.Arduino.noGeneratorCodeLine; +Blockly.Arduino.controls_flow_statements = function(a) { + switch (a.getFieldValue("FLOW")) { + case "BREAK": + return "break;\n"; + case "CONTINUE": + return "continue;\n" + } + throw "Unknown flow statement."; +}; +Blockly.Arduino.map = {}; +Blockly.Arduino.base_map = function(a) { + var b = Blockly.Arduino.valueToCode(a, "NUM", Blockly.Arduino.ORDER_NONE) || "0"; + a = Blockly.Arduino.valueToCode(a, "DMAX", Blockly.Arduino.ORDER_ATOMIC) || "0"; + return ["map(" + b + ", 0, 1024, 0, " + a + ")", Blockly.Arduino.ORDER_NONE] +}; +Blockly.Arduino.math = {}; +Blockly.Arduino.math_number = function(a) { + a = parseFloat(a.getFieldValue("NUM")); + Infinity == a ? a = "INFINITY" : -Infinity == a && (a = "-INFINITY"); + return [a, Blockly.Arduino.ORDER_ATOMIC] +}; +Blockly.Arduino.math_arithmetic = function(a) { + var b = { + ADD: [" + ", Blockly.Arduino.ORDER_ADDITIVE], + MINUS: [" - ", Blockly.Arduino.ORDER_ADDITIVE], + MULTIPLY: [" * ", Blockly.Arduino.ORDER_MULTIPLICATIVE], + DIVIDE: [" / ", Blockly.Arduino.ORDER_MULTIPLICATIVE], + POWER: [null, Blockly.Arduino.ORDER_NONE] + } [a.getFieldValue("OP")], + c = b[0], + b = b[1], + d = Blockly.Arduino.valueToCode(a, "A", b) || "0"; + a = Blockly.Arduino.valueToCode(a, "B", b) || "0"; + return c ? [d + c + a, b] : ["Math.pow(" + d + ", " + a + ")", Blockly.Arduino.ORDER_UNARY_POSTFIX] +}; +Blockly.Arduino.math_single = function(a) { + var b = a.getFieldValue("OP"), + c; + if ("NEG" == b) return a = Blockly.Arduino.valueToCode(a, "NUM", Blockly.Arduino.ORDER_UNARY_PREFIX) || "0", "-" == a[0] && (a = " " + a), ["-" + a, Blockly.Arduino.ORDER_UNARY_PREFIX]; + a = "ABS" == b || "ROUND" == b.substring(0, 5) ? Blockly.Arduino.valueToCode(a, "NUM", Blockly.Arduino.ORDER_UNARY_POSTFIX) || "0" : "SIN" == b || "COS" == b || "TAN" == b ? Blockly.Arduino.valueToCode(a, "NUM", Blockly.Arduino.ORDER_MULTIPLICATIVE) || "0" : Blockly.Arduino.valueToCode(a, "NUM", Blockly.Arduino.ORDER_NONE) || + "0"; + switch (b) { + case "ABS": + c = "abs(" + a + ")"; + break; + case "ROOT": + c = "sqrt(" + a + ")"; + break; + case "LN": + c = "log(" + a + ")"; + break; + case "EXP": + c = "exp(" + a + ")"; + break; + case "POW10": + c = "pow(10," + a + ")"; + break; + case "ROUND": + c = "round(" + a + ")"; + break; + case "ROUNDUP": + c = "ceil(" + a + ")"; + break; + case "ROUNDDOWN": + c = "floor(" + a + ")"; + break; + case "SIN": + c = "sin(" + a + " / 180 * Math.PI)"; + break; + case "COS": + c = "cos(" + a + " / 180 * Math.PI)"; + break; + case "TAN": + c = "tan(" + a + " / 180 * Math.PI)" + } + if (c) return [c, Blockly.Arduino.ORDER_UNARY_POSTFIX]; + switch (b) { + case "LOG10": + c = + "log(" + a + ") / log(10)"; + break; + case "ASIN": + c = "asin(" + a + ") / M_PI * 180"; + break; + case "ACOS": + c = "acos(" + a + ") / M_PI * 180"; + break; + case "ATAN": + c = "atan(" + a + ") / M_PI * 180"; + break; + default: + throw "Unknown math operator: " + b; + } + return [c, Blockly.Arduino.ORDER_MULTIPLICATIVE] +}; +Blockly.Arduino.math_constant = function(a) { + return { + PI: ["M_PI", Blockly.Arduino.ORDER_UNARY_POSTFIX], + E: ["M_E", Blockly.Arduino.ORDER_UNARY_POSTFIX], + GOLDEN_RATIO: ["(1 + sqrt(5)) / 2", Blockly.Arduino.ORDER_MULTIPLICATIVE], + SQRT2: ["M_SQRT2", Blockly.Arduino.ORDER_UNARY_POSTFIX], + SQRT1_2: ["M_SQRT1_2", Blockly.Arduino.ORDER_UNARY_POSTFIX], + INFINITY: ["INFINITY", Blockly.Arduino.ORDER_ATOMIC] + } [a.getFieldValue("CONSTANT")] +}; +Blockly.Arduino.math_number_property = function(a) { + var b = Blockly.Arduino.valueToCode(a, "NUMBER_TO_CHECK", Blockly.Arduino.ORDER_MULTIPLICATIVE) || "0", + c = a.getFieldValue("PROPERTY"), + d; + if ("PRIME" == c) return a = Blockly.Arduino.addFunction("mathIsPrime", ["boolean " + Blockly.Arduino.DEF_FUNC_NAME + "(int n) {", " // https://en.wikipedia.org/wiki/Primality_test#Naive_methods\n if (n == 2 || n == 3) {\n return true;\n }\n // False if n is NaN, negative, is 1.\n // And false if n is divisible by 2 or 3.\n if (isnan(n) || (n <= 1) || (n == 1) || (n % 2 == 0) || (n % 3 == 0)) {\n return false;\n }\n // Check all the numbers of form 6k +/- 1, up to sqrt(n).\n for (int x = 6; x <= sqrt(n) + 1; x += 6) {\n if (n % (x - 1) == 0 || n % (x + 1) == 0) {\n return false;\n }\n }\n return true;\n}"].join("\n")), + Blockly.Arduino.addInclude("math", "#include "), [a + "(" + b + ")", Blockly.Arduino.ORDER_UNARY_POSTFIX]; + switch (c) { + case "EVEN": + d = b + " % 2 == 0"; + break; + case "ODD": + d = b + " % 2 == 1"; + break; + case "WHOLE": + Blockly.Arduino.addInclude("math", "#include "); + d = "(floor(" + b + ") == " + b + ")"; + break; + case "POSITIVE": + d = b + " > 0"; + break; + case "NEGATIVE": + d = b + " < 0"; + break; + case "DIVISIBLE_BY": + a = Blockly.Arduino.valueToCode(a, "DIVISOR", Blockly.Arduino.ORDER_MULTIPLICATIVE) || "0", d = b + " % " + a + " == 0" + } + return [d, Blockly.Arduino.ORDER_EQUALITY] +}; +Blockly.Arduino.math_change = function(a) { + var b = Blockly.Arduino.valueToCode(a, "DELTA", Blockly.Arduino.ORDER_ADDITIVE) || "0"; + return Blockly.Arduino.variableDB_.getName(a.getFieldValue("VAR"), Blockly.Variables.NAME_TYPE) + " += " + b + ";\n" +}; +Blockly.Arduino.math_round = Blockly.Arduino.math_single; +Blockly.Arduino.math_trig = Blockly.Arduino.math_single; +Blockly.Arduino.math_on_list = Blockly.Arduino.noGeneratorCodeInline; +Blockly.Arduino.math_modulo = function(a) { + var b = Blockly.Arduino.valueToCode(a, "DIVIDEND", Blockly.Arduino.ORDER_MULTIPLICATIVE) || "0"; + a = Blockly.Arduino.valueToCode(a, "DIVISOR", Blockly.Arduino.ORDER_MULTIPLICATIVE) || "0"; + return [b + " % " + a, Blockly.Arduino.ORDER_MULTIPLICATIVE] +}; +Blockly.Arduino.math_constrain = function(a) { + var b = Blockly.Arduino.valueToCode(a, "VALUE", Blockly.Arduino.ORDER_NONE) || "0", + c = Blockly.Arduino.valueToCode(a, "LOW", Blockly.Arduino.ORDER_NONE) || "0"; + a = Blockly.Arduino.valueToCode(a, "HIGH", Blockly.Arduino.ORDER_NONE) || "0"; + return ["(" + b + " < " + c + " ? " + c + " : ( " + b + " > " + a + " ? " + a + " : " + b + "))", Blockly.Arduino.ORDER_UNARY_POSTFIX] +}; +Blockly.Arduino.math_random_int = function(a) { + var b = Blockly.Arduino.valueToCode(a, "FROM", Blockly.Arduino.ORDER_NONE) || "0"; + a = Blockly.Arduino.valueToCode(a, "TO", Blockly.Arduino.ORDER_NONE) || "0"; + var c = Blockly.Arduino.variableDB_.getDistinctName("math_random_int", Blockly.Generator.NAME_TYPE); + Blockly.Arduino.math_random_int.random_function = c; + return [Blockly.Arduino.addFunction("mathRandomInt", ["int " + Blockly.Arduino.DEF_FUNC_NAME + "(int min, int max) {", " if (min > max) {\n // Swap min and max to ensure min is smaller.\n int temp = min;\n min = max;\n max = temp;\n }\n return min + (rand() % (max - min + 1));\n}"].join("\n")) + + "(" + b + ", " + a + ")", Blockly.Arduino.ORDER_UNARY_POSTFIX + ] +}; +Blockly.Arduino.math_random_float = function(a) { + return ["(rand() / RAND_MAX)", Blockly.Arduino.ORDER_UNARY_POSTFIX] +}; +Blockly.Arduino.procedures = {}; +Blockly.Arduino.procedures_defreturn = function(a) { + var b = Blockly.Arduino.variableDB_.getName(a.getFieldValue("NAME"), Blockly.Procedures.NAME_TYPE), + c = Blockly.Arduino.statementToCode(a, "STACK"); + Blockly.Arduino.STATEMENT_PREFIX && (c = Blockly.Arduino.prefixLines(Blockly.Arduino.STATEMENT_PREFIX.replace(/%1/g, "'" + a.id + "'"), Blockly.Arduino.INDENT) + c); + Blockly.Arduino.INFINITE_LOOP_TRAP && (c = Blockly.Arduino.INFINITE_LOOP_TRAP.replace(/%1/g, "'" + a.id + "'") + c); + var d = Blockly.Arduino.valueToCode(a, "RETURN", Blockly.Arduino.ORDER_NONE) || + ""; + d && (d = " return " + d + ";\n"); + for (var e = [], f = 0; f < a.arguments_.length; f++) e[f] = Blockly.Arduino.getArduinoType_(a.getArgType(a.arguments_[f])) + " " + Blockly.Arduino.variableDB_.getName(a.arguments_[f], Blockly.Variables.NAME_TYPE); + f = Blockly.Types.NULL; + a.getReturnType && (f = a.getReturnType()); + f = Blockly.Arduino.getArduinoType_(f); + c = f + " " + b + "(" + e.join(", ") + ") {\n" + c + d + "}"; + c = Blockly.Arduino.scrub_(a, c); + Blockly.Arduino.userFunctions_[b] = c; + return null +}; +Blockly.Arduino.procedures_defnoreturn = Blockly.Arduino.procedures_defreturn; +Blockly.Arduino.procedures_callreturn = function(a) { + for (var b = Blockly.Arduino.variableDB_.getName(a.getFieldValue("NAME"), Blockly.Procedures.NAME_TYPE), c = [], d = 0; d < a.arguments_.length; d++) c[d] = Blockly.Arduino.valueToCode(a, "ARG" + d, Blockly.Arduino.ORDER_NONE) || "null"; + return [b + "(" + c.join(", ") + ")", Blockly.Arduino.ORDER_UNARY_POSTFIX] +}; +Blockly.Arduino.procedures_callnoreturn = function(a) { + for (var b = Blockly.Arduino.variableDB_.getName(a.getFieldValue("NAME"), Blockly.Procedures.NAME_TYPE), c = [], d = 0; d < a.arguments_.length; d++) c[d] = Blockly.Arduino.valueToCode(a, "ARG" + d, Blockly.Arduino.ORDER_NONE) || "null"; + return b + "(" + c.join(", ") + ");\n" +}; +Blockly.Arduino.procedures_ifreturn = function(a) { + var b = "if (" + (Blockly.Arduino.valueToCode(a, "CONDITION", Blockly.Arduino.ORDER_NONE) || "false") + ") {\n"; + a.hasReturnValue_ ? (a = Blockly.Arduino.valueToCode(a, "VALUE", Blockly.Arduino.ORDER_NONE) || "null", b += " return " + a + ";\n") : b += " return;\n"; + return b + "}\n" +}; +Blockly.Arduino.arduino_functions = function(a) { + var b = Blockly.Arduino.statementToCode(a, "SETUP_FUNC"); + b && Blockly.Arduino.addSetup("userSetupCode", b, !0); + a = a.getInputTargetBlock("LOOP_FUNC"); + b = Blockly.Arduino.blockToCode(a); + if (!goog.isString(b)) throw 'Expecting code from statement block "' + a.type + '".'; + return b +}; +Blockly.Arduino.serial = {}; +Blockly.Arduino.serial_print = function(a) { + for (var b = a.getFieldValue("SERIAL_ID"), c = Blockly.Arduino.valueToCode(a, "CONTENT", Blockly.Arduino.ORDER_ATOMIC) || "0", d = "TRUE" == a.getFieldValue("NEW_LINE"), e = Blockly.Arduino.Boards.selected.serialPins[b], f = 0; f < e.length; f++) Blockly.Arduino.reservePin(a, e[f][1], Blockly.Arduino.PinTypes.SERIAL, "SERIAL " + e[f][0]); + return d ? b + ".println(" + c + ");\n" : b + ".print(" + c + ");\n" +}; +Blockly.Arduino.serial_setup = function(a) { + var b = a.getFieldValue("SERIAL_ID"); + a = a.getFieldValue("SPEED"); + Blockly.Arduino.addSetup("serial_" + b, b + ".begin(" + a + ");", !0); + return "" +}; +Blockly.Arduino.servo = {}; +Blockly.Arduino.servo_write = function(a) { + var b = a.getFieldValue("SERVO_PIN"), + c = Blockly.Arduino.valueToCode(a, "SERVO_ANGLE", Blockly.Arduino.ORDER_ATOMIC) || "90", + d = "myServo" + b; + Blockly.Arduino.reservePin(a, b, Blockly.Arduino.PinTypes.SERVO, "Servo Write"); + Blockly.Arduino.addInclude("servo", "#include "); + Blockly.Arduino.addDeclaration("servo_" + b, "Servo " + d + ";"); + Blockly.Arduino.addSetup("servo_" + b, d + ".attach(" + b + ");", !0); + return d + ".write(" + c + ");\n" +}; +Blockly.Arduino.servo_read = function(a) { + var b = a.getFieldValue("SERVO_PIN"), + c = "myServo" + b; + Blockly.Arduino.reservePin(a, b, Blockly.Arduino.PinTypes.SERVO, "Servo Read"); + Blockly.Arduino.addInclude("servo", "#include "); + Blockly.Arduino.addDeclaration("servo_" + b, "Servo " + c + ";"); + Blockly.Arduino.addSetup("servo_" + b, c + ".attach(" + b + ");", !0); + return [c + ".read()", Blockly.Arduino.ORDER_ATOMIC] +}; +Blockly.Arduino.spi = {}; +Blockly.Arduino.spi_setup = function(a) { + var b = a.getFieldValue("SPI_ID"), + c = a.getFieldValue("SPI_SHIFT_ORDER"), + d = a.getFieldValue("SPI_CLOCK_DIVIDE"); + a = a.getFieldValue("SPI_MODE"); + Blockly.Arduino.addInclude("spi", "#include "); + Blockly.Arduino.addSetup("spi_order", b + ".setBitOrder(" + c + ");", !0); + Blockly.Arduino.addSetup("spi_mode", b + ".setDataMode(" + a + ");", !0); + Blockly.Arduino.addSetup("spi_div", b + ".setClockDivider(" + d + ");", !0); + Blockly.Arduino.addSetup("spi_begin", b + ".begin();", !0); + return "" +}; +Blockly.Arduino.spi_transfer = function(a) { + var b = a.getFieldValue("SPI_ID"), + c = a.getFieldValue("SPI_SS"), + d = Blockly.Arduino.valueToCode(a, "SPI_DATA", Blockly.Arduino.ORDER_ATOMIC) || "0"; + Blockly.Arduino.addInclude("spi", "#include "); + Blockly.Arduino.addSetup("spi_begin", b + ".begin();", !1); + for (var e = Blockly.Arduino.Boards.selected.spiPins[b], f = 0; f < e.length; f++) Blockly.Arduino.reservePin(a, e[f][1], Blockly.Arduino.PinTypes.SPI, "SPI " + e[f][0]); + "none" !== c && (Blockly.Arduino.reservePin(a, c, Blockly.Arduino.PinTypes.OUTPUT, + "SPI Slave pin"), Blockly.Arduino.addSetup("io_" + c, "pinMode(" + c + ", OUTPUT);", !1)); + a = []; + "none" !== c && a.push("digitalWrite(" + c + ", HIGH);"); + a.push(b + ".transfer(" + d + ");"); + "none" !== c && a.push("digitalWrite(" + c + ", LOW);"); + return a.join("\n") + "\n" +}; +Blockly.Arduino.spi_transfer_return = function(a) { + var b = a.getFieldValue("SPI_ID"), + c = a.getFieldValue("SPI_SS"), + d = Blockly.Arduino.valueToCode(a, "SPI_DATA", Blockly.Arduino.ORDER_ATOMIC) || "0"; + Blockly.Arduino.spi_transfer(a); + return ["none" === c ? b + ".transfer(" + d + ")" : Blockly.Arduino.addFunction("spiReturnSlave" + c, ["int " + Blockly.Arduino.DEF_FUNC_NAME + "() {", " int spiReturn = 0;", " digitalWrite(" + c + ", HIGH);", " spiReturn = " + b + ".transfer(" + d + ");", " digitalWrite(" + c + ", LOW);", " return spiReturn;\n}"].join("\n")) + + "()", Blockly.Arduino.ORDER_UNARY_POSTFIX + ] +}; +Blockly.Arduino.stepper = {}; +Blockly.Arduino.stepper_config = function(a) { + var b = Blockly.Arduino.PinTypes.STEPPER, + c = a.getFieldValue("STEPPER_NAME"), + d = a.getFieldValue("STEPPER_NUMBER_OF_PINS"), + e = Blockly.Arduino.valueToCode(a, "STEPPER_STEPS", Blockly.Arduino.ORDER_ATOMIC) || "360", + f = Blockly.Arduino.valueToCode(a, "STEPPER_SPEED", Blockly.Arduino.ORDER_ATOMIC) || "90", + g = [a.getFieldValue("STEPPER_PIN1"), a.getFieldValue("STEPPER_PIN2")]; + "FOUR" === d && (g.push(a.getFieldValue("STEPPER_PIN3")), g.push(a.getFieldValue("STEPPER_PIN4"))); + for (var d = + "int " + c + "[" + g.length + "] = {", e = "Stepper stepper_" + c + "(" + e + ", ", h = 0; h < g.length; h++) Blockly.Arduino.reservePin(a, g[h], b, "Stepper"), d += g[h] + ", ", e += g[h] + ", "; + d = d.slice(0, -2) + "};"; + e = e.slice(0, -2) + ");"; + Blockly.Arduino.addVariable(c, d, !0); + c = "stepper_" + c; + Blockly.Arduino.addInclude("stepper", "#include "); + Blockly.Arduino.addDeclaration(c, e); + Blockly.Arduino.addSetup(c, c + ".setSpeed(" + f + ");", !0); + return "" +}; +Blockly.Arduino.stepper_step = function(a) { + var b = "stepper_" + a.getFieldValue("STEPPER_NAME"); + a = Blockly.Arduino.valueToCode(a, "STEPPER_STEPS", Blockly.Arduino.ORDER_ATOMIC) || "0"; + return b + ".step(" + a + ");\n" +}; +Blockly.Arduino.text = {}; +Blockly.Arduino.text = function(a) { + return [Blockly.Arduino.quote_(a.getFieldValue("TEXT")), Blockly.Arduino.ORDER_ATOMIC] +}; +Blockly.Arduino.text_join = function(a) { + var b; + if (0 == a.itemCount_) return ['""', Blockly.Arduino.ORDER_ATOMIC]; + if (1 == a.itemCount_) return ["String(" + (Blockly.Arduino.valueToCode(a, "ADD0", Blockly.Arduino.ORDER_UNARY_POSTFIX) || '""') + ")", Blockly.Arduino.ORDER_UNARY_POSTFIX]; + var c; + b = []; + for (var d = 0; d < a.itemCount_; d++) c = Blockly.Arduino.valueToCode(a, "ADD" + d, Blockly.Arduino.ORDER_NONE), b[d] = "" == c ? '""' : "String(" + c + ")"; + b = b.join(" + "); + return [b, Blockly.Arduino.ORDER_UNARY_POSTFIX] +}; +Blockly.Arduino.text_append = function(a) { + var b = Blockly.Arduino.variableDB_.getName(a.getFieldValue("VAR"), Blockly.Variables.NAME_TYPE); + a = Blockly.Arduino.valueToCode(a, "TEXT", Blockly.Arduino.ORDER_UNARY_POSTFIX); + return b + " += " + ("" == a ? '""' : "String(" + a + ")") + ";\n" +}; +Blockly.Arduino.text_length = function(a) { + return ["String(" + (Blockly.Arduino.valueToCode(a, "VALUE", Blockly.Arduino.ORDER_UNARY_POSTFIX) || '""') + ").length()", Blockly.Arduino.ORDER_UNARY_POSTFIX] +}; +Blockly.Arduino.text_isEmpty = function(a) { + var b = []; + b.push("boolean " + Blockly.Arduino.DEF_FUNC_NAME + "(String msg) {"); + b.push(" if (msg.length() == 0) {"); + b.push(" return true;"); + b.push(" } else {"); + b.push(" return false;"); + b.push(" }"); + b.push("}"); + b = Blockly.Arduino.addFunction("isStringEmpty", b.join("\n")); + a = Blockly.Arduino.valueToCode(a, "VALUE", Blockly.Arduino.ORDER_UNARY_POSTFIX); + return [b + "(" + ("" == a ? '""' : "String(" + a + ")") + ")", Blockly.Arduino.ORDER_UNARY_POSTFIX] +}; +Blockly.Arduino.text_trim = function(a) { + Blockly.Arduino.text_trim.OPERATORS = { + LEFT: ".trim()", + RIGHT: ".trim()", + BOTH: ".trim()" + }; + var b = a.getFieldValue("MODE"), + b = Blockly.Arduino.text_trim.OPERATORS[b]; + a = Blockly.Arduino.valueToCode(a, "TEXT", Blockly.Arduino.ORDER_UNARY_POSTFIX); + return [("" == a ? '""' : "String(" + a + ")") + b, Blockly.Arduino.ORDER_UNARY_POSTFIX] +}; +Blockly.Arduino.text_print = function(a) { + var b = Blockly.Arduino.Boards.selected.serial[0][1]; + Blockly.Arduino.addSetup("serial_" + b, b + ".begin(9600);", !1); + a = Blockly.Arduino.valueToCode(a, "TEXT", Blockly.Arduino.ORDER_NONE); + return b + ".print(" + ("" == a ? '""' : "String(" + a + ")") + ");\n" +}; +Blockly.Arduino.text_prompt_ext = function(a) { + var b = Blockly.Arduino.Boards.selected.serial[0][1], + c = a.getFieldValue("TYPE"), + d = [], + e = c == Blockly.Types.NUMBER.output; + e ? d.push("int " + Blockly.Arduino.DEF_FUNC_NAME + "(String msg) {") : d.push("String " + Blockly.Arduino.DEF_FUNC_NAME + "(String msg) {"); + d.push(" " + b + ".println(msg);"); + d.push(" boolean stringComplete = false;"); + e ? d.push(" int content = 0;") : d.push(' String content = "";'); + d.push(" while (stringComplete == false) {"); + d.push(" if (" + b + ".available()) {"); + e ? (d.push(" content = " + b + ".parseInt();"), d.push(" stringComplete = true;")) : (d.push(" char readChar = (char)" + b + ".read();"), d.push(" if (readChar == '\\n' || readChar == '\\r') {"), d.push(" stringComplete = true;"), d.push(" } else {"), d.push(" content += readChar;"), d.push(" }")); + d.push(" }"); + d.push(" }"); + d.push(" // Empty incoming serial buffer"); + d.push(" while(Serial.available()) { Serial.read(); };"); + d.push(" return content;"); + d.push("}"); + c = Blockly.Arduino.addFunction("getUserInputPrompt" + + c, d.join("\n")); + Blockly.Arduino.addSetup("serial_" + b, b + ".begin(9600);", !1); + a = Blockly.Arduino.valueToCode(a, "TEXT", Blockly.Arduino.ORDER_NONE) || '""'; + return [c + "(" + a + ")", Blockly.Arduino.ORDER_UNARY_POSTFIX] +}; +Blockly.Arduino.text_endString = function(a) { + return ["", Blockly.Arduino.ORDER_UNARY_POSTFIX] +}; +Blockly.Arduino.text_indexOf = function(a) { + return ["", Blockly.Arduino.ORDER_UNARY_POSTFIX] +}; +Blockly.Arduino.text_charAt = function(a) { + return ["", Blockly.Arduino.ORDER_UNARY_POSTFIX] +}; +Blockly.Arduino.text_getSubstring = function(a) { + return ["", Blockly.Arduino.ORDER_UNARY_POSTFIX] +}; +Blockly.Arduino.text_changeCase = function(a) { + return ["", Blockly.Arduino.ORDER_UNARY_POSTFIX] +}; +Blockly.Arduino.text_prompt = function(a) { + return ["", Blockly.Arduino.ORDER_UNARY_POSTFIX] +}; +Blockly.Arduino.time = {}; +Blockly.Arduino.time_delay = function(a) { + return "delay(" + (Blockly.Arduino.valueToCode(a, "DELAY_TIME_MILI", Blockly.Arduino.ORDER_ATOMIC) || "0") + ");\n" +}; +Blockly.Arduino.time_delaymicros = function(a) { + return "delayMicroseconds(" + (Blockly.Arduino.valueToCode(a, "DELAY_TIME_MICRO", Blockly.Arduino.ORDER_ATOMIC) || "0") + ");\n" +}; +Blockly.Arduino.time_millis = function(a) { + return ["millis()", Blockly.Arduino.ORDER_ATOMIC] +}; +Blockly.Arduino.time_micros = function(a) { + return ["micros()", Blockly.Arduino.ORDER_ATOMIC] +}; +Blockly.Arduino.infinite_loop = function(a) { + return "while(true);\n" +}; +Blockly.Arduino.tone = {}; +Blockly.Arduino.io_tone = function(a) { + var b = a.getFieldValue("TONEPIN"), + c = Blockly.Arduino.valueToCode(a, "FREQUENCY", Blockly.Arduino.ORDER_ATOMIC); + Blockly.Arduino.reservePin(a, b, Blockly.Arduino.PinTypes.OUTPUT, "Tone Pin"); + Blockly.Arduino.addSetup("io_" + b, "pinMode(" + b + ", OUTPUT);\n", !1); + return "tone(" + b + "," + c + ");\n" +}; +Blockly.Arduino.io_notone = function(a) { + var b = a.getFieldValue("TONEPIN"); + Blockly.Arduino.reservePin(a, b, Blockly.Arduino.PinTypes.OUTPUT, "Tone Pin"); + Blockly.Arduino.addSetup("io_" + b, "pinMode(" + b + ", OUTPUT);\n", !1); + return "noTone(" + b + ");\n" +}; +Blockly.Arduino.variables = {}; +Blockly.Arduino.variables_get = function(a) { + return [Blockly.Arduino.variableDB_.getName(a.getFieldValue("VAR"), Blockly.Variables.NAME_TYPE), Blockly.Arduino.ORDER_ATOMIC] +}; +Blockly.Arduino.variables_set = function(a) { + var b = Blockly.Arduino.valueToCode(a, "VALUE", Blockly.Arduino.ORDER_ASSIGNMENT) || "0"; + return Blockly.Arduino.variableDB_.getName(a.getFieldValue("VAR"), Blockly.Variables.NAME_TYPE) + " = " + b + ";\n" +}; +Blockly.Arduino.variables_set_type = function(a) { + var b = Blockly.Arduino.valueToCode(a, "VARIABLE_SETTYPE_INPUT", Blockly.Arduino.ORDER_ASSIGNMENT) || "0"; + return ["(" + Blockly.Arduino.getArduinoType_(Blockly.Types[a.getFieldValue("VARIABLE_SETTYPE_TYPE")]) + ")(" + b + ")", Blockly.Arduino.ORDER_ATOMIC] +}; + +//inline comment +Blockly.Arduino.insert_comment = function(a) { + var b; + var x; + if (0 == a.itemCount_) return "// \n"; + if (1 == a.itemCount_) { + x = (Blockly.Arduino.valueToCode(a, "ADD0", Blockly.Arduino.ORDER_UNARY_POSTFIX) || ''); + x = x.slice(0,-1); + x = x.substring(1); + return "// " + x + "\n"; + } + var c; + b = []; + for (var d = 0; d < a.itemCount_; d++){ + c = Blockly.Arduino.valueToCode(a, "ADD" + d, Blockly.Arduino.ORDER_NONE); + c = c.slice(0,-1); + c = c.substring(1); + b[d] = "" == c ? '' : "// " + c + "\n"; + } + b = b.join(""); + return b; +}; + +//block comment +Blockly.Arduino.block_comment = function(a) { + var b = Blockly.Arduino.statementToCode(a, 'comment'); + return "/* " + a.getFieldValue("comment_input") + "\n" + b + "*/\n"; +}; \ No newline at end of file diff --git a/client/public/lib/avrgirl-arduino.global.js b/client/public/lib/avrgirl-arduino.global.js index 281e913d..a6776a0a 100644 --- a/client/public/lib/avrgirl-arduino.global.js +++ b/client/public/lib/avrgirl-arduino.global.js @@ -1,160 +1,108 @@ window["AvrgirlArduino"] = - /******/ (function (modules) { // webpackBootstrap + /******/ (function(modules) { // webpackBootstrap /******/ // The module cache - /******/ - var installedModules = {}; + /******/ var installedModules = {}; /******/ /******/ // The require function - /******/ - function __webpack_require__(moduleId) { + /******/ function __webpack_require__(moduleId) { /******/ /******/ // Check if module is in cache - /******/ - if (installedModules[moduleId]) { - /******/ - return installedModules[moduleId].exports; - /******/ - } + /******/ if(installedModules[moduleId]) { + /******/ return installedModules[moduleId].exports; + /******/ } /******/ // Create a new module (and put it into the cache) - /******/ - var module = installedModules[moduleId] = { - /******/ i: moduleId, - /******/ l: false, - /******/ exports: {} - /******/ - }; + /******/ var module = installedModules[moduleId] = { + /******/ i: moduleId, + /******/ l: false, + /******/ exports: {} + /******/ }; /******/ /******/ // Execute the module function - /******/ - modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); + /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ /******/ // Flag the module as loaded - /******/ - module.l = true; + /******/ module.l = true; /******/ /******/ // Return the exports of the module - /******/ - return module.exports; - /******/ - } - + /******/ return module.exports; + /******/ } /******/ /******/ /******/ // expose the modules object (__webpack_modules__) - /******/ - __webpack_require__.m = modules; + /******/ __webpack_require__.m = modules; /******/ /******/ // expose the module cache - /******/ - __webpack_require__.c = installedModules; + /******/ __webpack_require__.c = installedModules; /******/ /******/ // define getter function for harmony exports - /******/ - __webpack_require__.d = function (exports, name, getter) { - /******/ - if (!__webpack_require__.o(exports, name)) { - /******/ - Object.defineProperty(exports, name, {enumerable: true, get: getter}); - /******/ - } - /******/ - }; + /******/ __webpack_require__.d = function(exports, name, getter) { + /******/ if(!__webpack_require__.o(exports, name)) { + /******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); + /******/ } + /******/ }; /******/ /******/ // define __esModule on exports - /******/ - __webpack_require__.r = function (exports) { - /******/ - if (typeof Symbol !== 'undefined' && Symbol.toStringTag) { - /******/ - Object.defineProperty(exports, Symbol.toStringTag, {value: 'Module'}); - /******/ - } - /******/ - Object.defineProperty(exports, '__esModule', {value: true}); - /******/ - }; + /******/ __webpack_require__.r = function(exports) { + /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { + /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); + /******/ } + /******/ Object.defineProperty(exports, '__esModule', { value: true }); + /******/ }; /******/ /******/ // create a fake namespace object /******/ // mode & 1: value is a module id, require it /******/ // mode & 2: merge all properties of value into the ns /******/ // mode & 4: return value when already ns object /******/ // mode & 8|1: behave like require - /******/ - __webpack_require__.t = function (value, mode) { - /******/ - if (mode & 1) value = __webpack_require__(value); - /******/ - if (mode & 8) return value; - /******/ - if ((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; - /******/ - var ns = Object.create(null); - /******/ - __webpack_require__.r(ns); - /******/ - Object.defineProperty(ns, 'default', {enumerable: true, value: value}); - /******/ - if (mode & 2 && typeof value != 'string') for (var key in value) __webpack_require__.d(ns, key, function (key) { - return value[key]; - }.bind(null, key)); - /******/ - return ns; - /******/ - }; + /******/ __webpack_require__.t = function(value, mode) { + /******/ if(mode & 1) value = __webpack_require__(value); + /******/ if(mode & 8) return value; + /******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; + /******/ var ns = Object.create(null); + /******/ __webpack_require__.r(ns); + /******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); + /******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); + /******/ return ns; + /******/ }; /******/ /******/ // getDefaultExport function for compatibility with non-harmony modules - /******/ - __webpack_require__.n = function (module) { - /******/ - var getter = module && module.__esModule ? - /******/ function getDefault() { - return module['default']; - } : - /******/ function getModuleExports() { - return module; - }; - /******/ - __webpack_require__.d(getter, 'a', getter); - /******/ - return getter; - /******/ - }; + /******/ __webpack_require__.n = function(module) { + /******/ var getter = module && module.__esModule ? + /******/ function getDefault() { return module['default']; } : + /******/ function getModuleExports() { return module; }; + /******/ __webpack_require__.d(getter, 'a', getter); + /******/ return getter; + /******/ }; /******/ /******/ // Object.prototype.hasOwnProperty.call - /******/ - __webpack_require__.o = function (object, property) { - return Object.prototype.hasOwnProperty.call(object, property); - }; + /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; /******/ /******/ // __webpack_public_path__ - /******/ - __webpack_require__.p = ""; + /******/ __webpack_require__.p = ""; /******/ /******/ /******/ // Load entry module and return exports - /******/ - return __webpack_require__(__webpack_require__.s = 30); - /******/ -}) + /******/ return __webpack_require__(__webpack_require__.s = 28); + /******/ }) /************************************************************************/ /******/ ([ /* 0 */ - /***/ (function (module, exports, __webpack_require__) { + /***/ (function(module, exports, __webpack_require__) { "use strict"; - /* WEBPACK VAR INJECTION */ - (function (global) {/*! + /* WEBPACK VAR INJECTION */(function(global) {/*! * The buffer module from node.js, for the browser. * - * @author Feross Aboukhadijeh + * @author Feross Aboukhadijeh * @license MIT */ /* eslint-disable no-proto */ - var base64 = __webpack_require__(32) - var ieee754 = __webpack_require__(33) - var isArray = __webpack_require__(20) + + var base64 = __webpack_require__(30) + var ieee754 = __webpack_require__(31) + var isArray = __webpack_require__(18) exports.Buffer = Buffer exports.SlowBuffer = SlowBuffer @@ -193,14 +141,10 @@ window["AvrgirlArduino"] = */ exports.kMaxLength = kMaxLength() - function typedArraySupport() { + function typedArraySupport () { try { var arr = new Uint8Array(1) - arr.__proto__ = { - __proto__: Uint8Array.prototype, foo: function () { - return 42 - } - } + arr.__proto__ = {__proto__: Uint8Array.prototype, foo: function () { return 42 }} return arr.foo() === 42 && // typed array instances can be augmented typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray` arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray` @@ -209,13 +153,13 @@ window["AvrgirlArduino"] = } } - function kMaxLength() { + function kMaxLength () { return Buffer.TYPED_ARRAY_SUPPORT ? 0x7fffffff : 0x3fffffff } - function createBuffer(that, length) { + function createBuffer (that, length) { if (kMaxLength() < length) { throw new RangeError('Invalid typed array length') } @@ -244,7 +188,7 @@ window["AvrgirlArduino"] = * The `Uint8Array` prototype remains unmodified. */ - function Buffer(arg, encodingOrOffset, length) { + function Buffer (arg, encodingOrOffset, length) { if (!Buffer.TYPED_ARRAY_SUPPORT && !(this instanceof Buffer)) { return new Buffer(arg, encodingOrOffset, length) } @@ -269,7 +213,7 @@ window["AvrgirlArduino"] = return arr } - function from(that, value, encodingOrOffset, length) { + function from (that, value, encodingOrOffset, length) { if (typeof value === 'number') { throw new TypeError('"value" argument must not be a number') } @@ -310,7 +254,7 @@ window["AvrgirlArduino"] = } } - function assertSize(size) { + function assertSize (size) { if (typeof size !== 'number') { throw new TypeError('"size" argument must be a number') } else if (size < 0) { @@ -318,7 +262,7 @@ window["AvrgirlArduino"] = } } - function alloc(that, size, fill, encoding) { + function alloc (that, size, fill, encoding) { assertSize(size) if (size <= 0) { return createBuffer(that, size) @@ -342,7 +286,7 @@ window["AvrgirlArduino"] = return alloc(null, size, fill, encoding) } - function allocUnsafe(that, size) { + function allocUnsafe (that, size) { assertSize(size) that = createBuffer(that, size < 0 ? 0 : checked(size) | 0) if (!Buffer.TYPED_ARRAY_SUPPORT) { @@ -366,7 +310,7 @@ window["AvrgirlArduino"] = return allocUnsafe(null, size) } - function fromString(that, string, encoding) { + function fromString (that, string, encoding) { if (typeof encoding !== 'string' || encoding === '') { encoding = 'utf8' } @@ -390,7 +334,7 @@ window["AvrgirlArduino"] = return that } - function fromArrayLike(that, array) { + function fromArrayLike (that, array) { var length = array.length < 0 ? 0 : checked(array.length) | 0 that = createBuffer(that, length) for (var i = 0; i < length; i += 1) { @@ -399,7 +343,7 @@ window["AvrgirlArduino"] = return that } - function fromArrayBuffer(that, array, byteOffset, length) { + function fromArrayBuffer (that, array, byteOffset, length) { array.byteLength // this throws if `array` is not a valid ArrayBuffer if (byteOffset < 0 || array.byteLength < byteOffset) { @@ -429,7 +373,7 @@ window["AvrgirlArduino"] = return that } - function fromObject(that, obj) { + function fromObject (that, obj) { if (Buffer.isBuffer(obj)) { var len = checked(obj.length) | 0 that = createBuffer(that, len) @@ -459,7 +403,7 @@ window["AvrgirlArduino"] = throw new TypeError('First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.') } - function checked(length) { + function checked (length) { // Note: cannot use `length < kMaxLength()` here because that fails when // length is NaN (which is otherwise coerced to zero.) if (length >= kMaxLength()) { @@ -469,18 +413,18 @@ window["AvrgirlArduino"] = return length | 0 } - function SlowBuffer(length) { + function SlowBuffer (length) { if (+length != length) { // eslint-disable-line eqeqeq length = 0 } return Buffer.alloc(+length) } - Buffer.isBuffer = function isBuffer(b) { + Buffer.isBuffer = function isBuffer (b) { return !!(b != null && b._isBuffer) } - Buffer.compare = function compare(a, b) { + Buffer.compare = function compare (a, b) { if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) { throw new TypeError('Arguments must be Buffers') } @@ -503,7 +447,7 @@ window["AvrgirlArduino"] = return 0 } - Buffer.isEncoding = function isEncoding(encoding) { + Buffer.isEncoding = function isEncoding (encoding) { switch (String(encoding).toLowerCase()) { case 'hex': case 'utf8': @@ -522,7 +466,7 @@ window["AvrgirlArduino"] = } } - Buffer.concat = function concat(list, length) { + Buffer.concat = function concat (list, length) { if (!isArray(list)) { throw new TypeError('"list" argument must be an Array of Buffers') } @@ -552,7 +496,7 @@ window["AvrgirlArduino"] = return buffer } - function byteLength(string, encoding) { + function byteLength (string, encoding) { if (Buffer.isBuffer(string)) { return string.length } @@ -569,7 +513,7 @@ window["AvrgirlArduino"] = // Use a for loop to avoid recursion var loweredCase = false - for (; ;) { + for (;;) { switch (encoding) { case 'ascii': case 'latin1': @@ -595,10 +539,9 @@ window["AvrgirlArduino"] = } } } - Buffer.byteLength = byteLength - function slowToString(encoding, start, end) { + function slowToString (encoding, start, end) { var loweredCase = false // No need to verify that "this.length <= MAX_UINT32" since it's a read-only @@ -672,13 +615,13 @@ window["AvrgirlArduino"] = // Buffer instances. Buffer.prototype._isBuffer = true - function swap(b, n, m) { + function swap (b, n, m) { var i = b[n] b[n] = b[m] b[m] = i } - Buffer.prototype.swap16 = function swap16() { + Buffer.prototype.swap16 = function swap16 () { var len = this.length if (len % 2 !== 0) { throw new RangeError('Buffer size must be a multiple of 16-bits') @@ -689,7 +632,7 @@ window["AvrgirlArduino"] = return this } - Buffer.prototype.swap32 = function swap32() { + Buffer.prototype.swap32 = function swap32 () { var len = this.length if (len % 4 !== 0) { throw new RangeError('Buffer size must be a multiple of 32-bits') @@ -701,7 +644,7 @@ window["AvrgirlArduino"] = return this } - Buffer.prototype.swap64 = function swap64() { + Buffer.prototype.swap64 = function swap64 () { var len = this.length if (len % 8 !== 0) { throw new RangeError('Buffer size must be a multiple of 64-bits') @@ -715,20 +658,20 @@ window["AvrgirlArduino"] = return this } - Buffer.prototype.toString = function toString() { + Buffer.prototype.toString = function toString () { var length = this.length | 0 if (length === 0) return '' if (arguments.length === 0) return utf8Slice(this, 0, length) return slowToString.apply(this, arguments) } - Buffer.prototype.equals = function equals(b) { + Buffer.prototype.equals = function equals (b) { if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer') if (this === b) return true return Buffer.compare(this, b) === 0 } - Buffer.prototype.inspect = function inspect() { + Buffer.prototype.inspect = function inspect () { var str = '' var max = exports.INSPECT_MAX_BYTES if (this.length > 0) { @@ -738,7 +681,7 @@ window["AvrgirlArduino"] = return '' } - Buffer.prototype.compare = function compare(target, start, end, thisStart, thisEnd) { + Buffer.prototype.compare = function compare (target, start, end, thisStart, thisEnd) { if (!Buffer.isBuffer(target)) { throw new TypeError('Argument must be a Buffer') } @@ -806,7 +749,7 @@ window["AvrgirlArduino"] = // - byteOffset - an index into `buffer`; will be clamped to an int32 // - encoding - an optional encoding, relevant is val is a string // - dir - true for indexOf, false for lastIndexOf - function bidirectionalIndexOf(buffer, val, byteOffset, encoding, dir) { + function bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) { // Empty buffer means no match if (buffer.length === 0) return -1 @@ -857,13 +800,13 @@ window["AvrgirlArduino"] = return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset) } } - return arrayIndexOf(buffer, [val], byteOffset, encoding, dir) + return arrayIndexOf(buffer, [ val ], byteOffset, encoding, dir) } throw new TypeError('val must be string, number or Buffer') } - function arrayIndexOf(arr, val, byteOffset, encoding, dir) { + function arrayIndexOf (arr, val, byteOffset, encoding, dir) { var indexSize = 1 var arrLength = arr.length var valLength = val.length @@ -882,7 +825,7 @@ window["AvrgirlArduino"] = } } - function read(buf, i) { + function read (buf, i) { if (indexSize === 1) { return buf[i] } else { @@ -919,19 +862,19 @@ window["AvrgirlArduino"] = return -1 } - Buffer.prototype.includes = function includes(val, byteOffset, encoding) { + Buffer.prototype.includes = function includes (val, byteOffset, encoding) { return this.indexOf(val, byteOffset, encoding) !== -1 } - Buffer.prototype.indexOf = function indexOf(val, byteOffset, encoding) { + Buffer.prototype.indexOf = function indexOf (val, byteOffset, encoding) { return bidirectionalIndexOf(this, val, byteOffset, encoding, true) } - Buffer.prototype.lastIndexOf = function lastIndexOf(val, byteOffset, encoding) { + Buffer.prototype.lastIndexOf = function lastIndexOf (val, byteOffset, encoding) { return bidirectionalIndexOf(this, val, byteOffset, encoding, false) } - function hexWrite(buf, string, offset, length) { + function hexWrite (buf, string, offset, length) { offset = Number(offset) || 0 var remaining = buf.length - offset if (!length) { @@ -958,27 +901,27 @@ window["AvrgirlArduino"] = return i } - function utf8Write(buf, string, offset, length) { + function utf8Write (buf, string, offset, length) { return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length) } - function asciiWrite(buf, string, offset, length) { + function asciiWrite (buf, string, offset, length) { return blitBuffer(asciiToBytes(string), buf, offset, length) } - function latin1Write(buf, string, offset, length) { + function latin1Write (buf, string, offset, length) { return asciiWrite(buf, string, offset, length) } - function base64Write(buf, string, offset, length) { + function base64Write (buf, string, offset, length) { return blitBuffer(base64ToBytes(string), buf, offset, length) } - function ucs2Write(buf, string, offset, length) { + function ucs2Write (buf, string, offset, length) { return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length) } - Buffer.prototype.write = function write(string, offset, length, encoding) { + Buffer.prototype.write = function write (string, offset, length, encoding) { // Buffer#write(string) if (offset === undefined) { encoding = 'utf8' @@ -1016,7 +959,7 @@ window["AvrgirlArduino"] = if (!encoding) encoding = 'utf8' var loweredCase = false - for (; ;) { + for (;;) { switch (encoding) { case 'hex': return hexWrite(this, string, offset, length) @@ -1050,14 +993,14 @@ window["AvrgirlArduino"] = } } - Buffer.prototype.toJSON = function toJSON() { + Buffer.prototype.toJSON = function toJSON () { return { type: 'Buffer', data: Array.prototype.slice.call(this._arr || this, 0) } } - function base64Slice(buf, start, end) { + function base64Slice (buf, start, end) { if (start === 0 && end === buf.length) { return base64.fromByteArray(buf) } else { @@ -1065,7 +1008,7 @@ window["AvrgirlArduino"] = } } - function utf8Slice(buf, start, end) { + function utf8Slice (buf, start, end) { end = Math.min(buf.length, end) var res = [] @@ -1143,7 +1086,7 @@ window["AvrgirlArduino"] = // We go 1 magnitude less, for safety var MAX_ARGUMENTS_LENGTH = 0x1000 - function decodeCodePointsArray(codePoints) { + function decodeCodePointsArray (codePoints) { var len = codePoints.length if (len <= MAX_ARGUMENTS_LENGTH) { return String.fromCharCode.apply(String, codePoints) // avoid extra slice() @@ -1161,7 +1104,7 @@ window["AvrgirlArduino"] = return res } - function asciiSlice(buf, start, end) { + function asciiSlice (buf, start, end) { var ret = '' end = Math.min(buf.length, end) @@ -1171,7 +1114,7 @@ window["AvrgirlArduino"] = return ret } - function latin1Slice(buf, start, end) { + function latin1Slice (buf, start, end) { var ret = '' end = Math.min(buf.length, end) @@ -1181,7 +1124,7 @@ window["AvrgirlArduino"] = return ret } - function hexSlice(buf, start, end) { + function hexSlice (buf, start, end) { var len = buf.length if (!start || start < 0) start = 0 @@ -1194,7 +1137,7 @@ window["AvrgirlArduino"] = return out } - function utf16leSlice(buf, start, end) { + function utf16leSlice (buf, start, end) { var bytes = buf.slice(start, end) var res = '' for (var i = 0; i < bytes.length; i += 2) { @@ -1203,7 +1146,7 @@ window["AvrgirlArduino"] = return res } - Buffer.prototype.slice = function slice(start, end) { + Buffer.prototype.slice = function slice (start, end) { var len = this.length start = ~~start end = end === undefined ? len : ~~end @@ -1242,12 +1185,12 @@ window["AvrgirlArduino"] = /* * Need to make sure that buffer isn't trying to write out of bounds. */ - function checkOffset(offset, ext, length) { + function checkOffset (offset, ext, length) { if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint') if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length') } - Buffer.prototype.readUIntLE = function readUIntLE(offset, byteLength, noAssert) { + Buffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) { offset = offset | 0 byteLength = byteLength | 0 if (!noAssert) checkOffset(offset, byteLength, this.length) @@ -1262,7 +1205,7 @@ window["AvrgirlArduino"] = return val } - Buffer.prototype.readUIntBE = function readUIntBE(offset, byteLength, noAssert) { + Buffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) { offset = offset | 0 byteLength = byteLength | 0 if (!noAssert) { @@ -1278,22 +1221,22 @@ window["AvrgirlArduino"] = return val } - Buffer.prototype.readUInt8 = function readUInt8(offset, noAssert) { + Buffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) { if (!noAssert) checkOffset(offset, 1, this.length) return this[offset] } - Buffer.prototype.readUInt16LE = function readUInt16LE(offset, noAssert) { + Buffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) { if (!noAssert) checkOffset(offset, 2, this.length) return this[offset] | (this[offset + 1] << 8) } - Buffer.prototype.readUInt16BE = function readUInt16BE(offset, noAssert) { + Buffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) { if (!noAssert) checkOffset(offset, 2, this.length) return (this[offset] << 8) | this[offset + 1] } - Buffer.prototype.readUInt32LE = function readUInt32LE(offset, noAssert) { + Buffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) { if (!noAssert) checkOffset(offset, 4, this.length) return ((this[offset]) | @@ -1302,7 +1245,7 @@ window["AvrgirlArduino"] = (this[offset + 3] * 0x1000000) } - Buffer.prototype.readUInt32BE = function readUInt32BE(offset, noAssert) { + Buffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) { if (!noAssert) checkOffset(offset, 4, this.length) return (this[offset] * 0x1000000) + @@ -1311,7 +1254,7 @@ window["AvrgirlArduino"] = this[offset + 3]) } - Buffer.prototype.readIntLE = function readIntLE(offset, byteLength, noAssert) { + Buffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) { offset = offset | 0 byteLength = byteLength | 0 if (!noAssert) checkOffset(offset, byteLength, this.length) @@ -1329,7 +1272,7 @@ window["AvrgirlArduino"] = return val } - Buffer.prototype.readIntBE = function readIntBE(offset, byteLength, noAssert) { + Buffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) { offset = offset | 0 byteLength = byteLength | 0 if (!noAssert) checkOffset(offset, byteLength, this.length) @@ -1347,25 +1290,25 @@ window["AvrgirlArduino"] = return val } - Buffer.prototype.readInt8 = function readInt8(offset, noAssert) { + Buffer.prototype.readInt8 = function readInt8 (offset, noAssert) { if (!noAssert) checkOffset(offset, 1, this.length) if (!(this[offset] & 0x80)) return (this[offset]) return ((0xff - this[offset] + 1) * -1) } - Buffer.prototype.readInt16LE = function readInt16LE(offset, noAssert) { + Buffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) { if (!noAssert) checkOffset(offset, 2, this.length) var val = this[offset] | (this[offset + 1] << 8) return (val & 0x8000) ? val | 0xFFFF0000 : val } - Buffer.prototype.readInt16BE = function readInt16BE(offset, noAssert) { + Buffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) { if (!noAssert) checkOffset(offset, 2, this.length) var val = this[offset + 1] | (this[offset] << 8) return (val & 0x8000) ? val | 0xFFFF0000 : val } - Buffer.prototype.readInt32LE = function readInt32LE(offset, noAssert) { + Buffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) { if (!noAssert) checkOffset(offset, 4, this.length) return (this[offset]) | @@ -1374,7 +1317,7 @@ window["AvrgirlArduino"] = (this[offset + 3] << 24) } - Buffer.prototype.readInt32BE = function readInt32BE(offset, noAssert) { + Buffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) { if (!noAssert) checkOffset(offset, 4, this.length) return (this[offset] << 24) | @@ -1383,33 +1326,33 @@ window["AvrgirlArduino"] = (this[offset + 3]) } - Buffer.prototype.readFloatLE = function readFloatLE(offset, noAssert) { + Buffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) { if (!noAssert) checkOffset(offset, 4, this.length) return ieee754.read(this, offset, true, 23, 4) } - Buffer.prototype.readFloatBE = function readFloatBE(offset, noAssert) { + Buffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) { if (!noAssert) checkOffset(offset, 4, this.length) return ieee754.read(this, offset, false, 23, 4) } - Buffer.prototype.readDoubleLE = function readDoubleLE(offset, noAssert) { + Buffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) { if (!noAssert) checkOffset(offset, 8, this.length) return ieee754.read(this, offset, true, 52, 8) } - Buffer.prototype.readDoubleBE = function readDoubleBE(offset, noAssert) { + Buffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) { if (!noAssert) checkOffset(offset, 8, this.length) return ieee754.read(this, offset, false, 52, 8) } - function checkInt(buf, value, offset, ext, max, min) { + function checkInt (buf, value, offset, ext, max, min) { if (!Buffer.isBuffer(buf)) throw new TypeError('"buffer" argument must be a Buffer instance') if (value > max || value < min) throw new RangeError('"value" argument is out of bounds') if (offset + ext > buf.length) throw new RangeError('Index out of range') } - Buffer.prototype.writeUIntLE = function writeUIntLE(value, offset, byteLength, noAssert) { + Buffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) { value = +value offset = offset | 0 byteLength = byteLength | 0 @@ -1428,7 +1371,7 @@ window["AvrgirlArduino"] = return offset + byteLength } - Buffer.prototype.writeUIntBE = function writeUIntBE(value, offset, byteLength, noAssert) { + Buffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) { value = +value offset = offset | 0 byteLength = byteLength | 0 @@ -1447,7 +1390,7 @@ window["AvrgirlArduino"] = return offset + byteLength } - Buffer.prototype.writeUInt8 = function writeUInt8(value, offset, noAssert) { + Buffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) { value = +value offset = offset | 0 if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0) @@ -1456,7 +1399,7 @@ window["AvrgirlArduino"] = return offset + 1 } - function objectWriteUInt16(buf, value, offset, littleEndian) { + function objectWriteUInt16 (buf, value, offset, littleEndian) { if (value < 0) value = 0xffff + value + 1 for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; ++i) { buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>> @@ -1464,7 +1407,7 @@ window["AvrgirlArduino"] = } } - Buffer.prototype.writeUInt16LE = function writeUInt16LE(value, offset, noAssert) { + Buffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) { value = +value offset = offset | 0 if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0) @@ -1477,7 +1420,7 @@ window["AvrgirlArduino"] = return offset + 2 } - Buffer.prototype.writeUInt16BE = function writeUInt16BE(value, offset, noAssert) { + Buffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) { value = +value offset = offset | 0 if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0) @@ -1490,14 +1433,14 @@ window["AvrgirlArduino"] = return offset + 2 } - function objectWriteUInt32(buf, value, offset, littleEndian) { + function objectWriteUInt32 (buf, value, offset, littleEndian) { if (value < 0) value = 0xffffffff + value + 1 for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; ++i) { buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff } } - Buffer.prototype.writeUInt32LE = function writeUInt32LE(value, offset, noAssert) { + Buffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) { value = +value offset = offset | 0 if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0) @@ -1512,7 +1455,7 @@ window["AvrgirlArduino"] = return offset + 4 } - Buffer.prototype.writeUInt32BE = function writeUInt32BE(value, offset, noAssert) { + Buffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) { value = +value offset = offset | 0 if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0) @@ -1527,7 +1470,7 @@ window["AvrgirlArduino"] = return offset + 4 } - Buffer.prototype.writeIntLE = function writeIntLE(value, offset, byteLength, noAssert) { + Buffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) { value = +value offset = offset | 0 if (!noAssert) { @@ -1550,7 +1493,7 @@ window["AvrgirlArduino"] = return offset + byteLength } - Buffer.prototype.writeIntBE = function writeIntBE(value, offset, byteLength, noAssert) { + Buffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) { value = +value offset = offset | 0 if (!noAssert) { @@ -1573,7 +1516,7 @@ window["AvrgirlArduino"] = return offset + byteLength } - Buffer.prototype.writeInt8 = function writeInt8(value, offset, noAssert) { + Buffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) { value = +value offset = offset | 0 if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80) @@ -1583,7 +1526,7 @@ window["AvrgirlArduino"] = return offset + 1 } - Buffer.prototype.writeInt16LE = function writeInt16LE(value, offset, noAssert) { + Buffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) { value = +value offset = offset | 0 if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000) @@ -1596,7 +1539,7 @@ window["AvrgirlArduino"] = return offset + 2 } - Buffer.prototype.writeInt16BE = function writeInt16BE(value, offset, noAssert) { + Buffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) { value = +value offset = offset | 0 if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000) @@ -1609,7 +1552,7 @@ window["AvrgirlArduino"] = return offset + 2 } - Buffer.prototype.writeInt32LE = function writeInt32LE(value, offset, noAssert) { + Buffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) { value = +value offset = offset | 0 if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000) @@ -1624,7 +1567,7 @@ window["AvrgirlArduino"] = return offset + 4 } - Buffer.prototype.writeInt32BE = function writeInt32BE(value, offset, noAssert) { + Buffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) { value = +value offset = offset | 0 if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000) @@ -1640,12 +1583,12 @@ window["AvrgirlArduino"] = return offset + 4 } - function checkIEEE754(buf, value, offset, ext, max, min) { + function checkIEEE754 (buf, value, offset, ext, max, min) { if (offset + ext > buf.length) throw new RangeError('Index out of range') if (offset < 0) throw new RangeError('Index out of range') } - function writeFloat(buf, value, offset, littleEndian, noAssert) { + function writeFloat (buf, value, offset, littleEndian, noAssert) { if (!noAssert) { checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38) } @@ -1653,15 +1596,15 @@ window["AvrgirlArduino"] = return offset + 4 } - Buffer.prototype.writeFloatLE = function writeFloatLE(value, offset, noAssert) { + Buffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) { return writeFloat(this, value, offset, true, noAssert) } - Buffer.prototype.writeFloatBE = function writeFloatBE(value, offset, noAssert) { + Buffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) { return writeFloat(this, value, offset, false, noAssert) } - function writeDouble(buf, value, offset, littleEndian, noAssert) { + function writeDouble (buf, value, offset, littleEndian, noAssert) { if (!noAssert) { checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308) } @@ -1669,16 +1612,16 @@ window["AvrgirlArduino"] = return offset + 8 } - Buffer.prototype.writeDoubleLE = function writeDoubleLE(value, offset, noAssert) { + Buffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) { return writeDouble(this, value, offset, true, noAssert) } - Buffer.prototype.writeDoubleBE = function writeDoubleBE(value, offset, noAssert) { + Buffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) { return writeDouble(this, value, offset, false, noAssert) } // copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length) - Buffer.prototype.copy = function copy(target, targetStart, start, end) { + Buffer.prototype.copy = function copy (target, targetStart, start, end) { if (!start) start = 0 if (!end && end !== 0) end = this.length if (targetStart >= target.length) targetStart = target.length @@ -1730,7 +1673,7 @@ window["AvrgirlArduino"] = // buffer.fill(number[, offset[, end]]) // buffer.fill(buffer[, offset[, end]]) // buffer.fill(string[, offset[, end]][, encoding]) - Buffer.prototype.fill = function fill(val, start, end, encoding) { + Buffer.prototype.fill = function fill (val, start, end, encoding) { // Handle string cases: if (typeof val === 'string') { if (typeof start === 'string') { @@ -1794,7 +1737,7 @@ window["AvrgirlArduino"] = var INVALID_BASE64_RE = /[^+\/0-9A-Za-z-_]/g - function base64clean(str) { + function base64clean (str) { // Node strips out invalid characters like \n and \t from the string, base64-js does not str = stringtrim(str).replace(INVALID_BASE64_RE, '') // Node converts strings with length < 2 to '' @@ -1806,17 +1749,17 @@ window["AvrgirlArduino"] = return str } - function stringtrim(str) { + function stringtrim (str) { if (str.trim) return str.trim() return str.replace(/^\s+|\s+$/g, '') } - function toHex(n) { + function toHex (n) { if (n < 16) return '0' + n.toString(16) return n.toString(16) } - function utf8ToBytes(string, units) { + function utf8ToBytes (string, units) { units = units || Infinity var codePoint var length = string.length @@ -1896,7 +1839,7 @@ window["AvrgirlArduino"] = return bytes } - function asciiToBytes(str) { + function asciiToBytes (str) { var byteArray = [] for (var i = 0; i < str.length; ++i) { // Node's code seems to be doing this and not & 0x7F.. @@ -1905,7 +1848,7 @@ window["AvrgirlArduino"] = return byteArray } - function utf16leToBytes(str, units) { + function utf16leToBytes (str, units) { var c, hi, lo var byteArray = [] for (var i = 0; i < str.length; ++i) { @@ -1921,11 +1864,11 @@ window["AvrgirlArduino"] = return byteArray } - function base64ToBytes(str) { + function base64ToBytes (str) { return base64.toByteArray(base64clean(str)) } - function blitBuffer(src, dst, offset, length) { + function blitBuffer (src, dst, offset, length) { for (var i = 0; i < length; ++i) { if ((i + offset >= dst.length) || (i >= src.length)) break dst[i + offset] = src[i] @@ -1933,17 +1876,15 @@ window["AvrgirlArduino"] = return i } - function isnan(val) { + function isnan (val) { return val !== val // eslint-disable-line no-self-compare } - /* WEBPACK VAR INJECTION */ - }.call(this, __webpack_require__(2))) + /* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(2))) - /***/ - }), + /***/ }), /* 1 */ - /***/ (function (module, exports) { + /***/ (function(module, exports) { // shim for using process in browser var process = module.exports = {}; @@ -1959,11 +1900,9 @@ window["AvrgirlArduino"] = function defaultSetTimout() { throw new Error('setTimeout has not been defined'); } - - function defaultClearTimeout() { + function defaultClearTimeout () { throw new Error('clearTimeout has not been defined'); } - (function () { try { if (typeof setTimeout === 'function') { @@ -1983,8 +1922,7 @@ window["AvrgirlArduino"] = } catch (e) { cachedClearTimeout = defaultClearTimeout; } - }()) - + } ()) function runTimeout(fun) { if (cachedSetTimeout === setTimeout) { //normal enviroments in sane situations @@ -1998,11 +1936,11 @@ window["AvrgirlArduino"] = try { // when when somebody has screwed with setTimeout but no I.E. maddness return cachedSetTimeout(fun, 0); - } catch (e) { + } catch(e){ try { // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally return cachedSetTimeout.call(null, fun, 0); - } catch (e) { + } catch(e){ // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error return cachedSetTimeout.call(this, fun, 0); } @@ -2010,7 +1948,6 @@ window["AvrgirlArduino"] = } - function runClearTimeout(marker) { if (cachedClearTimeout === clearTimeout) { //normal enviroments in sane situations @@ -2024,11 +1961,11 @@ window["AvrgirlArduino"] = try { // when when somebody has screwed with setTimeout but no I.E. maddness return cachedClearTimeout(marker); - } catch (e) { + } catch (e){ try { // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally return cachedClearTimeout.call(null, marker); - } catch (e) { + } catch (e){ // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error. // Some versions of I.E. have different rules for clearTimeout vs setTimeout return cachedClearTimeout.call(this, marker); @@ -2036,8 +1973,8 @@ window["AvrgirlArduino"] = } - } + } var queue = []; var draining = false; var currentQueue; @@ -2066,7 +2003,7 @@ window["AvrgirlArduino"] = draining = true; var len = queue.length; - while (len) { + while(len) { currentQueue = queue; queue = []; while (++queueIndex < len) { @@ -2100,7 +2037,6 @@ window["AvrgirlArduino"] = this.fun = fun; this.array = array; } - Item.prototype.run = function () { this.fun.apply(null, this.array); }; @@ -2111,8 +2047,7 @@ window["AvrgirlArduino"] = process.version = ''; // empty string to avoid regexp issues process.versions = {}; - function noop() { - } + function noop() {} process.on = noop; process.addListener = noop; @@ -2124,34 +2059,27 @@ window["AvrgirlArduino"] = process.prependListener = noop; process.prependOnceListener = noop; - process.listeners = function (name) { - return [] - } + process.listeners = function (name) { return [] } process.binding = function (name) { throw new Error('process.binding is not supported'); }; - process.cwd = function () { - return '/' - }; + process.cwd = function () { return '/' }; process.chdir = function (dir) { throw new Error('process.chdir is not supported'); }; - process.umask = function () { - return 0; - }; + process.umask = function() { return 0; }; - /***/ - }), + /***/ }), /* 2 */ - /***/ (function (module, exports) { + /***/ (function(module, exports) { var g; // This works in non-strict mode - g = (function () { + g = (function() { return this; })(); @@ -2170,41 +2098,9 @@ window["AvrgirlArduino"] = module.exports = g; - /***/ - }), + /***/ }), /* 3 */ - /***/ (function (module, exports) { - - if (typeof Object.create === 'function') { - // implementation from standard node.js 'util' module - module.exports = function inherits(ctor, superCtor) { - ctor.super_ = superCtor - ctor.prototype = Object.create(superCtor.prototype, { - constructor: { - value: ctor, - enumerable: false, - writable: true, - configurable: true - } - }); - }; - } else { - // old school shim for old browsers - module.exports = function inherits(ctor, superCtor) { - ctor.super_ = superCtor - var TempCtor = function () { - } - TempCtor.prototype = superCtor.prototype - ctor.prototype = new TempCtor() - ctor.prototype.constructor = ctor - } - } - - - /***/ - }), - /* 4 */ - /***/ (function (module, exports, __webpack_require__) { + /***/ (function(module, exports, __webpack_require__) { "use strict"; // Copyright Joyent, Inc. and other Node contributors. @@ -2234,9 +2130,10 @@ window["AvrgirlArduino"] = // Writable. + /**/ - var pna = __webpack_require__(11); + var pna = __webpack_require__(9); /**/ /**/ @@ -2244,20 +2141,19 @@ window["AvrgirlArduino"] = var keys = []; for (var key in obj) { keys.push(key); - } - return keys; + }return keys; }; /**/ module.exports = Duplex; /**/ - var util = __webpack_require__(9); - util.inherits = __webpack_require__(3); + var util = Object.create(__webpack_require__(8)); + util.inherits = __webpack_require__(6); /**/ - var Readable = __webpack_require__(25); - var Writable = __webpack_require__(19); + var Readable = __webpack_require__(23); + var Writable = __webpack_require__(17); util.inherits(Duplex, Readable); @@ -2339,10 +2235,9 @@ window["AvrgirlArduino"] = pna.nextTick(cb, err); }; - /***/ - }), - /* 5 */ - /***/ (function (module, exports, __webpack_require__) { + /***/ }), + /* 4 */ + /***/ (function(module, exports, __webpack_require__) { "use strict"; // Copyright Joyent, Inc. and other Node contributors. @@ -2367,6 +2262,7 @@ window["AvrgirlArduino"] = // USE OR OTHER DEALINGS IN THE SOFTWARE. + var R = typeof Reflect === 'object' ? Reflect : null var ReflectApply = R && typeof R.apply === 'function' ? R.apply @@ -2399,8 +2295,8 @@ window["AvrgirlArduino"] = function EventEmitter() { EventEmitter.init.call(this); } - module.exports = EventEmitter; + module.exports.once = once; // Backwards-compat with node 0.10.x EventEmitter.EventEmitter = EventEmitter; @@ -2413,12 +2309,18 @@ window["AvrgirlArduino"] = // added to it. This is a useful default which helps finding memory leaks. var defaultMaxListeners = 10; + function checkListener(listener) { + if (typeof listener !== 'function') { + throw new TypeError('The "listener" argument must be of type Function. Received type ' + typeof listener); + } + } + Object.defineProperty(EventEmitter, 'defaultMaxListeners', { enumerable: true, - get: function () { + get: function() { return defaultMaxListeners; }, - set: function (arg) { + set: function(arg) { if (typeof arg !== 'number' || arg < 0 || NumberIsNaN(arg)) { throw new RangeError('The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received ' + arg + '.'); } @@ -2426,7 +2328,7 @@ window["AvrgirlArduino"] = } }); - EventEmitter.init = function () { + EventEmitter.init = function() { if (this._events === undefined || this._events === Object.getPrototypeOf(this)._events) { @@ -2447,14 +2349,14 @@ window["AvrgirlArduino"] = return this; }; - function $getMaxListeners(that) { + function _getMaxListeners(that) { if (that._maxListeners === undefined) return EventEmitter.defaultMaxListeners; return that._maxListeners; } EventEmitter.prototype.getMaxListeners = function getMaxListeners() { - return $getMaxListeners(this); + return _getMaxListeners(this); }; EventEmitter.prototype.emit = function emit(type) { @@ -2506,9 +2408,7 @@ window["AvrgirlArduino"] = var events; var existing; - if (typeof listener !== 'function') { - throw new TypeError('The "listener" argument must be of type Function. Received type ' + typeof listener); - } + checkListener(listener); events = target._events; if (events === undefined) { @@ -2545,7 +2445,7 @@ window["AvrgirlArduino"] = } // Check for listener leak - m = $getMaxListeners(target); + m = _getMaxListeners(target); if (m > 0 && existing.length > m && !existing.warned) { existing.warned = true; // No error code for this since it is a Warning @@ -2577,17 +2477,17 @@ window["AvrgirlArduino"] = }; function onceWrapper() { - var args = []; - for (var i = 0; i < arguments.length; i++) args.push(arguments[i]); if (!this.fired) { this.target.removeListener(this.type, this.wrapFn); this.fired = true; - ReflectApply(this.listener, this.target, args); + if (arguments.length === 0) + return this.listener.call(this.target); + return this.listener.apply(this.target, arguments); } } function _onceWrap(target, type, listener) { - var state = {fired: false, wrapFn: undefined, target: target, type: type, listener: listener}; + var state = { fired: false, wrapFn: undefined, target: target, type: type, listener: listener }; var wrapped = onceWrapper.bind(state); wrapped.listener = listener; state.wrapFn = wrapped; @@ -2595,18 +2495,14 @@ window["AvrgirlArduino"] = } EventEmitter.prototype.once = function once(type, listener) { - if (typeof listener !== 'function') { - throw new TypeError('The "listener" argument must be of type Function. Received type ' + typeof listener); - } + checkListener(listener); this.on(type, _onceWrap(this, type, listener)); return this; }; EventEmitter.prototype.prependOnceListener = function prependOnceListener(type, listener) { - if (typeof listener !== 'function') { - throw new TypeError('The "listener" argument must be of type Function. Received type ' + typeof listener); - } + checkListener(listener); this.prependListener(type, _onceWrap(this, type, listener)); return this; }; @@ -2616,9 +2512,7 @@ window["AvrgirlArduino"] = function removeListener(type, listener) { var list, events, position, i, originalListener; - if (typeof listener !== 'function') { - throw new TypeError('The "listener" argument must be of type Function. Received type ' + typeof listener); - } + checkListener(listener); events = this._events; if (events === undefined) @@ -2744,7 +2638,7 @@ window["AvrgirlArduino"] = return _listeners(this, type, false); }; - EventEmitter.listenerCount = function (emitter, type) { + EventEmitter.listenerCount = function(emitter, type) { if (typeof emitter.listenerCount === 'function') { return emitter.listenerCount(type); } else { @@ -2753,7 +2647,6 @@ window["AvrgirlArduino"] = }; EventEmitter.prototype.listenerCount = listenerCount; - function listenerCount(type) { var events = this._events; @@ -2795,6946 +2688,6636 @@ window["AvrgirlArduino"] = return ret; } + function once(emitter, name) { + return new Promise(function (resolve, reject) { + function eventListener() { + if (errorListener !== undefined) { + emitter.removeListener('error', errorListener); + } + resolve([].slice.call(arguments)); + }; + var errorListener; + + // Adding an error listener is not optional because + // if an error is thrown on an event emitter we cannot + // guarantee that the actual event we are waiting will + // be fired. The result could be a silent way to create + // memory or file descriptor leaks, which is something + // we should avoid. + if (name !== 'error') { + errorListener = function errorListener(err) { + emitter.removeListener(name, eventListener); + reject(err); + }; - /***/ - }), - /* 6 */ - /***/ (function (module, exports, __webpack_require__) { - - /* - -The MIT License (MIT) + emitter.once('error', errorListener); + } -Original Library - - Copyright (c) Marak Squires + emitter.once(name, eventListener); + }); + } -Additional functionality - - Copyright (c) Sindre Sorhus (sindresorhus.com) -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: + /***/ }), + /* 5 */ + /***/ (function(module, exports, __webpack_require__) { -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. + /* WEBPACK VAR INJECTION */(function(process) {// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. + var getOwnPropertyDescriptors = Object.getOwnPropertyDescriptors || + function getOwnPropertyDescriptors(obj) { + var keys = Object.keys(obj); + var descriptors = {}; + for (var i = 0; i < keys.length; i++) { + descriptors[keys[i]] = Object.getOwnPropertyDescriptor(obj, keys[i]); + } + return descriptors; + }; -*/ + var formatRegExp = /%[sdj%]/g; + exports.format = function(f) { + if (!isString(f)) { + var objects = []; + for (var i = 0; i < arguments.length; i++) { + objects.push(inspect(arguments[i])); + } + return objects.join(' '); + } - var colors = {}; - module['exports'] = colors; + var i = 1; + var args = arguments; + var len = args.length; + var str = String(f).replace(formatRegExp, function(x) { + if (x === '%%') return '%'; + if (i >= len) return x; + switch (x) { + case '%s': return String(args[i++]); + case '%d': return Number(args[i++]); + case '%j': + try { + return JSON.stringify(args[i++]); + } catch (_) { + return '[Circular]'; + } + default: + return x; + } + }); + for (var x = args[i]; i < len; x = args[++i]) { + if (isNull(x) || !isObject(x)) { + str += ' ' + x; + } else { + str += ' ' + inspect(x); + } + } + return str; + }; - colors.themes = {}; - var ansiStyles = colors.styles = __webpack_require__(47); - var defineProps = Object.defineProperties; +// Mark that a method should not be used. +// Returns a modified function which warns once by default. +// If --no-deprecation is set, then it is a no-op. + exports.deprecate = function(fn, msg) { + if (typeof process !== 'undefined' && process.noDeprecation === true) { + return fn; + } - colors.supportsColor = __webpack_require__(48); + // Allow for deprecating things in the process of starting up. + if (typeof process === 'undefined') { + return function() { + return exports.deprecate(fn, msg).apply(this, arguments); + }; + } - if (typeof colors.enabled === "undefined") { - colors.enabled = colors.supportsColor; - } + var warned = false; + function deprecated() { + if (!warned) { + if (process.throwDeprecation) { + throw new Error(msg); + } else if (process.traceDeprecation) { + console.trace(msg); + } else { + console.error(msg); + } + warned = true; + } + return fn.apply(this, arguments); + } - colors.stripColors = colors.strip = function (str) { - return ("" + str).replace(/\x1B\[\d+m/g, ''); - }; + return deprecated; + }; - var stylize = colors.stylize = function stylize(str, style) { - if (!colors.enabled) { - return str + ''; - } + var debugs = {}; + var debugEnviron; + exports.debuglog = function(set) { + if (isUndefined(debugEnviron)) + debugEnviron = process.env.NODE_DEBUG || ''; + set = set.toUpperCase(); + if (!debugs[set]) { + if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) { + var pid = process.pid; + debugs[set] = function() { + var msg = exports.format.apply(exports, arguments); + console.error('%s %d: %s', set, pid, msg); + }; + } else { + debugs[set] = function() {}; + } + } + return debugs[set]; + }; - return ansiStyles[style].open + str + ansiStyles[style].close; - } - var matchOperatorsRe = /[|\\{}()[\]^$+*?.]/g; - var escapeStringRegexp = function (str) { - if (typeof str !== 'string') { - throw new TypeError('Expected a string'); + /** + * Echos the value of a value. Trys to print the value out + * in the best way possible given the different types. + * + * @param {Object} obj The object to print out. + * @param {Object} opts Optional options object that alters the output. + */ + /* legacy: obj, showHidden, depth, colors*/ + function inspect(obj, opts) { + // default options + var ctx = { + seen: [], + stylize: stylizeNoColor + }; + // legacy... + if (arguments.length >= 3) ctx.depth = arguments[2]; + if (arguments.length >= 4) ctx.colors = arguments[3]; + if (isBoolean(opts)) { + // legacy... + ctx.showHidden = opts; + } else if (opts) { + // got an "options" object + exports._extend(ctx, opts); + } + // set default options + if (isUndefined(ctx.showHidden)) ctx.showHidden = false; + if (isUndefined(ctx.depth)) ctx.depth = 2; + if (isUndefined(ctx.colors)) ctx.colors = false; + if (isUndefined(ctx.customInspect)) ctx.customInspect = true; + if (ctx.colors) ctx.stylize = stylizeWithColor; + return formatValue(ctx, obj, ctx.depth); } - return str.replace(matchOperatorsRe, '\\$&'); - } + exports.inspect = inspect; - function build(_styles) { - var builder = function builder() { - return applyStyle.apply(builder, arguments); + +// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics + inspect.colors = { + 'bold' : [1, 22], + 'italic' : [3, 23], + 'underline' : [4, 24], + 'inverse' : [7, 27], + 'white' : [37, 39], + 'grey' : [90, 39], + 'black' : [30, 39], + 'blue' : [34, 39], + 'cyan' : [36, 39], + 'green' : [32, 39], + 'magenta' : [35, 39], + 'red' : [31, 39], + 'yellow' : [33, 39] }; - builder._styles = _styles; - // __proto__ is used because we must return a function, but there is - // no way to create a function with a different prototype. - builder.__proto__ = proto; - return builder; - } - var styles = (function () { - var ret = {}; - ansiStyles.grey = ansiStyles.gray; - Object.keys(ansiStyles).forEach(function (key) { - ansiStyles[key].closeRe = new RegExp(escapeStringRegexp(ansiStyles[key].close), 'g'); - ret[key] = { - get: function () { - return build(this._styles.concat(key)); - } - }; - }); - return ret; - })(); +// Don't use 'blue' not visible on cmd.exe + inspect.styles = { + 'special': 'cyan', + 'number': 'yellow', + 'boolean': 'yellow', + 'undefined': 'grey', + 'null': 'bold', + 'string': 'green', + 'date': 'magenta', + // "name": intentionally not styling + 'regexp': 'red' + }; - var proto = defineProps(function colors() { - }, styles); - function applyStyle() { - var args = arguments; - var argsLen = args.length; - var str = argsLen !== 0 && String(arguments[0]); - if (argsLen > 1) { - for (var a = 1; a < argsLen; a++) { - str += ' ' + args[a]; + function stylizeWithColor(str, styleType) { + var style = inspect.styles[styleType]; + + if (style) { + return '\u001b[' + inspect.colors[style][0] + 'm' + str + + '\u001b[' + inspect.colors[style][1] + 'm'; + } else { + return str; } } - if (!colors.enabled || !str) { + + function stylizeNoColor(str, styleType) { return str; } - var nestedStyles = this._styles; - var i = nestedStyles.length; - while (i--) { - var code = ansiStyles[nestedStyles[i]]; - str = code.open + str.replace(code.closeRe, code.open) + code.close; - } + function arrayToHash(array) { + var hash = {}; - return str; - } + array.forEach(function(val, idx) { + hash[val] = true; + }); - function applyTheme(theme) { - for (var style in theme) { - (function (style) { - colors[style] = function (str) { - if (typeof theme[style] === 'object') { - var out = str; - for (var i in theme[style]) { - out = colors[theme[style][i]](out); - } - return out; - } - return colors[theme[style]](str); - }; - })(style) + return hash; } - } - colors.setTheme = function (theme) { - if (typeof theme === 'string') { - try { - colors.themes[theme] = __webpack_require__(23)(theme); - applyTheme(colors.themes[theme]); - return colors.themes[theme]; - } catch (err) { - console.log(err); - return err; - } - } else { - applyTheme(theme); - } - }; - function init() { - var ret = {}; - Object.keys(styles).forEach(function (name) { - ret[name] = { - get: function () { - return build([name]); + function formatValue(ctx, value, recurseTimes) { + // Provide a hook for user-specified inspect functions. + // Check that value is an object with an inspect function on it + if (ctx.customInspect && + value && + isFunction(value.inspect) && + // Filter out the util module, it's inspect function is special + value.inspect !== exports.inspect && + // Also filter out any prototype objects using the circular check. + !(value.constructor && value.constructor.prototype === value)) { + var ret = value.inspect(recurseTimes, ctx); + if (!isString(ret)) { + ret = formatValue(ctx, ret, recurseTimes); } - }; - }); - return ret; - } + return ret; + } - var sequencer = function sequencer(map, str) { - var exploded = str.split(""), i = 0; - exploded = exploded.map(map); - return exploded.join(""); - }; + // Primitive types cannot have properties + var primitive = formatPrimitive(ctx, value); + if (primitive) { + return primitive; + } -// custom formatter methods - colors.trap = __webpack_require__(49); - colors.zalgo = __webpack_require__(50); + // Look up the keys of the object. + var keys = Object.keys(value); + var visibleKeys = arrayToHash(keys); -// maps - colors.maps = {}; - colors.maps.america = __webpack_require__(51); - colors.maps.zebra = __webpack_require__(52); - colors.maps.rainbow = __webpack_require__(53); - colors.maps.random = __webpack_require__(54) + if (ctx.showHidden) { + keys = Object.getOwnPropertyNames(value); + } - for (var map in colors.maps) { - (function (map) { - colors[map] = function (str) { - return sequencer(colors.maps[map], str); + // IE doesn't make error fields non-enumerable + // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx + if (isError(value) + && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) { + return formatError(value); } - })(map) - } - defineProps(colors, init()); + // Some type of object without properties can be shortcutted. + if (keys.length === 0) { + if (isFunction(value)) { + var name = value.name ? ': ' + value.name : ''; + return ctx.stylize('[Function' + name + ']', 'special'); + } + if (isRegExp(value)) { + return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); + } + if (isDate(value)) { + return ctx.stylize(Date.prototype.toString.call(value), 'date'); + } + if (isError(value)) { + return formatError(value); + } + } - /***/ - }), - /* 7 */ - /***/ (function (module, exports, __webpack_require__) { + var base = '', array = false, braces = ['{', '}']; - /* WEBPACK VAR INJECTION */ - (function (global) { - var scope = (typeof global !== "undefined" && global) || - (typeof self !== "undefined" && self) || - window; - var apply = Function.prototype.apply; + // Make Array say that they are Array + if (isArray(value)) { + array = true; + braces = ['[', ']']; + } -// DOM APIs, for completeness + // Make functions say that they are functions + if (isFunction(value)) { + var n = value.name ? ': ' + value.name : ''; + base = ' [Function' + n + ']'; + } - exports.setTimeout = function () { - return new Timeout(apply.call(setTimeout, scope, arguments), clearTimeout); - }; - exports.setInterval = function () { - return new Timeout(apply.call(setInterval, scope, arguments), clearInterval); - }; - exports.clearTimeout = - exports.clearInterval = function (timeout) { - if (timeout) { - timeout.close(); - } - }; + // Make RegExps say that they are RegExps + if (isRegExp(value)) { + base = ' ' + RegExp.prototype.toString.call(value); + } - function Timeout(id, clearFn) { - this._id = id; - this._clearFn = clearFn; - } + // Make dates with properties first say the date + if (isDate(value)) { + base = ' ' + Date.prototype.toUTCString.call(value); + } - Timeout.prototype.unref = Timeout.prototype.ref = function () { - }; - Timeout.prototype.close = function () { - this._clearFn.call(scope, this._id); - }; + // Make error with message first say the error + if (isError(value)) { + base = ' ' + formatError(value); + } -// Does not start the time, just sets up the members needed. - exports.enroll = function (item, msecs) { - clearTimeout(item._idleTimeoutId); - item._idleTimeout = msecs; - }; + if (keys.length === 0 && (!array || value.length == 0)) { + return braces[0] + base + braces[1]; + } - exports.unenroll = function (item) { - clearTimeout(item._idleTimeoutId); - item._idleTimeout = -1; - }; + if (recurseTimes < 0) { + if (isRegExp(value)) { + return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); + } else { + return ctx.stylize('[Object]', 'special'); + } + } - exports._unrefActive = exports.active = function (item) { - clearTimeout(item._idleTimeoutId); + ctx.seen.push(value); - var msecs = item._idleTimeout; - if (msecs >= 0) { - item._idleTimeoutId = setTimeout(function onTimeout() { - if (item._onTimeout) - item._onTimeout(); - }, msecs); + var output; + if (array) { + output = formatArray(ctx, value, recurseTimes, visibleKeys, keys); + } else { + output = keys.map(function(key) { + return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array); + }); } - }; -// setimmediate attaches itself to the global object - __webpack_require__(36); -// On some exotic environments, it's not clear which object `setimmediate` was -// able to install onto. Search each possibility in the same order as the -// `setimmediate` library. - exports.setImmediate = (typeof self !== "undefined" && self.setImmediate) || - (typeof global !== "undefined" && global.setImmediate) || - (this && this.setImmediate); - exports.clearImmediate = (typeof self !== "undefined" && self.clearImmediate) || - (typeof global !== "undefined" && global.clearImmediate) || - (this && this.clearImmediate); + ctx.seen.pop(); - /* WEBPACK VAR INJECTION */ - }.call(this, __webpack_require__(2))) + return reduceToSingleString(output, base, braces); + } - /***/ - }), - /* 8 */ - /***/ (function (module, exports, __webpack_require__) { - /* WEBPACK VAR INJECTION */ - (function (process) {// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. + function formatPrimitive(ctx, value) { + if (isUndefined(value)) + return ctx.stylize('undefined', 'undefined'); + if (isString(value)) { + var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') + .replace(/'/g, "\\'") + .replace(/\\"/g, '"') + '\''; + return ctx.stylize(simple, 'string'); + } + if (isNumber(value)) + return ctx.stylize('' + value, 'number'); + if (isBoolean(value)) + return ctx.stylize('' + value, 'boolean'); + // For some reason typeof null is "object", so special case here. + if (isNull(value)) + return ctx.stylize('null', 'null'); + } - var getOwnPropertyDescriptors = Object.getOwnPropertyDescriptors || - function getOwnPropertyDescriptors(obj) { - var keys = Object.keys(obj); - var descriptors = {}; - for (var i = 0; i < keys.length; i++) { - descriptors[keys[i]] = Object.getOwnPropertyDescriptor(obj, keys[i]); - } - return descriptors; - }; - var formatRegExp = /%[sdj%]/g; - exports.format = function (f) { - if (!isString(f)) { - var objects = []; - for (var i = 0; i < arguments.length; i++) { - objects.push(inspect(arguments[i])); + function formatError(value) { + return '[' + Error.prototype.toString.call(value) + ']'; + } + + + function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { + var output = []; + for (var i = 0, l = value.length; i < l; ++i) { + if (hasOwnProperty(value, String(i))) { + output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, + String(i), true)); + } else { + output.push(''); } - return objects.join(' '); } + keys.forEach(function(key) { + if (!key.match(/^\d+$/)) { + output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, + key, true)); + } + }); + return output; + } - var i = 1; - var args = arguments; - var len = args.length; - var str = String(f).replace(formatRegExp, function (x) { - if (x === '%%') return '%'; - if (i >= len) return x; - switch (x) { - case '%s': - return String(args[i++]); - case '%d': - return Number(args[i++]); - case '%j': - try { - return JSON.stringify(args[i++]); - } catch (_) { - return '[Circular]'; + + function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) { + var name, str, desc; + desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] }; + if (desc.get) { + if (desc.set) { + str = ctx.stylize('[Getter/Setter]', 'special'); + } else { + str = ctx.stylize('[Getter]', 'special'); + } + } else { + if (desc.set) { + str = ctx.stylize('[Setter]', 'special'); + } + } + if (!hasOwnProperty(visibleKeys, key)) { + name = '[' + key + ']'; + } + if (!str) { + if (ctx.seen.indexOf(desc.value) < 0) { + if (isNull(recurseTimes)) { + str = formatValue(ctx, desc.value, null); + } else { + str = formatValue(ctx, desc.value, recurseTimes - 1); + } + if (str.indexOf('\n') > -1) { + if (array) { + str = str.split('\n').map(function(line) { + return ' ' + line; + }).join('\n').substr(2); + } else { + str = '\n' + str.split('\n').map(function(line) { + return ' ' + line; + }).join('\n'); } - default: - return x; + } + } else { + str = ctx.stylize('[Circular]', 'special'); } - }); - for (var x = args[i]; i < len; x = args[++i]) { - if (isNull(x) || !isObject(x)) { - str += ' ' + x; + } + if (isUndefined(name)) { + if (array && key.match(/^\d+$/)) { + return str; + } + name = JSON.stringify('' + key); + if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { + name = name.substr(1, name.length - 2); + name = ctx.stylize(name, 'name'); } else { - str += ' ' + inspect(x); + name = name.replace(/'/g, "\\'") + .replace(/\\"/g, '"') + .replace(/(^"|"$)/g, "'"); + name = ctx.stylize(name, 'string'); } } - return str; + + return name + ': ' + str; + } + + + function reduceToSingleString(output, base, braces) { + var numLinesEst = 0; + var length = output.reduce(function(prev, cur) { + numLinesEst++; + if (cur.indexOf('\n') >= 0) numLinesEst++; + return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1; + }, 0); + + if (length > 60) { + return braces[0] + + (base === '' ? '' : base + '\n ') + + ' ' + + output.join(',\n ') + + ' ' + + braces[1]; + } + + return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; + } + + +// NOTE: These type checking functions intentionally don't use `instanceof` +// because it is fragile and can be easily faked with `Object.create()`. + function isArray(ar) { + return Array.isArray(ar); + } + exports.isArray = isArray; + + function isBoolean(arg) { + return typeof arg === 'boolean'; + } + exports.isBoolean = isBoolean; + + function isNull(arg) { + return arg === null; + } + exports.isNull = isNull; + + function isNullOrUndefined(arg) { + return arg == null; + } + exports.isNullOrUndefined = isNullOrUndefined; + + function isNumber(arg) { + return typeof arg === 'number'; + } + exports.isNumber = isNumber; + + function isString(arg) { + return typeof arg === 'string'; + } + exports.isString = isString; + + function isSymbol(arg) { + return typeof arg === 'symbol'; + } + exports.isSymbol = isSymbol; + + function isUndefined(arg) { + return arg === void 0; + } + exports.isUndefined = isUndefined; + + function isRegExp(re) { + return isObject(re) && objectToString(re) === '[object RegExp]'; + } + exports.isRegExp = isRegExp; + + function isObject(arg) { + return typeof arg === 'object' && arg !== null; + } + exports.isObject = isObject; + + function isDate(d) { + return isObject(d) && objectToString(d) === '[object Date]'; + } + exports.isDate = isDate; + + function isError(e) { + return isObject(e) && + (objectToString(e) === '[object Error]' || e instanceof Error); + } + exports.isError = isError; + + function isFunction(arg) { + return typeof arg === 'function'; + } + exports.isFunction = isFunction; + + function isPrimitive(arg) { + return arg === null || + typeof arg === 'boolean' || + typeof arg === 'number' || + typeof arg === 'string' || + typeof arg === 'symbol' || // ES6 symbol + typeof arg === 'undefined'; + } + exports.isPrimitive = isPrimitive; + + exports.isBuffer = __webpack_require__(45); + + function objectToString(o) { + return Object.prototype.toString.call(o); + } + + + function pad(n) { + return n < 10 ? '0' + n.toString(10) : n.toString(10); + } + + + var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', + 'Oct', 'Nov', 'Dec']; + +// 26 Feb 16:19:34 + function timestamp() { + var d = new Date(); + var time = [pad(d.getHours()), + pad(d.getMinutes()), + pad(d.getSeconds())].join(':'); + return [d.getDate(), months[d.getMonth()], time].join(' '); + } + + +// log is just a thin wrapper to console.log that prepends a timestamp + exports.log = function() { + console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments)); }; -// Mark that a method should not be used. -// Returns a modified function which warns once by default. -// If --no-deprecation is set, then it is a no-op. - exports.deprecate = function (fn, msg) { - if (typeof process !== 'undefined' && process.noDeprecation === true) { - return fn; + /** + * Inherit the prototype methods from one constructor into another. + * + * The Function.prototype.inherits from lang.js rewritten as a standalone + * function (not on Function.prototype). NOTE: If this file is to be loaded + * during bootstrapping this function needs to be rewritten using some native + * functions as prototype setup using normal JavaScript does not work as + * expected during bootstrapping (see mirror.js in r114903). + * + * @param {function} ctor Constructor function which needs to inherit the + * prototype. + * @param {function} superCtor Constructor function to inherit prototype from. + */ + exports.inherits = __webpack_require__(46); + + exports._extend = function(origin, add) { + // Don't do anything if add isn't an object + if (!add || !isObject(add)) return origin; + + var keys = Object.keys(add); + var i = keys.length; + while (i--) { + origin[keys[i]] = add[keys[i]]; } + return origin; + }; - // Allow for deprecating things in the process of starting up. - if (typeof process === 'undefined') { - return function () { - return exports.deprecate(fn, msg).apply(this, arguments); - }; + function hasOwnProperty(obj, prop) { + return Object.prototype.hasOwnProperty.call(obj, prop); + } + + var kCustomPromisifiedSymbol = typeof Symbol !== 'undefined' ? Symbol('util.promisify.custom') : undefined; + + exports.promisify = function promisify(original) { + if (typeof original !== 'function') + throw new TypeError('The "original" argument must be of type Function'); + + if (kCustomPromisifiedSymbol && original[kCustomPromisifiedSymbol]) { + var fn = original[kCustomPromisifiedSymbol]; + if (typeof fn !== 'function') { + throw new TypeError('The "util.promisify.custom" argument must be of type Function'); + } + Object.defineProperty(fn, kCustomPromisifiedSymbol, { + value: fn, enumerable: false, writable: false, configurable: true + }); + return fn; } - var warned = false; + function fn() { + var promiseResolve, promiseReject; + var promise = new Promise(function (resolve, reject) { + promiseResolve = resolve; + promiseReject = reject; + }); - function deprecated() { - if (!warned) { - if (process.throwDeprecation) { - throw new Error(msg); - } else if (process.traceDeprecation) { - console.trace(msg); + var args = []; + for (var i = 0; i < arguments.length; i++) { + args.push(arguments[i]); + } + args.push(function (err, value) { + if (err) { + promiseReject(err); } else { - console.error(msg); + promiseResolve(value); } - warned = true; + }); + + try { + original.apply(this, args); + } catch (err) { + promiseReject(err); } - return fn.apply(this, arguments); + + return promise; } - return deprecated; + Object.setPrototypeOf(fn, Object.getPrototypeOf(original)); + + if (kCustomPromisifiedSymbol) Object.defineProperty(fn, kCustomPromisifiedSymbol, { + value: fn, enumerable: false, writable: false, configurable: true + }); + return Object.defineProperties( + fn, + getOwnPropertyDescriptors(original) + ); + } + + exports.promisify.custom = kCustomPromisifiedSymbol + + function callbackifyOnRejected(reason, cb) { + // `!reason` guard inspired by bluebird (Ref: https://goo.gl/t5IS6M). + // Because `null` is a special error value in callbacks which means "no error + // occurred", we error-wrap so the callback consumer can distinguish between + // "the promise rejected with null" or "the promise fulfilled with undefined". + if (!reason) { + var newReason = new Error('Promise was rejected with a falsy value'); + newReason.reason = reason; + reason = newReason; + } + return cb(reason); + } + + function callbackify(original) { + if (typeof original !== 'function') { + throw new TypeError('The "original" argument must be of type Function'); + } + + // We DO NOT return the promise as it gives the user a false sense that + // the promise is actually somehow related to the callback's execution + // and that the callback throwing will reject the promise. + function callbackified() { + var args = []; + for (var i = 0; i < arguments.length; i++) { + args.push(arguments[i]); + } + + var maybeCb = args.pop(); + if (typeof maybeCb !== 'function') { + throw new TypeError('The last argument must be of type Function'); + } + var self = this; + var cb = function() { + return maybeCb.apply(self, arguments); + }; + // In true node style we process the callback on `nextTick` with all the + // implications (stack, `uncaughtException`, `async_hooks`) + original.apply(this, args) + .then(function(ret) { process.nextTick(cb, null, ret) }, + function(rej) { process.nextTick(callbackifyOnRejected, rej, cb) }); + } + + Object.setPrototypeOf(callbackified, Object.getPrototypeOf(original)); + Object.defineProperties(callbackified, + getOwnPropertyDescriptors(original)); + return callbackified; + } + exports.callbackify = callbackify; + + /* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(1))) + + /***/ }), + /* 6 */ + /***/ (function(module, exports) { + + if (typeof Object.create === 'function') { + // implementation from standard node.js 'util' module + module.exports = function inherits(ctor, superCtor) { + if (superCtor) { + ctor.super_ = superCtor + ctor.prototype = Object.create(superCtor.prototype, { + constructor: { + value: ctor, + enumerable: false, + writable: true, + configurable: true + } + }) + } }; + } else { + // old school shim for old browsers + module.exports = function inherits(ctor, superCtor) { + if (superCtor) { + ctor.super_ = superCtor + var TempCtor = function () {} + TempCtor.prototype = superCtor.prototype + ctor.prototype = new TempCtor() + ctor.prototype.constructor = ctor + } + } + } - var debugs = {}; - var debugEnviron; - exports.debuglog = function (set) { - if (isUndefined(debugEnviron)) - debugEnviron = process.env.NODE_DEBUG || ''; - set = set.toUpperCase(); - if (!debugs[set]) { - if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) { - var pid = process.pid; - debugs[set] = function () { - var msg = exports.format.apply(exports, arguments); - console.error('%s %d: %s', set, pid, msg); - }; - } else { - debugs[set] = function () { - }; + /***/ }), + /* 7 */ + /***/ (function(module, exports, __webpack_require__) { + + /* WEBPACK VAR INJECTION */(function(global) {var scope = (typeof global !== "undefined" && global) || + (typeof self !== "undefined" && self) || + window; + var apply = Function.prototype.apply; + +// DOM APIs, for completeness + + exports.setTimeout = function() { + return new Timeout(apply.call(setTimeout, scope, arguments), clearTimeout); + }; + exports.setInterval = function() { + return new Timeout(apply.call(setInterval, scope, arguments), clearInterval); + }; + exports.clearTimeout = + exports.clearInterval = function(timeout) { + if (timeout) { + timeout.close(); } + }; + + function Timeout(id, clearFn) { + this._id = id; + this._clearFn = clearFn; + } + Timeout.prototype.unref = Timeout.prototype.ref = function() {}; + Timeout.prototype.close = function() { + this._clearFn.call(scope, this._id); + }; + +// Does not start the time, just sets up the members needed. + exports.enroll = function(item, msecs) { + clearTimeout(item._idleTimeoutId); + item._idleTimeout = msecs; + }; + + exports.unenroll = function(item) { + clearTimeout(item._idleTimeoutId); + item._idleTimeout = -1; + }; + + exports._unrefActive = exports.active = function(item) { + clearTimeout(item._idleTimeoutId); + + var msecs = item._idleTimeout; + if (msecs >= 0) { + item._idleTimeoutId = setTimeout(function onTimeout() { + if (item._onTimeout) + item._onTimeout(); + }, msecs); } - return debugs[set]; }; +// setimmediate attaches itself to the global object + __webpack_require__(34); +// On some exotic environments, it's not clear which object `setimmediate` was +// able to install onto. Search each possibility in the same order as the +// `setimmediate` library. + exports.setImmediate = (typeof self !== "undefined" && self.setImmediate) || + (typeof global !== "undefined" && global.setImmediate) || + (this && this.setImmediate); + exports.clearImmediate = (typeof self !== "undefined" && self.clearImmediate) || + (typeof global !== "undefined" && global.clearImmediate) || + (this && this.clearImmediate); - /** - * Echos the value of a value. Trys to print the value out - * in the best way possible given the different types. - * - * @param {Object} obj The object to print out. - * @param {Object} opts Optional options object that alters the output. - */ + /* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(2))) - /* legacy: obj, showHidden, depth, colors*/ - function inspect(obj, opts) { - // default options - var ctx = { - seen: [], - stylize: stylizeNoColor - }; - // legacy... - if (arguments.length >= 3) ctx.depth = arguments[2]; - if (arguments.length >= 4) ctx.colors = arguments[3]; - if (isBoolean(opts)) { - // legacy... - ctx.showHidden = opts; - } else if (opts) { - // got an "options" object - exports._extend(ctx, opts); + /***/ }), + /* 8 */ + /***/ (function(module, exports, __webpack_require__) { + + /* WEBPACK VAR INJECTION */(function(Buffer) {// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +// NOTE: These type checking functions intentionally don't use `instanceof` +// because it is fragile and can be easily faked with `Object.create()`. + + function isArray(arg) { + if (Array.isArray) { + return Array.isArray(arg); } - // set default options - if (isUndefined(ctx.showHidden)) ctx.showHidden = false; - if (isUndefined(ctx.depth)) ctx.depth = 2; - if (isUndefined(ctx.colors)) ctx.colors = false; - if (isUndefined(ctx.customInspect)) ctx.customInspect = true; - if (ctx.colors) ctx.stylize = stylizeWithColor; - return formatValue(ctx, obj, ctx.depth); + return objectToString(arg) === '[object Array]'; } + exports.isArray = isArray; - exports.inspect = inspect; + function isBoolean(arg) { + return typeof arg === 'boolean'; + } + exports.isBoolean = isBoolean; + function isNull(arg) { + return arg === null; + } + exports.isNull = isNull; -// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics - inspect.colors = { - 'bold': [1, 22], - 'italic': [3, 23], - 'underline': [4, 24], - 'inverse': [7, 27], - 'white': [37, 39], - 'grey': [90, 39], - 'black': [30, 39], - 'blue': [34, 39], - 'cyan': [36, 39], - 'green': [32, 39], - 'magenta': [35, 39], - 'red': [31, 39], - 'yellow': [33, 39] - }; + function isNullOrUndefined(arg) { + return arg == null; + } + exports.isNullOrUndefined = isNullOrUndefined; -// Don't use 'blue' not visible on cmd.exe - inspect.styles = { - 'special': 'cyan', - 'number': 'yellow', - 'boolean': 'yellow', - 'undefined': 'grey', - 'null': 'bold', - 'string': 'green', - 'date': 'magenta', - // "name": intentionally not styling - 'regexp': 'red' - }; + function isNumber(arg) { + return typeof arg === 'number'; + } + exports.isNumber = isNumber; + function isString(arg) { + return typeof arg === 'string'; + } + exports.isString = isString; - function stylizeWithColor(str, styleType) { - var style = inspect.styles[styleType]; + function isSymbol(arg) { + return typeof arg === 'symbol'; + } + exports.isSymbol = isSymbol; - if (style) { - return '\u001b[' + inspect.colors[style][0] + 'm' + str + - '\u001b[' + inspect.colors[style][1] + 'm'; - } else { - return str; - } + function isUndefined(arg) { + return arg === void 0; } + exports.isUndefined = isUndefined; + function isRegExp(re) { + return objectToString(re) === '[object RegExp]'; + } + exports.isRegExp = isRegExp; - function stylizeNoColor(str, styleType) { - return str; + function isObject(arg) { + return typeof arg === 'object' && arg !== null; } + exports.isObject = isObject; + function isDate(d) { + return objectToString(d) === '[object Date]'; + } + exports.isDate = isDate; - function arrayToHash(array) { - var hash = {}; + function isError(e) { + return (objectToString(e) === '[object Error]' || e instanceof Error); + } + exports.isError = isError; - array.forEach(function (val, idx) { - hash[val] = true; - }); + function isFunction(arg) { + return typeof arg === 'function'; + } + exports.isFunction = isFunction; - return hash; + function isPrimitive(arg) { + return arg === null || + typeof arg === 'boolean' || + typeof arg === 'number' || + typeof arg === 'string' || + typeof arg === 'symbol' || // ES6 symbol + typeof arg === 'undefined'; } + exports.isPrimitive = isPrimitive; + exports.isBuffer = Buffer.isBuffer; - function formatValue(ctx, value, recurseTimes) { - // Provide a hook for user-specified inspect functions. - // Check that value is an object with an inspect function on it - if (ctx.customInspect && - value && - isFunction(value.inspect) && - // Filter out the util module, it's inspect function is special - value.inspect !== exports.inspect && - // Also filter out any prototype objects using the circular check. - !(value.constructor && value.constructor.prototype === value)) { - var ret = value.inspect(recurseTimes, ctx); - if (!isString(ret)) { - ret = formatValue(ctx, ret, recurseTimes); - } - return ret; - } + function objectToString(o) { + return Object.prototype.toString.call(o); + } - // Primitive types cannot have properties - var primitive = formatPrimitive(ctx, value); - if (primitive) { - return primitive; - } + /* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(0).Buffer)) - // Look up the keys of the object. - var keys = Object.keys(value); - var visibleKeys = arrayToHash(keys); + /***/ }), + /* 9 */ + /***/ (function(module, exports, __webpack_require__) { - if (ctx.showHidden) { - keys = Object.getOwnPropertyNames(value); - } + "use strict"; + /* WEBPACK VAR INJECTION */(function(process) { - // IE doesn't make error fields non-enumerable - // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx - if (isError(value) - && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) { - return formatError(value); - } + if (typeof process === 'undefined' || + !process.version || + process.version.indexOf('v0.') === 0 || + process.version.indexOf('v1.') === 0 && process.version.indexOf('v1.8.') !== 0) { + module.exports = { nextTick: nextTick }; + } else { + module.exports = process + } - // Some type of object without properties can be shortcutted. - if (keys.length === 0) { - if (isFunction(value)) { - var name = value.name ? ': ' + value.name : ''; - return ctx.stylize('[Function' + name + ']', 'special'); - } - if (isRegExp(value)) { - return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); - } - if (isDate(value)) { - return ctx.stylize(Date.prototype.toString.call(value), 'date'); - } - if (isError(value)) { - return formatError(value); - } + function nextTick(fn, arg1, arg2, arg3) { + if (typeof fn !== 'function') { + throw new TypeError('"callback" argument must be a function'); } - - var base = '', array = false, braces = ['{', '}']; - - // Make Array say that they are Array - if (isArray(value)) { - array = true; - braces = ['[', ']']; + var len = arguments.length; + var args, i; + switch (len) { + case 0: + case 1: + return process.nextTick(fn); + case 2: + return process.nextTick(function afterTickOne() { + fn.call(null, arg1); + }); + case 3: + return process.nextTick(function afterTickTwo() { + fn.call(null, arg1, arg2); + }); + case 4: + return process.nextTick(function afterTickThree() { + fn.call(null, arg1, arg2, arg3); + }); + default: + args = new Array(len - 1); + i = 0; + while (i < args.length) { + args[i++] = arguments[i]; + } + return process.nextTick(function afterTick() { + fn.apply(null, args); + }); } + } - // Make functions say that they are functions - if (isFunction(value)) { - var n = value.name ? ': ' + value.name : ''; - base = ' [Function' + n + ']'; - } - // Make RegExps say that they are RegExps - if (isRegExp(value)) { - base = ' ' + RegExp.prototype.toString.call(value); - } + /* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(1))) - // Make dates with properties first say the date - if (isDate(value)) { - base = ' ' + Date.prototype.toUTCString.call(value); - } + /***/ }), + /* 10 */ + /***/ (function(module, exports, __webpack_require__) { - // Make error with message first say the error - if (isError(value)) { - base = ' ' + formatError(value); - } + /* WEBPACK VAR INJECTION */(function(setImmediate, process, global, module) {(function (global, factory) { + true ? factory(exports) : + undefined; + }(this, (function (exports) { 'use strict'; - if (keys.length === 0 && (!array || value.length == 0)) { - return braces[0] + base + braces[1]; + function slice(arrayLike, start) { + start = start|0; + var newLen = Math.max(arrayLike.length - start, 0); + var newArr = Array(newLen); + for(var idx = 0; idx < newLen; idx++) { + newArr[idx] = arrayLike[start + idx]; } + return newArr; + } - if (recurseTimes < 0) { - if (isRegExp(value)) { - return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); - } else { - return ctx.stylize('[Object]', 'special'); - } - } + /** + * Creates a continuation function with some arguments already applied. + * + * Useful as a shorthand when combined with other control flow functions. Any + * arguments passed to the returned function are added to the arguments + * originally passed to apply. + * + * @name apply + * @static + * @memberOf module:Utils + * @method + * @category Util + * @param {Function} fn - The function you want to eventually apply all + * arguments to. Invokes with (arguments...). + * @param {...*} arguments... - Any number of arguments to automatically apply + * when the continuation is called. + * @returns {Function} the partially-applied function + * @example + * + * // using apply + * async.parallel([ + * async.apply(fs.writeFile, 'testfile1', 'test1'), + * async.apply(fs.writeFile, 'testfile2', 'test2') + * ]); + * + * + * // the same process without using apply + * async.parallel([ + * function(callback) { + * fs.writeFile('testfile1', 'test1', callback); + * }, + * function(callback) { + * fs.writeFile('testfile2', 'test2', callback); + * } + * ]); + * + * // It's possible to pass any number of additional arguments when calling the + * // continuation: + * + * node> var fn = async.apply(sys.puts, 'one'); + * node> fn('two', 'three'); + * one + * two + * three + */ + var apply = function(fn/*, ...args*/) { + var args = slice(arguments, 1); + return function(/*callArgs*/) { + var callArgs = slice(arguments); + return fn.apply(null, args.concat(callArgs)); + }; + }; - ctx.seen.push(value); + var initialParams = function (fn) { + return function (/*...args, callback*/) { + var args = slice(arguments); + var callback = args.pop(); + fn.call(this, args, callback); + }; + }; - var output; - if (array) { - output = formatArray(ctx, value, recurseTimes, visibleKeys, keys); - } else { - output = keys.map(function (key) { - return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array); - }); - } + /** + * Checks if `value` is the + * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) + * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(_.noop); + * // => true + * + * _.isObject(null); + * // => false + */ + function isObject(value) { + var type = typeof value; + return value != null && (type == 'object' || type == 'function'); + } - ctx.seen.pop(); + var hasSetImmediate = typeof setImmediate === 'function' && setImmediate; + var hasNextTick = typeof process === 'object' && typeof process.nextTick === 'function'; - return reduceToSingleString(output, base, braces); + function fallback(fn) { + setTimeout(fn, 0); } - - function formatPrimitive(ctx, value) { - if (isUndefined(value)) - return ctx.stylize('undefined', 'undefined'); - if (isString(value)) { - var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') - .replace(/'/g, "\\'") - .replace(/\\"/g, '"') + '\''; - return ctx.stylize(simple, 'string'); - } - if (isNumber(value)) - return ctx.stylize('' + value, 'number'); - if (isBoolean(value)) - return ctx.stylize('' + value, 'boolean'); - // For some reason typeof null is "object", so special case here. - if (isNull(value)) - return ctx.stylize('null', 'null'); + function wrap(defer) { + return function (fn/*, ...args*/) { + var args = slice(arguments, 1); + defer(function () { + fn.apply(null, args); + }); + }; } + var _defer; - function formatError(value) { - return '[' + Error.prototype.toString.call(value) + ']'; + if (hasSetImmediate) { + _defer = setImmediate; + } else if (hasNextTick) { + _defer = process.nextTick; + } else { + _defer = fallback; } + var setImmediate$1 = wrap(_defer); - function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { - var output = []; - for (var i = 0, l = value.length; i < l; ++i) { - if (hasOwnProperty(value, String(i))) { - output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, - String(i), true)); + /** + * Take a sync function and make it async, passing its return value to a + * callback. This is useful for plugging sync functions into a waterfall, + * series, or other async functions. Any arguments passed to the generated + * function will be passed to the wrapped function (except for the final + * callback argument). Errors thrown will be passed to the callback. + * + * If the function passed to `asyncify` returns a Promise, that promises's + * resolved/rejected state will be used to call the callback, rather than simply + * the synchronous return value. + * + * This also means you can asyncify ES2017 `async` functions. + * + * @name asyncify + * @static + * @memberOf module:Utils + * @method + * @alias wrapSync + * @category Util + * @param {Function} func - The synchronous function, or Promise-returning + * function to convert to an {@link AsyncFunction}. + * @returns {AsyncFunction} An asynchronous wrapper of the `func`. To be + * invoked with `(args..., callback)`. + * @example + * + * // passing a regular synchronous function + * async.waterfall([ + * async.apply(fs.readFile, filename, "utf8"), + * async.asyncify(JSON.parse), + * function (data, next) { + * // data is the result of parsing the text. + * // If there was a parsing error, it would have been caught. + * } + * ], callback); + * + * // passing a function returning a promise + * async.waterfall([ + * async.apply(fs.readFile, filename, "utf8"), + * async.asyncify(function (contents) { + * return db.model.create(contents); + * }), + * function (model, next) { + * // `model` is the instantiated model object. + * // If there was an error, this function would be skipped. + * } + * ], callback); + * + * // es2017 example, though `asyncify` is not needed if your JS environment + * // supports async functions out of the box + * var q = async.queue(async.asyncify(async function(file) { + * var intermediateStep = await processFile(file); + * return await somePromise(intermediateStep) + * })); + * + * q.push(files); + */ + function asyncify(func) { + return initialParams(function (args, callback) { + var result; + try { + result = func.apply(this, args); + } catch (e) { + return callback(e); + } + // if result is Promise object + if (isObject(result) && typeof result.then === 'function') { + result.then(function(value) { + invokeCallback(callback, null, value); + }, function(err) { + invokeCallback(callback, err.message ? err : new Error(err)); + }); } else { - output.push(''); - } - } - keys.forEach(function (key) { - if (!key.match(/^\d+$/)) { - output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, - key, true)); + callback(null, result); } }); - return output; } - - function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) { - var name, str, desc; - desc = Object.getOwnPropertyDescriptor(value, key) || {value: value[key]}; - if (desc.get) { - if (desc.set) { - str = ctx.stylize('[Getter/Setter]', 'special'); - } else { - str = ctx.stylize('[Getter]', 'special'); - } - } else { - if (desc.set) { - str = ctx.stylize('[Setter]', 'special'); - } - } - if (!hasOwnProperty(visibleKeys, key)) { - name = '[' + key + ']'; - } - if (!str) { - if (ctx.seen.indexOf(desc.value) < 0) { - if (isNull(recurseTimes)) { - str = formatValue(ctx, desc.value, null); - } else { - str = formatValue(ctx, desc.value, recurseTimes - 1); - } - if (str.indexOf('\n') > -1) { - if (array) { - str = str.split('\n').map(function (line) { - return ' ' + line; - }).join('\n').substr(2); - } else { - str = '\n' + str.split('\n').map(function (line) { - return ' ' + line; - }).join('\n'); - } - } - } else { - str = ctx.stylize('[Circular]', 'special'); - } - } - if (isUndefined(name)) { - if (array && key.match(/^\d+$/)) { - return str; - } - name = JSON.stringify('' + key); - if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { - name = name.substr(1, name.length - 2); - name = ctx.stylize(name, 'name'); - } else { - name = name.replace(/'/g, "\\'") - .replace(/\\"/g, '"') - .replace(/(^"|"$)/g, "'"); - name = ctx.stylize(name, 'string'); - } + function invokeCallback(callback, error, value) { + try { + callback(error, value); + } catch (e) { + setImmediate$1(rethrow, e); } - - return name + ': ' + str; } + function rethrow(error) { + throw error; + } - function reduceToSingleString(output, base, braces) { - var numLinesEst = 0; - var length = output.reduce(function (prev, cur) { - numLinesEst++; - if (cur.indexOf('\n') >= 0) numLinesEst++; - return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1; - }, 0); - - if (length > 60) { - return braces[0] + - (base === '' ? '' : base + '\n ') + - ' ' + - output.join(',\n ') + - ' ' + - braces[1]; - } + var supportsSymbol = typeof Symbol === 'function'; - return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; + function isAsync(fn) { + return supportsSymbol && fn[Symbol.toStringTag] === 'AsyncFunction'; } + function wrapAsync(asyncFn) { + return isAsync(asyncFn) ? asyncify(asyncFn) : asyncFn; + } -// NOTE: These type checking functions intentionally don't use `instanceof` -// because it is fragile and can be easily faked with `Object.create()`. - function isArray(ar) { - return Array.isArray(ar); + function applyEach$1(eachfn) { + return function(fns/*, ...args*/) { + var args = slice(arguments, 1); + var go = initialParams(function(args, callback) { + var that = this; + return eachfn(fns, function (fn, cb) { + wrapAsync(fn).apply(that, args.concat(cb)); + }, callback); + }); + if (args.length) { + return go.apply(this, args); + } + else { + return go; + } + }; } - exports.isArray = isArray; + /** Detect free variable `global` from Node.js. */ + var freeGlobal = typeof global == 'object' && global && global.Object === Object && global; - function isBoolean(arg) { - return typeof arg === 'boolean'; - } + /** Detect free variable `self`. */ + var freeSelf = typeof self == 'object' && self && self.Object === Object && self; - exports.isBoolean = isBoolean; + /** Used as a reference to the global object. */ + var root = freeGlobal || freeSelf || Function('return this')(); - function isNull(arg) { - return arg === null; - } + /** Built-in value references. */ + var Symbol$1 = root.Symbol; - exports.isNull = isNull; + /** Used for built-in method references. */ + var objectProto = Object.prototype; - function isNullOrUndefined(arg) { - return arg == null; - } + /** Used to check objects for own properties. */ + var hasOwnProperty = objectProto.hasOwnProperty; - exports.isNullOrUndefined = isNullOrUndefined; + /** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ + var nativeObjectToString = objectProto.toString; - function isNumber(arg) { - return typeof arg === 'number'; - } + /** Built-in value references. */ + var symToStringTag$1 = Symbol$1 ? Symbol$1.toStringTag : undefined; - exports.isNumber = isNumber; + /** + * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the raw `toStringTag`. + */ + function getRawTag(value) { + var isOwn = hasOwnProperty.call(value, symToStringTag$1), + tag = value[symToStringTag$1]; - function isString(arg) { - return typeof arg === 'string'; + try { + value[symToStringTag$1] = undefined; + var unmasked = true; + } catch (e) {} + + var result = nativeObjectToString.call(value); + if (unmasked) { + if (isOwn) { + value[symToStringTag$1] = tag; + } else { + delete value[symToStringTag$1]; + } + } + return result; } - exports.isString = isString; + /** Used for built-in method references. */ + var objectProto$1 = Object.prototype; - function isSymbol(arg) { - return typeof arg === 'symbol'; + /** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) + * of values. + */ + var nativeObjectToString$1 = objectProto$1.toString; + + /** + * Converts `value` to a string using `Object.prototype.toString`. + * + * @private + * @param {*} value The value to convert. + * @returns {string} Returns the converted string. + */ + function objectToString(value) { + return nativeObjectToString$1.call(value); } - exports.isSymbol = isSymbol; + /** `Object#toString` result references. */ + var nullTag = '[object Null]'; + var undefinedTag = '[object Undefined]'; - function isUndefined(arg) { - return arg === void 0; + /** Built-in value references. */ + var symToStringTag = Symbol$1 ? Symbol$1.toStringTag : undefined; + + /** + * The base implementation of `getTag` without fallbacks for buggy environments. + * + * @private + * @param {*} value The value to query. + * @returns {string} Returns the `toStringTag`. + */ + function baseGetTag(value) { + if (value == null) { + return value === undefined ? undefinedTag : nullTag; + } + return (symToStringTag && symToStringTag in Object(value)) + ? getRawTag(value) + : objectToString(value); } - exports.isUndefined = isUndefined; + /** `Object#toString` result references. */ + var asyncTag = '[object AsyncFunction]'; + var funcTag = '[object Function]'; + var genTag = '[object GeneratorFunction]'; + var proxyTag = '[object Proxy]'; - function isRegExp(re) { - return isObject(re) && objectToString(re) === '[object RegExp]'; + /** + * Checks if `value` is classified as a `Function` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a function, else `false`. + * @example + * + * _.isFunction(_); + * // => true + * + * _.isFunction(/abc/); + * // => false + */ + function isFunction(value) { + if (!isObject(value)) { + return false; + } + // The use of `Object#toString` avoids issues with the `typeof` operator + // in Safari 9 which returns 'object' for typed arrays and other constructors. + var tag = baseGetTag(value); + return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag; } - exports.isRegExp = isRegExp; + /** Used as references for various `Number` constants. */ + var MAX_SAFE_INTEGER = 9007199254740991; - function isObject(arg) { - return typeof arg === 'object' && arg !== null; + /** + * Checks if `value` is a valid array-like length. + * + * **Note:** This method is loosely based on + * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. + * @example + * + * _.isLength(3); + * // => true + * + * _.isLength(Number.MIN_VALUE); + * // => false + * + * _.isLength(Infinity); + * // => false + * + * _.isLength('3'); + * // => false + */ + function isLength(value) { + return typeof value == 'number' && + value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; } - exports.isObject = isObject; - - function isDate(d) { - return isObject(d) && objectToString(d) === '[object Date]'; + /** + * Checks if `value` is array-like. A value is considered array-like if it's + * not a function and has a `value.length` that's an integer greater than or + * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is array-like, else `false`. + * @example + * + * _.isArrayLike([1, 2, 3]); + * // => true + * + * _.isArrayLike(document.body.children); + * // => true + * + * _.isArrayLike('abc'); + * // => true + * + * _.isArrayLike(_.noop); + * // => false + */ + function isArrayLike(value) { + return value != null && isLength(value.length) && !isFunction(value); } - exports.isDate = isDate; +// A temporary value used to identify if the loop should be broken. +// See #1064, #1293 + var breakLoop = {}; - function isError(e) { - return isObject(e) && - (objectToString(e) === '[object Error]' || e instanceof Error); + /** + * This method returns `undefined`. + * + * @static + * @memberOf _ + * @since 2.3.0 + * @category Util + * @example + * + * _.times(2, _.noop); + * // => [undefined, undefined] + */ + function noop() { + // No operation performed. } - exports.isError = isError; - - function isFunction(arg) { - return typeof arg === 'function'; + function once(fn) { + return function () { + if (fn === null) return; + var callFn = fn; + fn = null; + callFn.apply(this, arguments); + }; } - exports.isFunction = isFunction; - - function isPrimitive(arg) { - return arg === null || - typeof arg === 'boolean' || - typeof arg === 'number' || - typeof arg === 'string' || - typeof arg === 'symbol' || // ES6 symbol - typeof arg === 'undefined'; - } + var iteratorSymbol = typeof Symbol === 'function' && Symbol.iterator; - exports.isPrimitive = isPrimitive; + var getIterator = function (coll) { + return iteratorSymbol && coll[iteratorSymbol] && coll[iteratorSymbol](); + }; - exports.isBuffer = __webpack_require__(56); + /** + * The base implementation of `_.times` without support for iteratee shorthands + * or max array length checks. + * + * @private + * @param {number} n The number of times to invoke `iteratee`. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the array of results. + */ + function baseTimes(n, iteratee) { + var index = -1, + result = Array(n); - function objectToString(o) { - return Object.prototype.toString.call(o); + while (++index < n) { + result[index] = iteratee(index); + } + return result; } - - function pad(n) { - return n < 10 ? '0' + n.toString(10) : n.toString(10); + /** + * Checks if `value` is object-like. A value is object-like if it's not `null` + * and has a `typeof` result of "object". + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @example + * + * _.isObjectLike({}); + * // => true + * + * _.isObjectLike([1, 2, 3]); + * // => true + * + * _.isObjectLike(_.noop); + * // => false + * + * _.isObjectLike(null); + * // => false + */ + function isObjectLike(value) { + return value != null && typeof value == 'object'; } + /** `Object#toString` result references. */ + var argsTag = '[object Arguments]'; - var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', - 'Oct', 'Nov', 'Dec']; - -// 26 Feb 16:19:34 - function timestamp() { - var d = new Date(); - var time = [pad(d.getHours()), - pad(d.getMinutes()), - pad(d.getSeconds())].join(':'); - return [d.getDate(), months[d.getMonth()], time].join(' '); + /** + * The base implementation of `_.isArguments`. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an `arguments` object, + */ + function baseIsArguments(value) { + return isObjectLike(value) && baseGetTag(value) == argsTag; } + /** Used for built-in method references. */ + var objectProto$3 = Object.prototype; -// log is just a thin wrapper to console.log that prepends a timestamp - exports.log = function () { - console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments)); - }; + /** Used to check objects for own properties. */ + var hasOwnProperty$2 = objectProto$3.hasOwnProperty; + /** Built-in value references. */ + var propertyIsEnumerable = objectProto$3.propertyIsEnumerable; /** - * Inherit the prototype methods from one constructor into another. + * Checks if `value` is likely an `arguments` object. * - * The Function.prototype.inherits from lang.js rewritten as a standalone - * function (not on Function.prototype). NOTE: If this file is to be loaded - * during bootstrapping this function needs to be rewritten using some native - * functions as prototype setup using normal JavaScript does not work as - * expected during bootstrapping (see mirror.js in r114903). + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an `arguments` object, + * else `false`. + * @example * - * @param {function} ctor Constructor function which needs to inherit the - * prototype. - * @param {function} superCtor Constructor function to inherit prototype from. + * _.isArguments(function() { return arguments; }()); + * // => true + * + * _.isArguments([1, 2, 3]); + * // => false */ - exports.inherits = __webpack_require__(3); - - exports._extend = function (origin, add) { - // Don't do anything if add isn't an object - if (!add || !isObject(add)) return origin; - - var keys = Object.keys(add); - var i = keys.length; - while (i--) { - origin[keys[i]] = add[keys[i]]; - } - return origin; + var isArguments = baseIsArguments(function() { return arguments; }()) ? baseIsArguments : function(value) { + return isObjectLike(value) && hasOwnProperty$2.call(value, 'callee') && + !propertyIsEnumerable.call(value, 'callee'); }; - function hasOwnProperty(obj, prop) { - return Object.prototype.hasOwnProperty.call(obj, prop); + /** + * Checks if `value` is classified as an `Array` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array, else `false`. + * @example + * + * _.isArray([1, 2, 3]); + * // => true + * + * _.isArray(document.body.children); + * // => false + * + * _.isArray('abc'); + * // => false + * + * _.isArray(_.noop); + * // => false + */ + var isArray = Array.isArray; + + /** + * This method returns `false`. + * + * @static + * @memberOf _ + * @since 4.13.0 + * @category Util + * @returns {boolean} Returns `false`. + * @example + * + * _.times(2, _.stubFalse); + * // => [false, false] + */ + function stubFalse() { + return false; } - var kCustomPromisifiedSymbol = typeof Symbol !== 'undefined' ? Symbol('util.promisify.custom') : undefined; + /** Detect free variable `exports`. */ + var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports; - exports.promisify = function promisify(original) { - if (typeof original !== 'function') - throw new TypeError('The "original" argument must be of type Function'); + /** Detect free variable `module`. */ + var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module; - if (kCustomPromisifiedSymbol && original[kCustomPromisifiedSymbol]) { - var fn = original[kCustomPromisifiedSymbol]; - if (typeof fn !== 'function') { - throw new TypeError('The "util.promisify.custom" argument must be of type Function'); - } - Object.defineProperty(fn, kCustomPromisifiedSymbol, { - value: fn, enumerable: false, writable: false, configurable: true - }); - return fn; - } + /** Detect the popular CommonJS extension `module.exports`. */ + var moduleExports = freeModule && freeModule.exports === freeExports; - function fn() { - var promiseResolve, promiseReject; - var promise = new Promise(function (resolve, reject) { - promiseResolve = resolve; - promiseReject = reject; - }); + /** Built-in value references. */ + var Buffer = moduleExports ? root.Buffer : undefined; - var args = []; - for (var i = 0; i < arguments.length; i++) { - args.push(arguments[i]); - } - args.push(function (err, value) { - if (err) { - promiseReject(err); - } else { - promiseResolve(value); - } - }); + /* Built-in method references for those with the same name as other `lodash` methods. */ + var nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined; - try { - original.apply(this, args); - } catch (err) { - promiseReject(err); - } + /** + * Checks if `value` is a buffer. + * + * @static + * @memberOf _ + * @since 4.3.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a buffer, else `false`. + * @example + * + * _.isBuffer(new Buffer(2)); + * // => true + * + * _.isBuffer(new Uint8Array(2)); + * // => false + */ + var isBuffer = nativeIsBuffer || stubFalse; - return promise; - } + /** Used as references for various `Number` constants. */ + var MAX_SAFE_INTEGER$1 = 9007199254740991; - Object.setPrototypeOf(fn, Object.getPrototypeOf(original)); + /** Used to detect unsigned integer values. */ + var reIsUint = /^(?:0|[1-9]\d*)$/; - if (kCustomPromisifiedSymbol) Object.defineProperty(fn, kCustomPromisifiedSymbol, { - value: fn, enumerable: false, writable: false, configurable: true - }); - return Object.defineProperties( - fn, - getOwnPropertyDescriptors(original) - ); - } + /** + * Checks if `value` is a valid array-like index. + * + * @private + * @param {*} value The value to check. + * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. + * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. + */ + function isIndex(value, length) { + var type = typeof value; + length = length == null ? MAX_SAFE_INTEGER$1 : length; + + return !!length && + (type == 'number' || + (type != 'symbol' && reIsUint.test(value))) && + (value > -1 && value % 1 == 0 && value < length); + } + + /** `Object#toString` result references. */ + var argsTag$1 = '[object Arguments]'; + var arrayTag = '[object Array]'; + var boolTag = '[object Boolean]'; + var dateTag = '[object Date]'; + var errorTag = '[object Error]'; + var funcTag$1 = '[object Function]'; + var mapTag = '[object Map]'; + var numberTag = '[object Number]'; + var objectTag = '[object Object]'; + var regexpTag = '[object RegExp]'; + var setTag = '[object Set]'; + var stringTag = '[object String]'; + var weakMapTag = '[object WeakMap]'; + + var arrayBufferTag = '[object ArrayBuffer]'; + var dataViewTag = '[object DataView]'; + var float32Tag = '[object Float32Array]'; + var float64Tag = '[object Float64Array]'; + var int8Tag = '[object Int8Array]'; + var int16Tag = '[object Int16Array]'; + var int32Tag = '[object Int32Array]'; + var uint8Tag = '[object Uint8Array]'; + var uint8ClampedTag = '[object Uint8ClampedArray]'; + var uint16Tag = '[object Uint16Array]'; + var uint32Tag = '[object Uint32Array]'; + + /** Used to identify `toStringTag` values of typed arrays. */ + var typedArrayTags = {}; + typedArrayTags[float32Tag] = typedArrayTags[float64Tag] = + typedArrayTags[int8Tag] = typedArrayTags[int16Tag] = + typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] = + typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] = + typedArrayTags[uint32Tag] = true; + typedArrayTags[argsTag$1] = typedArrayTags[arrayTag] = + typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] = + typedArrayTags[dataViewTag] = typedArrayTags[dateTag] = + typedArrayTags[errorTag] = typedArrayTags[funcTag$1] = + typedArrayTags[mapTag] = typedArrayTags[numberTag] = + typedArrayTags[objectTag] = typedArrayTags[regexpTag] = + typedArrayTags[setTag] = typedArrayTags[stringTag] = + typedArrayTags[weakMapTag] = false; - exports.promisify.custom = kCustomPromisifiedSymbol + /** + * The base implementation of `_.isTypedArray` without Node.js optimizations. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a typed array, else `false`. + */ + function baseIsTypedArray(value) { + return isObjectLike(value) && + isLength(value.length) && !!typedArrayTags[baseGetTag(value)]; + } - function callbackifyOnRejected(reason, cb) { - // `!reason` guard inspired by bluebird (Ref: https://goo.gl/t5IS6M). - // Because `null` is a special error value in callbacks which means "no error - // occurred", we error-wrap so the callback consumer can distinguish between - // "the promise rejected with null" or "the promise fulfilled with undefined". - if (!reason) { - var newReason = new Error('Promise was rejected with a falsy value'); - newReason.reason = reason; - reason = newReason; - } - return cb(reason); + /** + * The base implementation of `_.unary` without support for storing metadata. + * + * @private + * @param {Function} func The function to cap arguments for. + * @returns {Function} Returns the new capped function. + */ + function baseUnary(func) { + return function(value) { + return func(value); + }; } - function callbackify(original) { - if (typeof original !== 'function') { - throw new TypeError('The "original" argument must be of type Function'); - } + /** Detect free variable `exports`. */ + var freeExports$1 = typeof exports == 'object' && exports && !exports.nodeType && exports; - // We DO NOT return the promise as it gives the user a false sense that - // the promise is actually somehow related to the callback's execution - // and that the callback throwing will reject the promise. - function callbackified() { - var args = []; - for (var i = 0; i < arguments.length; i++) { - args.push(arguments[i]); - } + /** Detect free variable `module`. */ + var freeModule$1 = freeExports$1 && typeof module == 'object' && module && !module.nodeType && module; - var maybeCb = args.pop(); - if (typeof maybeCb !== 'function') { - throw new TypeError('The last argument must be of type Function'); - } - var self = this; - var cb = function () { - return maybeCb.apply(self, arguments); - }; - // In true node style we process the callback on `nextTick` with all the - // implications (stack, `uncaughtException`, `async_hooks`) - original.apply(this, args) - .then(function (ret) { - process.nextTick(cb, null, ret) - }, - function (rej) { - process.nextTick(callbackifyOnRejected, rej, cb) - }); - } + /** Detect the popular CommonJS extension `module.exports`. */ + var moduleExports$1 = freeModule$1 && freeModule$1.exports === freeExports$1; - Object.setPrototypeOf(callbackified, Object.getPrototypeOf(original)); - Object.defineProperties(callbackified, - getOwnPropertyDescriptors(original)); - return callbackified; - } + /** Detect free variable `process` from Node.js. */ + var freeProcess = moduleExports$1 && freeGlobal.process; - exports.callbackify = callbackify; + /** Used to access faster Node.js helpers. */ + var nodeUtil = (function() { + try { + // Use `util.types` for Node.js 10+. + var types = freeModule$1 && freeModule$1.require && freeModule$1.require('util').types; - /* WEBPACK VAR INJECTION */ - }.call(this, __webpack_require__(1))) + if (types) { + return types; + } - /***/ - }), - /* 9 */ - /***/ (function (module, exports, __webpack_require__) { + // Legacy `process.binding('util')` for Node.js < 10. + return freeProcess && freeProcess.binding && freeProcess.binding('util'); + } catch (e) {} + }()); - /* WEBPACK VAR INJECTION */ - (function (Buffer) {// Copyright Joyent, Inc. and other Node contributors. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to permit -// persons to whom the Software is furnished to do so, subject to the -// following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN -// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR -// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE -// USE OR OTHER DEALINGS IN THE SOFTWARE. + /* Node.js helper references. */ + var nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray; -// NOTE: These type checking functions intentionally don't use `instanceof` -// because it is fragile and can be easily faked with `Object.create()`. + /** + * Checks if `value` is classified as a typed array. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a typed array, else `false`. + * @example + * + * _.isTypedArray(new Uint8Array); + * // => true + * + * _.isTypedArray([]); + * // => false + */ + var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray; + + /** Used for built-in method references. */ + var objectProto$2 = Object.prototype; - function isArray(arg) { - if (Array.isArray) { - return Array.isArray(arg); + /** Used to check objects for own properties. */ + var hasOwnProperty$1 = objectProto$2.hasOwnProperty; + + /** + * Creates an array of the enumerable property names of the array-like `value`. + * + * @private + * @param {*} value The value to query. + * @param {boolean} inherited Specify returning inherited property names. + * @returns {Array} Returns the array of property names. + */ + function arrayLikeKeys(value, inherited) { + var isArr = isArray(value), + isArg = !isArr && isArguments(value), + isBuff = !isArr && !isArg && isBuffer(value), + isType = !isArr && !isArg && !isBuff && isTypedArray(value), + skipIndexes = isArr || isArg || isBuff || isType, + result = skipIndexes ? baseTimes(value.length, String) : [], + length = result.length; + + for (var key in value) { + if ((inherited || hasOwnProperty$1.call(value, key)) && + !(skipIndexes && ( + // Safari 9 has enumerable `arguments.length` in strict mode. + key == 'length' || + // Node.js 0.10 has enumerable non-index properties on buffers. + (isBuff && (key == 'offset' || key == 'parent')) || + // PhantomJS 2 has enumerable non-index properties on typed arrays. + (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) || + // Skip index properties. + isIndex(key, length) + ))) { + result.push(key); + } } - return objectToString(arg) === '[object Array]'; + return result; } - exports.isArray = isArray; + /** Used for built-in method references. */ + var objectProto$5 = Object.prototype; - function isBoolean(arg) { - return typeof arg === 'boolean'; - } + /** + * Checks if `value` is likely a prototype object. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a prototype, else `false`. + */ + function isPrototype(value) { + var Ctor = value && value.constructor, + proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto$5; - exports.isBoolean = isBoolean; + return value === proto; + } - function isNull(arg) { - return arg === null; + /** + * Creates a unary function that invokes `func` with its argument transformed. + * + * @private + * @param {Function} func The function to wrap. + * @param {Function} transform The argument transform. + * @returns {Function} Returns the new function. + */ + function overArg(func, transform) { + return function(arg) { + return func(transform(arg)); + }; } - exports.isNull = isNull; + /* Built-in method references for those with the same name as other `lodash` methods. */ + var nativeKeys = overArg(Object.keys, Object); - function isNullOrUndefined(arg) { - return arg == null; - } + /** Used for built-in method references. */ + var objectProto$4 = Object.prototype; - exports.isNullOrUndefined = isNullOrUndefined; + /** Used to check objects for own properties. */ + var hasOwnProperty$3 = objectProto$4.hasOwnProperty; - function isNumber(arg) { - return typeof arg === 'number'; + /** + * The base implementation of `_.keys` which doesn't treat sparse arrays as dense. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ + function baseKeys(object) { + if (!isPrototype(object)) { + return nativeKeys(object); + } + var result = []; + for (var key in Object(object)) { + if (hasOwnProperty$3.call(object, key) && key != 'constructor') { + result.push(key); + } + } + return result; } - exports.isNumber = isNumber; + /** + * Creates an array of the own enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. See the + * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) + * for more details. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keys(new Foo); + * // => ['a', 'b'] (iteration order is not guaranteed) + * + * _.keys('hi'); + * // => ['0', '1'] + */ + function keys(object) { + return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object); + } - function isString(arg) { - return typeof arg === 'string'; + function createArrayIterator(coll) { + var i = -1; + var len = coll.length; + return function next() { + return ++i < len ? {value: coll[i], key: i} : null; + } } - exports.isString = isString; + function createES2015Iterator(iterator) { + var i = -1; + return function next() { + var item = iterator.next(); + if (item.done) + return null; + i++; + return {value: item.value, key: i}; + } + } - function isSymbol(arg) { - return typeof arg === 'symbol'; + function createObjectIterator(obj) { + var okeys = keys(obj); + var i = -1; + var len = okeys.length; + return function next() { + var key = okeys[++i]; + return i < len ? {value: obj[key], key: key} : null; + }; } - exports.isSymbol = isSymbol; + function iterator(coll) { + if (isArrayLike(coll)) { + return createArrayIterator(coll); + } - function isUndefined(arg) { - return arg === void 0; + var iterator = getIterator(coll); + return iterator ? createES2015Iterator(iterator) : createObjectIterator(coll); } - exports.isUndefined = isUndefined; - - function isRegExp(re) { - return objectToString(re) === '[object RegExp]'; + function onlyOnce(fn) { + return function() { + if (fn === null) throw new Error("Callback was already called."); + var callFn = fn; + fn = null; + callFn.apply(this, arguments); + }; } - exports.isRegExp = isRegExp; + function _eachOfLimit(limit) { + return function (obj, iteratee, callback) { + callback = once(callback || noop); + if (limit <= 0 || !obj) { + return callback(null); + } + var nextElem = iterator(obj); + var done = false; + var running = 0; + var looping = false; - function isObject(arg) { - return typeof arg === 'object' && arg !== null; + function iterateeCallback(err, value) { + running -= 1; + if (err) { + done = true; + callback(err); + } + else if (value === breakLoop || (done && running <= 0)) { + done = true; + return callback(null); + } + else if (!looping) { + replenish(); + } + } + + function replenish () { + looping = true; + while (running < limit && !done) { + var elem = nextElem(); + if (elem === null) { + done = true; + if (running <= 0) { + callback(null); + } + return; + } + running += 1; + iteratee(elem.value, elem.key, onlyOnce(iterateeCallback)); + } + looping = false; + } + + replenish(); + }; } - exports.isObject = isObject; + /** + * The same as [`eachOf`]{@link module:Collections.eachOf} but runs a maximum of `limit` async operations at a + * time. + * + * @name eachOfLimit + * @static + * @memberOf module:Collections + * @method + * @see [async.eachOf]{@link module:Collections.eachOf} + * @alias forEachOfLimit + * @category Collection + * @param {Array|Iterable|Object} coll - A collection to iterate over. + * @param {number} limit - The maximum number of async operations at a time. + * @param {AsyncFunction} iteratee - An async function to apply to each + * item in `coll`. The `key` is the item's key, or index in the case of an + * array. + * Invoked with (item, key, callback). + * @param {Function} [callback] - A callback which is called when all + * `iteratee` functions have finished, or an error occurs. Invoked with (err). + */ + function eachOfLimit(coll, limit, iteratee, callback) { + _eachOfLimit(limit)(coll, wrapAsync(iteratee), callback); + } - function isDate(d) { - return objectToString(d) === '[object Date]'; + function doLimit(fn, limit) { + return function (iterable, iteratee, callback) { + return fn(iterable, limit, iteratee, callback); + }; } - exports.isDate = isDate; +// eachOf implementation optimized for array-likes + function eachOfArrayLike(coll, iteratee, callback) { + callback = once(callback || noop); + var index = 0, + completed = 0, + length = coll.length; + if (length === 0) { + callback(null); + } - function isError(e) { - return (objectToString(e) === '[object Error]' || e instanceof Error); + function iteratorCallback(err, value) { + if (err) { + callback(err); + } else if ((++completed === length) || value === breakLoop) { + callback(null); + } + } + + for (; index < length; index++) { + iteratee(coll[index], index, onlyOnce(iteratorCallback)); + } } - exports.isError = isError; +// a generic version of eachOf which can handle array, object, and iterator cases. + var eachOfGeneric = doLimit(eachOfLimit, Infinity); - function isFunction(arg) { - return typeof arg === 'function'; + /** + * Like [`each`]{@link module:Collections.each}, except that it passes the key (or index) as the second argument + * to the iteratee. + * + * @name eachOf + * @static + * @memberOf module:Collections + * @method + * @alias forEachOf + * @category Collection + * @see [async.each]{@link module:Collections.each} + * @param {Array|Iterable|Object} coll - A collection to iterate over. + * @param {AsyncFunction} iteratee - A function to apply to each + * item in `coll`. + * The `key` is the item's key, or index in the case of an array. + * Invoked with (item, key, callback). + * @param {Function} [callback] - A callback which is called when all + * `iteratee` functions have finished, or an error occurs. Invoked with (err). + * @example + * + * var obj = {dev: "/dev.json", test: "/test.json", prod: "/prod.json"}; + * var configs = {}; + * + * async.forEachOf(obj, function (value, key, callback) { + * fs.readFile(__dirname + value, "utf8", function (err, data) { + * if (err) return callback(err); + * try { + * configs[key] = JSON.parse(data); + * } catch (e) { + * return callback(e); + * } + * callback(); + * }); + * }, function (err) { + * if (err) console.error(err.message); + * // configs is now a map of JSON data + * doSomethingWith(configs); + * }); + */ + var eachOf = function(coll, iteratee, callback) { + var eachOfImplementation = isArrayLike(coll) ? eachOfArrayLike : eachOfGeneric; + eachOfImplementation(coll, wrapAsync(iteratee), callback); + }; + + function doParallel(fn) { + return function (obj, iteratee, callback) { + return fn(eachOf, obj, wrapAsync(iteratee), callback); + }; } - exports.isFunction = isFunction; + function _asyncMap(eachfn, arr, iteratee, callback) { + callback = callback || noop; + arr = arr || []; + var results = []; + var counter = 0; + var _iteratee = wrapAsync(iteratee); - function isPrimitive(arg) { - return arg === null || - typeof arg === 'boolean' || - typeof arg === 'number' || - typeof arg === 'string' || - typeof arg === 'symbol' || // ES6 symbol - typeof arg === 'undefined'; + eachfn(arr, function (value, _, callback) { + var index = counter++; + _iteratee(value, function (err, v) { + results[index] = v; + callback(err); + }); + }, function (err) { + callback(err, results); + }); } - exports.isPrimitive = isPrimitive; + /** + * Produces a new collection of values by mapping each value in `coll` through + * the `iteratee` function. The `iteratee` is called with an item from `coll` + * and a callback for when it has finished processing. Each of these callback + * takes 2 arguments: an `error`, and the transformed item from `coll`. If + * `iteratee` passes an error to its callback, the main `callback` (for the + * `map` function) is immediately called with the error. + * + * Note, that since this function applies the `iteratee` to each item in + * parallel, there is no guarantee that the `iteratee` functions will complete + * in order. However, the results array will be in the same order as the + * original `coll`. + * + * If `map` is passed an Object, the results will be an Array. The results + * will roughly be in the order of the original Objects' keys (but this can + * vary across JavaScript engines). + * + * @name map + * @static + * @memberOf module:Collections + * @method + * @category Collection + * @param {Array|Iterable|Object} coll - A collection to iterate over. + * @param {AsyncFunction} iteratee - An async function to apply to each item in + * `coll`. + * The iteratee should complete with the transformed item. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called when all `iteratee` + * functions have finished, or an error occurs. Results is an Array of the + * transformed items from the `coll`. Invoked with (err, results). + * @example + * + * async.map(['file1','file2','file3'], fs.stat, function(err, results) { + * // results is now an array of stats for each file + * }); + */ + var map = doParallel(_asyncMap); - exports.isBuffer = Buffer.isBuffer; + /** + * Applies the provided arguments to each function in the array, calling + * `callback` after all functions have completed. If you only provide the first + * argument, `fns`, then it will return a function which lets you pass in the + * arguments as if it were a single function call. If more arguments are + * provided, `callback` is required while `args` is still optional. + * + * @name applyEach + * @static + * @memberOf module:ControlFlow + * @method + * @category Control Flow + * @param {Array|Iterable|Object} fns - A collection of {@link AsyncFunction}s + * to all call with the same arguments + * @param {...*} [args] - any number of separate arguments to pass to the + * function. + * @param {Function} [callback] - the final argument should be the callback, + * called when all functions have completed processing. + * @returns {Function} - If only the first argument, `fns`, is provided, it will + * return a function which lets you pass in the arguments as if it were a single + * function call. The signature is `(..args, callback)`. If invoked with any + * arguments, `callback` is required. + * @example + * + * async.applyEach([enableSearch, updateSchema], 'bucket', callback); + * + * // partial application example: + * async.each( + * buckets, + * async.applyEach([enableSearch, updateSchema]), + * callback + * ); + */ + var applyEach = applyEach$1(map); - function objectToString(o) { - return Object.prototype.toString.call(o); + function doParallelLimit(fn) { + return function (obj, limit, iteratee, callback) { + return fn(_eachOfLimit(limit), obj, wrapAsync(iteratee), callback); + }; } - /* WEBPACK VAR INJECTION */ - }.call(this, __webpack_require__(0).Buffer)) - - /***/ - }), - /* 10 */ - /***/ (function (module, exports, __webpack_require__) { + /** + * The same as [`map`]{@link module:Collections.map} but runs a maximum of `limit` async operations at a time. + * + * @name mapLimit + * @static + * @memberOf module:Collections + * @method + * @see [async.map]{@link module:Collections.map} + * @category Collection + * @param {Array|Iterable|Object} coll - A collection to iterate over. + * @param {number} limit - The maximum number of async operations at a time. + * @param {AsyncFunction} iteratee - An async function to apply to each item in + * `coll`. + * The iteratee should complete with the transformed item. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called when all `iteratee` + * functions have finished, or an error occurs. Results is an array of the + * transformed items from the `coll`. Invoked with (err, results). + */ + var mapLimit = doParallelLimit(_asyncMap); - /* WEBPACK VAR INJECTION */ - (function (Buffer) { - var fs = __webpack_require__(21); - var intelhex = __webpack_require__(22); + /** + * The same as [`map`]{@link module:Collections.map} but runs only a single async operation at a time. + * + * @name mapSeries + * @static + * @memberOf module:Collections + * @method + * @see [async.map]{@link module:Collections.map} + * @category Collection + * @param {Array|Iterable|Object} coll - A collection to iterate over. + * @param {AsyncFunction} iteratee - An async function to apply to each item in + * `coll`. + * The iteratee should complete with the transformed item. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called when all `iteratee` + * functions have finished, or an error occurs. Results is an array of the + * transformed items from the `coll`. Invoked with (err, results). + */ + var mapSeries = doLimit(mapLimit, 1); - var tools = {}; + /** + * The same as [`applyEach`]{@link module:ControlFlow.applyEach} but runs only a single async operation at a time. + * + * @name applyEachSeries + * @static + * @memberOf module:ControlFlow + * @method + * @see [async.applyEach]{@link module:ControlFlow.applyEach} + * @category Control Flow + * @param {Array|Iterable|Object} fns - A collection of {@link AsyncFunction}s to all + * call with the same arguments + * @param {...*} [args] - any number of separate arguments to pass to the + * function. + * @param {Function} [callback] - the final argument should be the callback, + * called when all functions have completed processing. + * @returns {Function} - If only the first argument is provided, it will return + * a function which lets you pass in the arguments as if it were a single + * function call. + */ + var applyEachSeries = applyEach$1(mapSeries); /** - * Opens and parses a given hex file - * (STEM+C) edited to take in raw hex instead of a file + * A specialized version of `_.forEach` for arrays without support for + * iteratee shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns `array`. */ - tools._parseHex = function (file) { - try { - return intelhex.parse(file).data; - } catch (error) { - return error; + function arrayEach(array, iteratee) { + var index = -1, + length = array == null ? 0 : array.length; + + while (++index < length) { + if (iteratee(array[index], index, array) === false) { + break; + } } - }; + return array; + } + + /** + * Creates a base function for methods like `_.forIn` and `_.forOwn`. + * + * @private + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Function} Returns the new base function. + */ + function createBaseFor(fromRight) { + return function(object, iteratee, keysFunc) { + var index = -1, + iterable = Object(object), + props = keysFunc(object), + length = props.length; - tools._hexStringToByte = function (str) { - return Buffer.from([parseInt(str, 16)]); + while (length--) { + var key = props[fromRight ? length : ++index]; + if (iteratee(iterable[key], key, iterable) === false) { + break; + } + } + return object; + }; } - module.exports = tools; + /** + * The base implementation of `baseForOwn` which iterates over `object` + * properties returned by `keysFunc` and invokes `iteratee` for each property. + * Iteratee functions may exit iteration early by explicitly returning `false`. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @param {Function} keysFunc The function to get the keys of `object`. + * @returns {Object} Returns `object`. + */ + var baseFor = createBaseFor(); - /* WEBPACK VAR INJECTION */ - }.call(this, __webpack_require__(0).Buffer)) + /** + * The base implementation of `_.forOwn` without support for iteratee shorthands. + * + * @private + * @param {Object} object The object to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Object} Returns `object`. + */ + function baseForOwn(object, iteratee) { + return object && baseFor(object, iteratee, keys); + } - /***/ - }), - /* 11 */ - /***/ (function (module, exports, __webpack_require__) { + /** + * The base implementation of `_.findIndex` and `_.findLastIndex` without + * support for iteratee shorthands. + * + * @private + * @param {Array} array The array to inspect. + * @param {Function} predicate The function invoked per iteration. + * @param {number} fromIndex The index to search from. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function baseFindIndex(array, predicate, fromIndex, fromRight) { + var length = array.length, + index = fromIndex + (fromRight ? 1 : -1); - "use strict"; - /* WEBPACK VAR INJECTION */ - (function (process) { + while ((fromRight ? index-- : ++index < length)) { + if (predicate(array[index], index, array)) { + return index; + } + } + return -1; + } - if (!process.version || - process.version.indexOf('v0.') === 0 || - process.version.indexOf('v1.') === 0 && process.version.indexOf('v1.8.') !== 0) { - module.exports = {nextTick: nextTick}; - } else { - module.exports = process + /** + * The base implementation of `_.isNaN` without support for number objects. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. + */ + function baseIsNaN(value) { + return value !== value; } - function nextTick(fn, arg1, arg2, arg3) { - if (typeof fn !== 'function') { - throw new TypeError('"callback" argument must be a function'); - } - var len = arguments.length; - var args, i; - switch (len) { - case 0: - case 1: - return process.nextTick(fn); - case 2: - return process.nextTick(function afterTickOne() { - fn.call(null, arg1); - }); - case 3: - return process.nextTick(function afterTickTwo() { - fn.call(null, arg1, arg2); - }); - case 4: - return process.nextTick(function afterTickThree() { - fn.call(null, arg1, arg2, arg3); - }); - default: - args = new Array(len - 1); - i = 0; - while (i < args.length) { - args[i++] = arguments[i]; - } - return process.nextTick(function afterTick() { - fn.apply(null, args); - }); + /** + * A specialized version of `_.indexOf` which performs strict equality + * comparisons of values, i.e. `===`. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function strictIndexOf(array, value, fromIndex) { + var index = fromIndex - 1, + length = array.length; + + while (++index < length) { + if (array[index] === value) { + return index; + } } + return -1; } + /** + * The base implementation of `_.indexOf` without `fromIndex` bounds checks. + * + * @private + * @param {Array} array The array to inspect. + * @param {*} value The value to search for. + * @param {number} fromIndex The index to search from. + * @returns {number} Returns the index of the matched value, else `-1`. + */ + function baseIndexOf(array, value, fromIndex) { + return value === value + ? strictIndexOf(array, value, fromIndex) + : baseFindIndex(array, baseIsNaN, fromIndex); + } + + /** + * Determines the best order for running the {@link AsyncFunction}s in `tasks`, based on + * their requirements. Each function can optionally depend on other functions + * being completed first, and each function is run as soon as its requirements + * are satisfied. + * + * If any of the {@link AsyncFunction}s pass an error to their callback, the `auto` sequence + * will stop. Further tasks will not execute (so any other functions depending + * on it will not run), and the main `callback` is immediately called with the + * error. + * + * {@link AsyncFunction}s also receive an object containing the results of functions which + * have completed so far as the first argument, if they have dependencies. If a + * task function has no dependencies, it will only be passed a callback. + * + * @name auto + * @static + * @memberOf module:ControlFlow + * @method + * @category Control Flow + * @param {Object} tasks - An object. Each of its properties is either a + * function or an array of requirements, with the {@link AsyncFunction} itself the last item + * in the array. The object's key of a property serves as the name of the task + * defined by that property, i.e. can be used when specifying requirements for + * other tasks. The function receives one or two arguments: + * * a `results` object, containing the results of the previously executed + * functions, only passed if the task has any dependencies, + * * a `callback(err, result)` function, which must be called when finished, + * passing an `error` (which can be `null`) and the result of the function's + * execution. + * @param {number} [concurrency=Infinity] - An optional `integer` for + * determining the maximum number of tasks that can be run in parallel. By + * default, as many as possible. + * @param {Function} [callback] - An optional callback which is called when all + * the tasks have been completed. It receives the `err` argument if any `tasks` + * pass an error to their callback. Results are always returned; however, if an + * error occurs, no further `tasks` will be performed, and the results object + * will only contain partial results. Invoked with (err, results). + * @returns undefined + * @example + * + * async.auto({ + * // this function will just be passed a callback + * readData: async.apply(fs.readFile, 'data.txt', 'utf-8'), + * showData: ['readData', function(results, cb) { + * // results.readData is the file's contents + * // ... + * }] + * }, callback); + * + * async.auto({ + * get_data: function(callback) { + * console.log('in get_data'); + * // async code to get some data + * callback(null, 'data', 'converted to array'); + * }, + * make_folder: function(callback) { + * console.log('in make_folder'); + * // async code to create a directory to store a file in + * // this is run at the same time as getting the data + * callback(null, 'folder'); + * }, + * write_file: ['get_data', 'make_folder', function(results, callback) { + * console.log('in write_file', JSON.stringify(results)); + * // once there is some data and the directory exists, + * // write the data to a file in the directory + * callback(null, 'filename'); + * }], + * email_link: ['write_file', function(results, callback) { + * console.log('in email_link', JSON.stringify(results)); + * // once the file is written let's email a link to it... + * // results.write_file contains the filename returned by write_file. + * callback(null, {'file':results.write_file, 'email':'user@example.com'}); + * }] + * }, function(err, results) { + * console.log('err = ', err); + * console.log('results = ', results); + * }); + */ + var auto = function (tasks, concurrency, callback) { + if (typeof concurrency === 'function') { + // concurrency is optional, shift the args. + callback = concurrency; + concurrency = null; + } + callback = once(callback || noop); + var keys$$1 = keys(tasks); + var numTasks = keys$$1.length; + if (!numTasks) { + return callback(null); + } + if (!concurrency) { + concurrency = numTasks; + } - /* WEBPACK VAR INJECTION */ - }.call(this, __webpack_require__(1))) + var results = {}; + var runningTasks = 0; + var hasError = false; - /***/ - }), - /* 12 */ - /***/ (function (module, exports, __webpack_require__) { + var listeners = Object.create(null); - /* eslint-disable node/no-deprecated-api */ - var buffer = __webpack_require__(0) - var Buffer = buffer.Buffer + var readyTasks = []; -// alternative to using Object.keys for old browsers - function copyProps(src, dst) { - for (var key in src) { - dst[key] = src[key] - } - } + // for cycle detection: + var readyToCheck = []; // tasks that have been identified as reachable + // without the possibility of returning to an ancestor task + var uncheckedDependencies = {}; - if (Buffer.from && Buffer.alloc && Buffer.allocUnsafe && Buffer.allocUnsafeSlow) { - module.exports = buffer - } else { - // Copy properties from require('buffer') - copyProps(buffer, exports) - exports.Buffer = SafeBuffer - } + baseForOwn(tasks, function (task, key) { + if (!isArray(task)) { + // no dependencies + enqueueTask(key, [task]); + readyToCheck.push(key); + return; + } - function SafeBuffer(arg, encodingOrOffset, length) { - return Buffer(arg, encodingOrOffset, length) - } + var dependencies = task.slice(0, task.length - 1); + var remainingDependencies = dependencies.length; + if (remainingDependencies === 0) { + enqueueTask(key, task); + readyToCheck.push(key); + return; + } + uncheckedDependencies[key] = remainingDependencies; -// Copy static methods from Buffer - copyProps(Buffer, SafeBuffer) + arrayEach(dependencies, function (dependencyName) { + if (!tasks[dependencyName]) { + throw new Error('async.auto task `' + key + + '` has a non-existent dependency `' + + dependencyName + '` in ' + + dependencies.join(', ')); + } + addListener(dependencyName, function () { + remainingDependencies--; + if (remainingDependencies === 0) { + enqueueTask(key, task); + } + }); + }); + }); - SafeBuffer.from = function (arg, encodingOrOffset, length) { - if (typeof arg === 'number') { - throw new TypeError('Argument must not be a number') - } - return Buffer(arg, encodingOrOffset, length) - } + checkForDeadlocks(); + processQueue(); - SafeBuffer.alloc = function (size, fill, encoding) { - if (typeof size !== 'number') { - throw new TypeError('Argument must be a number') - } - var buf = Buffer(size) - if (fill !== undefined) { - if (typeof encoding === 'string') { - buf.fill(fill, encoding) - } else { - buf.fill(fill) + function enqueueTask(key, task) { + readyTasks.push(function () { + runTask(key, task); + }); } - } else { - buf.fill(0) - } - return buf - } - - SafeBuffer.allocUnsafe = function (size) { - if (typeof size !== 'number') { - throw new TypeError('Argument must be a number') - } - return Buffer(size) - } - SafeBuffer.allocUnsafeSlow = function (size) { - if (typeof size !== 'number') { - throw new TypeError('Argument must be a number') - } - return buffer.SlowBuffer(size) - } + function processQueue() { + if (readyTasks.length === 0 && runningTasks === 0) { + return callback(null, results); + } + while(readyTasks.length && runningTasks < concurrency) { + var run = readyTasks.shift(); + run(); + } + } - /***/ - }), - /* 13 */ - /***/ (function (module, exports, __webpack_require__) { - - /* WEBPACK VAR INJECTION */ - (function (setImmediate, process, global, module) { - (function (global, factory) { - true ? factory(exports) : - undefined; - }(this, (function (exports) { - 'use strict'; - - function slice(arrayLike, start) { - start = start | 0; - var newLen = Math.max(arrayLike.length - start, 0); - var newArr = Array(newLen); - for (var idx = 0; idx < newLen; idx++) { - newArr[idx] = arrayLike[start + idx]; - } - return newArr; - } - - /** - * Creates a continuation function with some arguments already applied. - * - * Useful as a shorthand when combined with other control flow functions. Any - * arguments passed to the returned function are added to the arguments - * originally passed to apply. - * - * @name apply - * @static - * @memberOf module:Utils - * @method - * @category Util - * @param {Function} fn - The function you want to eventually apply all - * arguments to. Invokes with (arguments...). - * @param {...*} arguments... - Any number of arguments to automatically apply - * when the continuation is called. - * @returns {Function} the partially-applied function - * @example - * - * // using apply - * async.parallel([ - * async.apply(fs.writeFile, 'testfile1', 'test1'), - * async.apply(fs.writeFile, 'testfile2', 'test2') - * ]); - * - * - * // the same process without using apply - * async.parallel([ - * function(callback) { - * fs.writeFile('testfile1', 'test1', callback); - * }, - * function(callback) { - * fs.writeFile('testfile2', 'test2', callback); - * } - * ]); - * - * // It's possible to pass any number of additional arguments when calling the - * // continuation: - * - * node> var fn = async.apply(sys.puts, 'one'); - * node> fn('two', 'three'); - * one - * two - * three - */ - var apply = function (fn/*, ...args*/) { - var args = slice(arguments, 1); - return function (/*callArgs*/) { - var callArgs = slice(arguments); - return fn.apply(null, args.concat(callArgs)); - }; - }; + function addListener(taskName, fn) { + var taskListeners = listeners[taskName]; + if (!taskListeners) { + taskListeners = listeners[taskName] = []; + } - var initialParams = function (fn) { - return function (/*...args, callback*/) { - var args = slice(arguments); - var callback = args.pop(); - fn.call(this, args, callback); - }; - }; + taskListeners.push(fn); + } - /** - * Checks if `value` is the - * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) - * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an object, else `false`. - * @example - * - * _.isObject({}); - * // => true - * - * _.isObject([1, 2, 3]); - * // => true - * - * _.isObject(_.noop); - * // => true - * - * _.isObject(null); - * // => false - */ - function isObject(value) { - var type = typeof value; - return value != null && (type == 'object' || type == 'function'); - } - - var hasSetImmediate = typeof setImmediate === 'function' && setImmediate; - var hasNextTick = typeof process === 'object' && typeof process.nextTick === 'function'; - - function fallback(fn) { - setTimeout(fn, 0); - } - - function wrap(defer) { - return function (fn/*, ...args*/) { - var args = slice(arguments, 1); - defer(function () { - fn.apply(null, args); - }); - }; + function taskComplete(taskName) { + var taskListeners = listeners[taskName] || []; + arrayEach(taskListeners, function (fn) { + fn(); + }); + processQueue(); } - var _defer; - if (hasSetImmediate) { - _defer = setImmediate; - } else if (hasNextTick) { - _defer = process.nextTick; - } else { - _defer = fallback; - } - - var setImmediate$1 = wrap(_defer); - - /** - * Take a sync function and make it async, passing its return value to a - * callback. This is useful for plugging sync functions into a waterfall, - * series, or other async functions. Any arguments passed to the generated - * function will be passed to the wrapped function (except for the final - * callback argument). Errors thrown will be passed to the callback. - * - * If the function passed to `asyncify` returns a Promise, that promises's - * resolved/rejected state will be used to call the callback, rather than simply - * the synchronous return value. - * - * This also means you can asyncify ES2017 `async` functions. - * - * @name asyncify - * @static - * @memberOf module:Utils - * @method - * @alias wrapSync - * @category Util - * @param {Function} func - The synchronous function, or Promise-returning - * function to convert to an {@link AsyncFunction}. - * @returns {AsyncFunction} An asynchronous wrapper of the `func`. To be - * invoked with `(args..., callback)`. - * @example - * - * // passing a regular synchronous function - * async.waterfall([ - * async.apply(fs.readFile, filename, "utf8"), - * async.asyncify(JSON.parse), - * function (data, next) { - * // data is the result of parsing the text. - * // If there was a parsing error, it would have been caught. - * } - * ], callback); - * - * // passing a function returning a promise - * async.waterfall([ - * async.apply(fs.readFile, filename, "utf8"), - * async.asyncify(function (contents) { - * return db.model.create(contents); - * }), - * function (model, next) { - * // `model` is the instantiated model object. - * // If there was an error, this function would be skipped. - * } - * ], callback); - * - * // es2017 example, though `asyncify` is not needed if your JS environment - * // supports async functions out of the box - * var q = async.queue(async.asyncify(async function(file) { - * var intermediateStep = await processFile(file); - * return await somePromise(intermediateStep) - * })); - * - * q.push(files); - */ - function asyncify(func) { - return initialParams(function (args, callback) { - var result; - try { - result = func.apply(this, args); - } catch (e) { - return callback(e); + function runTask(key, task) { + if (hasError) return; + + var taskCallback = onlyOnce(function(err, result) { + runningTasks--; + if (arguments.length > 2) { + result = slice(arguments, 1); } - // if result is Promise object - if (isObject(result) && typeof result.then === 'function') { - result.then(function (value) { - invokeCallback(callback, null, value); - }, function (err) { - invokeCallback(callback, err.message ? err : new Error(err)); + if (err) { + var safeResults = {}; + baseForOwn(results, function(val, rkey) { + safeResults[rkey] = val; }); + safeResults[key] = result; + hasError = true; + listeners = Object.create(null); + + callback(err, safeResults); } else { - callback(null, result); + results[key] = result; + taskComplete(key); } }); + + runningTasks++; + var taskFn = wrapAsync(task[task.length - 1]); + if (task.length > 1) { + taskFn(results, taskCallback); + } else { + taskFn(taskCallback); + } } - function invokeCallback(callback, error, value) { - try { - callback(error, value); - } catch (e) { - setImmediate$1(rethrow, e); + function checkForDeadlocks() { + // Kahn's algorithm + // https://en.wikipedia.org/wiki/Topological_sorting#Kahn.27s_algorithm + // http://connalle.blogspot.com/2013/10/topological-sortingkahn-algorithm.html + var currentTask; + var counter = 0; + while (readyToCheck.length) { + currentTask = readyToCheck.pop(); + counter++; + arrayEach(getDependents(currentTask), function (dependent) { + if (--uncheckedDependencies[dependent] === 0) { + readyToCheck.push(dependent); + } + }); + } + + if (counter !== numTasks) { + throw new Error( + 'async.auto cannot execute tasks due to a recursive dependency' + ); } } - function rethrow(error) { - throw error; + function getDependents(taskName) { + var result = []; + baseForOwn(tasks, function (task, key) { + if (isArray(task) && baseIndexOf(task, taskName, 0) >= 0) { + result.push(key); + } + }); + return result; } + }; - var supportsSymbol = typeof Symbol === 'function'; + /** + * A specialized version of `_.map` for arrays without support for iteratee + * shorthands. + * + * @private + * @param {Array} [array] The array to iterate over. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the new mapped array. + */ + function arrayMap(array, iteratee) { + var index = -1, + length = array == null ? 0 : array.length, + result = Array(length); - function isAsync(fn) { - return supportsSymbol && fn[Symbol.toStringTag] === 'AsyncFunction'; + while (++index < length) { + result[index] = iteratee(array[index], index, array); } + return result; + } - function wrapAsync(asyncFn) { - return isAsync(asyncFn) ? asyncify(asyncFn) : asyncFn; - } + /** `Object#toString` result references. */ + var symbolTag = '[object Symbol]'; - function applyEach$1(eachfn) { - return function (fns/*, ...args*/) { - var args = slice(arguments, 1); - var go = initialParams(function (args, callback) { - var that = this; - return eachfn(fns, function (fn, cb) { - wrapAsync(fn).apply(that, args.concat(cb)); - }, callback); - }); - if (args.length) { - return go.apply(this, args); - } else { - return go; - } - }; - } + /** + * Checks if `value` is classified as a `Symbol` primitive or object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. + * @example + * + * _.isSymbol(Symbol.iterator); + * // => true + * + * _.isSymbol('abc'); + * // => false + */ + function isSymbol(value) { + return typeof value == 'symbol' || + (isObjectLike(value) && baseGetTag(value) == symbolTag); + } + + /** Used as references for various `Number` constants. */ + var INFINITY = 1 / 0; - /** Detect free variable `global` from Node.js. */ - var freeGlobal = typeof global == 'object' && global && global.Object === Object && global; + /** Used to convert symbols to primitives and strings. */ + var symbolProto = Symbol$1 ? Symbol$1.prototype : undefined; + var symbolToString = symbolProto ? symbolProto.toString : undefined; + + /** + * The base implementation of `_.toString` which doesn't convert nullish + * values to empty strings. + * + * @private + * @param {*} value The value to process. + * @returns {string} Returns the string. + */ + function baseToString(value) { + // Exit early for strings to avoid a performance hit in some environments. + if (typeof value == 'string') { + return value; + } + if (isArray(value)) { + // Recursively convert values (susceptible to call stack limits). + return arrayMap(value, baseToString) + ''; + } + if (isSymbol(value)) { + return symbolToString ? symbolToString.call(value) : ''; + } + var result = (value + ''); + return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; + } - /** Detect free variable `self`. */ - var freeSelf = typeof self == 'object' && self && self.Object === Object && self; + /** + * The base implementation of `_.slice` without an iteratee call guard. + * + * @private + * @param {Array} array The array to slice. + * @param {number} [start=0] The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns the slice of `array`. + */ + function baseSlice(array, start, end) { + var index = -1, + length = array.length; - /** Used as a reference to the global object. */ - var root = freeGlobal || freeSelf || Function('return this')(); + if (start < 0) { + start = -start > length ? 0 : (length + start); + } + end = end > length ? length : end; + if (end < 0) { + end += length; + } + length = start > end ? 0 : ((end - start) >>> 0); + start >>>= 0; - /** Built-in value references. */ - var Symbol$1 = root.Symbol; + var result = Array(length); + while (++index < length) { + result[index] = array[index + start]; + } + return result; + } - /** Used for built-in method references. */ - var objectProto = Object.prototype; + /** + * Casts `array` to a slice if it's needed. + * + * @private + * @param {Array} array The array to inspect. + * @param {number} start The start position. + * @param {number} [end=array.length] The end position. + * @returns {Array} Returns the cast slice. + */ + function castSlice(array, start, end) { + var length = array.length; + end = end === undefined ? length : end; + return (!start && end >= length) ? array : baseSlice(array, start, end); + } - /** Used to check objects for own properties. */ - var hasOwnProperty = objectProto.hasOwnProperty; + /** + * Used by `_.trim` and `_.trimEnd` to get the index of the last string symbol + * that is not found in the character symbols. + * + * @private + * @param {Array} strSymbols The string symbols to inspect. + * @param {Array} chrSymbols The character symbols to find. + * @returns {number} Returns the index of the last unmatched string symbol. + */ + function charsEndIndex(strSymbols, chrSymbols) { + var index = strSymbols.length; - /** - * Used to resolve the - * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) - * of values. - */ - var nativeObjectToString = objectProto.toString; + while (index-- && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {} + return index; + } - /** Built-in value references. */ - var symToStringTag$1 = Symbol$1 ? Symbol$1.toStringTag : undefined; + /** + * Used by `_.trim` and `_.trimStart` to get the index of the first string symbol + * that is not found in the character symbols. + * + * @private + * @param {Array} strSymbols The string symbols to inspect. + * @param {Array} chrSymbols The character symbols to find. + * @returns {number} Returns the index of the first unmatched string symbol. + */ + function charsStartIndex(strSymbols, chrSymbols) { + var index = -1, + length = strSymbols.length; - /** - * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values. - * - * @private - * @param {*} value The value to query. - * @returns {string} Returns the raw `toStringTag`. - */ - function getRawTag(value) { - var isOwn = hasOwnProperty.call(value, symToStringTag$1), - tag = value[symToStringTag$1]; + while (++index < length && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) {} + return index; + } - try { - value[symToStringTag$1] = undefined; - var unmasked = true; - } catch (e) { - } + /** + * Converts an ASCII `string` to an array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the converted array. + */ + function asciiToArray(string) { + return string.split(''); + } - var result = nativeObjectToString.call(value); - if (unmasked) { - if (isOwn) { - value[symToStringTag$1] = tag; - } else { - delete value[symToStringTag$1]; - } - } - return result; - } + /** Used to compose unicode character classes. */ + var rsAstralRange = '\\ud800-\\udfff'; + var rsComboMarksRange = '\\u0300-\\u036f'; + var reComboHalfMarksRange = '\\ufe20-\\ufe2f'; + var rsComboSymbolsRange = '\\u20d0-\\u20ff'; + var rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange; + var rsVarRange = '\\ufe0e\\ufe0f'; - /** Used for built-in method references. */ - var objectProto$1 = Object.prototype; - - /** - * Used to resolve the - * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) - * of values. - */ - var nativeObjectToString$1 = objectProto$1.toString; - - /** - * Converts `value` to a string using `Object.prototype.toString`. - * - * @private - * @param {*} value The value to convert. - * @returns {string} Returns the converted string. - */ - function objectToString(value) { - return nativeObjectToString$1.call(value); - } - - /** `Object#toString` result references. */ - var nullTag = '[object Null]'; - var undefinedTag = '[object Undefined]'; - - /** Built-in value references. */ - var symToStringTag = Symbol$1 ? Symbol$1.toStringTag : undefined; - - /** - * The base implementation of `getTag` without fallbacks for buggy environments. - * - * @private - * @param {*} value The value to query. - * @returns {string} Returns the `toStringTag`. - */ - function baseGetTag(value) { - if (value == null) { - return value === undefined ? undefinedTag : nullTag; - } - return (symToStringTag && symToStringTag in Object(value)) - ? getRawTag(value) - : objectToString(value); - } - - /** `Object#toString` result references. */ - var asyncTag = '[object AsyncFunction]'; - var funcTag = '[object Function]'; - var genTag = '[object GeneratorFunction]'; - var proxyTag = '[object Proxy]'; - - /** - * Checks if `value` is classified as a `Function` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a function, else `false`. - * @example - * - * _.isFunction(_); - * // => true - * - * _.isFunction(/abc/); - * // => false - */ - function isFunction(value) { - if (!isObject(value)) { - return false; - } - // The use of `Object#toString` avoids issues with the `typeof` operator - // in Safari 9 which returns 'object' for typed arrays and other constructors. - var tag = baseGetTag(value); - return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag; - } - - /** Used as references for various `Number` constants. */ - var MAX_SAFE_INTEGER = 9007199254740991; - - /** - * Checks if `value` is a valid array-like length. - * - * **Note:** This method is loosely based on - * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength). - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. - * @example - * - * _.isLength(3); - * // => true - * - * _.isLength(Number.MIN_VALUE); - * // => false - * - * _.isLength(Infinity); - * // => false - * - * _.isLength('3'); - * // => false - */ - function isLength(value) { - return typeof value == 'number' && - value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; - } - - /** - * Checks if `value` is array-like. A value is considered array-like if it's - * not a function and has a `value.length` that's an integer greater than or - * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is array-like, else `false`. - * @example - * - * _.isArrayLike([1, 2, 3]); - * // => true - * - * _.isArrayLike(document.body.children); - * // => true - * - * _.isArrayLike('abc'); - * // => true - * - * _.isArrayLike(_.noop); - * // => false - */ - function isArrayLike(value) { - return value != null && isLength(value.length) && !isFunction(value); - } + /** Used to compose unicode capture groups. */ + var rsZWJ = '\\u200d'; -// A temporary value used to identify if the loop should be broken. -// See #1064, #1293 - var breakLoop = {}; - - /** - * This method returns `undefined`. - * - * @static - * @memberOf _ - * @since 2.3.0 - * @category Util - * @example - * - * _.times(2, _.noop); - * // => [undefined, undefined] - */ - function noop() { - // No operation performed. - } - - function once(fn) { - return function () { - if (fn === null) return; - var callFn = fn; - fn = null; - callFn.apply(this, arguments); - }; - } + /** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */ + var reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange + rsComboRange + rsVarRange + ']'); - var iteratorSymbol = typeof Symbol === 'function' && Symbol.iterator; + /** + * Checks if `string` contains Unicode symbols. + * + * @private + * @param {string} string The string to inspect. + * @returns {boolean} Returns `true` if a symbol is found, else `false`. + */ + function hasUnicode(string) { + return reHasUnicode.test(string); + } + + /** Used to compose unicode character classes. */ + var rsAstralRange$1 = '\\ud800-\\udfff'; + var rsComboMarksRange$1 = '\\u0300-\\u036f'; + var reComboHalfMarksRange$1 = '\\ufe20-\\ufe2f'; + var rsComboSymbolsRange$1 = '\\u20d0-\\u20ff'; + var rsComboRange$1 = rsComboMarksRange$1 + reComboHalfMarksRange$1 + rsComboSymbolsRange$1; + var rsVarRange$1 = '\\ufe0e\\ufe0f'; + + /** Used to compose unicode capture groups. */ + var rsAstral = '[' + rsAstralRange$1 + ']'; + var rsCombo = '[' + rsComboRange$1 + ']'; + var rsFitz = '\\ud83c[\\udffb-\\udfff]'; + var rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')'; + var rsNonAstral = '[^' + rsAstralRange$1 + ']'; + var rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}'; + var rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]'; + var rsZWJ$1 = '\\u200d'; + + /** Used to compose unicode regexes. */ + var reOptMod = rsModifier + '?'; + var rsOptVar = '[' + rsVarRange$1 + ']?'; + var rsOptJoin = '(?:' + rsZWJ$1 + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*'; + var rsSeq = rsOptVar + reOptMod + rsOptJoin; + var rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')'; + + /** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */ + var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g'); - var getIterator = function (coll) { - return iteratorSymbol && coll[iteratorSymbol] && coll[iteratorSymbol](); - }; + /** + * Converts a Unicode `string` to an array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the converted array. + */ + function unicodeToArray(string) { + return string.match(reUnicode) || []; + } - /** - * The base implementation of `_.times` without support for iteratee shorthands - * or max array length checks. - * - * @private - * @param {number} n The number of times to invoke `iteratee`. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns the array of results. - */ - function baseTimes(n, iteratee) { - var index = -1, - result = Array(n); + /** + * Converts `string` to an array. + * + * @private + * @param {string} string The string to convert. + * @returns {Array} Returns the converted array. + */ + function stringToArray(string) { + return hasUnicode(string) + ? unicodeToArray(string) + : asciiToArray(string); + } - while (++index < n) { - result[index] = iteratee(index); - } - return result; - } + /** + * Converts `value` to a string. An empty string is returned for `null` + * and `undefined` values. The sign of `-0` is preserved. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {string} Returns the converted string. + * @example + * + * _.toString(null); + * // => '' + * + * _.toString(-0); + * // => '-0' + * + * _.toString([1, 2, 3]); + * // => '1,2,3' + */ + function toString(value) { + return value == null ? '' : baseToString(value); + } - /** - * Checks if `value` is object-like. A value is object-like if it's not `null` - * and has a `typeof` result of "object". - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is object-like, else `false`. - * @example - * - * _.isObjectLike({}); - * // => true - * - * _.isObjectLike([1, 2, 3]); - * // => true - * - * _.isObjectLike(_.noop); - * // => false - * - * _.isObjectLike(null); - * // => false - */ - function isObjectLike(value) { - return value != null && typeof value == 'object'; - } - - /** `Object#toString` result references. */ - var argsTag = '[object Arguments]'; - - /** - * The base implementation of `_.isArguments`. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an `arguments` object, - */ - function baseIsArguments(value) { - return isObjectLike(value) && baseGetTag(value) == argsTag; - } - - /** Used for built-in method references. */ - var objectProto$3 = Object.prototype; - - /** Used to check objects for own properties. */ - var hasOwnProperty$2 = objectProto$3.hasOwnProperty; - - /** Built-in value references. */ - var propertyIsEnumerable = objectProto$3.propertyIsEnumerable; - - /** - * Checks if `value` is likely an `arguments` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an `arguments` object, - * else `false`. - * @example - * - * _.isArguments(function() { return arguments; }()); - * // => true - * - * _.isArguments([1, 2, 3]); - * // => false - */ - var isArguments = baseIsArguments(function () { - return arguments; - }()) ? baseIsArguments : function (value) { - return isObjectLike(value) && hasOwnProperty$2.call(value, 'callee') && - !propertyIsEnumerable.call(value, 'callee'); - }; + /** Used to match leading and trailing whitespace. */ + var reTrim = /^\s+|\s+$/g; - /** - * Checks if `value` is classified as an `Array` object. - * - * @static - * @memberOf _ - * @since 0.1.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is an array, else `false`. - * @example - * - * _.isArray([1, 2, 3]); - * // => true - * - * _.isArray(document.body.children); - * // => false - * - * _.isArray('abc'); - * // => false - * - * _.isArray(_.noop); - * // => false - */ - var isArray = Array.isArray; - - /** - * This method returns `false`. - * - * @static - * @memberOf _ - * @since 4.13.0 - * @category Util - * @returns {boolean} Returns `false`. - * @example - * - * _.times(2, _.stubFalse); - * // => [false, false] - */ - function stubFalse() { - return false; + /** + * Removes leading and trailing whitespace or specified characters from `string`. + * + * @static + * @memberOf _ + * @since 3.0.0 + * @category String + * @param {string} [string=''] The string to trim. + * @param {string} [chars=whitespace] The characters to trim. + * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. + * @returns {string} Returns the trimmed string. + * @example + * + * _.trim(' abc '); + * // => 'abc' + * + * _.trim('-_-abc-_-', '_-'); + * // => 'abc' + * + * _.map([' foo ', ' bar '], _.trim); + * // => ['foo', 'bar'] + */ + function trim(string, chars, guard) { + string = toString(string); + if (string && (guard || chars === undefined)) { + return string.replace(reTrim, ''); } - - /** Detect free variable `exports`. */ - var freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports; - - /** Detect free variable `module`. */ - var freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module; - - /** Detect the popular CommonJS extension `module.exports`. */ - var moduleExports = freeModule && freeModule.exports === freeExports; - - /** Built-in value references. */ - var Buffer = moduleExports ? root.Buffer : undefined; - - /* Built-in method references for those with the same name as other `lodash` methods. */ - var nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined; - - /** - * Checks if `value` is a buffer. - * - * @static - * @memberOf _ - * @since 4.3.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a buffer, else `false`. - * @example - * - * _.isBuffer(new Buffer(2)); - * // => true - * - * _.isBuffer(new Uint8Array(2)); - * // => false - */ - var isBuffer = nativeIsBuffer || stubFalse; - - /** Used as references for various `Number` constants. */ - var MAX_SAFE_INTEGER$1 = 9007199254740991; - - /** Used to detect unsigned integer values. */ - var reIsUint = /^(?:0|[1-9]\d*)$/; - - /** - * Checks if `value` is a valid array-like index. - * - * @private - * @param {*} value The value to check. - * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. - * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. - */ - function isIndex(value, length) { - length = length == null ? MAX_SAFE_INTEGER$1 : length; - return !!length && - (typeof value == 'number' || reIsUint.test(value)) && - (value > -1 && value % 1 == 0 && value < length); - } - - /** `Object#toString` result references. */ - var argsTag$1 = '[object Arguments]'; - var arrayTag = '[object Array]'; - var boolTag = '[object Boolean]'; - var dateTag = '[object Date]'; - var errorTag = '[object Error]'; - var funcTag$1 = '[object Function]'; - var mapTag = '[object Map]'; - var numberTag = '[object Number]'; - var objectTag = '[object Object]'; - var regexpTag = '[object RegExp]'; - var setTag = '[object Set]'; - var stringTag = '[object String]'; - var weakMapTag = '[object WeakMap]'; - - var arrayBufferTag = '[object ArrayBuffer]'; - var dataViewTag = '[object DataView]'; - var float32Tag = '[object Float32Array]'; - var float64Tag = '[object Float64Array]'; - var int8Tag = '[object Int8Array]'; - var int16Tag = '[object Int16Array]'; - var int32Tag = '[object Int32Array]'; - var uint8Tag = '[object Uint8Array]'; - var uint8ClampedTag = '[object Uint8ClampedArray]'; - var uint16Tag = '[object Uint16Array]'; - var uint32Tag = '[object Uint32Array]'; - - /** Used to identify `toStringTag` values of typed arrays. */ - var typedArrayTags = {}; - typedArrayTags[float32Tag] = typedArrayTags[float64Tag] = - typedArrayTags[int8Tag] = typedArrayTags[int16Tag] = - typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] = - typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] = - typedArrayTags[uint32Tag] = true; - typedArrayTags[argsTag$1] = typedArrayTags[arrayTag] = - typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] = - typedArrayTags[dataViewTag] = typedArrayTags[dateTag] = - typedArrayTags[errorTag] = typedArrayTags[funcTag$1] = - typedArrayTags[mapTag] = typedArrayTags[numberTag] = - typedArrayTags[objectTag] = typedArrayTags[regexpTag] = - typedArrayTags[setTag] = typedArrayTags[stringTag] = - typedArrayTags[weakMapTag] = false; - - /** - * The base implementation of `_.isTypedArray` without Node.js optimizations. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a typed array, else `false`. - */ - function baseIsTypedArray(value) { - return isObjectLike(value) && - isLength(value.length) && !!typedArrayTags[baseGetTag(value)]; - } - - /** - * The base implementation of `_.unary` without support for storing metadata. - * - * @private - * @param {Function} func The function to cap arguments for. - * @returns {Function} Returns the new capped function. - */ - function baseUnary(func) { - return function (value) { - return func(value); - }; + if (!string || !(chars = baseToString(chars))) { + return string; } + var strSymbols = stringToArray(string), + chrSymbols = stringToArray(chars), + start = charsStartIndex(strSymbols, chrSymbols), + end = charsEndIndex(strSymbols, chrSymbols) + 1; + + return castSlice(strSymbols, start, end).join(''); + } - /** Detect free variable `exports`. */ - var freeExports$1 = typeof exports == 'object' && exports && !exports.nodeType && exports; + var FN_ARGS = /^(?:async\s+)?(function)?\s*[^\(]*\(\s*([^\)]*)\)/m; + var FN_ARG_SPLIT = /,/; + var FN_ARG = /(=.+)?(\s*)$/; + var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg; - /** Detect free variable `module`. */ - var freeModule$1 = freeExports$1 && typeof module == 'object' && module && !module.nodeType && module; + function parseParams(func) { + func = func.toString().replace(STRIP_COMMENTS, ''); + func = func.match(FN_ARGS)[2].replace(' ', ''); + func = func ? func.split(FN_ARG_SPLIT) : []; + func = func.map(function (arg){ + return trim(arg.replace(FN_ARG, '')); + }); + return func; + } - /** Detect the popular CommonJS extension `module.exports`. */ - var moduleExports$1 = freeModule$1 && freeModule$1.exports === freeExports$1; + /** + * A dependency-injected version of the [async.auto]{@link module:ControlFlow.auto} function. Dependent + * tasks are specified as parameters to the function, after the usual callback + * parameter, with the parameter names matching the names of the tasks it + * depends on. This can provide even more readable task graphs which can be + * easier to maintain. + * + * If a final callback is specified, the task results are similarly injected, + * specified as named parameters after the initial error parameter. + * + * The autoInject function is purely syntactic sugar and its semantics are + * otherwise equivalent to [async.auto]{@link module:ControlFlow.auto}. + * + * @name autoInject + * @static + * @memberOf module:ControlFlow + * @method + * @see [async.auto]{@link module:ControlFlow.auto} + * @category Control Flow + * @param {Object} tasks - An object, each of whose properties is an {@link AsyncFunction} of + * the form 'func([dependencies...], callback). The object's key of a property + * serves as the name of the task defined by that property, i.e. can be used + * when specifying requirements for other tasks. + * * The `callback` parameter is a `callback(err, result)` which must be called + * when finished, passing an `error` (which can be `null`) and the result of + * the function's execution. The remaining parameters name other tasks on + * which the task is dependent, and the results from those tasks are the + * arguments of those parameters. + * @param {Function} [callback] - An optional callback which is called when all + * the tasks have been completed. It receives the `err` argument if any `tasks` + * pass an error to their callback, and a `results` object with any completed + * task results, similar to `auto`. + * @example + * + * // The example from `auto` can be rewritten as follows: + * async.autoInject({ + * get_data: function(callback) { + * // async code to get some data + * callback(null, 'data', 'converted to array'); + * }, + * make_folder: function(callback) { + * // async code to create a directory to store a file in + * // this is run at the same time as getting the data + * callback(null, 'folder'); + * }, + * write_file: function(get_data, make_folder, callback) { + * // once there is some data and the directory exists, + * // write the data to a file in the directory + * callback(null, 'filename'); + * }, + * email_link: function(write_file, callback) { + * // once the file is written let's email a link to it... + * // write_file contains the filename returned by write_file. + * callback(null, {'file':write_file, 'email':'user@example.com'}); + * } + * }, function(err, results) { + * console.log('err = ', err); + * console.log('email_link = ', results.email_link); + * }); + * + * // If you are using a JS minifier that mangles parameter names, `autoInject` + * // will not work with plain functions, since the parameter names will be + * // collapsed to a single letter identifier. To work around this, you can + * // explicitly specify the names of the parameters your task function needs + * // in an array, similar to Angular.js dependency injection. + * + * // This still has an advantage over plain `auto`, since the results a task + * // depends on are still spread into arguments. + * async.autoInject({ + * //... + * write_file: ['get_data', 'make_folder', function(get_data, make_folder, callback) { + * callback(null, 'filename'); + * }], + * email_link: ['write_file', function(write_file, callback) { + * callback(null, {'file':write_file, 'email':'user@example.com'}); + * }] + * //... + * }, function(err, results) { + * console.log('err = ', err); + * console.log('email_link = ', results.email_link); + * }); + */ + function autoInject(tasks, callback) { + var newTasks = {}; + + baseForOwn(tasks, function (taskFn, key) { + var params; + var fnIsAsync = isAsync(taskFn); + var hasNoDeps = + (!fnIsAsync && taskFn.length === 1) || + (fnIsAsync && taskFn.length === 0); + + if (isArray(taskFn)) { + params = taskFn.slice(0, -1); + taskFn = taskFn[taskFn.length - 1]; + + newTasks[key] = params.concat(params.length > 0 ? newTask : taskFn); + } else if (hasNoDeps) { + // no dependencies, use the function as-is + newTasks[key] = taskFn; + } else { + params = parseParams(taskFn); + if (taskFn.length === 0 && !fnIsAsync && params.length === 0) { + throw new Error("autoInject task functions require explicit parameters."); + } - /** Detect free variable `process` from Node.js. */ - var freeProcess = moduleExports$1 && freeGlobal.process; + // remove callback param + if (!fnIsAsync) params.pop(); - /** Used to access faster Node.js helpers. */ - var nodeUtil = (function () { - try { - return freeProcess && freeProcess.binding && freeProcess.binding('util'); - } catch (e) { + newTasks[key] = params.concat(newTask); } - }()); - - /* Node.js helper references. */ - var nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray; - - /** - * Checks if `value` is classified as a typed array. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a typed array, else `false`. - * @example - * - * _.isTypedArray(new Uint8Array); - * // => true - * - * _.isTypedArray([]); - * // => false - */ - var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray; - - /** Used for built-in method references. */ - var objectProto$2 = Object.prototype; - - /** Used to check objects for own properties. */ - var hasOwnProperty$1 = objectProto$2.hasOwnProperty; - - /** - * Creates an array of the enumerable property names of the array-like `value`. - * - * @private - * @param {*} value The value to query. - * @param {boolean} inherited Specify returning inherited property names. - * @returns {Array} Returns the array of property names. - */ - function arrayLikeKeys(value, inherited) { - var isArr = isArray(value), - isArg = !isArr && isArguments(value), - isBuff = !isArr && !isArg && isBuffer(value), - isType = !isArr && !isArg && !isBuff && isTypedArray(value), - skipIndexes = isArr || isArg || isBuff || isType, - result = skipIndexes ? baseTimes(value.length, String) : [], - length = result.length; - - for (var key in value) { - if ((inherited || hasOwnProperty$1.call(value, key)) && - !(skipIndexes && ( - // Safari 9 has enumerable `arguments.length` in strict mode. - key == 'length' || - // Node.js 0.10 has enumerable non-index properties on buffers. - (isBuff && (key == 'offset' || key == 'parent')) || - // PhantomJS 2 has enumerable non-index properties on typed arrays. - (isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) || - // Skip index properties. - isIndex(key, length) - ))) { - result.push(key); - } + + function newTask(results, taskCb) { + var newArgs = arrayMap(params, function (name) { + return results[name]; + }); + newArgs.push(taskCb); + wrapAsync(taskFn).apply(null, newArgs); } - return result; - } + }); - /** Used for built-in method references. */ - var objectProto$5 = Object.prototype; - - /** - * Checks if `value` is likely a prototype object. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a prototype, else `false`. - */ - function isPrototype(value) { - var Ctor = value && value.constructor, - proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto$5; - - return value === proto; - } - - /** - * Creates a unary function that invokes `func` with its argument transformed. - * - * @private - * @param {Function} func The function to wrap. - * @param {Function} transform The argument transform. - * @returns {Function} Returns the new function. - */ - function overArg(func, transform) { - return function (arg) { - return func(transform(arg)); - }; - } + auto(newTasks, callback); + } + +// Simple doubly linked list (https://en.wikipedia.org/wiki/Doubly_linked_list) implementation +// used for queues. This implementation assumes that the node provided by the user can be modified +// to adjust the next and last properties. We implement only the minimal functionality +// for queue support. + function DLL() { + this.head = this.tail = null; + this.length = 0; + } - /* Built-in method references for those with the same name as other `lodash` methods. */ - var nativeKeys = overArg(Object.keys, Object); + function setInitial(dll, node) { + dll.length = 1; + dll.head = dll.tail = node; + } - /** Used for built-in method references. */ - var objectProto$4 = Object.prototype; + DLL.prototype.removeLink = function(node) { + if (node.prev) node.prev.next = node.next; + else this.head = node.next; + if (node.next) node.next.prev = node.prev; + else this.tail = node.prev; - /** Used to check objects for own properties. */ - var hasOwnProperty$3 = objectProto$4.hasOwnProperty; + node.prev = node.next = null; + this.length -= 1; + return node; + }; - /** - * The base implementation of `_.keys` which doesn't treat sparse arrays as dense. - * - * @private - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names. - */ - function baseKeys(object) { - if (!isPrototype(object)) { - return nativeKeys(object); - } - var result = []; - for (var key in Object(object)) { - if (hasOwnProperty$3.call(object, key) && key != 'constructor') { - result.push(key); - } - } - return result; - } + DLL.prototype.empty = function () { + while(this.head) this.shift(); + return this; + }; - /** - * Creates an array of the own enumerable property names of `object`. - * - * **Note:** Non-object values are coerced to objects. See the - * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys) - * for more details. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Object - * @param {Object} object The object to query. - * @returns {Array} Returns the array of property names. - * @example - * - * function Foo() { - * this.a = 1; - * this.b = 2; - * } - * - * Foo.prototype.c = 3; - * - * _.keys(new Foo); - * // => ['a', 'b'] (iteration order is not guaranteed) - * - * _.keys('hi'); - * // => ['0', '1'] - */ - function keys(object) { - return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object); - } - - function createArrayIterator(coll) { - var i = -1; - var len = coll.length; - return function next() { - return ++i < len ? {value: coll[i], key: i} : null; - } - } - - function createES2015Iterator(iterator) { - var i = -1; - return function next() { - var item = iterator.next(); - if (item.done) - return null; - i++; - return {value: item.value, key: i}; - } - } - - function createObjectIterator(obj) { - var okeys = keys(obj); - var i = -1; - var len = okeys.length; - return function next() { - var key = okeys[++i]; - return i < len ? {value: obj[key], key: key} : null; - }; - } + DLL.prototype.insertAfter = function(node, newNode) { + newNode.prev = node; + newNode.next = node.next; + if (node.next) node.next.prev = newNode; + else this.tail = newNode; + node.next = newNode; + this.length += 1; + }; - function iterator(coll) { - if (isArrayLike(coll)) { - return createArrayIterator(coll); - } + DLL.prototype.insertBefore = function(node, newNode) { + newNode.prev = node.prev; + newNode.next = node; + if (node.prev) node.prev.next = newNode; + else this.head = newNode; + node.prev = newNode; + this.length += 1; + }; - var iterator = getIterator(coll); - return iterator ? createES2015Iterator(iterator) : createObjectIterator(coll); - } + DLL.prototype.unshift = function(node) { + if (this.head) this.insertBefore(this.head, node); + else setInitial(this, node); + }; - function onlyOnce(fn) { - return function () { - if (fn === null) throw new Error("Callback was already called."); - var callFn = fn; - fn = null; - callFn.apply(this, arguments); - }; - } + DLL.prototype.push = function(node) { + if (this.tail) this.insertAfter(this.tail, node); + else setInitial(this, node); + }; - function _eachOfLimit(limit) { - return function (obj, iteratee, callback) { - callback = once(callback || noop); - if (limit <= 0 || !obj) { - return callback(null); - } - var nextElem = iterator(obj); - var done = false; - var running = 0; + DLL.prototype.shift = function() { + return this.head && this.removeLink(this.head); + }; - function iterateeCallback(err, value) { - running -= 1; - if (err) { - done = true; - callback(err); - } else if (value === breakLoop || (done && running <= 0)) { - done = true; - return callback(null); - } else { - replenish(); - } - } + DLL.prototype.pop = function() { + return this.tail && this.removeLink(this.tail); + }; - function replenish() { - while (running < limit && !done) { - var elem = nextElem(); - if (elem === null) { - done = true; - if (running <= 0) { - callback(null); - } - return; - } - running += 1; - iteratee(elem.value, elem.key, onlyOnce(iterateeCallback)); - } - } + DLL.prototype.toArray = function () { + var arr = Array(this.length); + var curr = this.head; + for(var idx = 0; idx < this.length; idx++) { + arr[idx] = curr.data; + curr = curr.next; + } + return arr; + }; - replenish(); - }; + DLL.prototype.remove = function (testFn) { + var curr = this.head; + while(!!curr) { + var next = curr.next; + if (testFn(curr)) { + this.removeLink(curr); + } + curr = next; } + return this; + }; - /** - * The same as [`eachOf`]{@link module:Collections.eachOf} but runs a maximum of `limit` async operations at a - * time. - * - * @name eachOfLimit - * @static - * @memberOf module:Collections - * @method - * @see [async.eachOf]{@link module:Collections.eachOf} - * @alias forEachOfLimit - * @category Collection - * @param {Array|Iterable|Object} coll - A collection to iterate over. - * @param {number} limit - The maximum number of async operations at a time. - * @param {AsyncFunction} iteratee - An async function to apply to each - * item in `coll`. The `key` is the item's key, or index in the case of an - * array. - * Invoked with (item, key, callback). - * @param {Function} [callback] - A callback which is called when all - * `iteratee` functions have finished, or an error occurs. Invoked with (err). - */ - function eachOfLimit(coll, limit, iteratee, callback) { - _eachOfLimit(limit)(coll, wrapAsync(iteratee), callback); - } - - function doLimit(fn, limit) { - return function (iterable, iteratee, callback) { - return fn(iterable, limit, iteratee, callback); - }; + function queue(worker, concurrency, payload) { + if (concurrency == null) { + concurrency = 1; + } + else if(concurrency === 0) { + throw new Error('Concurrency must not be zero'); } -// eachOf implementation optimized for array-likes - function eachOfArrayLike(coll, iteratee, callback) { - callback = once(callback || noop); - var index = 0, - completed = 0, - length = coll.length; - if (length === 0) { - callback(null); + var _worker = wrapAsync(worker); + var numRunning = 0; + var workersList = []; + + var processingScheduled = false; + function _insert(data, insertAtFront, callback) { + if (callback != null && typeof callback !== 'function') { + throw new Error('task callback must be a function'); + } + q.started = true; + if (!isArray(data)) { + data = [data]; + } + if (data.length === 0 && q.idle()) { + // call drain immediately if there are no tasks + return setImmediate$1(function() { + q.drain(); + }); } - function iteratorCallback(err, value) { - if (err) { - callback(err); - } else if ((++completed === length) || value === breakLoop) { - callback(null); + for (var i = 0, l = data.length; i < l; i++) { + var item = { + data: data[i], + callback: callback || noop + }; + + if (insertAtFront) { + q._tasks.unshift(item); + } else { + q._tasks.push(item); } } - for (; index < length; index++) { - iteratee(coll[index], index, onlyOnce(iteratorCallback)); + if (!processingScheduled) { + processingScheduled = true; + setImmediate$1(function() { + processingScheduled = false; + q.process(); + }); } } -// a generic version of eachOf which can handle array, object, and iterator cases. - var eachOfGeneric = doLimit(eachOfLimit, Infinity); - - /** - * Like [`each`]{@link module:Collections.each}, except that it passes the key (or index) as the second argument - * to the iteratee. - * - * @name eachOf - * @static - * @memberOf module:Collections - * @method - * @alias forEachOf - * @category Collection - * @see [async.each]{@link module:Collections.each} - * @param {Array|Iterable|Object} coll - A collection to iterate over. - * @param {AsyncFunction} iteratee - A function to apply to each - * item in `coll`. - * The `key` is the item's key, or index in the case of an array. - * Invoked with (item, key, callback). - * @param {Function} [callback] - A callback which is called when all - * `iteratee` functions have finished, or an error occurs. Invoked with (err). - * @example - * - * var obj = {dev: "/dev.json", test: "/test.json", prod: "/prod.json"}; - * var configs = {}; - * - * async.forEachOf(obj, function (value, key, callback) { - * fs.readFile(__dirname + value, "utf8", function (err, data) { - * if (err) return callback(err); - * try { - * configs[key] = JSON.parse(data); - * } catch (e) { - * return callback(e); - * } - * callback(); - * }); - * }, function (err) { - * if (err) console.error(err.message); - * // configs is now a map of JSON data - * doSomethingWith(configs); - * }); - */ - var eachOf = function (coll, iteratee, callback) { - var eachOfImplementation = isArrayLike(coll) ? eachOfArrayLike : eachOfGeneric; - eachOfImplementation(coll, wrapAsync(iteratee), callback); - }; - - function doParallel(fn) { - return function (obj, iteratee, callback) { - return fn(eachOf, obj, wrapAsync(iteratee), callback); - }; - } + function _next(tasks) { + return function(err){ + numRunning -= 1; - function _asyncMap(eachfn, arr, iteratee, callback) { - callback = callback || noop; - arr = arr || []; - var results = []; - var counter = 0; - var _iteratee = wrapAsync(iteratee); + for (var i = 0, l = tasks.length; i < l; i++) { + var task = tasks[i]; - eachfn(arr, function (value, _, callback) { - var index = counter++; - _iteratee(value, function (err, v) { - results[index] = v; - callback(err); - }); - }, function (err) { - callback(err, results); - }); - } + var index = baseIndexOf(workersList, task, 0); + if (index === 0) { + workersList.shift(); + } else if (index > 0) { + workersList.splice(index, 1); + } - /** - * Produces a new collection of values by mapping each value in `coll` through - * the `iteratee` function. The `iteratee` is called with an item from `coll` - * and a callback for when it has finished processing. Each of these callback - * takes 2 arguments: an `error`, and the transformed item from `coll`. If - * `iteratee` passes an error to its callback, the main `callback` (for the - * `map` function) is immediately called with the error. - * - * Note, that since this function applies the `iteratee` to each item in - * parallel, there is no guarantee that the `iteratee` functions will complete - * in order. However, the results array will be in the same order as the - * original `coll`. - * - * If `map` is passed an Object, the results will be an Array. The results - * will roughly be in the order of the original Objects' keys (but this can - * vary across JavaScript engines). - * - * @name map - * @static - * @memberOf module:Collections - * @method - * @category Collection - * @param {Array|Iterable|Object} coll - A collection to iterate over. - * @param {AsyncFunction} iteratee - An async function to apply to each item in - * `coll`. - * The iteratee should complete with the transformed item. - * Invoked with (item, callback). - * @param {Function} [callback] - A callback which is called when all `iteratee` - * functions have finished, or an error occurs. Results is an Array of the - * transformed items from the `coll`. Invoked with (err, results). - * @example - * - * async.map(['file1','file2','file3'], fs.stat, function(err, results) { - * // results is now an array of stats for each file - * }); - */ - var map = doParallel(_asyncMap); - - /** - * Applies the provided arguments to each function in the array, calling - * `callback` after all functions have completed. If you only provide the first - * argument, `fns`, then it will return a function which lets you pass in the - * arguments as if it were a single function call. If more arguments are - * provided, `callback` is required while `args` is still optional. - * - * @name applyEach - * @static - * @memberOf module:ControlFlow - * @method - * @category Control Flow - * @param {Array|Iterable|Object} fns - A collection of {@link AsyncFunction}s - * to all call with the same arguments - * @param {...*} [args] - any number of separate arguments to pass to the - * function. - * @param {Function} [callback] - the final argument should be the callback, - * called when all functions have completed processing. - * @returns {Function} - If only the first argument, `fns`, is provided, it will - * return a function which lets you pass in the arguments as if it were a single - * function call. The signature is `(..args, callback)`. If invoked with any - * arguments, `callback` is required. - * @example - * - * async.applyEach([enableSearch, updateSchema], 'bucket', callback); - * - * // partial application example: - * async.each( - * buckets, - * async.applyEach([enableSearch, updateSchema]), - * callback - * ); - */ - var applyEach = applyEach$1(map); - - function doParallelLimit(fn) { - return function (obj, limit, iteratee, callback) { - return fn(_eachOfLimit(limit), obj, wrapAsync(iteratee), callback); - }; - } + task.callback.apply(task, arguments); - /** - * The same as [`map`]{@link module:Collections.map} but runs a maximum of `limit` async operations at a time. - * - * @name mapLimit - * @static - * @memberOf module:Collections - * @method - * @see [async.map]{@link module:Collections.map} - * @category Collection - * @param {Array|Iterable|Object} coll - A collection to iterate over. - * @param {number} limit - The maximum number of async operations at a time. - * @param {AsyncFunction} iteratee - An async function to apply to each item in - * `coll`. - * The iteratee should complete with the transformed item. - * Invoked with (item, callback). - * @param {Function} [callback] - A callback which is called when all `iteratee` - * functions have finished, or an error occurs. Results is an array of the - * transformed items from the `coll`. Invoked with (err, results). - */ - var mapLimit = doParallelLimit(_asyncMap); - - /** - * The same as [`map`]{@link module:Collections.map} but runs only a single async operation at a time. - * - * @name mapSeries - * @static - * @memberOf module:Collections - * @method - * @see [async.map]{@link module:Collections.map} - * @category Collection - * @param {Array|Iterable|Object} coll - A collection to iterate over. - * @param {AsyncFunction} iteratee - An async function to apply to each item in - * `coll`. - * The iteratee should complete with the transformed item. - * Invoked with (item, callback). - * @param {Function} [callback] - A callback which is called when all `iteratee` - * functions have finished, or an error occurs. Results is an array of the - * transformed items from the `coll`. Invoked with (err, results). - */ - var mapSeries = doLimit(mapLimit, 1); - - /** - * The same as [`applyEach`]{@link module:ControlFlow.applyEach} but runs only a single async operation at a time. - * - * @name applyEachSeries - * @static - * @memberOf module:ControlFlow - * @method - * @see [async.applyEach]{@link module:ControlFlow.applyEach} - * @category Control Flow - * @param {Array|Iterable|Object} fns - A collection of {@link AsyncFunction}s to all - * call with the same arguments - * @param {...*} [args] - any number of separate arguments to pass to the - * function. - * @param {Function} [callback] - the final argument should be the callback, - * called when all functions have completed processing. - * @returns {Function} - If only the first argument is provided, it will return - * a function which lets you pass in the arguments as if it were a single - * function call. - */ - var applyEachSeries = applyEach$1(mapSeries); - - /** - * A specialized version of `_.forEach` for arrays without support for - * iteratee shorthands. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns `array`. - */ - function arrayEach(array, iteratee) { - var index = -1, - length = array == null ? 0 : array.length; + if (err != null) { + q.error(err, task.data); + } + } - while (++index < length) { - if (iteratee(array[index], index, array) === false) { - break; + if (numRunning <= (q.concurrency - q.buffer) ) { + q.unsaturated(); } - } - return array; - } - - /** - * Creates a base function for methods like `_.forIn` and `_.forOwn`. - * - * @private - * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {Function} Returns the new base function. - */ - function createBaseFor(fromRight) { - return function (object, iteratee, keysFunc) { - var index = -1, - iterable = Object(object), - props = keysFunc(object), - length = props.length; - - while (length--) { - var key = props[fromRight ? length : ++index]; - if (iteratee(iterable[key], key, iterable) === false) { - break; - } + + if (q.idle()) { + q.drain(); } - return object; + q.process(); }; } - /** - * The base implementation of `baseForOwn` which iterates over `object` - * properties returned by `keysFunc` and invokes `iteratee` for each property. - * Iteratee functions may exit iteration early by explicitly returning `false`. - * - * @private - * @param {Object} object The object to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @param {Function} keysFunc The function to get the keys of `object`. - * @returns {Object} Returns `object`. - */ - var baseFor = createBaseFor(); - - /** - * The base implementation of `_.forOwn` without support for iteratee shorthands. - * - * @private - * @param {Object} object The object to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Object} Returns `object`. - */ - function baseForOwn(object, iteratee) { - return object && baseFor(object, iteratee, keys); - } - - /** - * The base implementation of `_.findIndex` and `_.findLastIndex` without - * support for iteratee shorthands. - * - * @private - * @param {Array} array The array to inspect. - * @param {Function} predicate The function invoked per iteration. - * @param {number} fromIndex The index to search from. - * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {number} Returns the index of the matched value, else `-1`. - */ - function baseFindIndex(array, predicate, fromIndex, fromRight) { - var length = array.length, - index = fromIndex + (fromRight ? 1 : -1); - - while ((fromRight ? index-- : ++index < length)) { - if (predicate(array[index], index, array)) { - return index; + var isProcessing = false; + var q = { + _tasks: new DLL(), + concurrency: concurrency, + payload: payload, + saturated: noop, + unsaturated:noop, + buffer: concurrency / 4, + empty: noop, + drain: noop, + error: noop, + started: false, + paused: false, + push: function (data, callback) { + _insert(data, false, callback); + }, + kill: function () { + q.drain = noop; + q._tasks.empty(); + }, + unshift: function (data, callback) { + _insert(data, true, callback); + }, + remove: function (testFn) { + q._tasks.remove(testFn); + }, + process: function () { + // Avoid trying to start too many processing operations. This can occur + // when callbacks resolve synchronously (#1267). + if (isProcessing) { + return; } - } - return -1; - } - - /** - * The base implementation of `_.isNaN` without support for number objects. - * - * @private - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. - */ - function baseIsNaN(value) { - return value !== value; - } - - /** - * A specialized version of `_.indexOf` which performs strict equality - * comparisons of values, i.e. `===`. - * - * @private - * @param {Array} array The array to inspect. - * @param {*} value The value to search for. - * @param {number} fromIndex The index to search from. - * @returns {number} Returns the index of the matched value, else `-1`. - */ - function strictIndexOf(array, value, fromIndex) { - var index = fromIndex - 1, - length = array.length; - - while (++index < length) { - if (array[index] === value) { - return index; + isProcessing = true; + while(!q.paused && numRunning < q.concurrency && q._tasks.length){ + var tasks = [], data = []; + var l = q._tasks.length; + if (q.payload) l = Math.min(l, q.payload); + for (var i = 0; i < l; i++) { + var node = q._tasks.shift(); + tasks.push(node); + workersList.push(node); + data.push(node.data); + } + + numRunning += 1; + + if (q._tasks.length === 0) { + q.empty(); + } + + if (numRunning === q.concurrency) { + q.saturated(); + } + + var cb = onlyOnce(_next(tasks)); + _worker(data, cb); } + isProcessing = false; + }, + length: function () { + return q._tasks.length; + }, + running: function () { + return numRunning; + }, + workersList: function () { + return workersList; + }, + idle: function() { + return q._tasks.length + numRunning === 0; + }, + pause: function () { + q.paused = true; + }, + resume: function () { + if (q.paused === false) { return; } + q.paused = false; + setImmediate$1(q.process); } - return -1; - } - - /** - * The base implementation of `_.indexOf` without `fromIndex` bounds checks. - * - * @private - * @param {Array} array The array to inspect. - * @param {*} value The value to search for. - * @param {number} fromIndex The index to search from. - * @returns {number} Returns the index of the matched value, else `-1`. - */ - function baseIndexOf(array, value, fromIndex) { - return value === value - ? strictIndexOf(array, value, fromIndex) - : baseFindIndex(array, baseIsNaN, fromIndex); - } - - /** - * Determines the best order for running the {@link AsyncFunction}s in `tasks`, based on - * their requirements. Each function can optionally depend on other functions - * being completed first, and each function is run as soon as its requirements - * are satisfied. - * - * If any of the {@link AsyncFunction}s pass an error to their callback, the `auto` sequence - * will stop. Further tasks will not execute (so any other functions depending - * on it will not run), and the main `callback` is immediately called with the - * error. - * - * {@link AsyncFunction}s also receive an object containing the results of functions which - * have completed so far as the first argument, if they have dependencies. If a - * task function has no dependencies, it will only be passed a callback. - * - * @name auto - * @static - * @memberOf module:ControlFlow - * @method - * @category Control Flow - * @param {Object} tasks - An object. Each of its properties is either a - * function or an array of requirements, with the {@link AsyncFunction} itself the last item - * in the array. The object's key of a property serves as the name of the task - * defined by that property, i.e. can be used when specifying requirements for - * other tasks. The function receives one or two arguments: - * * a `results` object, containing the results of the previously executed - * functions, only passed if the task has any dependencies, - * * a `callback(err, result)` function, which must be called when finished, - * passing an `error` (which can be `null`) and the result of the function's - * execution. - * @param {number} [concurrency=Infinity] - An optional `integer` for - * determining the maximum number of tasks that can be run in parallel. By - * default, as many as possible. - * @param {Function} [callback] - An optional callback which is called when all - * the tasks have been completed. It receives the `err` argument if any `tasks` - * pass an error to their callback. Results are always returned; however, if an - * error occurs, no further `tasks` will be performed, and the results object - * will only contain partial results. Invoked with (err, results). - * @returns undefined - * @example - * - * async.auto({ - * // this function will just be passed a callback - * readData: async.apply(fs.readFile, 'data.txt', 'utf-8'), - * showData: ['readData', function(results, cb) { - * // results.readData is the file's contents - * // ... - * }] - * }, callback); - * - * async.auto({ - * get_data: function(callback) { - * console.log('in get_data'); - * // async code to get some data - * callback(null, 'data', 'converted to array'); - * }, - * make_folder: function(callback) { - * console.log('in make_folder'); - * // async code to create a directory to store a file in - * // this is run at the same time as getting the data - * callback(null, 'folder'); - * }, - * write_file: ['get_data', 'make_folder', function(results, callback) { - * console.log('in write_file', JSON.stringify(results)); - * // once there is some data and the directory exists, - * // write the data to a file in the directory - * callback(null, 'filename'); - * }], - * email_link: ['write_file', function(results, callback) { - * console.log('in email_link', JSON.stringify(results)); - * // once the file is written let's email a link to it... - * // results.write_file contains the filename returned by write_file. - * callback(null, {'file':results.write_file, 'email':'user@example.com'}); - * }] - * }, function(err, results) { - * console.log('err = ', err); - * console.log('results = ', results); - * }); - */ - var auto = function (tasks, concurrency, callback) { - if (typeof concurrency === 'function') { - // concurrency is optional, shift the args. - callback = concurrency; - concurrency = null; - } - callback = once(callback || noop); - var keys$$1 = keys(tasks); - var numTasks = keys$$1.length; - if (!numTasks) { - return callback(null); - } - if (!concurrency) { - concurrency = numTasks; - } + }; + return q; + } - var results = {}; - var runningTasks = 0; - var hasError = false; + /** + * A cargo of tasks for the worker function to complete. Cargo inherits all of + * the same methods and event callbacks as [`queue`]{@link module:ControlFlow.queue}. + * @typedef {Object} CargoObject + * @memberOf module:ControlFlow + * @property {Function} length - A function returning the number of items + * waiting to be processed. Invoke like `cargo.length()`. + * @property {number} payload - An `integer` for determining how many tasks + * should be process per round. This property can be changed after a `cargo` is + * created to alter the payload on-the-fly. + * @property {Function} push - Adds `task` to the `queue`. The callback is + * called once the `worker` has finished processing the task. Instead of a + * single task, an array of `tasks` can be submitted. The respective callback is + * used for every task in the list. Invoke like `cargo.push(task, [callback])`. + * @property {Function} saturated - A callback that is called when the + * `queue.length()` hits the concurrency and further tasks will be queued. + * @property {Function} empty - A callback that is called when the last item + * from the `queue` is given to a `worker`. + * @property {Function} drain - A callback that is called when the last item + * from the `queue` has returned from the `worker`. + * @property {Function} idle - a function returning false if there are items + * waiting or being processed, or true if not. Invoke like `cargo.idle()`. + * @property {Function} pause - a function that pauses the processing of tasks + * until `resume()` is called. Invoke like `cargo.pause()`. + * @property {Function} resume - a function that resumes the processing of + * queued tasks when the queue is paused. Invoke like `cargo.resume()`. + * @property {Function} kill - a function that removes the `drain` callback and + * empties remaining tasks from the queue forcing it to go idle. Invoke like `cargo.kill()`. + */ - var listeners = Object.create(null); + /** + * Creates a `cargo` object with the specified payload. Tasks added to the + * cargo will be processed altogether (up to the `payload` limit). If the + * `worker` is in progress, the task is queued until it becomes available. Once + * the `worker` has completed some tasks, each callback of those tasks is + * called. Check out [these](https://camo.githubusercontent.com/6bbd36f4cf5b35a0f11a96dcd2e97711ffc2fb37/68747470733a2f2f662e636c6f75642e6769746875622e636f6d2f6173736574732f313637363837312f36383130382f62626330636662302d356632392d313165322d393734662d3333393763363464633835382e676966) [animations](https://camo.githubusercontent.com/f4810e00e1c5f5f8addbe3e9f49064fd5d102699/68747470733a2f2f662e636c6f75642e6769746875622e636f6d2f6173736574732f313637363837312f36383130312f38346339323036362d356632392d313165322d383134662d3964336430323431336266642e676966) + * for how `cargo` and `queue` work. + * + * While [`queue`]{@link module:ControlFlow.queue} passes only one task to one of a group of workers + * at a time, cargo passes an array of tasks to a single worker, repeating + * when the worker is finished. + * + * @name cargo + * @static + * @memberOf module:ControlFlow + * @method + * @see [async.queue]{@link module:ControlFlow.queue} + * @category Control Flow + * @param {AsyncFunction} worker - An asynchronous function for processing an array + * of queued tasks. Invoked with `(tasks, callback)`. + * @param {number} [payload=Infinity] - An optional `integer` for determining + * how many tasks should be processed per round; if omitted, the default is + * unlimited. + * @returns {module:ControlFlow.CargoObject} A cargo object to manage the tasks. Callbacks can + * attached as certain properties to listen for specific events during the + * lifecycle of the cargo and inner queue. + * @example + * + * // create a cargo object with payload 2 + * var cargo = async.cargo(function(tasks, callback) { + * for (var i=0; i true + */ + function identity(value) { + return value; + } - var taskCallback = onlyOnce(function (err, result) { - runningTasks--; - if (arguments.length > 2) { - result = slice(arguments, 1); - } + function _createTester(check, getResult) { + return function(eachfn, arr, iteratee, cb) { + cb = cb || noop; + var testPassed = false; + var testResult; + eachfn(arr, function(value, _, callback) { + iteratee(value, function(err, result) { if (err) { - var safeResults = {}; - baseForOwn(results, function (val, rkey) { - safeResults[rkey] = val; - }); - safeResults[key] = result; - hasError = true; - listeners = Object.create(null); - - callback(err, safeResults); + callback(err); + } else if (check(result) && !testResult) { + testPassed = true; + testResult = getResult(true, value); + callback(null, breakLoop); } else { - results[key] = result; - taskComplete(key); + callback(); } }); - - runningTasks++; - var taskFn = wrapAsync(task[task.length - 1]); - if (task.length > 1) { - taskFn(results, taskCallback); + }, function(err) { + if (err) { + cb(err); } else { - taskFn(taskCallback); + cb(null, testPassed ? testResult : getResult(false)); } - } + }); + }; + } - function checkForDeadlocks() { - // Kahn's algorithm - // https://en.wikipedia.org/wiki/Topological_sorting#Kahn.27s_algorithm - // http://connalle.blogspot.com/2013/10/topological-sortingkahn-algorithm.html - var currentTask; - var counter = 0; - while (readyToCheck.length) { - currentTask = readyToCheck.pop(); - counter++; - arrayEach(getDependents(currentTask), function (dependent) { - if (--uncheckedDependencies[dependent] === 0) { - readyToCheck.push(dependent); - } - }); - } + function _findGetResult(v, x) { + return x; + } - if (counter !== numTasks) { - throw new Error( - 'async.auto cannot execute tasks due to a recursive dependency' - ); - } - } + /** + * Returns the first value in `coll` that passes an async truth test. The + * `iteratee` is applied in parallel, meaning the first iteratee to return + * `true` will fire the detect `callback` with that result. That means the + * result might not be the first item in the original `coll` (in terms of order) + * that passes the test. + + * If order within the original `coll` is important, then look at + * [`detectSeries`]{@link module:Collections.detectSeries}. + * + * @name detect + * @static + * @memberOf module:Collections + * @method + * @alias find + * @category Collections + * @param {Array|Iterable|Object} coll - A collection to iterate over. + * @param {AsyncFunction} iteratee - A truth test to apply to each item in `coll`. + * The iteratee must complete with a boolean value as its result. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called as soon as any + * iteratee returns `true`, or after all the `iteratee` functions have finished. + * Result will be the first item in the array that passes the truth test + * (iteratee) or the value `undefined` if none passed. Invoked with + * (err, result). + * @example + * + * async.detect(['file1','file2','file3'], function(filePath, callback) { + * fs.access(filePath, function(err) { + * callback(null, !err) + * }); + * }, function(err, result) { + * // result now equals the first file in the list that exists + * }); + */ + var detect = doParallel(_createTester(identity, _findGetResult)); - function getDependents(taskName) { - var result = []; - baseForOwn(tasks, function (task, key) { - if (isArray(task) && baseIndexOf(task, taskName, 0) >= 0) { - result.push(key); - } - }); - return result; - } - }; + /** + * The same as [`detect`]{@link module:Collections.detect} but runs a maximum of `limit` async operations at a + * time. + * + * @name detectLimit + * @static + * @memberOf module:Collections + * @method + * @see [async.detect]{@link module:Collections.detect} + * @alias findLimit + * @category Collections + * @param {Array|Iterable|Object} coll - A collection to iterate over. + * @param {number} limit - The maximum number of async operations at a time. + * @param {AsyncFunction} iteratee - A truth test to apply to each item in `coll`. + * The iteratee must complete with a boolean value as its result. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called as soon as any + * iteratee returns `true`, or after all the `iteratee` functions have finished. + * Result will be the first item in the array that passes the truth test + * (iteratee) or the value `undefined` if none passed. Invoked with + * (err, result). + */ + var detectLimit = doParallelLimit(_createTester(identity, _findGetResult)); - /** - * A specialized version of `_.map` for arrays without support for iteratee - * shorthands. - * - * @private - * @param {Array} [array] The array to iterate over. - * @param {Function} iteratee The function invoked per iteration. - * @returns {Array} Returns the new mapped array. - */ - function arrayMap(array, iteratee) { - var index = -1, - length = array == null ? 0 : array.length, - result = Array(length); + /** + * The same as [`detect`]{@link module:Collections.detect} but runs only a single async operation at a time. + * + * @name detectSeries + * @static + * @memberOf module:Collections + * @method + * @see [async.detect]{@link module:Collections.detect} + * @alias findSeries + * @category Collections + * @param {Array|Iterable|Object} coll - A collection to iterate over. + * @param {AsyncFunction} iteratee - A truth test to apply to each item in `coll`. + * The iteratee must complete with a boolean value as its result. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called as soon as any + * iteratee returns `true`, or after all the `iteratee` functions have finished. + * Result will be the first item in the array that passes the truth test + * (iteratee) or the value `undefined` if none passed. Invoked with + * (err, result). + */ + var detectSeries = doLimit(detectLimit, 1); - while (++index < length) { - result[index] = iteratee(array[index], index, array); - } - return result; - } + function consoleFunc(name) { + return function (fn/*, ...args*/) { + var args = slice(arguments, 1); + args.push(function (err/*, ...args*/) { + var args = slice(arguments, 1); + if (typeof console === 'object') { + if (err) { + if (console.error) { + console.error(err); + } + } else if (console[name]) { + arrayEach(args, function (x) { + console[name](x); + }); + } + } + }); + wrapAsync(fn).apply(null, args); + }; + } - /** `Object#toString` result references. */ - var symbolTag = '[object Symbol]'; - - /** - * Checks if `value` is classified as a `Symbol` primitive or object. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to check. - * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. - * @example - * - * _.isSymbol(Symbol.iterator); - * // => true - * - * _.isSymbol('abc'); - * // => false - */ - function isSymbol(value) { - return typeof value == 'symbol' || - (isObjectLike(value) && baseGetTag(value) == symbolTag); - } - - /** Used as references for various `Number` constants. */ - var INFINITY = 1 / 0; - - /** Used to convert symbols to primitives and strings. */ - var symbolProto = Symbol$1 ? Symbol$1.prototype : undefined; - var symbolToString = symbolProto ? symbolProto.toString : undefined; - - /** - * The base implementation of `_.toString` which doesn't convert nullish - * values to empty strings. - * - * @private - * @param {*} value The value to process. - * @returns {string} Returns the string. - */ - function baseToString(value) { - // Exit early for strings to avoid a performance hit in some environments. - if (typeof value == 'string') { - return value; - } - if (isArray(value)) { - // Recursively convert values (susceptible to call stack limits). - return arrayMap(value, baseToString) + ''; - } - if (isSymbol(value)) { - return symbolToString ? symbolToString.call(value) : ''; - } - var result = (value + ''); - return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result; - } - - /** - * The base implementation of `_.slice` without an iteratee call guard. - * - * @private - * @param {Array} array The array to slice. - * @param {number} [start=0] The start position. - * @param {number} [end=array.length] The end position. - * @returns {Array} Returns the slice of `array`. - */ - function baseSlice(array, start, end) { - var index = -1, - length = array.length; + /** + * Logs the result of an [`async` function]{@link AsyncFunction} to the + * `console` using `console.dir` to display the properties of the resulting object. + * Only works in Node.js or in browsers that support `console.dir` and + * `console.error` (such as FF and Chrome). + * If multiple arguments are returned from the async function, + * `console.dir` is called on each argument in order. + * + * @name dir + * @static + * @memberOf module:Utils + * @method + * @category Util + * @param {AsyncFunction} function - The function you want to eventually apply + * all arguments to. + * @param {...*} arguments... - Any number of arguments to apply to the function. + * @example + * + * // in a module + * var hello = function(name, callback) { + * setTimeout(function() { + * callback(null, {hello: name}); + * }, 1000); + * }; + * + * // in the node repl + * node> async.dir(hello, 'world'); + * {hello: 'world'} + */ + var dir = consoleFunc('dir'); - if (start < 0) { - start = -start > length ? 0 : (length + start); - } - end = end > length ? length : end; - if (end < 0) { - end += length; - } - length = start > end ? 0 : ((end - start) >>> 0); - start >>>= 0; + /** + * The post-check version of [`during`]{@link module:ControlFlow.during}. To reflect the difference in + * the order of operations, the arguments `test` and `fn` are switched. + * + * Also a version of [`doWhilst`]{@link module:ControlFlow.doWhilst} with asynchronous `test` function. + * @name doDuring + * @static + * @memberOf module:ControlFlow + * @method + * @see [async.during]{@link module:ControlFlow.during} + * @category Control Flow + * @param {AsyncFunction} fn - An async function which is called each time + * `test` passes. Invoked with (callback). + * @param {AsyncFunction} test - asynchronous truth test to perform before each + * execution of `fn`. Invoked with (...args, callback), where `...args` are the + * non-error args from the previous callback of `fn`. + * @param {Function} [callback] - A callback which is called after the test + * function has failed and repeated execution of `fn` has stopped. `callback` + * will be passed an error if one occurred, otherwise `null`. + */ + function doDuring(fn, test, callback) { + callback = onlyOnce(callback || noop); + var _fn = wrapAsync(fn); + var _test = wrapAsync(test); - var result = Array(length); - while (++index < length) { - result[index] = array[index + start]; - } - return result; + function next(err/*, ...args*/) { + if (err) return callback(err); + var args = slice(arguments, 1); + args.push(check); + _test.apply(this, args); + } + + function check(err, truth) { + if (err) return callback(err); + if (!truth) return callback(null); + _fn(next); } - /** - * Casts `array` to a slice if it's needed. - * - * @private - * @param {Array} array The array to inspect. - * @param {number} start The start position. - * @param {number} [end=array.length] The end position. - * @returns {Array} Returns the cast slice. - */ - function castSlice(array, start, end) { - var length = array.length; - end = end === undefined ? length : end; - return (!start && end >= length) ? array : baseSlice(array, start, end); - } - - /** - * Used by `_.trim` and `_.trimEnd` to get the index of the last string symbol - * that is not found in the character symbols. - * - * @private - * @param {Array} strSymbols The string symbols to inspect. - * @param {Array} chrSymbols The character symbols to find. - * @returns {number} Returns the index of the last unmatched string symbol. - */ - function charsEndIndex(strSymbols, chrSymbols) { - var index = strSymbols.length; - - while (index-- && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) { - } - return index; - } - - /** - * Used by `_.trim` and `_.trimStart` to get the index of the first string symbol - * that is not found in the character symbols. - * - * @private - * @param {Array} strSymbols The string symbols to inspect. - * @param {Array} chrSymbols The character symbols to find. - * @returns {number} Returns the index of the first unmatched string symbol. - */ - function charsStartIndex(strSymbols, chrSymbols) { - var index = -1, - length = strSymbols.length; - - while (++index < length && baseIndexOf(chrSymbols, strSymbols[index], 0) > -1) { - } - return index; - } - - /** - * Converts an ASCII `string` to an array. - * - * @private - * @param {string} string The string to convert. - * @returns {Array} Returns the converted array. - */ - function asciiToArray(string) { - return string.split(''); - } - - /** Used to compose unicode character classes. */ - var rsAstralRange = '\\ud800-\\udfff'; - var rsComboMarksRange = '\\u0300-\\u036f'; - var reComboHalfMarksRange = '\\ufe20-\\ufe2f'; - var rsComboSymbolsRange = '\\u20d0-\\u20ff'; - var rsComboRange = rsComboMarksRange + reComboHalfMarksRange + rsComboSymbolsRange; - var rsVarRange = '\\ufe0e\\ufe0f'; - - /** Used to compose unicode capture groups. */ - var rsZWJ = '\\u200d'; - - /** Used to detect strings with [zero-width joiners or code points from the astral planes](http://eev.ee/blog/2015/09/12/dark-corners-of-unicode/). */ - var reHasUnicode = RegExp('[' + rsZWJ + rsAstralRange + rsComboRange + rsVarRange + ']'); - - /** - * Checks if `string` contains Unicode symbols. - * - * @private - * @param {string} string The string to inspect. - * @returns {boolean} Returns `true` if a symbol is found, else `false`. - */ - function hasUnicode(string) { - return reHasUnicode.test(string); - } - - /** Used to compose unicode character classes. */ - var rsAstralRange$1 = '\\ud800-\\udfff'; - var rsComboMarksRange$1 = '\\u0300-\\u036f'; - var reComboHalfMarksRange$1 = '\\ufe20-\\ufe2f'; - var rsComboSymbolsRange$1 = '\\u20d0-\\u20ff'; - var rsComboRange$1 = rsComboMarksRange$1 + reComboHalfMarksRange$1 + rsComboSymbolsRange$1; - var rsVarRange$1 = '\\ufe0e\\ufe0f'; - - /** Used to compose unicode capture groups. */ - var rsAstral = '[' + rsAstralRange$1 + ']'; - var rsCombo = '[' + rsComboRange$1 + ']'; - var rsFitz = '\\ud83c[\\udffb-\\udfff]'; - var rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')'; - var rsNonAstral = '[^' + rsAstralRange$1 + ']'; - var rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}'; - var rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]'; - var rsZWJ$1 = '\\u200d'; - - /** Used to compose unicode regexes. */ - var reOptMod = rsModifier + '?'; - var rsOptVar = '[' + rsVarRange$1 + ']?'; - var rsOptJoin = '(?:' + rsZWJ$1 + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*'; - var rsSeq = rsOptVar + reOptMod + rsOptJoin; - var rsSymbol = '(?:' + [rsNonAstral + rsCombo + '?', rsCombo, rsRegional, rsSurrPair, rsAstral].join('|') + ')'; - - /** Used to match [string symbols](https://mathiasbynens.be/notes/javascript-unicode). */ - var reUnicode = RegExp(rsFitz + '(?=' + rsFitz + ')|' + rsSymbol + rsSeq, 'g'); - - /** - * Converts a Unicode `string` to an array. - * - * @private - * @param {string} string The string to convert. - * @returns {Array} Returns the converted array. - */ - function unicodeToArray(string) { - return string.match(reUnicode) || []; - } - - /** - * Converts `string` to an array. - * - * @private - * @param {string} string The string to convert. - * @returns {Array} Returns the converted array. - */ - function stringToArray(string) { - return hasUnicode(string) - ? unicodeToArray(string) - : asciiToArray(string); - } - - /** - * Converts `value` to a string. An empty string is returned for `null` - * and `undefined` values. The sign of `-0` is preserved. - * - * @static - * @memberOf _ - * @since 4.0.0 - * @category Lang - * @param {*} value The value to convert. - * @returns {string} Returns the converted string. - * @example - * - * _.toString(null); - * // => '' - * - * _.toString(-0); - * // => '-0' - * - * _.toString([1, 2, 3]); - * // => '1,2,3' - */ - function toString(value) { - return value == null ? '' : baseToString(value); - } - - /** Used to match leading and trailing whitespace. */ - var reTrim = /^\s+|\s+$/g; - - /** - * Removes leading and trailing whitespace or specified characters from `string`. - * - * @static - * @memberOf _ - * @since 3.0.0 - * @category String - * @param {string} [string=''] The string to trim. - * @param {string} [chars=whitespace] The characters to trim. - * @param- {Object} [guard] Enables use as an iteratee for methods like `_.map`. - * @returns {string} Returns the trimmed string. - * @example - * - * _.trim(' abc '); - * // => 'abc' - * - * _.trim('-_-abc-_-', '_-'); - * // => 'abc' - * - * _.map([' foo ', ' bar '], _.trim); - * // => ['foo', 'bar'] - */ - function trim(string, chars, guard) { - string = toString(string); - if (string && (guard || chars === undefined)) { - return string.replace(reTrim, ''); - } - if (!string || !(chars = baseToString(chars))) { - return string; - } - var strSymbols = stringToArray(string), - chrSymbols = stringToArray(chars), - start = charsStartIndex(strSymbols, chrSymbols), - end = charsEndIndex(strSymbols, chrSymbols) + 1; - - return castSlice(strSymbols, start, end).join(''); - } - - var FN_ARGS = /^(?:async\s+)?(function)?\s*[^\(]*\(\s*([^\)]*)\)/m; - var FN_ARG_SPLIT = /,/; - var FN_ARG = /(=.+)?(\s*)$/; - var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg; - - function parseParams(func) { - func = func.toString().replace(STRIP_COMMENTS, ''); - func = func.match(FN_ARGS)[2].replace(' ', ''); - func = func ? func.split(FN_ARG_SPLIT) : []; - func = func.map(function (arg) { - return trim(arg.replace(FN_ARG, '')); - }); - return func; - } - - /** - * A dependency-injected version of the [async.auto]{@link module:ControlFlow.auto} function. Dependent - * tasks are specified as parameters to the function, after the usual callback - * parameter, with the parameter names matching the names of the tasks it - * depends on. This can provide even more readable task graphs which can be - * easier to maintain. - * - * If a final callback is specified, the task results are similarly injected, - * specified as named parameters after the initial error parameter. - * - * The autoInject function is purely syntactic sugar and its semantics are - * otherwise equivalent to [async.auto]{@link module:ControlFlow.auto}. - * - * @name autoInject - * @static - * @memberOf module:ControlFlow - * @method - * @see [async.auto]{@link module:ControlFlow.auto} - * @category Control Flow - * @param {Object} tasks - An object, each of whose properties is an {@link AsyncFunction} of - * the form 'func([dependencies...], callback). The object's key of a property - * serves as the name of the task defined by that property, i.e. can be used - * when specifying requirements for other tasks. - * * The `callback` parameter is a `callback(err, result)` which must be called - * when finished, passing an `error` (which can be `null`) and the result of - * the function's execution. The remaining parameters name other tasks on - * which the task is dependent, and the results from those tasks are the - * arguments of those parameters. - * @param {Function} [callback] - An optional callback which is called when all - * the tasks have been completed. It receives the `err` argument if any `tasks` - * pass an error to their callback, and a `results` object with any completed - * task results, similar to `auto`. - * @example - * - * // The example from `auto` can be rewritten as follows: - * async.autoInject({ - * get_data: function(callback) { - * // async code to get some data - * callback(null, 'data', 'converted to array'); - * }, - * make_folder: function(callback) { - * // async code to create a directory to store a file in - * // this is run at the same time as getting the data - * callback(null, 'folder'); - * }, - * write_file: function(get_data, make_folder, callback) { - * // once there is some data and the directory exists, - * // write the data to a file in the directory - * callback(null, 'filename'); - * }, - * email_link: function(write_file, callback) { - * // once the file is written let's email a link to it... - * // write_file contains the filename returned by write_file. - * callback(null, {'file':write_file, 'email':'user@example.com'}); - * } - * }, function(err, results) { - * console.log('err = ', err); - * console.log('email_link = ', results.email_link); - * }); - * - * // If you are using a JS minifier that mangles parameter names, `autoInject` - * // will not work with plain functions, since the parameter names will be - * // collapsed to a single letter identifier. To work around this, you can - * // explicitly specify the names of the parameters your task function needs - * // in an array, similar to Angular.js dependency injection. - * - * // This still has an advantage over plain `auto`, since the results a task - * // depends on are still spread into arguments. - * async.autoInject({ - * //... - * write_file: ['get_data', 'make_folder', function(get_data, make_folder, callback) { - * callback(null, 'filename'); - * }], - * email_link: ['write_file', function(write_file, callback) { - * callback(null, {'file':write_file, 'email':'user@example.com'}); - * }] - * //... - * }, function(err, results) { - * console.log('err = ', err); - * console.log('email_link = ', results.email_link); - * }); - */ - function autoInject(tasks, callback) { - var newTasks = {}; - - baseForOwn(tasks, function (taskFn, key) { - var params; - var fnIsAsync = isAsync(taskFn); - var hasNoDeps = - (!fnIsAsync && taskFn.length === 1) || - (fnIsAsync && taskFn.length === 0); - - if (isArray(taskFn)) { - params = taskFn.slice(0, -1); - taskFn = taskFn[taskFn.length - 1]; - - newTasks[key] = params.concat(params.length > 0 ? newTask : taskFn); - } else if (hasNoDeps) { - // no dependencies, use the function as-is - newTasks[key] = taskFn; - } else { - params = parseParams(taskFn); - if (taskFn.length === 0 && !fnIsAsync && params.length === 0) { - throw new Error("autoInject task functions require explicit parameters."); - } + check(null, true); - // remove callback param - if (!fnIsAsync) params.pop(); + } - newTasks[key] = params.concat(newTask); - } + /** + * The post-check version of [`whilst`]{@link module:ControlFlow.whilst}. To reflect the difference in + * the order of operations, the arguments `test` and `iteratee` are switched. + * + * `doWhilst` is to `whilst` as `do while` is to `while` in plain JavaScript. + * + * @name doWhilst + * @static + * @memberOf module:ControlFlow + * @method + * @see [async.whilst]{@link module:ControlFlow.whilst} + * @category Control Flow + * @param {AsyncFunction} iteratee - A function which is called each time `test` + * passes. Invoked with (callback). + * @param {Function} test - synchronous truth test to perform after each + * execution of `iteratee`. Invoked with any non-error callback results of + * `iteratee`. + * @param {Function} [callback] - A callback which is called after the test + * function has failed and repeated execution of `iteratee` has stopped. + * `callback` will be passed an error and any arguments passed to the final + * `iteratee`'s callback. Invoked with (err, [results]); + */ + function doWhilst(iteratee, test, callback) { + callback = onlyOnce(callback || noop); + var _iteratee = wrapAsync(iteratee); + var next = function(err/*, ...args*/) { + if (err) return callback(err); + var args = slice(arguments, 1); + if (test.apply(this, args)) return _iteratee(next); + callback.apply(null, [null].concat(args)); + }; + _iteratee(next); + } - function newTask(results, taskCb) { - var newArgs = arrayMap(params, function (name) { - return results[name]; - }); - newArgs.push(taskCb); - wrapAsync(taskFn).apply(null, newArgs); - } - }); + /** + * Like ['doWhilst']{@link module:ControlFlow.doWhilst}, except the `test` is inverted. Note the + * argument ordering differs from `until`. + * + * @name doUntil + * @static + * @memberOf module:ControlFlow + * @method + * @see [async.doWhilst]{@link module:ControlFlow.doWhilst} + * @category Control Flow + * @param {AsyncFunction} iteratee - An async function which is called each time + * `test` fails. Invoked with (callback). + * @param {Function} test - synchronous truth test to perform after each + * execution of `iteratee`. Invoked with any non-error callback results of + * `iteratee`. + * @param {Function} [callback] - A callback which is called after the test + * function has passed and repeated execution of `iteratee` has stopped. `callback` + * will be passed an error and any arguments passed to the final `iteratee`'s + * callback. Invoked with (err, [results]); + */ + function doUntil(iteratee, test, callback) { + doWhilst(iteratee, function() { + return !test.apply(this, arguments); + }, callback); + } - auto(newTasks, callback); - } + /** + * Like [`whilst`]{@link module:ControlFlow.whilst}, except the `test` is an asynchronous function that + * is passed a callback in the form of `function (err, truth)`. If error is + * passed to `test` or `fn`, the main callback is immediately called with the + * value of the error. + * + * @name during + * @static + * @memberOf module:ControlFlow + * @method + * @see [async.whilst]{@link module:ControlFlow.whilst} + * @category Control Flow + * @param {AsyncFunction} test - asynchronous truth test to perform before each + * execution of `fn`. Invoked with (callback). + * @param {AsyncFunction} fn - An async function which is called each time + * `test` passes. Invoked with (callback). + * @param {Function} [callback] - A callback which is called after the test + * function has failed and repeated execution of `fn` has stopped. `callback` + * will be passed an error, if one occurred, otherwise `null`. + * @example + * + * var count = 0; + * + * async.during( + * function (callback) { + * return callback(null, count < 5); + * }, + * function (callback) { + * count++; + * setTimeout(callback, 1000); + * }, + * function (err) { + * // 5 seconds have passed + * } + * ); + */ + function during(test, fn, callback) { + callback = onlyOnce(callback || noop); + var _fn = wrapAsync(fn); + var _test = wrapAsync(test); -// Simple doubly linked list (https://en.wikipedia.org/wiki/Doubly_linked_list) implementation -// used for queues. This implementation assumes that the node provided by the user can be modified -// to adjust the next and last properties. We implement only the minimal functionality -// for queue support. - function DLL() { - this.head = this.tail = null; - this.length = 0; + function next(err) { + if (err) return callback(err); + _test(check); } - function setInitial(dll, node) { - dll.length = 1; - dll.head = dll.tail = node; + function check(err, truth) { + if (err) return callback(err); + if (!truth) return callback(null); + _fn(next); } - DLL.prototype.removeLink = function (node) { - if (node.prev) node.prev.next = node.next; - else this.head = node.next; - if (node.next) node.next.prev = node.prev; - else this.tail = node.prev; + _test(check); + } - node.prev = node.next = null; - this.length -= 1; - return node; + function _withoutIndex(iteratee) { + return function (value, index, callback) { + return iteratee(value, callback); }; + } - DLL.prototype.empty = function () { - while (this.head) this.shift(); - return this; - }; + /** + * Applies the function `iteratee` to each item in `coll`, in parallel. + * The `iteratee` is called with an item from the list, and a callback for when + * it has finished. If the `iteratee` passes an error to its `callback`, the + * main `callback` (for the `each` function) is immediately called with the + * error. + * + * Note, that since this function applies `iteratee` to each item in parallel, + * there is no guarantee that the iteratee functions will complete in order. + * + * @name each + * @static + * @memberOf module:Collections + * @method + * @alias forEach + * @category Collection + * @param {Array|Iterable|Object} coll - A collection to iterate over. + * @param {AsyncFunction} iteratee - An async function to apply to + * each item in `coll`. Invoked with (item, callback). + * The array index is not passed to the iteratee. + * If you need the index, use `eachOf`. + * @param {Function} [callback] - A callback which is called when all + * `iteratee` functions have finished, or an error occurs. Invoked with (err). + * @example + * + * // assuming openFiles is an array of file names and saveFile is a function + * // to save the modified contents of that file: + * + * async.each(openFiles, saveFile, function(err){ + * // if any of the saves produced an error, err would equal that error + * }); + * + * // assuming openFiles is an array of file names + * async.each(openFiles, function(file, callback) { + * + * // Perform operation on file here. + * console.log('Processing file ' + file); + * + * if( file.length > 32 ) { + * console.log('This file name is too long'); + * callback('File name too long'); + * } else { + * // Do work to process file here + * console.log('File processed'); + * callback(); + * } + * }, function(err) { + * // if any of the file processing produced an error, err would equal that error + * if( err ) { + * // One of the iterations produced an error. + * // All processing will now stop. + * console.log('A file failed to process'); + * } else { + * console.log('All files have been processed successfully'); + * } + * }); + */ + function eachLimit(coll, iteratee, callback) { + eachOf(coll, _withoutIndex(wrapAsync(iteratee)), callback); + } - DLL.prototype.insertAfter = function (node, newNode) { - newNode.prev = node; - newNode.next = node.next; - if (node.next) node.next.prev = newNode; - else this.tail = newNode; - node.next = newNode; - this.length += 1; - }; + /** + * The same as [`each`]{@link module:Collections.each} but runs a maximum of `limit` async operations at a time. + * + * @name eachLimit + * @static + * @memberOf module:Collections + * @method + * @see [async.each]{@link module:Collections.each} + * @alias forEachLimit + * @category Collection + * @param {Array|Iterable|Object} coll - A collection to iterate over. + * @param {number} limit - The maximum number of async operations at a time. + * @param {AsyncFunction} iteratee - An async function to apply to each item in + * `coll`. + * The array index is not passed to the iteratee. + * If you need the index, use `eachOfLimit`. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called when all + * `iteratee` functions have finished, or an error occurs. Invoked with (err). + */ + function eachLimit$1(coll, limit, iteratee, callback) { + _eachOfLimit(limit)(coll, _withoutIndex(wrapAsync(iteratee)), callback); + } - DLL.prototype.insertBefore = function (node, newNode) { - newNode.prev = node.prev; - newNode.next = node; - if (node.prev) node.prev.next = newNode; - else this.head = newNode; - node.prev = newNode; - this.length += 1; - }; + /** + * The same as [`each`]{@link module:Collections.each} but runs only a single async operation at a time. + * + * @name eachSeries + * @static + * @memberOf module:Collections + * @method + * @see [async.each]{@link module:Collections.each} + * @alias forEachSeries + * @category Collection + * @param {Array|Iterable|Object} coll - A collection to iterate over. + * @param {AsyncFunction} iteratee - An async function to apply to each + * item in `coll`. + * The array index is not passed to the iteratee. + * If you need the index, use `eachOfSeries`. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called when all + * `iteratee` functions have finished, or an error occurs. Invoked with (err). + */ + var eachSeries = doLimit(eachLimit$1, 1); - DLL.prototype.unshift = function (node) { - if (this.head) this.insertBefore(this.head, node); - else setInitial(this, node); - }; + /** + * Wrap an async function and ensure it calls its callback on a later tick of + * the event loop. If the function already calls its callback on a next tick, + * no extra deferral is added. This is useful for preventing stack overflows + * (`RangeError: Maximum call stack size exceeded`) and generally keeping + * [Zalgo](http://blog.izs.me/post/59142742143/designing-apis-for-asynchrony) + * contained. ES2017 `async` functions are returned as-is -- they are immune + * to Zalgo's corrupting influences, as they always resolve on a later tick. + * + * @name ensureAsync + * @static + * @memberOf module:Utils + * @method + * @category Util + * @param {AsyncFunction} fn - an async function, one that expects a node-style + * callback as its last argument. + * @returns {AsyncFunction} Returns a wrapped function with the exact same call + * signature as the function passed in. + * @example + * + * function sometimesAsync(arg, callback) { + * if (cache[arg]) { + * return callback(null, cache[arg]); // this would be synchronous!! + * } else { + * doSomeIO(arg, callback); // this IO would be asynchronous + * } + * } + * + * // this has a risk of stack overflows if many results are cached in a row + * async.mapSeries(args, sometimesAsync, done); + * + * // this will defer sometimesAsync's callback if necessary, + * // preventing stack overflows + * async.mapSeries(args, async.ensureAsync(sometimesAsync), done); + */ + function ensureAsync(fn) { + if (isAsync(fn)) return fn; + return initialParams(function (args, callback) { + var sync = true; + args.push(function () { + var innerArgs = arguments; + if (sync) { + setImmediate$1(function () { + callback.apply(null, innerArgs); + }); + } else { + callback.apply(null, innerArgs); + } + }); + fn.apply(this, args); + sync = false; + }); + } - DLL.prototype.push = function (node) { - if (this.tail) this.insertAfter(this.tail, node); - else setInitial(this, node); - }; + function notId(v) { + return !v; + } - DLL.prototype.shift = function () { - return this.head && this.removeLink(this.head); - }; + /** + * Returns `true` if every element in `coll` satisfies an async test. If any + * iteratee call returns `false`, the main `callback` is immediately called. + * + * @name every + * @static + * @memberOf module:Collections + * @method + * @alias all + * @category Collection + * @param {Array|Iterable|Object} coll - A collection to iterate over. + * @param {AsyncFunction} iteratee - An async truth test to apply to each item + * in the collection in parallel. + * The iteratee must complete with a boolean result value. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called after all the + * `iteratee` functions have finished. Result will be either `true` or `false` + * depending on the values of the async tests. Invoked with (err, result). + * @example + * + * async.every(['file1','file2','file3'], function(filePath, callback) { + * fs.access(filePath, function(err) { + * callback(null, !err) + * }); + * }, function(err, result) { + * // if result is true then every file exists + * }); + */ + var every = doParallel(_createTester(notId, notId)); + + /** + * The same as [`every`]{@link module:Collections.every} but runs a maximum of `limit` async operations at a time. + * + * @name everyLimit + * @static + * @memberOf module:Collections + * @method + * @see [async.every]{@link module:Collections.every} + * @alias allLimit + * @category Collection + * @param {Array|Iterable|Object} coll - A collection to iterate over. + * @param {number} limit - The maximum number of async operations at a time. + * @param {AsyncFunction} iteratee - An async truth test to apply to each item + * in the collection in parallel. + * The iteratee must complete with a boolean result value. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called after all the + * `iteratee` functions have finished. Result will be either `true` or `false` + * depending on the values of the async tests. Invoked with (err, result). + */ + var everyLimit = doParallelLimit(_createTester(notId, notId)); + + /** + * The same as [`every`]{@link module:Collections.every} but runs only a single async operation at a time. + * + * @name everySeries + * @static + * @memberOf module:Collections + * @method + * @see [async.every]{@link module:Collections.every} + * @alias allSeries + * @category Collection + * @param {Array|Iterable|Object} coll - A collection to iterate over. + * @param {AsyncFunction} iteratee - An async truth test to apply to each item + * in the collection in series. + * The iteratee must complete with a boolean result value. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called after all the + * `iteratee` functions have finished. Result will be either `true` or `false` + * depending on the values of the async tests. Invoked with (err, result). + */ + var everySeries = doLimit(everyLimit, 1); - DLL.prototype.pop = function () { - return this.tail && this.removeLink(this.tail); + /** + * The base implementation of `_.property` without support for deep paths. + * + * @private + * @param {string} key The key of the property to get. + * @returns {Function} Returns the new accessor function. + */ + function baseProperty(key) { + return function(object) { + return object == null ? undefined : object[key]; }; + } - DLL.prototype.toArray = function () { - var arr = Array(this.length); - var curr = this.head; - for (var idx = 0; idx < this.length; idx++) { - arr[idx] = curr.data; - curr = curr.next; + function filterArray(eachfn, arr, iteratee, callback) { + var truthValues = new Array(arr.length); + eachfn(arr, function (x, index, callback) { + iteratee(x, function (err, v) { + truthValues[index] = !!v; + callback(err); + }); + }, function (err) { + if (err) return callback(err); + var results = []; + for (var i = 0; i < arr.length; i++) { + if (truthValues[i]) results.push(arr[i]); } - return arr; - }; + callback(null, results); + }); + } - DLL.prototype.remove = function (testFn) { - var curr = this.head; - while (!!curr) { - var next = curr.next; - if (testFn(curr)) { - this.removeLink(curr); + function filterGeneric(eachfn, coll, iteratee, callback) { + var results = []; + eachfn(coll, function (x, index, callback) { + iteratee(x, function (err, v) { + if (err) { + callback(err); + } else { + if (v) { + results.push({index: index, value: x}); + } + callback(); } - curr = next; + }); + }, function (err) { + if (err) { + callback(err); + } else { + callback(null, arrayMap(results.sort(function (a, b) { + return a.index - b.index; + }), baseProperty('value'))); } - return this; - }; + }); + } - function queue(worker, concurrency, payload) { - if (concurrency == null) { - concurrency = 1; - } else if (concurrency === 0) { - throw new Error('Concurrency must not be zero'); - } + function _filter(eachfn, coll, iteratee, callback) { + var filter = isArrayLike(coll) ? filterArray : filterGeneric; + filter(eachfn, coll, wrapAsync(iteratee), callback || noop); + } - var _worker = wrapAsync(worker); - var numRunning = 0; - var workersList = []; + /** + * Returns a new array of all the values in `coll` which pass an async truth + * test. This operation is performed in parallel, but the results array will be + * in the same order as the original. + * + * @name filter + * @static + * @memberOf module:Collections + * @method + * @alias select + * @category Collection + * @param {Array|Iterable|Object} coll - A collection to iterate over. + * @param {Function} iteratee - A truth test to apply to each item in `coll`. + * The `iteratee` is passed a `callback(err, truthValue)`, which must be called + * with a boolean argument once it has completed. Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called after all the + * `iteratee` functions have finished. Invoked with (err, results). + * @example + * + * async.filter(['file1','file2','file3'], function(filePath, callback) { + * fs.access(filePath, function(err) { + * callback(null, !err) + * }); + * }, function(err, results) { + * // results now equals an array of the existing files + * }); + */ + var filter = doParallel(_filter); - var processingScheduled = false; + /** + * The same as [`filter`]{@link module:Collections.filter} but runs a maximum of `limit` async operations at a + * time. + * + * @name filterLimit + * @static + * @memberOf module:Collections + * @method + * @see [async.filter]{@link module:Collections.filter} + * @alias selectLimit + * @category Collection + * @param {Array|Iterable|Object} coll - A collection to iterate over. + * @param {number} limit - The maximum number of async operations at a time. + * @param {Function} iteratee - A truth test to apply to each item in `coll`. + * The `iteratee` is passed a `callback(err, truthValue)`, which must be called + * with a boolean argument once it has completed. Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called after all the + * `iteratee` functions have finished. Invoked with (err, results). + */ + var filterLimit = doParallelLimit(_filter); - function _insert(data, insertAtFront, callback) { - if (callback != null && typeof callback !== 'function') { - throw new Error('task callback must be a function'); - } - q.started = true; - if (!isArray(data)) { - data = [data]; - } - if (data.length === 0 && q.idle()) { - // call drain immediately if there are no tasks - return setImmediate$1(function () { - q.drain(); - }); - } + /** + * The same as [`filter`]{@link module:Collections.filter} but runs only a single async operation at a time. + * + * @name filterSeries + * @static + * @memberOf module:Collections + * @method + * @see [async.filter]{@link module:Collections.filter} + * @alias selectSeries + * @category Collection + * @param {Array|Iterable|Object} coll - A collection to iterate over. + * @param {Function} iteratee - A truth test to apply to each item in `coll`. + * The `iteratee` is passed a `callback(err, truthValue)`, which must be called + * with a boolean argument once it has completed. Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called after all the + * `iteratee` functions have finished. Invoked with (err, results) + */ + var filterSeries = doLimit(filterLimit, 1); - for (var i = 0, l = data.length; i < l; i++) { - var item = { - data: data[i], - callback: callback || noop - }; + /** + * Calls the asynchronous function `fn` with a callback parameter that allows it + * to call itself again, in series, indefinitely. + + * If an error is passed to the callback then `errback` is called with the + * error, and execution stops, otherwise it will never be called. + * + * @name forever + * @static + * @memberOf module:ControlFlow + * @method + * @category Control Flow + * @param {AsyncFunction} fn - an async function to call repeatedly. + * Invoked with (next). + * @param {Function} [errback] - when `fn` passes an error to it's callback, + * this function will be called, and execution stops. Invoked with (err). + * @example + * + * async.forever( + * function(next) { + * // next is suitable for passing to things that need a callback(err [, whatever]); + * // it will result in this function being called again. + * }, + * function(err) { + * // if next is called with a value in its first parameter, it will appear + * // in here as 'err', and execution will stop. + * } + * ); + */ + function forever(fn, errback) { + var done = onlyOnce(errback || noop); + var task = wrapAsync(ensureAsync(fn)); + + function next(err) { + if (err) return done(err); + task(next); + } + next(); + } - if (insertAtFront) { - q._tasks.unshift(item); + /** + * The same as [`groupBy`]{@link module:Collections.groupBy} but runs a maximum of `limit` async operations at a time. + * + * @name groupByLimit + * @static + * @memberOf module:Collections + * @method + * @see [async.groupBy]{@link module:Collections.groupBy} + * @category Collection + * @param {Array|Iterable|Object} coll - A collection to iterate over. + * @param {number} limit - The maximum number of async operations at a time. + * @param {AsyncFunction} iteratee - An async function to apply to each item in + * `coll`. + * The iteratee should complete with a `key` to group the value under. + * Invoked with (value, callback). + * @param {Function} [callback] - A callback which is called when all `iteratee` + * functions have finished, or an error occurs. Result is an `Object` whoses + * properties are arrays of values which returned the corresponding key. + */ + var groupByLimit = function(coll, limit, iteratee, callback) { + callback = callback || noop; + var _iteratee = wrapAsync(iteratee); + mapLimit(coll, limit, function(val, callback) { + _iteratee(val, function(err, key) { + if (err) return callback(err); + return callback(null, {key: key, val: val}); + }); + }, function(err, mapResults) { + var result = {}; + // from MDN, handle object having an `hasOwnProperty` prop + var hasOwnProperty = Object.prototype.hasOwnProperty; + + for (var i = 0; i < mapResults.length; i++) { + if (mapResults[i]) { + var key = mapResults[i].key; + var val = mapResults[i].val; + + if (hasOwnProperty.call(result, key)) { + result[key].push(val); } else { - q._tasks.push(item); + result[key] = [val]; } } - - if (!processingScheduled) { - processingScheduled = true; - setImmediate$1(function () { - processingScheduled = false; - q.process(); - }); - } } - function _next(tasks) { - return function (err) { - numRunning -= 1; - - for (var i = 0, l = tasks.length; i < l; i++) { - var task = tasks[i]; - - var index = baseIndexOf(workersList, task, 0); - if (index === 0) { - workersList.shift(); - } else if (index > 0) { - workersList.splice(index, 1); - } - - task.callback.apply(task, arguments); + return callback(err, result); + }); + }; - if (err != null) { - q.error(err, task.data); - } - } + /** + * Returns a new object, where each value corresponds to an array of items, from + * `coll`, that returned the corresponding key. That is, the keys of the object + * correspond to the values passed to the `iteratee` callback. + * + * Note: Since this function applies the `iteratee` to each item in parallel, + * there is no guarantee that the `iteratee` functions will complete in order. + * However, the values for each key in the `result` will be in the same order as + * the original `coll`. For Objects, the values will roughly be in the order of + * the original Objects' keys (but this can vary across JavaScript engines). + * + * @name groupBy + * @static + * @memberOf module:Collections + * @method + * @category Collection + * @param {Array|Iterable|Object} coll - A collection to iterate over. + * @param {AsyncFunction} iteratee - An async function to apply to each item in + * `coll`. + * The iteratee should complete with a `key` to group the value under. + * Invoked with (value, callback). + * @param {Function} [callback] - A callback which is called when all `iteratee` + * functions have finished, or an error occurs. Result is an `Object` whoses + * properties are arrays of values which returned the corresponding key. + * @example + * + * async.groupBy(['userId1', 'userId2', 'userId3'], function(userId, callback) { + * db.findById(userId, function(err, user) { + * if (err) return callback(err); + * return callback(null, user.age); + * }); + * }, function(err, result) { + * // result is object containing the userIds grouped by age + * // e.g. { 30: ['userId1', 'userId3'], 42: ['userId2']}; + * }); + */ + var groupBy = doLimit(groupByLimit, Infinity); - if (numRunning <= (q.concurrency - q.buffer)) { - q.unsaturated(); - } + /** + * The same as [`groupBy`]{@link module:Collections.groupBy} but runs only a single async operation at a time. + * + * @name groupBySeries + * @static + * @memberOf module:Collections + * @method + * @see [async.groupBy]{@link module:Collections.groupBy} + * @category Collection + * @param {Array|Iterable|Object} coll - A collection to iterate over. + * @param {number} limit - The maximum number of async operations at a time. + * @param {AsyncFunction} iteratee - An async function to apply to each item in + * `coll`. + * The iteratee should complete with a `key` to group the value under. + * Invoked with (value, callback). + * @param {Function} [callback] - A callback which is called when all `iteratee` + * functions have finished, or an error occurs. Result is an `Object` whoses + * properties are arrays of values which returned the corresponding key. + */ + var groupBySeries = doLimit(groupByLimit, 1); - if (q.idle()) { - q.drain(); - } - q.process(); - }; - } + /** + * Logs the result of an `async` function to the `console`. Only works in + * Node.js or in browsers that support `console.log` and `console.error` (such + * as FF and Chrome). If multiple arguments are returned from the async + * function, `console.log` is called on each argument in order. + * + * @name log + * @static + * @memberOf module:Utils + * @method + * @category Util + * @param {AsyncFunction} function - The function you want to eventually apply + * all arguments to. + * @param {...*} arguments... - Any number of arguments to apply to the function. + * @example + * + * // in a module + * var hello = function(name, callback) { + * setTimeout(function() { + * callback(null, 'hello ' + name); + * }, 1000); + * }; + * + * // in the node repl + * node> async.log(hello, 'world'); + * 'hello world' + */ + var log = consoleFunc('log'); - var isProcessing = false; - var q = { - _tasks: new DLL(), - concurrency: concurrency, - payload: payload, - saturated: noop, - unsaturated: noop, - buffer: concurrency / 4, - empty: noop, - drain: noop, - error: noop, - started: false, - paused: false, - push: function (data, callback) { - _insert(data, false, callback); - }, - kill: function () { - q.drain = noop; - q._tasks.empty(); - }, - unshift: function (data, callback) { - _insert(data, true, callback); - }, - remove: function (testFn) { - q._tasks.remove(testFn); - }, - process: function () { - // Avoid trying to start too many processing operations. This can occur - // when callbacks resolve synchronously (#1267). - if (isProcessing) { - return; - } - isProcessing = true; - while (!q.paused && numRunning < q.concurrency && q._tasks.length) { - var tasks = [], data = []; - var l = q._tasks.length; - if (q.payload) l = Math.min(l, q.payload); - for (var i = 0; i < l; i++) { - var node = q._tasks.shift(); - tasks.push(node); - workersList.push(node); - data.push(node.data); - } + /** + * The same as [`mapValues`]{@link module:Collections.mapValues} but runs a maximum of `limit` async operations at a + * time. + * + * @name mapValuesLimit + * @static + * @memberOf module:Collections + * @method + * @see [async.mapValues]{@link module:Collections.mapValues} + * @category Collection + * @param {Object} obj - A collection to iterate over. + * @param {number} limit - The maximum number of async operations at a time. + * @param {AsyncFunction} iteratee - A function to apply to each value and key + * in `coll`. + * The iteratee should complete with the transformed value as its result. + * Invoked with (value, key, callback). + * @param {Function} [callback] - A callback which is called when all `iteratee` + * functions have finished, or an error occurs. `result` is a new object consisting + * of each key from `obj`, with each transformed value on the right-hand side. + * Invoked with (err, result). + */ + function mapValuesLimit(obj, limit, iteratee, callback) { + callback = once(callback || noop); + var newObj = {}; + var _iteratee = wrapAsync(iteratee); + eachOfLimit(obj, limit, function(val, key, next) { + _iteratee(val, key, function (err, result) { + if (err) return next(err); + newObj[key] = result; + next(); + }); + }, function (err) { + callback(err, newObj); + }); + } - numRunning += 1; + /** + * A relative of [`map`]{@link module:Collections.map}, designed for use with objects. + * + * Produces a new Object by mapping each value of `obj` through the `iteratee` + * function. The `iteratee` is called each `value` and `key` from `obj` and a + * callback for when it has finished processing. Each of these callbacks takes + * two arguments: an `error`, and the transformed item from `obj`. If `iteratee` + * passes an error to its callback, the main `callback` (for the `mapValues` + * function) is immediately called with the error. + * + * Note, the order of the keys in the result is not guaranteed. The keys will + * be roughly in the order they complete, (but this is very engine-specific) + * + * @name mapValues + * @static + * @memberOf module:Collections + * @method + * @category Collection + * @param {Object} obj - A collection to iterate over. + * @param {AsyncFunction} iteratee - A function to apply to each value and key + * in `coll`. + * The iteratee should complete with the transformed value as its result. + * Invoked with (value, key, callback). + * @param {Function} [callback] - A callback which is called when all `iteratee` + * functions have finished, or an error occurs. `result` is a new object consisting + * of each key from `obj`, with each transformed value on the right-hand side. + * Invoked with (err, result). + * @example + * + * async.mapValues({ + * f1: 'file1', + * f2: 'file2', + * f3: 'file3' + * }, function (file, key, callback) { + * fs.stat(file, callback); + * }, function(err, result) { + * // result is now a map of stats for each file, e.g. + * // { + * // f1: [stats for file1], + * // f2: [stats for file2], + * // f3: [stats for file3] + * // } + * }); + */ - if (q._tasks.length === 0) { - q.empty(); - } + var mapValues = doLimit(mapValuesLimit, Infinity); - if (numRunning === q.concurrency) { - q.saturated(); - } + /** + * The same as [`mapValues`]{@link module:Collections.mapValues} but runs only a single async operation at a time. + * + * @name mapValuesSeries + * @static + * @memberOf module:Collections + * @method + * @see [async.mapValues]{@link module:Collections.mapValues} + * @category Collection + * @param {Object} obj - A collection to iterate over. + * @param {AsyncFunction} iteratee - A function to apply to each value and key + * in `coll`. + * The iteratee should complete with the transformed value as its result. + * Invoked with (value, key, callback). + * @param {Function} [callback] - A callback which is called when all `iteratee` + * functions have finished, or an error occurs. `result` is a new object consisting + * of each key from `obj`, with each transformed value on the right-hand side. + * Invoked with (err, result). + */ + var mapValuesSeries = doLimit(mapValuesLimit, 1); - var cb = onlyOnce(_next(tasks)); - _worker(data, cb); - } - isProcessing = false; - }, - length: function () { - return q._tasks.length; - }, - running: function () { - return numRunning; - }, - workersList: function () { - return workersList; - }, - idle: function () { - return q._tasks.length + numRunning === 0; - }, - pause: function () { - q.paused = true; - }, - resume: function () { - if (q.paused === false) { - return; - } - q.paused = false; - setImmediate$1(q.process); - } - }; - return q; - } + function has(obj, key) { + return key in obj; + } - /** - * A cargo of tasks for the worker function to complete. Cargo inherits all of - * the same methods and event callbacks as [`queue`]{@link module:ControlFlow.queue}. - * @typedef {Object} CargoObject - * @memberOf module:ControlFlow - * @property {Function} length - A function returning the number of items - * waiting to be processed. Invoke like `cargo.length()`. - * @property {number} payload - An `integer` for determining how many tasks - * should be process per round. This property can be changed after a `cargo` is - * created to alter the payload on-the-fly. - * @property {Function} push - Adds `task` to the `queue`. The callback is - * called once the `worker` has finished processing the task. Instead of a - * single task, an array of `tasks` can be submitted. The respective callback is - * used for every task in the list. Invoke like `cargo.push(task, [callback])`. - * @property {Function} saturated - A callback that is called when the - * `queue.length()` hits the concurrency and further tasks will be queued. - * @property {Function} empty - A callback that is called when the last item - * from the `queue` is given to a `worker`. - * @property {Function} drain - A callback that is called when the last item - * from the `queue` has returned from the `worker`. - * @property {Function} idle - a function returning false if there are items - * waiting or being processed, or true if not. Invoke like `cargo.idle()`. - * @property {Function} pause - a function that pauses the processing of tasks - * until `resume()` is called. Invoke like `cargo.pause()`. - * @property {Function} resume - a function that resumes the processing of - * queued tasks when the queue is paused. Invoke like `cargo.resume()`. - * @property {Function} kill - a function that removes the `drain` callback and - * empties remaining tasks from the queue forcing it to go idle. Invoke like `cargo.kill()`. - */ - - /** - * Creates a `cargo` object with the specified payload. Tasks added to the - * cargo will be processed altogether (up to the `payload` limit). If the - * `worker` is in progress, the task is queued until it becomes available. Once - * the `worker` has completed some tasks, each callback of those tasks is - * called. Check out [these](https://camo.githubusercontent.com/6bbd36f4cf5b35a0f11a96dcd2e97711ffc2fb37/68747470733a2f2f662e636c6f75642e6769746875622e636f6d2f6173736574732f313637363837312f36383130382f62626330636662302d356632392d313165322d393734662d3333393763363464633835382e676966) [animations](https://camo.githubusercontent.com/f4810e00e1c5f5f8addbe3e9f49064fd5d102699/68747470733a2f2f662e636c6f75642e6769746875622e636f6d2f6173736574732f313637363837312f36383130312f38346339323036362d356632392d313165322d383134662d3964336430323431336266642e676966) - * for how `cargo` and `queue` work. - * - * While [`queue`]{@link module:ControlFlow.queue} passes only one task to one of a group of workers - * at a time, cargo passes an array of tasks to a single worker, repeating - * when the worker is finished. - * - * @name cargo - * @static - * @memberOf module:ControlFlow - * @method - * @see [async.queue]{@link module:ControlFlow.queue} - * @category Control Flow - * @param {AsyncFunction} worker - An asynchronous function for processing an array - * of queued tasks. Invoked with `(tasks, callback)`. - * @param {number} [payload=Infinity] - An optional `integer` for determining - * how many tasks should be processed per round; if omitted, the default is - * unlimited. - * @returns {module:ControlFlow.CargoObject} A cargo object to manage the tasks. Callbacks can - * attached as certain properties to listen for specific events during the - * lifecycle of the cargo and inner queue. - * @example - * - * // create a cargo object with payload 2 - * var cargo = async.cargo(function(tasks, callback) { - * for (var i=0; i 2) { + result = slice(arguments, 1); } - - return callback(err, result); + results[key] = result; + callback(err); }); - }; + }, function (err) { + callback(err, results); + }); + } - /** - * Applies `iteratee` to each item in `coll`, concatenating the results. Returns - * the concatenated list. The `iteratee`s are called in parallel, and the - * results are concatenated as they return. There is no guarantee that the - * results array will be returned in the original order of `coll` passed to the - * `iteratee` function. - * - * @name concat - * @static - * @memberOf module:Collections - * @method - * @category Collection - * @param {Array|Iterable|Object} coll - A collection to iterate over. - * @param {AsyncFunction} iteratee - A function to apply to each item in `coll`, - * which should use an array as its result. Invoked with (item, callback). - * @param {Function} [callback(err)] - A callback which is called after all the - * `iteratee` functions have finished, or an error occurs. Results is an array - * containing the concatenated results of the `iteratee` function. Invoked with - * (err, results). - * @example - * - * async.concat(['dir1','dir2','dir3'], fs.readdir, function(err, files) { - * // files is now a list of filenames that exist in the 3 directories - * }); - */ - var concat = doLimit(concatLimit, Infinity); - - /** - * The same as [`concat`]{@link module:Collections.concat} but runs only a single async operation at a time. - * - * @name concatSeries - * @static - * @memberOf module:Collections - * @method - * @see [async.concat]{@link module:Collections.concat} - * @category Collection - * @param {Array|Iterable|Object} coll - A collection to iterate over. - * @param {AsyncFunction} iteratee - A function to apply to each item in `coll`. - * The iteratee should complete with an array an array of results. - * Invoked with (item, callback). - * @param {Function} [callback(err)] - A callback which is called after all the - * `iteratee` functions have finished, or an error occurs. Results is an array - * containing the concatenated results of the `iteratee` function. Invoked with - * (err, results). - */ - var concatSeries = doLimit(concatLimit, 1); - - /** - * Returns a function that when called, calls-back with the values provided. - * Useful as the first function in a [`waterfall`]{@link module:ControlFlow.waterfall}, or for plugging values in to - * [`auto`]{@link module:ControlFlow.auto}. - * - * @name constant - * @static - * @memberOf module:Utils - * @method - * @category Util - * @param {...*} arguments... - Any number of arguments to automatically invoke - * callback with. - * @returns {AsyncFunction} Returns a function that when invoked, automatically - * invokes the callback with the previous given arguments. - * @example - * - * async.waterfall([ - * async.constant(42), - * function (value, next) { - * // value === 42 - * }, - * //... - * ], callback); - * - * async.waterfall([ - * async.constant(filename, "utf8"), - * fs.readFile, - * function (fileData, next) { - * //... - * } - * //... - * ], callback); - * - * async.auto({ - * hostname: async.constant("https://server.net/"), - * port: findFreePort, - * launchServer: ["hostname", "port", function (options, cb) { - * startServer(options, cb); - * }], - * //... - * }, callback); - */ - var constant = function (/*...values*/) { - var values = slice(arguments); - var args = [null].concat(values); - return function (/*...ignoredArgs, callback*/) { - var callback = arguments[arguments.length - 1]; - return callback.apply(this, args); - }; - }; + /** + * Run the `tasks` collection of functions in parallel, without waiting until + * the previous function has completed. If any of the functions pass an error to + * its callback, the main `callback` is immediately called with the value of the + * error. Once the `tasks` have completed, the results are passed to the final + * `callback` as an array. + * + * **Note:** `parallel` is about kicking-off I/O tasks in parallel, not about + * parallel execution of code. If your tasks do not use any timers or perform + * any I/O, they will actually be executed in series. Any synchronous setup + * sections for each task will happen one after the other. JavaScript remains + * single-threaded. + * + * **Hint:** Use [`reflect`]{@link module:Utils.reflect} to continue the + * execution of other tasks when a task fails. + * + * It is also possible to use an object instead of an array. Each property will + * be run as a function and the results will be passed to the final `callback` + * as an object instead of an array. This can be a more readable way of handling + * results from {@link async.parallel}. + * + * @name parallel + * @static + * @memberOf module:ControlFlow + * @method + * @category Control Flow + * @param {Array|Iterable|Object} tasks - A collection of + * [async functions]{@link AsyncFunction} to run. + * Each async function can complete with any number of optional `result` values. + * @param {Function} [callback] - An optional callback to run once all the + * functions have completed successfully. This function gets a results array + * (or object) containing all the result arguments passed to the task callbacks. + * Invoked with (err, results). + * + * @example + * async.parallel([ + * function(callback) { + * setTimeout(function() { + * callback(null, 'one'); + * }, 200); + * }, + * function(callback) { + * setTimeout(function() { + * callback(null, 'two'); + * }, 100); + * } + * ], + * // optional callback + * function(err, results) { + * // the results array will equal ['one','two'] even though + * // the second function had a shorter timeout. + * }); + * + * // an example using an object instead of an array + * async.parallel({ + * one: function(callback) { + * setTimeout(function() { + * callback(null, 1); + * }, 200); + * }, + * two: function(callback) { + * setTimeout(function() { + * callback(null, 2); + * }, 100); + * } + * }, function(err, results) { + * // results is now equals to: {one: 1, two: 2} + * }); + */ + function parallelLimit(tasks, callback) { + _parallel(eachOf, tasks, callback); + } - /** - * This method returns the first argument it receives. - * - * @static - * @since 0.1.0 - * @memberOf _ - * @category Util - * @param {*} value Any value. - * @returns {*} Returns `value`. - * @example - * - * var object = { 'a': 1 }; - * - * console.log(_.identity(object) === object); - * // => true - */ - function identity(value) { - return value; - } + /** + * The same as [`parallel`]{@link module:ControlFlow.parallel} but runs a maximum of `limit` async operations at a + * time. + * + * @name parallelLimit + * @static + * @memberOf module:ControlFlow + * @method + * @see [async.parallel]{@link module:ControlFlow.parallel} + * @category Control Flow + * @param {Array|Iterable|Object} tasks - A collection of + * [async functions]{@link AsyncFunction} to run. + * Each async function can complete with any number of optional `result` values. + * @param {number} limit - The maximum number of async operations at a time. + * @param {Function} [callback] - An optional callback to run once all the + * functions have completed successfully. This function gets a results array + * (or object) containing all the result arguments passed to the task callbacks. + * Invoked with (err, results). + */ + function parallelLimit$1(tasks, limit, callback) { + _parallel(_eachOfLimit(limit), tasks, callback); + } - function _createTester(check, getResult) { - return function (eachfn, arr, iteratee, cb) { - cb = cb || noop; - var testPassed = false; - var testResult; - eachfn(arr, function (value, _, callback) { - iteratee(value, function (err, result) { - if (err) { - callback(err); - } else if (check(result) && !testResult) { - testPassed = true; - testResult = getResult(true, value); - callback(null, breakLoop); - } else { - callback(); - } - }); - }, function (err) { - if (err) { - cb(err); - } else { - cb(null, testPassed ? testResult : getResult(false)); - } - }); - }; - } + /** + * A queue of tasks for the worker function to complete. + * @typedef {Object} QueueObject + * @memberOf module:ControlFlow + * @property {Function} length - a function returning the number of items + * waiting to be processed. Invoke with `queue.length()`. + * @property {boolean} started - a boolean indicating whether or not any + * items have been pushed and processed by the queue. + * @property {Function} running - a function returning the number of items + * currently being processed. Invoke with `queue.running()`. + * @property {Function} workersList - a function returning the array of items + * currently being processed. Invoke with `queue.workersList()`. + * @property {Function} idle - a function returning false if there are items + * waiting or being processed, or true if not. Invoke with `queue.idle()`. + * @property {number} concurrency - an integer for determining how many `worker` + * functions should be run in parallel. This property can be changed after a + * `queue` is created to alter the concurrency on-the-fly. + * @property {Function} push - add a new task to the `queue`. Calls `callback` + * once the `worker` has finished processing the task. Instead of a single task, + * a `tasks` array can be submitted. The respective callback is used for every + * task in the list. Invoke with `queue.push(task, [callback])`, + * @property {Function} unshift - add a new task to the front of the `queue`. + * Invoke with `queue.unshift(task, [callback])`. + * @property {Function} remove - remove items from the queue that match a test + * function. The test function will be passed an object with a `data` property, + * and a `priority` property, if this is a + * [priorityQueue]{@link module:ControlFlow.priorityQueue} object. + * Invoked with `queue.remove(testFn)`, where `testFn` is of the form + * `function ({data, priority}) {}` and returns a Boolean. + * @property {Function} saturated - a callback that is called when the number of + * running workers hits the `concurrency` limit, and further tasks will be + * queued. + * @property {Function} unsaturated - a callback that is called when the number + * of running workers is less than the `concurrency` & `buffer` limits, and + * further tasks will not be queued. + * @property {number} buffer - A minimum threshold buffer in order to say that + * the `queue` is `unsaturated`. + * @property {Function} empty - a callback that is called when the last item + * from the `queue` is given to a `worker`. + * @property {Function} drain - a callback that is called when the last item + * from the `queue` has returned from the `worker`. + * @property {Function} error - a callback that is called when a task errors. + * Has the signature `function(error, task)`. + * @property {boolean} paused - a boolean for determining whether the queue is + * in a paused state. + * @property {Function} pause - a function that pauses the processing of tasks + * until `resume()` is called. Invoke with `queue.pause()`. + * @property {Function} resume - a function that resumes the processing of + * queued tasks when the queue is paused. Invoke with `queue.resume()`. + * @property {Function} kill - a function that removes the `drain` callback and + * empties remaining tasks from the queue forcing it to go idle. No more tasks + * should be pushed to the queue after calling this function. Invoke with `queue.kill()`. + */ - function _findGetResult(v, x) { - return x; - } - - /** - * Returns the first value in `coll` that passes an async truth test. The - * `iteratee` is applied in parallel, meaning the first iteratee to return - * `true` will fire the detect `callback` with that result. That means the - * result might not be the first item in the original `coll` (in terms of order) - * that passes the test. - - * If order within the original `coll` is important, then look at - * [`detectSeries`]{@link module:Collections.detectSeries}. - * - * @name detect - * @static - * @memberOf module:Collections - * @method - * @alias find - * @category Collections - * @param {Array|Iterable|Object} coll - A collection to iterate over. - * @param {AsyncFunction} iteratee - A truth test to apply to each item in `coll`. - * The iteratee must complete with a boolean value as its result. - * Invoked with (item, callback). - * @param {Function} [callback] - A callback which is called as soon as any - * iteratee returns `true`, or after all the `iteratee` functions have finished. - * Result will be the first item in the array that passes the truth test - * (iteratee) or the value `undefined` if none passed. Invoked with - * (err, result). - * @example - * - * async.detect(['file1','file2','file3'], function(filePath, callback) { - * fs.access(filePath, function(err) { - * callback(null, !err) - * }); - * }, function(err, result) { - * // result now equals the first file in the list that exists - * }); - */ - var detect = doParallel(_createTester(identity, _findGetResult)); - - /** - * The same as [`detect`]{@link module:Collections.detect} but runs a maximum of `limit` async operations at a - * time. - * - * @name detectLimit - * @static - * @memberOf module:Collections - * @method - * @see [async.detect]{@link module:Collections.detect} - * @alias findLimit - * @category Collections - * @param {Array|Iterable|Object} coll - A collection to iterate over. - * @param {number} limit - The maximum number of async operations at a time. - * @param {AsyncFunction} iteratee - A truth test to apply to each item in `coll`. - * The iteratee must complete with a boolean value as its result. - * Invoked with (item, callback). - * @param {Function} [callback] - A callback which is called as soon as any - * iteratee returns `true`, or after all the `iteratee` functions have finished. - * Result will be the first item in the array that passes the truth test - * (iteratee) or the value `undefined` if none passed. Invoked with - * (err, result). - */ - var detectLimit = doParallelLimit(_createTester(identity, _findGetResult)); - - /** - * The same as [`detect`]{@link module:Collections.detect} but runs only a single async operation at a time. - * - * @name detectSeries - * @static - * @memberOf module:Collections - * @method - * @see [async.detect]{@link module:Collections.detect} - * @alias findSeries - * @category Collections - * @param {Array|Iterable|Object} coll - A collection to iterate over. - * @param {AsyncFunction} iteratee - A truth test to apply to each item in `coll`. - * The iteratee must complete with a boolean value as its result. - * Invoked with (item, callback). - * @param {Function} [callback] - A callback which is called as soon as any - * iteratee returns `true`, or after all the `iteratee` functions have finished. - * Result will be the first item in the array that passes the truth test - * (iteratee) or the value `undefined` if none passed. Invoked with - * (err, result). - */ - var detectSeries = doLimit(detectLimit, 1); - - function consoleFunc(name) { - return function (fn/*, ...args*/) { - var args = slice(arguments, 1); - args.push(function (err/*, ...args*/) { - var args = slice(arguments, 1); - if (typeof console === 'object') { - if (err) { - if (console.error) { - console.error(err); - } - } else if (console[name]) { - arrayEach(args, function (x) { - console[name](x); - }); - } - } - }); - wrapAsync(fn).apply(null, args); - }; - } + /** + * Creates a `queue` object with the specified `concurrency`. Tasks added to the + * `queue` are processed in parallel (up to the `concurrency` limit). If all + * `worker`s are in progress, the task is queued until one becomes available. + * Once a `worker` completes a `task`, that `task`'s callback is called. + * + * @name queue + * @static + * @memberOf module:ControlFlow + * @method + * @category Control Flow + * @param {AsyncFunction} worker - An async function for processing a queued task. + * If you want to handle errors from an individual task, pass a callback to + * `q.push()`. Invoked with (task, callback). + * @param {number} [concurrency=1] - An `integer` for determining how many + * `worker` functions should be run in parallel. If omitted, the concurrency + * defaults to `1`. If the concurrency is `0`, an error is thrown. + * @returns {module:ControlFlow.QueueObject} A queue object to manage the tasks. Callbacks can + * attached as certain properties to listen for specific events during the + * lifecycle of the queue. + * @example + * + * // create a queue object with concurrency 2 + * var q = async.queue(function(task, callback) { + * console.log('hello ' + task.name); + * callback(); + * }, 2); + * + * // assign a callback + * q.drain = function() { + * console.log('all items have been processed'); + * }; + * + * // add some items to the queue + * q.push({name: 'foo'}, function(err) { + * console.log('finished processing foo'); + * }); + * q.push({name: 'bar'}, function (err) { + * console.log('finished processing bar'); + * }); + * + * // add some items to the queue (batch-wise) + * q.push([{name: 'baz'},{name: 'bay'},{name: 'bax'}], function(err) { + * console.log('finished processing item'); + * }); + * + * // add some items to the front of the queue + * q.unshift({name: 'bar'}, function (err) { + * console.log('finished processing bar'); + * }); + */ + var queue$1 = function (worker, concurrency) { + var _worker = wrapAsync(worker); + return queue(function (items, cb) { + _worker(items[0], cb); + }, concurrency, 1); + }; - /** - * Logs the result of an [`async` function]{@link AsyncFunction} to the - * `console` using `console.dir` to display the properties of the resulting object. - * Only works in Node.js or in browsers that support `console.dir` and - * `console.error` (such as FF and Chrome). - * If multiple arguments are returned from the async function, - * `console.dir` is called on each argument in order. - * - * @name dir - * @static - * @memberOf module:Utils - * @method - * @category Util - * @param {AsyncFunction} function - The function you want to eventually apply - * all arguments to. - * @param {...*} arguments... - Any number of arguments to apply to the function. - * @example - * - * // in a module - * var hello = function(name, callback) { - * setTimeout(function() { - * callback(null, {hello: name}); - * }, 1000); - * }; - * - * // in the node repl - * node> async.dir(hello, 'world'); - * {hello: 'world'} - */ - var dir = consoleFunc('dir'); - - /** - * The post-check version of [`during`]{@link module:ControlFlow.during}. To reflect the difference in - * the order of operations, the arguments `test` and `fn` are switched. - * - * Also a version of [`doWhilst`]{@link module:ControlFlow.doWhilst} with asynchronous `test` function. - * @name doDuring - * @static - * @memberOf module:ControlFlow - * @method - * @see [async.during]{@link module:ControlFlow.during} - * @category Control Flow - * @param {AsyncFunction} fn - An async function which is called each time - * `test` passes. Invoked with (callback). - * @param {AsyncFunction} test - asynchronous truth test to perform before each - * execution of `fn`. Invoked with (...args, callback), where `...args` are the - * non-error args from the previous callback of `fn`. - * @param {Function} [callback] - A callback which is called after the test - * function has failed and repeated execution of `fn` has stopped. `callback` - * will be passed an error if one occurred, otherwise `null`. - */ - function doDuring(fn, test, callback) { - callback = onlyOnce(callback || noop); - var _fn = wrapAsync(fn); - var _test = wrapAsync(test); - - function next(err/*, ...args*/) { - if (err) return callback(err); - var args = slice(arguments, 1); - args.push(check); - _test.apply(this, args); + /** + * The same as [async.queue]{@link module:ControlFlow.queue} only tasks are assigned a priority and + * completed in ascending priority order. + * + * @name priorityQueue + * @static + * @memberOf module:ControlFlow + * @method + * @see [async.queue]{@link module:ControlFlow.queue} + * @category Control Flow + * @param {AsyncFunction} worker - An async function for processing a queued task. + * If you want to handle errors from an individual task, pass a callback to + * `q.push()`. + * Invoked with (task, callback). + * @param {number} concurrency - An `integer` for determining how many `worker` + * functions should be run in parallel. If omitted, the concurrency defaults to + * `1`. If the concurrency is `0`, an error is thrown. + * @returns {module:ControlFlow.QueueObject} A priorityQueue object to manage the tasks. There are two + * differences between `queue` and `priorityQueue` objects: + * * `push(task, priority, [callback])` - `priority` should be a number. If an + * array of `tasks` is given, all tasks will be assigned the same priority. + * * The `unshift` method was removed. + */ + var priorityQueue = function(worker, concurrency) { + // Start with a normal queue + var q = queue$1(worker, concurrency); + + // Override push to accept second parameter representing priority + q.push = function(data, priority, callback) { + if (callback == null) callback = noop; + if (typeof callback !== 'function') { + throw new Error('task callback must be a function'); + } + q.started = true; + if (!isArray(data)) { + data = [data]; + } + if (data.length === 0) { + // call drain immediately if there are no tasks + return setImmediate$1(function() { + q.drain(); + }); } - function check(err, truth) { - if (err) return callback(err); - if (!truth) return callback(null); - _fn(next); - } - - check(null, true); - - } - - /** - * The post-check version of [`whilst`]{@link module:ControlFlow.whilst}. To reflect the difference in - * the order of operations, the arguments `test` and `iteratee` are switched. - * - * `doWhilst` is to `whilst` as `do while` is to `while` in plain JavaScript. - * - * @name doWhilst - * @static - * @memberOf module:ControlFlow - * @method - * @see [async.whilst]{@link module:ControlFlow.whilst} - * @category Control Flow - * @param {AsyncFunction} iteratee - A function which is called each time `test` - * passes. Invoked with (callback). - * @param {Function} test - synchronous truth test to perform after each - * execution of `iteratee`. Invoked with any non-error callback results of - * `iteratee`. - * @param {Function} [callback] - A callback which is called after the test - * function has failed and repeated execution of `iteratee` has stopped. - * `callback` will be passed an error and any arguments passed to the final - * `iteratee`'s callback. Invoked with (err, [results]); - */ - function doWhilst(iteratee, test, callback) { - callback = onlyOnce(callback || noop); - var _iteratee = wrapAsync(iteratee); - var next = function (err/*, ...args*/) { - if (err) return callback(err); - var args = slice(arguments, 1); - if (test.apply(this, args)) return _iteratee(next); - callback.apply(null, [null].concat(args)); - }; - _iteratee(next); - } - - /** - * Like ['doWhilst']{@link module:ControlFlow.doWhilst}, except the `test` is inverted. Note the - * argument ordering differs from `until`. - * - * @name doUntil - * @static - * @memberOf module:ControlFlow - * @method - * @see [async.doWhilst]{@link module:ControlFlow.doWhilst} - * @category Control Flow - * @param {AsyncFunction} iteratee - An async function which is called each time - * `test` fails. Invoked with (callback). - * @param {Function} test - synchronous truth test to perform after each - * execution of `iteratee`. Invoked with any non-error callback results of - * `iteratee`. - * @param {Function} [callback] - A callback which is called after the test - * function has passed and repeated execution of `iteratee` has stopped. `callback` - * will be passed an error and any arguments passed to the final `iteratee`'s - * callback. Invoked with (err, [results]); - */ - function doUntil(iteratee, test, callback) { - doWhilst(iteratee, function () { - return !test.apply(this, arguments); - }, callback); - } - - /** - * Like [`whilst`]{@link module:ControlFlow.whilst}, except the `test` is an asynchronous function that - * is passed a callback in the form of `function (err, truth)`. If error is - * passed to `test` or `fn`, the main callback is immediately called with the - * value of the error. - * - * @name during - * @static - * @memberOf module:ControlFlow - * @method - * @see [async.whilst]{@link module:ControlFlow.whilst} - * @category Control Flow - * @param {AsyncFunction} test - asynchronous truth test to perform before each - * execution of `fn`. Invoked with (callback). - * @param {AsyncFunction} fn - An async function which is called each time - * `test` passes. Invoked with (callback). - * @param {Function} [callback] - A callback which is called after the test - * function has failed and repeated execution of `fn` has stopped. `callback` - * will be passed an error, if one occurred, otherwise `null`. - * @example - * - * var count = 0; - * - * async.during( - * function (callback) { - * return callback(null, count < 5); - * }, - * function (callback) { - * count++; - * setTimeout(callback, 1000); - * }, - * function (err) { - * // 5 seconds have passed - * } - * ); - */ - function during(test, fn, callback) { - callback = onlyOnce(callback || noop); - var _fn = wrapAsync(fn); - var _test = wrapAsync(test); - - function next(err) { - if (err) return callback(err); - _test(check); + priority = priority || 0; + var nextNode = q._tasks.head; + while (nextNode && priority >= nextNode.priority) { + nextNode = nextNode.next; } - function check(err, truth) { - if (err) return callback(err); - if (!truth) return callback(null); - _fn(next); - } + for (var i = 0, l = data.length; i < l; i++) { + var item = { + data: data[i], + priority: priority, + callback: callback + }; - _test(check); - } + if (nextNode) { + q._tasks.insertBefore(nextNode, item); + } else { + q._tasks.push(item); + } + } + setImmediate$1(q.process); + }; - function _withoutIndex(iteratee) { - return function (value, index, callback) { - return iteratee(value, callback); - }; - } + // Remove unshift function + delete q.unshift; - /** - * Applies the function `iteratee` to each item in `coll`, in parallel. - * The `iteratee` is called with an item from the list, and a callback for when - * it has finished. If the `iteratee` passes an error to its `callback`, the - * main `callback` (for the `each` function) is immediately called with the - * error. - * - * Note, that since this function applies `iteratee` to each item in parallel, - * there is no guarantee that the iteratee functions will complete in order. - * - * @name each - * @static - * @memberOf module:Collections - * @method - * @alias forEach - * @category Collection - * @param {Array|Iterable|Object} coll - A collection to iterate over. - * @param {AsyncFunction} iteratee - An async function to apply to - * each item in `coll`. Invoked with (item, callback). - * The array index is not passed to the iteratee. - * If you need the index, use `eachOf`. - * @param {Function} [callback] - A callback which is called when all - * `iteratee` functions have finished, or an error occurs. Invoked with (err). - * @example - * - * // assuming openFiles is an array of file names and saveFile is a function - * // to save the modified contents of that file: - * - * async.each(openFiles, saveFile, function(err){ - * // if any of the saves produced an error, err would equal that error - * }); - * - * // assuming openFiles is an array of file names - * async.each(openFiles, function(file, callback) { - * - * // Perform operation on file here. - * console.log('Processing file ' + file); - * - * if( file.length > 32 ) { - * console.log('This file name is too long'); - * callback('File name too long'); - * } else { - * // Do work to process file here - * console.log('File processed'); - * callback(); - * } - * }, function(err) { - * // if any of the file processing produced an error, err would equal that error - * if( err ) { - * // One of the iterations produced an error. - * // All processing will now stop. - * console.log('A file failed to process'); - * } else { - * console.log('All files have been processed successfully'); - * } - * }); - */ - function eachLimit(coll, iteratee, callback) { - eachOf(coll, _withoutIndex(wrapAsync(iteratee)), callback); - } - - /** - * The same as [`each`]{@link module:Collections.each} but runs a maximum of `limit` async operations at a time. - * - * @name eachLimit - * @static - * @memberOf module:Collections - * @method - * @see [async.each]{@link module:Collections.each} - * @alias forEachLimit - * @category Collection - * @param {Array|Iterable|Object} coll - A collection to iterate over. - * @param {number} limit - The maximum number of async operations at a time. - * @param {AsyncFunction} iteratee - An async function to apply to each item in - * `coll`. - * The array index is not passed to the iteratee. - * If you need the index, use `eachOfLimit`. - * Invoked with (item, callback). - * @param {Function} [callback] - A callback which is called when all - * `iteratee` functions have finished, or an error occurs. Invoked with (err). - */ - function eachLimit$1(coll, limit, iteratee, callback) { - _eachOfLimit(limit)(coll, _withoutIndex(wrapAsync(iteratee)), callback); - } - - /** - * The same as [`each`]{@link module:Collections.each} but runs only a single async operation at a time. - * - * @name eachSeries - * @static - * @memberOf module:Collections - * @method - * @see [async.each]{@link module:Collections.each} - * @alias forEachSeries - * @category Collection - * @param {Array|Iterable|Object} coll - A collection to iterate over. - * @param {AsyncFunction} iteratee - An async function to apply to each - * item in `coll`. - * The array index is not passed to the iteratee. - * If you need the index, use `eachOfSeries`. - * Invoked with (item, callback). - * @param {Function} [callback] - A callback which is called when all - * `iteratee` functions have finished, or an error occurs. Invoked with (err). - */ - var eachSeries = doLimit(eachLimit$1, 1); - - /** - * Wrap an async function and ensure it calls its callback on a later tick of - * the event loop. If the function already calls its callback on a next tick, - * no extra deferral is added. This is useful for preventing stack overflows - * (`RangeError: Maximum call stack size exceeded`) and generally keeping - * [Zalgo](http://blog.izs.me/post/59142742143/designing-apis-for-asynchrony) - * contained. ES2017 `async` functions are returned as-is -- they are immune - * to Zalgo's corrupting influences, as they always resolve on a later tick. - * - * @name ensureAsync - * @static - * @memberOf module:Utils - * @method - * @category Util - * @param {AsyncFunction} fn - an async function, one that expects a node-style - * callback as its last argument. - * @returns {AsyncFunction} Returns a wrapped function with the exact same call - * signature as the function passed in. - * @example - * - * function sometimesAsync(arg, callback) { - * if (cache[arg]) { - * return callback(null, cache[arg]); // this would be synchronous!! - * } else { - * doSomeIO(arg, callback); // this IO would be asynchronous - * } - * } - * - * // this has a risk of stack overflows if many results are cached in a row - * async.mapSeries(args, sometimesAsync, done); - * - * // this will defer sometimesAsync's callback if necessary, - * // preventing stack overflows - * async.mapSeries(args, async.ensureAsync(sometimesAsync), done); - */ - function ensureAsync(fn) { - if (isAsync(fn)) return fn; - return initialParams(function (args, callback) { - var sync = true; - args.push(function () { - var innerArgs = arguments; - if (sync) { - setImmediate$1(function () { - callback.apply(null, innerArgs); - }); - } else { - callback.apply(null, innerArgs); - } - }); - fn.apply(this, args); - sync = false; - }); - } + return q; + }; - function notId(v) { - return !v; - } - - /** - * Returns `true` if every element in `coll` satisfies an async test. If any - * iteratee call returns `false`, the main `callback` is immediately called. - * - * @name every - * @static - * @memberOf module:Collections - * @method - * @alias all - * @category Collection - * @param {Array|Iterable|Object} coll - A collection to iterate over. - * @param {AsyncFunction} iteratee - An async truth test to apply to each item - * in the collection in parallel. - * The iteratee must complete with a boolean result value. - * Invoked with (item, callback). - * @param {Function} [callback] - A callback which is called after all the - * `iteratee` functions have finished. Result will be either `true` or `false` - * depending on the values of the async tests. Invoked with (err, result). - * @example - * - * async.every(['file1','file2','file3'], function(filePath, callback) { - * fs.access(filePath, function(err) { - * callback(null, !err) - * }); - * }, function(err, result) { - * // if result is true then every file exists - * }); - */ - var every = doParallel(_createTester(notId, notId)); - - /** - * The same as [`every`]{@link module:Collections.every} but runs a maximum of `limit` async operations at a time. - * - * @name everyLimit - * @static - * @memberOf module:Collections - * @method - * @see [async.every]{@link module:Collections.every} - * @alias allLimit - * @category Collection - * @param {Array|Iterable|Object} coll - A collection to iterate over. - * @param {number} limit - The maximum number of async operations at a time. - * @param {AsyncFunction} iteratee - An async truth test to apply to each item - * in the collection in parallel. - * The iteratee must complete with a boolean result value. - * Invoked with (item, callback). - * @param {Function} [callback] - A callback which is called after all the - * `iteratee` functions have finished. Result will be either `true` or `false` - * depending on the values of the async tests. Invoked with (err, result). - */ - var everyLimit = doParallelLimit(_createTester(notId, notId)); - - /** - * The same as [`every`]{@link module:Collections.every} but runs only a single async operation at a time. - * - * @name everySeries - * @static - * @memberOf module:Collections - * @method - * @see [async.every]{@link module:Collections.every} - * @alias allSeries - * @category Collection - * @param {Array|Iterable|Object} coll - A collection to iterate over. - * @param {AsyncFunction} iteratee - An async truth test to apply to each item - * in the collection in series. - * The iteratee must complete with a boolean result value. - * Invoked with (item, callback). - * @param {Function} [callback] - A callback which is called after all the - * `iteratee` functions have finished. Result will be either `true` or `false` - * depending on the values of the async tests. Invoked with (err, result). - */ - var everySeries = doLimit(everyLimit, 1); - - /** - * The base implementation of `_.property` without support for deep paths. - * - * @private - * @param {string} key The key of the property to get. - * @returns {Function} Returns the new accessor function. - */ - function baseProperty(key) { - return function (object) { - return object == null ? undefined : object[key]; - }; + /** + * Runs the `tasks` array of functions in parallel, without waiting until the + * previous function has completed. Once any of the `tasks` complete or pass an + * error to its callback, the main `callback` is immediately called. It's + * equivalent to `Promise.race()`. + * + * @name race + * @static + * @memberOf module:ControlFlow + * @method + * @category Control Flow + * @param {Array} tasks - An array containing [async functions]{@link AsyncFunction} + * to run. Each function can complete with an optional `result` value. + * @param {Function} callback - A callback to run once any of the functions have + * completed. This function gets an error or result from the first function that + * completed. Invoked with (err, result). + * @returns undefined + * @example + * + * async.race([ + * function(callback) { + * setTimeout(function() { + * callback(null, 'one'); + * }, 200); + * }, + * function(callback) { + * setTimeout(function() { + * callback(null, 'two'); + * }, 100); + * } + * ], + * // main callback + * function(err, result) { + * // the result will be equal to 'two' as it finishes earlier + * }); + */ + function race(tasks, callback) { + callback = once(callback || noop); + if (!isArray(tasks)) return callback(new TypeError('First argument to race must be an array of functions')); + if (!tasks.length) return callback(); + for (var i = 0, l = tasks.length; i < l; i++) { + wrapAsync(tasks[i])(callback); } + } - function filterArray(eachfn, arr, iteratee, callback) { - var truthValues = new Array(arr.length); - eachfn(arr, function (x, index, callback) { - iteratee(x, function (err, v) { - truthValues[index] = !!v; - callback(err); - }); - }, function (err) { - if (err) return callback(err); - var results = []; - for (var i = 0; i < arr.length; i++) { - if (truthValues[i]) results.push(arr[i]); - } - callback(null, results); - }); - } + /** + * Same as [`reduce`]{@link module:Collections.reduce}, only operates on `array` in reverse order. + * + * @name reduceRight + * @static + * @memberOf module:Collections + * @method + * @see [async.reduce]{@link module:Collections.reduce} + * @alias foldr + * @category Collection + * @param {Array} array - A collection to iterate over. + * @param {*} memo - The initial state of the reduction. + * @param {AsyncFunction} iteratee - A function applied to each item in the + * array to produce the next step in the reduction. + * The `iteratee` should complete with the next state of the reduction. + * If the iteratee complete with an error, the reduction is stopped and the + * main `callback` is immediately called with the error. + * Invoked with (memo, item, callback). + * @param {Function} [callback] - A callback which is called after all the + * `iteratee` functions have finished. Result is the reduced value. Invoked with + * (err, result). + */ + function reduceRight (array, memo, iteratee, callback) { + var reversed = slice(array).reverse(); + reduce(reversed, memo, iteratee, callback); + } - function filterGeneric(eachfn, coll, iteratee, callback) { - var results = []; - eachfn(coll, function (x, index, callback) { - iteratee(x, function (err, v) { - if (err) { - callback(err); + /** + * Wraps the async function in another function that always completes with a + * result object, even when it errors. + * + * The result object has either the property `error` or `value`. + * + * @name reflect + * @static + * @memberOf module:Utils + * @method + * @category Util + * @param {AsyncFunction} fn - The async function you want to wrap + * @returns {Function} - A function that always passes null to it's callback as + * the error. The second argument to the callback will be an `object` with + * either an `error` or a `value` property. + * @example + * + * async.parallel([ + * async.reflect(function(callback) { + * // do some stuff ... + * callback(null, 'one'); + * }), + * async.reflect(function(callback) { + * // do some more stuff but error ... + * callback('bad stuff happened'); + * }), + * async.reflect(function(callback) { + * // do some more stuff ... + * callback(null, 'two'); + * }) + * ], + * // optional callback + * function(err, results) { + * // values + * // results[0].value = 'one' + * // results[1].error = 'bad stuff happened' + * // results[2].value = 'two' + * }); + */ + function reflect(fn) { + var _fn = wrapAsync(fn); + return initialParams(function reflectOn(args, reflectCallback) { + args.push(function callback(error, cbArg) { + if (error) { + reflectCallback(null, { error: error }); + } else { + var value; + if (arguments.length <= 2) { + value = cbArg; } else { - if (v) { - results.push({index: index, value: x}); - } - callback(); + value = slice(arguments, 1); } - }); - }, function (err) { - if (err) { - callback(err); - } else { - callback(null, arrayMap(results.sort(function (a, b) { - return a.index - b.index; - }), baseProperty('value'))); + reflectCallback(null, { value: value }); } }); - } - - function _filter(eachfn, coll, iteratee, callback) { - var filter = isArrayLike(coll) ? filterArray : filterGeneric; - filter(eachfn, coll, wrapAsync(iteratee), callback || noop); - } - - /** - * Returns a new array of all the values in `coll` which pass an async truth - * test. This operation is performed in parallel, but the results array will be - * in the same order as the original. - * - * @name filter - * @static - * @memberOf module:Collections - * @method - * @alias select - * @category Collection - * @param {Array|Iterable|Object} coll - A collection to iterate over. - * @param {Function} iteratee - A truth test to apply to each item in `coll`. - * The `iteratee` is passed a `callback(err, truthValue)`, which must be called - * with a boolean argument once it has completed. Invoked with (item, callback). - * @param {Function} [callback] - A callback which is called after all the - * `iteratee` functions have finished. Invoked with (err, results). - * @example - * - * async.filter(['file1','file2','file3'], function(filePath, callback) { - * fs.access(filePath, function(err) { - * callback(null, !err) - * }); - * }, function(err, results) { - * // results now equals an array of the existing files - * }); - */ - var filter = doParallel(_filter); - - /** - * The same as [`filter`]{@link module:Collections.filter} but runs a maximum of `limit` async operations at a - * time. - * - * @name filterLimit - * @static - * @memberOf module:Collections - * @method - * @see [async.filter]{@link module:Collections.filter} - * @alias selectLimit - * @category Collection - * @param {Array|Iterable|Object} coll - A collection to iterate over. - * @param {number} limit - The maximum number of async operations at a time. - * @param {Function} iteratee - A truth test to apply to each item in `coll`. - * The `iteratee` is passed a `callback(err, truthValue)`, which must be called - * with a boolean argument once it has completed. Invoked with (item, callback). - * @param {Function} [callback] - A callback which is called after all the - * `iteratee` functions have finished. Invoked with (err, results). - */ - var filterLimit = doParallelLimit(_filter); - - /** - * The same as [`filter`]{@link module:Collections.filter} but runs only a single async operation at a time. - * - * @name filterSeries - * @static - * @memberOf module:Collections - * @method - * @see [async.filter]{@link module:Collections.filter} - * @alias selectSeries - * @category Collection - * @param {Array|Iterable|Object} coll - A collection to iterate over. - * @param {Function} iteratee - A truth test to apply to each item in `coll`. - * The `iteratee` is passed a `callback(err, truthValue)`, which must be called - * with a boolean argument once it has completed. Invoked with (item, callback). - * @param {Function} [callback] - A callback which is called after all the - * `iteratee` functions have finished. Invoked with (err, results) - */ - var filterSeries = doLimit(filterLimit, 1); - - /** - * Calls the asynchronous function `fn` with a callback parameter that allows it - * to call itself again, in series, indefinitely. - - * If an error is passed to the callback then `errback` is called with the - * error, and execution stops, otherwise it will never be called. - * - * @name forever - * @static - * @memberOf module:ControlFlow - * @method - * @category Control Flow - * @param {AsyncFunction} fn - an async function to call repeatedly. - * Invoked with (next). - * @param {Function} [errback] - when `fn` passes an error to it's callback, - * this function will be called, and execution stops. Invoked with (err). - * @example - * - * async.forever( - * function(next) { - * // next is suitable for passing to things that need a callback(err [, whatever]); - * // it will result in this function being called again. - * }, - * function(err) { - * // if next is called with a value in its first parameter, it will appear - * // in here as 'err', and execution will stop. - * } - * ); - */ - function forever(fn, errback) { - var done = onlyOnce(errback || noop); - var task = wrapAsync(ensureAsync(fn)); - - function next(err) { - if (err) return done(err); - task(next); - } - - next(); - } - - /** - * The same as [`groupBy`]{@link module:Collections.groupBy} but runs a maximum of `limit` async operations at a time. - * - * @name groupByLimit - * @static - * @memberOf module:Collections - * @method - * @see [async.groupBy]{@link module:Collections.groupBy} - * @category Collection - * @param {Array|Iterable|Object} coll - A collection to iterate over. - * @param {number} limit - The maximum number of async operations at a time. - * @param {AsyncFunction} iteratee - An async function to apply to each item in - * `coll`. - * The iteratee should complete with a `key` to group the value under. - * Invoked with (value, callback). - * @param {Function} [callback] - A callback which is called when all `iteratee` - * functions have finished, or an error occurs. Result is an `Object` whoses - * properties are arrays of values which returned the corresponding key. - */ - var groupByLimit = function (coll, limit, iteratee, callback) { - callback = callback || noop; - var _iteratee = wrapAsync(iteratee); - mapLimit(coll, limit, function (val, callback) { - _iteratee(val, function (err, key) { - if (err) return callback(err); - return callback(null, {key: key, val: val}); - }); - }, function (err, mapResults) { - var result = {}; - // from MDN, handle object having an `hasOwnProperty` prop - var hasOwnProperty = Object.prototype.hasOwnProperty; - - for (var i = 0; i < mapResults.length; i++) { - if (mapResults[i]) { - var key = mapResults[i].key; - var val = mapResults[i].val; - - if (hasOwnProperty.call(result, key)) { - result[key].push(val); - } else { - result[key] = [val]; - } - } - } - return callback(err, result); - }); - }; + return _fn.apply(this, args); + }); + } - /** - * Returns a new object, where each value corresponds to an array of items, from - * `coll`, that returned the corresponding key. That is, the keys of the object - * correspond to the values passed to the `iteratee` callback. - * - * Note: Since this function applies the `iteratee` to each item in parallel, - * there is no guarantee that the `iteratee` functions will complete in order. - * However, the values for each key in the `result` will be in the same order as - * the original `coll`. For Objects, the values will roughly be in the order of - * the original Objects' keys (but this can vary across JavaScript engines). - * - * @name groupBy - * @static - * @memberOf module:Collections - * @method - * @category Collection - * @param {Array|Iterable|Object} coll - A collection to iterate over. - * @param {AsyncFunction} iteratee - An async function to apply to each item in - * `coll`. - * The iteratee should complete with a `key` to group the value under. - * Invoked with (value, callback). - * @param {Function} [callback] - A callback which is called when all `iteratee` - * functions have finished, or an error occurs. Result is an `Object` whoses - * properties are arrays of values which returned the corresponding key. - * @example - * - * async.groupBy(['userId1', 'userId2', 'userId3'], function(userId, callback) { - * db.findById(userId, function(err, user) { - * if (err) return callback(err); - * return callback(null, user.age); - * }); - * }, function(err, result) { - * // result is object containing the userIds grouped by age - * // e.g. { 30: ['userId1', 'userId3'], 42: ['userId2']}; - * }); - */ - var groupBy = doLimit(groupByLimit, Infinity); - - /** - * The same as [`groupBy`]{@link module:Collections.groupBy} but runs only a single async operation at a time. - * - * @name groupBySeries - * @static - * @memberOf module:Collections - * @method - * @see [async.groupBy]{@link module:Collections.groupBy} - * @category Collection - * @param {Array|Iterable|Object} coll - A collection to iterate over. - * @param {number} limit - The maximum number of async operations at a time. - * @param {AsyncFunction} iteratee - An async function to apply to each item in - * `coll`. - * The iteratee should complete with a `key` to group the value under. - * Invoked with (value, callback). - * @param {Function} [callback] - A callback which is called when all `iteratee` - * functions have finished, or an error occurs. Result is an `Object` whoses - * properties are arrays of values which returned the corresponding key. - */ - var groupBySeries = doLimit(groupByLimit, 1); - - /** - * Logs the result of an `async` function to the `console`. Only works in - * Node.js or in browsers that support `console.log` and `console.error` (such - * as FF and Chrome). If multiple arguments are returned from the async - * function, `console.log` is called on each argument in order. - * - * @name log - * @static - * @memberOf module:Utils - * @method - * @category Util - * @param {AsyncFunction} function - The function you want to eventually apply - * all arguments to. - * @param {...*} arguments... - Any number of arguments to apply to the function. - * @example - * - * // in a module - * var hello = function(name, callback) { - * setTimeout(function() { - * callback(null, 'hello ' + name); - * }, 1000); - * }; - * - * // in the node repl - * node> async.log(hello, 'world'); - * 'hello world' - */ - var log = consoleFunc('log'); - - /** - * The same as [`mapValues`]{@link module:Collections.mapValues} but runs a maximum of `limit` async operations at a - * time. - * - * @name mapValuesLimit - * @static - * @memberOf module:Collections - * @method - * @see [async.mapValues]{@link module:Collections.mapValues} - * @category Collection - * @param {Object} obj - A collection to iterate over. - * @param {number} limit - The maximum number of async operations at a time. - * @param {AsyncFunction} iteratee - A function to apply to each value and key - * in `coll`. - * The iteratee should complete with the transformed value as its result. - * Invoked with (value, key, callback). - * @param {Function} [callback] - A callback which is called when all `iteratee` - * functions have finished, or an error occurs. `result` is a new object consisting - * of each key from `obj`, with each transformed value on the right-hand side. - * Invoked with (err, result). - */ - function mapValuesLimit(obj, limit, iteratee, callback) { - callback = once(callback || noop); - var newObj = {}; - var _iteratee = wrapAsync(iteratee); - eachOfLimit(obj, limit, function (val, key, next) { - _iteratee(val, key, function (err, result) { - if (err) return next(err); - newObj[key] = result; - next(); - }); - }, function (err) { - callback(err, newObj); + /** + * A helper function that wraps an array or an object of functions with `reflect`. + * + * @name reflectAll + * @static + * @memberOf module:Utils + * @method + * @see [async.reflect]{@link module:Utils.reflect} + * @category Util + * @param {Array|Object|Iterable} tasks - The collection of + * [async functions]{@link AsyncFunction} to wrap in `async.reflect`. + * @returns {Array} Returns an array of async functions, each wrapped in + * `async.reflect` + * @example + * + * let tasks = [ + * function(callback) { + * setTimeout(function() { + * callback(null, 'one'); + * }, 200); + * }, + * function(callback) { + * // do some more stuff but error ... + * callback(new Error('bad stuff happened')); + * }, + * function(callback) { + * setTimeout(function() { + * callback(null, 'two'); + * }, 100); + * } + * ]; + * + * async.parallel(async.reflectAll(tasks), + * // optional callback + * function(err, results) { + * // values + * // results[0].value = 'one' + * // results[1].error = Error('bad stuff happened') + * // results[2].value = 'two' + * }); + * + * // an example using an object instead of an array + * let tasks = { + * one: function(callback) { + * setTimeout(function() { + * callback(null, 'one'); + * }, 200); + * }, + * two: function(callback) { + * callback('two'); + * }, + * three: function(callback) { + * setTimeout(function() { + * callback(null, 'three'); + * }, 100); + * } + * }; + * + * async.parallel(async.reflectAll(tasks), + * // optional callback + * function(err, results) { + * // values + * // results.one.value = 'one' + * // results.two.error = 'two' + * // results.three.value = 'three' + * }); + */ + function reflectAll(tasks) { + var results; + if (isArray(tasks)) { + results = arrayMap(tasks, reflect); + } else { + results = {}; + baseForOwn(tasks, function(task, key) { + results[key] = reflect.call(this, task); }); } + return results; + } - /** - * A relative of [`map`]{@link module:Collections.map}, designed for use with objects. - * - * Produces a new Object by mapping each value of `obj` through the `iteratee` - * function. The `iteratee` is called each `value` and `key` from `obj` and a - * callback for when it has finished processing. Each of these callbacks takes - * two arguments: an `error`, and the transformed item from `obj`. If `iteratee` - * passes an error to its callback, the main `callback` (for the `mapValues` - * function) is immediately called with the error. - * - * Note, the order of the keys in the result is not guaranteed. The keys will - * be roughly in the order they complete, (but this is very engine-specific) - * - * @name mapValues - * @static - * @memberOf module:Collections - * @method - * @category Collection - * @param {Object} obj - A collection to iterate over. - * @param {AsyncFunction} iteratee - A function to apply to each value and key - * in `coll`. - * The iteratee should complete with the transformed value as its result. - * Invoked with (value, key, callback). - * @param {Function} [callback] - A callback which is called when all `iteratee` - * functions have finished, or an error occurs. `result` is a new object consisting - * of each key from `obj`, with each transformed value on the right-hand side. - * Invoked with (err, result). - * @example - * - * async.mapValues({ - * f1: 'file1', - * f2: 'file2', - * f3: 'file3' - * }, function (file, key, callback) { - * fs.stat(file, callback); - * }, function(err, result) { - * // result is now a map of stats for each file, e.g. - * // { - * // f1: [stats for file1], - * // f2: [stats for file2], - * // f3: [stats for file3] - * // } - * }); - */ - - var mapValues = doLimit(mapValuesLimit, Infinity); - - /** - * The same as [`mapValues`]{@link module:Collections.mapValues} but runs only a single async operation at a time. - * - * @name mapValuesSeries - * @static - * @memberOf module:Collections - * @method - * @see [async.mapValues]{@link module:Collections.mapValues} - * @category Collection - * @param {Object} obj - A collection to iterate over. - * @param {AsyncFunction} iteratee - A function to apply to each value and key - * in `coll`. - * The iteratee should complete with the transformed value as its result. - * Invoked with (value, key, callback). - * @param {Function} [callback] - A callback which is called when all `iteratee` - * functions have finished, or an error occurs. `result` is a new object consisting - * of each key from `obj`, with each transformed value on the right-hand side. - * Invoked with (err, result). - */ - var mapValuesSeries = doLimit(mapValuesLimit, 1); - - function has(obj, key) { - return key in obj; - } - - /** - * Caches the results of an async function. When creating a hash to store - * function results against, the callback is omitted from the hash and an - * optional hash function can be used. - * - * If no hash function is specified, the first argument is used as a hash key, - * which may work reasonably if it is a string or a data type that converts to a - * distinct string. Note that objects and arrays will not behave reasonably. - * Neither will cases where the other arguments are significant. In such cases, - * specify your own hash function. - * - * The cache of results is exposed as the `memo` property of the function - * returned by `memoize`. - * - * @name memoize - * @static - * @memberOf module:Utils - * @method - * @category Util - * @param {AsyncFunction} fn - The async function to proxy and cache results from. - * @param {Function} hasher - An optional function for generating a custom hash - * for storing results. It has all the arguments applied to it apart from the - * callback, and must be synchronous. - * @returns {AsyncFunction} a memoized version of `fn` - * @example - * - * var slow_fn = function(name, callback) { - * // do something - * callback(null, result); - * }; - * var fn = async.memoize(slow_fn); - * - * // fn can now be used as if it were slow_fn - * fn('some name', function() { - * // callback - * }); - */ - function memoize(fn, hasher) { - var memo = Object.create(null); - var queues = Object.create(null); - hasher = hasher || identity; - var _fn = wrapAsync(fn); - var memoized = initialParams(function memoized(args, callback) { - var key = hasher.apply(null, args); - if (has(memo, key)) { - setImmediate$1(function () { - callback.apply(null, memo[key]); - }); - } else if (has(queues, key)) { - queues[key].push(callback); - } else { - queues[key] = [callback]; - _fn.apply(null, args.concat(function (/*args*/) { - var args = slice(arguments); - memo[key] = args; - var q = queues[key]; - delete queues[key]; - for (var i = 0, l = q.length; i < l; i++) { - q[i].apply(null, args); - } - })); - } + function reject$1(eachfn, arr, iteratee, callback) { + _filter(eachfn, arr, function(value, cb) { + iteratee(value, function(err, v) { + cb(err, !v); }); - memoized.memo = memo; - memoized.unmemoized = fn; - return memoized; - } - - /** - * Calls `callback` on a later loop around the event loop. In Node.js this just - * calls `process.nextTicl`. In the browser it will use `setImmediate` if - * available, otherwise `setTimeout(callback, 0)`, which means other higher - * priority events may precede the execution of `callback`. - * - * This is used internally for browser-compatibility purposes. - * - * @name nextTick - * @static - * @memberOf module:Utils - * @method - * @see [async.setImmediate]{@link module:Utils.setImmediate} - * @category Util - * @param {Function} callback - The function to call on a later loop around - * the event loop. Invoked with (args...). - * @param {...*} args... - any number of additional arguments to pass to the - * callback on the next tick. - * @example - * - * var call_order = []; - * async.nextTick(function() { - * call_order.push('two'); - * // call_order now equals ['one','two'] - * }); - * call_order.push('one'); - * - * async.setImmediate(function (a, b, c) { - * // a, b, and c equal 1, 2, and 3 - * }, 1, 2, 3); - */ - var _defer$1; - - if (hasNextTick) { - _defer$1 = process.nextTick; - } else if (hasSetImmediate) { - _defer$1 = setImmediate; - } else { - _defer$1 = fallback; - } + }, callback); + } - var nextTick = wrap(_defer$1); + /** + * The opposite of [`filter`]{@link module:Collections.filter}. Removes values that pass an `async` truth test. + * + * @name reject + * @static + * @memberOf module:Collections + * @method + * @see [async.filter]{@link module:Collections.filter} + * @category Collection + * @param {Array|Iterable|Object} coll - A collection to iterate over. + * @param {Function} iteratee - An async truth test to apply to each item in + * `coll`. + * The should complete with a boolean value as its `result`. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called after all the + * `iteratee` functions have finished. Invoked with (err, results). + * @example + * + * async.reject(['file1','file2','file3'], function(filePath, callback) { + * fs.access(filePath, function(err) { + * callback(null, !err) + * }); + * }, function(err, results) { + * // results now equals an array of missing files + * createFiles(results); + * }); + */ + var reject = doParallel(reject$1); - function _parallel(eachfn, tasks, callback) { - callback = callback || noop; - var results = isArrayLike(tasks) ? [] : {}; + /** + * The same as [`reject`]{@link module:Collections.reject} but runs a maximum of `limit` async operations at a + * time. + * + * @name rejectLimit + * @static + * @memberOf module:Collections + * @method + * @see [async.reject]{@link module:Collections.reject} + * @category Collection + * @param {Array|Iterable|Object} coll - A collection to iterate over. + * @param {number} limit - The maximum number of async operations at a time. + * @param {Function} iteratee - An async truth test to apply to each item in + * `coll`. + * The should complete with a boolean value as its `result`. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called after all the + * `iteratee` functions have finished. Invoked with (err, results). + */ + var rejectLimit = doParallelLimit(reject$1); - eachfn(tasks, function (task, key, callback) { - wrapAsync(task)(function (err, result) { - if (arguments.length > 2) { - result = slice(arguments, 1); - } - results[key] = result; - callback(err); - }); - }, function (err) { - callback(err, results); - }); - } + /** + * The same as [`reject`]{@link module:Collections.reject} but runs only a single async operation at a time. + * + * @name rejectSeries + * @static + * @memberOf module:Collections + * @method + * @see [async.reject]{@link module:Collections.reject} + * @category Collection + * @param {Array|Iterable|Object} coll - A collection to iterate over. + * @param {Function} iteratee - An async truth test to apply to each item in + * `coll`. + * The should complete with a boolean value as its `result`. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called after all the + * `iteratee` functions have finished. Invoked with (err, results). + */ + var rejectSeries = doLimit(rejectLimit, 1); - /** - * Run the `tasks` collection of functions in parallel, without waiting until - * the previous function has completed. If any of the functions pass an error to - * its callback, the main `callback` is immediately called with the value of the - * error. Once the `tasks` have completed, the results are passed to the final - * `callback` as an array. - * - * **Note:** `parallel` is about kicking-off I/O tasks in parallel, not about - * parallel execution of code. If your tasks do not use any timers or perform - * any I/O, they will actually be executed in series. Any synchronous setup - * sections for each task will happen one after the other. JavaScript remains - * single-threaded. - * - * **Hint:** Use [`reflect`]{@link module:Utils.reflect} to continue the - * execution of other tasks when a task fails. - * - * It is also possible to use an object instead of an array. Each property will - * be run as a function and the results will be passed to the final `callback` - * as an object instead of an array. This can be a more readable way of handling - * results from {@link async.parallel}. - * - * @name parallel - * @static - * @memberOf module:ControlFlow - * @method - * @category Control Flow - * @param {Array|Iterable|Object} tasks - A collection of - * [async functions]{@link AsyncFunction} to run. - * Each async function can complete with any number of optional `result` values. - * @param {Function} [callback] - An optional callback to run once all the - * functions have completed successfully. This function gets a results array - * (or object) containing all the result arguments passed to the task callbacks. - * Invoked with (err, results). - * - * @example - * async.parallel([ - * function(callback) { - * setTimeout(function() { - * callback(null, 'one'); - * }, 200); - * }, - * function(callback) { - * setTimeout(function() { - * callback(null, 'two'); - * }, 100); - * } - * ], - * // optional callback - * function(err, results) { - * // the results array will equal ['one','two'] even though - * // the second function had a shorter timeout. - * }); - * - * // an example using an object instead of an array - * async.parallel({ - * one: function(callback) { - * setTimeout(function() { - * callback(null, 1); - * }, 200); - * }, - * two: function(callback) { - * setTimeout(function() { - * callback(null, 2); - * }, 100); - * } - * }, function(err, results) { - * // results is now equals to: {one: 1, two: 2} - * }); - */ - function parallelLimit(tasks, callback) { - _parallel(eachOf, tasks, callback); - } - - /** - * The same as [`parallel`]{@link module:ControlFlow.parallel} but runs a maximum of `limit` async operations at a - * time. - * - * @name parallelLimit - * @static - * @memberOf module:ControlFlow - * @method - * @see [async.parallel]{@link module:ControlFlow.parallel} - * @category Control Flow - * @param {Array|Iterable|Object} tasks - A collection of - * [async functions]{@link AsyncFunction} to run. - * Each async function can complete with any number of optional `result` values. - * @param {number} limit - The maximum number of async operations at a time. - * @param {Function} [callback] - An optional callback to run once all the - * functions have completed successfully. This function gets a results array - * (or object) containing all the result arguments passed to the task callbacks. - * Invoked with (err, results). - */ - function parallelLimit$1(tasks, limit, callback) { - _parallel(_eachOfLimit(limit), tasks, callback); - } - - /** - * A queue of tasks for the worker function to complete. - * @typedef {Object} QueueObject - * @memberOf module:ControlFlow - * @property {Function} length - a function returning the number of items - * waiting to be processed. Invoke with `queue.length()`. - * @property {boolean} started - a boolean indicating whether or not any - * items have been pushed and processed by the queue. - * @property {Function} running - a function returning the number of items - * currently being processed. Invoke with `queue.running()`. - * @property {Function} workersList - a function returning the array of items - * currently being processed. Invoke with `queue.workersList()`. - * @property {Function} idle - a function returning false if there are items - * waiting or being processed, or true if not. Invoke with `queue.idle()`. - * @property {number} concurrency - an integer for determining how many `worker` - * functions should be run in parallel. This property can be changed after a - * `queue` is created to alter the concurrency on-the-fly. - * @property {Function} push - add a new task to the `queue`. Calls `callback` - * once the `worker` has finished processing the task. Instead of a single task, - * a `tasks` array can be submitted. The respective callback is used for every - * task in the list. Invoke with `queue.push(task, [callback])`, - * @property {Function} unshift - add a new task to the front of the `queue`. - * Invoke with `queue.unshift(task, [callback])`. - * @property {Function} remove - remove items from the queue that match a test - * function. The test function will be passed an object with a `data` property, - * and a `priority` property, if this is a - * [priorityQueue]{@link module:ControlFlow.priorityQueue} object. - * Invoked with `queue.remove(testFn)`, where `testFn` is of the form - * `function ({data, priority}) {}` and returns a Boolean. - * @property {Function} saturated - a callback that is called when the number of - * running workers hits the `concurrency` limit, and further tasks will be - * queued. - * @property {Function} unsaturated - a callback that is called when the number - * of running workers is less than the `concurrency` & `buffer` limits, and - * further tasks will not be queued. - * @property {number} buffer - A minimum threshold buffer in order to say that - * the `queue` is `unsaturated`. - * @property {Function} empty - a callback that is called when the last item - * from the `queue` is given to a `worker`. - * @property {Function} drain - a callback that is called when the last item - * from the `queue` has returned from the `worker`. - * @property {Function} error - a callback that is called when a task errors. - * Has the signature `function(error, task)`. - * @property {boolean} paused - a boolean for determining whether the queue is - * in a paused state. - * @property {Function} pause - a function that pauses the processing of tasks - * until `resume()` is called. Invoke with `queue.pause()`. - * @property {Function} resume - a function that resumes the processing of - * queued tasks when the queue is paused. Invoke with `queue.resume()`. - * @property {Function} kill - a function that removes the `drain` callback and - * empties remaining tasks from the queue forcing it to go idle. No more tasks - * should be pushed to the queue after calling this function. Invoke with `queue.kill()`. - */ - - /** - * Creates a `queue` object with the specified `concurrency`. Tasks added to the - * `queue` are processed in parallel (up to the `concurrency` limit). If all - * `worker`s are in progress, the task is queued until one becomes available. - * Once a `worker` completes a `task`, that `task`'s callback is called. - * - * @name queue - * @static - * @memberOf module:ControlFlow - * @method - * @category Control Flow - * @param {AsyncFunction} worker - An async function for processing a queued task. - * If you want to handle errors from an individual task, pass a callback to - * `q.push()`. Invoked with (task, callback). - * @param {number} [concurrency=1] - An `integer` for determining how many - * `worker` functions should be run in parallel. If omitted, the concurrency - * defaults to `1`. If the concurrency is `0`, an error is thrown. - * @returns {module:ControlFlow.QueueObject} A queue object to manage the tasks. Callbacks can - * attached as certain properties to listen for specific events during the - * lifecycle of the queue. - * @example - * - * // create a queue object with concurrency 2 - * var q = async.queue(function(task, callback) { - * console.log('hello ' + task.name); - * callback(); - * }, 2); - * - * // assign a callback - * q.drain = function() { - * console.log('all items have been processed'); - * }; - * - * // add some items to the queue - * q.push({name: 'foo'}, function(err) { - * console.log('finished processing foo'); - * }); - * q.push({name: 'bar'}, function (err) { - * console.log('finished processing bar'); - * }); - * - * // add some items to the queue (batch-wise) - * q.push([{name: 'baz'},{name: 'bay'},{name: 'bax'}], function(err) { - * console.log('finished processing item'); - * }); - * - * // add some items to the front of the queue - * q.unshift({name: 'bar'}, function (err) { - * console.log('finished processing bar'); - * }); - */ - var queue$1 = function (worker, concurrency) { - var _worker = wrapAsync(worker); - return queue(function (items, cb) { - _worker(items[0], cb); - }, concurrency, 1); + /** + * Creates a function that returns `value`. + * + * @static + * @memberOf _ + * @since 2.4.0 + * @category Util + * @param {*} value The value to return from the new function. + * @returns {Function} Returns the new constant function. + * @example + * + * var objects = _.times(2, _.constant({ 'a': 1 })); + * + * console.log(objects); + * // => [{ 'a': 1 }, { 'a': 1 }] + * + * console.log(objects[0] === objects[1]); + * // => true + */ + function constant$1(value) { + return function() { + return value; }; + } - /** - * The same as [async.queue]{@link module:ControlFlow.queue} only tasks are assigned a priority and - * completed in ascending priority order. - * - * @name priorityQueue - * @static - * @memberOf module:ControlFlow - * @method - * @see [async.queue]{@link module:ControlFlow.queue} - * @category Control Flow - * @param {AsyncFunction} worker - An async function for processing a queued task. - * If you want to handle errors from an individual task, pass a callback to - * `q.push()`. - * Invoked with (task, callback). - * @param {number} concurrency - An `integer` for determining how many `worker` - * functions should be run in parallel. If omitted, the concurrency defaults to - * `1`. If the concurrency is `0`, an error is thrown. - * @returns {module:ControlFlow.QueueObject} A priorityQueue object to manage the tasks. There are two - * differences between `queue` and `priorityQueue` objects: - * * `push(task, priority, [callback])` - `priority` should be a number. If an - * array of `tasks` is given, all tasks will be assigned the same priority. - * * The `unshift` method was removed. - */ - var priorityQueue = function (worker, concurrency) { - // Start with a normal queue - var q = queue$1(worker, concurrency); - - // Override push to accept second parameter representing priority - q.push = function (data, priority, callback) { - if (callback == null) callback = noop; - if (typeof callback !== 'function') { - throw new Error('task callback must be a function'); - } - q.started = true; - if (!isArray(data)) { - data = [data]; - } - if (data.length === 0) { - // call drain immediately if there are no tasks - return setImmediate$1(function () { - q.drain(); - }); - } - - priority = priority || 0; - var nextNode = q._tasks.head; - while (nextNode && priority >= nextNode.priority) { - nextNode = nextNode.next; - } - - for (var i = 0, l = data.length; i < l; i++) { - var item = { - data: data[i], - priority: priority, - callback: callback - }; - - if (nextNode) { - q._tasks.insertBefore(nextNode, item); - } else { - q._tasks.push(item); - } - } - setImmediate$1(q.process); - }; - - // Remove unshift function - delete q.unshift; + /** + * Attempts to get a successful response from `task` no more than `times` times + * before returning an error. If the task is successful, the `callback` will be + * passed the result of the successful task. If all attempts fail, the callback + * will be passed the error and result (if any) of the final attempt. + * + * @name retry + * @static + * @memberOf module:ControlFlow + * @method + * @category Control Flow + * @see [async.retryable]{@link module:ControlFlow.retryable} + * @param {Object|number} [opts = {times: 5, interval: 0}| 5] - Can be either an + * object with `times` and `interval` or a number. + * * `times` - The number of attempts to make before giving up. The default + * is `5`. + * * `interval` - The time to wait between retries, in milliseconds. The + * default is `0`. The interval may also be specified as a function of the + * retry count (see example). + * * `errorFilter` - An optional synchronous function that is invoked on + * erroneous result. If it returns `true` the retry attempts will continue; + * if the function returns `false` the retry flow is aborted with the current + * attempt's error and result being returned to the final callback. + * Invoked with (err). + * * If `opts` is a number, the number specifies the number of times to retry, + * with the default interval of `0`. + * @param {AsyncFunction} task - An async function to retry. + * Invoked with (callback). + * @param {Function} [callback] - An optional callback which is called when the + * task has succeeded, or after the final failed attempt. It receives the `err` + * and `result` arguments of the last attempt at completing the `task`. Invoked + * with (err, results). + * + * @example + * + * // The `retry` function can be used as a stand-alone control flow by passing + * // a callback, as shown below: + * + * // try calling apiMethod 3 times + * async.retry(3, apiMethod, function(err, result) { + * // do something with the result + * }); + * + * // try calling apiMethod 3 times, waiting 200 ms between each retry + * async.retry({times: 3, interval: 200}, apiMethod, function(err, result) { + * // do something with the result + * }); + * + * // try calling apiMethod 10 times with exponential backoff + * // (i.e. intervals of 100, 200, 400, 800, 1600, ... milliseconds) + * async.retry({ + * times: 10, + * interval: function(retryCount) { + * return 50 * Math.pow(2, retryCount); + * } + * }, apiMethod, function(err, result) { + * // do something with the result + * }); + * + * // try calling apiMethod the default 5 times no delay between each retry + * async.retry(apiMethod, function(err, result) { + * // do something with the result + * }); + * + * // try calling apiMethod only when error condition satisfies, all other + * // errors will abort the retry control flow and return to final callback + * async.retry({ + * errorFilter: function(err) { + * return err.message === 'Temporary error'; // only retry on a specific error + * } + * }, apiMethod, function(err, result) { + * // do something with the result + * }); + * + * // to retry individual methods that are not as reliable within other + * // control flow functions, use the `retryable` wrapper: + * async.auto({ + * users: api.getUsers.bind(api), + * payments: async.retryable(3, api.getPayments.bind(api)) + * }, function(err, results) { + * // do something with the results + * }); + * + */ + function retry(opts, task, callback) { + var DEFAULT_TIMES = 5; + var DEFAULT_INTERVAL = 0; - return q; + var options = { + times: DEFAULT_TIMES, + intervalFunc: constant$1(DEFAULT_INTERVAL) }; - /** - * Runs the `tasks` array of functions in parallel, without waiting until the - * previous function has completed. Once any of the `tasks` complete or pass an - * error to its callback, the main `callback` is immediately called. It's - * equivalent to `Promise.race()`. - * - * @name race - * @static - * @memberOf module:ControlFlow - * @method - * @category Control Flow - * @param {Array} tasks - An array containing [async functions]{@link AsyncFunction} - * to run. Each function can complete with an optional `result` value. - * @param {Function} callback - A callback to run once any of the functions have - * completed. This function gets an error or result from the first function that - * completed. Invoked with (err, result). - * @returns undefined - * @example - * - * async.race([ - * function(callback) { - * setTimeout(function() { - * callback(null, 'one'); - * }, 200); - * }, - * function(callback) { - * setTimeout(function() { - * callback(null, 'two'); - * }, 100); - * } - * ], - * // main callback - * function(err, result) { - * // the result will be equal to 'two' as it finishes earlier - * }); - */ - function race(tasks, callback) { - callback = once(callback || noop); - if (!isArray(tasks)) return callback(new TypeError('First argument to race must be an array of functions')); - if (!tasks.length) return callback(); - for (var i = 0, l = tasks.length; i < l; i++) { - wrapAsync(tasks[i])(callback); - } - } - - /** - * Same as [`reduce`]{@link module:Collections.reduce}, only operates on `array` in reverse order. - * - * @name reduceRight - * @static - * @memberOf module:Collections - * @method - * @see [async.reduce]{@link module:Collections.reduce} - * @alias foldr - * @category Collection - * @param {Array} array - A collection to iterate over. - * @param {*} memo - The initial state of the reduction. - * @param {AsyncFunction} iteratee - A function applied to each item in the - * array to produce the next step in the reduction. - * The `iteratee` should complete with the next state of the reduction. - * If the iteratee complete with an error, the reduction is stopped and the - * main `callback` is immediately called with the error. - * Invoked with (memo, item, callback). - * @param {Function} [callback] - A callback which is called after all the - * `iteratee` functions have finished. Result is the reduced value. Invoked with - * (err, result). - */ - function reduceRight(array, memo, iteratee, callback) { - var reversed = slice(array).reverse(); - reduce(reversed, memo, iteratee, callback); - } - - /** - * Wraps the async function in another function that always completes with a - * result object, even when it errors. - * - * The result object has either the property `error` or `value`. - * - * @name reflect - * @static - * @memberOf module:Utils - * @method - * @category Util - * @param {AsyncFunction} fn - The async function you want to wrap - * @returns {Function} - A function that always passes null to it's callback as - * the error. The second argument to the callback will be an `object` with - * either an `error` or a `value` property. - * @example - * - * async.parallel([ - * async.reflect(function(callback) { - * // do some stuff ... - * callback(null, 'one'); - * }), - * async.reflect(function(callback) { - * // do some more stuff but error ... - * callback('bad stuff happened'); - * }), - * async.reflect(function(callback) { - * // do some more stuff ... - * callback(null, 'two'); - * }) - * ], - * // optional callback - * function(err, results) { - * // values - * // results[0].value = 'one' - * // results[1].error = 'bad stuff happened' - * // results[2].value = 'two' - * }); - */ - function reflect(fn) { - var _fn = wrapAsync(fn); - return initialParams(function reflectOn(args, reflectCallback) { - args.push(function callback(error, cbArg) { - if (error) { - reflectCallback(null, {error: error}); - } else { - var value; - if (arguments.length <= 2) { - value = cbArg; - } else { - value = slice(arguments, 1); - } - reflectCallback(null, {value: value}); - } - }); + function parseTimes(acc, t) { + if (typeof t === 'object') { + acc.times = +t.times || DEFAULT_TIMES; - return _fn.apply(this, args); - }); - } + acc.intervalFunc = typeof t.interval === 'function' ? + t.interval : + constant$1(+t.interval || DEFAULT_INTERVAL); - /** - * A helper function that wraps an array or an object of functions with `reflect`. - * - * @name reflectAll - * @static - * @memberOf module:Utils - * @method - * @see [async.reflect]{@link module:Utils.reflect} - * @category Util - * @param {Array|Object|Iterable} tasks - The collection of - * [async functions]{@link AsyncFunction} to wrap in `async.reflect`. - * @returns {Array} Returns an array of async functions, each wrapped in - * `async.reflect` - * @example - * - * let tasks = [ - * function(callback) { - * setTimeout(function() { - * callback(null, 'one'); - * }, 200); - * }, - * function(callback) { - * // do some more stuff but error ... - * callback(new Error('bad stuff happened')); - * }, - * function(callback) { - * setTimeout(function() { - * callback(null, 'two'); - * }, 100); - * } - * ]; - * - * async.parallel(async.reflectAll(tasks), - * // optional callback - * function(err, results) { - * // values - * // results[0].value = 'one' - * // results[1].error = Error('bad stuff happened') - * // results[2].value = 'two' - * }); - * - * // an example using an object instead of an array - * let tasks = { - * one: function(callback) { - * setTimeout(function() { - * callback(null, 'one'); - * }, 200); - * }, - * two: function(callback) { - * callback('two'); - * }, - * three: function(callback) { - * setTimeout(function() { - * callback(null, 'three'); - * }, 100); - * } - * }; - * - * async.parallel(async.reflectAll(tasks), - * // optional callback - * function(err, results) { - * // values - * // results.one.value = 'one' - * // results.two.error = 'two' - * // results.three.value = 'three' - * }); - */ - function reflectAll(tasks) { - var results; - if (isArray(tasks)) { - results = arrayMap(tasks, reflect); + acc.errorFilter = t.errorFilter; + } else if (typeof t === 'number' || typeof t === 'string') { + acc.times = +t || DEFAULT_TIMES; } else { - results = {}; - baseForOwn(tasks, function (task, key) { - results[key] = reflect.call(this, task); - }); + throw new Error("Invalid arguments for async.retry"); } - return results; } - function reject$1(eachfn, arr, iteratee, callback) { - _filter(eachfn, arr, function (value, cb) { - iteratee(value, function (err, v) { - cb(err, !v); - }); - }, callback); - } - - /** - * The opposite of [`filter`]{@link module:Collections.filter}. Removes values that pass an `async` truth test. - * - * @name reject - * @static - * @memberOf module:Collections - * @method - * @see [async.filter]{@link module:Collections.filter} - * @category Collection - * @param {Array|Iterable|Object} coll - A collection to iterate over. - * @param {Function} iteratee - An async truth test to apply to each item in - * `coll`. - * The should complete with a boolean value as its `result`. - * Invoked with (item, callback). - * @param {Function} [callback] - A callback which is called after all the - * `iteratee` functions have finished. Invoked with (err, results). - * @example - * - * async.reject(['file1','file2','file3'], function(filePath, callback) { - * fs.access(filePath, function(err) { - * callback(null, !err) - * }); - * }, function(err, results) { - * // results now equals an array of missing files - * createFiles(results); - * }); - */ - var reject = doParallel(reject$1); - - /** - * The same as [`reject`]{@link module:Collections.reject} but runs a maximum of `limit` async operations at a - * time. - * - * @name rejectLimit - * @static - * @memberOf module:Collections - * @method - * @see [async.reject]{@link module:Collections.reject} - * @category Collection - * @param {Array|Iterable|Object} coll - A collection to iterate over. - * @param {number} limit - The maximum number of async operations at a time. - * @param {Function} iteratee - An async truth test to apply to each item in - * `coll`. - * The should complete with a boolean value as its `result`. - * Invoked with (item, callback). - * @param {Function} [callback] - A callback which is called after all the - * `iteratee` functions have finished. Invoked with (err, results). - */ - var rejectLimit = doParallelLimit(reject$1); - - /** - * The same as [`reject`]{@link module:Collections.reject} but runs only a single async operation at a time. - * - * @name rejectSeries - * @static - * @memberOf module:Collections - * @method - * @see [async.reject]{@link module:Collections.reject} - * @category Collection - * @param {Array|Iterable|Object} coll - A collection to iterate over. - * @param {Function} iteratee - An async truth test to apply to each item in - * `coll`. - * The should complete with a boolean value as its `result`. - * Invoked with (item, callback). - * @param {Function} [callback] - A callback which is called after all the - * `iteratee` functions have finished. Invoked with (err, results). - */ - var rejectSeries = doLimit(rejectLimit, 1); - - /** - * Creates a function that returns `value`. - * - * @static - * @memberOf _ - * @since 2.4.0 - * @category Util - * @param {*} value The value to return from the new function. - * @returns {Function} Returns the new constant function. - * @example - * - * var objects = _.times(2, _.constant({ 'a': 1 })); - * - * console.log(objects); - * // => [{ 'a': 1 }, { 'a': 1 }] - * - * console.log(objects[0] === objects[1]); - * // => true - */ - function constant$1(value) { - return function () { - return value; - }; + if (arguments.length < 3 && typeof opts === 'function') { + callback = task || noop; + task = opts; + } else { + parseTimes(options, opts); + callback = callback || noop; } - /** - * Attempts to get a successful response from `task` no more than `times` times - * before returning an error. If the task is successful, the `callback` will be - * passed the result of the successful task. If all attempts fail, the callback - * will be passed the error and result (if any) of the final attempt. - * - * @name retry - * @static - * @memberOf module:ControlFlow - * @method - * @category Control Flow - * @see [async.retryable]{@link module:ControlFlow.retryable} - * @param {Object|number} [opts = {times: 5, interval: 0}| 5] - Can be either an - * object with `times` and `interval` or a number. - * * `times` - The number of attempts to make before giving up. The default - * is `5`. - * * `interval` - The time to wait between retries, in milliseconds. The - * default is `0`. The interval may also be specified as a function of the - * retry count (see example). - * * `errorFilter` - An optional synchronous function that is invoked on - * erroneous result. If it returns `true` the retry attempts will continue; - * if the function returns `false` the retry flow is aborted with the current - * attempt's error and result being returned to the final callback. - * Invoked with (err). - * * If `opts` is a number, the number specifies the number of times to retry, - * with the default interval of `0`. - * @param {AsyncFunction} task - An async function to retry. - * Invoked with (callback). - * @param {Function} [callback] - An optional callback which is called when the - * task has succeeded, or after the final failed attempt. It receives the `err` - * and `result` arguments of the last attempt at completing the `task`. Invoked - * with (err, results). - * - * @example - * - * // The `retry` function can be used as a stand-alone control flow by passing - * // a callback, as shown below: - * - * // try calling apiMethod 3 times - * async.retry(3, apiMethod, function(err, result) { - * // do something with the result - * }); - * - * // try calling apiMethod 3 times, waiting 200 ms between each retry - * async.retry({times: 3, interval: 200}, apiMethod, function(err, result) { - * // do something with the result - * }); - * - * // try calling apiMethod 10 times with exponential backoff - * // (i.e. intervals of 100, 200, 400, 800, 1600, ... milliseconds) - * async.retry({ - * times: 10, - * interval: function(retryCount) { - * return 50 * Math.pow(2, retryCount); - * } - * }, apiMethod, function(err, result) { - * // do something with the result - * }); - * - * // try calling apiMethod the default 5 times no delay between each retry - * async.retry(apiMethod, function(err, result) { - * // do something with the result - * }); - * - * // try calling apiMethod only when error condition satisfies, all other - * // errors will abort the retry control flow and return to final callback - * async.retry({ - * errorFilter: function(err) { - * return err.message === 'Temporary error'; // only retry on a specific error - * } - * }, apiMethod, function(err, result) { - * // do something with the result - * }); - * - * // to retry individual methods that are not as reliable within other - * // control flow functions, use the `retryable` wrapper: - * async.auto({ - * users: api.getUsers.bind(api), - * payments: async.retryable(3, api.getPayments.bind(api)) - * }, function(err, results) { - * // do something with the results - * }); - * - */ - function retry(opts, task, callback) { - var DEFAULT_TIMES = 5; - var DEFAULT_INTERVAL = 0; - - var options = { - times: DEFAULT_TIMES, - intervalFunc: constant$1(DEFAULT_INTERVAL) - }; - - function parseTimes(acc, t) { - if (typeof t === 'object') { - acc.times = +t.times || DEFAULT_TIMES; + if (typeof task !== 'function') { + throw new Error("Invalid arguments for async.retry"); + } - acc.intervalFunc = typeof t.interval === 'function' ? - t.interval : - constant$1(+t.interval || DEFAULT_INTERVAL); + var _task = wrapAsync(task); - acc.errorFilter = t.errorFilter; - } else if (typeof t === 'number' || typeof t === 'string') { - acc.times = +t || DEFAULT_TIMES; + var attempt = 1; + function retryAttempt() { + _task(function(err) { + if (err && attempt++ < options.times && + (typeof options.errorFilter != 'function' || + options.errorFilter(err))) { + setTimeout(retryAttempt, options.intervalFunc(attempt)); } else { - throw new Error("Invalid arguments for async.retry"); + callback.apply(null, arguments); } - } + }); + } - if (arguments.length < 3 && typeof opts === 'function') { - callback = task || noop; - task = opts; - } else { - parseTimes(options, opts); - callback = callback || noop; - } + retryAttempt(); + } - if (typeof task !== 'function') { - throw new Error("Invalid arguments for async.retry"); + /** + * A close relative of [`retry`]{@link module:ControlFlow.retry}. This method + * wraps a task and makes it retryable, rather than immediately calling it + * with retries. + * + * @name retryable + * @static + * @memberOf module:ControlFlow + * @method + * @see [async.retry]{@link module:ControlFlow.retry} + * @category Control Flow + * @param {Object|number} [opts = {times: 5, interval: 0}| 5] - optional + * options, exactly the same as from `retry` + * @param {AsyncFunction} task - the asynchronous function to wrap. + * This function will be passed any arguments passed to the returned wrapper. + * Invoked with (...args, callback). + * @returns {AsyncFunction} The wrapped function, which when invoked, will + * retry on an error, based on the parameters specified in `opts`. + * This function will accept the same parameters as `task`. + * @example + * + * async.auto({ + * dep1: async.retryable(3, getFromFlakyService), + * process: ["dep1", async.retryable(3, function (results, cb) { + * maybeProcessData(results.dep1, cb); + * })] + * }, callback); + */ + var retryable = function (opts, task) { + if (!task) { + task = opts; + opts = null; + } + var _task = wrapAsync(task); + return initialParams(function (args, callback) { + function taskFn(cb) { + _task.apply(null, args.concat(cb)); } - var _task = wrapAsync(task); + if (opts) retry(opts, taskFn, callback); + else retry(taskFn, callback); - var attempt = 1; + }); + }; - function retryAttempt() { - _task(function (err) { - if (err && attempt++ < options.times && - (typeof options.errorFilter != 'function' || - options.errorFilter(err))) { - setTimeout(retryAttempt, options.intervalFunc(attempt)); - } else { - callback.apply(null, arguments); - } - }); - } + /** + * Run the functions in the `tasks` collection in series, each one running once + * the previous function has completed. If any functions in the series pass an + * error to its callback, no more functions are run, and `callback` is + * immediately called with the value of the error. Otherwise, `callback` + * receives an array of results when `tasks` have completed. + * + * It is also possible to use an object instead of an array. Each property will + * be run as a function, and the results will be passed to the final `callback` + * as an object instead of an array. This can be a more readable way of handling + * results from {@link async.series}. + * + * **Note** that while many implementations preserve the order of object + * properties, the [ECMAScript Language Specification](http://www.ecma-international.org/ecma-262/5.1/#sec-8.6) + * explicitly states that + * + * > The mechanics and order of enumerating the properties is not specified. + * + * So if you rely on the order in which your series of functions are executed, + * and want this to work on all platforms, consider using an array. + * + * @name series + * @static + * @memberOf module:ControlFlow + * @method + * @category Control Flow + * @param {Array|Iterable|Object} tasks - A collection containing + * [async functions]{@link AsyncFunction} to run in series. + * Each function can complete with any number of optional `result` values. + * @param {Function} [callback] - An optional callback to run once all the + * functions have completed. This function gets a results array (or object) + * containing all the result arguments passed to the `task` callbacks. Invoked + * with (err, result). + * @example + * async.series([ + * function(callback) { + * // do some stuff ... + * callback(null, 'one'); + * }, + * function(callback) { + * // do some more stuff ... + * callback(null, 'two'); + * } + * ], + * // optional callback + * function(err, results) { + * // results is now equal to ['one', 'two'] + * }); + * + * async.series({ + * one: function(callback) { + * setTimeout(function() { + * callback(null, 1); + * }, 200); + * }, + * two: function(callback){ + * setTimeout(function() { + * callback(null, 2); + * }, 100); + * } + * }, function(err, results) { + * // results is now equal to: {one: 1, two: 2} + * }); + */ + function series(tasks, callback) { + _parallel(eachOfSeries, tasks, callback); + } - retryAttempt(); - } - - /** - * A close relative of [`retry`]{@link module:ControlFlow.retry}. This method - * wraps a task and makes it retryable, rather than immediately calling it - * with retries. - * - * @name retryable - * @static - * @memberOf module:ControlFlow - * @method - * @see [async.retry]{@link module:ControlFlow.retry} - * @category Control Flow - * @param {Object|number} [opts = {times: 5, interval: 0}| 5] - optional - * options, exactly the same as from `retry` - * @param {AsyncFunction} task - the asynchronous function to wrap. - * This function will be passed any arguments passed to the returned wrapper. - * Invoked with (...args, callback). - * @returns {AsyncFunction} The wrapped function, which when invoked, will - * retry on an error, based on the parameters specified in `opts`. - * This function will accept the same parameters as `task`. - * @example - * - * async.auto({ - * dep1: async.retryable(3, getFromFlakyService), - * process: ["dep1", async.retryable(3, function (results, cb) { - * maybeProcessData(results.dep1, cb); - * })] - * }, callback); - */ - var retryable = function (opts, task) { - if (!task) { - task = opts; - opts = null; - } - var _task = wrapAsync(task); - return initialParams(function (args, callback) { - function taskFn(cb) { - _task.apply(null, args.concat(cb)); - } + /** + * Returns `true` if at least one element in the `coll` satisfies an async test. + * If any iteratee call returns `true`, the main `callback` is immediately + * called. + * + * @name some + * @static + * @memberOf module:Collections + * @method + * @alias any + * @category Collection + * @param {Array|Iterable|Object} coll - A collection to iterate over. + * @param {AsyncFunction} iteratee - An async truth test to apply to each item + * in the collections in parallel. + * The iteratee should complete with a boolean `result` value. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called as soon as any + * iteratee returns `true`, or after all the iteratee functions have finished. + * Result will be either `true` or `false` depending on the values of the async + * tests. Invoked with (err, result). + * @example + * + * async.some(['file1','file2','file3'], function(filePath, callback) { + * fs.access(filePath, function(err) { + * callback(null, !err) + * }); + * }, function(err, result) { + * // if result is true then at least one of the files exists + * }); + */ + var some = doParallel(_createTester(Boolean, identity)); - if (opts) retry(opts, taskFn, callback); - else retry(taskFn, callback); + /** + * The same as [`some`]{@link module:Collections.some} but runs a maximum of `limit` async operations at a time. + * + * @name someLimit + * @static + * @memberOf module:Collections + * @method + * @see [async.some]{@link module:Collections.some} + * @alias anyLimit + * @category Collection + * @param {Array|Iterable|Object} coll - A collection to iterate over. + * @param {number} limit - The maximum number of async operations at a time. + * @param {AsyncFunction} iteratee - An async truth test to apply to each item + * in the collections in parallel. + * The iteratee should complete with a boolean `result` value. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called as soon as any + * iteratee returns `true`, or after all the iteratee functions have finished. + * Result will be either `true` or `false` depending on the values of the async + * tests. Invoked with (err, result). + */ + var someLimit = doParallelLimit(_createTester(Boolean, identity)); - }); - }; + /** + * The same as [`some`]{@link module:Collections.some} but runs only a single async operation at a time. + * + * @name someSeries + * @static + * @memberOf module:Collections + * @method + * @see [async.some]{@link module:Collections.some} + * @alias anySeries + * @category Collection + * @param {Array|Iterable|Object} coll - A collection to iterate over. + * @param {AsyncFunction} iteratee - An async truth test to apply to each item + * in the collections in series. + * The iteratee should complete with a boolean `result` value. + * Invoked with (item, callback). + * @param {Function} [callback] - A callback which is called as soon as any + * iteratee returns `true`, or after all the iteratee functions have finished. + * Result will be either `true` or `false` depending on the values of the async + * tests. Invoked with (err, result). + */ + var someSeries = doLimit(someLimit, 1); - /** - * Run the functions in the `tasks` collection in series, each one running once - * the previous function has completed. If any functions in the series pass an - * error to its callback, no more functions are run, and `callback` is - * immediately called with the value of the error. Otherwise, `callback` - * receives an array of results when `tasks` have completed. - * - * It is also possible to use an object instead of an array. Each property will - * be run as a function, and the results will be passed to the final `callback` - * as an object instead of an array. This can be a more readable way of handling - * results from {@link async.series}. - * - * **Note** that while many implementations preserve the order of object - * properties, the [ECMAScript Language Specification](http://www.ecma-international.org/ecma-262/5.1/#sec-8.6) - * explicitly states that - * - * > The mechanics and order of enumerating the properties is not specified. - * - * So if you rely on the order in which your series of functions are executed, - * and want this to work on all platforms, consider using an array. - * - * @name series - * @static - * @memberOf module:ControlFlow - * @method - * @category Control Flow - * @param {Array|Iterable|Object} tasks - A collection containing - * [async functions]{@link AsyncFunction} to run in series. - * Each function can complete with any number of optional `result` values. - * @param {Function} [callback] - An optional callback to run once all the - * functions have completed. This function gets a results array (or object) - * containing all the result arguments passed to the `task` callbacks. Invoked - * with (err, result). - * @example - * async.series([ - * function(callback) { - * // do some stuff ... - * callback(null, 'one'); - * }, - * function(callback) { - * // do some more stuff ... - * callback(null, 'two'); - * } - * ], - * // optional callback - * function(err, results) { - * // results is now equal to ['one', 'two'] - * }); - * - * async.series({ - * one: function(callback) { - * setTimeout(function() { - * callback(null, 1); - * }, 200); - * }, - * two: function(callback){ - * setTimeout(function() { - * callback(null, 2); - * }, 100); - * } - * }, function(err, results) { - * // results is now equal to: {one: 1, two: 2} - * }); - */ - function series(tasks, callback) { - _parallel(eachOfSeries, tasks, callback); - } - - /** - * Returns `true` if at least one element in the `coll` satisfies an async test. - * If any iteratee call returns `true`, the main `callback` is immediately - * called. - * - * @name some - * @static - * @memberOf module:Collections - * @method - * @alias any - * @category Collection - * @param {Array|Iterable|Object} coll - A collection to iterate over. - * @param {AsyncFunction} iteratee - An async truth test to apply to each item - * in the collections in parallel. - * The iteratee should complete with a boolean `result` value. - * Invoked with (item, callback). - * @param {Function} [callback] - A callback which is called as soon as any - * iteratee returns `true`, or after all the iteratee functions have finished. - * Result will be either `true` or `false` depending on the values of the async - * tests. Invoked with (err, result). - * @example - * - * async.some(['file1','file2','file3'], function(filePath, callback) { - * fs.access(filePath, function(err) { - * callback(null, !err) - * }); - * }, function(err, result) { - * // if result is true then at least one of the files exists - * }); - */ - var some = doParallel(_createTester(Boolean, identity)); - - /** - * The same as [`some`]{@link module:Collections.some} but runs a maximum of `limit` async operations at a time. - * - * @name someLimit - * @static - * @memberOf module:Collections - * @method - * @see [async.some]{@link module:Collections.some} - * @alias anyLimit - * @category Collection - * @param {Array|Iterable|Object} coll - A collection to iterate over. - * @param {number} limit - The maximum number of async operations at a time. - * @param {AsyncFunction} iteratee - An async truth test to apply to each item - * in the collections in parallel. - * The iteratee should complete with a boolean `result` value. - * Invoked with (item, callback). - * @param {Function} [callback] - A callback which is called as soon as any - * iteratee returns `true`, or after all the iteratee functions have finished. - * Result will be either `true` or `false` depending on the values of the async - * tests. Invoked with (err, result). - */ - var someLimit = doParallelLimit(_createTester(Boolean, identity)); - - /** - * The same as [`some`]{@link module:Collections.some} but runs only a single async operation at a time. - * - * @name someSeries - * @static - * @memberOf module:Collections - * @method - * @see [async.some]{@link module:Collections.some} - * @alias anySeries - * @category Collection - * @param {Array|Iterable|Object} coll - A collection to iterate over. - * @param {AsyncFunction} iteratee - An async truth test to apply to each item - * in the collections in series. - * The iteratee should complete with a boolean `result` value. - * Invoked with (item, callback). - * @param {Function} [callback] - A callback which is called as soon as any - * iteratee returns `true`, or after all the iteratee functions have finished. - * Result will be either `true` or `false` depending on the values of the async - * tests. Invoked with (err, result). - */ - var someSeries = doLimit(someLimit, 1); - - /** - * Sorts a list by the results of running each `coll` value through an async - * `iteratee`. - * - * @name sortBy - * @static - * @memberOf module:Collections - * @method - * @category Collection - * @param {Array|Iterable|Object} coll - A collection to iterate over. - * @param {AsyncFunction} iteratee - An async function to apply to each item in - * `coll`. - * The iteratee should complete with a value to use as the sort criteria as - * its `result`. - * Invoked with (item, callback). - * @param {Function} callback - A callback which is called after all the - * `iteratee` functions have finished, or an error occurs. Results is the items - * from the original `coll` sorted by the values returned by the `iteratee` - * calls. Invoked with (err, results). - * @example - * - * async.sortBy(['file1','file2','file3'], function(file, callback) { - * fs.stat(file, function(err, stats) { - * callback(err, stats.mtime); - * }); - * }, function(err, results) { - * // results is now the original array of files sorted by - * // modified date - * }); - * - * // By modifying the callback parameter the - * // sorting order can be influenced: - * - * // ascending order - * async.sortBy([1,9,3,5], function(x, callback) { - * callback(null, x); - * }, function(err,result) { - * // result callback - * }); - * - * // descending order - * async.sortBy([1,9,3,5], function(x, callback) { - * callback(null, x*-1); //<- x*-1 instead of x, turns the order around - * }, function(err,result) { - * // result callback - * }); - */ - function sortBy(coll, iteratee, callback) { - var _iteratee = wrapAsync(iteratee); - map(coll, function (x, callback) { - _iteratee(x, function (err, criteria) { - if (err) return callback(err); - callback(null, {value: x, criteria: criteria}); - }); - }, function (err, results) { + /** + * Sorts a list by the results of running each `coll` value through an async + * `iteratee`. + * + * @name sortBy + * @static + * @memberOf module:Collections + * @method + * @category Collection + * @param {Array|Iterable|Object} coll - A collection to iterate over. + * @param {AsyncFunction} iteratee - An async function to apply to each item in + * `coll`. + * The iteratee should complete with a value to use as the sort criteria as + * its `result`. + * Invoked with (item, callback). + * @param {Function} callback - A callback which is called after all the + * `iteratee` functions have finished, or an error occurs. Results is the items + * from the original `coll` sorted by the values returned by the `iteratee` + * calls. Invoked with (err, results). + * @example + * + * async.sortBy(['file1','file2','file3'], function(file, callback) { + * fs.stat(file, function(err, stats) { + * callback(err, stats.mtime); + * }); + * }, function(err, results) { + * // results is now the original array of files sorted by + * // modified date + * }); + * + * // By modifying the callback parameter the + * // sorting order can be influenced: + * + * // ascending order + * async.sortBy([1,9,3,5], function(x, callback) { + * callback(null, x); + * }, function(err,result) { + * // result callback + * }); + * + * // descending order + * async.sortBy([1,9,3,5], function(x, callback) { + * callback(null, x*-1); //<- x*-1 instead of x, turns the order around + * }, function(err,result) { + * // result callback + * }); + */ + function sortBy (coll, iteratee, callback) { + var _iteratee = wrapAsync(iteratee); + map(coll, function (x, callback) { + _iteratee(x, function (err, criteria) { if (err) return callback(err); - callback(null, arrayMap(results.sort(comparator), baseProperty('value'))); + callback(null, {value: x, criteria: criteria}); }); + }, function (err, results) { + if (err) return callback(err); + callback(null, arrayMap(results.sort(comparator), baseProperty('value'))); + }); - function comparator(left, right) { - var a = left.criteria, b = right.criteria; - return a < b ? -1 : a > b ? 1 : 0; - } - } - - /** - * Sets a time limit on an asynchronous function. If the function does not call - * its callback within the specified milliseconds, it will be called with a - * timeout error. The code property for the error object will be `'ETIMEDOUT'`. - * - * @name timeout - * @static - * @memberOf module:Utils - * @method - * @category Util - * @param {AsyncFunction} asyncFn - The async function to limit in time. - * @param {number} milliseconds - The specified time limit. - * @param {*} [info] - Any variable you want attached (`string`, `object`, etc) - * to timeout Error for more information.. - * @returns {AsyncFunction} Returns a wrapped function that can be used with any - * of the control flow functions. - * Invoke this function with the same parameters as you would `asyncFunc`. - * @example - * - * function myFunction(foo, callback) { - * doAsyncTask(foo, function(err, data) { - * // handle errors - * if (err) return callback(err); - * - * // do some stuff ... - * - * // return processed data - * return callback(null, data); - * }); - * } - * - * var wrapped = async.timeout(myFunction, 1000); - * - * // call `wrapped` as you would `myFunction` - * wrapped({ bar: 'bar' }, function(err, data) { - * // if `myFunction` takes < 1000 ms to execute, `err` - * // and `data` will have their expected values - * - * // else `err` will be an Error with the code 'ETIMEDOUT' - * }); - */ - function timeout(asyncFn, milliseconds, info) { - var fn = wrapAsync(asyncFn); - - return initialParams(function (args, callback) { - var timedOut = false; - var timer; - - function timeoutCallback() { - var name = asyncFn.name || 'anonymous'; - var error = new Error('Callback function "' + name + '" timed out.'); - error.code = 'ETIMEDOUT'; - if (info) { - error.info = info; - } - timedOut = true; - callback(error); - } + function comparator(left, right) { + var a = left.criteria, b = right.criteria; + return a < b ? -1 : a > b ? 1 : 0; + } + } - args.push(function () { - if (!timedOut) { - callback.apply(null, arguments); - clearTimeout(timer); - } - }); + /** + * Sets a time limit on an asynchronous function. If the function does not call + * its callback within the specified milliseconds, it will be called with a + * timeout error. The code property for the error object will be `'ETIMEDOUT'`. + * + * @name timeout + * @static + * @memberOf module:Utils + * @method + * @category Util + * @param {AsyncFunction} asyncFn - The async function to limit in time. + * @param {number} milliseconds - The specified time limit. + * @param {*} [info] - Any variable you want attached (`string`, `object`, etc) + * to timeout Error for more information.. + * @returns {AsyncFunction} Returns a wrapped function that can be used with any + * of the control flow functions. + * Invoke this function with the same parameters as you would `asyncFunc`. + * @example + * + * function myFunction(foo, callback) { + * doAsyncTask(foo, function(err, data) { + * // handle errors + * if (err) return callback(err); + * + * // do some stuff ... + * + * // return processed data + * return callback(null, data); + * }); + * } + * + * var wrapped = async.timeout(myFunction, 1000); + * + * // call `wrapped` as you would `myFunction` + * wrapped({ bar: 'bar' }, function(err, data) { + * // if `myFunction` takes < 1000 ms to execute, `err` + * // and `data` will have their expected values + * + * // else `err` will be an Error with the code 'ETIMEDOUT' + * }); + */ + function timeout(asyncFn, milliseconds, info) { + var fn = wrapAsync(asyncFn); + + return initialParams(function (args, callback) { + var timedOut = false; + var timer; + + function timeoutCallback() { + var name = asyncFn.name || 'anonymous'; + var error = new Error('Callback function "' + name + '" timed out.'); + error.code = 'ETIMEDOUT'; + if (info) { + error.info = info; + } + timedOut = true; + callback(error); + } - // setup timer and call original function - timer = setTimeout(timeoutCallback, milliseconds); - fn.apply(null, args); + args.push(function () { + if (!timedOut) { + callback.apply(null, arguments); + clearTimeout(timer); + } }); - } - /* Built-in method references for those with the same name as other `lodash` methods. */ - var nativeCeil = Math.ceil; - var nativeMax = Math.max; - - /** - * The base implementation of `_.range` and `_.rangeRight` which doesn't - * coerce arguments. - * - * @private - * @param {number} start The start of the range. - * @param {number} end The end of the range. - * @param {number} step The value to increment or decrement by. - * @param {boolean} [fromRight] Specify iterating from right to left. - * @returns {Array} Returns the range of numbers. - */ - function baseRange(start, end, step, fromRight) { - var index = -1, - length = nativeMax(nativeCeil((end - start) / (step || 1)), 0), - result = Array(length); + // setup timer and call original function + timer = setTimeout(timeoutCallback, milliseconds); + fn.apply(null, args); + }); + } - while (length--) { - result[fromRight ? length : ++index] = start; - start += step; - } - return result; - } + /* Built-in method references for those with the same name as other `lodash` methods. */ + var nativeCeil = Math.ceil; + var nativeMax = Math.max; - /** - * The same as [times]{@link module:ControlFlow.times} but runs a maximum of `limit` async operations at a - * time. - * - * @name timesLimit - * @static - * @memberOf module:ControlFlow - * @method - * @see [async.times]{@link module:ControlFlow.times} - * @category Control Flow - * @param {number} count - The number of times to run the function. - * @param {number} limit - The maximum number of async operations at a time. - * @param {AsyncFunction} iteratee - The async function to call `n` times. - * Invoked with the iteration index and a callback: (n, next). - * @param {Function} callback - see [async.map]{@link module:Collections.map}. - */ - function timeLimit(count, limit, iteratee, callback) { - var _iteratee = wrapAsync(iteratee); - mapLimit(baseRange(0, count, 1), limit, _iteratee, callback); - } - - /** - * Calls the `iteratee` function `n` times, and accumulates results in the same - * manner you would use with [map]{@link module:Collections.map}. - * - * @name times - * @static - * @memberOf module:ControlFlow - * @method - * @see [async.map]{@link module:Collections.map} - * @category Control Flow - * @param {number} n - The number of times to run the function. - * @param {AsyncFunction} iteratee - The async function to call `n` times. - * Invoked with the iteration index and a callback: (n, next). - * @param {Function} callback - see {@link module:Collections.map}. - * @example - * - * // Pretend this is some complicated async factory - * var createUser = function(id, callback) { - * callback(null, { - * id: 'user' + id - * }); - * }; - * - * // generate 5 users - * async.times(5, function(n, next) { - * createUser(n, function(err, user) { - * next(err, user); - * }); - * }, function(err, users) { - * // we should now have 5 users - * }); - */ - var times = doLimit(timeLimit, Infinity); - - /** - * The same as [times]{@link module:ControlFlow.times} but runs only a single async operation at a time. - * - * @name timesSeries - * @static - * @memberOf module:ControlFlow - * @method - * @see [async.times]{@link module:ControlFlow.times} - * @category Control Flow - * @param {number} n - The number of times to run the function. - * @param {AsyncFunction} iteratee - The async function to call `n` times. - * Invoked with the iteration index and a callback: (n, next). - * @param {Function} callback - see {@link module:Collections.map}. - */ - var timesSeries = doLimit(timeLimit, 1); - - /** - * A relative of `reduce`. Takes an Object or Array, and iterates over each - * element in series, each step potentially mutating an `accumulator` value. - * The type of the accumulator defaults to the type of collection passed in. - * - * @name transform - * @static - * @memberOf module:Collections - * @method - * @category Collection - * @param {Array|Iterable|Object} coll - A collection to iterate over. - * @param {*} [accumulator] - The initial state of the transform. If omitted, - * it will default to an empty Object or Array, depending on the type of `coll` - * @param {AsyncFunction} iteratee - A function applied to each item in the - * collection that potentially modifies the accumulator. - * Invoked with (accumulator, item, key, callback). - * @param {Function} [callback] - A callback which is called after all the - * `iteratee` functions have finished. Result is the transformed accumulator. - * Invoked with (err, result). - * @example - * - * async.transform([1,2,3], function(acc, item, index, callback) { - * // pointless async: - * process.nextTick(function() { - * acc.push(item * 2) - * callback(null) - * }); - * }, function(err, result) { - * // result is now equal to [2, 4, 6] - * }); - * - * @example - * - * async.transform({a: 1, b: 2, c: 3}, function (obj, val, key, callback) { - * setImmediate(function () { - * obj[key] = val * 2; - * callback(); - * }) - * }, function (err, result) { - * // result is equal to {a: 2, b: 4, c: 6} - * }) - */ - function transform(coll, accumulator, iteratee, callback) { - if (arguments.length <= 3) { - callback = iteratee; - iteratee = accumulator; - accumulator = isArray(coll) ? [] : {}; - } - callback = once(callback || noop); - var _iteratee = wrapAsync(iteratee); + /** + * The base implementation of `_.range` and `_.rangeRight` which doesn't + * coerce arguments. + * + * @private + * @param {number} start The start of the range. + * @param {number} end The end of the range. + * @param {number} step The value to increment or decrement by. + * @param {boolean} [fromRight] Specify iterating from right to left. + * @returns {Array} Returns the range of numbers. + */ + function baseRange(start, end, step, fromRight) { + var index = -1, + length = nativeMax(nativeCeil((end - start) / (step || 1)), 0), + result = Array(length); - eachOf(coll, function (v, k, cb) { - _iteratee(accumulator, v, k, cb); - }, function (err) { - callback(err, accumulator); - }); + while (length--) { + result[fromRight ? length : ++index] = start; + start += step; } + return result; + } - /** - * It runs each task in series but stops whenever any of the functions were - * successful. If one of the tasks were successful, the `callback` will be - * passed the result of the successful task. If all tasks fail, the callback - * will be passed the error and result (if any) of the final attempt. - * - * @name tryEach - * @static - * @memberOf module:ControlFlow - * @method - * @category Control Flow - * @param {Array|Iterable|Object} tasks - A collection containing functions to - * run, each function is passed a `callback(err, result)` it must call on - * completion with an error `err` (which can be `null`) and an optional `result` - * value. - * @param {Function} [callback] - An optional callback which is called when one - * of the tasks has succeeded, or all have failed. It receives the `err` and - * `result` arguments of the last attempt at completing the `task`. Invoked with - * (err, results). - * @example - * async.tryEach([ - * function getDataFromFirstWebsite(callback) { - * // Try getting the data from the first website - * callback(err, data); - * }, - * function getDataFromSecondWebsite(callback) { - * // First website failed, - * // Try getting the data from the backup website - * callback(err, data); - * } - * ], - * // optional callback - * function(err, results) { - * Now do something with the data. - * }); - * - */ - function tryEach(tasks, callback) { - var error = null; - var result; - callback = callback || noop; - eachSeries(tasks, function (task, callback) { - wrapAsync(task)(function (err, res/*, ...args*/) { - if (arguments.length > 2) { - result = slice(arguments, 1); - } else { - result = res; - } - error = err; - callback(!err); - }); - }, function () { - callback(error, result); - }); - } + /** + * The same as [times]{@link module:ControlFlow.times} but runs a maximum of `limit` async operations at a + * time. + * + * @name timesLimit + * @static + * @memberOf module:ControlFlow + * @method + * @see [async.times]{@link module:ControlFlow.times} + * @category Control Flow + * @param {number} count - The number of times to run the function. + * @param {number} limit - The maximum number of async operations at a time. + * @param {AsyncFunction} iteratee - The async function to call `n` times. + * Invoked with the iteration index and a callback: (n, next). + * @param {Function} callback - see [async.map]{@link module:Collections.map}. + */ + function timeLimit(count, limit, iteratee, callback) { + var _iteratee = wrapAsync(iteratee); + mapLimit(baseRange(0, count, 1), limit, _iteratee, callback); + } - /** - * Undoes a [memoize]{@link module:Utils.memoize}d function, reverting it to the original, - * unmemoized form. Handy for testing. - * - * @name unmemoize - * @static - * @memberOf module:Utils - * @method - * @see [async.memoize]{@link module:Utils.memoize} - * @category Util - * @param {AsyncFunction} fn - the memoized function - * @returns {AsyncFunction} a function that calls the original unmemoized function - */ - function unmemoize(fn) { - return function () { - return (fn.unmemoized || fn).apply(null, arguments); - }; - } + /** + * Calls the `iteratee` function `n` times, and accumulates results in the same + * manner you would use with [map]{@link module:Collections.map}. + * + * @name times + * @static + * @memberOf module:ControlFlow + * @method + * @see [async.map]{@link module:Collections.map} + * @category Control Flow + * @param {number} n - The number of times to run the function. + * @param {AsyncFunction} iteratee - The async function to call `n` times. + * Invoked with the iteration index and a callback: (n, next). + * @param {Function} callback - see {@link module:Collections.map}. + * @example + * + * // Pretend this is some complicated async factory + * var createUser = function(id, callback) { + * callback(null, { + * id: 'user' + id + * }); + * }; + * + * // generate 5 users + * async.times(5, function(n, next) { + * createUser(n, function(err, user) { + * next(err, user); + * }); + * }, function(err, users) { + * // we should now have 5 users + * }); + */ + var times = doLimit(timeLimit, Infinity); - /** - * Repeatedly call `iteratee`, while `test` returns `true`. Calls `callback` when - * stopped, or an error occurs. - * - * @name whilst - * @static - * @memberOf module:ControlFlow - * @method - * @category Control Flow - * @param {Function} test - synchronous truth test to perform before each - * execution of `iteratee`. Invoked with (). - * @param {AsyncFunction} iteratee - An async function which is called each time - * `test` passes. Invoked with (callback). - * @param {Function} [callback] - A callback which is called after the test - * function has failed and repeated execution of `iteratee` has stopped. `callback` - * will be passed an error and any arguments passed to the final `iteratee`'s - * callback. Invoked with (err, [results]); - * @returns undefined - * @example - * - * var count = 0; - * async.whilst( - * function() { return count < 5; }, - * function(callback) { - * count++; - * setTimeout(function() { - * callback(null, count); - * }, 1000); - * }, - * function (err, n) { - * // 5 seconds have passed, n = 5 - * } - * ); - */ - function whilst(test, iteratee, callback) { - callback = onlyOnce(callback || noop); - var _iteratee = wrapAsync(iteratee); - if (!test()) return callback(null); - var next = function (err/*, ...args*/) { - if (err) return callback(err); - if (test()) return _iteratee(next); - var args = slice(arguments, 1); - callback.apply(null, [null].concat(args)); - }; - _iteratee(next); - } - - /** - * Repeatedly call `iteratee` until `test` returns `true`. Calls `callback` when - * stopped, or an error occurs. `callback` will be passed an error and any - * arguments passed to the final `iteratee`'s callback. - * - * The inverse of [whilst]{@link module:ControlFlow.whilst}. - * - * @name until - * @static - * @memberOf module:ControlFlow - * @method - * @see [async.whilst]{@link module:ControlFlow.whilst} - * @category Control Flow - * @param {Function} test - synchronous truth test to perform before each - * execution of `iteratee`. Invoked with (). - * @param {AsyncFunction} iteratee - An async function which is called each time - * `test` fails. Invoked with (callback). - * @param {Function} [callback] - A callback which is called after the test - * function has passed and repeated execution of `iteratee` has stopped. `callback` - * will be passed an error and any arguments passed to the final `iteratee`'s - * callback. Invoked with (err, [results]); - */ - function until(test, iteratee, callback) { - whilst(function () { - return !test.apply(this, arguments); - }, iteratee, callback); - } - - /** - * Runs the `tasks` array of functions in series, each passing their results to - * the next in the array. However, if any of the `tasks` pass an error to their - * own callback, the next function is not executed, and the main `callback` is - * immediately called with the error. - * - * @name waterfall - * @static - * @memberOf module:ControlFlow - * @method - * @category Control Flow - * @param {Array} tasks - An array of [async functions]{@link AsyncFunction} - * to run. - * Each function should complete with any number of `result` values. - * The `result` values will be passed as arguments, in order, to the next task. - * @param {Function} [callback] - An optional callback to run once all the - * functions have completed. This will be passed the results of the last task's - * callback. Invoked with (err, [results]). - * @returns undefined - * @example - * - * async.waterfall([ - * function(callback) { - * callback(null, 'one', 'two'); - * }, - * function(arg1, arg2, callback) { - * // arg1 now equals 'one' and arg2 now equals 'two' - * callback(null, 'three'); - * }, - * function(arg1, callback) { - * // arg1 now equals 'three' - * callback(null, 'done'); - * } - * ], function (err, result) { - * // result now equals 'done' - * }); - * - * // Or, with named functions: - * async.waterfall([ - * myFirstFunction, - * mySecondFunction, - * myLastFunction, - * ], function (err, result) { - * // result now equals 'done' - * }); - * function myFirstFunction(callback) { - * callback(null, 'one', 'two'); - * } - * function mySecondFunction(arg1, arg2, callback) { - * // arg1 now equals 'one' and arg2 now equals 'two' - * callback(null, 'three'); - * } - * function myLastFunction(arg1, callback) { - * // arg1 now equals 'three' - * callback(null, 'done'); - * } - */ - var waterfall = function (tasks, callback) { - callback = once(callback || noop); - if (!isArray(tasks)) return callback(new Error('First argument to waterfall must be an array of functions')); - if (!tasks.length) return callback(); - var taskIndex = 0; + /** + * The same as [times]{@link module:ControlFlow.times} but runs only a single async operation at a time. + * + * @name timesSeries + * @static + * @memberOf module:ControlFlow + * @method + * @see [async.times]{@link module:ControlFlow.times} + * @category Control Flow + * @param {number} n - The number of times to run the function. + * @param {AsyncFunction} iteratee - The async function to call `n` times. + * Invoked with the iteration index and a callback: (n, next). + * @param {Function} callback - see {@link module:Collections.map}. + */ + var timesSeries = doLimit(timeLimit, 1); - function nextTask(args) { - var task = wrapAsync(tasks[taskIndex++]); - args.push(onlyOnce(next)); - task.apply(null, args); - } + /** + * A relative of `reduce`. Takes an Object or Array, and iterates over each + * element in series, each step potentially mutating an `accumulator` value. + * The type of the accumulator defaults to the type of collection passed in. + * + * @name transform + * @static + * @memberOf module:Collections + * @method + * @category Collection + * @param {Array|Iterable|Object} coll - A collection to iterate over. + * @param {*} [accumulator] - The initial state of the transform. If omitted, + * it will default to an empty Object or Array, depending on the type of `coll` + * @param {AsyncFunction} iteratee - A function applied to each item in the + * collection that potentially modifies the accumulator. + * Invoked with (accumulator, item, key, callback). + * @param {Function} [callback] - A callback which is called after all the + * `iteratee` functions have finished. Result is the transformed accumulator. + * Invoked with (err, result). + * @example + * + * async.transform([1,2,3], function(acc, item, index, callback) { + * // pointless async: + * process.nextTick(function() { + * acc.push(item * 2) + * callback(null) + * }); + * }, function(err, result) { + * // result is now equal to [2, 4, 6] + * }); + * + * @example + * + * async.transform({a: 1, b: 2, c: 3}, function (obj, val, key, callback) { + * setImmediate(function () { + * obj[key] = val * 2; + * callback(); + * }) + * }, function (err, result) { + * // result is equal to {a: 2, b: 4, c: 6} + * }) + */ + function transform (coll, accumulator, iteratee, callback) { + if (arguments.length <= 3) { + callback = iteratee; + iteratee = accumulator; + accumulator = isArray(coll) ? [] : {}; + } + callback = once(callback || noop); + var _iteratee = wrapAsync(iteratee); + + eachOf(coll, function(v, k, cb) { + _iteratee(accumulator, v, k, cb); + }, function(err) { + callback(err, accumulator); + }); + } - function next(err/*, ...args*/) { - if (err || taskIndex === tasks.length) { - return callback.apply(null, arguments); + /** + * It runs each task in series but stops whenever any of the functions were + * successful. If one of the tasks were successful, the `callback` will be + * passed the result of the successful task. If all tasks fail, the callback + * will be passed the error and result (if any) of the final attempt. + * + * @name tryEach + * @static + * @memberOf module:ControlFlow + * @method + * @category Control Flow + * @param {Array|Iterable|Object} tasks - A collection containing functions to + * run, each function is passed a `callback(err, result)` it must call on + * completion with an error `err` (which can be `null`) and an optional `result` + * value. + * @param {Function} [callback] - An optional callback which is called when one + * of the tasks has succeeded, or all have failed. It receives the `err` and + * `result` arguments of the last attempt at completing the `task`. Invoked with + * (err, results). + * @example + * async.tryEach([ + * function getDataFromFirstWebsite(callback) { + * // Try getting the data from the first website + * callback(err, data); + * }, + * function getDataFromSecondWebsite(callback) { + * // First website failed, + * // Try getting the data from the backup website + * callback(err, data); + * } + * ], + * // optional callback + * function(err, results) { + * Now do something with the data. + * }); + * + */ + function tryEach(tasks, callback) { + var error = null; + var result; + callback = callback || noop; + eachSeries(tasks, function(task, callback) { + wrapAsync(task)(function (err, res/*, ...args*/) { + if (arguments.length > 2) { + result = slice(arguments, 1); + } else { + result = res; } - nextTask(slice(arguments, 1)); - } + error = err; + callback(!err); + }); + }, function () { + callback(error, result); + }); + } - nextTask([]); + /** + * Undoes a [memoize]{@link module:Utils.memoize}d function, reverting it to the original, + * unmemoized form. Handy for testing. + * + * @name unmemoize + * @static + * @memberOf module:Utils + * @method + * @see [async.memoize]{@link module:Utils.memoize} + * @category Util + * @param {AsyncFunction} fn - the memoized function + * @returns {AsyncFunction} a function that calls the original unmemoized function + */ + function unmemoize(fn) { + return function () { + return (fn.unmemoized || fn).apply(null, arguments); }; + } - /** - * An "async function" in the context of Async is an asynchronous function with - * a variable number of parameters, with the final parameter being a callback. - * (`function (arg1, arg2, ..., callback) {}`) - * The final callback is of the form `callback(err, results...)`, which must be - * called once the function is completed. The callback should be called with a - * Error as its first argument to signal that an error occurred. - * Otherwise, if no error occurred, it should be called with `null` as the first - * argument, and any additional `result` arguments that may apply, to signal - * successful completion. - * The callback must be called exactly once, ideally on a later tick of the - * JavaScript event loop. - * - * This type of function is also referred to as a "Node-style async function", - * or a "continuation passing-style function" (CPS). Most of the methods of this - * library are themselves CPS/Node-style async functions, or functions that - * return CPS/Node-style async functions. - * - * Wherever we accept a Node-style async function, we also directly accept an - * [ES2017 `async` function]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function}. - * In this case, the `async` function will not be passed a final callback - * argument, and any thrown error will be used as the `err` argument of the - * implicit callback, and the return value will be used as the `result` value. - * (i.e. a `rejected` of the returned Promise becomes the `err` callback - * argument, and a `resolved` value becomes the `result`.) - * - * Note, due to JavaScript limitations, we can only detect native `async` - * functions and not transpilied implementations. - * Your environment must have `async`/`await` support for this to work. - * (e.g. Node > v7.6, or a recent version of a modern browser). - * If you are using `async` functions through a transpiler (e.g. Babel), you - * must still wrap the function with [asyncify]{@link module:Utils.asyncify}, - * because the `async function` will be compiled to an ordinary function that - * returns a promise. - * - * @typedef {Function} AsyncFunction - * @static - */ - - /** - * Async is a utility module which provides straight-forward, powerful functions - * for working with asynchronous JavaScript. Although originally designed for - * use with [Node.js](http://nodejs.org) and installable via - * `npm install --save async`, it can also be used directly in the browser. - * @module async - * @see AsyncFunction - */ - - - /** - * A collection of `async` functions for manipulating collections, such as - * arrays and objects. - * @module Collections - */ - - /** - * A collection of `async` functions for controlling the flow through a script. - * @module ControlFlow - */ - - /** - * A collection of `async` utility functions. - * @module Utils - */ - - var index = { - apply: apply, - applyEach: applyEach, - applyEachSeries: applyEachSeries, - asyncify: asyncify, - auto: auto, - autoInject: autoInject, - cargo: cargo, - compose: compose, - concat: concat, - concatLimit: concatLimit, - concatSeries: concatSeries, - constant: constant, - detect: detect, - detectLimit: detectLimit, - detectSeries: detectSeries, - dir: dir, - doDuring: doDuring, - doUntil: doUntil, - doWhilst: doWhilst, - during: during, - each: eachLimit, - eachLimit: eachLimit$1, - eachOf: eachOf, - eachOfLimit: eachOfLimit, - eachOfSeries: eachOfSeries, - eachSeries: eachSeries, - ensureAsync: ensureAsync, - every: every, - everyLimit: everyLimit, - everySeries: everySeries, - filter: filter, - filterLimit: filterLimit, - filterSeries: filterSeries, - forever: forever, - groupBy: groupBy, - groupByLimit: groupByLimit, - groupBySeries: groupBySeries, - log: log, - map: map, - mapLimit: mapLimit, - mapSeries: mapSeries, - mapValues: mapValues, - mapValuesLimit: mapValuesLimit, - mapValuesSeries: mapValuesSeries, - memoize: memoize, - nextTick: nextTick, - parallel: parallelLimit, - parallelLimit: parallelLimit$1, - priorityQueue: priorityQueue, - queue: queue$1, - race: race, - reduce: reduce, - reduceRight: reduceRight, - reflect: reflect, - reflectAll: reflectAll, - reject: reject, - rejectLimit: rejectLimit, - rejectSeries: rejectSeries, - retry: retry, - retryable: retryable, - seq: seq, - series: series, - setImmediate: setImmediate$1, - some: some, - someLimit: someLimit, - someSeries: someSeries, - sortBy: sortBy, - timeout: timeout, - times: times, - timesLimit: timeLimit, - timesSeries: timesSeries, - transform: transform, - tryEach: tryEach, - unmemoize: unmemoize, - until: until, - waterfall: waterfall, - whilst: whilst, - - // aliases - all: every, - allLimit: everyLimit, - allSeries: everySeries, - any: some, - anyLimit: someLimit, - anySeries: someSeries, - find: detect, - findLimit: detectLimit, - findSeries: detectSeries, - forEach: eachLimit, - forEachSeries: eachSeries, - forEachLimit: eachLimit$1, - forEachOf: eachOf, - forEachOfSeries: eachOfSeries, - forEachOfLimit: eachOfLimit, - inject: reduce, - foldl: reduce, - foldr: reduceRight, - select: filter, - selectLimit: filterLimit, - selectSeries: filterSeries, - wrapSync: asyncify + /** + * Repeatedly call `iteratee`, while `test` returns `true`. Calls `callback` when + * stopped, or an error occurs. + * + * @name whilst + * @static + * @memberOf module:ControlFlow + * @method + * @category Control Flow + * @param {Function} test - synchronous truth test to perform before each + * execution of `iteratee`. Invoked with (). + * @param {AsyncFunction} iteratee - An async function which is called each time + * `test` passes. Invoked with (callback). + * @param {Function} [callback] - A callback which is called after the test + * function has failed and repeated execution of `iteratee` has stopped. `callback` + * will be passed an error and any arguments passed to the final `iteratee`'s + * callback. Invoked with (err, [results]); + * @returns undefined + * @example + * + * var count = 0; + * async.whilst( + * function() { return count < 5; }, + * function(callback) { + * count++; + * setTimeout(function() { + * callback(null, count); + * }, 1000); + * }, + * function (err, n) { + * // 5 seconds have passed, n = 5 + * } + * ); + */ + function whilst(test, iteratee, callback) { + callback = onlyOnce(callback || noop); + var _iteratee = wrapAsync(iteratee); + if (!test()) return callback(null); + var next = function(err/*, ...args*/) { + if (err) return callback(err); + if (test()) return _iteratee(next); + var args = slice(arguments, 1); + callback.apply(null, [null].concat(args)); }; + _iteratee(next); + } - exports['default'] = index; - exports.apply = apply; - exports.applyEach = applyEach; - exports.applyEachSeries = applyEachSeries; - exports.asyncify = asyncify; - exports.auto = auto; - exports.autoInject = autoInject; - exports.cargo = cargo; - exports.compose = compose; - exports.concat = concat; - exports.concatLimit = concatLimit; - exports.concatSeries = concatSeries; - exports.constant = constant; - exports.detect = detect; - exports.detectLimit = detectLimit; - exports.detectSeries = detectSeries; - exports.dir = dir; - exports.doDuring = doDuring; - exports.doUntil = doUntil; - exports.doWhilst = doWhilst; - exports.during = during; - exports.each = eachLimit; - exports.eachLimit = eachLimit$1; - exports.eachOf = eachOf; - exports.eachOfLimit = eachOfLimit; - exports.eachOfSeries = eachOfSeries; - exports.eachSeries = eachSeries; - exports.ensureAsync = ensureAsync; - exports.every = every; - exports.everyLimit = everyLimit; - exports.everySeries = everySeries; - exports.filter = filter; - exports.filterLimit = filterLimit; - exports.filterSeries = filterSeries; - exports.forever = forever; - exports.groupBy = groupBy; - exports.groupByLimit = groupByLimit; - exports.groupBySeries = groupBySeries; - exports.log = log; - exports.map = map; - exports.mapLimit = mapLimit; - exports.mapSeries = mapSeries; - exports.mapValues = mapValues; - exports.mapValuesLimit = mapValuesLimit; - exports.mapValuesSeries = mapValuesSeries; - exports.memoize = memoize; - exports.nextTick = nextTick; - exports.parallel = parallelLimit; - exports.parallelLimit = parallelLimit$1; - exports.priorityQueue = priorityQueue; - exports.queue = queue$1; - exports.race = race; - exports.reduce = reduce; - exports.reduceRight = reduceRight; - exports.reflect = reflect; - exports.reflectAll = reflectAll; - exports.reject = reject; - exports.rejectLimit = rejectLimit; - exports.rejectSeries = rejectSeries; - exports.retry = retry; - exports.retryable = retryable; - exports.seq = seq; - exports.series = series; - exports.setImmediate = setImmediate$1; - exports.some = some; - exports.someLimit = someLimit; - exports.someSeries = someSeries; - exports.sortBy = sortBy; - exports.timeout = timeout; - exports.times = times; - exports.timesLimit = timeLimit; - exports.timesSeries = timesSeries; - exports.transform = transform; - exports.tryEach = tryEach; - exports.unmemoize = unmemoize; - exports.until = until; - exports.waterfall = waterfall; - exports.whilst = whilst; - exports.all = every; - exports.allLimit = everyLimit; - exports.allSeries = everySeries; - exports.any = some; - exports.anyLimit = someLimit; - exports.anySeries = someSeries; - exports.find = detect; - exports.findLimit = detectLimit; - exports.findSeries = detectSeries; - exports.forEach = eachLimit; - exports.forEachSeries = eachSeries; - exports.forEachLimit = eachLimit$1; - exports.forEachOf = eachOf; - exports.forEachOfSeries = eachOfSeries; - exports.forEachOfLimit = eachOfLimit; - exports.inject = reduce; - exports.foldl = reduce; - exports.foldr = reduceRight; - exports.select = filter; - exports.selectLimit = filterLimit; - exports.selectSeries = filterSeries; - exports.wrapSync = asyncify; - - Object.defineProperty(exports, '__esModule', {value: true}); - - }))); - - /* WEBPACK VAR INJECTION */ - }.call(this, __webpack_require__(7).setImmediate, __webpack_require__(1), __webpack_require__(2), __webpack_require__(37)(module))) - - /***/ - }), - /* 14 */ - /***/ (function (module, exports, __webpack_require__) { + /** + * Repeatedly call `iteratee` until `test` returns `true`. Calls `callback` when + * stopped, or an error occurs. `callback` will be passed an error and any + * arguments passed to the final `iteratee`'s callback. + * + * The inverse of [whilst]{@link module:ControlFlow.whilst}. + * + * @name until + * @static + * @memberOf module:ControlFlow + * @method + * @see [async.whilst]{@link module:ControlFlow.whilst} + * @category Control Flow + * @param {Function} test - synchronous truth test to perform before each + * execution of `iteratee`. Invoked with (). + * @param {AsyncFunction} iteratee - An async function which is called each time + * `test` fails. Invoked with (callback). + * @param {Function} [callback] - A callback which is called after the test + * function has passed and repeated execution of `iteratee` has stopped. `callback` + * will be passed an error and any arguments passed to the final `iteratee`'s + * callback. Invoked with (err, [results]); + */ + function until(test, iteratee, callback) { + whilst(function() { + return !test.apply(this, arguments); + }, iteratee, callback); + } + + /** + * Runs the `tasks` array of functions in series, each passing their results to + * the next in the array. However, if any of the `tasks` pass an error to their + * own callback, the next function is not executed, and the main `callback` is + * immediately called with the error. + * + * @name waterfall + * @static + * @memberOf module:ControlFlow + * @method + * @category Control Flow + * @param {Array} tasks - An array of [async functions]{@link AsyncFunction} + * to run. + * Each function should complete with any number of `result` values. + * The `result` values will be passed as arguments, in order, to the next task. + * @param {Function} [callback] - An optional callback to run once all the + * functions have completed. This will be passed the results of the last task's + * callback. Invoked with (err, [results]). + * @returns undefined + * @example + * + * async.waterfall([ + * function(callback) { + * callback(null, 'one', 'two'); + * }, + * function(arg1, arg2, callback) { + * // arg1 now equals 'one' and arg2 now equals 'two' + * callback(null, 'three'); + * }, + * function(arg1, callback) { + * // arg1 now equals 'three' + * callback(null, 'done'); + * } + * ], function (err, result) { + * // result now equals 'done' + * }); + * + * // Or, with named functions: + * async.waterfall([ + * myFirstFunction, + * mySecondFunction, + * myLastFunction, + * ], function (err, result) { + * // result now equals 'done' + * }); + * function myFirstFunction(callback) { + * callback(null, 'one', 'two'); + * } + * function mySecondFunction(arg1, arg2, callback) { + * // arg1 now equals 'one' and arg2 now equals 'two' + * callback(null, 'three'); + * } + * function myLastFunction(arg1, callback) { + * // arg1 now equals 'three' + * callback(null, 'done'); + * } + */ + var waterfall = function(tasks, callback) { + callback = once(callback || noop); + if (!isArray(tasks)) return callback(new Error('First argument to waterfall must be an array of functions')); + if (!tasks.length) return callback(); + var taskIndex = 0; - var Buffer = __webpack_require__(0).Buffer; // for use with browserify + function nextTask(args) { + var task = wrapAsync(tasks[taskIndex++]); + args.push(onlyOnce(next)); + task.apply(null, args); + } - module.exports = function (a, b) { - if (!Buffer.isBuffer(a)) return undefined; - if (!Buffer.isBuffer(b)) return undefined; - if (typeof a.equals === 'function') return a.equals(b); - if (a.length !== b.length) return false; + function next(err/*, ...args*/) { + if (err || taskIndex === tasks.length) { + return callback.apply(null, arguments); + } + nextTask(slice(arguments, 1)); + } - for (var i = 0; i < a.length; i++) { - if (a[i] !== b[i]) return false; - } + nextTask([]); + }; - return true; - }; + /** + * An "async function" in the context of Async is an asynchronous function with + * a variable number of parameters, with the final parameter being a callback. + * (`function (arg1, arg2, ..., callback) {}`) + * The final callback is of the form `callback(err, results...)`, which must be + * called once the function is completed. The callback should be called with a + * Error as its first argument to signal that an error occurred. + * Otherwise, if no error occurred, it should be called with `null` as the first + * argument, and any additional `result` arguments that may apply, to signal + * successful completion. + * The callback must be called exactly once, ideally on a later tick of the + * JavaScript event loop. + * + * This type of function is also referred to as a "Node-style async function", + * or a "continuation passing-style function" (CPS). Most of the methods of this + * library are themselves CPS/Node-style async functions, or functions that + * return CPS/Node-style async functions. + * + * Wherever we accept a Node-style async function, we also directly accept an + * [ES2017 `async` function]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function}. + * In this case, the `async` function will not be passed a final callback + * argument, and any thrown error will be used as the `err` argument of the + * implicit callback, and the return value will be used as the `result` value. + * (i.e. a `rejected` of the returned Promise becomes the `err` callback + * argument, and a `resolved` value becomes the `result`.) + * + * Note, due to JavaScript limitations, we can only detect native `async` + * functions and not transpilied implementations. + * Your environment must have `async`/`await` support for this to work. + * (e.g. Node > v7.6, or a recent version of a modern browser). + * If you are using `async` functions through a transpiler (e.g. Babel), you + * must still wrap the function with [asyncify]{@link module:Utils.asyncify}, + * because the `async function` will be compiled to an ordinary function that + * returns a promise. + * + * @typedef {Function} AsyncFunction + * @static + */ + + /** + * Async is a utility module which provides straight-forward, powerful functions + * for working with asynchronous JavaScript. Although originally designed for + * use with [Node.js](http://nodejs.org) and installable via + * `npm install --save async`, it can also be used directly in the browser. + * @module async + * @see AsyncFunction + */ - /***/ - }), - /* 15 */ - /***/ (function (module, exports, __webpack_require__) { + /** + * A collection of `async` functions for manipulating collections, such as + * arrays and objects. + * @module Collections + */ + + /** + * A collection of `async` functions for controlling the flow through a script. + * @module ControlFlow + */ + + /** + * A collection of `async` utility functions. + * @module Utils + */ + + var index = { + apply: apply, + applyEach: applyEach, + applyEachSeries: applyEachSeries, + asyncify: asyncify, + auto: auto, + autoInject: autoInject, + cargo: cargo, + compose: compose, + concat: concat, + concatLimit: concatLimit, + concatSeries: concatSeries, + constant: constant, + detect: detect, + detectLimit: detectLimit, + detectSeries: detectSeries, + dir: dir, + doDuring: doDuring, + doUntil: doUntil, + doWhilst: doWhilst, + during: during, + each: eachLimit, + eachLimit: eachLimit$1, + eachOf: eachOf, + eachOfLimit: eachOfLimit, + eachOfSeries: eachOfSeries, + eachSeries: eachSeries, + ensureAsync: ensureAsync, + every: every, + everyLimit: everyLimit, + everySeries: everySeries, + filter: filter, + filterLimit: filterLimit, + filterSeries: filterSeries, + forever: forever, + groupBy: groupBy, + groupByLimit: groupByLimit, + groupBySeries: groupBySeries, + log: log, + map: map, + mapLimit: mapLimit, + mapSeries: mapSeries, + mapValues: mapValues, + mapValuesLimit: mapValuesLimit, + mapValuesSeries: mapValuesSeries, + memoize: memoize, + nextTick: nextTick, + parallel: parallelLimit, + parallelLimit: parallelLimit$1, + priorityQueue: priorityQueue, + queue: queue$1, + race: race, + reduce: reduce, + reduceRight: reduceRight, + reflect: reflect, + reflectAll: reflectAll, + reject: reject, + rejectLimit: rejectLimit, + rejectSeries: rejectSeries, + retry: retry, + retryable: retryable, + seq: seq, + series: series, + setImmediate: setImmediate$1, + some: some, + someLimit: someLimit, + someSeries: someSeries, + sortBy: sortBy, + timeout: timeout, + times: times, + timesLimit: timeLimit, + timesSeries: timesSeries, + transform: transform, + tryEach: tryEach, + unmemoize: unmemoize, + until: until, + waterfall: waterfall, + whilst: whilst, + + // aliases + all: every, + allLimit: everyLimit, + allSeries: everySeries, + any: some, + anyLimit: someLimit, + anySeries: someSeries, + find: detect, + findLimit: detectLimit, + findSeries: detectSeries, + forEach: eachLimit, + forEachSeries: eachSeries, + forEachLimit: eachLimit$1, + forEachOf: eachOf, + forEachOfSeries: eachOfSeries, + forEachOfLimit: eachOfLimit, + inject: reduce, + foldl: reduce, + foldr: reduceRight, + select: filter, + selectLimit: filterLimit, + selectSeries: filterSeries, + wrapSync: asyncify + }; - /* WEBPACK VAR INJECTION */ - (function (Buffer) { - var Resp_STK_INSYNC = 0x14; + exports['default'] = index; + exports.apply = apply; + exports.applyEach = applyEach; + exports.applyEachSeries = applyEachSeries; + exports.asyncify = asyncify; + exports.auto = auto; + exports.autoInject = autoInject; + exports.cargo = cargo; + exports.compose = compose; + exports.concat = concat; + exports.concatLimit = concatLimit; + exports.concatSeries = concatSeries; + exports.constant = constant; + exports.detect = detect; + exports.detectLimit = detectLimit; + exports.detectSeries = detectSeries; + exports.dir = dir; + exports.doDuring = doDuring; + exports.doUntil = doUntil; + exports.doWhilst = doWhilst; + exports.during = during; + exports.each = eachLimit; + exports.eachLimit = eachLimit$1; + exports.eachOf = eachOf; + exports.eachOfLimit = eachOfLimit; + exports.eachOfSeries = eachOfSeries; + exports.eachSeries = eachSeries; + exports.ensureAsync = ensureAsync; + exports.every = every; + exports.everyLimit = everyLimit; + exports.everySeries = everySeries; + exports.filter = filter; + exports.filterLimit = filterLimit; + exports.filterSeries = filterSeries; + exports.forever = forever; + exports.groupBy = groupBy; + exports.groupByLimit = groupByLimit; + exports.groupBySeries = groupBySeries; + exports.log = log; + exports.map = map; + exports.mapLimit = mapLimit; + exports.mapSeries = mapSeries; + exports.mapValues = mapValues; + exports.mapValuesLimit = mapValuesLimit; + exports.mapValuesSeries = mapValuesSeries; + exports.memoize = memoize; + exports.nextTick = nextTick; + exports.parallel = parallelLimit; + exports.parallelLimit = parallelLimit$1; + exports.priorityQueue = priorityQueue; + exports.queue = queue$1; + exports.race = race; + exports.reduce = reduce; + exports.reduceRight = reduceRight; + exports.reflect = reflect; + exports.reflectAll = reflectAll; + exports.reject = reject; + exports.rejectLimit = rejectLimit; + exports.rejectSeries = rejectSeries; + exports.retry = retry; + exports.retryable = retryable; + exports.seq = seq; + exports.series = series; + exports.setImmediate = setImmediate$1; + exports.some = some; + exports.someLimit = someLimit; + exports.someSeries = someSeries; + exports.sortBy = sortBy; + exports.timeout = timeout; + exports.times = times; + exports.timesLimit = timeLimit; + exports.timesSeries = timesSeries; + exports.transform = transform; + exports.tryEach = tryEach; + exports.unmemoize = unmemoize; + exports.until = until; + exports.waterfall = waterfall; + exports.whilst = whilst; + exports.all = every; + exports.allLimit = everyLimit; + exports.allSeries = everySeries; + exports.any = some; + exports.anyLimit = someLimit; + exports.anySeries = someSeries; + exports.find = detect; + exports.findLimit = detectLimit; + exports.findSeries = detectSeries; + exports.forEach = eachLimit; + exports.forEachSeries = eachSeries; + exports.forEachLimit = eachLimit$1; + exports.forEachOf = eachOf; + exports.forEachOfSeries = eachOfSeries; + exports.forEachOfLimit = eachOfLimit; + exports.inject = reduce; + exports.foldl = reduce; + exports.foldr = reduceRight; + exports.select = filter; + exports.selectLimit = filterLimit; + exports.selectSeries = filterSeries; + exports.wrapSync = asyncify; + + Object.defineProperty(exports, '__esModule', { value: true }); + + }))); + + /* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(7).setImmediate, __webpack_require__(1), __webpack_require__(2), __webpack_require__(35)(module))) + + /***/ }), + /* 11 */ + /***/ (function(module, exports, __webpack_require__) { + + /* WEBPACK VAR INJECTION */(function(Buffer) {var Resp_STK_INSYNC = 0x14; var Resp_STK_OK = 0x10; module.exports = { @@ -9756,47 +9339,74 @@ THE SOFTWARE. Cmnd_STK_READ_PAGE: 0x74, - OK_RESPONSE: new Buffer([Resp_STK_INSYNC, Resp_STK_OK]) + OK_RESPONSE: Buffer.from([Resp_STK_INSYNC, Resp_STK_OK]) }; - /* WEBPACK VAR INJECTION */ - }.call(this, __webpack_require__(0).Buffer)) + /* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(0).Buffer)) - /***/ - }), - /* 16 */ - /***/ (function (module, exports, __webpack_require__) { + /***/ }), + /* 12 */ + /***/ (function(module, exports, __webpack_require__) { - var colors = __webpack_require__(6); + var colors = __webpack_require__(19); module['exports'] = colors; -// Remark: By default, colors will add style properties to String.prototype +// Remark: By default, colors will add style properties to String.prototype. // -// If you don't wish to extend String.prototype you can do this instead and native String will not be touched +// If you don't wish to extend String.prototype, you can do this instead and +// native String will not be touched: // // var colors = require('colors/safe); // colors.red("foo") // // - __webpack_require__(55)(); + __webpack_require__(57)(); - /***/ - }), - /* 17 */ - /***/ (function (module, exports) { + + /***/ }), + /* 13 */ + /***/ (function(module, exports, __webpack_require__) { + + /* WEBPACK VAR INJECTION */(function(Buffer) {var fs = __webpack_require__(20); + var intelhex = __webpack_require__(21); + + var tools = {}; + + /** + * Opens and parses a given hex file + */ + tools._parseHex = function(file) { + try { + return intelhex.parse(file).data; + } catch (error) { + return error; + } + }; + + tools._hexStringToByte = function(str) { + return Buffer.from([parseInt(str,16)]); + } + + module.exports = tools; + + /* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(0).Buffer)) + + /***/ }), + /* 14 */ + /***/ (function(module, exports) { /** * Generic Protocol for other protocols to inherit from * */ - var Protocol = function (options) { + var Protocol = function(options) { this.debug = options.debug; this.board = options.board; this.connection = options.connection; - this.chip = new options.protocol({quiet: true}); - + // eslint-disable-next-line new-cap + this.chip = new options.protocol({ quiet: true }); }; /** @@ -9807,44 +9417,109 @@ THE SOFTWARE. * * @param {function} callback - function to run upon completion/error */ - Protocol.prototype._reset = function (callback) { + Protocol.prototype._reset = function(callback) { var _this = this; - // cycle DTR/RTS from low to high - _this.connection._cycleDTR(function (error) { + // set DTR from high to low + _this.connection._setDTR(false, 250, function(error) { if (!error) { _this.debug('reset complete.'); } - return callback(error); - }); - }; + return callback(error); + }); + }; + + module.exports = Protocol; + + + /***/ }), + /* 15 */ + /***/ (function(module, exports, __webpack_require__) { + + exports = module.exports = __webpack_require__(23); + exports.Stream = exports; + exports.Readable = exports; + exports.Writable = __webpack_require__(17); + exports.Duplex = __webpack_require__(3); + exports.Transform = __webpack_require__(27); + exports.PassThrough = __webpack_require__(70); + + + /***/ }), + /* 16 */ + /***/ (function(module, exports, __webpack_require__) { + + /* eslint-disable node/no-deprecated-api */ + var buffer = __webpack_require__(0) + var Buffer = buffer.Buffer + +// alternative to using Object.keys for old browsers + function copyProps (src, dst) { + for (var key in src) { + dst[key] = src[key] + } + } + if (Buffer.from && Buffer.alloc && Buffer.allocUnsafe && Buffer.allocUnsafeSlow) { + module.exports = buffer + } else { + // Copy properties from require('buffer') + copyProps(buffer, exports) + exports.Buffer = SafeBuffer + } + + function SafeBuffer (arg, encodingOrOffset, length) { + return Buffer(arg, encodingOrOffset, length) + } - module.exports = Protocol; +// Copy static methods from Buffer + copyProps(Buffer, SafeBuffer) + SafeBuffer.from = function (arg, encodingOrOffset, length) { + if (typeof arg === 'number') { + throw new TypeError('Argument must not be a number') + } + return Buffer(arg, encodingOrOffset, length) + } - /***/ - }), - /* 18 */ - /***/ (function (module, exports, __webpack_require__) { + SafeBuffer.alloc = function (size, fill, encoding) { + if (typeof size !== 'number') { + throw new TypeError('Argument must be a number') + } + var buf = Buffer(size) + if (fill !== undefined) { + if (typeof encoding === 'string') { + buf.fill(fill, encoding) + } else { + buf.fill(fill) + } + } else { + buf.fill(0) + } + return buf + } - exports = module.exports = __webpack_require__(25); - exports.Stream = exports; - exports.Readable = exports; - exports.Writable = __webpack_require__(19); - exports.Duplex = __webpack_require__(4); - exports.Transform = __webpack_require__(29); - exports.PassThrough = __webpack_require__(68); + SafeBuffer.allocUnsafe = function (size) { + if (typeof size !== 'number') { + throw new TypeError('Argument must be a number') + } + return Buffer(size) + } + + SafeBuffer.allocUnsafeSlow = function (size) { + if (typeof size !== 'number') { + throw new TypeError('Argument must be a number') + } + return buffer.SlowBuffer(size) + } - /***/ - }), - /* 19 */ - /***/ (function (module, exports, __webpack_require__) { + /***/ }), + /* 17 */ + /***/ (function(module, exports, __webpack_require__) { "use strict"; - /* WEBPACK VAR INJECTION */ - (function (process, setImmediate, global) {// Copyright Joyent, Inc. and other Node contributors. + /* WEBPACK VAR INJECTION */(function(process, setImmediate, global) {// Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the @@ -9870,9 +9545,10 @@ THE SOFTWARE. // the drain event emission and buffering. + /**/ - var pna = __webpack_require__(11); + var pna = __webpack_require__(9); /**/ module.exports = Writable; @@ -9896,7 +9572,6 @@ THE SOFTWARE. onCorkedFinish(_this, state); }; } - /* */ /**/ @@ -9910,45 +9585,41 @@ THE SOFTWARE. Writable.WritableState = WritableState; /**/ - var util = __webpack_require__(9); - util.inherits = __webpack_require__(3); + var util = Object.create(__webpack_require__(8)); + util.inherits = __webpack_require__(6); /**/ /**/ var internalUtil = { - deprecate: __webpack_require__(67) + deprecate: __webpack_require__(68) }; /**/ /**/ - var Stream = __webpack_require__(26); + var Stream = __webpack_require__(24); /**/ /**/ - var Buffer = __webpack_require__(12).Buffer; - var OurUint8Array = global.Uint8Array || function () { - }; - + var Buffer = __webpack_require__(16).Buffer; + var OurUint8Array = global.Uint8Array || function () {}; function _uint8ArrayToBuffer(chunk) { return Buffer.from(chunk); } - function _isUint8Array(obj) { return Buffer.isBuffer(obj) || obj instanceof OurUint8Array; } /**/ - var destroyImpl = __webpack_require__(27); + var destroyImpl = __webpack_require__(25); util.inherits(Writable, Stream); - function nop() { - } + function nop() {} function WritableState(options, stream) { - Duplex = Duplex || __webpack_require__(4); + Duplex = Duplex || __webpack_require__(3); options = options || {}; @@ -9972,7 +9643,7 @@ THE SOFTWARE. var writableHwm = options.writableHighWaterMark; var defaultHwm = this.objectMode ? 16 : 16 * 1024; - if (hwm || hwm === 0) this.highWaterMark = hwm; else if (isDuplex && (writableHwm || writableHwm === 0)) this.highWaterMark = writableHwm; else this.highWaterMark = defaultHwm; + if (hwm || hwm === 0) this.highWaterMark = hwm;else if (isDuplex && (writableHwm || writableHwm === 0)) this.highWaterMark = writableHwm;else this.highWaterMark = defaultHwm; // cast to ints. this.highWaterMark = Math.floor(this.highWaterMark); @@ -10075,8 +9746,7 @@ THE SOFTWARE. return this.getBuffer(); }, '_writableState.buffer is deprecated. Use _writableState.getBuffer ' + 'instead.', 'DEP0003') }); - } catch (_) { - } + } catch (_) {} })(); // Test _writableState for inheritance to account for Duplex streams, @@ -10099,7 +9769,7 @@ THE SOFTWARE. } function Writable(options) { - Duplex = Duplex || __webpack_require__(4); + Duplex = Duplex || __webpack_require__(3); // Writable ctor is applied to Duplexes, too. // `realHasInstance` is necessary because using plain `instanceof` @@ -10176,11 +9846,11 @@ THE SOFTWARE. encoding = null; } - if (isBuf) encoding = 'buffer'; else if (!encoding) encoding = state.defaultEncoding; + if (isBuf) encoding = 'buffer';else if (!encoding) encoding = state.defaultEncoding; if (typeof cb !== 'function') cb = nop; - if (state.ended) writeAfterEnd(this, cb); else if (isBuf || validChunk(this, state, chunk, cb)) { + if (state.ended) writeAfterEnd(this, cb);else if (isBuf || validChunk(this, state, chunk, cb)) { state.pendingcb++; ret = writeOrBuffer(this, state, isBuf, chunk, encoding, cb); } @@ -10276,7 +9946,7 @@ THE SOFTWARE. state.writecb = cb; state.writing = true; state.sync = true; - if (writev) stream._writev(chunk, state.onwrite); else stream._write(chunk, encoding, state.onwrite); + if (writev) stream._writev(chunk, state.onwrite);else stream._write(chunk, encoding, state.onwrite); state.sync = false; } @@ -10318,7 +9988,7 @@ THE SOFTWARE. onwriteStateUpdate(state); - if (er) onwriteError(stream, state, sync, er, cb); else { + if (er) onwriteError(stream, state, sync, er, cb);else { // Check if we're actually ready to finish, but don't emit yet var finished = needFinish(state); @@ -10448,7 +10118,6 @@ THE SOFTWARE. function needFinish(state) { return state.ending && state.length === 0 && state.bufferedRequest === null && !state.finished && !state.writing; } - function callFinal(stream, state) { stream._final(function (err) { state.pendingcb--; @@ -10460,7 +10129,6 @@ THE SOFTWARE. finishMaybe(stream, state); }); } - function prefinish(stream, state) { if (!state.prefinished && !state.finalCalled) { if (typeof stream._final === 'function') { @@ -10490,7 +10158,7 @@ THE SOFTWARE. state.ending = true; finishMaybe(stream, state); if (cb) { - if (state.finished) pna.nextTick(cb); else stream.once('finish', cb); + if (state.finished) pna.nextTick(cb);else stream.once('finish', cb); } state.ended = true; stream.writable = false; @@ -10538,13 +10206,11 @@ THE SOFTWARE. this.end(); cb(err); }; - /* WEBPACK VAR INJECTION */ - }.call(this, __webpack_require__(1), __webpack_require__(7).setImmediate, __webpack_require__(2))) + /* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(1), __webpack_require__(7).setImmediate, __webpack_require__(2))) - /***/ - }), - /* 20 */ - /***/ (function (module, exports) { + /***/ }), + /* 18 */ + /***/ (function(module, exports) { var toString = {}.toString; @@ -10553,20 +10219,234 @@ THE SOFTWARE. }; - /***/ - }), - /* 21 */ - /***/ (function (module, exports) { + /***/ }), + /* 19 */ + /***/ (function(module, exports, __webpack_require__) { + + /* + +The MIT License (MIT) + +Original Library + - Copyright (c) Marak Squires + +Additional functionality + - Copyright (c) Sindre Sorhus (sindresorhus.com) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + + var colors = {}; + module['exports'] = colors; + + colors.themes = {}; + + var util = __webpack_require__(5); + var ansiStyles = colors.styles = __webpack_require__(47); + var defineProps = Object.defineProperties; + var newLineRegex = new RegExp(/[\r\n]+/g); + + colors.supportsColor = __webpack_require__(48).supportsColor; + + if (typeof colors.enabled === 'undefined') { + colors.enabled = colors.supportsColor() !== false; + } + + colors.enable = function() { + colors.enabled = true; + }; + + colors.disable = function() { + colors.enabled = false; + }; + + colors.stripColors = colors.strip = function(str) { + return ('' + str).replace(/\x1B\[\d+m/g, ''); + }; + +// eslint-disable-next-line no-unused-vars + var stylize = colors.stylize = function stylize(str, style) { + if (!colors.enabled) { + return str+''; + } + + var styleMap = ansiStyles[style]; + + // Stylize should work for non-ANSI styles, too + if(!styleMap && style in colors){ + // Style maps like trap operate as functions on strings; + // they don't have properties like open or close. + return colors[style](str); + } + + return styleMap.open + str + styleMap.close; + }; + + var matchOperatorsRe = /[|\\{}()[\]^$+*?.]/g; + var escapeStringRegexp = function(str) { + if (typeof str !== 'string') { + throw new TypeError('Expected a string'); + } + return str.replace(matchOperatorsRe, '\\$&'); + }; + + function build(_styles) { + var builder = function builder() { + return applyStyle.apply(builder, arguments); + }; + builder._styles = _styles; + // __proto__ is used because we must return a function, but there is + // no way to create a function with a different prototype. + builder.__proto__ = proto; + return builder; + } + + var styles = (function() { + var ret = {}; + ansiStyles.grey = ansiStyles.gray; + Object.keys(ansiStyles).forEach(function(key) { + ansiStyles[key].closeRe = + new RegExp(escapeStringRegexp(ansiStyles[key].close), 'g'); + ret[key] = { + get: function() { + return build(this._styles.concat(key)); + }, + }; + }); + return ret; + })(); + + var proto = defineProps(function colors() {}, styles); + + function applyStyle() { + var args = Array.prototype.slice.call(arguments); + + var str = args.map(function(arg) { + // Use weak equality check so we can colorize null/undefined in safe mode + if (arg != null && arg.constructor === String) { + return arg; + } else { + return util.inspect(arg); + } + }).join(' '); + + if (!colors.enabled || !str) { + return str; + } + + var newLinesPresent = str.indexOf('\n') != -1; + + var nestedStyles = this._styles; + + var i = nestedStyles.length; + while (i--) { + var code = ansiStyles[nestedStyles[i]]; + str = code.open + str.replace(code.closeRe, code.open) + code.close; + if (newLinesPresent) { + str = str.replace(newLineRegex, function(match) { + return code.close + match + code.open; + }); + } + } + + return str; + } + + colors.setTheme = function(theme) { + if (typeof theme === 'string') { + console.log('colors.setTheme now only accepts an object, not a string. ' + + 'If you are trying to set a theme from a file, it is now your (the ' + + 'caller\'s) responsibility to require the file. The old syntax ' + + 'looked like colors.setTheme(__dirname + ' + + '\'/../themes/generic-logging.js\'); The new syntax looks like '+ + 'colors.setTheme(require(__dirname + ' + + '\'/../themes/generic-logging.js\'));'); + return; + } + for (var style in theme) { + (function(style) { + colors[style] = function(str) { + if (typeof theme[style] === 'object') { + var out = str; + for (var i in theme[style]) { + out = colors[theme[style][i]](out); + } + return out; + } + return colors[theme[style]](str); + }; + })(style); + } + }; + + function init() { + var ret = {}; + Object.keys(styles).forEach(function(name) { + ret[name] = { + get: function() { + return build([name]); + }, + }; + }); + return ret; + } + + var sequencer = function sequencer(map, str) { + var exploded = str.split(''); + exploded = exploded.map(map); + return exploded.join(''); + }; + +// custom formatter methods + colors.trap = __webpack_require__(51); + colors.zalgo = __webpack_require__(52); + +// maps + colors.maps = {}; + colors.maps.america = __webpack_require__(53)(colors); + colors.maps.zebra = __webpack_require__(54)(colors); + colors.maps.rainbow = __webpack_require__(55)(colors); + colors.maps.random = __webpack_require__(56)(colors); + + for (var map in colors.maps) { + (function(map) { + colors[map] = function(str) { + return sequencer(colors.maps[map], str); + }; + })(map); + } + + defineProps(colors, init()); + + + /***/ }), + /* 20 */ + /***/ (function(module, exports) { /* (ignored) */ - /***/ - }), - /* 22 */ - /***/ (function (module, exports, __webpack_require__) { + /***/ }), + /* 21 */ + /***/ (function(module, exports, __webpack_require__) { - /* WEBPACK VAR INJECTION */ - (function (Buffer) {//Intel Hex record types + /* WEBPACK VAR INJECTION */(function(Buffer) {//Intel Hex record types const DATA = 0, END_OF_FILE = 1, EXT_SEGMENT_ADDR = 2, @@ -10590,10 +10470,10 @@ THE SOFTWARE. Special thanks to: http://en.wikipedia.org/wiki/Intel_HEX */ exports.parse = function parseIntelHex(data, bufferSize) { - if (data instanceof Buffer) + if(data instanceof Buffer) data = data.toString("ascii"); //Initialization - var buf = new Buffer(bufferSize || 8192), + var buf = Buffer.alloc(bufferSize || 8192), bufLength = 0, //Length of data in the buffer highAddress = 0, //upper address startSegmentAddress = null, @@ -10601,10 +10481,11 @@ THE SOFTWARE. lineNum = 0, //Line number in the Intel Hex string pos = 0; //Current position in the Intel Hex string const SMALLEST_LINE = 11; - while (pos + SMALLEST_LINE <= data.length) { + while(pos + SMALLEST_LINE <= data.length) + { //Parse an entire line - if (data.charAt(pos++) != ":") - throw new Error("Line " + (lineNum + 1) + + if(data.charAt(pos++) != ":") + throw new Error("Line " + (lineNum+1) + " does not start with a colon (:)."); else lineNum++; @@ -10619,7 +10500,7 @@ THE SOFTWARE. pos += 2; //Data field (hex-encoded string) var dataField = data.substr(pos, dataLength * 2), - dataFieldBuf = new Buffer(dataField, "hex"); + dataFieldBuf = Buffer.from(dataField, "hex"); pos += dataLength * 2; //Checksum var checksum = parseInt(data.substr(pos, 2), 16); @@ -10627,31 +10508,33 @@ THE SOFTWARE. //Validate checksum var calcChecksum = (dataLength + (lowAddress >> 8) + lowAddress + recordType) & 0xFF; - for (var i = 0; i < dataLength; i++) + for(var i = 0; i < dataLength; i++) calcChecksum = (calcChecksum + dataFieldBuf[i]) & 0xFF; calcChecksum = (0x100 - calcChecksum) & 0xFF; - if (checksum != calcChecksum) + if(checksum != calcChecksum) throw new Error("Invalid checksum on line " + lineNum + ": got " + checksum + ", but expected " + calcChecksum); //Parse the record based on its recordType - switch (recordType) { + switch(recordType) + { case DATA: var absoluteAddress = highAddress + lowAddress; //Expand buf, if necessary - if (absoluteAddress + dataLength >= buf.length) { - var tmp = new Buffer((absoluteAddress + dataLength) * 2); + if(absoluteAddress + dataLength >= buf.length) + { + var tmp = Buffer.alloc((absoluteAddress + dataLength) * 2); buf.copy(tmp, 0, 0, bufLength); buf = tmp; } //Write over skipped bytes with EMPTY_VALUE - if (absoluteAddress > bufLength) + if(absoluteAddress > bufLength) buf.fill(EMPTY_VALUE, bufLength, absoluteAddress); //Write the dataFieldBuf to buf dataFieldBuf.copy(buf, absoluteAddress); bufLength = Math.max(bufLength, absoluteAddress + dataLength); break; case END_OF_FILE: - if (dataLength != 0) + if(dataLength != 0) throw new Error("Invalid EOF record on line " + lineNum + "."); return { @@ -10661,25 +10544,25 @@ THE SOFTWARE. }; break; case EXT_SEGMENT_ADDR: - if (dataLength != 2 || lowAddress != 0) + if(dataLength != 2 || lowAddress != 0) throw new Error("Invalid extended segment address record on line " + lineNum + "."); highAddress = parseInt(dataField, 16) << 4; break; case START_SEGMENT_ADDR: - if (dataLength != 4 || lowAddress != 0) + if(dataLength != 4 || lowAddress != 0) throw new Error("Invalid start segment address record on line " + lineNum + "."); startSegmentAddress = parseInt(dataField, 16); break; case EXT_LINEAR_ADDR: - if (dataLength != 2 || lowAddress != 0) + if(dataLength != 2 || lowAddress != 0) throw new Error("Invalid extended linear address record on line " + lineNum + "."); highAddress = parseInt(dataField, 16) << 16; break; case START_LINEAR_ADDR: - if (dataLength != 4 || lowAddress != 0) + if(dataLength != 4 || lowAddress != 0) throw new Error("Invalid start linear address record on line " + lineNum + "."); startLinearAddress = parseInt(dataField, 16); @@ -10690,141 +10573,120 @@ THE SOFTWARE. break; } //Advance to the next line - if (data.charAt(pos) == "\r") + if(data.charAt(pos) == "\r") pos++; - if (data.charAt(pos) == "\n") + if(data.charAt(pos) == "\n") pos++; } throw new Error("Unexpected end of input: missing or invalid EOF record."); }; - /* WEBPACK VAR INJECTION */ - }.call(this, __webpack_require__(0).Buffer)) - - /***/ - }), - /* 23 */ - /***/ (function (module, exports) { - - function webpackEmptyContext(req) { - var e = new Error("Cannot find module '" + req + "'"); - e.code = 'MODULE_NOT_FOUND'; - throw e; - } - webpackEmptyContext.keys = function () { - return []; - }; - webpackEmptyContext.resolve = webpackEmptyContext; - module.exports = webpackEmptyContext; - webpackEmptyContext.id = 23; + /* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(0).Buffer)) - /***/ - }), - /* 24 */ - /***/ (function (module, exports) { + /***/ }), + /* 22 */ + /***/ (function(module, exports) { // STK message constants module.exports.MESSAGE_START = 0x1B - module.exports.TOKEN = 0x0E + module.exports.TOKEN = 0x0E // STK general command constants - module.exports.CMD_SIGN_ON = 0x01 - module.exports.CMD_SET_PARAMETER = 0x02 - module.exports.CMD_GET_PARAMETER = 0x03 + module.exports.CMD_SIGN_ON = 0x01 + module.exports.CMD_SET_PARAMETER = 0x02 + module.exports.CMD_GET_PARAMETER = 0x03 module.exports.CMD_SET_DEVICE_PARAMETERS = 0x04 - module.exports.CMD_OSCCAL = 0x05 - module.exports.CMD_LOAD_ADDRESS = 0x06 - module.exports.CMD_FIRMWARE_UPGRADE = 0x07 + module.exports.CMD_OSCCAL = 0x05 + module.exports.CMD_LOAD_ADDRESS = 0x06 + module.exports.CMD_FIRMWARE_UPGRADE = 0x07 // STK ISP command constants - module.exports.CMD_ENTER_PROGMODE_ISP = 0x10 - module.exports.CMD_LEAVE_PROGMODE_ISP = 0x11 - module.exports.CMD_CHIP_ERASE_ISP = 0x12 - module.exports.CMD_PROGRAM_FLASH_ISP = 0x13 - module.exports.CMD_READ_FLASH_ISP = 0x14 - module.exports.CMD_PROGRAM_EEPROM_ISP = 0x15 - module.exports.CMD_READ_EEPROM_ISP = 0x16 - module.exports.CMD_PROGRAM_FUSE_ISP = 0x17 - module.exports.CMD_READ_FUSE_ISP = 0x18 - module.exports.CMD_PROGRAM_LOCK_ISP = 0x19 - module.exports.CMD_READ_LOCK_ISP = 0x1A - module.exports.CMD_READ_SIGNATURE_ISP = 0x1B - module.exports.CMD_READ_OSCCAL_ISP = 0x1C - module.exports.CMD_SPI_MULTI = 0x1D + module.exports.CMD_ENTER_PROGMODE_ISP = 0x10 + module.exports.CMD_LEAVE_PROGMODE_ISP = 0x11 + module.exports.CMD_CHIP_ERASE_ISP = 0x12 + module.exports.CMD_PROGRAM_FLASH_ISP = 0x13 + module.exports.CMD_READ_FLASH_ISP = 0x14 + module.exports.CMD_PROGRAM_EEPROM_ISP = 0x15 + module.exports.CMD_READ_EEPROM_ISP = 0x16 + module.exports.CMD_PROGRAM_FUSE_ISP = 0x17 + module.exports.CMD_READ_FUSE_ISP = 0x18 + module.exports.CMD_PROGRAM_LOCK_ISP = 0x19 + module.exports.CMD_READ_LOCK_ISP = 0x1A + module.exports.CMD_READ_SIGNATURE_ISP = 0x1B + module.exports.CMD_READ_OSCCAL_ISP = 0x1C + module.exports.CMD_SPI_MULTI = 0x1D // STK PP command constants - module.exports.CMD_ENTER_PROGMODE_PP = 0x20 - module.exports.CMD_LEAVE_PROGMODE_PP = 0x21 - module.exports.CMD_CHIP_ERASE_PP = 0x22 - module.exports.CMD_PROGRAM_FLASH_PP = 0x23 - module.exports.CMD_READ_FLASH_PP = 0x24 - module.exports.CMD_PROGRAM_EEPROM_PP = 0x25 - module.exports.CMD_READ_EEPROM_PP = 0x26 - module.exports.CMD_PROGRAM_FUSE_PP = 0x27 - module.exports.CMD_READ_FUSE_PP = 0x28 - module.exports.CMD_PROGRAM_LOCK_PP = 0x29 - module.exports.CMD_READ_LOCK_PP = 0x2A - module.exports.CMD_READ_SIGNATURE_PP = 0x2B - module.exports.CMD_READ_OSCCAL_PP = 0x2C - module.exports.CMD_SET_CONTROL_STACK = 0x2D + module.exports.CMD_ENTER_PROGMODE_PP = 0x20 + module.exports.CMD_LEAVE_PROGMODE_PP = 0x21 + module.exports.CMD_CHIP_ERASE_PP = 0x22 + module.exports.CMD_PROGRAM_FLASH_PP = 0x23 + module.exports.CMD_READ_FLASH_PP = 0x24 + module.exports.CMD_PROGRAM_EEPROM_PP = 0x25 + module.exports.CMD_READ_EEPROM_PP = 0x26 + module.exports.CMD_PROGRAM_FUSE_PP = 0x27 + module.exports.CMD_READ_FUSE_PP = 0x28 + module.exports.CMD_PROGRAM_LOCK_PP = 0x29 + module.exports.CMD_READ_LOCK_PP = 0x2A + module.exports.CMD_READ_SIGNATURE_PP = 0x2B + module.exports.CMD_READ_OSCCAL_PP = 0x2C + module.exports.CMD_SET_CONTROL_STACK = 0x2D // STK HVSP command constants module.exports.CMD_ENTER_PROGMODE_HVSP = 0x30 module.exports.CMD_LEAVE_PROGMODE_HVSP = 0x31 - module.exports.CMD_CHIP_ERASE_HVSP = 0x32 - module.exports.CMD_PROGRAM_FLASH_HVSP = 0x33 - module.exports.CMD_READ_FLASH_HVSP = 0x34 + module.exports.CMD_CHIP_ERASE_HVSP = 0x32 + module.exports.CMD_PROGRAM_FLASH_HVSP = 0x33 + module.exports.CMD_READ_FLASH_HVSP = 0x34 module.exports.CMD_PROGRAM_EEPROM_HVSP = 0x35 - module.exports.CMD_READ_EEPROM_HVSP = 0x36 - module.exports.CMD_PROGRAM_FUSE_HVSP = 0x37 - module.exports.CMD_READ_FUSE_HVSP = 0x38 - module.exports.CMD_PROGRAM_LOCK_HVSP = 0x39 - module.exports.CMD_READ_LOCK_HVSP = 0x3A + module.exports.CMD_READ_EEPROM_HVSP = 0x36 + module.exports.CMD_PROGRAM_FUSE_HVSP = 0x37 + module.exports.CMD_READ_FUSE_HVSP = 0x38 + module.exports.CMD_PROGRAM_LOCK_HVSP = 0x39 + module.exports.CMD_READ_LOCK_HVSP = 0x3A module.exports.CMD_READ_SIGNATURE_HVSP = 0x3B - module.exports.CMD_READ_OSCCAL_HVSP = 0x3C + module.exports.CMD_READ_OSCCAL_HVSP = 0x3C // STK status constants // Success module.exports.STATUS_CMD_OK = 0x00 // Warnings - module.exports.STATUS_CMD_TOUT = 0x80 - module.exports.STATUS_RDY_BSY_TOUT = 0x81 + module.exports.STATUS_CMD_TOUT = 0x80 + module.exports.STATUS_RDY_BSY_TOUT = 0x81 module.exports.STATUS_SET_PARAM_MISSING = 0x82 // Errors - module.exports.STATUS_CMD_FAILED = 0xC0 + module.exports.STATUS_CMD_FAILED = 0xC0 module.exports.STATUS_CKSUM_ERROR = 0xC1 module.exports.STATUS_CMD_UNKNOWN = 0xC9 // STK parameter constants - module.exports.STATUS_BUILD_NUMBER_LOW = 0x80 + module.exports.STATUS_BUILD_NUMBER_LOW = 0x80 module.exports.STATUS_BUILD_NUMBER_HIGH = 0x81 - module.exports.STATUS_HW_VER = 0x90 - module.exports.STATUS_SW_MAJOR = 0x91 - module.exports.STATUS_SW_MINOR = 0x92 - module.exports.STATUS_VTARGET = 0x94 - module.exports.STATUS_VADJUST = 0x95 - module.exports.STATUS_OSC_PSCALE = 0x96 - module.exports.STATUS_OSC_CMATCH = 0x97 - module.exports.STATUS_SCK_DURATION = 0x98 - module.exports.STATUS_TOPCARD_DETECT = 0x9A - module.exports.STATUS_STATUS = 0x9C - module.exports.STATUS_DATA = 0x9D - module.exports.STATUS_RESET_POLARITY = 0x9E - module.exports.STATUS_CONTROLLER_INIT = 0x9F + module.exports.STATUS_HW_VER = 0x90 + module.exports.STATUS_SW_MAJOR = 0x91 + module.exports.STATUS_SW_MINOR = 0x92 + module.exports.STATUS_VTARGET = 0x94 + module.exports.STATUS_VADJUST = 0x95 + module.exports.STATUS_OSC_PSCALE = 0x96 + module.exports.STATUS_OSC_CMATCH = 0x97 + module.exports.STATUS_SCK_DURATION = 0x98 + module.exports.STATUS_TOPCARD_DETECT = 0x9A + module.exports.STATUS_STATUS = 0x9C + module.exports.STATUS_DATA = 0x9D + module.exports.STATUS_RESET_POLARITY = 0x9E + module.exports.STATUS_CONTROLLER_INIT = 0x9F // STK answer constants module.exports.ANSWER_CKSUM_ERROR = 0xB0 - /***/ - }), - /* 25 */ - /***/ (function (module, exports, __webpack_require__) { + /***/ }), + /* 23 */ + /***/ (function(module, exports, __webpack_require__) { "use strict"; - /* WEBPACK VAR INJECTION */ - (function (global, process) {// Copyright Joyent, Inc. and other Node contributors. + /* WEBPACK VAR INJECTION */(function(global, process) {// Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the @@ -10846,15 +10708,16 @@ THE SOFTWARE. // USE OR OTHER DEALINGS IN THE SOFTWARE. + /**/ - var pna = __webpack_require__(11); + var pna = __webpack_require__(9); /**/ module.exports = Readable; /**/ - var isArray = __webpack_require__(20); + var isArray = __webpack_require__(18); /**/ /**/ @@ -10864,7 +10727,7 @@ THE SOFTWARE. Readable.ReadableState = ReadableState; /**/ - var EE = __webpack_require__(5).EventEmitter; + var EE = __webpack_require__(4).EventEmitter; var EElistenerCount = function (emitter, type) { return emitter.listeners(type).length; @@ -10872,19 +10735,16 @@ THE SOFTWARE. /**/ /**/ - var Stream = __webpack_require__(26); + var Stream = __webpack_require__(24); /**/ /**/ - var Buffer = __webpack_require__(12).Buffer; - var OurUint8Array = global.Uint8Array || function () { - }; - + var Buffer = __webpack_require__(16).Buffer; + var OurUint8Array = global.Uint8Array || function () {}; function _uint8ArrayToBuffer(chunk) { return Buffer.from(chunk); } - function _isUint8Array(obj) { return Buffer.isBuffer(obj) || obj instanceof OurUint8Array; } @@ -10892,23 +10752,22 @@ THE SOFTWARE. /**/ /**/ - var util = __webpack_require__(9); - util.inherits = __webpack_require__(3); + var util = Object.create(__webpack_require__(8)); + util.inherits = __webpack_require__(6); /**/ /**/ - var debugUtil = __webpack_require__(64); + var debugUtil = __webpack_require__(65); var debug = void 0; if (debugUtil && debugUtil.debuglog) { debug = debugUtil.debuglog('stream'); } else { - debug = function () { - }; + debug = function () {}; } /**/ - var BufferList = __webpack_require__(65); - var destroyImpl = __webpack_require__(27); + var BufferList = __webpack_require__(66); + var destroyImpl = __webpack_require__(25); var StringDecoder; util.inherits(Readable, Stream); @@ -10924,11 +10783,11 @@ THE SOFTWARE. // userland ones. NEVER DO THIS. This is here only because this code needs // to continue to work with older versions of Node.js that do not include // the prependListener() method. The goal is to eventually remove this hack. - if (!emitter._events || !emitter._events[event]) emitter.on(event, fn); else if (isArray(emitter._events[event])) emitter._events[event].unshift(fn); else emitter._events[event] = [fn, emitter._events[event]]; + if (!emitter._events || !emitter._events[event]) emitter.on(event, fn);else if (isArray(emitter._events[event])) emitter._events[event].unshift(fn);else emitter._events[event] = [fn, emitter._events[event]]; } function ReadableState(options, stream) { - Duplex = Duplex || __webpack_require__(4); + Duplex = Duplex || __webpack_require__(3); options = options || {}; @@ -10951,7 +10810,7 @@ THE SOFTWARE. var readableHwm = options.readableHighWaterMark; var defaultHwm = this.objectMode ? 16 : 16 * 1024; - if (hwm || hwm === 0) this.highWaterMark = hwm; else if (isDuplex && (readableHwm || readableHwm === 0)) this.highWaterMark = readableHwm; else this.highWaterMark = defaultHwm; + if (hwm || hwm === 0) this.highWaterMark = hwm;else if (isDuplex && (readableHwm || readableHwm === 0)) this.highWaterMark = readableHwm;else this.highWaterMark = defaultHwm; // cast to ints. this.highWaterMark = Math.floor(this.highWaterMark); @@ -10998,14 +10857,14 @@ THE SOFTWARE. this.decoder = null; this.encoding = null; if (options.encoding) { - if (!StringDecoder) StringDecoder = __webpack_require__(28).StringDecoder; + if (!StringDecoder) StringDecoder = __webpack_require__(26).StringDecoder; this.decoder = new StringDecoder(options.encoding); this.encoding = options.encoding; } } function Readable(options) { - Duplex = Duplex || __webpack_require__(4); + Duplex = Duplex || __webpack_require__(3); if (!(this instanceof Readable)) return new Readable(options); @@ -11095,14 +10954,14 @@ THE SOFTWARE. } if (addToFront) { - if (state.endEmitted) stream.emit('error', new Error('stream.unshift() after end event')); else addChunk(stream, state, chunk, true); + if (state.endEmitted) stream.emit('error', new Error('stream.unshift() after end event'));else addChunk(stream, state, chunk, true); } else if (state.ended) { stream.emit('error', new Error('stream.push() after EOF')); } else { state.reading = false; if (state.decoder && !encoding) { chunk = state.decoder.write(chunk); - if (state.objectMode || chunk.length !== 0) addChunk(stream, state, chunk, false); else maybeReadMore(stream, state); + if (state.objectMode || chunk.length !== 0) addChunk(stream, state, chunk, false);else maybeReadMore(stream, state); } else { addChunk(stream, state, chunk, false); } @@ -11122,7 +10981,7 @@ THE SOFTWARE. } else { // update the buffer info. state.length += state.objectMode ? 1 : chunk.length; - if (addToFront) state.buffer.unshift(chunk); else state.buffer.push(chunk); + if (addToFront) state.buffer.unshift(chunk);else state.buffer.push(chunk); if (state.needReadable) emitReadable(stream); } @@ -11154,7 +11013,7 @@ THE SOFTWARE. // backwards compatibility. Readable.prototype.setEncoding = function (enc) { - if (!StringDecoder) StringDecoder = __webpack_require__(28).StringDecoder; + if (!StringDecoder) StringDecoder = __webpack_require__(26).StringDecoder; this._readableState.decoder = new StringDecoder(enc); this._readableState.encoding = enc; return this; @@ -11162,7 +11021,6 @@ THE SOFTWARE. // Don't raise the hwm > 8MB var MAX_HWM = 0x800000; - function computeNewHighWaterMark(n) { if (n >= MAX_HWM) { n = MAX_HWM; @@ -11187,7 +11045,7 @@ THE SOFTWARE. if (state.objectMode) return 1; if (n !== n) { // Only flow one buffer at a time - if (state.flowing && state.length) return state.buffer.head.data.length; else return state.length; + if (state.flowing && state.length) return state.buffer.head.data.length;else return state.length; } // If we're asking for more than the current hwm, then raise the hwm. if (n > state.highWaterMark) state.highWaterMark = computeNewHighWaterMark(n); @@ -11214,7 +11072,7 @@ THE SOFTWARE. // the 'readable' event and move on. if (n === 0 && state.needReadable && (state.length >= state.highWaterMark || state.ended)) { debug('read: emitReadable', state.length, state.ended); - if (state.length === 0 && state.ended) endReadable(this); else emitReadable(this); + if (state.length === 0 && state.ended) endReadable(this);else emitReadable(this); return null; } @@ -11278,7 +11136,7 @@ THE SOFTWARE. } var ret; - if (n > 0) ret = fromList(n, state); else ret = null; + if (n > 0) ret = fromList(n, state);else ret = null; if (ret === null) { state.needReadable = true; @@ -11325,7 +11183,7 @@ THE SOFTWARE. if (!state.emittedReadable) { debug('emitReadable', state.flowing); state.emittedReadable = true; - if (state.sync) pna.nextTick(emitReadable_, stream); else emitReadable_(stream); + if (state.sync) pna.nextTick(emitReadable_, stream);else emitReadable_(stream); } } @@ -11355,7 +11213,7 @@ THE SOFTWARE. stream.read(0); if (len === state.length) // didn't get any data, stop spinning. - break; else len = state.length; + break;else len = state.length; } state.readingMore = false; } @@ -11389,10 +11247,9 @@ THE SOFTWARE. var doEnd = (!pipeOpts || pipeOpts.end !== false) && dest !== process.stdout && dest !== process.stderr; var endFn = doEnd ? onend : unpipe; - if (state.endEmitted) pna.nextTick(endFn); else src.once('end', endFn); + if (state.endEmitted) pna.nextTick(endFn);else src.once('end', endFn); dest.on('unpipe', onunpipe); - function onunpipe(readable, unpipeInfo) { debug('onunpipe'); if (readable === src) { @@ -11416,7 +11273,6 @@ THE SOFTWARE. dest.on('drain', ondrain); var cleanedUp = false; - function cleanup() { debug('cleanup'); // cleanup event handlers once the pipe is broken @@ -11445,7 +11301,6 @@ THE SOFTWARE. // => Introduce a guard on increasing awaitDrain. var increasedAwaitDrain = false; src.on('data', ondata); - function ondata(chunk) { debug('ondata'); increasedAwaitDrain = false; @@ -11481,15 +11336,12 @@ THE SOFTWARE. dest.removeListener('finish', onfinish); unpipe(); } - dest.once('close', onclose); - function onfinish() { debug('onfinish'); dest.removeListener('close', onclose); unpipe(); } - dest.once('finish', onfinish); function unpipe() { @@ -11523,7 +11375,7 @@ THE SOFTWARE. Readable.prototype.unpipe = function (dest) { var state = this._readableState; - var unpipeInfo = {hasUnpiped: false}; + var unpipeInfo = { hasUnpiped: false }; // if we're not piping anywhere, then do nothing. if (state.pipesCount === 0) return this; @@ -11555,8 +11407,7 @@ THE SOFTWARE. for (var i = 0; i < len; i++) { dests[i].emit('unpipe', this, unpipeInfo); - } - return this; + }return this; } // try to find the right one. @@ -11647,8 +11498,7 @@ THE SOFTWARE. function flow(stream) { var state = stream._readableState; debug('flow', state.flowing); - while (state.flowing && stream.read() !== null) { - } + while (state.flowing && stream.read() !== null) {} } // wrap an old-style stream as the async data source. @@ -11675,7 +11525,7 @@ THE SOFTWARE. if (state.decoder) chunk = state.decoder.write(chunk); // don't skip over falsy values in objectMode - if (state.objectMode && (chunk === null || chunk === undefined)) return; else if (!state.objectMode && (!chunk || !chunk.length)) return; + if (state.objectMode && (chunk === null || chunk === undefined)) return;else if (!state.objectMode && (!chunk || !chunk.length)) return; var ret = _this.push(chunk); if (!ret) { @@ -11736,9 +11586,9 @@ THE SOFTWARE. if (state.length === 0) return null; var ret; - if (state.objectMode) ret = state.buffer.shift(); else if (!n || n >= state.length) { + if (state.objectMode) ret = state.buffer.shift();else if (!n || n >= state.length) { // read it all, truncate the list - if (state.decoder) ret = state.buffer.join(''); else if (state.buffer.length === 1) ret = state.buffer.head.data; else ret = state.buffer.concat(state.length); + if (state.decoder) ret = state.buffer.join('');else if (state.buffer.length === 1) ret = state.buffer.head.data;else ret = state.buffer.concat(state.length); state.buffer.clear(); } else { // read part of list @@ -11779,12 +11629,12 @@ THE SOFTWARE. while (p = p.next) { var str = p.data; var nb = n > str.length ? str.length : n; - if (nb === str.length) ret += str; else ret += str.slice(0, n); + if (nb === str.length) ret += str;else ret += str.slice(0, n); n -= nb; if (n === 0) { if (nb === str.length) { ++c; - if (p.next) list.head = p.next; else list.head = list.tail = null; + if (p.next) list.head = p.next;else list.head = list.tail = null; } else { list.head = p; p.data = str.slice(nb); @@ -11814,7 +11664,7 @@ THE SOFTWARE. if (n === 0) { if (nb === buf.length) { ++c; - if (p.next) list.head = p.next; else list.head = list.tail = null; + if (p.next) list.head = p.next;else list.head = list.tail = null; } else { list.head = p; p.data = buf.slice(nb); @@ -11855,29 +11705,25 @@ THE SOFTWARE. } return -1; } + /* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(2), __webpack_require__(1))) - /* WEBPACK VAR INJECTION */ - }.call(this, __webpack_require__(2), __webpack_require__(1))) - - /***/ - }), - /* 26 */ - /***/ (function (module, exports, __webpack_require__) { + /***/ }), + /* 24 */ + /***/ (function(module, exports, __webpack_require__) { - module.exports = __webpack_require__(5).EventEmitter; + module.exports = __webpack_require__(4).EventEmitter; - /***/ - }), - /* 27 */ - /***/ (function (module, exports, __webpack_require__) { + /***/ }), + /* 25 */ + /***/ (function(module, exports, __webpack_require__) { "use strict"; /**/ - var pna = __webpack_require__(11); + var pna = __webpack_require__(9); /**/ // undocumented cb() API, needed for core, not for public API @@ -11948,10 +11794,9 @@ THE SOFTWARE. undestroy: undestroy }; - /***/ - }), - /* 28 */ - /***/ (function (module, exports, __webpack_require__) { + /***/ }), + /* 26 */ + /***/ (function(module, exports, __webpack_require__) { "use strict"; // Copyright Joyent, Inc. and other Node contributors. @@ -11976,25 +11821,16 @@ THE SOFTWARE. // USE OR OTHER DEALINGS IN THE SOFTWARE. + /**/ - var Buffer = __webpack_require__(12).Buffer; + var Buffer = __webpack_require__(69).Buffer; /**/ var isEncoding = Buffer.isEncoding || function (encoding) { - encoding = '' + encoding; - switch (encoding && encoding.toLowerCase()) { - case 'hex': - case 'utf8': - case 'utf-8': - case 'ascii': - case 'binary': - case 'base64': - case 'ucs2': - case 'ucs-2': - case 'utf16le': - case 'utf-16le': - case 'raw': + encoding = '' + encoding; + switch (encoding && encoding.toLowerCase()) { + case 'hex':case 'utf8':case 'utf-8':case 'ascii':case 'binary':case 'base64':case 'ucs2':case 'ucs-2':case 'utf16le':case 'utf-16le':case 'raw': return true; default: return false; @@ -12027,7 +11863,7 @@ THE SOFTWARE. retried = true; } } - } + }; // Do not cache `Buffer.isEncoding` when checking encoding names as some // modules monkey-patch it to support additional encodings @@ -12041,7 +11877,6 @@ THE SOFTWARE. // buffers into a series of JS strings without breaking apart multi-byte // characters. exports.StringDecoder = StringDecoder; - function StringDecoder(encoding) { this.encoding = normalizeEncoding(encoding); var nb; @@ -12104,7 +11939,7 @@ THE SOFTWARE. // Checks the type of a UTF-8 byte, whether it's ASCII, a leading byte, or a // continuation byte. If an invalid byte is detected, -2 is returned. function utf8CheckByte(byte) { - if (byte <= 0x7F) return 0; else if (byte >> 5 === 0x06) return 2; else if (byte >> 4 === 0x0E) return 3; else if (byte >> 3 === 0x1E) return 4; + if (byte <= 0x7F) return 0;else if (byte >> 5 === 0x06) return 2;else if (byte >> 4 === 0x0E) return 3;else if (byte >> 3 === 0x1E) return 4; return byte >> 6 === 0x02 ? -1 : -2; } @@ -12129,7 +11964,7 @@ THE SOFTWARE. nb = utf8CheckByte(buf[j]); if (nb >= 0) { if (nb > 0) { - if (nb === 2) nb = 0; else self.lastNeed = nb - 3; + if (nb === 2) nb = 0;else self.lastNeed = nb - 3; } return nb; } @@ -12261,10 +12096,9 @@ THE SOFTWARE. return buf && buf.length ? this.write(buf) : ''; } - /***/ - }), - /* 29 */ - /***/ (function (module, exports, __webpack_require__) { + /***/ }), + /* 27 */ + /***/ (function(module, exports, __webpack_require__) { "use strict"; // Copyright Joyent, Inc. and other Node contributors. @@ -12331,13 +12165,14 @@ THE SOFTWARE. // the results of the previous transformed chunk were consumed. + module.exports = Transform; - var Duplex = __webpack_require__(4); + var Duplex = __webpack_require__(3); /**/ - var util = __webpack_require__(9); - util.inherits = __webpack_require__(3); + var util = Object.create(__webpack_require__(8)); + util.inherits = __webpack_require__(6); /**/ util.inherits(Transform, Duplex); @@ -12481,313 +12316,310 @@ THE SOFTWARE. return stream.push(null); } - /***/ - }), - /* 30 */ - /***/ (function (module, exports, __webpack_require__) { + /***/ }), + /* 28 */ + /***/ (function(module, exports, __webpack_require__) { - var boards = __webpack_require__(31); - var Connection = __webpack_require__(34); - var protocols = __webpack_require__(41); - var AvrgirlArduino = __webpack_require__(74); + var boards = __webpack_require__(29); + var Connection = __webpack_require__(32); + var protocols = __webpack_require__(39); + var AvrgirlArduino = __webpack_require__(76); module.exports = AvrgirlArduino(boards, Connection, protocols); - /***/ - }), - /* 31 */ - /***/ (function (module, exports, __webpack_require__) { - - /* WEBPACK VAR INJECTION */ - (function (Buffer) { - var boards = [ - { - name: 'uno', - baud: 115200, - signature: new Buffer([0x1e, 0x95, 0x0f]), - pageSize: 128, - numPages: 256, - timeout: 400, - productId: ['0x0043', '0x7523', '0x0001', '0xea60'], - productPage: 'https://store.arduino.cc/arduino-uno-rev3', - protocol: 'stk500v1' - }, - { - name: 'micro', - baud: 57600, - signature: new Buffer([0x43, 0x41, 0x54, 0x45, 0x52, 0x49, 0x4e]), - productId: ['0x0037', '0x8037', '0x0036', '0x0237'], - productPage: 'https://store.arduino.cc/arduino-micro', - protocol: 'avr109' - }, - { - name: 'imuduino', - baud: 57600, - signature: new Buffer([0x43, 0x41, 0x54, 0x45, 0x52, 0x49, 0x4e]), - productId: ['0x0036', '0x8037', '0x8036'], - productPage: 'https://www.kickstarter.com/projects/1265095814/imuduino-wireless-3d-motion-html-js-apps-arduino-p?lang=de', - protocol: 'avr109' - }, - { - name: 'leonardo', - baud: 57600, - signature: new Buffer([0x43, 0x41, 0x54, 0x45, 0x52, 0x49, 0x4e]), - productId: ['0x0036', '0x8036', '0x800c'], - productPage: 'https://store.arduino.cc/leonardo', - protocol: 'avr109' - }, - { - name: 'arduboy', - baud: 57600, - signature: new Buffer([0x43, 0x41, 0x54, 0x45, 0x52, 0x49, 0x4e]), - productId: ['0x0036', '0x8036', '0x800c'], - productPage: 'https://arduboy.com/', - protocol: 'avr109' - }, - { - name: 'feather', - baud: 57600, - signature: new Buffer([0x43, 0x41, 0x54, 0x45, 0x52, 0x49, 0x4e]), - productId: ['0x800c', '0x000c'], - productPage: 'https://www.adafruit.com/feather', - protocol: 'avr109' - }, - { - name: 'little-bits', - baud: 57600, - signature: new Buffer([0x43, 0x41, 0x54, 0x45, 0x52, 0x49, 0x4e]), - productId: ['0x0036', '0x8036'], - productPage: 'https://littlebits.com/collections/bits-and-accessories/products/arduino-bit', - protocol: 'avr109' - }, - { - name: 'blend-micro', - baud: 57600, - signature: new Buffer([0x43, 0x41, 0x54, 0x45, 0x52, 0x49, 0x4e]), - productId: ['0x2404'], - productPage: 'https://redbear.cc/product/retired/blend-micro.html', - protocol: 'avr109' - }, - { - name: 'nano', - baud: 57600, - signature: new Buffer([0x1e, 0x95, 0x0f]), - pageSize: 128, - numPages: 256, - timeout: 400, - productId: ['0x6001', '0x7523'], - productPage: 'https://web.archive.org/web/20150813095112/https://www.arduino.cc/en/Main/ArduinoBoardNano', - protocol: 'stk500v1' - }, - { - name: 'nano (new bootloader)', - baud: 115200, - signature: new Buffer([0x1e, 0x95, 0x0f]), - pageSize: 128, - numPages: 256, - timeout: 400, - productId: ['0x6001', '0x7523'], - productPage: 'https://store.arduino.cc/arduino-nano', - protocol: 'stk500v1' - }, - { - name: 'duemilanove168', - baud: 19200, - signature: new Buffer([0x1e, 0x94, 0x06]), - pageSize: 128, - numPages: 128, - timeout: 400, - productId: ['0x6001'], - productPage: 'https://www.arduino.cc/en/Main/arduinoBoardDuemilanove', - protocol: 'stk500v1' - }, - { - name: 'duemilanove328', - baud: 57600, - signature: new Buffer([0x1e, 0x95, 0x14]), - pageSize: 128, - numPages: 256, - timeout: 400, - productId: ['0x6001'], - productPage: 'https://www.arduino.cc/en/Main/arduinoBoardDuemilanove', - protocol: 'stk500v1' - }, - // the alias is here because of an accidental naming change of the tinyduino - // keeping in for backwards compatibility (SHA 05d65842) - { - name: 'tinyduino', - baud: 57600, - signature: new Buffer([0x1e, 0x95, 0x0f]), - pageSize: 128, - numPages: 256, - timeout: 400, - productId: ['0x6015'], - productPage: 'https://tinycircuits.com/pages/tinyduino-overview', - protocol: 'stk500v1', - aliases: ['tinduino'] - }, - { - name: 'mega', - baud: 115200, - signature: new Buffer([0x1e, 0x98, 0x01]), // ATmega2560 - pageSize: 256, - delay1: 10, - delay2: 1, - timeout: 0xc8, - stabDelay: 0x64, - cmdexeDelay: 0x19, - synchLoops: 0x20, - byteDelay: 0x00, - pollValue: 0x53, - pollIndex: 0x03, - productId: ['0x0042', '0x6001', '0x0010', '0x7523'], - productPage: 'https://store.arduino.cc/mega-2560-r3', - protocol: 'stk500v2' - }, - { - name: 'adk', - baud: 115200, - signature: new Buffer([0x1e, 0x98, 0x01]), // ATmega2560 - pageSize: 256, - delay1: 10, - delay2: 1, - timeout: 0xc8, - stabDelay: 0x64, - cmdexeDelay: 0x19, - synchLoops: 0x20, - byteDelay: 0x00, - pollValue: 0x53, - pollIndex: 0x03, - productId: ['0x0044', '0x6001', '0x003F'], - productPage: 'https://store.arduino.cc/arduino-mega-adk-rev3', - protocol: 'stk500v2' - }, - { - name: 'sf-pro-micro', - baud: 57600, - signature: new Buffer([0x43, 0x41, 0x54, 0x45, 0x52, 0x49, 0x4e]), - productId: ['0x9206', '0x9205'], - productPage: 'https://www.sparkfun.com/products/12640', - protocol: 'avr109' - }, - { - name: 'pro-mini', - baud: 57600, - signature: new Buffer([0x1e, 0x95, 0x0f]), - pageSize: 128, - numPages: 256, - timeout: 400, - productPage: 'https://store.arduino.cc/arduino-pro-mini', - protocol: 'stk500v1' - }, - { - name: 'qduino', - baud: 57600, - signature: new Buffer([0x43, 0x41, 0x54, 0x45, 0x52, 0x49, 0x4e]), - productId: ['0x516d', '0x514d'], - productPage: 'https://www.sparkfun.com/products/13614', - protocol: 'avr109' - }, - { - name: 'pinoccio', - baud: 115200, - signature: new Buffer([0x1e, 0xa8, 0x02]), // ATmega256RFR2 - pageSize: 256, - delay1: 10, - delay2: 1, - timeout: 0xc8, - stabDelay: 0x64, - cmdexeDelay: 0x19, - synchLoops: 0x20, - byteDelay: 0x00, - pollValue: 0x53, - pollIndex: 0x03, - productId: ['0x6051'], - productPage: 'https://www.mouser.de/new/crowd-supply/crowd-supply-pinoccio-microcontroller/', - protocol: 'stk500v2' - }, - { - name: 'lilypad-usb', - baud: 57600, - signature: new Buffer([0x43, 0x41, 0x54, 0x45, 0x52, 0x49, 0x4e]), - productId: ['0x9207', '0x9208', '0x1B4F'], - productPage: 'https://www.sparkfun.com/products/12049', - protocol: 'avr109' - }, - { - name: 'yun', - baud: 57600, - signature: new Buffer([0x43, 0x41, 0x54, 0x45, 0x52, 0x49, 0x4e]), - productId: ['0x0041', '0x8041'], - productPage: 'https://store.arduino.cc/arduino-yun', - protocol: 'avr109' - }, - { - name: 'esplora', - baud: 57600, - signature: new Buffer([0x43, 0x41, 0x54, 0x45, 0x52, 0x49, 0x4e]), - productId: ['0x003C', '0x803C'], - productPage: 'https://store.arduino.cc/arduino-esplora', - protocol: 'avr109' - }, - { - name: 'circuit-playground-classic', - baud: 57600, - signature: new Buffer([0x43, 0x41, 0x54, 0x45, 0x52, 0x49, 0x4e]), - productId: ['0x0011', '0x8011'], - productPage: 'https://www.adafruit.com/product/3000', - protocol: 'avr109' - }, - /** BQ - Arduino Based Boards. Used in Bitbloq -> bitbloq.bq.com and Arduino IDE*/ - { - name: 'zumjunior', - baud: 115200, - signature: new Buffer([0x1e, 0x95, 0x0f]), - pageSize: 128, - numPages: 256, - timeout: 400, - productId: ['0xEA60'], - productPage: 'https://store-de.bq.com/de/zum-kit-junior', - protocol: 'stk500v1' - }, - { - name: 'zumcore2', - baud: 115200, - signature: new Buffer([0x1e, 0x95, 0x0f]), - pageSize: 128, - numPages: 256, - timeout: 400, - productId: ['0xEA60'], - productPage: 'https://www.bq.com/de/zum-core-2-0', - protocol: 'stk500v1' - }, - { - name: 'bqZum', - baud: 19200, - signature: new Buffer([0x1e, 0x95, 0x0f]), - pageSize: 128, - numPages: 256, - timeout: 400, - productId: ['0x6001', '0x7523'], - productPage: 'http://diwo.bq.com/zum-bt-328-especificaciones-tecnicas/', - protocol: 'stk500v1' - }, - /** END OF BQ - Arduino Based Boards. Used in Bitbloq -> bitbloq.bq.com and Arduino IDE*/ - /** START OF Spark Concepts Boards - Arduino Based CNC Controller but uses Atmega328pb (Note 'pb' not 'p' = different signature) https://github.com/Spark-Concepts/xPro-V4 */ - { - name: 'xprov4', - baud: 115200, - signature: new Buffer([0x1e, 0x95, 0x16]), - pageSize: 128, - numPages: 256, - timeout: 400, - productId: ['0x0043', '0x7523', '0x0001', '0xea60'], - productPage: 'http://www.spark-concepts.com/cnc-xpro-v4-controller/', - protocol: 'stk500v1' - }, - ]; + /***/ }), + /* 29 */ + /***/ (function(module, exports, __webpack_require__) { + + /* WEBPACK VAR INJECTION */(function(Buffer) {var boards = [ + { + name: 'uno', + baud: 115200, + signature: Buffer.from([0x1e, 0x95, 0x0f]), + pageSize: 128, + numPages: 256, + timeout: 400, + productId: ['0x0043', '0x7523', '0x0001', '0xea60', '0x6015'], + productPage: 'https://store.arduino.cc/arduino-uno-rev3', + protocol: 'stk500v1' + }, + { + name: 'micro', + baud: 57600, + signature: Buffer.from([0x43, 0x41, 0x54, 0x45, 0x52, 0x49, 0x4e]), + productId: ['0x0037', '0x8037', '0x0036', '0x0237'], + productPage: 'https://store.arduino.cc/arduino-micro', + protocol: 'avr109' + }, + { + name: 'imuduino', + baud: 57600, + signature: Buffer.from([0x43, 0x41, 0x54, 0x45, 0x52, 0x49, 0x4e]), + productId: ['0x0036', '0x8037', '0x8036'], + productPage: 'https://www.kickstarter.com/projects/1265095814/imuduino-wireless-3d-motion-html-js-apps-arduino-p?lang=de', + protocol: 'avr109' + }, + { + name: 'leonardo', + baud: 57600, + signature: Buffer.from([0x43, 0x41, 0x54, 0x45, 0x52, 0x49, 0x4e]), + productId: ['0x0036', '0x8036', '0x800c'], + productPage: 'https://store.arduino.cc/leonardo', + protocol: 'avr109' + }, + { + name: 'arduboy', + baud: 57600, + signature: Buffer.from([0x43, 0x41, 0x54, 0x45, 0x52, 0x49, 0x4e]), + productId: ['0x0036', '0x8036', '0x800c'], + productPage: 'https://arduboy.com/', + protocol: 'avr109' + }, + { + name: 'feather', + baud: 57600, + signature: Buffer.from([0x43, 0x41, 0x54, 0x45, 0x52, 0x49, 0x4e]), + productId: ['0x800c', '0x000c'], + productPage: 'https://www.adafruit.com/feather', + protocol: 'avr109' + }, + { + name: 'little-bits', + baud: 57600, + signature: Buffer.from([0x43, 0x41, 0x54, 0x45, 0x52, 0x49, 0x4e]), + productId: ['0x0036', '0x8036'], + productPage: 'https://littlebits.com/collections/bits-and-accessories/products/arduino-bit', + protocol: 'avr109' + }, + { + name: 'blend-micro', + baud: 57600, + signature: Buffer.from([0x43, 0x41, 0x54, 0x45, 0x52, 0x49, 0x4e]), + productId: ['0x2404'], + productPage: 'https://redbear.cc/product/retired/blend-micro.html', + protocol: 'avr109' + }, + { + name: 'nano', + baud: 57600, + signature: Buffer.from([0x1e, 0x95, 0x0f]), + pageSize: 128, + numPages: 256, + timeout: 400, + productId: ['0x6001', '0x7523'], + productPage: 'https://web.archive.org/web/20150813095112/https://www.arduino.cc/en/Main/ArduinoBoardNano', + protocol: 'stk500v1' + }, + { + name: 'nano (new bootloader)', + baud: 115200, + signature: Buffer.from([0x1e, 0x95, 0x0f]), + pageSize: 128, + numPages: 256, + timeout: 400, + productId: ['0x6001', '0x7523'], + productPage: 'https://store.arduino.cc/arduino-nano', + protocol: 'stk500v1' + }, + { + name: 'duemilanove168', + baud: 19200, + signature: Buffer.from([0x1e, 0x94, 0x06]), + pageSize: 128, + numPages: 128, + timeout: 400, + productId: ['0x6001'], + productPage: 'https://www.arduino.cc/en/Main/arduinoBoardDuemilanove', + protocol: 'stk500v1' + }, + { + name: 'duemilanove328', + baud: 57600, + signature: Buffer.from([0x1e, 0x95, 0x14]), + pageSize: 128, + numPages: 256, + timeout: 400, + productId: ['0x6001'], + productPage: 'https://www.arduino.cc/en/Main/arduinoBoardDuemilanove', + protocol: 'stk500v1' + }, + // the alias is here because of an accidental naming change of the tinyduino + // keeping in for backwards compatibility (SHA 05d65842) + { + name: 'tinyduino', + baud: 57600, + signature: Buffer.from([0x1e, 0x95, 0x0f]), + pageSize: 128, + numPages: 256, + timeout: 400, + productId: ['0x6015'], + productPage: 'https://tinycircuits.com/pages/tinyduino-overview', + protocol: 'stk500v1', + aliases: ['tinduino'] + }, + { + name: 'mega', + baud: 115200, + signature: Buffer.from([0x1e, 0x98, 0x01]), // ATmega2560 + pageSize: 256, + delay1: 10, + delay2: 1, + timeout:0xc8, + stabDelay:0x64, + cmdexeDelay:0x19, + synchLoops:0x20, + byteDelay:0x00, + pollValue:0x53, + pollIndex:0x03, + productId: ['0x0042', '0x6001', '0x0010', '0x7523'], + productPage: 'https://store.arduino.cc/mega-2560-r3', + protocol: 'stk500v2' + }, + { + name: 'adk', + baud: 115200, + signature: Buffer.from([0x1e, 0x98, 0x01]), // ATmega2560 + pageSize: 256, + delay1: 10, + delay2: 1, + timeout:0xc8, + stabDelay:0x64, + cmdexeDelay:0x19, + synchLoops:0x20, + byteDelay:0x00, + pollValue:0x53, + pollIndex:0x03, + productId: ['0x0044', '0x6001', '0x003F'], + productPage: 'https://store.arduino.cc/arduino-mega-adk-rev3', + protocol: 'stk500v2' + }, + { + name: 'sf-pro-micro', + baud: 57600, + signature: Buffer.from([0x43, 0x41, 0x54, 0x45, 0x52, 0x49, 0x4e]), + productId: ['0x9206', '0x9205', '0x0036'], + productPage: 'https://www.sparkfun.com/products/12640', + protocol: 'avr109' + }, + { + name: 'pro-mini', + baud: 57600, + signature: Buffer.from([0x1e, 0x95, 0x0f]), + pageSize: 128, + numPages: 256, + timeout: 400, + productPage: 'https://store.arduino.cc/arduino-pro-mini', + protocol: 'stk500v1' + }, + { + name: 'qduino', + baud: 57600, + signature: Buffer.from([0x43, 0x41, 0x54, 0x45, 0x52, 0x49, 0x4e]), + productId: ['0x516d', '0x514d'], + productPage: 'https://www.sparkfun.com/products/13614', + protocol: 'avr109' + }, + { + name: 'pinoccio', + baud: 115200, + signature: Buffer.from([0x1e, 0xa8, 0x02]), // ATmega256RFR2 + pageSize: 256, + delay1: 10, + delay2: 1, + timeout:0xc8, + stabDelay:0x64, + cmdexeDelay:0x19, + synchLoops:0x20, + byteDelay:0x00, + pollValue:0x53, + pollIndex:0x03, + productId: ['0x6051'], + productPage: 'https://www.mouser.de/new/crowd-supply/crowd-supply-pinoccio-microcontroller/', + protocol: 'stk500v2' + }, + { + name: 'lilypad-usb', + baud: 57600, + signature: Buffer.from([0x43, 0x41, 0x54, 0x45, 0x52, 0x49, 0x4e]), + productId: ['0x9207', '0x9208', '0x1B4F'], + productPage: 'https://www.sparkfun.com/products/12049', + protocol: 'avr109' + }, + { + name: 'yun', + baud: 57600, + signature: Buffer.from([0x43, 0x41, 0x54, 0x45, 0x52, 0x49, 0x4e]), + productId: ['0x0041', '0x8041'], + productPage: 'https://store.arduino.cc/arduino-yun', + protocol: 'avr109' + }, + { + name: 'esplora', + baud: 57600, + signature: Buffer.from([0x43, 0x41, 0x54, 0x45, 0x52, 0x49, 0x4e]), + productId: ['0x003C', '0x803C'], + productPage: 'https://store.arduino.cc/arduino-esplora', + protocol: 'avr109' + }, + { + name: 'circuit-playground-classic', + baud: 57600, + signature: Buffer.from([0x43, 0x41, 0x54, 0x45, 0x52, 0x49, 0x4e]), + productId: ['0x0011', '0x8011'], + productPage: 'https://www.adafruit.com/product/3000', + protocol: 'avr109' + }, + /** BQ - Arduino Based Boards. Used in Bitbloq -> bitbloq.bq.com and Arduino IDE*/ + { + name: 'zumjunior', + baud: 115200, + signature: Buffer.from([0x1e, 0x95, 0x0f]), + pageSize: 128, + numPages: 256, + timeout: 400, + productId: ['0xEA60'], + productPage: 'https://store-de.bq.com/de/zum-kit-junior', + protocol: 'stk500v1' + }, + { + name: 'zumcore2', + baud: 115200, + signature: Buffer.from([0x1e, 0x95, 0x0f]), + pageSize: 128, + numPages: 256, + timeout: 400, + productId: ['0xEA60'], + productPage: 'https://www.bq.com/de/zum-core-2-0', + protocol: 'stk500v1' + }, + { + name: 'bqZum', + baud: 19200, + signature: Buffer.from([0x1e, 0x95, 0x0f]), + pageSize: 128, + numPages: 256, + timeout: 400, + productId: ['0x6001', '0x7523'], + productPage: 'http://diwo.bq.com/zum-bt-328-especificaciones-tecnicas/', + protocol: 'stk500v1' + }, + /** END OF BQ - Arduino Based Boards. Used in Bitbloq -> bitbloq.bq.com and Arduino IDE*/ + + /** START OF Spark Concepts Boards - Arduino Based CNC Controller but uses Atmega328pb (Note 'pb' not 'p' = different signature) https://github.com/Spark-Concepts/xPro-V4 */ + { + name: 'xprov4', + baud: 115200, + signature: Buffer.from([0x1e, 0x95, 0x16]), + pageSize: 128, + numPages: 256, + timeout: 400, + productId: ['0x0043', '0x7523', '0x0001', '0xea60'], + productPage: 'http://www.spark-concepts.com/cnc-xpro-v4-controller/', + protocol: 'stk500v1' + }, + ]; /** * Generate an object with board name keys for faster lookup @@ -12812,13 +12644,11 @@ THE SOFTWARE. module.exports = boardLookupTable(); - /* WEBPACK VAR INJECTION */ - }.call(this, __webpack_require__(0).Buffer)) + /* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(0).Buffer)) - /***/ - }), - /* 32 */ - /***/ (function (module, exports, __webpack_require__) { + /***/ }), + /* 30 */ + /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -12842,7 +12672,7 @@ THE SOFTWARE. revLookup['-'.charCodeAt(0)] = 62 revLookup['_'.charCodeAt(0)] = 63 - function getLens(b64) { + function getLens (b64) { var len = b64.length if (len % 4 > 0) { @@ -12862,18 +12692,18 @@ THE SOFTWARE. } // base64 is 4/3 + up to two characters of the original data - function byteLength(b64) { + function byteLength (b64) { var lens = getLens(b64) var validLen = lens[0] var placeHoldersLen = lens[1] return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen } - function _byteLength(b64, validLen, placeHoldersLen) { + function _byteLength (b64, validLen, placeHoldersLen) { return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen } - function toByteArray(b64) { + function toByteArray (b64) { var tmp var lens = getLens(b64) var validLen = lens[0] @@ -12919,14 +12749,14 @@ THE SOFTWARE. return arr } - function tripletToBase64(num) { + function tripletToBase64 (num) { return lookup[num >> 18 & 0x3F] + lookup[num >> 12 & 0x3F] + lookup[num >> 6 & 0x3F] + lookup[num & 0x3F] } - function encodeChunk(uint8, start, end) { + function encodeChunk (uint8, start, end) { var tmp var output = [] for (var i = start; i < end; i += 3) { @@ -12939,7 +12769,7 @@ THE SOFTWARE. return output.join('') } - function fromByteArray(uint8) { + function fromByteArray (uint8) { var tmp var len = uint8.length var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes @@ -12975,10 +12805,9 @@ THE SOFTWARE. } - /***/ - }), - /* 33 */ - /***/ (function (module, exports) { + /***/ }), + /* 31 */ + /***/ (function(module, exports) { exports.read = function (buffer, offset, isLE, mLen, nBytes) { var e, m @@ -12995,14 +12824,12 @@ THE SOFTWARE. e = s & ((1 << (-nBits)) - 1) s >>= (-nBits) nBits += eLen - for (; nBits > 0; e = (e * 256) + buffer[offset + i], i += d, nBits -= 8) { - } + for (; nBits > 0; e = (e * 256) + buffer[offset + i], i += d, nBits -= 8) {} m = e & ((1 << (-nBits)) - 1) e >>= (-nBits) nBits += mLen - for (; nBits > 0; m = (m * 256) + buffer[offset + i], i += d, nBits -= 8) { - } + for (; nBits > 0; m = (m * 256) + buffer[offset + i], i += d, nBits -= 8) {} if (e === 0) { e = 1 - eBias @@ -13058,38 +12885,39 @@ THE SOFTWARE. } } - for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) { - } + for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {} e = (e << mLen) | m eLen += mLen - for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) { - } + for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {} buffer[offset + i - d] |= s * 128 } - /***/ - }), - /* 34 */ - /***/ (function (module, exports, __webpack_require__) { + /***/ }), + /* 32 */ + /***/ (function(module, exports, __webpack_require__) { - var Serialport = __webpack_require__(35); - var async = __webpack_require__(13); - var awty = __webpack_require__(38); - var tools = __webpack_require__(10); + var Serialport = __webpack_require__(33); + var async = __webpack_require__(10); + var awty = __webpack_require__(36); - var Connection = function (options) { + var Connection = function(options) { this.options = options; - this.debug = this.options.debug ? console.log.bind(console) : function () { - }; + this.debug = this.options.debug ? console.log.bind(console) : function() {}; this.board = this.options.board; + // TODO: support avr109 boards + if (this.board.protocol === 'avr109') { + throw new Error( + `Sorry, we currently don't support ${this.board.name} or other avr109 boards in webserial. Please see https://github.com/noopkat/avrgirl-arduino/issues/204#issuecomment-703284131 for further details` + ); + } }; - Connection.prototype._init = function (callback) { - this._setUpSerial(function (error) { + Connection.prototype._init = function(callback) { + this._setUpSerial(function(error) { return callback(error); }); }; @@ -13097,14 +12925,13 @@ THE SOFTWARE. /** * Create new serialport instance for the Arduino board, but do not immediately connect. */ - Connection.prototype._setUpSerial = function (callback) { - var _this = this; + Connection.prototype._setUpSerial = function(callback) { this.serialPort = new Serialport('', { baudRate: this.board.baud, autoOpen: false }); - this.serialPort.on('open', function () { -// _this.emit('connection:open'); + this.serialPort.on('open', function() { + // _this.emit('connection:open'); }) return callback(null); }; @@ -13115,15 +12942,15 @@ THE SOFTWARE. * * @param {function} callback - function to run upon completion/error */ - Connection.prototype._sniffPort = function (callback) { + Connection.prototype._sniffPort = function(callback) { var _this = this; - var pidList = _this.board.productId.map(function (id) { + var pidList = _this.board.productId.map(function(id) { return parseInt(id, 16); }); - _this._listPorts(function (error, ports) { + _this._listPorts(function(error, ports) { // filter for a match by product id - var portMatch = ports.filter(function (p) { + var portMatch = ports.filter(function(p) { return pidList.indexOf(parseInt(p._standardPid, 16)) !== -1; }); @@ -13138,19 +12965,17 @@ THE SOFTWARE. * @param {number} timeout - number in milliseconds to delay after * @param {function} callback - function to run upon completion/error */ - Connection.prototype._setDTR = function (bool, timeout, callback) { + Connection.prototype._setDTR = function(bool, timeout, callback) { var _this = this; var props = { rts: false, dtr: bool }; - _this.serialPort.set(props, function (error) { - if (error) { - return callback(error); - } + _this.serialPort.set(props, function(error) { + if (error) { return callback(error); } - setTimeout(function () { + setTimeout(function() { callback(error); }, timeout); }); @@ -13161,14 +12986,14 @@ THE SOFTWARE. * * @param {function} callback - function to run upon completion/error */ - Connection.prototype._pollForPort = function (callback) { + Connection.prototype._pollForPort = function(callback) { var _this = this; - var poll = awty(function (next) { + var poll = awty(function(next) { var found = false; // try to sniff port instead (for port hopping devices) - _this._sniffPort(function (error, port) { + _this._sniffPort(function(error, port) { if (port.length) { // found a port, save it _this.options.port = port[0].comName; @@ -13181,11 +13006,11 @@ THE SOFTWARE. poll.every(100).ask(15); - poll(function (foundPort) { + poll(function(foundPort) { if (foundPort) { _this.debug('found port on', _this.options.port); // set up serialport for it - _this._setUpSerial(function (error) { + _this._setUpSerial(function(error) { return callback(error); }); } else { @@ -13195,18 +13020,18 @@ THE SOFTWARE. }); }; - Connection.prototype._pollForOpen = function (callback) { + Connection.prototype._pollForOpen = function(callback) { var _this = this; - var poll = awty(function (next) { - _this.serialPort.open(function (error) { + var poll = awty(function(next) { + _this.serialPort.open(function(error) { next(!error); }); }); poll.every(200).ask(10); - poll(function (isOpen) { + poll(function(isOpen) { var error; if (!isOpen) { error = new Error('could not open board on ' + _this.serialPort.path); @@ -13221,14 +13046,14 @@ THE SOFTWARE. * * @param {function} callback - function to run upon completion/error */ - Connection.prototype._cycleDTR = function (callback) { + Connection.prototype._cycleDTR = function(callback) { var _this = this; async.series([ _this._setDTR.bind(_this, true, 250), _this._setDTR.bind(_this, false, 50) ], - function (error) { + function(error) { return callback(error); }); @@ -13240,14 +13065,12 @@ THE SOFTWARE. * * @param {function} callback - function to run upon completion/error */ - Connection.prototype._listPorts = function (callback) { + Connection.prototype._listPorts = function(callback) { var foundPorts = []; // list all available ports - Serialport.list(function (err, ports) { - if (err) { - return callback(err); - } + Serialport.list(function(err, ports) { + if (err) { return callback(err); } // iterate through ports for (var i = 0; i < ports.length; i += 1) { @@ -13279,14 +13102,12 @@ THE SOFTWARE. module.exports = Connection; - /***/ - }), - /* 35 */ - /***/ (function (module, exports, __webpack_require__) { + /***/ }), + /* 33 */ + /***/ (function(module, exports, __webpack_require__) { - /* WEBPACK VAR INJECTION */ - (function (Buffer) {// TODO: switch out this browser shim for mitt: https://github.com/developit/mitt - const {EventEmitter} = __webpack_require__(5); + /* WEBPACK VAR INJECTION */(function(Buffer) {// TODO: switch out this browser shim for mitt: https://github.com/developit/mitt + const { EventEmitter } = __webpack_require__(4); class SerialPort extends EventEmitter { constructor(port, options) { @@ -13299,7 +13120,7 @@ THE SOFTWARE. this.port = null; this.writer = null; this.reader = null; - this.baudrate = this.options.baudRate; + this.baudRate = this.options.baudRate; this.requestOptions = this.options.requestOptions || {}; if (this.options.autoOpen) this.open(); @@ -13307,24 +13128,16 @@ THE SOFTWARE. list(callback) { return navigator.serial.getPorts() - .then((list) => { - if (callback) { - return callback(null, list) - } - }) - .catch((error) => { - if (callback) { - return callback(error) - } - }); + .then((list) => {if (callback) {return callback(null, list)}}) + .catch((error) => {if (callback) {return callback(error)}}); } open(callback) { - navigator.serial.requestPort(this.requestOptions) + window.navigator.serial.requestPort(this.requestOptions) .then(serialPort => { this.port = serialPort; if (this.isOpen) return; - return this.port.open({baudrate: this.baudrate || 57600}); + return this.port.open({ baudRate: this.baudRate || 57600 }); }) .then(() => this.writer = this.port.writable.getWriter()) .then(() => this.reader = this.port.readable.getReader()) @@ -13332,21 +13145,19 @@ THE SOFTWARE. this.emit('open'); this.isOpen = true; callback(null); - try { - while (this.port.readable.locked) { - const {value, done} = await this.reader.read(); + while (this.port.readable.locked) { + try { + const { value, done } = await this.reader.read(); if (done) { break; } this.emit('data', Buffer.from(value)); + } catch (e) { + console.error(e); } - } catch (e) { - throw e; } }) - .catch(error => { - callback(error) - }); + .catch(error => {callback(error)}); } async close(callback) { @@ -13362,9 +13173,21 @@ THE SOFTWARE. callback && callback(null); } - async set(props, callback) { + async set(props = {}, callback) { try { - await this.port.setSignals(props); + const signals = {}; + if (Object.prototype.hasOwnProperty.call(props, 'dtr')) { + signals.dataTerminalReady = props.dtr; + } + if (Object.prototype.hasOwnProperty.call(props, 'rts')) { + signals.requestToSend = props.rts; + } + if (Object.prototype.hasOwnProperty.call(props, 'brk')) { + signals.break = props.brk; + } + if (Object.keys(signals).length > 0) { + await this.port.setSignals(signals); + } } catch (error) { if (callback) return callback(error); throw error; @@ -13378,8 +13201,9 @@ THE SOFTWARE. } async read(callback) { + let buffer; try { - const buffer = await this.reader.read(); + buffer = await this.reader.read(); } catch (error) { if (callback) return callback(error); throw error; @@ -13404,229 +13228,220 @@ THE SOFTWARE. module.exports = SerialPort; - /* WEBPACK VAR INJECTION */ - }.call(this, __webpack_require__(0).Buffer)) + /* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(0).Buffer)) - /***/ - }), - /* 36 */ - /***/ (function (module, exports, __webpack_require__) { + /***/ }), + /* 34 */ + /***/ (function(module, exports, __webpack_require__) { - /* WEBPACK VAR INJECTION */ - (function (global, process) { - (function (global, undefined) { - "use strict"; + /* WEBPACK VAR INJECTION */(function(global, process) {(function (global, undefined) { + "use strict"; - if (global.setImmediate) { - return; - } + if (global.setImmediate) { + return; + } - var nextHandle = 1; // Spec says greater than zero - var tasksByHandle = {}; - var currentlyRunningATask = false; - var doc = global.document; - var registerImmediate; + var nextHandle = 1; // Spec says greater than zero + var tasksByHandle = {}; + var currentlyRunningATask = false; + var doc = global.document; + var registerImmediate; - function setImmediate(callback) { - // Callback can either be a function or a string - if (typeof callback !== "function") { - callback = new Function("" + callback); - } - // Copy function arguments - var args = new Array(arguments.length - 1); - for (var i = 0; i < args.length; i++) { - args[i] = arguments[i + 1]; - } - // Store and register the task - var task = {callback: callback, args: args}; - tasksByHandle[nextHandle] = task; - registerImmediate(nextHandle); - return nextHandle++; + function setImmediate(callback) { + // Callback can either be a function or a string + if (typeof callback !== "function") { + callback = new Function("" + callback); } - - function clearImmediate(handle) { - delete tasksByHandle[handle]; + // Copy function arguments + var args = new Array(arguments.length - 1); + for (var i = 0; i < args.length; i++) { + args[i] = arguments[i + 1]; } + // Store and register the task + var task = { callback: callback, args: args }; + tasksByHandle[nextHandle] = task; + registerImmediate(nextHandle); + return nextHandle++; + } - function run(task) { - var callback = task.callback; - var args = task.args; - switch (args.length) { - case 0: - callback(); - break; - case 1: - callback(args[0]); - break; - case 2: - callback(args[0], args[1]); - break; - case 3: - callback(args[0], args[1], args[2]); - break; - default: - callback.apply(undefined, args); - break; - } + function clearImmediate(handle) { + delete tasksByHandle[handle]; + } + + function run(task) { + var callback = task.callback; + var args = task.args; + switch (args.length) { + case 0: + callback(); + break; + case 1: + callback(args[0]); + break; + case 2: + callback(args[0], args[1]); + break; + case 3: + callback(args[0], args[1], args[2]); + break; + default: + callback.apply(undefined, args); + break; } + } - function runIfPresent(handle) { - // From the spec: "Wait until any invocations of this algorithm started before this one have completed." - // So if we're currently running a task, we'll need to delay this invocation. - if (currentlyRunningATask) { - // Delay by doing a setTimeout. setImmediate was tried instead, but in Firefox 7 it generated a - // "too much recursion" error. - setTimeout(runIfPresent, 0, handle); - } else { - var task = tasksByHandle[handle]; - if (task) { - currentlyRunningATask = true; - try { - run(task); - } finally { - clearImmediate(handle); - currentlyRunningATask = false; - } + function runIfPresent(handle) { + // From the spec: "Wait until any invocations of this algorithm started before this one have completed." + // So if we're currently running a task, we'll need to delay this invocation. + if (currentlyRunningATask) { + // Delay by doing a setTimeout. setImmediate was tried instead, but in Firefox 7 it generated a + // "too much recursion" error. + setTimeout(runIfPresent, 0, handle); + } else { + var task = tasksByHandle[handle]; + if (task) { + currentlyRunningATask = true; + try { + run(task); + } finally { + clearImmediate(handle); + currentlyRunningATask = false; } } } + } - function installNextTickImplementation() { - registerImmediate = function (handle) { - process.nextTick(function () { - runIfPresent(handle); - }); - }; - } + function installNextTickImplementation() { + registerImmediate = function(handle) { + process.nextTick(function () { runIfPresent(handle); }); + }; + } - function canUsePostMessage() { - // The test against `importScripts` prevents this implementation from being installed inside a web worker, - // where `global.postMessage` means something completely different and can't be used for this purpose. - if (global.postMessage && !global.importScripts) { - var postMessageIsAsynchronous = true; - var oldOnMessage = global.onmessage; - global.onmessage = function () { - postMessageIsAsynchronous = false; - }; - global.postMessage("", "*"); - global.onmessage = oldOnMessage; - return postMessageIsAsynchronous; - } + function canUsePostMessage() { + // The test against `importScripts` prevents this implementation from being installed inside a web worker, + // where `global.postMessage` means something completely different and can't be used for this purpose. + if (global.postMessage && !global.importScripts) { + var postMessageIsAsynchronous = true; + var oldOnMessage = global.onmessage; + global.onmessage = function() { + postMessageIsAsynchronous = false; + }; + global.postMessage("", "*"); + global.onmessage = oldOnMessage; + return postMessageIsAsynchronous; } + } - function installPostMessageImplementation() { - // Installs an event handler on `global` for the `message` event: see - // * https://developer.mozilla.org/en/DOM/window.postMessage - // * http://www.whatwg.org/specs/web-apps/current-work/multipage/comms.html#crossDocumentMessages - - var messagePrefix = "setImmediate$" + Math.random() + "$"; - var onGlobalMessage = function (event) { - if (event.source === global && - typeof event.data === "string" && - event.data.indexOf(messagePrefix) === 0) { - runIfPresent(+event.data.slice(messagePrefix.length)); - } - }; + function installPostMessageImplementation() { + // Installs an event handler on `global` for the `message` event: see + // * https://developer.mozilla.org/en/DOM/window.postMessage + // * http://www.whatwg.org/specs/web-apps/current-work/multipage/comms.html#crossDocumentMessages - if (global.addEventListener) { - global.addEventListener("message", onGlobalMessage, false); - } else { - global.attachEvent("onmessage", onGlobalMessage); + var messagePrefix = "setImmediate$" + Math.random() + "$"; + var onGlobalMessage = function(event) { + if (event.source === global && + typeof event.data === "string" && + event.data.indexOf(messagePrefix) === 0) { + runIfPresent(+event.data.slice(messagePrefix.length)); } + }; - registerImmediate = function (handle) { - global.postMessage(messagePrefix + handle, "*"); - }; + if (global.addEventListener) { + global.addEventListener("message", onGlobalMessage, false); + } else { + global.attachEvent("onmessage", onGlobalMessage); } - function installMessageChannelImplementation() { - var channel = new MessageChannel(); - channel.port1.onmessage = function (event) { - var handle = event.data; - runIfPresent(handle); - }; + registerImmediate = function(handle) { + global.postMessage(messagePrefix + handle, "*"); + }; + } - registerImmediate = function (handle) { - channel.port2.postMessage(handle); - }; - } + function installMessageChannelImplementation() { + var channel = new MessageChannel(); + channel.port1.onmessage = function(event) { + var handle = event.data; + runIfPresent(handle); + }; - function installReadyStateChangeImplementation() { - var html = doc.documentElement; - registerImmediate = function (handle) { - // Create a