mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-07-23 20:42:02 +00:00
feat(ui): add ThreatMap component and refactor chart color system
- Add ThreatMap component with world map visualization - Refactor chart colors to use chart- prefix in CSS variables - Update all graph components to use new color system - Add topojson-client and d3-geo dependencies
This commit is contained in:
@@ -46,6 +46,14 @@ help: ## Show this help.
|
||||
@echo "Prowler Makefile"
|
||||
@awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m<target>\033[0m\n"} /^[a-zA-Z_-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST)
|
||||
|
||||
##@ Build no cache
|
||||
build-no-cache-dev:
|
||||
docker compose -f docker-compose-dev.yml build --no-cache api-dev worker-dev worker-beat
|
||||
|
||||
##@ Development Environment
|
||||
run-api-dev: ## Start development environment with API, PostgreSQL, Valkey, and workers
|
||||
docker compose -f docker-compose-dev.yml up api-dev postgres valkey worker-dev worker-beat --build
|
||||
docker compose -f docker-compose-dev.yml up api-dev postgres valkey worker-dev worker-beat
|
||||
|
||||
##@ Development Environment
|
||||
build-and-run-api-dev: build-no-cache-dev run-api-dev
|
||||
|
||||
|
||||
@@ -110,7 +110,7 @@ export function HorizontalBarChart({ data, title }: HorizontalBarChartProps) {
|
||||
>
|
||||
<span className="font-semibold">{item.percentage}%</span>
|
||||
<span className="text-slate-400">•</span>
|
||||
<span>{item.value.toLocaleString()}</span>
|
||||
<span className="font-bold">{item.value.toLocaleString()}</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -28,7 +28,7 @@ interface RadarChartProps {
|
||||
const chartConfig = {
|
||||
value: {
|
||||
label: "Findings",
|
||||
color: "var(--color-magenta)",
|
||||
color: "var(--chart-radar-primary)",
|
||||
},
|
||||
} satisfies ChartConfig;
|
||||
|
||||
@@ -84,8 +84,9 @@ const CustomDot = (props: any) => {
|
||||
cx={cx}
|
||||
cy={cy}
|
||||
r={isSelected ? 9 : 6}
|
||||
fill={isSelected ? "var(--color-success)" : "var(--color-purple-dark)"}
|
||||
fill={isSelected ? "var(--chart-success-color)" : "var(--chart-radar-primary)"}
|
||||
fillOpacity={1}
|
||||
className={isSelected ? "drop-shadow-[0_0_8px_#86da26]" : ""}
|
||||
style={{
|
||||
cursor: onSelectPoint ? "pointer" : "default",
|
||||
pointerEvents: "all",
|
||||
@@ -117,7 +118,7 @@ export function RadarChart({
|
||||
<PolarGrid strokeOpacity={0.3} />
|
||||
<Radar
|
||||
dataKey={dataKey}
|
||||
fill="var(--color-magenta)"
|
||||
fill="var(--chart-radar-primary)"
|
||||
fillOpacity={0.2}
|
||||
activeDot={false}
|
||||
dot={
|
||||
@@ -135,7 +136,7 @@ export function RadarChart({
|
||||
}
|
||||
: {
|
||||
r: 6,
|
||||
fill: "var(--color-purple-dark)",
|
||||
fill: "var(--chart-radar-primary)",
|
||||
fillOpacity: 1,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ interface RadialChartProps {
|
||||
export function RadialChart({
|
||||
percentage,
|
||||
label = "Score",
|
||||
color = "var(--color-success)",
|
||||
color = "var(--chart-success-color)",
|
||||
backgroundColor = CHART_COLORS.tooltipBackground,
|
||||
height = 250,
|
||||
innerRadius = 60,
|
||||
|
||||
@@ -23,11 +23,11 @@ interface SankeyChartProps {
|
||||
}
|
||||
|
||||
const COLORS: Record<string, string> = {
|
||||
Success: "var(--color-success)",
|
||||
Fail: "var(--color-destructive)",
|
||||
AWS: "var(--color-orange)",
|
||||
Azure: "var(--color-cyan)",
|
||||
Google: "var(--color-red)",
|
||||
Success: "var(--chart-success-color)",
|
||||
Fail: "var(--chart-fail)",
|
||||
AWS: "var(--chart-provider-aws)",
|
||||
Azure: "var(--chart-provider-azure)",
|
||||
Google: "var(--chart-provider-google)",
|
||||
...SEVERITY_COLORS,
|
||||
};
|
||||
|
||||
|
||||
@@ -34,9 +34,9 @@ interface ScatterPlotProps {
|
||||
}
|
||||
|
||||
const PROVIDER_COLORS = {
|
||||
AWS: "var(--color-orange)",
|
||||
Azure: "var(--color-cyan)",
|
||||
Google: "var(--color-red)",
|
||||
AWS: "var(--chart-provider-aws)",
|
||||
Azure: "var(--chart-provider-azure)",
|
||||
Google: "var(--chart-provider-google)",
|
||||
};
|
||||
|
||||
const CustomTooltip = ({ active, payload }: any) => {
|
||||
@@ -69,7 +69,7 @@ const CustomScatterDot = ({
|
||||
const isSelected = selectedPoint?.name === payload.name;
|
||||
const size = isSelected ? 18 : 8;
|
||||
const fill = isSelected
|
||||
? "var(--color-success)"
|
||||
? "#86DA26"
|
||||
: PROVIDER_COLORS[payload.provider as keyof typeof PROVIDER_COLORS] ||
|
||||
CHART_COLORS.defaultColor;
|
||||
|
||||
@@ -79,8 +79,9 @@ const CustomScatterDot = ({
|
||||
cy={cy}
|
||||
r={size / 2}
|
||||
fill={fill}
|
||||
stroke={isSelected ? "var(--color-success)" : "transparent"}
|
||||
stroke={isSelected ? "#86DA26" : "transparent"}
|
||||
strokeWidth={2}
|
||||
className={isSelected ? "drop-shadow-[0_0_8px_#86da26]" : ""}
|
||||
style={{ cursor: "pointer" }}
|
||||
onClick={() => onSelectPoint?.(payload)}
|
||||
/>
|
||||
|
||||
@@ -0,0 +1,438 @@
|
||||
"use client";
|
||||
|
||||
import * as d3 from "d3";
|
||||
import type {
|
||||
Feature,
|
||||
FeatureCollection,
|
||||
GeoJsonProperties,
|
||||
Geometry,
|
||||
} from "geojson";
|
||||
import { AlertTriangle, ChevronDown, Info, MapPin } from "lucide-react";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
import { feature } from "topojson-client";
|
||||
import type {
|
||||
GeometryCollection,
|
||||
Objects,
|
||||
Topology,
|
||||
} from "topojson-specification";
|
||||
|
||||
import { HorizontalBarChart } from "./HorizontalBarChart";
|
||||
import { BarDataPoint } from "./types";
|
||||
|
||||
// Constants
|
||||
const MAP_CONFIG = {
|
||||
defaultWidth: 688,
|
||||
defaultHeight: 400,
|
||||
pointRadius: 6,
|
||||
selectedPointRadius: 8,
|
||||
transitionDuration: 300,
|
||||
} as const;
|
||||
|
||||
const MAP_COLORS = {
|
||||
landFill: "var(--chart-border-emphasis)",
|
||||
landStroke: "var(--chart-border)",
|
||||
pointDefault: "#DB2B49",
|
||||
pointSelected: "#86DA26",
|
||||
pointHover: "#DB2B49",
|
||||
} as const;
|
||||
|
||||
const RISK_LEVELS = {
|
||||
LOW_HIGH: "low-high",
|
||||
HIGH: "high",
|
||||
CRITICAL: "critical",
|
||||
} as const;
|
||||
|
||||
type RiskLevel = (typeof RISK_LEVELS)[keyof typeof RISK_LEVELS];
|
||||
|
||||
interface LocationPoint {
|
||||
id: string;
|
||||
name: string;
|
||||
region: string;
|
||||
coordinates: [number, number];
|
||||
totalFindings: number;
|
||||
riskLevel: RiskLevel;
|
||||
severityData: BarDataPoint[];
|
||||
change?: number;
|
||||
}
|
||||
|
||||
interface ThreatMapData {
|
||||
locations: LocationPoint[];
|
||||
regions: string[];
|
||||
}
|
||||
|
||||
interface ThreatMapProps {
|
||||
data: ThreatMapData;
|
||||
height?: number;
|
||||
onLocationSelect?: (location: LocationPoint | null) => void;
|
||||
}
|
||||
|
||||
// Utility functions
|
||||
function createProjection(width: number, height: number) {
|
||||
return d3
|
||||
.geoNaturalEarth1()
|
||||
.fitExtent(
|
||||
[
|
||||
[1, 1],
|
||||
[width - 1, height - 1],
|
||||
],
|
||||
{ type: "Sphere" },
|
||||
)
|
||||
.precision(0.2);
|
||||
}
|
||||
|
||||
async function fetchWorldData(): Promise<FeatureCollection | null> {
|
||||
try {
|
||||
const worldAtlasModule = await import("world-atlas/countries-110m.json");
|
||||
const worldData = worldAtlasModule.default || worldAtlasModule;
|
||||
const topology = worldData as unknown as Topology<Objects>;
|
||||
return feature(
|
||||
topology,
|
||||
topology.objects.countries as GeometryCollection,
|
||||
) as FeatureCollection;
|
||||
} catch (error) {
|
||||
console.error("Error loading world map data:", error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// Helper: Create SVG element
|
||||
function createSVGElement<T extends SVGElement>(
|
||||
type: string,
|
||||
attributes: Record<string, string>,
|
||||
): T {
|
||||
const element = document.createElementNS(
|
||||
"http://www.w3.org/2000/svg",
|
||||
type,
|
||||
) as T;
|
||||
Object.entries(attributes).forEach(([key, value]) => {
|
||||
element.setAttribute(key, value);
|
||||
});
|
||||
return element;
|
||||
}
|
||||
|
||||
// Components
|
||||
function MapTooltip({
|
||||
location,
|
||||
position,
|
||||
}: {
|
||||
location: LocationPoint;
|
||||
position: { x: number; y: number };
|
||||
}) {
|
||||
return (
|
||||
<div
|
||||
className="pointer-events-none absolute z-50 min-w-[200px] rounded-lg border border-slate-700 bg-slate-800 p-3 shadow-lg"
|
||||
style={{
|
||||
left: `${position.x + 15}px`,
|
||||
top: `${position.y + 15}px`,
|
||||
transform: "translate(0, -50%)",
|
||||
}}
|
||||
>
|
||||
<div className="flex items-center gap-2">
|
||||
<MapPin size={14} className="text-slate-400" />
|
||||
<span className="text-sm font-semibold text-white">
|
||||
{location.name}
|
||||
</span>
|
||||
</div>
|
||||
<div className="mt-1 flex items-center gap-2">
|
||||
<AlertTriangle size={14} className="text-[#DB2B49]" />
|
||||
<span className="text-sm text-white">
|
||||
{location.totalFindings.toLocaleString()} Fail Findings
|
||||
</span>
|
||||
</div>
|
||||
{location.change !== undefined && (
|
||||
<p className="mt-1 text-xs text-slate-400">
|
||||
<span className="font-bold">
|
||||
{location.change > 0 ? "+" : ""}
|
||||
{location.change}%
|
||||
</span>{" "}
|
||||
since last scan
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function EmptyState() {
|
||||
return (
|
||||
<div className="flex h-full min-h-[400px] items-center justify-center rounded-lg border border-slate-700 bg-slate-800 p-6">
|
||||
<div className="text-center">
|
||||
<Info size={48} className="mx-auto mb-2 text-slate-500" />
|
||||
<p className="text-sm text-slate-400">
|
||||
Select a location on the map to view details
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function LoadingState({ height }: { height: number }) {
|
||||
return (
|
||||
<div className="flex items-center justify-center" style={{ height }}>
|
||||
<div className="text-center">
|
||||
<div className="mb-2 text-slate-400">Loading map...</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export function ThreatMap({
|
||||
data,
|
||||
height = MAP_CONFIG.defaultHeight,
|
||||
}: ThreatMapProps) {
|
||||
const svgRef = useRef<SVGSVGElement>(null);
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
const [selectedLocation, setSelectedLocation] =
|
||||
useState<LocationPoint | null>(null);
|
||||
const [hoveredLocation, setHoveredLocation] = useState<LocationPoint | null>(
|
||||
null,
|
||||
);
|
||||
const [tooltipPosition, setTooltipPosition] = useState<{
|
||||
x: number;
|
||||
y: number;
|
||||
} | null>(null);
|
||||
const [selectedRegion, setSelectedRegion] = useState<string>("All Regions");
|
||||
const [worldData, setWorldData] = useState<FeatureCollection | null>(null);
|
||||
const [isLoadingMap, setIsLoadingMap] = useState(true);
|
||||
const [dimensions, setDimensions] = useState<{
|
||||
width: number;
|
||||
height: number;
|
||||
}>({
|
||||
width: MAP_CONFIG.defaultWidth,
|
||||
height,
|
||||
});
|
||||
|
||||
const filteredLocations =
|
||||
selectedRegion === "All Regions"
|
||||
? data.locations
|
||||
: data.locations.filter((loc) => loc.region === selectedRegion);
|
||||
|
||||
// Fetch world data once on mount
|
||||
useEffect(() => {
|
||||
let isMounted = true;
|
||||
fetchWorldData()
|
||||
.then((data) => {
|
||||
if (isMounted && data) setWorldData(data);
|
||||
})
|
||||
.catch(console.error)
|
||||
.finally(() => {
|
||||
if (isMounted) setIsLoadingMap(false);
|
||||
});
|
||||
return () => {
|
||||
isMounted = false;
|
||||
};
|
||||
}, []);
|
||||
|
||||
// Update dimensions on resize
|
||||
useEffect(() => {
|
||||
const updateDimensions = () => {
|
||||
if (containerRef.current) {
|
||||
setDimensions({ width: containerRef.current.clientWidth, height });
|
||||
}
|
||||
};
|
||||
updateDimensions();
|
||||
window.addEventListener("resize", updateDimensions);
|
||||
return () => window.removeEventListener("resize", updateDimensions);
|
||||
}, [height]);
|
||||
|
||||
// Render the map
|
||||
useEffect(() => {
|
||||
if (!svgRef.current || !worldData || isLoadingMap) return;
|
||||
|
||||
const svg = svgRef.current;
|
||||
const { width, height } = dimensions;
|
||||
svg.innerHTML = "";
|
||||
|
||||
const projection = createProjection(width, height);
|
||||
const path = d3.geoPath().projection(projection);
|
||||
|
||||
// Render countries
|
||||
const mapGroup = createSVGElement<SVGGElement>("g", {
|
||||
class: "map-countries",
|
||||
});
|
||||
worldData.features?.forEach(
|
||||
(feature: Feature<Geometry, GeoJsonProperties>) => {
|
||||
const pathData = path(feature);
|
||||
if (pathData) {
|
||||
const pathElement = createSVGElement<SVGPathElement>("path", {
|
||||
d: pathData,
|
||||
fill: MAP_COLORS.landFill,
|
||||
stroke: MAP_COLORS.landStroke,
|
||||
"stroke-width": "0.5",
|
||||
});
|
||||
mapGroup.appendChild(pathElement);
|
||||
}
|
||||
},
|
||||
);
|
||||
svg.appendChild(mapGroup);
|
||||
|
||||
// Helper to update tooltip position
|
||||
const updateTooltip = (e: MouseEvent) => {
|
||||
const rect = svg.getBoundingClientRect();
|
||||
setTooltipPosition({
|
||||
x: e.clientX - rect.left,
|
||||
y: e.clientY - rect.top,
|
||||
});
|
||||
};
|
||||
|
||||
// Helper to create circle
|
||||
const createCircle = (location: LocationPoint) => {
|
||||
const projected = projection(location.coordinates);
|
||||
if (!projected) return null;
|
||||
|
||||
const [x, y] = projected;
|
||||
if (x < 0 || x > width || y < 0 || y > height) return null;
|
||||
|
||||
const isSelected = selectedLocation?.id === location.id;
|
||||
const isHovered = hoveredLocation?.id === location.id;
|
||||
const classes = ["cursor-pointer"];
|
||||
|
||||
if (isSelected) classes.push("drop-shadow-[0_0_8px_#86da26]");
|
||||
if (isHovered && !isSelected) classes.push("opacity-70");
|
||||
|
||||
const circle = createSVGElement<SVGCircleElement>("circle", {
|
||||
cx: x.toString(),
|
||||
cy: y.toString(),
|
||||
r: (isSelected
|
||||
? MAP_CONFIG.selectedPointRadius
|
||||
: MAP_CONFIG.pointRadius
|
||||
).toString(),
|
||||
fill: isSelected ? MAP_COLORS.pointSelected : MAP_COLORS.pointDefault,
|
||||
class: classes.join(" "),
|
||||
});
|
||||
|
||||
circle.addEventListener("click", () =>
|
||||
setSelectedLocation(isSelected ? null : location),
|
||||
);
|
||||
circle.addEventListener("mouseenter", (e) => {
|
||||
setHoveredLocation(location);
|
||||
updateTooltip(e);
|
||||
});
|
||||
circle.addEventListener("mousemove", updateTooltip);
|
||||
circle.addEventListener("mouseleave", () => {
|
||||
setHoveredLocation(null);
|
||||
setTooltipPosition(null);
|
||||
});
|
||||
|
||||
return circle;
|
||||
};
|
||||
|
||||
// Render points
|
||||
const pointsGroup = createSVGElement<SVGGElement>("g", {
|
||||
class: "threat-points",
|
||||
});
|
||||
|
||||
// Unselected points first
|
||||
filteredLocations.forEach((location) => {
|
||||
if (selectedLocation?.id !== location.id) {
|
||||
const circle = createCircle(location);
|
||||
if (circle) pointsGroup.appendChild(circle);
|
||||
}
|
||||
});
|
||||
|
||||
// Selected point last (on top)
|
||||
if (selectedLocation) {
|
||||
const selectedData = filteredLocations.find(
|
||||
(loc) => loc.id === selectedLocation.id,
|
||||
);
|
||||
if (selectedData) {
|
||||
const circle = createCircle(selectedData);
|
||||
if (circle) pointsGroup.appendChild(circle);
|
||||
}
|
||||
}
|
||||
|
||||
svg.appendChild(pointsGroup);
|
||||
}, [
|
||||
dimensions,
|
||||
filteredLocations,
|
||||
selectedLocation,
|
||||
hoveredLocation,
|
||||
worldData,
|
||||
isLoadingMap,
|
||||
]);
|
||||
|
||||
return (
|
||||
<div className="flex w-full flex-col gap-6 lg:flex-row lg:items-start">
|
||||
{/* Map Section */}
|
||||
<div className="flex-1">
|
||||
<div className="mb-4 flex items-center justify-between">
|
||||
<h3 className="text-lg font-semibold text-white">Threat Map</h3>
|
||||
<div className="relative">
|
||||
<select
|
||||
value={selectedRegion}
|
||||
onChange={(e) => setSelectedRegion(e.target.value)}
|
||||
className="appearance-none rounded-lg border border-slate-700 bg-slate-800 px-4 py-2 pr-10 text-sm text-white focus:border-slate-600 focus:outline-none"
|
||||
>
|
||||
<option value="All Regions">All Regions</option>
|
||||
{data.regions.map((region) => (
|
||||
<option key={region} value={region}>
|
||||
{region}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
<ChevronDown
|
||||
size={16}
|
||||
className="pointer-events-none absolute top-1/2 right-3 -translate-y-1/2 text-slate-400"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
ref={containerRef}
|
||||
className="rounded-lg border border-slate-700 bg-slate-800/50 p-4"
|
||||
>
|
||||
{isLoadingMap ? (
|
||||
<LoadingState height={dimensions.height} />
|
||||
) : (
|
||||
<>
|
||||
<div className="relative">
|
||||
<svg
|
||||
ref={svgRef}
|
||||
width={dimensions.width}
|
||||
height={dimensions.height}
|
||||
className="w-full"
|
||||
style={{ maxWidth: "100%" }}
|
||||
/>
|
||||
{hoveredLocation && tooltipPosition && (
|
||||
<MapTooltip
|
||||
location={hoveredLocation}
|
||||
position={tooltipPosition}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
<div className="mt-4 flex items-center gap-2">
|
||||
<div className="h-3 w-3 rounded-full bg-[#DB2B49]" />
|
||||
<span className="text-sm text-slate-400">
|
||||
{filteredLocations.length} Locations
|
||||
</span>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Details Section */}
|
||||
<div className="w-full lg:w-[400px]">
|
||||
<div className="mb-4 h-10" />
|
||||
{selectedLocation ? (
|
||||
<div className="rounded-lg border border-slate-700 bg-slate-800 p-6">
|
||||
<div className="mb-6">
|
||||
<div className="mb-1 flex items-center gap-2">
|
||||
<div className="h-2 w-2 rounded-full bg-[#86DA26]" />
|
||||
<h4 className="text-base font-semibold text-white">
|
||||
{selectedLocation.name}
|
||||
</h4>
|
||||
</div>
|
||||
<p className="text-sm text-slate-400">
|
||||
{selectedLocation.totalFindings.toLocaleString()} Total Findings
|
||||
</p>
|
||||
</div>
|
||||
<HorizontalBarChart data={selectedLocation.severityData} />
|
||||
</div>
|
||||
) : (
|
||||
<EmptyState />
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -7,3 +7,4 @@ export { RadialChart } from "./RadialChart";
|
||||
export { SankeyChart } from "./SankeyChart";
|
||||
export { ScatterPlot } from "./ScatterPlot";
|
||||
export { ChartLegend, type ChartLegendItem } from "./shared/ChartLegend";
|
||||
export { ThreatMap } from "./ThreatMap";
|
||||
|
||||
@@ -1,21 +1,22 @@
|
||||
export const SEVERITY_COLORS = {
|
||||
Informational: "var(--color-info)",
|
||||
Low: "var(--color-warning)",
|
||||
Medium: "var(--color-warning-emphasis)",
|
||||
High: "var(--color-danger)",
|
||||
Critical: "var(--color-danger-emphasis)",
|
||||
Informational: "var(--chart-info)",
|
||||
Info: "var(--chart-info)",
|
||||
Low: "var(--chart-warning)",
|
||||
Medium: "var(--chart-warning-emphasis)",
|
||||
High: "var(--chart-danger)",
|
||||
Critical: "var(--chart-danger-emphasis)",
|
||||
} as const;
|
||||
|
||||
export const CHART_COLORS = {
|
||||
tooltipBorder: "var(--color-slate-700)",
|
||||
tooltipBackground: "var(--color-slate-800)",
|
||||
textPrimary: "var(--color-white)",
|
||||
textSecondary: "var(--color-slate-400)",
|
||||
gridLine: "var(--color-slate-700)",
|
||||
tooltipBorder: "var(--chart-border-emphasis)",
|
||||
tooltipBackground: "var(--chart-background)",
|
||||
textPrimary: "#ffffff",
|
||||
textSecondary: "var(--chart-text-secondary)",
|
||||
gridLine: "var(--chart-border-emphasis)",
|
||||
backgroundTrack: "rgba(51, 65, 85, 0.5)", // slate-700 with 50% opacity
|
||||
alertPillBg: "var(--color-alert-pill-bg)",
|
||||
alertPillText: "var(--color-alert-pill-text)",
|
||||
defaultColor: "var(--color-slate-500)", // Default fallback color for charts
|
||||
alertPillBg: "var(--chart-alert-bg)",
|
||||
alertPillText: "var(--chart-alert-text)",
|
||||
defaultColor: "#64748b", // slate-500
|
||||
} as const;
|
||||
|
||||
export const CHART_DIMENSIONS = {
|
||||
|
||||
@@ -215,6 +215,14 @@
|
||||
"strategy": "installed",
|
||||
"generatedAt": "2025-09-10T11:50:17.548Z"
|
||||
},
|
||||
{
|
||||
"section": "dependencies",
|
||||
"name": "d3",
|
||||
"from": "7.9.0",
|
||||
"to": "7.9.0",
|
||||
"strategy": "installed",
|
||||
"generatedAt": "2025-10-16T10:46:11.221Z"
|
||||
},
|
||||
{
|
||||
"section": "dependencies",
|
||||
"name": "date-fns",
|
||||
@@ -399,6 +407,14 @@
|
||||
"strategy": "installed",
|
||||
"generatedAt": "2025-09-10T11:50:17.548Z"
|
||||
},
|
||||
{
|
||||
"section": "dependencies",
|
||||
"name": "topojson-client",
|
||||
"from": "3.1.0",
|
||||
"to": "3.1.0",
|
||||
"strategy": "installed",
|
||||
"generatedAt": "2025-10-16T10:46:11.221Z"
|
||||
},
|
||||
{
|
||||
"section": "dependencies",
|
||||
"name": "uuid",
|
||||
@@ -407,6 +423,14 @@
|
||||
"strategy": "installed",
|
||||
"generatedAt": "2025-09-10T11:50:17.548Z"
|
||||
},
|
||||
{
|
||||
"section": "dependencies",
|
||||
"name": "world-atlas",
|
||||
"from": "2.0.2",
|
||||
"to": "2.0.2",
|
||||
"strategy": "installed",
|
||||
"generatedAt": "2025-10-16T10:46:11.221Z"
|
||||
},
|
||||
{
|
||||
"section": "dependencies",
|
||||
"name": "zod",
|
||||
@@ -439,6 +463,14 @@
|
||||
"strategy": "installed",
|
||||
"generatedAt": "2025-09-10T11:50:17.554Z"
|
||||
},
|
||||
{
|
||||
"section": "devDependencies",
|
||||
"name": "@types/d3",
|
||||
"from": "7.4.3",
|
||||
"to": "7.4.3",
|
||||
"strategy": "installed",
|
||||
"generatedAt": "2025-10-16T10:46:11.221Z"
|
||||
},
|
||||
{
|
||||
"section": "devDependencies",
|
||||
"name": "@types/node",
|
||||
@@ -463,6 +495,14 @@
|
||||
"strategy": "installed",
|
||||
"generatedAt": "2025-09-23T10:22:08.630Z"
|
||||
},
|
||||
{
|
||||
"section": "devDependencies",
|
||||
"name": "@types/topojson-client",
|
||||
"from": "3.1.5",
|
||||
"to": "3.1.5",
|
||||
"strategy": "installed",
|
||||
"generatedAt": "2025-10-16T10:46:11.221Z"
|
||||
},
|
||||
{
|
||||
"section": "devDependencies",
|
||||
"name": "@types/uuid",
|
||||
|
||||
Generated
+581
@@ -36,6 +36,7 @@
|
||||
"alert": "6.0.2",
|
||||
"class-variance-authority": "0.7.1",
|
||||
"clsx": "2.1.1",
|
||||
"d3": "7.9.0",
|
||||
"date-fns": "4.1.0",
|
||||
"framer-motion": "11.18.2",
|
||||
"intl-messageformat": "10.7.16",
|
||||
@@ -59,16 +60,20 @@
|
||||
"sharp": "0.33.5",
|
||||
"tailwind-merge": "3.3.1",
|
||||
"tailwindcss-animate": "1.0.7",
|
||||
"topojson-client": "3.1.0",
|
||||
"uuid": "11.1.0",
|
||||
"world-atlas": "2.0.2",
|
||||
"zod": "4.1.11",
|
||||
"zustand": "5.0.8"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@iconify/react": "5.2.1",
|
||||
"@playwright/test": "1.53.2",
|
||||
"@types/d3": "7.4.3",
|
||||
"@types/node": "20.5.7",
|
||||
"@types/react": "19.1.13",
|
||||
"@types/react-dom": "19.1.9",
|
||||
"@types/topojson-client": "3.1.5",
|
||||
"@types/uuid": "10.0.0",
|
||||
"@typescript-eslint/eslint-plugin": "7.18.0",
|
||||
"@typescript-eslint/parser": "7.18.0",
|
||||
@@ -7630,24 +7635,173 @@
|
||||
"integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/d3": {
|
||||
"version": "7.4.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/d3/-/d3-7.4.3.tgz",
|
||||
"integrity": "sha512-lZXZ9ckh5R8uiFVt8ogUNf+pIrK4EsWrx2Np75WvF/eTpJ0FMHNhjXk8CKEx/+gpHbNQyJWehbFaTvqmHWB3ww==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/d3-array": "*",
|
||||
"@types/d3-axis": "*",
|
||||
"@types/d3-brush": "*",
|
||||
"@types/d3-chord": "*",
|
||||
"@types/d3-color": "*",
|
||||
"@types/d3-contour": "*",
|
||||
"@types/d3-delaunay": "*",
|
||||
"@types/d3-dispatch": "*",
|
||||
"@types/d3-drag": "*",
|
||||
"@types/d3-dsv": "*",
|
||||
"@types/d3-ease": "*",
|
||||
"@types/d3-fetch": "*",
|
||||
"@types/d3-force": "*",
|
||||
"@types/d3-format": "*",
|
||||
"@types/d3-geo": "*",
|
||||
"@types/d3-hierarchy": "*",
|
||||
"@types/d3-interpolate": "*",
|
||||
"@types/d3-path": "*",
|
||||
"@types/d3-polygon": "*",
|
||||
"@types/d3-quadtree": "*",
|
||||
"@types/d3-random": "*",
|
||||
"@types/d3-scale": "*",
|
||||
"@types/d3-scale-chromatic": "*",
|
||||
"@types/d3-selection": "*",
|
||||
"@types/d3-shape": "*",
|
||||
"@types/d3-time": "*",
|
||||
"@types/d3-time-format": "*",
|
||||
"@types/d3-timer": "*",
|
||||
"@types/d3-transition": "*",
|
||||
"@types/d3-zoom": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/d3-array": {
|
||||
"version": "3.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/d3-array/-/d3-array-3.2.2.tgz",
|
||||
"integrity": "sha512-hOLWVbm7uRza0BYXpIIW5pxfrKe0W+D5lrFiAEYR+pb6w3N2SwSMaJbXdUfSEv+dT4MfHBLtn5js0LAWaO6otw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/d3-axis": {
|
||||
"version": "3.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/d3-axis/-/d3-axis-3.0.6.tgz",
|
||||
"integrity": "sha512-pYeijfZuBd87T0hGn0FO1vQ/cgLk6E1ALJjfkC0oJ8cbwkZl3TpgS8bVBLZN+2jjGgg38epgxb2zmoGtSfvgMw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/d3-selection": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/d3-brush": {
|
||||
"version": "3.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/d3-brush/-/d3-brush-3.0.6.tgz",
|
||||
"integrity": "sha512-nH60IZNNxEcrh6L1ZSMNA28rj27ut/2ZmI3r96Zd+1jrZD++zD3LsMIjWlvg4AYrHn/Pqz4CF3veCxGjtbqt7A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/d3-selection": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/d3-chord": {
|
||||
"version": "3.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/d3-chord/-/d3-chord-3.0.6.tgz",
|
||||
"integrity": "sha512-LFYWWd8nwfwEmTZG9PfQxd17HbNPksHBiJHaKuY1XeqscXacsS2tyoo6OdRsjf+NQYeB6XrNL3a25E3gH69lcg==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/d3-color": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz",
|
||||
"integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/d3-contour": {
|
||||
"version": "3.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/d3-contour/-/d3-contour-3.0.6.tgz",
|
||||
"integrity": "sha512-BjzLgXGnCWjUSYGfH1cpdo41/hgdWETu4YxpezoztawmqsvCeep+8QGfiY6YbDvfgHz/DkjeIkkZVJavB4a3rg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/d3-array": "*",
|
||||
"@types/geojson": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/d3-delaunay": {
|
||||
"version": "6.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/d3-delaunay/-/d3-delaunay-6.0.4.tgz",
|
||||
"integrity": "sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/d3-dispatch": {
|
||||
"version": "3.0.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/d3-dispatch/-/d3-dispatch-3.0.7.tgz",
|
||||
"integrity": "sha512-5o9OIAdKkhN1QItV2oqaE5KMIiXAvDWBDPrD85e58Qlz1c1kI/J0NcqbEG88CoTwJrYe7ntUCVfeUl2UJKbWgA==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/d3-drag": {
|
||||
"version": "3.0.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/d3-drag/-/d3-drag-3.0.7.tgz",
|
||||
"integrity": "sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/d3-selection": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/d3-dsv": {
|
||||
"version": "3.0.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/d3-dsv/-/d3-dsv-3.0.7.tgz",
|
||||
"integrity": "sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/d3-ease": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/d3-ease/-/d3-ease-3.0.2.tgz",
|
||||
"integrity": "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/d3-fetch": {
|
||||
"version": "3.0.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/d3-fetch/-/d3-fetch-3.0.7.tgz",
|
||||
"integrity": "sha512-fTAfNmxSb9SOWNB9IoG5c8Hg6R+AzUHDRlsXsDZsNp6sxAEOP0tkP3gKkNSO/qmHPoBFTxNrjDprVHDQDvo5aA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/d3-dsv": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/d3-force": {
|
||||
"version": "3.0.10",
|
||||
"resolved": "https://registry.npmjs.org/@types/d3-force/-/d3-force-3.0.10.tgz",
|
||||
"integrity": "sha512-ZYeSaCF3p73RdOKcjj+swRlZfnYpK1EbaDiYICEEp5Q6sUiqFaFQ9qgoshp5CzIyyb/yD09kD9o2zEltCexlgw==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/d3-format": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/d3-format/-/d3-format-3.0.4.tgz",
|
||||
"integrity": "sha512-fALi2aI6shfg7vM5KiR1wNJnZ7r6UuggVqtDA+xiEdPZQwy/trcQaHnwShLuLdta2rTymCNpxYTiMZX/e09F4g==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/d3-geo": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/d3-geo/-/d3-geo-3.1.0.tgz",
|
||||
"integrity": "sha512-856sckF0oP/diXtS4jNsiQw/UuK5fQG8l/a9VVLeSouf1/PPbBE1i1W852zVwKwYCBkFJJB7nCFTbk6UMEXBOQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/geojson": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/d3-hierarchy": {
|
||||
"version": "3.1.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/d3-hierarchy/-/d3-hierarchy-3.1.7.tgz",
|
||||
"integrity": "sha512-tJFtNoYBtRtkNysX1Xq4sxtjK8YgoWUNpIiUee0/jHGRwqvzYxkq0hGVbbOGSz+JgFxxRu4K8nb3YpG3CMARtg==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/d3-interpolate": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz",
|
||||
@@ -7663,6 +7817,27 @@
|
||||
"integrity": "sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/d3-polygon": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/d3-polygon/-/d3-polygon-3.0.2.tgz",
|
||||
"integrity": "sha512-ZuWOtMaHCkN9xoeEMr1ubW2nGWsp4nIql+OPQRstu4ypeZ+zk3YKqQT0CXVe/PYqrKpZAi+J9mTs05TKwjXSRA==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/d3-quadtree": {
|
||||
"version": "3.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/d3-quadtree/-/d3-quadtree-3.0.6.tgz",
|
||||
"integrity": "sha512-oUzyO1/Zm6rsxKRHA1vH0NEDG58HrT5icx/azi9MF1TWdtttWl0UIUsjEQBBh+SIkrpd21ZjEv7ptxWys1ncsg==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/d3-random": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/d3-random/-/d3-random-3.0.3.tgz",
|
||||
"integrity": "sha512-Imagg1vJ3y76Y2ea0871wpabqp613+8/r0mCLEBfdtqC7xMSfj9idOnmBYyMoULfHePJyxMAw3nWhJxzc+LFwQ==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/d3-scale": {
|
||||
"version": "4.0.9",
|
||||
"resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-4.0.9.tgz",
|
||||
@@ -7672,6 +7847,20 @@
|
||||
"@types/d3-time": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/d3-scale-chromatic": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz",
|
||||
"integrity": "sha512-iWMJgwkK7yTRmWqRB5plb1kadXyQ5Sj8V/zYlFGMUBbIPKQScw+Dku9cAAMgJG+z5GYDoMjWGLVOvjghDEFnKQ==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/d3-selection": {
|
||||
"version": "3.0.11",
|
||||
"resolved": "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-3.0.11.tgz",
|
||||
"integrity": "sha512-bhAXu23DJWsrI45xafYpkQ4NtcKMwWnAC/vKrd2l+nxMFuvOT3XMYTIj2opv8vq8AO5Yh7Qac/nSeP/3zjTK0w==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/d3-shape": {
|
||||
"version": "3.1.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.7.tgz",
|
||||
@@ -7687,12 +7876,40 @@
|
||||
"integrity": "sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/d3-time-format": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/d3-time-format/-/d3-time-format-4.0.3.tgz",
|
||||
"integrity": "sha512-5xg9rC+wWL8kdDj153qZcsJ0FWiFt0J5RB6LYUNZjwSnesfblqrI/bJ1wBdJ8OQfncgbJG5+2F+qfqnqyzYxyg==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/d3-timer": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/d3-timer/-/d3-timer-3.0.2.tgz",
|
||||
"integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/d3-transition": {
|
||||
"version": "3.0.9",
|
||||
"resolved": "https://registry.npmjs.org/@types/d3-transition/-/d3-transition-3.0.9.tgz",
|
||||
"integrity": "sha512-uZS5shfxzO3rGlu0cC3bjmMFKsXv+SmZZcgp0KD22ts4uGXp5EVYGzu/0YdwZeKmddhcAccYtREJKkPfXkZuCg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/d3-selection": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/d3-zoom": {
|
||||
"version": "3.0.8",
|
||||
"resolved": "https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-3.0.8.tgz",
|
||||
"integrity": "sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/d3-interpolate": "*",
|
||||
"@types/d3-selection": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/debug": {
|
||||
"version": "4.1.12",
|
||||
"resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz",
|
||||
@@ -7717,6 +7934,13 @@
|
||||
"@types/estree": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/geojson": {
|
||||
"version": "7946.0.16",
|
||||
"resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.16.tgz",
|
||||
"integrity": "sha512-6C8nqWur3j98U6+lXDfTUWIfgvZU+EumvpHKcYjujKH7woYyLj2sUmff0tRhrqM7BohUw7Pz3ZB1jj2gW9Fvmg==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/hast": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz",
|
||||
@@ -7798,6 +8022,27 @@
|
||||
"integrity": "sha512-xMAgYwceFhRA2zY+XbEA7mxYbA093wdiW8Vu6gZPGWy9cmOyU9XesH1tNcEWsKFd5Vzrqx5T3D38PWx1FIIXkA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/topojson-client": {
|
||||
"version": "3.1.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/topojson-client/-/topojson-client-3.1.5.tgz",
|
||||
"integrity": "sha512-C79rySTyPxnQNNguTZNI1Ct4D7IXgvyAs3p9HPecnl6mNrJ5+UhvGNYcZfpROYV2lMHI48kJPxwR+F9C6c7nmw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/geojson": "*",
|
||||
"@types/topojson-specification": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/topojson-specification": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/topojson-specification/-/topojson-specification-1.0.5.tgz",
|
||||
"integrity": "sha512-C7KvcQh+C2nr6Y2Ub4YfgvWvWCgP2nOQMtfhlnwsRL4pYmmwzBS7HclGiS87eQfDOU/DLQpX6GEscviaz4yLIQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/geojson": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/unist": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz",
|
||||
@@ -9406,6 +9651,47 @@
|
||||
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/d3": {
|
||||
"version": "7.9.0",
|
||||
"resolved": "https://registry.npmjs.org/d3/-/d3-7.9.0.tgz",
|
||||
"integrity": "sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"d3-array": "3",
|
||||
"d3-axis": "3",
|
||||
"d3-brush": "3",
|
||||
"d3-chord": "3",
|
||||
"d3-color": "3",
|
||||
"d3-contour": "4",
|
||||
"d3-delaunay": "6",
|
||||
"d3-dispatch": "3",
|
||||
"d3-drag": "3",
|
||||
"d3-dsv": "3",
|
||||
"d3-ease": "3",
|
||||
"d3-fetch": "3",
|
||||
"d3-force": "3",
|
||||
"d3-format": "3",
|
||||
"d3-geo": "3",
|
||||
"d3-hierarchy": "3",
|
||||
"d3-interpolate": "3",
|
||||
"d3-path": "3",
|
||||
"d3-polygon": "3",
|
||||
"d3-quadtree": "3",
|
||||
"d3-random": "3",
|
||||
"d3-scale": "4",
|
||||
"d3-scale-chromatic": "3",
|
||||
"d3-selection": "3",
|
||||
"d3-shape": "3",
|
||||
"d3-time": "3",
|
||||
"d3-time-format": "4",
|
||||
"d3-timer": "3",
|
||||
"d3-transition": "3",
|
||||
"d3-zoom": "3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/d3-array": {
|
||||
"version": "3.2.4",
|
||||
"resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz",
|
||||
@@ -9418,6 +9704,43 @@
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/d3-axis": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-3.0.0.tgz",
|
||||
"integrity": "sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==",
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/d3-brush": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-3.0.0.tgz",
|
||||
"integrity": "sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"d3-dispatch": "1 - 3",
|
||||
"d3-drag": "2 - 3",
|
||||
"d3-interpolate": "1 - 3",
|
||||
"d3-selection": "3",
|
||||
"d3-transition": "3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/d3-chord": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/d3-chord/-/d3-chord-3.0.1.tgz",
|
||||
"integrity": "sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"d3-path": "1 - 3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/d3-color": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz",
|
||||
@@ -9427,6 +9750,86 @@
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/d3-contour": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/d3-contour/-/d3-contour-4.0.2.tgz",
|
||||
"integrity": "sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"d3-array": "^3.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/d3-delaunay": {
|
||||
"version": "6.0.4",
|
||||
"resolved": "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-6.0.4.tgz",
|
||||
"integrity": "sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"delaunator": "5"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/d3-dispatch": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz",
|
||||
"integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==",
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/d3-drag": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz",
|
||||
"integrity": "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"d3-dispatch": "1 - 3",
|
||||
"d3-selection": "3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/d3-dsv": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-3.0.1.tgz",
|
||||
"integrity": "sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"commander": "7",
|
||||
"iconv-lite": "0.6",
|
||||
"rw": "1"
|
||||
},
|
||||
"bin": {
|
||||
"csv2json": "bin/dsv2json.js",
|
||||
"csv2tsv": "bin/dsv2dsv.js",
|
||||
"dsv2dsv": "bin/dsv2dsv.js",
|
||||
"dsv2json": "bin/dsv2json.js",
|
||||
"json2csv": "bin/json2dsv.js",
|
||||
"json2dsv": "bin/json2dsv.js",
|
||||
"json2tsv": "bin/json2dsv.js",
|
||||
"tsv2csv": "bin/dsv2dsv.js",
|
||||
"tsv2json": "bin/dsv2json.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/d3-dsv/node_modules/commander": {
|
||||
"version": "7.2.0",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz",
|
||||
"integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/d3-ease": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz",
|
||||
@@ -9436,6 +9839,32 @@
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/d3-fetch": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/d3-fetch/-/d3-fetch-3.0.1.tgz",
|
||||
"integrity": "sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"d3-dsv": "1 - 3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/d3-force": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/d3-force/-/d3-force-3.0.0.tgz",
|
||||
"integrity": "sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"d3-dispatch": "1 - 3",
|
||||
"d3-quadtree": "1 - 3",
|
||||
"d3-timer": "1 - 3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/d3-format": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz",
|
||||
@@ -9445,6 +9874,27 @@
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/d3-geo": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-3.1.1.tgz",
|
||||
"integrity": "sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"d3-array": "2.5.0 - 3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/d3-hierarchy": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz",
|
||||
"integrity": "sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==",
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/d3-interpolate": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz",
|
||||
@@ -9466,6 +9916,33 @@
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/d3-polygon": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/d3-polygon/-/d3-polygon-3.0.1.tgz",
|
||||
"integrity": "sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==",
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/d3-quadtree": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-3.0.1.tgz",
|
||||
"integrity": "sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==",
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/d3-random": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/d3-random/-/d3-random-3.0.1.tgz",
|
||||
"integrity": "sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==",
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/d3-scale": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz",
|
||||
@@ -9482,6 +9959,28 @@
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/d3-scale-chromatic": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz",
|
||||
"integrity": "sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"d3-color": "1 - 3",
|
||||
"d3-interpolate": "1 - 3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/d3-selection": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz",
|
||||
"integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==",
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/d3-shape": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz",
|
||||
@@ -9527,6 +10026,41 @@
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/d3-transition": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz",
|
||||
"integrity": "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"d3-color": "1 - 3",
|
||||
"d3-dispatch": "1 - 3",
|
||||
"d3-ease": "1 - 3",
|
||||
"d3-interpolate": "1 - 3",
|
||||
"d3-timer": "1 - 3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"d3-selection": "2 - 3"
|
||||
}
|
||||
},
|
||||
"node_modules/d3-zoom": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz",
|
||||
"integrity": "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"d3-dispatch": "1 - 3",
|
||||
"d3-drag": "2 - 3",
|
||||
"d3-interpolate": "1 - 3",
|
||||
"d3-selection": "2 - 3",
|
||||
"d3-transition": "2 - 3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/damerau-levenshtein": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz",
|
||||
@@ -9724,6 +10258,15 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/delaunator": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/delaunator/-/delaunator-5.0.1.tgz",
|
||||
"integrity": "sha512-8nvh+XBe96aCESrGOqMp/84b13H9cdKbG5P2ejQCh4d4sK9RL4371qou9drQjMhvnPmhWl5hnmqbEE0fXr9Xnw==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"robust-predicates": "^3.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/depd": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
|
||||
@@ -16409,6 +16952,12 @@
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/robust-predicates": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.2.tgz",
|
||||
"integrity": "sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==",
|
||||
"license": "Unlicense"
|
||||
},
|
||||
"node_modules/router": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz",
|
||||
@@ -16468,6 +17017,12 @@
|
||||
"queue-microtask": "^1.2.2"
|
||||
}
|
||||
},
|
||||
"node_modules/rw": {
|
||||
"version": "1.3.3",
|
||||
"resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz",
|
||||
"integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==",
|
||||
"license": "BSD-3-Clause"
|
||||
},
|
||||
"node_modules/safe-array-concat": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz",
|
||||
@@ -17777,6 +18332,26 @@
|
||||
"node": ">=0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/topojson-client": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/topojson-client/-/topojson-client-3.1.0.tgz",
|
||||
"integrity": "sha512-605uxS6bcYxGXw9qi62XyrV6Q3xwbndjachmNxu8HWTtVPxZfEJN9fd/SZS1Q54Sn2y0TMyMxFj/cJINqGHrKw==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"commander": "2"
|
||||
},
|
||||
"bin": {
|
||||
"topo2geo": "bin/topo2geo",
|
||||
"topomerge": "bin/topomerge",
|
||||
"topoquantize": "bin/topoquantize"
|
||||
}
|
||||
},
|
||||
"node_modules/topojson-client/node_modules/commander": {
|
||||
"version": "2.20.3",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
|
||||
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/tough-cookie": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-6.0.0.tgz",
|
||||
@@ -18513,6 +19088,12 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/world-atlas": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/world-atlas/-/world-atlas-2.0.2.tgz",
|
||||
"integrity": "sha512-IXfV0qwlKXpckz1FhwXVwKRjiIhOnWttOskm5CtxMsjgE/MXAYRHWJqgXOpM8IkcPBoXnyTU5lFHcYa5ChG0LQ==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/wrap-ansi": {
|
||||
"version": "9.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz",
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
"alert": "6.0.2",
|
||||
"class-variance-authority": "0.7.1",
|
||||
"clsx": "2.1.1",
|
||||
"d3": "7.9.0",
|
||||
"date-fns": "4.1.0",
|
||||
"framer-motion": "11.18.2",
|
||||
"intl-messageformat": "10.7.16",
|
||||
@@ -73,16 +74,20 @@
|
||||
"sharp": "0.33.5",
|
||||
"tailwind-merge": "3.3.1",
|
||||
"tailwindcss-animate": "1.0.7",
|
||||
"topojson-client": "3.1.0",
|
||||
"uuid": "11.1.0",
|
||||
"world-atlas": "2.0.2",
|
||||
"zod": "4.1.11",
|
||||
"zustand": "5.0.8"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@iconify/react": "5.2.1",
|
||||
"@playwright/test": "1.53.2",
|
||||
"@types/d3": "7.4.3",
|
||||
"@types/node": "20.5.7",
|
||||
"@types/react": "19.1.13",
|
||||
"@types/react-dom": "19.1.9",
|
||||
"@types/topojson-client": "3.1.5",
|
||||
"@types/uuid": "10.0.0",
|
||||
"@typescript-eslint/eslint-plugin": "7.18.0",
|
||||
"@typescript-eslint/parser": "7.18.0",
|
||||
|
||||
@@ -1,6 +1,38 @@
|
||||
@import "tailwindcss";
|
||||
@config "../tailwind.config.js";
|
||||
|
||||
@theme {
|
||||
/* Chart Severity Colors */
|
||||
--chart-info: #2e51b2;
|
||||
--chart-warning: #fdd34f;
|
||||
--chart-warning-emphasis: #ff7d19;
|
||||
--chart-danger: #ff3077;
|
||||
--chart-danger-emphasis: #971348;
|
||||
|
||||
/* Chart Status Colors */
|
||||
--chart-success-color: #86da26;
|
||||
--chart-fail: #db2b49;
|
||||
|
||||
/* Chart Radar Colors */
|
||||
--chart-radar-primary: #b51c80;
|
||||
--chart-radar-primary-rgb: 181 28 128;
|
||||
|
||||
/* Chart Provider Colors */
|
||||
--chart-provider-aws: #ff9900;
|
||||
--chart-provider-azure: #00bcd4;
|
||||
--chart-provider-google: #db2b49;
|
||||
|
||||
/* Chart UI Colors */
|
||||
--chart-text-secondary: #94a3b8;
|
||||
--chart-border: #475569;
|
||||
--chart-border-emphasis: #334155;
|
||||
--chart-background: #1e293b;
|
||||
|
||||
/* Chart Alert Colors */
|
||||
--chart-alert-bg: #432232;
|
||||
--chart-alert-text: #f54280;
|
||||
}
|
||||
|
||||
@layer base {
|
||||
:root {
|
||||
--chart-success: 146 80% 35%;
|
||||
@@ -56,6 +88,7 @@
|
||||
transform-box: fill-box;
|
||||
transform-origin: center;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@layer base {
|
||||
|
||||
Reference in New Issue
Block a user