Compare commits
No commits in common. "944207ed8a4d202bd791b057598eaaaf5b9ae112" and "7badd97610f9b022eea1c10389c3b9effd6f05ec" have entirely different histories.
944207ed8a
...
7badd97610
|
@ -2,12 +2,28 @@ const unzip = require('unzip-stream');
|
||||||
const csv = require('csv-parse');
|
const csv = require('csv-parse');
|
||||||
const axios = require('axios');
|
const axios = require('axios');
|
||||||
|
|
||||||
|
const overpassEndpoint = 'https://lz4.overpass-api.de/api/interpreter';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Submit an Overpass query.
|
||||||
|
*
|
||||||
|
* @async
|
||||||
|
* @param query Query in Overpass QL.
|
||||||
|
* @return Results as provided by the endpoint.
|
||||||
|
*/
|
||||||
|
const queryOverpass = query => axios.post(
|
||||||
|
overpassEndpoint,
|
||||||
|
'data=' + query
|
||||||
|
).then(res => res.data);
|
||||||
|
|
||||||
|
exports.queryOverpass = queryOverpass;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process a CSV stream to extract passings.
|
* Process a CSV stream to extract passings.
|
||||||
*
|
*
|
||||||
* @private
|
* @private
|
||||||
* @param csvStream Stream containing CSV data.
|
* @param csvStream Stream containing CSV data.
|
||||||
* @param callback See fetchRealtime for a description of the callback.
|
* @param callback See fetchTamRealtime for a description of the callback.
|
||||||
*/
|
*/
|
||||||
const processTamPassingStream = (csvStream, callback) =>
|
const processTamPassingStream = (csvStream, callback) =>
|
||||||
{
|
{
|
||||||
|
@ -58,14 +74,14 @@ const tamRealtimeEndpoint = 'http://data.montpellier3m.fr/node/10732/download';
|
||||||
* be non-null only if an error occurred. Second argument will contain passings
|
* be non-null only if an error occurred. Second argument will contain passings
|
||||||
* or be null if the end was reached.
|
* or be null if the end was reached.
|
||||||
*/
|
*/
|
||||||
const fetchRealtime = (callback) =>
|
const fetchTamRealtime = (callback) =>
|
||||||
{
|
{
|
||||||
axios.get(tamRealtimeEndpoint, {
|
axios.get(tamRealtimeEndpoint, {
|
||||||
responseType: 'stream'
|
responseType: 'stream'
|
||||||
}).then(res => processTamPassingStream(res.data, callback));
|
}).then(res => processTamPassingStream(res.data, callback));
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.fetchRealtime = fetchRealtime;
|
exports.fetchTamRealtime = fetchTamRealtime;
|
||||||
|
|
||||||
const tamTheoreticalEndpoint =
|
const tamTheoreticalEndpoint =
|
||||||
'http://data.montpellier3m.fr/node/10731/download';
|
'http://data.montpellier3m.fr/node/10731/download';
|
||||||
|
@ -78,7 +94,7 @@ const tamTheoreticalFileName = 'offre_du_jour.csv';
|
||||||
* be non-null only if an error occurred. Second argument will contain passings
|
* be non-null only if an error occurred. Second argument will contain passings
|
||||||
* or be null if the end was reached.
|
* or be null if the end was reached.
|
||||||
*/
|
*/
|
||||||
const fetchTheoretical = (callback) =>
|
const fetchTamTheoretical = (callback) =>
|
||||||
{
|
{
|
||||||
axios.get(tamTheoreticalEndpoint, {
|
axios.get(tamTheoreticalEndpoint, {
|
||||||
responseType: 'stream'
|
responseType: 'stream'
|
||||||
|
@ -101,4 +117,4 @@ const fetchTheoretical = (callback) =>
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.fetchTheoretical = fetchTheoretical;
|
exports.fetchTamTheoretical = fetchTamTheoretical;
|
|
@ -1,20 +1,21 @@
|
||||||
/**
|
|
||||||
* @file
|
|
||||||
*
|
|
||||||
* Extract static information about the TaM network from OpenStreetMap (OSM):
|
|
||||||
* tram and bus lines, stops and routes.
|
|
||||||
*
|
|
||||||
* Functions in this file also report and offer to correct errors that may
|
|
||||||
* occur in OSM data.
|
|
||||||
*
|
|
||||||
* Because of the static nature of this data, it is cached in a
|
|
||||||
* version-controlled file `network.json` next to this file. To update it, use
|
|
||||||
* the `script/update-network` script.
|
|
||||||
*/
|
|
||||||
|
|
||||||
const {choosePlural, joinSentence} = require('../util');
|
const {choosePlural, joinSentence} = require('../util');
|
||||||
const osm = require('./sources/osm');
|
const {queryOverpass, fetchTamTheoretical} = require('./endpoints');
|
||||||
const tam = require('./sources/tam');
|
|
||||||
|
const osmViewNode = 'https://www.openstreetmap.org/node';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a link to remotely add tags into JOSM.
|
||||||
|
*
|
||||||
|
* @param objectId Identifier for the object to add the tags to.
|
||||||
|
* @param tags Tags to add.
|
||||||
|
* @return Link for remotely adding the tags.
|
||||||
|
*/
|
||||||
|
const josmAddTagToNode = (objectId, tags) =>
|
||||||
|
'http://127.0.0.1:8111/load_object?' + [
|
||||||
|
`objects=n${objectId}`,
|
||||||
|
'new_layer=false',
|
||||||
|
'addtags=' + tags.join('%7C'),
|
||||||
|
].join('&');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use theoretical passings data to guess which lines use which stops in which
|
* Use theoretical passings data to guess which lines use which stops in which
|
||||||
|
@ -30,7 +31,7 @@ const fetchStopsRefAssociations = () => new Promise((res, rej) =>
|
||||||
{
|
{
|
||||||
const stops = {};
|
const stops = {};
|
||||||
|
|
||||||
tam.fetchTheoretical((err, row) =>
|
fetchTamTheoretical((err, row) =>
|
||||||
{
|
{
|
||||||
if (err)
|
if (err)
|
||||||
{
|
{
|
||||||
|
@ -122,7 +123,18 @@ const matchStopNames = (fullName, abbrName) =>
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetch stops and lines of the network.
|
* Determine if an OSM way is oneway or not.
|
||||||
|
*
|
||||||
|
* @param tags Set of tags of the way.
|
||||||
|
* @return True iff. the way is oneway.
|
||||||
|
*/
|
||||||
|
const isOneWay = tags =>
|
||||||
|
('oneway' in tags && tags.oneway === 'yes')
|
||||||
|
|| ('junction' in tags && tags.junction === 'roundabout')
|
||||||
|
|| ('highway' in tags && tags.highway === 'motorway');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch stops, segments and lines in the network.
|
||||||
*
|
*
|
||||||
* @param lineRefs List of lines to fetch.
|
* @param lineRefs List of lines to fetch.
|
||||||
* @return Object with a set of stops, segments and lines.
|
* @return Object with a set of stops, segments and lines.
|
||||||
|
@ -130,7 +142,7 @@ const matchStopNames = (fullName, abbrName) =>
|
||||||
const fetch = async (lineRefs) =>
|
const fetch = async (lineRefs) =>
|
||||||
{
|
{
|
||||||
// Retrieve routes, ways and stops from OpenStreetMap
|
// Retrieve routes, ways and stops from OpenStreetMap
|
||||||
const rawData = await osm.runQuery(`[out:json];
|
const rawData = await queryOverpass(`[out:json];
|
||||||
|
|
||||||
// Find the public transport line bearing the requested reference
|
// Find the public transport line bearing the requested reference
|
||||||
relation[network="TaM"][type="route_master"][ref~"^(${lineRefs.join('|')})$"];
|
relation[network="TaM"][type="route_master"][ref~"^(${lineRefs.join('|')})$"];
|
||||||
|
@ -148,7 +160,9 @@ out body qt;
|
||||||
const elementsList = rawData.elements;
|
const elementsList = rawData.elements;
|
||||||
|
|
||||||
// List of retrieved lines
|
// List of retrieved lines
|
||||||
const routeMasters = elementsList.filter(osm.isTransportLine);
|
const routeMasters = elementsList.filter(elt =>
|
||||||
|
elt.tags && elt.tags.type === 'route_master'
|
||||||
|
);
|
||||||
|
|
||||||
// Retrieved objects indexed by ID
|
// Retrieved objects indexed by ID
|
||||||
const elements = elementsList.reduce((prev, elt) =>
|
const elements = elementsList.reduce((prev, elt) =>
|
||||||
|
@ -185,7 +199,7 @@ out body qt;
|
||||||
console.warn(`Stop ${stop.id} is missing a “ref” tag
|
console.warn(`Stop ${stop.id} is missing a “ref” tag
|
||||||
Name: ${stop.tags.name}
|
Name: ${stop.tags.name}
|
||||||
Part of line: ${route.tags.name}
|
Part of line: ${route.tags.name}
|
||||||
URI: ${osm.viewNode(stop.id)}
|
URI: ${osmViewNode}/${stop.id}
|
||||||
`);
|
`);
|
||||||
|
|
||||||
// Try to identify stops matching this stop in the
|
// Try to identify stops matching this stop in the
|
||||||
|
@ -239,7 +253,7 @@ URI: ${osm.viewNode(stop.id)}
|
||||||
${choosePlural(candidate.lines.length, 'line', '.s')} \
|
${choosePlural(candidate.lines.length, 'line', '.s')} \
|
||||||
${joinSentence(Array.from(candidate.lines), ', ', ' and ')} going to \
|
${joinSentence(Array.from(candidate.lines), ', ', ' and ')} going to \
|
||||||
${joinSentence(Array.from(candidate.directions), ', ', ' or ')}
|
${joinSentence(Array.from(candidate.directions), ', ', ' or ')}
|
||||||
Apply in JOSM: ${osm.addTagsToNode(stop.id, ['ref=' + candidate.stopRef])}
|
Apply in JOSM: ${josmAddTagToNode(stop.id, ['ref=' + candidate.stopRef])}
|
||||||
`);
|
`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -269,7 +283,11 @@ ${joinSentence(Array.from(candidate.directions), ', ', ' or ')}
|
||||||
|
|
||||||
for (let route of rawRoutes)
|
for (let route of rawRoutes)
|
||||||
{
|
{
|
||||||
const {from, to, name} = route.tags;
|
const {from, to} = route.tags;
|
||||||
|
|
||||||
|
// Human-readable description of the route for errors
|
||||||
|
const routeDescription = `line ${lineRef}’s route from \
|
||||||
|
“${route.tags.from}” to “${route.tags.to}”`;
|
||||||
|
|
||||||
// Check that the route consists of a block of stops and platforms
|
// Check that the route consists of a block of stops and platforms
|
||||||
// followed by a block of routes as dictated by PTv2
|
// followed by a block of routes as dictated by PTv2
|
||||||
|
@ -282,7 +300,7 @@ ${joinSentence(Array.from(candidate.directions), ', ', ' or ')}
|
||||||
))
|
))
|
||||||
{
|
{
|
||||||
throw new Error(`Members with invalid roles in between stops
|
throw new Error(`Members with invalid roles in between stops
|
||||||
of ${name}`);
|
of ${routeDescription}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!route.members.slice(relationPivot).every(
|
if (!route.members.slice(relationPivot).every(
|
||||||
|
@ -290,7 +308,7 @@ of ${name}`);
|
||||||
))
|
))
|
||||||
{
|
{
|
||||||
throw new Error(`Members with invalid roles inside the path
|
throw new Error(`Members with invalid roles inside the path
|
||||||
of ${name}`);
|
of ${routeDescription}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// List of stops in the route, expected to be in the timetable
|
// List of stops in the route, expected to be in the timetable
|
||||||
|
@ -311,8 +329,8 @@ of ${name}`);
|
||||||
|
|
||||||
for (let wayIndex = 0; wayIndex < ways.length; wayIndex += 1)
|
for (let wayIndex = 0; wayIndex < ways.length; wayIndex += 1)
|
||||||
{
|
{
|
||||||
const way = elements[ways[wayIndex]];
|
const {nodes: wayNodes, tags: wayTags}
|
||||||
const {nodes: wayNodes, tags: wayTags} = way;
|
= elements[ways[wayIndex]];
|
||||||
const wayNodesSet = new Set(wayNodes);
|
const wayNodesSet = new Set(wayNodes);
|
||||||
|
|
||||||
const curNodeIndex = wayNodes.indexOf(currentNode);
|
const curNodeIndex = wayNodes.indexOf(currentNode);
|
||||||
|
@ -330,7 +348,7 @@ of ${name}`);
|
||||||
if (nextNodeCandidates.length !== 1)
|
if (nextNodeCandidates.length !== 1)
|
||||||
{
|
{
|
||||||
throw new Error(`There should be exactly one point
|
throw new Error(`There should be exactly one point
|
||||||
connecting way n°${wayIndex} and way n°${wayIndex + 1} in ${name},
|
connecting way n°${wayIndex} and way n°${wayIndex + 1} in ${routeDescription},
|
||||||
but there are ${nextNodeCandidates.length}`);
|
but there are ${nextNodeCandidates.length}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -352,10 +370,10 @@ but there are ${nextNodeCandidates.length}`);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Use the way in the reverse direction
|
// Use the way in the reverse direction
|
||||||
if (osm.isOneWay(way))
|
if (isOneWay(wayTags))
|
||||||
{
|
{
|
||||||
throw new Error(`Way n°${wayIndex} in
|
throw new Error(`Way n°${wayIndex} in
|
||||||
${name} is one-way and cannot be used in reverse.`);
|
${routeDescription} is one-way and cannot be used in reverse.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
path = path.concat(
|
path = path.concat(
|
||||||
|
@ -374,7 +392,7 @@ ${name} is one-way and cannot be used in reverse.`);
|
||||||
{
|
{
|
||||||
segments.push(path.slice(
|
segments.push(path.slice(
|
||||||
path.indexOf(stops[stopIndex]),
|
path.indexOf(stops[stopIndex]),
|
||||||
path.indexOf(stops[stopIndex + 1]) + 1,
|
path.indexOf(stops[stopIndex + 1] + 1),
|
||||||
).map(id => ({
|
).map(id => ({
|
||||||
lat: elements[id].lat,
|
lat: elements[id].lat,
|
||||||
lon: elements[id].lon
|
lon: elements[id].lon
|
||||||
|
@ -382,7 +400,8 @@ ${name} is one-way and cannot be used in reverse.`);
|
||||||
}
|
}
|
||||||
|
|
||||||
routes.push({
|
routes.push({
|
||||||
from, to, name,
|
from, to,
|
||||||
|
name: route.tags.name,
|
||||||
segments,
|
segments,
|
||||||
stops: stops.map(id => elements[id].tags.ref),
|
stops: stops.map(id => elements[id].tags.ref),
|
||||||
});
|
});
|
||||||
|
|
238591
back/data/network.json
238591
back/data/network.json
File diff suppressed because it is too large
Load Diff
|
@ -1,89 +0,0 @@
|
||||||
/**
|
|
||||||
* @file
|
|
||||||
*
|
|
||||||
* Interface with the OpenStreetMap collaborative mapping database.
|
|
||||||
*/
|
|
||||||
|
|
||||||
const axios = require('axios');
|
|
||||||
const {isObject} = require('../../util');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Submit a query to an Overpass endpoint.
|
|
||||||
*
|
|
||||||
* See <https://wiki.openstreetmap.org/wiki/Overpass_API/Overpass_QL> for more
|
|
||||||
* information on the Overpass Query Language (Overpass QL).
|
|
||||||
*
|
|
||||||
* @async
|
|
||||||
* @param query Query to send.
|
|
||||||
* @param [endpoint] Overpass endpoint to use.
|
|
||||||
* @return Results returned by the endpoint. If JSON output is requested in
|
|
||||||
* the query, the result will automatically be parsed into a JS object.
|
|
||||||
*/
|
|
||||||
const runQuery = (
|
|
||||||
query,
|
|
||||||
endpoint = 'https://lz4.overpass-api.de/api/interpreter'
|
|
||||||
) => axios.post(endpoint, 'data=' + query)
|
|
||||||
.then(res => res.data);
|
|
||||||
|
|
||||||
exports.runQuery = runQuery;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a link to add tags into JOSM.
|
|
||||||
*
|
|
||||||
* The JOSM remote control must be activated and JOSM must be running for this
|
|
||||||
* link to work. See <https://wiki.openstreetmap.org/wiki/JOSM/RemoteControl>.
|
|
||||||
*
|
|
||||||
* @param id Identifier for the object to add the tags to.
|
|
||||||
* @param tags List of tags to add, in the `key=value` format.
|
|
||||||
* @return Link for remotely adding the tags.
|
|
||||||
*/
|
|
||||||
const addTagsToNode = (id, tags) =>
|
|
||||||
'http://127.0.0.1:8111/load_object?' + [
|
|
||||||
`objects=n${id}`,
|
|
||||||
'new_layer=false',
|
|
||||||
'addtags=' + tags.join('%7C'),
|
|
||||||
].join('&');
|
|
||||||
|
|
||||||
exports.addTagsToNode = addTagsToNode;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a link to view a node.
|
|
||||||
*
|
|
||||||
* @param id Identifier for the node to view.
|
|
||||||
* @return Link to view this node on the OSM website.
|
|
||||||
*/
|
|
||||||
const viewNode = id => `https://www.openstreetmap.org/node/${id}`;
|
|
||||||
|
|
||||||
exports.viewNode = viewNode;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determine if an OSM way is one-way or not.
|
|
||||||
*
|
|
||||||
* See <https://wiki.openstreetmap.org/wiki/Key:oneway> for details.
|
|
||||||
*
|
|
||||||
* @param tags Set of tags of the way.
|
|
||||||
* @return True iff. the way is one-way.
|
|
||||||
*/
|
|
||||||
const isOneWay = object =>
|
|
||||||
object.type === 'way'
|
|
||||||
&& isObject(object.tags)
|
|
||||||
&& (object.tags.oneway === 'yes' || object.tags.junction === 'roundabout'
|
|
||||||
|| object.tags.highway === 'motorway');
|
|
||||||
|
|
||||||
exports.isOneWay = isOneWay;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determine if an OSM object is a public transport line (route master).
|
|
||||||
*
|
|
||||||
* See <https://wiki.openstreetmap.org/wiki/Relation:route_master>
|
|
||||||
* and <https://wiki.openstreetmap.org/wiki/Public_transport#Route_Master_relations>.
|
|
||||||
*
|
|
||||||
* @param object OSM object.
|
|
||||||
* @return True iff. the relation is a public transport line.
|
|
||||||
*/
|
|
||||||
const isTransportLine = object =>
|
|
||||||
object.type === 'relation'
|
|
||||||
&& isObject(object.tags)
|
|
||||||
&& object.tags.type === 'route_master';
|
|
||||||
|
|
||||||
exports.isTransportLine = isTransportLine;
|
|
10
back/util.js
10
back/util.js
|
@ -58,13 +58,3 @@ const joinSentence = (array, separator, lastSeparator) =>
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.joinSentence = joinSentence;
|
exports.joinSentence = joinSentence;
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if a value is a JS object.
|
|
||||||
*
|
|
||||||
* @param value Value to check.
|
|
||||||
* @return True iff. `value` is a JS object.
|
|
||||||
*/
|
|
||||||
const isObject = value => value !== null && typeof value === 'object';
|
|
||||||
|
|
||||||
exports.isObject = isObject;
|
|
||||||
|
|
|
@ -1907,16 +1907,6 @@
|
||||||
"qs": "6.7.0",
|
"qs": "6.7.0",
|
||||||
"raw-body": "2.4.0",
|
"raw-body": "2.4.0",
|
||||||
"type-is": "~1.6.17"
|
"type-is": "~1.6.17"
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"debug": {
|
|
||||||
"version": "2.6.9",
|
|
||||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
|
||||||
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
|
||||||
"requires": {
|
|
||||||
"ms": "2.0.0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"boolbase": {
|
"boolbase": {
|
||||||
|
@ -3070,9 +3060,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"debug": {
|
"debug": {
|
||||||
"version": "3.1.0",
|
"version": "2.6.9",
|
||||||
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
||||||
"integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
|
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"ms": "2.0.0"
|
"ms": "2.0.0"
|
||||||
}
|
}
|
||||||
|
@ -3689,15 +3679,6 @@
|
||||||
"to-regex": "^3.0.1"
|
"to-regex": "^3.0.1"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"debug": {
|
|
||||||
"version": "2.6.9",
|
|
||||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
|
||||||
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"ms": "2.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"define-property": {
|
"define-property": {
|
||||||
"version": "0.2.5",
|
"version": "0.2.5",
|
||||||
"resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
|
"resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
|
||||||
|
@ -3753,16 +3734,6 @@
|
||||||
"type-is": "~1.6.18",
|
"type-is": "~1.6.18",
|
||||||
"utils-merge": "1.0.1",
|
"utils-merge": "1.0.1",
|
||||||
"vary": "~1.1.2"
|
"vary": "~1.1.2"
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"debug": {
|
|
||||||
"version": "2.6.9",
|
|
||||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
|
||||||
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
|
||||||
"requires": {
|
|
||||||
"ms": "2.0.0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"extend": {
|
"extend": {
|
||||||
|
@ -4006,16 +3977,6 @@
|
||||||
"parseurl": "~1.3.3",
|
"parseurl": "~1.3.3",
|
||||||
"statuses": "~1.5.0",
|
"statuses": "~1.5.0",
|
||||||
"unpipe": "~1.0.0"
|
"unpipe": "~1.0.0"
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"debug": {
|
|
||||||
"version": "2.6.9",
|
|
||||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
|
||||||
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
|
||||||
"requires": {
|
|
||||||
"ms": "2.0.0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"flat-cache": {
|
"flat-cache": {
|
||||||
|
@ -4041,6 +4002,16 @@
|
||||||
"integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==",
|
"integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"debug": "=3.1.0"
|
"debug": "=3.1.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"debug": {
|
||||||
|
"version": "3.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
|
||||||
|
"integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
|
||||||
|
"requires": {
|
||||||
|
"ms": "2.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"for-in": {
|
"for-in": {
|
||||||
|
@ -7332,21 +7303,6 @@
|
||||||
"statuses": "~1.5.0"
|
"statuses": "~1.5.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"debug": {
|
|
||||||
"version": "2.6.9",
|
|
||||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
|
||||||
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
|
||||||
"requires": {
|
|
||||||
"ms": "2.0.0"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"ms": {
|
|
||||||
"version": "2.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
|
||||||
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"ms": {
|
"ms": {
|
||||||
"version": "2.1.1",
|
"version": "2.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
|
||||||
|
@ -7485,15 +7441,6 @@
|
||||||
"use": "^3.1.0"
|
"use": "^3.1.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"debug": {
|
|
||||||
"version": "2.6.9",
|
|
||||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
|
||||||
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"ms": "2.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"define-property": {
|
"define-property": {
|
||||||
"version": "0.2.5",
|
"version": "0.2.5",
|
||||||
"resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
|
"resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
|
||||||
|
@ -8200,17 +8147,6 @@
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"debug": "^2.2.0"
|
"debug": "^2.2.0"
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"debug": {
|
|
||||||
"version": "2.6.9",
|
|
||||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
|
||||||
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
|
||||||
"ms": "2.0.0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"unicode-canonical-property-names-ecmascript": {
|
"unicode-canonical-property-names-ecmascript": {
|
||||||
|
|
Loading…
Reference in New Issue