@unmap/themes 0.1.3 → 0.2.0
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/README.md +10 -8
- package/dist/index.d.ts +188 -36
- package/dist/index.js +868 -559
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -23,6 +23,22 @@ var ink = {
|
|
|
23
23
|
950: "#0E191C",
|
|
24
24
|
1e3: "#030E10"
|
|
25
25
|
};
|
|
26
|
+
var paper = {
|
|
27
|
+
25: "#FBF5F2",
|
|
28
|
+
50: "#F5EFEC",
|
|
29
|
+
100: "#ECE6E3",
|
|
30
|
+
200: "#E1DBD8",
|
|
31
|
+
300: "#D4CECB",
|
|
32
|
+
400: "#C3BDBA",
|
|
33
|
+
500: "#A9A3A0",
|
|
34
|
+
600: "#8A8582",
|
|
35
|
+
700: "#696361",
|
|
36
|
+
800: "#4A4543",
|
|
37
|
+
850: "#373330",
|
|
38
|
+
900: "#272220",
|
|
39
|
+
950: "#1A1614",
|
|
40
|
+
1e3: "#0E0B09"
|
|
41
|
+
};
|
|
26
42
|
var wave = {
|
|
27
43
|
100: "#C7F1F3",
|
|
28
44
|
200: "#B3E2E4",
|
|
@@ -36,6 +52,19 @@ var wave = {
|
|
|
36
52
|
950: "#001C1E",
|
|
37
53
|
980: "#001012"
|
|
38
54
|
};
|
|
55
|
+
var sky = {
|
|
56
|
+
100: "#CCEEFF",
|
|
57
|
+
200: "#A7E2FF",
|
|
58
|
+
300: "#8ACFF0",
|
|
59
|
+
400: "#73B7D7",
|
|
60
|
+
500: "#5A9CBC",
|
|
61
|
+
600: "#387D9C",
|
|
62
|
+
700: "#155F7C",
|
|
63
|
+
800: "#004057",
|
|
64
|
+
900: "#002837",
|
|
65
|
+
950: "#001B27",
|
|
66
|
+
980: "#000F17"
|
|
67
|
+
};
|
|
39
68
|
var verdant = {
|
|
40
69
|
100: "#D3F1DA",
|
|
41
70
|
200: "#C3E3CA",
|
|
@@ -68,9 +97,62 @@ var graphite = {
|
|
|
68
97
|
900: "#232323",
|
|
69
98
|
1e3: "#0B0B0B"
|
|
70
99
|
};
|
|
100
|
+
var mist = {
|
|
101
|
+
100: "#E7E7E7",
|
|
102
|
+
200: "#D7D7D7",
|
|
103
|
+
300: "#C4C4C4",
|
|
104
|
+
400: "#ACACAC",
|
|
105
|
+
500: "#929292",
|
|
106
|
+
600: "#757575",
|
|
107
|
+
700: "#575757",
|
|
108
|
+
800: "#3A3A3A",
|
|
109
|
+
900: "#242424",
|
|
110
|
+
950: "#171717",
|
|
111
|
+
980: "#0D0D0D"
|
|
112
|
+
};
|
|
113
|
+
var jade = {
|
|
114
|
+
25: "#F1F9F4",
|
|
115
|
+
50: "#E6F4ED",
|
|
116
|
+
100: "#D7EEE2",
|
|
117
|
+
200: "#C3E6D4",
|
|
118
|
+
300: "#ACDDC4",
|
|
119
|
+
400: "#8BCFAF",
|
|
120
|
+
500: "#56BB90",
|
|
121
|
+
600: "#459975",
|
|
122
|
+
700: "#327357",
|
|
123
|
+
800: "#21513D",
|
|
124
|
+
850: "#173C2C",
|
|
125
|
+
900: "#0E2A1E",
|
|
126
|
+
950: "#071C13",
|
|
127
|
+
1e3: "#030F09"
|
|
128
|
+
};
|
|
129
|
+
var cobalt = {
|
|
130
|
+
25: "#F4F7FB",
|
|
131
|
+
50: "#ECF0F9",
|
|
132
|
+
100: "#E1E8F7",
|
|
133
|
+
200: "#D2DCF5",
|
|
134
|
+
300: "#C0CFF3",
|
|
135
|
+
400: "#A8BDF1",
|
|
136
|
+
500: "#84A2EE",
|
|
137
|
+
600: "#587EEA",
|
|
138
|
+
700: "#2C4EE5",
|
|
139
|
+
800: "#243D93",
|
|
140
|
+
850: "#1D2F65",
|
|
141
|
+
900: "#162241",
|
|
142
|
+
950: "#0F1629",
|
|
143
|
+
1e3: "#080B15"
|
|
144
|
+
};
|
|
71
145
|
|
|
72
146
|
// src/recipe.ts
|
|
73
|
-
var THEME_BASES = ["base", "muted", "
|
|
147
|
+
var THEME_BASES = ["base", "muted", "outdoor", "decimal", "blueprint"];
|
|
148
|
+
var RETIRED_BASES = {
|
|
149
|
+
relief: "outdoor",
|
|
150
|
+
street: "base"
|
|
151
|
+
};
|
|
152
|
+
function normalizeThemeBase(base) {
|
|
153
|
+
if (THEME_BASES.includes(base)) return base;
|
|
154
|
+
return RETIRED_BASES[base] ?? null;
|
|
155
|
+
}
|
|
74
156
|
var MODES = ["light", "dark"];
|
|
75
157
|
function makeFlavor(r) {
|
|
76
158
|
return {
|
|
@@ -158,61 +240,73 @@ function makeFlavor(r) {
|
|
|
158
240
|
}
|
|
159
241
|
|
|
160
242
|
// src/recipes.ts
|
|
161
|
-
var STOCK_RAMPS = {
|
|
243
|
+
var STOCK_RAMPS = {
|
|
244
|
+
ink,
|
|
245
|
+
paper,
|
|
246
|
+
wave,
|
|
247
|
+
sky,
|
|
248
|
+
verdant,
|
|
249
|
+
sandstone,
|
|
250
|
+
graphite,
|
|
251
|
+
mist,
|
|
252
|
+
jade,
|
|
253
|
+
cobalt,
|
|
254
|
+
ember
|
|
255
|
+
};
|
|
162
256
|
function buildRecipes(r) {
|
|
163
257
|
const BASE_LIGHT = {
|
|
164
|
-
background: r.
|
|
165
|
-
earth: r.
|
|
166
|
-
water: r.
|
|
167
|
-
parkA: r.verdant[
|
|
168
|
-
parkB: r.verdant[
|
|
169
|
-
woodA: r.verdant[
|
|
170
|
-
woodB: r.verdant[
|
|
258
|
+
background: r.paper[100],
|
|
259
|
+
earth: r.paper[25],
|
|
260
|
+
water: r.sky[200],
|
|
261
|
+
parkA: r.verdant[300],
|
|
262
|
+
parkB: r.verdant[400],
|
|
263
|
+
woodA: r.verdant[300],
|
|
264
|
+
woodB: r.verdant[400],
|
|
171
265
|
scrubA: r.verdant[200],
|
|
172
266
|
scrubB: r.verdant[300],
|
|
173
267
|
sand: r.sandstone[200],
|
|
174
268
|
beach: r.sandstone[200],
|
|
175
|
-
glacier: r.
|
|
176
|
-
institutional: r.
|
|
177
|
-
pedestrian: r.
|
|
178
|
-
aerodrome: r.
|
|
179
|
-
runway: r.
|
|
180
|
-
pier: r.
|
|
181
|
-
buildings: r.
|
|
182
|
-
railway: r.
|
|
183
|
-
boundaries: r.
|
|
269
|
+
glacier: r.paper[25],
|
|
270
|
+
institutional: r.paper[100],
|
|
271
|
+
pedestrian: r.paper[100],
|
|
272
|
+
aerodrome: r.cobalt[200],
|
|
273
|
+
runway: r.cobalt[300],
|
|
274
|
+
pier: r.paper[300],
|
|
275
|
+
buildings: r.paper[200],
|
|
276
|
+
railway: r.graphite[400],
|
|
277
|
+
boundaries: r.cobalt[600],
|
|
184
278
|
roads: {
|
|
185
|
-
other: r.
|
|
186
|
-
otherCasing: r.
|
|
187
|
-
minor:
|
|
188
|
-
minorCasing: r.
|
|
189
|
-
service: r.
|
|
190
|
-
serviceCasing: r.
|
|
279
|
+
other: r.paper[100],
|
|
280
|
+
otherCasing: r.graphite[200],
|
|
281
|
+
minor: "#FFFFFF",
|
|
282
|
+
minorCasing: r.graphite[200],
|
|
283
|
+
service: r.paper[100],
|
|
284
|
+
serviceCasing: r.graphite[200],
|
|
191
285
|
major: "#FFFFFF",
|
|
192
|
-
majorCasing: r.
|
|
193
|
-
highway:
|
|
194
|
-
highwayCasing: r.
|
|
195
|
-
link:
|
|
196
|
-
linkCasing: r.
|
|
286
|
+
majorCasing: r.graphite[300],
|
|
287
|
+
highway: r.ember[400],
|
|
288
|
+
highwayCasing: r.ember[600],
|
|
289
|
+
link: r.ember[300],
|
|
290
|
+
linkCasing: r.ember[500]
|
|
197
291
|
},
|
|
198
|
-
tunnelFill: r.
|
|
199
|
-
tunnelCasing: r.
|
|
200
|
-
bridgeCasing: r.
|
|
292
|
+
tunnelFill: r.paper[200],
|
|
293
|
+
tunnelCasing: r.graphite[200],
|
|
294
|
+
bridgeCasing: r.graphite[400],
|
|
201
295
|
labels: {
|
|
202
|
-
city: r.
|
|
203
|
-
cityHalo: r.
|
|
204
|
-
state: r.
|
|
205
|
-
stateHalo: r.
|
|
206
|
-
country: r.
|
|
207
|
-
subplace: r.
|
|
208
|
-
subplaceHalo: r.
|
|
209
|
-
address: r.
|
|
210
|
-
addressHalo: r.
|
|
211
|
-
roadMinor: r.
|
|
212
|
-
roadMinorHalo: r.
|
|
213
|
-
roadMajor: r.
|
|
214
|
-
roadMajorHalo: r.
|
|
215
|
-
ocean: r.
|
|
296
|
+
city: r.paper[1e3],
|
|
297
|
+
cityHalo: r.paper[25],
|
|
298
|
+
state: r.paper[700],
|
|
299
|
+
stateHalo: r.paper[25],
|
|
300
|
+
country: r.paper[700],
|
|
301
|
+
subplace: r.paper[700],
|
|
302
|
+
subplaceHalo: r.paper[25],
|
|
303
|
+
address: r.paper[700],
|
|
304
|
+
addressHalo: r.paper[25],
|
|
305
|
+
roadMinor: r.paper[800],
|
|
306
|
+
roadMinorHalo: r.paper[25],
|
|
307
|
+
roadMajor: r.paper[900],
|
|
308
|
+
roadMajorHalo: r.paper[25],
|
|
309
|
+
ocean: r.sky[800]
|
|
216
310
|
},
|
|
217
311
|
pois: {
|
|
218
312
|
blue: "#2D6E8F",
|
|
@@ -220,73 +314,73 @@ function buildRecipes(r) {
|
|
|
220
314
|
lapis: "#3F5C93",
|
|
221
315
|
pink: "#8F4A6B",
|
|
222
316
|
red: "#9B4340",
|
|
223
|
-
slategray: r.
|
|
317
|
+
slategray: r.paper[700],
|
|
224
318
|
tangerine: "#8F5322",
|
|
225
|
-
turquoise: r.
|
|
319
|
+
turquoise: r.sky[700]
|
|
226
320
|
},
|
|
227
321
|
landcover: {
|
|
228
322
|
grassland: r.verdant[200],
|
|
229
323
|
barren: r.sandstone[200],
|
|
230
|
-
urban_area: r.
|
|
324
|
+
urban_area: r.paper[50],
|
|
231
325
|
farmland: r.verdant[100],
|
|
232
|
-
glacier: r.
|
|
233
|
-
scrub: r.verdant[
|
|
234
|
-
forest: r.verdant[
|
|
326
|
+
glacier: r.paper[25],
|
|
327
|
+
scrub: r.verdant[200],
|
|
328
|
+
forest: r.verdant[400]
|
|
235
329
|
}
|
|
236
330
|
};
|
|
237
331
|
const BASE_DARK = {
|
|
238
|
-
background: r.
|
|
239
|
-
earth: r.
|
|
240
|
-
water: r.
|
|
332
|
+
background: r.paper[950],
|
|
333
|
+
earth: r.paper[900],
|
|
334
|
+
water: r.sky[980],
|
|
241
335
|
parkA: r.verdant[800],
|
|
242
336
|
parkB: r.verdant[700],
|
|
243
337
|
woodA: r.verdant[800],
|
|
244
338
|
woodB: r.verdant[700],
|
|
245
|
-
scrubA: r.verdant[
|
|
246
|
-
scrubB: r.verdant[
|
|
339
|
+
scrubA: r.verdant[900],
|
|
340
|
+
scrubB: r.verdant[800],
|
|
247
341
|
sand: r.sandstone[500],
|
|
248
342
|
beach: r.sandstone[500],
|
|
249
|
-
glacier: r.
|
|
250
|
-
institutional: r.
|
|
251
|
-
pedestrian: r.
|
|
252
|
-
aerodrome: r.
|
|
253
|
-
runway: r.
|
|
254
|
-
pier: r.
|
|
255
|
-
buildings: r.
|
|
256
|
-
railway: r.
|
|
257
|
-
boundaries: r.
|
|
343
|
+
glacier: r.paper[700],
|
|
344
|
+
institutional: r.paper[950],
|
|
345
|
+
pedestrian: r.paper[950],
|
|
346
|
+
aerodrome: r.cobalt[900],
|
|
347
|
+
runway: r.cobalt[850],
|
|
348
|
+
pier: r.paper[850],
|
|
349
|
+
buildings: r.paper[850],
|
|
350
|
+
railway: r.paper[700],
|
|
351
|
+
boundaries: r.cobalt[500],
|
|
258
352
|
roads: {
|
|
259
|
-
other: r.
|
|
260
|
-
otherCasing: r.
|
|
261
|
-
minor: r.
|
|
262
|
-
minorCasing: r.
|
|
263
|
-
service: r.
|
|
264
|
-
serviceCasing: r.
|
|
265
|
-
major: r.
|
|
266
|
-
majorCasing: r.
|
|
267
|
-
highway: r.
|
|
268
|
-
highwayCasing: r.
|
|
269
|
-
link: r.
|
|
270
|
-
linkCasing: r.
|
|
353
|
+
other: r.paper[850],
|
|
354
|
+
otherCasing: r.paper[1e3],
|
|
355
|
+
minor: r.paper[800],
|
|
356
|
+
minorCasing: r.paper[1e3],
|
|
357
|
+
service: r.paper[850],
|
|
358
|
+
serviceCasing: r.paper[1e3],
|
|
359
|
+
major: r.paper[700],
|
|
360
|
+
majorCasing: r.paper[1e3],
|
|
361
|
+
highway: r.ember[600],
|
|
362
|
+
highwayCasing: r.paper[1e3],
|
|
363
|
+
link: r.ember[700],
|
|
364
|
+
linkCasing: r.paper[1e3]
|
|
271
365
|
},
|
|
272
|
-
tunnelFill: r.
|
|
273
|
-
tunnelCasing: r.
|
|
274
|
-
bridgeCasing: r.
|
|
366
|
+
tunnelFill: r.paper[900],
|
|
367
|
+
tunnelCasing: r.paper[1e3],
|
|
368
|
+
bridgeCasing: r.paper[1e3],
|
|
275
369
|
labels: {
|
|
276
|
-
city: r.
|
|
277
|
-
cityHalo: r.
|
|
278
|
-
state: r.
|
|
279
|
-
stateHalo: r.
|
|
280
|
-
country: r.
|
|
281
|
-
subplace: r.
|
|
282
|
-
subplaceHalo: r.
|
|
283
|
-
address: r.
|
|
284
|
-
addressHalo: r.
|
|
285
|
-
roadMinor: r.
|
|
286
|
-
roadMinorHalo: r.
|
|
287
|
-
roadMajor: r.
|
|
288
|
-
roadMajorHalo: r.
|
|
289
|
-
ocean: r.
|
|
370
|
+
city: r.paper[100],
|
|
371
|
+
cityHalo: r.paper[1e3],
|
|
372
|
+
state: r.paper[500],
|
|
373
|
+
stateHalo: r.paper[1e3],
|
|
374
|
+
country: r.paper[500],
|
|
375
|
+
subplace: r.paper[500],
|
|
376
|
+
subplaceHalo: r.paper[1e3],
|
|
377
|
+
address: r.paper[500],
|
|
378
|
+
addressHalo: r.paper[1e3],
|
|
379
|
+
roadMinor: r.paper[500],
|
|
380
|
+
roadMinorHalo: r.paper[1e3],
|
|
381
|
+
roadMajor: r.paper[400],
|
|
382
|
+
roadMajorHalo: r.paper[1e3],
|
|
383
|
+
ocean: r.sky[400]
|
|
290
384
|
},
|
|
291
385
|
pois: {
|
|
292
386
|
blue: "#7FC4E8",
|
|
@@ -294,35 +388,35 @@ function buildRecipes(r) {
|
|
|
294
388
|
lapis: "#8FB0EA",
|
|
295
389
|
pink: "#E3A0C0",
|
|
296
390
|
red: "#EE968F",
|
|
297
|
-
slategray: r.
|
|
391
|
+
slategray: r.paper[500],
|
|
298
392
|
tangerine: "#E8AC7C",
|
|
299
|
-
turquoise: r.
|
|
393
|
+
turquoise: r.sky[400]
|
|
300
394
|
},
|
|
301
395
|
landcover: {
|
|
302
396
|
grassland: r.verdant[800],
|
|
303
397
|
barren: r.sandstone[500],
|
|
304
|
-
urban_area: r.
|
|
398
|
+
urban_area: r.paper[950],
|
|
305
399
|
farmland: r.verdant[900],
|
|
306
|
-
glacier: r.
|
|
400
|
+
glacier: r.paper[700],
|
|
307
401
|
scrub: r.verdant[900],
|
|
308
402
|
forest: r.verdant[700]
|
|
309
403
|
}
|
|
310
404
|
};
|
|
311
405
|
const MUTED_LIGHT = {
|
|
312
|
-
background: r.graphite[
|
|
313
|
-
earth: r.graphite[
|
|
314
|
-
water: r.
|
|
315
|
-
parkA: r.graphite[
|
|
316
|
-
parkB: r.graphite[
|
|
317
|
-
woodA: r.graphite[
|
|
318
|
-
woodB: r.graphite[
|
|
319
|
-
scrubA: r.graphite[
|
|
320
|
-
scrubB: r.graphite[
|
|
406
|
+
background: r.graphite[100],
|
|
407
|
+
earth: r.graphite[25],
|
|
408
|
+
water: r.mist[200],
|
|
409
|
+
parkA: r.graphite[50],
|
|
410
|
+
parkB: r.graphite[100],
|
|
411
|
+
woodA: r.graphite[50],
|
|
412
|
+
woodB: r.graphite[100],
|
|
413
|
+
scrubA: r.graphite[50],
|
|
414
|
+
scrubB: r.graphite[100],
|
|
321
415
|
sand: r.graphite[100],
|
|
322
416
|
beach: r.graphite[100],
|
|
323
417
|
glacier: r.graphite[25],
|
|
324
418
|
institutional: r.graphite[100],
|
|
325
|
-
pedestrian: r.graphite[
|
|
419
|
+
pedestrian: r.graphite[50],
|
|
326
420
|
aerodrome: r.graphite[100],
|
|
327
421
|
runway: r.graphite[200],
|
|
328
422
|
pier: r.graphite[200],
|
|
@@ -338,14 +432,14 @@ function buildRecipes(r) {
|
|
|
338
432
|
serviceCasing: r.graphite[200],
|
|
339
433
|
major: "#FFFFFF",
|
|
340
434
|
majorCasing: r.graphite[300],
|
|
341
|
-
highway:
|
|
435
|
+
highway: r.graphite[200],
|
|
342
436
|
highwayCasing: r.graphite[300],
|
|
343
437
|
link: "#FFFFFF",
|
|
344
438
|
linkCasing: r.graphite[300]
|
|
345
439
|
},
|
|
346
440
|
tunnelFill: r.graphite[100],
|
|
347
441
|
tunnelCasing: r.graphite[200],
|
|
348
|
-
bridgeCasing: r.graphite[
|
|
442
|
+
bridgeCasing: r.graphite[400],
|
|
349
443
|
labels: {
|
|
350
444
|
city: r.graphite[1e3],
|
|
351
445
|
cityHalo: r.graphite[25],
|
|
@@ -375,7 +469,7 @@ function buildRecipes(r) {
|
|
|
375
469
|
landcover: {
|
|
376
470
|
grassland: r.graphite[50],
|
|
377
471
|
barren: r.graphite[100],
|
|
378
|
-
urban_area: r.graphite[
|
|
472
|
+
urban_area: r.graphite[50],
|
|
379
473
|
farmland: r.graphite[50],
|
|
380
474
|
glacier: r.graphite[25],
|
|
381
475
|
scrub: r.graphite[50],
|
|
@@ -385,7 +479,7 @@ function buildRecipes(r) {
|
|
|
385
479
|
const MUTED_DARK = {
|
|
386
480
|
background: r.graphite[1e3],
|
|
387
481
|
earth: r.graphite[900],
|
|
388
|
-
water: r.
|
|
482
|
+
water: r.mist[980],
|
|
389
483
|
parkA: r.graphite[900],
|
|
390
484
|
parkB: r.graphite[800],
|
|
391
485
|
woodA: r.graphite[900],
|
|
@@ -456,44 +550,45 @@ function buildRecipes(r) {
|
|
|
456
550
|
forest: r.graphite[800]
|
|
457
551
|
}
|
|
458
552
|
};
|
|
459
|
-
const
|
|
553
|
+
const OUTDOOR_LIGHT = {
|
|
460
554
|
background: r.ink[200],
|
|
461
555
|
earth: r.ink[50],
|
|
462
556
|
water: r.wave[300],
|
|
463
|
-
parkA: r.verdant[
|
|
464
|
-
parkB: r.verdant[
|
|
465
|
-
woodA: r.verdant[
|
|
466
|
-
woodB: r.verdant[
|
|
557
|
+
parkA: r.verdant[300],
|
|
558
|
+
parkB: r.verdant[400],
|
|
559
|
+
woodA: r.verdant[300],
|
|
560
|
+
woodB: r.verdant[400],
|
|
467
561
|
scrubA: r.verdant[200],
|
|
468
562
|
scrubB: r.verdant[300],
|
|
469
|
-
sand: r.sandstone[
|
|
470
|
-
beach: r.sandstone[
|
|
563
|
+
sand: r.sandstone[300],
|
|
564
|
+
beach: r.sandstone[300],
|
|
471
565
|
glacier: r.ink[25],
|
|
472
566
|
institutional: r.ink[25],
|
|
473
567
|
pedestrian: r.ink[50],
|
|
474
568
|
aerodrome: r.ink[50],
|
|
475
569
|
runway: r.ink[200],
|
|
476
570
|
pier: r.ink[300],
|
|
477
|
-
|
|
571
|
+
// A step lighter than `base`: outdoors, the building footprint is context, not content.
|
|
572
|
+
buildings: r.ink[200],
|
|
478
573
|
railway: r.ink[500],
|
|
479
574
|
boundaries: r.ink[600],
|
|
480
575
|
roads: {
|
|
481
576
|
other: r.ink[50],
|
|
482
|
-
otherCasing: r.ink[
|
|
577
|
+
otherCasing: r.ink[200],
|
|
483
578
|
minor: r.ink[25],
|
|
484
|
-
minorCasing: r.ink[
|
|
579
|
+
minorCasing: r.ink[200],
|
|
485
580
|
service: r.ink[50],
|
|
486
|
-
serviceCasing: r.ink[
|
|
581
|
+
serviceCasing: r.ink[200],
|
|
487
582
|
major: "#FFFFFF",
|
|
488
|
-
majorCasing: r.ink[
|
|
583
|
+
majorCasing: r.ink[300],
|
|
489
584
|
highway: "#FFFFFF",
|
|
490
|
-
highwayCasing: r.ink[
|
|
585
|
+
highwayCasing: r.ink[400],
|
|
491
586
|
link: "#FFFFFF",
|
|
492
|
-
linkCasing: r.ink[
|
|
587
|
+
linkCasing: r.ink[300]
|
|
493
588
|
},
|
|
494
589
|
tunnelFill: r.ink[200],
|
|
495
590
|
tunnelCasing: r.ink[300],
|
|
496
|
-
bridgeCasing: r.ink[
|
|
591
|
+
bridgeCasing: r.ink[400],
|
|
497
592
|
labels: {
|
|
498
593
|
city: r.ink[1e3],
|
|
499
594
|
cityHalo: r.ink[25],
|
|
@@ -512,7 +607,9 @@ function buildRecipes(r) {
|
|
|
512
607
|
},
|
|
513
608
|
pois: {
|
|
514
609
|
blue: "#2D6E8F",
|
|
515
|
-
green
|
|
610
|
+
// Peaks, parks, forests and gardens all come through green. On this flavour they are the
|
|
611
|
+
// POIs worth finding, so it carries a full step more weight than elsewhere.
|
|
612
|
+
green: r.verdant[800],
|
|
516
613
|
lapis: "#3F5C93",
|
|
517
614
|
pink: "#8F4A6B",
|
|
518
615
|
red: "#9B4340",
|
|
@@ -522,22 +619,22 @@ function buildRecipes(r) {
|
|
|
522
619
|
},
|
|
523
620
|
landcover: {
|
|
524
621
|
grassland: r.verdant[200],
|
|
525
|
-
barren: r.sandstone[
|
|
526
|
-
urban_area: r.ink[
|
|
527
|
-
farmland: r.
|
|
622
|
+
barren: r.sandstone[300],
|
|
623
|
+
urban_area: r.ink[100],
|
|
624
|
+
farmland: r.sandstone[200],
|
|
528
625
|
glacier: r.ink[25],
|
|
529
|
-
scrub: r.verdant[
|
|
530
|
-
forest: r.verdant[
|
|
626
|
+
scrub: r.verdant[300],
|
|
627
|
+
forest: r.verdant[400]
|
|
531
628
|
}
|
|
532
629
|
};
|
|
533
|
-
const
|
|
630
|
+
const OUTDOOR_DARK = {
|
|
534
631
|
background: r.ink[1e3],
|
|
535
632
|
earth: r.ink[950],
|
|
536
633
|
water: r.wave[980],
|
|
537
|
-
parkA: r.verdant[
|
|
538
|
-
parkB: r.verdant[
|
|
539
|
-
woodA: r.verdant[
|
|
540
|
-
woodB: r.verdant[
|
|
634
|
+
parkA: r.verdant[700],
|
|
635
|
+
parkB: r.verdant[600],
|
|
636
|
+
woodA: r.verdant[700],
|
|
637
|
+
woodB: r.verdant[600],
|
|
541
638
|
scrubA: r.verdant[800],
|
|
542
639
|
scrubB: r.verdant[700],
|
|
543
640
|
sand: r.sandstone[500],
|
|
@@ -552,11 +649,13 @@ function buildRecipes(r) {
|
|
|
552
649
|
railway: r.ink[700],
|
|
553
650
|
boundaries: r.ink[600],
|
|
554
651
|
roads: {
|
|
555
|
-
|
|
652
|
+
// The minor tier recedes toward `earth`; majors and highways hold their contrast,
|
|
653
|
+
// because a road you cannot see is a different failure from a road that is merely quiet.
|
|
654
|
+
other: r.ink[900],
|
|
556
655
|
otherCasing: r.ink[1e3],
|
|
557
|
-
minor: r.ink[
|
|
656
|
+
minor: r.ink[850],
|
|
558
657
|
minorCasing: r.ink[1e3],
|
|
559
|
-
service: r.ink[
|
|
658
|
+
service: r.ink[900],
|
|
560
659
|
serviceCasing: r.ink[1e3],
|
|
561
660
|
major: r.ink[700],
|
|
562
661
|
majorCasing: r.ink[1e3],
|
|
@@ -586,7 +685,7 @@ function buildRecipes(r) {
|
|
|
586
685
|
},
|
|
587
686
|
pois: {
|
|
588
687
|
blue: "#7FC4E8",
|
|
589
|
-
green: r.verdant[
|
|
688
|
+
green: r.verdant[300],
|
|
590
689
|
lapis: "#8FB0EA",
|
|
591
690
|
pink: "#E3A0C0",
|
|
592
691
|
red: "#EE968F",
|
|
@@ -595,322 +694,317 @@ function buildRecipes(r) {
|
|
|
595
694
|
turquoise: r.wave[400]
|
|
596
695
|
},
|
|
597
696
|
landcover: {
|
|
598
|
-
grassland: r.verdant[
|
|
697
|
+
grassland: r.verdant[700],
|
|
599
698
|
barren: r.sandstone[500],
|
|
600
699
|
urban_area: r.ink[950],
|
|
601
700
|
farmland: r.verdant[900],
|
|
602
701
|
glacier: r.ink[700],
|
|
603
|
-
scrub: r.verdant[
|
|
604
|
-
forest: r.verdant[
|
|
702
|
+
scrub: r.verdant[800],
|
|
703
|
+
forest: r.verdant[600]
|
|
605
704
|
}
|
|
606
705
|
};
|
|
607
|
-
const
|
|
608
|
-
background: r.
|
|
609
|
-
earth: r.
|
|
610
|
-
water: r.
|
|
611
|
-
parkA: r.
|
|
612
|
-
parkB: r.
|
|
613
|
-
woodA: r.
|
|
614
|
-
woodB: r.
|
|
615
|
-
scrubA: r.
|
|
616
|
-
scrubB: r.
|
|
617
|
-
sand: r.
|
|
618
|
-
beach: r.
|
|
619
|
-
glacier: r.
|
|
620
|
-
institutional: r.
|
|
621
|
-
pedestrian: r.
|
|
622
|
-
aerodrome: r.
|
|
623
|
-
runway: r.
|
|
624
|
-
pier: r.
|
|
625
|
-
buildings: r.
|
|
626
|
-
railway: r.
|
|
627
|
-
boundaries: r.
|
|
706
|
+
const DECIMAL_LIGHT = {
|
|
707
|
+
background: r.jade[100],
|
|
708
|
+
earth: r.jade[25],
|
|
709
|
+
water: r.jade[200],
|
|
710
|
+
parkA: r.jade[50],
|
|
711
|
+
parkB: r.jade[100],
|
|
712
|
+
woodA: r.jade[50],
|
|
713
|
+
woodB: r.jade[100],
|
|
714
|
+
scrubA: r.jade[50],
|
|
715
|
+
scrubB: r.jade[100],
|
|
716
|
+
sand: r.jade[50],
|
|
717
|
+
beach: r.jade[50],
|
|
718
|
+
glacier: r.jade[25],
|
|
719
|
+
institutional: r.jade[50],
|
|
720
|
+
pedestrian: r.jade[50],
|
|
721
|
+
aerodrome: r.jade[50],
|
|
722
|
+
runway: r.jade[200],
|
|
723
|
+
pier: r.jade[200],
|
|
724
|
+
buildings: r.jade[100],
|
|
725
|
+
railway: r.jade[500],
|
|
726
|
+
boundaries: r.jade[600],
|
|
628
727
|
roads: {
|
|
629
|
-
other: r.
|
|
630
|
-
otherCasing: r.
|
|
631
|
-
minor: r.
|
|
632
|
-
minorCasing: r.
|
|
633
|
-
service: r.
|
|
634
|
-
serviceCasing: r.
|
|
635
|
-
major:
|
|
636
|
-
majorCasing: r.
|
|
637
|
-
highway: r.
|
|
638
|
-
highwayCasing: r.
|
|
639
|
-
link:
|
|
640
|
-
linkCasing: r.
|
|
728
|
+
other: r.jade[200],
|
|
729
|
+
otherCasing: r.jade[25],
|
|
730
|
+
minor: r.jade[300],
|
|
731
|
+
minorCasing: r.jade[25],
|
|
732
|
+
service: r.jade[200],
|
|
733
|
+
serviceCasing: r.jade[25],
|
|
734
|
+
major: r.jade[400],
|
|
735
|
+
majorCasing: r.jade[25],
|
|
736
|
+
highway: r.jade[500],
|
|
737
|
+
highwayCasing: r.jade[25],
|
|
738
|
+
link: r.jade[400],
|
|
739
|
+
linkCasing: r.jade[25]
|
|
641
740
|
},
|
|
642
|
-
tunnelFill: r.
|
|
643
|
-
tunnelCasing: r.
|
|
644
|
-
bridgeCasing: r.
|
|
741
|
+
tunnelFill: r.jade[100],
|
|
742
|
+
tunnelCasing: r.jade[200],
|
|
743
|
+
bridgeCasing: r.jade[600],
|
|
645
744
|
labels: {
|
|
646
|
-
city: r.
|
|
647
|
-
cityHalo: r.
|
|
648
|
-
state: r.
|
|
649
|
-
stateHalo: r.
|
|
650
|
-
country: r.
|
|
651
|
-
subplace: r.
|
|
652
|
-
subplaceHalo: r.
|
|
653
|
-
address: r.
|
|
654
|
-
addressHalo: r.
|
|
655
|
-
roadMinor: r.
|
|
656
|
-
roadMinorHalo: r.
|
|
657
|
-
roadMajor: r.
|
|
658
|
-
roadMajorHalo: r.
|
|
659
|
-
ocean: r.
|
|
745
|
+
city: r.jade[1e3],
|
|
746
|
+
cityHalo: r.jade[25],
|
|
747
|
+
state: r.jade[700],
|
|
748
|
+
stateHalo: r.jade[25],
|
|
749
|
+
country: r.jade[700],
|
|
750
|
+
subplace: r.jade[700],
|
|
751
|
+
subplaceHalo: r.jade[25],
|
|
752
|
+
address: r.jade[700],
|
|
753
|
+
addressHalo: r.jade[25],
|
|
754
|
+
roadMinor: r.jade[700],
|
|
755
|
+
roadMinorHalo: r.jade[25],
|
|
756
|
+
roadMajor: r.jade[800],
|
|
757
|
+
roadMajorHalo: r.jade[25],
|
|
758
|
+
ocean: r.jade[800]
|
|
660
759
|
},
|
|
661
760
|
pois: {
|
|
662
|
-
blue:
|
|
663
|
-
green: r.
|
|
664
|
-
lapis:
|
|
665
|
-
pink:
|
|
666
|
-
red:
|
|
667
|
-
slategray: r.
|
|
668
|
-
tangerine:
|
|
669
|
-
turquoise: r.
|
|
761
|
+
blue: r.jade[700],
|
|
762
|
+
green: r.jade[700],
|
|
763
|
+
lapis: r.jade[700],
|
|
764
|
+
pink: r.jade[700],
|
|
765
|
+
red: r.jade[700],
|
|
766
|
+
slategray: r.jade[700],
|
|
767
|
+
tangerine: r.jade[700],
|
|
768
|
+
turquoise: r.jade[700]
|
|
670
769
|
},
|
|
671
770
|
landcover: {
|
|
672
|
-
grassland: r.
|
|
673
|
-
barren: r.
|
|
674
|
-
urban_area: r.
|
|
675
|
-
farmland: r.
|
|
676
|
-
glacier: r.
|
|
677
|
-
scrub: r.
|
|
678
|
-
forest: r.
|
|
771
|
+
grassland: r.jade[50],
|
|
772
|
+
barren: r.jade[50],
|
|
773
|
+
urban_area: r.jade[50],
|
|
774
|
+
farmland: r.jade[50],
|
|
775
|
+
glacier: r.jade[25],
|
|
776
|
+
scrub: r.jade[50],
|
|
777
|
+
forest: r.jade[100]
|
|
679
778
|
}
|
|
680
779
|
};
|
|
681
|
-
const
|
|
682
|
-
background: r.
|
|
683
|
-
earth: r.
|
|
684
|
-
water: r.
|
|
685
|
-
parkA: r.
|
|
686
|
-
parkB: r.
|
|
687
|
-
woodA: r.
|
|
688
|
-
woodB: r.
|
|
689
|
-
scrubA: r.
|
|
690
|
-
scrubB: r.
|
|
691
|
-
sand: r.
|
|
692
|
-
beach: r.
|
|
693
|
-
glacier: r.
|
|
694
|
-
institutional: r.
|
|
695
|
-
pedestrian: r.
|
|
696
|
-
aerodrome: r.
|
|
697
|
-
runway: r.
|
|
698
|
-
pier: r.
|
|
699
|
-
buildings: r.
|
|
700
|
-
railway: r.
|
|
701
|
-
boundaries: r.
|
|
780
|
+
const DECIMAL_DARK = {
|
|
781
|
+
background: r.jade[1e3],
|
|
782
|
+
earth: r.jade[1e3],
|
|
783
|
+
water: r.jade[900],
|
|
784
|
+
parkA: r.jade[950],
|
|
785
|
+
parkB: r.jade[900],
|
|
786
|
+
woodA: r.jade[950],
|
|
787
|
+
woodB: r.jade[900],
|
|
788
|
+
scrubA: r.jade[950],
|
|
789
|
+
scrubB: r.jade[900],
|
|
790
|
+
sand: r.jade[950],
|
|
791
|
+
beach: r.jade[950],
|
|
792
|
+
glacier: r.jade[900],
|
|
793
|
+
institutional: r.jade[950],
|
|
794
|
+
pedestrian: r.jade[950],
|
|
795
|
+
aerodrome: r.jade[950],
|
|
796
|
+
runway: r.jade[850],
|
|
797
|
+
pier: r.jade[850],
|
|
798
|
+
buildings: r.jade[900],
|
|
799
|
+
railway: r.jade[800],
|
|
800
|
+
boundaries: r.jade[700],
|
|
702
801
|
roads: {
|
|
703
|
-
other: r.
|
|
704
|
-
otherCasing: r.
|
|
705
|
-
minor: r.
|
|
706
|
-
minorCasing: r.
|
|
707
|
-
service: r.
|
|
708
|
-
serviceCasing: r.
|
|
709
|
-
major: r.
|
|
710
|
-
majorCasing: r.
|
|
711
|
-
highway: r.
|
|
712
|
-
highwayCasing: r.
|
|
713
|
-
link: r.
|
|
714
|
-
linkCasing: r.
|
|
802
|
+
other: r.jade[850],
|
|
803
|
+
otherCasing: r.jade[1e3],
|
|
804
|
+
minor: r.jade[800],
|
|
805
|
+
minorCasing: r.jade[1e3],
|
|
806
|
+
service: r.jade[850],
|
|
807
|
+
serviceCasing: r.jade[1e3],
|
|
808
|
+
major: r.jade[700],
|
|
809
|
+
majorCasing: r.jade[1e3],
|
|
810
|
+
highway: r.jade[600],
|
|
811
|
+
highwayCasing: r.jade[1e3],
|
|
812
|
+
link: r.jade[700],
|
|
813
|
+
linkCasing: r.jade[1e3]
|
|
715
814
|
},
|
|
716
|
-
tunnelFill: r.
|
|
717
|
-
tunnelCasing: r.
|
|
718
|
-
bridgeCasing: r.
|
|
815
|
+
tunnelFill: r.jade[900],
|
|
816
|
+
tunnelCasing: r.jade[1e3],
|
|
817
|
+
bridgeCasing: r.jade[1e3],
|
|
719
818
|
labels: {
|
|
720
|
-
city: r.
|
|
721
|
-
cityHalo: r.
|
|
722
|
-
state: r.
|
|
723
|
-
stateHalo: r.
|
|
724
|
-
country: r.
|
|
725
|
-
subplace: r.
|
|
726
|
-
subplaceHalo: r.
|
|
727
|
-
address: r.
|
|
728
|
-
addressHalo: r.
|
|
729
|
-
roadMinor: r.
|
|
730
|
-
roadMinorHalo: r.
|
|
731
|
-
roadMajor: r.
|
|
732
|
-
roadMajorHalo: r.
|
|
733
|
-
ocean: r.
|
|
819
|
+
city: r.jade[500],
|
|
820
|
+
cityHalo: r.jade[1e3],
|
|
821
|
+
state: r.jade[600],
|
|
822
|
+
stateHalo: r.jade[1e3],
|
|
823
|
+
country: r.jade[600],
|
|
824
|
+
subplace: r.jade[600],
|
|
825
|
+
subplaceHalo: r.jade[1e3],
|
|
826
|
+
address: r.jade[600],
|
|
827
|
+
addressHalo: r.jade[1e3],
|
|
828
|
+
roadMinor: r.jade[600],
|
|
829
|
+
roadMinorHalo: r.jade[1e3],
|
|
830
|
+
roadMajor: r.jade[500],
|
|
831
|
+
roadMajorHalo: r.jade[1e3],
|
|
832
|
+
ocean: r.jade[500]
|
|
734
833
|
},
|
|
735
834
|
pois: {
|
|
736
|
-
blue:
|
|
737
|
-
green: r.
|
|
738
|
-
lapis:
|
|
739
|
-
pink:
|
|
740
|
-
red:
|
|
741
|
-
slategray: r.
|
|
742
|
-
tangerine:
|
|
743
|
-
turquoise: r.
|
|
835
|
+
blue: r.jade[600],
|
|
836
|
+
green: r.jade[600],
|
|
837
|
+
lapis: r.jade[600],
|
|
838
|
+
pink: r.jade[600],
|
|
839
|
+
red: r.jade[600],
|
|
840
|
+
slategray: r.jade[600],
|
|
841
|
+
tangerine: r.jade[600],
|
|
842
|
+
turquoise: r.jade[600]
|
|
744
843
|
},
|
|
745
844
|
landcover: {
|
|
746
|
-
grassland: r.
|
|
747
|
-
barren: r.
|
|
748
|
-
urban_area: r.
|
|
749
|
-
farmland: r.
|
|
750
|
-
glacier: r.
|
|
751
|
-
scrub: r.
|
|
752
|
-
forest: r.
|
|
845
|
+
grassland: r.jade[950],
|
|
846
|
+
barren: r.jade[950],
|
|
847
|
+
urban_area: r.jade[950],
|
|
848
|
+
farmland: r.jade[950],
|
|
849
|
+
glacier: r.jade[900],
|
|
850
|
+
scrub: r.jade[950],
|
|
851
|
+
forest: r.jade[900]
|
|
753
852
|
}
|
|
754
853
|
};
|
|
755
|
-
const
|
|
756
|
-
background: r.
|
|
757
|
-
earth: r.
|
|
758
|
-
water: r.
|
|
759
|
-
parkA: r.
|
|
760
|
-
parkB: r.
|
|
761
|
-
woodA: r.
|
|
762
|
-
woodB: r.
|
|
763
|
-
scrubA: r.
|
|
764
|
-
scrubB: r.
|
|
765
|
-
sand: r.
|
|
766
|
-
beach: r.
|
|
767
|
-
glacier: r.
|
|
768
|
-
institutional: r.
|
|
769
|
-
pedestrian: r.
|
|
770
|
-
aerodrome: r.
|
|
771
|
-
runway: r.
|
|
772
|
-
pier: r.
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
boundaries: r.ink[600],
|
|
854
|
+
const BLUEPRINT_LIGHT = {
|
|
855
|
+
background: r.cobalt[100],
|
|
856
|
+
earth: r.cobalt[25],
|
|
857
|
+
water: r.cobalt[200],
|
|
858
|
+
parkA: r.cobalt[50],
|
|
859
|
+
parkB: r.cobalt[100],
|
|
860
|
+
woodA: r.cobalt[50],
|
|
861
|
+
woodB: r.cobalt[100],
|
|
862
|
+
scrubA: r.cobalt[50],
|
|
863
|
+
scrubB: r.cobalt[100],
|
|
864
|
+
sand: r.cobalt[50],
|
|
865
|
+
beach: r.cobalt[50],
|
|
866
|
+
glacier: r.cobalt[25],
|
|
867
|
+
institutional: r.cobalt[50],
|
|
868
|
+
pedestrian: r.cobalt[50],
|
|
869
|
+
aerodrome: r.cobalt[50],
|
|
870
|
+
runway: r.cobalt[200],
|
|
871
|
+
pier: r.cobalt[200],
|
|
872
|
+
buildings: r.cobalt[100],
|
|
873
|
+
railway: r.cobalt[500],
|
|
874
|
+
boundaries: r.cobalt[600],
|
|
777
875
|
roads: {
|
|
778
|
-
other: r.
|
|
779
|
-
otherCasing: r.
|
|
780
|
-
minor: r.
|
|
781
|
-
minorCasing: r.
|
|
782
|
-
service: r.
|
|
783
|
-
serviceCasing: r.
|
|
784
|
-
major:
|
|
785
|
-
majorCasing: r.
|
|
786
|
-
highway:
|
|
787
|
-
highwayCasing: r.
|
|
788
|
-
link:
|
|
789
|
-
linkCasing: r.
|
|
876
|
+
other: r.cobalt[200],
|
|
877
|
+
otherCasing: r.cobalt[25],
|
|
878
|
+
minor: r.cobalt[300],
|
|
879
|
+
minorCasing: r.cobalt[25],
|
|
880
|
+
service: r.cobalt[200],
|
|
881
|
+
serviceCasing: r.cobalt[25],
|
|
882
|
+
major: r.cobalt[400],
|
|
883
|
+
majorCasing: r.cobalt[25],
|
|
884
|
+
highway: r.cobalt[500],
|
|
885
|
+
highwayCasing: r.cobalt[25],
|
|
886
|
+
link: r.cobalt[400],
|
|
887
|
+
linkCasing: r.cobalt[25]
|
|
790
888
|
},
|
|
791
|
-
tunnelFill: r.
|
|
792
|
-
tunnelCasing: r.
|
|
793
|
-
bridgeCasing: r.
|
|
889
|
+
tunnelFill: r.cobalt[100],
|
|
890
|
+
tunnelCasing: r.cobalt[200],
|
|
891
|
+
bridgeCasing: r.cobalt[600],
|
|
794
892
|
labels: {
|
|
795
|
-
city: r.
|
|
796
|
-
cityHalo: r.
|
|
797
|
-
state: r.
|
|
798
|
-
stateHalo: r.
|
|
799
|
-
country: r.
|
|
800
|
-
subplace: r.
|
|
801
|
-
subplaceHalo: r.
|
|
802
|
-
address: r.
|
|
803
|
-
addressHalo: r.
|
|
804
|
-
roadMinor: r.
|
|
805
|
-
roadMinorHalo: r.
|
|
806
|
-
roadMajor: r.
|
|
807
|
-
roadMajorHalo: r.
|
|
808
|
-
ocean: r.
|
|
893
|
+
city: r.cobalt[1e3],
|
|
894
|
+
cityHalo: r.cobalt[25],
|
|
895
|
+
state: r.cobalt[700],
|
|
896
|
+
stateHalo: r.cobalt[25],
|
|
897
|
+
country: r.cobalt[700],
|
|
898
|
+
subplace: r.cobalt[700],
|
|
899
|
+
subplaceHalo: r.cobalt[25],
|
|
900
|
+
address: r.cobalt[700],
|
|
901
|
+
addressHalo: r.cobalt[25],
|
|
902
|
+
roadMinor: r.cobalt[700],
|
|
903
|
+
roadMinorHalo: r.cobalt[25],
|
|
904
|
+
roadMajor: r.cobalt[800],
|
|
905
|
+
roadMajorHalo: r.cobalt[25],
|
|
906
|
+
ocean: r.cobalt[800]
|
|
809
907
|
},
|
|
810
908
|
pois: {
|
|
811
|
-
blue:
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
tangerine: "#8F5322",
|
|
820
|
-
turquoise: r.wave[700]
|
|
909
|
+
blue: r.cobalt[700],
|
|
910
|
+
green: r.cobalt[700],
|
|
911
|
+
lapis: r.cobalt[700],
|
|
912
|
+
pink: r.cobalt[700],
|
|
913
|
+
red: r.cobalt[700],
|
|
914
|
+
slategray: r.cobalt[700],
|
|
915
|
+
tangerine: r.cobalt[700],
|
|
916
|
+
turquoise: r.cobalt[700]
|
|
821
917
|
},
|
|
822
918
|
landcover: {
|
|
823
|
-
grassland: r.
|
|
824
|
-
barren: r.
|
|
825
|
-
urban_area: r.
|
|
826
|
-
farmland: r.
|
|
827
|
-
glacier: r.
|
|
828
|
-
scrub: r.
|
|
829
|
-
forest: r.
|
|
919
|
+
grassland: r.cobalt[50],
|
|
920
|
+
barren: r.cobalt[50],
|
|
921
|
+
urban_area: r.cobalt[50],
|
|
922
|
+
farmland: r.cobalt[50],
|
|
923
|
+
glacier: r.cobalt[25],
|
|
924
|
+
scrub: r.cobalt[50],
|
|
925
|
+
forest: r.cobalt[100]
|
|
830
926
|
}
|
|
831
927
|
};
|
|
832
|
-
const
|
|
833
|
-
background: r.
|
|
834
|
-
earth: r.
|
|
835
|
-
water: r.
|
|
836
|
-
parkA: r.
|
|
837
|
-
parkB: r.
|
|
838
|
-
woodA: r.
|
|
839
|
-
woodB: r.
|
|
840
|
-
scrubA: r.
|
|
841
|
-
scrubB: r.
|
|
842
|
-
sand: r.
|
|
843
|
-
beach: r.
|
|
844
|
-
glacier: r.
|
|
845
|
-
institutional: r.
|
|
846
|
-
pedestrian: r.
|
|
847
|
-
aerodrome: r.
|
|
848
|
-
runway: r.
|
|
849
|
-
pier: r.
|
|
850
|
-
buildings: r.
|
|
851
|
-
railway: r.
|
|
852
|
-
boundaries: r.
|
|
928
|
+
const BLUEPRINT_DARK = {
|
|
929
|
+
background: r.cobalt[700],
|
|
930
|
+
earth: r.cobalt[700],
|
|
931
|
+
water: r.cobalt[400],
|
|
932
|
+
parkA: r.cobalt[600],
|
|
933
|
+
parkB: r.cobalt[600],
|
|
934
|
+
woodA: r.cobalt[600],
|
|
935
|
+
woodB: r.cobalt[600],
|
|
936
|
+
scrubA: r.cobalt[600],
|
|
937
|
+
scrubB: r.cobalt[600],
|
|
938
|
+
sand: r.cobalt[600],
|
|
939
|
+
beach: r.cobalt[600],
|
|
940
|
+
glacier: r.cobalt[500],
|
|
941
|
+
institutional: r.cobalt[600],
|
|
942
|
+
pedestrian: r.cobalt[700],
|
|
943
|
+
aerodrome: r.cobalt[600],
|
|
944
|
+
runway: r.cobalt[800],
|
|
945
|
+
pier: r.cobalt[800],
|
|
946
|
+
buildings: r.cobalt[600],
|
|
947
|
+
railway: r.cobalt[400],
|
|
948
|
+
boundaries: r.cobalt[300],
|
|
853
949
|
roads: {
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
link: r.ink[700],
|
|
867
|
-
linkCasing: r.ink[1e3]
|
|
950
|
+
other: r.cobalt[800],
|
|
951
|
+
otherCasing: r.cobalt[700],
|
|
952
|
+
minor: r.cobalt[850],
|
|
953
|
+
minorCasing: r.cobalt[600],
|
|
954
|
+
service: r.cobalt[800],
|
|
955
|
+
serviceCasing: r.cobalt[700],
|
|
956
|
+
major: r.cobalt[900],
|
|
957
|
+
majorCasing: r.cobalt[600],
|
|
958
|
+
highway: r.cobalt[950],
|
|
959
|
+
highwayCasing: r.cobalt[500],
|
|
960
|
+
link: r.cobalt[900],
|
|
961
|
+
linkCasing: r.cobalt[600]
|
|
868
962
|
},
|
|
869
|
-
tunnelFill: r.
|
|
870
|
-
tunnelCasing: r.
|
|
871
|
-
bridgeCasing: r.
|
|
963
|
+
tunnelFill: r.cobalt[800],
|
|
964
|
+
tunnelCasing: r.cobalt[700],
|
|
965
|
+
bridgeCasing: r.cobalt[500],
|
|
872
966
|
labels: {
|
|
873
|
-
city: r.
|
|
874
|
-
cityHalo: r.
|
|
875
|
-
state: r.
|
|
876
|
-
stateHalo: r.
|
|
877
|
-
country: r.
|
|
878
|
-
subplace: r.
|
|
879
|
-
subplaceHalo: r.
|
|
880
|
-
address: r.
|
|
881
|
-
addressHalo: r.
|
|
882
|
-
roadMinor: r.
|
|
883
|
-
roadMinorHalo: r.
|
|
884
|
-
roadMajor: r.
|
|
885
|
-
roadMajorHalo: r.
|
|
886
|
-
ocean: r.
|
|
967
|
+
city: r.cobalt[25],
|
|
968
|
+
cityHalo: r.cobalt[700],
|
|
969
|
+
state: r.cobalt[200],
|
|
970
|
+
stateHalo: r.cobalt[700],
|
|
971
|
+
country: r.cobalt[200],
|
|
972
|
+
subplace: r.cobalt[300],
|
|
973
|
+
subplaceHalo: r.cobalt[700],
|
|
974
|
+
address: r.cobalt[300],
|
|
975
|
+
addressHalo: r.cobalt[700],
|
|
976
|
+
roadMinor: r.cobalt[300],
|
|
977
|
+
roadMinorHalo: r.cobalt[700],
|
|
978
|
+
roadMajor: r.cobalt[100],
|
|
979
|
+
roadMajorHalo: r.cobalt[700],
|
|
980
|
+
ocean: r.cobalt[900]
|
|
887
981
|
},
|
|
888
982
|
pois: {
|
|
889
|
-
blue:
|
|
890
|
-
green: r.
|
|
891
|
-
lapis:
|
|
892
|
-
pink:
|
|
893
|
-
red:
|
|
894
|
-
slategray: r.
|
|
895
|
-
tangerine:
|
|
896
|
-
turquoise: r.
|
|
983
|
+
blue: r.cobalt[200],
|
|
984
|
+
green: r.cobalt[200],
|
|
985
|
+
lapis: r.cobalt[200],
|
|
986
|
+
pink: r.cobalt[200],
|
|
987
|
+
red: r.cobalt[200],
|
|
988
|
+
slategray: r.cobalt[200],
|
|
989
|
+
tangerine: r.cobalt[200],
|
|
990
|
+
turquoise: r.cobalt[200]
|
|
897
991
|
},
|
|
898
992
|
landcover: {
|
|
899
|
-
grassland: r.
|
|
900
|
-
barren: r.
|
|
901
|
-
urban_area: r.
|
|
902
|
-
farmland: r.
|
|
903
|
-
glacier: r.
|
|
904
|
-
scrub: r.
|
|
905
|
-
forest: r.
|
|
993
|
+
grassland: r.cobalt[600],
|
|
994
|
+
barren: r.cobalt[600],
|
|
995
|
+
urban_area: r.cobalt[700],
|
|
996
|
+
farmland: r.cobalt[600],
|
|
997
|
+
glacier: r.cobalt[500],
|
|
998
|
+
scrub: r.cobalt[600],
|
|
999
|
+
forest: r.cobalt[600]
|
|
906
1000
|
}
|
|
907
1001
|
};
|
|
908
1002
|
return {
|
|
909
1003
|
base: { light: BASE_LIGHT, dark: BASE_DARK },
|
|
910
1004
|
muted: { light: MUTED_LIGHT, dark: MUTED_DARK },
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
1005
|
+
outdoor: { light: OUTDOOR_LIGHT, dark: OUTDOOR_DARK },
|
|
1006
|
+
decimal: { light: DECIMAL_LIGHT, dark: DECIMAL_DARK },
|
|
1007
|
+
blueprint: { light: BLUEPRINT_LIGHT, dark: BLUEPRINT_DARK }
|
|
914
1008
|
};
|
|
915
1009
|
}
|
|
916
1010
|
var RECIPES = buildRecipes(STOCK_RAMPS);
|
|
@@ -990,7 +1084,8 @@ function validateTheme(input) {
|
|
|
990
1084
|
if (!DOC_KEYS.includes(key)) errors.push(`${key}: unknown field`);
|
|
991
1085
|
}
|
|
992
1086
|
if (input.v !== 1) errors.push("v: must be 1");
|
|
993
|
-
|
|
1087
|
+
const base = typeof input.base === "string" ? normalizeThemeBase(input.base) : null;
|
|
1088
|
+
if (!base) {
|
|
994
1089
|
errors.push(`base: must be one of ${THEME_BASES.join(", ")}`);
|
|
995
1090
|
}
|
|
996
1091
|
if (input.name !== void 0) {
|
|
@@ -1028,85 +1123,73 @@ function validateTheme(input) {
|
|
|
1028
1123
|
}
|
|
1029
1124
|
}
|
|
1030
1125
|
if (errors.length > 0) throw new ThemeError("invalid theme", errors);
|
|
1126
|
+
if (base && base !== input.base) return { ...input, base };
|
|
1031
1127
|
return input;
|
|
1032
1128
|
}
|
|
1033
1129
|
|
|
1034
|
-
// src/
|
|
1035
|
-
var
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
let size = 0;
|
|
1042
|
-
for (; ; ) {
|
|
1043
|
-
const { done, value } = await reader.read();
|
|
1044
|
-
if (done) break;
|
|
1045
|
-
size += value.byteLength;
|
|
1046
|
-
if (size > cap) {
|
|
1047
|
-
await reader.cancel().catch(() => {
|
|
1048
|
-
});
|
|
1049
|
-
throw new ThemeError("invalid theme", ["theme document too large"]);
|
|
1050
|
-
}
|
|
1051
|
-
chunks.push(value);
|
|
1052
|
-
}
|
|
1053
|
-
const out = new Uint8Array(size);
|
|
1054
|
-
let off = 0;
|
|
1055
|
-
for (const c of chunks) {
|
|
1056
|
-
out.set(c, off);
|
|
1057
|
-
off += c.byteLength;
|
|
1058
|
-
}
|
|
1059
|
-
return out;
|
|
1060
|
-
}
|
|
1061
|
-
var toB64url = (b) => {
|
|
1062
|
-
let bin = "";
|
|
1063
|
-
for (let i = 0; i < b.length; i += 32768) {
|
|
1064
|
-
bin += String.fromCharCode(...b.subarray(i, i + 32768));
|
|
1065
|
-
}
|
|
1066
|
-
return btoa(bin).replaceAll("+", "-").replaceAll("/", "_").replace(/=+$/, "");
|
|
1067
|
-
};
|
|
1068
|
-
var fromB64url = (s) => {
|
|
1069
|
-
const bin = atob(s.replaceAll("-", "+").replaceAll("_", "/"));
|
|
1070
|
-
return Uint8Array.from(bin, (c) => c.charCodeAt(0));
|
|
1130
|
+
// src/presets.ts
|
|
1131
|
+
var STYLE_THEMES = {
|
|
1132
|
+
base: { v: 1, name: "base", base: "base" },
|
|
1133
|
+
muted: { v: 1, name: "muted", base: "muted" },
|
|
1134
|
+
outdoor: { v: 1, name: "outdoor", base: "outdoor" },
|
|
1135
|
+
decimal: { v: 1, name: "decimal", base: "decimal" },
|
|
1136
|
+
blueprint: { v: 1, name: "blueprint", base: "blueprint" }
|
|
1071
1137
|
};
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1138
|
+
|
|
1139
|
+
// src/oklch.ts
|
|
1140
|
+
var srgbToLinear = (v) => v <= 0.04045 ? v / 12.92 : ((v + 0.055) / 1.055) ** 2.4;
|
|
1141
|
+
var linearToSrgb = (v) => v <= 31308e-7 ? 12.92 * v : 1.055 * v ** (1 / 2.4) - 0.055;
|
|
1142
|
+
function hexToRgb(hex) {
|
|
1143
|
+
const h = hex.replace("#", "");
|
|
1144
|
+
return [
|
|
1145
|
+
parseInt(h.slice(0, 2), 16) / 255,
|
|
1146
|
+
parseInt(h.slice(2, 4), 16) / 255,
|
|
1147
|
+
parseInt(h.slice(4, 6), 16) / 255
|
|
1148
|
+
];
|
|
1075
1149
|
}
|
|
1076
|
-
|
|
1077
|
-
const
|
|
1078
|
-
const
|
|
1079
|
-
const
|
|
1080
|
-
const
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1150
|
+
function hexToOklch(hex) {
|
|
1151
|
+
const [r, g, b] = hexToRgb(hex).map(srgbToLinear);
|
|
1152
|
+
const l = Math.cbrt(0.4122214708 * r + 0.5363325363 * g + 0.0514459929 * b);
|
|
1153
|
+
const m = Math.cbrt(0.2119034982 * r + 0.6806995451 * g + 0.1073969566 * b);
|
|
1154
|
+
const s = Math.cbrt(0.0883024619 * r + 0.2817188376 * g + 0.6299787005 * b);
|
|
1155
|
+
const L = 0.2104542553 * l + 0.793617785 * m - 0.0040720468 * s;
|
|
1156
|
+
const a = 1.9779984951 * l - 2.428592205 * m + 0.4505937099 * s;
|
|
1157
|
+
const bb = 0.0259040371 * l + 0.7827717662 * m - 0.808675766 * s;
|
|
1158
|
+
const c = Math.hypot(a, bb);
|
|
1159
|
+
let h = Math.atan2(bb, a) * 180 / Math.PI;
|
|
1160
|
+
if (h < 0) h += 360;
|
|
1161
|
+
return { l: L, c, h };
|
|
1087
1162
|
}
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
let
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1163
|
+
function oklchToLinear({ l: L, c, h }) {
|
|
1164
|
+
const hr = h * Math.PI / 180;
|
|
1165
|
+
const a = c * Math.cos(hr);
|
|
1166
|
+
const bb = c * Math.sin(hr);
|
|
1167
|
+
const l = (L + 0.3963377774 * a + 0.2158037573 * bb) ** 3;
|
|
1168
|
+
const m = (L - 0.1055613458 * a - 0.0638541728 * bb) ** 3;
|
|
1169
|
+
const s = (L - 0.0894841775 * a - 1.291485548 * bb) ** 3;
|
|
1170
|
+
return [
|
|
1171
|
+
4.0767416621 * l - 3.3077115913 * m + 0.2309699292 * s,
|
|
1172
|
+
-1.2684380046 * l + 2.6097574011 * m - 0.3413193965 * s,
|
|
1173
|
+
-0.0041960863 * l - 0.7034186147 * m + 1.707614701 * s
|
|
1174
|
+
];
|
|
1175
|
+
}
|
|
1176
|
+
var inGamut = (rgb) => rgb.every((v) => v >= -1e-6 && v <= 1 + 1e-6);
|
|
1177
|
+
function oklchToHex(color) {
|
|
1178
|
+
let { c } = color;
|
|
1179
|
+
let rgb = oklchToLinear({ ...color, c });
|
|
1180
|
+
if (!inGamut(rgb)) {
|
|
1181
|
+
let lo = 0;
|
|
1182
|
+
let hi = c;
|
|
1183
|
+
for (let i = 0; i < 24; i++) {
|
|
1184
|
+
c = (lo + hi) / 2;
|
|
1185
|
+
rgb = oklchToLinear({ ...color, c });
|
|
1186
|
+
if (inGamut(rgb)) lo = c;
|
|
1187
|
+
else hi = c;
|
|
1188
|
+
}
|
|
1189
|
+
rgb = oklchToLinear({ ...color, c: lo });
|
|
1108
1190
|
}
|
|
1109
|
-
|
|
1191
|
+
const to255 = (v) => Math.round(Math.min(1, Math.max(0, linearToSrgb(v))) * 255);
|
|
1192
|
+
return "#" + rgb.map((v) => to255(v).toString(16).padStart(2, "0")).join("").toUpperCase();
|
|
1110
1193
|
}
|
|
1111
1194
|
|
|
1112
1195
|
// src/compose.ts
|
|
@@ -1206,75 +1289,11 @@ function contrastWarnings(doc) {
|
|
|
1206
1289
|
return warnings;
|
|
1207
1290
|
}
|
|
1208
1291
|
|
|
1209
|
-
// src/presets.ts
|
|
1210
|
-
var PRESET_THEMES = {
|
|
1211
|
-
base: { v: 1, name: "ink", base: "base" },
|
|
1212
|
-
muted: { v: 1, name: "graphite", base: "muted" },
|
|
1213
|
-
relief: { v: 1, name: "relief", base: "relief" },
|
|
1214
|
-
street: { v: 1, name: "street", base: "street" },
|
|
1215
|
-
outdoor: { v: 1, name: "outdoor", base: "outdoor" }
|
|
1216
|
-
};
|
|
1217
|
-
|
|
1218
|
-
// src/oklch.ts
|
|
1219
|
-
var srgbToLinear = (v) => v <= 0.04045 ? v / 12.92 : ((v + 0.055) / 1.055) ** 2.4;
|
|
1220
|
-
var linearToSrgb = (v) => v <= 31308e-7 ? 12.92 * v : 1.055 * v ** (1 / 2.4) - 0.055;
|
|
1221
|
-
function hexToRgb(hex) {
|
|
1222
|
-
const h = hex.replace("#", "");
|
|
1223
|
-
return [
|
|
1224
|
-
parseInt(h.slice(0, 2), 16) / 255,
|
|
1225
|
-
parseInt(h.slice(2, 4), 16) / 255,
|
|
1226
|
-
parseInt(h.slice(4, 6), 16) / 255
|
|
1227
|
-
];
|
|
1228
|
-
}
|
|
1229
|
-
function hexToOklch(hex) {
|
|
1230
|
-
const [r, g, b] = hexToRgb(hex).map(srgbToLinear);
|
|
1231
|
-
const l = Math.cbrt(0.4122214708 * r + 0.5363325363 * g + 0.0514459929 * b);
|
|
1232
|
-
const m = Math.cbrt(0.2119034982 * r + 0.6806995451 * g + 0.1073969566 * b);
|
|
1233
|
-
const s = Math.cbrt(0.0883024619 * r + 0.2817188376 * g + 0.6299787005 * b);
|
|
1234
|
-
const L = 0.2104542553 * l + 0.793617785 * m - 0.0040720468 * s;
|
|
1235
|
-
const a = 1.9779984951 * l - 2.428592205 * m + 0.4505937099 * s;
|
|
1236
|
-
const bb = 0.0259040371 * l + 0.7827717662 * m - 0.808675766 * s;
|
|
1237
|
-
const c = Math.hypot(a, bb);
|
|
1238
|
-
let h = Math.atan2(bb, a) * 180 / Math.PI;
|
|
1239
|
-
if (h < 0) h += 360;
|
|
1240
|
-
return { l: L, c, h };
|
|
1241
|
-
}
|
|
1242
|
-
function oklchToLinear({ l: L, c, h }) {
|
|
1243
|
-
const hr = h * Math.PI / 180;
|
|
1244
|
-
const a = c * Math.cos(hr);
|
|
1245
|
-
const bb = c * Math.sin(hr);
|
|
1246
|
-
const l = (L + 0.3963377774 * a + 0.2158037573 * bb) ** 3;
|
|
1247
|
-
const m = (L - 0.1055613458 * a - 0.0638541728 * bb) ** 3;
|
|
1248
|
-
const s = (L - 0.0894841775 * a - 1.291485548 * bb) ** 3;
|
|
1249
|
-
return [
|
|
1250
|
-
4.0767416621 * l - 3.3077115913 * m + 0.2309699292 * s,
|
|
1251
|
-
-1.2684380046 * l + 2.6097574011 * m - 0.3413193965 * s,
|
|
1252
|
-
-0.0041960863 * l - 0.7034186147 * m + 1.707614701 * s
|
|
1253
|
-
];
|
|
1254
|
-
}
|
|
1255
|
-
var inGamut = (rgb) => rgb.every((v) => v >= -1e-6 && v <= 1 + 1e-6);
|
|
1256
|
-
function oklchToHex(color) {
|
|
1257
|
-
let { c } = color;
|
|
1258
|
-
let rgb = oklchToLinear({ ...color, c });
|
|
1259
|
-
if (!inGamut(rgb)) {
|
|
1260
|
-
let lo = 0;
|
|
1261
|
-
let hi = c;
|
|
1262
|
-
for (let i = 0; i < 24; i++) {
|
|
1263
|
-
c = (lo + hi) / 2;
|
|
1264
|
-
rgb = oklchToLinear({ ...color, c });
|
|
1265
|
-
if (inGamut(rgb)) lo = c;
|
|
1266
|
-
else hi = c;
|
|
1267
|
-
}
|
|
1268
|
-
rgb = oklchToLinear({ ...color, c: lo });
|
|
1269
|
-
}
|
|
1270
|
-
const to255 = (v) => Math.round(Math.min(1, Math.max(0, linearToSrgb(v))) * 255);
|
|
1271
|
-
return "#" + rgb.map((v) => to255(v).toString(16).padStart(2, "0")).join("").toUpperCase();
|
|
1272
|
-
}
|
|
1273
|
-
|
|
1274
1292
|
// src/generate.ts
|
|
1275
1293
|
var NEUTRAL_CHROMA_CAP = 0.045;
|
|
1276
1294
|
var MUTED_CHROMA_CAP = 0.012;
|
|
1277
1295
|
var CHROMA_CAP = 0.32;
|
|
1296
|
+
var NEUTRAL_RAMP_CHROMA = 5e-3;
|
|
1278
1297
|
var DEFAULT_SEEDS = {
|
|
1279
1298
|
land: STOCK_RAMPS.ink[500],
|
|
1280
1299
|
water: STOCK_RAMPS.wave[500],
|
|
@@ -1285,14 +1304,15 @@ function reRamp(ref, seedHex, cap) {
|
|
|
1285
1304
|
const seed = hexToOklch(seedHex);
|
|
1286
1305
|
const steps = Object.keys(ref);
|
|
1287
1306
|
const midStep = steps[Math.floor(steps.length / 2)];
|
|
1288
|
-
const midChroma =
|
|
1289
|
-
const
|
|
1307
|
+
const midChroma = hexToOklch(ref[midStep]).c;
|
|
1308
|
+
const neutral = midChroma < NEUTRAL_RAMP_CHROMA;
|
|
1309
|
+
const factor = Math.min(Math.max(seed.c / Math.max(midChroma, 5e-3), 0.15), 3);
|
|
1290
1310
|
const out = {};
|
|
1291
1311
|
for (const step of steps) {
|
|
1292
1312
|
const refColor = hexToOklch(ref[step]);
|
|
1293
1313
|
out[step] = oklchToHex({
|
|
1294
1314
|
l: refColor.l,
|
|
1295
|
-
c: Math.min(refColor.c * factor, cap),
|
|
1315
|
+
c: Math.min(neutral ? seed.c : refColor.c * factor, cap),
|
|
1296
1316
|
h: seed.h
|
|
1297
1317
|
});
|
|
1298
1318
|
}
|
|
@@ -1308,7 +1328,10 @@ function enforceLabelContrast(recipe) {
|
|
|
1308
1328
|
if (contrast(label, bg) >= floor) break;
|
|
1309
1329
|
const l = hexToOklch(label);
|
|
1310
1330
|
const direction = hexToOklch(bg).l > l.l ? -1 : 1;
|
|
1311
|
-
const nudged = oklchToHex({
|
|
1331
|
+
const nudged = oklchToHex({
|
|
1332
|
+
...l,
|
|
1333
|
+
l: Math.min(1, Math.max(0, l.l + direction * 0.015))
|
|
1334
|
+
});
|
|
1312
1335
|
setLabelSlot(fixed, labelSlot, nudged);
|
|
1313
1336
|
}
|
|
1314
1337
|
}
|
|
@@ -1354,8 +1377,13 @@ function generateTheme(base, seeds) {
|
|
|
1354
1377
|
const ramps = {
|
|
1355
1378
|
...STOCK_RAMPS,
|
|
1356
1379
|
ink: reRamp(STOCK_RAMPS.ink, seeds.land, NEUTRAL_CHROMA_CAP),
|
|
1380
|
+
paper: reRamp(STOCK_RAMPS.paper, seeds.land, NEUTRAL_CHROMA_CAP),
|
|
1357
1381
|
graphite: reRamp(STOCK_RAMPS.graphite, seeds.land, MUTED_CHROMA_CAP),
|
|
1382
|
+
jade: reRamp(STOCK_RAMPS.jade, seeds.land, CHROMA_CAP),
|
|
1383
|
+
cobalt: reRamp(STOCK_RAMPS.cobalt, seeds.land, CHROMA_CAP),
|
|
1358
1384
|
wave: reRamp(STOCK_RAMPS.wave, seeds.water, CHROMA_CAP),
|
|
1385
|
+
sky: reRamp(STOCK_RAMPS.sky, seeds.water, CHROMA_CAP),
|
|
1386
|
+
mist: reRamp(STOCK_RAMPS.mist, seeds.water, CHROMA_CAP),
|
|
1359
1387
|
verdant: reRamp(STOCK_RAMPS.verdant, seeds.nature, CHROMA_CAP)
|
|
1360
1388
|
};
|
|
1361
1389
|
const generated = buildRecipes(ramps);
|
|
@@ -1375,7 +1403,7 @@ function generateTheme(base, seeds) {
|
|
|
1375
1403
|
}
|
|
1376
1404
|
|
|
1377
1405
|
// src/palettes.ts
|
|
1378
|
-
var
|
|
1406
|
+
var THEME_PRESETS = [
|
|
1379
1407
|
{ name: "process ink", seeds: DEFAULT_SEEDS },
|
|
1380
1408
|
{
|
|
1381
1409
|
name: "boreal",
|
|
@@ -1416,6 +1444,274 @@ function shuffleSeeds(rng = Math.random) {
|
|
|
1416
1444
|
accent: oklchToHex({ l: 0.65, c: 0.22 + rng() * 0.08, h: wrap(h + 170 + rng() * 40) })
|
|
1417
1445
|
};
|
|
1418
1446
|
}
|
|
1447
|
+
|
|
1448
|
+
// src/preset.ts
|
|
1449
|
+
var PRESET_CODE_PREFIX = "u";
|
|
1450
|
+
var PRESET_CODE_RE = /^u[0-9A-Za-z]{2,24}$/;
|
|
1451
|
+
var BASE62 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
|
1452
|
+
var SEED_KEYS = ["land", "water", "nature", "accent"];
|
|
1453
|
+
var STYLE_ENCODE = {
|
|
1454
|
+
base: 0,
|
|
1455
|
+
muted: 1,
|
|
1456
|
+
outdoor: 4,
|
|
1457
|
+
decimal: 5,
|
|
1458
|
+
blueprint: 6
|
|
1459
|
+
};
|
|
1460
|
+
var STYLE_DECODE = [
|
|
1461
|
+
"base",
|
|
1462
|
+
"muted",
|
|
1463
|
+
"outdoor",
|
|
1464
|
+
"base",
|
|
1465
|
+
"outdoor",
|
|
1466
|
+
"decimal",
|
|
1467
|
+
"blueprint",
|
|
1468
|
+
void 0
|
|
1469
|
+
];
|
|
1470
|
+
var PRESET_OFFSET = 8n;
|
|
1471
|
+
var ORIGINAL_SLOTS = 5n;
|
|
1472
|
+
var ORIGINAL_PRESET_LIMIT = 64n;
|
|
1473
|
+
var LATER_PRESET_OFFSET = PRESET_OFFSET + ORIGINAL_PRESET_LIMIT * ORIGINAL_SLOTS;
|
|
1474
|
+
var LATER_SLOT_BASE = 5;
|
|
1475
|
+
var LATER_SLOTS = 3n;
|
|
1476
|
+
var CUSTOM_OFFSET = 1024n;
|
|
1477
|
+
var LATER_PRESET_LIMIT = (CUSTOM_OFFSET - LATER_PRESET_OFFSET) / LATER_SLOTS;
|
|
1478
|
+
var sameHex = (a, b) => a.toLowerCase() === b.toLowerCase();
|
|
1479
|
+
function isThemePresetCode(code) {
|
|
1480
|
+
return PRESET_CODE_RE.test(code);
|
|
1481
|
+
}
|
|
1482
|
+
function presetId(name) {
|
|
1483
|
+
return name.replace(/\s+([a-zA-Z])/g, (_, c) => c.toUpperCase()).replace(/\s/g, "");
|
|
1484
|
+
}
|
|
1485
|
+
function toBase62(n, min = 2) {
|
|
1486
|
+
if (n === 0n) return "0".repeat(min);
|
|
1487
|
+
let s = "";
|
|
1488
|
+
let x = n;
|
|
1489
|
+
while (x > 0n) {
|
|
1490
|
+
s = BASE62[Number(x % 62n)] + s;
|
|
1491
|
+
x /= 62n;
|
|
1492
|
+
}
|
|
1493
|
+
return s.padStart(min, "0");
|
|
1494
|
+
}
|
|
1495
|
+
function fromBase62(s) {
|
|
1496
|
+
let n = 0n;
|
|
1497
|
+
for (const ch of s) {
|
|
1498
|
+
const i = BASE62.indexOf(ch);
|
|
1499
|
+
if (i < 0) {
|
|
1500
|
+
throw new ThemeError("invalid theme", ["code is not a valid preset"]);
|
|
1501
|
+
}
|
|
1502
|
+
n = n * 62n + BigInt(i);
|
|
1503
|
+
}
|
|
1504
|
+
return n;
|
|
1505
|
+
}
|
|
1506
|
+
function rgb24(hex) {
|
|
1507
|
+
return BigInt(parseInt(hex.replace("#", "").slice(0, 6), 16));
|
|
1508
|
+
}
|
|
1509
|
+
function fromRgb24(n) {
|
|
1510
|
+
return `#${n.toString(16).toUpperCase().padStart(6, "0")}`;
|
|
1511
|
+
}
|
|
1512
|
+
function isBareStyle(doc) {
|
|
1513
|
+
return doc.seeds === void 0 && doc.light === void 0 && doc.dark === void 0;
|
|
1514
|
+
}
|
|
1515
|
+
function deepEqual(a, b) {
|
|
1516
|
+
if (a === b) return true;
|
|
1517
|
+
if (typeof a !== typeof b) return false;
|
|
1518
|
+
if (a && b && typeof a === "object") {
|
|
1519
|
+
const ak = Object.keys(a).sort();
|
|
1520
|
+
const bk = Object.keys(b).sort();
|
|
1521
|
+
return ak.length === bk.length && ak.every((k, i) => k === bk[i] && deepEqual(a[k], b[k]));
|
|
1522
|
+
}
|
|
1523
|
+
return false;
|
|
1524
|
+
}
|
|
1525
|
+
function seedsMatch(a, b) {
|
|
1526
|
+
return SEED_KEYS.every((k) => {
|
|
1527
|
+
const left = a[k];
|
|
1528
|
+
const right = b[k];
|
|
1529
|
+
if (left === void 0 && right === void 0) return true;
|
|
1530
|
+
if (typeof left !== "string" || typeof right !== "string") return left === right;
|
|
1531
|
+
return sameHex(left, right);
|
|
1532
|
+
});
|
|
1533
|
+
}
|
|
1534
|
+
function generatedMatch(doc) {
|
|
1535
|
+
if (!doc.seeds) return false;
|
|
1536
|
+
const generated = generateTheme(doc.base, doc.seeds);
|
|
1537
|
+
return generated.base === doc.base && seedsMatch(generated.seeds, doc.seeds) && deepEqual(generated.light, doc.light) && deepEqual(generated.dark, doc.dark);
|
|
1538
|
+
}
|
|
1539
|
+
function findPresetIndex(seeds) {
|
|
1540
|
+
return THEME_PRESETS.findIndex((p) => seedsMatch(p.seeds, { ...DEFAULT_SEEDS, ...seeds }));
|
|
1541
|
+
}
|
|
1542
|
+
function encodeBits(bits) {
|
|
1543
|
+
return PRESET_CODE_PREFIX + toBase62(bits);
|
|
1544
|
+
}
|
|
1545
|
+
function encodePreset(doc) {
|
|
1546
|
+
const slot = STYLE_ENCODE[doc.base];
|
|
1547
|
+
if (slot === void 0) return null;
|
|
1548
|
+
if (isBareStyle(doc)) {
|
|
1549
|
+
return encodeBits(BigInt(slot));
|
|
1550
|
+
}
|
|
1551
|
+
if (!doc.seeds || !generatedMatch(doc)) return null;
|
|
1552
|
+
const presetIndex = findPresetIndex(doc.seeds);
|
|
1553
|
+
if (presetIndex >= 0) {
|
|
1554
|
+
const p = BigInt(presetIndex);
|
|
1555
|
+
if (slot < LATER_SLOT_BASE) {
|
|
1556
|
+
if (p < ORIGINAL_PRESET_LIMIT) {
|
|
1557
|
+
return encodeBits(PRESET_OFFSET + p * ORIGINAL_SLOTS + BigInt(slot));
|
|
1558
|
+
}
|
|
1559
|
+
} else if (p < LATER_PRESET_LIMIT) {
|
|
1560
|
+
return encodeBits(LATER_PRESET_OFFSET + p * LATER_SLOTS + BigInt(slot - LATER_SLOT_BASE));
|
|
1561
|
+
}
|
|
1562
|
+
}
|
|
1563
|
+
if (!doc.seeds.accent) return null;
|
|
1564
|
+
const filled = { ...DEFAULT_SEEDS, ...doc.seeds };
|
|
1565
|
+
let bits = CUSTOM_OFFSET + BigInt(slot);
|
|
1566
|
+
let shift = 3n;
|
|
1567
|
+
for (const key of SEED_KEYS) {
|
|
1568
|
+
bits += rgb24(filled[key]) << shift;
|
|
1569
|
+
shift += 24n;
|
|
1570
|
+
}
|
|
1571
|
+
return encodeBits(bits);
|
|
1572
|
+
}
|
|
1573
|
+
function decodePreset(code) {
|
|
1574
|
+
if (!isThemePresetCode(code)) {
|
|
1575
|
+
throw new ThemeError("invalid theme", ["code is not a valid preset"]);
|
|
1576
|
+
}
|
|
1577
|
+
const bits = fromBase62(code.slice(PRESET_CODE_PREFIX.length));
|
|
1578
|
+
if (bits < PRESET_OFFSET) {
|
|
1579
|
+
const base2 = STYLE_DECODE[Number(bits)];
|
|
1580
|
+
if (!base2) {
|
|
1581
|
+
throw new ThemeError("invalid theme", ["preset style slot is out of range"]);
|
|
1582
|
+
}
|
|
1583
|
+
return structuredClone(STYLE_THEMES[base2]);
|
|
1584
|
+
}
|
|
1585
|
+
if (bits < CUSTOM_OFFSET) {
|
|
1586
|
+
let slot;
|
|
1587
|
+
let presetIndex;
|
|
1588
|
+
if (bits < LATER_PRESET_OFFSET) {
|
|
1589
|
+
const n = bits - PRESET_OFFSET;
|
|
1590
|
+
slot = Number(n % ORIGINAL_SLOTS);
|
|
1591
|
+
presetIndex = Number(n / ORIGINAL_SLOTS);
|
|
1592
|
+
} else {
|
|
1593
|
+
const n = bits - LATER_PRESET_OFFSET;
|
|
1594
|
+
slot = LATER_SLOT_BASE + Number(n % LATER_SLOTS);
|
|
1595
|
+
presetIndex = Number(n / LATER_SLOTS);
|
|
1596
|
+
}
|
|
1597
|
+
const base2 = STYLE_DECODE[slot];
|
|
1598
|
+
const preset = THEME_PRESETS[presetIndex];
|
|
1599
|
+
if (!base2 || !preset) {
|
|
1600
|
+
throw new ThemeError("invalid theme", ["preset is out of range"]);
|
|
1601
|
+
}
|
|
1602
|
+
return generateTheme(base2, preset.seeds);
|
|
1603
|
+
}
|
|
1604
|
+
const payload = bits - CUSTOM_OFFSET;
|
|
1605
|
+
const base = STYLE_DECODE[Number(payload & 7n)];
|
|
1606
|
+
if (!base) {
|
|
1607
|
+
throw new ThemeError("invalid theme", ["preset style slot is out of range"]);
|
|
1608
|
+
}
|
|
1609
|
+
let rest = payload >> 3n;
|
|
1610
|
+
const seeds = { ...DEFAULT_SEEDS };
|
|
1611
|
+
for (const key of SEED_KEYS) {
|
|
1612
|
+
seeds[key] = fromRgb24(rest & 0xffffffn);
|
|
1613
|
+
rest >>= 24n;
|
|
1614
|
+
}
|
|
1615
|
+
if (rest !== 0n) {
|
|
1616
|
+
throw new ThemeError("invalid theme", ["preset payload has unused bits"]);
|
|
1617
|
+
}
|
|
1618
|
+
return generateTheme(base, seeds);
|
|
1619
|
+
}
|
|
1620
|
+
function registryThemeKey(doc) {
|
|
1621
|
+
if (isBareStyle(doc)) return STYLE_THEMES[doc.base]?.name;
|
|
1622
|
+
if (!doc.seeds || doc.base !== "base" || !generatedMatch(doc)) return void 0;
|
|
1623
|
+
const presetIndex = findPresetIndex(doc.seeds);
|
|
1624
|
+
if (presetIndex < 0) return void 0;
|
|
1625
|
+
return presetId(THEME_PRESETS[presetIndex].name);
|
|
1626
|
+
}
|
|
1627
|
+
|
|
1628
|
+
// src/codec.ts
|
|
1629
|
+
var THEME_CODE_PREFIX = "ut1.";
|
|
1630
|
+
var MAX_CODE_LENGTH = 4096;
|
|
1631
|
+
var MAX_JSON_BYTES = 16 * 1024;
|
|
1632
|
+
async function pump(stream, cap) {
|
|
1633
|
+
const reader = stream.getReader();
|
|
1634
|
+
const chunks = [];
|
|
1635
|
+
let size = 0;
|
|
1636
|
+
for (; ; ) {
|
|
1637
|
+
const { done, value } = await reader.read();
|
|
1638
|
+
if (done) break;
|
|
1639
|
+
size += value.byteLength;
|
|
1640
|
+
if (size > cap) {
|
|
1641
|
+
await reader.cancel().catch(() => {
|
|
1642
|
+
});
|
|
1643
|
+
throw new ThemeError("invalid theme", ["theme document too large"]);
|
|
1644
|
+
}
|
|
1645
|
+
chunks.push(value);
|
|
1646
|
+
}
|
|
1647
|
+
const out = new Uint8Array(size);
|
|
1648
|
+
let off = 0;
|
|
1649
|
+
for (const c of chunks) {
|
|
1650
|
+
out.set(c, off);
|
|
1651
|
+
off += c.byteLength;
|
|
1652
|
+
}
|
|
1653
|
+
return out;
|
|
1654
|
+
}
|
|
1655
|
+
var toB64url = (b) => {
|
|
1656
|
+
let bin = "";
|
|
1657
|
+
for (let i = 0; i < b.length; i += 32768) {
|
|
1658
|
+
bin += String.fromCharCode(...b.subarray(i, i + 32768));
|
|
1659
|
+
}
|
|
1660
|
+
return btoa(bin).replaceAll("+", "-").replaceAll("/", "_").replace(/=+$/, "");
|
|
1661
|
+
};
|
|
1662
|
+
var fromB64url = (s) => {
|
|
1663
|
+
const bin = atob(s.replaceAll("-", "+").replaceAll("_", "/"));
|
|
1664
|
+
return Uint8Array.from(bin, (c) => c.charCodeAt(0));
|
|
1665
|
+
};
|
|
1666
|
+
async function through(bytes, transform, cap) {
|
|
1667
|
+
const stream = new Blob([bytes]).stream().pipeThrough(transform);
|
|
1668
|
+
return pump(stream, cap);
|
|
1669
|
+
}
|
|
1670
|
+
async function encodeTheme(doc) {
|
|
1671
|
+
const valid = validateTheme(doc);
|
|
1672
|
+
const preset = encodePreset(valid);
|
|
1673
|
+
if (preset) return preset;
|
|
1674
|
+
const json = new TextEncoder().encode(JSON.stringify(valid));
|
|
1675
|
+
const packed = await through(json, new CompressionStream("deflate"), Number.POSITIVE_INFINITY);
|
|
1676
|
+
const code = THEME_CODE_PREFIX + toB64url(packed);
|
|
1677
|
+
if (code.length > MAX_CODE_LENGTH) {
|
|
1678
|
+
throw new ThemeError("invalid theme", [
|
|
1679
|
+
`encoded theme exceeds ${MAX_CODE_LENGTH} characters`
|
|
1680
|
+
]);
|
|
1681
|
+
}
|
|
1682
|
+
return code;
|
|
1683
|
+
}
|
|
1684
|
+
async function decodeTheme(code) {
|
|
1685
|
+
if (code.length > MAX_CODE_LENGTH) {
|
|
1686
|
+
throw new ThemeError("invalid theme", [`code exceeds ${MAX_CODE_LENGTH} characters`]);
|
|
1687
|
+
}
|
|
1688
|
+
if (code.startsWith(THEME_CODE_PREFIX)) {
|
|
1689
|
+
return decodeDeflate(code);
|
|
1690
|
+
}
|
|
1691
|
+
if (isThemePresetCode(code)) {
|
|
1692
|
+
return validateTheme(decodePreset(code));
|
|
1693
|
+
}
|
|
1694
|
+
throw new ThemeError("invalid theme", [
|
|
1695
|
+
`code must start with "${THEME_CODE_PREFIX}" or be a short preset`
|
|
1696
|
+
]);
|
|
1697
|
+
}
|
|
1698
|
+
async function decodeDeflate(code) {
|
|
1699
|
+
let bytes;
|
|
1700
|
+
try {
|
|
1701
|
+
const packed = fromB64url(code.slice(THEME_CODE_PREFIX.length));
|
|
1702
|
+
bytes = await through(packed, new DecompressionStream("deflate"), MAX_JSON_BYTES);
|
|
1703
|
+
} catch (e) {
|
|
1704
|
+
if (e instanceof ThemeError) throw e;
|
|
1705
|
+
throw new ThemeError("invalid theme", ["code is not valid base64url deflate data"]);
|
|
1706
|
+
}
|
|
1707
|
+
let parsed;
|
|
1708
|
+
try {
|
|
1709
|
+
parsed = JSON.parse(new TextDecoder().decode(bytes));
|
|
1710
|
+
} catch {
|
|
1711
|
+
throw new ThemeError("invalid theme", ["decoded payload is not JSON"]);
|
|
1712
|
+
}
|
|
1713
|
+
return validateTheme(parsed);
|
|
1714
|
+
}
|
|
1419
1715
|
export {
|
|
1420
1716
|
DEFAULT_MARKER,
|
|
1421
1717
|
DEFAULT_ROUTE,
|
|
@@ -1423,29 +1719,42 @@ export {
|
|
|
1423
1719
|
LABEL_PAIRS,
|
|
1424
1720
|
MAX_CODE_LENGTH,
|
|
1425
1721
|
MODES,
|
|
1426
|
-
|
|
1722
|
+
PRESET_CODE_PREFIX,
|
|
1723
|
+
PRESET_CODE_RE,
|
|
1427
1724
|
RECIPES,
|
|
1428
|
-
SEED_PALETTES,
|
|
1429
1725
|
STOCK_RAMPS,
|
|
1726
|
+
STYLE_THEMES,
|
|
1430
1727
|
THEME_BASES,
|
|
1431
1728
|
THEME_CODE_PREFIX,
|
|
1729
|
+
THEME_PRESETS,
|
|
1432
1730
|
ThemeError,
|
|
1433
1731
|
buildRecipes,
|
|
1732
|
+
cobalt,
|
|
1434
1733
|
contrast,
|
|
1435
1734
|
contrastWarnings,
|
|
1735
|
+
decodePreset,
|
|
1436
1736
|
decodeTheme,
|
|
1437
1737
|
ember,
|
|
1738
|
+
encodePreset,
|
|
1438
1739
|
encodeTheme,
|
|
1439
1740
|
generateTheme,
|
|
1440
1741
|
graphite,
|
|
1441
1742
|
hexToOklch,
|
|
1442
1743
|
ink,
|
|
1744
|
+
isThemePresetCode,
|
|
1745
|
+
jade,
|
|
1443
1746
|
makeFlavor,
|
|
1444
1747
|
mergeRecipe,
|
|
1748
|
+
mist,
|
|
1749
|
+
normalizeThemeBase,
|
|
1445
1750
|
oklchToHex,
|
|
1751
|
+
paper,
|
|
1752
|
+
presetId,
|
|
1753
|
+
registryThemeKey,
|
|
1446
1754
|
resolveTheme,
|
|
1447
1755
|
sandstone,
|
|
1448
1756
|
shuffleSeeds,
|
|
1757
|
+
sky,
|
|
1449
1758
|
validateTheme,
|
|
1450
1759
|
verdant,
|
|
1451
1760
|
wave
|