SlideShare a Scribd company logo
app.js
/****************************************************
***************************
* Copyright (c) 2014 IBM Corp.
*
* All rights reserved. This program and the accompanying
materials
* are made available under the terms of the Eclipse Public
License v1.0
* and Eclipse Distribution License v1.0 which accompany this
distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Bryan Boyd - Initial implementation
*****************************************************
**************************/
var parseString = require('xml2js').parseString;
var vincenty = require('node-vincenty');
var fs = require('fs');
var argv = require('optimist').argv;
var mqtt = require('mqtt');
var http = require('http');
var settings = require('./config/settings');
var appInfo = JSON.parse(process.env.VCAP_APPLICATION ||
"{}");
var appHost = appInfo.host || "localhost";
console.log(argv);
var deviceIndex = (appInfo && appInfo.instance_index) ?
appInfo.instance_index : 0;
var deviceId = settings.iot_deviceSet[deviceIndex].deviceId;
var token = settings.iot_deviceSet[deviceIndex].token;
var iot_server = settings.iot_deviceOrg +
".messaging.internetofthings.ibmcloud.com";
var iot_port = 1883;
var iot_username = "use-token-auth";
var iot_password = token;
var iot_clientid = "d:" + settings.iot_deviceOrg + ":" +
settings.iot_deviceType + ":" + deviceId
console.log(iot_server, iot_clientid, iot_username,
iot_password);
//var client = mqtt.createClient(1883, iot_server, { clientId:
iot_clientid, username: iot_username, password: iot_password
});
var options1 = {
port: 1883,
host: iot_server,
clientId: iot_clientid,
username: iot_username,
password: iot_password,
protocolId: 'MQIsdp',
protocolVersion: 3
};
var client = mqtt.connect(options1);
console.log(JSON.stringify(process.env));
var VEHICLE_COUNT = (argv.count ? argv.count :
(process.env.VEHICLE_COUNT || 1));
var TELEMETRY_RATE = (argv.rate ? argv.rate :
(process.env.TELEMETRY_RATE || 2));
console.log("Simulating " + VEHICLE_COUNT + " vehicles");
// subscribe
var propertyTopic = "iot-2/cmd/setProperty/fmt/json";
// publish
var telemetryTopic = "iot-2/evt/telemetry/fmt/json";
//////////////////
// MAP //
//////////////////
var num_nodes = 0;
var num_edges = 0;
var map = {
nodes: {},
edges: {}
};
function Map(abbr, name, filename) {
this.abbr = abbr;
this.name = name;
this.nodeCount = 0;
this.edgeCount = 0;
this.nodes = {};
this.edges = {};
this.loadFromFile(filename);
}
Map.prototype.loadFromFile = function(filename) {
fs.readFile(filename, (function(map) {
return function(err, data) {
if (err) throw err;
parseString(data, function(err, result) {
console.log("parseString");
if (err) throw err;
map.createMapFromJSON(result);
setTimeout(mapLoaded, 5000);
});
}
})(this));
}
Map.prototype.createMapFromJSON = function(json) {
console.log("createMapFromJSON");
for (var i in json.osm.node) {
var n = json.osm.node[i];
this.nodes[n.$.id] = {
id: n.$.id,
lon: parseFloat(n.$.lon),
lat: parseFloat(n.$.lat),
edges: Array()
}
this.nodeCount++;
if (this.nodeCount % 1000 == 0) {
console.log("nodes: " + this.nodeCount); }
}
for (var i in json.osm.way) {
var w = json.osm.way[i];
var wId = w.$.id;
var tags = {};
for (var j in w.tag) {
tags[w.tag[j].$.k] = w.tag[j].$.v;
}
var last_ref = null;
for (var j in w.nd) {
var ref = w.nd[j].$.ref; // node id
if (last_ref) {
//console.log(this.nodes[last_ref],
this.nodes[ref]);
var res =
vincenty.distVincenty(this.nodes[last_ref].lat,
this.nodes[last_ref].lon, this.nodes[ref].lat, this.nodes[ref].lon);
//console.log(res);
var meters = res.distance;
var bearing = res.initialBearing;
if (tags.oneway && tags.oneway == "yes")
{
var edge = {
id: wId + "-" + last_ref + "_" +
ref,
type: tags.highway,
a: last_ref,
b: ref,
heading: bearing,
dist: meters
};
this.edges[edge.id] = edge;
this.nodes[last_ref].edges.push(edge);
this.edgeCount++;
} else {
var edgeA = {
id: wId + "-" + last_ref + "_" +
ref,
type: tags.highway,
a: last_ref,
b: ref,
heading: bearing,
dist: meters
}
this.edges[edgeA.id] = edgeA;
this.nodes[last_ref].edges.push(edgeA);
this.edgeCount++;
var edgeB = {
id: wId + "-" + ref + "_" +
last_ref,
type: tags.highway,
a: ref,
b: last_ref,
heading: (bearing < 180 ?
bearing + 180 : bearing - 180),
dist: meters
}
this.edges[edgeB.id] = edgeB;
this.nodes[ref].edges.push(edgeB);
this.edgeCount++;
}
}
last_ref = ref;
}
if (this.edgeCount % 1000 == 0) {
console.log("edges: " + this.edgeCount); }
}
var del = 0;
for (var i in this.nodes) {
var n = this.nodes[i];
var count = 0;
for (var j in n.edges) {
if (this.nodes[n.edges[j].b]) {
count++;
}
}
if (count == 0) {
delete this.nodes[i];
del++;
this.nodeCount--;
}
}
//console.log("deleted " + del + " nodes");
//this.publishData();
this.print();
}
Map.prototype.print = function() {
/*
fs.writeFile("map_nodes.txt", JSON.stringify(this.nodes,
null, 4), function(err) {
if(err) {
console.log(err);
} else {
console.log("nodes saved to map_nodes.txt");
}
});
fs.writeFile("map_edges.txt", JSON.stringify(this.edges,
null, 4), function(err) {
if(err) {
console.log(err);
} else {
console.log("edges saved to map_edges.txt");
}
});
*/
console.log("loaded map!");
console.log("num_edges = " + this.edgeCount);
console.log("num_nodes = " + this.nodeCount);
}
Map.prototype.publishData = function() {
//var topic = topicPrefix + "map/"+this.abbr;
var payload = JSON.stringify({
name: this.name,
abbr: this.abbr,
nodeCount: this.nodeCount,
edgeCount: this.edgeCount,
nodes: this.nodes,
edges: this.edges
});
var b64 = new Buffer(payload).toString('base64');
//console.log("publish : " + topic + " : " + b64);
console.log(b64);
console.log("length = " + b64.length);
//client.publish(topicPrefix + "map/"+ this.abbr, b64, {
qos: 1, retain: true });
}
var austin_map = new Map("austin", "Austin - Downtown",
"maps/austin_downtown-clean.osm");
function Vehicle(id, suffix) {
this.id = id;
this.suffix = suffix;
this.name = "Car " + id + suffix;
this.map = austin_map;
this.speed = null;
this.state = "normal";
this.description = "I am a connected car.";
this.type = "car";
this.customProps = {
turnSignal: "OFF"
},
this.geo = {
lon: 0,
lat: 0
}
this.currentEdge = null;
this.perc = 0; // % of edge travelled
this.lastUpdateTime = null;
this.setSpeed(30);
this.frame = 0;
}
Vehicle.prototype.drive = function() {
this.frame++;
if (!this.currentEdge) {
this.setStartingEdge();
} else {
//console.log("update " + this.name);
this.update();
}
}
Vehicle.prototype.update = function() {
var delta = (new Date()).getTime() - this.lastUpdateTime;
//console.log("delta = " + delta);
// move car 'delta' milliseconds
// speed (m/s) = speed (km/hr) * 3600 / 1000
// dist (m) = speed (m/s) * (delta / 1000)
var dist_to_move = (this.speed * (1000 / 3600)) * (delta /
1000);
//console.log("updating vehicle: distance remaining = " +
dist_to_move);
while (dist_to_move > 0) {
var dist_remaining_on_edge = (1.0 - this.perc) *
this.currentEdge.dist;
if (dist_to_move > dist_remaining_on_edge) {
// finished an edge! get a new edge and keep
going
//console.log("finished an edge! distance
remaining = " + dist_to_move);
dist_to_move -= dist_remaining_on_edge;
this.setNextEdge();
} else {
// didn't finish an edge, update perc
this.perc += (dist_to_move /
this.currentEdge.dist);
dist_to_move = 0;
//console.log("didn't finish, perc = " +
this.perc);
}
}
this.updatePosition();
this.lastUpdateTime = (new Date()).getTime();
}
Vehicle.prototype.getPublishPayload = function() {
return {
id: this.id + this.suffix,
name: this.name,
lng: this.geo.lon.toString(),
lat: this.geo.lat.toString(),
heading: this.currentEdge.heading,
speed: this.speed,
state: this.state,
description: this.description,
type: this.type,
customProps: this.customProps
};
}
Vehicle.prototype.setSpeed = function(val) {
// speed = km/hr
if (val >= 0 && val <= 120) {
console.log("setting speed to " + val);
this.speed = val;
}
}
Vehicle.prototype.setTurnSignal = function(val) {
if (val == "LEFT" || val == "NONE" || val == "RIGHT" ||
val == "OFF") {
this.customProps.turnSignal = val;
}
}
Vehicle.prototype.setStartingEdge = function() {
var keys = [];
for (var i in this.map.edges) {
keys.push(i);
}
this.currentEdge =
this.map.edges[keys[Math.floor(Math.random() *
keys.length)]];
this.perc = 0;
this.lastUpdateTime = (new Date()).getTime();
}
Vehicle.prototype.updatePosition = function() {
var a = this.map.nodes[this.currentEdge.a];
var b = this.map.nodes[this.currentEdge.b];
if (a && b) {
this.geo.lon = a.lon + this.perc * (b.lon - a.lon);
this.geo.lat = a.lat + this.perc * (b.lat - a.lat);
} else {
//console.log("ERROR", a, b);
this.setStartingEdge();
}
//console.log("updatePosition: " + this.geo.lon + ", " +
this.geo.lat);
}
Vehicle.prototype.setNextEdge = function() {
//console.log(" setNextEdge");
var n = this.map.nodes[this.currentEdge.b];
if (!n) {
// no valid next edge
//console.log("RESPAWNING");
this.setStartingEdge();
return;
}
var edge = null;
var reverseCount = 0;
var leftTurnEdge = null, leftTurnAngle = 0;
var rightTurnEdge = null, rightTurnAngle = 0;
var straightEdge = null, straightAngle = 180;
var a1 = this.currentEdge.heading;
for (var i in n.edges) {
var a2 = n.edges[i].heading;
var left_diff = (a1-a2+360)%360;
var right_diff = (a2-a1+360)%360;
if (left_diff > leftTurnAngle && left_diff < 160) {
leftTurnEdge = n.edges[i];
leftTurnAngle = left_diff;
}
if (right_diff > rightTurnAngle && right_diff < 160)
{
rightTurnEdge = n.edges[i];
rightTurnAngle = right_diff;
}
var smallest = Math.min(left_diff, right_diff);
if (smallest < straightAngle) {
straightEdge = n.edges[i];
straightAngle = smallest;
}
console.log("possible edge: " + n.edges[i].id + " |
heading: " + n.edges[i].heading + " | left_diff: " + left_diff + " |
right_diff: " + right_diff);
}
console.log("-- LEFT edge: " + (leftTurnEdge ?
leftTurnEdge.id : "(nil)") + " | angle: " + leftTurnAngle);
console.log("-- RIGHT edge: " + (rightTurnEdge ?
rightTurnEdge.id : "(nil)") + " | angle: " + rightTurnAngle);
console.log("-- STRAIGHT edge: " + (straightEdge ?
straightEdge.id : "(nil)") + " | angle: " + straightAngle);
while (!edge) {
try {
if (this.customProps.turnSignal &&
this.customProps.turnSignal == "LEFT" && leftTurnEdge) {
console.log("trying LEFT turn: " +
leftTurnEdge.id);
edge = leftTurnEdge;
} else if (this.customProps.turnSignal &&
this.customProps.turnSignal == "RIGHT" && rightTurnEdge) {
console.log("trying RIGHT turn: " +
rightTurnEdge.id);
edge = rightTurnEdge;
} else if (this.customProps.turnSignal &&
this.customProps.turnSignal == "STRAIGHT" && straightEdge)
{
console.log("trying STRAIGHT: " +
straightEdge.id);
edge = straightEdge;
} else {
console.log("trying RANDOM turn");
var idx = Math.floor(Math.random() *
n.edges.length);
edge = n.edges[idx];
}
// check to make sure we didn't reverse direction
if there are multiple edges
console.log("checking edge: " +
this.currentEdge.a + " " + edge.b);
if (this.currentEdge.a == edge.b) {
if (n.edges.length == 1) {
//console.log("End of the line!
Respawning...");
this.setStartingEdge();
return;
} else {
//console.log("edge won't work, it's a
reverse!");
reverseCount++;
if (reverseCount > 10) {
this.setStartingEdge();
return;
} else {
edge = null;
}
}
}
} catch (e) {
console.log(e, "ERROR", n, this.currentEdge);
this.setStartingEdge();
return;
}
}
//console.log("new edge = ", edge);
this.perc = 0;
this.currentEdge = edge;
}
var vehicles = Array();
for (var i = 1; i <= VEHICLE_COUNT; i++) {
var vid = deviceId;
var suffix = "";
if (VEHICLE_COUNT > 1) { suffix = "-" + i; }
vehicles.push(new Vehicle(vid, suffix));
}
var bMapLoaded = false;
function drive() {
for (var i in vehicles) {
vehicles[i].drive();
}
}
function subscribeToProperties() {
client.subscribe(propertyTopic);
console.log("subscribed to: " + propertyTopic);
client.on('message', function(topic, message) {
console.log("message recv: " + topic + " = " +
message);
try {
//var id = topic.split("/")[3];
var data = JSON.parse(message);
var id = data.id;
if (!id) { id = deviceId; }
console.log("setProperty(id="+id+"): " +
data.property + " = " + data.value);
var v = getVehicle(id);
var prop = data.property;
var val = data.value;
if (v) {
if (prop == "lng" || prop == "lat" || prop ==
"heading" || prop == "id") { return; }
switch (prop) {
case "speed": v.setSpeed(val); break;
case "state": v.state = val; break;
case "description": v.description =
val; break;
case "type": v.type = val; break;
default:
if (val == "") {
if (v.customProps[prop]) {
delete v.customProps[prop]; }
} else {
v.customProps[prop] = val;
}
}
}
} catch (e) { console.error(e); }
});
}
function publishVehicleData() {
var payload = [];
for (var i in vehicles) {
payload.push(vehicles[i].getPublishPayload());
}
//console.log("publishing data: " + telemetryTopic + " | " +
JSON.stringify(payload));
if (payload.length == 1) {
client.publish(telemetryTopic,
JSON.stringify(payload[0]));
} else {
client.publish(telemetryTopic,
JSON.stringify(payload));
}
}
function getVehicle(id) {
for (var i in vehicles) {
if ((vehicles[i].id + vehicles[i].suffix) == id) {
return vehicles[i];
}
}
return null;
}
function mapLoaded() {
subscribeToProperties();
setInterval(function() {
drive();
publishVehicleData();
}, 1000 / TELEMETRY_RATE);
}
// setup middleware
var express = require('express'),
https = require('https'),
path = require('path');
var app = express();
var bodyParser = require('body-parser');
var methodOverride = require('method-override')
// all environments
app.set('port', process.env.PORT || 3000);
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(bodyParser.json());
app.use(methodOverride());
app.use(express.urlencoded());
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));
// development only
if ('development' === app.get('env')) {
app.use(express.errorHandler());
}
var geo_props = null;
//parse VCAP_SERVICES if running in Bluemix
if (process.env.VCAP_SERVICES) {
var env = JSON.parse(process.env.VCAP_SERVICES);
console.log(env);
//find the Streams Geo service
if (env["Geospatial Analytics"])
{
geo_props = env['Geospatial
Analytics'][0]['credentials'];
console.log(geo_props);
}
else
{
console.log('You must bind the Streams Geo service
to this application');
}
}
if (geo_props) {
// sample vehicle topic/payload:
// {"id":"G-13","name":"Car G-13","lng":-
122.41950721920685,"lat":37.76330689770606,"heading":177.0
6799545408498,"speed":30,"state":"normal","description":"I am
a connected
car.","type":"car","customProps":{"customProp":"customValue"
}}
var inputClientId = "a:"+settings.iot_deviceOrg +
":geoInput" + Math.floor(Math.random() * 1000);
var notifyClientId = "a:"+settings.iot_deviceOrg +
":geoNotify" + Math.floor(Math.random() * 1000);
var apis = [
{
name: "start",
path: geo_props.start_path,
method: "PUT",
json: {
"mqtt_client_id_input" : inputClientId,
"mqtt_client_id_notify" : notifyClientId,
"mqtt_uid" : settings.iot_apiKey,
"mqtt_pw" : settings.iot_apiToken,
"mqtt_uri" : settings.iot_deviceOrg +
".messaging.internetofthings.ibmcloud.com:1883",
"mqtt_input_topics" : settings.inputTopic,
"mqtt_notify_topic" : settings.notifyTopic,
"device_id_attr_name" : "id",
"latitude_attr_name" : "lat",
"longitude_attr_name" : "lng"
}
},
{
name: "stop",
path: geo_props.stop_path,
method: "PUT",
json: null
},
{
name: "addRegion",
path: geo_props.add_region_path,
method: "PUT",
json: { // sample JSON for adding a region
"regions" : [
{
"region_type": "custom",
"name": "custom_poly",
"notifyOnExit": "true",
"polygon": [
{"latitude": "30.27830",
"longitude": "-97.74316"},
{"latitude": "30.27617",
"longitude": "-97.73573"},
{"latitude": "30.26676",
"longitude": "-97.73917"},
{"latitude": "30.26852",
"longitude": "-97.74560"}
// an edge is drawn
between last and first points to close the poly
]
}
]
}
},
{
name: "removeRegion",
path: geo_props.remove_region_path,
method: "PUT",
json: { // sample JSON for removing the sample
region
"region_type": "custom",
"region_name": "custom_poly"
}
},
{
name: "restart",
path: geo_props.restart_path,
method: "PUT",
json: null
},
{
name: "status",
path: geo_props.status_path,
method: "GET",
json: null
},
]
// build routes
for (var i in apis) {
var route = "/GeospatialService_"+apis[i].name;
console.log("Creating route: " + route);
app.get(route, (function(api) {
return function(request, response) {
var route =
"/GeospatialService_"+api.name;
console.log("About to call " + route);
// prepare options
var options = {
host: geo_props.geo_host,
port: geo_props.geo_port,
path: api.path,
method: api.method,
headers: {
'Authorization' : ('Basic ' + new
Buffer(geo_props.userid + ':' +
geo_props.password).toString('base64'))
}
};
// start by loading sample JSON
var bodyJson = api.json;
// if we pass in query parameters, overwrite
the sample JSON with this information
if (request.query &&
Object.keys(request.query).length > 0) {
console.log("BODY: ", request.query);
bodyJson = request.query;
} else {
console.log("NO BODY");
}
if (bodyJson) {
options.headers['Content-Type'] =
'application/json';
options.headers['Content-Length'] =
Buffer.byteLength(JSON.stringify(bodyJson), 'utf8');
}
console.log('Options prepared:', options);
console.log('Do the GeospatialService_' +
api.name + ' call');
// do the PUT call
var reqPut = https.request(options,
function(res) {
// uncomment it for header details
console.log("headers: ", res.headers);
console.log("statusCode: ",
res.statusCode);
var responseData = '';
res.on('data', function(chunk) {
responseData +=
chunk.toString();
});
res.on('end', function() {
try {
console.log(route + '
response:n');
console.log(responseData);
console.log("n" + route + '
completed');
console.log("statusCode: ",
res.statusCode);
var result =
JSON.parse(responseData);
console.log("result:n",
result);
if (res.statusCode != 200) {
response.send(res.statusCode, "<h1>"+route+" failed with
code: "+res.statusCode+"</h1>");
} else {
if (route ==
"/GeospatialService_status") {
response.send(res.statusCode, result);
} else {
response.send(res.statusCode, "<h1>"+route+"
succeeded!</h1><pre>" + JSON.stringify(result, null, 4) +
"</pre>");
}
}
} catch (e) { console.error(e);
response.send(500, { error: "parse error: " + route }); }
});
if (res.statusCode != 200) {
runError = 1;
}
});
if (bodyJson) {
// write the json data
console.log('Writing json:n',
JSON.stringify(bodyJson, null, 4));
reqPut.write(JSON.stringify(bodyJson));
}
reqPut.end();
reqPut.on('error', function(e) {
console.error(e);
});
}
})(apis[i]));
}
}
app.get("/credentials", function(request, response) {
response.send(200, settings);
});
http.createServer(app).listen(app.get('port'), function(){
console.log('Express server listening on port ' +
app.get('port'));
});
config/settings.js
/****************************************************
***************************
* Copyright (c) 2014 IBM Corp.
*
* All rights reserved. This program and the accompanying
materials
* are made available under the terms of the Eclipse Public
License v1.0
* and Eclipse Distribution License v1.0 which accompany this
distribution.
*
* The Eclipse Public License is available at
* http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
* Bryan Boyd - Initial implementation
*****************************************************
**************************/
var config = {
iot_deviceType: "Vehicle", // replace with your
deviceType
iot_deviceOrg: "lzfew7", // replace with your IoT
Foundation organization
iot_deviceSet: [ // replace with your registered
device(s)
{ deviceId: "Vehicle1", token: "qaz123WSX" },
{ deviceId: "Vehicle2", token: "wsx123QAZ" },
{ deviceId: "Vehicle3", token: "edc123WSX" }
],
iot_apiKey: "a-lzfew7-rdy0ukhyjs", // replace with the
key for a generated API token
iot_apiToken: "2IJ3YkURaos!Hj&RH)", // replace with
the generated API token
// these topics will be used by Geospatial Analytics
notifyTopic: "iot-
2/type/api/id/geospatial/cmd/geoAlert/fmt/json",
inputTopic: "iot-
2/type/Vehicle/id/+/evt/telemetry/fmt/json",
};
try {
module.exports = config;
} catch (e) { window.config = config; }
docs/add_overlay1.png
docs/config1.png
docs/geospatial1.png
docs/geospatial2.png
docs/geospatial3.png
docs/geospatial4.png
docs/iot1.png
docs/iot2.png
docs/iot3.png
docs/iot4.png
docs/iot5.png
docs/iot6.png
docs/iot7.png
docs/iot8.png
docs/map1.png
docs/messaging.png
docs/node_red0.png
docs/node_red1_1.png
docs/node_red1_2.png
docs/node_red1_3.png
docs/node_red2_1.png
docs/node_red2_2.png
docs/node_red2_3.png
docs/node_red2_4.png
docs/node_red3_1.png
docs/node_red3_2.png
docs/node_red4_1.png
docs/node_red4_2.png
docs/set_property1.png
docs/set_property2.png
docs/vehicle_count1.png
docs/vehicle_count2.png
LICENSE
Eclipse Public License - v 1.0
THE ACCOMPANYING PROGRAM IS PROVIDED UNDER
THE TERMS OF THIS ECLIPSE PUBLIC
LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR
DISTRIBUTION OF THE PROGRAM
CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS
AGREEMENT.
1. DEFINITIONS
"Contribution" means:
a) in the case of the initial Contributor, the initial code and
documentation
distributed under this Agreement, and
b) in the case of each subsequent Contributor:
i) changes to the Program, and
ii) additions to the Program;
where such changes and/or additions to the Program originate
from and are
distributed by that particular Contributor. A Contribution
'originates'
from a Contributor if it was added to the Program by such
Contributor
itself or anyone acting on such Contributor's behalf.
Contributions do not
include additions to the Program which: (i) are separate
modules of
software distributed in conjunction with the Program under
their own
license agreement, and (ii) are not derivative works of the
Program.
"Contributor" means any person or entity that distributes the
Program.
"Licensed Patents" mean patent claims licensable by a
Contributor which are
necessarily infringed by the use or sale of its Contribution alone
or when
combined with the Program.
"Program" means the Contributions distributed in accordance
with this
Agreement.
"Recipient" means anyone who receives the Program under this
Agreement,
including all Contributors.
2. GRANT OF RIGHTS
a) Subject to the terms of this Agreement, each Contributor
hereby grants
Recipient a non-exclusive, worldwide, royalty-free copyright
license to
reproduce, prepare derivative works of, publicly display,
publicly
perform, distribute and sublicense the Contribution of such
Contributor,
if any, and such derivative works, in source code and object
code form.
b) Subject to the terms of this Agreement, each Contributor
hereby grants
Recipient a non-exclusive, worldwide, royalty-free patent
license under
Licensed Patents to make, use, sell, offer to sell, import and
otherwise
transfer the Contribution of such Contributor, if any, in
source code and
object code form. This patent license shall apply to the
combination of
the Contribution and the Program if, at the time the
Contribution is
added by the Contributor, such addition of the Contribution
causes such
combination to be covered by the Licensed Patents. The
patent license
shall not apply to any other combinations which include the
Contribution.
No hardware per se is licensed hereunder.
c) Recipient understands that although each Contributor grants
the licenses
to its Contributions set forth herein, no assurances are
provided by any
Contributor that the Program does not infringe the patent or
other
intellectual property rights of any other entity. Each
Contributor
disclaims any liability to Recipient for claims brought by
any other
entity based on infringement of intellectual property rights
or
otherwise. As a condition to exercising the rights and
licenses granted
hereunder, each Recipient hereby assumes sole
responsibility to secure
any other intellectual property rights needed, if any. For
example, if a
third party patent license is required to allow Recipient to
distribute
the Program, it is Recipient's responsibility to acquire that
license
before distributing the Program.
d) Each Contributor represents that to its knowledge it has
sufficient
copyright rights in its Contribution, if any, to grant the
copyright
license set forth in this Agreement.
3. REQUIREMENTS
A Contributor may choose to distribute the Program in object
code form under
its own license agreement, provided that:
a) it complies with the terms and conditions of this
Agreement; and
b) its license agreement:
i) effectively disclaims on behalf of all Contributors all
warranties
and conditions, express and implied, including warranties
or
conditions of title and non-infringement, and implied
warranties or
conditions of merchantability and fitness for a particular
purpose;
ii) effectively excludes on behalf of all Contributors all
liability for
damages, including direct, indirect, special, incidental
and
consequential damages, such as lost profits;
iii) states that any provisions which differ from this
Agreement are
offered by that Contributor alone and not by any other
party; and
iv) states that source code for the Program is available from
such
Contributor, and informs licensees how to obtain it in a
reasonable
manner on or through a medium customarily used for
software exchange.
When the Program is made available in source code form:
a) it must be made available under this Agreement; and
b) a copy of this Agreement must be included with each copy
of the Program.
Contributors may not remove or alter any copyright notices
contained
within the Program.
Each Contributor must identify itself as the originator of its
Contribution,
if
any, in a manner that reasonably allows subsequent Recipients
to identify the
originator of the Contribution.
4. COMMERCIAL DISTRIBUTION
Commercial distributors of software may accept certain
responsibilities with
respect to end users, business partners and the like. While this
license is
intended to facilitate the commercial use of the Program, the
Contributor who
includes the Program in a commercial product offering should
do so in a manner
which does not create potential liability for other Contributors.
Therefore,
if a Contributor includes the Program in a commercial product
offering, such
Contributor ("Commercial Contributor") hereby agrees to
defend and indemnify
every other Contributor ("Indemnified Contributor") against any
losses,
damages and costs (collectively "Losses") arising from claims,
lawsuits and
other legal actions brought by a third party against the
Indemnified
Contributor to the extent caused by the acts or omissions of
such Commercial
Contributor in connection with its distribution of the Program in
a commercial
product offering. The obligations in this section do not apply to
any claims
or Losses relating to any actual or alleged intellectual property
infringement. In order to qualify, an Indemnified Contributor
must:
a) promptly notify the Commercial Contributor in writing of
such claim, and
b) allow the Commercial Contributor to control, and cooperate
with the
Commercial Contributor in, the defense and any related
settlement
negotiations. The Indemnified Contributor may participate in
any such claim at
its own expense.
For example, a Contributor might include the Program in a
commercial product
offering, Product X. That Contributor is then a Commercial
Contributor. If
that Commercial Contributor then makes performance claims, or
offers
warranties related to Product X, those performance claims and
warranties are
such Commercial Contributor's responsibility alone. Under this
section, the
Commercial Contributor would have to defend claims against
the other
Contributors related to those performance claims and
warranties, and if a
court requires any other Contributor to pay any damages as a
result, the
Commercial Contributor must pay those damages.
5. NO WARRANTY
EXCEPT AS EXPRESSLY SET FORTH IN THIS
AGREEMENT, THE PROGRAM IS PROVIDED ON AN
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
OF ANY KIND, EITHER EXPRESS OR
IMPLIED INCLUDING, WITHOUT LIMITATION, ANY
WARRANTIES OR CONDITIONS OF TITLE,
NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS
FOR A PARTICULAR PURPOSE. Each
Recipient is solely responsible for determining the
appropriateness of using
and distributing the Program and assumes all risks associated
with its
exercise of rights under this Agreement , including but not
limited to the
risks and costs of program errors, compliance with applicable
laws, damage to
or loss of data, programs or equipment, and unavailability or
interruption of
operations.
6. DISCLAIMER OF LIABILITY
EXCEPT AS EXPRESSLY SET FORTH IN THIS
AGREEMENT, NEITHER RECIPIENT NOR ANY
CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING WITHOUT LIMITATION
LOST PROFITS), HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OR
DISTRIBUTION OF THE PROGRAM OR THE
EXERCISE OF ANY RIGHTS GRANTED HEREUNDER,
EVEN IF ADVISED OF THE POSSIBILITY
OF SUCH DAMAGES.
7. GENERAL
If any provision of this Agreement is invalid or unenforceable
under
applicable law, it shall not affect the validity or enforceability
of the
remainder of the terms of this Agreement, and without further
action by the
parties hereto, such provision shall be reformed to the minimum
extent
necessary to make such provision valid and enforceable.
If Recipient institutes patent litigation against any entity
(including a
cross-claim or counterclaim in a lawsuit) alleging that the
Program itself
(excluding combinations of the Program with other software or
hardware)
infringes such Recipient's patent(s), then such Recipient's rights
granted
under Section 2(b) shall terminate as of the date such litigation
is filed.
All Recipient's rights under this Agreement shall terminate if it
fails to
comply with any of the material terms or conditions of this
Agreement and does
not cure such failure in a reasonable period of time after
becoming aware of
such noncompliance. If all Recipient's rights under this
Agreement terminate,
Recipient agrees to cease use and distribution of the Program as
soon as
reasonably practicable. However, Recipient's obligations under
this Agreement
and any licenses granted by Recipient relating to the Program
shall continue
and survive.
Everyone is permitted to copy and distribute copies of this
Agreement, but in
order to avoid inconsistency the Agreement is copyrighted and
may only be
modified in the following manner. The Agreement Steward
reserves the right to
publish new versions (including revisions) of this Agreement
from time to
time. No one other than the Agreement Steward has the right to
modify this
Agreement. The Eclipse Foundation is the initial Agreement
Steward. The
Eclipse Foundation may assign the responsibility to serve as the
Agreement
Steward to a suitable separate entity. Each new version of the
Agreement will
be given a distinguishing version number. The Program
(including
Contributions) may always be distributed subject to the version
of the
Agreement under which it was received. In addition, after a new
version of the
Agreement is published, Contributor may elect to distribute the
Program
(including its Contributions) under the new version. Except as
expressly
stated in Sections 2(a) and 2(b) above, Recipient receives no
rights or
licenses to the intellectual property of any Contributor under
this Agreement,
whether expressly, by implication, estoppel or otherwise. All
rights in the
Program not expressly granted under this Agreement are
reserved.
This Agreement is governed by the laws of the State of New
York and the
intellectual property laws of the United States of America. No
party to this
Agreement will bring a legal action under this Agreement more
than one year
after the cause of action arose. Each party waives its rights to a
jury trial in
any resulting litigation.
manifest.yml
applications:
- host: Lab8TestT12018Assignment3
disk: 128M
name: Lab8TestT12018Assignment3
command: node app.js
path: .
domain: mybluemix.net
memory: 128M
instances: 3
maps/austin_downtown-clean.osm
maps/san_francisco-clean.osm
maps/vegas-clean.osm
node_modules/body-parser/HISTORY.md
1.17.2 / 2017-05-17
===================
* deps: [email protected]
- Fix `DEBUG_MAX_ARRAY_LENGTH`
- deps: [email protected]
* deps: [email protected]~1.6.15
- deps: [email protected]~2.1.15
1.17.1 / 2017-03-06
===================
* deps: [email protected]
- Fix regression parsing keys starting with `[`
1.17.0 / 2017-03-01
===================
* deps: [email protected]~1.6.1
- Make `message` property enumerable for `HttpError`s
- deps: [email protected]
* deps: [email protected]
- Fix compacting nested arrays
1.16.1 / 2017-02-10
===================
* deps: [email protected]
- Fix deprecation messages in WebStorm and other editors
- Undeprecate `DEBUG_FD` set to `1` or `2`
1.16.0 / 2017-01-17
===================
* deps: [email protected]
- Allow colors in workers
- Deprecated `DEBUG_FD` environment variable
- Fix error when running under React Native
- Use same color for same namespace
- deps: [email protected]
* deps: [email protected]~1.5.1
- deps: [email protected]
- deps: [email protected]
- deps: [email protected]'>= 1.3.1 < 2'
* deps: [email protected]
- Added encoding MS-31J
- Added encoding MS-932
- Added encoding MS-936
- Added encoding MS-949
- Added encoding MS-950
- Fix GBK/GB18030 handling of Euro character
* deps: [email protected]
- Fix array parsing from skipping empty values
* deps: [email protected]~2.2.0
- deps: [email protected]
* deps: [email protected]~1.6.14
- deps: [email protected]~2.1.13
1.15.2 / 2016-06-19
===================
* deps: [email protected]
* deps: [email protected]~1.0.2
- perf: enable strict mode
* deps: [email protected]~1.5.0
- Use `setprototypeof` module to replace `__proto__` setting
- deps: [email protected]'>= 1.3.0 < 2'
- perf: enable strict mode
* deps: [email protected]
* deps: [email protected]~2.1.7
- deps: [email protected]
- perf: remove double-cleanup on happy path
* deps: [email protected]~1.6.13
- deps: [email protected]~2.1.11
1.15.1 / 2016-05-05
===================
* deps: [email protected]
- Drop partial bytes on all parsed units
- Fix parsing byte string that looks like hex
* deps: [email protected]~2.1.6
- deps: [email protected]
* deps: [email protected]~1.6.12
- deps: [email protected]~2.1.10
1.15.0 / 2016-02-10
===================
* deps: [email protected]~1.4.0
- Add `HttpError` export, for `err instanceof
createError.HttpError`
- deps: [email protected]
- deps: [email protected]'>= 1.2.1 < 2'
* deps: [email protected]
* deps: [email protected]~1.6.11
- deps: [email protected]~2.1.9
1.14.2 / 2015-12-16
===================
* deps: [email protected]
* deps: [email protected]
* deps: [email protected]
* deps: [email protected]~2.1.5
- deps: [email protected]
- deps: [email protected]
* deps: [email protected]~1.6.10
- deps: [email protected]~2.1.8
1.14.1 / 2015-09-27
===================
* Fix issue where invalid charset results in 400 when `verify`
used
* deps: [email protected]
- Fix CESU-8 decoding in Node.js 4.x
* deps: [email protected]~2.1.4
- Fix masking critical errors from `iconv-lite`
- deps: [email protected]
* deps: [email protected]~1.6.9
- deps: [email protected]~2.1.7
1.14.0 / 2015-09-16
===================
* Fix JSON strict parse error to match syntax errors
* Provide static `require` analysis in `urlencoded` parser
* deps: [email protected]~1.1.0
- Support web browser loading
* deps: [email protected]
* deps: [email protected]~2.1.3
- Fix sync callback when attaching data listener causes sync
read
* deps: [email protected]~1.6.8
- Fix type error when given invalid type to match against
- deps: [email protected]~2.1.6
1.13.3 / 2015-07-31
===================
* deps: [email protected]~1.6.6
- deps: [email protected]~2.1.4
1.13.2 / 2015-07-05
===================
* deps: [email protected]
* deps: [email protected]
- Fix dropping parameters like `hasOwnProperty`
- Fix user-visible incompatibilities from 3.1.0
- Fix various parsing edge cases
* deps: [email protected]~2.1.2
- Fix error stack traces to skip `makeError`
- deps: [email protected]
* deps: [email protected]~1.6.4
- deps: [email protected]~2.1.2
- perf: enable strict mode
- perf: remove argument reassignment
1.13.1 / 2015-06-16
===================
* deps: [email protected]
- Downgraded from 3.1.0 because of user-visible
incompatibilities
1.13.0 / 2015-06-14
===================
* Add `statusCode` property on `Error`s, in addition to `status`
* Change `type` default to `application/json` for JSON parser
* Change `type` default to `application/x-www-form-
urlencoded` for urlencoded parser
* Provide static `require` analysis
* Use the `http-errors` module to generate errors
* deps: [email protected]
- Slight optimizations
* deps: [email protected]
- The encoding UTF-16 without BOM now defaults to UTF-
16LE when detection fails
- Leading BOM is now removed when decoding
* deps: [email protected]~2.3.0
- Add defined behavior for HTTP `CONNECT` requests
- Add defined behavior for HTTP `Upgrade` requests
- deps: [email protected]
* deps: [email protected]
- Fix dropping parameters like `hasOwnProperty`
- Fix various parsing edge cases
- Parsed object now has `null` prototype
* deps: [email protected]~2.1.1
- Use `unpipe` module for unpiping requests
- deps: [email protected]
* deps: [email protected]~1.6.3
- deps: [email protected]~2.1.1
- perf: reduce try block size
- perf: remove bitwise operations
* perf: enable strict mode
* perf: remove argument reassignment
* perf: remove delete call
1.12.4 / 2015-05-10
===================
* deps: [email protected]~2.2.0
* deps: [email protected]
- Fix allowing parameters like `constructor`
* deps: [email protected]~2.2.1
* deps: [email protected]~2.0.1
- Fix a false-positive when unpiping in Node.js 0.8
- deps: [email protected]
* deps: [email protected]~1.6.2
- deps: [email protected]~2.0.11
1.12.3 / 2015-04-15
===================
* Slight efficiency improvement when not debugging
* deps: [email protected]~1.0.1
* deps: [email protected]
- Add encoding alias UNICODE-1-1-UTF-7
* deps: [email protected]
- Fix hanging callback if request aborts during read
- deps: [email protected]
1.12.2 / 2015-03-16
===================
* deps: [email protected]
- Fix error when parameter `hasOwnProperty` is present
1.12.1 / 2015-03-15
===================
* deps: [email protected]~2.1.3
- Fix high intensity foreground color for bold
- deps: [email protected]
* deps: [email protected]~1.6.1
- deps: [email protected]~2.0.10
1.12.0 / 2015-02-13
===================
* add `debug` messages
* accept a function for the `type` option
* use `content-type` to parse `Content-Type` headers
* deps: [email protected]
- Gracefully support enumerables on `Object.prototype`
* deps: [email protected]
- deps: [email protected]
* deps: [email protected]~1.6.0
- fix argument reassignment
- fix false-positives in `hasBody` `Transfer-Encoding` check
- support wildcard for both type and subtype (`*/*`)
- deps: [email protected]~2.0.9
1.11.0 / 2015-01-30
===================
* make internal `extended: true` depth limit infinity
* deps: [email protected]~1.5.6
- deps: [email protected]~2.0.8
1.10.2 / 2015-01-20
===================
* deps: [email protected]
- Fix rare aliases of single-byte encodings
* deps: [email protected]
- deps: [email protected]
1.10.1 / 2015-01-01
===================
* deps: [email protected]~2.2.0
* deps: [email protected]~1.5.5
- deps: [email protected]~2.0.7
1.10.0 / 2014-12-02
===================
* make internal `extended: true` array limit dynamic
1.9.3 / 2014-11-21
==================
* deps: [email protected]
- Fix Windows-31J and X-SJIS encoding support
* deps: [email protected]
- Fix `arrayLimit` behavior
* deps: [email protected]
- deps: [email protected]
* deps: [email protected]~1.5.3
- deps: [email protected]~2.0.3
1.9.2 / 2014-10-27
==================
* deps: [email protected]
- Fix parsing of mixed objects and values
1.9.1 / 2014-10-22
==================
* deps: [email protected]~2.1.1
- Fix handling of pipelined requests
* deps: [email protected]
- Fix parsing of mixed implicit and explicit arrays
* deps: [email protected]~1.5.2
- deps: [email protected]~2.0.2
1.9.0 / 2014-09-24
==================
* include the charset in "unsupported charset" error message
* include the encoding in "unsupported content encoding"
error message
* deps: [email protected]~1.0.0
1.8.4 / 2014-09-23
==================
* fix content encoding to be case-insensitive
1.8.3 / 2014-09-19
==================
* deps: [email protected]
- Fix issue with object keys starting with numbers truncated
1.8.2 / 2014-09-15
==================
* deps: [email protected]
1.8.1 / 2014-09-07
==================
* deps: [email protected]
* deps: [email protected]~1.5.1
1.8.0 / 2014-09-05
==================
* make empty-body-handling consistent between chunked
requests
- empty `json` produces `{}`
- empty `raw` produces `new Buffer(0)`
- empty `text` produces `''`
- empty `urlencoded` produces `{}`
* deps: [email protected]
- Fix issue where first empty value in array is discarded
* deps: [email protected]~1.5.0
- fix `hasbody` to be true for `content-length: 0`
1.7.0 / 2014-09-01
==================
* add `parameterLimit` option to `urlencoded` parser
* change `urlencoded` extended array limit to 100
* respond with 413 when over `parameterLimit` in
`urlencoded`
1.6.7 / 2014-08-29
==================
* deps: [email protected]
- Remove unnecessary cloning
1.6.6 / 2014-08-27
==================
* deps: [email protected]
- Array parsing fix
- Performance improvements
1.6.5 / 2014-08-16
==================
* deps: [email protected]
1.6.4 / 2014-08-14
==================
* deps: [email protected]
1.6.3 / 2014-08-10
==================
* deps: [email protected]
1.6.2 / 2014-08-07
==================
* deps: [email protected]
- Fix parsing array of objects
1.6.1 / 2014-08-06
==================
* deps: [email protected]
- Accept urlencoded square brackets
- Accept empty values in implicit array notation
1.6.0 / 2014-08-05
==================
* deps: [email protected]
- Complete rewrite
- Limits array length to 20
- Limits object depth to 5
- Limits parameters to 1,000
1.5.2 / 2014-07-27
==================
* deps: [email protected]
- Work-around v8 generating empty stack traces
1.5.1 / 2014-07-26
==================
* deps: [email protected]
- Fix exception when global `Error.stackTraceLimit` is too
low
1.5.0 / 2014-07-20
==================
* deps: [email protected]
- Add `TRACE_DEPRECATION` environment variable
- Remove non-standard grey color from color output
- Support `--no-deprecation` argument
- Support `--trace-deprecation` argument
* deps: [email protected]
- Added encoding UTF-7
* deps: [email protected]
- deps: [email protected]
- Added encoding UTF-7
- Fix `Cannot switch to old mode now` error on Node.js
0.10+
* deps: [email protected]~1.3.2
1.4.3 / 2014-06-19
==================
* deps: [email protected]
- fix global variable leak
1.4.2 / 2014-06-19
==================
* deps: [email protected]
- improve type parsing
1.4.1 / 2014-06-19
==================
* fix urlencoded extended deprecation message
1.4.0 / 2014-06-19
==================
* add `text` parser
* add `raw` parser
* check accepted charset in content-type (accepts utf-8)
* check accepted encoding in content-encoding (accepts
identity)
* deprecate `bodyParser()` middleware; use `.json()` and
`.urlencoded()` as needed
* deprecate `urlencoded()` without provided `extended` option
* lazy-load urlencoded parsers
* parsers split into files for reduced mem usage
* support gzip and deflate bodies
- set `inflate: false` to turn off
* deps: [email protected]
- Support all encodings from `iconv-lite`
1.3.1 / 2014-06-11
==================
* deps: [email protected]
- Switch dependency from mime to [email protected]
1.3.0 / 2014-05-31
==================
* add `extended` option to urlencoded parser
1.2.2 / 2014-05-27
==================
* deps: [email protected]
- assert stream encoding on node.js 0.8
- assert stream encoding on node.js < 0.10.6
- deps: [email protected]
1.2.1 / 2014-05-26
==================
* invoke `next(err)` after request fully read
- prevents hung responses and socket hang ups
1.2.0 / 2014-05-11
==================
* add `verify` option
* deps: [email protected]
- support suffix matching
1.1.2 / 2014-05-11
==================
* improve json parser speed
1.1.1 / 2014-05-11
==================
* fix repeated limit parsing with every request
1.1.0 / 2014-05-10
==================
* add `type` option
* deps: pin for safety and consistency
1.0.2 / 2014-04-14
==================
* use `type-is` module
1.0.1 / 2014-03-20
==================
* lower default limits to 100kb
node_modules/body-parser/index.js
/*!
* body-parser
* Copyright(c) 2014-2015 Douglas Christopher Wilson
* MIT Licensed
*/
'use strict'
/**
* Module dependencies.
* @private
*/
var deprecate = require('depd')('body-parser')
/**
* Cache of loaded parsers.
* @private
*/
var parsers = Object.create(null)
/**
* @typedef Parsers
* @type {function}
* @property {function} json
* @property {function} raw
* @property {function} text
* @property {function} urlencoded
*/
/**
* Module exports.
* @type {Parsers}
*/
exports = module.exports = deprecate.function(bodyParser,
'bodyParser: use individual json/urlencoded middlewares')
/**
* JSON parser.
* @public
*/
Object.defineProperty(exports, 'json', {
configurable: true,
enumerable: true,
get: createParserGetter('json')
})
/**
* Raw parser.
* @public
*/
Object.defineProperty(exports, 'raw', {
configurable: true,
enumerable: true,
get: createParserGetter('raw')
})
/**
* Text parser.
* @public
*/
Object.defineProperty(exports, 'text', {
configurable: true,
enumerable: true,
get: createParserGetter('text')
})
/**
* URL-encoded parser.
* @public
*/
Object.defineProperty(exports, 'urlencoded', {
configurable: true,
enumerable: true,
get: createParserGetter('urlencoded')
})
/**
* Create a middleware to parse json and urlencoded bodies.
*
* @param {object} [options]
* @return {function}
* @deprecated
* @public
*/
function bodyParser (options) {
var opts = {}
// exclude type option
if (options) {
for (var prop in options) {
if (prop !== 'type') {
opts[prop] = options[prop]
}
}
}
var _urlencoded = exports.urlencoded(opts)
var _json = exports.json(opts)
return function bodyParser (req, res, next) {
_json(req, res, function (err) {
if (err) return next(err)
_urlencoded(req, res, next)
})
}
}
/**
* Create a getter for loading a parser.
* @private
*/
function createParserGetter (name) {
return function get () {
return loadParser(name)
}
}
/**
* Load a parser module.
* @private
*/
function loadParser (parserName) {
var parser = parsers[parserName]
if (parser !== undefined) {
return parser
}
// this uses a switch for static require analysis
switch (parserName) {
case 'json':
parser = require('./lib/types/json')
break
case 'raw':
parser = require('./lib/types/raw')
break
case 'text':
parser = require('./lib/types/text')
break
case 'urlencoded':
parser = require('./lib/types/urlencoded')
break
}
// store to prevent invoking require()
return (parsers[parserName] = parser)
}
node_modules/body-parser/lib/read.js
/*!
* body-parser
* Copyright(c) 2014-2015 Douglas Christopher Wilson
* MIT Licensed
*/
'use strict'
/**
* Module dependencies.
* @private
*/
var createError = require('http-errors')
var getBody = require('raw-body')
var iconv = require('iconv-lite')
var onFinished = require('on-finished')
var zlib = require('zlib')
/**
* Module exports.
*/
module.exports = read
/**
* Read a request into a buffer and parse.
*
* @param {object} req
* @param {object} res
* @param {function} next
* @param {function} parse
* @param {function} debug
* @param {object} options
* @private
*/
function read (req, res, next, parse, debug, options) {
var length
var opts = options
var stream
// flag as parsed
req._body = true
// read options
var encoding = opts.encoding !== null
? opts.encoding
: null
var verify = opts.verify
try {
// get the content stream
stream = contentstream(req, debug, opts.inflate)
length = stream.length
stream.length = undefined
} catch (err) {
return next(err)
}
// set raw-body options
opts.length = length
opts.encoding = verify
? null
: encoding
// assert charset is supported
if (opts.encoding === null && encoding !== null &&
!iconv.encodingExists(encoding)) {
return next(createError(415, 'unsupported charset "' +
encoding.toUpperCase() + '"', {
charset: encoding.toLowerCase()
}))
}
// read body
debug('read body')
getBody(stream, opts, function (err, body) {
if (err) {
// default to 400
setErrorStatus(err, 400)
// echo back charset
if (err.type === 'encoding.unsupported') {
err = createError(415, 'unsupported charset "' +
encoding.toUpperCase() + '"', {
charset: encoding.toLowerCase()
})
}
// read off entire request
stream.resume()
onFinished(req, function onfinished () {
next(err)
})
return
}
// verify
if (verify) {
try {
debug('verify body')
verify(req, res, body, encoding)
} catch (err) {
// default to 403
setErrorStatus(err, 403)
next(err)
return
}
}
// parse
var str
try {
debug('parse body')
str = typeof body !== 'string' && encoding !== null
? iconv.decode(body, encoding)
: body
req.body = parse(str)
} catch (err) {
// istanbul ignore next
err.body = str === undefined
? body
: str
// default to 400
setErrorStatus(err, 400)
next(err)
return
}
next()
})
}
/**
* Get the content stream of the request.
*
* @param {object} req
* @param {function} debug
* @param {boolean} [inflate=true]
* @return {object}
* @api private
*/
function contentstream (req, debug, inflate) {
var encoding = (req.headers['content-encoding'] ||
'identity').toLowerCase()
var length = req.headers['content-length']
var stream
debug('content-encoding "%s"', encoding)
if (inflate === false && encoding !== 'identity') {
throw createError(415, 'content encoding unsupported')
}
switch (encoding) {
case 'deflate':
stream = zlib.createInflate()
debug('inflate body')
req.pipe(stream)
break
case 'gzip':
stream = zlib.createGunzip()
debug('gunzip body')
req.pipe(stream)
break
case 'identity':
stream = req
stream.length = length
break
default:
throw createError(415, 'unsupported content encoding "' +
encoding + '"', {
encoding: encoding
})
}
return stream
}
/**
* Set a status on an error object, if ones does not exist
* @private
*/
function setErrorStatus (error, status) {
if (!error.status && !error.statusCode) {
error.status = status
error.statusCode = status
}
}
node_modules/body-parser/lib/types/json.js
/*!
* body-parser
* Copyright(c) 2014 Jonathan Ong
* Copyright(c) 2014-2015 Douglas Christopher Wilson
* MIT Licensed
*/
'use strict'
/**
* Module dependencies.
* @private
*/
var bytes = require('bytes')
var contentType = require('content-type')
var createError = require('http-errors')
var debug = require('debug')('body-parser:json')
var read = require('../read')
var typeis = require('type-is')
/**
* Module exports.
*/
module.exports = json
/**
* RegExp to match the first non-space in a string.
*
* Allowed whitespace is defined in RFC 7159:
*
* ws = *(
* %x20 / ; Space
* %x09 / ; Horizontal tab
* %x0A / ; Line feed or New line
* %x0D ) ; Carriage return
*/
var FIRST_CHAR_REGEXP = /^[x20x09x0ax0d]*(.)/ //
eslint-disable-line no-control-regex
/**
* Create a middleware to parse JSON bodies.
*
* @param {object} [options]
* @return {function}
* @public
*/
function json (options) {
var opts = options || {}
var limit = typeof opts.limit !== 'number'
? bytes.parse(opts.limit || '100kb')
: opts.limit
var inflate = opts.inflate !== false
var reviver = opts.reviver
var strict = opts.strict !== false
var type = opts.type || 'application/json'
var verify = opts.verify || false
if (verify !== false && typeof verify !== 'function') {
throw new TypeError('option verify must be function')
}
// create the appropriate type checking function
var shouldParse = typeof type !== 'function'
? typeChecker(type)
: type
function parse (body) {
if (body.length === 0) {
// special-case empty json body, as it's a common client-side
mistake
// TODO: maybe make this configurable or part of "strict"
option
return {}
}
if (strict) {
var first = firstchar(body)
if (first !== '{' && first !== '[') {
debug('strict violation')
throw new SyntaxError('Unexpected token ' + first)
}
}
debug('parse json')
return JSON.parse(body, reviver)
}
return function jsonParser (req, res, next) {
if (req._body) {
debug('body already parsed')
next()
return
}
req.body = req.body || {}
// skip requests without bodies
if (!typeis.hasBody(req)) {
debug('skip empty body')
next()
return
}
debug('content-type %j', req.headers['content-type'])
// determine if request should be parsed
if (!shouldParse(req)) {
debug('skip parsing')
next()
return
}
// assert charset per RFC 7159 sec 8.1
var charset = getCharset(req) || 'utf-8'
if (charset.substr(0, 4) !== 'utf-') {
debug('invalid charset')
next(createError(415, 'unsupported charset "' +
charset.toUpperCase() + '"', {
charset: charset
}))
return
}
// read
read(req, res, next, parse, debug, {
encoding: charset,
inflate: inflate,
limit: limit,
verify: verify
})
}
}
/**
* Get the first non-whitespace character in a string.
*
* @param {string} str
* @return {function}
* @private
*/
function firstchar (str) {
return FIRST_CHAR_REGEXP.exec(str)[1]
}
/**
* Get the charset of a request.
*
* @param {object} req
* @api private
*/
function getCharset (req) {
try {
return
contentType.parse(req).parameters.charset.toLowerCase()
} catch (e) {
return undefined
}
}
/**
* Get the simple type checker.
*
* @param {string} type
* @return {function}
*/
function typeChecker (type) {
return function checkType (req) {
return Boolean(typeis(req, type))
}
}
node_modules/body-parser/lib/types/raw.js
/*!
* body-parser
* Copyright(c) 2014-2015 Douglas Christopher Wilson
* MIT Licensed
*/
'use strict'
/**
* Module dependencies.
*/
var bytes = require('bytes')
var debug = require('debug')('body-parser:raw')
var read = require('../read')
var typeis = require('type-is')
/**
* Module exports.
*/
module.exports = raw
/**
* Create a middleware to parse raw bodies.
*
* @param {object} [options]
* @return {function}
* @api public
*/
function raw (options) {
var opts = options || {}
var inflate = opts.inflate !== false
var limit = typeof opts.limit !== 'number'
? bytes.parse(opts.limit || '100kb')
: opts.limit
var type = opts.type || 'application/octet-stream'
var verify = opts.verify || false
if (verify !== false && typeof verify !== 'function') {
throw new TypeError('option verify must be function')
}
// create the appropriate type checking function
var shouldParse = typeof type !== 'function'
? typeChecker(type)
: type
function parse (buf) {
return buf
}
return function rawParser (req, res, next) {
if (req._body) {
debug('body already parsed')
next()
return
}
req.body = req.body || {}
// skip requests without bodies
if (!typeis.hasBody(req)) {
debug('skip empty body')
next()
return
}
debug('content-type %j', req.headers['content-type'])
// determine if request should be parsed
if (!shouldParse(req)) {
debug('skip parsing')
next()
return
}
// read
read(req, res, next, parse, debug, {
encoding: null,
inflate: inflate,
limit: limit,
verify: verify
})
}
}
/**
* Get the simple type checker.
*
* @param {string} type
* @return {function}
*/
function typeChecker (type) {
return function checkType (req) {
return Boolean(typeis(req, type))
}
}
node_modules/body-parser/lib/types/text.js
/*!
* body-parser
* Copyright(c) 2014-2015 Douglas Christopher Wilson
* MIT Licensed
*/
'use strict'
/**
* Module dependencies.
*/
var bytes = require('bytes')
var contentType = require('content-type')
var debug = require('debug')('body-parser:text')
var read = require('../read')
var typeis = require('type-is')
/**
* Module exports.
*/
module.exports = text
/**
* Create a middleware to parse text bodies.
*
* @param {object} [options]
* @return {function}
* @api public
*/
function text (options) {
var opts = options || {}
var defaultCharset = opts.defaultCharset || 'utf-8'
var inflate = opts.inflate !== false
var limit = typeof opts.limit !== 'number'
? bytes.parse(opts.limit || '100kb')
: opts.limit
var type = opts.type || 'text/plain'
var verify = opts.verify || false
if (verify !== false && typeof verify !== 'function') {
throw new TypeError('option verify must be function')
}
// create the appropriate type checking function
var shouldParse = typeof type !== 'function'
? typeChecker(type)
: type
function parse (buf) {
return buf
}
return function textParser (req, res, next) {
if (req._body) {
debug('body already parsed')
next()
return
}
req.body = req.body || {}
// skip requests without bodies
if (!typeis.hasBody(req)) {
debug('skip empty body')
next()
return
}
debug('content-type %j', req.headers['content-type'])
// determine if request should be parsed
if (!shouldParse(req)) {
debug('skip parsing')
next()
return
}
// get charset
var charset = getCharset(req) || defaultCharset
// read
read(req, res, next, parse, debug, {
encoding: charset,
inflate: inflate,
limit: limit,
verify: verify
})
}
}
/**
* Get the charset of a request.
*
* @param {object} req
* @api private
*/
function getCharset (req) {
try {
return
contentType.parse(req).parameters.charset.toLowerCase()
} catch (e) {
return undefined
}
}
/**
* Get the simple type checker.
*
* @param {string} type
* @return {function}
*/
function typeChecker (type) {
return function checkType (req) {
return Boolean(typeis(req, type))
}
}
node_modules/body-parser/lib/types/urlencoded.js
/*!
* body-parser
* Copyright(c) 2014 Jonathan Ong
* Copyright(c) 2014-2015 Douglas Christopher Wilson
* MIT Licensed
*/
'use strict'
/**
* Module dependencies.
* @private
*/
var bytes = require('bytes')
var contentType = require('content-type')
var createError = require('http-errors')
var debug = require('debug')('body-parser:urlencoded')
var deprecate = require('depd')('body-parser')
var read = require('../read')
var typeis = require('type-is')
/**
* Module exports.
*/
module.exports = urlencoded
/**
* Cache of parser modules.
*/
var parsers = Object.create(null)
/**
* Create a middleware to parse urlencoded bodies.
*
* @param {object} [options]
* @return {function}
* @public
*/
function urlencoded (options) {
var opts = options || {}
// notice because option default will flip in next major
if (opts.extended === undefined) {
deprecate('undefined extended: provide extended option')
}
var extended = opts.extended !== false
var inflate = opts.inflate !== false
var limit = typeof opts.limit !== 'number'
? bytes.parse(opts.limit || '100kb')
: opts.limit
var type = opts.type || 'application/x-www-form-urlencoded'
var verify = opts.verify || false
if (verify !== false && typeof verify !== 'function') {
throw new TypeError('option verify must be function')
}
// create the appropriate query parser
var queryparse = extended
? extendedparser(opts)
: simpleparser(opts)
// create the appropriate type checking function
var shouldParse = typeof type !== 'function'
? typeChecker(type)
: type
function parse (body) {
return body.length
? queryparse(body)
: {}
}
return function urlencodedParser (req, res, next) {
if (req._body) {
debug('body already parsed')
next()
return
}
req.body = req.body || {}
// skip requests without bodies
if (!typeis.hasBody(req)) {
debug('skip empty body')
next()
return
}
debug('content-type %j', req.headers['content-type'])
// determine if request should be parsed
if (!shouldParse(req)) {
debug('skip parsing')
next()
return
}
// assert charset
var charset = getCharset(req) || 'utf-8'
if (charset !== 'utf-8') {
debug('invalid charset')
next(createError(415, 'unsupported charset "' +
charset.toUpperCase() + '"', {
charset: charset
}))
return
}
// read
read(req, res, next, parse, debug, {
debug: debug,
encoding: charset,
inflate: inflate,
limit: limit,
verify: verify
})
}
}
/**
* Get the extended query parser.
*
* @param {object} options
*/
function extendedparser (options) {
var parameterLimit = options.parameterLimit !== undefined
? options.parameterLimit
: 1000
var parse = parser('qs')
if (isNaN(parameterLimit) || parameterLimit < 1) {
throw new TypeError('option parameterLimit must be a
positive number')
}
if (isFinite(parameterLimit)) {
parameterLimit = parameterLimit | 0
}
return function queryparse (body) {
var paramCount = parameterCount(body, parameterLimit)
if (paramCount === undefined) {
debug('too many parameters')
throw createError(413, 'too many parameters')
}
var arrayLimit = Math.max(100, paramCount)
debug('parse extended urlencoding')
return parse(body, {
allowPrototypes: true,
arrayLimit: arrayLimit,
depth: Infinity,
parameterLimit: parameterLimit
})
}
}
/**
* Get the charset of a request.
*
* @param {object} req
* @api private
*/
function getCharset (req) {
try {
return
contentType.parse(req).parameters.charset.toLowerCase()
} catch (e) {
return undefined
}
}
/**
* Count the number of parameters, stopping once limit reached
*
* @param {string} body
* @param {number} limit
* @api private
*/
function parameterCount (body, limit) {
var count = 0
var index = 0
while ((index = body.indexOf('&', index)) !== -1) {
count++
index++
if (count === limit) {
return undefined
}
}
return count
}
/**
* Get parser for module name dynamically.
*
* @param {string} name
* @return {function}
* @api private
*/
function parser (name) {
var mod = parsers[name]
if (mod !== undefined) {
return mod.parse
}
// this uses a switch for static require analysis
switch (name) {
case 'qs':
mod = require('qs')
break
case 'querystring':
mod = require('querystring')
break
}
// store to prevent invoking require()
parsers[name] = mod
return mod.parse
}
/**
* Get the simple query parser.
*
* @param {object} options
*/
function simpleparser (options) {
var parameterLimit = options.parameterLimit !== undefined
? options.parameterLimit
: 1000
var parse = parser('querystring')
if (isNaN(parameterLimit) || parameterLimit < 1) {
throw new TypeError('option parameterLimit must be a
positive number')
}
if (isFinite(parameterLimit)) {
parameterLimit = parameterLimit | 0
}
return function queryparse (body) {
var paramCount = parameterCount(body, parameterLimit)
if (paramCount === undefined) {
debug('too many parameters')
throw createError(413, 'too many parameters')
}
debug('parse urlencoding')
return parse(body, undefined, undefined, {maxKeys:
parameterLimit})
}
}
/**
* Get the simple type checker.
*
* @param {string} type
* @return {function}
*/
function typeChecker (type) {
return function checkType (req) {
return Boolean(typeis(req, type))
}
}
node_modules/body-parser/LICENSE
(The MIT License)
Copyright (c) 2014 Jonathan Ong <[email protected]>
Copyright (c) 2014-2015 Douglas Christopher Wilson
<[email protected]>
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_modules/body-parser/package.json
{
"_args": [
[
{
"raw": "body-parser",
"scope": null,
"escapedName": "body-parser",
"name": "body-parser",
"rawSpec": "",
"spec": "latest",
"type": "tag"
},
"C:UsersraybDesktopCQU coursesT2-
2017COIT20260LabsLab 8Lab8"
]
],
"_from": "[email protected]",
"_id": "[email protected]",
"_inCache": true,
"_location": "/body-parser",
"_nodeVersion": "6.10.3",
"_npmOperationalInternal": {
"host": "packages-18-east.internal.npmjs.com",
"tmp": "tmp/body-parser-
1.17.2.tgz_1495083464528_0.912320519099012"
},
"_npmUser": {
"name": "dougwilson",
"email": "[email protected]"
},
"_npmVersion": "3.10.10",
"_phantomChildren": {},
"_requested": {
"raw": "body-parser",
"scope": null,
"escapedName": "body-parser",
"name": "body-parser",
"rawSpec": "",
"spec": "latest",
"type": "tag"
},
"_requiredBy": [
"#USER",
"/"
],
"_resolved": "https://registry.npmjs.org/body-parser/-/body-
parser-1.17.2.tgz",
"_shasum": "f8892abc8f9e627d42aedafbca66bf5ab99104ee",
"_shrinkwrap": null,
"_spec": "body-parser",
"_where": "C:UsersraybDesktopCQU coursesT2-
2017COIT20260LabsLab 8Lab8",
"bugs": {
"url": "https://github.com/expressjs/body-parser/issues"
},
"contributors": [
{
"name": "Douglas Christopher Wilson",
"email": "[email protected]"
},
{
"name": "Jonathan Ong",
"email": "[email protected]",
"url": "http://jongleberry.com"
}
],
"dependencies": {
"bytes": "2.4.0",
"content-type": "~1.0.2",
"debug": "2.6.7",
"depd": "~1.1.0",
"http-errors": "~1.6.1",
"iconv-lite": "0.4.15",
"on-finished": "~2.3.0",
"qs": "6.4.0",
"raw-body": "~2.2.0",
"type-is": "~1.6.15"
},
"description": "Node.js body parsing middleware",
"devDependencies": {
"eslint": "3.19.0",
"eslint-config-standard": "10.2.1",
"eslint-plugin-import": "2.2.0",
"eslint-plugin-markdown": "1.0.0-beta.6",
"eslint-plugin-node": "4.2.2",
"eslint-plugin-promise": "3.5.0",
"eslint-plugin-standard": "3.0.1",
"istanbul": "0.4.5",
"methods": "1.1.2",
"mocha": "2.5.3",
"safe-buffer": "5.0.1",
"supertest": "1.1.0"
},
"directories": {},
"dist": {
"shasum": "f8892abc8f9e627d42aedafbca66bf5ab99104ee",
"tarball": "https://registry.npmjs.org/body-parser/-/body-
parser-1.17.2.tgz"
},
"engines": {
"node": ">= 0.8"
},
"files": [
"lib/",
"LICENSE",
"HISTORY.md",
"index.js"
],
"gitHead": "77b74312edb46b2e8d8df0c8436aaba396a721e9",
"homepage": "https://github.com/expressjs/body-
parser#readme",
"license": "MIT",
"maintainers": [
{
"name": "dougwilson",
"email": "[email protected]"
}
],
"name": "body-parser",
"optionalDependencies": {},
"readme": "ERROR: No README data found!",
"repository": {
"type": "git",
"url": "git+https://github.com/expressjs/body-parser.git"
},
"scripts": {
"lint": "eslint --plugin markdown --ext js,md .",
"test": "mocha --require test/support/env --reporter spec --
check-leaks --bail test/",
"test-cov": "istanbul cover node_modules/mocha/bin/_mocha
-- --require test/support/env --reporter dot --check-leaks test/",
"test-travis": "istanbul cover
node_modules/mocha/bin/_mocha --report lcovonly -- --require
test/support/env --reporter spec --check-leaks test/"
},
"version": "1.17.2"
}
node_modules/body-parser/README.md
# body-parser
[![NPM Version][npm-image]][npm-url]
[![NPM Downloads][downloads-image]][downloads-url]
[![Build Status][travis-image]][travis-url]
[![Test Coverage][coveralls-image]][coveralls-url]
[![Gratipay][gratipay-image]][gratipay-url]
Node.js body parsing middleware.
Parse incoming request bodies in a middleware before your
handlers, available
under the `req.body` property.
[Learn about the anatomy of an HTTP transaction in
Node.js](https://nodejs.org/en/docs/guides/anatomy-of-an-http-
transaction/).
_This does not handle multipart bodies_, due to their complex
and typically
large nature. For multipart bodies, you may be interested in the
following
modules:
* [busboy](https://www.npmjs.org/package/busboy#readme)
and
[connect-busboy](https://www.npmjs.org/package/connect-
busboy#readme)
*
[multiparty](https://www.npmjs.org/package/multiparty#readme
) and
[connect-
multiparty](https://www.npmjs.org/package/connect-
multiparty#readme)
*
[formidable](https://www.npmjs.org/package/formidable#readm
e)
* [multer](https://www.npmjs.org/package/multer#readme)
This module provides the following parsers:
* [JSON body parser](#bodyparserjsonoptions)
* [Raw body parser](#bodyparserrawoptions)
* [Text body parser](#bodyparsertextoptions)
* [URL-encoded form body
parser](#bodyparserurlencodedoptions)
Other body parsers you might be interested in:
- [body](https://www.npmjs.org/package/body#readme)
- [co-body](https://www.npmjs.org/package/co-body#readme)
## Installation
```sh
$ npm install body-parser
```
## API
<!-- eslint-disable no-unused-vars -->
```js
var bodyParser = require('body-parser')
```
The `bodyParser` object exposes various factories to create
middlewares. All
middlewares will populate the `req.body` property with the
parsed body when
the `Content-Type` request header matches the `type` option, or
an empty
object (`{}`) if there was no body to parse, the `Content-Type`
was not matched,
or an error occurred.
The various errors returned by this module are described in the
[errors section](#errors).
### bodyParser.json(options)
Returns middleware that only parses `json` and only looks at
requests where
the `Content-Type` header matches the `type` option. This
parser accepts any
Unicode encoding of the body and supports automatic inflation
of `gzip` and
`deflate` encodings.
A new `body` object containing the parsed data is populated on
the `request`
object after the middleware (i.e. `req.body`).
#### Options
The `json` function takes an option `options` object that may
contain any of
the following keys:
##### inflate
When set to `true`, then deflated (compressed) bodies will be
inflated; when
`false`, deflated bodies are rejected. Defaults to `true`.
##### limit
Controls the maximum request body size. If this is a number,
then the value
specifies the number of bytes; if it is a string, the value is
passed to the
[bytes](https://www.npmjs.com/package/bytes) library for
parsing. Defaults
to `'100kb'`.
##### reviver
The `reviver` option is passed directly to `JSON.parse` as the
second
argument. You can find more information on this argument
[in the MDN documentation about
JSON.parse](https://developer.mozilla.org/en-
US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse
#Example.3A_Using_the_reviver_parameter).
##### strict
When set to `true`, will only accept arrays and objects; when
`false` will
accept anything `JSON.parse` accepts. Defaults to `true`.
##### type
The `type` option is used to determine what media type the
middleware will
parse. This option can be a function or a string. If a string,
`type` option
is passed directly to the [type-
is](https://www.npmjs.org/package/type-is#readme)
library and this can be an extension name (like `json`), a mime
type (like
`application/json`), or a mime type with a wildcard (like `*/*`
or `*/json`).
If a function, the `type` option is called as `fn(req)` and the
request is
parsed if it returns a truthy value. Defaults to `application/json`.
##### verify
The `verify` option, if supplied, is called as `verify(req, res,
buf, encoding)`,
where `buf` is a `Buffer` of the raw request body and `encoding`
is the
encoding of the request. The parsing can be aborted by throwing
an error.
### bodyParser.raw(options)
Returns middleware that parses all bodies as a `Buffer` and only
looks at
requests where the `Content-Type` header matches the `type`
option. This
parser supports automatic inflation of `gzip` and `deflate`
encodings.
A new `body` object containing the parsed data is populated on
the `request`
object after the middleware (i.e. `req.body`). This will be a
`Buffer` object
of the body.
#### Options
The `raw` function takes an option `options` object that may
contain any of
the following keys:
##### inflate
When set to `true`, then deflated (compressed) bodies will be
inflated; when
`false`, deflated bodies are rejected. Defaults to `true`.
##### limit
Controls the maximum request body size. If this is a number,
then the value
specifies the number of bytes; if it is a string, the value is
passed to the
[bytes](https://www.npmjs.com/package/bytes) library for
parsing. Defaults
to `'100kb'`.
##### type
The `type` option is used to determine what media type the
middleware will
parse. This option can be a function or a string. If a string,
`type` option
is passed directly to the [type-
is](https://www.npmjs.org/package/type-is#readme)
library and this can be an extension name (like `bin`), a mime
type (like
`application/octet-stream`), or a mime type with a wildcard (like
`*/*` or
`application/*`). If a function, the `type` option is called as
`fn(req)`
and the request is parsed if it returns a truthy value. Defaults to
`application/octet-stream`.
##### verify
The `verify` option, if supplied, is called as `verify(req, res,
buf, encoding)`,
where `buf` is a `Buffer` of the raw request body and `encoding`
is the
encoding of the request. The parsing can be aborted by throwing
an error.
### bodyParser.text(options)
Returns middleware that parses all bodies as a string and only
looks at
requests where the `Content-Type` header matches the `type`
option. This
parser supports automatic inflation of `gzip` and `deflate`
encodings.
A new `body` string containing the parsed data is populated on
the `request`
object after the middleware (i.e. `req.body`). This will be a
string of the
body.
#### Options
The `text` function takes an option `options` object that may
contain any of
the following keys:
##### defaultCharset
Specify the default character set for the text content if the
charset is not
specified in the `Content-Type` header of the request. Defaults
to `utf-8`.
##### inflate
When set to `true`, then deflated (compressed) bodies will be
inflated; when
`false`, deflated bodies are rejected. Defaults to `true`.
##### limit
Controls the maximum request body size. If this is a number,
then the value
specifies the number of bytes; if it is a string, the value is
passed to the
[bytes](https://www.npmjs.com/package/bytes) library for
parsing. Defaults
to `'100kb'`.
##### type
The `type` option is used to determine what media type the
middleware will
parse. This option can be a function or a string. If a string,
`type` option
is passed directly to the [type-
is](https://www.npmjs.org/package/type-is#readme)
library and this can be an extension name (like `txt`), a mime
type (like
`text/plain`), or a mime type with a wildcard (like `*/*` or
`text/*`).
If a function, the `type` option is called as `fn(req)` and the
request is
parsed if it returns a truthy value. Defaults to `text/plain`.
##### verify
The `verify` option, if supplied, is called as `verify(req, res,
buf, encoding)`,
where `buf` is a `Buffer` of the raw request body and `encoding`
is the
encoding of the request. The parsing can be aborted by throwing
an error.
### bodyParser.urlencoded(options)
Returns middleware that only parses `urlencoded` bodies and
only looks at
requests where the `Content-Type` header matches the `type`
option. This
parser accepts only UTF-8 encoding of the body and supports
automatic
inflation of `gzip` and `deflate` encodings.
A new `body` object containing the parsed data is populated on
the `request`
object after the middleware (i.e. `req.body`). This object will
contain
key-value pairs, where the value can be a string or array (when
`extended` is
`false`), or any type (when `extended` is `true`).
#### Options
The `urlencoded` function takes an option `options` object that
may contain
any of the following keys:
##### extended
The `extended` option allows to choose between parsing the
URL-encoded data
with the `querystring` library (when `false`) or the `qs` library
(when
`true`). The "extended" syntax allows for rich objects and arrays
to be
encoded into the URL-encoded format, allowing for a JSON-
like experience
with URL-encoded. For more information, please
[see the qs library](https://www.npmjs.org/package/qs#readme).
Defaults to `true`, but using the default has been deprecated.
Please
research into the difference between `qs` and `querystring` and
choose the
appropriate setting.
##### inflate
When set to `true`, then deflated (compressed) bodies will be
inflated; when
`false`, deflated bodies are rejected. Defaults to `true`.
##### limit
Controls the maximum request body size. If this is a number,
then the value
specifies the number of bytes; if it is a string, the value is
passed to the
[bytes](https://www.npmjs.com/package/bytes) library for
parsing. Defaults
to `'100kb'`.
##### parameterLimit
The `parameterLimit` option controls the maximum number of
parameters that
are allowed in the URL-encoded data. If a request contains more
parameters
than this value, a 413 will be returned to the client. Defaults to
`1000`.
##### type
The `type` option is used to determine what media type the
middleware will
parse. This option can be a function or a string. If a string,
`type` option
is passed directly to the [type-
is](https://www.npmjs.org/package/type-is#readme)
library and this can be an extension name (like `urlencoded`), a
mime type (like
`application/x-www-form-urlencoded`), or a mime type with a
wildcard (like
`*/x-www-form-urlencoded`). If a function, the `type` option is
called as
`fn(req)` and the request is parsed if it returns a truthy value.
Defaults
to `application/x-www-form-urlencoded`.
##### verify
The `verify` option, if supplied, is called as `verify(req, res,
buf, encoding)`,
where `buf` is a `Buffer` of the raw request body and `encoding`
is the
encoding of the request. The parsing can be aborted by throwing
an error.
## Errors
The middlewares provided by this module create errors
depending on the error
condition during parsing. The errors will typically have a
`status` property
that contains the suggested HTTP response code and a `body`
property containing
the read body, if available.
The following are the common errors emitted, though any error
can come through
for various reasons.
### content encoding unsupported
This error will occur when the request had a `Content-
Encoding` header that
contained an encoding but the "inflation" option was set to
`false`. The
`status` property is set to `415`.
### request aborted
This error will occur when the request is aborted by the client
before reading
the body has finished. The `received` property will be set to the
number of
bytes received before the request was aborted and the
`expected` property is
set to the number of expected bytes. The `status` property is set
to `400`.
### request entity too large
This error will occur when the request body's size is larger than
the "limit"
option. The `limit` property will be set to the byte limit and the
`length`
property will be set to the request body's length. The `status`
property is
set to `413`.
### request size did not match content length
This error will occur when the request's length did not match
the length from
the `Content-Length` header. This typically occurs when the
request is malformed,
typically when the `Content-Length` header was calculated
based on characters
instead of bytes. The `status` property is set to `400`.
### stream encoding should not be set
This error will occur when something called the
`req.setEncoding` method prior
to this middleware. This module operates directly on bytes only
and you cannot
call `req.setEncoding` when using this module. The `status`
property is set to
`500`.
### unsupported charset "BOGUS"
This error will occur when the request had a charset parameter
in the
`Content-Type` header, but the `iconv-lite` module does not
support it OR the
parser does not support it. The charset is contained in the
message as well
as in the `charset` property. The `status` property is set to
`415`.
### unsupported content encoding "bogus"
This error will occur when the request had a `Content-
Encoding` header that
contained an unsupported encoding. The encoding is contained
in the message
as well as in the `encoding` property. The `status` property is
set to `415`.
## Examples
### Express/Connect top-level generic
This example demonstrates adding a generic JSON and URL-
encoded parser as a
top-level middleware, which will parse the bodies of all
incoming requests.
This is the simplest setup.
```js
var express = require('express')
var bodyParser = require('body-parser')
var app = express()
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))
// parse application/json
app.use(bodyParser.json())
app.use(function (req, res) {
res.setHeader('Content-Type', 'text/plain')
res.write('you posted:n')
res.end(JSON.stringify(req.body, null, 2))
})
```
### Express route-specific
This example demonstrates adding body parsers specifically to
the routes that
need them. In general, this is the most recommended way to use
body-parser with
Express.
```js
var express = require('express')
var bodyParser = require('body-parser')
var app = express()
// create application/json parser
var jsonParser = bodyParser.json()
// create application/x-www-form-urlencoded parser
var urlencodedParser = bodyParser.urlencoded({ extended: false
})
// POST /login gets urlencoded bodies
app.post('/login', urlencodedParser, function (req, res) {
if (!req.body) return res.sendStatus(400)
res.send('welcome, ' + req.body.username)
})
// POST /api/users gets JSON bodies
app.post('/api/users', jsonParser, function (req, res) {
if (!req.body) return res.sendStatus(400)
// create user in req.body
})
```
### Change accepted type for parsers
All the parsers accept a `type` option which allows you to
change the
`Content-Type` that the middleware will parse.
```js
var express = require('express')
var bodyParser = require('body-parser')
var app = express()
// parse various different custom JSON types as JSON
app.use(bodyParser.json({ type: 'application/*+json' }))
// parse some custom thing into a Buffer
app.use(bodyParser.raw({ type: 'application/vnd.custom-type'
}))
// parse an HTML body into a string
app.use(bodyParser.text({ type: 'text/html' }))
```
## License
[MIT](LICENSE)
[npm-image]: https://img.shields.io/npm/v/body-parser.svg
[npm-url]: https://npmjs.org/package/body-parser
[travis-image]: https://img.shields.io/travis/expressjs/body-
parser/master.svg
[travis-url]: https://travis-ci.org/expressjs/body-parser
[coveralls-image]:
https://img.shields.io/coveralls/expressjs/body-
parser/master.svg
[coveralls-url]: https://coveralls.io/r/expressjs/body-
parser?branch=master
[downloads-image]: https://img.shields.io/npm/dm/body-
parser.svg
[downloads-url]: https://npmjs.org/package/body-parser
[gratipay-image]: https://img.shields.io/gratipay/dougwilson.svg
[gratipay-url]: https://www.gratipay.com/dougwilson/
node_modules/bytes/History.md
2.4.0 / 2016-06-01
==================
* Add option "unitSeparator"
2.3.0 / 2016-02-15
==================
* Drop partial bytes on all parsed units
* Fix non-finite numbers to `.format` to return `null`
* Fix parsing byte string that looks like hex
* perf: hoist regular expressions
2.2.0 / 2015-11-13
==================
* add option "decimalPlaces"
* add option "fixedDecimals"
2.1.0 / 2015-05-21
==================
* add `.format` export
* add `.parse` export
2.0.2 / 2015-05-20
==================
* remove map recreation
* remove unnecessary object construction
2.0.1 / 2015-05-07
==================
* fix browserify require
* remove node.extend dependency
2.0.0 / 2015-04-12
==================
* add option "case"
* add option "thousandsSeparator"
* return "null" on invalid parse input
* support proper round-trip: bytes(bytes(num)) === num
* units no longer case sensitive when parsing
1.0.0 / 2014-05-05
==================
* add negative support. fixes #6
0.3.0 / 2014-03-19
==================
* added terabyte support
0.2.1 / 2013-04-01
==================
* add .component
0.2.0 / 2012-10-28
==================
* bytes(200).should.eql('200b')
0.1.0 / 2012-07-04
==================
* add bytes to string conversion [yields]
node_modules/bytes/index.js
/*!
* bytes
* Copyright(c) 2012-2014 TJ Holowaychuk
* Copyright(c) 2015 Jed Watson
* MIT Licensed
*/
'use strict';
/**
* Module exports.
* @public
*/
module.exports = bytes;
module.exports.format = format;
module.exports.parse = parse;
/**
* Module variables.
* @private
*/
var formatThousandsRegExp = /B(?=(d{3})+(?!d))/g;
var formatDecimalsRegExp = /(?:.0*|(.[^0]+)0+)$/;
var map = {
b: 1,
kb: 1 << 10,
mb: 1 << 20,
gb: 1 << 30,
tb: ((1 << 30) * 1024)
};
// TODO: use is-finite module?
var numberIsFinite = Number.isFinite || function (v) { return
typeof v === 'number' && isFinite(v); };
var parseRegExp = /^((-|+)?(d+(?:.d+)?)) *(kb|mb|gb|tb)$/i;
/**
* Convert the given value in bytes into a string or parse to
string to an integer in bytes.
*
* @param {string|number} value
* @param {{
* case: [string],
* decimalPlaces: [number]
* fixedDecimals: [boolean]
* thousandsSeparator: [string]
* unitSeparator: [string]
* }} [options] bytes options.
*
* @returns {string|number|null}
*/
function bytes(value, options) {
if (typeof value === 'string') {
return parse(value);
}
if (typeof value === 'number') {
return format(value, options);
}
return null;
}
/**
* Format the given value in bytes into a string.
*
* If the value is negative, it is kept as such. If it is a float,
* it is rounded.
*
* @param {number} value
* @param {object} [options]
* @param {number} [options.decimalPlaces=2]
* @param {number} [options.fixedDecimals=false]
* @param {string} [options.thousandsSeparator=]
* @param {string} [options.unitSeparator=]
*
* @returns {string|null}
* @public
*/
function format(value, options) {
if (!numberIsFinite(value)) {
return null;
}
var mag = Math.abs(value);
var thousandsSeparator = (options &&
options.thousandsSeparator) || '';
var unitSeparator = (options && options.unitSeparator) || '';
var decimalPlaces = (options && options.decimalPlaces !==
undefined) ? options.decimalPlaces : 2;
var fixedDecimals = Boolean(options &&
options.fixedDecimals);
var unit = 'B';
if (mag >= map.tb) {
unit = 'TB';
} else if (mag >= map.gb) {
unit = 'GB';
} else if (mag >= map.mb) {
unit = 'MB';
} else if (mag >= map.kb) {
unit = 'kB';
}
var val = value / map[unit.toLowerCase()];
var str = val.toFixed(decimalPlaces);
if (!fixedDecimals) {
str = str.replace(formatDecimalsRegExp, '$1');
}
if (thousandsSeparator) {
str = str.replace(formatThousandsRegExp,
thousandsSeparator);
}
return str + unitSeparator + unit;
}
/**
* Parse the string value into an integer in bytes.
*
* If no unit is given, it is assumed the value is in bytes.
*
* @param {number|string} val
*
* @returns {number|null}
* @public
*/
function parse(val) {
if (typeof val === 'number' && !isNaN(val)) {
return val;
}
if (typeof val !== 'string') {
return null;
}
// Test if the string passed is valid
var results = parseRegExp.exec(val);
var floatValue;
var unit = 'b';
if (!results) {
// Nothing could be extracted from the given string
floatValue = parseInt(val, 10);
unit = 'b'
} else {
// Retrieve the value and the unit
floatValue = parseFloat(results[1]);
unit = results[4].toLowerCase();
}
return Math.floor(map[unit] * floatValue);
}
node_modules/bytes/LICENSE
(The MIT License)
Copyright (c) 2012-2014 TJ Holowaychuk <[email protected]>
Copyright (c) 2015 Jed Watson <[email protected]>
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_modules/bytes/package.json
{
"_args": [
[
{
"raw": "[email protected]",
"scope": null,
"escapedName": "bytes",
"name": "bytes",
"rawSpec": "2.4.0",
"spec": "2.4.0",
"type": "version"
},
"C:UsersraybDesktopCQU coursesT2-
2017COIT20260LabsLab 8Lab8node_modulesbody-
parser"
]
],
"_from": "[email protected]",
"_id": "[email protected]",
"_inCache": true,
"_location": "/bytes",
"_npmOperationalInternal": {
"host": "packages-16-east.internal.npmjs.com",
"tmp": "tmp/bytes-
2.4.0.tgz_1464812473023_0.6271433881483972"
},
"_npmUser": {
"name": "dougwilson",
"email": "[email protected]"
},
"_npmVersion": "1.4.28",
"_phantomChildren": {},
"_requested": {
"raw": "[email protected]",
"scope": null,
"escapedName": "bytes",
"name": "bytes",
"rawSpec": "2.4.0",
"spec": "2.4.0",
"type": "version"
},
"_requiredBy": [
"/body-parser",
"/raw-body"
],
"_resolved": "https://registry.npmjs.org/bytes/-/bytes-
2.4.0.tgz",
"_shasum": "7d97196f9d5baf7f6935e25985549edd2a6c2339",
"_shrinkwrap": null,
"_spec": "[email protected]",
"_where": "C:UsersraybDesktopCQU coursesT2-
2017COIT20260LabsLab 8Lab8node_modulesbody-
parser",
"author": {
"name": "TJ Holowaychuk",
"email": "[email protected]",
"url": "http://tjholowaychuk.com"
},
"bugs": {
"url": "https://github.com/visionmedia/bytes.js/issues"
},
"component": {
"scripts": {
"bytes/index.js": "index.js"
}
},
"contributors": [
{
"name": "Jed Watson",
"email": "[email protected]"
},
{
"name": "Théo FIDRY",
"email": "[email protected]"
}
],
"dependencies": {},
"description": "Utility to parse a string bytes to bytes and
vice-versa",
"devDependencies": {
"mocha": "1.21.5"
},
"directories": {},
"dist": {
"shasum": "7d97196f9d5baf7f6935e25985549edd2a6c2339",
"tarball": "https://registry.npmjs.org/bytes/-/bytes-2.4.0.tgz"
},
"files": [
"History.md",
"LICENSE",
"Readme.md",
"index.js"
],
"gitHead": "2a598442bdfa796df8d01a96cc54495cda550e70",
"homepage": "https://github.com/visionmedia/bytes.js",
"keywords": [
"byte",
"bytes",
"utility",
"parse",
"parser",
"convert",
"converter"
],
"license": "MIT",
"maintainers": [
{
"name": "dougwilson",
"email": "[email protected]"
},
{
"name": "tjholowaychuk",
"email": "[email protected]"
}
],
"name": "bytes",
"optionalDependencies": {},
"readme": "ERROR: No README data found!",
"repository": {
"type": "git",
"url": "git+https://github.com/visionmedia/bytes.js.git"
},
"scripts": {
"test": "mocha --check-leaks --reporter spec"
},
"version": "2.4.0"
}
node_modules/bytes/Readme.md
# Bytes utility
[![NPM Version][npm-image]][npm-url]
[![NPM Downloads][downloads-image]][downloads-url]
[![Build Status][travis-image]][travis-url]
Utility to parse a string bytes (ex: `1TB`) to bytes
(`1099511627776`) and vice-versa.
## Usage
```js
var bytes = require('bytes');
```
#### bytes.format(number value, [options]): string|null
Format the given value in bytes into a string. If the value is
negative, it is kept as such. If it is a float, it is
rounded.
**Arguments**
| Name | Type | Description |
|---------|--------|--------------------|
| value | `number` | Value in bytes |
| options | `Object` | Conversion options |
**Options**
| Property | Type | Description
|
|-------------------|--------|----------------------------------------------
-------------------------------------------|
| decimalPlaces | `number`&#124;`null` | Maximum number of
decimal places to include in output. Default value to `2`. |
| fixedDecimals | `boolean`&#124;`null` | Whether to always
display the maximum number of decimal places. Default value
to `false` |
| thousandsSeparator | `string`&#124;`null` | Example of values:
`' '`, `','` and `.`... Default value to `' '`. |
| unitSeparator | `string`&#124;`null` | Separator to use between
number and unit. Default value to `''`. |
**Returns**
| Name | Type | Description |
|---------|-------------|-------------------------|
| results | `string`&#124;`null` | Return null upon error. String
value otherwise. |
**Example**
```js
bytes(1024);
// output: '1kB'
bytes(1000);
// output: '1000B'
bytes(1000, {thousandsSeparator: ' '});
// output: '1 000B'
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx
app.js.docx

More Related Content

Similar to app.js.docx

Bonnes pratiques de développement avec Node js
Bonnes pratiques de développement avec Node jsBonnes pratiques de développement avec Node js
Bonnes pratiques de développement avec Node js
Francois Zaninotto
 
Reduxing like a pro
Reduxing like a proReduxing like a pro
Reduxing like a pro
Boris Dinkevich
 
Rntb20200805
Rntb20200805Rntb20200805
Rntb20200805
t k
 
ES6: Features + Rails
ES6: Features + RailsES6: Features + Rails
ES6: Features + Rails
Santosh Wadghule
 
I Phone On Rails
I Phone On RailsI Phone On Rails
I Phone On Rails
John Wilker
 
JavaScript Core
JavaScript CoreJavaScript Core
JavaScript Core
François Sarradin
 
Connecting Pebble to the World
Connecting Pebble to the WorldConnecting Pebble to the World
Connecting Pebble to the World
Pebble Technology
 
AST - the only true tool for building JavaScript
AST - the only true tool for building JavaScriptAST - the only true tool for building JavaScript
AST - the only true tool for building JavaScript
Ingvar Stepanyan
 
Nodejs do teste de unidade ao de integração
Nodejs  do teste de unidade ao de integraçãoNodejs  do teste de unidade ao de integração
Nodejs do teste de unidade ao de integração
Vinícius Pretto da Silva
 
java compilerCompiler1.javajava compilerCompiler1.javaimport.docx
java compilerCompiler1.javajava compilerCompiler1.javaimport.docxjava compilerCompiler1.javajava compilerCompiler1.javaimport.docx
java compilerCompiler1.javajava compilerCompiler1.javaimport.docx
priestmanmable
 
ES6 Overview
ES6 OverviewES6 Overview
ES6 Overview
Bruno Scopelliti
 
Pengenalan blaast platform sdk
Pengenalan blaast platform sdkPengenalan blaast platform sdk
Pengenalan blaast platform sdk
Arief Bayu Purwanto
 
Js hacks
Js hacksJs hacks
Workshop 1: Good practices in JavaScript
Workshop 1: Good practices in JavaScriptWorkshop 1: Good practices in JavaScript
Workshop 1: Good practices in JavaScript
Visual Engineering
 
Cross Domain Web
Mashups with JQuery and Google App Engine
Cross Domain Web
Mashups with JQuery and Google App EngineCross Domain Web
Mashups with JQuery and Google App Engine
Cross Domain Web
Mashups with JQuery and Google App Engine
Andy McKay
 
Five things for you - Yahoo developer offers
Five things for you - Yahoo developer offersFive things for you - Yahoo developer offers
Five things for you - Yahoo developer offers
Christian Heilmann
 
Chaincode Development 區塊鏈鏈碼開發
Chaincode Development 區塊鏈鏈碼開發Chaincode Development 區塊鏈鏈碼開發
Chaincode Development 區塊鏈鏈碼開發
HO-HSUN LIN
 
mobl
moblmobl
mobl
zefhemel
 
Angular Workshop_Sarajevo2
Angular Workshop_Sarajevo2Angular Workshop_Sarajevo2
Angular Workshop_Sarajevo2
Christoffer Noring
 
"О некоторых особенностях Objective-C++" Влад Михайленко (Maps.Me)
"О некоторых особенностях Objective-C++" Влад Михайленко (Maps.Me)"О некоторых особенностях Objective-C++" Влад Михайленко (Maps.Me)
"О некоторых особенностях Objective-C++" Влад Михайленко (Maps.Me)
AvitoTech
 

Similar to app.js.docx (20)

Bonnes pratiques de développement avec Node js
Bonnes pratiques de développement avec Node jsBonnes pratiques de développement avec Node js
Bonnes pratiques de développement avec Node js
 
Reduxing like a pro
Reduxing like a proReduxing like a pro
Reduxing like a pro
 
Rntb20200805
Rntb20200805Rntb20200805
Rntb20200805
 
ES6: Features + Rails
ES6: Features + RailsES6: Features + Rails
ES6: Features + Rails
 
I Phone On Rails
I Phone On RailsI Phone On Rails
I Phone On Rails
 
JavaScript Core
JavaScript CoreJavaScript Core
JavaScript Core
 
Connecting Pebble to the World
Connecting Pebble to the WorldConnecting Pebble to the World
Connecting Pebble to the World
 
AST - the only true tool for building JavaScript
AST - the only true tool for building JavaScriptAST - the only true tool for building JavaScript
AST - the only true tool for building JavaScript
 
Nodejs do teste de unidade ao de integração
Nodejs  do teste de unidade ao de integraçãoNodejs  do teste de unidade ao de integração
Nodejs do teste de unidade ao de integração
 
java compilerCompiler1.javajava compilerCompiler1.javaimport.docx
java compilerCompiler1.javajava compilerCompiler1.javaimport.docxjava compilerCompiler1.javajava compilerCompiler1.javaimport.docx
java compilerCompiler1.javajava compilerCompiler1.javaimport.docx
 
ES6 Overview
ES6 OverviewES6 Overview
ES6 Overview
 
Pengenalan blaast platform sdk
Pengenalan blaast platform sdkPengenalan blaast platform sdk
Pengenalan blaast platform sdk
 
Js hacks
Js hacksJs hacks
Js hacks
 
Workshop 1: Good practices in JavaScript
Workshop 1: Good practices in JavaScriptWorkshop 1: Good practices in JavaScript
Workshop 1: Good practices in JavaScript
 
Cross Domain Web
Mashups with JQuery and Google App Engine
Cross Domain Web
Mashups with JQuery and Google App EngineCross Domain Web
Mashups with JQuery and Google App Engine
Cross Domain Web
Mashups with JQuery and Google App Engine
 
Five things for you - Yahoo developer offers
Five things for you - Yahoo developer offersFive things for you - Yahoo developer offers
Five things for you - Yahoo developer offers
 
Chaincode Development 區塊鏈鏈碼開發
Chaincode Development 區塊鏈鏈碼開發Chaincode Development 區塊鏈鏈碼開發
Chaincode Development 區塊鏈鏈碼開發
 
mobl
moblmobl
mobl
 
Angular Workshop_Sarajevo2
Angular Workshop_Sarajevo2Angular Workshop_Sarajevo2
Angular Workshop_Sarajevo2
 
"О некоторых особенностях Objective-C++" Влад Михайленко (Maps.Me)
"О некоторых особенностях Objective-C++" Влад Михайленко (Maps.Me)"О некоторых особенностях Objective-C++" Влад Михайленко (Maps.Me)
"О некоторых особенностях Objective-C++" Влад Михайленко (Maps.Me)
 

More from armitageclaire49

Apply Information System Auditing AssignmentResearch an art.docx
Apply Information System Auditing AssignmentResearch an art.docxApply Information System Auditing AssignmentResearch an art.docx
Apply Information System Auditing AssignmentResearch an art.docx
armitageclaire49
 
Apply information from the Aquifer Case Study to answer the followin.docx
Apply information from the Aquifer Case Study to answer the followin.docxApply information from the Aquifer Case Study to answer the followin.docx
Apply information from the Aquifer Case Study to answer the followin.docx
armitageclaire49
 
Apply Development PlanCreate a 700- to 1,050-word development.docx
Apply Development PlanCreate a 700- to 1,050-word development.docxApply Development PlanCreate a 700- to 1,050-word development.docx
Apply Development PlanCreate a 700- to 1,050-word development.docx
armitageclaire49
 
Applied TodayMedia—tv, movies booksConcept of PrisonerKe.docx
Applied TodayMedia—tv, movies booksConcept of PrisonerKe.docxApplied TodayMedia—tv, movies booksConcept of PrisonerKe.docx
Applied TodayMedia—tv, movies booksConcept of PrisonerKe.docx
armitageclaire49
 
Applied Social PsychologyApplied social psychology is a field .docx
Applied Social PsychologyApplied social psychology is a field .docxApplied Social PsychologyApplied social psychology is a field .docx
Applied Social PsychologyApplied social psychology is a field .docx
armitageclaire49
 
Applied Numerical Methodswith MATLAB® for Engineers and .docx
Applied Numerical Methodswith MATLAB® for Engineers and .docxApplied Numerical Methodswith MATLAB® for Engineers and .docx
Applied Numerical Methodswith MATLAB® for Engineers and .docx
armitageclaire49
 
Applied LearningPsychology is an interesting field of study be.docx
Applied LearningPsychology is an interesting field of study be.docxApplied LearningPsychology is an interesting field of study be.docx
Applied LearningPsychology is an interesting field of study be.docx
armitageclaire49
 
Applied Assignment III – write 5 primary goals and their metrics f.docx
Applied Assignment III – write 5 primary goals and their metrics f.docxApplied Assignment III – write 5 primary goals and their metrics f.docx
Applied Assignment III – write 5 primary goals and their metrics f.docx
armitageclaire49
 
Applied Assignment I – describe the primary business processes, key .docx
Applied Assignment I – describe the primary business processes, key .docxApplied Assignment I – describe the primary business processes, key .docx
Applied Assignment I – describe the primary business processes, key .docx
armitageclaire49
 
Applied Final ProjectThe Cultural OtherResearch the hist.docx
Applied Final ProjectThe Cultural OtherResearch the hist.docxApplied Final ProjectThe Cultural OtherResearch the hist.docx
Applied Final ProjectThe Cultural OtherResearch the hist.docx
armitageclaire49
 
applied sciencesReviewA State-of-the-Art Review of .docx
applied  sciencesReviewA State-of-the-Art Review of .docxapplied  sciencesReviewA State-of-the-Art Review of .docx
applied sciencesReviewA State-of-the-Art Review of .docx
armitageclaire49
 
Applications of Epidemiology – A Case Study The situation at Goo.docx
Applications of Epidemiology – A Case Study The situation at Goo.docxApplications of Epidemiology – A Case Study The situation at Goo.docx
Applications of Epidemiology – A Case Study The situation at Goo.docx
armitageclaire49
 
ApplicationFederal Statutes and the Impact of Legislative Bills.docx
ApplicationFederal Statutes and the Impact of Legislative Bills.docxApplicationFederal Statutes and the Impact of Legislative Bills.docx
ApplicationFederal Statutes and the Impact of Legislative Bills.docx
armitageclaire49
 
ApplicationFederal Statutes and the Impact of Legislative B.docx
ApplicationFederal Statutes and the Impact of Legislative B.docxApplicationFederal Statutes and the Impact of Legislative B.docx
ApplicationFederal Statutes and the Impact of Legislative B.docx
armitageclaire49
 
Application Topics The APPLICATION PROJECT OPTIONS from which yo.docx
Application Topics The APPLICATION PROJECT OPTIONS from which yo.docxApplication Topics The APPLICATION PROJECT OPTIONS from which yo.docx
Application Topics The APPLICATION PROJECT OPTIONS from which yo.docx
armitageclaire49
 
ApplicationDeveloping Your Professional Philosophy of Teaching .docx
ApplicationDeveloping Your Professional Philosophy of Teaching .docxApplicationDeveloping Your Professional Philosophy of Teaching .docx
ApplicationDeveloping Your Professional Philosophy of Teaching .docx
armitageclaire49
 
Application Social ClassIn the Discussion, you addressed how .docx
Application Social ClassIn the Discussion, you addressed how .docxApplication Social ClassIn the Discussion, you addressed how .docx
Application Social ClassIn the Discussion, you addressed how .docx
armitageclaire49
 
Application Role and Value of EvaluationThe United Nations, the.docx
Application Role and Value of EvaluationThe United Nations, the.docxApplication Role and Value of EvaluationThe United Nations, the.docx
Application Role and Value of EvaluationThe United Nations, the.docx
armitageclaire49
 
Application of Nursing Theory to Practice What would _(Pla.docx
Application of Nursing Theory to Practice What would _(Pla.docxApplication of Nursing Theory to Practice What would _(Pla.docx
Application of Nursing Theory to Practice What would _(Pla.docx
armitageclaire49
 
Application Paper #4 1.Please pick 1 or 2 of Gardners Intell.docx
Application Paper #4 1.Please pick 1 or 2 of Gardners  Intell.docxApplication Paper #4 1.Please pick 1 or 2 of Gardners  Intell.docx
Application Paper #4 1.Please pick 1 or 2 of Gardners Intell.docx
armitageclaire49
 

More from armitageclaire49 (20)

Apply Information System Auditing AssignmentResearch an art.docx
Apply Information System Auditing AssignmentResearch an art.docxApply Information System Auditing AssignmentResearch an art.docx
Apply Information System Auditing AssignmentResearch an art.docx
 
Apply information from the Aquifer Case Study to answer the followin.docx
Apply information from the Aquifer Case Study to answer the followin.docxApply information from the Aquifer Case Study to answer the followin.docx
Apply information from the Aquifer Case Study to answer the followin.docx
 
Apply Development PlanCreate a 700- to 1,050-word development.docx
Apply Development PlanCreate a 700- to 1,050-word development.docxApply Development PlanCreate a 700- to 1,050-word development.docx
Apply Development PlanCreate a 700- to 1,050-word development.docx
 
Applied TodayMedia—tv, movies booksConcept of PrisonerKe.docx
Applied TodayMedia—tv, movies booksConcept of PrisonerKe.docxApplied TodayMedia—tv, movies booksConcept of PrisonerKe.docx
Applied TodayMedia—tv, movies booksConcept of PrisonerKe.docx
 
Applied Social PsychologyApplied social psychology is a field .docx
Applied Social PsychologyApplied social psychology is a field .docxApplied Social PsychologyApplied social psychology is a field .docx
Applied Social PsychologyApplied social psychology is a field .docx
 
Applied Numerical Methodswith MATLAB® for Engineers and .docx
Applied Numerical Methodswith MATLAB® for Engineers and .docxApplied Numerical Methodswith MATLAB® for Engineers and .docx
Applied Numerical Methodswith MATLAB® for Engineers and .docx
 
Applied LearningPsychology is an interesting field of study be.docx
Applied LearningPsychology is an interesting field of study be.docxApplied LearningPsychology is an interesting field of study be.docx
Applied LearningPsychology is an interesting field of study be.docx
 
Applied Assignment III – write 5 primary goals and their metrics f.docx
Applied Assignment III – write 5 primary goals and their metrics f.docxApplied Assignment III – write 5 primary goals and their metrics f.docx
Applied Assignment III – write 5 primary goals and their metrics f.docx
 
Applied Assignment I – describe the primary business processes, key .docx
Applied Assignment I – describe the primary business processes, key .docxApplied Assignment I – describe the primary business processes, key .docx
Applied Assignment I – describe the primary business processes, key .docx
 
Applied Final ProjectThe Cultural OtherResearch the hist.docx
Applied Final ProjectThe Cultural OtherResearch the hist.docxApplied Final ProjectThe Cultural OtherResearch the hist.docx
Applied Final ProjectThe Cultural OtherResearch the hist.docx
 
applied sciencesReviewA State-of-the-Art Review of .docx
applied  sciencesReviewA State-of-the-Art Review of .docxapplied  sciencesReviewA State-of-the-Art Review of .docx
applied sciencesReviewA State-of-the-Art Review of .docx
 
Applications of Epidemiology – A Case Study The situation at Goo.docx
Applications of Epidemiology – A Case Study The situation at Goo.docxApplications of Epidemiology – A Case Study The situation at Goo.docx
Applications of Epidemiology – A Case Study The situation at Goo.docx
 
ApplicationFederal Statutes and the Impact of Legislative Bills.docx
ApplicationFederal Statutes and the Impact of Legislative Bills.docxApplicationFederal Statutes and the Impact of Legislative Bills.docx
ApplicationFederal Statutes and the Impact of Legislative Bills.docx
 
ApplicationFederal Statutes and the Impact of Legislative B.docx
ApplicationFederal Statutes and the Impact of Legislative B.docxApplicationFederal Statutes and the Impact of Legislative B.docx
ApplicationFederal Statutes and the Impact of Legislative B.docx
 
Application Topics The APPLICATION PROJECT OPTIONS from which yo.docx
Application Topics The APPLICATION PROJECT OPTIONS from which yo.docxApplication Topics The APPLICATION PROJECT OPTIONS from which yo.docx
Application Topics The APPLICATION PROJECT OPTIONS from which yo.docx
 
ApplicationDeveloping Your Professional Philosophy of Teaching .docx
ApplicationDeveloping Your Professional Philosophy of Teaching .docxApplicationDeveloping Your Professional Philosophy of Teaching .docx
ApplicationDeveloping Your Professional Philosophy of Teaching .docx
 
Application Social ClassIn the Discussion, you addressed how .docx
Application Social ClassIn the Discussion, you addressed how .docxApplication Social ClassIn the Discussion, you addressed how .docx
Application Social ClassIn the Discussion, you addressed how .docx
 
Application Role and Value of EvaluationThe United Nations, the.docx
Application Role and Value of EvaluationThe United Nations, the.docxApplication Role and Value of EvaluationThe United Nations, the.docx
Application Role and Value of EvaluationThe United Nations, the.docx
 
Application of Nursing Theory to Practice What would _(Pla.docx
Application of Nursing Theory to Practice What would _(Pla.docxApplication of Nursing Theory to Practice What would _(Pla.docx
Application of Nursing Theory to Practice What would _(Pla.docx
 
Application Paper #4 1.Please pick 1 or 2 of Gardners Intell.docx
Application Paper #4 1.Please pick 1 or 2 of Gardners  Intell.docxApplication Paper #4 1.Please pick 1 or 2 of Gardners  Intell.docx
Application Paper #4 1.Please pick 1 or 2 of Gardners Intell.docx
 

Recently uploaded

Mule event processing models | MuleSoft Mysore Meetup #47
Mule event processing models | MuleSoft Mysore Meetup #47Mule event processing models | MuleSoft Mysore Meetup #47
Mule event processing models | MuleSoft Mysore Meetup #47
MysoreMuleSoftMeetup
 
RESULTS OF THE EVALUATION QUESTIONNAIRE.pptx
RESULTS OF THE EVALUATION QUESTIONNAIRE.pptxRESULTS OF THE EVALUATION QUESTIONNAIRE.pptx
RESULTS OF THE EVALUATION QUESTIONNAIRE.pptx
zuzanka
 
math operations ued in python and all used
math operations ued in python and all usedmath operations ued in python and all used
math operations ued in python and all used
ssuser13ffe4
 
Stack Memory Organization of 8086 Microprocessor
Stack Memory Organization of 8086 MicroprocessorStack Memory Organization of 8086 Microprocessor
Stack Memory Organization of 8086 Microprocessor
JomonJoseph58
 
B. Ed Syllabus for babasaheb ambedkar education university.pdf
B. Ed Syllabus for babasaheb ambedkar education university.pdfB. Ed Syllabus for babasaheb ambedkar education university.pdf
B. Ed Syllabus for babasaheb ambedkar education university.pdf
BoudhayanBhattachari
 
مصحف القراءات العشر أعد أحرف الخلاف سمير بسيوني.pdf
مصحف القراءات العشر   أعد أحرف الخلاف سمير بسيوني.pdfمصحف القراءات العشر   أعد أحرف الخلاف سمير بسيوني.pdf
مصحف القراءات العشر أعد أحرف الخلاف سمير بسيوني.pdf
سمير بسيوني
 
Benner "Expanding Pathways to Publishing Careers"
Benner "Expanding Pathways to Publishing Careers"Benner "Expanding Pathways to Publishing Careers"
Benner "Expanding Pathways to Publishing Careers"
National Information Standards Organization (NISO)
 
Bonku-Babus-Friend by Sathyajith Ray (9)
Bonku-Babus-Friend by Sathyajith Ray  (9)Bonku-Babus-Friend by Sathyajith Ray  (9)
Bonku-Babus-Friend by Sathyajith Ray (9)
nitinpv4ai
 
Level 3 NCEA - NZ: A Nation In the Making 1872 - 1900 SML.ppt
Level 3 NCEA - NZ: A  Nation In the Making 1872 - 1900 SML.pptLevel 3 NCEA - NZ: A  Nation In the Making 1872 - 1900 SML.ppt
Level 3 NCEA - NZ: A Nation In the Making 1872 - 1900 SML.ppt
Henry Hollis
 
BBR 2024 Summer Sessions Interview Training
BBR  2024 Summer Sessions Interview TrainingBBR  2024 Summer Sessions Interview Training
BBR 2024 Summer Sessions Interview Training
Katrina Pritchard
 
Présentationvvvvvvvvvvvvvvvvvvvvvvvvvvvv2.pptx
Présentationvvvvvvvvvvvvvvvvvvvvvvvvvvvv2.pptxPrésentationvvvvvvvvvvvvvvvvvvvvvvvvvvvv2.pptx
Présentationvvvvvvvvvvvvvvvvvvvvvvvvvvvv2.pptx
siemaillard
 
RHEOLOGY Physical pharmaceutics-II notes for B.pharm 4th sem students
RHEOLOGY Physical pharmaceutics-II notes for B.pharm 4th sem studentsRHEOLOGY Physical pharmaceutics-II notes for B.pharm 4th sem students
RHEOLOGY Physical pharmaceutics-II notes for B.pharm 4th sem students
Himanshu Rai
 
How to Make a Field Mandatory in Odoo 17
How to Make a Field Mandatory in Odoo 17How to Make a Field Mandatory in Odoo 17
How to Make a Field Mandatory in Odoo 17
Celine George
 
Pharmaceutics Pharmaceuticals best of brub
Pharmaceutics Pharmaceuticals best of brubPharmaceutics Pharmaceuticals best of brub
Pharmaceutics Pharmaceuticals best of brub
danielkiash986
 
BÀI TẬP BỔ TRỢ TIẾNG ANH LỚP 9 CẢ NĂM - GLOBAL SUCCESS - NĂM HỌC 2024-2025 - ...
BÀI TẬP BỔ TRỢ TIẾNG ANH LỚP 9 CẢ NĂM - GLOBAL SUCCESS - NĂM HỌC 2024-2025 - ...BÀI TẬP BỔ TRỢ TIẾNG ANH LỚP 9 CẢ NĂM - GLOBAL SUCCESS - NĂM HỌC 2024-2025 - ...
BÀI TẬP BỔ TRỢ TIẾNG ANH LỚP 9 CẢ NĂM - GLOBAL SUCCESS - NĂM HỌC 2024-2025 - ...
Nguyen Thanh Tu Collection
 
BÀI TẬP BỔ TRỢ TIẾNG ANH 8 CẢ NĂM - GLOBAL SUCCESS - NĂM HỌC 2023-2024 (CÓ FI...
BÀI TẬP BỔ TRỢ TIẾNG ANH 8 CẢ NĂM - GLOBAL SUCCESS - NĂM HỌC 2023-2024 (CÓ FI...BÀI TẬP BỔ TRỢ TIẾNG ANH 8 CẢ NĂM - GLOBAL SUCCESS - NĂM HỌC 2023-2024 (CÓ FI...
BÀI TẬP BỔ TRỢ TIẾNG ANH 8 CẢ NĂM - GLOBAL SUCCESS - NĂM HỌC 2023-2024 (CÓ FI...
Nguyen Thanh Tu Collection
 
Film vocab for eal 3 students: Australia the movie
Film vocab for eal 3 students: Australia the movieFilm vocab for eal 3 students: Australia the movie
Film vocab for eal 3 students: Australia the movie
Nicholas Montgomery
 
C1 Rubenstein AP HuG xxxxxxxxxxxxxx.pptx
C1 Rubenstein AP HuG xxxxxxxxxxxxxx.pptxC1 Rubenstein AP HuG xxxxxxxxxxxxxx.pptx
C1 Rubenstein AP HuG xxxxxxxxxxxxxx.pptx
mulvey2
 
writing about opinions about Australia the movie
writing about opinions about Australia the moviewriting about opinions about Australia the movie
writing about opinions about Australia the movie
Nicholas Montgomery
 
NEWSPAPERS - QUESTION 1 - REVISION POWERPOINT.pptx
NEWSPAPERS - QUESTION 1 - REVISION POWERPOINT.pptxNEWSPAPERS - QUESTION 1 - REVISION POWERPOINT.pptx
NEWSPAPERS - QUESTION 1 - REVISION POWERPOINT.pptx
iammrhaywood
 

Recently uploaded (20)

Mule event processing models | MuleSoft Mysore Meetup #47
Mule event processing models | MuleSoft Mysore Meetup #47Mule event processing models | MuleSoft Mysore Meetup #47
Mule event processing models | MuleSoft Mysore Meetup #47
 
RESULTS OF THE EVALUATION QUESTIONNAIRE.pptx
RESULTS OF THE EVALUATION QUESTIONNAIRE.pptxRESULTS OF THE EVALUATION QUESTIONNAIRE.pptx
RESULTS OF THE EVALUATION QUESTIONNAIRE.pptx
 
math operations ued in python and all used
math operations ued in python and all usedmath operations ued in python and all used
math operations ued in python and all used
 
Stack Memory Organization of 8086 Microprocessor
Stack Memory Organization of 8086 MicroprocessorStack Memory Organization of 8086 Microprocessor
Stack Memory Organization of 8086 Microprocessor
 
B. Ed Syllabus for babasaheb ambedkar education university.pdf
B. Ed Syllabus for babasaheb ambedkar education university.pdfB. Ed Syllabus for babasaheb ambedkar education university.pdf
B. Ed Syllabus for babasaheb ambedkar education university.pdf
 
مصحف القراءات العشر أعد أحرف الخلاف سمير بسيوني.pdf
مصحف القراءات العشر   أعد أحرف الخلاف سمير بسيوني.pdfمصحف القراءات العشر   أعد أحرف الخلاف سمير بسيوني.pdf
مصحف القراءات العشر أعد أحرف الخلاف سمير بسيوني.pdf
 
Benner "Expanding Pathways to Publishing Careers"
Benner "Expanding Pathways to Publishing Careers"Benner "Expanding Pathways to Publishing Careers"
Benner "Expanding Pathways to Publishing Careers"
 
Bonku-Babus-Friend by Sathyajith Ray (9)
Bonku-Babus-Friend by Sathyajith Ray  (9)Bonku-Babus-Friend by Sathyajith Ray  (9)
Bonku-Babus-Friend by Sathyajith Ray (9)
 
Level 3 NCEA - NZ: A Nation In the Making 1872 - 1900 SML.ppt
Level 3 NCEA - NZ: A  Nation In the Making 1872 - 1900 SML.pptLevel 3 NCEA - NZ: A  Nation In the Making 1872 - 1900 SML.ppt
Level 3 NCEA - NZ: A Nation In the Making 1872 - 1900 SML.ppt
 
BBR 2024 Summer Sessions Interview Training
BBR  2024 Summer Sessions Interview TrainingBBR  2024 Summer Sessions Interview Training
BBR 2024 Summer Sessions Interview Training
 
Présentationvvvvvvvvvvvvvvvvvvvvvvvvvvvv2.pptx
Présentationvvvvvvvvvvvvvvvvvvvvvvvvvvvv2.pptxPrésentationvvvvvvvvvvvvvvvvvvvvvvvvvvvv2.pptx
Présentationvvvvvvvvvvvvvvvvvvvvvvvvvvvv2.pptx
 
RHEOLOGY Physical pharmaceutics-II notes for B.pharm 4th sem students
RHEOLOGY Physical pharmaceutics-II notes for B.pharm 4th sem studentsRHEOLOGY Physical pharmaceutics-II notes for B.pharm 4th sem students
RHEOLOGY Physical pharmaceutics-II notes for B.pharm 4th sem students
 
How to Make a Field Mandatory in Odoo 17
How to Make a Field Mandatory in Odoo 17How to Make a Field Mandatory in Odoo 17
How to Make a Field Mandatory in Odoo 17
 
Pharmaceutics Pharmaceuticals best of brub
Pharmaceutics Pharmaceuticals best of brubPharmaceutics Pharmaceuticals best of brub
Pharmaceutics Pharmaceuticals best of brub
 
BÀI TẬP BỔ TRỢ TIẾNG ANH LỚP 9 CẢ NĂM - GLOBAL SUCCESS - NĂM HỌC 2024-2025 - ...
BÀI TẬP BỔ TRỢ TIẾNG ANH LỚP 9 CẢ NĂM - GLOBAL SUCCESS - NĂM HỌC 2024-2025 - ...BÀI TẬP BỔ TRỢ TIẾNG ANH LỚP 9 CẢ NĂM - GLOBAL SUCCESS - NĂM HỌC 2024-2025 - ...
BÀI TẬP BỔ TRỢ TIẾNG ANH LỚP 9 CẢ NĂM - GLOBAL SUCCESS - NĂM HỌC 2024-2025 - ...
 
BÀI TẬP BỔ TRỢ TIẾNG ANH 8 CẢ NĂM - GLOBAL SUCCESS - NĂM HỌC 2023-2024 (CÓ FI...
BÀI TẬP BỔ TRỢ TIẾNG ANH 8 CẢ NĂM - GLOBAL SUCCESS - NĂM HỌC 2023-2024 (CÓ FI...BÀI TẬP BỔ TRỢ TIẾNG ANH 8 CẢ NĂM - GLOBAL SUCCESS - NĂM HỌC 2023-2024 (CÓ FI...
BÀI TẬP BỔ TRỢ TIẾNG ANH 8 CẢ NĂM - GLOBAL SUCCESS - NĂM HỌC 2023-2024 (CÓ FI...
 
Film vocab for eal 3 students: Australia the movie
Film vocab for eal 3 students: Australia the movieFilm vocab for eal 3 students: Australia the movie
Film vocab for eal 3 students: Australia the movie
 
C1 Rubenstein AP HuG xxxxxxxxxxxxxx.pptx
C1 Rubenstein AP HuG xxxxxxxxxxxxxx.pptxC1 Rubenstein AP HuG xxxxxxxxxxxxxx.pptx
C1 Rubenstein AP HuG xxxxxxxxxxxxxx.pptx
 
writing about opinions about Australia the movie
writing about opinions about Australia the moviewriting about opinions about Australia the movie
writing about opinions about Australia the movie
 
NEWSPAPERS - QUESTION 1 - REVISION POWERPOINT.pptx
NEWSPAPERS - QUESTION 1 - REVISION POWERPOINT.pptxNEWSPAPERS - QUESTION 1 - REVISION POWERPOINT.pptx
NEWSPAPERS - QUESTION 1 - REVISION POWERPOINT.pptx
 

app.js.docx

  • 1. app.js /**************************************************** *************************** * Copyright (c) 2014 IBM Corp. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * and Eclipse Distribution License v1.0 which accompany this distribution. * * The Eclipse Public License is available at * http://www.eclipse.org/legal/epl-v10.html * and the Eclipse Distribution License is available at * http://www.eclipse.org/org/documents/edl-v10.php. * * Contributors: * Bryan Boyd - Initial implementation ***************************************************** **************************/ var parseString = require('xml2js').parseString; var vincenty = require('node-vincenty'); var fs = require('fs'); var argv = require('optimist').argv; var mqtt = require('mqtt'); var http = require('http'); var settings = require('./config/settings'); var appInfo = JSON.parse(process.env.VCAP_APPLICATION || "{}"); var appHost = appInfo.host || "localhost";
  • 2. console.log(argv); var deviceIndex = (appInfo && appInfo.instance_index) ? appInfo.instance_index : 0; var deviceId = settings.iot_deviceSet[deviceIndex].deviceId; var token = settings.iot_deviceSet[deviceIndex].token; var iot_server = settings.iot_deviceOrg + ".messaging.internetofthings.ibmcloud.com"; var iot_port = 1883; var iot_username = "use-token-auth"; var iot_password = token; var iot_clientid = "d:" + settings.iot_deviceOrg + ":" + settings.iot_deviceType + ":" + deviceId console.log(iot_server, iot_clientid, iot_username, iot_password); //var client = mqtt.createClient(1883, iot_server, { clientId: iot_clientid, username: iot_username, password: iot_password }); var options1 = { port: 1883, host: iot_server, clientId: iot_clientid, username: iot_username, password: iot_password, protocolId: 'MQIsdp', protocolVersion: 3 }; var client = mqtt.connect(options1); console.log(JSON.stringify(process.env)); var VEHICLE_COUNT = (argv.count ? argv.count :
  • 3. (process.env.VEHICLE_COUNT || 1)); var TELEMETRY_RATE = (argv.rate ? argv.rate : (process.env.TELEMETRY_RATE || 2)); console.log("Simulating " + VEHICLE_COUNT + " vehicles"); // subscribe var propertyTopic = "iot-2/cmd/setProperty/fmt/json"; // publish var telemetryTopic = "iot-2/evt/telemetry/fmt/json"; ////////////////// // MAP // ////////////////// var num_nodes = 0; var num_edges = 0; var map = { nodes: {}, edges: {} }; function Map(abbr, name, filename) { this.abbr = abbr; this.name = name; this.nodeCount = 0; this.edgeCount = 0; this.nodes = {}; this.edges = {}; this.loadFromFile(filename); } Map.prototype.loadFromFile = function(filename) { fs.readFile(filename, (function(map) { return function(err, data) {
  • 4. if (err) throw err; parseString(data, function(err, result) { console.log("parseString"); if (err) throw err; map.createMapFromJSON(result); setTimeout(mapLoaded, 5000); }); } })(this)); } Map.prototype.createMapFromJSON = function(json) { console.log("createMapFromJSON"); for (var i in json.osm.node) { var n = json.osm.node[i]; this.nodes[n.$.id] = { id: n.$.id, lon: parseFloat(n.$.lon), lat: parseFloat(n.$.lat), edges: Array() } this.nodeCount++; if (this.nodeCount % 1000 == 0) { console.log("nodes: " + this.nodeCount); } } for (var i in json.osm.way) { var w = json.osm.way[i]; var wId = w.$.id; var tags = {}; for (var j in w.tag) { tags[w.tag[j].$.k] = w.tag[j].$.v; } var last_ref = null; for (var j in w.nd) { var ref = w.nd[j].$.ref; // node id
  • 5. if (last_ref) { //console.log(this.nodes[last_ref], this.nodes[ref]); var res = vincenty.distVincenty(this.nodes[last_ref].lat, this.nodes[last_ref].lon, this.nodes[ref].lat, this.nodes[ref].lon); //console.log(res); var meters = res.distance; var bearing = res.initialBearing; if (tags.oneway && tags.oneway == "yes") { var edge = { id: wId + "-" + last_ref + "_" + ref, type: tags.highway, a: last_ref, b: ref, heading: bearing, dist: meters }; this.edges[edge.id] = edge; this.nodes[last_ref].edges.push(edge); this.edgeCount++; } else { var edgeA = { id: wId + "-" + last_ref + "_" + ref, type: tags.highway, a: last_ref, b: ref, heading: bearing, dist: meters } this.edges[edgeA.id] = edgeA; this.nodes[last_ref].edges.push(edgeA);
  • 6. this.edgeCount++; var edgeB = { id: wId + "-" + ref + "_" + last_ref, type: tags.highway, a: ref, b: last_ref, heading: (bearing < 180 ? bearing + 180 : bearing - 180), dist: meters } this.edges[edgeB.id] = edgeB; this.nodes[ref].edges.push(edgeB); this.edgeCount++; } } last_ref = ref; } if (this.edgeCount % 1000 == 0) { console.log("edges: " + this.edgeCount); } } var del = 0; for (var i in this.nodes) { var n = this.nodes[i]; var count = 0; for (var j in n.edges) { if (this.nodes[n.edges[j].b]) { count++; } } if (count == 0) { delete this.nodes[i]; del++; this.nodeCount--;
  • 7. } } //console.log("deleted " + del + " nodes"); //this.publishData(); this.print(); } Map.prototype.print = function() { /* fs.writeFile("map_nodes.txt", JSON.stringify(this.nodes, null, 4), function(err) { if(err) { console.log(err); } else { console.log("nodes saved to map_nodes.txt"); } }); fs.writeFile("map_edges.txt", JSON.stringify(this.edges, null, 4), function(err) { if(err) { console.log(err); } else { console.log("edges saved to map_edges.txt"); } }); */ console.log("loaded map!"); console.log("num_edges = " + this.edgeCount); console.log("num_nodes = " + this.nodeCount); } Map.prototype.publishData = function() { //var topic = topicPrefix + "map/"+this.abbr; var payload = JSON.stringify({ name: this.name, abbr: this.abbr,
  • 8. nodeCount: this.nodeCount, edgeCount: this.edgeCount, nodes: this.nodes, edges: this.edges }); var b64 = new Buffer(payload).toString('base64'); //console.log("publish : " + topic + " : " + b64); console.log(b64); console.log("length = " + b64.length); //client.publish(topicPrefix + "map/"+ this.abbr, b64, { qos: 1, retain: true }); } var austin_map = new Map("austin", "Austin - Downtown", "maps/austin_downtown-clean.osm"); function Vehicle(id, suffix) { this.id = id; this.suffix = suffix; this.name = "Car " + id + suffix; this.map = austin_map; this.speed = null; this.state = "normal"; this.description = "I am a connected car."; this.type = "car"; this.customProps = { turnSignal: "OFF" }, this.geo = { lon: 0, lat: 0 } this.currentEdge = null; this.perc = 0; // % of edge travelled
  • 9. this.lastUpdateTime = null; this.setSpeed(30); this.frame = 0; } Vehicle.prototype.drive = function() { this.frame++; if (!this.currentEdge) { this.setStartingEdge(); } else { //console.log("update " + this.name); this.update(); } } Vehicle.prototype.update = function() { var delta = (new Date()).getTime() - this.lastUpdateTime; //console.log("delta = " + delta); // move car 'delta' milliseconds // speed (m/s) = speed (km/hr) * 3600 / 1000 // dist (m) = speed (m/s) * (delta / 1000) var dist_to_move = (this.speed * (1000 / 3600)) * (delta / 1000); //console.log("updating vehicle: distance remaining = " + dist_to_move); while (dist_to_move > 0) { var dist_remaining_on_edge = (1.0 - this.perc) * this.currentEdge.dist; if (dist_to_move > dist_remaining_on_edge) { // finished an edge! get a new edge and keep going //console.log("finished an edge! distance remaining = " + dist_to_move); dist_to_move -= dist_remaining_on_edge;
  • 10. this.setNextEdge(); } else { // didn't finish an edge, update perc this.perc += (dist_to_move / this.currentEdge.dist); dist_to_move = 0; //console.log("didn't finish, perc = " + this.perc); } } this.updatePosition(); this.lastUpdateTime = (new Date()).getTime(); } Vehicle.prototype.getPublishPayload = function() { return { id: this.id + this.suffix, name: this.name, lng: this.geo.lon.toString(), lat: this.geo.lat.toString(), heading: this.currentEdge.heading, speed: this.speed, state: this.state, description: this.description, type: this.type, customProps: this.customProps }; } Vehicle.prototype.setSpeed = function(val) { // speed = km/hr if (val >= 0 && val <= 120) { console.log("setting speed to " + val); this.speed = val; }
  • 11. } Vehicle.prototype.setTurnSignal = function(val) { if (val == "LEFT" || val == "NONE" || val == "RIGHT" || val == "OFF") { this.customProps.turnSignal = val; } } Vehicle.prototype.setStartingEdge = function() { var keys = []; for (var i in this.map.edges) { keys.push(i); } this.currentEdge = this.map.edges[keys[Math.floor(Math.random() * keys.length)]]; this.perc = 0; this.lastUpdateTime = (new Date()).getTime(); } Vehicle.prototype.updatePosition = function() { var a = this.map.nodes[this.currentEdge.a]; var b = this.map.nodes[this.currentEdge.b]; if (a && b) { this.geo.lon = a.lon + this.perc * (b.lon - a.lon); this.geo.lat = a.lat + this.perc * (b.lat - a.lat); } else { //console.log("ERROR", a, b); this.setStartingEdge(); } //console.log("updatePosition: " + this.geo.lon + ", " + this.geo.lat); } Vehicle.prototype.setNextEdge = function() {
  • 12. //console.log(" setNextEdge"); var n = this.map.nodes[this.currentEdge.b]; if (!n) { // no valid next edge //console.log("RESPAWNING"); this.setStartingEdge(); return; } var edge = null; var reverseCount = 0; var leftTurnEdge = null, leftTurnAngle = 0; var rightTurnEdge = null, rightTurnAngle = 0; var straightEdge = null, straightAngle = 180; var a1 = this.currentEdge.heading; for (var i in n.edges) { var a2 = n.edges[i].heading; var left_diff = (a1-a2+360)%360; var right_diff = (a2-a1+360)%360; if (left_diff > leftTurnAngle && left_diff < 160) { leftTurnEdge = n.edges[i]; leftTurnAngle = left_diff; } if (right_diff > rightTurnAngle && right_diff < 160) { rightTurnEdge = n.edges[i]; rightTurnAngle = right_diff; } var smallest = Math.min(left_diff, right_diff); if (smallest < straightAngle) { straightEdge = n.edges[i]; straightAngle = smallest; } console.log("possible edge: " + n.edges[i].id + " | heading: " + n.edges[i].heading + " | left_diff: " + left_diff + " | right_diff: " + right_diff); }
  • 13. console.log("-- LEFT edge: " + (leftTurnEdge ? leftTurnEdge.id : "(nil)") + " | angle: " + leftTurnAngle); console.log("-- RIGHT edge: " + (rightTurnEdge ? rightTurnEdge.id : "(nil)") + " | angle: " + rightTurnAngle); console.log("-- STRAIGHT edge: " + (straightEdge ? straightEdge.id : "(nil)") + " | angle: " + straightAngle); while (!edge) { try { if (this.customProps.turnSignal && this.customProps.turnSignal == "LEFT" && leftTurnEdge) { console.log("trying LEFT turn: " + leftTurnEdge.id); edge = leftTurnEdge; } else if (this.customProps.turnSignal && this.customProps.turnSignal == "RIGHT" && rightTurnEdge) { console.log("trying RIGHT turn: " + rightTurnEdge.id); edge = rightTurnEdge; } else if (this.customProps.turnSignal && this.customProps.turnSignal == "STRAIGHT" && straightEdge) { console.log("trying STRAIGHT: " + straightEdge.id); edge = straightEdge; } else { console.log("trying RANDOM turn"); var idx = Math.floor(Math.random() * n.edges.length); edge = n.edges[idx]; } // check to make sure we didn't reverse direction if there are multiple edges console.log("checking edge: " + this.currentEdge.a + " " + edge.b); if (this.currentEdge.a == edge.b) {
  • 14. if (n.edges.length == 1) { //console.log("End of the line! Respawning..."); this.setStartingEdge(); return; } else { //console.log("edge won't work, it's a reverse!"); reverseCount++; if (reverseCount > 10) { this.setStartingEdge(); return; } else { edge = null; } } } } catch (e) { console.log(e, "ERROR", n, this.currentEdge); this.setStartingEdge(); return; } } //console.log("new edge = ", edge); this.perc = 0; this.currentEdge = edge; } var vehicles = Array(); for (var i = 1; i <= VEHICLE_COUNT; i++) { var vid = deviceId; var suffix = ""; if (VEHICLE_COUNT > 1) { suffix = "-" + i; } vehicles.push(new Vehicle(vid, suffix)); }
  • 15. var bMapLoaded = false; function drive() { for (var i in vehicles) { vehicles[i].drive(); } } function subscribeToProperties() { client.subscribe(propertyTopic); console.log("subscribed to: " + propertyTopic); client.on('message', function(topic, message) { console.log("message recv: " + topic + " = " + message); try { //var id = topic.split("/")[3]; var data = JSON.parse(message); var id = data.id; if (!id) { id = deviceId; } console.log("setProperty(id="+id+"): " + data.property + " = " + data.value); var v = getVehicle(id); var prop = data.property; var val = data.value; if (v) { if (prop == "lng" || prop == "lat" || prop == "heading" || prop == "id") { return; } switch (prop) { case "speed": v.setSpeed(val); break; case "state": v.state = val; break; case "description": v.description = val; break; case "type": v.type = val; break; default: if (val == "") {
  • 16. if (v.customProps[prop]) { delete v.customProps[prop]; } } else { v.customProps[prop] = val; } } } } catch (e) { console.error(e); } }); } function publishVehicleData() { var payload = []; for (var i in vehicles) { payload.push(vehicles[i].getPublishPayload()); } //console.log("publishing data: " + telemetryTopic + " | " + JSON.stringify(payload)); if (payload.length == 1) { client.publish(telemetryTopic, JSON.stringify(payload[0])); } else { client.publish(telemetryTopic, JSON.stringify(payload)); } } function getVehicle(id) { for (var i in vehicles) { if ((vehicles[i].id + vehicles[i].suffix) == id) { return vehicles[i]; } } return null; }
  • 17. function mapLoaded() { subscribeToProperties(); setInterval(function() { drive(); publishVehicleData(); }, 1000 / TELEMETRY_RATE); } // setup middleware var express = require('express'), https = require('https'), path = require('path'); var app = express(); var bodyParser = require('body-parser'); var methodOverride = require('method-override') // all environments app.set('port', process.env.PORT || 3000); app.use(express.favicon()); app.use(express.logger('dev')); app.use(bodyParser.json()); app.use(methodOverride()); app.use(express.urlencoded()); app.use(app.router); app.use(express.static(path.join(__dirname, 'public'))); // development only if ('development' === app.get('env')) { app.use(express.errorHandler()); } var geo_props = null;
  • 18. //parse VCAP_SERVICES if running in Bluemix if (process.env.VCAP_SERVICES) { var env = JSON.parse(process.env.VCAP_SERVICES); console.log(env); //find the Streams Geo service if (env["Geospatial Analytics"]) { geo_props = env['Geospatial Analytics'][0]['credentials']; console.log(geo_props); } else { console.log('You must bind the Streams Geo service to this application'); } } if (geo_props) { // sample vehicle topic/payload: // {"id":"G-13","name":"Car G-13","lng":- 122.41950721920685,"lat":37.76330689770606,"heading":177.0 6799545408498,"speed":30,"state":"normal","description":"I am a connected car.","type":"car","customProps":{"customProp":"customValue" }} var inputClientId = "a:"+settings.iot_deviceOrg + ":geoInput" + Math.floor(Math.random() * 1000); var notifyClientId = "a:"+settings.iot_deviceOrg + ":geoNotify" + Math.floor(Math.random() * 1000); var apis = [ {
  • 19. name: "start", path: geo_props.start_path, method: "PUT", json: { "mqtt_client_id_input" : inputClientId, "mqtt_client_id_notify" : notifyClientId, "mqtt_uid" : settings.iot_apiKey, "mqtt_pw" : settings.iot_apiToken, "mqtt_uri" : settings.iot_deviceOrg + ".messaging.internetofthings.ibmcloud.com:1883", "mqtt_input_topics" : settings.inputTopic, "mqtt_notify_topic" : settings.notifyTopic, "device_id_attr_name" : "id", "latitude_attr_name" : "lat", "longitude_attr_name" : "lng" } }, { name: "stop", path: geo_props.stop_path, method: "PUT", json: null }, { name: "addRegion", path: geo_props.add_region_path, method: "PUT", json: { // sample JSON for adding a region "regions" : [ { "region_type": "custom", "name": "custom_poly", "notifyOnExit": "true", "polygon": [ {"latitude": "30.27830", "longitude": "-97.74316"},
  • 20. {"latitude": "30.27617", "longitude": "-97.73573"}, {"latitude": "30.26676", "longitude": "-97.73917"}, {"latitude": "30.26852", "longitude": "-97.74560"} // an edge is drawn between last and first points to close the poly ] } ] } }, { name: "removeRegion", path: geo_props.remove_region_path, method: "PUT", json: { // sample JSON for removing the sample region "region_type": "custom", "region_name": "custom_poly" } }, { name: "restart", path: geo_props.restart_path, method: "PUT", json: null }, { name: "status", path: geo_props.status_path, method: "GET", json: null }, ]
  • 21. // build routes for (var i in apis) { var route = "/GeospatialService_"+apis[i].name; console.log("Creating route: " + route); app.get(route, (function(api) { return function(request, response) { var route = "/GeospatialService_"+api.name; console.log("About to call " + route); // prepare options var options = { host: geo_props.geo_host, port: geo_props.geo_port, path: api.path, method: api.method, headers: { 'Authorization' : ('Basic ' + new Buffer(geo_props.userid + ':' + geo_props.password).toString('base64')) } }; // start by loading sample JSON var bodyJson = api.json; // if we pass in query parameters, overwrite the sample JSON with this information if (request.query && Object.keys(request.query).length > 0) { console.log("BODY: ", request.query); bodyJson = request.query;
  • 22. } else { console.log("NO BODY"); } if (bodyJson) { options.headers['Content-Type'] = 'application/json'; options.headers['Content-Length'] = Buffer.byteLength(JSON.stringify(bodyJson), 'utf8'); } console.log('Options prepared:', options); console.log('Do the GeospatialService_' + api.name + ' call'); // do the PUT call var reqPut = https.request(options, function(res) { // uncomment it for header details console.log("headers: ", res.headers); console.log("statusCode: ", res.statusCode); var responseData = ''; res.on('data', function(chunk) { responseData += chunk.toString(); }); res.on('end', function() { try { console.log(route + ' response:n'); console.log(responseData); console.log("n" + route + ' completed');
  • 23. console.log("statusCode: ", res.statusCode); var result = JSON.parse(responseData); console.log("result:n", result); if (res.statusCode != 200) { response.send(res.statusCode, "<h1>"+route+" failed with code: "+res.statusCode+"</h1>"); } else { if (route == "/GeospatialService_status") { response.send(res.statusCode, result); } else { response.send(res.statusCode, "<h1>"+route+" succeeded!</h1><pre>" + JSON.stringify(result, null, 4) + "</pre>"); } } } catch (e) { console.error(e); response.send(500, { error: "parse error: " + route }); } }); if (res.statusCode != 200) { runError = 1; } }); if (bodyJson) { // write the json data console.log('Writing json:n', JSON.stringify(bodyJson, null, 4)); reqPut.write(JSON.stringify(bodyJson));
  • 24. } reqPut.end(); reqPut.on('error', function(e) { console.error(e); }); } })(apis[i])); } } app.get("/credentials", function(request, response) { response.send(200, settings); }); http.createServer(app).listen(app.get('port'), function(){ console.log('Express server listening on port ' + app.get('port')); }); config/settings.js /**************************************************** *************************** * Copyright (c) 2014 IBM Corp. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * and Eclipse Distribution License v1.0 which accompany this distribution. * * The Eclipse Public License is available at * http://www.eclipse.org/legal/epl-v10.html * and the Eclipse Distribution License is available at * http://www.eclipse.org/org/documents/edl-v10.php.
  • 25. * * Contributors: * Bryan Boyd - Initial implementation ***************************************************** **************************/ var config = { iot_deviceType: "Vehicle", // replace with your deviceType iot_deviceOrg: "lzfew7", // replace with your IoT Foundation organization iot_deviceSet: [ // replace with your registered device(s) { deviceId: "Vehicle1", token: "qaz123WSX" }, { deviceId: "Vehicle2", token: "wsx123QAZ" }, { deviceId: "Vehicle3", token: "edc123WSX" } ], iot_apiKey: "a-lzfew7-rdy0ukhyjs", // replace with the key for a generated API token iot_apiToken: "2IJ3YkURaos!Hj&RH)", // replace with the generated API token // these topics will be used by Geospatial Analytics notifyTopic: "iot- 2/type/api/id/geospatial/cmd/geoAlert/fmt/json", inputTopic: "iot- 2/type/Vehicle/id/+/evt/telemetry/fmt/json", }; try { module.exports = config; } catch (e) { window.config = config; } docs/add_overlay1.png
  • 27. docs/node_red1_3.png docs/node_red2_1.png docs/node_red2_2.png docs/node_red2_3.png docs/node_red2_4.png docs/node_red3_1.png docs/node_red3_2.png docs/node_red4_1.png docs/node_red4_2.png docs/set_property1.png docs/set_property2.png docs/vehicle_count1.png docs/vehicle_count2.png LICENSE Eclipse Public License - v 1.0 THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
  • 28. 1. DEFINITIONS "Contribution" means: a) in the case of the initial Contributor, the initial code and documentation distributed under this Agreement, and b) in the case of each subsequent Contributor: i) changes to the Program, and ii) additions to the Program; where such changes and/or additions to the Program originate from and are distributed by that particular Contributor. A Contribution 'originates' from a Contributor if it was added to the Program by such Contributor itself or anyone acting on such Contributor's behalf. Contributions do not include additions to the Program which: (i) are separate modules of software distributed in conjunction with the Program under their own license agreement, and (ii) are not derivative works of the Program. "Contributor" means any person or entity that distributes the Program. "Licensed Patents" mean patent claims licensable by a Contributor which are necessarily infringed by the use or sale of its Contribution alone or when combined with the Program.
  • 29. "Program" means the Contributions distributed in accordance with this Agreement. "Recipient" means anyone who receives the Program under this Agreement, including all Contributors. 2. GRANT OF RIGHTS a) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, distribute and sublicense the Contribution of such Contributor, if any, and such derivative works, in source code and object code form. b) Subject to the terms of this Agreement, each Contributor hereby grants Recipient a non-exclusive, worldwide, royalty-free patent license under Licensed Patents to make, use, sell, offer to sell, import and otherwise transfer the Contribution of such Contributor, if any, in source code and object code form. This patent license shall apply to the combination of the Contribution and the Program if, at the time the Contribution is added by the Contributor, such addition of the Contribution causes such combination to be covered by the Licensed Patents. The patent license shall not apply to any other combinations which include the
  • 30. Contribution. No hardware per se is licensed hereunder. c) Recipient understands that although each Contributor grants the licenses to its Contributions set forth herein, no assurances are provided by any Contributor that the Program does not infringe the patent or other intellectual property rights of any other entity. Each Contributor disclaims any liability to Recipient for claims brought by any other entity based on infringement of intellectual property rights or otherwise. As a condition to exercising the rights and licenses granted hereunder, each Recipient hereby assumes sole responsibility to secure any other intellectual property rights needed, if any. For example, if a third party patent license is required to allow Recipient to distribute the Program, it is Recipient's responsibility to acquire that license before distributing the Program. d) Each Contributor represents that to its knowledge it has sufficient copyright rights in its Contribution, if any, to grant the copyright license set forth in this Agreement. 3. REQUIREMENTS A Contributor may choose to distribute the Program in object code form under its own license agreement, provided that:
  • 31. a) it complies with the terms and conditions of this Agreement; and b) its license agreement: i) effectively disclaims on behalf of all Contributors all warranties and conditions, express and implied, including warranties or conditions of title and non-infringement, and implied warranties or conditions of merchantability and fitness for a particular purpose; ii) effectively excludes on behalf of all Contributors all liability for damages, including direct, indirect, special, incidental and consequential damages, such as lost profits; iii) states that any provisions which differ from this Agreement are offered by that Contributor alone and not by any other party; and iv) states that source code for the Program is available from such Contributor, and informs licensees how to obtain it in a reasonable manner on or through a medium customarily used for software exchange. When the Program is made available in source code form: a) it must be made available under this Agreement; and b) a copy of this Agreement must be included with each copy of the Program. Contributors may not remove or alter any copyright notices contained within the Program.
  • 32. Each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent Recipients to identify the originator of the Contribution. 4. COMMERCIAL DISTRIBUTION Commercial distributors of software may accept certain responsibilities with respect to end users, business partners and the like. While this license is intended to facilitate the commercial use of the Program, the Contributor who includes the Program in a commercial product offering should do so in a manner which does not create potential liability for other Contributors. Therefore, if a Contributor includes the Program in a commercial product offering, such Contributor ("Commercial Contributor") hereby agrees to defend and indemnify every other Contributor ("Indemnified Contributor") against any losses, damages and costs (collectively "Losses") arising from claims, lawsuits and other legal actions brought by a third party against the Indemnified Contributor to the extent caused by the acts or omissions of such Commercial Contributor in connection with its distribution of the Program in a commercial product offering. The obligations in this section do not apply to any claims
  • 33. or Losses relating to any actual or alleged intellectual property infringement. In order to qualify, an Indemnified Contributor must: a) promptly notify the Commercial Contributor in writing of such claim, and b) allow the Commercial Contributor to control, and cooperate with the Commercial Contributor in, the defense and any related settlement negotiations. The Indemnified Contributor may participate in any such claim at its own expense. For example, a Contributor might include the Program in a commercial product offering, Product X. That Contributor is then a Commercial Contributor. If that Commercial Contributor then makes performance claims, or offers warranties related to Product X, those performance claims and warranties are such Commercial Contributor's responsibility alone. Under this section, the Commercial Contributor would have to defend claims against the other Contributors related to those performance claims and warranties, and if a court requires any other Contributor to pay any damages as a result, the Commercial Contributor must pay those damages. 5. NO WARRANTY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
  • 34. OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the appropriateness of using and distributing the Program and assumes all risks associated with its exercise of rights under this Agreement , including but not limited to the risks and costs of program errors, compliance with applicable laws, damage to or loss of data, programs or equipment, and unavailability or interruption of operations. 6. DISCLAIMER OF LIABILITY EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 7. GENERAL
  • 35. If any provision of this Agreement is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this Agreement, and without further action by the parties hereto, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. If Recipient institutes patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Program itself (excluding combinations of the Program with other software or hardware) infringes such Recipient's patent(s), then such Recipient's rights granted under Section 2(b) shall terminate as of the date such litigation is filed. All Recipient's rights under this Agreement shall terminate if it fails to comply with any of the material terms or conditions of this Agreement and does not cure such failure in a reasonable period of time after becoming aware of such noncompliance. If all Recipient's rights under this Agreement terminate, Recipient agrees to cease use and distribution of the Program as soon as reasonably practicable. However, Recipient's obligations under this Agreement and any licenses granted by Recipient relating to the Program shall continue
  • 36. and survive. Everyone is permitted to copy and distribute copies of this Agreement, but in order to avoid inconsistency the Agreement is copyrighted and may only be modified in the following manner. The Agreement Steward reserves the right to publish new versions (including revisions) of this Agreement from time to time. No one other than the Agreement Steward has the right to modify this Agreement. The Eclipse Foundation is the initial Agreement Steward. The Eclipse Foundation may assign the responsibility to serve as the Agreement Steward to a suitable separate entity. Each new version of the Agreement will be given a distinguishing version number. The Program (including Contributions) may always be distributed subject to the version of the Agreement under which it was received. In addition, after a new version of the Agreement is published, Contributor may elect to distribute the Program (including its Contributions) under the new version. Except as expressly stated in Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to the intellectual property of any Contributor under this Agreement, whether expressly, by implication, estoppel or otherwise. All rights in the Program not expressly granted under this Agreement are reserved.
  • 37. This Agreement is governed by the laws of the State of New York and the intellectual property laws of the United States of America. No party to this Agreement will bring a legal action under this Agreement more than one year after the cause of action arose. Each party waives its rights to a jury trial in any resulting litigation. manifest.yml applications: - host: Lab8TestT12018Assignment3 disk: 128M name: Lab8TestT12018Assignment3 command: node app.js path: . domain: mybluemix.net memory: 128M instances: 3 maps/austin_downtown-clean.osm maps/san_francisco-clean.osm maps/vegas-clean.osm node_modules/body-parser/HISTORY.md 1.17.2 / 2017-05-17 =================== * deps: [email protected] - Fix `DEBUG_MAX_ARRAY_LENGTH`
  • 38. - deps: [email protected] * deps: [email protected]~1.6.15 - deps: [email protected]~2.1.15 1.17.1 / 2017-03-06 =================== * deps: [email protected] - Fix regression parsing keys starting with `[` 1.17.0 / 2017-03-01 =================== * deps: [email protected]~1.6.1 - Make `message` property enumerable for `HttpError`s - deps: [email protected] * deps: [email protected] - Fix compacting nested arrays 1.16.1 / 2017-02-10 =================== * deps: [email protected] - Fix deprecation messages in WebStorm and other editors - Undeprecate `DEBUG_FD` set to `1` or `2` 1.16.0 / 2017-01-17 =================== * deps: [email protected] - Allow colors in workers - Deprecated `DEBUG_FD` environment variable - Fix error when running under React Native - Use same color for same namespace - deps: [email protected] * deps: [email protected]~1.5.1
  • 39. - deps: [email protected] - deps: [email protected] - deps: [email protected]'>= 1.3.1 < 2' * deps: [email protected] - Added encoding MS-31J - Added encoding MS-932 - Added encoding MS-936 - Added encoding MS-949 - Added encoding MS-950 - Fix GBK/GB18030 handling of Euro character * deps: [email protected] - Fix array parsing from skipping empty values * deps: [email protected]~2.2.0 - deps: [email protected] * deps: [email protected]~1.6.14 - deps: [email protected]~2.1.13 1.15.2 / 2016-06-19 =================== * deps: [email protected] * deps: [email protected]~1.0.2 - perf: enable strict mode * deps: [email protected]~1.5.0 - Use `setprototypeof` module to replace `__proto__` setting - deps: [email protected]'>= 1.3.0 < 2' - perf: enable strict mode * deps: [email protected] * deps: [email protected]~2.1.7 - deps: [email protected] - perf: remove double-cleanup on happy path * deps: [email protected]~1.6.13 - deps: [email protected]~2.1.11 1.15.1 / 2016-05-05 ===================
  • 40. * deps: [email protected] - Drop partial bytes on all parsed units - Fix parsing byte string that looks like hex * deps: [email protected]~2.1.6 - deps: [email protected] * deps: [email protected]~1.6.12 - deps: [email protected]~2.1.10 1.15.0 / 2016-02-10 =================== * deps: [email protected]~1.4.0 - Add `HttpError` export, for `err instanceof createError.HttpError` - deps: [email protected] - deps: [email protected]'>= 1.2.1 < 2' * deps: [email protected] * deps: [email protected]~1.6.11 - deps: [email protected]~2.1.9 1.14.2 / 2015-12-16 =================== * deps: [email protected] * deps: [email protected] * deps: [email protected] * deps: [email protected]~2.1.5 - deps: [email protected] - deps: [email protected] * deps: [email protected]~1.6.10 - deps: [email protected]~2.1.8 1.14.1 / 2015-09-27 ===================
  • 41. * Fix issue where invalid charset results in 400 when `verify` used * deps: [email protected] - Fix CESU-8 decoding in Node.js 4.x * deps: [email protected]~2.1.4 - Fix masking critical errors from `iconv-lite` - deps: [email protected] * deps: [email protected]~1.6.9 - deps: [email protected]~2.1.7 1.14.0 / 2015-09-16 =================== * Fix JSON strict parse error to match syntax errors * Provide static `require` analysis in `urlencoded` parser * deps: [email protected]~1.1.0 - Support web browser loading * deps: [email protected] * deps: [email protected]~2.1.3 - Fix sync callback when attaching data listener causes sync read * deps: [email protected]~1.6.8 - Fix type error when given invalid type to match against - deps: [email protected]~2.1.6 1.13.3 / 2015-07-31 =================== * deps: [email protected]~1.6.6 - deps: [email protected]~2.1.4 1.13.2 / 2015-07-05 =================== * deps: [email protected] * deps: [email protected]
  • 42. - Fix dropping parameters like `hasOwnProperty` - Fix user-visible incompatibilities from 3.1.0 - Fix various parsing edge cases * deps: [email protected]~2.1.2 - Fix error stack traces to skip `makeError` - deps: [email protected] * deps: [email protected]~1.6.4 - deps: [email protected]~2.1.2 - perf: enable strict mode - perf: remove argument reassignment 1.13.1 / 2015-06-16 =================== * deps: [email protected] - Downgraded from 3.1.0 because of user-visible incompatibilities 1.13.0 / 2015-06-14 =================== * Add `statusCode` property on `Error`s, in addition to `status` * Change `type` default to `application/json` for JSON parser * Change `type` default to `application/x-www-form- urlencoded` for urlencoded parser * Provide static `require` analysis * Use the `http-errors` module to generate errors * deps: [email protected] - Slight optimizations * deps: [email protected] - The encoding UTF-16 without BOM now defaults to UTF- 16LE when detection fails - Leading BOM is now removed when decoding * deps: [email protected]~2.3.0 - Add defined behavior for HTTP `CONNECT` requests - Add defined behavior for HTTP `Upgrade` requests
  • 43. - deps: [email protected] * deps: [email protected] - Fix dropping parameters like `hasOwnProperty` - Fix various parsing edge cases - Parsed object now has `null` prototype * deps: [email protected]~2.1.1 - Use `unpipe` module for unpiping requests - deps: [email protected] * deps: [email protected]~1.6.3 - deps: [email protected]~2.1.1 - perf: reduce try block size - perf: remove bitwise operations * perf: enable strict mode * perf: remove argument reassignment * perf: remove delete call 1.12.4 / 2015-05-10 =================== * deps: [email protected]~2.2.0 * deps: [email protected] - Fix allowing parameters like `constructor` * deps: [email protected]~2.2.1 * deps: [email protected]~2.0.1 - Fix a false-positive when unpiping in Node.js 0.8 - deps: [email protected] * deps: [email protected]~1.6.2 - deps: [email protected]~2.0.11 1.12.3 / 2015-04-15 =================== * Slight efficiency improvement when not debugging * deps: [email protected]~1.0.1 * deps: [email protected] - Add encoding alias UNICODE-1-1-UTF-7
  • 44. * deps: [email protected] - Fix hanging callback if request aborts during read - deps: [email protected] 1.12.2 / 2015-03-16 =================== * deps: [email protected] - Fix error when parameter `hasOwnProperty` is present 1.12.1 / 2015-03-15 =================== * deps: [email protected]~2.1.3 - Fix high intensity foreground color for bold - deps: [email protected] * deps: [email protected]~1.6.1 - deps: [email protected]~2.0.10 1.12.0 / 2015-02-13 =================== * add `debug` messages * accept a function for the `type` option * use `content-type` to parse `Content-Type` headers * deps: [email protected] - Gracefully support enumerables on `Object.prototype` * deps: [email protected] - deps: [email protected] * deps: [email protected]~1.6.0 - fix argument reassignment - fix false-positives in `hasBody` `Transfer-Encoding` check - support wildcard for both type and subtype (`*/*`) - deps: [email protected]~2.0.9 1.11.0 / 2015-01-30
  • 45. =================== * make internal `extended: true` depth limit infinity * deps: [email protected]~1.5.6 - deps: [email protected]~2.0.8 1.10.2 / 2015-01-20 =================== * deps: [email protected] - Fix rare aliases of single-byte encodings * deps: [email protected] - deps: [email protected] 1.10.1 / 2015-01-01 =================== * deps: [email protected]~2.2.0 * deps: [email protected]~1.5.5 - deps: [email protected]~2.0.7 1.10.0 / 2014-12-02 =================== * make internal `extended: true` array limit dynamic 1.9.3 / 2014-11-21 ================== * deps: [email protected] - Fix Windows-31J and X-SJIS encoding support * deps: [email protected] - Fix `arrayLimit` behavior * deps: [email protected] - deps: [email protected] * deps: [email protected]~1.5.3
  • 46. - deps: [email protected]~2.0.3 1.9.2 / 2014-10-27 ================== * deps: [email protected] - Fix parsing of mixed objects and values 1.9.1 / 2014-10-22 ================== * deps: [email protected]~2.1.1 - Fix handling of pipelined requests * deps: [email protected] - Fix parsing of mixed implicit and explicit arrays * deps: [email protected]~1.5.2 - deps: [email protected]~2.0.2 1.9.0 / 2014-09-24 ================== * include the charset in "unsupported charset" error message * include the encoding in "unsupported content encoding" error message * deps: [email protected]~1.0.0 1.8.4 / 2014-09-23 ================== * fix content encoding to be case-insensitive 1.8.3 / 2014-09-19 ================== * deps: [email protected] - Fix issue with object keys starting with numbers truncated
  • 47. 1.8.2 / 2014-09-15 ================== * deps: [email protected] 1.8.1 / 2014-09-07 ================== * deps: [email protected] * deps: [email protected]~1.5.1 1.8.0 / 2014-09-05 ================== * make empty-body-handling consistent between chunked requests - empty `json` produces `{}` - empty `raw` produces `new Buffer(0)` - empty `text` produces `''` - empty `urlencoded` produces `{}` * deps: [email protected] - Fix issue where first empty value in array is discarded * deps: [email protected]~1.5.0 - fix `hasbody` to be true for `content-length: 0` 1.7.0 / 2014-09-01 ================== * add `parameterLimit` option to `urlencoded` parser * change `urlencoded` extended array limit to 100 * respond with 413 when over `parameterLimit` in `urlencoded` 1.6.7 / 2014-08-29 ==================
  • 48. * deps: [email protected] - Remove unnecessary cloning 1.6.6 / 2014-08-27 ================== * deps: [email protected] - Array parsing fix - Performance improvements 1.6.5 / 2014-08-16 ================== * deps: [email protected] 1.6.4 / 2014-08-14 ================== * deps: [email protected] 1.6.3 / 2014-08-10 ================== * deps: [email protected] 1.6.2 / 2014-08-07 ================== * deps: [email protected] - Fix parsing array of objects 1.6.1 / 2014-08-06 ================== * deps: [email protected]
  • 49. - Accept urlencoded square brackets - Accept empty values in implicit array notation 1.6.0 / 2014-08-05 ================== * deps: [email protected] - Complete rewrite - Limits array length to 20 - Limits object depth to 5 - Limits parameters to 1,000 1.5.2 / 2014-07-27 ================== * deps: [email protected] - Work-around v8 generating empty stack traces 1.5.1 / 2014-07-26 ================== * deps: [email protected] - Fix exception when global `Error.stackTraceLimit` is too low 1.5.0 / 2014-07-20 ================== * deps: [email protected] - Add `TRACE_DEPRECATION` environment variable - Remove non-standard grey color from color output - Support `--no-deprecation` argument - Support `--trace-deprecation` argument * deps: [email protected] - Added encoding UTF-7 * deps: [email protected]
  • 50. - deps: [email protected] - Added encoding UTF-7 - Fix `Cannot switch to old mode now` error on Node.js 0.10+ * deps: [email protected]~1.3.2 1.4.3 / 2014-06-19 ================== * deps: [email protected] - fix global variable leak 1.4.2 / 2014-06-19 ================== * deps: [email protected] - improve type parsing 1.4.1 / 2014-06-19 ================== * fix urlencoded extended deprecation message 1.4.0 / 2014-06-19 ================== * add `text` parser * add `raw` parser * check accepted charset in content-type (accepts utf-8) * check accepted encoding in content-encoding (accepts identity) * deprecate `bodyParser()` middleware; use `.json()` and `.urlencoded()` as needed * deprecate `urlencoded()` without provided `extended` option * lazy-load urlencoded parsers * parsers split into files for reduced mem usage
  • 51. * support gzip and deflate bodies - set `inflate: false` to turn off * deps: [email protected] - Support all encodings from `iconv-lite` 1.3.1 / 2014-06-11 ================== * deps: [email protected] - Switch dependency from mime to [email protected] 1.3.0 / 2014-05-31 ================== * add `extended` option to urlencoded parser 1.2.2 / 2014-05-27 ================== * deps: [email protected] - assert stream encoding on node.js 0.8 - assert stream encoding on node.js < 0.10.6 - deps: [email protected] 1.2.1 / 2014-05-26 ================== * invoke `next(err)` after request fully read - prevents hung responses and socket hang ups 1.2.0 / 2014-05-11 ================== * add `verify` option * deps: [email protected] - support suffix matching
  • 52. 1.1.2 / 2014-05-11 ================== * improve json parser speed 1.1.1 / 2014-05-11 ================== * fix repeated limit parsing with every request 1.1.0 / 2014-05-10 ================== * add `type` option * deps: pin for safety and consistency 1.0.2 / 2014-04-14 ================== * use `type-is` module 1.0.1 / 2014-03-20 ================== * lower default limits to 100kb node_modules/body-parser/index.js /*! * body-parser * Copyright(c) 2014-2015 Douglas Christopher Wilson * MIT Licensed */ 'use strict'
  • 53. /** * Module dependencies. * @private */ var deprecate = require('depd')('body-parser') /** * Cache of loaded parsers. * @private */ var parsers = Object.create(null) /** * @typedef Parsers * @type {function} * @property {function} json * @property {function} raw * @property {function} text * @property {function} urlencoded */ /** * Module exports. * @type {Parsers} */ exports = module.exports = deprecate.function(bodyParser, 'bodyParser: use individual json/urlencoded middlewares') /** * JSON parser. * @public */
  • 54. Object.defineProperty(exports, 'json', { configurable: true, enumerable: true, get: createParserGetter('json') }) /** * Raw parser. * @public */ Object.defineProperty(exports, 'raw', { configurable: true, enumerable: true, get: createParserGetter('raw') }) /** * Text parser. * @public */ Object.defineProperty(exports, 'text', { configurable: true, enumerable: true, get: createParserGetter('text') }) /** * URL-encoded parser. * @public */ Object.defineProperty(exports, 'urlencoded', { configurable: true,
  • 55. enumerable: true, get: createParserGetter('urlencoded') }) /** * Create a middleware to parse json and urlencoded bodies. * * @param {object} [options] * @return {function} * @deprecated * @public */ function bodyParser (options) { var opts = {} // exclude type option if (options) { for (var prop in options) { if (prop !== 'type') { opts[prop] = options[prop] } } } var _urlencoded = exports.urlencoded(opts) var _json = exports.json(opts) return function bodyParser (req, res, next) { _json(req, res, function (err) { if (err) return next(err) _urlencoded(req, res, next) }) } }
  • 56. /** * Create a getter for loading a parser. * @private */ function createParserGetter (name) { return function get () { return loadParser(name) } } /** * Load a parser module. * @private */ function loadParser (parserName) { var parser = parsers[parserName] if (parser !== undefined) { return parser } // this uses a switch for static require analysis switch (parserName) { case 'json': parser = require('./lib/types/json') break case 'raw': parser = require('./lib/types/raw') break case 'text': parser = require('./lib/types/text') break case 'urlencoded': parser = require('./lib/types/urlencoded')
  • 57. break } // store to prevent invoking require() return (parsers[parserName] = parser) } node_modules/body-parser/lib/read.js /*! * body-parser * Copyright(c) 2014-2015 Douglas Christopher Wilson * MIT Licensed */ 'use strict' /** * Module dependencies. * @private */ var createError = require('http-errors') var getBody = require('raw-body') var iconv = require('iconv-lite') var onFinished = require('on-finished') var zlib = require('zlib') /** * Module exports. */ module.exports = read /** * Read a request into a buffer and parse.
  • 58. * * @param {object} req * @param {object} res * @param {function} next * @param {function} parse * @param {function} debug * @param {object} options * @private */ function read (req, res, next, parse, debug, options) { var length var opts = options var stream // flag as parsed req._body = true // read options var encoding = opts.encoding !== null ? opts.encoding : null var verify = opts.verify try { // get the content stream stream = contentstream(req, debug, opts.inflate) length = stream.length stream.length = undefined } catch (err) { return next(err) } // set raw-body options opts.length = length opts.encoding = verify
  • 59. ? null : encoding // assert charset is supported if (opts.encoding === null && encoding !== null && !iconv.encodingExists(encoding)) { return next(createError(415, 'unsupported charset "' + encoding.toUpperCase() + '"', { charset: encoding.toLowerCase() })) } // read body debug('read body') getBody(stream, opts, function (err, body) { if (err) { // default to 400 setErrorStatus(err, 400) // echo back charset if (err.type === 'encoding.unsupported') { err = createError(415, 'unsupported charset "' + encoding.toUpperCase() + '"', { charset: encoding.toLowerCase() }) } // read off entire request stream.resume() onFinished(req, function onfinished () { next(err) }) return } // verify
  • 60. if (verify) { try { debug('verify body') verify(req, res, body, encoding) } catch (err) { // default to 403 setErrorStatus(err, 403) next(err) return } } // parse var str try { debug('parse body') str = typeof body !== 'string' && encoding !== null ? iconv.decode(body, encoding) : body req.body = parse(str) } catch (err) { // istanbul ignore next err.body = str === undefined ? body : str // default to 400 setErrorStatus(err, 400) next(err) return } next() }) }
  • 61. /** * Get the content stream of the request. * * @param {object} req * @param {function} debug * @param {boolean} [inflate=true] * @return {object} * @api private */ function contentstream (req, debug, inflate) { var encoding = (req.headers['content-encoding'] || 'identity').toLowerCase() var length = req.headers['content-length'] var stream debug('content-encoding "%s"', encoding) if (inflate === false && encoding !== 'identity') { throw createError(415, 'content encoding unsupported') } switch (encoding) { case 'deflate': stream = zlib.createInflate() debug('inflate body') req.pipe(stream) break case 'gzip': stream = zlib.createGunzip() debug('gunzip body') req.pipe(stream) break case 'identity': stream = req
  • 62. stream.length = length break default: throw createError(415, 'unsupported content encoding "' + encoding + '"', { encoding: encoding }) } return stream } /** * Set a status on an error object, if ones does not exist * @private */ function setErrorStatus (error, status) { if (!error.status && !error.statusCode) { error.status = status error.statusCode = status } } node_modules/body-parser/lib/types/json.js /*! * body-parser * Copyright(c) 2014 Jonathan Ong * Copyright(c) 2014-2015 Douglas Christopher Wilson * MIT Licensed */ 'use strict' /**
  • 63. * Module dependencies. * @private */ var bytes = require('bytes') var contentType = require('content-type') var createError = require('http-errors') var debug = require('debug')('body-parser:json') var read = require('../read') var typeis = require('type-is') /** * Module exports. */ module.exports = json /** * RegExp to match the first non-space in a string. * * Allowed whitespace is defined in RFC 7159: * * ws = *( * %x20 / ; Space * %x09 / ; Horizontal tab * %x0A / ; Line feed or New line * %x0D ) ; Carriage return */ var FIRST_CHAR_REGEXP = /^[x20x09x0ax0d]*(.)/ // eslint-disable-line no-control-regex /** * Create a middleware to parse JSON bodies. * * @param {object} [options]
  • 64. * @return {function} * @public */ function json (options) { var opts = options || {} var limit = typeof opts.limit !== 'number' ? bytes.parse(opts.limit || '100kb') : opts.limit var inflate = opts.inflate !== false var reviver = opts.reviver var strict = opts.strict !== false var type = opts.type || 'application/json' var verify = opts.verify || false if (verify !== false && typeof verify !== 'function') { throw new TypeError('option verify must be function') } // create the appropriate type checking function var shouldParse = typeof type !== 'function' ? typeChecker(type) : type function parse (body) { if (body.length === 0) { // special-case empty json body, as it's a common client-side mistake // TODO: maybe make this configurable or part of "strict" option return {} } if (strict) { var first = firstchar(body)
  • 65. if (first !== '{' && first !== '[') { debug('strict violation') throw new SyntaxError('Unexpected token ' + first) } } debug('parse json') return JSON.parse(body, reviver) } return function jsonParser (req, res, next) { if (req._body) { debug('body already parsed') next() return } req.body = req.body || {} // skip requests without bodies if (!typeis.hasBody(req)) { debug('skip empty body') next() return } debug('content-type %j', req.headers['content-type']) // determine if request should be parsed if (!shouldParse(req)) { debug('skip parsing') next() return }
  • 66. // assert charset per RFC 7159 sec 8.1 var charset = getCharset(req) || 'utf-8' if (charset.substr(0, 4) !== 'utf-') { debug('invalid charset') next(createError(415, 'unsupported charset "' + charset.toUpperCase() + '"', { charset: charset })) return } // read read(req, res, next, parse, debug, { encoding: charset, inflate: inflate, limit: limit, verify: verify }) } } /** * Get the first non-whitespace character in a string. * * @param {string} str * @return {function} * @private */ function firstchar (str) { return FIRST_CHAR_REGEXP.exec(str)[1] } /** * Get the charset of a request. *
  • 67. * @param {object} req * @api private */ function getCharset (req) { try { return contentType.parse(req).parameters.charset.toLowerCase() } catch (e) { return undefined } } /** * Get the simple type checker. * * @param {string} type * @return {function} */ function typeChecker (type) { return function checkType (req) { return Boolean(typeis(req, type)) } } node_modules/body-parser/lib/types/raw.js /*! * body-parser * Copyright(c) 2014-2015 Douglas Christopher Wilson * MIT Licensed */ 'use strict'
  • 68. /** * Module dependencies. */ var bytes = require('bytes') var debug = require('debug')('body-parser:raw') var read = require('../read') var typeis = require('type-is') /** * Module exports. */ module.exports = raw /** * Create a middleware to parse raw bodies. * * @param {object} [options] * @return {function} * @api public */ function raw (options) { var opts = options || {} var inflate = opts.inflate !== false var limit = typeof opts.limit !== 'number' ? bytes.parse(opts.limit || '100kb') : opts.limit var type = opts.type || 'application/octet-stream' var verify = opts.verify || false if (verify !== false && typeof verify !== 'function') { throw new TypeError('option verify must be function') }
  • 69. // create the appropriate type checking function var shouldParse = typeof type !== 'function' ? typeChecker(type) : type function parse (buf) { return buf } return function rawParser (req, res, next) { if (req._body) { debug('body already parsed') next() return } req.body = req.body || {} // skip requests without bodies if (!typeis.hasBody(req)) { debug('skip empty body') next() return } debug('content-type %j', req.headers['content-type']) // determine if request should be parsed if (!shouldParse(req)) { debug('skip parsing') next() return } // read
  • 70. read(req, res, next, parse, debug, { encoding: null, inflate: inflate, limit: limit, verify: verify }) } } /** * Get the simple type checker. * * @param {string} type * @return {function} */ function typeChecker (type) { return function checkType (req) { return Boolean(typeis(req, type)) } } node_modules/body-parser/lib/types/text.js /*! * body-parser * Copyright(c) 2014-2015 Douglas Christopher Wilson * MIT Licensed */ 'use strict' /** * Module dependencies. */
  • 71. var bytes = require('bytes') var contentType = require('content-type') var debug = require('debug')('body-parser:text') var read = require('../read') var typeis = require('type-is') /** * Module exports. */ module.exports = text /** * Create a middleware to parse text bodies. * * @param {object} [options] * @return {function} * @api public */ function text (options) { var opts = options || {} var defaultCharset = opts.defaultCharset || 'utf-8' var inflate = opts.inflate !== false var limit = typeof opts.limit !== 'number' ? bytes.parse(opts.limit || '100kb') : opts.limit var type = opts.type || 'text/plain' var verify = opts.verify || false if (verify !== false && typeof verify !== 'function') { throw new TypeError('option verify must be function') } // create the appropriate type checking function
  • 72. var shouldParse = typeof type !== 'function' ? typeChecker(type) : type function parse (buf) { return buf } return function textParser (req, res, next) { if (req._body) { debug('body already parsed') next() return } req.body = req.body || {} // skip requests without bodies if (!typeis.hasBody(req)) { debug('skip empty body') next() return } debug('content-type %j', req.headers['content-type']) // determine if request should be parsed if (!shouldParse(req)) { debug('skip parsing') next() return } // get charset var charset = getCharset(req) || defaultCharset
  • 73. // read read(req, res, next, parse, debug, { encoding: charset, inflate: inflate, limit: limit, verify: verify }) } } /** * Get the charset of a request. * * @param {object} req * @api private */ function getCharset (req) { try { return contentType.parse(req).parameters.charset.toLowerCase() } catch (e) { return undefined } } /** * Get the simple type checker. * * @param {string} type * @return {function} */ function typeChecker (type) { return function checkType (req) { return Boolean(typeis(req, type))
  • 74. } } node_modules/body-parser/lib/types/urlencoded.js /*! * body-parser * Copyright(c) 2014 Jonathan Ong * Copyright(c) 2014-2015 Douglas Christopher Wilson * MIT Licensed */ 'use strict' /** * Module dependencies. * @private */ var bytes = require('bytes') var contentType = require('content-type') var createError = require('http-errors') var debug = require('debug')('body-parser:urlencoded') var deprecate = require('depd')('body-parser') var read = require('../read') var typeis = require('type-is') /** * Module exports. */ module.exports = urlencoded /** * Cache of parser modules. */
  • 75. var parsers = Object.create(null) /** * Create a middleware to parse urlencoded bodies. * * @param {object} [options] * @return {function} * @public */ function urlencoded (options) { var opts = options || {} // notice because option default will flip in next major if (opts.extended === undefined) { deprecate('undefined extended: provide extended option') } var extended = opts.extended !== false var inflate = opts.inflate !== false var limit = typeof opts.limit !== 'number' ? bytes.parse(opts.limit || '100kb') : opts.limit var type = opts.type || 'application/x-www-form-urlencoded' var verify = opts.verify || false if (verify !== false && typeof verify !== 'function') { throw new TypeError('option verify must be function') } // create the appropriate query parser var queryparse = extended ? extendedparser(opts) : simpleparser(opts)
  • 76. // create the appropriate type checking function var shouldParse = typeof type !== 'function' ? typeChecker(type) : type function parse (body) { return body.length ? queryparse(body) : {} } return function urlencodedParser (req, res, next) { if (req._body) { debug('body already parsed') next() return } req.body = req.body || {} // skip requests without bodies if (!typeis.hasBody(req)) { debug('skip empty body') next() return } debug('content-type %j', req.headers['content-type']) // determine if request should be parsed if (!shouldParse(req)) { debug('skip parsing') next() return }
  • 77. // assert charset var charset = getCharset(req) || 'utf-8' if (charset !== 'utf-8') { debug('invalid charset') next(createError(415, 'unsupported charset "' + charset.toUpperCase() + '"', { charset: charset })) return } // read read(req, res, next, parse, debug, { debug: debug, encoding: charset, inflate: inflate, limit: limit, verify: verify }) } } /** * Get the extended query parser. * * @param {object} options */ function extendedparser (options) { var parameterLimit = options.parameterLimit !== undefined ? options.parameterLimit : 1000 var parse = parser('qs') if (isNaN(parameterLimit) || parameterLimit < 1) { throw new TypeError('option parameterLimit must be a
  • 78. positive number') } if (isFinite(parameterLimit)) { parameterLimit = parameterLimit | 0 } return function queryparse (body) { var paramCount = parameterCount(body, parameterLimit) if (paramCount === undefined) { debug('too many parameters') throw createError(413, 'too many parameters') } var arrayLimit = Math.max(100, paramCount) debug('parse extended urlencoding') return parse(body, { allowPrototypes: true, arrayLimit: arrayLimit, depth: Infinity, parameterLimit: parameterLimit }) } } /** * Get the charset of a request. * * @param {object} req * @api private */ function getCharset (req) { try {
  • 79. return contentType.parse(req).parameters.charset.toLowerCase() } catch (e) { return undefined } } /** * Count the number of parameters, stopping once limit reached * * @param {string} body * @param {number} limit * @api private */ function parameterCount (body, limit) { var count = 0 var index = 0 while ((index = body.indexOf('&', index)) !== -1) { count++ index++ if (count === limit) { return undefined } } return count } /** * Get parser for module name dynamically. * * @param {string} name * @return {function}
  • 80. * @api private */ function parser (name) { var mod = parsers[name] if (mod !== undefined) { return mod.parse } // this uses a switch for static require analysis switch (name) { case 'qs': mod = require('qs') break case 'querystring': mod = require('querystring') break } // store to prevent invoking require() parsers[name] = mod return mod.parse } /** * Get the simple query parser. * * @param {object} options */ function simpleparser (options) { var parameterLimit = options.parameterLimit !== undefined ? options.parameterLimit : 1000
  • 81. var parse = parser('querystring') if (isNaN(parameterLimit) || parameterLimit < 1) { throw new TypeError('option parameterLimit must be a positive number') } if (isFinite(parameterLimit)) { parameterLimit = parameterLimit | 0 } return function queryparse (body) { var paramCount = parameterCount(body, parameterLimit) if (paramCount === undefined) { debug('too many parameters') throw createError(413, 'too many parameters') } debug('parse urlencoding') return parse(body, undefined, undefined, {maxKeys: parameterLimit}) } } /** * Get the simple type checker. * * @param {string} type * @return {function} */ function typeChecker (type) { return function checkType (req) { return Boolean(typeis(req, type)) }
  • 82. } node_modules/body-parser/LICENSE (The MIT License) Copyright (c) 2014 Jonathan Ong <[email protected]> Copyright (c) 2014-2015 Douglas Christopher Wilson <[email protected]> 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
  • 83. CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. node_modules/body-parser/package.json { "_args": [ [ { "raw": "body-parser", "scope": null, "escapedName": "body-parser", "name": "body-parser", "rawSpec": "", "spec": "latest", "type": "tag" }, "C:UsersraybDesktopCQU coursesT2- 2017COIT20260LabsLab 8Lab8" ] ], "_from": "[email protected]", "_id": "[email protected]", "_inCache": true, "_location": "/body-parser", "_nodeVersion": "6.10.3", "_npmOperationalInternal": { "host": "packages-18-east.internal.npmjs.com", "tmp": "tmp/body-parser- 1.17.2.tgz_1495083464528_0.912320519099012" }, "_npmUser": { "name": "dougwilson", "email": "[email protected]" },
  • 84. "_npmVersion": "3.10.10", "_phantomChildren": {}, "_requested": { "raw": "body-parser", "scope": null, "escapedName": "body-parser", "name": "body-parser", "rawSpec": "", "spec": "latest", "type": "tag" }, "_requiredBy": [ "#USER", "/" ], "_resolved": "https://registry.npmjs.org/body-parser/-/body- parser-1.17.2.tgz", "_shasum": "f8892abc8f9e627d42aedafbca66bf5ab99104ee", "_shrinkwrap": null, "_spec": "body-parser", "_where": "C:UsersraybDesktopCQU coursesT2- 2017COIT20260LabsLab 8Lab8", "bugs": { "url": "https://github.com/expressjs/body-parser/issues" }, "contributors": [ { "name": "Douglas Christopher Wilson", "email": "[email protected]" }, { "name": "Jonathan Ong", "email": "[email protected]", "url": "http://jongleberry.com" } ],
  • 85. "dependencies": { "bytes": "2.4.0", "content-type": "~1.0.2", "debug": "2.6.7", "depd": "~1.1.0", "http-errors": "~1.6.1", "iconv-lite": "0.4.15", "on-finished": "~2.3.0", "qs": "6.4.0", "raw-body": "~2.2.0", "type-is": "~1.6.15" }, "description": "Node.js body parsing middleware", "devDependencies": { "eslint": "3.19.0", "eslint-config-standard": "10.2.1", "eslint-plugin-import": "2.2.0", "eslint-plugin-markdown": "1.0.0-beta.6", "eslint-plugin-node": "4.2.2", "eslint-plugin-promise": "3.5.0", "eslint-plugin-standard": "3.0.1", "istanbul": "0.4.5", "methods": "1.1.2", "mocha": "2.5.3", "safe-buffer": "5.0.1", "supertest": "1.1.0" }, "directories": {}, "dist": { "shasum": "f8892abc8f9e627d42aedafbca66bf5ab99104ee", "tarball": "https://registry.npmjs.org/body-parser/-/body- parser-1.17.2.tgz" }, "engines": { "node": ">= 0.8" },
  • 86. "files": [ "lib/", "LICENSE", "HISTORY.md", "index.js" ], "gitHead": "77b74312edb46b2e8d8df0c8436aaba396a721e9", "homepage": "https://github.com/expressjs/body- parser#readme", "license": "MIT", "maintainers": [ { "name": "dougwilson", "email": "[email protected]" } ], "name": "body-parser", "optionalDependencies": {}, "readme": "ERROR: No README data found!", "repository": { "type": "git", "url": "git+https://github.com/expressjs/body-parser.git" }, "scripts": { "lint": "eslint --plugin markdown --ext js,md .", "test": "mocha --require test/support/env --reporter spec -- check-leaks --bail test/", "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --require test/support/env --reporter dot --check-leaks test/", "test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --require test/support/env --reporter spec --check-leaks test/" }, "version": "1.17.2" }
  • 87. node_modules/body-parser/README.md # body-parser [![NPM Version][npm-image]][npm-url] [![NPM Downloads][downloads-image]][downloads-url] [![Build Status][travis-image]][travis-url] [![Test Coverage][coveralls-image]][coveralls-url] [![Gratipay][gratipay-image]][gratipay-url] Node.js body parsing middleware. Parse incoming request bodies in a middleware before your handlers, available under the `req.body` property. [Learn about the anatomy of an HTTP transaction in Node.js](https://nodejs.org/en/docs/guides/anatomy-of-an-http- transaction/). _This does not handle multipart bodies_, due to their complex and typically large nature. For multipart bodies, you may be interested in the following modules: * [busboy](https://www.npmjs.org/package/busboy#readme) and [connect-busboy](https://www.npmjs.org/package/connect- busboy#readme) * [multiparty](https://www.npmjs.org/package/multiparty#readme ) and [connect- multiparty](https://www.npmjs.org/package/connect- multiparty#readme)
  • 88. * [formidable](https://www.npmjs.org/package/formidable#readm e) * [multer](https://www.npmjs.org/package/multer#readme) This module provides the following parsers: * [JSON body parser](#bodyparserjsonoptions) * [Raw body parser](#bodyparserrawoptions) * [Text body parser](#bodyparsertextoptions) * [URL-encoded form body parser](#bodyparserurlencodedoptions) Other body parsers you might be interested in: - [body](https://www.npmjs.org/package/body#readme) - [co-body](https://www.npmjs.org/package/co-body#readme) ## Installation ```sh $ npm install body-parser ``` ## API <!-- eslint-disable no-unused-vars --> ```js var bodyParser = require('body-parser') ``` The `bodyParser` object exposes various factories to create middlewares. All middlewares will populate the `req.body` property with the parsed body when
  • 89. the `Content-Type` request header matches the `type` option, or an empty object (`{}`) if there was no body to parse, the `Content-Type` was not matched, or an error occurred. The various errors returned by this module are described in the [errors section](#errors). ### bodyParser.json(options) Returns middleware that only parses `json` and only looks at requests where the `Content-Type` header matches the `type` option. This parser accepts any Unicode encoding of the body and supports automatic inflation of `gzip` and `deflate` encodings. A new `body` object containing the parsed data is populated on the `request` object after the middleware (i.e. `req.body`). #### Options The `json` function takes an option `options` object that may contain any of the following keys: ##### inflate When set to `true`, then deflated (compressed) bodies will be inflated; when `false`, deflated bodies are rejected. Defaults to `true`. ##### limit
  • 90. Controls the maximum request body size. If this is a number, then the value specifies the number of bytes; if it is a string, the value is passed to the [bytes](https://www.npmjs.com/package/bytes) library for parsing. Defaults to `'100kb'`. ##### reviver The `reviver` option is passed directly to `JSON.parse` as the second argument. You can find more information on this argument [in the MDN documentation about JSON.parse](https://developer.mozilla.org/en- US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse #Example.3A_Using_the_reviver_parameter). ##### strict When set to `true`, will only accept arrays and objects; when `false` will accept anything `JSON.parse` accepts. Defaults to `true`. ##### type The `type` option is used to determine what media type the middleware will parse. This option can be a function or a string. If a string, `type` option is passed directly to the [type- is](https://www.npmjs.org/package/type-is#readme) library and this can be an extension name (like `json`), a mime type (like `application/json`), or a mime type with a wildcard (like `*/*`
  • 91. or `*/json`). If a function, the `type` option is called as `fn(req)` and the request is parsed if it returns a truthy value. Defaults to `application/json`. ##### verify The `verify` option, if supplied, is called as `verify(req, res, buf, encoding)`, where `buf` is a `Buffer` of the raw request body and `encoding` is the encoding of the request. The parsing can be aborted by throwing an error. ### bodyParser.raw(options) Returns middleware that parses all bodies as a `Buffer` and only looks at requests where the `Content-Type` header matches the `type` option. This parser supports automatic inflation of `gzip` and `deflate` encodings. A new `body` object containing the parsed data is populated on the `request` object after the middleware (i.e. `req.body`). This will be a `Buffer` object of the body. #### Options The `raw` function takes an option `options` object that may contain any of the following keys: ##### inflate
  • 92. When set to `true`, then deflated (compressed) bodies will be inflated; when `false`, deflated bodies are rejected. Defaults to `true`. ##### limit Controls the maximum request body size. If this is a number, then the value specifies the number of bytes; if it is a string, the value is passed to the [bytes](https://www.npmjs.com/package/bytes) library for parsing. Defaults to `'100kb'`. ##### type The `type` option is used to determine what media type the middleware will parse. This option can be a function or a string. If a string, `type` option is passed directly to the [type- is](https://www.npmjs.org/package/type-is#readme) library and this can be an extension name (like `bin`), a mime type (like `application/octet-stream`), or a mime type with a wildcard (like `*/*` or `application/*`). If a function, the `type` option is called as `fn(req)` and the request is parsed if it returns a truthy value. Defaults to `application/octet-stream`. ##### verify The `verify` option, if supplied, is called as `verify(req, res, buf, encoding)`,
  • 93. where `buf` is a `Buffer` of the raw request body and `encoding` is the encoding of the request. The parsing can be aborted by throwing an error. ### bodyParser.text(options) Returns middleware that parses all bodies as a string and only looks at requests where the `Content-Type` header matches the `type` option. This parser supports automatic inflation of `gzip` and `deflate` encodings. A new `body` string containing the parsed data is populated on the `request` object after the middleware (i.e. `req.body`). This will be a string of the body. #### Options The `text` function takes an option `options` object that may contain any of the following keys: ##### defaultCharset Specify the default character set for the text content if the charset is not specified in the `Content-Type` header of the request. Defaults to `utf-8`. ##### inflate When set to `true`, then deflated (compressed) bodies will be
  • 94. inflated; when `false`, deflated bodies are rejected. Defaults to `true`. ##### limit Controls the maximum request body size. If this is a number, then the value specifies the number of bytes; if it is a string, the value is passed to the [bytes](https://www.npmjs.com/package/bytes) library for parsing. Defaults to `'100kb'`. ##### type The `type` option is used to determine what media type the middleware will parse. This option can be a function or a string. If a string, `type` option is passed directly to the [type- is](https://www.npmjs.org/package/type-is#readme) library and this can be an extension name (like `txt`), a mime type (like `text/plain`), or a mime type with a wildcard (like `*/*` or `text/*`). If a function, the `type` option is called as `fn(req)` and the request is parsed if it returns a truthy value. Defaults to `text/plain`. ##### verify The `verify` option, if supplied, is called as `verify(req, res, buf, encoding)`, where `buf` is a `Buffer` of the raw request body and `encoding` is the encoding of the request. The parsing can be aborted by throwing
  • 95. an error. ### bodyParser.urlencoded(options) Returns middleware that only parses `urlencoded` bodies and only looks at requests where the `Content-Type` header matches the `type` option. This parser accepts only UTF-8 encoding of the body and supports automatic inflation of `gzip` and `deflate` encodings. A new `body` object containing the parsed data is populated on the `request` object after the middleware (i.e. `req.body`). This object will contain key-value pairs, where the value can be a string or array (when `extended` is `false`), or any type (when `extended` is `true`). #### Options The `urlencoded` function takes an option `options` object that may contain any of the following keys: ##### extended The `extended` option allows to choose between parsing the URL-encoded data with the `querystring` library (when `false`) or the `qs` library (when `true`). The "extended" syntax allows for rich objects and arrays to be encoded into the URL-encoded format, allowing for a JSON- like experience
  • 96. with URL-encoded. For more information, please [see the qs library](https://www.npmjs.org/package/qs#readme). Defaults to `true`, but using the default has been deprecated. Please research into the difference between `qs` and `querystring` and choose the appropriate setting. ##### inflate When set to `true`, then deflated (compressed) bodies will be inflated; when `false`, deflated bodies are rejected. Defaults to `true`. ##### limit Controls the maximum request body size. If this is a number, then the value specifies the number of bytes; if it is a string, the value is passed to the [bytes](https://www.npmjs.com/package/bytes) library for parsing. Defaults to `'100kb'`. ##### parameterLimit The `parameterLimit` option controls the maximum number of parameters that are allowed in the URL-encoded data. If a request contains more parameters than this value, a 413 will be returned to the client. Defaults to `1000`. ##### type
  • 97. The `type` option is used to determine what media type the middleware will parse. This option can be a function or a string. If a string, `type` option is passed directly to the [type- is](https://www.npmjs.org/package/type-is#readme) library and this can be an extension name (like `urlencoded`), a mime type (like `application/x-www-form-urlencoded`), or a mime type with a wildcard (like `*/x-www-form-urlencoded`). If a function, the `type` option is called as `fn(req)` and the request is parsed if it returns a truthy value. Defaults to `application/x-www-form-urlencoded`. ##### verify The `verify` option, if supplied, is called as `verify(req, res, buf, encoding)`, where `buf` is a `Buffer` of the raw request body and `encoding` is the encoding of the request. The parsing can be aborted by throwing an error. ## Errors The middlewares provided by this module create errors depending on the error condition during parsing. The errors will typically have a `status` property that contains the suggested HTTP response code and a `body` property containing the read body, if available. The following are the common errors emitted, though any error
  • 98. can come through for various reasons. ### content encoding unsupported This error will occur when the request had a `Content- Encoding` header that contained an encoding but the "inflation" option was set to `false`. The `status` property is set to `415`. ### request aborted This error will occur when the request is aborted by the client before reading the body has finished. The `received` property will be set to the number of bytes received before the request was aborted and the `expected` property is set to the number of expected bytes. The `status` property is set to `400`. ### request entity too large This error will occur when the request body's size is larger than the "limit" option. The `limit` property will be set to the byte limit and the `length` property will be set to the request body's length. The `status` property is set to `413`. ### request size did not match content length This error will occur when the request's length did not match the length from
  • 99. the `Content-Length` header. This typically occurs when the request is malformed, typically when the `Content-Length` header was calculated based on characters instead of bytes. The `status` property is set to `400`. ### stream encoding should not be set This error will occur when something called the `req.setEncoding` method prior to this middleware. This module operates directly on bytes only and you cannot call `req.setEncoding` when using this module. The `status` property is set to `500`. ### unsupported charset "BOGUS" This error will occur when the request had a charset parameter in the `Content-Type` header, but the `iconv-lite` module does not support it OR the parser does not support it. The charset is contained in the message as well as in the `charset` property. The `status` property is set to `415`. ### unsupported content encoding "bogus" This error will occur when the request had a `Content- Encoding` header that contained an unsupported encoding. The encoding is contained in the message as well as in the `encoding` property. The `status` property is set to `415`.
  • 100. ## Examples ### Express/Connect top-level generic This example demonstrates adding a generic JSON and URL- encoded parser as a top-level middleware, which will parse the bodies of all incoming requests. This is the simplest setup. ```js var express = require('express') var bodyParser = require('body-parser') var app = express() // parse application/x-www-form-urlencoded app.use(bodyParser.urlencoded({ extended: false })) // parse application/json app.use(bodyParser.json()) app.use(function (req, res) { res.setHeader('Content-Type', 'text/plain') res.write('you posted:n') res.end(JSON.stringify(req.body, null, 2)) }) ``` ### Express route-specific This example demonstrates adding body parsers specifically to the routes that need them. In general, this is the most recommended way to use body-parser with Express.
  • 101. ```js var express = require('express') var bodyParser = require('body-parser') var app = express() // create application/json parser var jsonParser = bodyParser.json() // create application/x-www-form-urlencoded parser var urlencodedParser = bodyParser.urlencoded({ extended: false }) // POST /login gets urlencoded bodies app.post('/login', urlencodedParser, function (req, res) { if (!req.body) return res.sendStatus(400) res.send('welcome, ' + req.body.username) }) // POST /api/users gets JSON bodies app.post('/api/users', jsonParser, function (req, res) { if (!req.body) return res.sendStatus(400) // create user in req.body }) ``` ### Change accepted type for parsers All the parsers accept a `type` option which allows you to change the `Content-Type` that the middleware will parse. ```js var express = require('express') var bodyParser = require('body-parser')
  • 102. var app = express() // parse various different custom JSON types as JSON app.use(bodyParser.json({ type: 'application/*+json' })) // parse some custom thing into a Buffer app.use(bodyParser.raw({ type: 'application/vnd.custom-type' })) // parse an HTML body into a string app.use(bodyParser.text({ type: 'text/html' })) ``` ## License [MIT](LICENSE) [npm-image]: https://img.shields.io/npm/v/body-parser.svg [npm-url]: https://npmjs.org/package/body-parser [travis-image]: https://img.shields.io/travis/expressjs/body- parser/master.svg [travis-url]: https://travis-ci.org/expressjs/body-parser [coveralls-image]: https://img.shields.io/coveralls/expressjs/body- parser/master.svg [coveralls-url]: https://coveralls.io/r/expressjs/body- parser?branch=master [downloads-image]: https://img.shields.io/npm/dm/body- parser.svg [downloads-url]: https://npmjs.org/package/body-parser [gratipay-image]: https://img.shields.io/gratipay/dougwilson.svg [gratipay-url]: https://www.gratipay.com/dougwilson/ node_modules/bytes/History.md
  • 103. 2.4.0 / 2016-06-01 ================== * Add option "unitSeparator" 2.3.0 / 2016-02-15 ================== * Drop partial bytes on all parsed units * Fix non-finite numbers to `.format` to return `null` * Fix parsing byte string that looks like hex * perf: hoist regular expressions 2.2.0 / 2015-11-13 ================== * add option "decimalPlaces" * add option "fixedDecimals" 2.1.0 / 2015-05-21 ================== * add `.format` export * add `.parse` export 2.0.2 / 2015-05-20 ================== * remove map recreation * remove unnecessary object construction 2.0.1 / 2015-05-07 ================== * fix browserify require * remove node.extend dependency
  • 104. 2.0.0 / 2015-04-12 ================== * add option "case" * add option "thousandsSeparator" * return "null" on invalid parse input * support proper round-trip: bytes(bytes(num)) === num * units no longer case sensitive when parsing 1.0.0 / 2014-05-05 ================== * add negative support. fixes #6 0.3.0 / 2014-03-19 ================== * added terabyte support 0.2.1 / 2013-04-01 ================== * add .component 0.2.0 / 2012-10-28 ================== * bytes(200).should.eql('200b') 0.1.0 / 2012-07-04 ================== * add bytes to string conversion [yields]
  • 105. node_modules/bytes/index.js /*! * bytes * Copyright(c) 2012-2014 TJ Holowaychuk * Copyright(c) 2015 Jed Watson * MIT Licensed */ 'use strict'; /** * Module exports. * @public */ module.exports = bytes; module.exports.format = format; module.exports.parse = parse; /** * Module variables. * @private */ var formatThousandsRegExp = /B(?=(d{3})+(?!d))/g; var formatDecimalsRegExp = /(?:.0*|(.[^0]+)0+)$/; var map = { b: 1, kb: 1 << 10, mb: 1 << 20, gb: 1 << 30, tb: ((1 << 30) * 1024) };
  • 106. // TODO: use is-finite module? var numberIsFinite = Number.isFinite || function (v) { return typeof v === 'number' && isFinite(v); }; var parseRegExp = /^((-|+)?(d+(?:.d+)?)) *(kb|mb|gb|tb)$/i; /** * Convert the given value in bytes into a string or parse to string to an integer in bytes. * * @param {string|number} value * @param {{ * case: [string], * decimalPlaces: [number] * fixedDecimals: [boolean] * thousandsSeparator: [string] * unitSeparator: [string] * }} [options] bytes options. * * @returns {string|number|null} */ function bytes(value, options) { if (typeof value === 'string') { return parse(value); } if (typeof value === 'number') { return format(value, options); } return null; } /** * Format the given value in bytes into a string.
  • 107. * * If the value is negative, it is kept as such. If it is a float, * it is rounded. * * @param {number} value * @param {object} [options] * @param {number} [options.decimalPlaces=2] * @param {number} [options.fixedDecimals=false] * @param {string} [options.thousandsSeparator=] * @param {string} [options.unitSeparator=] * * @returns {string|null} * @public */ function format(value, options) { if (!numberIsFinite(value)) { return null; } var mag = Math.abs(value); var thousandsSeparator = (options && options.thousandsSeparator) || ''; var unitSeparator = (options && options.unitSeparator) || ''; var decimalPlaces = (options && options.decimalPlaces !== undefined) ? options.decimalPlaces : 2; var fixedDecimals = Boolean(options && options.fixedDecimals); var unit = 'B'; if (mag >= map.tb) { unit = 'TB'; } else if (mag >= map.gb) { unit = 'GB'; } else if (mag >= map.mb) { unit = 'MB';
  • 108. } else if (mag >= map.kb) { unit = 'kB'; } var val = value / map[unit.toLowerCase()]; var str = val.toFixed(decimalPlaces); if (!fixedDecimals) { str = str.replace(formatDecimalsRegExp, '$1'); } if (thousandsSeparator) { str = str.replace(formatThousandsRegExp, thousandsSeparator); } return str + unitSeparator + unit; } /** * Parse the string value into an integer in bytes. * * If no unit is given, it is assumed the value is in bytes. * * @param {number|string} val * * @returns {number|null} * @public */ function parse(val) { if (typeof val === 'number' && !isNaN(val)) { return val; } if (typeof val !== 'string') {
  • 109. return null; } // Test if the string passed is valid var results = parseRegExp.exec(val); var floatValue; var unit = 'b'; if (!results) { // Nothing could be extracted from the given string floatValue = parseInt(val, 10); unit = 'b' } else { // Retrieve the value and the unit floatValue = parseFloat(results[1]); unit = results[4].toLowerCase(); } return Math.floor(map[unit] * floatValue); } node_modules/bytes/LICENSE (The MIT License) Copyright (c) 2012-2014 TJ Holowaychuk <[email protected]> Copyright (c) 2015 Jed Watson <[email protected]> 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
  • 110. 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_modules/bytes/package.json { "_args": [ [ { "raw": "[email protected]", "scope": null, "escapedName": "bytes", "name": "bytes", "rawSpec": "2.4.0", "spec": "2.4.0", "type": "version" },
  • 111. "C:UsersraybDesktopCQU coursesT2- 2017COIT20260LabsLab 8Lab8node_modulesbody- parser" ] ], "_from": "[email protected]", "_id": "[email protected]", "_inCache": true, "_location": "/bytes", "_npmOperationalInternal": { "host": "packages-16-east.internal.npmjs.com", "tmp": "tmp/bytes- 2.4.0.tgz_1464812473023_0.6271433881483972" }, "_npmUser": { "name": "dougwilson", "email": "[email protected]" }, "_npmVersion": "1.4.28", "_phantomChildren": {}, "_requested": { "raw": "[email protected]", "scope": null, "escapedName": "bytes", "name": "bytes", "rawSpec": "2.4.0", "spec": "2.4.0", "type": "version" }, "_requiredBy": [ "/body-parser", "/raw-body" ], "_resolved": "https://registry.npmjs.org/bytes/-/bytes- 2.4.0.tgz", "_shasum": "7d97196f9d5baf7f6935e25985549edd2a6c2339",
  • 112. "_shrinkwrap": null, "_spec": "[email protected]", "_where": "C:UsersraybDesktopCQU coursesT2- 2017COIT20260LabsLab 8Lab8node_modulesbody- parser", "author": { "name": "TJ Holowaychuk", "email": "[email protected]", "url": "http://tjholowaychuk.com" }, "bugs": { "url": "https://github.com/visionmedia/bytes.js/issues" }, "component": { "scripts": { "bytes/index.js": "index.js" } }, "contributors": [ { "name": "Jed Watson", "email": "[email protected]" }, { "name": "Théo FIDRY", "email": "[email protected]" } ], "dependencies": {}, "description": "Utility to parse a string bytes to bytes and vice-versa", "devDependencies": { "mocha": "1.21.5" }, "directories": {}, "dist": {
  • 113. "shasum": "7d97196f9d5baf7f6935e25985549edd2a6c2339", "tarball": "https://registry.npmjs.org/bytes/-/bytes-2.4.0.tgz" }, "files": [ "History.md", "LICENSE", "Readme.md", "index.js" ], "gitHead": "2a598442bdfa796df8d01a96cc54495cda550e70", "homepage": "https://github.com/visionmedia/bytes.js", "keywords": [ "byte", "bytes", "utility", "parse", "parser", "convert", "converter" ], "license": "MIT", "maintainers": [ { "name": "dougwilson", "email": "[email protected]" }, { "name": "tjholowaychuk", "email": "[email protected]" } ], "name": "bytes", "optionalDependencies": {}, "readme": "ERROR: No README data found!", "repository": { "type": "git",
  • 114. "url": "git+https://github.com/visionmedia/bytes.js.git" }, "scripts": { "test": "mocha --check-leaks --reporter spec" }, "version": "2.4.0" } node_modules/bytes/Readme.md # Bytes utility [![NPM Version][npm-image]][npm-url] [![NPM Downloads][downloads-image]][downloads-url] [![Build Status][travis-image]][travis-url] Utility to parse a string bytes (ex: `1TB`) to bytes (`1099511627776`) and vice-versa. ## Usage ```js var bytes = require('bytes'); ``` #### bytes.format(number value, [options]): string|null Format the given value in bytes into a string. If the value is negative, it is kept as such. If it is a float, it is rounded. **Arguments** | Name | Type | Description | |---------|--------|--------------------| | value | `number` | Value in bytes |
  • 115. | options | `Object` | Conversion options | **Options** | Property | Type | Description | |-------------------|--------|---------------------------------------------- -------------------------------------------| | decimalPlaces | `number`&#124;`null` | Maximum number of decimal places to include in output. Default value to `2`. | | fixedDecimals | `boolean`&#124;`null` | Whether to always display the maximum number of decimal places. Default value to `false` | | thousandsSeparator | `string`&#124;`null` | Example of values: `' '`, `','` and `.`... Default value to `' '`. | | unitSeparator | `string`&#124;`null` | Separator to use between number and unit. Default value to `''`. | **Returns** | Name | Type | Description | |---------|-------------|-------------------------| | results | `string`&#124;`null` | Return null upon error. String value otherwise. | **Example** ```js bytes(1024); // output: '1kB' bytes(1000); // output: '1000B' bytes(1000, {thousandsSeparator: ' '}); // output: '1 000B'