@diagrammo/dgmo 0.20.2 → 0.21.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/dist/index.js CHANGED
@@ -833,13 +833,9 @@ var init_reserved_key_registry = __esm({
833
833
  "icon"
834
834
  ]);
835
835
  MAP_REGISTRY = staticRegistry([
836
- "score",
836
+ "value",
837
837
  "label",
838
- "size",
839
- "description",
840
- "weight",
841
- "style",
842
- "date"
838
+ "style"
843
839
  ]);
844
840
  ORG_REGISTRY = staticRegistry([
845
841
  "color",
@@ -15870,7 +15866,8 @@ function parseMap(content) {
15870
15866
  continue;
15871
15867
  }
15872
15868
  if (open.route && indent > open.route.indent) {
15873
- open.route.route.stops.push(parseStop(trimmed, lineNumber));
15869
+ const leg = parseLeg(trimmed, lineNumber, open.route.route.style);
15870
+ open.route.route.legs.push(leg);
15874
15871
  continue;
15875
15872
  }
15876
15873
  if (open.poi && indent > open.poi.indent) {
@@ -15901,6 +15898,10 @@ function parseMap(content) {
15901
15898
  handleTag(trimmed, lineNumber);
15902
15899
  continue;
15903
15900
  }
15901
+ if ((firstWord === "muted" || firstWord === "natural") && trimmed === firstWord) {
15902
+ handleDirective(firstWord, "", lineNumber);
15903
+ continue;
15904
+ }
15904
15905
  if (DIRECTIVE_SET.has(firstWord) && !trimmed.slice(firstWord.length).trimStart().startsWith(":")) {
15905
15906
  handleDirective(
15906
15907
  firstWord,
@@ -15965,13 +15966,17 @@ function parseMap(content) {
15965
15966
  );
15966
15967
  d.projection = value;
15967
15968
  break;
15968
- case "metric":
15969
- dup(d.metric);
15970
- d.metric = value;
15969
+ case "region-metric":
15970
+ dup(d.regionMetric);
15971
+ d.regionMetric = value;
15972
+ break;
15973
+ case "poi-metric":
15974
+ dup(d.poiMetric);
15975
+ d.poiMetric = value;
15971
15976
  break;
15972
- case "size-metric":
15973
- dup(d.sizeMetric);
15974
- d.sizeMetric = value;
15977
+ case "flow-metric":
15978
+ dup(d.flowMetric);
15979
+ d.flowMetric = value;
15975
15980
  break;
15976
15981
  case "scale":
15977
15982
  dup(d.scale);
@@ -16013,6 +16018,15 @@ function parseMap(content) {
16013
16018
  case "no-legend":
16014
16019
  d.noLegend = true;
16015
16020
  break;
16021
+ case "muted":
16022
+ case "natural":
16023
+ if (d.basemapStyle !== void 0 && d.basemapStyle !== key)
16024
+ pushWarning(
16025
+ line12,
16026
+ `Conflicting basemap dress \u2014 "${d.basemapStyle}" then "${key}"; last wins.`
16027
+ );
16028
+ d.basemapStyle = key;
16029
+ break;
16016
16030
  case "subtitle":
16017
16031
  dup(d.subtitle);
16018
16032
  d.subtitle = value;
@@ -16090,14 +16104,14 @@ function parseMap(content) {
16090
16104
  line12
16091
16105
  );
16092
16106
  const { tags, meta } = partitionMeta(split.meta, tagGroupNames());
16093
- let scoreNum;
16094
- const score = meta["score"];
16095
- if (score !== void 0) {
16096
- delete meta["score"];
16097
- scoreNum = Number(score);
16098
- if (!Number.isFinite(scoreNum)) {
16099
- pushError(line12, `score must be a number (got "${score}").`);
16100
- scoreNum = void 0;
16107
+ let valueNum;
16108
+ const value = meta["value"];
16109
+ if (value !== void 0) {
16110
+ delete meta["value"];
16111
+ valueNum = Number(value);
16112
+ if (!Number.isFinite(valueNum)) {
16113
+ pushError(line12, `value must be a number (got "${value}").`);
16114
+ valueNum = void 0;
16101
16115
  }
16102
16116
  }
16103
16117
  let regionName = split.name;
@@ -16115,7 +16129,7 @@ function parseMap(content) {
16115
16129
  lineNumber: line12
16116
16130
  };
16117
16131
  if (regionScope !== void 0) region.scope = regionScope;
16118
- if (scoreNum !== void 0) region.score = scoreNum;
16132
+ if (valueNum !== void 0) region.value = valueNum;
16119
16133
  regions.push(region);
16120
16134
  }
16121
16135
  function handlePoi(rest, line12, indent) {
@@ -16144,24 +16158,76 @@ function parseMap(content) {
16144
16158
  open.poi = { poi, indent };
16145
16159
  }
16146
16160
  function handleRoute(rest, line12, indent) {
16147
- const meta = rest ? splitNameAndMeta(rest, registry(), aliasMap).meta : {};
16148
- const route = { stops: [], meta, lineNumber: line12 };
16161
+ const split = rest ? splitNameAndMeta(
16162
+ rest,
16163
+ registry(),
16164
+ aliasMap,
16165
+ void 0,
16166
+ diagnostics,
16167
+ line12
16168
+ ) : { name: "", meta: {}, alias: void 0 };
16169
+ const pos = parsePos(split.name, line12);
16170
+ if (!pos || pos.kind === "name" && !pos.name) {
16171
+ pushError(
16172
+ line12,
16173
+ "route requires an origin: `route <origin> [style: arc]`."
16174
+ );
16175
+ return;
16176
+ }
16177
+ const { tags, meta } = partitionMeta(split.meta, tagGroupNames());
16178
+ const originLabel = meta["label"];
16179
+ const originValue = meta["value"];
16180
+ const style = meta["style"] === "arc" ? "arc" : "straight";
16181
+ const route = {
16182
+ origin: pos,
16183
+ ...split.alias !== void 0 && { originAlias: split.alias },
16184
+ ...originLabel !== void 0 && { originLabel },
16185
+ ...originValue !== void 0 && { originValue },
16186
+ originTags: tags,
16187
+ style,
16188
+ legs: [],
16189
+ lineNumber: line12
16190
+ };
16149
16191
  routes.push(route);
16150
16192
  open.route = { route, indent };
16151
16193
  }
16152
- function parseStop(trimmed, line12) {
16153
- const split = splitNameAndMeta(trimmed, registry(), aliasMap);
16154
- const ref = parsePos(split.name, line12) ?? {
16194
+ function parseLeg(trimmed, line12, headerStyle) {
16195
+ let arrowStyle = "straight";
16196
+ let label;
16197
+ let rest = trimmed;
16198
+ const m = trimmed.match(LEG_ARROW_RE);
16199
+ if (m) {
16200
+ const arr = classifyArrow(m[1], line12);
16201
+ arrowStyle = arr.style;
16202
+ label = arr.label;
16203
+ rest = m[2];
16204
+ }
16205
+ const split = splitNameAndMeta(
16206
+ rest,
16207
+ registry(),
16208
+ aliasMap,
16209
+ void 0,
16210
+ diagnostics,
16211
+ line12
16212
+ );
16213
+ const pos = parsePos(split.name, line12) ?? {
16155
16214
  kind: "name",
16156
16215
  name: split.name
16157
16216
  };
16158
- const stop = {
16159
- ref,
16160
- meta: split.meta,
16217
+ const { tags, meta } = partitionMeta(split.meta, tagGroupNames());
16218
+ const value = meta["value"];
16219
+ const destLabel = meta["label"];
16220
+ const style = arrowStyle === "arc" || headerStyle === "arc" ? "arc" : "straight";
16221
+ return {
16222
+ ...label !== void 0 && { label },
16223
+ style,
16224
+ ...value !== void 0 && { value },
16225
+ dest: pos,
16226
+ ...split.alias !== void 0 && { destAlias: split.alias },
16227
+ ...destLabel !== void 0 && { destLabel },
16228
+ destTags: tags,
16161
16229
  lineNumber: line12
16162
16230
  };
16163
- if (split.alias) stop.alias = split.alias;
16164
- return stop;
16165
16231
  }
16166
16232
  function handleEdges(trimmed, line12) {
16167
16233
  const parts = trimmed.split(ARROW_SPLIT);
@@ -16263,7 +16329,7 @@ function partitionMeta(meta, tagGroupNames) {
16263
16329
  function poiName(pos) {
16264
16330
  return pos.kind === "name" ? pos.name : void 0;
16265
16331
  }
16266
- var COORD_RE, NUMERIC_LEAD_RE, SCOPE_RE, ARROW_SPLIT, HUB_RE, AT_RE, DIRECTIVE_SET;
16332
+ var COORD_RE, NUMERIC_LEAD_RE, SCOPE_RE, ARROW_SPLIT, HUB_RE, LEG_ARROW_RE, AT_RE, DIRECTIVE_SET;
16267
16333
  var init_parser12 = __esm({
16268
16334
  "src/map/parser.ts"() {
16269
16335
  "use strict";
@@ -16277,12 +16343,14 @@ var init_parser12 = __esm({
16277
16343
  SCOPE_RE = /^[A-Z]{2}(?:-[A-Z0-9]{1,3})?$/;
16278
16344
  ARROW_SPLIT = /\s+(-[^>]*?->|->|~[^>]*?~>|~>|--)\s+/;
16279
16345
  HUB_RE = /^(->|~>)\s+(.+)$/;
16346
+ LEG_ARROW_RE = /^(-[^>]*?->|->|~[^>]*?~>|~>|--)\s+(.+)$/;
16280
16347
  AT_RE = /(^|[\s,])at\s*:/i;
16281
16348
  DIRECTIVE_SET = /* @__PURE__ */ new Set([
16282
16349
  "region",
16283
16350
  "projection",
16284
- "metric",
16285
- "size-metric",
16351
+ "region-metric",
16352
+ "poi-metric",
16353
+ "flow-metric",
16286
16354
  "scale",
16287
16355
  "region-labels",
16288
16356
  "poi-labels",
@@ -45567,6 +45635,11 @@ var resolver_exports = {};
45567
45635
  __export(resolver_exports, {
45568
45636
  resolveMap: () => resolveMap
45569
45637
  });
45638
+ function usStateFromBareScope(scope) {
45639
+ if (!scope) return null;
45640
+ const up = scope.toUpperCase();
45641
+ return US_STATE_POSTAL.has(up) ? `US-${up}` : null;
45642
+ }
45570
45643
  function looksUS(lat, lon) {
45571
45644
  if (lat < 15 || lat > 72) return false;
45572
45645
  return lon >= -180 && lon <= -64 || lon >= 172;
@@ -45616,9 +45689,9 @@ function resolveMap(parsed, data) {
45616
45689
  const f = fold(r.name);
45617
45690
  return usStateIndex.has(f) && !countryIndex.has(f);
45618
45691
  }) || parsed.regions.some(
45619
- (r) => r.scope === "US" || r.scope?.startsWith("US-")
45692
+ (r) => r.scope === "US" || r.scope?.startsWith("US-") || usStateFromBareScope(r.scope) !== null
45620
45693
  ) || parsed.pois.some(
45621
- (p) => p.pos.kind === "name" && p.pos.scope?.startsWith("US-")
45694
+ (p) => p.pos.kind === "name" && (p.pos.scope?.startsWith("US-") || usStateFromBareScope(p.pos.scope) !== null)
45622
45695
  );
45623
45696
  const regions = [];
45624
45697
  const seenRegion = /* @__PURE__ */ new Map();
@@ -45685,7 +45758,7 @@ function resolveMap(parsed, data) {
45685
45758
  iso: chosen.id,
45686
45759
  name: chosen.name,
45687
45760
  layer: chosen.layer,
45688
- ...r.score !== void 0 && { score: r.score },
45761
+ ...r.value !== void 0 && { value: r.value },
45689
45762
  tags: r.tags,
45690
45763
  meta: r.meta,
45691
45764
  lineNumber: r.lineNumber
@@ -45743,9 +45816,10 @@ function resolveMap(parsed, data) {
45743
45816
  let cands = idxs.map((i) => data.gazetteer.cities[i]);
45744
45817
  const scopeUse = scope ?? scopeHint;
45745
45818
  if (scopeUse) {
45746
- const isSub = /^[A-Za-z]{2}-/.test(scopeUse);
45819
+ const bareState = usStateFromBareScope(scopeUse);
45820
+ const subScope = /^[A-Za-z]{2}-/.test(scopeUse) ? scopeUse : bareState;
45747
45821
  const filtered = cands.filter(
45748
- (c2) => isSub ? c2[5] === scopeUse : c2[2] === scopeUse
45822
+ (c2) => subScope ? c2[5] === subScope : c2[2] === scopeUse
45749
45823
  );
45750
45824
  if (filtered.length) cands = filtered;
45751
45825
  else if (scope) {
@@ -45874,33 +45948,89 @@ function resolveMap(parsed, data) {
45874
45948
  lineNumber: e.lineNumber
45875
45949
  });
45876
45950
  }
45877
- const routes = [];
45878
- for (const rt of parsed.routes) {
45879
- const stopIds = [];
45880
- for (const stop of rt.stops) {
45881
- let id;
45882
- if (stop.ref.kind === "coords") {
45883
- id = stop.alias ? fold(stop.alias) : `@${stop.ref.lat},${stop.ref.lon}`;
45884
- if (!looksUS(stop.ref.lat, stop.ref.lon)) anyNonUsPoi = true;
45885
- if (!registry.has(id)) {
45886
- const poi = {
45951
+ const resolveStop = (pos, alias, label, tags, sizeValue, line12) => {
45952
+ const meta = sizeValue !== void 0 ? { value: sizeValue } : {};
45953
+ if (pos.kind === "coords") {
45954
+ const id = alias ? fold(alias) : `@${pos.lat},${pos.lon}`;
45955
+ if (!looksUS(pos.lat, pos.lon)) anyNonUsPoi = true;
45956
+ if (!registry.has(id)) {
45957
+ registerPoi(
45958
+ id,
45959
+ {
45887
45960
  id,
45888
- ...stop.alias !== void 0 && { name: stop.alias },
45889
- lat: stop.ref.lat,
45890
- lon: stop.ref.lon,
45891
- tags: {},
45892
- meta: stop.meta,
45893
- lineNumber: stop.lineNumber,
45894
- implicit: true
45895
- };
45896
- registerPoi(id, poi, stop.lineNumber);
45897
- }
45898
- } else {
45899
- id = stop.alias && registry.has(fold(stop.alias)) ? fold(stop.alias) : resolveEndpoint2(stop.ref.name, stop.lineNumber);
45961
+ ...alias !== void 0 && { name: alias },
45962
+ lat: pos.lat,
45963
+ lon: pos.lon,
45964
+ ...label !== void 0 && { label },
45965
+ tags,
45966
+ meta,
45967
+ lineNumber: line12
45968
+ },
45969
+ line12
45970
+ );
45900
45971
  }
45901
- if (id) stopIds.push(id);
45972
+ return id;
45973
+ }
45974
+ const f = fold(pos.name);
45975
+ if (registry.has(f)) return f;
45976
+ const aliased = declaredByName.get(f);
45977
+ if (aliased) return aliased;
45978
+ const got = lookupName(pos.name, pos.scope, line12, inferredCountry, true);
45979
+ if (got.kind !== "ok") return null;
45980
+ noteCountry(got.iso);
45981
+ registerPoi(
45982
+ f,
45983
+ {
45984
+ id: f,
45985
+ name: pos.name,
45986
+ lat: got.lat,
45987
+ lon: got.lon,
45988
+ ...label !== void 0 && { label },
45989
+ tags,
45990
+ meta,
45991
+ lineNumber: line12
45992
+ },
45993
+ line12
45994
+ );
45995
+ return f;
45996
+ };
45997
+ const routes = [];
45998
+ for (const rt of parsed.routes) {
45999
+ const originId = resolveStop(
46000
+ rt.origin,
46001
+ rt.originAlias,
46002
+ rt.originLabel,
46003
+ rt.originTags,
46004
+ rt.originValue,
46005
+ rt.lineNumber
46006
+ );
46007
+ if (!originId) continue;
46008
+ const stopIds = [originId];
46009
+ const legs = [];
46010
+ let prevId = originId;
46011
+ for (const leg of rt.legs) {
46012
+ const destId = resolveStop(
46013
+ leg.dest,
46014
+ leg.destAlias,
46015
+ leg.destLabel,
46016
+ leg.destTags,
46017
+ void 0,
46018
+ // a leg's `value:` is leg thickness, not the dest's size
46019
+ leg.lineNumber
46020
+ );
46021
+ if (!destId) continue;
46022
+ legs.push({
46023
+ fromId: prevId,
46024
+ toId: destId,
46025
+ ...leg.label !== void 0 && { label: leg.label },
46026
+ style: leg.style,
46027
+ ...leg.value !== void 0 && { value: leg.value },
46028
+ lineNumber: leg.lineNumber
46029
+ });
46030
+ if (!stopIds.includes(destId)) stopIds.push(destId);
46031
+ prevId = destId;
45902
46032
  }
45903
- routes.push({ stopIds, meta: rt.meta, lineNumber: rt.lineNumber });
46033
+ routes.push({ stopIds, legs, lineNumber: rt.lineNumber });
45904
46034
  }
45905
46035
  const subdivisions = [];
45906
46036
  if (usSubdivisionReferenced || parsed.directives.region === "us-states")
@@ -45992,7 +46122,7 @@ function firstError(diags) {
45992
46122
  const e = diags.find((d) => d.severity === "error");
45993
46123
  return e ? formatDgmoError(e) : null;
45994
46124
  }
45995
- var WORLD_SPAN, MERCATOR_MAX_SPAN, PAD_FRACTION, WORLD_LAT_SOUTH, WORLD_LAT_NORTH, REGION_ALIASES;
46125
+ var WORLD_SPAN, MERCATOR_MAX_SPAN, PAD_FRACTION, WORLD_LAT_SOUTH, WORLD_LAT_NORTH, REGION_ALIASES, US_STATE_POSTAL;
45996
46126
  var init_resolver2 = __esm({
45997
46127
  "src/map/resolver.ts"() {
45998
46128
  "use strict";
@@ -46024,6 +46154,59 @@ var init_resolver2 = __esm({
46024
46154
  "north macedonia": "macedonia",
46025
46155
  "czech republic": "czechia"
46026
46156
  };
46157
+ US_STATE_POSTAL = /* @__PURE__ */ new Set([
46158
+ "AL",
46159
+ "AK",
46160
+ "AZ",
46161
+ "AR",
46162
+ "CA",
46163
+ "CO",
46164
+ "CT",
46165
+ "DE",
46166
+ "FL",
46167
+ "GA",
46168
+ "HI",
46169
+ "ID",
46170
+ "IL",
46171
+ "IN",
46172
+ "IA",
46173
+ "KS",
46174
+ "KY",
46175
+ "LA",
46176
+ "ME",
46177
+ "MD",
46178
+ "MA",
46179
+ "MI",
46180
+ "MN",
46181
+ "MS",
46182
+ "MO",
46183
+ "MT",
46184
+ "NE",
46185
+ "NV",
46186
+ "NH",
46187
+ "NJ",
46188
+ "NM",
46189
+ "NY",
46190
+ "NC",
46191
+ "ND",
46192
+ "OH",
46193
+ "OK",
46194
+ "OR",
46195
+ "PA",
46196
+ "RI",
46197
+ "SC",
46198
+ "SD",
46199
+ "TN",
46200
+ "TX",
46201
+ "UT",
46202
+ "VT",
46203
+ "VA",
46204
+ "WA",
46205
+ "WV",
46206
+ "WI",
46207
+ "WY",
46208
+ "DC"
46209
+ ]);
46027
46210
  }
46028
46211
  });
46029
46212
 
@@ -46171,9 +46354,24 @@ function projectionFor(family) {
46171
46354
  return geoEquirectangular();
46172
46355
  }
46173
46356
  }
46174
- function mapBackgroundColor(palette) {
46357
+ function mapBackgroundColor(palette, isDark = false, dataActive = false) {
46358
+ if (dataActive)
46359
+ return mix(
46360
+ palette.colors.gray,
46361
+ palette.bg,
46362
+ isDark ? MUTED_WATER_DARK : MUTED_WATER_LIGHT
46363
+ );
46175
46364
  return mix(palette.colors.blue, palette.bg, WATER_TINT);
46176
46365
  }
46366
+ function mapNeutralLandColor(palette, isDark, dataActive = false) {
46367
+ if (dataActive)
46368
+ return isDark ? mix(palette.colors.gray, palette.bg, MUTED_LAND_DARK) : palette.bg;
46369
+ return mix(
46370
+ palette.colors.green,
46371
+ palette.bg,
46372
+ isDark ? LAND_TINT_DARK : LAND_TINT_LIGHT
46373
+ );
46374
+ }
46177
46375
  function layoutMap(resolved, data, size, opts) {
46178
46376
  const { palette, isDark } = opts;
46179
46377
  const { width, height } = size;
@@ -46193,28 +46391,19 @@ function layoutMap(resolved, data, size, opts) {
46193
46391
  }
46194
46392
  }
46195
46393
  const usLayer = wantsUsStates ? decodeLayer(data.usStates) : null;
46196
- const landTint = isDark ? LAND_TINT_DARK : LAND_TINT_LIGHT;
46197
- const neutralFill = mix(palette.colors.green, palette.bg, landTint);
46198
- const water = mapBackgroundColor(palette);
46199
46394
  const usContext = usLayer !== null;
46200
- const foreignFill = mix(
46201
- palette.colors.gray,
46202
- palette.bg,
46203
- isDark ? FOREIGN_TINT_DARK : FOREIGN_TINT_LIGHT
46204
- );
46205
46395
  const regionStroke = isDark ? mix(palette.bg, palette.text, 78) : mix(palette.text, palette.bg, 78);
46206
- const scores = resolved.regions.filter((r) => r.score !== void 0).map((r) => r.score);
46396
+ const values = resolved.regions.filter((r) => r.value !== void 0).map((r) => r.value);
46207
46397
  const scaleOverride = resolved.directives.scale;
46208
- const rampMin = scaleOverride ? scaleOverride.min : Math.min(...scores);
46209
- const rampMax = scaleOverride ? scaleOverride.max : Math.max(...scores);
46398
+ const rampMin = scaleOverride ? scaleOverride.min : Math.min(...values);
46399
+ const rampMax = scaleOverride ? scaleOverride.max : Math.max(...values);
46210
46400
  const rampHue = palette.colors.red;
46211
- const hasRamp = scores.length > 0;
46212
- const SCORE_NAME = hasRamp ? resolved.directives.metric?.trim() || "Score" : null;
46401
+ const hasRamp = values.length > 0;
46402
+ const VALUE_NAME = hasRamp ? resolved.directives.regionMetric?.trim() || "Value" : null;
46213
46403
  const matchColorGroup = (v) => {
46214
46404
  const lv = v.trim().toLowerCase();
46215
46405
  if (lv === "none") return null;
46216
- if (SCORE_NAME && (lv === "score" || lv === SCORE_NAME.toLowerCase()))
46217
- return SCORE_NAME;
46406
+ if (lv === VALUE_NAME?.toLowerCase()) return VALUE_NAME;
46218
46407
  const tg = resolved.tagGroups.find((g) => g.name.toLowerCase() === lv);
46219
46408
  return tg ? tg.name : v;
46220
46409
  };
@@ -46225,11 +46414,19 @@ function layoutMap(resolved, data, size, opts) {
46225
46414
  } else if (resolved.directives.activeTag !== void 0) {
46226
46415
  activeGroup = matchColorGroup(resolved.directives.activeTag);
46227
46416
  } else {
46228
- activeGroup = SCORE_NAME ?? (resolved.tagGroups.length > 0 ? resolved.tagGroups[0].name : null);
46417
+ activeGroup = VALUE_NAME ?? (resolved.tagGroups.length > 0 ? resolved.tagGroups[0].name : null);
46229
46418
  }
46230
- const activeIsScore = SCORE_NAME !== null && activeGroup === SCORE_NAME;
46419
+ const activeIsScore = VALUE_NAME !== null && activeGroup === VALUE_NAME;
46420
+ const mutedBasemap = resolved.directives.basemapStyle === "muted" ? true : resolved.directives.basemapStyle === "natural" ? false : activeGroup !== null;
46421
+ const neutralFill = mapNeutralLandColor(palette, isDark, mutedBasemap);
46422
+ const water = mapBackgroundColor(palette, isDark, mutedBasemap);
46423
+ const foreignFill = mix(
46424
+ palette.colors.gray,
46425
+ palette.bg,
46426
+ mutedBasemap ? isDark ? MUTED_FOREIGN_DARK : MUTED_FOREIGN_LIGHT : isDark ? FOREIGN_TINT_DARK : FOREIGN_TINT_LIGHT
46427
+ );
46231
46428
  const rampBase = isDark ? mix(palette.surface, palette.text, 28) : palette.bg;
46232
- const fillForScore = (s) => {
46429
+ const fillForValue = (s) => {
46233
46430
  const t = rampMax > rampMin ? (s - rampMin) / (rampMax - rampMin) : 1;
46234
46431
  const pct = RAMP_FLOOR + Math.max(0, Math.min(1, t)) * (100 - RAMP_FLOOR);
46235
46432
  return mix(rampHue, rampBase, pct);
@@ -46254,7 +46451,7 @@ function layoutMap(resolved, data, size, opts) {
46254
46451
  };
46255
46452
  const regionFill = (r) => {
46256
46453
  if (activeIsScore) {
46257
- return r.score !== void 0 ? fillForScore(r.score) : neutralFill;
46454
+ return r.value !== void 0 ? fillForValue(r.value) : neutralFill;
46258
46455
  }
46259
46456
  return tagFill(r.tags, activeGroup) ?? neutralFill;
46260
46457
  };
@@ -46466,7 +46663,7 @@ function layoutMap(resolved, data, size, opts) {
46466
46663
  stroke: regionStroke,
46467
46664
  lineNumber,
46468
46665
  layer: "us-state",
46469
- ...r?.score !== void 0 && { score: r.score },
46666
+ ...r?.value !== void 0 && { value: r.value },
46470
46667
  ...r && Object.keys(r.tags).length > 0 && { tags: r.tags }
46471
46668
  });
46472
46669
  const ctr = geoPath(proj).centroid(f);
@@ -46582,6 +46779,8 @@ function layoutMap(resolved, data, size, opts) {
46582
46779
  if (layerKind === "us-state" && usContext && INSET_STATES.has(iso))
46583
46780
  continue;
46584
46781
  if (layerKind === "country" && usContext && iso === "US") continue;
46782
+ if (layerKind === "country" && iso === "AQ" && !regionById.has("AQ"))
46783
+ continue;
46585
46784
  const r = regionById.get(iso);
46586
46785
  const viewF = shouldCull ? cullFeatureToView(f) : dropFrameFillers(f);
46587
46786
  if (!viewF) continue;
@@ -46607,7 +46806,7 @@ function layoutMap(resolved, data, size, opts) {
46607
46806
  lineNumber,
46608
46807
  layer,
46609
46808
  ...label !== void 0 && { label },
46610
- ...isThisLayer && r.score !== void 0 && { score: r.score },
46809
+ ...isThisLayer && r.value !== void 0 && { value: r.value },
46611
46810
  ...isThisLayer && Object.keys(r.tags).length > 0 && { tags: r.tags }
46612
46811
  });
46613
46812
  }
@@ -46642,11 +46841,11 @@ function layoutMap(resolved, data, size, opts) {
46642
46841
  rivers.push({ d, color: riverColor, width: RIVER_WIDTH });
46643
46842
  }
46644
46843
  }
46645
- const sizeVals = resolved.pois.map((p) => Number(p.meta["size"])).filter((n) => Number.isFinite(n) && n > 0);
46844
+ const sizeVals = resolved.pois.map((p) => Number(p.meta["value"])).filter((n) => Number.isFinite(n) && n > 0);
46646
46845
  const sizeMin = sizeVals.length ? Math.min(...sizeVals) : 0;
46647
46846
  const sizeMax = sizeVals.length ? Math.max(...sizeVals) : 0;
46648
46847
  const radiusFor = (p) => {
46649
- const v = Number(p.meta["size"]);
46848
+ const v = Number(p.meta["value"]);
46650
46849
  if (!Number.isFinite(v) || v <= 0 || sizeMax <= 0) return R_DEFAULT;
46651
46850
  const t = sizeMax > sizeMin ? (Math.sqrt(v) - Math.sqrt(sizeMin)) / (Math.sqrt(sizeMax) - Math.sqrt(sizeMin)) : 1;
46652
46851
  return R_MIN + Math.max(0, Math.min(1, t)) * (R_MAX - R_MIN);
@@ -46713,7 +46912,8 @@ function layoutMap(resolved, data, size, opts) {
46713
46912
  lineNumber: e.p.lineNumber,
46714
46913
  implicit: !!e.p.implicit,
46715
46914
  isOrigin: originIds.has(e.p.id),
46716
- ...num !== void 0 && { routeNumber: num }
46915
+ ...num !== void 0 && { routeNumber: num },
46916
+ ...Object.keys(e.p.tags).length > 0 && { tags: e.p.tags }
46717
46917
  });
46718
46918
  });
46719
46919
  }
@@ -46749,26 +46949,40 @@ function layoutMap(resolved, data, size, opts) {
46749
46949
  const by = b.cy - (b.cy - py) / tb * trimB;
46750
46950
  return `M${ax},${ay}Q${px},${py} ${bx},${by}`;
46751
46951
  };
46952
+ const routeLegVals = resolved.routes.flatMap((rt) => rt.legs).map((l) => Number(l.value)).filter((n) => Number.isFinite(n) && n > 0);
46953
+ const rlMin = routeLegVals.length ? Math.min(...routeLegVals) : 0;
46954
+ const rlMax = routeLegVals.length ? Math.max(...routeLegVals) : 0;
46955
+ const routeWidthFor = (v) => {
46956
+ if (!Number.isFinite(v) || v <= 0 || rlMax <= 0) return W_MIN;
46957
+ const t = rlMax > rlMin ? (v - rlMin) / (rlMax - rlMin) : 1;
46958
+ return W_MIN + t * (W_MAX - W_MIN);
46959
+ };
46752
46960
  for (const rt of resolved.routes) {
46753
- const curved = rt.meta["style"] === "arc";
46754
- for (let i = 1; i < rt.stopIds.length; i++) {
46755
- const a = poiScreen.get(rt.stopIds[i - 1]);
46756
- const b = poiScreen.get(rt.stopIds[i]);
46961
+ for (const leg of rt.legs) {
46962
+ const a = poiScreen.get(leg.fromId);
46963
+ const b = poiScreen.get(leg.toId);
46757
46964
  if (!a || !b) continue;
46965
+ const mx = (a.cx + b.cx) / 2;
46966
+ const my = (a.cy + b.cy) / 2;
46758
46967
  legs.push({
46759
- d: legPath(a, b, curved, 0),
46760
- width: W_MIN,
46968
+ d: legPath(a, b, leg.style === "arc", 0),
46969
+ width: routeWidthFor(Number(leg.value)),
46761
46970
  color: mix(palette.text, palette.bg, 72),
46762
46971
  arrow: true,
46763
- lineNumber: rt.lineNumber
46972
+ lineNumber: leg.lineNumber,
46973
+ ...leg.label !== void 0 && {
46974
+ label: leg.label,
46975
+ labelX: mx,
46976
+ labelY: my - 4
46977
+ }
46764
46978
  });
46765
46979
  }
46766
46980
  }
46767
- const weightVals = resolved.edges.map((e) => Number(e.meta["weight"])).filter((n) => Number.isFinite(n) && n > 0);
46981
+ const weightVals = resolved.edges.map((e) => Number(e.meta["value"])).filter((n) => Number.isFinite(n) && n > 0);
46768
46982
  const wMin = weightVals.length ? Math.min(...weightVals) : 0;
46769
46983
  const wMax = weightVals.length ? Math.max(...weightVals) : 0;
46770
46984
  const widthFor = (e) => {
46771
- const v = Number(e.meta["weight"]);
46985
+ const v = Number(e.meta["value"]);
46772
46986
  if (!Number.isFinite(v) || v <= 0 || wMax <= 0) return W_MIN;
46773
46987
  const t = wMax > wMin ? (v - wMin) / (wMax - wMin) : 1;
46774
46988
  return W_MIN + t * (W_MAX - W_MIN);
@@ -47031,8 +47245,8 @@ function layoutMap(resolved, data, size, opts) {
47031
47245
  activeGroup,
47032
47246
  ...hasRamp && {
47033
47247
  ramp: {
47034
- ...resolved.directives.metric !== void 0 && {
47035
- metric: resolved.directives.metric
47248
+ ...resolved.directives.regionMetric !== void 0 && {
47249
+ metric: resolved.directives.regionMetric
47036
47250
  },
47037
47251
  min: rampMin,
47038
47252
  max: rampMax,
@@ -47060,7 +47274,7 @@ function layoutMap(resolved, data, size, opts) {
47060
47274
  insetRegions
47061
47275
  };
47062
47276
  }
47063
- var FIT_PAD, RAMP_FLOOR, R_DEFAULT, R_MIN, R_MAX, W_MIN, W_MAX, FONT, COLO_EPS, LAND_TINT_LIGHT, LAND_TINT_DARK, TAG_TINT_LIGHT, TAG_TINT_DARK, WATER_TINT, RIVER_WIDTH, FOREIGN_TINT_LIGHT, FOREIGN_TINT_DARK, COLO_R, GOLDEN_ANGLE, FAN_STEP, ARC_CURVE_FRAC, usConusProjection, alaskaProjection, hawaiiProjection, INSET_STATES, US_NON_CONUS;
47277
+ var FIT_PAD, RAMP_FLOOR, R_DEFAULT, R_MIN, R_MAX, W_MIN, W_MAX, FONT, COLO_EPS, LAND_TINT_LIGHT, LAND_TINT_DARK, TAG_TINT_LIGHT, TAG_TINT_DARK, WATER_TINT, RIVER_WIDTH, FOREIGN_TINT_LIGHT, FOREIGN_TINT_DARK, MUTED_WATER_LIGHT, MUTED_WATER_DARK, MUTED_FOREIGN_LIGHT, MUTED_FOREIGN_DARK, MUTED_LAND_DARK, COLO_R, GOLDEN_ANGLE, FAN_STEP, ARC_CURVE_FRAC, usConusProjection, alaskaProjection, hawaiiProjection, INSET_STATES, US_NON_CONUS;
47064
47278
  var init_layout15 = __esm({
47065
47279
  "src/map/layout.ts"() {
47066
47280
  "use strict";
@@ -47085,6 +47299,11 @@ var init_layout15 = __esm({
47085
47299
  RIVER_WIDTH = 1.3;
47086
47300
  FOREIGN_TINT_LIGHT = 30;
47087
47301
  FOREIGN_TINT_DARK = 62;
47302
+ MUTED_WATER_LIGHT = 14;
47303
+ MUTED_WATER_DARK = 10;
47304
+ MUTED_FOREIGN_LIGHT = 28;
47305
+ MUTED_FOREIGN_DARK = 16;
47306
+ MUTED_LAND_DARK = 24;
47088
47307
  COLO_R = 9;
47089
47308
  GOLDEN_ANGLE = 2.399963229728653;
47090
47309
  FAN_STEP = 16;
@@ -47139,7 +47358,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
47139
47358
  const p = g.append("path").attr("d", r.d).attr("fill", r.fill).attr("stroke", r.stroke).attr("stroke-width", strokeWidth);
47140
47359
  if (r.layer !== "base") {
47141
47360
  p.classed("dgmo-map-region", true).attr("data-region", r.id);
47142
- if (r.score !== void 0) p.attr("data-score", r.score);
47361
+ if (r.value !== void 0) p.attr("data-value", r.value);
47143
47362
  if (r.tags) {
47144
47363
  for (const [group, value] of Object.entries(r.tags)) {
47145
47364
  p.attr(`data-tag-${group.toLowerCase()}`, value.toLowerCase());
@@ -47200,6 +47419,11 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
47200
47419
  gPois.append("circle").attr("cx", poi.cx).attr("cy", poi.cy).attr("r", poi.r + 3).attr("fill", "none").attr("stroke", poi.stroke).attr("stroke-width", 1.5);
47201
47420
  }
47202
47421
  const c = gPois.append("circle").attr("cx", poi.cx).attr("cy", poi.cy).attr("r", poi.r).attr("fill", poi.fill).attr("stroke", poi.stroke).attr("stroke-width", 1).attr("data-line-number", poi.lineNumber).attr("data-poi", poi.id);
47422
+ if (poi.tags) {
47423
+ for (const [group, value] of Object.entries(poi.tags)) {
47424
+ c.attr(`data-tag-${group.toLowerCase()}`, value.toLowerCase());
47425
+ }
47426
+ }
47203
47427
  if (onClickItem) {
47204
47428
  c.style("cursor", "pointer").on(
47205
47429
  "click",
@@ -47249,7 +47473,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
47249
47473
  const legendG = svg.append("g").attr("class", "dgmo-map-legend").attr("transform", `translate(0, ${legendY})`);
47250
47474
  const ramp = layout.legend.ramp;
47251
47475
  const scoreGroup = ramp ? {
47252
- name: ramp.metric?.trim() || "Score",
47476
+ name: ramp.metric?.trim() || "Value",
47253
47477
  entries: [],
47254
47478
  gradient: {
47255
47479
  min: ramp.min,