mapshaper 0.7.74 → 0.7.75

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 CHANGED
@@ -71333,7 +71333,7 @@ ${css.join('\n')}
71333
71333
  return new Rgb(o.r, o.g, o.b, o.opacity);
71334
71334
  }
71335
71335
 
71336
- function rgb$1(r, g, b, opacity) {
71336
+ function rgb(r, g, b, opacity) {
71337
71337
  return arguments.length === 1 ? rgbConvert(r) : new Rgb(r, g, b, opacity == null ? 1 : opacity);
71338
71338
  }
71339
71339
 
@@ -71344,7 +71344,7 @@ ${css.join('\n')}
71344
71344
  this.opacity = +opacity;
71345
71345
  }
71346
71346
 
71347
- define(Rgb, rgb$1, extend(Color, {
71347
+ define(Rgb, rgb, extend(Color, {
71348
71348
  brighter(k) {
71349
71349
  k = k == null ? brighter : Math.pow(brighter, k);
71350
71350
  return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity);
@@ -71606,11 +71606,11 @@ ${css.join('\n')}
71606
71606
  return d ? linear(a, d) : constant(isNaN(a) ? b : a);
71607
71607
  }
71608
71608
 
71609
- var rgb = (function rgbGamma(y) {
71609
+ var interpolateRgb = (function rgbGamma(y) {
71610
71610
  var color = gamma(y);
71611
71611
 
71612
- function rgb(start, end) {
71613
- var r = color((start = rgb$1(start)).r, (end = rgb$1(end)).r),
71612
+ function rgb$1(start, end) {
71613
+ var r = color((start = rgb(start)).r, (end = rgb(end)).r),
71614
71614
  g = color(start.g, end.g),
71615
71615
  b = color(start.b, end.b),
71616
71616
  opacity = nogamma(start.opacity, end.opacity);
@@ -71623,9 +71623,9 @@ ${css.join('\n')}
71623
71623
  };
71624
71624
  }
71625
71625
 
71626
- rgb.gamma = rgbGamma;
71626
+ rgb$1.gamma = rgbGamma;
71627
71627
 
71628
- return rgb;
71628
+ return rgb$1;
71629
71629
  })(1);
71630
71630
 
71631
71631
  function rgbSpline(spline) {
@@ -71636,7 +71636,7 @@ ${css.join('\n')}
71636
71636
  b = new Array(n),
71637
71637
  i, color;
71638
71638
  for (i = 0; i < n; ++i) {
71639
- color = rgb$1(colors[i]);
71639
+ color = rgb(colors[i]);
71640
71640
  r[i] = color.r || 0;
71641
71641
  g[i] = color.g || 0;
71642
71642
  b[i] = color.b || 0;
@@ -71789,8 +71789,8 @@ ${css.join('\n')}
71789
71789
  var t = typeof b, c;
71790
71790
  return b == null || t === "boolean" ? constant(b)
71791
71791
  : (t === "number" ? number
71792
- : t === "string" ? ((c = color(b)) ? (b = c, rgb) : string)
71793
- : b instanceof color ? rgb
71792
+ : t === "string" ? ((c = color(b)) ? (b = c, interpolateRgb) : string)
71793
+ : b instanceof color ? interpolateRgb
71794
71794
  : b instanceof Date ? date
71795
71795
  : isNumberArray(b) ? numberArray
71796
71796
  : Array.isArray(b) ? genericArray
@@ -71825,6 +71825,16 @@ ${css.join('\n')}
71825
71825
  cubehelix$1(hue);
71826
71826
  var cubehelixLong = cubehelix$1(nogamma);
71827
71827
 
71828
+ function piecewise(interpolate, values) {
71829
+ if (values === undefined) values = interpolate, interpolate = d3_interpolate;
71830
+ var i = 0, n = values.length - 1, v = values[0], I = new Array(n < 0 ? 0 : n);
71831
+ while (i < n) I[i] = interpolate(v, v = values[++i]);
71832
+ return function(t) {
71833
+ var i = Math.max(0, Math.min(n - 1, Math.floor(t *= n)));
71834
+ return I[i](t - i);
71835
+ };
71836
+ }
71837
+
71828
71838
  // OKLab conversion (Björn Ottosson, https://bottosson.github.io/posts/oklab/)
71829
71839
  // RGB objects use 0-255 channels, as returned by parseColor().
71830
71840
 
@@ -73968,7 +73978,7 @@ ${css.join('\n')}
73968
73978
  return c$1 + "";
73969
73979
  }
73970
73980
 
73971
- var c = rgb$1(),
73981
+ var c = rgb(),
73972
73982
  pi_1_3 = Math.PI / 3,
73973
73983
  pi_2_3 = Math.PI * 2 / 3;
73974
73984
 
@@ -74084,6 +74094,59 @@ ${css.join('\n')}
74084
74094
  schemeYlOrRd: scheme$6
74085
74095
  });
74086
74096
 
74097
+ // Scientific colour maps, version 8.0.1, by Fabio Crameri
74098
+ // https://www.fabiocrameri.ch/colourmaps/ (https://doi.org/10.5281/zenodo.8409685)
74099
+ //
74100
+ // Each ramp is 33 evenly spaced colors (as packed hex), sampled from the
74101
+ // 256-color version, which they reproduce to within 0.008 OKLab deltaE; the
74102
+ // odd count gives diverging ramps a color at their center. batlowS is the
74103
+ // first 20 swatches of batlow's categorical palette.
74104
+ //
74105
+ // The Scientific colour maps are licensed under a MIT License
74106
+ // Copyright (c) 2023, Fabio Crameri
74107
+ // Permission is hereby granted, free of charge, to any person obtaining a
74108
+ // copy of this software and associated documentation files (the "Software"),
74109
+ // to deal in the Software without restriction, including without limitation
74110
+ // the rights to use, copy, modify, merge, publish, distribute, sublicense,
74111
+ // and/or sell copies of the Software, and to permit persons to whom the
74112
+ // Software is furnished to do so, subject to the following conditions:
74113
+ // The above copyright notice and this permission notice shall be included in
74114
+ // all copies or substantial portions of the Software.
74115
+ // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
74116
+ // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
74117
+ // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
74118
+ // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
74119
+ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
74120
+ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
74121
+ // DEALINGS IN THE SOFTWARE.
74122
+
74123
+ var crameriSequential = {
74124
+ batlow: '01195908255b0d315d0f3b5f114360134b611652621b59622260612a655e356a59406f544d734d597646667a3f737e3881823290862da08a2bb08d2ebf9035ce923fdb954ce8985bf29d6cf8a27efca891fdaea3fdb4b4fdbac5fcc0d6fbc6e8faccfa',
74125
+ batlowW: '01195908255b0d315d0f3b5f114360134a611651621a5862205f6228655f326a5c3d6f5749745155794b627d446f823e7d87388c8c339d9232ae9838be9d44cca154d7a565e0a875e8ac84efb094f5b8a6fbc3bafed1ceffdfddffebeafff5f5fffefe',
74126
+ acton: '260d402d17493420523a2a5a413362473b6a4d4472534c79595481615b876a608b74628d7d638e87648e91648f9c658fa76690b36791bf6a93c97097cf789fd482a7d78db0da97b9dda2c2e0accae3b6d2e5c0dae8cae1ead3e8ecdbeeeee3f4f0eafa',
74127
+ bamako: '003b47043d45083f430c424010453e14483b194b381f4e342552312b562d325b29395f2440642048691b516f16597410627a0b6b7f057584017f87008a8900948c019f9108a99815b4a122bfa930cab240d4bb52ddc465e6cc78efd58af7dd9cffe5ad',
74128
+ bilbao: '4c0001580b1064161a6e202478292e8232398b3b4293444a994e509c56549f5d56a16458a26a59a4705aa6765ca77c5da9825eaa885fac8e61ae9463b09c66b4a46eb8ac7bbcb389bfb897c2bda4c5c2b0c9c7bccfcdc8d7d7d5e3e3e2f1f1f1ffffff',
74129
+ davos: '00054a031256081c610e276c1431761a3c802146892850902f5a9636639a3e6b9c46729d4e789d557e9b5d84996489966c8d937392907b978d839d8a8ba38895aa87a0b289adbc8dbcc894cbd49fdadfade6e9bceff0cbf6f6d9faf9e6fcfcf3fefefe',
74130
+ devon: '2c1a4c2b21542a285b29306329376a283f7227477b274f8429588f2c5f9a3265a5386bb04271bc4e78c65e80cf6e87d67d8edd8c95e29a9ce7a6a3ebb0aaeeb7b1f0beb8f2c4bff3cbc6f4d1cdf6d7d4f7dedbf8e4e2faebe9fbf2f0fcf8f8feffffff',
74131
+ lajolla: '191900201c04271e082f210d3724114127164c2b1c592f22663429753931853d3895423fa64644b64a48c54f4ad1564cd95f4ede6a4fe1744fe37e50e58751e79152e99a52eba353edad54efb755f1c159f4cd62f7d972fae588fcef9ffef7b6fffecb',
74132
+ lapaz: '1a0c641d176b1f207122297824327e263a842842892a4a8e2c52932f5a9733629b386a9e3d71a04378a24a7fa35286a45b8ca36591a27096a07a9b9e859e9b90a1999ba496a7a895b4ac96c2b299d0baa1dec4aceaceb9f3d8c8f9e1d6fceae5fef2f3',
74133
+ oslo: '010101050a100a121a0d18240e1e2e0f2439112a4413314f15395b1840671c4773214f7f26568c2d5e993667a54270b14f7abc5c83c3678bc77292c97c99ca859fca8fa4c998aac9a2b0caacb7cbb7bfcdc2c7d1ced1d7dadcdfe6e7e9f3f3f4ffffff',
74134
+ tokyo: '1c0e3429123837163d441d415024465b2d4963364c683f4e6b47506e4e506f5351705951715d52716152726652736a53746f53757554767c54778355798c567b95587e9f5b81ab5f87b7668fc3709ad17da8dd8eb8e9a2c9f1b4d8f7c5e5fad2effcdd',
74135
+ turku: '0000000e0e0d18181620201d28282330302a39382f41413549493951513e5a59426261456a6a4973724d7c7a51878355928b5a9e9360ab9a66b79f6dc2a373cca579d5a780dda887e4aa90ebae9af2b4a5f7bbb1fbc3bdfdccc8fed5d3ffdddcffe6e6'
74136
+ };
74137
+
74138
+ var crameriDiverging = {
74139
+ bam: '65024b77175d88266e97357da5428cb25099bd5ea5c76db0d17ebbd990c6e0a2d0e6b4d9ecc5e2f1d4e9f4e1eef6ebf1f6f1f1f3f3ecedf2e3e4eed4d7e7c1c7deaab4d191a0c3798cb5657aa6546999465a8c3a4c802f3e7425306819205a0d0d4c00',
74140
+ broc: '2c1a4c2b26582a3164293e70294a7d2d588939669449749f5a82a86c8fb27e9dbc91acc5a4bacfb7c8d9cad7e3dde5ebebeeecedeee0e7e7ceddddbcd4d4a9c9c995bbbb82abab709b9b618b8b547b7b476c6c3a5d5d2d4e4e2140401632330c262600',
74141
+ cork: '2c194c2b26592a3265283f71284b7e2d588a38669446729e567ea6668bae7798b889a6c19db4cbb1c4d6c7d4e1dbe4ebe6edecdfeae0cedfcebbd2bba8c5a794b89481ab816e9e6e5d935c4c884c3c7c3c2d702c20621e18541414450e1137090f2903',
74142
+ roma: '7e1700862c068e3c0c964b129d5818a3651ea97223af7e2ab68c32bd9a3cc4aa4acaba5cd0c971d2d789d1e19fcbe8b3c1eac2b2e9cda1e4d48ddcd778d2d764c5d452b8d044aacc399dc63190c12b83bc2677b7226ab11e5dab184fa511409f033198',
74143
+ vik: '001261021f69022b710237790344810450890c5e921b6d9b2f7ca6478db1609dbc79adc792bdd2acccdcc5dbe5dce5e9ece5e1eedacfe9cbb9e2bba4dcab8fd59c7bcf8e68c97f55c37243bc6331b3531fa5400e932e06832106741506660a07590008'
74144
+ };
74145
+
74146
+ var crameriCategorical = {
74147
+ batlowS: '011959faccfa828231226061f29d6d4d734d114360c09036fdb4b4dd954d356a59fcbfd6175262677b3ea18a2b0d315dfca890fbc6e82b655eb18d2f'
74148
+ };
74149
+
74087
74150
  var index = {
74088
74151
  categorical: [],
74089
74152
  sequential: [],
@@ -74092,10 +74155,29 @@ ${css.join('\n')}
74092
74155
  all: []
74093
74156
  };
74094
74157
  var ramps;
74158
+ // interpolators of the ramps that are stored as stops (not from d3)
74159
+ var stopInterpolators;
74160
+ // scheme name -> where the scheme comes from (see getColorSchemeGroups())
74161
+ var sources;
74162
+ // the order of the sources in lists of schemes
74163
+ var sourceOrder = ['ColorBrewer', 'Tableau', 'Matplotlib', 'Crameri', 'd3'];
74164
+ // Schemes are listed by their designers, as far as they're known. 'd3' is
74165
+ // d3-scale-chromatic's own schemes, and others that it brings in: Turbo
74166
+ // (Google) and CubehelixDefault (D. A. Green's cubehelix).
74167
+ var d3Sources = {
74168
+ ColorBrewer: 'Accent,Dark2,Paired,Pastel1,Pastel2,Set1,Set2,Set3,' +
74169
+ 'Blues,Greens,Greys,Purples,Reds,Oranges,BuGn,BuPu,GnBu,OrRd,PuBuGn,PuBu,PuRd,RdPu,YlGnBu,YlGn,YlOrBr,YlOrRd,' +
74170
+ 'BrBG,PRGn,PiYG,PuOr,RdBu,RdGy,RdYlBu,RdYlGn,Spectral',
74171
+ Tableau: 'Tableau10,Tableau20',
74172
+ Matplotlib: 'Cividis,Viridis,Magma,Inferno,Plasma',
74173
+ d3: 'Category10,Category20,Category20b,Category20c,CubehelixDefault,Rainbow,Warm,Cool,Sinebow,Turbo'
74174
+ };
74095
74175
 
74096
74176
  function initSchemes() {
74097
74177
  if (ramps) return;
74098
74178
  ramps = {};
74179
+ stopInterpolators = {};
74180
+ sources = {};
74099
74181
  addSchemesFromD3('categorical', 'Category10,Accent,Dark2,Paired,Pastel1,Pastel2,Set1,Set2,Set3,Tableau10');
74100
74182
  addSchemesFromD3('sequential', 'Blues,Greens,Greys,Purples,Reds,Oranges,BuGn,BuPu,GnBu,OrRd,PuBuGn,PuBu,PuRd,RdPu,YlGnBu,YlGn,YlOrBr,YlOrRd');
74101
74183
  addSchemesFromD3('rainbow', 'Cividis,CubehelixDefault,Rainbow,Warm,Cool,Sinebow,Turbo,Viridis,Magma,Inferno,Plasma');
@@ -74109,9 +74191,29 @@ ${css.join('\n')}
74109
74191
  '3182bd6baed69ecae1c6dbefe6550dfd8d3cfdae6bfdd0a231a35474c476a1d99bc7e9c0756bb19e9ac8bcbddcdadaeb636363969696bdbdbdd9d9d9');
74110
74192
  addCategoricalScheme('Tableau20',
74111
74193
  '4c78a89ecae9f58518ffbf7954a24b88d27ab79a20f2cf5b43989483bcb6e45756ff9d9879706ebab0acd67195fcbfd2b279a2d6a5c99e765fd8b5a5');
74194
+ Object.keys(d3Sources).forEach(function(source) {
74195
+ d3Sources[source].split(',').forEach(function(name) {
74196
+ sources[name] = source;
74197
+ });
74198
+ });
74199
+ addStoppedSchemes('sequential', crameriSequential, 'Crameri');
74200
+ addStoppedSchemes('diverging', crameriDiverging, 'Crameri');
74201
+ Object.keys(crameriCategorical).forEach(function(name) {
74202
+ addCategoricalScheme(name, crameriCategorical[name]);
74203
+ sources[name] = 'Crameri';
74204
+ });
74112
74205
  index.all = [].concat(index.sequential, index.rainbow, index.diverging, index.categorical);
74113
74206
  }
74114
74207
 
74208
+ // Ramps stored as evenly spaced colors, interpolated linearly between them
74209
+ function addStoppedSchemes(type, schemes, source) {
74210
+ Object.keys(schemes).forEach(function(name) {
74211
+ index[type].push(name);
74212
+ stopInterpolators[name] = piecewise(interpolateRgb, unpackRamp(schemes[name]));
74213
+ sources[name] = source;
74214
+ });
74215
+ }
74216
+
74115
74217
  function standardName(name) {
74116
74218
  if (!name) return null;
74117
74219
  var lcname = name.toLowerCase();
@@ -74173,12 +74275,15 @@ ${css.join('\n')}
74173
74275
  }
74174
74276
 
74175
74277
  function printColorSchemeNames() {
74278
+ var types = [['categorical', 'Categorical'], ['sequential', 'Sequential'],
74279
+ ['diverging', 'Diverging'], ['rainbow', 'Multi-hue/rainbow']];
74176
74280
  initSchemes();
74177
- print('Built-in color schemes (from d3):');
74178
- print ('Categorical\n' + formatStringsAsGrid(index.categorical));
74179
- print ('\nSequential\n' + formatStringsAsGrid(index.sequential));
74180
- print ('\nDiverging\n' + formatStringsAsGrid(index.diverging));
74181
- print ('\nMulti-hue/rainbow\n' + formatStringsAsGrid(index.rainbow));
74281
+ print('Built-in color schemes');
74282
+ types.forEach(function(type) {
74283
+ getColorSchemeGroups(type[0]).forEach(function(group) {
74284
+ print('\n' + type[1] + ' (' + group.source + ')\n' + formatStringsAsGrid(group.names));
74285
+ });
74286
+ });
74182
74287
  }
74183
74288
 
74184
74289
  // type: categorical, sequential, rainbow or diverging
@@ -74188,6 +74293,19 @@ ${css.join('\n')}
74188
74293
  return index[type].concat();
74189
74294
  }
74190
74295
 
74296
+ // The schemes of one or more types, by source: [{source, names}]
74297
+ // (sources: ColorBrewer, Tableau, Matplotlib, Crameri, d3)
74298
+ function getColorSchemeGroups(types) {
74299
+ var names = [].concat(types).reduce(function(memo, type) {
74300
+ return memo.concat(getColorSchemeNames(type));
74301
+ }, []);
74302
+ return sourceOrder.map(function(source) {
74303
+ return {source: source, names: names.filter(function(name) { return sources[name] == source; })};
74304
+ }).filter(function(group) {
74305
+ return group.names.length > 0;
74306
+ });
74307
+ }
74308
+
74191
74309
  function pickRandomColorScheme(type) {
74192
74310
  initSchemes();
74193
74311
  var names = index[type];
@@ -74267,7 +74385,7 @@ ${css.join('\n')}
74267
74385
  initSchemes();
74268
74386
  name = standardName(name);
74269
74387
  var ramps = d3Scales['scheme' + name];
74270
- var interpolate = d3Scales['interpolate' + name];
74388
+ var interpolate = d3Scales['interpolate' + name] || stopInterpolators[name];
74271
74389
  var ramp;
74272
74390
  if (!ramps && !interpolate) {
74273
74391
  stop$1('Unknown color scheme name:', name);
@@ -74286,6 +74404,26 @@ ${css.join('\n')}
74286
74404
  return ramp;
74287
74405
  }
74288
74406
 
74407
+ // n colors from part of a ramp, evenly spaced from start to end (0-1).
74408
+ // base: interpolate between the colors of the scheme's set of this size, if
74409
+ // it has one (ColorBrewer's hand-picked sets), so that a section of a set
74410
+ // keeps its colors; otherwise the scheme's own interpolator is used
74411
+ function getColorRampSection(name, n, start, end, base) {
74412
+ initSchemes();
74413
+ name = standardName(name);
74414
+ var sets = d3Scales['scheme' + name];
74415
+ var interpolate = d3Scales['interpolate' + name] || stopInterpolators[name];
74416
+ var colors = [];
74417
+ if (!interpolate || index.categorical.includes(name)) {
74418
+ stop$1('Not a sequential or diverging color scheme:', name);
74419
+ }
74420
+ if (sets && sets[base]) interpolate = piecewise(interpolateRgb, sets[base]);
74421
+ for (var i=0; i<n; i++) {
74422
+ colors.push(interpolate(n > 1 ? start + (end - start) * i / (n - 1) : (start + end) / 2));
74423
+ }
74424
+ return colors;
74425
+ }
74426
+
74289
74427
  function getInterpolatedRamp(interpolate, n) {
74290
74428
  if (n > 0 === false || !utils.isInteger(n)) {
74291
74429
  error('Expected a positive integer');
@@ -74302,6 +74440,8 @@ ${css.join('\n')}
74302
74440
  getCategoricalColorScheme: getCategoricalColorScheme,
74303
74441
  getCategoricalColors: getCategoricalColors,
74304
74442
  getColorRamp: getColorRamp,
74443
+ getColorRampSection: getColorRampSection,
74444
+ getColorSchemeGroups: getColorSchemeGroups,
74305
74445
  getColorSchemeNames: getColorSchemeNames,
74306
74446
  getRandomizedCategoricalColorScheme: getRandomizedCategoricalColorScheme,
74307
74447
  isCategoricalColorScheme: isCategoricalColorScheme,
@@ -87771,7 +87911,7 @@ ${css.join('\n')}
87771
87911
  return name == 'rectangle' || name == 'rectangles' || name == 'filter' && opts.cleanup;
87772
87912
  }
87773
87913
 
87774
- var version = "0.7.74";
87914
+ var version = "0.7.75";
87775
87915
 
87776
87916
  // Parse command line args into commands and run them
87777
87917
  // Function takes an optional Node-style callback. A Promise is returned if no callback is given.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mapshaper",
3
- "version": "0.7.74",
3
+ "version": "0.7.75",
4
4
  "description": "A tool for editing geospatial data for mapping and GIS.",
5
5
  "keywords": [
6
6
  "shapefile",
@@ -5177,7 +5177,7 @@
5177
5177
  var recipe = getRasterViewRecipe(grid, view && view.recipe);
5178
5178
  var stats = getRasterViewScalingStats(raster, recipe);
5179
5179
  var sourceRange = recipe.scaling == 'none' ? getPixelTypeRange(grid.pixelType) : null;
5180
- var displayRange = getDisplayRange(recipe.scaleRange);
5180
+ var displayRange = getDisplayRange$1(recipe.scaleRange);
5181
5181
  var offset = pixelId * grid.bands;
5182
5182
  var color = [0, 1, 2].map(function(band) {
5183
5183
  return scaleSample(grid.samples[offset + band], stats && stats[band], sourceRange, displayRange);
@@ -5204,7 +5204,7 @@
5204
5204
  var pixels = new Uint8ClampedArray(width * height * 4);
5205
5205
  var stats = statsArg || getScalingStats(samples, bands, noData, recipe);
5206
5206
  var sourceRange = recipe.scaling == 'none' ? getPixelTypeRange(grid.pixelType) : null;
5207
- var displayRange = getDisplayRange(recipe.scaleRange);
5207
+ var displayRange = getDisplayRange$1(recipe.scaleRange);
5208
5208
  var src, dest, val, isNoData, j, sample;
5209
5209
  for (var y = 0; y < height; y++) {
5210
5210
  for (var x = 0; x < width; x++) {
@@ -5642,7 +5642,7 @@
5642
5642
  return range;
5643
5643
  }
5644
5644
 
5645
- function getDisplayRange(scaleRange) {
5645
+ function getDisplayRange$1(scaleRange) {
5646
5646
  return [
5647
5647
  scaleRange[0] / 100 * 255,
5648
5648
  scaleRange[1] / 100 * 255
@@ -21063,6 +21063,10 @@
21063
21063
  // diverging schemes, of classes:
21064
21064
  // the total, or per side)
21065
21065
  // preset: name or null, reversed: boolean, (presets)
21066
+ // range: {start, end, base} or null (presets: the part of the ramp
21067
+ // the tiles are taken from, 0-1
21068
+ // in the preset's own direction;
21069
+ // see getSchemeRange())
21066
21070
  // pins: [{t, color}] or null, (custom sequential ramps)
21067
21071
  // vibrance, longHue (custom sequential ramps, see
21068
21072
  // getOklchInterpolator())
@@ -21126,7 +21130,7 @@
21126
21130
  var minSchemeColors = 2;
21127
21131
  var maxSchemeColors = 12;
21128
21132
  var maxCategoricalColors = 20;
21129
- var defaultCategoricalPreset = 'Tableau10';
21133
+ var defaultCategoricalPreset = 'batlowS';
21130
21134
  var defaultNonAdjacentColors = 5;
21131
21135
  var defaultDivergingPreset = 'RdBu';
21132
21136
  var defaultDivergingClasses = 7;
@@ -21138,7 +21142,8 @@
21138
21142
  // (-classify's vibrance= is the same, scaled to 0-1)
21139
21143
  var defaultVibrance = 0;
21140
21144
  var maxVibrance = internal.MAX_VIBRANCE_CHROMA;
21141
- var defaultEnds = ['#344a72', '#f0d26b'];
21145
+ // the default sequential ramp: cream to blue, through green and teal
21146
+ var defaultEnds = ['#fff8da', '#2d4d8e'];
21142
21147
  // Cyclic ramps start and end on the same hue, which reads as a category
21143
21148
  // rather than an order.
21144
21149
  var excludedPresets = ['Rainbow', 'Sinebow'];
@@ -21149,19 +21154,33 @@
21149
21154
  var layerSchemes = new WeakMap();
21150
21155
 
21151
21156
  function getSequentialPresetNames() {
21152
- return internal.getColorSchemeNames('sequential')
21153
- .concat(internal.getColorSchemeNames('rainbow'))
21154
- .filter(function(name) {
21155
- return !excludedPresets.includes(name);
21156
- });
21157
+ return flattenGroups(getPresetGroups('sequential'));
21157
21158
  }
21158
21159
 
21159
21160
  function getDivergingPresetNames() {
21160
- return internal.getColorSchemeNames('diverging');
21161
+ return flattenGroups(getPresetGroups('diverging'));
21161
21162
  }
21162
21163
 
21163
21164
  function getCategoricalPresetNames() {
21164
- return internal.getColorSchemeNames('categorical');
21165
+ return flattenGroups(getPresetGroups('categorical'));
21166
+ }
21167
+
21168
+ // The presets of a scheme type, by source, for the palette menu:
21169
+ // [{source, names}]. Sequential presets include -classify's multi-hue
21170
+ // ('rainbow') schemes.
21171
+ function getPresetGroups(type) {
21172
+ var types = type == 'sequential' ? ['sequential', 'rainbow'] : [type];
21173
+ return internal.getColorSchemeGroups(types).map(function(group) {
21174
+ return {source: group.source, names: group.names.filter(function(name) {
21175
+ return !excludedPresets.includes(name);
21176
+ })};
21177
+ }).filter(function(group) {
21178
+ return group.names.length > 0;
21179
+ });
21180
+ }
21181
+
21182
+ function flattenGroups(groups) {
21183
+ return groups.reduce(function(memo, group) { return memo.concat(group.names); }, []);
21165
21184
  }
21166
21185
 
21167
21186
  // The scheme a panel tab starts with on a layer
@@ -21594,7 +21613,8 @@
21594
21613
  });
21595
21614
  }
21596
21615
  if (scheme.preset) {
21597
- colors = getPresetColors(scheme.preset, getRampSize(scheme));
21616
+ colors = scheme.range ? getPresetSection(scheme, getRampSize(scheme), scheme.range) :
21617
+ getPresetColors(scheme.preset, getRampSize(scheme));
21598
21618
  if (scheme.reversed) colors.reverse();
21599
21619
  return colors.map(function(color) {
21600
21620
  return {color: color, pinned: false, adjusted: false};
@@ -21628,6 +21648,88 @@
21628
21648
  return internal.getColorRamp(name, n).map(toHex);
21629
21649
  }
21630
21650
 
21651
+ // The part of a sequential or diverging preset that its tiles are taken
21652
+ // from: {start, end, base}, 0-1 in the preset's own direction (before
21653
+ // reversing). A diverging range is the same on both sides of the center.
21654
+ // base is the number of tiles when the range was first narrowed: a preset
21655
+ // with a hand-picked set of that size (ColorBrewer's) is interpolated
21656
+ // between the set's colors, so that removing an end tile leaves the others
21657
+ // as they were.
21658
+ var minRangeSpan = 0.1;
21659
+
21660
+ function getSchemeRange(scheme) {
21661
+ return scheme.range || {start: 0, end: 1, base: getRampSize(scheme)};
21662
+ }
21663
+
21664
+ function hasSchemeRange(scheme) {
21665
+ return !!scheme.preset && scheme.type != 'categorical';
21666
+ }
21667
+
21668
+ // The range as positions along the tiles, left to right: [left, right]
21669
+ function getDisplayRange(scheme) {
21670
+ var range = getSchemeRange(scheme);
21671
+ return scheme.reversed ? [1 - range.end, 1 - range.start] : [range.start, range.end];
21672
+ }
21673
+
21674
+ // Moves one end of the range, given as a position along the tiles (0-1,
21675
+ // left to right); a diverging range moves at both ends.
21676
+ // side: 'left' or 'right'
21677
+ function setSchemeRangeEnd(scheme, side, pos) {
21678
+ var display = getDisplayRange(scheme);
21679
+ var left = display[0], right = display[1];
21680
+ pos = clamp$4(+pos || 0, 0, 1);
21681
+ if (scheme.type == 'diverging') {
21682
+ left = side == 'left' ? pos : 1 - pos;
21683
+ left = clamp$4(left, 0, (1 - minRangeSpan) / 2);
21684
+ right = 1 - left;
21685
+ } else if (side == 'left') {
21686
+ left = Math.min(pos, right - minRangeSpan);
21687
+ } else {
21688
+ right = Math.max(pos, left + minRangeSpan);
21689
+ }
21690
+ return setDisplayRange(scheme, left, right);
21691
+ }
21692
+
21693
+ function resetSchemeRange(scheme) {
21694
+ return Object.assign({}, scheme, {range: null});
21695
+ }
21696
+
21697
+ // Takes the tile at one end of a sequential preset away, keeping the colors
21698
+ // of the others: the range ends where the next tile was.
21699
+ // side: 'left' or 'right'
21700
+ function removeEndTile(scheme, side) {
21701
+ var display, step;
21702
+ if (!canRemoveEndTile(scheme)) return scheme;
21703
+ display = getDisplayRange(scheme);
21704
+ step = (display[1] - display[0]) / (scheme.n - 1);
21705
+ if (side == 'left') display[0] += step;
21706
+ else display[1] -= step;
21707
+ return Object.assign(setDisplayRange(scheme, display[0], display[1]), {n: scheme.n - 1});
21708
+ }
21709
+
21710
+ function canRemoveEndTile(scheme) {
21711
+ return hasSchemeRange(scheme) && scheme.type == 'sequential' &&
21712
+ scheme.n > getMinSchemeColors(scheme);
21713
+ }
21714
+
21715
+ function setDisplayRange(scheme, left, right) {
21716
+ var base = getSchemeRange(scheme).base;
21717
+ var start = scheme.reversed ? 1 - right : left;
21718
+ var end = scheme.reversed ? 1 - left : right;
21719
+ if (start <= 0 && end >= 1) return resetSchemeRange(scheme);
21720
+ return Object.assign({}, scheme, {range: {start: Math.max(start, 0), end: Math.min(end, 1), base: base}});
21721
+ }
21722
+
21723
+ // The whole of a preset, left to right, as the range's strip shows it
21724
+ function getRangeStripColors(scheme, n) {
21725
+ var colors = getPresetSection(scheme, n, {start: 0, end: 1, base: getSchemeRange(scheme).base});
21726
+ return scheme.reversed ? colors.reverse() : colors;
21727
+ }
21728
+
21729
+ function getPresetSection(scheme, n, range) {
21730
+ return internal.getColorRampSection(scheme.preset, n, range.start, range.end, range.base).map(toHex);
21731
+ }
21732
+
21631
21733
  // All the swatches of a categorical scheme, in order: the first n are used
21632
21734
  function getCategoricalPalette(scheme) {
21633
21735
  var colors;
@@ -21671,7 +21773,7 @@
21671
21773
  next.n = clampColorCount(next, next.n, count);
21672
21774
  return next;
21673
21775
  }
21674
- return Object.assign({}, scheme, {preset: name, reversed: false, pins: null});
21776
+ return Object.assign({}, scheme, {preset: name, reversed: false, pins: null, range: null});
21675
21777
  }
21676
21778
 
21677
21779
  // A preset as a custom ramp, pinned at its ends, for editing.
@@ -21685,6 +21787,7 @@
21685
21787
  return Object.assign({}, scheme, {
21686
21788
  preset: null,
21687
21789
  reversed: false,
21790
+ range: null,
21688
21791
  pins: scheme.type == 'diverging' ?
21689
21792
  [{t: 0, color: colors[0]}, {t: 0.5, color: colors[(colors.length - 1) / 2]},
21690
21793
  {t: 1, color: colors[colors.length - 1]}] :
@@ -21969,6 +22072,7 @@
21969
22072
  var paletteBtn, paletteMenu, countField, tileRow, gradientEl, tilesEl, picker, fieldRow, fieldSelect, methodSelect,
21970
22073
  noFieldsNote, selectionNote, controlsEl, vibranceRow, vibranceInput,
21971
22074
  longHueBtn, continuousBtn, reverseBtn, shuffleBtn, dropMarker, nullControl, nullCount, countLabel,
22075
+ rangeEl, rangeStrip, rangeShades, rangeHandles,
21972
22076
  divergingEl, pivotSelect, pivotInput, pivotNote, neutralToggle, splitSelect;
21973
22077
  // set while a tile is being dragged, so that letting go isn't a click
21974
22078
  var tileDrag = null;
@@ -22126,6 +22230,7 @@
22126
22230
  changeScheme(setSchemeVibrance(scheme, val / 1000));
22127
22231
  });
22128
22232
  vibranceInput = vibranceRow.findChild('input');
22233
+ initRangeControl(vibranceRow);
22129
22234
  longHueBtn = addIconButton(vibranceRow, 'Go the long way around the color wheel', longHueIcon, function() {
22130
22235
  changeScheme(setSchemeLongHue(scheme, !scheme.longHue));
22131
22236
  }).addClass('long-hue-btn');
@@ -22326,6 +22431,7 @@
22326
22431
  var input = El('input').attr('type', 'range').attr('min', min).attr('max', max).attr('step', step)
22327
22432
  .attr('aria-label', label).appendTo(row)
22328
22433
  .on('input', function() {
22434
+ showSliderFill(input);
22329
22435
  onInput(+input.node().value);
22330
22436
  })
22331
22437
  .on('change', releaseFocus);
@@ -22340,12 +22446,109 @@
22340
22446
  return btn;
22341
22447
  }
22342
22448
 
22449
+ // The part of a preset that the tiles are taken from: a strip of the whole
22450
+ // ramp, shaded outside the part in use, with a handle at each end of it
22451
+ function initRangeControl(row) {
22452
+ var label = El('span').addClass('color-scheme-hint-label color-scheme-range-part')
22453
+ .attr('data-tooltip', 'Use part of the color ramp\n(double-click the strip to use all of it)')
22454
+ .appendTo(row).text('Range')
22455
+ .on('mouseenter', function() { keepTooltipInWindow(label.node()); });
22456
+ rangeEl = El('div').addClass('color-scheme-range color-scheme-range-part').appendTo(row)
22457
+ .on('pointerdown', startRangeDrag)
22458
+ .on('dblclick', function() {
22459
+ changeScheme(resetSchemeRange(scheme));
22460
+ });
22461
+ rangeStrip = El('div').addClass('color-scheme-range-strip').appendTo(rangeEl);
22462
+ rangeShades = ['left', 'right'].map(function(side) {
22463
+ return El('div').addClass('color-scheme-range-shade ' + side).appendTo(rangeEl);
22464
+ });
22465
+ rangeHandles = ['left', 'right'].map(function(side) {
22466
+ return El('div').addClass('color-scheme-range-handle').attr('role', 'slider').attr('tabindex', '0')
22467
+ .attr('aria-label', side == 'left' ? 'Start of range' : 'End of range')
22468
+ .attr('aria-valuemin', '0').attr('aria-valuemax', '100')
22469
+ .appendTo(rangeEl)
22470
+ .on('keydown', function(e) {
22471
+ onRangeKey(e, side);
22472
+ });
22473
+ });
22474
+ }
22475
+
22476
+ function renderRange() {
22477
+ var display, colors;
22478
+ if (!hasSchemeRange(scheme)) return;
22479
+ display = getDisplayRange(scheme);
22480
+ colors = getRangeStripColors(scheme, 33);
22481
+ rangeStrip.css('background-image', 'linear-gradient(to right, ' + colors.join(', ') + ')');
22482
+ rangeShades[0].css('width', pct(display[0]));
22483
+ rangeShades[1].css('width', pct(1 - display[1]));
22484
+ rangeHandles.forEach(function(handle, i) {
22485
+ handle.css('left', pct(display[i])).attr('aria-valuenow', String(Math.round(display[i] * 100)));
22486
+ });
22487
+ }
22488
+
22489
+ function pct(val) {
22490
+ return round(val * 100) + '%';
22491
+ }
22492
+
22493
+ // Dragging a handle (or pressing the strip, which takes the nearer handle
22494
+ // there) moves that end of the range
22495
+ function startRangeDrag(e) {
22496
+ var box = rangeStrip.node().getBoundingClientRect();
22497
+ var display = getDisplayRange(scheme);
22498
+ var pos = getPos(e);
22499
+ var side = e.target == rangeHandles[0].node() ? 'left' :
22500
+ e.target == rangeHandles[1].node() ? 'right' :
22501
+ Math.abs(pos - display[0]) <= Math.abs(pos - display[1]) ? 'left' : 'right';
22502
+ if (e.button !== 0 || !(box.width > 0)) return;
22503
+ e.preventDefault();
22504
+ picker.hide();
22505
+ move(e);
22506
+ document.addEventListener('pointermove', move);
22507
+ document.addEventListener('pointerup', finish);
22508
+ document.addEventListener('pointercancel', finish);
22509
+
22510
+ // in steps of half a percent, so that a drag runs fewer commands
22511
+ function getPos(e) {
22512
+ return Math.round((e.clientX - box.left) / box.width * 200) / 200;
22513
+ }
22514
+
22515
+ function move(e) {
22516
+ var next = setSchemeRangeEnd(scheme, side, getPos(e));
22517
+ if (getDisplayRange(next).join() != getDisplayRange(scheme).join()) changeScheme(next);
22518
+ }
22519
+
22520
+ function finish() {
22521
+ document.removeEventListener('pointermove', move);
22522
+ document.removeEventListener('pointerup', finish);
22523
+ document.removeEventListener('pointercancel', finish);
22524
+ }
22525
+ }
22526
+
22527
+ function onRangeKey(e, side) {
22528
+ var step = e.shiftKey ? 0.05 : 0.01;
22529
+ var display = getDisplayRange(scheme);
22530
+ var pos = side == 'left' ? display[0] : display[1];
22531
+ if (e.key == 'ArrowLeft' || e.key == 'ArrowDown') {
22532
+ pos -= step;
22533
+ } else if (e.key == 'ArrowRight' || e.key == 'ArrowUp') {
22534
+ pos += step;
22535
+ } else {
22536
+ return;
22537
+ }
22538
+ e.preventDefault();
22539
+ e.stopPropagation();
22540
+ changeScheme(setSchemeRangeEnd(scheme, side, pos));
22541
+ }
22542
+
22343
22543
  // Presets and categorical schemes have no interpolated tiles for vibrance
22344
- // or the hue path to change; the row keeps only the reverse button for them.
22544
+ // or the hue path to change; the row keeps only the reverse button for them,
22545
+ // and for sequential and diverging presets, the range.
22345
22546
  function renderVibrance() {
22346
22547
  var vibrance = getSchemeVibrance(scheme);
22347
22548
  setSliderValue(vibranceInput, Math.round(vibrance * 1000));
22348
22549
  vibranceRow.classed('preset', !!scheme.preset || scheme.type == 'categorical');
22550
+ vibranceRow.classed('ranged', hasSchemeRange(scheme));
22551
+ renderRange();
22349
22552
  reverseBtn.classed('hidden', scheme.type == 'categorical');
22350
22553
  shuffleBtn.classed('hidden', scheme.type != 'categorical');
22351
22554
  // each half of a diverging ramp runs from a low-chroma center, where the
@@ -22360,6 +22563,16 @@
22360
22563
 
22361
22564
  function setSliderValue(input, val) {
22362
22565
  if (input.node().value != val) input.node().value = val;
22566
+ showSliderFill(input);
22567
+ }
22568
+
22569
+ // the track is filled up to the center of the handle, which travels the
22570
+ // track's width less its 12px box (see page.css)
22571
+ function showSliderFill(input) {
22572
+ var el = input.node();
22573
+ var min = +el.min, max = +el.max;
22574
+ var fill = max > min ? (el.value - min) / (max - min) : 0;
22575
+ el.style.setProperty('--fill', 'calc(6px + (100% - 12px) * ' + round(fill * 1000) / 1000 + ')');
22363
22576
  }
22364
22577
 
22365
22578
  function renderFieldOptions(fields) {
@@ -22389,6 +22602,8 @@
22389
22602
  var classLabels = categorical ? null : continuous ? getStopLabels() : getClassLabels(tileUse);
22390
22603
  var groups = categorical && scheme.method == 'categorical' ?
22391
22604
  getSwatchCategories(getCategories(targetLayer, scheme.field), used) : null;
22605
+ // the end tiles of a sequential preset can be taken away
22606
+ var removable = canRemoveEndTile(scheme);
22392
22607
  var n, perRow;
22393
22608
  // a categorical scheme shows its whole palette, and marks the swatches
22394
22609
  // in use
@@ -22423,6 +22638,14 @@
22423
22638
  startTileDrag(e, i);
22424
22639
  });
22425
22640
  }
22641
+ if (removable && (i === 0 || i == n - 1)) {
22642
+ El('button').addClass('color-scheme-tile-remove').attr('type', 'button')
22643
+ .attr('aria-label', 'Remove this color').text('×').appendTo(tileEl)
22644
+ .on('click', function(e) {
22645
+ e.stopPropagation();
22646
+ changeScheme(removeEndTile(scheme, i === 0 ? 'left' : 'right'));
22647
+ });
22648
+ }
22426
22649
  if (groups && inUse || classLabels && classLabels[i]) {
22427
22650
  tileEl.attr('data-tooltip', groups ? formatCategories(groups[i]) : classLabels[i])
22428
22651
  .on('mouseenter', function() { keepTooltipInWindow(tileEl.node()); });
@@ -22674,16 +22897,17 @@
22674
22897
 
22675
22898
  function renderPaletteMenu() {
22676
22899
  var categorical = scheme.type == 'categorical';
22677
- var names = categorical ? getCategoricalPresetNames() :
22678
- scheme.type == 'diverging' ? getDivergingPresetNames() : getSequentialPresetNames();
22679
22900
  paletteMenu.empty();
22680
22901
  addPaletteItem('Custom', getSchemeColors(makeSchemeCustom(scheme)), !scheme.preset, function() {
22681
22902
  changeScheme(makeSchemeCustom(scheme));
22682
22903
  });
22683
- names.forEach(function(name) {
22684
- var colors = categorical ? getCategoricalPresetColors(name) : getPresetColors(name, 7);
22685
- addPaletteItem(name, colors, scheme.preset == name, function() {
22686
- changeScheme(choosePreset(scheme, name, getCategoryCount()));
22904
+ getPresetGroups(scheme.type).forEach(function(group) {
22905
+ El('div').addClass('color-scheme-palette-heading').appendTo(paletteMenu).text(group.source);
22906
+ group.names.forEach(function(name) {
22907
+ var colors = categorical ? getCategoricalPresetColors(name) : getPresetColors(name, 7);
22908
+ addPaletteItem(name, colors, scheme.preset == name, function() {
22909
+ changeScheme(choosePreset(scheme, name, getCategoryCount()));
22910
+ });
22687
22911
  });
22688
22912
  });
22689
22913
  }
@@ -26293,9 +26517,20 @@
26293
26517
  _self.dispatchEvent('leave');
26294
26518
  }
26295
26519
 
26520
+ // mouseover and mouseout can arrive after a quick move has already pressed
26521
+ // and released the button somewhere else -- a click on a panel over the map
26522
+ // then looked like a click on the map. A press or release is over the area
26523
+ // if it lands on the area itself.
26524
+ function updateHover(e) {
26525
+ var over = !!e.target && element.contains(e.target);
26526
+ if (over && !_isOver) onAreaEnter();
26527
+ else if (!over && _isOver) onAreaOut();
26528
+ }
26529
+
26296
26530
  function onMouseUp(e) {
26297
- var evt = procMouseEvent(e),
26298
- elapsed, dx, dy;
26531
+ var evt, elapsed, dx, dy;
26532
+ updateHover(e);
26533
+ evt = procMouseEvent(e);
26299
26534
  _self.dispatchEvent('mouseup', evt);
26300
26535
  if (_dragging) {
26301
26536
  stopDragging(evt);
@@ -26317,6 +26552,7 @@
26317
26552
  }
26318
26553
 
26319
26554
  function onMouseDown(e) {
26555
+ updateHover(e);
26320
26556
  if (e.button != 2 && e.which != 3) { // ignore right-click
26321
26557
  _downEvt = procMouseEvent(e);
26322
26558
  }
package/www/mapshaper.js CHANGED
@@ -71333,7 +71333,7 @@ ${css.join('\n')}
71333
71333
  return new Rgb(o.r, o.g, o.b, o.opacity);
71334
71334
  }
71335
71335
 
71336
- function rgb$1(r, g, b, opacity) {
71336
+ function rgb(r, g, b, opacity) {
71337
71337
  return arguments.length === 1 ? rgbConvert(r) : new Rgb(r, g, b, opacity == null ? 1 : opacity);
71338
71338
  }
71339
71339
 
@@ -71344,7 +71344,7 @@ ${css.join('\n')}
71344
71344
  this.opacity = +opacity;
71345
71345
  }
71346
71346
 
71347
- define(Rgb, rgb$1, extend(Color, {
71347
+ define(Rgb, rgb, extend(Color, {
71348
71348
  brighter(k) {
71349
71349
  k = k == null ? brighter : Math.pow(brighter, k);
71350
71350
  return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity);
@@ -71606,11 +71606,11 @@ ${css.join('\n')}
71606
71606
  return d ? linear(a, d) : constant(isNaN(a) ? b : a);
71607
71607
  }
71608
71608
 
71609
- var rgb = (function rgbGamma(y) {
71609
+ var interpolateRgb = (function rgbGamma(y) {
71610
71610
  var color = gamma(y);
71611
71611
 
71612
- function rgb(start, end) {
71613
- var r = color((start = rgb$1(start)).r, (end = rgb$1(end)).r),
71612
+ function rgb$1(start, end) {
71613
+ var r = color((start = rgb(start)).r, (end = rgb(end)).r),
71614
71614
  g = color(start.g, end.g),
71615
71615
  b = color(start.b, end.b),
71616
71616
  opacity = nogamma(start.opacity, end.opacity);
@@ -71623,9 +71623,9 @@ ${css.join('\n')}
71623
71623
  };
71624
71624
  }
71625
71625
 
71626
- rgb.gamma = rgbGamma;
71626
+ rgb$1.gamma = rgbGamma;
71627
71627
 
71628
- return rgb;
71628
+ return rgb$1;
71629
71629
  })(1);
71630
71630
 
71631
71631
  function rgbSpline(spline) {
@@ -71636,7 +71636,7 @@ ${css.join('\n')}
71636
71636
  b = new Array(n),
71637
71637
  i, color;
71638
71638
  for (i = 0; i < n; ++i) {
71639
- color = rgb$1(colors[i]);
71639
+ color = rgb(colors[i]);
71640
71640
  r[i] = color.r || 0;
71641
71641
  g[i] = color.g || 0;
71642
71642
  b[i] = color.b || 0;
@@ -71789,8 +71789,8 @@ ${css.join('\n')}
71789
71789
  var t = typeof b, c;
71790
71790
  return b == null || t === "boolean" ? constant(b)
71791
71791
  : (t === "number" ? number
71792
- : t === "string" ? ((c = color(b)) ? (b = c, rgb) : string)
71793
- : b instanceof color ? rgb
71792
+ : t === "string" ? ((c = color(b)) ? (b = c, interpolateRgb) : string)
71793
+ : b instanceof color ? interpolateRgb
71794
71794
  : b instanceof Date ? date
71795
71795
  : isNumberArray(b) ? numberArray
71796
71796
  : Array.isArray(b) ? genericArray
@@ -71825,6 +71825,16 @@ ${css.join('\n')}
71825
71825
  cubehelix$1(hue);
71826
71826
  var cubehelixLong = cubehelix$1(nogamma);
71827
71827
 
71828
+ function piecewise(interpolate, values) {
71829
+ if (values === undefined) values = interpolate, interpolate = d3_interpolate;
71830
+ var i = 0, n = values.length - 1, v = values[0], I = new Array(n < 0 ? 0 : n);
71831
+ while (i < n) I[i] = interpolate(v, v = values[++i]);
71832
+ return function(t) {
71833
+ var i = Math.max(0, Math.min(n - 1, Math.floor(t *= n)));
71834
+ return I[i](t - i);
71835
+ };
71836
+ }
71837
+
71828
71838
  // OKLab conversion (Björn Ottosson, https://bottosson.github.io/posts/oklab/)
71829
71839
  // RGB objects use 0-255 channels, as returned by parseColor().
71830
71840
 
@@ -73968,7 +73978,7 @@ ${css.join('\n')}
73968
73978
  return c$1 + "";
73969
73979
  }
73970
73980
 
73971
- var c = rgb$1(),
73981
+ var c = rgb(),
73972
73982
  pi_1_3 = Math.PI / 3,
73973
73983
  pi_2_3 = Math.PI * 2 / 3;
73974
73984
 
@@ -74084,6 +74094,59 @@ ${css.join('\n')}
74084
74094
  schemeYlOrRd: scheme$6
74085
74095
  });
74086
74096
 
74097
+ // Scientific colour maps, version 8.0.1, by Fabio Crameri
74098
+ // https://www.fabiocrameri.ch/colourmaps/ (https://doi.org/10.5281/zenodo.8409685)
74099
+ //
74100
+ // Each ramp is 33 evenly spaced colors (as packed hex), sampled from the
74101
+ // 256-color version, which they reproduce to within 0.008 OKLab deltaE; the
74102
+ // odd count gives diverging ramps a color at their center. batlowS is the
74103
+ // first 20 swatches of batlow's categorical palette.
74104
+ //
74105
+ // The Scientific colour maps are licensed under a MIT License
74106
+ // Copyright (c) 2023, Fabio Crameri
74107
+ // Permission is hereby granted, free of charge, to any person obtaining a
74108
+ // copy of this software and associated documentation files (the "Software"),
74109
+ // to deal in the Software without restriction, including without limitation
74110
+ // the rights to use, copy, modify, merge, publish, distribute, sublicense,
74111
+ // and/or sell copies of the Software, and to permit persons to whom the
74112
+ // Software is furnished to do so, subject to the following conditions:
74113
+ // The above copyright notice and this permission notice shall be included in
74114
+ // all copies or substantial portions of the Software.
74115
+ // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
74116
+ // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
74117
+ // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
74118
+ // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
74119
+ // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
74120
+ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
74121
+ // DEALINGS IN THE SOFTWARE.
74122
+
74123
+ var crameriSequential = {
74124
+ batlow: '01195908255b0d315d0f3b5f114360134b611652621b59622260612a655e356a59406f544d734d597646667a3f737e3881823290862da08a2bb08d2ebf9035ce923fdb954ce8985bf29d6cf8a27efca891fdaea3fdb4b4fdbac5fcc0d6fbc6e8faccfa',
74125
+ batlowW: '01195908255b0d315d0f3b5f114360134a611651621a5862205f6228655f326a5c3d6f5749745155794b627d446f823e7d87388c8c339d9232ae9838be9d44cca154d7a565e0a875e8ac84efb094f5b8a6fbc3bafed1ceffdfddffebeafff5f5fffefe',
74126
+ acton: '260d402d17493420523a2a5a413362473b6a4d4472534c79595481615b876a608b74628d7d638e87648e91648f9c658fa76690b36791bf6a93c97097cf789fd482a7d78db0da97b9dda2c2e0accae3b6d2e5c0dae8cae1ead3e8ecdbeeeee3f4f0eafa',
74127
+ bamako: '003b47043d45083f430c424010453e14483b194b381f4e342552312b562d325b29395f2440642048691b516f16597410627a0b6b7f057584017f87008a8900948c019f9108a99815b4a122bfa930cab240d4bb52ddc465e6cc78efd58af7dd9cffe5ad',
74128
+ bilbao: '4c0001580b1064161a6e202478292e8232398b3b4293444a994e509c56549f5d56a16458a26a59a4705aa6765ca77c5da9825eaa885fac8e61ae9463b09c66b4a46eb8ac7bbcb389bfb897c2bda4c5c2b0c9c7bccfcdc8d7d7d5e3e3e2f1f1f1ffffff',
74129
+ davos: '00054a031256081c610e276c1431761a3c802146892850902f5a9636639a3e6b9c46729d4e789d557e9b5d84996489966c8d937392907b978d839d8a8ba38895aa87a0b289adbc8dbcc894cbd49fdadfade6e9bceff0cbf6f6d9faf9e6fcfcf3fefefe',
74130
+ devon: '2c1a4c2b21542a285b29306329376a283f7227477b274f8429588f2c5f9a3265a5386bb04271bc4e78c65e80cf6e87d67d8edd8c95e29a9ce7a6a3ebb0aaeeb7b1f0beb8f2c4bff3cbc6f4d1cdf6d7d4f7dedbf8e4e2faebe9fbf2f0fcf8f8feffffff',
74131
+ lajolla: '191900201c04271e082f210d3724114127164c2b1c592f22663429753931853d3895423fa64644b64a48c54f4ad1564cd95f4ede6a4fe1744fe37e50e58751e79152e99a52eba353edad54efb755f1c159f4cd62f7d972fae588fcef9ffef7b6fffecb',
74132
+ lapaz: '1a0c641d176b1f207122297824327e263a842842892a4a8e2c52932f5a9733629b386a9e3d71a04378a24a7fa35286a45b8ca36591a27096a07a9b9e859e9b90a1999ba496a7a895b4ac96c2b299d0baa1dec4aceaceb9f3d8c8f9e1d6fceae5fef2f3',
74133
+ oslo: '010101050a100a121a0d18240e1e2e0f2439112a4413314f15395b1840671c4773214f7f26568c2d5e993667a54270b14f7abc5c83c3678bc77292c97c99ca859fca8fa4c998aac9a2b0caacb7cbb7bfcdc2c7d1ced1d7dadcdfe6e7e9f3f3f4ffffff',
74134
+ tokyo: '1c0e3429123837163d441d415024465b2d4963364c683f4e6b47506e4e506f5351705951715d52716152726652736a53746f53757554767c54778355798c567b95587e9f5b81ab5f87b7668fc3709ad17da8dd8eb8e9a2c9f1b4d8f7c5e5fad2effcdd',
74135
+ turku: '0000000e0e0d18181620201d28282330302a39382f41413549493951513e5a59426261456a6a4973724d7c7a51878355928b5a9e9360ab9a66b79f6dc2a373cca579d5a780dda887e4aa90ebae9af2b4a5f7bbb1fbc3bdfdccc8fed5d3ffdddcffe6e6'
74136
+ };
74137
+
74138
+ var crameriDiverging = {
74139
+ bam: '65024b77175d88266e97357da5428cb25099bd5ea5c76db0d17ebbd990c6e0a2d0e6b4d9ecc5e2f1d4e9f4e1eef6ebf1f6f1f1f3f3ecedf2e3e4eed4d7e7c1c7deaab4d191a0c3798cb5657aa6546999465a8c3a4c802f3e7425306819205a0d0d4c00',
74140
+ broc: '2c1a4c2b26582a3164293e70294a7d2d588939669449749f5a82a86c8fb27e9dbc91acc5a4bacfb7c8d9cad7e3dde5ebebeeecedeee0e7e7ceddddbcd4d4a9c9c995bbbb82abab709b9b618b8b547b7b476c6c3a5d5d2d4e4e2140401632330c262600',
74141
+ cork: '2c194c2b26592a3265283f71284b7e2d588a38669446729e567ea6668bae7798b889a6c19db4cbb1c4d6c7d4e1dbe4ebe6edecdfeae0cedfcebbd2bba8c5a794b89481ab816e9e6e5d935c4c884c3c7c3c2d702c20621e18541414450e1137090f2903',
74142
+ roma: '7e1700862c068e3c0c964b129d5818a3651ea97223af7e2ab68c32bd9a3cc4aa4acaba5cd0c971d2d789d1e19fcbe8b3c1eac2b2e9cda1e4d48ddcd778d2d764c5d452b8d044aacc399dc63190c12b83bc2677b7226ab11e5dab184fa511409f033198',
74143
+ vik: '001261021f69022b710237790344810450890c5e921b6d9b2f7ca6478db1609dbc79adc792bdd2acccdcc5dbe5dce5e9ece5e1eedacfe9cbb9e2bba4dcab8fd59c7bcf8e68c97f55c37243bc6331b3531fa5400e932e06832106741506660a07590008'
74144
+ };
74145
+
74146
+ var crameriCategorical = {
74147
+ batlowS: '011959faccfa828231226061f29d6d4d734d114360c09036fdb4b4dd954d356a59fcbfd6175262677b3ea18a2b0d315dfca890fbc6e82b655eb18d2f'
74148
+ };
74149
+
74087
74150
  var index = {
74088
74151
  categorical: [],
74089
74152
  sequential: [],
@@ -74092,10 +74155,29 @@ ${css.join('\n')}
74092
74155
  all: []
74093
74156
  };
74094
74157
  var ramps;
74158
+ // interpolators of the ramps that are stored as stops (not from d3)
74159
+ var stopInterpolators;
74160
+ // scheme name -> where the scheme comes from (see getColorSchemeGroups())
74161
+ var sources;
74162
+ // the order of the sources in lists of schemes
74163
+ var sourceOrder = ['ColorBrewer', 'Tableau', 'Matplotlib', 'Crameri', 'd3'];
74164
+ // Schemes are listed by their designers, as far as they're known. 'd3' is
74165
+ // d3-scale-chromatic's own schemes, and others that it brings in: Turbo
74166
+ // (Google) and CubehelixDefault (D. A. Green's cubehelix).
74167
+ var d3Sources = {
74168
+ ColorBrewer: 'Accent,Dark2,Paired,Pastel1,Pastel2,Set1,Set2,Set3,' +
74169
+ 'Blues,Greens,Greys,Purples,Reds,Oranges,BuGn,BuPu,GnBu,OrRd,PuBuGn,PuBu,PuRd,RdPu,YlGnBu,YlGn,YlOrBr,YlOrRd,' +
74170
+ 'BrBG,PRGn,PiYG,PuOr,RdBu,RdGy,RdYlBu,RdYlGn,Spectral',
74171
+ Tableau: 'Tableau10,Tableau20',
74172
+ Matplotlib: 'Cividis,Viridis,Magma,Inferno,Plasma',
74173
+ d3: 'Category10,Category20,Category20b,Category20c,CubehelixDefault,Rainbow,Warm,Cool,Sinebow,Turbo'
74174
+ };
74095
74175
 
74096
74176
  function initSchemes() {
74097
74177
  if (ramps) return;
74098
74178
  ramps = {};
74179
+ stopInterpolators = {};
74180
+ sources = {};
74099
74181
  addSchemesFromD3('categorical', 'Category10,Accent,Dark2,Paired,Pastel1,Pastel2,Set1,Set2,Set3,Tableau10');
74100
74182
  addSchemesFromD3('sequential', 'Blues,Greens,Greys,Purples,Reds,Oranges,BuGn,BuPu,GnBu,OrRd,PuBuGn,PuBu,PuRd,RdPu,YlGnBu,YlGn,YlOrBr,YlOrRd');
74101
74183
  addSchemesFromD3('rainbow', 'Cividis,CubehelixDefault,Rainbow,Warm,Cool,Sinebow,Turbo,Viridis,Magma,Inferno,Plasma');
@@ -74109,9 +74191,29 @@ ${css.join('\n')}
74109
74191
  '3182bd6baed69ecae1c6dbefe6550dfd8d3cfdae6bfdd0a231a35474c476a1d99bc7e9c0756bb19e9ac8bcbddcdadaeb636363969696bdbdbdd9d9d9');
74110
74192
  addCategoricalScheme('Tableau20',
74111
74193
  '4c78a89ecae9f58518ffbf7954a24b88d27ab79a20f2cf5b43989483bcb6e45756ff9d9879706ebab0acd67195fcbfd2b279a2d6a5c99e765fd8b5a5');
74194
+ Object.keys(d3Sources).forEach(function(source) {
74195
+ d3Sources[source].split(',').forEach(function(name) {
74196
+ sources[name] = source;
74197
+ });
74198
+ });
74199
+ addStoppedSchemes('sequential', crameriSequential, 'Crameri');
74200
+ addStoppedSchemes('diverging', crameriDiverging, 'Crameri');
74201
+ Object.keys(crameriCategorical).forEach(function(name) {
74202
+ addCategoricalScheme(name, crameriCategorical[name]);
74203
+ sources[name] = 'Crameri';
74204
+ });
74112
74205
  index.all = [].concat(index.sequential, index.rainbow, index.diverging, index.categorical);
74113
74206
  }
74114
74207
 
74208
+ // Ramps stored as evenly spaced colors, interpolated linearly between them
74209
+ function addStoppedSchemes(type, schemes, source) {
74210
+ Object.keys(schemes).forEach(function(name) {
74211
+ index[type].push(name);
74212
+ stopInterpolators[name] = piecewise(interpolateRgb, unpackRamp(schemes[name]));
74213
+ sources[name] = source;
74214
+ });
74215
+ }
74216
+
74115
74217
  function standardName(name) {
74116
74218
  if (!name) return null;
74117
74219
  var lcname = name.toLowerCase();
@@ -74173,12 +74275,15 @@ ${css.join('\n')}
74173
74275
  }
74174
74276
 
74175
74277
  function printColorSchemeNames() {
74278
+ var types = [['categorical', 'Categorical'], ['sequential', 'Sequential'],
74279
+ ['diverging', 'Diverging'], ['rainbow', 'Multi-hue/rainbow']];
74176
74280
  initSchemes();
74177
- print('Built-in color schemes (from d3):');
74178
- print ('Categorical\n' + formatStringsAsGrid(index.categorical));
74179
- print ('\nSequential\n' + formatStringsAsGrid(index.sequential));
74180
- print ('\nDiverging\n' + formatStringsAsGrid(index.diverging));
74181
- print ('\nMulti-hue/rainbow\n' + formatStringsAsGrid(index.rainbow));
74281
+ print('Built-in color schemes');
74282
+ types.forEach(function(type) {
74283
+ getColorSchemeGroups(type[0]).forEach(function(group) {
74284
+ print('\n' + type[1] + ' (' + group.source + ')\n' + formatStringsAsGrid(group.names));
74285
+ });
74286
+ });
74182
74287
  }
74183
74288
 
74184
74289
  // type: categorical, sequential, rainbow or diverging
@@ -74188,6 +74293,19 @@ ${css.join('\n')}
74188
74293
  return index[type].concat();
74189
74294
  }
74190
74295
 
74296
+ // The schemes of one or more types, by source: [{source, names}]
74297
+ // (sources: ColorBrewer, Tableau, Matplotlib, Crameri, d3)
74298
+ function getColorSchemeGroups(types) {
74299
+ var names = [].concat(types).reduce(function(memo, type) {
74300
+ return memo.concat(getColorSchemeNames(type));
74301
+ }, []);
74302
+ return sourceOrder.map(function(source) {
74303
+ return {source: source, names: names.filter(function(name) { return sources[name] == source; })};
74304
+ }).filter(function(group) {
74305
+ return group.names.length > 0;
74306
+ });
74307
+ }
74308
+
74191
74309
  function pickRandomColorScheme(type) {
74192
74310
  initSchemes();
74193
74311
  var names = index[type];
@@ -74267,7 +74385,7 @@ ${css.join('\n')}
74267
74385
  initSchemes();
74268
74386
  name = standardName(name);
74269
74387
  var ramps = d3Scales['scheme' + name];
74270
- var interpolate = d3Scales['interpolate' + name];
74388
+ var interpolate = d3Scales['interpolate' + name] || stopInterpolators[name];
74271
74389
  var ramp;
74272
74390
  if (!ramps && !interpolate) {
74273
74391
  stop$1('Unknown color scheme name:', name);
@@ -74286,6 +74404,26 @@ ${css.join('\n')}
74286
74404
  return ramp;
74287
74405
  }
74288
74406
 
74407
+ // n colors from part of a ramp, evenly spaced from start to end (0-1).
74408
+ // base: interpolate between the colors of the scheme's set of this size, if
74409
+ // it has one (ColorBrewer's hand-picked sets), so that a section of a set
74410
+ // keeps its colors; otherwise the scheme's own interpolator is used
74411
+ function getColorRampSection(name, n, start, end, base) {
74412
+ initSchemes();
74413
+ name = standardName(name);
74414
+ var sets = d3Scales['scheme' + name];
74415
+ var interpolate = d3Scales['interpolate' + name] || stopInterpolators[name];
74416
+ var colors = [];
74417
+ if (!interpolate || index.categorical.includes(name)) {
74418
+ stop$1('Not a sequential or diverging color scheme:', name);
74419
+ }
74420
+ if (sets && sets[base]) interpolate = piecewise(interpolateRgb, sets[base]);
74421
+ for (var i=0; i<n; i++) {
74422
+ colors.push(interpolate(n > 1 ? start + (end - start) * i / (n - 1) : (start + end) / 2));
74423
+ }
74424
+ return colors;
74425
+ }
74426
+
74289
74427
  function getInterpolatedRamp(interpolate, n) {
74290
74428
  if (n > 0 === false || !utils.isInteger(n)) {
74291
74429
  error('Expected a positive integer');
@@ -74302,6 +74440,8 @@ ${css.join('\n')}
74302
74440
  getCategoricalColorScheme: getCategoricalColorScheme,
74303
74441
  getCategoricalColors: getCategoricalColors,
74304
74442
  getColorRamp: getColorRamp,
74443
+ getColorRampSection: getColorRampSection,
74444
+ getColorSchemeGroups: getColorSchemeGroups,
74305
74445
  getColorSchemeNames: getColorSchemeNames,
74306
74446
  getRandomizedCategoricalColorScheme: getRandomizedCategoricalColorScheme,
74307
74447
  isCategoricalColorScheme: isCategoricalColorScheme,
@@ -87771,7 +87911,7 @@ ${css.join('\n')}
87771
87911
  return name == 'rectangle' || name == 'rectangles' || name == 'filter' && opts.cleanup;
87772
87912
  }
87773
87913
 
87774
- var version = "0.7.74";
87914
+ var version = "0.7.75";
87775
87915
 
87776
87916
  // Parse command line args into commands and run them
87777
87917
  // Function takes an optional Node-style callback. A Promise is returned if no callback is given.
package/www/page.css CHANGED
@@ -4758,6 +4758,13 @@ body.dragging-color-picker * {
4758
4758
  background-color: var(--lt-theme-col);
4759
4759
  }
4760
4760
 
4761
+ .color-scheme-palette-heading {
4762
+ padding: 7px 8px 2px;
4763
+ font-size: 11px;
4764
+ color: #888;
4765
+ cursor: default;
4766
+ }
4767
+
4761
4768
  .color-scheme-tile-row {
4762
4769
  margin-top: 10px;
4763
4770
  }
@@ -4966,23 +4973,162 @@ body.dragging-color-picker * {
4966
4973
  cursor: default;
4967
4974
  }
4968
4975
 
4976
+ /* Gray like the fields and buttons, and the same at rest, on hover and while
4977
+ dragged. --fill (set by the script) is how far the light gray part of the
4978
+ track goes. The handle is a 12px box, which sets how far it travels, drawn
4979
+ as a 16px circle by its box-shadow rings, so that at either end it covers
4980
+ the end of the track. */
4969
4981
  .color-scheme-slider-row input[type=range] {
4982
+ -webkit-appearance: none;
4983
+ appearance: none;
4970
4984
  flex: 1;
4971
4985
  min-width: 0;
4972
- margin: 0 5px 0 2px;
4973
- accent-color: var(--theme-col);
4986
+ height: 18px;
4987
+ margin: 0 7px 0 4px;
4988
+ background: transparent;
4989
+ cursor: pointer;
4990
+ }
4991
+
4992
+ .color-scheme-slider-row input[type=range]:focus {
4993
+ outline: none;
4994
+ }
4995
+
4996
+ .color-scheme-slider-row input[type=range]::-webkit-slider-runnable-track {
4997
+ box-sizing: border-box;
4998
+ height: 7px;
4999
+ border: 1px solid var(--label-field-border);
5000
+ border-radius: 3.5px;
5001
+ background: linear-gradient(to right, #dadada var(--fill, 0%), white var(--fill, 0%));
5002
+ }
5003
+
5004
+ .color-scheme-slider-row input[type=range]::-moz-range-track {
5005
+ box-sizing: border-box;
5006
+ height: 7px;
5007
+ border: 1px solid var(--label-field-border);
5008
+ border-radius: 3.5px;
5009
+ background: white;
5010
+ }
5011
+
5012
+ .color-scheme-slider-row input[type=range]::-moz-range-progress {
5013
+ height: 5px;
5014
+ border-radius: 3.5px 0 0 3.5px;
5015
+ background: #dadada;
4974
5016
  }
4975
5017
 
4976
- /* Presets have only the reverse button in the vibrance row */
5018
+ .color-scheme-slider-row input[type=range]::-webkit-slider-thumb {
5019
+ -webkit-appearance: none;
5020
+ width: 12px;
5021
+ height: 12px;
5022
+ margin-top: -3.5px;
5023
+ border: none;
5024
+ border-radius: 50%;
5025
+ background: white;
5026
+ box-shadow: 0 0 0 1px white, 0 0 0 2px #888;
5027
+ }
5028
+
5029
+ .color-scheme-slider-row input[type=range]::-moz-range-thumb {
5030
+ width: 12px;
5031
+ height: 12px;
5032
+ border: none;
5033
+ border-radius: 50%;
5034
+ background: white;
5035
+ box-shadow: 0 0 0 1px white, 0 0 0 2px #888;
5036
+ }
5037
+
5038
+ .color-scheme-slider-row input[type=range]:focus-visible::-webkit-slider-thumb {
5039
+ box-shadow: 0 0 0 1px white, 0 0 0 2px #888, 0 0 0 4px var(--theme-col);
5040
+ }
5041
+
5042
+ .color-scheme-slider-row input[type=range]:focus-visible::-moz-range-thumb {
5043
+ box-shadow: 0 0 0 1px white, 0 0 0 2px #888, 0 0 0 4px var(--theme-col);
5044
+ }
5045
+
5046
+ /* Presets have only the reverse button in the vibrance row, and sequential
5047
+ and diverging presets, the range */
4977
5048
  .color-scheme-slider-row.preset {
4978
5049
  justify-content: flex-end;
4979
5050
  }
4980
5051
 
4981
- .color-scheme-slider-row.preset > :not(.color-scheme-icon-btn),
4982
- .color-scheme-slider-row.preset > .long-hue-btn {
5052
+ .color-scheme-slider-row.preset > :not(.color-scheme-icon-btn):not(.color-scheme-range-part),
5053
+ .color-scheme-slider-row.preset > .long-hue-btn,
5054
+ .color-scheme-slider-row:not(.ranged) > .color-scheme-range-part {
4983
5055
  display: none;
4984
5056
  }
4985
5057
 
5058
+ /* A strip of the whole preset, shaded outside the part the tiles use */
5059
+ .color-scheme-range {
5060
+ position: relative;
5061
+ flex: 1;
5062
+ min-width: 0;
5063
+ height: 12px;
5064
+ margin: 0 9px 0 6px;
5065
+ cursor: pointer;
5066
+ touch-action: none;
5067
+ }
5068
+
5069
+ .color-scheme-range-strip {
5070
+ position: absolute;
5071
+ inset: 0;
5072
+ border-radius: 2px;
5073
+ box-shadow: inset 0 0 0 1px rgba(0,0,0,0.12);
5074
+ }
5075
+
5076
+ .color-scheme-range-shade {
5077
+ position: absolute;
5078
+ top: 0;
5079
+ bottom: 0;
5080
+ background-color: rgba(255, 255, 255, 0.75);
5081
+ }
5082
+
5083
+ .color-scheme-range-shade.left {
5084
+ left: 0;
5085
+ }
5086
+
5087
+ .color-scheme-range-shade.right {
5088
+ right: 0;
5089
+ }
5090
+
5091
+ .color-scheme-range-handle {
5092
+ position: absolute;
5093
+ top: -4px;
5094
+ bottom: -4px;
5095
+ width: 4px;
5096
+ margin-left: -3px;
5097
+ border: 1px solid #444;
5098
+ border-radius: 2px;
5099
+ background-color: white;
5100
+ cursor: ew-resize;
5101
+ }
5102
+
5103
+ .color-scheme-range-handle:focus-visible {
5104
+ outline: 2px solid var(--theme-col);
5105
+ outline-offset: 1px;
5106
+ }
5107
+
5108
+ /* Takes an end tile of a sequential preset away, shown over the tile on hover */
5109
+ .color-scheme-tile-remove {
5110
+ display: none;
5111
+ position: absolute;
5112
+ top: 2px;
5113
+ right: 2px;
5114
+ width: 14px;
5115
+ height: 14px;
5116
+ padding: 0;
5117
+ border: none;
5118
+ border-radius: 50%;
5119
+ background-color: rgba(255, 255, 255, 0.85);
5120
+ box-shadow: 0 0 0 1px rgba(0,0,0,0.2);
5121
+ color: #333;
5122
+ font-size: 12px;
5123
+ line-height: 14px;
5124
+ text-align: center;
5125
+ cursor: pointer;
5126
+ }
5127
+
5128
+ .color-scheme-tile:hover > .color-scheme-tile-remove {
5129
+ display: block;
5130
+ }
5131
+
4986
5132
  .color-scheme-icon-btn {
4987
5133
  position: relative;
4988
5134
  flex: none;