@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/auto.mjs CHANGED
@@ -758,13 +758,9 @@ var init_reserved_key_registry = __esm({
758
758
  "icon"
759
759
  ]);
760
760
  MAP_REGISTRY = staticRegistry([
761
- "score",
761
+ "value",
762
762
  "label",
763
- "size",
764
- "description",
765
- "weight",
766
- "style",
767
- "date"
763
+ "style"
768
764
  ]);
769
765
  ORG_REGISTRY = staticRegistry([
770
766
  "color",
@@ -15795,7 +15791,8 @@ function parseMap(content) {
15795
15791
  continue;
15796
15792
  }
15797
15793
  if (open.route && indent > open.route.indent) {
15798
- open.route.route.stops.push(parseStop(trimmed, lineNumber));
15794
+ const leg = parseLeg(trimmed, lineNumber, open.route.route.style);
15795
+ open.route.route.legs.push(leg);
15799
15796
  continue;
15800
15797
  }
15801
15798
  if (open.poi && indent > open.poi.indent) {
@@ -15826,6 +15823,10 @@ function parseMap(content) {
15826
15823
  handleTag(trimmed, lineNumber);
15827
15824
  continue;
15828
15825
  }
15826
+ if ((firstWord === "muted" || firstWord === "natural") && trimmed === firstWord) {
15827
+ handleDirective(firstWord, "", lineNumber);
15828
+ continue;
15829
+ }
15829
15830
  if (DIRECTIVE_SET.has(firstWord) && !trimmed.slice(firstWord.length).trimStart().startsWith(":")) {
15830
15831
  handleDirective(
15831
15832
  firstWord,
@@ -15890,13 +15891,17 @@ function parseMap(content) {
15890
15891
  );
15891
15892
  d.projection = value;
15892
15893
  break;
15893
- case "metric":
15894
- dup(d.metric);
15895
- d.metric = value;
15894
+ case "region-metric":
15895
+ dup(d.regionMetric);
15896
+ d.regionMetric = value;
15897
+ break;
15898
+ case "poi-metric":
15899
+ dup(d.poiMetric);
15900
+ d.poiMetric = value;
15896
15901
  break;
15897
- case "size-metric":
15898
- dup(d.sizeMetric);
15899
- d.sizeMetric = value;
15902
+ case "flow-metric":
15903
+ dup(d.flowMetric);
15904
+ d.flowMetric = value;
15900
15905
  break;
15901
15906
  case "scale":
15902
15907
  dup(d.scale);
@@ -15938,6 +15943,15 @@ function parseMap(content) {
15938
15943
  case "no-legend":
15939
15944
  d.noLegend = true;
15940
15945
  break;
15946
+ case "muted":
15947
+ case "natural":
15948
+ if (d.basemapStyle !== void 0 && d.basemapStyle !== key)
15949
+ pushWarning(
15950
+ line12,
15951
+ `Conflicting basemap dress \u2014 "${d.basemapStyle}" then "${key}"; last wins.`
15952
+ );
15953
+ d.basemapStyle = key;
15954
+ break;
15941
15955
  case "subtitle":
15942
15956
  dup(d.subtitle);
15943
15957
  d.subtitle = value;
@@ -16015,14 +16029,14 @@ function parseMap(content) {
16015
16029
  line12
16016
16030
  );
16017
16031
  const { tags, meta } = partitionMeta(split.meta, tagGroupNames());
16018
- let scoreNum;
16019
- const score = meta["score"];
16020
- if (score !== void 0) {
16021
- delete meta["score"];
16022
- scoreNum = Number(score);
16023
- if (!Number.isFinite(scoreNum)) {
16024
- pushError(line12, `score must be a number (got "${score}").`);
16025
- scoreNum = void 0;
16032
+ let valueNum;
16033
+ const value = meta["value"];
16034
+ if (value !== void 0) {
16035
+ delete meta["value"];
16036
+ valueNum = Number(value);
16037
+ if (!Number.isFinite(valueNum)) {
16038
+ pushError(line12, `value must be a number (got "${value}").`);
16039
+ valueNum = void 0;
16026
16040
  }
16027
16041
  }
16028
16042
  let regionName = split.name;
@@ -16040,7 +16054,7 @@ function parseMap(content) {
16040
16054
  lineNumber: line12
16041
16055
  };
16042
16056
  if (regionScope !== void 0) region.scope = regionScope;
16043
- if (scoreNum !== void 0) region.score = scoreNum;
16057
+ if (valueNum !== void 0) region.value = valueNum;
16044
16058
  regions.push(region);
16045
16059
  }
16046
16060
  function handlePoi(rest, line12, indent) {
@@ -16069,24 +16083,76 @@ function parseMap(content) {
16069
16083
  open.poi = { poi, indent };
16070
16084
  }
16071
16085
  function handleRoute(rest, line12, indent) {
16072
- const meta = rest ? splitNameAndMeta(rest, registry(), aliasMap).meta : {};
16073
- const route = { stops: [], meta, lineNumber: line12 };
16086
+ const split = rest ? splitNameAndMeta(
16087
+ rest,
16088
+ registry(),
16089
+ aliasMap,
16090
+ void 0,
16091
+ diagnostics,
16092
+ line12
16093
+ ) : { name: "", meta: {}, alias: void 0 };
16094
+ const pos = parsePos(split.name, line12);
16095
+ if (!pos || pos.kind === "name" && !pos.name) {
16096
+ pushError(
16097
+ line12,
16098
+ "route requires an origin: `route <origin> [style: arc]`."
16099
+ );
16100
+ return;
16101
+ }
16102
+ const { tags, meta } = partitionMeta(split.meta, tagGroupNames());
16103
+ const originLabel = meta["label"];
16104
+ const originValue = meta["value"];
16105
+ const style = meta["style"] === "arc" ? "arc" : "straight";
16106
+ const route = {
16107
+ origin: pos,
16108
+ ...split.alias !== void 0 && { originAlias: split.alias },
16109
+ ...originLabel !== void 0 && { originLabel },
16110
+ ...originValue !== void 0 && { originValue },
16111
+ originTags: tags,
16112
+ style,
16113
+ legs: [],
16114
+ lineNumber: line12
16115
+ };
16074
16116
  routes.push(route);
16075
16117
  open.route = { route, indent };
16076
16118
  }
16077
- function parseStop(trimmed, line12) {
16078
- const split = splitNameAndMeta(trimmed, registry(), aliasMap);
16079
- const ref = parsePos(split.name, line12) ?? {
16119
+ function parseLeg(trimmed, line12, headerStyle) {
16120
+ let arrowStyle = "straight";
16121
+ let label;
16122
+ let rest = trimmed;
16123
+ const m = trimmed.match(LEG_ARROW_RE);
16124
+ if (m) {
16125
+ const arr = classifyArrow(m[1], line12);
16126
+ arrowStyle = arr.style;
16127
+ label = arr.label;
16128
+ rest = m[2];
16129
+ }
16130
+ const split = splitNameAndMeta(
16131
+ rest,
16132
+ registry(),
16133
+ aliasMap,
16134
+ void 0,
16135
+ diagnostics,
16136
+ line12
16137
+ );
16138
+ const pos = parsePos(split.name, line12) ?? {
16080
16139
  kind: "name",
16081
16140
  name: split.name
16082
16141
  };
16083
- const stop = {
16084
- ref,
16085
- meta: split.meta,
16142
+ const { tags, meta } = partitionMeta(split.meta, tagGroupNames());
16143
+ const value = meta["value"];
16144
+ const destLabel = meta["label"];
16145
+ const style = arrowStyle === "arc" || headerStyle === "arc" ? "arc" : "straight";
16146
+ return {
16147
+ ...label !== void 0 && { label },
16148
+ style,
16149
+ ...value !== void 0 && { value },
16150
+ dest: pos,
16151
+ ...split.alias !== void 0 && { destAlias: split.alias },
16152
+ ...destLabel !== void 0 && { destLabel },
16153
+ destTags: tags,
16086
16154
  lineNumber: line12
16087
16155
  };
16088
- if (split.alias) stop.alias = split.alias;
16089
- return stop;
16090
16156
  }
16091
16157
  function handleEdges(trimmed, line12) {
16092
16158
  const parts = trimmed.split(ARROW_SPLIT);
@@ -16188,7 +16254,7 @@ function partitionMeta(meta, tagGroupNames) {
16188
16254
  function poiName(pos) {
16189
16255
  return pos.kind === "name" ? pos.name : void 0;
16190
16256
  }
16191
- var COORD_RE, NUMERIC_LEAD_RE, SCOPE_RE, ARROW_SPLIT, HUB_RE, AT_RE, DIRECTIVE_SET;
16257
+ var COORD_RE, NUMERIC_LEAD_RE, SCOPE_RE, ARROW_SPLIT, HUB_RE, LEG_ARROW_RE, AT_RE, DIRECTIVE_SET;
16192
16258
  var init_parser12 = __esm({
16193
16259
  "src/map/parser.ts"() {
16194
16260
  "use strict";
@@ -16202,12 +16268,14 @@ var init_parser12 = __esm({
16202
16268
  SCOPE_RE = /^[A-Z]{2}(?:-[A-Z0-9]{1,3})?$/;
16203
16269
  ARROW_SPLIT = /\s+(-[^>]*?->|->|~[^>]*?~>|~>|--)\s+/;
16204
16270
  HUB_RE = /^(->|~>)\s+(.+)$/;
16271
+ LEG_ARROW_RE = /^(-[^>]*?->|->|~[^>]*?~>|~>|--)\s+(.+)$/;
16205
16272
  AT_RE = /(^|[\s,])at\s*:/i;
16206
16273
  DIRECTIVE_SET = /* @__PURE__ */ new Set([
16207
16274
  "region",
16208
16275
  "projection",
16209
- "metric",
16210
- "size-metric",
16276
+ "region-metric",
16277
+ "poi-metric",
16278
+ "flow-metric",
16211
16279
  "scale",
16212
16280
  "region-labels",
16213
16281
  "poi-labels",
@@ -45492,6 +45560,11 @@ var resolver_exports = {};
45492
45560
  __export(resolver_exports, {
45493
45561
  resolveMap: () => resolveMap
45494
45562
  });
45563
+ function usStateFromBareScope(scope) {
45564
+ if (!scope) return null;
45565
+ const up = scope.toUpperCase();
45566
+ return US_STATE_POSTAL.has(up) ? `US-${up}` : null;
45567
+ }
45495
45568
  function looksUS(lat, lon) {
45496
45569
  if (lat < 15 || lat > 72) return false;
45497
45570
  return lon >= -180 && lon <= -64 || lon >= 172;
@@ -45541,9 +45614,9 @@ function resolveMap(parsed, data) {
45541
45614
  const f = fold(r.name);
45542
45615
  return usStateIndex.has(f) && !countryIndex.has(f);
45543
45616
  }) || parsed.regions.some(
45544
- (r) => r.scope === "US" || r.scope?.startsWith("US-")
45617
+ (r) => r.scope === "US" || r.scope?.startsWith("US-") || usStateFromBareScope(r.scope) !== null
45545
45618
  ) || parsed.pois.some(
45546
- (p) => p.pos.kind === "name" && p.pos.scope?.startsWith("US-")
45619
+ (p) => p.pos.kind === "name" && (p.pos.scope?.startsWith("US-") || usStateFromBareScope(p.pos.scope) !== null)
45547
45620
  );
45548
45621
  const regions = [];
45549
45622
  const seenRegion = /* @__PURE__ */ new Map();
@@ -45610,7 +45683,7 @@ function resolveMap(parsed, data) {
45610
45683
  iso: chosen.id,
45611
45684
  name: chosen.name,
45612
45685
  layer: chosen.layer,
45613
- ...r.score !== void 0 && { score: r.score },
45686
+ ...r.value !== void 0 && { value: r.value },
45614
45687
  tags: r.tags,
45615
45688
  meta: r.meta,
45616
45689
  lineNumber: r.lineNumber
@@ -45668,9 +45741,10 @@ function resolveMap(parsed, data) {
45668
45741
  let cands = idxs.map((i) => data.gazetteer.cities[i]);
45669
45742
  const scopeUse = scope ?? scopeHint;
45670
45743
  if (scopeUse) {
45671
- const isSub = /^[A-Za-z]{2}-/.test(scopeUse);
45744
+ const bareState = usStateFromBareScope(scopeUse);
45745
+ const subScope = /^[A-Za-z]{2}-/.test(scopeUse) ? scopeUse : bareState;
45672
45746
  const filtered = cands.filter(
45673
- (c2) => isSub ? c2[5] === scopeUse : c2[2] === scopeUse
45747
+ (c2) => subScope ? c2[5] === subScope : c2[2] === scopeUse
45674
45748
  );
45675
45749
  if (filtered.length) cands = filtered;
45676
45750
  else if (scope) {
@@ -45799,33 +45873,89 @@ function resolveMap(parsed, data) {
45799
45873
  lineNumber: e.lineNumber
45800
45874
  });
45801
45875
  }
45802
- const routes = [];
45803
- for (const rt of parsed.routes) {
45804
- const stopIds = [];
45805
- for (const stop of rt.stops) {
45806
- let id;
45807
- if (stop.ref.kind === "coords") {
45808
- id = stop.alias ? fold(stop.alias) : `@${stop.ref.lat},${stop.ref.lon}`;
45809
- if (!looksUS(stop.ref.lat, stop.ref.lon)) anyNonUsPoi = true;
45810
- if (!registry.has(id)) {
45811
- const poi = {
45876
+ const resolveStop = (pos, alias, label, tags, sizeValue, line12) => {
45877
+ const meta = sizeValue !== void 0 ? { value: sizeValue } : {};
45878
+ if (pos.kind === "coords") {
45879
+ const id = alias ? fold(alias) : `@${pos.lat},${pos.lon}`;
45880
+ if (!looksUS(pos.lat, pos.lon)) anyNonUsPoi = true;
45881
+ if (!registry.has(id)) {
45882
+ registerPoi(
45883
+ id,
45884
+ {
45812
45885
  id,
45813
- ...stop.alias !== void 0 && { name: stop.alias },
45814
- lat: stop.ref.lat,
45815
- lon: stop.ref.lon,
45816
- tags: {},
45817
- meta: stop.meta,
45818
- lineNumber: stop.lineNumber,
45819
- implicit: true
45820
- };
45821
- registerPoi(id, poi, stop.lineNumber);
45822
- }
45823
- } else {
45824
- id = stop.alias && registry.has(fold(stop.alias)) ? fold(stop.alias) : resolveEndpoint2(stop.ref.name, stop.lineNumber);
45886
+ ...alias !== void 0 && { name: alias },
45887
+ lat: pos.lat,
45888
+ lon: pos.lon,
45889
+ ...label !== void 0 && { label },
45890
+ tags,
45891
+ meta,
45892
+ lineNumber: line12
45893
+ },
45894
+ line12
45895
+ );
45825
45896
  }
45826
- if (id) stopIds.push(id);
45897
+ return id;
45898
+ }
45899
+ const f = fold(pos.name);
45900
+ if (registry.has(f)) return f;
45901
+ const aliased = declaredByName.get(f);
45902
+ if (aliased) return aliased;
45903
+ const got = lookupName(pos.name, pos.scope, line12, inferredCountry, true);
45904
+ if (got.kind !== "ok") return null;
45905
+ noteCountry(got.iso);
45906
+ registerPoi(
45907
+ f,
45908
+ {
45909
+ id: f,
45910
+ name: pos.name,
45911
+ lat: got.lat,
45912
+ lon: got.lon,
45913
+ ...label !== void 0 && { label },
45914
+ tags,
45915
+ meta,
45916
+ lineNumber: line12
45917
+ },
45918
+ line12
45919
+ );
45920
+ return f;
45921
+ };
45922
+ const routes = [];
45923
+ for (const rt of parsed.routes) {
45924
+ const originId = resolveStop(
45925
+ rt.origin,
45926
+ rt.originAlias,
45927
+ rt.originLabel,
45928
+ rt.originTags,
45929
+ rt.originValue,
45930
+ rt.lineNumber
45931
+ );
45932
+ if (!originId) continue;
45933
+ const stopIds = [originId];
45934
+ const legs = [];
45935
+ let prevId = originId;
45936
+ for (const leg of rt.legs) {
45937
+ const destId = resolveStop(
45938
+ leg.dest,
45939
+ leg.destAlias,
45940
+ leg.destLabel,
45941
+ leg.destTags,
45942
+ void 0,
45943
+ // a leg's `value:` is leg thickness, not the dest's size
45944
+ leg.lineNumber
45945
+ );
45946
+ if (!destId) continue;
45947
+ legs.push({
45948
+ fromId: prevId,
45949
+ toId: destId,
45950
+ ...leg.label !== void 0 && { label: leg.label },
45951
+ style: leg.style,
45952
+ ...leg.value !== void 0 && { value: leg.value },
45953
+ lineNumber: leg.lineNumber
45954
+ });
45955
+ if (!stopIds.includes(destId)) stopIds.push(destId);
45956
+ prevId = destId;
45827
45957
  }
45828
- routes.push({ stopIds, meta: rt.meta, lineNumber: rt.lineNumber });
45958
+ routes.push({ stopIds, legs, lineNumber: rt.lineNumber });
45829
45959
  }
45830
45960
  const subdivisions = [];
45831
45961
  if (usSubdivisionReferenced || parsed.directives.region === "us-states")
@@ -45917,7 +46047,7 @@ function firstError(diags) {
45917
46047
  const e = diags.find((d) => d.severity === "error");
45918
46048
  return e ? formatDgmoError(e) : null;
45919
46049
  }
45920
- var WORLD_SPAN, MERCATOR_MAX_SPAN, PAD_FRACTION, WORLD_LAT_SOUTH, WORLD_LAT_NORTH, REGION_ALIASES;
46050
+ var WORLD_SPAN, MERCATOR_MAX_SPAN, PAD_FRACTION, WORLD_LAT_SOUTH, WORLD_LAT_NORTH, REGION_ALIASES, US_STATE_POSTAL;
45921
46051
  var init_resolver2 = __esm({
45922
46052
  "src/map/resolver.ts"() {
45923
46053
  "use strict";
@@ -45949,6 +46079,59 @@ var init_resolver2 = __esm({
45949
46079
  "north macedonia": "macedonia",
45950
46080
  "czech republic": "czechia"
45951
46081
  };
46082
+ US_STATE_POSTAL = /* @__PURE__ */ new Set([
46083
+ "AL",
46084
+ "AK",
46085
+ "AZ",
46086
+ "AR",
46087
+ "CA",
46088
+ "CO",
46089
+ "CT",
46090
+ "DE",
46091
+ "FL",
46092
+ "GA",
46093
+ "HI",
46094
+ "ID",
46095
+ "IL",
46096
+ "IN",
46097
+ "IA",
46098
+ "KS",
46099
+ "KY",
46100
+ "LA",
46101
+ "ME",
46102
+ "MD",
46103
+ "MA",
46104
+ "MI",
46105
+ "MN",
46106
+ "MS",
46107
+ "MO",
46108
+ "MT",
46109
+ "NE",
46110
+ "NV",
46111
+ "NH",
46112
+ "NJ",
46113
+ "NM",
46114
+ "NY",
46115
+ "NC",
46116
+ "ND",
46117
+ "OH",
46118
+ "OK",
46119
+ "OR",
46120
+ "PA",
46121
+ "RI",
46122
+ "SC",
46123
+ "SD",
46124
+ "TN",
46125
+ "TX",
46126
+ "UT",
46127
+ "VT",
46128
+ "VA",
46129
+ "WA",
46130
+ "WV",
46131
+ "WI",
46132
+ "WY",
46133
+ "DC"
46134
+ ]);
45952
46135
  }
45953
46136
  });
45954
46137
 
@@ -46096,9 +46279,24 @@ function projectionFor(family) {
46096
46279
  return geoEquirectangular();
46097
46280
  }
46098
46281
  }
46099
- function mapBackgroundColor(palette) {
46282
+ function mapBackgroundColor(palette, isDark = false, dataActive = false) {
46283
+ if (dataActive)
46284
+ return mix(
46285
+ palette.colors.gray,
46286
+ palette.bg,
46287
+ isDark ? MUTED_WATER_DARK : MUTED_WATER_LIGHT
46288
+ );
46100
46289
  return mix(palette.colors.blue, palette.bg, WATER_TINT);
46101
46290
  }
46291
+ function mapNeutralLandColor(palette, isDark, dataActive = false) {
46292
+ if (dataActive)
46293
+ return isDark ? mix(palette.colors.gray, palette.bg, MUTED_LAND_DARK) : palette.bg;
46294
+ return mix(
46295
+ palette.colors.green,
46296
+ palette.bg,
46297
+ isDark ? LAND_TINT_DARK : LAND_TINT_LIGHT
46298
+ );
46299
+ }
46102
46300
  function layoutMap(resolved, data, size, opts) {
46103
46301
  const { palette, isDark } = opts;
46104
46302
  const { width, height } = size;
@@ -46118,28 +46316,19 @@ function layoutMap(resolved, data, size, opts) {
46118
46316
  }
46119
46317
  }
46120
46318
  const usLayer = wantsUsStates ? decodeLayer(data.usStates) : null;
46121
- const landTint = isDark ? LAND_TINT_DARK : LAND_TINT_LIGHT;
46122
- const neutralFill = mix(palette.colors.green, palette.bg, landTint);
46123
- const water = mapBackgroundColor(palette);
46124
46319
  const usContext = usLayer !== null;
46125
- const foreignFill = mix(
46126
- palette.colors.gray,
46127
- palette.bg,
46128
- isDark ? FOREIGN_TINT_DARK : FOREIGN_TINT_LIGHT
46129
- );
46130
46320
  const regionStroke = isDark ? mix(palette.bg, palette.text, 78) : mix(palette.text, palette.bg, 78);
46131
- const scores = resolved.regions.filter((r) => r.score !== void 0).map((r) => r.score);
46321
+ const values = resolved.regions.filter((r) => r.value !== void 0).map((r) => r.value);
46132
46322
  const scaleOverride = resolved.directives.scale;
46133
- const rampMin = scaleOverride ? scaleOverride.min : Math.min(...scores);
46134
- const rampMax = scaleOverride ? scaleOverride.max : Math.max(...scores);
46323
+ const rampMin = scaleOverride ? scaleOverride.min : Math.min(...values);
46324
+ const rampMax = scaleOverride ? scaleOverride.max : Math.max(...values);
46135
46325
  const rampHue = palette.colors.red;
46136
- const hasRamp = scores.length > 0;
46137
- const SCORE_NAME = hasRamp ? resolved.directives.metric?.trim() || "Score" : null;
46326
+ const hasRamp = values.length > 0;
46327
+ const VALUE_NAME = hasRamp ? resolved.directives.regionMetric?.trim() || "Value" : null;
46138
46328
  const matchColorGroup = (v) => {
46139
46329
  const lv = v.trim().toLowerCase();
46140
46330
  if (lv === "none") return null;
46141
- if (SCORE_NAME && (lv === "score" || lv === SCORE_NAME.toLowerCase()))
46142
- return SCORE_NAME;
46331
+ if (lv === VALUE_NAME?.toLowerCase()) return VALUE_NAME;
46143
46332
  const tg = resolved.tagGroups.find((g) => g.name.toLowerCase() === lv);
46144
46333
  return tg ? tg.name : v;
46145
46334
  };
@@ -46150,11 +46339,19 @@ function layoutMap(resolved, data, size, opts) {
46150
46339
  } else if (resolved.directives.activeTag !== void 0) {
46151
46340
  activeGroup = matchColorGroup(resolved.directives.activeTag);
46152
46341
  } else {
46153
- activeGroup = SCORE_NAME ?? (resolved.tagGroups.length > 0 ? resolved.tagGroups[0].name : null);
46342
+ activeGroup = VALUE_NAME ?? (resolved.tagGroups.length > 0 ? resolved.tagGroups[0].name : null);
46154
46343
  }
46155
- const activeIsScore = SCORE_NAME !== null && activeGroup === SCORE_NAME;
46344
+ const activeIsScore = VALUE_NAME !== null && activeGroup === VALUE_NAME;
46345
+ const mutedBasemap = resolved.directives.basemapStyle === "muted" ? true : resolved.directives.basemapStyle === "natural" ? false : activeGroup !== null;
46346
+ const neutralFill = mapNeutralLandColor(palette, isDark, mutedBasemap);
46347
+ const water = mapBackgroundColor(palette, isDark, mutedBasemap);
46348
+ const foreignFill = mix(
46349
+ palette.colors.gray,
46350
+ palette.bg,
46351
+ mutedBasemap ? isDark ? MUTED_FOREIGN_DARK : MUTED_FOREIGN_LIGHT : isDark ? FOREIGN_TINT_DARK : FOREIGN_TINT_LIGHT
46352
+ );
46156
46353
  const rampBase = isDark ? mix(palette.surface, palette.text, 28) : palette.bg;
46157
- const fillForScore = (s) => {
46354
+ const fillForValue = (s) => {
46158
46355
  const t = rampMax > rampMin ? (s - rampMin) / (rampMax - rampMin) : 1;
46159
46356
  const pct = RAMP_FLOOR + Math.max(0, Math.min(1, t)) * (100 - RAMP_FLOOR);
46160
46357
  return mix(rampHue, rampBase, pct);
@@ -46179,7 +46376,7 @@ function layoutMap(resolved, data, size, opts) {
46179
46376
  };
46180
46377
  const regionFill = (r) => {
46181
46378
  if (activeIsScore) {
46182
- return r.score !== void 0 ? fillForScore(r.score) : neutralFill;
46379
+ return r.value !== void 0 ? fillForValue(r.value) : neutralFill;
46183
46380
  }
46184
46381
  return tagFill(r.tags, activeGroup) ?? neutralFill;
46185
46382
  };
@@ -46391,7 +46588,7 @@ function layoutMap(resolved, data, size, opts) {
46391
46588
  stroke: regionStroke,
46392
46589
  lineNumber,
46393
46590
  layer: "us-state",
46394
- ...r?.score !== void 0 && { score: r.score },
46591
+ ...r?.value !== void 0 && { value: r.value },
46395
46592
  ...r && Object.keys(r.tags).length > 0 && { tags: r.tags }
46396
46593
  });
46397
46594
  const ctr = geoPath(proj).centroid(f);
@@ -46507,6 +46704,8 @@ function layoutMap(resolved, data, size, opts) {
46507
46704
  if (layerKind === "us-state" && usContext && INSET_STATES.has(iso))
46508
46705
  continue;
46509
46706
  if (layerKind === "country" && usContext && iso === "US") continue;
46707
+ if (layerKind === "country" && iso === "AQ" && !regionById.has("AQ"))
46708
+ continue;
46510
46709
  const r = regionById.get(iso);
46511
46710
  const viewF = shouldCull ? cullFeatureToView(f) : dropFrameFillers(f);
46512
46711
  if (!viewF) continue;
@@ -46532,7 +46731,7 @@ function layoutMap(resolved, data, size, opts) {
46532
46731
  lineNumber,
46533
46732
  layer,
46534
46733
  ...label !== void 0 && { label },
46535
- ...isThisLayer && r.score !== void 0 && { score: r.score },
46734
+ ...isThisLayer && r.value !== void 0 && { value: r.value },
46536
46735
  ...isThisLayer && Object.keys(r.tags).length > 0 && { tags: r.tags }
46537
46736
  });
46538
46737
  }
@@ -46567,11 +46766,11 @@ function layoutMap(resolved, data, size, opts) {
46567
46766
  rivers.push({ d, color: riverColor, width: RIVER_WIDTH });
46568
46767
  }
46569
46768
  }
46570
- const sizeVals = resolved.pois.map((p) => Number(p.meta["size"])).filter((n) => Number.isFinite(n) && n > 0);
46769
+ const sizeVals = resolved.pois.map((p) => Number(p.meta["value"])).filter((n) => Number.isFinite(n) && n > 0);
46571
46770
  const sizeMin = sizeVals.length ? Math.min(...sizeVals) : 0;
46572
46771
  const sizeMax = sizeVals.length ? Math.max(...sizeVals) : 0;
46573
46772
  const radiusFor = (p) => {
46574
- const v = Number(p.meta["size"]);
46773
+ const v = Number(p.meta["value"]);
46575
46774
  if (!Number.isFinite(v) || v <= 0 || sizeMax <= 0) return R_DEFAULT;
46576
46775
  const t = sizeMax > sizeMin ? (Math.sqrt(v) - Math.sqrt(sizeMin)) / (Math.sqrt(sizeMax) - Math.sqrt(sizeMin)) : 1;
46577
46776
  return R_MIN + Math.max(0, Math.min(1, t)) * (R_MAX - R_MIN);
@@ -46638,7 +46837,8 @@ function layoutMap(resolved, data, size, opts) {
46638
46837
  lineNumber: e.p.lineNumber,
46639
46838
  implicit: !!e.p.implicit,
46640
46839
  isOrigin: originIds.has(e.p.id),
46641
- ...num !== void 0 && { routeNumber: num }
46840
+ ...num !== void 0 && { routeNumber: num },
46841
+ ...Object.keys(e.p.tags).length > 0 && { tags: e.p.tags }
46642
46842
  });
46643
46843
  });
46644
46844
  }
@@ -46674,26 +46874,40 @@ function layoutMap(resolved, data, size, opts) {
46674
46874
  const by = b.cy - (b.cy - py) / tb * trimB;
46675
46875
  return `M${ax},${ay}Q${px},${py} ${bx},${by}`;
46676
46876
  };
46877
+ const routeLegVals = resolved.routes.flatMap((rt) => rt.legs).map((l) => Number(l.value)).filter((n) => Number.isFinite(n) && n > 0);
46878
+ const rlMin = routeLegVals.length ? Math.min(...routeLegVals) : 0;
46879
+ const rlMax = routeLegVals.length ? Math.max(...routeLegVals) : 0;
46880
+ const routeWidthFor = (v) => {
46881
+ if (!Number.isFinite(v) || v <= 0 || rlMax <= 0) return W_MIN;
46882
+ const t = rlMax > rlMin ? (v - rlMin) / (rlMax - rlMin) : 1;
46883
+ return W_MIN + t * (W_MAX - W_MIN);
46884
+ };
46677
46885
  for (const rt of resolved.routes) {
46678
- const curved = rt.meta["style"] === "arc";
46679
- for (let i = 1; i < rt.stopIds.length; i++) {
46680
- const a = poiScreen.get(rt.stopIds[i - 1]);
46681
- const b = poiScreen.get(rt.stopIds[i]);
46886
+ for (const leg of rt.legs) {
46887
+ const a = poiScreen.get(leg.fromId);
46888
+ const b = poiScreen.get(leg.toId);
46682
46889
  if (!a || !b) continue;
46890
+ const mx = (a.cx + b.cx) / 2;
46891
+ const my = (a.cy + b.cy) / 2;
46683
46892
  legs.push({
46684
- d: legPath(a, b, curved, 0),
46685
- width: W_MIN,
46893
+ d: legPath(a, b, leg.style === "arc", 0),
46894
+ width: routeWidthFor(Number(leg.value)),
46686
46895
  color: mix(palette.text, palette.bg, 72),
46687
46896
  arrow: true,
46688
- lineNumber: rt.lineNumber
46897
+ lineNumber: leg.lineNumber,
46898
+ ...leg.label !== void 0 && {
46899
+ label: leg.label,
46900
+ labelX: mx,
46901
+ labelY: my - 4
46902
+ }
46689
46903
  });
46690
46904
  }
46691
46905
  }
46692
- const weightVals = resolved.edges.map((e) => Number(e.meta["weight"])).filter((n) => Number.isFinite(n) && n > 0);
46906
+ const weightVals = resolved.edges.map((e) => Number(e.meta["value"])).filter((n) => Number.isFinite(n) && n > 0);
46693
46907
  const wMin = weightVals.length ? Math.min(...weightVals) : 0;
46694
46908
  const wMax = weightVals.length ? Math.max(...weightVals) : 0;
46695
46909
  const widthFor = (e) => {
46696
- const v = Number(e.meta["weight"]);
46910
+ const v = Number(e.meta["value"]);
46697
46911
  if (!Number.isFinite(v) || v <= 0 || wMax <= 0) return W_MIN;
46698
46912
  const t = wMax > wMin ? (v - wMin) / (wMax - wMin) : 1;
46699
46913
  return W_MIN + t * (W_MAX - W_MIN);
@@ -46956,8 +47170,8 @@ function layoutMap(resolved, data, size, opts) {
46956
47170
  activeGroup,
46957
47171
  ...hasRamp && {
46958
47172
  ramp: {
46959
- ...resolved.directives.metric !== void 0 && {
46960
- metric: resolved.directives.metric
47173
+ ...resolved.directives.regionMetric !== void 0 && {
47174
+ metric: resolved.directives.regionMetric
46961
47175
  },
46962
47176
  min: rampMin,
46963
47177
  max: rampMax,
@@ -46985,7 +47199,7 @@ function layoutMap(resolved, data, size, opts) {
46985
47199
  insetRegions
46986
47200
  };
46987
47201
  }
46988
- 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;
47202
+ 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;
46989
47203
  var init_layout15 = __esm({
46990
47204
  "src/map/layout.ts"() {
46991
47205
  "use strict";
@@ -47010,6 +47224,11 @@ var init_layout15 = __esm({
47010
47224
  RIVER_WIDTH = 1.3;
47011
47225
  FOREIGN_TINT_LIGHT = 30;
47012
47226
  FOREIGN_TINT_DARK = 62;
47227
+ MUTED_WATER_LIGHT = 14;
47228
+ MUTED_WATER_DARK = 10;
47229
+ MUTED_FOREIGN_LIGHT = 28;
47230
+ MUTED_FOREIGN_DARK = 16;
47231
+ MUTED_LAND_DARK = 24;
47013
47232
  COLO_R = 9;
47014
47233
  GOLDEN_ANGLE = 2.399963229728653;
47015
47234
  FAN_STEP = 16;
@@ -47064,7 +47283,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
47064
47283
  const p = g.append("path").attr("d", r.d).attr("fill", r.fill).attr("stroke", r.stroke).attr("stroke-width", strokeWidth);
47065
47284
  if (r.layer !== "base") {
47066
47285
  p.classed("dgmo-map-region", true).attr("data-region", r.id);
47067
- if (r.score !== void 0) p.attr("data-score", r.score);
47286
+ if (r.value !== void 0) p.attr("data-value", r.value);
47068
47287
  if (r.tags) {
47069
47288
  for (const [group, value] of Object.entries(r.tags)) {
47070
47289
  p.attr(`data-tag-${group.toLowerCase()}`, value.toLowerCase());
@@ -47125,6 +47344,11 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
47125
47344
  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);
47126
47345
  }
47127
47346
  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);
47347
+ if (poi.tags) {
47348
+ for (const [group, value] of Object.entries(poi.tags)) {
47349
+ c.attr(`data-tag-${group.toLowerCase()}`, value.toLowerCase());
47350
+ }
47351
+ }
47128
47352
  if (onClickItem) {
47129
47353
  c.style("cursor", "pointer").on(
47130
47354
  "click",
@@ -47174,7 +47398,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
47174
47398
  const legendG = svg.append("g").attr("class", "dgmo-map-legend").attr("transform", `translate(0, ${legendY})`);
47175
47399
  const ramp = layout.legend.ramp;
47176
47400
  const scoreGroup = ramp ? {
47177
- name: ramp.metric?.trim() || "Score",
47401
+ name: ramp.metric?.trim() || "Value",
47178
47402
  entries: [],
47179
47403
  gradient: {
47180
47404
  min: ramp.min,
@@ -56403,13 +56627,16 @@ var DIRECTIVE_KEYWORDS = /* @__PURE__ */ new Set([
56403
56627
  // Map (§24B) directives
56404
56628
  "region",
56405
56629
  "projection",
56406
- "metric",
56407
- "size-metric",
56630
+ "region-metric",
56631
+ "poi-metric",
56632
+ "flow-metric",
56408
56633
  "region-labels",
56409
56634
  "poi-labels",
56410
56635
  "default-country",
56411
56636
  "default-state",
56412
56637
  "no-legend",
56638
+ "muted",
56639
+ "natural",
56413
56640
  "subtitle",
56414
56641
  "caption",
56415
56642
  "poi",
@@ -57077,7 +57304,7 @@ pre.dgmo, code.language-dgmo, pre > code.language-dgmo,
57077
57304
 
57078
57305
  // src/auto/index.ts
57079
57306
  init_safe_href();
57080
- var VERSION = "0.20.2";
57307
+ var VERSION = "0.21.0";
57081
57308
  var DEFAULTS = {
57082
57309
  theme: "auto",
57083
57310
  palette: "nord",