diff --git a/.build/generate-maps.ts b/.build/generate-maps.ts new file mode 100644 index 000000000..c3ce15883 --- /dev/null +++ b/.build/generate-maps.ts @@ -0,0 +1,289 @@ +#!/usr/bin/env tsx + +/** + * Generates the map files of the VectorMap plugin (`core/js/maps/*.ts`) from + * Natural Earth (https://www.naturalearthdata.com, public domain). + * + * The shapes are projected here, at build time, and written as ready SVG path + * data. The plugin only puts them into an ``, so no geo library ships to + * the browser. + * + * Usage: pnpm run generate:maps + */ + +import { writeFileSync } from 'node:fs' +import { dirname, join } from 'node:path' +import process from 'node:process' +import { fileURLToPath } from 'node:url' +import * as prettier from 'prettier' + +const __dirname = dirname(fileURLToPath(import.meta.url)) +const outDir = join(__dirname, '..', 'core', 'js', 'maps') + +// Pinned, so that a new run gives the same file. +const SOURCE = 'https://raw.githubusercontent.com/nvkelso/natural-earth-vector/v5.1.2/geojson' + +type Position = [number, number] +type Ring = Position[] + +interface Feature { + properties: Record + geometry: { type: 'Polygon'; coordinates: Ring[] } | { type: 'MultiPolygon'; coordinates: Ring[][] } +} + +interface MapConfig { + /** File name in `core/js/maps/` and the name the map is registered under */ + name: string + /** Natural Earth file, without the extension */ + source: string + /** Width of the viewBox; the height follows from the projection */ + width: number + /** Region codes left out of the map */ + exclude: string[] + /** + * Countries too small to have a shape in `source`. They are taken from a + * more detailed file and put on the map as a point. + */ + points?: { + /** Natural Earth file, without the extension */ + source: string + /** Natural Earth `TYPE` values that get a point */ + types: string[] + /** Region codes that get a point whatever their type */ + include: string[] + } +} + +const maps: MapConfig[] = [ + { + name: 'world', + source: 'ne_110m_admin_0_countries', + width: 1000, + exclude: ['AQ'], + points: { + source: 'ne_50m_admin_0_countries', + types: ['Sovereign country'], + include: ['HK', 'MO'], + }, + }, +] + +// Territories with no ISO 3166-1 code in Natural Earth, keyed by `ADM0_A3`. +// `XK` is the code Kosovo uses in practice; the other two are user-assigned. +const CODE_OVERRIDES: Record = { + KOS: 'XK', + CYN: 'XC', + SOL: 'XS', +} + +// One decimal place in a 1000 unit wide viewBox is about 0.04° of longitude, +// well below the detail of the 110m data. +const PRECISION = 10 + +const RADIANS = Math.PI / 180 + +/** + * Miller cylindrical projection, in radians. Placing a point on the map by its + * coordinates takes the same formula, which is why `projection` is written + * into the map file. + */ +const miller = ([lng, lat]: Position): Position => [lng * RADIANS, 1.25 * Math.log(Math.tan(Math.PI / 4 + 0.4 * lat * RADIANS))] + +const regionCode = (properties: Feature['properties']): string | null => { + const override = CODE_OVERRIDES[String(properties.ADM0_A3)] + if (override) { + return override + } + + // `ISO_A2` is "-99" for France and Norway; `ISO_A2_EH` has them right. + for (const key of ['ISO_A2_EH', 'ISO_A2']) { + const code = String(properties[key] ?? '') + if (/^[A-Z]{2}$/.test(code)) { + return code + } + } + + return null +} + +const ringsOf = (geometry: Feature['geometry']): Ring[] => (geometry.type === 'Polygon' ? geometry.coordinates : geometry.coordinates.flat()) + +// "0.5" → ".5", "-0.5" → "-.5" +const formatNumber = (tenths: number): string => String(tenths / PRECISION).replace(/^(-?)0\./, '$1.') + +// A minus sign already separates two numbers, so a space is only needed in +// front of a positive one. +const joinNumbers = (numbers: number[]): string => { + let out = '' + for (const number of numbers) { + const text = formatNumber(number) + out += out && !text.startsWith('-') ? ` ${text}` : text + } + + return out +} + +/** + * One ring as path data: an absolute move, then relative lines. The deltas are + * taken between already rounded points, so rounding does not add up. + */ +const ringPath = (points: Position[]): string => { + const rounded: Position[] = [] + for (const [x, y] of points) { + const point: Position = [Math.round(x * PRECISION), Math.round(y * PRECISION)] + const last = rounded.at(-1) + if (!last || last[0] !== point[0] || last[1] !== point[1]) { + rounded.push(point) + } + } + + // GeoJSON repeats the first point at the end; `z` closes the ring instead. + const first = rounded[0] + const last = rounded.at(-1) + if (rounded.length > 1 && first && last && first[0] === last[0] && first[1] === last[1]) { + rounded.pop() + } + + if (rounded.length < 3) { + return '' + } + + const deltas: number[] = [] + for (let i = 1; i < rounded.length; i++) { + deltas.push(rounded[i][0] - rounded[i - 1][0], rounded[i][1] - rounded[i - 1][1]) + } + + return `M${joinNumbers(rounded[0])}l${joinNumbers(deltas)}z` +} + +async function load(source: string): Promise { + const url = `${SOURCE}/${source}.geojson` + const response = await fetch(url) + if (!response.ok) { + throw new Error(`Could not load ${url}: ${response.status}`) + } + + const { features } = (await response.json()) as { features: Feature[] } + return features +} + +// Where the long name of Natural Earth is the formal one, not the common one +const NAME_OVERRIDES: Record = { + CV: 'Cabo Verde', +} + +const regionName = (properties: Feature['properties']): string => NAME_OVERRIDES[regionCode(properties) ?? ''] ?? String(properties.NAME_LONG ?? properties.NAME) + +async function generate(config: MapConfig): Promise { + const features = await load(config.source) + + const regions: { code: string; name: string; rings: Ring[] }[] = [] + for (const feature of features) { + const code = regionCode(feature.properties) + if (!code) { + console.warn(` skipped "${feature.properties.NAME}": no region code`) + continue + } + + if (config.exclude.includes(code)) { + continue + } + + regions.push({ + code, + name: regionName(feature.properties), + rings: ringsOf(feature.geometry).map((ring) => ring.map(miller)), + }) + } + + const duplicate = regions.find((region, index) => regions.findIndex((other) => other.code === region.code) !== index) + if (duplicate) { + throw new Error(`Region code "${duplicate.code}" is used twice`) + } + + // Fit the projected shapes into the viewBox. The y axis points down in SVG. + let [minX, minY, maxX, maxY] = [Infinity, Infinity, -Infinity, -Infinity] + for (const [x, y] of regions.flatMap((region) => region.rings.flat())) { + minX = Math.min(minX, x) + maxX = Math.max(maxX, x) + minY = Math.min(minY, y) + maxY = Math.max(maxY, y) + } + + const scale = config.width / (maxX - minX) + const translate: Position = [-minX * scale, maxY * scale] + const height = Math.ceil((maxY - minY) * scale) + const round = (value: number): number => Math.round(value * 1000) / 1000 + + // A point sits where Natural Earth puts the label of the country. + const points: { code: string; name: string; position: Position }[] = [] + if (config.points) { + const { source, types, include } = config.points + for (const { properties } of await load(source)) { + const code = regionCode(properties) + if (!code || config.exclude.includes(code) || regions.some((region) => region.code === code)) { + continue + } + + if (!types.includes(String(properties.TYPE)) && !include.includes(code)) { + continue + } + + const [x, y] = miller([Number(properties.LABEL_X), Number(properties.LABEL_Y)]) + const position: Position = [x * scale + translate[0], translate[1] - y * scale] + if (!(position[0] >= 0 && position[0] <= config.width && position[1] >= 0 && position[1] <= height)) { + throw new Error(`Point "${code}" is outside of the map`) + } + + points.push({ code, name: regionName(properties), position }) + } + } + + regions.sort((a, b) => a.code.localeCompare(b.code)) + points.sort((a, b) => a.code.localeCompare(b.code)) + + const data = { + width: config.width, + height, + projection: { type: 'miller', scale: round(scale), translate: translate.map(round) }, + regions: Object.fromEntries([ + ...regions.map((region) => { + const path = region.rings.map((ring) => ringPath(ring.map(([x, y]): Position => [x * scale + translate[0], translate[1] - y * scale]))).join('') + + if (!path) { + throw new Error(`Region "${region.code}" has no shape left after rounding`) + } + + return [region.code, { name: region.name, path }] + }), + // A line of no length: the plugin draws it as a dot + ...points.map((point) => [point.code, { name: point.name, path: `M${joinNumbers(point.position.map((value) => Math.round(value * PRECISION)))}h0`, point: true }]), + ]), + } + + const source = `// Generated by \`pnpm run generate:maps\` from Natural Earth (public domain, +// https://www.naturalearthdata.com). Do not edit by hand. + +import type { VectorMapData } from '../src/vector-map' + +export const ${config.name}: VectorMapData = ${JSON.stringify(data)} +` + + const file = join(outDir, `${config.name}.ts`) + const options = await prettier.resolveConfig(file) + const formatted = await prettier.format(source, { ...options, filepath: file }) + writeFileSync(file, formatted) + + console.log(`✓ ${config.name}: ${regions.length} regions, ${points.length} points, ${config.width}x${height}, ${(formatted.length / 1024).toFixed(1)} kB`) +} + +async function main(): Promise { + for (const config of maps) { + await generate(config) + } +} + +main().catch((error: unknown) => { + console.error(error) + process.exit(1) +}) diff --git a/.changeset/vector-map-plugin.md b/.changeset/vector-map-plugin.md new file mode 100644 index 000000000..20feac7f2 --- /dev/null +++ b/.changeset/vector-map-plugin.md @@ -0,0 +1,7 @@ +--- +"@tabler/core": minor +"@tabler/preview": minor +"@tabler/docs": minor +--- + +Added the `VectorMap` plugin: an SVG world map with values, color scales, a legend, markers, lines, selection, tooltips and zoom. diff --git a/core/.build/vite.config.mts b/core/.build/vite.config.mts index 848cdfbf9..2db20ff69 100644 --- a/core/.build/vite.config.mts +++ b/core/.build/vite.config.mts @@ -8,10 +8,14 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url)) const baseName = process.env.BASE_NAME || 'tabler' const entryFile = baseName -// `tabler-map` is an add-on to the main bundle: its UMD build extends the -// `tabler` global instead of creating one of its own. -const isAddon = baseName === 'tabler-map' -const libraryName = isAddon ? 'tabler' : baseName +// Some entries add to a global instead of creating their own, so they can be +// loaded next to the main bundle: +// - `tabler-map` and `tabler-vector-map` are add-ons, their UMD builds extend +// the `tabler` global; +// - `maps/*` are map files, each adds its map to the `tablerVectorMaps` global. +const isMap = baseName.startsWith('maps/') +const isAddon = baseName === 'tabler-map' || baseName === 'tabler-vector-map' +const libraryName = isMap ? 'tablerVectorMaps' : isAddon ? 'tabler' : baseName const bannerText = getBanner() @@ -29,5 +33,5 @@ export default createViteConfig({ outDir: path.resolve(__dirname, '../dist/js'), banner: bannerText, minify: false, - extend: isAddon, + extend: isMap || isAddon, }) diff --git a/core/js/maps/world.ts b/core/js/maps/world.ts new file mode 100644 index 000000000..650857107 --- /dev/null +++ b/core/js/maps/world.ts @@ -0,0 +1,453 @@ +// Generated by `pnpm run generate:maps` from Natural Earth (public domain, +// https://www.naturalearthdata.com). Do not edit by hand. + +import type { VectorMapData } from '../src/vector-map' + +export const world: VectorMapData = { + width: 1000, + height: 489, + projection: { type: 'miller', scale: 159.155, translate: [500, 316.038] }, + regions: { + AE: { name: 'United Arab Emirates', path: 'M643.3 247.4l.5-.2 .1 .8 2.1-.4 2.3 0 1.7 .1 1.9-2 2.1-1.9 1.8-1.8 .5 1 .4 2.4-1.5 0-.2 1.9 .5 .4-1.3 .6 0 1.2-.8 1.2 0 1.2-.6 .6-8.4-1.5-1-3z' }, + AF: { + name: 'Afghanistan', + path: 'M684.8 207.2l1.5 0 2.1 .7 .9 .4 2-1 .9 .6 .9-1.5 1.7 .1 .4-.5 .3-1.3 1.2-1.1 1.5 .7-.3 1 .8 .2-.2 2.6 1.1 1.1 .9-.7 1.3-.3 1.7-1.4 1.9 .2 2.9 0 .5 .9-1.6 .4-1.5 .6-3.1 .4-3 .6-1.6 1.4 .6 1.3 .3 1.6-1.4 1.3 .2 1.2-.8 1.2-2.6-.1 1 2-1.7 .8-1.2 1.9 .1 1.8-1 .9-1.1-.3-2.1 .4-.3 .9-2.1 0-1.5 1.7-.1 2.6-3.6 1.3-1.9-.3-.6 .7-1.7-.4-2.8 .4-4.6-1.5 2.5-2.8-.2-2-2.1-.5-.2-1.9-.9-2.5 1.1-1.7-1.2-.5 .8-2.2 1.1-4 2.9 1.2 2.1-.4 .5-1.4 2.2-.5 1.6-1 .6-2.5 2.3-.6 .4-1.2 1.3 .9z', + }, + AL: { name: 'Albania', path: 'M558.4 195.9l-.1 .9-.9 .4-.1 1.1-1.3 1.6-.5-.2-.1-.8-1.5-1.1-.2-1.5 .2-2.3 .4-1-.5-.5-.2-1.1 1.2-1.7 .2 .7 .8-.3 .5 .9 .7 .3 .2 1.2-.4 1.2 .4 1.4z' }, + AM: { name: 'Armenia', path: 'M629.2 202.7l-1 .1-1.2-1.9 .1-.5-1.3 0-.8-.9-.6 .1-1.1-1-2-.8 .2-1.6-.4-1.1 3.8-.6 .6 .9 1.1 .6-.6 .8 1.5 1.1-.8 1.1 1.2 .9 1.2 .5z' }, + AO: { + name: 'Angola', + path: 'M536.1 329.3l-1 .6-.5 .7-.1 1.2-.7 .3-.7-2.1 1.1-1.2 .9-.4zM534.2 333l1.2-.4 .8 .1 1-.4 8.2 .1 .6 2.1 .8 1.6 .7 .9 1 1.5 1.9-.2 .9-.4 1.5 .4 .4-.7 .7-1.7 1.8-.1 .1-.4 1.4-.1-.2 1.1 3.4-.1 0 1.8 .6 1.1-.4 1.6 .2 1.8 .9 1-.2 3.4 .7-.3 1.2 .1 1.8-.5 1.2 .2 .3 .9-.3 1.3 .5 1.4-.4 1 .2 1-5.8 0-.1 9 1.9 2.3 1.8 1.8-5.1 1.2-6.7-.4-2-1.4-11.2 .1-.4 .2-1.7-1.3-1.8-.1-1.7 .5-1.3 .6-.3-1.8 .4-2.5 1-2.6 .1-1.2 .9-2.6 .7-1.2 1.6-1.8 .9-1.3 .3-2-.2-1.6-.8-1-.8-1.7-.6-1.7 .1-.6 .9-1.1-.9-2.7-.5-1.9-1.4-1.8z', + }, + AR: { + name: 'Argentina', + path: 'M309.3 477.5l1.1 1.8 1.4 2.8 3.6 2.3 3.9 1-1.2 1.9-2.7 .2-1.4-1.4-1.7-.1-2.9 0zM339.9 402.6l-.7 2.4-.7 3.2 0 3.1-.6 .6-.2 2.1-.2 1.6 3.5 2.7-.3 2.2 1.7 1.3-.1 1.6-2.7 4.1-4.1 1.8-5.6 .6-3.1-.3 .6 1.9-.5 2.5 .5 1.6-1.7 1.2-2.8 .5-2.7-1.2-1.1 .8 .4 3.3 1.9 1 1.5-1 .8 1.7-2.5 1.1-2.3 2.1-.4 3.4-.6 1.8-2.6 0-2.2 1.8-.8 2.6 2.7 2.5 2.7 .7-1 3.2-3.3 2-1.8 4.2-2.5 1.5-1.2 1.7 .9 3.8 1.9 2.2-1.2-.2-2.6-.6-6.7-.5-1.1-2.2 0-2.7-1.8 .2-1-1.3-.2-3.8 2.1-1.6 .9-2.3-.3-1.8 1.4-3 1-4.6-.3-2 1.3-.7-.3-1.2-1.3-.7 .9-1.5-1.3-1.2-.6-3.9 1.1-.7-.5-4 .7-3.4 .7-2.9 1.7-1.2-.9-3.1 0-3 2.1-2 0-2.7 1.6-3.1 0-2.8-.8-.6-1.2-5.3 1.7-3.2-.3-2.9 1-2.7 1.8-2.9 2-1.8-.8-1.2 .5-.9 0-5 3-1.4 .9-3.1-.3-.7 2.3-2.7 3.6 .8 1.7 2.1 1.1-2.4 3.1 .1 .5 .7 5.1 4.7 2.3 .5 3.3 2.2 2.9 1.1 .4 1.3-2.7 4.6 2.8 .8 3.1 .4 2.2-.5 2.5-2.2 .5-2.7 1.3-.5 1.4 1.7 0 2.4-2.4 1.6-1.8 1.2-3.2 2.9z', + }, + AT: { name: 'Austria', path: 'M547.2 171l-.2 1.4-1.6 0 .5 .8-.9 2.3-.5 .6-2.5 .1-1.4 .7-2.2-.2-4-.9-.6-1.2-2.8 .6-.3 .6-1.7-.5-1.4-.1-1.3-.6 .5-.9-.1-.6 .8-.2 1.4 1 .4-.9 2.4 .1 2-.6 1.4 .1 .8 .7 .3-.6-.4-2.3 1-.4 1-1.7 2 1.2 1.6-1.5 1-.3 2.1 1.1 1.3-.2 1.3 .7-.2 .5z' }, + AU: { + name: 'Australia', + path: 'M910.2 436.1l1.7 .2 .2 3.9-.9 1.2-.3 2.7-1-.9-1.9 2.3-.6-.2-1.7-.1-1.7-2.8-.4-2.3-1.6-2.9 .1-1.5 1.8 .3 2.7 1.2 1.5-.5zM850.4 408.7l-2.9 1.6-2.4 .7-.6 1.6-1 1.3-2.4 .1-1.7 .3-2.5-.6-2 .3-1.9 .2-1.6 1.6-.8-.1-1.4 .9-1.4 1-2-.1-1.8 0-3-2-1.5-.6 .1-1.8 1.4-.5 .4-.7-.1-1.1 .4-2.1-.3-1.9-1.5-3-.5-1.8 .2-1.7-1.2-2 0-.9-1.3-1.2-.3-2.3-1.6-2.4-.4-1.3 1.3 1.3-1-2.7 1.4 .8 .8 1.2 0-1.5-1.4-2.4-.3-.9-.6-.9 .3-1.7 .6-.7 .3-1.5-.3-1.7 1.2-2.1 .2 2.2 1.2-2 2.2-.9 1.4-1.3 2.1-1 1.3-.3 .7 .4 2.2-1.1 1.7-.3 .4-.6 .8-.3 1.5 .1 2.9-.9 1.5-1.3 .7-1.5 1.7-1.5 .1-1.1 .1-1.6 1.9-2.4 1.2 2.5 1.2-.6-1-1.3 .8-1.4 1.3 .6 .3-2.2 1.5-1.4 .7-1.1 1.4-.5 0-.8 1.2 .4 .1-.8 1.2-.4 1.4-.3 2 1.3 1.6 1.6 1.7 .1 1.8 .2-.6-1.5 1.3-2.3 1.3-.7-.5-.7 1.2-1.7 1.7-1 1.4 .4 2.4-.5-.1-1.5-2-.9 1.5-.4 1.8 .7 1.5 1.1 2.3 .7 .8-.2 1.7 .8 1.7-.8 1 .3 .6-.6 1.3 1.4-.7 1.5-1.1 1.2-.9 .1 .3 1.1-.8 1.4-1 1.4 .2 .8 2.2 1.6 2.1 .9 1.5 1 2 1.7 .8 0 1.4 .7 .4 .9 2.7 .9 1.8-.9 .6-1.6 .5-1.2 .4-1.6 .8-2.3-.4-1.3 .2-.9-.3-1.6 .4-2.1 .5-.6-.4-.9 .6-1.5 .6-1.6 0-.8 1.1-1 .8 1.4 .2 1.7 .6 .4 .2 1.1 1 1.5 .2 1.6-.1 1 1 2.2 1.8-1 .9 1.2 1.3 1.1-.3 1.2 .6 2.5 .4 1.4 .7 .3 .8 2.5-.3 1.5 .9 1.9 3 1.5 2 1.4 1.9 1.3-.4 .7 1.6 1.8 1.1 3.1 1.1-.6 1.1 1.3 .7-.5 .5 3.1 1.9 1.8 1.3 1.1 2.2 2.4 .8 2.4 0 1.7-.1 1.9 1.3 2.5-.2 2.7-.5 1.4-.7 2.7 0 1.7-.5 2.2-1.2 2.8-2.1 1.6-1 2.4-.9 1.5-.8 2.7-1.1 1.6-.7 2.4-.4 2.2 .2 1-1.6 1.1-3.1 .1-2.6 1.3-1.3 1.3-1.7 1.4-2.3-1.5-1.7-.5 .5-1.7-1.6 .6-2.4 2.3-2.4-.8-1.6-.5-1.5-.3-2.7-.9-1.8-2-.5-2.4-.7-1.6-1.4-1.3-2.6-.4 .9-1.5-.7-2.4-1.3 2.2-2.5 .6 1.4-1.7 .5-1.8 1-1.6-.2-2.3-2.3 2.7-1.7 1-1.1 2.5-2.1-1.3 .1-1.6-1.8-2.3-1.4-1.1 .5-.8-3.6-1.8-1.9-.1-2.7-1.5-5 .3-3.6 1.1-3.1 1z', + }, + AZ: { + name: 'Azerbaijan', + path: 'M628.9 192.5l.8 .1 1.9 2 1.2 .3 .5-.9 1.7-1.3 1.4 1.7 1.4 2.4 1.3 .1 .9 .9-2.3 .3-.5 2.5-.5 1.2-1 .7 .1 1.6-.7 .2-1.7-1.7 .9-1.6-.8-1-1 .3-3.3 2.4-.1-2.3-1.2-.5-1.2-.9 .8-1.1-1.5-1.1 .6-.8-1.1-.6-.6-.9 .7-.5 2.1 1 1.5 .2 .3-.4-1.3-1.8zM628.2 202.8l-1.9-.5-1.4-1.5-.5-1.2 .6-.1 .8 .9 1.3 0-.1 .5z', + }, + BA: { name: 'Bosnia and Herzegovina', path: 'M551.6 189.9l-2.5-1.3-1.1-1.4-1-.8-1.3-1.2-.6-1.1-1.3-1.6 .5-1.4 1 .8 .6-.7 1.3-.1 2.4 .6 1.9-.1 1.3 .8 1 0-.7 1.5 1.3 1.3-.4 1.6-.6 .1-.5 .3-.9 .8z' }, + BD: { name: 'Bangladesh', path: 'M757.4 253.8l0 2.1-1-.4 .2 2.3-.8-1.5-.2-1.5-.5-1.4-1.2-1.7-2.5-.1 .2 1.2-.8 1.6-1.2-.6-.4 .6-.8-.4-1.1-.2-.4-2.4-1-2.2 .5-1.8-1.7-.8 .6-1.1 1.7-1.1-2-1.5 1-2.1 2.2 1.3 1.3 .2 .3 2 2.6 .4 2.6 0 1.6 .5-1.3 2.5-1.2 .2-.9 1.6 1.5 1.6 .5-1.9 .8 0z' }, + BE: { name: 'Belgium', path: 'M517.1 161.3l-.3 2.5-.7 .1-.3 2.1-2.5-1.7-1.4 .3-1.9-1.7-1.3-1.5-1.3 0-.4-1.3 2.2-.8 2 .3 2.6-.7 1.8 1.6z' }, + BF: { name: 'Burkina Faso', path: 'M485 287.1l-.2-1.6 .8-1.2-.1-.9 2.2-2.4 .4-1.9 .8-.7 1.3 .4 1.2-.6 .4-.7 2.1-1.3 .5-.9 2.6-1.2 1.6-.4 .7 .6 1.7 0-.2 1.3 .4 1.3 1.6 1.9 0 1.3 3.2 .7 0 1.9-.6 .9-1.4 .2-.5 1.3-1 .3-2.4-.1-1.3-.2-.9 .4-1.2-.2-4.9 .2 0 1.6 .3 2.1-1.9-.8-1.3 .2-.9 .7-1.3-.6-.5-1z' }, + BG: { name: 'Bulgaria', path: 'M562.9 184.5l.8 1.4 1.1-.2 2.1 .5 4.1 .2 1.4-.9 3.3-.8 2 1.2 1.6 .4-1.4 1.4-1 2.4 .9 1.9-2.4-.4-2.9 1 0 1.7-2.5 .3-2-1.2-2.2 .9-2-.1-.2-2.2-1.4-1 .4-.5-.3-.4 .5-1.1 1.1-1-1.4-1.5-.2-1.2z' }, + BI: { name: 'Burundi', path: 'M584.6 322.7l.2 1.1 .6 .7 0 .9-.7 .6-1 1.4-1.1 1-1.1 .1-.2-3.3-.7-1.3 1.7 .2 .9-1.5z' }, + BJ: { name: 'Benin', path: 'M507.5 298.6l-2.3 .4-.7-2 .1-6.4-.5-.6-.1-1.3-1-1-.9-.9 .4-1.4 1-.3 .5-1.3 1.4-.2 .6-.9 .9-.8 1 0 2.1 1.6-.1 .9 .6 1.7-.5 1.1 .3 .8-1.4 1.7-.8 .9-.5 1.8 0 1.7z' }, + BN: { name: 'Brunei Darussalam', path: 'M820.7 300.9l-.1 1.4-.2 1.7-1.3 0-.6 .9-1.3-1.4 1.1-1.1z' }, + BO: { + name: 'Bolivia', + path: 'M306.9 346.6l2 .2 1.5 0 .6-.9 2.4-1.1 1.5-1.1 3.6-.5-.3 2.1 .4 1.1-.3 1.9 3 2.5 3.2 .5 1 1.1 1.9 .5 1.2 .8 1.7 0 1.6 .8 .2 1.7 .5 .8 0 1.2-.8 .1 1.1 3.3 5.3 .1-.4 1.7 .3 1.1 1.5 .8 .7 1.8-.5 2.2-.8 1.3 .3 1.6-.9 .6 0-.8-2.6-1.5-2.6-.1-4.8 .9-1.4 2.5 0 1.6-1.1 3.5-.5-.7-3.1-.1-1.1 2.4-1.7-2.1-3.6-.8-2.3 2.7-2 .4-1.1-4-1.5-3.3 .9-2.8-1.5-1.2-.3-2.1-1.4-1.9 1.7-3.1-1.1-2.4 .6-1-.5-1 1.1-1.4 0-2.4 .2-2 .6-1z', + }, + BR: { + name: 'Brazil', + path: 'M351.7 413.5l-.7-1.7 1.2-1.5-1.6-2.1-2.2-1.7-2.8-2-1.1 .1-2.8-2.3-1.8 .3 3.7-4.2 3.2-2.9 1.8-1.2 2.4-1.6 0-2.4-1.4-1.7-1.3 .5 .5-1.7 .4-1.7 0-1.6-1-.6-1.1 .5-1-.1-.3-1.2-.3-2.7-.5-.8-1.9-.8-1.1 .6-2.9-.6 .1-3.9-.8-1.7 .9-.6-.3-1.6 .8-1.3 .5-2.2-.7-1.8-1.5-.8-.3-1.1 .4-1.7-5.3-.1-1.1-3.3 .8-.1 0-1.2-.5-.8-.2-1.7-1.6-.8-1.7 0-1.2-.8-1.9-.5-1-1.1-3.2-.5-3-2.5 .3-1.9-.4-1.1 .3-2.1-3.6 .5-1.5 1.1-2.4 1.1-.6 .9-1.5 0-2-.2-1.6 .5-1.3-.4 .2-4.2-2.3 1.6-2.4 0-1.1-1.5-1.8-.2 .6-1.2-1.6-1.7-1.1-2.5 .7-.5 0-1.2 1.7-.8-.3-1.5 .7-1 .2-1.3 3.2-1.9 2.3-.5 .3-.4 2.6 .1 1.2-7.6 .1-1.2-.5-1.6-1.2-1 0-2.1 1.6-.4 .5 .3 .1-1.1-1.6-.3 0-1.7 5.4 0 .9-.9 .8 .9 .5 1.6 .5-.3 1.6 1.4 2.1-.2 .6-.8 2-.7 1.2-.4 .3-1.2 2-.8-.2-.6-2.3-.2-.4-1.7 .1-1.9-1.2-.7 .5-.3 2 .4 2.2 .7 .8-.7 2-.4 3.1-1.1 1.1-1-.4-.8 1.4-.1 .7 .6-.4 1.2 1 .4 .6 1.3-.8 1-.4 2.4 .7 1.4 .2 1.3 1.7 1.3 1.4 .1 .3-.5 .9-.1 1.2-.5 .9-.8 1.6 .3 .6-.1 1.6 .2 .2-.6-.5-.5 .3-.8 1.1 .2 1.4-.3 1.5 .6 1.3 .6 .8-.8 .6 .2 .4 .7 1.3-.2 1.1-1 .9-2.1 1.6-2.5 1-.1 .6 1.5 1.6 4.9 1.5 .4 .1 1.9-2.1 2.3 .8 .9 4.9 .4 .1 2.8 2.2-1.8 3.4 1 4.7 1.6 1.3 1.7-.4 1.5 3.2-.8 5.4 1.4 4.1-.1 4.2 2.3 3.5 3.1 2.1 .8 2.4 .2 1 .8 1 3.6 .4 1.7-1.1 4.6-1.4 1.8-3.9 3.9-1.8 3.2-2 2.5-.7 0-.8 2.1 .2 5.3-.8 4.4-.3 1.9-.9 1.1-.4 3.9-2.9 3.7-.4 3.1-2.3 1.2-.6 1.8-3.1 0-4.3 1.1-2 1.3-3.1 .9-3.3 2.3-2.3 2.9-.4 2.3 .4 1.6-.5 3-.6 1.5-1.9 1.7-3.1 5.3-2.5 2.5-1.9 1.4-1.2 2.9z', + }, + BS: { name: 'Bahamas', path: 'M280.6 239.8l1.3-.2 1.9 .1 0 .7-3 .5zM283.9 239.1l2.2 1.3-.5 2.1-.5-.3 .1-1.6-1.3-1.2zM282.8 244.5l.8 .1 1 2.5 0 1.7-.7 .1-.7-1.7-1-.8z' }, + BT: { name: 'Bhutan', path: 'M754.7 236.9l1.1 .9-.2 1.9-2.2 .1-2.4-.2-1.7 .4-2.5-1.1-.1-.6 1.8-2.2 1.5-.8 2 .7 1.5 .1z' }, + BW: { name: 'Botswana', path: 'M581.8 378.4l-4 2.2-2.5 2.1-.9 2-.8 1.1-1.5 .2-.5 1.5-.3 .9-1.8 .7-2.2-.2-1.4-.8-1.1-.4-1.4 .7-.7 1.4-1.3 .9-1.4 1.4-2 .3-.6-1.1 .3-1.8-1.7-2.8-.7-.4 0-8.6 2.7-.1 .1-10.3 2.1-.1 4.2-1 1.1 1.2 1.8-1.1 .8-.1 1.6-.6 .5 .2 1 2.3 .6 .5 .9 1.7 3.1 3.2 1.2 .3 0 1 .8 1.8 2.2 .5z' }, + BY: { + name: 'Belarus', + path: 'M578.3 141l2.9 1 .4 1 1.4-.5 2.8 .9 .2 1.8-.6 1.1 1.8 2.5 1.1 .7-.2 .7 1.9 .7 .8 1-1.1 .8-2.2-.1-.5 .3 .6 1.3 .7 2.3-2.4 .3-.8 .8-.2 1.8-1.1-.3-2.5 .2-.8-.9-1 .6-1.1-.5-2.1-.1-3.1-.9-2.8-.2-2.2 0-1.5 1-1.3 .2-.1-1.7-.9-1.7 1.7-.8 0-1.5-.7-1.4-.2-1.7 2.7 .1 3-1.5 .7-2.1 2.3-1.3-.3-1.7 1.7-.7z', + }, + BZ: { name: 'Belize', path: 'M252.4 266.1l0-.5 .3-.1 .5 .3 1-1.7 .5 0 0 .4 .6 0-.1 .8-.4 1.2 .2 .5-.3 1 .2 .3-.3 1.4-.6 .8-.5 .1-.5 .9-.9 0 .3-3.2z' }, + CA: { + name: 'Canada', + path: 'M158.8 167.9l-.4 0-5.4-3.6-2-1.6-5-1.5-1.5-3.2 .4-2.3-3.6-1.6-.5-3-3.3-2.8-.1-2 1.5-1.8 0-2.5-4.8-2.5-2.8-4.5-1.7-2.9-2.6-1.9-1.8-1.6-1.5-2.2-2.8 1.4-2.7 2.3-2.5-2.7-1.9-1.8-2.7-1.2-2.8-.1 .1-24.9 0-17.7 5.2 1.2 4.3 2.3 2.9 .5 2.5-2 3.3-1.6 4.2 .6 4.1-2.1 4.6-1.3 1.9 2.1 2-1.2 .7-2.3 1.9 .5 4.7 4.4 3.7-3.3 .4 3.7 3.4-.8 1-1.4 3.4 .3 4.2 2.1 6.5 1.7 3.8 .9 2.8-.3 3.7 2.4-3.9 2.4 5 1 7.5-.6 2.4-.8 3 2.9 3-2.4-2.9-2.1 1.8-1.6 3.4-.2 2.2-.5 2.3 1.1 2.8 2.6 3.1-.4 4.9 2.2 4.3-.8 4 .2-.3-3 2.5-.9 4.3 1.7 0 4.5 1.8-3.8 2.2 .1 1.2-4.8-2.9-3.1-3.3-2 .2-5.5 3.3-3.8 3.7 .9 2.8 2.2 3.8 5.7-2.5 2.5 5.2 1 0 4.9 3.7-3.8 3.3 3.2-.8 3.5 2.7 3.2 2.9-3.4 2-4.2 .1-5.3 4 .3 4.1 .8 3.7 2.4 .2 2.4-2.1 2.6 2 2.5-.4 2.3-5.4 3.3-3.9 .7-2.8-1.4-.9 2.3-2.7 3.9-.8 1.9-3.2 3.1-4 .3-2.2 1.8-.1 2.9-3.3 .5-3.4 3.5-3 4.8-1.1 3.3-.1 4.8 4.1 .7 1.2 3.8 1.3 3 3.9-.8 5.2 1.7 2.7 1.5 2 1.9 3.5 1.1 3 1.6 4.5 .2 3.1 .4-.5 3.3 .9 3.8 2 4.2 4.1 3.5 2.2-1.2 1.5-3.8-1.5-5.9-1.9-2.1 4.4-1.8 3.1-2.7 1.6-2.7-.2-2.7-1.9-3.4-3.4-3 3.3-4.3-1.2-3.8-1-6.7 2-.9 4.7 1.1 2.9 .4 2.3-1.1 2.6 1.5 3.4 2.4 .8 1.7 5 .3-.1 3.5 .9 5.3 2.6 .6 2 2.4 4-2.3 2.7-4.5 1.8-1.9 2.2 3.7 3.6 5.2 3.1 4.8-1.2 2.4 3.7 2.3 2.5 2.2 4.5 1 1.7 1.2 1.1 3.2 2.2 .5 1.1 1.5 .2 4.2-2 1.4-2 1.3-4.6 1.3-3.5 3-4.7 .6-5.9-.8-4.2 0-2.8 .2-2.4 2.6-3.5 1.6-4 4.7-3.2 3.3 2.3-.6 4.5-4.6 5.8-3 4.2-.4 2.4 1.8-2.6 2.4 .9 3.8 .9 2.6 3.6 1.7 4.6-.5 2.8-3.9 .2 2.6 1.8 1.2-3.5 2.3-6.1 2-2.8 1.4-3.1 2.5-2.1-.3-.1-2.9 4.8-2.8-4.4 .1-3.1 .4-1.8-1.9 0-4.8-1.2-1-1.9 .6-.9-.9-2.1 2.6-.9 2.7-1 1.6-1.2 .5-.8 .2-.3 .9-5.1 0-4.3 0-1.2 .6-3 2.5-.3 .2-.9 1.4-2.5 0-2.8 0-1.2 .5 .4 .7 .3 1-.1 .4-3.6 1.6-2.9 .5-3.2 1.8-.7 0-.9-.5-.4-.5 .1-.3 .6-1.2 1.3-1.8 .8-2-.5-3-.6-3.1-2.9-1.6 .3-.6-.4-.5-.7 0-.6-.5-.1-.8-.6 .3-.7-.1 .2-.3-.7-.4-.3-.9-2.1-1.1-2.3-1.2-2.7-1.4-2.6-1.2-2.5 1-.9 0-3.4-.9-2.3 .4-2.6-1.1-2.9-.5-1.9-.3-.9-.6-.5-1.9-.9 0 0 1.4-5.8 0-9.5 0-9.4 0-8.4 0-8.3 0-8.2 0-8.5 0-2.7 0-8.2 0zM266.7 115.2l2-2 3.9 0-.1 .9-3.2 2.3-2-.1zM278.4 65.9l-3.1-2.8 .2-1.9 1.3-.4 6.4 .6 4.7 2.9 .3 1.5-3-.1-3-.2-3 .8zM276.9 116.8l1.1-1.3 1.1 .1 .7 .8-1.1 2.3-1.2-.4-.7-1.2zM240 54.1l-1.5 2.2-4.1-.4-3.3-1.5 1.4-2.5 4-1.5 2.5 2zM239.3 39.6l-1.2 .2-5.2-.4-.8-1.7 5.6 .1 2 1.1zM231.2 32.1l3.4 2.1-.8 2.2-4.1 1.2-2.3-1.4-1.2-2.2-.2-2.6 3.6 .3zM255.1 57.4l-4.4-.7-7.4-1.8-1-3-.3-2.8-2.8-2.5-5.8-.7-3.2-1.8 1.1-2.4 5.7 .4 3.1 1.9 5.4-.1 2.4 1.9-.6 2.2 3.2 1.3 1.8 1.3 3.7 .3 4.1 .4 4.4-1.2 5.6-.5 4.5 .4 3 2.2 .6 2.3-1.7 1.4-4.1 1.2-3.6-.7-8 .9zM190.9 35.8l3.9 1-.9 1.7-5.2 1.7-4.1-1.9 2.3-1.9zM191.8 31.9l3.6 1.2-3.4 1.2-4.6 0 0-.9 2.9-1.8zM345.6 159.4l-1.5 2.4-1.9 3.1 1.8-1.2 1.9 .8-1 1.3 2.5 .9 1.3-.8 2.8 1.1-.9 2.6 1.9-.6 .4 1.9 .9 2.2-1.2 3.1-1.3 .1-1.8-.7 .6-2.8-.8-.5-3.2 3.1-1.6-.2 1.9-1.6-2.7-.9-2.9 .2-5.4-.1-.5-1 1.8-1.3-1.2-.9 2.3-2.2 2.9-5.8 1.7-2 2.4-1.3 1.3 .1zM267 103.4l3 1.6 3.2 1.4 .3 2.1 2-.4 2 1.5-2.5 1.4-4.3-1.1-1.6-1.9-2.7 2.3-4 2.3-.9-2.6-3.8 .4 2.4-2.2 .4-3.5 .9-4.1 2 .3 .6 2 1.4-.7zM281.2 68.3l2.6-2.1 6.2 2.7 3.8 2.4 .4 2.3 5.1-1.2 2.9 3.3 6.7 2 2.4 2 2.7 4.6-5.1 2.3 6.5 3.1 4.4 1 4 4.4 4.4 .3-.9 3.2-4.9 5.3-3.4-1.9-4.3-4.4-3.6 .6-.4 2.6 2.9 2.6 3.8 2.1 1.2 1.2 1.8 4.4-1 3.1-3.5-1.2-7-3.5 4 3.8 2.9 2.6 .4 1.5-7.5-1.7-6-2.5-3.4-2.1 1-1.3-4.1-2.3-4.1-2.1 .1 1.3-8.1 .7-2.3-1.5 1.8-3.4 5.2 0 5.8-.6-1-1.7 1-2.3 3.6-4.5-.8-2.1-1-1.6-4.3-2.3-5.6-1.7 1.8-1.2-3-3.1-2.4-.3-2.2-1.7-1.5 1.5-5 .7-10.2-1.2-5.8-1.4-4.5-.8-2.3-1.7 2.9-2.3-4-.1-.9-5.2 2.2-4.7 2.8-2.2 7.2-1.4-2.1 3.5 2.2 3.2 2.6-4.2 7-2.2 4.8 5.5-.4 3.4zM237.5 58.8l5.8 .2 5.3 1.3-4.2 4.8-3.3 1-3 3.9-3.1-.2-1.8-4.6 .1-2.6 1.4-2.3zM158.7 47.7l4.8-4.3 5.7-3.8 4.2 .1 3.8-.9-.4 4.6-2.1 2-2.6 .3-5.2 2.4-4.4 .9zM131.4 149.2l2.6-.3-.8 4.3 2.4 3.1-1.1-.1-1.7-1.7-1-1.7-1.4-1.2-.5-1.6 .2-1.2zM207 28.8l5.4 .8 7.5 2.3 2.2 2.9 1 2.5-4.5-.7-4.6-1.9-6.2-.3 2.7-1.8-3.3-1.4zM156.9 169.6l-1.4 .5-4.5-1.6-.9-1.3-2.5-1.2-.5-1.1-2.8-.6-1.1-2 .2-.8 3 .8 1.7 .5 2.6 .4 .9 1.2 1.4 1.8 2.8 1.4zM162.4 57.1l4 1.1 7.1 .3 2.7 1.6 2.9 2.3-3.5 1.3-6.8 3.7-3.4 3.7 0 2.2-7.3 2.5-1.5-2.3-6.4-2.7 1.2-2.2 1.9-3.8 2.4-3.5-2.7-3.4zM200.5 49.3l2.5-1 2.9 .3 .5 2.8-1.7 2.6-9.4 .9-7 2.4-4.3 .1-.3-1.8 5.8-2.5-12.6 .7-3.9-1 3.8-5.5 2.6-1.6 7.8 1.9 5 3.4 4.8 .4-3.9-5.4 2.5-2.2 2.9 .7 .9 2.8zM204.1 64.5l3.1 2.1 1.8 5.1 .8 3.6 4.7 2.5 5 2.4-.3 2.1-4.6 .4 1.8 1.9-.9 1.8-5.1-.8-4.7-1.3-3.3 .3-5.2 1.7-7 .7-5 .4-1.5-2.2-3.8-1.4-2.4 .6-3.4-3.9 1.8-.6 4.3-.8 3.9 .2 3.6-.8-5.3-1.2-6 .4-3.9-.1-1.5-1.9 6.5-2-4.3 .1-4.9-1.4 2.4-3.9 1.9-2.1 7.4-3.2 2.9 1-1.4 2.5 6.2-1.6 3.8 2.7 3.2-2.7 2.5 1.7 2.3 5.1 1.4-2.1-2-5.4 2.4-.8zM221 66.4l-3.1-3.4 3.3-2.6 3.3 1.1 5-.7 .7 1.6-2.6 2.5 4.2 2.3-.5 4.7-4.5 2-2.7-.5-1.9-1.9-6.9-4 0-1.7zM203.9 61.7l3.7-.2 2.1 1.2-2.4 3.5-4.4-3.8zM226.4 44.3l2.1 2.6 .1 3-1.3 4.1-4.5 .6-3-.9 0-3.2-4.5 .4-.2-4.4 3 .2 4.2-2 3.9 .3zM233.3 20.6l1.9-2 2.9-.5-1.3-1.5 6.5-.3 3.6 3.5 4.6 1.4 4.6 1.2 2.2 4.1 3.3 2.1-3.8 1.8-5.1 4.6-4.9 .4-5.8-.7-3-2.5 .1-2.2 2.2-1.7-5.1 0-3.1-2-1.7-2.9zM245.6 12.1l4.1-1.3 3.3-.2 5.4-1.1 4.1-2.6 3.4 .4 3 1.9 2.2-3.7 3.6-1.1 5-.8 8.5-.3 1.5 .8 8-1.2 6 .4 6 .5 7.4 .5 6 .9 5.1 1.9-.1 1.8-6.8 2.9-6.7 1.4-2.5 1.5 6-.1-6.5 4-4.6 1.9-4.7 5.2-5.8 1-1.7 1.3-8.4 .7 3.8 .7-1.9 1.1 2.3 3.1-2.7 2-4.3 1.7-1.3 2.4-3.9 1.7 .4 1.3 4.8-.2 0 1.4-7.4 3.5-7.2-1.6-8.2 .9-4.1-.7-5.3-.3-.3-2.8 5.1-1.3-1.4-4.3 1.7-.4 7.5 2.6-3.8-3.9-4.5-1.1 2.2-2.4 4.9-1.4 .8-2.2-3.9-2.4-1.2-3.3 7.6 .3 2.2 .7 4.3-2.4-6.2-.7-9.7 .4-4.9-2.2-2.4-2.6-3.2-2zM291.1 92.7l-1.8 1.3-3.2 .3-.6-2.3 1.1-2.7 2.6-.7 2.1 1.4 .1 2zM232.6 82.8l1.7 1.9-1.7 1.7-3.8-1.5-2.2 .5-3.8-2.2 2.4-1.5 2-2.1 2.9 1.4 1.7 .9zM320.8 164.7l.9-.3 3.7 .9 2.8 1.5 .1 .7-1.3 .1-3.6-1.2zM322.2 174.8l1 1.7 2 .5 2.5-.1-1.3 1.4-1.1 .3-3.5-1.5-.7-1.2z', + }, + CD: { + name: 'Democratic Republic of the Congo', + path: 'M581.5 328.5l.5 2.6-.3 1.5 .6 1.6 1.6 1.5 1.5 3.6-1.1-.3-3.7 .4-.8 .4-.8 1.8 .6 1.2-.4 3.3-.4 2.8 .8 .5 1.9 1.1 .8-.5 .2 3.1-2.1 0-1.2-1.6-1-1.2-2.1-.4-.6-1.5-1.7 .9-2.3-.4-.9-1.3-1.8-.2-1.3 .1-.1-.9-1-.1-1.2-.2-1.8 .5-1.2-.1-.7 .3 .2-3.4-.9-1-.2-1.8 .4-1.6-.6-1.1 0-1.8-3.4 .1 .2-1.1-1.4 .1-.1 .4-1.8 .1-.7 1.7-.4 .7-1.5-.4-.9 .4-1.9 .2-1-1.5-.7-.9-.8-1.6-.6-2.1-8.2-.1-1 .4-.8-.1-1.2 .4-.4-.9 .7-.3 .1-1.2 .5-.7 1-.6 .7 .3 1-1.1 1.5 .1 .2 .8 1 .5 1.6-1.8 1.7-1.3 .7-.9-.1-2.3 1.2-2.7 1.2-1.5 1.9-1.3 .3-.9 .1-1 .4-1-.1-1.5 .3-2.5 .6-1.7 .8-1.5 .2-1.7 .2-1.9 1.1-1.5 1.5-.8 2.3 .9 1.7 1 2.1 .3 2 .5 .9-1.6 .3-.3 1.3 .3 3.1-1.4 1.1 .6 .9-.1 .4-.6 1.1-.3 2 .3 1.8 .1 .9-.3 1.7 2.3 1.3 .3 .7-.4 1.3 .1 1.5-.6 .7 1.2 2.4 1.9-.1 3.2 1.1 .4-.9 1-1.1 .7-1 1.5-.6 1.3-.2 2.2-.6 1.1 0 2.1-.8 .7-.1 1.7-.4 .2-.3 1.5 .7 1.3z', + }, + CF: { + name: 'Central African Republic', + path: 'M576 301.5l-.9 .3-1.8-.1-2-.3-1.1 .3-.4 .6-.9 .1-1.1-.6-3.1 1.4-1.3-.3-.3 .3-.9 1.6-2-.5-2.1-.3-1.7-1-2.3-.9-1.5 .8-1.1 1.5-.2 1.9-1.8-.2-1.9-.4-1.7 1.5-1.4 2.5-.3-.8-.1-1.2-1.3-.9-1-1.5-.3-1-1.3-1.4 .2-.8-.2-1.2 .2-2.2 .6-.5 1.4-2.8 2.3-.2 .6-.7 .4 0 .7 .6 3.5-1 1.2-1.1 1.4-1-.2-1 .7-.2 2.7 .1 2.6-1.3 2-3 1.5-1.2 1.7-.4 .3 1.2 1.6 1.7 0 1.2-.4 1.1 .2 .9 .9 .8 2.1 1.2 1.6 1.2 0 .9 1.9 1.4 1.1 1.2 .7 1.7 2.1 1.1z', + }, + CG: { + name: 'Republic of the Congo', + path: 'M551.3 306.3l-.2 1.7-.8 1.5-.6 1.7-.3 2.5 .1 1.5-.4 1-.1 1-.3 .9-1.9 1.3-1.2 1.5-1.2 2.7 .1 2.3-.7 .9-1.7 1.3-1.6 1.8-1-.5-.2-.8-1.5-.1-1 1.1-.7-.3-1-.9-.9 .4-1.1 1.2-2.3-2.9 2.1-1.5-1-1.9 .9-.7 1.9-.3 .2-1.2 1.5 1.3 2.5 .1 .8-1.3 .4-1.9-.3-2.1-1.3-1.7 1.2-3.2-.7-.5-2.1 .2-.8-1.4 .2-1.3 3.5 .1 2.3 .8 2.2 .6 .2-1.5 1.4-2.5 1.7-1.5 1.9 .4z', + }, + CH: { name: 'Switzerland', path: 'M526.7 173.1l.1 .6-.5 .9 1.3 .6 1.4 .1-.2 1.5-1.2 .6-2.1-.5-.6 1.4-1.3 .1-.5-.5-1.6 1.2-1.3 .1-1.2-.7-.9-1.5-1.4 .5 .1-1.6 2-2-.1-.8 1.3 .3 .7-.6 2.4 0 .6-.8z' }, + CI: { + name: "Côte d'Ivoire", + path: 'M477.7 287.6l.4-.3 .7 .5 2.2 0 .5-.8 .5 0 .8-.3 .4 1.2 .6-.4 1.2-.4 1.2 .6 .5 1 1.3 .6 .9-.7 1.3-.2 1.9 .8 .8 4-1.2 2.3-.7 3.2 1.2 2.4-.1 1.1-1.3 0-1.9-.6-1.8 .1-3.3 .5-1.9 .8-2.8 1-.5-.1 .2-2.3 .3-.3-.1-1.1-1.2-1.2-.9-.2-.8-.8 .6-1.2-.3-1.3 .2-.9 .4 0 .2-1.2-.3-.5 .3-.4 1-.3-.6-2.3-.7-1.1 .2-1z', + }, + CL: { + name: 'Chile', + path: 'M309.3 477.5l.1 8.5 2.9 0 1.7 .1-.9 1.6-2.4 1.2-1.4-.1-1.6-.4-2-1.1-2.9-.6-3.5-2.1-2.9-2.1-3.8-4.2 2.3 .8 3.9 2.5 3.7 1.4 1.4-1.8 .9-2.6 2.6-1.5zM306.7 365.4l1.4 1.9 .3 2.1 1.5 1.2-.9 2.8 1.5 3.3 1.1 4 2-.4 .3 .7-.9 3.1-3 1.4 0 5-.5 .9 .8 1.2-2 1.8-1.8 2.9-1 2.7 .3 2.9-1.7 3.2 1.2 5.3 .8 .6 0 2.8-1.6 3.1 0 2.7-2.1 2 0 3 .9 3.1-1.7 1.2-.7 2.9-.7 3.4 .5 4-1.1 .7 .6 3.9 1.3 1.2-.9 1.5 1.3 .7 .3 1.2-1.3 .7 .3 2-1 4.6-1.4 3 .3 1.8-.9 2.3-2.1 1.6 .2 3.8 1 1.3 1.8-.2 0 2.7 1.1 2.2 6.7 .5 2.6 .6-2.4-.1-1.4 1-2.5 1.3-.4 3.5-1.2 .1-3.1-1.2-3.2-2.6-3.5-2.2-.9-2.3 .8-2.2-1.4-2.4-.3-6.2 1.2-3.4 2.9-2.7-4.2-1 2.6-3.1 1-5.7 3.1 1.2 1.4-7-1.9-.9-.8 4.2-1.8-.5 .9-4.8 .9-6.1 1.3-2.2-.8-3.2-.2-3.6 1.2-.1 1.7-5.1 1.9-5 1.2-4.7-.7-4.6 .8-2.5-.3-3.7 1.6-3.7 .5-5.8 .9-6.1 .9-6.5-.2-4.8-.6-4 1.4-.8z', + }, + CM: { + name: 'Cameroon', + path: 'M540.3 280.1l1.1 1.8 .2 1.9-.1 1.9 1.5 2.5-1.6 0-.8 .2-1.2-.3-.6 1.3 1.6 1.7 1.2 .4 .4 1.2 .9 1.9-.5 .8-1.4 2.8-.6 .5-.2 2.2 .2 1.2-.2 .8 1.3 1.4 .3 1 1 1.5 1.3 .9 .1 1.2 .3 .8-.2 1.5-2.2-.6-2.3-.8-3.5-.1-.3-.1-1.7 .3-1.7-.3-1.3 .2-4.5-.1 .4-2.2-1.1-1.8-1.2-.5-.6-1.3-.7-.4 0-.7 .7-2 1.3-2.7 .9 0 1.6-1.6 1.1-.1 1.5 1.2 1.9-1 .3-1.1 .6-1.2 .4-1.4 1.5-1.1 .6-2 .6-.6 .4-1.5 .7-1.8 2.3-2.1 .2-1 .3-.5-1.1-1.1 .1-.9z', + }, + CN: { + name: 'China', + path: 'M804.1 264.9l-2.3-.9-.1-2.4 1.4-1.3 3-.8 1.6 0 .7 1.1-1.3 1.3-.6 1.7zM722.9 190.9l-.2-1.9 1.9-.9-2.5-5.9 5.5-1.4 1.5-.8 2-6.2 5.5 1.2 1.5-1.6 .1-3.6 2.4-.3 2.1-2.4 1.1-.3 .7 2.5 2.3 1.9 4 1.3 1.9 2.8-1.1 4.1 1 1.5 3.3 .6 3.8 .5 3.3 2.1 1.7 .4 1.3 3.1 1.6 2 3.1-.1 5.7 .8 3.7-.5 2.8 .5 4.1 2.1 3.3 0 1.3 1 3.2-1.8 4.5-1.2 4.2-.1 3.2-1.2 2-1.8 1.9-1.1-.4-1.1-.9-1.3 1.5-2.3 1.5 .4 2.9 .7 2.7-1.9 4.3-1.3 2-2.3 2-1 4-.5 2.2 .4 .3-1.2-2.5-2.5-2.2-1.1-2.2 1.3-2.7-.5-1.6 .4-.7-1.4 2-3.6 1.3-2.7 3.3 1.3 4-2.3-.1-1.6 2.5-3.9 1.6-1.1-.1-2.1-1.5-.9 2.3-1.9 3.5-.6 3.7-.1 4.1 1.1 2.5 1.4 1.7 3.7 1 1.6 1 2.3 1 3.5 4.8 1.2 3.3 2.5 1.2 3.4 4.2 0 2.4-1.4 4.6-1.1-1.5 3.2-1.1 1.3-.9 3.8-1.9 3.4-3.4-.6-2.3 1.2 .7 2.9-.4 4-1.4 .1 0 1.7-1.8-2-1.1 1.9-4.3 1.5 .4 1.7-2.4-.1-1.3-1-1.9 2.3-3.1 1.8-2.2 2.1-3.9 .9-2 1.6-3 .8 1.4-1.5-.5-1.2 2.2-2.2-1.5-1.8-2.4 1.2-3.2 2.3-1.7 2.1-2.7 .2-1.4 1.5 1.4 2.2 2.3 .5 .1 1.4 2.2 1 3.1-2.3 2.5 1.2 1.8 .1 .4 1.7-3.9 .9-1.3 1.7-2.7 1.6-1.4 2.2 3 1.7 1.1 3.1 1.6 2.8 1.9 2.4 0 2.3-1.8 .8 .7 1.6 1.6 1-.4 2.4-.7 2.4-1.5 .3-2.1 3.2-2.2 3.9-2.6 3.6-3.8 2.7-3.9 2.5-3.1 .3-1.7 1.3-1-1-1.5 1.5-3.9 1.5-3 .4-.9 3.1-1.6 .1-.7-2.1 .7-1.1-3.7-.9-1.4 .4-2.8-.7-1.3-1.2 .5-1.7-2.6-.5-1.3-1.1-2.4 1.6-2.7 .3-2.2 0-1.5 .7-1.4 .4 .4 3.3-1.5 0-.2-.7-.1-1.2-2.1 .8-1.2-.5-2-1.1 .8-2.4-1.8-.6-.6-2.7-3 .5 .4-3.5 2.6-2.5 .1-2.4-.1-2.3-1.2-.7-.9-1.8-1.6 .2-3-.4 .9-1.3-1.3-1.9-2 1.3-2.3-.8-3.2 2-2.5 2.2-2.3 .4-1.2-.8-1.5-.1-2-.7-1.5 .8-1.8 2.2-.2-2.4-1.7 .7-3.3-.3-3.1-.7-2.3-1.3-2.1-.6-.9-1.5-1.6-.4-2.8-2-2.2-.9-1.2 .7-3.9-2.1-2.7-2-.8-3.4 2 .4 .1-1.5-1.1-1.6 .3-2.6-3-3.7-4.6-1.2-.8-2.5-2-1.5-.5-.9-.4-1.8 .1-1.3-1.7-.7-.9 .3-.7-3 .7-.7-.3-.8 2.6-1.5 1.9-.7 3 .5 1-2.2 3.6-.3 1-1.4 4.4-1.8z', + }, + CO: { + name: 'Colombia', + path: 'M314.2 312.6l-.5 .3-.5-1.6-.8-.9-.9 .9-5.4 0 0 1.7 1.6 .3-.1 1.1-.5-.3-1.6 .4 0 2.1 1.2 1 .5 1.6-.1 1.2-1.2 7.6-1.4-1.5-.9-.1 1.8-2.8-2.1-1.3-1.7 .2-1-.4-1.5 .7-2.1-.3-1.6-3-1.3-.7-.9-1.3-1.8-1.3-.8 .3-1.2-.7-1.3-.9-.8 .4-2.4-.4-.6-1.2-.6 .1-2.7-1.6-.4-.9 1-.2-.1-1.4 .6-1 1.4-.2 1.2-1.7 1.1-1.5-1.1-.6 .6-1.6-.7-2.6 .6-.7-.4-2.4-1.1-1.5 .3-1.3 .9 .2 .5-.8-.6-1.7 .3-.4 1.5 .1 2-2 1.2-.3 0-.9 .5-2.4 1.6-1.3 1.8 0 .2-.6 2.2 .2 2.2-1.4 1-.6 1.4-1.4 1 .2 .7 .7-.5 1-1.8 .5-.7 1.4-1.1 .8-.8 1-.4 2-.7 1.6 1.4 .2 .4 1.3 .6 .6 .2 1.2-.3 1 .1 .6 .6 .2 .7 1 3.6-.3 1.6 .4 2 2.4 1.1-.3 2 .1 1.6-.3 .9 .5-.5 1.5-.6 .9-.2 2 .6 1.9 .8 .8 0 .6-1.4 1.4 1 .6 .8 1z', + }, + CR: { name: 'Costa Rica', path: 'M270.7 289.4l-1.1 .2 0 1.2 .6 .4-.4 .3 .1 .5-.2 .6-.2 .5-1.5-.6-.5-.6 .3-.5-.1-.6-.8-.6-1.1-.6-.9-.4-.2-.8-.7-.5 .1 .8-.5 .7-.7-.8-.8-.2-.4-.6 0-.9 .4-.8-.8-.4 .6-.6 .4-.3 1.9 .7 .6-.4 .9 .3 .4 .5 .9 .2 .6-.6 .7 1.6 1.1 1.1z' }, + CU: { name: 'Cuba', path: 'M271.5 250.5l2.4 .2 2.2 0 2.6 1 1.1 1.1 2.6-.4 1 .7 2.3 1.8 1.7 1.4 .9-.1 1.7 .6-.2 .8 2.1 .1 2 1.2-.3 .7-1.8 .4-1.9 .1-1.9-.2-4 .3 1.9-1.6-1.2-.8-1.7-.2-1-.8-.7-1.7-1.5 .1-2.6-.8-.9-.6-3.6-.4-.9-.6 1-.7-2.7-.2-2 1.6-1.2 0-.4 .7-1.4 .3-1.1-.3 1.4-.9 .6-1 1.3-.7 1.4-.5 2.1-.3z' }, + CY: { name: 'Cyprus', path: 'M590.9 214.3l.5 .1 .8-.2 .5 0 .2 .2 .1 .3 .1-.1 .4 0 .6-.2 .3 .1 .1 .3-2.9 1.2-1.3-.4-.7-1.2z' }, + CZ: { name: 'Czech Republic', path: 'M541.7 160.2l1.3 1.2 2.1 .3-.2 1 1.5 .8 .5-1 1.9 .4 .2 1.2 2.1 .2 1.3 1.8-.9 0-.4 .6-.6 .2-.2 .8-.5 .2-.1 .3-1 .4-1.2-.1-.4 .8-1.3-.7-1.3 .2-2.1-1.1-1 .3-1.6 1.5-2-1.2-1.6-1.5-1.4-.9-.3-1.5-.5-1.1 2-.8 1.1-.9 1.9-.7 .7-.7 .8 .4z' }, + DE: { + name: 'Germany', + path: 'M539.2 150.3l.7 1.9-.8 1.1 1 1.3 .7 2-.2 1.3 1.1 2.3-1.2 .4-.8-.4-.7 .7-1.9 .7-1.1 .9-2 .8 .5 1.1 .3 1.5 1.4 .9 1.6 1.5-1 1.7-1 .4 .4 2.3-.3 .6-.8-.7-1.4-.1-2 .6-2.4-.1-.4 .9-1.4-1-.8 .2-3-1.1-.6 .8-2.4 0 .4-2.6 1.4-2.4-4-.7-1.3-.9 .1-1.6-.5-.8 .3-2.5-.5-3.8 1.7 0 .7-1.4 .7-3.5-.5-1.2 .5-.8 2.3-.2 .6 .8 1.8-1.9-.6-1.4-.1-2.2 2.1 .5 1.8-.6 0 1.5 2.8 .9 0 1.4 2.8-.8 1.6-1 3.1 1.5z', + }, + DJ: { name: 'Djibouti', path: 'M617.6 281l1.2 .3 .9-.7 .6 .8-.1 1.2-1.5 .7 1.1 .8-1 1.5-.6-.5-.7 .2-1.5-.1-.1-.8-.2-.8 1-1.3z' }, + DK: { name: 'Denmark', path: 'M527.6 145.6l-1.8 .6-2.1-.5-1.1-2.1-.1-4 .4-1.1 .8-1.2 2.5-.3 1-1.1 2.2-1.1-.1 2.1-.8 1.3 .3 1.1 1.5 .6-.7 1.5-.8-.5-2 2.8zM534.4 141.2l.9 2-1.7 3.1-2.9-2.1-.4-1.7z' }, + DO: { name: 'Dominican Republic', path: 'M300.8 265.4l.1-.8-.7-.9 .6-.5 .2-1.1-.2-1.5 .3-.5 2.2 0 1.7 .7 .7 0 .5 1 1.5-.1-.1 .9 1.3 .1 1.3 1-1 1.2-1.3-.6-1.3 .1-.9-.1-.5 .5-1.1 .2-.4-.7-.9 .4-1.1 2-.7-.5z' }, + DZ: { + name: 'Algeria', + path: 'M475.9 238l0-.6 0-.2 0-3.5 4.5-2.3 2.8-.4 2.2-.8 1.1-1.6 3.2-1.2 .2-2.2 1.6-.3 1.2-1.2 3.7-.5 .5-1.2-.8-.6-.9-3.3-.2-1.9-1-2 2.6-1.8 3-.5 1.8-1.3 2.7-1 4.7-.6 4.6-.2 1.4 .5 2.6-1.3 3 0 1.1 .7 1.9-.2-.6 1.7 .5 3-.7 2.6-1.7 1.7 .2 2.4 2.3 1.8 0 .8 1.8 1.2 1.1 5.5 .9 2.7 .2 1.4-.5 2.5 .2 1.3-.4 1.7 .3 1.9-1.1 1.2 1.6 2.2 .1 1.2 1 1.7 1.3-.6 2.2 1.4 1.2 1.8-9.5 5.6-8 5.7-3.9 1.3-3.1 .3-.1-1.9-1.2-.4-1.8-.9-.6-1.3-9.4-6.4-9.4-6.4z', + }, + EC: { name: 'Ecuador', path: 'M290.6 316.5l.4 2.1-.8 1.8-3.1 2.9-3.3 1.1-1.7 2.4-.5 1.9-1.6 1.1-1.2-1.4-1.1-.3-1.2 .2 0-1 .8-.6-.4-1.2 1.5-2.1-.6-1.2-1 1.3-1.7-1.2 .6-.8-.5-2.5 1-.4 .5-1.8 1-1.8-.2-1.1 1.5-.6 2-1.1 2.7 1.6 .6-.1 .6 1.2 2.4 .4 .8-.4 1.3 .9z' }, + EE: { name: 'Estonia', path: 'M577.7 127.7l.4 .7-1.9 2.4 .8 3.8-1.2 1.2-2.3 0-2.4-1.5-1.2-.4-2.4 .7 .4-2.4-1.1 .5-1.7-1.4-.3-2.4 3.5-1.1 3.5-.6 3.1 .6z' }, + EG: { + name: 'Egypt', + path: 'M602.4 253.9l-11 0-10.8 0-11.2 0 0-10.8 0-10.6-.8-2.5 .7-1.9-.4-1.3 1-1.4 3.7-.1 2.7 .8 2.7 .9 1.3 .5 2.2-1 1.1-.8 2.4-.3 2 .4 .8 1.5 .6-1 2.2 .7 2.2 .2 1.4-.8 1.5 4.5 .3 .8-.8 1.2-.6 2.3-.7 1.5-.7 .6-.9-1-1.3-1.4-1.9-4.3-.3 .3 1.1 3.2 1.7 3 2.1 4.7 1.1 1.6 .9 1.6 2.4 3.3-.5 .5 .1 1.9 3.2 2.6z', + }, + EH: { name: 'Western Sahara', path: 'M475.9 237.2l0 .2 0 .6 0 4.5-9.1-.1 0 7.5-2.6 .3-.6 1.5 .5 4.2-10.9 0-.6 1 .1-1.3 .1 0 6.2-.2 .4-1.1 1.1-1.3 .9-4 3.9-3.2 1.3-3.7 .8-.2 1-2.4 2.3-.3 1 .4 1.3 0 .9-.7 1.7-.1-.1-1.6z' }, + ER: { name: 'Eritrea', path: 'M601.2 275.7l-.3-1.1 1.2-4.2 .3-1.9 .8-.9 2.1-.5 1.4-1.6 1.6 3.3 .8 2.6 1.5 1.4 3.8 2.7 1.5 1.6 1.5 1.7 .9 .9 1.4 .9-.9 .7-1.2-.3-.9-.9-1.1-1.7-1.3-.9-.7-.9-2.4-1.2-1.9 0-.7-.6-1.6 .7-1.7-1.3-.9 2.1z' }, + ES: { + name: 'Spain', + path: 'M479.3 208l-.2-1 1-1.2 .4-.9-1-1 .8-2.1-1.1-1.9 1.2-.3 .1-1.5 .4-.5 .1-2.6 1.3-.9-.8-1.7-1.6-.1-.5 .4-1.7 0-.7-1.6-1.1 .5-1 .8 .1-2.3-1.1-1.5 3.9-2.4 3.4 .6 3.8 0 2.9 .5 2.3-.1 4.5 .1 1.1 1.3 5.1 1.5 1-.7 3.2 1.5 3.2-.4 .1 1.9-2.6 2.2-3.5 .7-.3 1.1-1.7 1.8-1.1 2.7 1.1 1.9-1.6 1.4-.6 2.1-2.1 .6-2 2.5-3.5 0-2.6 0-1.8 1.1-1 1.2-1.4-.3-1-1-.8-1.9z', + }, + ET: { + name: 'Ethiopia', + path: 'M632.7 293.8l-7.8 8.3-3.6 .2-2.5 1.9-1.8 .1-.7 .8-1.9 0-1.2-.9-2.5 1.2-.8 1.1-1.9-.2-.6-.3-.6 .1-.9-.1-3.5-2.3-2 0-.9-.9 0-1.6-1.4-.5-1.7-3-1.3-.7-.4-1.1-1.5-1.3-1.7-.2 1-1.6 1.5-.1 .4-.8-.1-2.6 .9-2.9 1.3-.8 .3-1.1 1.1-2.2 1.7-1.4 1.2-2.8 .4-2.4 3.2 .6 .9-2.1 1.7 1.3 1.6-.7 .7 .6 1.9 0 2.4 1.2 .7 .9 1.3 .9 1.1 1.7 .9 .9-.9 1.3-1 1.3 .2 .8 .1 .8 1.5 .1 .7-.2 .6 .5-.6 1 1 1.5 1.1 1.4 1 1 9.1 3.3z', + }, + FI: { + name: 'Finland', + path: 'M579.4 84.9l-.4 3.4 4.3 3.2-2.6 3.5 3.2 5.3-1.8 3.9 2.5 3.3-1.2 2.9 4.1 3-1 2.2-2.6 2.5-5.9 5.4-5.1 .3-4.9 1.5-4.5 .9-1.6-2.3-2.7-1.4 .6-4.1-1.3-3.9 1.3-2.5 2.5-2.8 6.4-4.8 1.9-1-.3-1.9-3.9-2.2-.9-1.7-.1-7.3-4.3-3.2-3.8-2.4 1.7-1.3 3.1 2.6 3.6-.3 3 1.2 2.7-2.2 1.3-3.6 4.3-1.6 3.6 1.9z', + }, + FJ: { name: 'Fiji', path: 'M1000 361l0 1.4-1.8 .7-1.7 .6-.4-1 1.4-.6 .9-.2zM994.8 365.2l.7-.5 .9 .8-.4 1.5-1.7 .4-1.6-.4-.2-1.2 1-1zM.6 360.9l-.4 1.4-.2 .1 0-1.4z' }, + FK: { name: 'Falkland Islands / Malvinas', path: 'M330 474.6l3.3-2.2 2.4 .9 1.7-1.5 2.2 1.7-.8 1.3-3.8 1.1-1.2-1.3-2.4 1.7z' }, + FR: { + name: 'France', + path: 'M356.5 304.5l-1.6 2.5-.9 2.1-1.1 1-1.3 .2-.4-.7-.6-.2-.8 .8-1.3-.6 .8-1.2 .2-1.2 .5-1.2-1.1-1.7-.2-1.9 1.4-2.4 1 .3 2 .7 2.9 2.3zM517.2 166.2l1.3 .9 4 .7-1.4 2.4-.4 2.6-.7 .6-1.3-.3 .1 .8-2 2-.1 1.6 1.4-.5 .9 1.5-.1 1 .8 1.2-1 1.1 .8 2.6 1.5 .5-.3 1.5-2.6 1.9-5.4-1-4.1 1.1-.3 2.1-3.2 .4-3.2-1.5-1 .7-5.1-1.5-1.1-1.3 1.5-2.1 .5-6.8-2.9-3.7-2-1.7-4.3-1.4-.3-2.6 3.6-.8 4.7 .9-.9-4 2.7 1.5 6.4-2.8 .9-3 2.4-.7 .4 1.3 1.3 0 1.3 1.5 1.9 1.7 1.4-.3 2.5 1.7 .6 .3zM524.3 189.9l1.8-1.2 .5 2.8-1 2.6-1.2-.7-.7-2.2z', + }, + GA: { name: 'Gabon', path: 'M531.3 309.8l1.3-.2 1.7 .3 1.7-.3 .3 .1-.2 1.3 .8 1.4 2.1-.2 .7 .5-1.2 3.2 1.3 1.7 .3 2.1-.4 1.9-.8 1.3-2.5-.1-1.5-1.3-.2 1.2-1.9 .3-.9 .7 1 1.9-2.1 1.5-2.8-2.8-1.9-2.3-1.7-2.9 .1-.9 .6-.9 .7-2 .6-2.1 .9-.1 4 0z' }, + GB: { + name: 'United Kingdom', + path: 'M482.8 149.9l-2.1-.8-1.7 .1 .5-2.1-.5-2 2.3-.2 3 2.4zM491.4 151.7l.4-2.2-1.8-2.4-.1-.1-3.4-.6-.6-1.1 1-1.7-.9-1.1-1.5 1.9-.2-3.8-1.4-2 1-4.1 2.2-3.3 2.2 .3 3.4-.3-3 4.3 2.8-.5 3.1 0-.8 3.2-2.5 3.6 2.9 .2 .2 .4 2.5 4.6 1.9 .6 1.7 4.4 .8 1.4 3.4 .8-.4 2.4-1.4 1 1.1 2-2.5 1.9-3.7-.1-4.7 1-1.3-.7-1.8 1.7-2.6-.4-2 1.4-1.4-.7 4-3.9 2.5-.8-4.3-.6-.8-1.4 2.9-1.2-1.6-2 .6-2.5z', + }, + GE: { name: 'Georgia', path: 'M611 187.2l.3-.4 2.4 .6 4.1 .6 3.7 1.6 .5 .6 1.7-.5 2.6 .7 .9 1.3 1.7 .8-.7 .5 1.3 1.8-.3 .4-1.5-.2-2.1-1-.7 .5-3.8 .6-2.7-1.7-3 .2 .4-1.4-.7-2.3-1.6-1.3-1.5-.3z' }, + GH: { name: 'Ghana', path: 'M500.1 285.3l-.2 .9 1.1 1.4 0 2.1 .3 2.2 .7 1-.6 2.5 .2 1.4 .7 1.8 .6 1-4.3 1.6-1.6 .9-2.5 .8-2.4-.7 .1-1.1-1.2-2.4 .7-3.2 1.2-2.3-.8-4-.3-2.1 0-1.6 4.9-.2 1.2 .2 .9-.4z' }, + GL: { + name: 'Greenland', + path: 'M370.1 7.1l9.3-4.1 9.8 .3 3.5-2.6 9.8-.7 22.2 .9 17.4 5.5-5.1 2.6-10.7 .3-14.9 .7 1.4 1.2 9.8-.7 8.4 2.3 5.4-2.1 2.3 2.4-3.1 3.9 7.1-2.5 13.5-2.6 8.3 1.3 1.6 2.9-11.3 4.6-1.6 1.5-8.9 1.1 6.4 .3-3.2 4.6-2.2 4 .1 6.7 3.3 3.8-4.4 .3-4.5 1.8 5.1 3.1 .7 4.8-3 .5 3.6 4.7-6.2 .4 3.2 2.2-.9 1.9-3.9 .8-3.9 .1 3.5 3.5 .1 2.4-5.5-2.2-1.5 1.4 3.8 1.3 3.6 3.2 1.1 4.1-5 .9-2.1-1.9-3.5-2.9 1 3.4-3.2 2.7 7.3 .2 3.8 .2-7.4 4.3-7.6 3.9-8.1 1.6-3.1 0-2.8 1.9-3.9 4.9-6 3.3-1.9 .2-3.7 1.1-4 1.1-2.4 2.8 0 3.1-1.4 2.9-4.5 3.5 1.1 3.3-1.3 3.6-1.4 4.1-3.9 .2-4.1-3.4-5.6 0-2.7-2.3-1.8-4.2-4.8-5.4-1.4-2.9-.4-4.1-3.9-4.2 1-3.4-1.8-1.6 2.7-5.6 4.2-1.8 1.1-2 .6-3.9-3.2 1.8-1.5 .7-2.5 .7-3.4-1.6-.2-3.4 1.1-2.6 2.6-.1 5.6 1.3-4.7-3.2-2.5-1.7-2.8 .7-2.3-1.3 3.1-4.8-1.7-2-2.2-3.7-3.3-5.8-3.6-2.1 .1-2.4-7.5-3.3-5.9-.4-7.4 .2-6.8 .5-3.2-1.9-4.8-3.6 7.3-1.8 5.5-.4-11.8-1.5-6.3-2.4 .4-2.4 10.5-2.9 10.2-3 1-2.3-7.5-2.2 2.5-2.6 9.6-4.5 4-.7-1.1-3 6.5-1.8 8.6-1 8.5-.1 3.1 2.1 7.3-3.7 6.7 2.5 3.9 .5 5.7 2.2-6.6-3.6z', + }, + GM: { name: 'The Gambia', path: 'M453.6 278l3 0 .6-.7 .9-.1 1.1 .7 .9 .1 .9-.5 .5 .8-1.2 .6-1.2 0-1.2-.6-1 .6-.5 .1-.7 .4-2.5-.1z' }, + GN: { + name: 'Guinea', + path: 'M461.9 280.9l1.4 0 2 .7 .6-.1 .2-.3 1.5 .3 .4-.2 .2 1 .4 0 .7-.3 .5 0 .8 .8 1.2 .2 .7-.6 .9-.4 .7-.4 .5 .1 .7 .6 .3 .8 1.1 1.2-.5 .7-.1 .9 .5-.3 .4 .3-.2 .9 .9 .8-.6 .2-.2 1 .7 1.1 .6 2.3-1 .3-.3 .4 .3 .5-.2 1.2-.4 0-.8 0-.6 1.1-.8 0-.5-.6 .2-1.1-1.2-1.7-.7 .3-.6 0-.8 .2 0-1-.4-.8 .1-.8-.6-1.2-.8-1-2.2 0-.7 .6-.7 0-.5 .6-.3 .8-1.5 1.2-1.2-1.6-1.1-1.1-.7-.4-.7-.5-.3-1.3-.4-.6-.8-.5 1.2-1.3 .8 0 .8-.4 .6 0 .4-.4-.2-1 .3-.2z', + }, + GQ: { name: 'Equatorial Guinea', path: 'M526.8 309.7l4.5 .1 0 3.3-4 0-.9 .1-.6-.4z' }, + GR: { + name: 'Greece', + path: 'M573 213.8l-.3 .9-4 .2 0-.5-3.4-.6 .5-1.3 1.6 1 2.1-.1 2.1 .2-.1 .5zM563.8 194.2l2 .1 2.2-.9 2 1.2 2.5-.3 0-1.7 1.4 .9-.9 2.1-.6 .3-1.7 0-1.5-.4-3.3 .9 1.9 1.8-1.4 .6-1.6 0-1.4-1.7-.5 .7 .6 2 1.4 1.5-1.1 .7 1.6 1.5 1.3 .9 .1 1.9-2.6-.9 .8 1.6-1.7 .4 1 2.8-1.8 0-2.3-1.3-1-2.6-.5-2.2-1.1-1.4-1.4-1.9-.2-.9 1.3-1.6 .1-1.1 .9-.4 .1-.9 1.8-.3 1.1-.7 1.5 0 .4-.5z', + }, + GT: { name: 'Guatemala', path: 'M243.8 275.4l.1-.9 .3-.6-.4-.6 1.3-2.3 3.6 0 .1-.9-.5-.2-.3-.6-1-.7-1-1 1.2 0 0-1.6 2.6 0 2.6 .1 0 2.2-.3 3.2 .9 0 .9 .6 .2-.5 .8 .4-1.2 1.1-1.4 .8-.1 .5 .2 .6-.6 .7-.7 .2 .2 .3-.5 .3-1 .7-.1 .4-1.4-.4-1.7-.1-1.3-.6z' }, + GW: { name: 'Guinea-Bissau', path: 'M453.7 281.5l1.4-.5 1 .1 .7-.3 5.1 .1 0 1-.3 .2 .2 1-.4 .4-.6 0-.8 .4-.8 0-1.2 1.3-1.5-1.1-1.2-.2-.6-.8 0-.4-.8-.6z' }, + GY: { name: 'Guyana', path: 'M342.9 310.8l-.6 .1-1.6-.3-.9 .8-1.2 .5-.9 .1-.3 .5-1.4-.1-1.7-1.3-.2-1.3-.7-1.4 .4-2.4 .8-1-.6-1.3-1-.4 .4-1.2-.7-.6-1.4 .1-1.9-2.1 .8-.8-.1-1.3 1.7-.4 .7-.6-.9-1 .2-1 2.2-1.7 1.8 1.1 1.7 1.8 .1 1.4 1.1 .1 1.5 1.4 1.1 .9-.5 2.5-1.7 .8 .2 .6-.5 1.5 1.2 2 .9 0 .3 1.5z' }, + HN: { + name: 'Honduras', + path: 'M269 274.1l-.9-.1-.4 .4-1 .4-.7 0-.6 .3-.5-.1-.5-.4-.3 .1-.4 .6-.2 0-.1 .6-.9 .8-.6 .3-.2 .4-.9-.6-.6 .7-.5 0-.7 .1 .1 1.4-.4 0-.4 .7-.8 .1-.5-.9-.9-.3 .2-1.1-.4-.3-.5-.2-1.2 .3-.1-.3-.9-.5-.6-.6-.8-.2 .6-.7-.2-.6 .1-.5 1.4-.8 1.2-1.1 .3 .1 .6-.5 .8 0 .3 .2 .4-.1 1.3 .2 1.3-.1 .9-.3 .3-.3 .9 .2 .7 .1 .7 0 .5-.3 1.3 .4 .4 .1 .9 .5 .8 .7 1 .4z', + }, + HR: { name: 'Croatia', path: 'M546 176.7l.9 .4 2.1 1.5 2.3 .7 1-.5 .7 1.3 .9 1-1.1 1.3-1.3-.8-1.9 .1-2.4-.6-1.3 .1-.6 .7-1-.8-.5 1.4 1.3 1.6 .6 1.1 1.3 1.2 1 .8 1.1 1.4 2.5 1.3-.3 .5-2.7-1.2-1.6-1.2-2.5-1-2.3-2.5 .5-.3-1.3-1.4 0-1.2-1.8-.5-.8 1.5-.9-1.2 .1-1.2 .1 0 1.9 .1 .5-.6 1 .6 1.1 0 0-.9 .9-.4 .3-1.4z' }, + HT: { name: 'Haiti', path: 'M300.8 260.6l.2 1.5-.2 1.1-.6 .5 .7 .9-.1 .8-1.8-.5-1.3 .2-1.7-.2-1.3 .5-1.5-.9 .2-.9 2.6 .4 2.1 .2 1-.6-1.3-1.3 0-1.1-1.7-.4 .6-.8 1.7 .1z' }, + HU: { name: 'Hungary', path: 'M561.3 169.9l1.6 1 .2 .9-1.7 .8-1.3 2.4-1.7 2.3-2.2 .7-1.8-.2-2.1 1-1 .5-2.3-.7-2.1-1.5-.9-.4-.5-1.2-.5 0 .9-2.3-.5-.8 1.6 0 .2-1.4 1.4 .9 1 .4 2.3-.4 .3-.8 1.1-.1 1.3-.5 .3 .2 1.3-.4 .7-.9 .9-.2 3 1.1z' }, + ID: { + name: 'Indonesia', + path: 'M891.7 323.3l0 9 .1 9.1-2.5-2.3-2.8-.5-.7 .8-3.5 .1 1.1-2.3 1.8-.8-.7-3-1.4-2.4-5.4-2.3-2.2-.3-4.2-2.5-.8 1.3-1.1 .3-.6-1.1 0-1.2-2.2-1.3 3-1 2 0-.2-.7-4.1 0-1.1-1.7-2.5-.5-1.1-1.4 3.7-.6 1.4-.9 4.5 1.1 .4 1 .8 4.5 2.9 1.7 2.3-3 3.2-1.6 2.4 0 2.4 .9 2.1 1zM847.1 340.8l.3 .6 .1 .8-1.8 2.1-2.4 .6-.4-.3 .3-1 1.2-1.7zM872.8 335.2l-.3-2.1 .5-1 .6-.9 .6 .8 0 1.3zM827.5 304.5l-1.6 2.6 2 2.6-.5 1.3 3.1 2.5-3.2 .4-1 1.9 .1 2.5-2.6 1.9-.1 2.7-1.1 4.3-.4-1-3.1 1.3-1.1-1.7-2-.2-1.4-.9-3.3 1-1-1.3-1.8 .1-2.3-.3-.4-3.7-1.4-.8-1.4-2.4-.4-2.4 .4-2.6 1.6-1.8 .5 1.8 1.9 1.6 1.8-.6 1.7 .2 1.7-1.4 1.3-.2 2.6 .8 2.3-.6 1.4-3.9 1.1-1 .9-3.1 3.2 0zM859.4 323.8l3 .8 1 2.2-2.3-1.2-2.3-.2-1.6 .2-1.9-.1 .6-1.6zM852.4 326.6l-1.9-.5-.5-1.2 2.8-.2 .7 1zM855.4 310l.2 1.5 1.6 .3 .3 1.1-.2 2.4-1.4-.3-.4 1.7 1.1 1.5-.8 .3-1.1-1.7-.8-3.6 .5-2.2zM841.5 313.6l3.2-.1 2.7-2 .5 .6-2.2 2.7-2.1 .6-2.7-.6-4.6 .2-2.5 .4-.4 2.1 2.5 2.5 1.5-1.3 5.2-1-.2 1.3-1.2-.4-1.2 1.7-2.5 1 2.7 3.6-.6 .9 2.5 3.3 0 1.8-1.5 .8-1.1-1 1.4-2.3-2.7 1.1-.7-.7 .3-1.1-2-1.7 .2-2.7-1.8 .9 .2 3.2 .1 4-1.7 .4-1.2-.8 .8-2.6-.5-2.7-1.1 0-.9-1.9 1.2-1.8 .4-2.2 1.3-4.2 .6-1.1 2.4-2.1 2.2 .8zM834.2 344.6l-3.7-1.9 2.6-.6 1.4 .9 1 .8-.2 .8zM837.1 339.8l1.8-.2 2.5-1-.4 1.5-4.2 .8-3.7-.3 0-1 2.2-.6zM828.5 339.3l1.7-.2 .7 1.2-3.2 .5-1.9 .4-1.5 0 .9-1.6 1.6 0 .7-1zM801.4 333.9l.3 1 5.4 .3 .6-1.2 5.1 1.4 1 1.8 4.2 .5 3.4 1.6-3.2 1.1-3-1.1-2.5 .1-2.9-.2-2.6-.6-3.2-1-2.1-.3-1.1 .4-5.1-1.2-.5-1.2-2.5-.2 1.9-2.7 3.4 .2 2.2 1.1zM789.9 319.1l.5 1.9 1 1.5 2 .3 1.3 1.7-.7 3.5-.1 4.3-3 .1-2.4-2.4-3.5-2.2-1.2-1.7-2.1-2.3-1.4-2.1-2.1-3.9-2.5-2.3-.8-2.4-1-2.1-2.5-1.8-1.5-2.4-2.1-1.5-2.9-3.1-.2-1.4 1.8 .1 4.3 .6 2.4 2.7 2.2 1.9 1.5 1.1 2.7 3 2.8 0 2.3 2 1.6 2.3 2.1 1.2-1.1 2.3 1.6 1z', + }, + IE: { name: 'Ireland', path: 'M482.8 149.9l.4 2.7-2.1 3.4-4.9 2.1-3.9-.5 2.2-3.9-1.4-3.8 3.8-3 2.1-1.8 .5 2-.5 2.1 1.7-.1z' }, + IL: { name: 'Israel', path: 'M599.2 221.8l-.5 1-1-.4-.5 2 .6 .4-.7 .4-.1 .8 1.3-.4 .1 1.2-1.4 4.9-.3-.8-1.5-4.5 .8-1-.2-.2 .7-1.4 .6-2.3 .4-.8 .1 0 .9 0 .3-.6 .7 0 0 1.3z' }, + IN: { + name: 'India', + path: 'M770.4 235.4l.2 1.2-1 .5 .2 1.8-2-.5-3.6 2.1 .1 1.7-1.5 2.5-.2 1.4-1.2 2.4-2.2-.6-.1 3-.6 1 .3 1.2-1.4 .7-1.4-4.6-.8 0-.5 1.9-1.5-1.6 .9-1.6 1.2-.2 1.3-2.5-1.6-.5-2.6 0-2.6-.4-.3-2-1.3-.2-2.2-1.3-1 2.1 2 1.5-1.7 1.1-.6 1.1 1.7 .8-.5 1.8 1 2.2 .4 2.4-.4 1-1.9 0-3.4 .6 .2 2.2-1.5 1.7-4 2-3.1 3.3-2.1 1.8-2.8 1.9 0 1.3-1.4 .7-2.5 1.1-1.3 .1-.8 2.2 .6 3.7 .1 2.3-1.2 2.7 0 4.8-1.4 .1-1.3 2.1 .9 1-2.6 .8-.9 1.9-1.1 .8-2.6-2.6-1.3-4-1.1-2.8-1-1.3-1.4-2.7-.7-3.6-.5-1.7-2.5-4-1.2-5.5-.8-3.7 0-3.5-.5-2.7-4.1 1.8-1.9-.4-3.7-3.5 1.4-1.1-.9-1.1-3.2-2.5 1.8-2 6.1 0-.5-2.5-1.6-1.5-.3-2.3-1.8-1.3 3.1-3.2 3.2 .3 2.9-3.2 1.7-3.1 2.7-3 0-2.2 2.4-1.8-2.3-1.5-1-2.1-.9-2.8 1.3-1.3 4.2 .8 3.1-.5 2.7-2.7 3 3.7-.3 2.6 1.1 1.6-.1 1.5-2-.4 .8 3.4 2.7 2 3.9 2.1-1.8 1.4-1 2.8 2.7 1.1 2.6 1.5 3.6 1.7 3.8 .4 1.6 1.5 2.2 .3 3.3 .7 2.3-.1 .3-1.1-.3-1.9 .2-1.3 1.7-.7 .2 2.4 .1 .6 2.5 1.1 1.7-.4 2.4 .2 2.2-.1 .2-1.9-1.1-.9 2.3-.4 2.5-2.2 3.2-2 2.3 .8 2-1.3 1.3 1.9-.9 1.3z', + }, + IQ: { name: 'Iraq', path: 'M608.9 223.5l-1.1-3.7 6.1-3.3 1.1-3.8-.3-2.3 1.5-.8 1.4-2 1.2-.5 3.3 .4 .9 .9 1.4-.6 1.8 3.8 1.8 1 .2 1.8-1.4 1.1-.6 2.4 1.9 3 3.4 1.7 1.4 2.3-.4 2.3 .8 0 .1 1.6 1.5 1.6-1.6-.2-1.9-.2-2 2.9-5.2-.3-7.8-6.1-4.2-2.1z' }, + IR: { + name: 'Iran', + path: 'M634.9 230.4l-1.5-1.6-.1-1.6-.8 0 .4-2.3-1.4-2.3-3.4-1.7-1.9-3 .6-2.4 1.4-1.1-.2-1.8-1.8-1-1.8-3.8-1.6-2.6 .6-1-.9-3.7 1.9-.9 .5 1.2 1.4 1.5 1.9 .5 1-.1 3.3-2.4 1-.3 .8 1-.9 1.6 1.7 1.7 .7-.2 .9 2.4 2.6 .7 1.9 1.6 4 .5 4.3-.8 .3-.8 2.4-.6 2-1.8 1.9 .1 1.2-.6 2 .3 3 1.6 2.2 .3 3.2 2.9 2.1 .1 .2 2.6-1.1 4-.8 2.2 1.2 .5-1.1 1.7 .9 2.5 .2 1.9 2.1 .5 .2 2-2.5 2.8 1.4 1.6 1.1 1.8 2.6 1.3 .1 2.7 1.3 .4 .3 1.4-4 1.6-1.1 3.4-5.2-.9-3-.7-3.2-.4-1.1-3.6-1.4-.5-2.1 .5-2.8 1.4-3.4-.9-2.8-2.3-2.7-.9-1.8-2.9-2.1-4-1.5 .5-1.8-1z', + }, + IS: { name: 'Iceland', path: 'M459.7 97.3l-.6 3 3.1 3.1-3.6 3.4-8 3-2.4 .8-3.7-.6-7.7-1.4 2.7-2-6-2.2 4.9-.9-.1-1.3-5.9-1 1.9-3 4.2-.7 4.3 3.1 4.3-2.5 3.5 1.3 4.5-2.5z' }, + IT: { + name: 'Italy', + path: 'M529 175.3l1.7 .5 .3-.6 2.8-.6 .6 1.2 4 .9-.3 1.7 .6 1.5-2.2-.5-2.3 1.2 .2 1.7-.3 1 .9 1.7 2.6 1.7 1.4 2.8 3.1 2.7 2.1 0 .7 .7-.8 .7 2.5 1.2 2.1 1 2.3 1.7 .3 .6-.5 1.2-1.5-1.6-2.4-.5-1.2 2.1 2 1.2-.3 1.7-1.2 .2-1.5 2.8-1.1 .2 0-.9 .5-1.8 .6-.7-1-1.9-.9-1.6-1.1-.4-.9-1.4-1.7-.6-1.2-1.4-2.1-.2-2.2-1.5-2.5-2.1-1.9-2-.9-3.3-1.3-.4-2.3-1.1-1.3 .4-1.6 1.6-1.1 .3 .3-1.5-1.5-.5-.8-2.6 1-1.1-.8-1.2 .1-1 1.2 .7 1.3-.1 1.6-1.2 .5 .5 1.3-.1 .6-1.4 2.1 .5 1.2-.6zM541 204.7l2.1-.3-1 2.5 .4 1-.6 1.7-2.1-1.2-1.4-.4-3.9-1.6 .4-1.7 3.3 .3zM524.2 195.7l1.4-1 1.6 2.3-.3 4.3-1.3-.2-1.1 1.1-1.1-.8-.1-4-.6-1.9z', + }, + JM: { name: 'Jamaica', path: 'M284.5 264.1l1.9 .3 1.5 .6 .4 .8-1.9 .1-.9 .5-1.5-.5-1.6-1 .3-.7 1.2-.2z' }, + JO: { name: 'Jordan', path: 'M598.7 222.8l.5-1 3.1 1.3 5.5-3.3 1.1 3.7-.6 .5-5.5 1.5 2.8 3.1-1 .5-.4 1-2.1 .5-.7 1.1-1.2 .9-3.1-.5-.1-.4 1.4-4.9-.1-1.2 .4-.9z' }, + JP: { + name: 'Japan', + path: 'M894.1 201.3l-2.5 3.3 0 3.3-1 2.5 .4 1.6-1.4 2.3-3.6 1.4-4.8 .2-4 3.6-1.9-1.2-.1-2.3-4.8 .7-3.3 1.4-3.2 .1 2.8 2.3-1.9 5.2-1.8 1.3-1.3-1.2 .7-2.7-1.8-.9-1.1-2.2 2.6-.9 1.5-2 2.7-1.6 2.1-2.2 5.5-.9 3 .6 2.9-5.6 1.8 1.5 4.1-3.2 1.6-1.2 1.7-4-.4-3.7 1.1-2.1 3-.6 1.5 4.6zM901.7 185.4l2-1.4 .6 3.8-4.1 .9-2.5 3.4-4.3-2.3-1.5 3.6-3.1 .1-.4-3.3 1.4-2.6 2.9-.2 .8-4.7 .9-2.7 3.2 3.6 2.2 1.1zM867.7 219.5l1.5-1.9 1.6 .4 1.2-1.3 2 .7 .4 1-1.6 1.9-1.2-1-1.4 .7-.7 1.9-1.8-.9z', + }, + KE: { name: 'Kenya', path: 'M608.9 329l-4-2.7-.2-1.7-10.1-5.6-.4-.3-.1-3 .8-1.1 1.4-1.8 1-2.1-1.2-3.1-.3-1.4-1.3-2 1.7-1.6 1.9-1.9 1.4 .5 0 1.6 .9 .9 2 0 3.5 2.3 .9 .1 .6-.1 .6 .3 1.9 .2 .8-1.1 2.5-1.2 1.2 .9 1.9 0-2.5 3.2 .1 10.1 1.6 2.3-1.9 1.1-.7 1.2-1.1 .2-.4 1.9-.8 1.2-.6 1.8z' }, + KG: { name: 'Kyrgyzstan', path: 'M697.1 191.2l.6-1.5 1.9-.5 4.5 1.2 .5-2 1.5-.7 4 1.4 1-.4 4.6 .1 4.1 .4 1.4 1.2 1.7 .5-.3 .7-4.4 1.8-1 1.4-3.6 .3-1 2.2-3-.5-1.9 .7-2.6 1.5 .3 .8-.7 .7-5.3 .5-3.4-1.1-3 .3 .2-1.9 3 .6 1.1-1 2.1 .3 3.5-2.4-3.3-1.7-1.9 .8-2.1-1.3 2.3-2.1z' }, + KH: { name: 'Cambodia', path: 'M785 282l-.7-3.4 1.8-2.3 3.6-.6 2.6 .4 2.3 1.1 1.2-1.9 2.5 1 .6 1.9-.3 3.4-4.7 2.2 1.2 1.7-2.9 .2-2.4 1.1-2.3-.4-1.1-1.5z' }, + KP: { + name: 'Dem. Rep. Korea', + path: 'M862.9 190.7l.4 .6-1.1-.2-1.2 1.1-.8 1.2 .1 2.4-1.4 .7-.5 .6-1.1 .9-1.8 .6-1.2 .9-.1 1.4-.4 .3 1.2 .6 1.5 1.4-.4 .8-1.2 .2-1.9 .1-1.1 1.5-1.2-.1-.2 .3-1.4-.7-.3 .6-.8 .3-.1-.6-.7-.3-.8-.5 .8-1.4 .6-.4-.2-.6 .7-1.7-.2-.6-1.6-.3-1.3-.9 2.2-2.1 3.1-1.8 1.9-2.3 1.3 1 2.4 .1-.4-1.7 4.3-1.5 1.1-1.9z', + }, + KR: { name: 'Republic of Korea', path: 'M850.5 206l.2-.3 1.2 .1 1.1-1.5 1.9-.1 1.2-.2 .4-.8 2.4 3.8 .7 2 0 3.7-1 1.7-2.5 .6-2.2 1.3-2.6 .3-.3-1.7 .6-2.4-1.3-3.3 2.1-.5z' }, + KW: { name: 'Kuwait', path: 'M633.3 230.2l.5 1.4-.2 .7 .9 2.2-2 .1-.7-1.4-2.4-.3 2-2.9z' }, + KZ: { + name: 'Kazakhstan', + path: 'M742.7 167.1l-2.1 2.4-2.4 .3-.1 3.6-1.5 1.6-5.5-1.2-2 6.2-1.5 .8-5.5 1.4 2.5 5.9-1.9 .9 .2 1.9-1.7-.5-1.4-1.2-4.1-.4-4.6-.1-1 .4-4-1.4-1.5 .7-.5 2-4.5-1.2-1.9 .5-.6 1.5-1.6 .6-3.6 2.3-1.3 2.4-1 0-.8-1.6-3.5-.1-.5-2.7-1.4 0 .2-3.4-3.3-2.5-4.8 .3-3.2 .5-2.7-3.1-2.3-1.3-4.3-2.4-.5-.3-7.1 2 .1 12.4-1.5 .2-1.9-2.6-1.9-.9-3.1 .7-1.3 1.1-.1-.8 .7-1.4-.6-1.2-3.2-1.2-1.2-3-1.6-.9-.1-1.1 2.7 .4 .1-2.6 2.4-.5 2.4 .5 .5-3.4-.5-2.1-2.7 .1-2.4-.8-3.2 1.5-2.6 .8-1.4-.6 .3-1.8-1.8-2.4-2.1 .1-2.3-2.4 1.6-2.7-.8-.7 2.2-4 2.8 2.1 .4-2.6 5.7-4 4.4-.1 6.1 2.5 3.3 1.5 2.9-1.5 4.4-.1 3.6 1.9 .8-1.1 3.9 .2 .7-1.8-4.5-2.5 2.6-1.8-.5-1.1 2.7-.9-2-2.6 1.3-1.3 10.4-1.4 1.3-.9 7-1.4 2.5-1.6 4.9 .8 .9 4 2.9-.9 3.6 1.3-.2 2 2.6-.2 7-3.6-1 1.2 3.5 3 6.2 9.4 1.5-1.9 3.8 2.1 4-.9 1.6 .6 1.3 2.1 1.9 .7 1.2 1.6 3.6-.5z', + }, + LA: { name: 'Lao PDR', path: 'M798.3 276.3l-2.5-1-1.2 1.9-2.3-1.1 .9-1.3 .1-2.4-2.2-2.4-.2-2.9-2.1-2.3-2.1-.2-.6 1-1.6 .1-.9-.5-2.9 1.7 0-2.6 .6-3-1.8-.1-.2-1.8-1.2-.9 .6-1 2.4-1.9 .2 .7 1.5 0-.4-3.3 1.4-.4 1.6 2.3 1.3 2.6 3.4 .1 1.1 2.5-1.8 .7-.8 1.1 3.3 1.7 2.3 3.4 1.8 2.5 2.1 2 .7 2z' }, + LB: { name: 'Lebanon', path: 'M599.5 220.1l-.7 0-.3 .6-.9 0 1-2.6 1.3-2.2 .1-.1 1.2 .2 .5 1.2-1.5 1.2z' }, + LK: { name: 'Sri Lanka', path: 'M727.2 295.1l-.4 2.9-1.2 .8-2.4 .6-1.3-2.2-.5-4 1.2-4.5 2 1.5 1.2 2z' }, + LR: { name: 'Liberia', path: 'M476.6 294.6l-.2 .9 .3 1.3-.6 1.2 .8 .8 .9 .2 1.2 1.2 .1 1.1-.3 .3-.2 2.3-.8 0-2.8-1.3-2.5-2.1-2.4-1.5-1.9-1.8 .7-.9 .1-.8 1.3-1.6 1.3-1.3 .6 0 .7-.3 1.2 1.7-.2 1.1 .5 .6 .8 0 .6-1.1z' }, + LS: { name: 'Lesotho', path: 'M580.5 398.8l1 .9-.9 1.4-.5 1-1.5 .5-.5 1-1 .3-2.1-2.4 1.5-1.9 1.5-1.2 1.3-.6z' }, + LT: { name: 'Lithuania', path: 'M573.6 143.2l.3 1.7-2.3 1.3-.7 2.1-3 1.5-2.7-.1-.6-1.1-1.5-.5-.2-.9 .3-1.1-1.2-.6-2.9-.7-.6-3.2 3.2-1.3 4.6 .3 2.8-.4 .3 .8 1.5 .3z' }, + LU: { name: 'Luxembourg', path: 'M516.8 163.8l.5 .8-.1 1.6-.8 .1-.6-.3 .3-2.1z' }, + LV: { name: 'Latvia', path: 'M575.8 135.8l1.3 1 .3 1.9 .9 2.3-3 1.5-1.7 .7-2.7-1.9-1.5-.3-.3-.8-2.8 .4-4.6-.3-3.2 1.3 .1-3 1.3-2.5 2.7-1.4 2.2 3 2.2-.1 .5-3 2.4-.7 1.2 .4 2.4 1.5z' }, + LY: { + name: 'Libya', + path: 'M569.4 253.9l0 5.8-3.1 0-.1 1.3-11.1-5.6-11-5.6-2.8 1.6-2 1.1-1.6-1.6-4.4-1.3-1.2-1.8-2.2-1.4-1.3 .6-1-1.7-.1-1.2-1.6-2.2 1.1-1.2-.3-1.9 .4-1.7-.2-1.3 .5-2.5-.2-1.4-.9-2.7 1.4-.7 .2-1.3-.3-1.2 1.9-1.2 .9-1 1.4-.9 .1-2.4 3.3 1.1 1.1-.3 2.4 .5 3.6 1.4 1.3 2.8 2.5 .5 4 1.3 2.9 1.5 1.4-.7 1.3-1.5-.6-2.3 .8-1.5 2-1.4 1.9-.5 3.8 .7 .9 1.3 1.1 .1 .9 .5 2.7 .3 .7 1.1-1 1.4 .4 1.3-.7 1.9 .8 2.5 0 10.6z', + }, + MA: { + name: 'Morocco', + path: 'M494 214.2l1 2 .2 1.9 .9 3.3 .8 .6-.5 1.2-3.7 .5-1.2 1.2-1.6 .3-.2 2.2-3.2 1.2-1.1 1.6-2.2 .8-2.8 .4-4.5 2.3 0 3.5-.4 0 .1 1.6-1.7 .1-.9 .7-1.3 0-1-.4-2.3 .3-1 2.4-.8 .2-1.3 3.7-3.9 3.2-.9 4-1.1 1.3-.4 1.1-6.2 .2-.1 0 .2-1.3 1-.8 .9-1.5-.2-1 1-2.1 1.5-1.9 1-.4 .7-1.8 .1-1.5 1-1.9 1.8-1.1 1.8-3 .1-.1 1.3-1.1 2.6-.3 2.2-2.1 1.4-.8 2.3-2.5-.7-3.8 1.1-2.7 .4-1.6 1.8-2.1 2.7-1.4 2.1-1.3 1.9-3.3 .8-1.9 2.1 0 1.6 1.4 2.7-.3 2.9 .7z', + }, + MD: { name: 'Moldova', path: 'M573.9 170.6l.7-.5 1.9-.3 2 1.1 1.1 .1 1.3 1-.2 1.2 1 .5 .4 1.5 1 .9-.2 .5 .5 .4-.7 .2-1.7-.1-.2-.5-.6 .3 .2 .6-.8 1.2-.5 1.1-.7 .4-.5-1.6 .3-1.4-.1-1.6-1.6-2.1-.9-1.5-.8-1z' }, + ME: { name: 'Montenegro', path: 'M555.8 190.1l-.8 .3-.2-.7-1.2 1.7 .2 1.1-.6-.3-.7-1.1-1.2-.7 .3-.5 .4-1.9 .9-.8 .5-.3 .7 .6 .4 .5 .9 .3 1.1 .7-.2 .3z' }, + MG: { + name: 'Madagascar', + path: 'M637.6 350.9l.8 1.2 .6 1.8 .5 3.4 .7 1.4-.3 1.3-.5 .9-.9-1.7-.5 .8 .5 2.1-.2 1.3-.8 .6-.2 2.4-1.1 3.4-1.3 4-1.8 5.5-1 4-1.3 3.5-2.2 .7-2.5 1.2-1.6-.7-2.2-1.1-.7-1.6-.2-2.6-1-2.3-.2-2.1 .4-2.1 1.3-.5 0-1 1.4-2.2 .2-1.8-.6-1.4-.6-1.8-.2-2.6 1-1.6 .4-1.8 1.3-.1 1.6-.6 1-.5 1.2-.1 1.6-1.6 2.3-1.7 .8-1.5-.3-1.2 1.1 .4 1.6-2 0-1.7 1-1.3z', + }, + MK: { name: 'North Macedonia', path: 'M562.2 191l1.4 1 .2 2.2-.6 .2-.4 .5-1.5 0-1.1 .7-1.8 .3-1.2-.8-.4-1.4 .4-1.2 .3 .1 .2-.7 1.6-.5 .6-.2 1-.2z' }, + ML: { + name: 'Mali', + path: 'M468 281.3l.1-.9-.2-1.1-1-.8-.6-1.6-.1-1.7 .9-.6 .5-1.6 .9-.1 1.9 .8 1.6-.6 1.1 .2 .4-.6 11.1-.1 .6-2-.4-.3-1.4-12.4-1.3-12.6 4.2-.1 9.4 6.4 9.4 6.4 .6 1.3 1.8 .9 1.2 .4 .1 1.9 3.1-.3 0 6.6-1.6 1.9-.2 1.7-2.5 .5-3.8 .2-1 1.1-1.8 .1-1.7 0-.7-.6-1.6 .4-2.6 1.2-.5 .9-2.1 1.3-.4 .7-1.2 .6-1.3-.4-.8 .7-.4 1.9-2.2 2.4 .1 .9-.8 1.2 .2 1.6-1.2 .4-.6 .4-.4-1.2-.8 .3-.5 0-.5 .8-2.2 0-.7-.5-.4 .3-.9-.8 .2-.9-.4-.3-.5 .3 .1-.9 .5-.7-1.1-1.2-.3-.8-.7-.6-.5-.1-.7 .4-.9 .4-.7 .6-1.2-.2-.8-.8-.5 0-.7 .3-.4 0z', + }, + MM: { + name: 'Myanmar', + path: 'M778.1 258.5l-1.6 .7-1.6 1.3-2 .1-1.2 3.1-1.2 .5 1.3 2.5 1.8 2.1 1.1 1.9-1 2.5-.9 .5 .6 1.4 1.9 2.3 .3 1.6-.1 1.3 1.1 2.6-1.5 2.6-1.3 2.9-.3-2.1 .8-2.2-.9-1.6 .2-3.1-1.1-1.5-.9-3.4-.5-3.6-1.2-2.3-1.8 1.4-3.2 2-1.5-.2-1.8-.7 1-3.5-.6-2.7-2.2-3.3 .4-1.1-1.6-.3-2-2.4-.2-2.3 1 .4 0-2.1 1.4-.7-.3-1.2 .6-1 .1-3 2.2 .6 1.2-2.4 .2-1.4 1.5-2.5-.1-1.7 3.6-2.1 2 .5-.2-1.8 1-.5-.2-1.2 1.6-.2 .9 1.8 1.2 .7 .1 2.3-.1 2.4-2.6 2.5-.4 3.5 3-.5 .6 2.7 1.8 .6-.8 2.4 2 1.1 1.2 .5 2.1-.8 .1 1.2-2.4 1.9z', + }, + MN: { + name: 'Mongolia', + path: 'M743.8 166.8l2.9-.6 5.3-3.1 4.2-1.8 2.4 1.2 2.9 0 1.9 1.7 2.8 .1 4 1 2.7-2.6-1.2-2.1 2.9-3.9 3.1 1.6 2.5 .4 3.3 1 .5 2.7 4 1.5 2.6-.6 3.5-.5 2.8 .5 2.7 1.7 1.7 1.9 2.6-.1 3.5 .6 2.5-.9 3.7-.6 4.1-2.5 1.6 .4 1.5 1.2 3.3-.3-1.3 2.7-2 3.6 .7 1.4 1.6-.4 2.7 .5 2.2-1.3 2.2 1.1 2.5 2.5-.3 1.2-2.2-.4-4 .5-2 1-2 2.3-4.3 1.3-2.7 1.9-2.9-.7-1.5-.4-1.5 2.3 .9 1.3 .4 1.1-1.9 1.1-2 1.8-3.2 1.2-4.2 .1-4.5 1.2-3.2 1.8-1.3-1-3.3 0-4.1-2.1-2.8-.5-3.7 .5-5.7-.8-3.1 .1-1.6-2-1.3-3.1-1.7-.4-3.3-2.1-3.8-.5-3.3-.6-1-1.5 1.1-4.1-1.9-2.8-4-1.3-2.3-1.9z', + }, + MR: { name: 'Mauritania', path: 'M452.6 256.9l.6-1 10.9 0-.5-4.2 .6-1.5 2.6-.3 0-7.5 9.1 .1 0-4.5 10.4 7.2-4.2 .1 1.3 12.6 1.4 12.4 .4 .3-.6 2-11.1 .1-.4 .6-1.1-.2-1.6 .6-1.9-.8-.9 .1-.5 1.6-.9 .6-1.8-2-1.7-2.1-1.9-.7-1.3-.9-1.5 0-1.4 .7-1.4-.3-.9 .9-.3-1.5 .8-1.4 .3-2.7-.3-2.8-.3-1.5 .3-1.4-.7-1.4z' }, + MW: { name: 'Malawi', path: 'M591 341.8l2.7 .5 .6 .7 .9 1.4 .8 3.8-.8 2.1 .8 3.7 1-.1 1 1 1.1 2 .3 3.7-1.2 .6-.9 1.9-1.8-1.7-.2-2 .6-1.3-.2-1.2-1.1-.7-.7 .3-1.6-1.4-1.5-.7 .8-2.7 .9-.9-.5-2.4 .5-2.3 .5-.7-.7-2.4z' }, + MX: { + name: 'Mexico', + path: 'M174.6 222.4l3.2-.3 3.5-.3-.2 .6 4.2 1.5 6.3 2.2 5.5 0 2.2 0 0-1.3 4.8 0 1.1 1.1 1.4 .9 1.6 1.4 1 1.6 .6 1.7 1.5 .9 2.3 .9 1.7-2.4 2.3-.1 2 1.2 1.4 2.1 .9 1.8 1.7 1.7 .6 2.1 .7 1.4 2.2 .9 2 .7 1.1-.1-1.1 2.6-.5 2.1-.2 3.9-.3 1.4 .5 1.6 .9 1.5 .5 2.2 1.9 2.2 .6 1.6 1.1 1.4 3 .8 1.1 1.2 2.4-.8 2.2-.3 2-.5 1.8-.5 1.8-1.2 .6-1.7 .2-2.4 .5-.8 1.9-.8 2.9-.7 2.5 .1 1.7-.2 .7 .6-.1 1.4-1.5 1.7-.7 1.8 .5 .5-.4 1.2-.7 2.3-.7-.8-.6 .1-.5 0-1 1.7-.5-.3-.3 .1 0 .5-2.6-.1-2.6 0 0 1.6-1.2 0 1 1 1 .7 .3 .6 .5 .2-.1 .9-3.6 0-1.3 2.3 .4 .6-.3 .6-.1 .9-3.1-3.1-1.5-.9-2.2-.8-1.6 .3-2.2 1-1.4 .3-2-.7-2.1-.6-2.6-1.3-2-.4-3.2-1.3-2.3-1.4-.7-.8-1.6-.1-2.8-.9-1.2-1.3-2.9-1.7-1.4-1.8-.7-1.4 .9-.3-.3-.8 .7-.8 0-1-.9-1.3-.3-1.1-.9-1.5-2.5-2.9-2.8-2.3-1.3-1.9-2.4-1.2-.5-.7 .4-1.8-1.4-.7-1.6-1.5-.7-2.1-1.5-.2-1.6-1.6-1.3-1.5-.2-.9-1.5-2.3-.9-2.3 0-1.2-2-1.2-.9 .1-1.6-.8-.5 1.2 .5 1.5 .3 2.3 .9 1.2 2.1 2.1 .4 .7 .5 .2 .3 1.1 .5-.1 .6 2 .8 .7 .6 1.1 1.8 1.5 .9 2.8 .8 1.3 .8 1.4 .1 1.5 1.4 .1 1.1 1.3 1 1.4-.1 .5-1.2 1.1-.4-.1-.8-1.7-1.8-1.7-2-1.4-1.4-.8 .1-2.2-.4-1.6-1.4-.9-1.9-1.3-.3 .4-.7-.8-1.8-.7-1.6-1.8 .2-.2 1.1 .2 1.1-1.1 .1-1.4-2.2-2.2-1.6-.8-1-1.9-1-2-1.3-2.4z', + }, + MY: { + name: 'Malaysia', + path: 'M778 298.1l.5-.5 2.3 1.2 .2 1.4 1.8-.3 .9-1.2 .7 .3 1.6 1.7 1.2 1.8 .1 1.9-.3 1.3 .3 .9 .2 1.7 1 .7 1.1 2.5-.1 .9-1.9 .2-2.7-2-3.3-2.2-.3-1.4-1.6-1.9-.4-2.3-1-1.5 .3-2.1zM827.5 304.5l-2.5-.4-3.2 0-.9 3.1-1.1 1-1.4 3.9-2.3 .6-2.6-.8-1.3 .2-1.7 1.4-1.7-.2-1.8 .6-1.9-1.6-.5-1.8 2.1 .9 2.1-.5 .6-2.4 1.1-.5 3.4-.6 2-2.2 1.3-1.7 1.3 1.4 .6-.9 1.3 0 .2-1.7 .1-1.4 2.1-1.9 1.4-2.2 1.2 0 1.4 1.4 .1 1.2 1.8 .8 2.4 .8-.2 1.1-1.9 .1 .5 1.4z', + }, + MZ: { + name: 'Mozambique', + path: 'M596 348.2l2.1-.3 3.3 .8 .8-.3 1.9-.1 1-.8 1.6 0 3.1-1.1 2.2-1.6 .4 1.3-.1 2.8 .4 2.4 .1 4.4 .5 1.4-.9 2.1-1 1.9-1.8 1.8-2.5 1.1-3.2 1.4-3.1 3.1-1.1 .5-1.9 2-1.2 .7-.2 2.1 1.3 2.2 .6 1.7 0 .8 .5-.1-.1 2.9-.4 1.3 .6 .5-.4 1.2-1.2 1.1-2.3 1-3.3 1.6-1.2 1.1 .2 1.2 .7 .2-.2 1.6-2.1 0-.3-1.3-.4-1.4-.2-1 .5-3.3-.7-2.1-1.4-4.1 3-3.3 .7-2.1 .4-.3 .3-1.7-.4-.8 .1-2.2 .5-2 0-3.6-1.4-.9-1.3-.2-.6-.7-1.3-.6-2.3 0-.2-1-.3-2.1 8.5-2.3 1.6 1.4 .7-.3 1.1 .7 .2 1.2-.6 1.3 .2 2 1.8 1.7 .9-1.9 1.2-.6-.3-3.7-1.1-2-1-1-1 .1-.8-3.7z', + }, + NA: { + name: 'Namibia', + path: 'M555.3 386.3l0 11-2.5 1.5-1.5 .2-1.8-.5-1.2-.3-.5-1.3-1.1-.8-1.3 1.5-2.1-2.3-1-2.1-.7-2.9-.6-2.2-1-4.5 0-3.5-.4-1.6-1.1-1.2-1.4-2.4-1.5-3.5-.6-1.8-2.2-2.8-.2-2.2 1.3-.6 1.7-.5 1.8 .1 1.7 1.3 .4-.2 11.2-.1 2 1.4 6.7 .4 5.1-1.2 2.3-.6 1.8 .1 1.1 .7 0 .2-1.6 .6-.8 .1-1.8 1.1-1.1-1.2-4.2 1-2.1 .1-.1 10.3-2.7 .1z', + }, + NC: { name: 'New Caledonia', path: 'M960.5 375.5l2.3 1.8 1.4 1.3-1 .7-1.6-.8-1.9-1.3-1.8-1.5-1.9-2.1-.4-1 1.2 .1 1.6 1 1.2 .9z' }, + NE: { + name: 'Niger', + path: 'M541.3 251.4l.6 4.6 1.1 .7 0 .9 1.2 1-.6 1.3-1.1 5.8-.1 3.7-3.6 2.7-1.2 3.8 1.2 1 0 1.8 1.7 .1-.2 1.3-.8 .2-.1 .9-.5 0-1.9-3-.7-.2-2.1 1.6-2.2-.8-1.5-.2-.8 .4-1.6-.1-1.6 1.2-1.5 .1-3.3-1.4-1.3 .7-1.5-.1-1-1.1-2.8-1-3 .3-.7 .6-.4 1.7-.8 1.1-.2 2.5-2.1-1.6-1 0-.9 .8 0-1.9-3.2-.7 0-1.3-1.6-1.9-.4-1.3 .2-1.3 1.8-.1 1-1.1 3.8-.2 2.5-.5 .2-1.7 1.6-1.9 0-6.6 3.9-1.3 8-5.7 9.5-5.6 4.4 1.3 1.6 1.6z', + }, + NG: { + name: 'Nigeria', + path: 'M507.5 298.6l.1-4.5 0-1.7 .5-1.8 .8-.9 1.4-1.7-.3-.8 .5-1.1-.6-1.7 .1-.9 .2-2.5 .8-1.1 .4-1.7 .7-.6 3-.3 2.8 1 1 1.1 1.5 .1 1.3-.7 3.3 1.4 1.5-.1 1.6-1.2 1.6 .1 .8-.4 1.5 .2 2.2 .8 2.1-1.6 .7 .2 1.9 3 .5 0 1.1 1.1-.3 .5-.2 1-2.3 2.1-.7 1.8-.4 1.5-.6 .6-.6 2-1.5 1.1-.4 1.4-.6 1.2-.3 1.1-1.9 1-1.5-1.2-1.1 .1-1.6 1.6-.9 0-1.3 2.7-.7 2-2.9 1-1-.2-1.1 .7-2.2-.1-1.5-1.7-.9-2.1-2-1.8-2.1 0z', + }, + NI: { + name: 'Nicaragua', + path: 'M267.6 285.5l-.6 .6-.9-.2-.4-.5-.9-.3-.6 .4-1.9-.7-.4 .3-1-.9-1.2-1.1-.7-1-1.1-.8-1.4-1.3 .3-.5 .4 .5 .3-.2 .8-.1 .4-.7 .4 0-.1-1.4 .7-.1 .5 0 .6-.7 .9 .6 .2-.4 .6-.3 .9-.8 .1-.6 .2 0 .4-.6 .3-.1 .5 .4 .5 .1 .6-.3 .7 0 1-.4 .4-.4 .9 .1-.2 .2-.1 .7 .2 1-.6 1-.3 1.1-.1 1.3 .2 .7 0 1.3-.4 .2-.3 1.2 .2 .8-.5 .7 .1 .8z', + }, + NL: { name: 'Netherlands', path: 'M519.2 151.4l.5 1.2-.7 3.5-.7 1.4-1.7 0 .5 3.8-1.5-.8-1.8-1.6-2.6 .7-2-.3 1.4-1 2.5-5.5 3.8-1.5z' }, + NO: { + name: 'Norway', + path: 'M542.1 26.5l1-2.2 4.1-.2 3.5 2.2 9.1 4.6-6.9 2.4-1.6 4.5-2.4 1.1-1.3 4.9-3.4 .2-6-3.6 2.5-2.1-4.1-1.7-5.4-5.1-2.2-4.9 7.6-2.3 1.5 2.2zM586.4 82.5l-4.7 1.9-2.3 .5 1.2-3.5-3.6-1.9-4.3 1.6-1.3 3.6-2.7 2.2-3-1.2-3.6 .3-3.1-2.6-1.7 1.3-1.7 .2-.4 3.2-5.2-.8-.8 2.7-2.6-.1-1.9 3.4-2.7 5.2-4.3 6.4 1 1.5-1 1.8-2.8-.1-1.8 4.1 .2 5.8 1.8 2.1-.9 5-2.3 2.8-1.3 2.4-1.8-2.6-5.5 4.8-3.7 .9-3.9-2-1-4.4-.8-9.8 2.5-2.7 7.4-3.7 5.4-4.6 5.1-6.3 6.7-9 4.7-3.6 7.6-6.1 6.1-2.2 4.6 .3 4.2-4.2 5.1 .2 4.9-1 8.7 3.7-3.6 1.4zM576.1 24l-4.1 3.4-8 .8-8.2-1.1-.5-1.7-4-.1-3.1-2.9 8.6-1.8 4.1 1.5 2.8-1.9 7 1.6zM568.7 37.6l-6.2 2.4-4.9-1.3 1.9-1.6-1.7-1.9 5.8-1.2 1.1 2.3z', + }, + NP: { name: 'Nepal', path: 'M744.8 236.6l-.2 1.3 .3 1.9-.3 1.1-2.3 .1-3.3-.7-2.2-.3-1.6-1.5-3.8-.4-3.6-1.7-2.6-1.5-2.7-1.1 1-2.8 1.8-1.4 1.2-.7 2.2 .9 2.8 2 1.6 .4 .9 1.5 2.1 .6 2.3 1.3 3.1 .7z' }, + NZ: { + name: 'New Zealand', + path: 'M991.3 433.6l-1 1.8-1.4 2.3-2.1 1.3-.5-.9-1.2-.5 1.6-2.7-.9-1.8-3-1.3 .1-1.2 2-1.1 .5-2.5-.1-2.1-1.2-2.1 .1-.6-1.3-1.3-2.2-2.8-1.2-2.2 1.1-.2 1.5 1.7 2.1 .8 .8 2.8 2 3.4 .1-2.2 1.3 .9 .4 2.4 2.2 1 1.9 .3 1.6-1.2 1.4 .3-.7 2.9-.8 1.9-2.2-.1-.7 1 .3 1.4zM971.3 445.3l2.4-1.8 1.6-1.8 1.3-2.4 1-.9 .4-1.8 2-1.6 .6 1.4 .6 1.4 2-1.3 .8 1.4 0 1.4-1 1.5-1.8 2.5-1.4 1.3 1 1.7-2.2 0-2.3 1.3-.8 2.2-1.6 3.5-2.1 1.6-1.4 1-2.6-.1-1.8-1.2-3-.2-.5-1.3 1.5-2.5 3.5-3.4 1.8-.7z', + }, + OM: { + name: 'Oman', + path: 'M653.4 251.9l0-1.2 .8-1.2 0-1.2 1.3-.6-.5-.4 .2-1.9 1.5 0 1.2 2 1.6 1 2 .4 1.6 .6 1.3 1.6 .7 1 1 .4 0 .6-1 1.8-.4 .8-1.2 .9-1 2-1.3-.1-.6 .6-.4 1.5 .3 1.9-.2 .4-1.3 0-1.8 1.1-.2 1.4-.7 .6-1.7-.1-1.1 .8 0 1.1-1.3 .8-1.5-.3-1.9 1-1.3 .2-.9-2-2.2-4.8 8.4-2.9 1.8-5.8zM656.3 243l-.5-1 .8-1 .3 .3-.3 1.2z', + }, + PA: { + name: 'Panama', + path: 'M285.1 291.9l-.3 .4 .6 1.7-.5 .8-.9-.2-.3 1.3-1-.8-.6-1.5 .7-.7-.7-.2-.5-.9-1.4-.8-1.2 .2-.6 .9-1.1 .7-.6 .1-.3 .6 1.4 1.5-.8 .4-.4 .4-1.3 .1-.5-1.6-.3 .5-.9-.2-.6-1.1-1.1-.2-.8-.3-1.2 0 0 .6-.4-.5 .2-.5 .2-.6-.1-.5 .4-.3-.6-.4 0-1.2 1.1-.2 1 1-.1 .6 1.2 .1 .2-.2 .8 .7 1.3-.2 1.2-.7 1.7-.6 1-.8 1.5 .1-.1 .3 1.5 .1 1.3 .5 .9 .8z', + }, + PE: { + name: 'Peru', + path: 'M305.9 328l-2.6-.1-.3 .4-2.3 .5-3.2 1.9-.2 1.3-.7 1 .3 1.5-1.7 .8 0 1.2-.7 .5 1.1 2.5 1.6 1.7-.6 1.2 1.8 .2 1.1 1.5 2.4 0 2.3-1.6-.2 4.2 1.3 .4 1.6-.5 2.4 4.5-.6 1-.2 2 0 2.4-1.1 1.4 .5 1-.6 1 1.1 2.4-1.7 3.1-.8 1.4-1.4 .8-2.8-1.7-.2-1.2-5.5-2.8-5-3.1-2.1-1.8-1.2-2.3 .5-.8-2.4-3.7-2.7-5.2-2.6-5.6-1.2-1.3-.9-2-2.1-1.9-2-1.1 .9-1.2-1.3-2.7 .8-1.9 2.2-1.8 .4 1.2-.8 .6 0 1 1.2-.2 1.1 .3 1.2 1.4 1.6-1.1 .5-1.9 1.7-2.4 3.3-1.1 3.1-2.9 .8-1.8-.4-2.1 .8-.3 1.8 1.3 .9 1.3 1.3 .7 1.6 3 2.1 .3 1.5-.7 1 .4 1.7-.2 2.1 1.3-1.8 2.8 .9 .1z', + }, + PG: { + name: 'Papua New Guinea', + path: 'M891.7 323.3l4.8 1.9 5.1 1.6 1.9 1.4 1.6 1.4 .4 1.6 4.6 1.8 .7 1.4-2.5 .3 .6 1.9 2.4 1.8 1.9 3 1.5-.1-.1 1.2 2.2 .5-.9 .6 3 1.1-.3 .8-1.9 .2-.6-.7-2.4-.3-2.8-.4-2.2-1.8-1.6-1.6-1.4-2.4-3.6-1.2-2.4 .8-1.7 .9 .4 2.1-2.2 .9-1.6-.4-2.8-.2-.1-9.1zM924 326.2l1.1 .9 .3 1.4-.9 .8-.5-1.7-.6-1-1.3-.9-1.6-1.2-2-.8 .8-.7 1.5 .8 .9 .6 1.2 .6zM920.3 332.3l-1.5 .7-1.5 .6-1.4 0-2.3-.8-1.6-.8 .2-.8 2.5 .4 1.5-.3 .5-1.3 .4-.1 .2 1.5 1.6-.2 .8-.9 1.5-1-.3-1.7 1.7 0 .6 .4-.1 1.6-.9 1.7-1.5 .2zM929.9 330.9l.8 .6 1.4 1.8 1.3 .9-.4 .8-.8 .3-1.2-1.1-1.2-1.8-.6-2.1 .4-.2z', + }, + PH: { + name: 'Philippines', + path: 'M835.6 280.6l-1.4-2.2 2.4 .1 1 1-.8 2.5zM840.5 288.2l.7-.8 .3-1.7 1.6-.2-.5 1.9 2.1-2.7-.3 2.7-1 .9-.9 1.8-.8 .8-1.8-1.9zM851 292.6l.3 1.9 .2 1.5-1 2.6-1-2.9-1.3 1.5 .9 2-.8 1.3-3.2-1.6-.8-2 .8-1.3-1.7-1.4-.9 1.2-1.3-.1-2.1 1.5-.4-.8 1.1-2.3 1.7-.8 1.5-1.1 1 1.3 2.1-.8 .5-1.2 1.9-.1-.1-2.2 2.2 1.4 .3 1.4zM829.2 290.1l-3.7 2.6 1.3-1.9 2.1-1.7 1.6-2 1.5-2.8 .5 2.3-1.9 1.6zM839.8 264.9l-.4 1.1 .9 2.1-.7 2.4-1.6 .9-.5 2.3 .6 2.3 1.5 .3 1.2-.4 3.5 1.6-.3 1.6 .9 .6-.2 1.3-2.2-1.4-1-1.4-.7 1-1.8-1.7-2.5 .4-1.4-.6 .1-1.2 .9-.7-.8-.6-.4 1-1.4-1.7-.4-1.2-.1-2.7 1.1 .9 .3-4.4 .9-2.6 1.7 0 1.7 .8 .9-.8zM839 284.2l-.4-1.3 1.6 .8 1.8 0-.1 1.2-1.2 1.2-1.8 .8-.1-1.3zM848.6 282.1l.8 3.1-2.1-.7 0 .9 .7 1.8-1.3 .6-.1-2-.9-.1-.4-1.7 1.6 .2 0-1.1-1.7-2.1 2.7 0z', + }, + PK: { + name: 'Pakistan', + path: 'M716.2 213.1l-2.7 2.7-3.1 .5-4.2-.8-1.3 1.3 .9 2.8 1 2.1 2.3 1.5-2.4 1.8 0 2.2-2.7 3-1.7 3.1-2.9 3.2-3.2-.3-3.1 3.2 1.8 1.3 .3 2.3 1.6 1.5 .5 2.5-6.1 0-1.8 2-2.1-.7-.8-2.2-2.1-2.2-5.1 .5-4.6 .1-3.9 .4 1.1-3.4 4-1.6-.3-1.4-1.3-.4-.1-2.7-2.6-1.3-1.1-1.8-1.4-1.6 4.6 1.5 2.8-.4 1.7 .4 .6-.7 1.9 .3 3.6-1.3 .1-2.6 1.5-1.7 2.1 0 .3-.9 2.1-.4 1.1 .3 1-.9-.1-1.8 1.2-1.9 1.7-.8-1-2 2.6 .1 .8-1.2-.2-1.2 1.4-1.3-.3-1.6-.6-1.3 1.6-1.4 3-.6 3.1-.4 1.5-.6 1.6-.4 2 1.5 .8 2.5z', + }, + PL: { + name: 'Poland', + path: 'M565.2 149.7l.2 1.7 .7 1.4 0 1.5-1.7 .8 .9 1.7 .1 1.7 1.3 3.2-.2 1-1.4 .4-2.5 3.1 .7 1.6-.6-.2-2.7-1.4-2 .5-1.3-.4-1.6 .8-1.4-1.3-1.2 .5-.1-.2-1.3-1.8-2.1-.2-.2-1.2-1.9-.4-.5 1-1.5-.8 .2-1-2.1-.3-1.3-1.2-1.1-2.3 .2-1.3-.7-2-1-1.3 .8-1.1-.7-1.9 1.9-1.1 4.4-1.8 3.5-1.3 2.7 .7 .2 .9 2.7 .1 3.4 .4 5.1-.1 1.5 .5z', + }, + PR: { name: 'Puerto Rico', path: 'M315.9 264l1.4 .3 .5 .5-.7 .8-2.1 0-1.6 .1-.2-1.3 .4-.4z' }, + PS: { name: 'Palestine', path: 'M598.3 225.6l-1.3 .4 .1-.8 .7-.4-.6-.4 .5-2 1 .4 0 1.9z' }, + PT: { name: 'Portugal', path: 'M474.9 192.4l1-.8 1.1-.5 .7 1.6 1.7 0 .5-.4 1.6 .1 .8 1.7-1.3 .9-.1 2.6-.4 .5-.1 1.5-1.2 .3 1.1 1.9-.8 2.1 1 1-.4 .9-1 1.2 .2 1-1.1 .9-1.5-.5-1.4 .4 .4-2.5-.3-2-1.2-.3-.7-1.2 .3-2.2 1.1-1.1 .2-1.4 .5-1.9 0-1.4-.6-1.2z' }, + PY: { name: 'Paraguay', path: 'M338.4 372.8l.8 1.7-.1 3.9 2.9 .6 1.1-.6 1.9 .8 .5 .8 .3 2.7 .3 1.2 1 .1 1.1-.5 1 .6 0 1.6-.4 1.7-.5 1.7-.5 2.7-2.5 2.2-2.2 .5-3.1-.4-2.8-.8 2.7-4.6-.4-1.3-2.9-1.1-3.3-2.2-2.3-.5-5.1-4.7 1.1-3.5 0-1.6 1.4-2.5 4.8-.9 2.6 .1 2.6 1.5z' }, + QA: { name: 'Qatar', path: 'M641.1 245.9l-.1-2.2 .7-1.5 .8-.4 .8 1 .1 1.7-.7 1.7-.7 .2z' }, + RO: { + name: 'Romania', + path: 'M578.4 180.2l1.3 .7 1.3-.6 1.2 .6 .1 .9-1.4 .7-.8-.3-.8 4.1-1.6-.4-2-1.2-3.3 .8-1.4 .9-4.1-.2-2.1-.5-1.1 .2-.8-1.4-.5-.6 .7-.6-.7-.4-.9 .8-1.6-1-.2-1.4-1.7-.8-.3-1.1-1.5-1.4 2.2-.7 1.7-2.3 1.3-2.4 1.7-.8 1.2-.7 1.7 .4 1.8 0 1.3 .9 .9-.6 2.1-.3 .7-.9 1.1 0 .9 .4 .8 1 .9 1.5 1.6 2.1 .1 1.6-.3 1.4z', + }, + RS: { + name: 'Serbia', + path: 'M552.3 178.8l2.1-1 1.8 .2 1.5 1.4 .3 1.1 1.7 .8 .2 1.4 1.6 1 .9-.8 .7 .4-.7 .6 .5 .6-.6 .8 .2 1.2 1.4 1.5-1.1 1-.5 1.1 .3 .4-.4 .5-1.3 0-1 .2-.1-.2 .4-.4 .3-.8-.4 0-.5-.6-.5-.2-.4-.5-.5-.2-.4-.5-.5 .2-.4 1.1-.6 .2 .2-.3-1.1-.7-.9-.3-.4-.5-.7-.6 .6-.1 .4-1.6-1.3-1.3 .7-1.5-1 0 1.1-1.3-.9-1z', + }, + RU: { + name: 'Russian Federation', + path: 'M996.5 74.8l3.5-2.2 0 3.5-3 .3zM636.4 177.1l-1.3 2-2.7 .6-2.7 3.5 2.5 3.3-.3 2.2 3.1 4-1.7 1.3-.5 .9-1.2-.3-1.9-2-.8-.1-1.7-.8-.9-1.3-2.6-.7-1.7 .5-.5-.6-3.7-1.6-4.1-.6-2.4-.6-.3 .4-3.6-2.8-3.1-1.3-2.4-2 2-.6 2.3-2.9-1.6-1.4 4.1-1.4 0-.8-2.5 .6 .1-1.6 1.4-1 2.7-.2 .4-1.2-.6-2 1.1-1.8 0-1.1-4.1-1.2-1.6 .1-1.7-1.7-2.2 .5-3.5-1.2 .1-.8-1-1.5-2.2-.2-.3-1.2 .7-.7-1.7-2.1-2.9 .3-.9-.2-.7 .9-1-.2-.7-2.3-.6-1.3 .5-.3 2.2 .1 1.1-.8-.8-1-1.9-.7 .2-.7-1.1-.7-1.8-2.5 .6-1.1-.2-1.8-2.8-.9-1.4 .5-.4-1-2.9-1-.9-2.3-.3-1.9-1.3-1 1.2-1.2-.8-3.8 1.9-2.4-.4-.7 3.2-2.3-2.9-1.9 5.9-5.4 2.6-2.5 1-2.2-4.1-3 1.2-2.9-2.5-3.3 1.8-3.9-3.2-5.3 2.6-3.5-4.3-3.2 .4-3.4 2.3-.5 4.7-1.9 2.9-1.8 4.5 3 7.6 1.2 10.5 5.4 2.2 2.3 .1 3.1-3 2.5-4.6 1.2-12.4-3.5-2 .6 4.5 3.3 .2 2.2 .2 4.6 3.5 1.3 2.2 1.2 .4-2.2-1.7-1.9 1.8-1.7 6.7 2.8 2.3-1.1-1.8-3.3 6.4-4.5 2.6 .2 2.6 1.7 1.6-3.2-2.3-2.8 1.3-2.8-2-3 7.8 1.5 1.6 2.7-3.6 .6 .1 2.6 2.1 1.6 4.3-1 .7-3 5.8-2.3 9.7-4.1 2.1 .2-2.7 3 3.4 .5 2-1.7 5.2-.1 4.1-2 3.2 2.9 3.2-3.2-2.9-2.8 1.4-1.7 8.2 1.5 3.8 1.6 10.1 5.5 1.9-2.5-2.9-2.6 0-1-3.4-.5 .9-2.4-1.5-3.9 0-1.6 5.1-4.6 1.8-4.8 2.1-1 7.3 1.4 .6 2.9-2.6 4.2 1.7 1.6 .9 3.5-.6 6.8 3 3-1.2 3.2-5.4 6.6 3.2 .7 1.1-1.7 3-1.2 .8-2.3 2.4-2.2-1.6-2.8 1.3-3.2-3.1-.4-.7-2.7 2.3-5-3.6-4.1 4.9-3.5-.6-3.7 1.4-.1 1.4 2.9-1.1 5 3 .9-1.3-3.7 4.7-2.1 5.8-.2 5.1 2.9-2.5-4.3-.3-5.7 4.9-1.1 6.7 .3 6-.7-2.3-2.9 3.2-3.6 3.2-.2 5.4-2.7 7.4-.8 .9-1.6 7.3-.5 2.3 1.3 6.2-3 5.1 .1 .8-2.5 2.6-2.5 6.6-2.5 4.7 2-3.8 1.4 6.3 .9 .8 2.9 2.5-1.4 8.1 0 6.3 2.8 2.2 2.2-.7 2.9-3 1.7-7.3 3-2.1 1.6 3.4 .8 4.1 1.4 2.5-1 1.5 3.4 1.2-1.4 4.4-.8 8.9 .9 .7 2.5 11.6 .7 .2-4 5.9 .9 4.4 0 4.5 2.8 1.3 3.4-1.7 2.1 3.5 4.1 4.4 2 2.7-5.3 4.4 2.3 4.8-1.4 5.3 1.6 2.1-1.4 4.5 .7-2-4.8 3.7-2.3 25.1 3.4 2.3 3.1 7.3 3.9 11.2-1 5.6 .8 2.3 2.1-.4 3.7 3.5 1.4 3.7-1 4.9-.2 5.2 1 5.3-.6 4.8 4.4 3.5-1.6-2.3-3.1 1.3-2.2 8.8 1.4 5.8-.3 8 2.3 3.9 2.2 0 18.6-3.6 2-3.6-.3 2.5 2.4 1.7 3.6 1.3 1.2 .3 1.8-.7 1.1-5.2-.9-7.8 3.2-2.5 .5-4.2 3-4 2.6-1.1 1.8-3.9-2.8-7.3 3.2-1.2-1.5-2.7 1.8-3.7-.6-.9 2.7-3.4 4 .1 1.6 3.2 .9-.4 5.8-2.5 .1-1.2 3.3 1.1 1.6-4.8 2-1 4.3-4.1 .9-.9 3.8-4 3.5-1-2.6-1.2-5.4-1.5-8.5 1.3-5.4 2.3-2.4 .2-1.9 4.3-.9 5-5.1 4.7-4.3 5-3.3 2.3-6-3.4 .3-1.7 3.5-7 4.7-2.3-5.2-7.2 1.4-6.9 7.1 2.3 2.5-6.2 1.1-4.3 .4 .2-3-4.3-.6-3.5 2-8.5-.7-9.1 1.2-9 7.9-10.6 9.2 4.3 .5 1.4 2.4 2.7 .8 1.8-1.9 3 .3 4 4.1 .1 3.2-2.2 3.7-.2 4.4-1.2 5.7-4.2 5.2-1 2.4-3.7 4-3.8 3.9-1.8 2.1-3.7 1.9-1.7 .1-1.8-1.7-3.7 2.5-.4 1.1-.4-.6 0-1.7 1.4-.1 .4-4-.7-2.9 2.3-1.2 3.4 .6 1.9-3.4 .9-3.8 1.1-1.3 1.5-3.2-4.6 1.1-2.4 1.4-4.2 0-1.2-3.4-3.3-2.5-4.8-1.2-1-3.5-1-2.3-1-1.6-1.7-3.7-2.5-1.4-4.1-1.1-3.7 .1-3.5 .6-2.3 1.9 1.5 .9 .1 2.1-1.6 1.1-2.5 3.9 .1 1.6-4 2.3-3.3-1.3-3.3 .3-1.5-1.2-1.6-.4-4.1 2.5-3.7 .6-2.5 .9-3.5-.6-2.6 .1-1.7-1.9-2.7-1.7-2.8-.5-3.5 .5-2.6 .6-4-1.5-.5-2.7-3.3-1-2.5-.4-3.1-1.6-2.9 3.9 1.2 2.1-2.7 2.6-4-1-2.8-.1-1.9-1.7-2.9 0-2.4-1.2-4.2 1.8-5.3 3.1-2.9 .6-1.1 .3-1.5-2.2-3.6 .5-1.2-1.6-1.9-.7-1.3-2.1-1.6-.6-4 .9-3.8-2.1-1.5 1.9-6.2-9.4-3.5-3 1-1.2-7 3.6-2.6 .2 .2-2-3.6-1.3-2.9 .9-.9-4-4.9-.8-2.5 1.6-7 1.4-1.3 .9-10.4 1.4-1.3 1.3 2 2.6-2.7 .9 .5 1.1-2.6 1.8 4.5 2.5-.7 1.8-3.9-.2-.8 1.1-3.6-1.9-4.4 .1-2.9 1.5-3.3-1.5-6.1-2.5-4.4 .1-5.7 4-.4 2.6-2.8-2.1-2.2 4 .8 .7-1.6 2.7 2.3 2.4 2.1-.1 1.8 2.4-.3 1.8zM760.5 17.8l6-1.5 5.4 3.3 6.4 6.2-.7 5.6-6.1 .8-7.7-1.8-4.6-2.4-2.1-4.5-3.8-1.3zM785.7 28.9l7 3.5-.8 2.5-15.7 2.3 5.1-8 2.3-.7zM885.6 47.6l7.4 .3 10 3-2.2 4.1-10.2-.1-4.6 1.3-5.5-3.6 1.5-3.9zM911.7 52.1l7 1.5-3.2 2.2-4.5-.5-5.1-2.2 .7-1.8zM888.5 62.9l2.6-2.1 3.5-.5 4 2.1 .3 1.4-4.2 0-5.7-.6zM624.6 20.6l5.4-1.1 4.2-.1 .6 1.7 1.6-1.5 2.6-1.1 4.1 1.4-1.1 1-3.7 .9-2.5 .4-.4 1.1-3.2 1-3-1.5 1.6-2zM563.1 148.1l-5.1 .1-3.4-.4 .6-1.7 3.9-1.3 2.9 .7 1.2 .6-.3 1.1zM648.6 60.9l6.7-4.8-.8-2.5 6.2-3 9.2-3.6 9.3-1.1 4.7-2.1 5.4-.8 2 2.3-1.9 1.8-9.9 2.8-8.4 2.7-8.7 5.2-4.1 5.3-4.4 5.1 .6 4.3 5.3 4.2-1.6 .4-9.1-.6-.7-2.3-5.1-1.4-.4-2.7 2.9-1.2-.1-2.8 5.5-4.6zM897 150.5l.9 3.7 0 3.6 1.1 3.7 2.8 6.5-4.1-1.2-1.7 5.1 2.7 3.6-.1 2.5-2.1-2.1-1.8 2.7-.5-3 .3-3.4-.3-3.8 .6-2.7 .1-4.9-1.6-3.6 .3-5.2 2.5-1.7-1.1-1.8 1.3-.5zM14.1 93.8l-.3 2.9 1.9 1.1-.6-3.3 7.5 .6 5.5 4.4-2.8 2-4.6 .4 0 4.5-1.1 .9-2.6-.2-2.1-1.5-3.7-1.3-.7-2-2.8-.7-3.1 .6-1.6-1.6 .6-1.7-3.3 1.1 1.3 2.1-1.6 1.9 0-18.6 6.8 3.7zM3.6 75.8l-3.6 .3 0-3.5 .4-.2 2.3 0 4 1.5-.2 .7zM592.9 178.5l.7-.8 2 .7 .9 .2 .3 .6 .5 .2 0 .3 1.3 .8 2.9-.2-.6 1.2-3 .6-3.8 2-1.5-.7 .6-1.6-3-1 .4-.7 2.7-1.1z', + }, + RW: { name: 'Rwanda', path: 'M584.5 319.2l1.1 1.6-.2 1.6-.8 .3-1.4-.1-.9 1.5-1.7-.2 .3-1.5 .4-.2 .1-1.7 .8-.7 .6 .2z' }, + SA: { + name: 'Saudi Arabia', + path: 'M597.1 232.1l3.1 .5 1.2-.9 .7-1.1 2.1-.5 .4-1 1-.5-2.8-3.1 5.5-1.5 .6-.5 3.3 .9 4.2 2.1 7.8 6.1 5.2 .3 2.4 .3 .7 1.4 2-.1 1.1 2.6 1.3 .7 .5 1.1 1.9 1.2 .2 1.3-.3 .9 .4 1 .8 .9 .3 .9 .4 .8 .9 .5 .7-.2 .6 1.2 .1 .6 1 3 8.4 1.5 .6-.6 1.2 2-1.8 5.8-8.4 2.9-8 1.1-2.6 1.3-1.9 3-1.3 .5-.7-.9-1.1 .1-2.7-.3-.5-.3-3.2 .1-.8 .3-1.1-.8-.7 1.4 .3 1.2-1.3 .9-.3-1.2-.9-.9-.2-1.1-1.4-1-1.5-2.4-.8-2.4-1.9-2-1.2-.4-1.9-2.8-.3-2 .1-1.7-1.6-3.3-1.3-1.1-1.5-.7-.9-1.6 .2-.7-.8-1.5-.8-.7-1.1-2.2-1.7-2.4-1.4-2.1-1.4 0 .4-1.6 .2-1.1z', + }, + SB: { name: 'Solomon Islands', path: 'M950.3 345.3l.8 .9-1.9 0-1.1-1.7 1.7 .7zM949.1 342.8l-.4 .5-2.1-2.4-.5-1.7 .9 0 1 2.2zM946.8 343.6l-1.1 0-1.7-.3-.6-.4 .2-1.1 1.9 .4 .9 .6zM943.4 338.4l.7 .9 .1 .5-2.2-1.2-1.5-1-1-.9 .4-.3 1.3 .7zM936.5 335.6l1.1 .9-.5 .1-1.3-.6-1.1-1.1 .1-.5z' }, + SD: { + name: 'Sudan', + path: 'M568.2 293.1l-2.1-1.2-.9-.8-.2-.9 .4-1.1 0-1.2-1.6-1.7-.3-1.2 0-.7-1-.8 0-1.7-.6-1.1-1 .2 .3-1 .7-1.2-.3-1.2 .9-.9-.5-.6 .7-1.8 1.3-2.1 2.4 .2-.2-11.3 .1-1.3 3.1 0 0-5.8 11.2 0 10.8 0 11 0 .9 2.9-.6 .5 .4 3 1 3.4 1.1 .7 1.5 1.1-1.4 1.6-2.1 .5-.8 .9-.3 1.9-1.2 4.2 .3 1.1-.4 2.4-1.2 2.8-1.7 1.4-1.1 2.2-.3 1.1-1.3 .8-.9 2.9 .1 2.6-.1-2.2-.3-.1 0-1.4-.3-.9-1.5-1.2-.3-2 .3-2.1-1.2-.2-.2 .7-1.7 .1 .7 .8 .2 1.7-1.5 1.6-1.4 2-1.4 .3-2.4-1.6-1 .5-.3 .9-1.4 .5-.1 .6-2.8 0-.4-.6-2-.1-1 .5-.8-.3-1.4-1.6-.5-.8-2 .4-.7 1.3-.7 2.5-1 .5-.8 .3z', + }, + SE: { + name: 'Sweden', + path: 'M530.6 130.3l1.3-2.4 2.3-2.8 .9-5-1.8-2.1-.2-5.8 1.8-4.1 2.8 .1 1-1.8-1-1.5 4.3-6.4 2.7-5.2 1.9-3.4 2.6 .1 .8-2.7 5.2 .8 .4-3.2 1.7-.2 3.8 2.4 4.3 3.2 .1 7.3 .9 1.7-4.8 1.3-2.7 3.2 .5 2.8-4.5 3.5-5.3 3.8-2 6 1.9 3 2.7 2.3-2.6 4.7-2.9 .9-1 6.8-1.6 3.7-3.4-.4-1.5 3.1-3.2 .2-.9-3.7-2.4-4.5z', + }, + SI: { name: 'Slovenia', path: 'M538.4 176.7l2.2 .2 1.4-.7 2.5-.1 .5-.6 .5 0 .5 1.2-2.2 .9-.3 1.4-.9 .4 0 .9-1.1 0-1-.6-.5 .6-1.9-.1 .6-.3-.6-1.5z' }, + SK: { name: 'Slovakia', path: 'M562.7 167.6l-.8 .9-.6 1.4-.5 .4-3-1.1-.9 .2-.7 .9-1.3 .4-.3-.2-1.3 .5-1.1 .1-.3 .8-2.3 .4-1-.4-1.4-.9-.3-1.2 .2-.5 .4-.8 1.2 .1 1-.4 .1-.3 .5-.2 .2-.8 .6-.2 .4-.6 .9 0 .1 .2 1.2-.5 1.4 1.3 1.6-.8 1.3 .4 2-.5z' }, + SL: { name: 'Sierra Leone', path: 'M463.2 291.2l1.5-1.2 .3-.8 .5-.6 .7 0 .7-.6 2.2 0 .8 1 .6 1.2-.1 .8 .4 .8 0 1 .8-.2-1.3 1.3-1.3 1.6-.1 .8-.7 .9-.7-.2-2-1.2-1.5-1.5-.5-1z' }, + SN: { name: 'Senegal', path: 'M453.6 278l-1.2-2.2-1.4-1 1.3-.5 1.3-2 .7-1.5 .9-.9 1.4 .3 1.4-.7 1.5 0 1.3 .9 1.9 .7 1.7 2.1 1.8 2 .1 1.7 .6 1.6 1 .8 .2 1.1-.1 .9-.4 .2-1.5-.3-.2 .3-.6 .1-2-.7-1.4 0-5.1-.1-.7 .3-1-.1-1.4 .5-.5-2.2 2.5 .1 .7-.4 .5-.1 1-.6 1.2 .6 1.2 0 1.2-.6-.5-.8-.9 .5-.9-.1-1.1-.7-.9 .1-.6 .7z' }, + SO: { name: 'Somalia', path: 'M615.5 320.7l-1.6-2.3-.1-10.1 2.5-3.2 .7-.8 1.8-.1 2.5-1.9 3.6-.2 7.8-8.3 2-2.4 1.2-1.7 0-1.5 0-2.8 .1-1.1 0-.1 .9 0 1.2-.5 1.5-.2 1.3-1 1.1 0 0 .8-.2 1.6 0 1.5-.6 1-.8 3-1.3 3.1-1.7 3.6-2.4 4.1-2.4 3.1-3.3 3.8-2.7 2.3-4.2 2.7-2.6 2.1-3 3.4-.7 1.5z' }, + SR: { name: 'Suriname', path: 'M348.5 309.6l-1.5-.6-1.4 .3-1.1-.2-.3 .8 .5 .5-.2 .6-1.6-.2-1.7-2.5-.3-1.5-.9 0-1.2-2 .5-1.5-.2-.6 1.7-.8 .5-2.5 3.3 .6 .3-.5 2.2-.2 3 .7-1.4 2.4 .2 1.9 1.1 1.7-.5 1.2-.2 1.2z' }, + SS: { + name: 'South Sudan', + path: 'M585.6 306.3l-2.4-1.9-.7-1.2-1.5 .6-1.3-.1-.7 .4-1.3-.3-1.7-2.3-.4-.9-2.1-1.1-.7-1.7-1.1-1.2-1.9-1.4 0-.9-1.6-1.2-1.8-1.1 .8-.3 1-.5 .7-2.5 .7-1.3 2-.4 .5 .8 1.4 1.6 .8 .3 1-.5 2 .1 .4 .6 2.8 0 .1-.6 1.4-.5 .3-.9 1-.5 2.4 1.6 1.4-.3 1.4-2 1.5-1.6-.2-1.7-.7-.8 1.7-.1 .2-.7 1.2 .2-.3 2.1 .3 2 1.5 1.2 .3 .9 0 1.4 .3 .1 .1 2.2-.4 .8-1.5 .1-1 1.6 1.7 .2 1.5 1.3 .4 1.1 1.3 .7 1.7 3-1.9 1.9-1.7 1.6-1.7 1.3-2 0-2.2 .7-1.8-.7z', + }, + SV: { name: 'El Salvador', path: 'M251.8 275.7l.8 .2 .6 .6 .9 .5 .1 .3 1.2-.3 .5 .2 .4 .3-.2 1.1-.3 .7-1.6 0-1-.3-1.1-.6-1.6-.1-.8-.7 .1-.4 1-.7 .5-.3-.2-.3z' }, + SY: { name: 'Syria', path: 'M599.2 221.8l.3-.4 0-1.3 .7-1.7 1.5-1.2-.5-1.2-1.2-.2-.3-2.4 .7-1.3 .8-.7 .7-.7 .2-1.8 .9 .7 3-.9 1.5 .6 2.3 0 3.2-1.2 1.5 0 3.1-.5-1.4 2-1.5 .8 .3 2.3-1.1 3.8-6.1 3.3-5.5 3.3z' }, + SZ: { name: 'Kingdom of eSwatini', path: 'M589.1 392.1l-.6 1.3-1.6 .3-1.7-1.6 0-1 .8-1.1 .2-.9 .8-.2 1.4 .5 .4 1.4z' }, + TD: { + name: 'Chad', + path: 'M566.2 261l.2 11.3-2.4-.2-1.3 2.1-.7 1.8 .5 .6-.9 .9 .3 1.2-.7 1.2-.3 1 1-.2 .6 1.1 0 1.7 1 .8 0 .7-1.7 .4-1.5 1.2-2 3-2.6 1.3-2.7-.1-.7 .2 .2 1-1.4 1-1.2 1.1-3.5 1-.7-.6-.4 0-.6 .7-2.3 .2 .5-.8-.9-1.9-.4-1.2-1.2-.4-1.6-1.7 .6-1.3 1.2 .3 .8-.2 1.6 0-1.5-2.5 .1-1.9-.2-1.9-1.1-1.8 .2-1.3-1.7-.1 0-1.8-1.2-1 1.2-3.8 3.6-2.7 .1-3.7 1.1-5.8 .6-1.3-1.2-1 0-.9-1.1-.7-.6-4.6 2.8-1.6 11 5.6z', + }, + TF: { name: 'French Southern and Antarctic Lands', path: 'M691.5 462.9l1.8 1.1 2.6 .4 .1 .7-.8 1.7-4.2 .2-.1-1.9 .4-1.5z' }, + TG: { name: 'Togo', path: 'M502.5 285.4l-.4 1.4 .9 .9 1 1 .1 1.3 .5 .6-.1 6.4 .7 2-2.3 .6-.6-1-.7-1.8-.2-1.4 .6-2.5-.7-1-.3-2.2 0-2.1-1.1-1.4 .2-.9z' }, + TH: { + name: 'Thailand', + path: 'M792.3 276.1l-2.6-.4-3.6 .6-1.8 2.3 .7 3.4-2.5-1.3-2.4 .1 .4-2.2-2.5 0-.2 3.1-1.5 4.1-.9 2.5 .2 2 1.8 .1 1.2 2.5 .5 2.5 1.5 1.6 1.7 .3 1.4 1.4-.9 1.2-1.8 .3-.2-1.4-2.3-1.2-.5 .5-1.1-1.1-.5-1.4-1.4-1.6-1.4-1.3-.4 1.6-.6-1.5 .3-1.8 .9-2.6 1.3-2.9 1.5-2.6-1.1-2.6 .1-1.3-.3-1.6-1.9-2.3-.6-1.4 .9-.5 1-2.5-1.1-1.9-1.8-2.1-1.3-2.5 1.2-.5 1.2-3.1 2-.1 1.6-1.3 1.6-.7 1.2 .9 .2 1.8 1.8 .1-.6 3 0 2.6 2.9-1.7 .9 .5 1.6-.1 .6-1 2.1 .2 2.1 2.3 .2 2.9 2.2 2.4-.1 2.4z', + }, + TJ: { name: 'Tajikistan', path: 'M688.4 207.9l1.6-3.3-.6-2.4-2.1-.7 .8-1.5 2.3 .2 1.3-1.8 .9-2.1 3.7-.8-.6 1.5 .4 .9 1.2 0-1.1 1-3-.6-.2 1.9 3-.3 3.4 1.1 5.3-.5 .7 3 .9-.3 1.7 .7-.1 1.3 .4 1.8-2.9 0-1.9-.2-1.7 1.4-1.3 .3-.9 .7-1.1-1.1 .2-2.6-.8-.2 .3-1-1.5-.7-1.2 1.1-.3 1.3-.4 .5-1.7-.1-.9 1.5-.9-.6-2 1z' }, + TL: { name: 'Timor-Leste', path: 'M847.1 340.8l.4-.7 2.4-.6 1.9-.1 .9-.3 1 .3-1 .8-2.9 1.2-2.3 .8-.1-.8z' }, + TM: { + name: 'Turkmenistan', + path: 'M645.8 192.8l1.3-1.1 3.1-.7 1.9 .9 1.9 2.6 1.5-.2 3.1 0-.5-1.7 2.4-1.1 2.4-2 3.7 1.8 .3 2.7 1.1 .6 3-.1 .9 .6 1.4 3.4 3.1 2.2 1.9 1.6 2.9 1.6 3.7 1.3-.1 2-.9-.1-1.3-.9-.4 1.2-2.3 .6-.6 2.5-1.6 1-2.2 .5-.5 1.4-2.1 .4-2.9-1.2-.2-2.6-2.1-.1-3.2-2.9-2.2-.3-3-1.6-2-.3-1.2 .6-1.9-.1-2 1.8-2.4 .6-.5-2.2 .4-3.4-2.2-1.1 .7-2.3-1.8-.2 .6-2.7 2.6 .8 2.4-1.1-2-2-.8-1.9-2.2 .9-.3 2.4z', + }, + TN: { name: 'Tunisia', path: 'M526.3 229.2l-1.1-5.5-1.8-1.2 0-.8-2.3-1.8-.2-2.4 1.7-1.7 .7-2.6-.5-3 .6-1.7 3-1.3 2 .4-.1 1.6 2.3-1.1 .2 .6-1.4 1.5 0 1.5 1 .8-.4 2.7-1.8 1.6 .5 1.7 1.5 .1 .7 1.4 1 .5-.1 2.4-1.4 .9-.9 1-1.9 1.2 .3 1.2-.2 1.3z' }, + TR: { + name: 'Turkey', + path: 'M624.4 207.8l-1.4 .6-.9-.9-3.3-.4-1.2 .5-3.1 .5-1.5 0-3.2 1.2-2.3 0-1.5-.6-3 .9-.9-.7-.2 1.8-.7 .7-.8 .7-1-1.4 1-1.2-1.6 .2-2.4-.7-1.9 1.8-4.2 .4-2.2-1.7-3-.1-.7 1.3-1.9 .4-2.7-1.7-3 0-1.7-3.1-2-1.8 1.4-2.5-1.8-1.6 3.1-3.1 4.3-.2 1.1-2.5 5.3 .5 3.4-2.2 3.2-.9 4.6-.1 4.8 2.4 4 1.2 3.3-.5 2.3 .3 3.3-1.7 3-.2 2.7 1.7 .4 1.1-.2 1.6 2 .8 1.1 1-1.9 .9 .9 3.7-.6 1zM572.5 192.6l2.9-1 2.4 .4 .3 1.3 2.4 1.1-.5 .8-3.3 .2-1.2 1-2.3 1.8-.9-1.6 .1-.7 .6-.3 .9-2.1z', + }, + TT: { name: 'Trinidad and Tobago', path: 'M328.7 286l1.6-.3 .5 .1-.1 2.1-2.3 .3-.5-.3 .8-.8z' }, + TW: { name: 'Taiwan', path: 'M838.3 246.9l-1.7 4.7-1.2 2.4-1.5-2.4-.3-2.2 1.7-2.9 2.2-2.2 1.3 .8z' }, + TZ: { + name: 'Tanzania', + path: 'M594.2 318.7l.4 .3 10.1 5.6 .2 1.7 4 2.7-1.3 3.5 .2 1.6 1.8 1 0 .7-.7 1.7 .1 .8-.1 1.4 .9 1.7 1.2 2.8 1 .6-2.2 1.6-3.1 1.1-1.6 0-1 .8-1.9 .1-.8 .3-3.3-.8-2.1 .3-.8-3.8-.9-1.4-.6-.7-2.7-.5-1.6-.9-1.7-.5-1.2-.4-1.1-.7-1.5-3.6-1.6-1.5-.6-1.6 .3-1.5-.5-2.6 1.1-.1 1.1-1 1-1.4 .7-.6 0-.9-.6-.7-.2-1.1 .8-.3 .2-1.6-1.1-1.6 1-.3 3 0z', + }, + UA: { + name: 'Ukraine', + path: 'M588.3 156.5l1 .2 .7-.9 .9 .2 2.9-.3 1.7 2.1-.7 .7 .3 1.2 2.2 .2 1 1.5-.1 .8 3.5 1.2 2.2-.5 1.7 1.7 1.6-.1 4.1 1.2 0 1.1-1.1 1.8 .6 2-.4 1.2-2.7 .2-1.4 1-.1 1.6-2.2 .3-1.9 1.1-2.6 .2-2.4 1.3 .2 1.9-.5-.2-.3-.6-.9-.2-2-.7-.7 .8-.4-.3-4.3-.9-.2-1.3-2.6 .4-1 1.9-2.2 2.6-1.2-.6-1.3 .6-1.3-.7 .7-.4 .5-1.1 .8-1.2-.2-.6 .6-.3 .2 .5 1.7 .1 .7-.2-.5-.4 .2-.5-1-.9-.4-1.5-1-.5 .2-1.2-1.3-1-1.1-.1-2-1.1-1.9 .3-.7 .5-1.1 0-.7 .9-2.1 .3-.9 .6-1.3-.9-1.8 0-1.7-.4-1.2 .7-.2-.9-1.6-1 .6-1.4 .8-.9 .6 .2-.7-1.6 2.5-3.1 1.4-.4 .2-1-1.3-3.2 1.3-.2 1.5-1 2.2 0 2.8 .2 3.1 .9 2.1 .1 1.1 .5 1-.6 .8 .9 2.5-.2 1.1 .3 .2-1.8 .8-.8z', + }, + UG: { name: 'Uganda', path: 'M594.2 318.7l-5.7 .2-3 0-1 .3-1.7 .8-.6-.2 0-2.1 .6-1.1 .2-2.2 .6-1.3 1-1.5 1.1-.7 .9-1-1.1-.4 .1-3.2 1.2-.8 1.8 .7 2.2-.7 2 0 1.7-1.3 1.3 2 .3 1.4 1.2 3.1-1 2.1-1.4 1.8-.8 1.1z' }, + US: { + name: 'United States', + path: 'M158.8 167.9l7.9 0 8.2 0 2.7 0 8.5 0 8.2 0 8.3 0 8.4 0 9.4 0 9.5 0 5.8 0 0-1.4 .9 0 .5 1.9 .9 .6 1.9 .3 2.9 .5 2.6 1.1 2.3-.4 3.4 .9 .9 0 2.5-1 2.6 1.2 2.7 1.4 2.3 1.2 2.1 1.1 .3 .9 .7 .4-.2 .3 .7 .1 .6-.3 .1 .8 .6 .5 .7 0 .4 .5-.3 .6 2.9 1.6 .6 3.1 .5 3-.8 2-1.3 1.8-.6 1.2-.1 .3 .4 .5 .9 .5 .7 0 3.2-1.8 2.9-.5 3.6-1.6 .1-.4-.3-1-.4-.7 1.2-.5 2.8 0 2.5 0 .9-1.4 .3-.2 3-2.5 1.2-.6 4.3 0 5.1 0 .3-.9 .8-.2 1.2-.5 1-1.6 .9-2.7 2.1-2.6 .9 .9 1.9-.6 1.2 1 0 4.8 1.8 1.9 .5 1.1-3 1.7-2.8 1.2-3 1-1.4 2-.5 .7 0 1.8 .9 1.8 1.1 .1-.3-1.2 .9 .7-.2 1-1.9 .5-1.4-.1-2 .6-1.2 .2-1.6 .1-2.3 1 4-.6 .9 .6-3.9 1-1.8 0 .1-.4-.9 .9 .8 .2-.6 2.3-2 2.5-.2-.8-.6-.2-.9-.8 .6 1.7 .7 .6 0 1.2-.9 1.3-1.5 2.6-.3-.2 .9-2.1-1.5-1.3-.3-2.7-.5 1.4 .6 2.1-1.9-.5 2 1 .1 3.1 .8 .2 .3 1.1 .3 3.2-1.7 2.3-2.9 .9-1.8 1.9-1.4 .2-1.4 1.1-.4 1.1-3.1 2-1.5 1.4-1.3 1.9-.5 2.1 .5 2.1 1 2.6 1.2 2.2 0 1.3 1.3 3.5-.1 2-.1 1.1-.7 1.8-.8 .4-1.4-.4-.4-1.3-1.1-.6-1.4-2.6-1.3-2.3-.5-1.2 .6-2-.8-1.6-2.1-2.6-1.1-.4-2.8 1.4-.5-.2-1.4-1.4-1.7-.8-3.1 .4-2.5-.3-2.1 .2-1.2 .5 .5 .8 0 1.2 .6 .6-.6 .4-1-.4-1 .5-2-.1-2.1-1.6-2.4 .4-2.1-.7-1.7 .2-2.3 .7-2.6 2.3-2.7 1.3-1.5 1.4-.7 1.4 0 2 .1 1.5 .6 1-1.1 .1-2-.7-2.2-.9-.7-1.4-.6-2.1-1.7-1.7-.9-1.8-1.4-2.1-2-1.2-2.3 .1-1.7 2.4-2.3-.9-1.5-.9-.6-1.7-1-1.6-1.6-1.4-1.4-.9-1.1-1.1-4.8 0 0 1.3-2.2 0-5.5 0-6.3-2.2-4.2-1.5 .2-.6-3.5 .3-3.2 .3-.4-1.6-1.8-1.8-1.3-.4-.3-.9-1.6-.1-1-.9-2.6-.3-.7-.5-.3-1.7-2.7-3.2-2.3-4.4 .1-.8-1.2-1-2.2-2.7-.4-2.7-1.5-1.8 .7-2.7-.1-2.9-.9-2.5 1.1-3.2 .3-3.1 .3-3.1-.5-4.7-.8-3-.9-1.6 .4-.7 4 1.2 1.5 3.3 .7-.9-.5-2.9zM68.3 259.5l.5 .3 .5 .4 .7 1-.1 .1-1.1 .6-.9 .5-.4 .5-.7-.4 .1-.8-.4-1.1 .1-.3 .5-.5-.2-.6 .2-.2 .2 0zM66.7 257.5l-.3 .4-.9 .2-.5-.6-.3-.3 0-.1 .3-.3 1 .3zM64.6 256.3l-.1 .4-1.5-.1 .2-.4zM61 254.8l.3 .2 .8 .9-.2 .2-.2-.1-.9-.1-.4-.6-.1-.1zM57.3 253.3l.1 .7-.4 .3-.9-.5 .2-.3 .4-.2zM37.6 124l2.2 .3 .3 1.6-1.7 .7-1.9-.8-1.7-1.1zM74.4 133.9l1.8 .2 1.2 1.3-2.4 1.9-2.8 1.5-1.4-1-.4-1.9 2.5-1.4zM108.4 81.7l0 17.7-.1 24.9 2.8 .1 2.7 1.2 1.9 1.8 2.5 2.7 2.7-2.3 2.8-1.4 1.5 2.2 1.8 1.6 2.6 1.9 1.7 2.9 2.8 4.5 4.8 2.5 0 2.5-1.5 1.8-1.5-1.4-2.5-1.3-.8-3.4-3.5-3.2-1.5-3.8-2.7-.2-4.4-.1-3.3-1.2-5.7-4.2-2.7-.8-4.8-1.5-3.9 .4-5.4-2-3.4-1.7-3 .8 .5 2.9-1.5 .3-3.2 .9-2.5 1.4-3 .8-.4-2.4 1.2-4.1 3-1.3-.8-1-3.5 2.3-1.9 2.8-4 2.9 2 2-2.6 2.9-3 1.7-2.8 1.2-.7 1.8-4.3 2.1-.9 1.8-3.2 1.7-1.9-.3-2.6 1.1-2.9 1.3-2.3 1.3-4.7 1.1-.5-.7 3.1-1.8 2.7-1.2 2.9-2.1 3.5-.5 1.4-1.6 3.8-2.3 .6-.8 2.1-1.4 .5-3.1 1.4-2.4-3.2 1.2-.9-.7-1.5 1.5-1.8-2-.8 1.4-1-2-2.8 1.6-1.7 0-.3-2.4 .5-1.5-1.7-1.5-3.7 .8-2.3-2-1.9-1 0-2.3-2.1-1.8 1-2.5 2.3-2.4 1-2.2 2.2-.4 1.9 .7 2.3-2.1 2 .4 2.1-1.4-.5-2-1.6-.8 2.1-1.7-1.7 0-3 1-.8 1-2.2-1-3.9 .5-4.1-1.1-1.2-1.8-3.5-2.6 3.9-1.9 6.2-2.3 2.3 0-.4 2.3 5.9-.2-2.3-2.8-3.4-1.8-2-2.4-2.6-2-3.8-1.5 1.5-2.5 4.9-.2 3.6-2.2 .6-2.4 2.9-2.4 2.7-.6 5.2-2.2 2.6 .3 4.3-2.7 4.2 1.1 2 2.3 1.2-1 4.7 .3-.2 1.2 4.3 .8 2.8-.5 5.9 1.6 5.3 .5 2.1 .6 3.7-.8 4.3 1.5zM23 109.4l1.7 .8 1.7-.4 2.3 1.1 2.7 .6-.2 .5-2.1 .9-2.1-.9-1.1-.8-2.4 .2-.7-.4z', + }, + UY: { name: 'Uruguay', path: 'M339.9 402.6l1.8-.3 2.8 2.3 1.1-.1 2.8 2 2.2 1.7 1.6 2.1-1.2 1.5 .7 1.7-1.2 2-3.1 1.7-2.1-.6-1.5 .3-2.5-1.3-1.9 .1-1.7-1.7 .2-2.1 .6-.6 0-3.1 .7-3.2z' }, + UZ: { + name: 'Uzbekistan', + path: 'M655.5 194.3l-.1-12.4 7.1-2 .5 .3 4.3 2.4 2.3 1.3 2.7 3.1 3.2-.5 4.8-.3 3.3 2.5-.2 3.4 1.4 0 .5 2.7 3.5 .1 .8 1.6 1 0 1.3-2.4 3.6-2.3 1.6-.6 .8 .3-2.3 2.1 2.1 1.3 1.9-.8 3.3 1.7-3.5 2.4-2.1-.3-1.2 0-.4-.9 .6-1.5-3.7 .8-.9 2.1-1.3 1.8-2.3-.2-.8 1.5 2.1 .7 .6 2.4-1.6 3.3-2.1-.7-1.5 0 .1-2-3.7-1.3-2.9-1.6-1.9-1.6-3.1-2.2-1.4-3.4-.9-.6-3 .1-1.1-.6-.3-2.7-3.7-1.8-2.4 2-2.4 1.1 .5 1.7z', + }, + VE: { + name: 'Venezuela', + path: 'M331.3 301.6l.4 .8-1.1 1-3.1 1.1-2 .4-.8 .7-2.2-.7-2-.4-.5 .3 1.2 .7-.1 1.9 .4 1.7 2.3 .2 .2 .6-2 .8-.3 1.2-1.2 .4-2 .7-.6 .8-2.1 .2-1.6-1.4-.8-2.8-.8-1-1-.6 1.4-1.4 0-.6-.8-.8-.6-1.9 .2-2 .6-.9 .5-1.5-.9-.5-1.6 .3-2-.1-1.1 .3-2-2.4-1.6-.4-3.6 .3-.7-1-.6-.2-.1-.6 .3-1-.2-1.2-.6-.6-.4-1.3-1.4-.2 .7-1.6 .4-2 .8-1 1.1-.8 .7-1.4 1.8-.5-.1 .6-1.7 .4 1 1.2-.1 1.5-1.2 1.6 1 2.3 1.2-.2 .7-2-.9-1-.1-2.2 3.4-1.1-.4-1.3 1-.9 1 2 2 0 1.8 1.6 .1 .9 2.5 0 2.9-.3 1.6 1.3 2.1 .4 1.6-.9 0-.7 3.5-.2 3.3 0-2.4 .8 1 1.3 2.2 .2 2.1 1.4 .5 2.2 1.4 0 1.1 .6-2.2 1.7-.2 1 .9 1-.7 .6-1.7 .4 .1 1.3-.8 .8z', + }, + VN: { + name: 'Vietnam', + path: 'M789.8 286.8l2.4-1.1 2.9-.2-1.2-1.7 4.7-2.2 .3-3.4-.6-1.9 .5-2.8-.7-2-2.1-2-1.8-2.5-2.3-3.4-3.3-1.7 .8-1.1 1.8-.7-1.1-2.5-3.4-.1-1.3-2.6-1.6-2.3 1.5-.7 2.2 0 2.7-.3 2.4-1.6 1.3 1.1 2.6 .5-.5 1.7 1.3 1.2 2.8 .7-3.7 2.5-2.3 2.8-.6 2 2.1 3 2.6 3.7 2.5 1.8 1.7 2.3 1.3 5.2-.4 5-2.3 1.8-3.2 1.8-2.2 2.4-3.5 2.6-1-1.8 .8-1.9z', + }, + VU: { name: 'Vanuatu', path: 'M964.5 360.5l1.7 1.7-.9 .4-.9-1.3zM963.3 359.9l-.4-.8 0-2.1 1.3 .8 .4 2.3-.7-.3z' }, + XC: { name: 'Northern Cyprus', path: 'M590.9 214.3l.2-.1 .4-.7 2 0 2.5-.9-1.8 1.3 .2 .6-.3-.1-.6 .2-.4 0-.1 .1-.1-.3-.2-.2-.5 0-.8 .2z' }, + XK: { name: 'Kosovo', path: 'M557.2 192.5l-.2-1.2-.7-.3-.5-.9 .5-.8 .6-.2 .4-1.1 .5-.2 .4 .5 .5 .2 .4 .5 .5 .2 .5 .6 .4 0-.3 .8-.4 .4 .1 .2-.6 .2-1.6 .5-.2 .7z' }, + XS: { name: 'Somaliland', path: 'M636 284.2l0 .1-.1 1.1 0 2.8 0 1.5-1.2 1.7-2 2.4-2.3 0-9.1-3.3-1-1-1.1-1.4-1-1.5 .6-1 1-1.5 1 .5 .5 1.1 1.2 1.2 1.4 0 2.6-.7 3.1-.3 2.4-.9 1.4-.2 1-.5z' }, + YE: { + name: 'Yemen', + path: 'M644.4 262.6l2.2 4.8 .9 2-2 .7-.5 1.3-.1 1-2.8 1.2-4.4 1.3-2.5 2-1.2 .1-.8-.1-1.7 1.2-1.7 .5-2.4 .1-.7 .2-.6 .8-.7 .2-.4 .7-1.4-.1-.9 .4-1.9-.1-.7-1.7 0-1.5-.4-.9-.6-2.1-.8-1.1 .6-.2-.3-1.3 .4-.5-.2-1.3 1.3-.9-.3-1.2 .7-1.4 1.1 .8 .8-.3 3.2-.1 .5 .3 2.7 .3 1.1-.1 .7 .9 1.3-.5 1.9-3 2.6-1.3z', + }, + ZA: { + name: 'South Africa', + path: 'M545.4 397.6l1.3-1.5 1.1 .8 .5 1.3 1.2 .3 1.8 .5 1.5-.2 2.5-1.5 0-11 .7 .4 1.7 2.8-.3 1.8 .6 1.1 2-.3 1.4-1.4 1.3-.9 .7-1.4 1.4-.7 1.1 .4 1.4 .8 2.2 .2 1.8-.7 .3-.9 .5-1.5 1.5-.2 .8-1.1 .9-2 2.5-2.1 4-2.2 1.1 0 1.3 .5 1-.3 1.4 .3 1.4 4.1 .7 2.1-.5 3.3 .2 1-1.4-.5-.8 .2-.2 .9-.8 1.1 0 1 1.7 1.6 1.6-.3 .6-1.3 2.1 0-.7 2.2-.3 2.5-.7 1.3-1.9 1.6-.6 .4-1.2 1.5-.7 1.6-1.6 2.2-3.2 3.2-1.9 1.8-2.1 1.4-2.9 1.2-1.4 .2-.4 .9-1.7-.5-1.4 .6-3-.6-1.6 .4-1.2-.2-2.9 1.3-2.3 .4-1.7 1.2-1.3 .1-1.2-1.1-.9-.1-1.2-1.4-.2 .5-.3-.9 0-1.8-.9-2.1 .9-.5-.1-2.4-1.8-2.9-1.4-2.5 0-.1zM580.5 398.8l-1.2-1-1.3 .6-1.5 1.2-1.5 1.9 2.1 2.4 1-.3 .5-1 1.5-.5 .5-1 .9-1.4z', + }, + ZM: { + name: 'Zambia', + path: 'M585.4 339.3l1.1 .7 1.2 .4 1.7 .5 1.6 .9 1.3 1.2 .7 2.4-.5 .7-.5 2.3 .5 2.4-.9 .9-.8 2.7 1.5 .7-8.5 2.3 .3 2.1-2.1 .3-1.6 1.2-.3 1-1 .2-2.4 2.3-1.6 1.9-.9 .1-.9-.4-3.1-.3-.5-.2 0-.2-1.1-.7-1.8-.1-2.3 .6-1.8-1.8-1.9-2.3 .1-9 5.8 0-.2-1 .4-1-.5-1.4 .3-1.3-.3-.9 1 .1 .1 .9 1.3-.1 1.8 .2 .9 1.3 2.3 .4 1.7-.9 .6 1.5 2.1 .4 1 1.2 1.2 1.6 2.1 0-.2-3.1-.8 .5-1.9-1.1-.8-.5 .4-2.8 .4-3.3-.6-1.2 .8-1.8 .8-.4 3.7-.4z', + }, + ZW: { name: 'Zimbabwe', path: 'M586.6 378.9l-1.4-.3-1 .3-1.3-.5-1.1 0-1.8-1.3-2.2-.5-.8-1.8 0-1-1.2-.3-3.1-3.2-.9-1.7-.6-.5-1-2.3 3.1 .3 .9 .4 .9-.1 1.6-1.9 2.4-2.3 1-.2 .3-1 1.6-1.2 2.1-.3 .2 1 2.3 0 1.3 .6 .6 .7 1.3 .2 1.4 .9 0 3.6-.5 2-.1 2.2 .4 .8-.3 1.7-.4 .3-.7 2.1z' }, + AD: { name: 'Andorra', path: 'M504.3 190.2h0', point: true }, + AG: { name: 'Antigua and Barbuda', path: 'M328.4 267.4h0', point: true }, + BB: { name: 'Barbados', path: 'M334.5 279.3h0', point: true }, + BH: { name: 'Bahrain', path: 'M640.4 242h0', point: true }, + CV: { name: 'Cabo Verde', path: 'M434.3 273.9h0', point: true }, + DM: { name: 'Dominica', path: 'M329.6 272.8h0', point: true }, + FM: { name: 'Federated States of Micronesia', path: 'M939.5 296.9h0', point: true }, + GD: { name: 'Grenada', path: 'M328.7 282.2h0', point: true }, + HK: { name: 'Hong Kong', path: 'M816.9 252.6h0', point: true }, + KI: { name: 'Kiribati', path: 'M62.8 311h0', point: true }, + KM: { name: 'Comoros', path: 'M620.3 348.8h0', point: true }, + KN: { name: 'Saint Kitts and Nevis', path: 'M325.7 267.4h0', point: true }, + LC: { name: 'Saint Lucia', path: 'M330.6 277.2h0', point: true }, + LI: { name: 'Liechtenstein', path: 'M526.6 174.6h0', point: true }, + MC: { name: 'Monaco', path: 'M520.6 186.2h0', point: true }, + MH: { name: 'Marshall Islands', path: 'M975.5 296.3h0', point: true }, + MO: { name: 'Macao', path: 'M815.4 253.6h0', point: true }, + MT: { name: 'Malta', path: 'M540.1 211.9h0', point: true }, + MU: { name: 'Mauritius', path: 'M659.9 373.2h0', point: true }, + MV: { name: 'Maldives', path: 'M704.2 304.4h0', point: true }, + NR: { name: 'Nauru', path: 'M963.7 317.5h0', point: true }, + PW: { name: 'Palau', path: 'M873.8 295.1h0', point: true }, + SC: { name: 'Seychelles', path: 'M654.1 329h0', point: true }, + SG: { name: 'Singapore', path: 'M788.4 312.2h0', point: true }, + SM: { name: 'San Marino', path: 'M534.6 185.5h0', point: true }, + ST: { name: 'São Tomé and Principe', path: 'M519.5 313.3h0', point: true }, + TO: { name: 'Tonga', path: 'M13.4 375.8h0', point: true }, + TV: { name: 'Tuvalu', path: 'M997.8 339.7h0', point: true }, + VA: { name: 'Vatican', path: 'M534.6 192.4h0', point: true }, + VC: { name: 'Saint Vincent and the Grenadines', path: 'M329.6 279.5h0', point: true }, + WS: { name: 'Samoa', path: 'M21 354.2h0', point: true }, + }, +} diff --git a/core/js/src/global.d.ts b/core/js/src/global.d.ts index 84aa38e79..7c8ea8239 100644 --- a/core/js/src/global.d.ts +++ b/core/js/src/global.d.ts @@ -13,5 +13,7 @@ declare global { maplibregl?: import('./map').MapLibrary Sortable?: new (element: HTMLElement, options?: Record) => import('./sortable').SortableInstance jQuery?: JQueryStaticLike + // Filled by the map files of the VectorMap plugin (`dist/js/maps/*.js`) + tablerVectorMaps?: Record } } diff --git a/core/js/src/vector-map.ts b/core/js/src/vector-map.ts new file mode 100644 index 000000000..79cb70e08 --- /dev/null +++ b/core/js/src/vector-map.ts @@ -0,0 +1,1013 @@ +/** + * -------------------------------------------------------------------------- + * Tabler vector-map.ts + * Licensed under MIT (https://github.com/tabler/tabler/blob/dev/LICENSE) + * -------------------------------------------------------------------------- + */ + +import BaseComponent from './bootstrap/base-component' +import EventHandler from './bootstrap/dom/event-handler' +import { initAll } from './bootstrap/util/component-functions' +import type { ComponentConfig as BaseConfig, ElementSelector } from './bootstrap/types' + +export type VectorMapRegion = { + name: string + /** SVG path data, already projected into the viewBox of the map */ + path: string + /** Too small for a shape at the scale of the map: `path` is a single point, drawn as a dot */ + point?: boolean +} + +export type VectorMapData = { + width: number + height: number + /** How the shapes were projected, to place a point by its coordinates */ + projection: { type: 'miller'; scale: number; translate: number[] } + /** Regions by their code, for example ISO 3166-1 alpha-2 for countries */ + regions: Record +} + +export type VectorMapMarker = { + /** Shown in the tooltip, and what a line refers to */ + name?: string + lat: number + lng: number +} + +export type VectorMapLine = { + /** Names of the two markers the line joins */ + from: string + to: string +} + +/** What the pointer is over when a tooltip is about to show */ +export type VectorMapTooltipItem = { type: 'region'; code: string; name: string; value?: number } | { type: 'marker'; name: string } + +type VectorMapValues = Record +type VectorMapTooltip = boolean | ((item: VectorMapTooltipItem) => string) +type VectorMapLegend = boolean | ((value: number) => string) +type VectorMapSelect = 'none' | 'single' | 'multiple' +type Point = [number, number] +// The part of the map in sight: its top left corner and how many times it is magnified +type View = { x: number; y: number; scale: number } + +type ComponentConfig = { + map: string | VectorMapData + values: VectorMapValues + min: number | null + max: number | null + colors: string[] + markers: VectorMapMarker[] + lines: VectorMapLine[] + tooltip: VectorMapTooltip + legend: VectorMapLegend + select: VectorMapSelect + selected: string[] + zoom: boolean + zoomMax: number + zoomOnScroll: boolean + zoomInLabel: string + zoomOutLabel: string + label: string | null +} + +type ComponentConfigInput = Partial + +/** + * Constants + */ + +const NAME = 'vector-map' +const DATA_KEY = `bs.${NAME}` +const EVENT_KEY = `.${DATA_KEY}` + +const EVENT_RENDERED = `rendered${EVENT_KEY}` +const EVENT_UPDATED = `updated${EVENT_KEY}` +const EVENT_REGION_CLICK = `regionclick${EVENT_KEY}` +const EVENT_MARKER_CLICK = `markerclick${EVENT_KEY}` +const EVENT_SELECTED = `selected${EVENT_KEY}` +const EVENT_POINTERMOVE = `pointermove${EVENT_KEY}` +const EVENT_POINTERLEAVE = `pointerleave${EVENT_KEY}` +const EVENT_POINTERDOWN = `pointerdown${EVENT_KEY}` +const EVENT_POINTERUP = `pointerup${EVENT_KEY}` +const EVENT_POINTERCANCEL = `pointercancel${EVENT_KEY}` +const EVENT_DBLCLICK = `dblclick${EVENT_KEY}` +const EVENT_CLICK = `click${EVENT_KEY}` + +const CLASS_NAME_SVG = 'vector-map-svg' +const CLASS_NAME_REGION = 'vector-map-region' +const CLASS_NAME_POINT = 'vector-map-region-point' +const CLASS_NAME_POINT_HALO = 'vector-map-region-point-halo' +const CLASS_NAME_POINT_DOT = 'vector-map-region-point-dot' +const CLASS_NAME_LINE = 'vector-map-line' +const CLASS_NAME_MARKER = 'vector-map-marker' +const CLASS_NAME_MARKER_HALO = 'vector-map-marker-halo' +const CLASS_NAME_MARKER_DOT = 'vector-map-marker-dot' +const CLASS_NAME_TOOLTIP = 'vector-map-tooltip' +const CLASS_NAME_COLORS = 'vector-map-colors' +const CLASS_NAME_LEGEND = 'vector-map-legend' +const CLASS_NAME_LEGEND_LABEL = 'vector-map-legend-label' +const CLASS_NAME_LEGEND_SCALE = 'vector-map-legend-scale' +const CLASS_NAME_LEGEND_STEP = 'vector-map-legend-step' +const CLASS_NAME_SELECTABLE = 'vector-map-selectable' +const CLASS_NAME_SELECTED = 'vector-map-region-selected' +const CLASS_NAME_ZOOMABLE = 'vector-map-zoomable' +const CLASS_NAME_DRAGGING = 'vector-map-dragging' +const CLASS_NAME_CONTROLS = 'vector-map-controls' +const CLASS_NAME_CONTROL_GROUP = 'btn-group-vertical' +const CLASS_NAME_CONTROL = 'btn btn-sm btn-icon' + +const ATTRIBUTE_REGION = 'data-region' +const ATTRIBUTE_VALUE = 'data-value' +const ATTRIBUTE_MARKER = 'data-marker' +const ATTRIBUTE_ACTION = 'data-bs-vector-map-action' + +const SELECTOR_TOOLTIP_TARGET = `.${CLASS_NAME_REGION}, .${CLASS_NAME_MARKER}` +const SELECTOR_ACTION = `[${ATTRIBUTE_ACTION}]` +// What a selected shape is moved in front of, so its outline is not covered +// by the shapes around it but stays under everything drawn over the map +const SELECTOR_OVER_SHAPES = `.${CLASS_NAME_POINT}, .${CLASS_NAME_LINE}, .${CLASS_NAME_MARKER}` + +const SELECT_NONE = 'none' +const SELECT_MULTIPLE = 'multiple' + +// How far a pointer has to move, in pixels, before a press becomes a drag +// and stops being a click +const DRAG_THRESHOLD = 4 + +const ACTION_ZOOM_IN = 'zoom-in' +const ACTION_ZOOM_OUT = 'zoom-out' + +// One step of a button or a double click +const ZOOM_STEP = 2 +const ZOOM_DURATION = 200 +// How much one unit of wheel movement magnifies. A pinch on a trackpad comes +// as a wheel event with `ctrlKey` and much smaller numbers. +const WHEEL_SPEED = 0.002 +const WHEEL_SPEED_PINCH = 0.01 + +const ICON_ZOOM_IN = 'M12 5v14M5 12h14' +const ICON_ZOOM_OUT = 'M5 12h14' + +// How far a line bends away from the straight one, as a share of its length +const LINE_CURVE = 0.2 +const RADIANS = Math.PI / 180 + +const SELECTOR_DATA_TOGGLE = `[data-bs-toggle="${NAME}"], [data-tblr-toggle="${NAME}"]` + +// Declared on `.vector-map-region` in scss/ui/_vector-map.scss, where it gets +// the `--tblr-` prefix at build time. +const CSS_VAR_VALUE = '--tblr-vector-map-value' +// The colours of a scale, numbered from 1, and how many of them there are. +// scss/ui/_vector-map.scss mixes them, for at most this many. +const CSS_VAR_COLOR = '--tblr-vector-map-color-' +const CSS_VAR_COLORS = '--tblr-vector-map-colors' +const COLORS_MAX = 5 +// Enough slices for the bar of the legend to read as one smooth gradient +const LEGEND_STEPS = 24 +const SVG_NS = 'http://www.w3.org/2000/svg' + +const Default: ComponentConfig = { + map: 'world', + values: {}, + min: null, + max: null, + colors: [], + markers: [], + lines: [], + tooltip: true, + legend: false, + select: 'none', + selected: [], + zoom: false, + zoomMax: 8, + zoomOnScroll: true, + zoomInLabel: 'Zoom in', + zoomOutLabel: 'Zoom out', + label: null, +} + +const DefaultType: Record = { + map: '(string|object)', + values: 'object', + min: '(number|null)', + max: '(number|null)', + colors: 'array', + markers: 'array', + lines: 'array', + tooltip: '(boolean|function)', + legend: '(boolean|function)', + select: 'string', + selected: 'array', + zoom: 'boolean', + zoomMax: 'number', + zoomOnScroll: 'boolean', + zoomInLabel: 'string', + zoomOutLabel: 'string', + label: '(string|null)', +} + +/** + * Helpers + */ + +const svgEl = (tag: K): SVGElementTagNameMap[K] => document.createElementNS(SVG_NS, tag) + +// Keeps the entries that are a real number, so a `null` or a typo in the data +// leaves that region without a value instead of painting it as zero. +const toValues = (input: unknown): VectorMapValues => { + const values: VectorMapValues = {} + if (typeof input !== 'object' || input === null) { + return values + } + + for (const [code, value] of Object.entries(input)) { + if (typeof value === 'number' && Number.isFinite(value)) { + values[code] = value + } + } + + return values +} + +const isRecord = (input: unknown): input is Record => typeof input === 'object' && input !== null + +// Keeps the markers with real coordinates; one with a typo is left out. +const toMarkers = (input: unknown): VectorMapMarker[] => { + const markers: VectorMapMarker[] = [] + for (const item of Array.isArray(input) ? (input as unknown[]) : []) { + if (isRecord(item) && typeof item.lat === 'number' && typeof item.lng === 'number' && Number.isFinite(item.lat) && Number.isFinite(item.lng)) { + markers.push({ lat: item.lat, lng: item.lng, ...(typeof item.name === 'string' ? { name: item.name } : {}) }) + } + } + + return markers +} + +// A scale needs two colours at least; with one, or none, the map keeps the +// single colour of `--tblr-vector-map-color`. +const toColors = (input: unknown): string[] => { + const colors = (Array.isArray(input) ? (input as unknown[]) : []).filter((color): color is string => typeof color === 'string' && color.trim() !== '') + return colors.length < 2 ? [] : colors.slice(0, COLORS_MAX) +} + +const toLines = (input: unknown): VectorMapLine[] => { + const lines: VectorMapLine[] = [] + for (const item of Array.isArray(input) ? (input as unknown[]) : []) { + if (isRecord(item) && typeof item.from === 'string' && typeof item.to === 'string') { + lines.push({ from: item.from, to: item.to }) + } + } + + return lines +} + +// The same projection the map file was generated with (.build/generate-maps.ts) +const project = ({ projection }: VectorMapData, lng: number, lat: number): Point => { + const { scale, translate } = projection + const y = 1.25 * Math.log(Math.tan(Math.PI / 4 + 0.4 * lat * RADIANS)) + return [lng * RADIANS * scale + translate[0], translate[1] - y * scale] +} + +const round = (value: number): number => Math.round(value * 10) / 10 + +const clamp = (value: number, min: number, max: number): number => Math.min(Math.max(value, min), max) + +const reducedMotion = (): boolean => window.matchMedia('(prefers-reduced-motion: reduce)').matches + +/** + * Class definition + * + * A map drawn as inline SVG from a map file, with regions shaded by value, + * markers placed by their coordinates and lines between them: + * + *
+ * + * The shapes come projected from the map file (`dist/js/maps/world.js`), so + * only the markers are projected here. Colours and sizes come from the + * `--tblr-vector-map-*` custom properties. + * + * With `data-bs-zoom="true"` the map can be magnified with its buttons, the + * wheel, a double click or a pinch, and dragged around. + */ + +class VectorMap extends BaseComponent { + declare _element: HTMLElement + declare _config: ComponentConfig + _userConfig: ComponentConfigInput = {} + _map: VectorMapData | null = null + _tooltip: HTMLElement | null = null + _view: View = { x: 0, y: 0, scale: 1 } + _frame = 0 + // Pointers that are down on the map, with where each was last seen + _pointers = new Map() + // Whether the pointers that are down have moved the map. A click that ends + // a drag is not a click on a region. + _dragged = false + // The codes of the selected regions; filled from `selected` on the first render + _selected: Set | null = null + + /** Maps added with `addMap()`, by name */ + static maps: Record = {} + + constructor(element: ElementSelector, config?: ComponentConfigInput) { + super(element, config) + + if (!this._element) { + return + } + + // Kept so that render() can re-read the data attributes on top of it. + this._userConfig = { ...config } + this.render() + + EventHandler.on(this._element, EVENT_POINTERMOVE, (event: PointerEvent) => { + this._onPointerMove(event) + }) + EventHandler.on(this._element, EVENT_POINTERLEAVE, () => { + this._hideTooltip() + }) + EventHandler.on(this._element, EVENT_POINTERDOWN, (event: PointerEvent) => { + this._onPointerDown(event) + }) + for (const eventName of [EVENT_POINTERUP, EVENT_POINTERCANCEL]) { + EventHandler.on(this._element, eventName, (event: PointerEvent) => { + this._onPointerUp(event) + }) + } + + // `wheel` is not among the native events EventHandler knows, and the + // listener must not be passive to keep the page from scrolling. + this._element.addEventListener('wheel', this._onWheel, { passive: false }) + EventHandler.on(this._element, EVENT_CLICK, (event: MouseEvent) => { + this._onClick(event) + }) + EventHandler.on(this._element, EVENT_DBLCLICK, (event: MouseEvent) => { + if (this._config.zoom && this._isOnMap(event)) { + this._zoomBy(ZOOM_STEP, this._toMapPoint(event.clientX, event.clientY), true) + } + }) + EventHandler.on(this._element, EVENT_CLICK, SELECTOR_ACTION, (event: Event) => { + const button = (event.target as Element).closest(SELECTOR_ACTION) + if (button?.getAttribute(ATTRIBUTE_ACTION) === ACTION_ZOOM_IN) { + this.zoomIn() + } else { + this.zoomOut() + } + }) + } + + // Getters + static get Default(): ComponentConfig { + return Default + } + + static get DefaultType(): Record { + return DefaultType + } + + static get NAME(): string { + return NAME + } + + // Static + static addMap(name: string, data: VectorMapData): void { + VectorMap.maps[name] = data + } + + // Public + render(): void { + this._config = this._getConfig(this._userConfig) as ComponentConfig + const map = (this._map = this._getMap()) + const { label } = this._config + + const svg = svgEl('svg') + svg.setAttribute('class', CLASS_NAME_SVG) + svg.setAttribute('viewBox', `0 0 ${map.width} ${map.height}`) + + // Without a label the map says nothing to a screen reader, so it is hidden + // rather than announced as an unnamed image. + if (label) { + svg.setAttribute('role', 'img') + svg.setAttribute('aria-label', label) + } else { + svg.setAttribute('aria-hidden', 'true') + } + + // The points go in after the shapes, so a small country shows on top of + // the large one around it. + const regions = Object.entries(map.regions) + for (const [code, region] of [...regions.filter(([, { point }]) => !point), ...regions.filter(([, { point }]) => point)]) { + svg.append(region.point ? this._createPoint(code, region) : this._createShape(code, region)) + } + + this._renderMarkers(svg, map) + + cancelAnimationFrame(this._frame) + this._pointers.clear() + this._hideTooltip() + this._getSvg()?.remove() + this._element.append(svg) + this._renderControls() + this._applyColors() + this._applySelected() + this._setView({ x: 0, y: 0, scale: 1 }) + this._applyValues() + + EventHandler.trigger(this._element, EVENT_RENDERED) + } + + update(values: VectorMapValues): void { + this._userConfig.values = values + this._config = this._getConfig(this._userConfig) as ComponentConfig + this._applyValues() + + EventHandler.trigger(this._element, EVENT_UPDATED) + } + + // The codes of the selected regions, in the order they were selected + getSelected(): string[] { + return [...(this._selected ?? [])] + } + + // Selects exactly these regions. Codes that are not on the map are left + // out, and all but the first when only one region can be selected. + setSelected(codes: string[]): void { + this._selected = this._toSelected(codes) + this._applySelected() + EventHandler.trigger(this._element, EVENT_SELECTED, { selected: this.getSelected() }) + } + + zoomIn(): void { + this._zoomBy(ZOOM_STEP, null, true) + } + + zoomOut(): void { + this._zoomBy(1 / ZOOM_STEP, null, true) + } + + // Back to the whole map + reset(): void { + this._animateTo({ x: 0, y: 0, scale: 1 }) + } + + dispose(): void { + cancelAnimationFrame(this._frame) + this._getSvg()?.remove() + this._getControls()?.remove() + this._getLegend()?.remove() + this._tooltip?.remove() + this._config.colors = [] + this._applyColors() + this._element.classList.remove(CLASS_NAME_ZOOMABLE, CLASS_NAME_DRAGGING, CLASS_NAME_SELECTABLE) + this._element.removeEventListener('wheel', this._onWheel) + super.dispose() + } + + // Private + _configAfterMerge(config: BaseConfig): BaseConfig { + config.values = toValues(config.values) + config.colors = toColors(config.colors) + config.markers = toMarkers(config.markers) + config.lines = toLines(config.lines) + return config + } + + _getSvg(): SVGSVGElement | null { + return this._element.querySelector(`.${CLASS_NAME_SVG}`) + } + + _getMap(): VectorMapData { + const { map } = this._config + if (typeof map !== 'string') { + return map + } + + // `tablerVectorMaps` is what a map file loaded with a ` -`} + code={` + +`} /> -Use `maps/world-merc.js` instead for the Mercator projection. +The styles are part of `tabler.css`. -## Usage - -Add an empty element with a height, then point jsVectorMap at it. The `map` option has to match the map file you loaded. - -```html -
-``` +With a bundler, import the component and the map, then register the map under a name: ```js -new jsVectorMap({ - selector: '#map-world', - map: 'world', +import { VectorMap } from '@tabler/core/dist/js/tabler-vector-map.esm.js'; +import { world } from '@tabler/core/dist/js/maps/world.esm.js'; + +VectorMap.addMap('world', world); +``` + +## Default markup + +Add `class="vector-map"` and `data-bs-toggle="vector-map"` to an empty element. Tabler draws the map on page load. The map is as wide as its parent and keeps its own proportions, so it needs no height. + +Set `data-bs-label` to a short text that says what the map shows. Without it the map is hidden from screen readers. + + +
+
+ +## Values + +Pass a number per country in `data-bs-values`, as a JSON object. The keys are ISO 3166-1 alpha-2 codes, such as `PL` or `US`. The country with the highest value gets the full color and the others get a lighter shade. + + +
+
+ +The shades are spread between the lowest and the highest value. Set `data-bs-min` and `data-bs-max` to use a fixed range instead, for example `0` and `100` for a percentage. + +### Color + +The map uses the primary color. Set `--tblr-vector-map-color` to change it. + + +
+
+ +### Color scale + +One color shows how much. A scale of several colors also shows good and bad, or cold and hot. Pass two to five colors in `data-bs-colors`, as a JSON array. The first color is for the lowest value and the last one for the highest. The values between them get a mix of the two nearest colors. + + +
+
+ +Any CSS color works, also a Tabler color such as `var(--tblr-red)`. The browser mixes the colors with `color-mix()`, so they follow the theme and you can change them later with CSS. + +The plugin writes the colors to `--tblr-vector-map-color-1`, `--tblr-vector-map-color-2` and so on, and their number to `--tblr-vector-map-colors`. To set a scale without JavaScript options, add the `vector-map-colors` class and these properties yourself: + +```html +
+``` + +With a scale, the lowest value gets the first color in full, so `--tblr-vector-map-value-min` is not used. Markers keep the color from `--tblr-vector-map-color`. + +### Legend + +Colors alone do not say how much. Add `data-bs-legend="true"` to show the scale under the map, as a bar between the lowest and the highest value. The bar uses the same colors as the map, also with a scale of several colors. + + +
+
+ +The two numbers are the range of the scale: `min` and `max` when you set them, the lowest and the highest value otherwise. Pass a function from JavaScript to add a unit or to format the numbers: + +```js +new tabler.VectorMap('#satisfaction', { + values: { PL: 88, DE: 96 }, + legend: (value) => `${value}%`, }); ``` -The map sizes itself from its container, so the container needs a height before the map is created. Call `updateSize()` on resize to keep it in step: - -```js -const map = new jsVectorMap({ selector: '#map-world', map: 'world' }); - -window.addEventListener('resize', () => map.updateSize()); -``` - -## Default map - -The code for a world map with the default options: - - - - - -## Sample demo - -The same map rendered on the page: - - - - +Set the size of the bar with `--tblr-vector-map-legend-width` and `--tblr-vector-map-legend-height`. ## Markers -Markers point out single locations, such as offices or customers: +Markers point at single places, such as offices or customers. Pass them in `data-bs-markers` as a JSON array. Each marker has a `lat`, a `lng` and an optional `name`. A marker keeps its size when the map is resized or zoomed. - +
## Lines -Lines connect locations, for a route or a link between two points: +Lines join two markers, for a route or a connection. Pass them in `data-bs-lines` as a JSON array. `from` and `to` are the names of two markers. The dashes move from the start of the line to its end, and stand still for users who ask for reduced motion. - +
+## Zoom + +Add `data-bs-zoom="true"` to let users look closer. The map gets two buttons, and reacts to the mouse wheel, a double click, a pinch and a drag. + + +
+
+ +While the pointer is over a zoomable map, the wheel zooms the map and does not scroll the page. Set `data-bs-zoom-on-scroll="false"` to keep the wheel for the page. On a touch screen a finger on the map moves the map, not the page, so leave some room around a large map. + +## Selecting countries + +Set `data-bs-select` to let users pick countries with a click. With `single` a click on another country moves the selection. With `multiple` every click adds a country. A click on a selected country takes it out again. Pass the countries that start selected in `data-bs-selected`. + + +
+
+ +A selected country gets an outline and keeps the color of its value. Change the outline with `--tblr-vector-map-selected-stroke` and `--tblr-vector-map-selected-stroke-width`. + +The map fires `selected.bs.vector-map` after every change. Read the selection from the event, or with `getSelected()`: + +```js +const element = document.getElementById('compare'); + +element.addEventListener('selected.bs.vector-map', (event) => { + console.log(event.selected); // ['PL', 'FR', 'BR', 'DE'] +}); + +tabler.VectorMap.getInstance(element).setSelected(['US', 'CA']); +``` + +## Clicks + +The map fires `regionclick.bs.vector-map` when a country is clicked and `markerclick.bs.vector-map` when a marker is clicked, also when nothing can be selected. Use them to open a page or to filter a table. A drag on a zoomable map is not a click. + +```js +element.addEventListener('regionclick.bs.vector-map', (event) => { + console.log(event.code, event.name, event.value); // 'PL', 'Poland', 54 +}); + +element.addEventListener('markerclick.bs.vector-map', (event) => { + console.log(event.name, event.lat, event.lng); +}); +``` + +Call `event.preventDefault()` in `regionclick.bs.vector-map` to keep that click from changing the selection. + +## Tooltip + +A tooltip shows the name of the country or marker under the pointer, with the value when the country has one. Set `data-bs-tooltip="false"` to turn it off. + +Pass a function from JavaScript to write your own text. It gets the item under the pointer and returns a string. The string is shown as plain text. Return an empty string to show nothing. + +```js +new tabler.VectorMap('#visits', { + values: { PL: 54, DE: 80 }, + tooltip: (item) => (item.type === 'region' && item.value !== undefined ? `${item.name}: ${item.value}%` : item.name), +}); +``` + +## Options + +Set options with data attributes or pass them to the constructor. For a data attribute, add `data-bs-` to the name and write it in kebab case, for example `data-bs-zoom-max`. + +| Name | Type | Default | Description | +| --- | --- | --- | --- | +| `map` | string, object | `'world'` | Name of a loaded map, or the map data itself. | +| `values` | object | `{}` | A number per region code. | +| `min` | number, null | `null` | Value that gets the lightest shade. The lowest value when `null`. | +| `max` | number, null | `null` | Value that gets the full color. The highest value when `null`. | +| `colors` | array | `[]` | Two to five colors of a scale, from the lowest value to the highest. | +| `markers` | array | `[]` | Places as `{ name, lat, lng }`. | +| `lines` | array | `[]` | Connections as `{ from, to }`, by marker name. | +| `tooltip` | boolean, function | `true` | Shows a tooltip, or builds its text. | +| `legend` | boolean, function | `false` | Shows the scale under the map, or formats its two numbers. | +| `select` | string | `'none'` | Lets users select countries: `'none'`, `'single'` or `'multiple'`. | +| `selected` | array | `[]` | Codes of the countries that start selected. | +| `zoom` | boolean | `false` | Lets users zoom and drag the map. | +| `zoomMax` | number | `8` | The largest magnification. | +| `zoomOnScroll` | boolean | `true` | Zooms with the mouse wheel. Needs `zoom`. | +| `zoomInLabel` | string | `'Zoom in'` | Accessible name of the zoom in button. | +| `zoomOutLabel` | string | `'Zoom out'` | Accessible name of the zoom out button. | +| `label` | string, null | `null` | Accessible name of the map. | + +## JavaScript + +Tabler wraps the element in a `VectorMap` component that works like the Bootstrap components: it is created once per element and stored on it. When the page is loaded, Tabler creates one for every element with `data-bs-toggle="vector-map"`. This is the code that runs: + + + +Create the component yourself for an element added later, or to pass the data from code: + +```js +const visits = tabler.VectorMap.getOrCreateInstance(document.getElementById('visits'), { + values: { PL: 54, DE: 80, FR: 66 }, +}); +``` + +Call `update()` with new values to shade the map again. The map is not drawn again, so this is cheap enough for live data: + +```js +visits.update({ PL: 61, DE: 77, FR: 70 }); +``` + +| Method | Description | +| --- | --- | +| `update(values)` | Shades the regions with new values. Fires `updated.bs.vector-map`. | +| `render()` | Reads the attributes again and draws the map from the start. Fires `rendered.bs.vector-map`. | +| `getSelected()` | Returns the codes of the selected countries. | +| `setSelected(codes)` | Selects exactly these countries. Fires `selected.bs.vector-map`. | +| `zoomIn()` | Zooms in one step, around the middle of the view. | +| `zoomOut()` | Zooms out one step. | +| `reset()` | Goes back to the whole map. | +| `dispose()` | Removes the map, the buttons, the legend, the tooltip and the component from the element. | +| `VectorMap.addMap(name, data)` | Static. Registers a map under a name. | +| `getInstance(element)` | Static. Returns the component for the element, or `null`. | +| `getOrCreateInstance(element, config)` | Static. Returns the component for the element and creates it when needed. | + +| Event | Description | +| --- | --- | +| `rendered.bs.vector-map` | Fired on the element after every render. | +| `updated.bs.vector-map` | Fired on the element after `update()`. | +| `regionclick.bs.vector-map` | Fired when a country is clicked. Has `code`, `name`, `value` when the country has one, and the element in `relatedTarget`. Can be prevented. | +| `markerclick.bs.vector-map` | Fired when a marker is clicked. Has `name`, `lat`, `lng` and the element in `relatedTarget`. | +| `selected.bs.vector-map` | Fired after the selection changes. Has the codes in `selected`, and the clicked `code` when a click made the change. | + +## Styling a single country + +Every country has its code in `data-region`, so one rule can color it. Set `--tblr-vector-map-region-color`, which works for a shape and for the dot of a small country: + +```css +.vector-map [data-region='PL'] { + --tblr-vector-map-region-color: var(--tblr-red); +} +``` + +## Custom properties + +The map reads its colors and sizes from custom properties on the element. Change them for one map with a `style` attribute, or for a section with a class. + +| Property | Default | Description | +| --- | --- | --- | +| `--tblr-vector-map-color` | `var(--tblr-primary)` | Color of the highest value, and of the markers. | +| `--tblr-vector-map-region-fill` | `var(--tblr-border-color)` | Fill of a country with no value. | +| `--tblr-vector-map-region-stroke` | `var(--tblr-bg-surface)` | Border between countries. | +| `--tblr-vector-map-region-stroke-width` | `1px` | Width of the border. | +| `--tblr-vector-map-value-min` | `0.1` | Share of the color the lowest value gets, from 0 to 1. | +| `--tblr-vector-map-color-1` to `-5` | none | Colors of a scale, from the lowest value to the highest. | +| `--tblr-vector-map-colors` | none | Number of colors in the scale. | +| `--tblr-vector-map-point-size` | `0.375rem` | Diameter of the dot of a small country. | +| `--tblr-vector-map-selected-stroke` | `var(--tblr-body-color)` | Outline of a selected country. | +| `--tblr-vector-map-selected-stroke-width` | `2px` | Width of that outline. | +| `--tblr-vector-map-marker-size` | `0.5rem` | Diameter of a marker. | +| `--tblr-vector-map-marker-color` | `var(--tblr-vector-map-color)` | Color of a marker. | +| `--tblr-vector-map-marker-halo-color` | `var(--tblr-bg-surface)` | Color of the ring around a marker and around the dot of a small country. | +| `--tblr-vector-map-marker-halo-width` | `2px` | Width of the ring. | +| `--tblr-vector-map-line-color` | `var(--tblr-secondary)` | Color of a line. | +| `--tblr-vector-map-line-width` | `1px` | Width of a line. | +| `--tblr-vector-map-line-dash` | `4px` | Length of a dash and of the gap after it. | +| `--tblr-vector-map-line-duration` | `1s` | Time one dash takes to move to the place of the next. | +| `--tblr-vector-map-legend-width` | `8rem` | Width of the bar of the legend. | +| `--tblr-vector-map-legend-height` | `0.5rem` | Height of the bar. | +| `--tblr-vector-map-controls-offset` | `var(--tblr-spacer-2)` | Distance of the zoom buttons from the corner. | + +## The world map + +The world map has 207 countries in the Miller projection, without Antarctica. Values for a code that is not on the map are skipped. + +### Small countries + +31 countries are too small to see as a shape on a map of the world, for example Andorra, San Marino, Malta or Singapore. The map shows such a country as a dot when it has a value. A dot works like any other country: it gets the same shade and has a tooltip. It keeps its size when the map is resized or zoomed. + + +
+
+ +The dots are the sovereign states that have no shape on the map, plus Hong Kong and Macao. Dependent territories, such as Gibraltar or Guam, are not on the map. Set the size of a dot with `--tblr-vector-map-point-size`. + +A small country with no value is hidden, so a map with a few markers does not fill up with grey dots. To show all of them, add this rule: + +```css +.vector-map-region-point:not([data-value]) { + display: inline; +} +``` + +Three territories have no ISO code. The map uses `XK` for Kosovo, `XC` for Northern Cyprus and `XS` for Somaliland. Borders follow the default view of Natural Earth. + ## Accessibility -- A map is a picture built from paths, and a screen reader reads them as a list of shapes. Give the container `role="img"` and an `aria-label` that says what it shows. -- The data behind the map has to be reachable another way. A table of the same values, next to or below the map, serves screen reader users and anyone printing the page. -- Hovering a region is mouse-only. Do not put anything there that is not also available in the text version. -- Colour scales are hard to read for many users. Add a legend with the actual numbers rather than color alone. -- Do not make every region focusable. A world map would be hundreds of tab stops. +- Set `data-bs-label`. The map is then an image with that name. The countries themselves are not read out one by one. +- The data behind the map has to be reachable another way. Put a table of the same values next to or below the map. It serves screen reader users and anyone who prints the page. +- The tooltip is for the pointer only. Do not put anything there that is not in the text version too. +- Shades of one color are hard to tell apart for many users. Turn on the legend, and for exact numbers add a table. +- Countries and markers can be clicked with a pointer only. They are not in the tab order, because a world map would be two hundred tab stops. When a click or a selection does something, offer the same choice in another control, such as a list of checkboxes or a select, and keep the two in step with `setSelected()`. +- The zoom buttons work with the keyboard and have accessible names. Change the names with `data-bs-zoom-in-label` and `data-bs-zoom-out-label` when the page is not in English. + +## Variables + + + +## Migration notes + +Before 1.7 this page used [jsVectorMap](https://jvm-docs.vercel.app/). Its files are still in `dist/libs/jsvectormap` and its styles are still in `tabler-vendors.css`, so a page that uses it keeps working. The demo and the docs now use the component above. diff --git a/docs/layouts/DocsLayout.astro b/docs/layouts/DocsLayout.astro index 1c32849c1..bd7fa8b4c 100644 --- a/docs/layouts/DocsLayout.astro +++ b/docs/layouts/DocsLayout.astro @@ -142,7 +142,7 @@ const editFilePath = // docs-libs for this page. In dev, file names stay unchanged // (e.g. dist/plyr.min.js keeps .min). -type Lib = { npm?: string; js?: string[]; css?: string[]; module?: { file: string; global: string }; addon?: string }; +type Lib = { npm?: string; js?: string[]; css?: string[]; module?: { file: string; global: string }; addon?: string; maps?: string[] }; const libEntries = Object.entries(libs as Record); const libUrl = (lib: Lib, file: string) => isExternal(file) @@ -155,6 +155,7 @@ const docsLibAddons = libEntries.filter(([name]) => docsLibs.includes(name)).fla const docsLibModules = libEntries .filter(([name]) => docsLibs.includes(name)) .flatMap(([, lib]) => (lib.module ? [`import * as lib from '${libUrl(lib, lib.module.file)}'; window.${lib.module.global} = lib`] : [])); +const docsLibMaps = libEntries.filter(([name]) => docsLibs.includes(name)).flatMap(([, lib]) => lib.maps ?? []); const docsLibJs = libEntries .filter(([name]) => docsLibs.includes(name)) .flatMap(([, lib]) => (lib.js ?? []).map((file) => libUrl(lib, file))); @@ -527,6 +528,7 @@ const relatedPages = await Promise.all( {docsLibAddons.map((addon) => `} />)} {libAddons.map((addon) => `} />)} {libAddons.map((addon) => - - - - ) + data && ( +
+ ) } diff --git a/shared/data/maps-vector.json b/shared/data/maps-vector.json index 9dd561630..25733348b 100644 --- a/shared/data/maps-vector.json +++ b/shared/data/maps-vector.json @@ -9,425 +9,245 @@ "map": "world", "color": "primary", "values": { - "AF": "scale2", - "AL": "scale2", - "DZ": "scale4", - "AO": "scale3", - "AG": "scale1", - "AR": "scale5", - "AM": "scale1", - "AU": "scale7", - "AT": "scale5", - "AZ": "scale3", - "BS": "scale1", - "BH": "scale2", - "BD": "scale4", - "BB": "scale1", - "BY": "scale3", - "BE": "scale5", - "BZ": "scale1", - "BJ": "scale1", - "BT": "scale1", - "BO": "scale2", - "BA": "scale2", - "BW": "scale2", - "BR": "scale8", - "BN": "scale2", - "BG": "scale2", - "BF": "scale1", - "BI": "scale1", - "KH": "scale2", - "CM": "scale2", - "CA": "scale7", - "CV": "scale1", - "CF": "scale1", - "TD": "scale1", - "CL": "scale4", - "CN": "scale9", - "CO": "scale5", - "KM": "scale1", - "CD": "scale2", - "CG": "scale2", - "CR": "scale2", - "CI": "scale2", - "HR": "scale3", - "CY": "scale2", - "CZ": "scale4", - "DK": "scale5", - "DJ": "scale1", - "DM": "scale1", - "DO": "scale3", - "EC": "scale3", - "EG": "scale5", - "SV": "scale2", - "GQ": "scale2", - "ER": "scale1", - "EE": "scale2", - "ET": "scale2", - "FJ": "scale1", - "FI": "scale5", - "FR": "scale8", - "GA": "scale2", - "GM": "scale1", - "GE": "scale2", - "DE": "scale8", - "GH": "scale2", - "GR": "scale5", - "GD": "scale1", - "GT": "scale2", - "GN": "scale1", - "GW": "scale1", - "GY": "scale1", - "HT": "scale1", - "HN": "scale2", - "HK": "scale5", - "HU": "scale4", - "IS": "scale2", - "IN": "scale7", - "ID": "scale6", - "IR": "scale5", - "IQ": "scale3", - "IE": "scale5", - "IL": "scale5", - "IT": "scale8", - "JM": "scale2", - "JP": "scale9", - "JO": "scale2", - "KZ": "scale4", - "KE": "scale2", - "KI": "scale1", - "KR": "scale6", - "KW": "scale4", - "KG": "scale1", - "LA": "scale1", - "LV": "scale2", - "LB": "scale2", - "LS": "scale1", - "LR": "scale1", - "LY": "scale3", - "LT": "scale2", - "LU": "scale3", - "MK": "scale1", - "MG": "scale1", - "MW": "scale1", - "MY": "scale5", - "MV": "scale1", - "ML": "scale1", - "MT": "scale1", - "MR": "scale1", - "MU": "scale1", - "MX": "scale7", - "MD": "scale1", - "MN": "scale1", - "ME": "scale1", - "MA": "scale3", - "MZ": "scale2", - "MM": "scale2", - "NA": "scale2", - "NP": "scale2", - "NL": "scale6", - "NZ": "scale4", - "NI": "scale1", - "NE": "scale1", - "NG": "scale5", - "NO": "scale5", - "OM": "scale3", - "PK": "scale4", - "PA": "scale2", - "PG": "scale1", - "PY": "scale2", - "PE": "scale4", - "PH": "scale4", - "PL": "scale10", - "PT": "scale5", - "QA": "scale4", - "RO": "scale4", - "RU": "scale7", - "RW": "scale1", - "WS": "scale1", - "ST": "scale1", - "SA": "scale5", - "SN": "scale2", - "RS": "scale2", - "SC": "scale1", - "SL": "scale1", - "SG": "scale5", - "SK": "scale3", - "SI": "scale2", - "SB": "scale1", - "ZA": "scale5", - "ES": "scale7", - "LK": "scale2", - "KN": "scale1", - "LC": "scale1", - "VC": "scale1", - "SD": "scale3", - "SR": "scale1", - "SZ": "scale1", - "SE": "scale5", - "CH": "scale6", - "SY": "scale3", - "TW": "scale5", - "TJ": "scale1", - "TZ": "scale2", - "TH": "scale5", - "TL": "scale1", - "TG": "scale1", - "TO": "scale1", - "TT": "scale2", - "TN": "scale2", - "TR": "scale6", - "TM": "scale1", - "UG": "scale2", - "UA": "scale4", - "AE": "scale5", - "GB": "scale8", - "US": "scale10", - "UY": "scale2", - "UZ": "scale2", - "VU": "scale1", - "VE": "scale5", - "VN": "scale4", - "YE": "scale2", - "ZM": "scale2", - "ZW": "scale1" - } - }, - "world-merc": { - "title": "World map", - "map": "world_merc", - "color": "primary", - "values": { - "AF": "scale2", - "AL": "scale2", - "DZ": "scale4", - "AO": "scale3", - "AG": "scale1", - "AR": "scale5", - "AM": "scale1", - "AU": "scale7", - "AT": "scale5", - "AZ": "scale3", - "BS": "scale1", - "BH": "scale2", - "BD": "scale4", - "BB": "scale1", - "BY": "scale3", - "BE": "scale5", - "BZ": "scale1", - "BJ": "scale1", - "BT": "scale1", - "BO": "scale2", - "BA": "scale2", - "BW": "scale2", - "BR": "scale8", - "BN": "scale2", - "BG": "scale2", - "BF": "scale1", - "BI": "scale1", - "KH": "scale2", - "CM": "scale2", - "CA": "scale7", - "CV": "scale1", - "CF": "scale1", - "TD": "scale1", - "CL": "scale4", - "CN": "scale9", - "CO": "scale5", - "KM": "scale1", - "CD": "scale2", - "CG": "scale2", - "CR": "scale2", - "CI": "scale2", - "HR": "scale3", - "CY": "scale2", - "CZ": "scale4", - "DK": "scale5", - "DJ": "scale1", - "DM": "scale1", - "DO": "scale3", - "EC": "scale3", - "EG": "scale5", - "SV": "scale2", - "GQ": "scale2", - "ER": "scale1", - "EE": "scale2", - "ET": "scale2", - "FJ": "scale1", - "FI": "scale5", - "FR": "scale8", - "GA": "scale2", - "GM": "scale1", - "GE": "scale2", - "DE": "scale8", - "GH": "scale2", - "GR": "scale5", - "GD": "scale1", - "GT": "scale2", - "GN": "scale1", - "GW": "scale1", - "GY": "scale1", - "HT": "scale1", - "HN": "scale2", - "HK": "scale5", - "HU": "scale4", - "IS": "scale2", - "IN": "scale7", - "ID": "scale6", - "IR": "scale5", - "IQ": "scale3", - "IE": "scale5", - "IL": "scale5", - "IT": "scale8", - "JM": "scale2", - "JP": "scale9", - "JO": "scale2", - "KZ": "scale4", - "KE": "scale2", - "KI": "scale1", - "KR": "scale6", - "KW": "scale4", - "KG": "scale1", - "LA": "scale1", - "LV": "scale2", - "LB": "scale2", - "LS": "scale1", - "LR": "scale1", - "LY": "scale3", - "LT": "scale2", - "LU": "scale3", - "MK": "scale1", - "MG": "scale1", - "MW": "scale1", - "MY": "scale5", - "MV": "scale1", - "ML": "scale1", - "MT": "scale1", - "MR": "scale1", - "MU": "scale1", - "MX": "scale7", - "MD": "scale1", - "MN": "scale1", - "ME": "scale1", - "MA": "scale3", - "MZ": "scale2", - "MM": "scale2", - "NA": "scale2", - "NP": "scale2", - "NL": "scale6", - "NZ": "scale4", - "NI": "scale1", - "NE": "scale1", - "NG": "scale5", - "NO": "scale5", - "OM": "scale3", - "PK": "scale4", - "PA": "scale2", - "PG": "scale1", - "PY": "scale2", - "PE": "scale4", - "PH": "scale4", - "PL": "scale10", - "PT": "scale5", - "QA": "scale4", - "RO": "scale4", - "RU": "scale7", - "RW": "scale1", - "WS": "scale1", - "ST": "scale1", - "SA": "scale5", - "SN": "scale2", - "RS": "scale2", - "SC": "scale1", - "SL": "scale1", - "SG": "scale5", - "SK": "scale3", - "SI": "scale2", - "SB": "scale1", - "ZA": "scale5", - "ES": "scale7", - "LK": "scale2", - "KN": "scale1", - "LC": "scale1", - "VC": "scale1", - "SD": "scale3", - "SR": "scale1", - "SZ": "scale1", - "SE": "scale5", - "CH": "scale6", - "SY": "scale3", - "TW": "scale5", - "TJ": "scale1", - "TZ": "scale2", - "TH": "scale5", - "TL": "scale1", - "TG": "scale1", - "TO": "scale1", - "TT": "scale2", - "TN": "scale2", - "TR": "scale6", - "TM": "scale1", - "UG": "scale2", - "UA": "scale4", - "AE": "scale5", - "GB": "scale8", - "US": "scale10", - "UY": "scale2", - "UZ": "scale2", - "VU": "scale1", - "VE": "scale5", - "VN": "scale4", - "YE": "scale2", - "ZM": "scale2", - "ZW": "scale1" + "AF": 2, + "AL": 2, + "DZ": 4, + "AO": 3, + "AG": 1, + "AR": 5, + "AM": 1, + "AU": 7, + "AT": 5, + "AZ": 3, + "BS": 1, + "BH": 2, + "BD": 4, + "BB": 1, + "BY": 3, + "BE": 5, + "BZ": 1, + "BJ": 1, + "BT": 1, + "BO": 2, + "BA": 2, + "BW": 2, + "BR": 8, + "BN": 2, + "BG": 2, + "BF": 1, + "BI": 1, + "KH": 2, + "CM": 2, + "CA": 7, + "CV": 1, + "CF": 1, + "TD": 1, + "CL": 4, + "CN": 9, + "CO": 5, + "KM": 1, + "CD": 2, + "CG": 2, + "CR": 2, + "CI": 2, + "HR": 3, + "CY": 2, + "CZ": 4, + "DK": 5, + "DJ": 1, + "DM": 1, + "DO": 3, + "EC": 3, + "EG": 5, + "SV": 2, + "GQ": 2, + "ER": 1, + "EE": 2, + "ET": 2, + "FJ": 1, + "FI": 5, + "FR": 8, + "GA": 2, + "GM": 1, + "GE": 2, + "DE": 8, + "GH": 2, + "GR": 5, + "GD": 1, + "GT": 2, + "GN": 1, + "GW": 1, + "GY": 1, + "HT": 1, + "HN": 2, + "HK": 5, + "HU": 4, + "IS": 2, + "IN": 7, + "ID": 6, + "IR": 5, + "IQ": 3, + "IE": 5, + "IL": 5, + "IT": 8, + "JM": 2, + "JP": 9, + "JO": 2, + "KZ": 4, + "KE": 2, + "KI": 1, + "KR": 6, + "KW": 4, + "KG": 1, + "LA": 1, + "LV": 2, + "LB": 2, + "LS": 1, + "LR": 1, + "LY": 3, + "LT": 2, + "LU": 3, + "MK": 1, + "MG": 1, + "MW": 1, + "MY": 5, + "MV": 1, + "ML": 1, + "MT": 1, + "MR": 1, + "MU": 1, + "MX": 7, + "MD": 1, + "MN": 1, + "ME": 1, + "MA": 3, + "MZ": 2, + "MM": 2, + "NA": 2, + "NP": 2, + "NL": 6, + "NZ": 4, + "NI": 1, + "NE": 1, + "NG": 5, + "NO": 5, + "OM": 3, + "PK": 4, + "PA": 2, + "PG": 1, + "PY": 2, + "PE": 4, + "PH": 4, + "PL": 10, + "PT": 5, + "QA": 4, + "RO": 4, + "RU": 7, + "RW": 1, + "WS": 1, + "ST": 1, + "SA": 5, + "SN": 2, + "RS": 2, + "SC": 1, + "SL": 1, + "SG": 5, + "SK": 3, + "SI": 2, + "SB": 1, + "ZA": 5, + "ES": 7, + "LK": 2, + "KN": 1, + "LC": 1, + "VC": 1, + "SD": 3, + "SR": 1, + "SZ": 1, + "SE": 5, + "CH": 6, + "SY": 3, + "TW": 5, + "TJ": 1, + "TZ": 2, + "TH": 5, + "TL": 1, + "TG": 1, + "TO": 1, + "TT": 2, + "TN": 2, + "TR": 6, + "TM": 1, + "UG": 2, + "UA": 4, + "AE": 5, + "GB": 8, + "US": 10, + "UY": 2, + "UZ": 2, + "VU": 1, + "VE": 5, + "VN": 4, + "YE": 2, + "ZM": 2, + "ZW": 1 } }, "world-markers": { "title": "Map with markers", - "map": "world_merc", + "map": "world", "color": "red", "markers": [ { "name": "Russia", - "coords": "61.524, 105.3188" + "lat": 61.524, + "lng": 105.3188 }, { "name": "Canada", - "coords": "56.1304, -106.3468" + "lat": 56.1304, + "lng": -106.3468 }, { "name": "Greenland", - "coords": "71.7069, -42.6043" + "lat": 71.7069, + "lng": -42.6043 }, { "name": "Egypt", - "coords": "26.8206, 30.8025" + "lat": 26.8206, + "lng": 30.8025 }, { "name": "Brazil", - "coords": "-14.235, -51.9253" + "lat": -14.235, + "lng": -51.9253 }, { "name": "China", - "coords": "35.8617, 104.1954" + "lat": 35.8617, + "lng": 104.1954 }, { "name": "United States", - "coords": "37.0902, -95.7129" + "lat": 37.0902, + "lng": -95.7129 }, { "name": "Norway", - "coords": "60.472024, 8.468946" + "lat": 60.472024, + "lng": 8.468946 }, { "name": "Ukraine", - "coords": "48.379433, 31.16558" + "lat": 48.379433, + "lng": 31.16558 } ] }, "world-lines": { - "title": "Map with markers", - "map": "world_merc", + "title": "Map with markers and lines", + "map": "world", "color": "primary", "lines": [ { @@ -462,40 +282,263 @@ "markers": [ { "name": "Russia", - "coords": "61.524, 105.3188" + "lat": 61.524, + "lng": 105.3188 }, { "name": "Canada", - "coords": "56.1304, -106.3468" + "lat": 56.1304, + "lng": -106.3468 }, { "name": "Greenland", - "coords": "71.7069, -42.6043" + "lat": 71.7069, + "lng": -42.6043 }, { "name": "Egypt", - "coords": "26.8206, 30.8025" + "lat": 26.8206, + "lng": 30.8025 }, { "name": "Brazil", - "coords": "-14.235, -51.9253" + "lat": -14.235, + "lng": -51.9253 }, { "name": "China", - "coords": "35.8617, 104.1954" + "lat": 35.8617, + "lng": 104.1954 }, { "name": "United States", - "coords": "37.0902, -95.7129" + "lat": 37.0902, + "lng": -95.7129 }, { "name": "Norway", - "coords": "60.472024, 8.468946" + "lat": 60.472024, + "lng": 8.468946 }, { "name": "Ukraine", - "coords": "48.379433, 31.16558" + "lat": 48.379433, + "lng": 31.16558 } ] + }, + "world-zoom": { + "title": "Map with zoom", + "map": "world", + "color": "green", + "zoom": true, + "values": { + "PL": 8, + "DE": 6, + "FR": 5, + "ES": 3, + "IT": 4, + "GB": 7, + "SE": 2, + "UA": 3, + "RO": 2, + "CZ": 5 + } + }, + "world-colors": { + "title": "Map with a color scale", + "map": "world", + "colors": ["var(--tblr-red)", "var(--tblr-yellow)", "var(--tblr-green)"], + "values": { + "AF": 2, + "AL": 2, + "DZ": 4, + "AO": 3, + "AG": 1, + "AR": 5, + "AM": 1, + "AU": 7, + "AT": 5, + "AZ": 3, + "BS": 1, + "BH": 2, + "BD": 4, + "BB": 1, + "BY": 3, + "BE": 5, + "BZ": 1, + "BJ": 1, + "BT": 1, + "BO": 2, + "BA": 2, + "BW": 2, + "BR": 8, + "BN": 2, + "BG": 2, + "BF": 1, + "BI": 1, + "KH": 2, + "CM": 2, + "CA": 7, + "CV": 1, + "CF": 1, + "TD": 1, + "CL": 4, + "CN": 9, + "CO": 5, + "KM": 1, + "CD": 2, + "CG": 2, + "CR": 2, + "CI": 2, + "HR": 3, + "CY": 2, + "CZ": 4, + "DK": 5, + "DJ": 1, + "DM": 1, + "DO": 3, + "EC": 3, + "EG": 5, + "SV": 2, + "GQ": 2, + "ER": 1, + "EE": 2, + "ET": 2, + "FJ": 1, + "FI": 5, + "FR": 8, + "GA": 2, + "GM": 1, + "GE": 2, + "DE": 8, + "GH": 2, + "GR": 5, + "GD": 1, + "GT": 2, + "GN": 1, + "GW": 1, + "GY": 1, + "HT": 1, + "HN": 2, + "HK": 5, + "HU": 4, + "IS": 2, + "IN": 7, + "ID": 6, + "IR": 5, + "IQ": 3, + "IE": 5, + "IL": 5, + "IT": 8, + "JM": 2, + "JP": 9, + "JO": 2, + "KZ": 4, + "KE": 2, + "KI": 1, + "KR": 6, + "KW": 4, + "KG": 1, + "LA": 1, + "LV": 2, + "LB": 2, + "LS": 1, + "LR": 1, + "LY": 3, + "LT": 2, + "LU": 3, + "MK": 1, + "MG": 1, + "MW": 1, + "MY": 5, + "MV": 1, + "ML": 1, + "MT": 1, + "MR": 1, + "MU": 1, + "MX": 7, + "MD": 1, + "MN": 1, + "ME": 1, + "MA": 3, + "MZ": 2, + "MM": 2, + "NA": 2, + "NP": 2, + "NL": 6, + "NZ": 4, + "NI": 1, + "NE": 1, + "NG": 5, + "NO": 5, + "OM": 3, + "PK": 4, + "PA": 2, + "PG": 1, + "PY": 2, + "PE": 4, + "PH": 4, + "PL": 10, + "PT": 5, + "QA": 4, + "RO": 4, + "RU": 7, + "RW": 1, + "WS": 1, + "ST": 1, + "SA": 5, + "SN": 2, + "RS": 2, + "SC": 1, + "SL": 1, + "SG": 5, + "SK": 3, + "SI": 2, + "SB": 1, + "ZA": 5, + "ES": 7, + "LK": 2, + "KN": 1, + "LC": 1, + "VC": 1, + "SD": 3, + "SR": 1, + "SZ": 1, + "SE": 5, + "CH": 6, + "SY": 3, + "TW": 5, + "TJ": 1, + "TZ": 2, + "TH": 5, + "TL": 1, + "TG": 1, + "TO": 1, + "TT": 2, + "TN": 2, + "TR": 6, + "TM": 1, + "UG": 2, + "UA": 4, + "AE": 5, + "GB": 8, + "US": 10, + "UY": 2, + "UZ": 2, + "VU": 1, + "VE": 5, + "VN": 4, + "YE": 2, + "ZM": 2, + "ZW": 1 + }, + "legend": true + }, + "world-select": { + "title": "Map with selection", + "map": "world", + "select": "multiple", + "selected": ["PL", "FR", "BR", "AU"] } -} \ No newline at end of file +} diff --git a/shared/data/open-source.json b/shared/data/open-source.json index bd134e951..7fd9d5353 100644 --- a/shared/data/open-source.json +++ b/shared/data/open-source.json @@ -89,6 +89,13 @@ "description": "Lightweight JavaScript library for creating interactive maps and data visualizations.", "license": "MIT" }, + { + "name": "Natural Earth", + "lib": "vector-map", + "url": "https://www.naturalearthdata.com/", + "description": "Public domain map dataset, the source of the country shapes in the vector map.", + "license": "Public Domain" + }, { "name": "List.js", "npm": "list.js", diff --git a/shared/layouts/BaseLayout.astro b/shared/layouts/BaseLayout.astro index 8352c7d4e..4bbea0bda 100644 --- a/shared/layouts/BaseLayout.astro +++ b/shared/layouts/BaseLayout.astro @@ -9,7 +9,7 @@ import { themeDefaults, themePresets, sidebarOnlyKeys, navbarOnlyKeys, themeData interface Props { title?: string | undefined - /** Third-party libs from libs.json, e.g. ['apexcharts', 'jsvectormap'] */ + /** Third-party libs from libs.json, e.g. ['apexcharts', 'vector-map'] */ pageLibs?: string[] | undefined /** Extra body classes, e.g. "layout-boxed" / "layout-fluid" */ bodyClass?: string | undefined @@ -39,7 +39,7 @@ const isProduction = process.env.VERCEL_ENV === 'production' // RTL swaps tabler/plugin stylesheets for their .rtl.css variants (demo stays LTR) const rtlSuffix = rtl ? '.rtl' : '' -type Lib = { npm?: string; js?: string[]; css?: string[]; head?: boolean; module?: { file: string; global: string }; addon?: string } +type Lib = { npm?: string; js?: string[]; css?: string[]; head?: boolean; module?: { file: string; global: string }; addon?: string; maps?: string[] } const unknownLibs = pageLibs.filter((name) => !(name in libs)) if (unknownLibs.length > 0) { throw new Error(`BaseLayout: unknown pageLibs ${unknownLibs.map((name) => `"${name}"`).join(', ')} — use a key from core/libs.json`) @@ -54,6 +54,8 @@ const libCssFiles = pageLibEntries.flatMap(([, lib]) => (lib.css ?? []).map((fil const libModules = pageLibEntries.flatMap(([, lib]) => (lib.module ? [`import * as lib from '${libHref(lib, lib.module.file)}'\n window.${lib.module.global} = lib`] : [])) // Tabler add-on bundles (dist/js) that a library needs, loaded after tabler.js const libAddons = pageLibEntries.flatMap(([, lib]) => (lib.addon ? [lib.addon] : [])) +// Map files of the vector map (dist/js/maps), which are plain data +const libMaps = pageLibEntries.flatMap(([, lib]) => lib.maps ?? []) const libJsFiles = (head: boolean) => pageLibEntries.filter(([, lib]) => Boolean(lib.head) === head).flatMap(([, lib]) => (lib.js ?? []).map((file) => libHref(lib, file))) --- @@ -140,6 +142,7 @@ const libJsFiles = (head: boolean) => pageLibEntries.filter(([, lib]) => Boolean {libAddons.map((addon) =>