Replace WorldMap with Magic UI DottedMap for visitor locations
- New DottedMap component using svg-dotted-map with country centroid markers - Marker size scales by pageview proportion (brand orange) - Static country-centroids.ts lookup (~200 ISO codes) - Remove react-simple-maps, i18n-iso-countries, world-atlas CDN dependency
This commit is contained in:
95
components/dashboard/DottedMap.tsx
Normal file
95
components/dashboard/DottedMap.tsx
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
'use client'
|
||||||
|
|
||||||
|
import { useMemo } from 'react'
|
||||||
|
import { createMap } from 'svg-dotted-map'
|
||||||
|
import { cn } from '@ciphera-net/ui'
|
||||||
|
import { countryCentroids } from '@/lib/country-centroids'
|
||||||
|
|
||||||
|
interface DottedMapProps {
|
||||||
|
data: Array<{ country: string; pageviews: number }>
|
||||||
|
className?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function DottedMap({ data, className }: DottedMapProps) {
|
||||||
|
const width = 150
|
||||||
|
const height = 75
|
||||||
|
const dotRadius = 0.2
|
||||||
|
|
||||||
|
const { points, addMarkers } = createMap({ width, height, mapSamples: 5000 })
|
||||||
|
|
||||||
|
const markers = useMemo(() => {
|
||||||
|
if (!data.length) return []
|
||||||
|
|
||||||
|
const max = Math.max(...data.map((d) => d.pageviews))
|
||||||
|
if (max === 0) return []
|
||||||
|
|
||||||
|
return data
|
||||||
|
.filter((d) => d.country && d.country !== 'Unknown' && countryCentroids[d.country])
|
||||||
|
.map((d) => ({
|
||||||
|
lat: countryCentroids[d.country].lat,
|
||||||
|
lng: countryCentroids[d.country].lng,
|
||||||
|
size: 0.4 + (d.pageviews / max) * 0.8,
|
||||||
|
}))
|
||||||
|
}, [data])
|
||||||
|
|
||||||
|
const processedMarkers = addMarkers(markers)
|
||||||
|
|
||||||
|
// Compute stagger helpers
|
||||||
|
const { xStep, yToRowIndex } = useMemo(() => {
|
||||||
|
const sorted = [...points].sort((a, b) => a.y - b.y || a.x - b.x)
|
||||||
|
const rowMap = new Map<number, number>()
|
||||||
|
let step = 0
|
||||||
|
let prevY = Number.NaN
|
||||||
|
let prevXInRow = Number.NaN
|
||||||
|
|
||||||
|
for (const p of sorted) {
|
||||||
|
if (p.y !== prevY) {
|
||||||
|
prevY = p.y
|
||||||
|
prevXInRow = Number.NaN
|
||||||
|
if (!rowMap.has(p.y)) rowMap.set(p.y, rowMap.size)
|
||||||
|
}
|
||||||
|
if (!Number.isNaN(prevXInRow)) {
|
||||||
|
const delta = p.x - prevXInRow
|
||||||
|
if (delta > 0) step = step === 0 ? delta : Math.min(step, delta)
|
||||||
|
}
|
||||||
|
prevXInRow = p.x
|
||||||
|
}
|
||||||
|
|
||||||
|
return { xStep: step || 1, yToRowIndex: rowMap }
|
||||||
|
}, [points])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
viewBox={`0 0 ${width} ${height}`}
|
||||||
|
className={cn('text-neutral-300 dark:text-neutral-700', className)}
|
||||||
|
style={{ width: '100%', height: '100%' }}
|
||||||
|
>
|
||||||
|
{points.map((point, index) => {
|
||||||
|
const rowIndex = yToRowIndex.get(point.y) ?? 0
|
||||||
|
const offsetX = rowIndex % 2 === 1 ? xStep / 2 : 0
|
||||||
|
return (
|
||||||
|
<circle
|
||||||
|
cx={point.x + offsetX}
|
||||||
|
cy={point.y}
|
||||||
|
r={dotRadius}
|
||||||
|
fill="currentColor"
|
||||||
|
key={`${point.x}-${point.y}-${index}`}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
{processedMarkers.map((marker, index) => {
|
||||||
|
const rowIndex = yToRowIndex.get(marker.y) ?? 0
|
||||||
|
const offsetX = rowIndex % 2 === 1 ? xStep / 2 : 0
|
||||||
|
return (
|
||||||
|
<circle
|
||||||
|
cx={marker.x + offsetX}
|
||||||
|
cy={marker.y}
|
||||||
|
r={marker.size ?? dotRadius}
|
||||||
|
fill="#FD5E0F"
|
||||||
|
key={`marker-${marker.x}-${marker.y}-${index}`}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</svg>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -6,7 +6,7 @@ import { formatNumber } from '@ciphera-net/ui'
|
|||||||
import { useTabListKeyboard } from '@/lib/hooks/useTabListKeyboard'
|
import { useTabListKeyboard } from '@/lib/hooks/useTabListKeyboard'
|
||||||
import * as Flags from 'country-flag-icons/react/3x2'
|
import * as Flags from 'country-flag-icons/react/3x2'
|
||||||
import iso3166 from 'iso-3166-2'
|
import iso3166 from 'iso-3166-2'
|
||||||
import WorldMap from './WorldMap'
|
import DottedMap from './DottedMap'
|
||||||
import { Modal, GlobeIcon } from '@ciphera-net/ui'
|
import { Modal, GlobeIcon } from '@ciphera-net/ui'
|
||||||
import { ListSkeleton } from '@/components/skeletons'
|
import { ListSkeleton } from '@/components/skeletons'
|
||||||
import { ShieldCheck, Detective, Broadcast } from '@phosphor-icons/react'
|
import { ShieldCheck, Detective, Broadcast } from '@phosphor-icons/react'
|
||||||
@@ -225,7 +225,7 @@ export default function Locations({ countries, cities, regions, geoDataLevel = '
|
|||||||
<p className="text-neutral-500 dark:text-neutral-400 text-sm">{getDisabledMessage()}</p>
|
<p className="text-neutral-500 dark:text-neutral-400 text-sm">{getDisabledMessage()}</p>
|
||||||
</div>
|
</div>
|
||||||
) : activeTab === 'map' ? (
|
) : activeTab === 'map' ? (
|
||||||
hasData ? <WorldMap data={filterUnknown(countries) as { country: string; pageviews: number }[]} /> : (
|
hasData ? <DottedMap data={filterUnknown(countries) as { country: string; pageviews: number }[]} /> : (
|
||||||
<div className="h-full flex flex-col items-center justify-center text-center px-6 py-8 gap-3">
|
<div className="h-full flex flex-col items-center justify-center text-center px-6 py-8 gap-3">
|
||||||
<div className="rounded-full bg-neutral-100 dark:bg-neutral-800 p-4">
|
<div className="rounded-full bg-neutral-100 dark:bg-neutral-800 p-4">
|
||||||
<GlobeIcon className="w-8 h-8 text-neutral-500 dark:text-neutral-400" />
|
<GlobeIcon className="w-8 h-8 text-neutral-500 dark:text-neutral-400" />
|
||||||
|
|||||||
@@ -1,110 +0,0 @@
|
|||||||
'use client'
|
|
||||||
|
|
||||||
import React, { memo, useMemo, useState } from 'react'
|
|
||||||
import { ComposableMap, Geographies, Geography } from 'react-simple-maps'
|
|
||||||
import countries from 'i18n-iso-countries'
|
|
||||||
import enLocale from 'i18n-iso-countries/langs/en.json'
|
|
||||||
import { useTheme } from '@ciphera-net/ui'
|
|
||||||
|
|
||||||
countries.registerLocale(enLocale)
|
|
||||||
|
|
||||||
const geoUrl = "https://cdn.jsdelivr.net/npm/world-atlas@2/countries-110m.json"
|
|
||||||
|
|
||||||
interface WorldMapProps {
|
|
||||||
data: Array<{ country: string; pageviews: number }>
|
|
||||||
}
|
|
||||||
|
|
||||||
const WorldMap = ({ data }: WorldMapProps) => {
|
|
||||||
const { resolvedTheme } = useTheme()
|
|
||||||
const [tooltipContent, setTooltipContent] = useState<{ content: string; x: number; y: number } | null>(null)
|
|
||||||
|
|
||||||
const processedData = useMemo(() => {
|
|
||||||
const map = new Map<string, number>()
|
|
||||||
let max = 0
|
|
||||||
data.forEach(item => {
|
|
||||||
if (item.country === 'Unknown') return
|
|
||||||
// API returns 2 letter code. Convert to numeric (3 digits string)
|
|
||||||
const numericCode = countries.alpha2ToNumeric(item.country)
|
|
||||||
if (numericCode) {
|
|
||||||
map.set(numericCode, item.pageviews)
|
|
||||||
if (item.pageviews > max) max = item.pageviews
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return { map, max }
|
|
||||||
}, [data])
|
|
||||||
|
|
||||||
// Plausible-like colors based on provided SVG snippet
|
|
||||||
const isDark = resolvedTheme === 'dark'
|
|
||||||
const defaultFill = isDark ? "var(--color-neutral-800)" : "var(--color-neutral-100)"
|
|
||||||
const defaultStroke = isDark ? "var(--color-neutral-900)" : "#ffffff"
|
|
||||||
const brandOrange = "var(--color-brand-orange)"
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="relative w-full">
|
|
||||||
<ComposableMap
|
|
||||||
width={800}
|
|
||||||
height={400}
|
|
||||||
projectionConfig={{ rotate: [-10, 0, 0], scale: 170, center: [0, 10] }}
|
|
||||||
className="w-full h-auto"
|
|
||||||
>
|
|
||||||
<Geographies geography={geoUrl}>
|
|
||||||
{({ geographies }) =>
|
|
||||||
geographies
|
|
||||||
.filter(geo => geo.id !== "010") // Remove Antarctica
|
|
||||||
.map((geo) => {
|
|
||||||
const id = String(geo.id).padStart(3, '0')
|
|
||||||
const count = processedData.map.get(id) || 0
|
|
||||||
const fillColor = count > 0 ? brandOrange : defaultFill
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Geography
|
|
||||||
key={geo.rsmKey}
|
|
||||||
geography={geo}
|
|
||||||
fill={fillColor}
|
|
||||||
stroke={defaultStroke}
|
|
||||||
strokeWidth={0.5}
|
|
||||||
style={{
|
|
||||||
default: { outline: "none", transition: "all 250ms" },
|
|
||||||
hover: {
|
|
||||||
fill: fillColor,
|
|
||||||
stroke: brandOrange,
|
|
||||||
strokeWidth: 2,
|
|
||||||
outline: "none",
|
|
||||||
cursor: 'pointer',
|
|
||||||
zIndex: 100 // Bring border to front
|
|
||||||
},
|
|
||||||
pressed: { outline: "none" },
|
|
||||||
}}
|
|
||||||
onMouseEnter={(evt) => {
|
|
||||||
const { name } = geo.properties
|
|
||||||
setTooltipContent({
|
|
||||||
content: `${name}: ${count} visitors`,
|
|
||||||
x: evt.clientX,
|
|
||||||
y: evt.clientY
|
|
||||||
})
|
|
||||||
}}
|
|
||||||
onMouseLeave={() => {
|
|
||||||
setTooltipContent(null)
|
|
||||||
}}
|
|
||||||
onMouseMove={(evt) => {
|
|
||||||
setTooltipContent(prev => prev ? { ...prev, x: evt.clientX, y: evt.clientY } : null)
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
</Geographies>
|
|
||||||
</ComposableMap>
|
|
||||||
{tooltipContent && (
|
|
||||||
<div
|
|
||||||
className="fixed z-50 px-2 py-1 text-xs font-medium text-white bg-black/80 backdrop-blur-sm rounded shadow pointer-events-none transform -translate-x-1/2 -translate-y-full -mt-2.5"
|
|
||||||
style={{ left: tooltipContent.x, top: tooltipContent.y }}
|
|
||||||
>
|
|
||||||
{tooltipContent.content}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
export default memo(WorldMap)
|
|
||||||
205
lib/country-centroids.ts
Normal file
205
lib/country-centroids.ts
Normal file
@@ -0,0 +1,205 @@
|
|||||||
|
/**
|
||||||
|
* Country centroids: ISO 3166-1 alpha-2 → { lat, lng }
|
||||||
|
* Used to place markers on the DottedMap for visitor locations.
|
||||||
|
*/
|
||||||
|
export const countryCentroids: Record<string, { lat: number; lng: number }> = {
|
||||||
|
AD: { lat: 42.5, lng: 1.5 },
|
||||||
|
AE: { lat: 24.0, lng: 54.0 },
|
||||||
|
AF: { lat: 33.0, lng: 65.0 },
|
||||||
|
AG: { lat: 17.1, lng: -61.8 },
|
||||||
|
AL: { lat: 41.0, lng: 20.0 },
|
||||||
|
AM: { lat: 40.0, lng: 45.0 },
|
||||||
|
AO: { lat: -12.5, lng: 18.5 },
|
||||||
|
AR: { lat: -34.0, lng: -64.0 },
|
||||||
|
AT: { lat: 47.3, lng: 13.3 },
|
||||||
|
AU: { lat: -25.0, lng: 134.0 },
|
||||||
|
AZ: { lat: 40.5, lng: 47.5 },
|
||||||
|
BA: { lat: 44.0, lng: 17.8 },
|
||||||
|
BB: { lat: 13.2, lng: -59.5 },
|
||||||
|
BD: { lat: 24.0, lng: 90.0 },
|
||||||
|
BE: { lat: 50.8, lng: 4.0 },
|
||||||
|
BF: { lat: 13.0, lng: -1.5 },
|
||||||
|
BG: { lat: 43.0, lng: 25.0 },
|
||||||
|
BH: { lat: 26.0, lng: 50.6 },
|
||||||
|
BI: { lat: -3.5, lng: 29.9 },
|
||||||
|
BJ: { lat: 9.3, lng: 2.3 },
|
||||||
|
BN: { lat: 4.5, lng: 114.7 },
|
||||||
|
BO: { lat: -17.0, lng: -65.0 },
|
||||||
|
BR: { lat: -10.0, lng: -55.0 },
|
||||||
|
BS: { lat: 24.3, lng: -76.0 },
|
||||||
|
BT: { lat: 27.5, lng: 90.5 },
|
||||||
|
BW: { lat: -22.0, lng: 24.0 },
|
||||||
|
BY: { lat: 53.0, lng: 28.0 },
|
||||||
|
BZ: { lat: 17.3, lng: -88.8 },
|
||||||
|
CA: { lat: 56.0, lng: -96.0 },
|
||||||
|
CD: { lat: -3.0, lng: 23.0 },
|
||||||
|
CF: { lat: 7.0, lng: 21.0 },
|
||||||
|
CG: { lat: -1.0, lng: 15.0 },
|
||||||
|
CH: { lat: 47.0, lng: 8.0 },
|
||||||
|
CI: { lat: 8.0, lng: -5.5 },
|
||||||
|
CL: { lat: -30.0, lng: -71.0 },
|
||||||
|
CM: { lat: 6.0, lng: 12.5 },
|
||||||
|
CN: { lat: 35.0, lng: 105.0 },
|
||||||
|
CO: { lat: 4.0, lng: -72.0 },
|
||||||
|
CR: { lat: 10.0, lng: -84.0 },
|
||||||
|
CU: { lat: 22.0, lng: -79.5 },
|
||||||
|
CV: { lat: 16.0, lng: -24.0 },
|
||||||
|
CY: { lat: 35.0, lng: 33.0 },
|
||||||
|
CZ: { lat: 49.8, lng: 15.5 },
|
||||||
|
DE: { lat: 51.2, lng: 10.4 },
|
||||||
|
DJ: { lat: 11.5, lng: 43.1 },
|
||||||
|
DK: { lat: 56.0, lng: 10.0 },
|
||||||
|
DM: { lat: 15.4, lng: -61.4 },
|
||||||
|
DO: { lat: 19.0, lng: -70.7 },
|
||||||
|
DZ: { lat: 28.0, lng: 3.0 },
|
||||||
|
EC: { lat: -2.0, lng: -77.5 },
|
||||||
|
EE: { lat: 59.0, lng: 26.0 },
|
||||||
|
EG: { lat: 27.0, lng: 30.0 },
|
||||||
|
ER: { lat: 15.0, lng: 39.0 },
|
||||||
|
ES: { lat: 40.0, lng: -4.0 },
|
||||||
|
ET: { lat: 8.0, lng: 38.0 },
|
||||||
|
FI: { lat: 64.0, lng: 26.0 },
|
||||||
|
FJ: { lat: -18.0, lng: 175.0 },
|
||||||
|
FM: { lat: 6.9, lng: 158.2 },
|
||||||
|
FR: { lat: 46.0, lng: 2.0 },
|
||||||
|
GA: { lat: -1.0, lng: 11.8 },
|
||||||
|
GB: { lat: 54.0, lng: -2.0 },
|
||||||
|
GD: { lat: 12.1, lng: -61.7 },
|
||||||
|
GE: { lat: 42.0, lng: 43.5 },
|
||||||
|
GH: { lat: 8.0, lng: -2.0 },
|
||||||
|
GM: { lat: 13.5, lng: -15.3 },
|
||||||
|
GN: { lat: 11.0, lng: -10.0 },
|
||||||
|
GQ: { lat: 2.0, lng: 10.0 },
|
||||||
|
GR: { lat: 39.0, lng: 22.0 },
|
||||||
|
GT: { lat: 15.5, lng: -90.3 },
|
||||||
|
GW: { lat: 12.0, lng: -15.0 },
|
||||||
|
GY: { lat: 5.0, lng: -59.0 },
|
||||||
|
HK: { lat: 22.3, lng: 114.2 },
|
||||||
|
HN: { lat: 15.0, lng: -86.5 },
|
||||||
|
HR: { lat: 45.2, lng: 15.5 },
|
||||||
|
HT: { lat: 19.0, lng: -72.4 },
|
||||||
|
HU: { lat: 47.0, lng: 20.0 },
|
||||||
|
ID: { lat: -5.0, lng: 120.0 },
|
||||||
|
IE: { lat: 53.0, lng: -8.0 },
|
||||||
|
IL: { lat: 31.5, lng: 34.8 },
|
||||||
|
IN: { lat: 20.0, lng: 77.0 },
|
||||||
|
IQ: { lat: 33.0, lng: 44.0 },
|
||||||
|
IR: { lat: 32.0, lng: 53.0 },
|
||||||
|
IS: { lat: 65.0, lng: -18.0 },
|
||||||
|
IT: { lat: 42.8, lng: 12.8 },
|
||||||
|
JM: { lat: 18.3, lng: -77.4 },
|
||||||
|
JO: { lat: 31.0, lng: 36.0 },
|
||||||
|
JP: { lat: 36.0, lng: 138.0 },
|
||||||
|
KE: { lat: 1.0, lng: 38.0 },
|
||||||
|
KG: { lat: 41.0, lng: 75.0 },
|
||||||
|
KH: { lat: 13.0, lng: 105.0 },
|
||||||
|
KI: { lat: 1.4, lng: 173.0 },
|
||||||
|
KM: { lat: -12.2, lng: 44.2 },
|
||||||
|
KN: { lat: 17.3, lng: -62.7 },
|
||||||
|
KP: { lat: 40.0, lng: 127.0 },
|
||||||
|
KR: { lat: 37.0, lng: 127.5 },
|
||||||
|
KW: { lat: 29.5, lng: 47.8 },
|
||||||
|
KZ: { lat: 48.0, lng: 68.0 },
|
||||||
|
LA: { lat: 18.0, lng: 105.0 },
|
||||||
|
LB: { lat: 33.9, lng: 35.8 },
|
||||||
|
LC: { lat: 13.9, lng: -61.0 },
|
||||||
|
LI: { lat: 47.2, lng: 9.5 },
|
||||||
|
LK: { lat: 7.0, lng: 81.0 },
|
||||||
|
LR: { lat: 6.5, lng: -9.5 },
|
||||||
|
LS: { lat: -29.5, lng: 28.5 },
|
||||||
|
LT: { lat: 56.0, lng: 24.0 },
|
||||||
|
LU: { lat: 49.8, lng: 6.2 },
|
||||||
|
LV: { lat: 57.0, lng: 25.0 },
|
||||||
|
LY: { lat: 25.0, lng: 17.0 },
|
||||||
|
MA: { lat: 32.0, lng: -5.0 },
|
||||||
|
MC: { lat: 43.7, lng: 7.4 },
|
||||||
|
MD: { lat: 47.0, lng: 29.0 },
|
||||||
|
ME: { lat: 42.5, lng: 19.3 },
|
||||||
|
MG: { lat: -20.0, lng: 47.0 },
|
||||||
|
MK: { lat: 41.8, lng: 22.0 },
|
||||||
|
ML: { lat: 17.0, lng: -4.0 },
|
||||||
|
MM: { lat: 22.0, lng: 98.0 },
|
||||||
|
MN: { lat: 46.0, lng: 105.0 },
|
||||||
|
MO: { lat: 22.2, lng: 113.5 },
|
||||||
|
MR: { lat: 20.0, lng: -12.0 },
|
||||||
|
MT: { lat: 35.9, lng: 14.4 },
|
||||||
|
MU: { lat: -20.3, lng: 57.6 },
|
||||||
|
MV: { lat: 3.2, lng: 73.2 },
|
||||||
|
MW: { lat: -13.5, lng: 34.0 },
|
||||||
|
MX: { lat: 23.0, lng: -102.0 },
|
||||||
|
MY: { lat: 2.5, lng: 112.5 },
|
||||||
|
MZ: { lat: -18.3, lng: 35.0 },
|
||||||
|
NA: { lat: -22.0, lng: 17.0 },
|
||||||
|
NE: { lat: 16.0, lng: 8.0 },
|
||||||
|
NG: { lat: 10.0, lng: 8.0 },
|
||||||
|
NI: { lat: 13.0, lng: -85.0 },
|
||||||
|
NL: { lat: 52.5, lng: 5.8 },
|
||||||
|
NO: { lat: 62.0, lng: 10.0 },
|
||||||
|
NP: { lat: 28.0, lng: 84.0 },
|
||||||
|
NR: { lat: -0.5, lng: 166.9 },
|
||||||
|
NZ: { lat: -41.0, lng: 174.0 },
|
||||||
|
OM: { lat: 21.0, lng: 57.0 },
|
||||||
|
PA: { lat: 9.0, lng: -80.0 },
|
||||||
|
PE: { lat: -10.0, lng: -76.0 },
|
||||||
|
PG: { lat: -6.0, lng: 147.0 },
|
||||||
|
PH: { lat: 13.0, lng: 122.0 },
|
||||||
|
PK: { lat: 30.0, lng: 70.0 },
|
||||||
|
PL: { lat: 52.0, lng: 20.0 },
|
||||||
|
PR: { lat: 18.3, lng: -66.6 },
|
||||||
|
PS: { lat: 31.9, lng: 35.2 },
|
||||||
|
PT: { lat: 39.5, lng: -8.0 },
|
||||||
|
PW: { lat: 7.5, lng: 134.6 },
|
||||||
|
PY: { lat: -23.0, lng: -58.0 },
|
||||||
|
QA: { lat: 25.5, lng: 51.3 },
|
||||||
|
RO: { lat: 46.0, lng: 25.0 },
|
||||||
|
RS: { lat: 44.0, lng: 21.0 },
|
||||||
|
RU: { lat: 60.0, lng: 100.0 },
|
||||||
|
RW: { lat: -2.0, lng: 29.9 },
|
||||||
|
SA: { lat: 24.0, lng: 45.0 },
|
||||||
|
SB: { lat: -8.0, lng: 159.0 },
|
||||||
|
SC: { lat: -4.7, lng: 55.5 },
|
||||||
|
SD: { lat: 15.0, lng: 30.0 },
|
||||||
|
SE: { lat: 62.0, lng: 15.0 },
|
||||||
|
SG: { lat: 1.4, lng: 103.8 },
|
||||||
|
SI: { lat: 46.1, lng: 15.0 },
|
||||||
|
SK: { lat: 48.7, lng: 19.5 },
|
||||||
|
SL: { lat: 8.5, lng: -11.8 },
|
||||||
|
SM: { lat: 43.9, lng: 12.4 },
|
||||||
|
SN: { lat: 14.5, lng: -14.5 },
|
||||||
|
SO: { lat: 5.0, lng: 46.0 },
|
||||||
|
SR: { lat: 4.0, lng: -56.0 },
|
||||||
|
SS: { lat: 7.0, lng: 30.0 },
|
||||||
|
ST: { lat: 1.0, lng: 7.0 },
|
||||||
|
SV: { lat: 13.8, lng: -88.9 },
|
||||||
|
SY: { lat: 35.0, lng: 38.0 },
|
||||||
|
SZ: { lat: -26.5, lng: 31.5 },
|
||||||
|
TD: { lat: 15.0, lng: 19.0 },
|
||||||
|
TG: { lat: 8.0, lng: 1.2 },
|
||||||
|
TH: { lat: 15.0, lng: 100.0 },
|
||||||
|
TJ: { lat: 39.0, lng: 71.0 },
|
||||||
|
TL: { lat: -8.8, lng: 126.0 },
|
||||||
|
TM: { lat: 40.0, lng: 60.0 },
|
||||||
|
TN: { lat: 34.0, lng: 9.0 },
|
||||||
|
TO: { lat: -20.0, lng: -175.0 },
|
||||||
|
TR: { lat: 39.0, lng: 35.0 },
|
||||||
|
TT: { lat: 10.5, lng: -61.3 },
|
||||||
|
TV: { lat: -8.0, lng: 178.0 },
|
||||||
|
TW: { lat: 23.5, lng: 121.0 },
|
||||||
|
TZ: { lat: -6.0, lng: 35.0 },
|
||||||
|
UA: { lat: 49.0, lng: 32.0 },
|
||||||
|
UG: { lat: 1.0, lng: 32.0 },
|
||||||
|
US: { lat: 39.8, lng: -98.5 },
|
||||||
|
UY: { lat: -33.0, lng: -56.0 },
|
||||||
|
UZ: { lat: 41.0, lng: 64.0 },
|
||||||
|
VA: { lat: 41.9, lng: 12.5 },
|
||||||
|
VC: { lat: 13.3, lng: -61.2 },
|
||||||
|
VE: { lat: 8.0, lng: -66.0 },
|
||||||
|
VN: { lat: 16.0, lng: 108.0 },
|
||||||
|
VU: { lat: -16.0, lng: 167.0 },
|
||||||
|
WS: { lat: -13.8, lng: -172.1 },
|
||||||
|
XK: { lat: 42.6, lng: 21.0 },
|
||||||
|
YE: { lat: 15.0, lng: 48.0 },
|
||||||
|
ZA: { lat: -29.0, lng: 24.0 },
|
||||||
|
ZM: { lat: -15.0, lng: 28.0 },
|
||||||
|
ZW: { lat: -20.0, lng: 30.0 },
|
||||||
|
}
|
||||||
240
package-lock.json
generated
240
package-lock.json
generated
@@ -19,7 +19,6 @@
|
|||||||
"d3-scale": "^4.0.2",
|
"d3-scale": "^4.0.2",
|
||||||
"framer-motion": "^12.23.26",
|
"framer-motion": "^12.23.26",
|
||||||
"html-to-image": "^1.11.13",
|
"html-to-image": "^1.11.13",
|
||||||
"i18n-iso-countries": "^7.14.0",
|
|
||||||
"iso-3166-2": "^1.0.0",
|
"iso-3166-2": "^1.0.0",
|
||||||
"jspdf": "^4.0.0",
|
"jspdf": "^4.0.0",
|
||||||
"jspdf-autotable": "^5.0.7",
|
"jspdf-autotable": "^5.0.7",
|
||||||
@@ -27,9 +26,9 @@
|
|||||||
"react": "^19.2.3",
|
"react": "^19.2.3",
|
||||||
"react-dom": "^19.2.3",
|
"react-dom": "^19.2.3",
|
||||||
"react-markdown": "^10.1.0",
|
"react-markdown": "^10.1.0",
|
||||||
"react-simple-maps": "^3.0.0",
|
|
||||||
"recharts": "^2.15.0",
|
"recharts": "^2.15.0",
|
||||||
"sonner": "^2.0.7",
|
"sonner": "^2.0.7",
|
||||||
|
"svg-dotted-map": "^2.0.1",
|
||||||
"swr": "^2.3.3",
|
"swr": "^2.3.3",
|
||||||
"xlsx": "^0.18.5"
|
"xlsx": "^0.18.5"
|
||||||
},
|
},
|
||||||
@@ -41,7 +40,6 @@
|
|||||||
"@types/node": "^20.14.12",
|
"@types/node": "^20.14.12",
|
||||||
"@types/react": "^19.2.14",
|
"@types/react": "^19.2.14",
|
||||||
"@types/react-dom": "^19.2.3",
|
"@types/react-dom": "^19.2.3",
|
||||||
"@types/react-simple-maps": "^3.0.6",
|
|
||||||
"@vitejs/plugin-react": "^5.1.4",
|
"@vitejs/plugin-react": "^5.1.4",
|
||||||
"autoprefixer": "^10.4.19",
|
"autoprefixer": "^10.4.19",
|
||||||
"eslint": "^9.39.2",
|
"eslint": "^9.39.2",
|
||||||
@@ -4045,26 +4043,6 @@
|
|||||||
"integrity": "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==",
|
"integrity": "sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@types/d3-geo": {
|
|
||||||
"version": "2.0.7",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/d3-geo/-/d3-geo-2.0.7.tgz",
|
|
||||||
"integrity": "sha512-RIXlxPdxvX+LAZFv+t78CuYpxYag4zuw9mZc+AwfB8tZpKU90rMEn2il2ADncmeZlb7nER9dDsJpRisA3lRvjA==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@types/geojson": "*"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@types/d3-interpolate": {
|
|
||||||
"version": "2.0.5",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-2.0.5.tgz",
|
|
||||||
"integrity": "sha512-UINE41RDaUMbulp+bxQMDnhOi51rh5lA2dG+dWZU0UY/IwQiG/u2x8TfnWYU9+xwGdXsJoAvrBYUEQl0r91atg==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@types/d3-color": "^2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@types/d3-path": {
|
"node_modules/@types/d3-path": {
|
||||||
"version": "3.1.1",
|
"version": "3.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-3.1.1.tgz",
|
||||||
@@ -4080,13 +4058,6 @@
|
|||||||
"@types/d3-time": "*"
|
"@types/d3-time": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/d3-selection": {
|
|
||||||
"version": "2.0.5",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-2.0.5.tgz",
|
|
||||||
"integrity": "sha512-71BorcY0yXl12S7lvb01JdaN9TpeUHBDb4RRhSq8U8BEkX/nIk5p7Byho+ZRTsx5nYLMpAbY3qt5EhqFzfGJlw==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT"
|
|
||||||
},
|
|
||||||
"node_modules/@types/d3-shape": {
|
"node_modules/@types/d3-shape": {
|
||||||
"version": "3.1.8",
|
"version": "3.1.8",
|
||||||
"resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.8.tgz",
|
"resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-3.1.8.tgz",
|
||||||
@@ -4108,17 +4079,6 @@
|
|||||||
"integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==",
|
"integrity": "sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/@types/d3-zoom": {
|
|
||||||
"version": "2.0.7",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-2.0.7.tgz",
|
|
||||||
"integrity": "sha512-JWke4E8ZyrKUQ68ESTWSK16fVb0OYnaiJ+WXJRYxKLn4aXU0o4CLYxMWBEiouUfO3TTCoyroOrGPcBG6u1aAxA==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@types/d3-interpolate": "^2",
|
|
||||||
"@types/d3-selection": "^2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@types/debug": {
|
"node_modules/@types/debug": {
|
||||||
"version": "4.1.12",
|
"version": "4.1.12",
|
||||||
"resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz",
|
"resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz",
|
||||||
@@ -4170,13 +4130,6 @@
|
|||||||
"@types/estree": "*"
|
"@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": {
|
"node_modules/@types/hast": {
|
||||||
"version": "3.0.4",
|
"version": "3.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz",
|
||||||
@@ -4257,19 +4210,6 @@
|
|||||||
"@types/react": "^19.2.0"
|
"@types/react": "^19.2.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/react-simple-maps": {
|
|
||||||
"version": "3.0.6",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/react-simple-maps/-/react-simple-maps-3.0.6.tgz",
|
|
||||||
"integrity": "sha512-hR01RXt6VvsE41FxDd+Bqm1PPGdKbYjCYVtCgh38YeBPt46z3SwmWPWu2L3EdCAP6bd6VYEgztucihRw1C0Klg==",
|
|
||||||
"dev": true,
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@types/d3-geo": "^2",
|
|
||||||
"@types/d3-zoom": "^2",
|
|
||||||
"@types/geojson": "*",
|
|
||||||
"@types/react": "*"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@types/resolve": {
|
"node_modules/@types/resolve": {
|
||||||
"version": "1.20.2",
|
"version": "1.20.2",
|
||||||
"resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz",
|
"resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz",
|
||||||
@@ -6320,28 +6260,6 @@
|
|||||||
"node": ">=12"
|
"node": ">=12"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/d3-dispatch": {
|
|
||||||
"version": "2.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-2.0.0.tgz",
|
|
||||||
"integrity": "sha512-S/m2VsXI7gAti2pBoLClFFTMOO1HTtT0j99AuXLoGFKO6deHDdnv6ZGTxSTTUTgO1zVcv82fCOtDjYK4EECmWA==",
|
|
||||||
"license": "BSD-3-Clause"
|
|
||||||
},
|
|
||||||
"node_modules/d3-drag": {
|
|
||||||
"version": "2.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-2.0.0.tgz",
|
|
||||||
"integrity": "sha512-g9y9WbMnF5uqB9qKqwIIa/921RYWzlUDv9Jl1/yONQwxbOfszAWTCm8u7HOTgJgRDXiRZN56cHT9pd24dmXs8w==",
|
|
||||||
"license": "BSD-3-Clause",
|
|
||||||
"dependencies": {
|
|
||||||
"d3-dispatch": "1 - 2",
|
|
||||||
"d3-selection": "2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/d3-ease": {
|
|
||||||
"version": "2.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-2.0.0.tgz",
|
|
||||||
"integrity": "sha512-68/n9JWarxXkOWMshcT5IcjbB+agblQUaIsbnXmrzejn2O82n3p2A9R2zEB9HIEFWKFwPAEDDN8gR0VdSAyyAQ==",
|
|
||||||
"license": "BSD-3-Clause"
|
|
||||||
},
|
|
||||||
"node_modules/d3-format": {
|
"node_modules/d3-format": {
|
||||||
"version": "3.1.2",
|
"version": "3.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.2.tgz",
|
||||||
@@ -6351,30 +6269,6 @@
|
|||||||
"node": ">=12"
|
"node": ">=12"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/d3-geo": {
|
|
||||||
"version": "2.0.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-2.0.2.tgz",
|
|
||||||
"integrity": "sha512-8pM1WGMLGFuhq9S+FpPURxic+gKzjluCD/CHTuUF3mXMeiCo0i6R0tO1s4+GArRFde96SLcW/kOFRjoAosPsFA==",
|
|
||||||
"license": "BSD-3-Clause",
|
|
||||||
"dependencies": {
|
|
||||||
"d3-array": "^2.5.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/d3-geo/node_modules/d3-array": {
|
|
||||||
"version": "2.12.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.12.1.tgz",
|
|
||||||
"integrity": "sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==",
|
|
||||||
"license": "BSD-3-Clause",
|
|
||||||
"dependencies": {
|
|
||||||
"internmap": "^1.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/d3-geo/node_modules/internmap": {
|
|
||||||
"version": "1.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/internmap/-/internmap-1.0.1.tgz",
|
|
||||||
"integrity": "sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==",
|
|
||||||
"license": "ISC"
|
|
||||||
},
|
|
||||||
"node_modules/d3-interpolate": {
|
"node_modules/d3-interpolate": {
|
||||||
"version": "3.0.1",
|
"version": "3.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz",
|
||||||
@@ -6412,13 +6306,6 @@
|
|||||||
"node": ">=12"
|
"node": ">=12"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/d3-selection": {
|
|
||||||
"version": "2.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-2.0.0.tgz",
|
|
||||||
"integrity": "sha512-XoGGqhLUN/W14NmaqcO/bb1nqjDAw5WtSYb2X8wiuQWvSZUsUVYsOSkOybUrNvcBjaywBdYPy03eXHMXjk9nZA==",
|
|
||||||
"license": "BSD-3-Clause",
|
|
||||||
"peer": true
|
|
||||||
},
|
|
||||||
"node_modules/d3-shape": {
|
"node_modules/d3-shape": {
|
||||||
"version": "3.2.0",
|
"version": "3.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz",
|
||||||
@@ -6455,71 +6342,6 @@
|
|||||||
"node": ">=12"
|
"node": ">=12"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/d3-timer": {
|
|
||||||
"version": "2.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-2.0.0.tgz",
|
|
||||||
"integrity": "sha512-TO4VLh0/420Y/9dO3+f9abDEFYeCUr2WZRlxJvbp4HPTQcSylXNiL6yZa9FIUvV1yRiFufl1bszTCLDqv9PWNA==",
|
|
||||||
"license": "BSD-3-Clause"
|
|
||||||
},
|
|
||||||
"node_modules/d3-transition": {
|
|
||||||
"version": "2.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-2.0.0.tgz",
|
|
||||||
"integrity": "sha512-42ltAGgJesfQE3u9LuuBHNbGrI/AJjNL2OAUdclE70UE6Vy239GCBEYD38uBPoLeNsOhFStGpPI0BAOV+HMxog==",
|
|
||||||
"license": "BSD-3-Clause",
|
|
||||||
"dependencies": {
|
|
||||||
"d3-color": "1 - 2",
|
|
||||||
"d3-dispatch": "1 - 2",
|
|
||||||
"d3-ease": "1 - 2",
|
|
||||||
"d3-interpolate": "1 - 2",
|
|
||||||
"d3-timer": "1 - 2"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"d3-selection": "2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/d3-transition/node_modules/d3-color": {
|
|
||||||
"version": "2.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/d3-color/-/d3-color-2.0.0.tgz",
|
|
||||||
"integrity": "sha512-SPXi0TSKPD4g9tw0NMZFnR95XVgUZiBH+uUTqQuDu1OsE2zomHU7ho0FISciaPvosimixwHFl3WHLGabv6dDgQ==",
|
|
||||||
"license": "BSD-3-Clause"
|
|
||||||
},
|
|
||||||
"node_modules/d3-transition/node_modules/d3-interpolate": {
|
|
||||||
"version": "2.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-2.0.1.tgz",
|
|
||||||
"integrity": "sha512-c5UhwwTs/yybcmTpAVqwSFl6vrQ8JZJoT5F7xNFK9pymv5C0Ymcc9/LIJHtYIggg/yS9YHw8i8O8tgb9pupjeQ==",
|
|
||||||
"license": "BSD-3-Clause",
|
|
||||||
"dependencies": {
|
|
||||||
"d3-color": "1 - 2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/d3-zoom": {
|
|
||||||
"version": "2.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-2.0.0.tgz",
|
|
||||||
"integrity": "sha512-fFg7aoaEm9/jf+qfstak0IYpnesZLiMX6GZvXtUSdv8RH2o4E2qeelgdU09eKS6wGuiGMfcnMI0nTIqWzRHGpw==",
|
|
||||||
"license": "BSD-3-Clause",
|
|
||||||
"dependencies": {
|
|
||||||
"d3-dispatch": "1 - 2",
|
|
||||||
"d3-drag": "2",
|
|
||||||
"d3-interpolate": "1 - 2",
|
|
||||||
"d3-selection": "2",
|
|
||||||
"d3-transition": "2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/d3-zoom/node_modules/d3-color": {
|
|
||||||
"version": "2.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/d3-color/-/d3-color-2.0.0.tgz",
|
|
||||||
"integrity": "sha512-SPXi0TSKPD4g9tw0NMZFnR95XVgUZiBH+uUTqQuDu1OsE2zomHU7ho0FISciaPvosimixwHFl3WHLGabv6dDgQ==",
|
|
||||||
"license": "BSD-3-Clause"
|
|
||||||
},
|
|
||||||
"node_modules/d3-zoom/node_modules/d3-interpolate": {
|
|
||||||
"version": "2.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-2.0.1.tgz",
|
|
||||||
"integrity": "sha512-c5UhwwTs/yybcmTpAVqwSFl6vrQ8JZJoT5F7xNFK9pymv5C0Ymcc9/LIJHtYIggg/yS9YHw8i8O8tgb9pupjeQ==",
|
|
||||||
"license": "BSD-3-Clause",
|
|
||||||
"dependencies": {
|
|
||||||
"d3-color": "1 - 2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/damerau-levenshtein": {
|
"node_modules/damerau-levenshtein": {
|
||||||
"version": "1.0.8",
|
"version": "1.0.8",
|
||||||
"resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz",
|
"resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz",
|
||||||
@@ -6764,12 +6586,6 @@
|
|||||||
"url": "https://github.com/sponsors/wooorm"
|
"url": "https://github.com/sponsors/wooorm"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/diacritics": {
|
|
||||||
"version": "1.3.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/diacritics/-/diacritics-1.3.0.tgz",
|
|
||||||
"integrity": "sha512-wlwEkqcsaxvPJML+rDh/2iS824jbREk6DUMUKkEaSlxdYHeS43cClJtsWglvw2RfeXGm6ohKDqsXteJ5sP5enA==",
|
|
||||||
"license": "MIT"
|
|
||||||
},
|
|
||||||
"node_modules/didyoumean": {
|
"node_modules/didyoumean": {
|
||||||
"version": "1.2.2",
|
"version": "1.2.2",
|
||||||
"resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz",
|
"resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz",
|
||||||
@@ -8387,18 +8203,6 @@
|
|||||||
"node": ">= 14"
|
"node": ">= 14"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/i18n-iso-countries": {
|
|
||||||
"version": "7.14.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/i18n-iso-countries/-/i18n-iso-countries-7.14.0.tgz",
|
|
||||||
"integrity": "sha512-nXHJZYtNrfsi1UQbyRqm3Gou431elgLjKl//CYlnBGt5aTWdRPH1PiS2T/p/n8Q8LnqYqzQJik3Q7mkwvLokeg==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"diacritics": "1.3.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 12"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/idb": {
|
"node_modules/idb": {
|
||||||
"version": "7.1.1",
|
"version": "7.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/idb/-/idb-7.1.1.tgz",
|
||||||
@@ -11140,23 +10944,6 @@
|
|||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/react-simple-maps": {
|
|
||||||
"version": "3.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/react-simple-maps/-/react-simple-maps-3.0.0.tgz",
|
|
||||||
"integrity": "sha512-vKNFrvpPG8Vyfdjnz5Ne1N56rZlDfHXv5THNXOVZMqbX1rWZA48zQuYT03mx6PAKanqarJu/PDLgshIZAfHHqw==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"d3-geo": "^2.0.2",
|
|
||||||
"d3-selection": "^2.0.0",
|
|
||||||
"d3-zoom": "^2.0.0",
|
|
||||||
"topojson-client": "^3.1.0"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"prop-types": "^15.7.2",
|
|
||||||
"react": "^16.8.0 || 17.x || 18.x",
|
|
||||||
"react-dom": "^16.8.0 || 17.x || 18.x"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/react-smooth": {
|
"node_modules/react-smooth": {
|
||||||
"version": "4.0.4",
|
"version": "4.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/react-smooth/-/react-smooth-4.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/react-smooth/-/react-smooth-4.0.4.tgz",
|
||||||
@@ -12275,6 +12062,11 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/svg-dotted-map": {
|
||||||
|
"version": "2.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/svg-dotted-map/-/svg-dotted-map-2.0.1.tgz",
|
||||||
|
"integrity": "sha512-eeI2XzIKm23gmSVr7ASTMNVJvxAvBfyL30tN33Y/DcZCJXvC/Br/cxQp9Ts6jDK/e7fkE5TpZStEfduPqPXrIw=="
|
||||||
|
},
|
||||||
"node_modules/svg-pathdata": {
|
"node_modules/svg-pathdata": {
|
||||||
"version": "6.0.3",
|
"version": "6.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/svg-pathdata/-/svg-pathdata-6.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/svg-pathdata/-/svg-pathdata-6.0.3.tgz",
|
||||||
@@ -12613,26 +12405,6 @@
|
|||||||
"node": ">=8.0"
|
"node": ">=8.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"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": {
|
"node_modules/tough-cookie": {
|
||||||
"version": "6.0.0",
|
"version": "6.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-6.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-6.0.0.tgz",
|
||||||
|
|||||||
@@ -23,7 +23,6 @@
|
|||||||
"d3-scale": "^4.0.2",
|
"d3-scale": "^4.0.2",
|
||||||
"framer-motion": "^12.23.26",
|
"framer-motion": "^12.23.26",
|
||||||
"html-to-image": "^1.11.13",
|
"html-to-image": "^1.11.13",
|
||||||
"i18n-iso-countries": "^7.14.0",
|
|
||||||
"iso-3166-2": "^1.0.0",
|
"iso-3166-2": "^1.0.0",
|
||||||
"jspdf": "^4.0.0",
|
"jspdf": "^4.0.0",
|
||||||
"jspdf-autotable": "^5.0.7",
|
"jspdf-autotable": "^5.0.7",
|
||||||
@@ -31,9 +30,9 @@
|
|||||||
"react": "^19.2.3",
|
"react": "^19.2.3",
|
||||||
"react-dom": "^19.2.3",
|
"react-dom": "^19.2.3",
|
||||||
"react-markdown": "^10.1.0",
|
"react-markdown": "^10.1.0",
|
||||||
"react-simple-maps": "^3.0.0",
|
|
||||||
"recharts": "^2.15.0",
|
"recharts": "^2.15.0",
|
||||||
"sonner": "^2.0.7",
|
"sonner": "^2.0.7",
|
||||||
|
"svg-dotted-map": "^2.0.1",
|
||||||
"swr": "^2.3.3",
|
"swr": "^2.3.3",
|
||||||
"xlsx": "^0.18.5"
|
"xlsx": "^0.18.5"
|
||||||
},
|
},
|
||||||
@@ -51,7 +50,6 @@
|
|||||||
"@types/node": "^20.14.12",
|
"@types/node": "^20.14.12",
|
||||||
"@types/react": "^19.2.14",
|
"@types/react": "^19.2.14",
|
||||||
"@types/react-dom": "^19.2.3",
|
"@types/react-dom": "^19.2.3",
|
||||||
"@types/react-simple-maps": "^3.0.6",
|
|
||||||
"@vitejs/plugin-react": "^5.1.4",
|
"@vitejs/plugin-react": "^5.1.4",
|
||||||
"autoprefixer": "^10.4.19",
|
"autoprefixer": "^10.4.19",
|
||||||
"eslint": "^9.39.2",
|
"eslint": "^9.39.2",
|
||||||
|
|||||||
Reference in New Issue
Block a user