@canopy-iiif/app 1.10.4 → 1.10.6
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/lib/build/build.js +4 -0
- package/lib/build/iiif.js +68 -7
- package/lib/components/featured.js +79 -8
- package/package.json +1 -1
- package/ui/dist/index.mjs +302 -166
- package/ui/dist/index.mjs.map +4 -4
- package/ui/dist/server.mjs +307 -14
- package/ui/dist/server.mjs.map +4 -4
- package/ui/styles/components/_timeline.scss +40 -4
- package/ui/styles/index.css +40 -4
package/ui/dist/index.mjs
CHANGED
|
@@ -4172,7 +4172,7 @@ var init_rgb_hex = __esm({
|
|
|
4172
4172
|
});
|
|
4173
4173
|
|
|
4174
4174
|
// ../../node_modules/@allmaps/stdlib/dist/color.js
|
|
4175
|
-
function
|
|
4175
|
+
function hexToRgb2(hex) {
|
|
4176
4176
|
return hexRgb(hex, { format: "array" }).slice(0, 3);
|
|
4177
4177
|
}
|
|
4178
4178
|
function hexToOpaqueRgba(hex) {
|
|
@@ -4181,7 +4181,7 @@ function hexToOpaqueRgba(hex) {
|
|
|
4181
4181
|
return color;
|
|
4182
4182
|
}
|
|
4183
4183
|
function hexToFractionalRgb(hex) {
|
|
4184
|
-
return
|
|
4184
|
+
return hexToRgb2(hex).map((c) => c / 255);
|
|
4185
4185
|
}
|
|
4186
4186
|
function hexToFractionalOpaqueRgba(hex) {
|
|
4187
4187
|
return hexToOpaqueRgba(hex).map((c) => c / 255);
|
|
@@ -46543,6 +46543,214 @@ function ReferencedManifestCard({
|
|
|
46543
46543
|
);
|
|
46544
46544
|
}
|
|
46545
46545
|
|
|
46546
|
+
// ui/src/utils/keyLegend.js
|
|
46547
|
+
var DEFAULT_ACCENT_HEX = "#2563eb";
|
|
46548
|
+
function normalizeHex(value) {
|
|
46549
|
+
if (!value) return "";
|
|
46550
|
+
let input = String(value).trim();
|
|
46551
|
+
if (!input) return "";
|
|
46552
|
+
if (input.startsWith("var(")) return input;
|
|
46553
|
+
if (/^#[0-9a-f]{3}$/i.test(input)) {
|
|
46554
|
+
return "#" + input.replace(/^#/, "").split("").map((ch) => ch + ch).join("").toLowerCase();
|
|
46555
|
+
}
|
|
46556
|
+
if (/^#[0-9a-f]{6}$/i.test(input)) return input.toLowerCase();
|
|
46557
|
+
return "";
|
|
46558
|
+
}
|
|
46559
|
+
function hexToRgb(hex) {
|
|
46560
|
+
if (!hex) return null;
|
|
46561
|
+
const normalized = normalizeHex(hex);
|
|
46562
|
+
if (!normalized || normalized.startsWith("var(")) return null;
|
|
46563
|
+
const int = parseInt(normalized.slice(1), 16);
|
|
46564
|
+
if (Number.isNaN(int)) return null;
|
|
46565
|
+
return {
|
|
46566
|
+
r: int >> 16 & 255,
|
|
46567
|
+
g: int >> 8 & 255,
|
|
46568
|
+
b: int & 255
|
|
46569
|
+
};
|
|
46570
|
+
}
|
|
46571
|
+
function rgbToHsl({ r, g, b }) {
|
|
46572
|
+
const rn = r / 255;
|
|
46573
|
+
const gn = g / 255;
|
|
46574
|
+
const bn = b / 255;
|
|
46575
|
+
const max2 = Math.max(rn, gn, bn);
|
|
46576
|
+
const min2 = Math.min(rn, gn, bn);
|
|
46577
|
+
let h = 0;
|
|
46578
|
+
let s = 0;
|
|
46579
|
+
const l = (max2 + min2) / 2;
|
|
46580
|
+
const delta = max2 - min2;
|
|
46581
|
+
if (delta !== 0) {
|
|
46582
|
+
s = l > 0.5 ? delta / (2 - max2 - min2) : delta / (max2 + min2);
|
|
46583
|
+
switch (max2) {
|
|
46584
|
+
case rn:
|
|
46585
|
+
h = (gn - bn) / delta + (gn < bn ? 6 : 0);
|
|
46586
|
+
break;
|
|
46587
|
+
case gn:
|
|
46588
|
+
h = (bn - rn) / delta + 2;
|
|
46589
|
+
break;
|
|
46590
|
+
case bn:
|
|
46591
|
+
h = (rn - gn) / delta + 4;
|
|
46592
|
+
break;
|
|
46593
|
+
default:
|
|
46594
|
+
break;
|
|
46595
|
+
}
|
|
46596
|
+
h /= 6;
|
|
46597
|
+
}
|
|
46598
|
+
return { h: h * 360, s: s * 100, l: l * 100 };
|
|
46599
|
+
}
|
|
46600
|
+
function hslToHex(h, s, l) {
|
|
46601
|
+
const sat = s / 100;
|
|
46602
|
+
const light = l / 100;
|
|
46603
|
+
const c = (1 - Math.abs(2 * light - 1)) * sat;
|
|
46604
|
+
const hh = h / 60;
|
|
46605
|
+
const x = c * (1 - Math.abs(hh % 2 - 1));
|
|
46606
|
+
let r = 0;
|
|
46607
|
+
let g = 0;
|
|
46608
|
+
let b = 0;
|
|
46609
|
+
if (hh >= 0 && hh < 1) {
|
|
46610
|
+
r = c;
|
|
46611
|
+
g = x;
|
|
46612
|
+
} else if (hh >= 1 && hh < 2) {
|
|
46613
|
+
r = x;
|
|
46614
|
+
g = c;
|
|
46615
|
+
} else if (hh >= 2 && hh < 3) {
|
|
46616
|
+
g = c;
|
|
46617
|
+
b = x;
|
|
46618
|
+
} else if (hh >= 3 && hh < 4) {
|
|
46619
|
+
g = x;
|
|
46620
|
+
b = c;
|
|
46621
|
+
} else if (hh >= 4 && hh < 5) {
|
|
46622
|
+
r = x;
|
|
46623
|
+
b = c;
|
|
46624
|
+
} else {
|
|
46625
|
+
r = c;
|
|
46626
|
+
b = x;
|
|
46627
|
+
}
|
|
46628
|
+
const m = light - c / 2;
|
|
46629
|
+
const rn = Math.round((r + m) * 255);
|
|
46630
|
+
const gn = Math.round((g + m) * 255);
|
|
46631
|
+
const bn = Math.round((b + m) * 255);
|
|
46632
|
+
const toHex = (value) => value.toString(16).padStart(2, "0");
|
|
46633
|
+
return `#${toHex(rn)}${toHex(gn)}${toHex(bn)}`;
|
|
46634
|
+
}
|
|
46635
|
+
function rotateHue(baseHue, degrees) {
|
|
46636
|
+
return (baseHue + degrees + 360) % 360;
|
|
46637
|
+
}
|
|
46638
|
+
function resolveAccentHex() {
|
|
46639
|
+
let value = "";
|
|
46640
|
+
try {
|
|
46641
|
+
if (typeof window !== "undefined") {
|
|
46642
|
+
const styles = window.getComputedStyle(document.documentElement);
|
|
46643
|
+
value = styles.getPropertyValue("--color-accent-default");
|
|
46644
|
+
}
|
|
46645
|
+
} catch (_) {
|
|
46646
|
+
}
|
|
46647
|
+
const normalized = normalizeHex(value);
|
|
46648
|
+
return normalized && !normalized.startsWith("var(") ? normalized : DEFAULT_ACCENT_HEX;
|
|
46649
|
+
}
|
|
46650
|
+
function generateLegendColors(count) {
|
|
46651
|
+
if (!count || count <= 0) return [];
|
|
46652
|
+
const colors = [];
|
|
46653
|
+
const baseHex = resolveAccentHex();
|
|
46654
|
+
const accentVar = `var(--color-accent-default, ${baseHex})`;
|
|
46655
|
+
colors.push(accentVar);
|
|
46656
|
+
if (count === 1) return colors;
|
|
46657
|
+
const rgb = hexToRgb(baseHex);
|
|
46658
|
+
const baseHsl = rgb ? rgbToHsl(rgb) : { h: 220, s: 85, l: 56 };
|
|
46659
|
+
const rotations = [180, 120, -120, 60, -60, 90, -90, 30, -30];
|
|
46660
|
+
const needed = count - 1;
|
|
46661
|
+
for (let i = 0; i < needed; i += 1) {
|
|
46662
|
+
const angle2 = rotations[i] != null ? rotations[i] : 360 / (needed + 1) * (i + 1);
|
|
46663
|
+
const rotatedHue = rotateHue(baseHsl.h, angle2);
|
|
46664
|
+
const hex = hslToHex(rotatedHue, baseHsl.s, baseHsl.l);
|
|
46665
|
+
colors.push(hex);
|
|
46666
|
+
}
|
|
46667
|
+
return colors;
|
|
46668
|
+
}
|
|
46669
|
+
function createLookupStore() {
|
|
46670
|
+
try {
|
|
46671
|
+
if (typeof globalThis !== "undefined" && typeof globalThis.Map === "function") {
|
|
46672
|
+
return new globalThis.Map();
|
|
46673
|
+
}
|
|
46674
|
+
} catch (_) {
|
|
46675
|
+
}
|
|
46676
|
+
try {
|
|
46677
|
+
if (typeof window !== "undefined" && typeof window.Map === "function") {
|
|
46678
|
+
return new window.Map();
|
|
46679
|
+
}
|
|
46680
|
+
} catch (_) {
|
|
46681
|
+
}
|
|
46682
|
+
const store = /* @__PURE__ */ Object.create(null);
|
|
46683
|
+
return {
|
|
46684
|
+
has(key) {
|
|
46685
|
+
return Object.prototype.hasOwnProperty.call(store, key);
|
|
46686
|
+
},
|
|
46687
|
+
get(key) {
|
|
46688
|
+
return store[key];
|
|
46689
|
+
},
|
|
46690
|
+
set(key, value) {
|
|
46691
|
+
store[key] = value;
|
|
46692
|
+
return this;
|
|
46693
|
+
}
|
|
46694
|
+
};
|
|
46695
|
+
}
|
|
46696
|
+
function normalizeText(value) {
|
|
46697
|
+
if (value == null) return "";
|
|
46698
|
+
try {
|
|
46699
|
+
return String(value).trim();
|
|
46700
|
+
} catch (_) {
|
|
46701
|
+
return "";
|
|
46702
|
+
}
|
|
46703
|
+
}
|
|
46704
|
+
function normalizeKeyValue(entry) {
|
|
46705
|
+
var _a2, _b, _c;
|
|
46706
|
+
if (!entry) return "";
|
|
46707
|
+
const value = (_c = (_b = (_a2 = entry.id) != null ? _a2 : entry.value) != null ? _b : entry.key) != null ? _c : entry.slug;
|
|
46708
|
+
return normalizeText(value);
|
|
46709
|
+
}
|
|
46710
|
+
function normalizeKeyLabel(entry) {
|
|
46711
|
+
var _a2, _b, _c;
|
|
46712
|
+
if (!entry) return "";
|
|
46713
|
+
const label = (_c = (_b = (_a2 = entry.label) != null ? _a2 : entry.name) != null ? _b : entry.title) != null ? _c : entry.text;
|
|
46714
|
+
return normalizeText(label);
|
|
46715
|
+
}
|
|
46716
|
+
function normalizeKeyLegendEntries(entries, options = {}) {
|
|
46717
|
+
if (!Array.isArray(entries)) return [];
|
|
46718
|
+
const resolveVariant = typeof options.resolveVariant === "function" ? options.resolveVariant : null;
|
|
46719
|
+
const variantProp = options.variantProp || "variant";
|
|
46720
|
+
return entries.map((entry) => {
|
|
46721
|
+
if (!entry) return null;
|
|
46722
|
+
const keyValue = normalizeKeyValue(entry);
|
|
46723
|
+
const label = normalizeKeyLabel(entry);
|
|
46724
|
+
if (!keyValue || !label) return null;
|
|
46725
|
+
const normalized = {
|
|
46726
|
+
keyValue,
|
|
46727
|
+
label
|
|
46728
|
+
};
|
|
46729
|
+
if (resolveVariant) {
|
|
46730
|
+
const variant = resolveVariant(entry);
|
|
46731
|
+
if (variant) normalized[variantProp] = variant;
|
|
46732
|
+
}
|
|
46733
|
+
return normalized;
|
|
46734
|
+
}).filter(Boolean);
|
|
46735
|
+
}
|
|
46736
|
+
function buildKeyLegend(entries) {
|
|
46737
|
+
if (!Array.isArray(entries) || !entries.length) {
|
|
46738
|
+
return { groups: [], lookup: null };
|
|
46739
|
+
}
|
|
46740
|
+
const lookup = createLookupStore();
|
|
46741
|
+
const palette = generateLegendColors(entries.length);
|
|
46742
|
+
const groups = entries.map((entry, index) => {
|
|
46743
|
+
const color = palette[index] || palette[0] || DEFAULT_ACCENT_HEX;
|
|
46744
|
+
const group = {
|
|
46745
|
+
...entry,
|
|
46746
|
+
color
|
|
46747
|
+
};
|
|
46748
|
+
lookup.set(entry.keyValue, group);
|
|
46749
|
+
return group;
|
|
46750
|
+
});
|
|
46751
|
+
return { groups, lookup };
|
|
46752
|
+
}
|
|
46753
|
+
|
|
46546
46754
|
// ui/src/content/timeline/Timeline.jsx
|
|
46547
46755
|
var DAY_MS = 24 * 60 * 60 * 1e3;
|
|
46548
46756
|
var DEFAULT_TRACK_HEIGHT = 640;
|
|
@@ -46680,6 +46888,7 @@ function sanitizePoints(points) {
|
|
|
46680
46888
|
label: meta.label || "",
|
|
46681
46889
|
timestamp: Number.isFinite(timestamp) ? timestamp : null
|
|
46682
46890
|
},
|
|
46891
|
+
keyValue: point2.keyValue ? String(point2.keyValue).trim() : "",
|
|
46683
46892
|
manifests,
|
|
46684
46893
|
resources
|
|
46685
46894
|
};
|
|
@@ -46710,7 +46919,7 @@ function resolveTrackHeight(height, pointCount) {
|
|
|
46710
46919
|
}
|
|
46711
46920
|
return fallback;
|
|
46712
46921
|
}
|
|
46713
|
-
function TimelineConnector({ side, isActive, highlight }) {
|
|
46922
|
+
function TimelineConnector({ side, isActive, highlight, color }) {
|
|
46714
46923
|
const connectorClasses = [
|
|
46715
46924
|
"canopy-timeline__connector",
|
|
46716
46925
|
side === "left" ? "canopy-timeline__connector--left" : "canopy-timeline__connector--right"
|
|
@@ -46719,7 +46928,8 @@ function TimelineConnector({ side, isActive, highlight }) {
|
|
|
46719
46928
|
"canopy-timeline__connector-dot",
|
|
46720
46929
|
highlight || isActive ? "is-active" : ""
|
|
46721
46930
|
].filter(Boolean).join(" ");
|
|
46722
|
-
|
|
46931
|
+
const connectorStyle = color ? { "--canopy-timeline-point-color": color } : void 0;
|
|
46932
|
+
return /* @__PURE__ */ React41.createElement("span", { className: connectorClasses, "aria-hidden": "true", style: connectorStyle }, side === "left" ? /* @__PURE__ */ React41.createElement(React41.Fragment, null, /* @__PURE__ */ React41.createElement("span", { className: "canopy-timeline__connector-line" }), /* @__PURE__ */ React41.createElement("span", { className: dotClasses })) : /* @__PURE__ */ React41.createElement(React41.Fragment, null, /* @__PURE__ */ React41.createElement("span", { className: dotClasses }), /* @__PURE__ */ React41.createElement("span", { className: "canopy-timeline__connector-line" })));
|
|
46723
46933
|
}
|
|
46724
46934
|
function renderResourceSection(point2) {
|
|
46725
46935
|
if (!point2) return null;
|
|
@@ -46749,6 +46959,9 @@ function Timeline({
|
|
|
46749
46959
|
align = ALIGN_OPTIONS.CENTER,
|
|
46750
46960
|
steps = null,
|
|
46751
46961
|
points: pointsProp,
|
|
46962
|
+
keyConfig = [],
|
|
46963
|
+
timelineKey = [],
|
|
46964
|
+
legend = [],
|
|
46752
46965
|
__canopyTimeline: payload = null,
|
|
46753
46966
|
...rest
|
|
46754
46967
|
}) {
|
|
@@ -46762,6 +46975,35 @@ function Timeline({
|
|
|
46762
46975
|
() => sanitizePoints(rawPoints),
|
|
46763
46976
|
[rawPoints]
|
|
46764
46977
|
);
|
|
46978
|
+
const resolvedKeyInput = React41.useMemo(() => {
|
|
46979
|
+
if (Array.isArray(keyConfig) && keyConfig.length) return keyConfig;
|
|
46980
|
+
if (Array.isArray(timelineKey) && timelineKey.length) return timelineKey;
|
|
46981
|
+
if (Array.isArray(legend) && legend.length) return legend;
|
|
46982
|
+
return [];
|
|
46983
|
+
}, [keyConfig, timelineKey, legend]);
|
|
46984
|
+
const normalizedLegendConfig = React41.useMemo(
|
|
46985
|
+
() => normalizeKeyLegendEntries(resolvedKeyInput),
|
|
46986
|
+
[resolvedKeyInput]
|
|
46987
|
+
);
|
|
46988
|
+
const timelineKeyData = React41.useMemo(
|
|
46989
|
+
() => buildKeyLegend(normalizedLegendConfig),
|
|
46990
|
+
[normalizedLegendConfig]
|
|
46991
|
+
);
|
|
46992
|
+
const timelineKeyGroups = timelineKeyData.groups;
|
|
46993
|
+
const timelineKeyLookup = timelineKeyData.lookup;
|
|
46994
|
+
const getLegendMeta = React41.useCallback(
|
|
46995
|
+
(value) => {
|
|
46996
|
+
if (!value || !timelineKeyLookup || typeof timelineKeyLookup.get !== "function") {
|
|
46997
|
+
return null;
|
|
46998
|
+
}
|
|
46999
|
+
try {
|
|
47000
|
+
return timelineKeyLookup.get(value) || null;
|
|
47001
|
+
} catch (_) {
|
|
47002
|
+
return null;
|
|
47003
|
+
}
|
|
47004
|
+
},
|
|
47005
|
+
[timelineKeyLookup]
|
|
47006
|
+
);
|
|
46765
47007
|
const localeValue = payload && payload.locale ? payload.locale : localeProp;
|
|
46766
47008
|
const baseLocale = React41.useMemo(
|
|
46767
47009
|
() => createLocale(localeValue),
|
|
@@ -46792,13 +47034,22 @@ function Timeline({
|
|
|
46792
47034
|
const fallbackProgress = sanitizedPoints.length > 1 ? index / (sanitizedPoints.length - 1) : 0;
|
|
46793
47035
|
const progress = useUniformSpacing ? fallbackProgress : Number.isFinite(timestamp) ? clampProgress((timestamp - spanStart) / span) : fallbackProgress;
|
|
46794
47036
|
const side = enforcedSide || point2.side || (index % 2 === 0 ? "left" : "right");
|
|
47037
|
+
const keyMeta = point2.keyValue ? getLegendMeta(point2.keyValue) : null;
|
|
46795
47038
|
return {
|
|
46796
47039
|
...point2,
|
|
46797
47040
|
progress,
|
|
46798
|
-
side
|
|
47041
|
+
side,
|
|
47042
|
+
keyMeta
|
|
46799
47043
|
};
|
|
46800
47044
|
});
|
|
46801
|
-
}, [
|
|
47045
|
+
}, [
|
|
47046
|
+
sanitizedPoints,
|
|
47047
|
+
spanStart,
|
|
47048
|
+
span,
|
|
47049
|
+
useUniformSpacing,
|
|
47050
|
+
enforcedSide,
|
|
47051
|
+
getLegendMeta
|
|
47052
|
+
]);
|
|
46802
47053
|
const [activeId, setActiveId] = React41.useState(
|
|
46803
47054
|
() => getActivePointId(pointsWithPosition)
|
|
46804
47055
|
);
|
|
@@ -46851,6 +47102,7 @@ function Timeline({
|
|
|
46851
47102
|
className
|
|
46852
47103
|
].filter(Boolean).join(" ");
|
|
46853
47104
|
const rangeLabel = formatRangeLabel(effectiveRange);
|
|
47105
|
+
const hasKeyLegend = timelineKeyGroups.length > 0;
|
|
46854
47106
|
function renderPointEntry(point2) {
|
|
46855
47107
|
if (!point2) return null;
|
|
46856
47108
|
const wrapperClasses = [
|
|
@@ -46863,12 +47115,14 @@ function Timeline({
|
|
|
46863
47115
|
point2.id === activeId ? "is-active" : "",
|
|
46864
47116
|
point2.highlight ? "is-highlighted" : ""
|
|
46865
47117
|
].filter(Boolean).join(" ");
|
|
47118
|
+
const pointColor = point2.keyMeta && point2.keyMeta.color ? point2.keyMeta.color : null;
|
|
46866
47119
|
const connector = /* @__PURE__ */ React41.createElement(
|
|
46867
47120
|
TimelineConnector,
|
|
46868
47121
|
{
|
|
46869
47122
|
side: point2.side,
|
|
46870
47123
|
isActive: point2.id === activeId,
|
|
46871
|
-
highlight: point2.highlight
|
|
47124
|
+
highlight: point2.highlight,
|
|
47125
|
+
color: pointColor
|
|
46872
47126
|
}
|
|
46873
47127
|
);
|
|
46874
47128
|
const body = /* @__PURE__ */ React41.createElement("div", { className: "canopy-timeline__point-body" }, /* @__PURE__ */ React41.createElement("span", { className: "canopy-timeline__point-date" }, point2.meta.label), /* @__PURE__ */ React41.createElement("span", { className: "canopy-timeline__point-title" }, point2.title), point2.summary ? /* @__PURE__ */ React41.createElement("span", { className: "canopy-timeline__point-summary" }, point2.summary) : null);
|
|
@@ -46892,12 +47146,24 @@ function Timeline({
|
|
|
46892
47146
|
const wrapperStyle = { top: `${entry.progress * 100}%` };
|
|
46893
47147
|
const isExpanded = expandedGroupIds.has(entry.id);
|
|
46894
47148
|
const hasActivePoint = entry.points.some((point2) => point2.id === activeId);
|
|
47149
|
+
const groupKeyMeta = (() => {
|
|
47150
|
+
if (!entry.points || !entry.points.length) return null;
|
|
47151
|
+
const firstPoint = entry.points[0];
|
|
47152
|
+
if (!firstPoint || !firstPoint.keyValue) return null;
|
|
47153
|
+
const sameKey = entry.points.every(
|
|
47154
|
+
(point2) => point2 && point2.keyValue === firstPoint.keyValue
|
|
47155
|
+
);
|
|
47156
|
+
if (!sameKey) return null;
|
|
47157
|
+
return firstPoint.keyMeta || getLegendMeta(firstPoint.keyValue);
|
|
47158
|
+
})();
|
|
47159
|
+
const groupColor = groupKeyMeta && groupKeyMeta.color ? groupKeyMeta.color : null;
|
|
46895
47160
|
const connector = /* @__PURE__ */ React41.createElement(
|
|
46896
47161
|
TimelineConnector,
|
|
46897
47162
|
{
|
|
46898
47163
|
side: entry.side,
|
|
46899
47164
|
isActive: hasActivePoint,
|
|
46900
|
-
highlight: hasActivePoint
|
|
47165
|
+
highlight: hasActivePoint,
|
|
47166
|
+
color: groupColor
|
|
46901
47167
|
}
|
|
46902
47168
|
);
|
|
46903
47169
|
const groupClasses = [
|
|
@@ -46955,7 +47221,22 @@ function Timeline({
|
|
|
46955
47221
|
if (entry.type === "group") return renderGroupEntry(entry);
|
|
46956
47222
|
return renderPointEntry(entry.point);
|
|
46957
47223
|
})
|
|
46958
|
-
)))
|
|
47224
|
+
)), hasKeyLegend ? /* @__PURE__ */ React41.createElement("div", { className: "canopy-timeline__key", "aria-label": "Timeline key" }, /* @__PURE__ */ React41.createElement("ul", { className: "canopy-timeline__key-list" }, timelineKeyGroups.map((group) => /* @__PURE__ */ React41.createElement(
|
|
47225
|
+
"li",
|
|
47226
|
+
{
|
|
47227
|
+
key: group.keyValue || group.label,
|
|
47228
|
+
className: "canopy-timeline__key-item"
|
|
47229
|
+
},
|
|
47230
|
+
/* @__PURE__ */ React41.createElement(
|
|
47231
|
+
"span",
|
|
47232
|
+
{
|
|
47233
|
+
className: "canopy-timeline__key-dot",
|
|
47234
|
+
"aria-hidden": "true",
|
|
47235
|
+
style: { backgroundColor: group.color || void 0 }
|
|
47236
|
+
}
|
|
47237
|
+
),
|
|
47238
|
+
/* @__PURE__ */ React41.createElement("span", { className: "canopy-timeline__key-label" }, group.label)
|
|
47239
|
+
)))) : null);
|
|
46959
47240
|
}
|
|
46960
47241
|
function renderSteps(stepSize, range) {
|
|
46961
47242
|
if (!Number.isFinite(stepSize) || stepSize <= 0 || !range) return null;
|
|
@@ -47034,7 +47315,6 @@ var TRANSPARENT_TILE_URL = "data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAA
|
|
|
47034
47315
|
var CUSTOM_MARKER_SIZE = 40;
|
|
47035
47316
|
var CUSTOM_MARKER_RADIUS = CUSTOM_MARKER_SIZE / 2;
|
|
47036
47317
|
var CUSTOM_MARKER_POPUP_OFFSET = -CUSTOM_MARKER_RADIUS + 6;
|
|
47037
|
-
var DEFAULT_ACCENT_HEX = "#2563eb";
|
|
47038
47318
|
function resolveGlobalLeaflet() {
|
|
47039
47319
|
try {
|
|
47040
47320
|
if (typeof globalThis !== "undefined" && globalThis.L) return globalThis.L;
|
|
@@ -47167,126 +47447,6 @@ function createMarkerMap() {
|
|
|
47167
47447
|
}
|
|
47168
47448
|
};
|
|
47169
47449
|
}
|
|
47170
|
-
function normalizeHex(value) {
|
|
47171
|
-
if (!value) return "";
|
|
47172
|
-
let input = String(value).trim();
|
|
47173
|
-
if (!input) return "";
|
|
47174
|
-
if (input.startsWith("var(")) return input;
|
|
47175
|
-
if (/^#[0-9a-f]{3}$/i.test(input)) {
|
|
47176
|
-
return input.replace(/^#/, "").split("").map((ch) => ch + ch).join("").replace(/^/, "#");
|
|
47177
|
-
}
|
|
47178
|
-
if (/^#[0-9a-f]{6}$/i.test(input)) return input;
|
|
47179
|
-
return "";
|
|
47180
|
-
}
|
|
47181
|
-
function hexToRgb2(hex) {
|
|
47182
|
-
if (!hex) return null;
|
|
47183
|
-
const normalized = normalizeHex(hex);
|
|
47184
|
-
if (!normalized) return null;
|
|
47185
|
-
const int = parseInt(normalized.slice(1), 16);
|
|
47186
|
-
return {
|
|
47187
|
-
r: int >> 16 & 255,
|
|
47188
|
-
g: int >> 8 & 255,
|
|
47189
|
-
b: int & 255
|
|
47190
|
-
};
|
|
47191
|
-
}
|
|
47192
|
-
function rgbToHsl({ r, g, b }) {
|
|
47193
|
-
const rn = r / 255;
|
|
47194
|
-
const gn = g / 255;
|
|
47195
|
-
const bn = b / 255;
|
|
47196
|
-
const max2 = Math.max(rn, gn, bn);
|
|
47197
|
-
const min2 = Math.min(rn, gn, bn);
|
|
47198
|
-
let h = 0;
|
|
47199
|
-
let s = 0;
|
|
47200
|
-
const l = (max2 + min2) / 2;
|
|
47201
|
-
const delta = max2 - min2;
|
|
47202
|
-
if (delta !== 0) {
|
|
47203
|
-
s = l > 0.5 ? delta / (2 - max2 - min2) : delta / (max2 + min2);
|
|
47204
|
-
switch (max2) {
|
|
47205
|
-
case rn:
|
|
47206
|
-
h = (gn - bn) / delta + (gn < bn ? 6 : 0);
|
|
47207
|
-
break;
|
|
47208
|
-
case gn:
|
|
47209
|
-
h = (bn - rn) / delta + 2;
|
|
47210
|
-
break;
|
|
47211
|
-
case bn:
|
|
47212
|
-
h = (rn - gn) / delta + 4;
|
|
47213
|
-
break;
|
|
47214
|
-
default:
|
|
47215
|
-
break;
|
|
47216
|
-
}
|
|
47217
|
-
h /= 6;
|
|
47218
|
-
}
|
|
47219
|
-
return { h: h * 360, s: s * 100, l: l * 100 };
|
|
47220
|
-
}
|
|
47221
|
-
function hslToHex(h, s, l) {
|
|
47222
|
-
const sat = s / 100;
|
|
47223
|
-
const light = l / 100;
|
|
47224
|
-
const c = (1 - Math.abs(2 * light - 1)) * sat;
|
|
47225
|
-
const hh = h / 60;
|
|
47226
|
-
const x = c * (1 - Math.abs(hh % 2 - 1));
|
|
47227
|
-
let r = 0;
|
|
47228
|
-
let g = 0;
|
|
47229
|
-
let b = 0;
|
|
47230
|
-
if (hh >= 0 && hh < 1) {
|
|
47231
|
-
r = c;
|
|
47232
|
-
g = x;
|
|
47233
|
-
} else if (hh >= 1 && hh < 2) {
|
|
47234
|
-
r = x;
|
|
47235
|
-
g = c;
|
|
47236
|
-
} else if (hh >= 2 && hh < 3) {
|
|
47237
|
-
g = c;
|
|
47238
|
-
b = x;
|
|
47239
|
-
} else if (hh >= 3 && hh < 4) {
|
|
47240
|
-
g = x;
|
|
47241
|
-
b = c;
|
|
47242
|
-
} else if (hh >= 4 && hh < 5) {
|
|
47243
|
-
r = x;
|
|
47244
|
-
b = c;
|
|
47245
|
-
} else {
|
|
47246
|
-
r = c;
|
|
47247
|
-
b = x;
|
|
47248
|
-
}
|
|
47249
|
-
const m = light - c / 2;
|
|
47250
|
-
const rn = Math.round((r + m) * 255);
|
|
47251
|
-
const gn = Math.round((g + m) * 255);
|
|
47252
|
-
const bn = Math.round((b + m) * 255);
|
|
47253
|
-
const toHex = (value) => value.toString(16).padStart(2, "0");
|
|
47254
|
-
return `#${toHex(rn)}${toHex(gn)}${toHex(bn)}`;
|
|
47255
|
-
}
|
|
47256
|
-
function rotateHue(baseHue, degrees) {
|
|
47257
|
-
return (baseHue + degrees + 360) % 360;
|
|
47258
|
-
}
|
|
47259
|
-
function resolveAccentHex() {
|
|
47260
|
-
let value = "";
|
|
47261
|
-
try {
|
|
47262
|
-
if (typeof window !== "undefined") {
|
|
47263
|
-
const styles = window.getComputedStyle(document.documentElement);
|
|
47264
|
-
value = styles.getPropertyValue("--color-accent-default");
|
|
47265
|
-
}
|
|
47266
|
-
} catch (_) {
|
|
47267
|
-
}
|
|
47268
|
-
const normalized = normalizeHex(value);
|
|
47269
|
-
return normalized || DEFAULT_ACCENT_HEX;
|
|
47270
|
-
}
|
|
47271
|
-
function generateLegendColors(count) {
|
|
47272
|
-
if (!count || count <= 0) return [];
|
|
47273
|
-
const colors = [];
|
|
47274
|
-
const baseHex = resolveAccentHex();
|
|
47275
|
-
const accentVar = `var(--color-accent-default, ${baseHex})`;
|
|
47276
|
-
colors.push(accentVar);
|
|
47277
|
-
if (count === 1) return colors;
|
|
47278
|
-
const rgb = hexToRgb2(baseHex);
|
|
47279
|
-
const baseHsl = rgb ? rgbToHsl(rgb) : { h: 220, s: 85, l: 56 };
|
|
47280
|
-
const rotations = [180, 120, -120, 60, -60, 90, -90, 30, -30];
|
|
47281
|
-
const needed = count - 1;
|
|
47282
|
-
for (let i = 0; i < needed; i += 1) {
|
|
47283
|
-
const angle2 = rotations[i] != null ? rotations[i] : 360 / (needed + 1) * (i + 1);
|
|
47284
|
-
const rotatedHue = rotateHue(baseHsl.h, angle2);
|
|
47285
|
-
const hex = hslToHex(rotatedHue, baseHsl.s, baseHsl.l);
|
|
47286
|
-
colors.push(hex);
|
|
47287
|
-
}
|
|
47288
|
-
return colors;
|
|
47289
|
-
}
|
|
47290
47450
|
function readIiifType(resource) {
|
|
47291
47451
|
if (!resource) return "";
|
|
47292
47452
|
const raw = resource.type || resource["@type"];
|
|
@@ -47816,43 +47976,19 @@ function Map3({
|
|
|
47816
47976
|
if (Array.isArray(legend) && legend.length) return legend;
|
|
47817
47977
|
return [];
|
|
47818
47978
|
}, [keyConfig, mapKey, legend]);
|
|
47819
|
-
const normalizedLegendConfig = React42.useMemo(
|
|
47820
|
-
|
|
47821
|
-
|
|
47822
|
-
|
|
47823
|
-
|
|
47824
|
-
|
|
47825
|
-
|
|
47826
|
-
|
|
47827
|
-
|
|
47828
|
-
|
|
47829
|
-
|
|
47830
|
-
entry.markerType || entry.type || entry.variant
|
|
47831
|
-
)
|
|
47832
|
-
};
|
|
47833
|
-
}).filter(Boolean);
|
|
47834
|
-
}, [resolvedKeyInput]);
|
|
47835
|
-
const markerKeyData = React42.useMemo(() => {
|
|
47836
|
-
if (!normalizedLegendConfig.length) return { groups: [], metaMap: null };
|
|
47837
|
-
const metaMap = createMarkerMap();
|
|
47838
|
-
const palette = generateLegendColors(normalizedLegendConfig.length);
|
|
47839
|
-
const groups = normalizedLegendConfig.map((entry, index) => {
|
|
47840
|
-
const color = palette[index] || palette[0] || DEFAULT_ACCENT_HEX;
|
|
47841
|
-
metaMap.set(entry.keyValue, {
|
|
47842
|
-
color,
|
|
47843
|
-
markerType: entry.markerType || null
|
|
47844
|
-
});
|
|
47845
|
-
return {
|
|
47846
|
-
keyValue: entry.keyValue,
|
|
47847
|
-
label: entry.label,
|
|
47848
|
-
color,
|
|
47849
|
-
markerType: entry.markerType || null
|
|
47850
|
-
};
|
|
47851
|
-
});
|
|
47852
|
-
return { groups, metaMap };
|
|
47853
|
-
}, [normalizedLegendConfig]);
|
|
47979
|
+
const normalizedLegendConfig = React42.useMemo(
|
|
47980
|
+
() => normalizeKeyLegendEntries(resolvedKeyInput, {
|
|
47981
|
+
resolveVariant: (entry) => normalizeMarkerVariant(entry.markerType || entry.type || entry.variant),
|
|
47982
|
+
variantProp: "markerType"
|
|
47983
|
+
}),
|
|
47984
|
+
[resolvedKeyInput]
|
|
47985
|
+
);
|
|
47986
|
+
const markerKeyData = React42.useMemo(
|
|
47987
|
+
() => buildKeyLegend(normalizedLegendConfig),
|
|
47988
|
+
[normalizedLegendConfig]
|
|
47989
|
+
);
|
|
47854
47990
|
const markerKeyGroups = markerKeyData.groups;
|
|
47855
|
-
const markerKeyMetaMap = markerKeyData.
|
|
47991
|
+
const markerKeyMetaMap = markerKeyData.lookup;
|
|
47856
47992
|
const clusterOptions = React42.useMemo(
|
|
47857
47993
|
() => buildClusterOptions(leafletLib, typeof maxClusterRadius === "number" ? maxClusterRadius : null),
|
|
47858
47994
|
[leafletLib, maxClusterRadius]
|