@mapbox/mapbox-gl-style-spec 14.8.0 → 14.9.0-beta.1

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/dist/index.cjs CHANGED
@@ -113,6 +113,16 @@
113
113
  type: "fog",
114
114
  doc: "A global effect that fades layers and markers based on their distance to the camera. The fog can be used to approximate the effect of atmosphere on distant objects and enhance the depth perception of the map when used with terrain or 3D features. Note: fog is renamed to atmosphere in the Android and iOS SDKs and planned to be changed in GL-JS v.3.0.0."
115
115
  },
116
+ snow: {
117
+ type: "snow",
118
+ doc: "Global precipitation particle-based snow. Having snow present in the style forces constant map repaint mode",
119
+ experimental: true
120
+ },
121
+ rain: {
122
+ type: "rain",
123
+ doc: "Global precipitation particle-based rain effect. Having rain present in the style forces constant map repaint mode.",
124
+ experimental: true
125
+ },
116
126
  camera: {
117
127
  type: "camera",
118
128
  doc: "Global setting to control additional camera intrinsics parameters, e.g. projection type (perspective / orthographic)."
@@ -121,6 +131,11 @@
121
131
  type: "colorTheme",
122
132
  doc: "A global modifier for the colors of the style."
123
133
  },
134
+ indoor: {
135
+ type: "indoor",
136
+ experimental: true,
137
+ doc: "Controls the behaviour of indoor features."
138
+ },
124
139
  imports: {
125
140
  type: "array",
126
141
  value: "import",
@@ -461,6 +476,28 @@
461
476
  }
462
477
  }
463
478
  },
479
+ "shadow-quality": {
480
+ type: "number",
481
+ "property-type": "data-constant",
482
+ "default": 1,
483
+ minimum: 0,
484
+ maximum: 1,
485
+ expression: {
486
+ interpolated: false,
487
+ parameters: [
488
+ "zoom"
489
+ ]
490
+ },
491
+ transition: false,
492
+ doc: "Determines the quality of the shadows on the map. A value of 1 ensures the highest quality and is the default value.",
493
+ "sdk-support": {
494
+ "basic functionality": {
495
+ android: "11.9.0",
496
+ ios: "11.9.0"
497
+ }
498
+ },
499
+ experimental: true
500
+ },
464
501
  "shadow-intensity": {
465
502
  type: "number",
466
503
  "property-type": "data-constant",
@@ -1962,6 +1999,36 @@
1962
1999
  interpolated: false
1963
2000
  },
1964
2001
  "property-type": "constant"
2002
+ },
2003
+ "line-width-unit": {
2004
+ type: "enum",
2005
+ doc: "Selects the unit of line-width. The same unit is automatically used for line-blur and line-offset. Note: This is an experimental property and might be removed in a future release.",
2006
+ values: {
2007
+ pixels: {
2008
+ doc: "Width is rendered in pixels."
2009
+ },
2010
+ meters: {
2011
+ doc: "Width is rendered in meters."
2012
+ }
2013
+ },
2014
+ "default": "pixels",
2015
+ experimental: true,
2016
+ "private": true,
2017
+ transition: false,
2018
+ "sdk-support": {
2019
+ "basic functionality": {
2020
+ js: "3.9.0",
2021
+ android: "11.9.0",
2022
+ ios: "11.9.0"
2023
+ }
2024
+ },
2025
+ expression: {
2026
+ interpolated: false,
2027
+ parameters: [
2028
+ "zoom"
2029
+ ]
2030
+ },
2031
+ "property-type": "data-constant"
1965
2032
  }
1966
2033
  };
1967
2034
  var layout_symbol = {
@@ -2076,7 +2143,7 @@
2076
2143
  doc: "Sorts symbols by `symbol-sort-key` if set. Otherwise, sorts symbols by their y-position relative to the viewport if `icon-allow-overlap` or `text-allow-overlap` is set to `true` or `icon-ignore-placement` or `text-ignore-placement` is `false`."
2077
2144
  },
2078
2145
  "viewport-y": {
2079
- doc: "Sorts symbols by their y-position relative to the viewport if `icon-allow-overlap` or `text-allow-overlap` is set to `true` or `icon-ignore-placement` or `text-ignore-placement` is `false`."
2146
+ doc: "Sorts symbols by their y-position relative to the viewport if any of the following is set to `true`: `icon-allow-overlap`, `text-allow-overlap`, `icon-ignore-placement`, `text-ignore-placement`."
2080
2147
  },
2081
2148
  source: {
2082
2149
  doc: "Sorts symbols by `symbol-sort-key` if set. Otherwise, no sorting is applied; symbols are rendered in the same order as the source data."
@@ -2313,9 +2380,7 @@
2313
2380
  },
2314
2381
  "sdk-support": {
2315
2382
  "basic functionality": {
2316
- js: "3.8.0",
2317
- android: "11.8.0",
2318
- ios: "11.8.0"
2383
+ js: "3.8.0"
2319
2384
  }
2320
2385
  },
2321
2386
  "property-type": "data-constant"
@@ -2827,9 +2892,7 @@
2827
2892
  },
2828
2893
  "sdk-support": {
2829
2894
  "basic functionality": {
2830
- js: "3.8.0",
2831
- android: "11.8.0",
2832
- ios: "11.8.0"
2895
+ js: "3.8.0"
2833
2896
  }
2834
2897
  },
2835
2898
  "property-type": "data-constant"
@@ -4080,6 +4143,17 @@
4080
4143
  }
4081
4144
  }
4082
4145
  },
4146
+ "to-hsla": {
4147
+ doc: "Returns a four-element array containing the input color's Hue, Saturation, Luminance and alpha components, in that order.",
4148
+ group: "Color",
4149
+ "sdk-support": {
4150
+ "basic functionality": {
4151
+ js: "3.9.0",
4152
+ android: "11.9.0",
4153
+ ios: "11.9.0"
4154
+ }
4155
+ }
4156
+ },
4083
4157
  "to-color": {
4084
4158
  doc: "Converts the input value to a color. If multiple values are provided, each one is evaluated in order until the first successful conversion is obtained. If none of the inputs can be converted, the expression is an error.",
4085
4159
  group: "Types",
@@ -5013,11 +5087,11 @@
5013
5087
  relaxZoomRestriction: true
5014
5088
  },
5015
5089
  transition: true,
5016
- doc: "Snow particles density.",
5090
+ doc: "Snow particles density. Controls the overall particles number.",
5017
5091
  "sdk-support": {
5018
5092
  "basic functionality": {
5019
- android: "11.8.0",
5020
- ios: "11.8.0"
5093
+ android: "11.9.0",
5094
+ ios: "11.9.0"
5021
5095
  }
5022
5096
  }
5023
5097
  },
@@ -5037,11 +5111,11 @@
5037
5111
  relaxZoomRestriction: true
5038
5112
  },
5039
5113
  transition: true,
5040
- doc: "Snow particles movement factor.",
5114
+ doc: "Snow particles movement factor. Controls the overall particles movement speed.",
5041
5115
  "sdk-support": {
5042
5116
  "basic functionality": {
5043
- android: "11.8.0",
5044
- ios: "11.8.0"
5117
+ android: "11.9.0",
5118
+ ios: "11.9.0"
5045
5119
  }
5046
5120
  }
5047
5121
  },
@@ -5062,15 +5136,15 @@
5062
5136
  doc: "Snow particles color.",
5063
5137
  "sdk-support": {
5064
5138
  "basic functionality": {
5065
- android: "11.8.0",
5066
- ios: "11.8.0"
5139
+ android: "11.9.0",
5140
+ ios: "11.9.0"
5067
5141
  }
5068
5142
  }
5069
5143
  },
5070
5144
  opacity: {
5071
5145
  type: "number",
5072
5146
  "property-type": "data-constant",
5073
- "default": 1,
5147
+ "default": 0.9,
5074
5148
  minimum: 0,
5075
5149
  maximum: 1,
5076
5150
  experimental: true,
@@ -5086,15 +5160,15 @@
5086
5160
  doc: "Snow particles opacity.",
5087
5161
  "sdk-support": {
5088
5162
  "basic functionality": {
5089
- android: "11.8.0",
5090
- ios: "11.8.0"
5163
+ android: "11.9.0",
5164
+ ios: "11.9.0"
5091
5165
  }
5092
5166
  }
5093
5167
  },
5094
5168
  vignette: {
5095
5169
  type: "number",
5096
5170
  "property-type": "data-constant",
5097
- "default": 0,
5171
+ "default": 0.3,
5098
5172
  minimum: 0,
5099
5173
  maximum: 1,
5100
5174
  experimental: true,
@@ -5107,15 +5181,37 @@
5107
5181
  relaxZoomRestriction: true
5108
5182
  },
5109
5183
  transition: true,
5110
- doc: "Snow vignette screen-space effect.",
5184
+ doc: "Snow vignette screen-space effect. Adds snow tint to screen corners",
5111
5185
  "sdk-support": {
5112
5186
  "basic functionality": {
5113
- android: "11.8.0",
5114
- ios: "11.8.0"
5187
+ android: "11.9.0",
5188
+ ios: "11.9.0"
5115
5189
  }
5116
5190
  }
5117
5191
  },
5118
- centerThinning: {
5192
+ "vignette-color": {
5193
+ type: "color",
5194
+ "property-type": "data-constant",
5195
+ "default": "#ffffff",
5196
+ experimental: true,
5197
+ expression: {
5198
+ interpolated: true,
5199
+ parameters: [
5200
+ "zoom",
5201
+ "measure-light"
5202
+ ],
5203
+ relaxZoomRestriction: true
5204
+ },
5205
+ transition: true,
5206
+ doc: "Snow vignette screen-space corners tint color.",
5207
+ "sdk-support": {
5208
+ "basic functionality": {
5209
+ android: "11.9.0",
5210
+ ios: "11.9.0"
5211
+ }
5212
+ }
5213
+ },
5214
+ "center-thinning": {
5119
5215
  type: "number",
5120
5216
  "property-type": "data-constant",
5121
5217
  "default": 1,
@@ -5134,8 +5230,8 @@
5134
5230
  doc: "Thinning factor of snow particles from center. 0 - no thinning. 1 - maximal central area thinning.",
5135
5231
  "sdk-support": {
5136
5232
  "basic functionality": {
5137
- android: "11.8.0",
5138
- ios: "11.8.0"
5233
+ android: "11.9.0",
5234
+ ios: "11.9.0"
5139
5235
  }
5140
5236
  }
5141
5237
  },
@@ -5160,15 +5256,39 @@
5160
5256
  ],
5161
5257
  relaxZoomRestriction: true
5162
5258
  },
5163
- doc: "Main snow particles direction. Heading & pitch",
5259
+ doc: "Main snow particles direction. Azimuth and polar angles",
5164
5260
  example: [
5165
5261
  0,
5166
5262
  45
5167
5263
  ],
5168
5264
  "sdk-support": {
5169
5265
  "basic functionality": {
5170
- android: "11.8.0",
5171
- ios: "11.8.0"
5266
+ android: "11.9.0",
5267
+ ios: "11.9.0"
5268
+ }
5269
+ }
5270
+ },
5271
+ "flake-size": {
5272
+ type: "number",
5273
+ "property-type": "data-constant",
5274
+ "default": 1,
5275
+ minimum: 0,
5276
+ maximum: 5,
5277
+ experimental: true,
5278
+ expression: {
5279
+ interpolated: true,
5280
+ parameters: [
5281
+ "zoom",
5282
+ "measure-light"
5283
+ ],
5284
+ relaxZoomRestriction: true
5285
+ },
5286
+ transition: true,
5287
+ doc: "Snow flake particle size. Correlates with individual particle screen size",
5288
+ "sdk-support": {
5289
+ "basic functionality": {
5290
+ android: "11.9.0",
5291
+ ios: "11.9.0"
5172
5292
  }
5173
5293
  }
5174
5294
  }
@@ -5190,11 +5310,11 @@
5190
5310
  relaxZoomRestriction: true
5191
5311
  },
5192
5312
  transition: true,
5193
- doc: "Rain particles density.",
5313
+ doc: "Rain particles density. Controls the overall screen density of the rain.",
5194
5314
  "sdk-support": {
5195
5315
  "basic functionality": {
5196
- android: "11.8.0",
5197
- ios: "11.8.0"
5316
+ android: "11.9.0",
5317
+ ios: "11.9.0"
5198
5318
  }
5199
5319
  }
5200
5320
  },
@@ -5214,18 +5334,18 @@
5214
5334
  relaxZoomRestriction: true
5215
5335
  },
5216
5336
  transition: true,
5217
- doc: "Rain particles movement factor.",
5337
+ doc: "Rain particles movement factor. Controls the overall rain particles speed",
5218
5338
  "sdk-support": {
5219
5339
  "basic functionality": {
5220
- android: "11.8.0",
5221
- ios: "11.8.0"
5340
+ android: "11.9.0",
5341
+ ios: "11.9.0"
5222
5342
  }
5223
5343
  }
5224
5344
  },
5225
5345
  color: {
5226
5346
  type: "color",
5227
5347
  "property-type": "data-constant",
5228
- "default": "#ffffff",
5348
+ "default": "#919191",
5229
5349
  experimental: true,
5230
5350
  expression: {
5231
5351
  interpolated: true,
@@ -5236,18 +5356,18 @@
5236
5356
  relaxZoomRestriction: true
5237
5357
  },
5238
5358
  transition: true,
5239
- doc: "",
5359
+ doc: "Individual rain particle dorplets color.",
5240
5360
  "sdk-support": {
5241
5361
  "basic functionality": {
5242
- android: "11.8.0",
5243
- ios: "11.8.0"
5362
+ android: "11.9.0",
5363
+ ios: "11.9.0"
5244
5364
  }
5245
5365
  }
5246
5366
  },
5247
5367
  opacity: {
5248
5368
  type: "number",
5249
5369
  "property-type": "data-constant",
5250
- "default": 1,
5370
+ "default": 0.19,
5251
5371
  minimum: 0,
5252
5372
  maximum: 1,
5253
5373
  experimental: true,
@@ -5263,15 +5383,15 @@
5263
5383
  doc: "Rain particles opacity.",
5264
5384
  "sdk-support": {
5265
5385
  "basic functionality": {
5266
- android: "11.8.0",
5267
- ios: "11.8.0"
5386
+ android: "11.9.0",
5387
+ ios: "11.9.0"
5268
5388
  }
5269
5389
  }
5270
5390
  },
5271
5391
  vignette: {
5272
5392
  type: "number",
5273
5393
  "property-type": "data-constant",
5274
- "default": 0,
5394
+ "default": 0.3,
5275
5395
  minimum: 0,
5276
5396
  maximum: 1,
5277
5397
  experimental: true,
@@ -5284,15 +5404,37 @@
5284
5404
  relaxZoomRestriction: true
5285
5405
  },
5286
5406
  transition: true,
5287
- doc: "Rain vignette screen-space effect.",
5407
+ doc: "Screen-space vignette rain tinting effect intensity.",
5288
5408
  "sdk-support": {
5289
5409
  "basic functionality": {
5290
- android: "11.8.0",
5291
- ios: "11.8.0"
5410
+ android: "11.9.0",
5411
+ ios: "11.9.0"
5412
+ }
5413
+ }
5414
+ },
5415
+ "vignette-color": {
5416
+ type: "color",
5417
+ "property-type": "data-constant",
5418
+ "default": "#ffffff",
5419
+ experimental: true,
5420
+ expression: {
5421
+ interpolated: true,
5422
+ parameters: [
5423
+ "zoom",
5424
+ "measure-light"
5425
+ ],
5426
+ relaxZoomRestriction: true
5427
+ },
5428
+ transition: true,
5429
+ doc: "Rain vignette screen-space corners tint color.",
5430
+ "sdk-support": {
5431
+ "basic functionality": {
5432
+ android: "11.9.0",
5433
+ ios: "11.9.0"
5292
5434
  }
5293
5435
  }
5294
5436
  },
5295
- centerThinning: {
5437
+ "center-thinning": {
5296
5438
  type: "number",
5297
5439
  "property-type": "data-constant",
5298
5440
  "default": 1,
@@ -5311,8 +5453,8 @@
5311
5453
  doc: "Thinning factor of rain particles from center. 0 - no thinning. 1 - maximal central area thinning.",
5312
5454
  "sdk-support": {
5313
5455
  "basic functionality": {
5314
- android: "11.8.0",
5315
- ios: "11.8.0"
5456
+ android: "11.9.0",
5457
+ ios: "11.9.0"
5316
5458
  }
5317
5459
  }
5318
5460
  },
@@ -5337,15 +5479,72 @@
5337
5479
  ],
5338
5480
  relaxZoomRestriction: true
5339
5481
  },
5340
- doc: "Main rain particles direction. Heading & pitch",
5482
+ doc: "Main rain particles direction. Azimuth and polar angles.",
5341
5483
  example: [
5342
5484
  0,
5343
5485
  45
5344
5486
  ],
5345
5487
  "sdk-support": {
5346
5488
  "basic functionality": {
5347
- android: "11.8.0",
5348
- ios: "11.8.0"
5489
+ android: "11.9.0",
5490
+ ios: "11.9.0"
5491
+ }
5492
+ }
5493
+ },
5494
+ "droplet-size": {
5495
+ type: "array",
5496
+ "default": [
5497
+ 1,
5498
+ 10
5499
+ ],
5500
+ minimum: 0,
5501
+ maximum: 20,
5502
+ length: 2,
5503
+ value: "number",
5504
+ "property-type": "data-constant",
5505
+ transition: true,
5506
+ experimental: true,
5507
+ expression: {
5508
+ interpolated: true,
5509
+ parameters: [
5510
+ "zoom",
5511
+ "measure-light"
5512
+ ],
5513
+ relaxZoomRestriction: true
5514
+ },
5515
+ doc: "Rain droplet size. x - normal to direction, y - along direction",
5516
+ example: [
5517
+ 0,
5518
+ 45
5519
+ ],
5520
+ "sdk-support": {
5521
+ "basic functionality": {
5522
+ android: "11.9.0",
5523
+ ios: "11.9.0"
5524
+ }
5525
+ }
5526
+ },
5527
+ "distortion-strength": {
5528
+ type: "number",
5529
+ "property-type": "data-constant",
5530
+ "default": 0.5,
5531
+ minimum: 0,
5532
+ maximum: 1,
5533
+ experimental: true,
5534
+ expression: {
5535
+ interpolated: true,
5536
+ parameters: [
5537
+ "zoom",
5538
+ "measure-light"
5539
+ ],
5540
+ relaxZoomRestriction: true
5541
+ },
5542
+ transition: true,
5543
+ doc: "Rain particles screen-space distortion strength.",
5544
+ "sdk-support": {
5545
+ "basic functionality": {
5546
+ android: "11.9.0",
5547
+ ios: "11.9.0"
5349
5548
  }
5350
5549
  }
5351
5550
  }
@@ -5391,6 +5590,28 @@
5391
5590
  }
5392
5591
  }
5393
5592
  };
5593
+ var indoor = {
5594
+ floorplanFeaturesetId: {
5595
+ type: "string",
5596
+ doc: "An ID of a featureset to be used to query indoor floorplans.",
5597
+ experimental: true,
5598
+ transition: false,
5599
+ "property-type": "data-constant",
5600
+ expression: {
5601
+ interpolated: false
5602
+ }
5603
+ },
5604
+ buildingFeaturesetId: {
5605
+ type: "string",
5606
+ doc: "An ID of a featureset to be used to add interactivity for building selection.",
5607
+ experimental: true,
5608
+ transition: false,
5609
+ "property-type": "data-constant",
5610
+ expression: {
5611
+ interpolated: false
5612
+ }
5613
+ }
5614
+ };
5394
5615
  var light = {
5395
5616
  anchor: {
5396
5617
  type: "enum",
@@ -6050,7 +6271,8 @@
6050
6271
  "zoom",
6051
6272
  "feature",
6052
6273
  "feature-state",
6053
- "measure-light"
6274
+ "measure-light",
6275
+ "line-progress"
6054
6276
  ]
6055
6277
  },
6056
6278
  "property-type": "data-driven"
@@ -8176,7 +8398,7 @@
8176
8398
  doc: "The background is aligned to the plane of the map."
8177
8399
  },
8178
8400
  viewport: {
8179
- doc: "The background is aligned to the plane of the viewport, covering the whole screen."
8401
+ doc: "The background is aligned to the plane of the viewport, covering the whole screen. Note: This mode disables the automatic reordering of the layer when terrain or globe projection is used."
8180
8402
  }
8181
8403
  },
8182
8404
  "default": "map",
@@ -8193,6 +8415,7 @@
8193
8415
  parameters: [
8194
8416
  ]
8195
8417
  },
8418
+ experimental: true,
8196
8419
  "property-type": "data-constant"
8197
8420
  },
8198
8421
  "background-color": {
@@ -8544,11 +8767,13 @@
8544
8767
  "default": 1,
8545
8768
  minimum: 0,
8546
8769
  maximum: 1,
8547
- doc: "The opacity of the model layer.",
8770
+ doc: "The opacity of the model layer. Except for zoom, expressions that are data-driven are not supported if using GeoJSON or vector tile as the model layer source.",
8548
8771
  transition: true,
8549
8772
  expression: {
8550
8773
  interpolated: true,
8551
8774
  parameters: [
8775
+ "feature",
8776
+ "feature-state",
8552
8777
  "zoom"
8553
8778
  ]
8554
8779
  },
@@ -8557,9 +8782,14 @@
8557
8782
  js: "3.0.0",
8558
8783
  android: "11.0.0",
8559
8784
  ios: "11.0.0"
8785
+ },
8786
+ "data-driven styling": {
8787
+ js: "3.9.0",
8788
+ android: "11.9.0",
8789
+ ios: "11.9.0"
8560
8790
  }
8561
8791
  },
8562
- "property-type": "data-constant"
8792
+ "property-type": "data-driven"
8563
8793
  },
8564
8794
  "model-rotation": {
8565
8795
  type: "array",
@@ -8986,6 +9216,11 @@
8986
9216
  data: {
8987
9217
  type: "$root",
8988
9218
  doc: "The inlined style that must correspond to the contents of the specified URL."
9219
+ },
9220
+ "color-theme": {
9221
+ type: "colorTheme",
9222
+ optional: true,
9223
+ doc: "If specified, it overrides the color-theme of the imported style."
8989
9224
  }
8990
9225
  },
8991
9226
  config: config,
@@ -9262,6 +9497,7 @@
9262
9497
  rain: rain,
9263
9498
  camera: camera,
9264
9499
  colorTheme: colorTheme,
9500
+ indoor: indoor,
9265
9501
  light: light,
9266
9502
  projection: projection,
9267
9503
  terrain: terrain,
@@ -11657,7 +11893,7 @@
11657
11893
  * var translucentGreen = new Color.parse('rgba(26, 207, 26, .73)');
11658
11894
  * translucentGreen.toString(); // = "rgba(26,207,26,0.73)"
11659
11895
  */
11660
- toString() {
11896
+ toStringPremultipliedAlpha() {
11661
11897
  const [r, g, b, a] = this.a === 0 ? [
11662
11898
  0,
11663
11899
  0,
@@ -11671,10 +11907,22 @@
11671
11907
  ];
11672
11908
  return `rgba(${ Math.round(r) },${ Math.round(g) },${ Math.round(b) },${ a })`;
11673
11909
  }
11910
+ toString() {
11911
+ const [r, g, b, a] = [
11912
+ this.r,
11913
+ this.g,
11914
+ this.b,
11915
+ this.a
11916
+ ];
11917
+ return `rgba(${ Math.round(r * 255) },${ Math.round(g * 255) },${ Math.round(b * 255) },${ a })`;
11918
+ }
11674
11919
  toRenderColor(lut) {
11675
11920
  const {r, g, b, a} = this;
11676
11921
  return new RenderColor(lut, r, g, b, a);
11677
11922
  }
11923
+ clone() {
11924
+ return new Color(this.r, this.g, this.b, this.a);
11925
+ }
11678
11926
  }
11679
11927
  class RenderColor {
11680
11928
  constructor(lut, r, g, b, a) {
@@ -11736,6 +11984,53 @@
11736
11984
  ];
11737
11985
  }
11738
11986
  /**
11987
+ * Returns an HSLA array of values representing the color, unpremultiplied by A.
11988
+ *
11989
+ * @returns An array of HSLA color values.
11990
+ */
11991
+ toHslaArray() {
11992
+ if (this.a === 0) {
11993
+ return [
11994
+ 0,
11995
+ 0,
11996
+ 0,
11997
+ 0
11998
+ ];
11999
+ }
12000
+ const {r, g, b, a} = this;
12001
+ const red = Math.min(Math.max(r / a, 0), 1);
12002
+ const green = Math.min(Math.max(g / a, 0), 1);
12003
+ const blue = Math.min(Math.max(b / a, 0), 1);
12004
+ const min = Math.min(red, green, blue);
12005
+ const max = Math.max(red, green, blue);
12006
+ const l = (min + max) / 2;
12007
+ if (min === max) {
12008
+ return [
12009
+ 0,
12010
+ 0,
12011
+ l * 100,
12012
+ a
12013
+ ];
12014
+ }
12015
+ const delta = max - min;
12016
+ const s = l > 0.5 ? delta / (2 - max - min) : delta / (max + min);
12017
+ let h = 0;
12018
+ if (max === red) {
12019
+ h = (green - blue) / delta + (green < blue ? 6 : 0);
12020
+ } else if (max === green) {
12021
+ h = (blue - red) / delta + 2;
12022
+ } else if (max === blue) {
12023
+ h = (red - green) / delta + 4;
12024
+ }
12025
+ h *= 60;
12026
+ return [
12027
+ Math.min(Math.max(h, 0), 360),
12028
+ Math.min(Math.max(s * 100, 0), 100),
12029
+ Math.min(Math.max(l * 100, 0), 100),
12030
+ a
12031
+ ];
12032
+ }
12033
+ /**
11739
12034
  * Returns a RGBA array of float values representing the color, unpremultiplied by A.
11740
12035
  *
11741
12036
  * @returns An array of RGBA color values in the range [0, 1].
@@ -11852,7 +12147,7 @@
11852
12147
  isEmpty() {
11853
12148
  if (this.sections.length === 0)
11854
12149
  return true;
11855
- return !this.sections.some(section => section.text.length !== 0 || section.image && section.image.namePrimary.length !== 0);
12150
+ return !this.sections.some(section => section.text.length !== 0 || section.image && section.image.namePrimary);
11856
12151
  }
11857
12152
  static factory(text) {
11858
12153
  if (text instanceof Formatted) {
@@ -11896,42 +12191,113 @@
11896
12191
  }
11897
12192
  }
11898
12193
 
12194
+ class ImageIdWithOptions {
12195
+ constructor(id, options) {
12196
+ this.id = id;
12197
+ this.options = options || { params: {} };
12198
+ if (!this.options.transform) {
12199
+ this.options.transform = new DOMMatrix([
12200
+ 1,
12201
+ 0,
12202
+ 0,
12203
+ 1,
12204
+ 0,
12205
+ 0
12206
+ ]);
12207
+ } else {
12208
+ const {a, b, c, d, e, f} = this.options.transform;
12209
+ this.options.transform = new DOMMatrix([
12210
+ a,
12211
+ b,
12212
+ c,
12213
+ d,
12214
+ e,
12215
+ f
12216
+ ]);
12217
+ }
12218
+ }
12219
+ static deserializeFromString(serialized) {
12220
+ const deserializedObject = JSON.parse(serialized);
12221
+ ({ params: deserializedObject.options.params });
12222
+ const {a, b, c, d, e, f} = deserializedObject.options.transform;
12223
+ new DOMMatrix([
12224
+ a,
12225
+ b,
12226
+ c,
12227
+ d,
12228
+ e,
12229
+ f
12230
+ ]);
12231
+ return new ImageIdWithOptions(deserializedObject.id, deserializedObject.options);
12232
+ }
12233
+ scaleSelf(factor) {
12234
+ this.options.transform = this.options.transform.scale(factor);
12235
+ return this;
12236
+ }
12237
+ serialize() {
12238
+ const serialisedObject = { id: this.id };
12239
+ if (this.options) {
12240
+ serialisedObject.options = this.options;
12241
+ }
12242
+ const {a, b, c, d, e, f} = this.options.transform;
12243
+ serialisedObject.options.transform = {
12244
+ a,
12245
+ b,
12246
+ c,
12247
+ d,
12248
+ e,
12249
+ f
12250
+ };
12251
+ return JSON.stringify(serialisedObject);
12252
+ }
12253
+ }
12254
+
11899
12255
  class ResolvedImage {
11900
12256
  constructor(options) {
11901
12257
  this.namePrimary = options.namePrimary;
11902
12258
  if (options.nameSecondary) {
11903
12259
  this.nameSecondary = options.nameSecondary;
11904
12260
  }
12261
+ if (options.optionsPrimary) {
12262
+ this.optionsPrimary = options.optionsPrimary;
12263
+ }
12264
+ if (options.optionsSecondary) {
12265
+ this.optionsSecondary = options.optionsSecondary;
12266
+ }
11905
12267
  this.available = options.available;
11906
12268
  }
11907
12269
  toString() {
11908
- if (this.nameSecondary) {
12270
+ if (this.namePrimary && this.nameSecondary) {
11909
12271
  return `[${ this.namePrimary },${ this.nameSecondary }]`;
11910
12272
  }
11911
12273
  return this.namePrimary;
11912
12274
  }
11913
- static fromString(namePrimary, nameSecondary) {
12275
+ getPrimary() {
12276
+ return new ImageIdWithOptions(this.namePrimary, { params: this.optionsPrimary ? this.optionsPrimary.params || {} : {} });
12277
+ }
12278
+ getSerializedPrimary() {
12279
+ return this.getPrimary().serialize();
12280
+ }
12281
+ getSecondary() {
12282
+ if (this.nameSecondary) {
12283
+ return new ImageIdWithOptions(this.nameSecondary, { params: this.optionsSecondary ? this.optionsSecondary.params || {} : {} });
12284
+ }
12285
+ return null;
12286
+ }
12287
+ static from(image) {
12288
+ return typeof image === 'string' ? ResolvedImage.build(image) : image;
12289
+ }
12290
+ static build(namePrimary, nameSecondary, optionsPrimary, optionsSecondary) {
11914
12291
  if (!namePrimary)
11915
12292
  return null;
11916
12293
  return new ResolvedImage({
11917
12294
  namePrimary,
11918
12295
  nameSecondary,
12296
+ optionsPrimary,
12297
+ optionsSecondary,
11919
12298
  available: false
11920
12299
  });
11921
12300
  }
11922
- serialize() {
11923
- if (this.nameSecondary) {
11924
- return [
11925
- 'image',
11926
- this.namePrimary,
11927
- this.nameSecondary
11928
- ];
11929
- }
11930
- return [
11931
- 'image',
11932
- this.namePrimary
11933
- ];
11934
- }
11935
12301
  }
11936
12302
 
11937
12303
  function validateRGBA(r, g, b, a) {
@@ -12072,7 +12438,9 @@
12072
12438
  return '';
12073
12439
  } else if (type === 'string' || type === 'number' || type === 'boolean') {
12074
12440
  return String(value);
12075
- } else if (value instanceof Color || value instanceof Formatted || value instanceof ResolvedImage) {
12441
+ } else if (value instanceof Color) {
12442
+ return value.toStringPremultipliedAlpha();
12443
+ } else if (value instanceof Formatted || value instanceof ResolvedImage) {
12076
12444
  return value.toString();
12077
12445
  } else {
12078
12446
  return JSON.stringify(value);
@@ -12321,29 +12689,114 @@
12321
12689
  }
12322
12690
  }
12323
12691
 
12692
+ function isImageOptions(value) {
12693
+ if (typeof value !== 'string' && !isExpression(value)) {
12694
+ return true;
12695
+ }
12696
+ return false;
12697
+ }
12324
12698
  class ImageExpression {
12325
- constructor(inputPrimary, inputSecondary) {
12699
+ constructor(inputPrimary, inputSecondary, inputPrimaryParams, inputSecondaryParams) {
12700
+ this._imageWarnHistory = {};
12326
12701
  this.type = ResolvedImageType;
12327
12702
  this.inputPrimary = inputPrimary;
12328
12703
  this.inputSecondary = inputSecondary;
12704
+ this.inputPrimaryParams = inputPrimaryParams;
12705
+ this.inputSecondaryParams = inputSecondaryParams;
12329
12706
  }
12330
12707
  static parse(args, context) {
12331
12708
  if (args.length < 2) {
12332
12709
  return context.error(`Expected two or more arguments.`);
12333
12710
  }
12334
- const namePrimary = context.parse(args[1], 1, StringType);
12335
- if (!namePrimary)
12336
- return context.error(`No image name provided.`);
12337
- if (args.length === 2) {
12338
- return new ImageExpression(namePrimary);
12711
+ let nextArgId = 1;
12712
+ const imageExpression = [];
12713
+ function tryParseImage() {
12714
+ if (nextArgId < args.length) {
12715
+ const imageName = context.parse(args[nextArgId], nextArgId++, StringType);
12716
+ if (!imageName) {
12717
+ context.error(imageExpression.length ? `Secondary image variant is not a string.` : `No image name provided.`);
12718
+ return false;
12719
+ }
12720
+ imageExpression.push({
12721
+ image: imageName,
12722
+ options: void 0
12723
+ });
12724
+ return true;
12725
+ }
12726
+ return true;
12339
12727
  }
12340
- const nameSecondary = context.parse(args[2], 1, StringType);
12341
- if (!nameSecondary)
12342
- return context.error(`Secondary image variant is not a string.`);
12343
- return new ImageExpression(namePrimary, nameSecondary);
12728
+ function tryParseOptions() {
12729
+ if (nextArgId < args.length) {
12730
+ if (!isImageOptions(args[nextArgId])) {
12731
+ return true;
12732
+ }
12733
+ const params = args[nextArgId].params;
12734
+ const optionsContext = context.concat(nextArgId);
12735
+ if (!params) {
12736
+ nextArgId++;
12737
+ return true;
12738
+ }
12739
+ if (typeof params !== 'object' || params.constructor !== Object) {
12740
+ optionsContext.error(`Image options "params" should be an object`);
12741
+ return false;
12742
+ }
12743
+ const parsed = {};
12744
+ const childContext = optionsContext.concat(void 0, 'params');
12745
+ for (const key in params) {
12746
+ if (!key) {
12747
+ childContext.error(`Image parameter name should be non-empty`);
12748
+ return false;
12749
+ }
12750
+ const value = childContext.concat(void 0, key).parse(params[key], void 0, ColorType, void 0, { typeAnnotation: 'coerce' });
12751
+ if (!value) {
12752
+ return false;
12753
+ }
12754
+ parsed[key] = value;
12755
+ }
12756
+ imageExpression[imageExpression.length - 1].options = parsed;
12757
+ nextArgId++;
12758
+ return true;
12759
+ }
12760
+ return true;
12761
+ }
12762
+ for (let i = 0; i < 2; i++) {
12763
+ if (!tryParseImage() || !tryParseOptions()) {
12764
+ return;
12765
+ }
12766
+ }
12767
+ return new ImageExpression(imageExpression[0].image, imageExpression[1] ? imageExpression[1].image : void 0, imageExpression[0].options, imageExpression[1] ? imageExpression[1].options : void 0);
12768
+ }
12769
+ evaluateParams(ctx, params) {
12770
+ const result = {};
12771
+ if (params) {
12772
+ for (const key in params) {
12773
+ if (params[key]) {
12774
+ try {
12775
+ const color = params[key].evaluate(ctx);
12776
+ const msg = `Ignoring image parameter "${ key }" with semi-transparent color ${ color.toString() }`;
12777
+ if (color.a !== 1) {
12778
+ if (!this._imageWarnHistory[msg]) {
12779
+ console.warn(msg);
12780
+ this._imageWarnHistory[msg] = true;
12781
+ }
12782
+ continue;
12783
+ }
12784
+ result[key] = color;
12785
+ } catch (err) {
12786
+ continue;
12787
+ }
12788
+ }
12789
+ }
12790
+ } else {
12791
+ return void 0;
12792
+ }
12793
+ if (Object.keys(result).length === 0) {
12794
+ return void 0;
12795
+ }
12796
+ return { params: result };
12344
12797
  }
12345
12798
  evaluate(ctx) {
12346
- const value = ResolvedImage.fromString(this.inputPrimary.evaluate(ctx), this.inputSecondary ? this.inputSecondary.evaluate(ctx) : void 0);
12799
+ const value = ResolvedImage.build(this.inputPrimary.evaluate(ctx), this.inputSecondary ? this.inputSecondary.evaluate(ctx) : void 0, this.inputPrimaryParams ? this.evaluateParams(ctx, this.inputPrimaryParams) : void 0, this.inputSecondaryParams ? this.evaluateParams(ctx, this.inputSecondaryParams) : void 0);
12347
12800
  if (value && ctx.availableImages) {
12348
12801
  value.available = ctx.availableImages.indexOf(value.namePrimary) > -1;
12349
12802
  if (value.nameSecondary && value.available && ctx.availableImages) {
@@ -12354,25 +12807,55 @@
12354
12807
  }
12355
12808
  eachChild(fn) {
12356
12809
  fn(this.inputPrimary);
12810
+ if (this.inputPrimaryParams) {
12811
+ for (const key in this.inputPrimaryParams) {
12812
+ if (this.inputPrimaryParams[key]) {
12813
+ fn(this.inputPrimaryParams[key]);
12814
+ }
12815
+ }
12816
+ }
12357
12817
  if (this.inputSecondary) {
12358
12818
  fn(this.inputSecondary);
12819
+ if (this.inputSecondaryParams) {
12820
+ for (const key in this.inputSecondaryParams) {
12821
+ if (this.inputSecondaryParams[key]) {
12822
+ fn(this.inputSecondaryParams[key]);
12823
+ }
12824
+ }
12825
+ }
12359
12826
  }
12360
12827
  }
12361
12828
  outputDefined() {
12362
12829
  return false;
12363
12830
  }
12364
- serialize() {
12365
- if (this.inputSecondary) {
12366
- return [
12367
- 'image',
12368
- this.inputPrimary.serialize(),
12369
- this.inputSecondary.serialize()
12370
- ];
12831
+ serializeParams(params) {
12832
+ const result = {};
12833
+ if (params) {
12834
+ for (const key in params) {
12835
+ if (params[key]) {
12836
+ result[key] = params[key].serialize();
12837
+ }
12838
+ }
12839
+ } else {
12840
+ return void 0;
12371
12841
  }
12372
- return [
12842
+ return { params: result };
12843
+ }
12844
+ serialize() {
12845
+ const serialized = [
12373
12846
  'image',
12374
12847
  this.inputPrimary.serialize()
12375
12848
  ];
12849
+ if (this.inputPrimaryParams) {
12850
+ serialized.push(this.serializeParams(this.inputPrimaryParams));
12851
+ }
12852
+ if (this.inputSecondary) {
12853
+ serialized.push(this.inputSecondary.serialize());
12854
+ if (this.inputSecondaryParams) {
12855
+ serialized.push(this.serializeParams(this.inputSecondaryParams));
12856
+ }
12857
+ }
12858
+ return serialized;
12376
12859
  }
12377
12860
  }
12378
12861
 
@@ -12500,7 +12983,7 @@
12500
12983
  } else if (this.type.kind === 'formatted') {
12501
12984
  return Formatted.fromString(toString(this.args[0].evaluate(ctx)));
12502
12985
  } else if (this.type.kind === 'resolvedImage') {
12503
- return ResolvedImage.fromString(toString(this.args[0].evaluate(ctx)));
12986
+ return ResolvedImage.build(toString(this.args[0].evaluate(ctx)));
12504
12987
  } else if (this.type.kind === 'array') {
12505
12988
  return this.args.map(arg => {
12506
12989
  return arg.evaluate(ctx);
@@ -14254,7 +14737,7 @@
14254
14737
  return Formatted.fromString(toString(value));
14255
14738
  }
14256
14739
  case 'resolvedImage': {
14257
- return ResolvedImage.fromString(toString(value));
14740
+ return ResolvedImage.build(toString(value));
14258
14741
  }
14259
14742
  }
14260
14743
  return value;
@@ -14912,11 +15395,12 @@
14912
15395
  });
14913
15396
 
14914
15397
  class Interpolate {
14915
- constructor(type, operator, interpolation, input, stops) {
15398
+ constructor(type, operator, interpolation, input, dynamicStops, stops) {
14916
15399
  this.type = type;
14917
15400
  this.operator = operator;
14918
15401
  this.interpolation = interpolation;
14919
15402
  this.input = input;
15403
+ this.dynamicStops = dynamicStops;
14920
15404
  this.labels = [];
14921
15405
  this.outputs = [];
14922
15406
  for (const [label, expression] of stops) {
@@ -14964,10 +15448,10 @@
14964
15448
  } else {
14965
15449
  return context.error(`Unknown interpolation type ${ String(interpolation[0]) }`, 1, 0);
14966
15450
  }
14967
- if (args.length - 1 < 4) {
14968
- return context.error(`Expected at least 4 arguments, but found only ${ args.length - 1 }.`);
15451
+ if (args.length - 1 < 3) {
15452
+ return context.error(`Expected at least 3 arguments, but found only ${ args.length - 1 }.`);
14969
15453
  }
14970
- if ((args.length - 1) % 2 !== 0) {
15454
+ if (args.length - 1 > 3 && (args.length - 1) % 2 !== 0) {
14971
15455
  return context.error(`Expected an even number of arguments.`);
14972
15456
  }
14973
15457
  input = context.parse(input, 2, NumberType);
@@ -14980,6 +15464,12 @@
14980
15464
  } else if (context.expectedType && context.expectedType.kind !== 'value') {
14981
15465
  outputType = context.expectedType;
14982
15466
  }
15467
+ if (args.length - 1 === 3) {
15468
+ const dynamicStops = context.parse(rest[0], 3, ValueType);
15469
+ if (!dynamicStops)
15470
+ return null;
15471
+ return new Interpolate(outputType, operator, interpolation, input, dynamicStops, stops);
15472
+ }
14983
15473
  for (let i = 0; i < rest.length; i += 2) {
14984
15474
  const label = rest[i];
14985
15475
  const value = rest[i + 1];
@@ -15003,11 +15493,34 @@
15003
15493
  if (outputType.kind !== 'number' && outputType.kind !== 'color' && !(outputType.kind === 'array' && outputType.itemType.kind === 'number' && typeof outputType.N === 'number')) {
15004
15494
  return context.error(`Type ${ toString$1(outputType) } is not interpolatable.`);
15005
15495
  }
15006
- return new Interpolate(outputType, operator, interpolation, input, stops);
15496
+ return new Interpolate(outputType, operator, interpolation, input, null, stops);
15007
15497
  }
15008
15498
  evaluate(ctx) {
15009
- const labels = this.labels;
15010
- const outputs = this.outputs;
15499
+ let labels = this.labels;
15500
+ let outputs = this.outputs;
15501
+ if (this.dynamicStops) {
15502
+ const dynamicStopsValue = this.dynamicStops.evaluate(ctx);
15503
+ if (dynamicStopsValue.length % 2 !== 0) {
15504
+ throw new RuntimeError('Expected an even number of arguments.');
15505
+ }
15506
+ labels = [];
15507
+ outputs = [];
15508
+ for (let i = 0; i < dynamicStopsValue.length; i += 2) {
15509
+ const label = dynamicStopsValue[i];
15510
+ const output = new Literal(NumberType, dynamicStopsValue[i + 1]);
15511
+ if (typeof label !== 'number') {
15512
+ throw new RuntimeError('Input/output pairs for "interpolate" expressions must be defined using literal numeric values (not computed expressions) for the input values.');
15513
+ }
15514
+ if (labels.length && labels[labels.length - 1] >= label) {
15515
+ throw new RuntimeError('Input/output pairs for "interpolate" expressions must be arranged with input values in strictly ascending order.');
15516
+ }
15517
+ labels.push(label);
15518
+ outputs.push(output);
15519
+ }
15520
+ if (labels.length === 0) {
15521
+ throw new RuntimeError('Expected at least one input/output pair.');
15522
+ }
15523
+ }
15011
15524
  if (labels.length === 1) {
15012
15525
  return outputs[0].evaluate(ctx);
15013
15526
  }
@@ -15063,8 +15576,12 @@
15063
15576
  interpolation,
15064
15577
  this.input.serialize()
15065
15578
  ];
15066
- for (let i = 0; i < this.labels.length; i++) {
15067
- serialized.push(this.labels[i], this.outputs[i].serialize());
15579
+ if (this.dynamicStops) {
15580
+ serialized.push(this.dynamicStops.serialize());
15581
+ } else {
15582
+ for (let i = 0; i < this.labels.length; i++) {
15583
+ serialized.push(this.labels[i], this.outputs[i].serialize());
15584
+ }
15068
15585
  }
15069
15586
  return serialized;
15070
15587
  }
@@ -16052,6 +16569,13 @@
16052
16569
  return v.evaluate(ctx).toRenderColor(null).toArray();
16053
16570
  }
16054
16571
  ],
16572
+ 'to-hsla': [
16573
+ array$1(NumberType, 4),
16574
+ [ColorType],
16575
+ (ctx, [v]) => {
16576
+ return v.evaluate(ctx).toRenderColor(null).toHslaArray();
16577
+ }
16578
+ ],
16055
16579
  'rgb': [
16056
16580
  ColorType,
16057
16581
  [
@@ -16816,7 +17340,7 @@
16816
17340
  } else if (propertySpec.type === 'formatted') {
16817
17341
  input = Formatted.fromString(input.toString());
16818
17342
  } else if (propertySpec.type === 'resolvedImage') {
16819
- input = ResolvedImage.fromString(input.toString());
17343
+ input = ResolvedImage.build(input.toString());
16820
17344
  } else if (getType(input) !== propertySpec.type && (propertySpec.type !== 'enum' || !propertySpec.values[input])) {
16821
17345
  input = void 0;
16822
17346
  }
@@ -16895,10 +17419,11 @@
16895
17419
  return success(new StyleExpression(parsed, propertySpec, scope, options));
16896
17420
  }
16897
17421
  class ZoomConstantExpression {
16898
- constructor(kind, expression, isLightConstant) {
17422
+ constructor(kind, expression, isLightConstant, isLineProgressConstant) {
16899
17423
  this.kind = kind;
16900
17424
  this._styleExpression = expression;
16901
17425
  this.isLightConstant = isLightConstant;
17426
+ this.isLineProgressConstant = isLineProgressConstant;
16902
17427
  this.isStateDependent = kind !== 'constant' && !isStateConstant(expression.expression);
16903
17428
  this.configDependencies = getConfigDependencies(expression.expression);
16904
17429
  }
@@ -16910,12 +17435,13 @@
16910
17435
  }
16911
17436
  }
16912
17437
  class ZoomDependentExpression {
16913
- constructor(kind, expression, zoomStops, interpolationType, isLightConstant) {
17438
+ constructor(kind, expression, zoomStops, interpolationType, isLightConstant, isLineProgressConstant) {
16914
17439
  this.kind = kind;
16915
17440
  this.zoomStops = zoomStops;
16916
17441
  this._styleExpression = expression;
16917
17442
  this.isStateDependent = kind !== 'camera' && !isStateConstant(expression.expression);
16918
17443
  this.isLightConstant = isLightConstant;
17444
+ this.isLineProgressConstant = isLineProgressConstant;
16919
17445
  this.configDependencies = getConfigDependencies(expression.expression);
16920
17446
  this.interpolationType = interpolationType;
16921
17447
  }
@@ -16970,13 +17496,13 @@
16970
17496
  }
16971
17497
  if (!zoomCurve) {
16972
17498
  return success(isFeatureConstant$1 && isLineProgressConstant ? // @ts-expect-error - TS2339 - Property 'value' does not exist on type 'unknown'.
16973
- new ZoomConstantExpression('constant', expression.value, isLightConstant) : // @ts-expect-error - TS2339 - Property 'value' does not exist on type 'unknown'.
16974
- new ZoomConstantExpression('source', expression.value, isLightConstant));
17499
+ new ZoomConstantExpression('constant', expression.value, isLightConstant, isLineProgressConstant) : // @ts-expect-error - TS2339 - Property 'value' does not exist on type 'unknown'.
17500
+ new ZoomConstantExpression('source', expression.value, isLightConstant, isLineProgressConstant));
16975
17501
  }
16976
17502
  const interpolationType = zoomCurve instanceof Interpolate ? zoomCurve.interpolation : void 0;
16977
17503
  return success(isFeatureConstant$1 && isLineProgressConstant ? // @ts-expect-error - TS2339 - Property 'value' does not exist on type 'unknown'.
16978
- new ZoomDependentExpression('camera', expression.value, zoomCurve.labels, interpolationType, isLightConstant) : // @ts-expect-error - TS2339 - Property 'value' does not exist on type 'unknown'.
16979
- new ZoomDependentExpression('composite', expression.value, zoomCurve.labels, interpolationType, isLightConstant));
17504
+ new ZoomDependentExpression('camera', expression.value, zoomCurve.labels, interpolationType, isLightConstant, isLineProgressConstant) : // @ts-expect-error - TS2339 - Property 'value' does not exist on type 'unknown'.
17505
+ new ZoomDependentExpression('composite', expression.value, zoomCurve.labels, interpolationType, isLightConstant, isLineProgressConstant));
16980
17506
  }
16981
17507
  class StylePropertyFunction {
16982
17508
  constructor(parameters, specification) {
@@ -18098,6 +18624,14 @@ ${ JSON.stringify(filterExp, null, 2) }
18098
18624
  */
18099
18625
  setFog: 'setFog',
18100
18626
  /*
18627
+ * { command: 'setSnow', args: [snowProperties] }
18628
+ */
18629
+ setSnow: 'setSnow',
18630
+ /*
18631
+ * { command: 'setRain', args: [rainProperties] }
18632
+ */
18633
+ setRain: 'setRain',
18634
+ /*
18101
18635
  * { command: 'setCamera', args: [cameraProperties] }
18102
18636
  */
18103
18637
  setCamera: 'setCamera',
@@ -18498,6 +19032,18 @@ ${ JSON.stringify(filterExp, null, 2) }
18498
19032
  args: [after.fog]
18499
19033
  });
18500
19034
  }
19035
+ if (!deepEqual(before.snow, after.snow)) {
19036
+ commands.push({
19037
+ command: operations.setSnow,
19038
+ args: [after.snow]
19039
+ });
19040
+ }
19041
+ if (!deepEqual(before.rain, after.rain)) {
19042
+ commands.push({
19043
+ command: operations.setRain,
19044
+ args: [after.rain]
19045
+ });
19046
+ }
18501
19047
  if (!deepEqual(before.projection, after.projection)) {
18502
19048
  commands.push({
18503
19049
  command: operations.setProjection,
@@ -19109,6 +19655,16 @@ ${ JSON.stringify(filterExp, null, 2) }
19109
19655
  const layerSpec = styleSpec[`${ propertyType }_${ options.layerType }`];
19110
19656
  if (!layerSpec)
19111
19657
  return [];
19658
+ const useThemeMatch = propertyKey.match(/^(.*)-use-theme$/);
19659
+ if (propertyType === 'paint' && useThemeMatch && layerSpec[useThemeMatch[1]]) {
19660
+ return validate({
19661
+ key,
19662
+ value,
19663
+ valueSpec: { type: 'string' },
19664
+ style,
19665
+ styleSpec
19666
+ });
19667
+ }
19112
19668
  const transitionMatch = propertyKey.match(/^(.*)-transition$/);
19113
19669
  if (propertyType === 'paint' && transitionMatch && layerSpec[transitionMatch[1]] && layerSpec[transitionMatch[1]].transition) {
19114
19670
  return validate({
@@ -19483,7 +20039,16 @@ Use an identity property function instead: ${ example }.`)];
19483
20039
  }
19484
20040
  for (const key in light) {
19485
20041
  const transitionMatch = key.match(/^(.*)-transition$/);
19486
- if (transitionMatch && lightSpec[transitionMatch[1]] && lightSpec[transitionMatch[1]].transition) {
20042
+ const useThemeMatch = key.match(/^(.*)-use-theme$/);
20043
+ if (useThemeMatch && lightSpec[useThemeMatch[1]]) {
20044
+ errors = errors.concat(validate({
20045
+ key,
20046
+ value: light[key],
20047
+ valueSpec: { type: 'string' },
20048
+ style,
20049
+ styleSpec
20050
+ }));
20051
+ } else if (transitionMatch && lightSpec[transitionMatch[1]] && lightSpec[transitionMatch[1]].transition) {
19487
20052
  errors = errors.concat(validate({
19488
20053
  key,
19489
20054
  value: light[key],
@@ -19569,7 +20134,16 @@ Use an identity property function instead: ${ example }.`)];
19569
20134
  }
19570
20135
  } else {
19571
20136
  const transitionMatch = key2.match(/^(.*)-transition$/);
19572
- if (transitionMatch && lightSpec[transitionMatch[1]] && lightSpec[transitionMatch[1]].transition) {
20137
+ const useThemeMatch = key2.match(/^(.*)-use-theme$/);
20138
+ if (useThemeMatch && lightSpec[useThemeMatch[1]]) {
20139
+ errors = errors.concat(validate({
20140
+ key: key2,
20141
+ value: light[key2],
20142
+ valueSpec: { type: 'string' },
20143
+ style,
20144
+ styleSpec
20145
+ }));
20146
+ } else if (transitionMatch && lightSpec[transitionMatch[1]] && lightSpec[transitionMatch[1]].transition) {
19573
20147
  errors = errors.concat(validate({
19574
20148
  key: key2,
19575
20149
  value: light[key2],
@@ -19611,7 +20185,16 @@ Use an identity property function instead: ${ example }.`)];
19611
20185
  }
19612
20186
  for (const key2 in terrain) {
19613
20187
  const transitionMatch = key2.match(/^(.*)-transition$/);
19614
- if (transitionMatch && terrainSpec[transitionMatch[1]] && terrainSpec[transitionMatch[1]].transition) {
20188
+ const useThemeMatch = key2.match(/^(.*)-use-theme$/);
20189
+ if (useThemeMatch && terrainSpec[useThemeMatch[1]]) {
20190
+ errors = errors.concat(validate({
20191
+ key: key2,
20192
+ value: terrain[key2],
20193
+ valueSpec: { type: 'string' },
20194
+ style,
20195
+ styleSpec
20196
+ }));
20197
+ } else if (transitionMatch && terrainSpec[transitionMatch[1]] && terrainSpec[transitionMatch[1]].transition) {
19615
20198
  errors = errors.concat(validate({
19616
20199
  key: key2,
19617
20200
  value: terrain[key2],
@@ -19660,7 +20243,16 @@ Use an identity property function instead: ${ example }.`)];
19660
20243
  }
19661
20244
  for (const key in fog) {
19662
20245
  const transitionMatch = key.match(/^(.*)-transition$/);
19663
- if (transitionMatch && fogSpec[transitionMatch[1]] && fogSpec[transitionMatch[1]].transition) {
20246
+ const useThemeMatch = key.match(/^(.*)-use-theme$/);
20247
+ if (useThemeMatch && fogSpec[useThemeMatch[1]]) {
20248
+ errors = errors.concat(validate({
20249
+ key,
20250
+ value: fog[key],
20251
+ valueSpec: { type: 'string' },
20252
+ style,
20253
+ styleSpec
20254
+ }));
20255
+ } else if (transitionMatch && fogSpec[transitionMatch[1]] && fogSpec[transitionMatch[1]].transition) {
19664
20256
  errors = errors.concat(validate({
19665
20257
  key,
19666
20258
  value: fog[key],