@diagrammo/dgmo 0.20.3 → 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.cjs CHANGED
@@ -760,13 +760,9 @@ var init_reserved_key_registry = __esm({
760
760
  "icon"
761
761
  ]);
762
762
  MAP_REGISTRY = staticRegistry([
763
- "score",
763
+ "value",
764
764
  "label",
765
- "size",
766
- "description",
767
- "weight",
768
- "style",
769
- "date"
765
+ "style"
770
766
  ]);
771
767
  ORG_REGISTRY = staticRegistry([
772
768
  "color",
@@ -15779,7 +15775,8 @@ function parseMap(content) {
15779
15775
  continue;
15780
15776
  }
15781
15777
  if (open.route && indent > open.route.indent) {
15782
- open.route.route.stops.push(parseStop(trimmed, lineNumber));
15778
+ const leg = parseLeg(trimmed, lineNumber, open.route.route.style);
15779
+ open.route.route.legs.push(leg);
15783
15780
  continue;
15784
15781
  }
15785
15782
  if (open.poi && indent > open.poi.indent) {
@@ -15810,6 +15807,10 @@ function parseMap(content) {
15810
15807
  handleTag(trimmed, lineNumber);
15811
15808
  continue;
15812
15809
  }
15810
+ if ((firstWord === "muted" || firstWord === "natural") && trimmed === firstWord) {
15811
+ handleDirective(firstWord, "", lineNumber);
15812
+ continue;
15813
+ }
15813
15814
  if (DIRECTIVE_SET.has(firstWord) && !trimmed.slice(firstWord.length).trimStart().startsWith(":")) {
15814
15815
  handleDirective(
15815
15816
  firstWord,
@@ -15874,13 +15875,17 @@ function parseMap(content) {
15874
15875
  );
15875
15876
  d.projection = value;
15876
15877
  break;
15877
- case "metric":
15878
- dup(d.metric);
15879
- d.metric = value;
15878
+ case "region-metric":
15879
+ dup(d.regionMetric);
15880
+ d.regionMetric = value;
15881
+ break;
15882
+ case "poi-metric":
15883
+ dup(d.poiMetric);
15884
+ d.poiMetric = value;
15880
15885
  break;
15881
- case "size-metric":
15882
- dup(d.sizeMetric);
15883
- d.sizeMetric = value;
15886
+ case "flow-metric":
15887
+ dup(d.flowMetric);
15888
+ d.flowMetric = value;
15884
15889
  break;
15885
15890
  case "scale":
15886
15891
  dup(d.scale);
@@ -15922,6 +15927,15 @@ function parseMap(content) {
15922
15927
  case "no-legend":
15923
15928
  d.noLegend = true;
15924
15929
  break;
15930
+ case "muted":
15931
+ case "natural":
15932
+ if (d.basemapStyle !== void 0 && d.basemapStyle !== key)
15933
+ pushWarning(
15934
+ line12,
15935
+ `Conflicting basemap dress \u2014 "${d.basemapStyle}" then "${key}"; last wins.`
15936
+ );
15937
+ d.basemapStyle = key;
15938
+ break;
15925
15939
  case "subtitle":
15926
15940
  dup(d.subtitle);
15927
15941
  d.subtitle = value;
@@ -15999,14 +16013,14 @@ function parseMap(content) {
15999
16013
  line12
16000
16014
  );
16001
16015
  const { tags, meta } = partitionMeta(split.meta, tagGroupNames());
16002
- let scoreNum;
16003
- const score = meta["score"];
16004
- if (score !== void 0) {
16005
- delete meta["score"];
16006
- scoreNum = Number(score);
16007
- if (!Number.isFinite(scoreNum)) {
16008
- pushError(line12, `score must be a number (got "${score}").`);
16009
- scoreNum = void 0;
16016
+ let valueNum;
16017
+ const value = meta["value"];
16018
+ if (value !== void 0) {
16019
+ delete meta["value"];
16020
+ valueNum = Number(value);
16021
+ if (!Number.isFinite(valueNum)) {
16022
+ pushError(line12, `value must be a number (got "${value}").`);
16023
+ valueNum = void 0;
16010
16024
  }
16011
16025
  }
16012
16026
  let regionName = split.name;
@@ -16024,7 +16038,7 @@ function parseMap(content) {
16024
16038
  lineNumber: line12
16025
16039
  };
16026
16040
  if (regionScope !== void 0) region.scope = regionScope;
16027
- if (scoreNum !== void 0) region.score = scoreNum;
16041
+ if (valueNum !== void 0) region.value = valueNum;
16028
16042
  regions.push(region);
16029
16043
  }
16030
16044
  function handlePoi(rest, line12, indent) {
@@ -16053,24 +16067,76 @@ function parseMap(content) {
16053
16067
  open.poi = { poi, indent };
16054
16068
  }
16055
16069
  function handleRoute(rest, line12, indent) {
16056
- const meta = rest ? splitNameAndMeta(rest, registry(), aliasMap).meta : {};
16057
- const route = { stops: [], meta, lineNumber: line12 };
16070
+ const split = rest ? splitNameAndMeta(
16071
+ rest,
16072
+ registry(),
16073
+ aliasMap,
16074
+ void 0,
16075
+ diagnostics,
16076
+ line12
16077
+ ) : { name: "", meta: {}, alias: void 0 };
16078
+ const pos = parsePos(split.name, line12);
16079
+ if (!pos || pos.kind === "name" && !pos.name) {
16080
+ pushError(
16081
+ line12,
16082
+ "route requires an origin: `route <origin> [style: arc]`."
16083
+ );
16084
+ return;
16085
+ }
16086
+ const { tags, meta } = partitionMeta(split.meta, tagGroupNames());
16087
+ const originLabel = meta["label"];
16088
+ const originValue = meta["value"];
16089
+ const style = meta["style"] === "arc" ? "arc" : "straight";
16090
+ const route = {
16091
+ origin: pos,
16092
+ ...split.alias !== void 0 && { originAlias: split.alias },
16093
+ ...originLabel !== void 0 && { originLabel },
16094
+ ...originValue !== void 0 && { originValue },
16095
+ originTags: tags,
16096
+ style,
16097
+ legs: [],
16098
+ lineNumber: line12
16099
+ };
16058
16100
  routes.push(route);
16059
16101
  open.route = { route, indent };
16060
16102
  }
16061
- function parseStop(trimmed, line12) {
16062
- const split = splitNameAndMeta(trimmed, registry(), aliasMap);
16063
- const ref = parsePos(split.name, line12) ?? {
16103
+ function parseLeg(trimmed, line12, headerStyle) {
16104
+ let arrowStyle = "straight";
16105
+ let label;
16106
+ let rest = trimmed;
16107
+ const m = trimmed.match(LEG_ARROW_RE);
16108
+ if (m) {
16109
+ const arr = classifyArrow(m[1], line12);
16110
+ arrowStyle = arr.style;
16111
+ label = arr.label;
16112
+ rest = m[2];
16113
+ }
16114
+ const split = splitNameAndMeta(
16115
+ rest,
16116
+ registry(),
16117
+ aliasMap,
16118
+ void 0,
16119
+ diagnostics,
16120
+ line12
16121
+ );
16122
+ const pos = parsePos(split.name, line12) ?? {
16064
16123
  kind: "name",
16065
16124
  name: split.name
16066
16125
  };
16067
- const stop = {
16068
- ref,
16069
- meta: split.meta,
16126
+ const { tags, meta } = partitionMeta(split.meta, tagGroupNames());
16127
+ const value = meta["value"];
16128
+ const destLabel = meta["label"];
16129
+ const style = arrowStyle === "arc" || headerStyle === "arc" ? "arc" : "straight";
16130
+ return {
16131
+ ...label !== void 0 && { label },
16132
+ style,
16133
+ ...value !== void 0 && { value },
16134
+ dest: pos,
16135
+ ...split.alias !== void 0 && { destAlias: split.alias },
16136
+ ...destLabel !== void 0 && { destLabel },
16137
+ destTags: tags,
16070
16138
  lineNumber: line12
16071
16139
  };
16072
- if (split.alias) stop.alias = split.alias;
16073
- return stop;
16074
16140
  }
16075
16141
  function handleEdges(trimmed, line12) {
16076
16142
  const parts = trimmed.split(ARROW_SPLIT);
@@ -16172,7 +16238,7 @@ function partitionMeta(meta, tagGroupNames) {
16172
16238
  function poiName(pos) {
16173
16239
  return pos.kind === "name" ? pos.name : void 0;
16174
16240
  }
16175
- var COORD_RE, NUMERIC_LEAD_RE, SCOPE_RE, ARROW_SPLIT, HUB_RE, AT_RE, DIRECTIVE_SET;
16241
+ var COORD_RE, NUMERIC_LEAD_RE, SCOPE_RE, ARROW_SPLIT, HUB_RE, LEG_ARROW_RE, AT_RE, DIRECTIVE_SET;
16176
16242
  var init_parser12 = __esm({
16177
16243
  "src/map/parser.ts"() {
16178
16244
  "use strict";
@@ -16186,12 +16252,14 @@ var init_parser12 = __esm({
16186
16252
  SCOPE_RE = /^[A-Z]{2}(?:-[A-Z0-9]{1,3})?$/;
16187
16253
  ARROW_SPLIT = /\s+(-[^>]*?->|->|~[^>]*?~>|~>|--)\s+/;
16188
16254
  HUB_RE = /^(->|~>)\s+(.+)$/;
16255
+ LEG_ARROW_RE = /^(-[^>]*?->|->|~[^>]*?~>|~>|--)\s+(.+)$/;
16189
16256
  AT_RE = /(^|[\s,])at\s*:/i;
16190
16257
  DIRECTIVE_SET = /* @__PURE__ */ new Set([
16191
16258
  "region",
16192
16259
  "projection",
16193
- "metric",
16194
- "size-metric",
16260
+ "region-metric",
16261
+ "poi-metric",
16262
+ "flow-metric",
16195
16263
  "scale",
16196
16264
  "region-labels",
16197
16265
  "poi-labels",
@@ -45476,6 +45544,11 @@ var resolver_exports = {};
45476
45544
  __export(resolver_exports, {
45477
45545
  resolveMap: () => resolveMap
45478
45546
  });
45547
+ function usStateFromBareScope(scope) {
45548
+ if (!scope) return null;
45549
+ const up = scope.toUpperCase();
45550
+ return US_STATE_POSTAL.has(up) ? `US-${up}` : null;
45551
+ }
45479
45552
  function looksUS(lat, lon) {
45480
45553
  if (lat < 15 || lat > 72) return false;
45481
45554
  return lon >= -180 && lon <= -64 || lon >= 172;
@@ -45525,9 +45598,9 @@ function resolveMap(parsed, data) {
45525
45598
  const f = fold(r.name);
45526
45599
  return usStateIndex.has(f) && !countryIndex.has(f);
45527
45600
  }) || parsed.regions.some(
45528
- (r) => r.scope === "US" || r.scope?.startsWith("US-")
45601
+ (r) => r.scope === "US" || r.scope?.startsWith("US-") || usStateFromBareScope(r.scope) !== null
45529
45602
  ) || parsed.pois.some(
45530
- (p) => p.pos.kind === "name" && p.pos.scope?.startsWith("US-")
45603
+ (p) => p.pos.kind === "name" && (p.pos.scope?.startsWith("US-") || usStateFromBareScope(p.pos.scope) !== null)
45531
45604
  );
45532
45605
  const regions = [];
45533
45606
  const seenRegion = /* @__PURE__ */ new Map();
@@ -45594,7 +45667,7 @@ function resolveMap(parsed, data) {
45594
45667
  iso: chosen.id,
45595
45668
  name: chosen.name,
45596
45669
  layer: chosen.layer,
45597
- ...r.score !== void 0 && { score: r.score },
45670
+ ...r.value !== void 0 && { value: r.value },
45598
45671
  tags: r.tags,
45599
45672
  meta: r.meta,
45600
45673
  lineNumber: r.lineNumber
@@ -45652,9 +45725,10 @@ function resolveMap(parsed, data) {
45652
45725
  let cands = idxs.map((i) => data.gazetteer.cities[i]);
45653
45726
  const scopeUse = scope ?? scopeHint;
45654
45727
  if (scopeUse) {
45655
- const isSub = /^[A-Za-z]{2}-/.test(scopeUse);
45728
+ const bareState = usStateFromBareScope(scopeUse);
45729
+ const subScope = /^[A-Za-z]{2}-/.test(scopeUse) ? scopeUse : bareState;
45656
45730
  const filtered = cands.filter(
45657
- (c2) => isSub ? c2[5] === scopeUse : c2[2] === scopeUse
45731
+ (c2) => subScope ? c2[5] === subScope : c2[2] === scopeUse
45658
45732
  );
45659
45733
  if (filtered.length) cands = filtered;
45660
45734
  else if (scope) {
@@ -45783,33 +45857,89 @@ function resolveMap(parsed, data) {
45783
45857
  lineNumber: e.lineNumber
45784
45858
  });
45785
45859
  }
45786
- const routes = [];
45787
- for (const rt of parsed.routes) {
45788
- const stopIds = [];
45789
- for (const stop of rt.stops) {
45790
- let id;
45791
- if (stop.ref.kind === "coords") {
45792
- id = stop.alias ? fold(stop.alias) : `@${stop.ref.lat},${stop.ref.lon}`;
45793
- if (!looksUS(stop.ref.lat, stop.ref.lon)) anyNonUsPoi = true;
45794
- if (!registry.has(id)) {
45795
- const poi = {
45860
+ const resolveStop = (pos, alias, label, tags, sizeValue, line12) => {
45861
+ const meta = sizeValue !== void 0 ? { value: sizeValue } : {};
45862
+ if (pos.kind === "coords") {
45863
+ const id = alias ? fold(alias) : `@${pos.lat},${pos.lon}`;
45864
+ if (!looksUS(pos.lat, pos.lon)) anyNonUsPoi = true;
45865
+ if (!registry.has(id)) {
45866
+ registerPoi(
45867
+ id,
45868
+ {
45796
45869
  id,
45797
- ...stop.alias !== void 0 && { name: stop.alias },
45798
- lat: stop.ref.lat,
45799
- lon: stop.ref.lon,
45800
- tags: {},
45801
- meta: stop.meta,
45802
- lineNumber: stop.lineNumber,
45803
- implicit: true
45804
- };
45805
- registerPoi(id, poi, stop.lineNumber);
45806
- }
45807
- } else {
45808
- id = stop.alias && registry.has(fold(stop.alias)) ? fold(stop.alias) : resolveEndpoint2(stop.ref.name, stop.lineNumber);
45870
+ ...alias !== void 0 && { name: alias },
45871
+ lat: pos.lat,
45872
+ lon: pos.lon,
45873
+ ...label !== void 0 && { label },
45874
+ tags,
45875
+ meta,
45876
+ lineNumber: line12
45877
+ },
45878
+ line12
45879
+ );
45809
45880
  }
45810
- if (id) stopIds.push(id);
45881
+ return id;
45882
+ }
45883
+ const f = fold(pos.name);
45884
+ if (registry.has(f)) return f;
45885
+ const aliased = declaredByName.get(f);
45886
+ if (aliased) return aliased;
45887
+ const got = lookupName(pos.name, pos.scope, line12, inferredCountry, true);
45888
+ if (got.kind !== "ok") return null;
45889
+ noteCountry(got.iso);
45890
+ registerPoi(
45891
+ f,
45892
+ {
45893
+ id: f,
45894
+ name: pos.name,
45895
+ lat: got.lat,
45896
+ lon: got.lon,
45897
+ ...label !== void 0 && { label },
45898
+ tags,
45899
+ meta,
45900
+ lineNumber: line12
45901
+ },
45902
+ line12
45903
+ );
45904
+ return f;
45905
+ };
45906
+ const routes = [];
45907
+ for (const rt of parsed.routes) {
45908
+ const originId = resolveStop(
45909
+ rt.origin,
45910
+ rt.originAlias,
45911
+ rt.originLabel,
45912
+ rt.originTags,
45913
+ rt.originValue,
45914
+ rt.lineNumber
45915
+ );
45916
+ if (!originId) continue;
45917
+ const stopIds = [originId];
45918
+ const legs = [];
45919
+ let prevId = originId;
45920
+ for (const leg of rt.legs) {
45921
+ const destId = resolveStop(
45922
+ leg.dest,
45923
+ leg.destAlias,
45924
+ leg.destLabel,
45925
+ leg.destTags,
45926
+ void 0,
45927
+ // a leg's `value:` is leg thickness, not the dest's size
45928
+ leg.lineNumber
45929
+ );
45930
+ if (!destId) continue;
45931
+ legs.push({
45932
+ fromId: prevId,
45933
+ toId: destId,
45934
+ ...leg.label !== void 0 && { label: leg.label },
45935
+ style: leg.style,
45936
+ ...leg.value !== void 0 && { value: leg.value },
45937
+ lineNumber: leg.lineNumber
45938
+ });
45939
+ if (!stopIds.includes(destId)) stopIds.push(destId);
45940
+ prevId = destId;
45811
45941
  }
45812
- routes.push({ stopIds, meta: rt.meta, lineNumber: rt.lineNumber });
45942
+ routes.push({ stopIds, legs, lineNumber: rt.lineNumber });
45813
45943
  }
45814
45944
  const subdivisions = [];
45815
45945
  if (usSubdivisionReferenced || parsed.directives.region === "us-states")
@@ -45901,7 +46031,7 @@ function firstError(diags) {
45901
46031
  const e = diags.find((d) => d.severity === "error");
45902
46032
  return e ? formatDgmoError(e) : null;
45903
46033
  }
45904
- var WORLD_SPAN, MERCATOR_MAX_SPAN, PAD_FRACTION, WORLD_LAT_SOUTH, WORLD_LAT_NORTH, REGION_ALIASES;
46034
+ var WORLD_SPAN, MERCATOR_MAX_SPAN, PAD_FRACTION, WORLD_LAT_SOUTH, WORLD_LAT_NORTH, REGION_ALIASES, US_STATE_POSTAL;
45905
46035
  var init_resolver2 = __esm({
45906
46036
  "src/map/resolver.ts"() {
45907
46037
  "use strict";
@@ -45933,6 +46063,59 @@ var init_resolver2 = __esm({
45933
46063
  "north macedonia": "macedonia",
45934
46064
  "czech republic": "czechia"
45935
46065
  };
46066
+ US_STATE_POSTAL = /* @__PURE__ */ new Set([
46067
+ "AL",
46068
+ "AK",
46069
+ "AZ",
46070
+ "AR",
46071
+ "CA",
46072
+ "CO",
46073
+ "CT",
46074
+ "DE",
46075
+ "FL",
46076
+ "GA",
46077
+ "HI",
46078
+ "ID",
46079
+ "IL",
46080
+ "IN",
46081
+ "IA",
46082
+ "KS",
46083
+ "KY",
46084
+ "LA",
46085
+ "ME",
46086
+ "MD",
46087
+ "MA",
46088
+ "MI",
46089
+ "MN",
46090
+ "MS",
46091
+ "MO",
46092
+ "MT",
46093
+ "NE",
46094
+ "NV",
46095
+ "NH",
46096
+ "NJ",
46097
+ "NM",
46098
+ "NY",
46099
+ "NC",
46100
+ "ND",
46101
+ "OH",
46102
+ "OK",
46103
+ "OR",
46104
+ "PA",
46105
+ "RI",
46106
+ "SC",
46107
+ "SD",
46108
+ "TN",
46109
+ "TX",
46110
+ "UT",
46111
+ "VT",
46112
+ "VA",
46113
+ "WA",
46114
+ "WV",
46115
+ "WI",
46116
+ "WY",
46117
+ "DC"
46118
+ ]);
45936
46119
  }
45937
46120
  });
45938
46121
 
@@ -46071,9 +46254,24 @@ function projectionFor(family) {
46071
46254
  return (0, import_d3_geo2.geoEquirectangular)();
46072
46255
  }
46073
46256
  }
46074
- function mapBackgroundColor(palette) {
46257
+ function mapBackgroundColor(palette, isDark = false, dataActive = false) {
46258
+ if (dataActive)
46259
+ return mix(
46260
+ palette.colors.gray,
46261
+ palette.bg,
46262
+ isDark ? MUTED_WATER_DARK : MUTED_WATER_LIGHT
46263
+ );
46075
46264
  return mix(palette.colors.blue, palette.bg, WATER_TINT);
46076
46265
  }
46266
+ function mapNeutralLandColor(palette, isDark, dataActive = false) {
46267
+ if (dataActive)
46268
+ return isDark ? mix(palette.colors.gray, palette.bg, MUTED_LAND_DARK) : palette.bg;
46269
+ return mix(
46270
+ palette.colors.green,
46271
+ palette.bg,
46272
+ isDark ? LAND_TINT_DARK : LAND_TINT_LIGHT
46273
+ );
46274
+ }
46077
46275
  function layoutMap(resolved, data, size, opts) {
46078
46276
  const { palette, isDark } = opts;
46079
46277
  const { width, height } = size;
@@ -46093,28 +46291,19 @@ function layoutMap(resolved, data, size, opts) {
46093
46291
  }
46094
46292
  }
46095
46293
  const usLayer = wantsUsStates ? decodeLayer(data.usStates) : null;
46096
- const landTint = isDark ? LAND_TINT_DARK : LAND_TINT_LIGHT;
46097
- const neutralFill = mix(palette.colors.green, palette.bg, landTint);
46098
- const water = mapBackgroundColor(palette);
46099
46294
  const usContext = usLayer !== null;
46100
- const foreignFill = mix(
46101
- palette.colors.gray,
46102
- palette.bg,
46103
- isDark ? FOREIGN_TINT_DARK : FOREIGN_TINT_LIGHT
46104
- );
46105
46295
  const regionStroke = isDark ? mix(palette.bg, palette.text, 78) : mix(palette.text, palette.bg, 78);
46106
- const scores = resolved.regions.filter((r) => r.score !== void 0).map((r) => r.score);
46296
+ const values = resolved.regions.filter((r) => r.value !== void 0).map((r) => r.value);
46107
46297
  const scaleOverride = resolved.directives.scale;
46108
- const rampMin = scaleOverride ? scaleOverride.min : Math.min(...scores);
46109
- const rampMax = scaleOverride ? scaleOverride.max : Math.max(...scores);
46298
+ const rampMin = scaleOverride ? scaleOverride.min : Math.min(...values);
46299
+ const rampMax = scaleOverride ? scaleOverride.max : Math.max(...values);
46110
46300
  const rampHue = palette.colors.red;
46111
- const hasRamp = scores.length > 0;
46112
- const SCORE_NAME = hasRamp ? resolved.directives.metric?.trim() || "Score" : null;
46301
+ const hasRamp = values.length > 0;
46302
+ const VALUE_NAME = hasRamp ? resolved.directives.regionMetric?.trim() || "Value" : null;
46113
46303
  const matchColorGroup = (v) => {
46114
46304
  const lv = v.trim().toLowerCase();
46115
46305
  if (lv === "none") return null;
46116
- if (SCORE_NAME && (lv === "score" || lv === SCORE_NAME.toLowerCase()))
46117
- return SCORE_NAME;
46306
+ if (lv === VALUE_NAME?.toLowerCase()) return VALUE_NAME;
46118
46307
  const tg = resolved.tagGroups.find((g) => g.name.toLowerCase() === lv);
46119
46308
  return tg ? tg.name : v;
46120
46309
  };
@@ -46125,11 +46314,19 @@ function layoutMap(resolved, data, size, opts) {
46125
46314
  } else if (resolved.directives.activeTag !== void 0) {
46126
46315
  activeGroup = matchColorGroup(resolved.directives.activeTag);
46127
46316
  } else {
46128
- activeGroup = SCORE_NAME ?? (resolved.tagGroups.length > 0 ? resolved.tagGroups[0].name : null);
46317
+ activeGroup = VALUE_NAME ?? (resolved.tagGroups.length > 0 ? resolved.tagGroups[0].name : null);
46129
46318
  }
46130
- const activeIsScore = SCORE_NAME !== null && activeGroup === SCORE_NAME;
46319
+ const activeIsScore = VALUE_NAME !== null && activeGroup === VALUE_NAME;
46320
+ const mutedBasemap = resolved.directives.basemapStyle === "muted" ? true : resolved.directives.basemapStyle === "natural" ? false : activeGroup !== null;
46321
+ const neutralFill = mapNeutralLandColor(palette, isDark, mutedBasemap);
46322
+ const water = mapBackgroundColor(palette, isDark, mutedBasemap);
46323
+ const foreignFill = mix(
46324
+ palette.colors.gray,
46325
+ palette.bg,
46326
+ mutedBasemap ? isDark ? MUTED_FOREIGN_DARK : MUTED_FOREIGN_LIGHT : isDark ? FOREIGN_TINT_DARK : FOREIGN_TINT_LIGHT
46327
+ );
46131
46328
  const rampBase = isDark ? mix(palette.surface, palette.text, 28) : palette.bg;
46132
- const fillForScore = (s) => {
46329
+ const fillForValue = (s) => {
46133
46330
  const t = rampMax > rampMin ? (s - rampMin) / (rampMax - rampMin) : 1;
46134
46331
  const pct = RAMP_FLOOR + Math.max(0, Math.min(1, t)) * (100 - RAMP_FLOOR);
46135
46332
  return mix(rampHue, rampBase, pct);
@@ -46154,7 +46351,7 @@ function layoutMap(resolved, data, size, opts) {
46154
46351
  };
46155
46352
  const regionFill = (r) => {
46156
46353
  if (activeIsScore) {
46157
- return r.score !== void 0 ? fillForScore(r.score) : neutralFill;
46354
+ return r.value !== void 0 ? fillForValue(r.value) : neutralFill;
46158
46355
  }
46159
46356
  return tagFill(r.tags, activeGroup) ?? neutralFill;
46160
46357
  };
@@ -46366,7 +46563,7 @@ function layoutMap(resolved, data, size, opts) {
46366
46563
  stroke: regionStroke,
46367
46564
  lineNumber,
46368
46565
  layer: "us-state",
46369
- ...r?.score !== void 0 && { score: r.score },
46566
+ ...r?.value !== void 0 && { value: r.value },
46370
46567
  ...r && Object.keys(r.tags).length > 0 && { tags: r.tags }
46371
46568
  });
46372
46569
  const ctr = (0, import_d3_geo2.geoPath)(proj).centroid(f);
@@ -46509,7 +46706,7 @@ function layoutMap(resolved, data, size, opts) {
46509
46706
  lineNumber,
46510
46707
  layer,
46511
46708
  ...label !== void 0 && { label },
46512
- ...isThisLayer && r.score !== void 0 && { score: r.score },
46709
+ ...isThisLayer && r.value !== void 0 && { value: r.value },
46513
46710
  ...isThisLayer && Object.keys(r.tags).length > 0 && { tags: r.tags }
46514
46711
  });
46515
46712
  }
@@ -46544,11 +46741,11 @@ function layoutMap(resolved, data, size, opts) {
46544
46741
  rivers.push({ d, color: riverColor, width: RIVER_WIDTH });
46545
46742
  }
46546
46743
  }
46547
- const sizeVals = resolved.pois.map((p) => Number(p.meta["size"])).filter((n) => Number.isFinite(n) && n > 0);
46744
+ const sizeVals = resolved.pois.map((p) => Number(p.meta["value"])).filter((n) => Number.isFinite(n) && n > 0);
46548
46745
  const sizeMin = sizeVals.length ? Math.min(...sizeVals) : 0;
46549
46746
  const sizeMax = sizeVals.length ? Math.max(...sizeVals) : 0;
46550
46747
  const radiusFor = (p) => {
46551
- const v = Number(p.meta["size"]);
46748
+ const v = Number(p.meta["value"]);
46552
46749
  if (!Number.isFinite(v) || v <= 0 || sizeMax <= 0) return R_DEFAULT;
46553
46750
  const t = sizeMax > sizeMin ? (Math.sqrt(v) - Math.sqrt(sizeMin)) / (Math.sqrt(sizeMax) - Math.sqrt(sizeMin)) : 1;
46554
46751
  return R_MIN + Math.max(0, Math.min(1, t)) * (R_MAX - R_MIN);
@@ -46615,7 +46812,8 @@ function layoutMap(resolved, data, size, opts) {
46615
46812
  lineNumber: e.p.lineNumber,
46616
46813
  implicit: !!e.p.implicit,
46617
46814
  isOrigin: originIds.has(e.p.id),
46618
- ...num !== void 0 && { routeNumber: num }
46815
+ ...num !== void 0 && { routeNumber: num },
46816
+ ...Object.keys(e.p.tags).length > 0 && { tags: e.p.tags }
46619
46817
  });
46620
46818
  });
46621
46819
  }
@@ -46651,26 +46849,40 @@ function layoutMap(resolved, data, size, opts) {
46651
46849
  const by = b.cy - (b.cy - py) / tb * trimB;
46652
46850
  return `M${ax},${ay}Q${px},${py} ${bx},${by}`;
46653
46851
  };
46852
+ const routeLegVals = resolved.routes.flatMap((rt) => rt.legs).map((l) => Number(l.value)).filter((n) => Number.isFinite(n) && n > 0);
46853
+ const rlMin = routeLegVals.length ? Math.min(...routeLegVals) : 0;
46854
+ const rlMax = routeLegVals.length ? Math.max(...routeLegVals) : 0;
46855
+ const routeWidthFor = (v) => {
46856
+ if (!Number.isFinite(v) || v <= 0 || rlMax <= 0) return W_MIN;
46857
+ const t = rlMax > rlMin ? (v - rlMin) / (rlMax - rlMin) : 1;
46858
+ return W_MIN + t * (W_MAX - W_MIN);
46859
+ };
46654
46860
  for (const rt of resolved.routes) {
46655
- const curved = rt.meta["style"] === "arc";
46656
- for (let i = 1; i < rt.stopIds.length; i++) {
46657
- const a = poiScreen.get(rt.stopIds[i - 1]);
46658
- const b = poiScreen.get(rt.stopIds[i]);
46861
+ for (const leg of rt.legs) {
46862
+ const a = poiScreen.get(leg.fromId);
46863
+ const b = poiScreen.get(leg.toId);
46659
46864
  if (!a || !b) continue;
46865
+ const mx = (a.cx + b.cx) / 2;
46866
+ const my = (a.cy + b.cy) / 2;
46660
46867
  legs.push({
46661
- d: legPath(a, b, curved, 0),
46662
- width: W_MIN,
46868
+ d: legPath(a, b, leg.style === "arc", 0),
46869
+ width: routeWidthFor(Number(leg.value)),
46663
46870
  color: mix(palette.text, palette.bg, 72),
46664
46871
  arrow: true,
46665
- lineNumber: rt.lineNumber
46872
+ lineNumber: leg.lineNumber,
46873
+ ...leg.label !== void 0 && {
46874
+ label: leg.label,
46875
+ labelX: mx,
46876
+ labelY: my - 4
46877
+ }
46666
46878
  });
46667
46879
  }
46668
46880
  }
46669
- const weightVals = resolved.edges.map((e) => Number(e.meta["weight"])).filter((n) => Number.isFinite(n) && n > 0);
46881
+ const weightVals = resolved.edges.map((e) => Number(e.meta["value"])).filter((n) => Number.isFinite(n) && n > 0);
46670
46882
  const wMin = weightVals.length ? Math.min(...weightVals) : 0;
46671
46883
  const wMax = weightVals.length ? Math.max(...weightVals) : 0;
46672
46884
  const widthFor = (e) => {
46673
- const v = Number(e.meta["weight"]);
46885
+ const v = Number(e.meta["value"]);
46674
46886
  if (!Number.isFinite(v) || v <= 0 || wMax <= 0) return W_MIN;
46675
46887
  const t = wMax > wMin ? (v - wMin) / (wMax - wMin) : 1;
46676
46888
  return W_MIN + t * (W_MAX - W_MIN);
@@ -46933,8 +47145,8 @@ function layoutMap(resolved, data, size, opts) {
46933
47145
  activeGroup,
46934
47146
  ...hasRamp && {
46935
47147
  ramp: {
46936
- ...resolved.directives.metric !== void 0 && {
46937
- metric: resolved.directives.metric
47148
+ ...resolved.directives.regionMetric !== void 0 && {
47149
+ metric: resolved.directives.regionMetric
46938
47150
  },
46939
47151
  min: rampMin,
46940
47152
  max: rampMax,
@@ -46962,7 +47174,7 @@ function layoutMap(resolved, data, size, opts) {
46962
47174
  insetRegions
46963
47175
  };
46964
47176
  }
46965
- var import_d3_geo2, import_topojson_client2, 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;
47177
+ var import_d3_geo2, import_topojson_client2, 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;
46966
47178
  var init_layout15 = __esm({
46967
47179
  "src/map/layout.ts"() {
46968
47180
  "use strict";
@@ -46989,6 +47201,11 @@ var init_layout15 = __esm({
46989
47201
  RIVER_WIDTH = 1.3;
46990
47202
  FOREIGN_TINT_LIGHT = 30;
46991
47203
  FOREIGN_TINT_DARK = 62;
47204
+ MUTED_WATER_LIGHT = 14;
47205
+ MUTED_WATER_DARK = 10;
47206
+ MUTED_FOREIGN_LIGHT = 28;
47207
+ MUTED_FOREIGN_DARK = 16;
47208
+ MUTED_LAND_DARK = 24;
46992
47209
  COLO_R = 9;
46993
47210
  GOLDEN_ANGLE = 2.399963229728653;
46994
47211
  FAN_STEP = 16;
@@ -47042,7 +47259,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
47042
47259
  const p = g.append("path").attr("d", r.d).attr("fill", r.fill).attr("stroke", r.stroke).attr("stroke-width", strokeWidth);
47043
47260
  if (r.layer !== "base") {
47044
47261
  p.classed("dgmo-map-region", true).attr("data-region", r.id);
47045
- if (r.score !== void 0) p.attr("data-score", r.score);
47262
+ if (r.value !== void 0) p.attr("data-value", r.value);
47046
47263
  if (r.tags) {
47047
47264
  for (const [group, value] of Object.entries(r.tags)) {
47048
47265
  p.attr(`data-tag-${group.toLowerCase()}`, value.toLowerCase());
@@ -47103,6 +47320,11 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
47103
47320
  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);
47104
47321
  }
47105
47322
  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);
47323
+ if (poi.tags) {
47324
+ for (const [group, value] of Object.entries(poi.tags)) {
47325
+ c.attr(`data-tag-${group.toLowerCase()}`, value.toLowerCase());
47326
+ }
47327
+ }
47106
47328
  if (onClickItem) {
47107
47329
  c.style("cursor", "pointer").on(
47108
47330
  "click",
@@ -47152,7 +47374,7 @@ function renderMap(container, resolved, data, palette, isDark, onClickItem, expo
47152
47374
  const legendG = svg.append("g").attr("class", "dgmo-map-legend").attr("transform", `translate(0, ${legendY})`);
47153
47375
  const ramp = layout.legend.ramp;
47154
47376
  const scoreGroup = ramp ? {
47155
- name: ramp.metric?.trim() || "Score",
47377
+ name: ramp.metric?.trim() || "Value",
47156
47378
  entries: [],
47157
47379
  gradient: {
47158
47380
  min: ramp.min,
@@ -56396,13 +56618,16 @@ var DIRECTIVE_KEYWORDS = /* @__PURE__ */ new Set([
56396
56618
  // Map (§24B) directives
56397
56619
  "region",
56398
56620
  "projection",
56399
- "metric",
56400
- "size-metric",
56621
+ "region-metric",
56622
+ "poi-metric",
56623
+ "flow-metric",
56401
56624
  "region-labels",
56402
56625
  "poi-labels",
56403
56626
  "default-country",
56404
56627
  "default-state",
56405
56628
  "no-legend",
56629
+ "muted",
56630
+ "natural",
56406
56631
  "subtitle",
56407
56632
  "caption",
56408
56633
  "poi",
@@ -57070,7 +57295,7 @@ pre.dgmo, code.language-dgmo, pre > code.language-dgmo,
57070
57295
 
57071
57296
  // src/auto/index.ts
57072
57297
  init_safe_href();
57073
- var VERSION = "0.20.3";
57298
+ var VERSION = "0.21.0";
57074
57299
  var DEFAULTS = {
57075
57300
  theme: "auto",
57076
57301
  palette: "nord",