mapshaper 0.6.13 → 0.6.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/mapshaper.js +434 -225
- package/package.json +10 -7
- package/www/basemap.js +2 -2
- package/www/mapshaper-gui.js +151 -93
- package/www/mapshaper.js +434 -225
- package/www/modules.js +904 -2
package/mapshaper.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
(function () {
|
|
2
2
|
|
|
3
|
-
var VERSION = "0.6.
|
|
3
|
+
var VERSION = "0.6.15";
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
var utils = /*#__PURE__*/Object.freeze({
|
|
@@ -5560,7 +5560,9 @@
|
|
|
5560
5560
|
len = _nn[absId];
|
|
5561
5561
|
if (nth < 0) nth = len + nth;
|
|
5562
5562
|
if (absId != arcId) nth = len - nth - 1;
|
|
5563
|
-
if (nth < 0 || nth >= len)
|
|
5563
|
+
if (nth < 0 || nth >= len) {
|
|
5564
|
+
error("[ArcCollection] out-of-range vertex id");
|
|
5565
|
+
}
|
|
5564
5566
|
return _ii[absId] + nth;
|
|
5565
5567
|
};
|
|
5566
5568
|
|
|
@@ -7066,15 +7068,6 @@
|
|
|
7066
7068
|
transformPoints: transformPoints
|
|
7067
7069
|
});
|
|
7068
7070
|
|
|
7069
|
-
function runningInBrowser() {
|
|
7070
|
-
return typeof window !== 'undefined' && typeof window.document !== 'undefined';
|
|
7071
|
-
}
|
|
7072
|
-
|
|
7073
|
-
var Env = /*#__PURE__*/Object.freeze({
|
|
7074
|
-
__proto__: null,
|
|
7075
|
-
runningInBrowser: runningInBrowser
|
|
7076
|
-
});
|
|
7077
|
-
|
|
7078
7071
|
function getPathSep(path) {
|
|
7079
7072
|
// TODO: improve
|
|
7080
7073
|
return path.indexOf('/') == -1 && path.indexOf('\\') != -1 ? '\\' : '/';
|
|
@@ -7127,6 +7120,11 @@
|
|
|
7127
7120
|
return getPathBase(path) + '.' + ext;
|
|
7128
7121
|
}
|
|
7129
7122
|
|
|
7123
|
+
function toLowerCaseExtension(name) {
|
|
7124
|
+
var ext = getFileExtension(name);
|
|
7125
|
+
return ext ? getPathBase(name) + '.' + ext.toLowerCase() : name;
|
|
7126
|
+
}
|
|
7127
|
+
|
|
7130
7128
|
function getCommonFileBase(names) {
|
|
7131
7129
|
return names.reduce(function(memo, name, i) {
|
|
7132
7130
|
if (i === 0) {
|
|
@@ -7150,10 +7148,164 @@
|
|
|
7150
7148
|
getFileExtension: getFileExtension,
|
|
7151
7149
|
getPathBase: getPathBase,
|
|
7152
7150
|
replaceFileExtension: replaceFileExtension,
|
|
7151
|
+
toLowerCaseExtension: toLowerCaseExtension,
|
|
7153
7152
|
getCommonFileBase: getCommonFileBase,
|
|
7154
7153
|
getOutputFileBase: getOutputFileBase
|
|
7155
7154
|
});
|
|
7156
7155
|
|
|
7156
|
+
// Guess the type of a data file from file extension, or return null if not sure
|
|
7157
|
+
function guessInputFileType(file) {
|
|
7158
|
+
var ext = getFileExtension(file || '').toLowerCase(),
|
|
7159
|
+
type = null;
|
|
7160
|
+
if (ext == 'dbf' || ext == 'shp' || ext == 'prj' || ext == 'shx' || ext == 'kml' || ext == 'cpg') {
|
|
7161
|
+
type = ext;
|
|
7162
|
+
} else if (/json$/.test(ext)) {
|
|
7163
|
+
type = 'json';
|
|
7164
|
+
} else if (ext == 'csv' || ext == 'tsv' || ext == 'txt' || ext == 'tab') {
|
|
7165
|
+
type = 'text';
|
|
7166
|
+
}
|
|
7167
|
+
return type;
|
|
7168
|
+
}
|
|
7169
|
+
|
|
7170
|
+
function guessInputContentType(content) {
|
|
7171
|
+
var type = null;
|
|
7172
|
+
if (utils.isString(content)) {
|
|
7173
|
+
type = stringLooksLikeJSON(content) && 'json' ||
|
|
7174
|
+
stringLooksLikeKML(content) && 'kml' || 'text';
|
|
7175
|
+
} else if (utils.isObject(content) && content.type || utils.isArray(content)) {
|
|
7176
|
+
type = 'json';
|
|
7177
|
+
}
|
|
7178
|
+
return type;
|
|
7179
|
+
}
|
|
7180
|
+
|
|
7181
|
+
function guessInputType(file, content) {
|
|
7182
|
+
return guessInputFileType(file) || guessInputContentType(content);
|
|
7183
|
+
}
|
|
7184
|
+
|
|
7185
|
+
function stringLooksLikeJSON(str) {
|
|
7186
|
+
return /^\s*[{[]/.test(String(str));
|
|
7187
|
+
}
|
|
7188
|
+
|
|
7189
|
+
function stringLooksLikeKML(str) {
|
|
7190
|
+
str = String(str);
|
|
7191
|
+
return str.includes('<kml ') && str.includes('xmlns="http://www.opengis.net/kml/');
|
|
7192
|
+
}
|
|
7193
|
+
|
|
7194
|
+
function couldBeDsvFile(name) {
|
|
7195
|
+
var ext = getFileExtension(name).toLowerCase();
|
|
7196
|
+
return /csv|tsv|txt$/.test(ext);
|
|
7197
|
+
}
|
|
7198
|
+
|
|
7199
|
+
function isZipFile(file) {
|
|
7200
|
+
return /\.zip$/i.test(file);
|
|
7201
|
+
}
|
|
7202
|
+
|
|
7203
|
+
function isKmzFile(file) {
|
|
7204
|
+
return /\.kmz$/i.test(file);
|
|
7205
|
+
}
|
|
7206
|
+
|
|
7207
|
+
function isSupportedOutputFormat(fmt) {
|
|
7208
|
+
var types = ['geojson', 'topojson', 'json', 'dsv', 'dbf', 'shapefile', 'svg', 'kml'];
|
|
7209
|
+
return types.indexOf(fmt) > -1;
|
|
7210
|
+
}
|
|
7211
|
+
|
|
7212
|
+
function getFormatName(fmt) {
|
|
7213
|
+
return {
|
|
7214
|
+
geojson: 'GeoJSON',
|
|
7215
|
+
topojson: 'TopoJSON',
|
|
7216
|
+
json: 'JSON records',
|
|
7217
|
+
dsv: 'CSV',
|
|
7218
|
+
dbf: 'DBF',
|
|
7219
|
+
kml: 'KML',
|
|
7220
|
+
kmz: 'KMZ',
|
|
7221
|
+
shapefile: 'Shapefile',
|
|
7222
|
+
svg: 'SVG'
|
|
7223
|
+
}[fmt] || '';
|
|
7224
|
+
}
|
|
7225
|
+
|
|
7226
|
+
// Assumes file at @path is one of Mapshaper's supported file types
|
|
7227
|
+
function isSupportedBinaryInputType(path) {
|
|
7228
|
+
var ext = getFileExtension(path).toLowerCase();
|
|
7229
|
+
return ext == 'shp' || ext == 'shx' || ext == 'dbf'; // GUI also supports zip files
|
|
7230
|
+
}
|
|
7231
|
+
|
|
7232
|
+
// Detect extensions of some unsupported file types, for cmd line validation
|
|
7233
|
+
function filenameIsUnsupportedOutputType(file) {
|
|
7234
|
+
var rxp = /\.(shx|prj|xls|xlsx|gdb|sbn|sbx|xml)$/i;
|
|
7235
|
+
return rxp.test(file);
|
|
7236
|
+
}
|
|
7237
|
+
|
|
7238
|
+
var FileTypes = /*#__PURE__*/Object.freeze({
|
|
7239
|
+
__proto__: null,
|
|
7240
|
+
guessInputFileType: guessInputFileType,
|
|
7241
|
+
guessInputContentType: guessInputContentType,
|
|
7242
|
+
guessInputType: guessInputType,
|
|
7243
|
+
stringLooksLikeJSON: stringLooksLikeJSON,
|
|
7244
|
+
stringLooksLikeKML: stringLooksLikeKML,
|
|
7245
|
+
couldBeDsvFile: couldBeDsvFile,
|
|
7246
|
+
isZipFile: isZipFile,
|
|
7247
|
+
isKmzFile: isKmzFile,
|
|
7248
|
+
isSupportedOutputFormat: isSupportedOutputFormat,
|
|
7249
|
+
getFormatName: getFormatName,
|
|
7250
|
+
isSupportedBinaryInputType: isSupportedBinaryInputType,
|
|
7251
|
+
filenameIsUnsupportedOutputType: filenameIsUnsupportedOutputType
|
|
7252
|
+
});
|
|
7253
|
+
|
|
7254
|
+
// input: input file path or a Buffer containing .zip file bytes
|
|
7255
|
+
// cache: destination for extracted file contents
|
|
7256
|
+
function extractFiles(input, cache) {
|
|
7257
|
+
var zip = new require('adm-zip')(input);
|
|
7258
|
+
var files = zip.getEntries().map(function(entry) {
|
|
7259
|
+
// entry.entryName // path, including filename
|
|
7260
|
+
// entry.name // filename
|
|
7261
|
+
var file = toLowerCaseExtension(entry.name);
|
|
7262
|
+
if (file[0] == '.') return ''; // skip hidden system file
|
|
7263
|
+
var type = guessInputFileType(file);
|
|
7264
|
+
if (!type) return ''; // skip unrecognized extensions
|
|
7265
|
+
cache[file] = entry.getData();
|
|
7266
|
+
return file;
|
|
7267
|
+
});
|
|
7268
|
+
// remove auxiliary files from the import list
|
|
7269
|
+
// (these are files that can't be converted into datasets);
|
|
7270
|
+
return files.filter(function(file) {
|
|
7271
|
+
if (!file) return false;
|
|
7272
|
+
var type = guessInputFileType(file);
|
|
7273
|
+
if (type == 'dbf') {
|
|
7274
|
+
// don't import .dbf separately if .shp is present
|
|
7275
|
+
if (replaceFileExtension(file, 'shp') in cache) return false;
|
|
7276
|
+
}
|
|
7277
|
+
return type == 'text' || type == 'json' || type == 'shp' || type == 'dbf' || type == 'kml';
|
|
7278
|
+
});
|
|
7279
|
+
}
|
|
7280
|
+
|
|
7281
|
+
function convertOutputFiles(files, opts) {
|
|
7282
|
+
var filename = opts.zipfile || 'output.zip';
|
|
7283
|
+
var dirname = parseLocalPath(filename).basename;
|
|
7284
|
+
var zip = new require('adm-zip')();
|
|
7285
|
+
files.forEach(function(o) {
|
|
7286
|
+
var ofile = require('path').join(dirname, o.filename);
|
|
7287
|
+
var buf = Buffer.from(o.content);
|
|
7288
|
+
if (buf instanceof ArrayBuffer) {
|
|
7289
|
+
buf = new Uint8Array(buf);
|
|
7290
|
+
}
|
|
7291
|
+
zip.addFile(ofile, buf);
|
|
7292
|
+
delete o.content; // for gc?
|
|
7293
|
+
});
|
|
7294
|
+
return [{
|
|
7295
|
+
filename: filename,
|
|
7296
|
+
content: zip.toBuffer()
|
|
7297
|
+
}];
|
|
7298
|
+
}
|
|
7299
|
+
|
|
7300
|
+
function runningInBrowser() {
|
|
7301
|
+
return typeof window !== 'undefined' && typeof window.document !== 'undefined';
|
|
7302
|
+
}
|
|
7303
|
+
|
|
7304
|
+
var Env = /*#__PURE__*/Object.freeze({
|
|
7305
|
+
__proto__: null,
|
|
7306
|
+
runningInBrowser: runningInBrowser
|
|
7307
|
+
});
|
|
7308
|
+
|
|
7157
7309
|
var cli = {};
|
|
7158
7310
|
|
|
7159
7311
|
cli.isFile = function(path, cache) {
|
|
@@ -7163,6 +7315,13 @@
|
|
|
7163
7315
|
return ss && ss.isFile() || false;
|
|
7164
7316
|
};
|
|
7165
7317
|
|
|
7318
|
+
cli.checkCommandEnv = function(cname) {
|
|
7319
|
+
var blocked = ['i', 'include', 'require', 'external'];
|
|
7320
|
+
if (runningInBrowser() && blocked.includes(cname)) {
|
|
7321
|
+
stop('The -' + cname + ' command cannot be run in the browser');
|
|
7322
|
+
}
|
|
7323
|
+
};
|
|
7324
|
+
|
|
7166
7325
|
// cli.fileSize = function(path) {
|
|
7167
7326
|
// var ss = cli.statSync(path);
|
|
7168
7327
|
// return ss && ss.size || 0;
|
|
@@ -7303,6 +7462,9 @@
|
|
|
7303
7462
|
// trigger EAGAIN error, e.g. when piped to less)
|
|
7304
7463
|
return cli.writeFile('/dev/stdout', exports[0].content, cb);
|
|
7305
7464
|
} else {
|
|
7465
|
+
if (opts.zip) {
|
|
7466
|
+
exports = convertOutputFiles(exports, opts);
|
|
7467
|
+
}
|
|
7306
7468
|
var paths = getOutputPaths(utils.pluck(exports, 'filename'), opts);
|
|
7307
7469
|
var inputFiles = getStashedVar('input_files');
|
|
7308
7470
|
exports.forEach(function(obj, i) {
|
|
@@ -7312,7 +7474,7 @@
|
|
|
7312
7474
|
obj.content = cli.convertArrayBuffer(obj.content); // convert to Buffer
|
|
7313
7475
|
}
|
|
7314
7476
|
if (opts.gzip) {
|
|
7315
|
-
path = path + '.gz';
|
|
7477
|
+
path = /gz$/i.test(path) ? path : path + '.gz';
|
|
7316
7478
|
obj.content = require$1('zlib').gzipSync(obj.content);
|
|
7317
7479
|
}
|
|
7318
7480
|
if (opts.output) {
|
|
@@ -8080,55 +8242,71 @@
|
|
|
8080
8242
|
getFormattedStringify: getFormattedStringify
|
|
8081
8243
|
});
|
|
8082
8244
|
|
|
8083
|
-
|
|
8084
|
-
|
|
8085
|
-
|
|
8086
|
-
|
|
8245
|
+
function isValidArc(arcId, arcs) {
|
|
8246
|
+
// check for arcs with no vertices
|
|
8247
|
+
// TODO: also check for other kinds of degenerate arcs
|
|
8248
|
+
// (e.g. collapsed arcs consisting of identical points)
|
|
8249
|
+
return arcs.getArcLength(arcId) > 1;
|
|
8250
|
+
}
|
|
8251
|
+
|
|
8252
|
+
// Return id of rightmost connected arc in relation to @fromArcId
|
|
8253
|
+
// Return @fromArcId if no arcs can be found
|
|
8254
|
+
function getRightmostArc(fromArcId, nodes, filter) {
|
|
8255
|
+
var arcs = nodes.arcs,
|
|
8256
|
+
coords = arcs.getVertexData(),
|
|
8257
|
+
xx = coords.xx,
|
|
8258
|
+
yy = coords.yy,
|
|
8259
|
+
ids = nodes.getConnectedArcs(fromArcId),
|
|
8260
|
+
toArcId = fromArcId; // initialize to fromArcId -- an error condition
|
|
8261
|
+
|
|
8087
8262
|
if (filter) {
|
|
8088
8263
|
ids = ids.filter(filter);
|
|
8089
8264
|
}
|
|
8090
|
-
|
|
8091
|
-
|
|
8265
|
+
|
|
8266
|
+
if (!isValidArc(fromArcId, arcs) || ids.length === 0) {
|
|
8267
|
+
return fromArcId;
|
|
8092
8268
|
}
|
|
8093
|
-
return getRighmostArc2(arcId, ids, nodes.arcs);
|
|
8094
|
-
}
|
|
8095
8269
|
|
|
8096
|
-
|
|
8097
|
-
var coords = arcs.getVertexData(),
|
|
8098
|
-
xx = coords.xx,
|
|
8099
|
-
yy = coords.yy,
|
|
8100
|
-
inode = arcs.indexOfVertex(fromId, -1),
|
|
8270
|
+
var inode = arcs.indexOfVertex(fromArcId, -1),
|
|
8101
8271
|
nodeX = xx[inode],
|
|
8102
8272
|
nodeY = yy[inode],
|
|
8103
|
-
ifrom = arcs.indexOfVertex(
|
|
8273
|
+
ifrom = arcs.indexOfVertex(fromArcId, -2),
|
|
8104
8274
|
fromX = xx[ifrom],
|
|
8105
8275
|
fromY = yy[ifrom],
|
|
8106
|
-
toId = fromId, // initialize to from-arc -- an error
|
|
8107
8276
|
ito, candId, icand, code, j;
|
|
8108
8277
|
|
|
8109
8278
|
/*if (x == ax && y == ay) {
|
|
8110
8279
|
error("Duplicate point error");
|
|
8111
8280
|
}*/
|
|
8112
|
-
if (ids.length > 0) {
|
|
8113
|
-
toId = ids[0];
|
|
8114
|
-
ito = arcs.indexOfVertex(toId, -2);
|
|
8115
|
-
}
|
|
8116
8281
|
|
|
8117
|
-
|
|
8282
|
+
|
|
8283
|
+
for (j=0; j<ids.length; j++) {
|
|
8118
8284
|
candId = ids[j];
|
|
8285
|
+
if (!isValidArc(candId, arcs)) {
|
|
8286
|
+
// skip empty arcs
|
|
8287
|
+
continue;
|
|
8288
|
+
}
|
|
8119
8289
|
icand = arcs.indexOfVertex(candId, -2);
|
|
8290
|
+
|
|
8291
|
+
if (toArcId == fromArcId) {
|
|
8292
|
+
// first valid candidate
|
|
8293
|
+
ito = icand;
|
|
8294
|
+
toArcId = candId;
|
|
8295
|
+
continue;
|
|
8296
|
+
}
|
|
8297
|
+
|
|
8120
8298
|
code = chooseRighthandPath(fromX, fromY, nodeX, nodeY, xx[ito], yy[ito], xx[icand], yy[icand]);
|
|
8121
|
-
// code = internal.chooseRighthandPath(0, 0, nodeX - fromX, nodeY - fromY, xx[ito] - fromX, yy[ito] - fromY, xx[icand] - fromX, yy[icand] - fromY);
|
|
8122
8299
|
if (code == 2) {
|
|
8123
|
-
toId = candId;
|
|
8124
8300
|
ito = icand;
|
|
8301
|
+
toArcId = candId;
|
|
8125
8302
|
}
|
|
8126
8303
|
}
|
|
8127
|
-
|
|
8304
|
+
|
|
8305
|
+
if (toArcId == fromArcId) {
|
|
8128
8306
|
// This shouldn't occur, assuming that other arcs are present
|
|
8129
8307
|
error("Pathfinder error");
|
|
8130
8308
|
}
|
|
8131
|
-
return
|
|
8309
|
+
return toArcId;
|
|
8132
8310
|
}
|
|
8133
8311
|
|
|
8134
8312
|
function chooseRighthandPath2(fromX, fromY, nodeX, nodeY, ax, ay, bx, by) {
|
|
@@ -8327,11 +8505,19 @@
|
|
|
8327
8505
|
return ~getRightmostArc(prevId, nodes, testArc);
|
|
8328
8506
|
}
|
|
8329
8507
|
|
|
8508
|
+
function isEmptyArc(id) {
|
|
8509
|
+
return nodes.arcs.getArcLength(id) > 1 === false;
|
|
8510
|
+
}
|
|
8511
|
+
|
|
8330
8512
|
return function(startId) {
|
|
8331
8513
|
var path = [],
|
|
8332
8514
|
nextId, msg,
|
|
8333
8515
|
candId = startId;
|
|
8334
8516
|
|
|
8517
|
+
if (isEmptyArc(startId)) {
|
|
8518
|
+
return null;
|
|
8519
|
+
}
|
|
8520
|
+
|
|
8335
8521
|
do {
|
|
8336
8522
|
if (useRoute(candId)) {
|
|
8337
8523
|
path.push(candId);
|
|
@@ -15620,6 +15806,22 @@ ${svg}
|
|
|
15620
15806
|
layerHasLabels: layerHasLabels
|
|
15621
15807
|
});
|
|
15622
15808
|
|
|
15809
|
+
// import { isKmzFile } from '../io/mapshaper-file-types';
|
|
15810
|
+
|
|
15811
|
+
function exportKML(dataset, opts) {
|
|
15812
|
+
var toKML = require("@placemarkio/tokml").toKML;
|
|
15813
|
+
var geojsonOpts = Object.assign({combine_layers: true, geojson_type: 'FeatureCollection'}, opts);
|
|
15814
|
+
var geojson = exportDatasetAsGeoJSON(dataset, geojsonOpts);
|
|
15815
|
+
var kml = toKML(geojson);
|
|
15816
|
+
// TODO: add KMZ output
|
|
15817
|
+
// var useKmz = opts.file && isKmzFile(opts.file);
|
|
15818
|
+
var ofile = opts.file || getOutputFileBase(dataset) + '.kml';
|
|
15819
|
+
return [{
|
|
15820
|
+
content: kml,
|
|
15821
|
+
filename: ofile
|
|
15822
|
+
}];
|
|
15823
|
+
}
|
|
15824
|
+
|
|
15623
15825
|
function buffersAreIdentical(a, b) {
|
|
15624
15826
|
var alen = BinArray.bufferSize(a);
|
|
15625
15827
|
var blen = BinArray.bufferSize(b);
|
|
@@ -17292,97 +17494,6 @@ ${svg}
|
|
|
17292
17494
|
exportJSONTable: exportJSONTable
|
|
17293
17495
|
});
|
|
17294
17496
|
|
|
17295
|
-
// Guess the type of a data file from file extension, or return null if not sure
|
|
17296
|
-
function guessInputFileType(file) {
|
|
17297
|
-
var ext = getFileExtension(file || '').toLowerCase(),
|
|
17298
|
-
type = null;
|
|
17299
|
-
if (ext == 'dbf' || ext == 'shp' || ext == 'prj' || ext == 'shx' || ext == 'kml' || ext == 'cpg') {
|
|
17300
|
-
type = ext;
|
|
17301
|
-
} else if (/json$/.test(ext)) {
|
|
17302
|
-
type = 'json';
|
|
17303
|
-
} else if (ext == 'csv' || ext == 'tsv' || ext == 'txt' || ext == 'tab') {
|
|
17304
|
-
type = 'text';
|
|
17305
|
-
}
|
|
17306
|
-
return type;
|
|
17307
|
-
}
|
|
17308
|
-
|
|
17309
|
-
function guessInputContentType(content) {
|
|
17310
|
-
var type = null;
|
|
17311
|
-
if (utils.isString(content)) {
|
|
17312
|
-
type = stringLooksLikeJSON(content) && 'json' ||
|
|
17313
|
-
stringLooksLikeKML(content) && 'kml' || 'text';
|
|
17314
|
-
} else if (utils.isObject(content) && content.type || utils.isArray(content)) {
|
|
17315
|
-
type = 'json';
|
|
17316
|
-
}
|
|
17317
|
-
return type;
|
|
17318
|
-
}
|
|
17319
|
-
|
|
17320
|
-
function guessInputType(file, content) {
|
|
17321
|
-
return guessInputFileType(file) || guessInputContentType(content);
|
|
17322
|
-
}
|
|
17323
|
-
|
|
17324
|
-
function stringLooksLikeJSON(str) {
|
|
17325
|
-
return /^\s*[{[]/.test(String(str));
|
|
17326
|
-
}
|
|
17327
|
-
|
|
17328
|
-
function stringLooksLikeKML(str) {
|
|
17329
|
-
str = String(str);
|
|
17330
|
-
return str.includes('<kml ') && str.includes('xmlns="http://www.opengis.net/kml/');
|
|
17331
|
-
}
|
|
17332
|
-
|
|
17333
|
-
function couldBeDsvFile(name) {
|
|
17334
|
-
var ext = getFileExtension(name).toLowerCase();
|
|
17335
|
-
return /csv|tsv|txt$/.test(ext);
|
|
17336
|
-
}
|
|
17337
|
-
|
|
17338
|
-
function isZipFile(file) {
|
|
17339
|
-
return /\.zip$/i.test(file);
|
|
17340
|
-
}
|
|
17341
|
-
|
|
17342
|
-
function isSupportedOutputFormat(fmt) {
|
|
17343
|
-
var types = ['geojson', 'topojson', 'json', 'dsv', 'dbf', 'shapefile', 'svg'];
|
|
17344
|
-
return types.indexOf(fmt) > -1;
|
|
17345
|
-
}
|
|
17346
|
-
|
|
17347
|
-
function getFormatName(fmt) {
|
|
17348
|
-
return {
|
|
17349
|
-
geojson: 'GeoJSON',
|
|
17350
|
-
topojson: 'TopoJSON',
|
|
17351
|
-
json: 'JSON records',
|
|
17352
|
-
dsv: 'CSV',
|
|
17353
|
-
dbf: 'DBF',
|
|
17354
|
-
shapefile: 'Shapefile',
|
|
17355
|
-
svg: 'SVG'
|
|
17356
|
-
}[fmt] || '';
|
|
17357
|
-
}
|
|
17358
|
-
|
|
17359
|
-
// Assumes file at @path is one of Mapshaper's supported file types
|
|
17360
|
-
function isSupportedBinaryInputType(path) {
|
|
17361
|
-
var ext = getFileExtension(path).toLowerCase();
|
|
17362
|
-
return ext == 'shp' || ext == 'shx' || ext == 'dbf'; // GUI also supports zip files
|
|
17363
|
-
}
|
|
17364
|
-
|
|
17365
|
-
// Detect extensions of some unsupported file types, for cmd line validation
|
|
17366
|
-
function filenameIsUnsupportedOutputType(file) {
|
|
17367
|
-
var rxp = /\.(shx|prj|xls|xlsx|gdb|sbn|sbx|xml|kml)$/i;
|
|
17368
|
-
return rxp.test(file);
|
|
17369
|
-
}
|
|
17370
|
-
|
|
17371
|
-
var FileTypes = /*#__PURE__*/Object.freeze({
|
|
17372
|
-
__proto__: null,
|
|
17373
|
-
guessInputFileType: guessInputFileType,
|
|
17374
|
-
guessInputContentType: guessInputContentType,
|
|
17375
|
-
guessInputType: guessInputType,
|
|
17376
|
-
stringLooksLikeJSON: stringLooksLikeJSON,
|
|
17377
|
-
stringLooksLikeKML: stringLooksLikeKML,
|
|
17378
|
-
couldBeDsvFile: couldBeDsvFile,
|
|
17379
|
-
isZipFile: isZipFile,
|
|
17380
|
-
isSupportedOutputFormat: isSupportedOutputFormat,
|
|
17381
|
-
getFormatName: getFormatName,
|
|
17382
|
-
isSupportedBinaryInputType: isSupportedBinaryInputType,
|
|
17383
|
-
filenameIsUnsupportedOutputType: filenameIsUnsupportedOutputType
|
|
17384
|
-
});
|
|
17385
|
-
|
|
17386
17497
|
function getOutputFormat(dataset, opts) {
|
|
17387
17498
|
var outFile = opts.file || null,
|
|
17388
17499
|
inFmt = dataset.info && dataset.info.input_formats && dataset.info.input_formats[0],
|
|
@@ -17458,7 +17569,7 @@ ${svg}
|
|
|
17458
17569
|
function exportDatasets(datasets, opts) {
|
|
17459
17570
|
var format = getOutputFormat(datasets[0], opts);
|
|
17460
17571
|
var files;
|
|
17461
|
-
if (format == 'svg' || format == 'topojson' || format == 'geojson' && opts.combine_layers) {
|
|
17572
|
+
if (format == 'kml' || format == 'svg' || format == 'topojson' || format == 'geojson' && opts.combine_layers) {
|
|
17462
17573
|
// multi-layer formats: combine multiple datasets into one
|
|
17463
17574
|
if (datasets.length > 1) {
|
|
17464
17575
|
datasets = [mergeDatasetsForExport(datasets)];
|
|
@@ -17512,8 +17623,8 @@ ${svg}
|
|
|
17512
17623
|
}, dataset);
|
|
17513
17624
|
|
|
17514
17625
|
// Adjust layer names, so they can be used as output file names
|
|
17515
|
-
// (except for multi-layer formats TopoJSON
|
|
17516
|
-
if (opts.file && outFmt != 'topojson' && outFmt != 'svg') {
|
|
17626
|
+
// (except for multi-layer formats TopoJSON, SVG, KML)
|
|
17627
|
+
if (opts.file && outFmt != 'topojson' && outFmt != 'svg'&& outFmt != 'kml') {
|
|
17517
17628
|
dataset.layers.forEach(function(lyr) {
|
|
17518
17629
|
lyr.name = getFileBase(opts.file);
|
|
17519
17630
|
});
|
|
@@ -17558,7 +17669,8 @@ ${svg}
|
|
|
17558
17669
|
dsv: exportDelim,
|
|
17559
17670
|
dbf: exportDbf,
|
|
17560
17671
|
json: exportJSON,
|
|
17561
|
-
svg: exportSVG
|
|
17672
|
+
svg: exportSVG,
|
|
17673
|
+
kml: exportKML
|
|
17562
17674
|
};
|
|
17563
17675
|
|
|
17564
17676
|
|
|
@@ -18545,9 +18657,19 @@ ${svg}
|
|
|
18545
18657
|
// (cli.writeFile() now creates directories that don't exist)
|
|
18546
18658
|
// cli.validateOutputDir(o.directory);
|
|
18547
18659
|
}
|
|
18548
|
-
if (pathInfo.extension
|
|
18549
|
-
o.
|
|
18660
|
+
if (/gz/i.test(pathInfo.extension)) {
|
|
18661
|
+
// handle arguments like -o out.json.gz (the preferred format)
|
|
18662
|
+
if (parseLocalPath(pathInfo.basename).extension) {
|
|
18663
|
+
o.file = pathInfo.basename;
|
|
18664
|
+
} else {
|
|
18665
|
+
// handle arguments like -o out.gz
|
|
18666
|
+
o.file = pathInfo.filename;
|
|
18667
|
+
}
|
|
18550
18668
|
o.gzip = true;
|
|
18669
|
+
} else if (/zip/i.test(pathInfo.extension)) {
|
|
18670
|
+
o.file = null;
|
|
18671
|
+
o.zipfile = pathInfo.filename;
|
|
18672
|
+
o.zip = true;
|
|
18551
18673
|
} else {
|
|
18552
18674
|
o.file = pathInfo.filename;
|
|
18553
18675
|
}
|
|
@@ -19361,6 +19483,10 @@ ${svg}
|
|
|
19361
19483
|
describe: 'apply gzip compression to output files',
|
|
19362
19484
|
type: 'flag'
|
|
19363
19485
|
})
|
|
19486
|
+
.option('zip', {
|
|
19487
|
+
describe: 'save all output files in a single .zip file',
|
|
19488
|
+
type: 'flag'
|
|
19489
|
+
})
|
|
19364
19490
|
.option('dry-run', {
|
|
19365
19491
|
// describe: 'do not output any files'
|
|
19366
19492
|
type: 'flag'
|
|
@@ -23725,64 +23851,82 @@ ${svg}
|
|
|
23725
23851
|
importFileContent: importFileContent
|
|
23726
23852
|
});
|
|
23727
23853
|
|
|
23728
|
-
// Import multiple files to a single dataset
|
|
23729
|
-
function importFiles(files, opts) {
|
|
23730
|
-
var unbuiltTopology = false;
|
|
23731
|
-
var datasets = files.map(function(fname) {
|
|
23732
|
-
// import without topology or snapping
|
|
23733
|
-
var importOpts = utils.defaults({no_topology: true, snap: false, snap_interval: null, files: [fname]}, opts);
|
|
23734
|
-
var dataset = importFile(fname, importOpts);
|
|
23735
|
-
// check if dataset contains non-topological paths
|
|
23736
|
-
// TODO: may also need to rebuild topology if multiple topojson files are merged
|
|
23737
|
-
if (dataset.arcs && dataset.arcs.size() > 0 && dataset.info.input_formats[0] != 'topojson') {
|
|
23738
|
-
unbuiltTopology = true;
|
|
23739
|
-
}
|
|
23740
|
-
return dataset;
|
|
23741
|
-
});
|
|
23742
|
-
var combined = mergeDatasets(datasets);
|
|
23743
|
-
// Build topology, if needed
|
|
23744
|
-
// TODO: consider updating topology of TopoJSON files instead of concatenating arcs
|
|
23745
|
-
// (but problem of mismatched coordinates due to quantization in input files.)
|
|
23746
|
-
if (unbuiltTopology && !opts.no_topology) {
|
|
23747
|
-
cleanPathsAfterImport(combined, opts);
|
|
23748
|
-
buildTopology(combined);
|
|
23749
|
-
}
|
|
23750
|
-
return combined;
|
|
23751
|
-
}
|
|
23752
|
-
|
|
23753
|
-
var MergeFiles = /*#__PURE__*/Object.freeze({
|
|
23754
|
-
__proto__: null,
|
|
23755
|
-
importFiles: importFiles
|
|
23756
|
-
});
|
|
23757
|
-
|
|
23758
23854
|
cmd.importFiles = function(opts) {
|
|
23759
|
-
var files = opts.files || []
|
|
23760
|
-
|
|
23855
|
+
var files = opts.files || [];
|
|
23856
|
+
var dataset;
|
|
23761
23857
|
|
|
23858
|
+
cli.checkCommandEnv('i');
|
|
23762
23859
|
if (opts.stdin) {
|
|
23763
23860
|
return importFile('/dev/stdin', opts);
|
|
23764
23861
|
}
|
|
23765
23862
|
|
|
23863
|
+
|
|
23766
23864
|
if (files.length > 0 === false) {
|
|
23767
23865
|
stop('Missing input file(s)');
|
|
23768
23866
|
}
|
|
23769
23867
|
|
|
23770
23868
|
verbose("Importing: " + files.join(' '));
|
|
23771
23869
|
|
|
23870
|
+
// copy opts, so parameters can be modified within this command
|
|
23871
|
+
opts = Object.assign({}, opts);
|
|
23872
|
+
opts.input = Object.assign({}, opts.input); // make sure we have a cache
|
|
23873
|
+
|
|
23874
|
+
files = expandFiles(files, opts.input);
|
|
23875
|
+
|
|
23876
|
+
if (files.length === 0) {
|
|
23877
|
+
stop('Missing importable files');
|
|
23878
|
+
}
|
|
23879
|
+
|
|
23772
23880
|
if (files.length == 1) {
|
|
23773
23881
|
dataset = importFile(files[0], opts);
|
|
23774
|
-
} else
|
|
23882
|
+
} else {
|
|
23883
|
+
dataset = importFilesTogether(files, opts);
|
|
23884
|
+
}
|
|
23885
|
+
|
|
23886
|
+
if (opts.merge_files && files.length > 1) {
|
|
23775
23887
|
// TODO: deprecate and remove this option (use -merge-layers cmd instead)
|
|
23776
|
-
dataset = importFiles(files, opts);
|
|
23777
23888
|
dataset.layers = cmd.mergeLayers(dataset.layers);
|
|
23778
|
-
} else if (opts.combine_files) {
|
|
23779
|
-
dataset = importFiles(files, opts);
|
|
23780
|
-
} else {
|
|
23781
|
-
stop('Invalid inputs');
|
|
23782
23889
|
}
|
|
23783
23890
|
return dataset;
|
|
23784
23891
|
};
|
|
23785
23892
|
|
|
23893
|
+
function expandFiles(files, cache) {
|
|
23894
|
+
var files2 = [];
|
|
23895
|
+
files.forEach(function(file) {
|
|
23896
|
+
var expanded;
|
|
23897
|
+
if (isZipFile(file)) {
|
|
23898
|
+
expanded = expandZipFile(file, cache);
|
|
23899
|
+
} else if (isKmzFile(file)) {
|
|
23900
|
+
expanded = expandKmzFile(file, cache);
|
|
23901
|
+
} else {
|
|
23902
|
+
expanded = [file]; // ordinary file, no change
|
|
23903
|
+
}
|
|
23904
|
+
files2 = files2.concat(expanded);
|
|
23905
|
+
});
|
|
23906
|
+
return files2;
|
|
23907
|
+
}
|
|
23908
|
+
|
|
23909
|
+
function expandKmzFile(file, cache) {
|
|
23910
|
+
var files = expandZipFile(file, cache);
|
|
23911
|
+
var name = replaceFileExtension(parseLocalPath(file).filename, 'kml');
|
|
23912
|
+
if (files[0] == 'doc.kml') {
|
|
23913
|
+
files[0] = name;
|
|
23914
|
+
cache[name] = cache['doc.kml'];
|
|
23915
|
+
}
|
|
23916
|
+
return files;
|
|
23917
|
+
}
|
|
23918
|
+
|
|
23919
|
+
function expandZipFile(file, cache) {
|
|
23920
|
+
var input;
|
|
23921
|
+
if (file in cache) {
|
|
23922
|
+
input = cache[file];
|
|
23923
|
+
} else {
|
|
23924
|
+
input = file;
|
|
23925
|
+
cli.checkFileExists(file);
|
|
23926
|
+
}
|
|
23927
|
+
return extractFiles(input, cache);
|
|
23928
|
+
}
|
|
23929
|
+
|
|
23786
23930
|
// Let the web UI replace importFile() with a browser-friendly version
|
|
23787
23931
|
function replaceImportFile(func) {
|
|
23788
23932
|
_importFile = func;
|
|
@@ -23801,6 +23945,7 @@ ${svg}
|
|
|
23801
23945
|
content;
|
|
23802
23946
|
|
|
23803
23947
|
cli.checkFileExists(path, cache);
|
|
23948
|
+
|
|
23804
23949
|
if ((fileType == 'shp' || fileType == 'json' || fileType == 'text' || fileType == 'dbf') && !cached) {
|
|
23805
23950
|
// these file types are read incrementally
|
|
23806
23951
|
content = null;
|
|
@@ -23823,6 +23968,7 @@ ${svg}
|
|
|
23823
23968
|
stop('Unrecognized file type:', path);
|
|
23824
23969
|
}
|
|
23825
23970
|
// TODO: consider using a temp file, to support incremental reading
|
|
23971
|
+
// read to buffer, even for string-based types (to support larger input files)
|
|
23826
23972
|
content = require('zlib').gunzipSync(cli.readFile(pathgz));
|
|
23827
23973
|
|
|
23828
23974
|
} else { // type can't be inferred from filename -- try reading as text
|
|
@@ -23848,6 +23994,49 @@ ${svg}
|
|
|
23848
23994
|
return importContent(input, opts);
|
|
23849
23995
|
};
|
|
23850
23996
|
|
|
23997
|
+
|
|
23998
|
+
function importZipFile(path, opts) {
|
|
23999
|
+
var cache = {};
|
|
24000
|
+
var input;
|
|
24001
|
+
if (opts.input && (path in opts.input)) {
|
|
24002
|
+
// reading from a buffer
|
|
24003
|
+
input = opts.input[path];
|
|
24004
|
+
} else {
|
|
24005
|
+
// reading from a file
|
|
24006
|
+
cli.checkFileExists(path);
|
|
24007
|
+
input = path;
|
|
24008
|
+
}
|
|
24009
|
+
var files = extractFiles(input, cache);
|
|
24010
|
+
var zipOpts = Object.assign({}, opts, {input: cache, files: files});
|
|
24011
|
+
return cmd.importFiles(zipOpts);
|
|
24012
|
+
}
|
|
24013
|
+
|
|
24014
|
+
// Import multiple files to a single dataset
|
|
24015
|
+
function importFilesTogether(files, opts) {
|
|
24016
|
+
var unbuiltTopology = false;
|
|
24017
|
+
var datasets = files.map(function(fname) {
|
|
24018
|
+
// import without topology or snapping
|
|
24019
|
+
var importOpts = utils.defaults({no_topology: true, snap: false, snap_interval: null, files: [fname]}, opts);
|
|
24020
|
+
var dataset = importFile(fname, importOpts);
|
|
24021
|
+
// check if dataset contains non-topological paths
|
|
24022
|
+
// TODO: may also need to rebuild topology if multiple topojson files are merged
|
|
24023
|
+
if (dataset.arcs && dataset.arcs.size() > 0 && dataset.info.input_formats[0] != 'topojson') {
|
|
24024
|
+
unbuiltTopology = true;
|
|
24025
|
+
}
|
|
24026
|
+
return dataset;
|
|
24027
|
+
});
|
|
24028
|
+
var combined = mergeDatasets(datasets);
|
|
24029
|
+
// Build topology, if needed
|
|
24030
|
+
// TODO: consider updating topology of TopoJSON files instead of concatenating arcs
|
|
24031
|
+
// (but problem of mismatched coordinates due to quantization in input files.)
|
|
24032
|
+
if (unbuiltTopology && !opts.no_topology) {
|
|
24033
|
+
cleanPathsAfterImport(combined, opts);
|
|
24034
|
+
buildTopology(combined);
|
|
24035
|
+
}
|
|
24036
|
+
return combined;
|
|
24037
|
+
}
|
|
24038
|
+
|
|
24039
|
+
|
|
23851
24040
|
function getUnsupportedFileMessage(path) {
|
|
23852
24041
|
var ext = getFileExtension(path);
|
|
23853
24042
|
var msg = 'Unable to import ' + path;
|
|
@@ -23885,7 +24074,8 @@ ${svg}
|
|
|
23885
24074
|
var FileImport = /*#__PURE__*/Object.freeze({
|
|
23886
24075
|
__proto__: null,
|
|
23887
24076
|
replaceImportFile: replaceImportFile,
|
|
23888
|
-
importFile: importFile
|
|
24077
|
+
importFile: importFile,
|
|
24078
|
+
importFilesTogether: importFilesTogether
|
|
23889
24079
|
});
|
|
23890
24080
|
|
|
23891
24081
|
function convertSourceName(name, targets) {
|
|
@@ -28465,15 +28655,15 @@ ${svg}
|
|
|
28465
28655
|
var brighter = 1 / darker;
|
|
28466
28656
|
|
|
28467
28657
|
var reI = "\\s*([+-]?\\d+)\\s*",
|
|
28468
|
-
reN = "\\s*([+-]?\\d
|
|
28469
|
-
reP = "\\s*([+-]?\\d
|
|
28658
|
+
reN = "\\s*([+-]?(?:\\d*\\.)?\\d+(?:[eE][+-]?\\d+)?)\\s*",
|
|
28659
|
+
reP = "\\s*([+-]?(?:\\d*\\.)?\\d+(?:[eE][+-]?\\d+)?)%\\s*",
|
|
28470
28660
|
reHex = /^#([0-9a-f]{3,8})$/,
|
|
28471
|
-
reRgbInteger = new RegExp(
|
|
28472
|
-
reRgbPercent = new RegExp(
|
|
28473
|
-
reRgbaInteger = new RegExp(
|
|
28474
|
-
reRgbaPercent = new RegExp(
|
|
28475
|
-
reHslPercent = new RegExp(
|
|
28476
|
-
reHslaPercent = new RegExp(
|
|
28661
|
+
reRgbInteger = new RegExp(`^rgb\\(${reI},${reI},${reI}\\)$`),
|
|
28662
|
+
reRgbPercent = new RegExp(`^rgb\\(${reP},${reP},${reP}\\)$`),
|
|
28663
|
+
reRgbaInteger = new RegExp(`^rgba\\(${reI},${reI},${reI},${reN}\\)$`),
|
|
28664
|
+
reRgbaPercent = new RegExp(`^rgba\\(${reP},${reP},${reP},${reN}\\)$`),
|
|
28665
|
+
reHslPercent = new RegExp(`^hsl\\(${reN},${reP},${reP}\\)$`),
|
|
28666
|
+
reHslaPercent = new RegExp(`^hsla\\(${reN},${reP},${reP},${reN}\\)$`);
|
|
28477
28667
|
|
|
28478
28668
|
var named = {
|
|
28479
28669
|
aliceblue: 0xf0f8ff,
|
|
@@ -28627,14 +28817,15 @@ ${svg}
|
|
|
28627
28817
|
};
|
|
28628
28818
|
|
|
28629
28819
|
define(Color, color, {
|
|
28630
|
-
copy
|
|
28820
|
+
copy(channels) {
|
|
28631
28821
|
return Object.assign(new this.constructor, this, channels);
|
|
28632
28822
|
},
|
|
28633
|
-
displayable
|
|
28823
|
+
displayable() {
|
|
28634
28824
|
return this.rgb().displayable();
|
|
28635
28825
|
},
|
|
28636
28826
|
hex: color_formatHex, // Deprecated! Use color.formatHex.
|
|
28637
28827
|
formatHex: color_formatHex,
|
|
28828
|
+
formatHex8: color_formatHex8,
|
|
28638
28829
|
formatHsl: color_formatHsl,
|
|
28639
28830
|
formatRgb: color_formatRgb,
|
|
28640
28831
|
toString: color_formatRgb
|
|
@@ -28644,6 +28835,10 @@ ${svg}
|
|
|
28644
28835
|
return this.rgb().formatHex();
|
|
28645
28836
|
}
|
|
28646
28837
|
|
|
28838
|
+
function color_formatHex8() {
|
|
28839
|
+
return this.rgb().formatHex8();
|
|
28840
|
+
}
|
|
28841
|
+
|
|
28647
28842
|
function color_formatHsl() {
|
|
28648
28843
|
return hslConvert(this).formatHsl();
|
|
28649
28844
|
}
|
|
@@ -28699,18 +28894,21 @@ ${svg}
|
|
|
28699
28894
|
}
|
|
28700
28895
|
|
|
28701
28896
|
define(Rgb, rgb$1, extend(Color, {
|
|
28702
|
-
brighter
|
|
28897
|
+
brighter(k) {
|
|
28703
28898
|
k = k == null ? brighter : Math.pow(brighter, k);
|
|
28704
28899
|
return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity);
|
|
28705
28900
|
},
|
|
28706
|
-
darker
|
|
28901
|
+
darker(k) {
|
|
28707
28902
|
k = k == null ? darker : Math.pow(darker, k);
|
|
28708
28903
|
return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity);
|
|
28709
28904
|
},
|
|
28710
|
-
rgb
|
|
28905
|
+
rgb() {
|
|
28711
28906
|
return this;
|
|
28712
28907
|
},
|
|
28713
|
-
|
|
28908
|
+
clamp() {
|
|
28909
|
+
return new Rgb(clampi(this.r), clampi(this.g), clampi(this.b), clampa(this.opacity));
|
|
28910
|
+
},
|
|
28911
|
+
displayable() {
|
|
28714
28912
|
return (-0.5 <= this.r && this.r < 255.5)
|
|
28715
28913
|
&& (-0.5 <= this.g && this.g < 255.5)
|
|
28716
28914
|
&& (-0.5 <= this.b && this.b < 255.5)
|
|
@@ -28718,25 +28916,34 @@ ${svg}
|
|
|
28718
28916
|
},
|
|
28719
28917
|
hex: rgb_formatHex, // Deprecated! Use color.formatHex.
|
|
28720
28918
|
formatHex: rgb_formatHex,
|
|
28919
|
+
formatHex8: rgb_formatHex8,
|
|
28721
28920
|
formatRgb: rgb_formatRgb,
|
|
28722
28921
|
toString: rgb_formatRgb
|
|
28723
28922
|
}));
|
|
28724
28923
|
|
|
28725
28924
|
function rgb_formatHex() {
|
|
28726
|
-
return
|
|
28925
|
+
return `#${hex(this.r)}${hex(this.g)}${hex(this.b)}`;
|
|
28926
|
+
}
|
|
28927
|
+
|
|
28928
|
+
function rgb_formatHex8() {
|
|
28929
|
+
return `#${hex(this.r)}${hex(this.g)}${hex(this.b)}${hex((isNaN(this.opacity) ? 1 : this.opacity) * 255)}`;
|
|
28727
28930
|
}
|
|
28728
28931
|
|
|
28729
28932
|
function rgb_formatRgb() {
|
|
28730
|
-
|
|
28731
|
-
return
|
|
28732
|
-
|
|
28733
|
-
|
|
28734
|
-
|
|
28735
|
-
|
|
28933
|
+
const a = clampa(this.opacity);
|
|
28934
|
+
return `${a === 1 ? "rgb(" : "rgba("}${clampi(this.r)}, ${clampi(this.g)}, ${clampi(this.b)}${a === 1 ? ")" : `, ${a})`}`;
|
|
28935
|
+
}
|
|
28936
|
+
|
|
28937
|
+
function clampa(opacity) {
|
|
28938
|
+
return isNaN(opacity) ? 1 : Math.max(0, Math.min(1, opacity));
|
|
28939
|
+
}
|
|
28940
|
+
|
|
28941
|
+
function clampi(value) {
|
|
28942
|
+
return Math.max(0, Math.min(255, Math.round(value) || 0));
|
|
28736
28943
|
}
|
|
28737
28944
|
|
|
28738
28945
|
function hex(value) {
|
|
28739
|
-
value =
|
|
28946
|
+
value = clampi(value);
|
|
28740
28947
|
return (value < 16 ? "0" : "") + value.toString(16);
|
|
28741
28948
|
}
|
|
28742
28949
|
|
|
@@ -28785,15 +28992,15 @@ ${svg}
|
|
|
28785
28992
|
}
|
|
28786
28993
|
|
|
28787
28994
|
define(Hsl, hsl$2, extend(Color, {
|
|
28788
|
-
brighter
|
|
28995
|
+
brighter(k) {
|
|
28789
28996
|
k = k == null ? brighter : Math.pow(brighter, k);
|
|
28790
28997
|
return new Hsl(this.h, this.s, this.l * k, this.opacity);
|
|
28791
28998
|
},
|
|
28792
|
-
darker
|
|
28999
|
+
darker(k) {
|
|
28793
29000
|
k = k == null ? darker : Math.pow(darker, k);
|
|
28794
29001
|
return new Hsl(this.h, this.s, this.l * k, this.opacity);
|
|
28795
29002
|
},
|
|
28796
|
-
rgb
|
|
29003
|
+
rgb() {
|
|
28797
29004
|
var h = this.h % 360 + (this.h < 0) * 360,
|
|
28798
29005
|
s = isNaN(h) || isNaN(this.s) ? 0 : this.s,
|
|
28799
29006
|
l = this.l,
|
|
@@ -28806,21 +29013,29 @@ ${svg}
|
|
|
28806
29013
|
this.opacity
|
|
28807
29014
|
);
|
|
28808
29015
|
},
|
|
28809
|
-
|
|
29016
|
+
clamp() {
|
|
29017
|
+
return new Hsl(clamph(this.h), clampt(this.s), clampt(this.l), clampa(this.opacity));
|
|
29018
|
+
},
|
|
29019
|
+
displayable() {
|
|
28810
29020
|
return (0 <= this.s && this.s <= 1 || isNaN(this.s))
|
|
28811
29021
|
&& (0 <= this.l && this.l <= 1)
|
|
28812
29022
|
&& (0 <= this.opacity && this.opacity <= 1);
|
|
28813
29023
|
},
|
|
28814
|
-
formatHsl
|
|
28815
|
-
|
|
28816
|
-
return
|
|
28817
|
-
+ (this.h || 0) + ", "
|
|
28818
|
-
+ (this.s || 0) * 100 + "%, "
|
|
28819
|
-
+ (this.l || 0) * 100 + "%"
|
|
28820
|
-
+ (a === 1 ? ")" : ", " + a + ")");
|
|
29024
|
+
formatHsl() {
|
|
29025
|
+
const a = clampa(this.opacity);
|
|
29026
|
+
return `${a === 1 ? "hsl(" : "hsla("}${clamph(this.h)}, ${clampt(this.s) * 100}%, ${clampt(this.l) * 100}%${a === 1 ? ")" : `, ${a})`}`;
|
|
28821
29027
|
}
|
|
28822
29028
|
}));
|
|
28823
29029
|
|
|
29030
|
+
function clamph(value) {
|
|
29031
|
+
value = (value || 0) % 360;
|
|
29032
|
+
return value < 0 ? value + 360 : value;
|
|
29033
|
+
}
|
|
29034
|
+
|
|
29035
|
+
function clampt(value) {
|
|
29036
|
+
return Math.max(0, Math.min(1, value || 0));
|
|
29037
|
+
}
|
|
29038
|
+
|
|
28824
29039
|
/* From FvD 13.37, CSS Color Module Level 3 */
|
|
28825
29040
|
function hsl2rgb(h, m1, m2) {
|
|
28826
29041
|
return (h < 60 ? m1 + (m2 - m1) * h / 60
|
|
@@ -28873,13 +29088,13 @@ ${svg}
|
|
|
28873
29088
|
}
|
|
28874
29089
|
|
|
28875
29090
|
define(Lab, lab$1, extend(Color, {
|
|
28876
|
-
brighter
|
|
29091
|
+
brighter(k) {
|
|
28877
29092
|
return new Lab(this.l + K * (k == null ? 1 : k), this.a, this.b, this.opacity);
|
|
28878
29093
|
},
|
|
28879
|
-
darker
|
|
29094
|
+
darker(k) {
|
|
28880
29095
|
return new Lab(this.l - K * (k == null ? 1 : k), this.a, this.b, this.opacity);
|
|
28881
29096
|
},
|
|
28882
|
-
rgb
|
|
29097
|
+
rgb() {
|
|
28883
29098
|
var y = (this.l + 16) / 116,
|
|
28884
29099
|
x = isNaN(this.a) ? y : y + this.a / 500,
|
|
28885
29100
|
z = isNaN(this.b) ? y : y - this.b / 200;
|
|
@@ -28941,13 +29156,13 @@ ${svg}
|
|
|
28941
29156
|
}
|
|
28942
29157
|
|
|
28943
29158
|
define(Hcl, hcl$2, extend(Color, {
|
|
28944
|
-
brighter
|
|
29159
|
+
brighter(k) {
|
|
28945
29160
|
return new Hcl(this.h, this.c, this.l + K * (k == null ? 1 : k), this.opacity);
|
|
28946
29161
|
},
|
|
28947
|
-
darker
|
|
29162
|
+
darker(k) {
|
|
28948
29163
|
return new Hcl(this.h, this.c, this.l - K * (k == null ? 1 : k), this.opacity);
|
|
28949
29164
|
},
|
|
28950
|
-
rgb
|
|
29165
|
+
rgb() {
|
|
28951
29166
|
return hcl2lab(this).rgb();
|
|
28952
29167
|
}
|
|
28953
29168
|
}));
|
|
@@ -28987,15 +29202,15 @@ ${svg}
|
|
|
28987
29202
|
}
|
|
28988
29203
|
|
|
28989
29204
|
define(Cubehelix, cubehelix$3, extend(Color, {
|
|
28990
|
-
brighter
|
|
29205
|
+
brighter(k) {
|
|
28991
29206
|
k = k == null ? brighter : Math.pow(brighter, k);
|
|
28992
29207
|
return new Cubehelix(this.h, this.s, this.l * k, this.opacity);
|
|
28993
29208
|
},
|
|
28994
|
-
darker
|
|
29209
|
+
darker(k) {
|
|
28995
29210
|
k = k == null ? darker : Math.pow(darker, k);
|
|
28996
29211
|
return new Cubehelix(this.h, this.s, this.l * k, this.opacity);
|
|
28997
29212
|
},
|
|
28998
|
-
rgb
|
|
29213
|
+
rgb() {
|
|
28999
29214
|
var h = isNaN(this.h) ? 0 : (this.h + 120) * radians,
|
|
29000
29215
|
l = +this.l,
|
|
29001
29216
|
a = isNaN(this.s) ? 0 : this.s * l * (1 - l),
|
|
@@ -39352,12 +39567,12 @@ ${svg}
|
|
|
39352
39567
|
var parser = getOptionParser();
|
|
39353
39568
|
// support multiline string of commands pasted into console
|
|
39354
39569
|
str = str.split(/\n+/g).map(function(str) {
|
|
39355
|
-
var match = /^[a-z][\w-]
|
|
39570
|
+
var match = /^[a-z][\w-]*/i.exec(str = str.trim());
|
|
39356
39571
|
//if (match && parser.isCommandName(match[0])) {
|
|
39357
39572
|
if (match) {
|
|
39358
39573
|
// add hyphen prefix to bare command
|
|
39359
|
-
|
|
39360
|
-
|
|
39574
|
+
// also add hyphen to non-command strings, for a better error message
|
|
39575
|
+
// ("unsupported command" instead of "The -i command cannot be run in the browser")
|
|
39361
39576
|
str = '-' + str;
|
|
39362
39577
|
}
|
|
39363
39578
|
return str;
|
|
@@ -39367,15 +39582,10 @@ ${svg}
|
|
|
39367
39582
|
|
|
39368
39583
|
// Parse a command line string for the browser console
|
|
39369
39584
|
function parseConsoleCommands(raw) {
|
|
39370
|
-
var blocked = ['i', 'include', 'require', 'external'];
|
|
39371
39585
|
var str = standardizeConsoleCommands(raw);
|
|
39372
|
-
var parsed;
|
|
39373
|
-
parsed = parseCommands(str);
|
|
39586
|
+
var parsed = parseCommands(str);
|
|
39374
39587
|
parsed.forEach(function(cmd) {
|
|
39375
|
-
|
|
39376
|
-
if (i > -1) {
|
|
39377
|
-
stop("The -" + blocked[i] + " command cannot be run in the browser");
|
|
39378
|
-
}
|
|
39588
|
+
cli.checkCommandEnv(cmd.name);
|
|
39379
39589
|
});
|
|
39380
39590
|
return parsed;
|
|
39381
39591
|
}
|
|
@@ -42779,7 +42989,6 @@ ${svg}
|
|
|
42779
42989
|
LayerUtils,
|
|
42780
42990
|
Lines,
|
|
42781
42991
|
Logging,
|
|
42782
|
-
MergeFiles,
|
|
42783
42992
|
Merging,
|
|
42784
42993
|
MosaicIndex$1,
|
|
42785
42994
|
OptionParsingUtils,
|