37 Commits
1.2 ... 1.3b

Author SHA1 Message Date
18725261e3 Update app/build.gradle 2026-06-06 19:34:25 +02:00
soraefir
cc1a0c1aca Fix region saving bug 2026-06-06 19:30:18 +02:00
soraefir
f2a5efcec5 Update saving logic 2026-06-06 18:54:09 +02:00
soraefir
cfa784991b Updated SVGs and improved scripting
# Conflicts:
#	yarn.lock
2026-06-06 18:23:41 +02:00
soraefir
14f8543d3d Fix zoom and topbar 2026-06-06 18:23:26 +02:00
soraefir
5705749d12 Fix Caspian Sea 2026-06-06 18:23:26 +02:00
bot
1d0b814e77 Merge pull request 'Lock file maintenance' (#513) from renovate/lock-file-maintenance into main 2026-06-06 04:01:52 +02:00
Renovate Bot
ecc26f811a Lock file maintenance 2026-06-06 02:01:48 +00:00
bot
8cd93d866b Merge pull request 'Update plugin org.jetbrains.kotlin.plugin.serialization to v2.4.0' (#512) from renovate/org.jetbrains.kotlin.plugin.serialization-2.x into main 2026-06-05 04:05:29 +02:00
Renovate Bot
6bf4034e1e Update plugin org.jetbrains.kotlin.plugin.serialization to v2.4.0 2026-06-05 02:02:00 +00:00
bot
977321ddb5 Merge pull request 'Update plugin org.jetbrains.kotlin.plugin.compose to v2.4.0' (#511) from renovate/org.jetbrains.kotlin.plugin.compose-2.x into main 2026-06-04 04:11:32 +02:00
bot
bee96b5d9b Merge pull request 'Update plugin org.jetbrains.kotlin.android to v2.4.0' (#510) from renovate/org.jetbrains.kotlin.android-2.x into main 2026-06-04 04:11:19 +02:00
Renovate Bot
6d21f0da6d Update plugin org.jetbrains.kotlin.plugin.compose to v2.4.0 2026-06-04 02:11:18 +00:00
Renovate Bot
445ccbcac0 Update plugin org.jetbrains.kotlin.android to v2.4.0 2026-06-04 02:02:01 +00:00
bot
225e5bfdc8 Merge pull request 'Lock file maintenance' (#509) from renovate/lock-file-maintenance into main 2026-05-31 04:02:13 +02:00
Renovate Bot
0c446f0d59 Lock file maintenance 2026-05-31 02:02:04 +00:00
bot
7c0b9bda80 Merge pull request 'Update dependency mapshaper to v0.7.22' (#508) from renovate/mapshaper-0.x-lockfile into main 2026-05-30 04:02:10 +02:00
Renovate Bot
eaa0278764 Update dependency mapshaper to v0.7.22 2026-05-30 02:02:02 +00:00
bot
eeac01f638 Merge pull request 'Update dependency com.mikepenz:aboutlibraries-compose-m3 to v14.2.1' (#504) from renovate/com.mikepenz-aboutlibraries-compose-m3-14.x into main 2026-05-30 04:01:32 +02:00
Renovate Bot
9f8d5aaa18 Update dependency com.mikepenz:aboutlibraries-compose-m3 to v14.2.1 2026-05-30 02:01:26 +00:00
cdb9d51257 Update README.md 2026-05-29 19:01:20 +02:00
bot
2d6b895f57 Merge pull request 'Update dependency mapshaper to v0.7.21' (#507) from renovate/mapshaper-0.x-lockfile into main 2026-05-28 04:02:20 +02:00
Renovate Bot
80e191a50d Update dependency mapshaper to v0.7.21 2026-05-28 02:02:07 +00:00
bot
4114185a73 Merge pull request 'Update plugin com.mikepenz.aboutlibraries.plugin to v14.2.1' (#506) from renovate/com.mikepenz.aboutlibraries.plugin-14.x into main 2026-05-26 04:01:40 +02:00
bot
24fe56c02a Merge pull request 'Update dependency com.mikepenz:aboutlibraries-core to v14.2.1' (#505) from renovate/com.mikepenz-aboutlibraries-core-14.x into main 2026-05-26 04:01:35 +02:00
Renovate Bot
d83234cf5b Update plugin com.mikepenz.aboutlibraries.plugin to v14.2.1 2026-05-26 02:01:33 +00:00
Renovate Bot
e608b22c0c Update dependency com.mikepenz:aboutlibraries-core to v14.2.1 2026-05-26 02:01:31 +00:00
soraefir
f8ed30cd73 Fix Top bar padding on android16+ 2026-05-25 15:20:41 +02:00
soraefir
c50933908c Fix crash due to rename 2026-05-25 14:14:42 +02:00
bot
77edae3585 Merge pull request 'Update dependency com.mikepenz:aboutlibraries to v14.2.1' (#503) from renovate/com.mikepenz-aboutlibraries-14.x into main 2026-05-25 04:01:29 +02:00
Renovate Bot
50c152084e Update dependency com.mikepenz:aboutlibraries to v14.2.1 2026-05-25 02:01:22 +00:00
b0a107c749 Update README.md 2026-05-24 11:58:56 +02:00
bot
91050826b2 Merge pull request 'Lock file maintenance' (#502) from renovate/lock-file-maintenance into main 2026-05-24 04:04:58 +02:00
Renovate Bot
1004119fed Lock file maintenance 2026-05-24 02:04:55 +00:00
d262331d1b Update .github/workflows/build.yml 2026-05-23 14:45:03 +02:00
7440e85987 Update app/build.gradle 2026-05-23 14:42:40 +02:00
2351512af8 Update app/build.gradle 2026-05-23 14:42:30 +02:00
22 changed files with 3437 additions and 16422 deletions

View File

@@ -24,7 +24,9 @@ jobs:
steps: steps:
- uses: actions/checkout@v6 - uses: actions/checkout@v6
with:
fetch-depth: 0
- name: set up secrets - name: set up secrets
run: | run: |
echo "${{ secrets.RELEASE_KEYSTORE }}" > keystore.asc echo "${{ secrets.RELEASE_KEYSTORE }}" > keystore.asc
@@ -49,7 +51,9 @@ jobs:
uses: gradle/actions/setup-gradle@v6 uses: gradle/actions/setup-gradle@v6
- name: Build APK - name: Build APK
run: ./gradlew assembleSignedRelease run: |
VERSION_CODE=$(git rev-list --count HEAD)
./gradlew assembleSignedRelease -PVERSION_CODE=$VERSION_CODE
- name: Release - name: Release
uses: softprops/action-gh-release@v3 uses: softprops/action-gh-release@v3

View File

@@ -5,6 +5,8 @@
<p>A virtual scratchmap of the world</p> <p>A virtual scratchmap of the world</p>
<a href="https://ko-fi.com/I2I615VP5M"><img src="https://ko-fi.com/img/githubbutton_sm.svg" alt="ko-fi"></a>
<br>
<img src="https://forthebadge.com/images/badges/built-for-android.svg" alt="Built for Android"> <img src="https://forthebadge.com/images/badges/built-for-android.svg" alt="Built for Android">
<img src="https://forthebadge.com/images/badges/built-with-love.svg" alt="Built with love"> <img src="https://forthebadge.com/images/badges/built-with-love.svg" alt="Built with love">
<br> <br>
@@ -71,7 +73,7 @@ Thanks to all contributors, the developers of our dependencies, and our users.
## 📝 License ## 📝 License
``` ```
Copyright (C) 2024 Helcel & MYDOLI Copyright (C) 2026 Helcel & MYDOLI
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by

View File

@@ -1,21 +1,8 @@
def getCommitCount() {
try {
def stdout = new ByteArrayOutputStream()
exec {
commandLine 'git', 'rev-list', '--count', 'HEAD'
standardOutput = stdout
}
return stdout.toString().trim().toInteger()
} catch (ignored) {
return 1
}
}
plugins { plugins {
id 'com.android.application' id 'com.android.application'
id 'org.jetbrains.kotlin.plugin.serialization' version '2.3.21' id 'org.jetbrains.kotlin.plugin.serialization' version '2.4.0'
id 'org.jetbrains.kotlin.plugin.compose' version '2.3.21' id 'org.jetbrains.kotlin.plugin.compose' version '2.4.0'
id 'com.mikepenz.aboutlibraries.plugin' version '14.2.0' id 'com.mikepenz.aboutlibraries.plugin' version '14.2.1'
} }
android { android {
@@ -28,8 +15,8 @@ android {
applicationId 'net.helcel.beans' applicationId 'net.helcel.beans'
minSdk = 28 minSdk = 28
targetSdk = 37 targetSdk = 37
versionName "1.2" versionName "1.3b"
versionCode getCommitCount() versionCode project.hasProperty('VERSION_CODE') ? project.property('VERSION_CODE').toInteger() : 1
} }
signingConfigs { signingConfigs {
register("release") { register("release") {
@@ -118,11 +105,17 @@ dependencies {
implementation 'com.caverock:androidsvg-aar:1.4' implementation 'com.caverock:androidsvg-aar:1.4'
implementation 'com.github.chrisbanes:PhotoView:2.3.0' implementation 'com.github.chrisbanes:PhotoView:2.3.0'
implementation 'com.mikepenz:aboutlibraries:14.2.0' implementation 'com.mikepenz:aboutlibraries:14.2.1'
implementation 'com.mikepenz:aboutlibraries-compose-m3:14.2.0' implementation 'com.mikepenz:aboutlibraries-compose-m3:14.2.1'
implementation 'com.mikepenz:aboutlibraries-core:14.2.0' implementation 'com.mikepenz:aboutlibraries-core:14.2.1'
implementation platform('androidx.compose:compose-bom:2026.05.01') implementation platform('androidx.compose:compose-bom:2026.05.01')
debugImplementation 'androidx.compose.ui:ui-tooling:1.11.2' debugImplementation 'androidx.compose.ui:ui-tooling:1.11.2'
}
tasks.configureEach { task ->
if (task.name.startsWith("merge") && task.name.endsWith("Assets")) {
task.outputs.upToDateWhen { false }
}
} }

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 6.1 MiB

After

Width:  |  Height:  |  Size: 3.9 MiB

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 6.0 MiB

After

Width:  |  Height:  |  Size: 3.7 MiB

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 6.1 MiB

After

Width:  |  Height:  |  Size: 4.0 MiB

View File

@@ -9,10 +9,12 @@ import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.statusBarsPadding
import androidx.compose.material.Icon import androidx.compose.material.Icon
import androidx.compose.material.IconButton import androidx.compose.material.IconButton
import androidx.compose.material.MaterialTheme import androidx.compose.material.MaterialTheme
import androidx.compose.material.Scaffold import androidx.compose.material.Scaffold
import androidx.compose.material.Surface
import androidx.compose.material.Text import androidx.compose.material.Text
import androidx.compose.material.TopAppBar import androidx.compose.material.TopAppBar
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
@@ -22,6 +24,8 @@ import androidx.compose.material.icons.filled.Settings
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import androidx.compose.ui.viewinterop.AndroidView import androidx.compose.ui.viewinterop.AndroidView
import androidx.navigation.NavHostController import androidx.navigation.NavHostController
import androidx.navigation.compose.NavHost import androidx.navigation.compose.NavHost
@@ -46,12 +50,12 @@ class MainScreen : ComponentActivity() {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
actionBar?.hide() actionBar?.hide()
Settings.start(this) Settings.start(this)
GeoLocImporter.importStates(this)
Data.loadData(this, Int.MIN_VALUE) Data.loadData(this, Int.MIN_VALUE)
GeoLocImporter.importStates(this)
setContent { setContent {
SysTheme { SysTheme {
Box(modifier = Modifier.fillMaxSize().background(MaterialTheme.colors.background)) { Box(modifier = Modifier.fillMaxSize().background(MaterialTheme.colors.primary).statusBarsPadding(),) {
AppNavHost(psvg, css) AppNavHost(psvg, css)
} }
} }
@@ -110,6 +114,7 @@ class MainScreen : ComponentActivity() {
PhotoView(ctx).apply { PhotoView(ctx).apply {
setLayerType(ImageView.LAYER_TYPE_SOFTWARE, null) setLayerType(ImageView.LAYER_TYPE_SOFTWARE, null)
setImageDrawable(drawable) setImageDrawable(drawable)
maximumScale = 32f
scaleType = ImageView.ScaleType.FIT_CENTER scaleType = ImageView.ScaleType.FIT_CENTER
} }
}, modifier = Modifier.fillMaxSize()) }, modifier = Modifier.fillMaxSize())

View File

@@ -168,8 +168,10 @@ fun SettingsScreen(navController: NavHostController = settingsNav()) {
EditPlaceDialog(true) { EditPlaceDialog(true) {
showEdit = false showEdit = false
val g = Data.selected_group val g = Data.selected_group
if (it && g != null) if (it && g != null) {
Data.visits.reassignAllVisitedToGroup(g.key) Data.visits.reassignAllVisitedToGroup(g.key)
Data.saveData()
}
} }
LazyColumn( LazyColumn(
@@ -216,8 +218,10 @@ fun SettingsScreen(navController: NavHostController = settingsNav()) {
deleteMode = true, deleteMode = true,
onDismiss = { onDismiss = {
val g = Data.selected_group val g = Data.selected_group
if (g != null) if (g != null) {
Data.visits.reassignAllVisitedToGroup(g.key) Data.visits.reassignAllVisitedToGroup(g.key)
Data.saveData()
}
showDialog = false showDialog = false
}) })
} }

View File

@@ -54,27 +54,51 @@ fun EditPlaceScreenPreview(){
EditPlaceScreen(Group.EEE) EditPlaceScreen(Group.EEE)
} }
fun syncVisited(loc: GeoLoc?=World.WWW){ fun syncVisited(loc: GeoLoc?=World.WWW): Boolean {
var changed = false
loc?.children?.forEach { tt -> loc?.children?.forEach { tt ->
tt.children.forEach {itc-> tt.children.forEach {itc->
if(Data.visits.getVisited(itc) in listOf(AUTO_GROUP,NO_GROUP)) { if(Data.visits.getVisited(itc) in listOf(AUTO_GROUP,NO_GROUP)) {
if(itc.children.any { c -> Data.visits.getVisited(c) != NO_GROUP }) val newState = if(itc.children.any { c -> Data.visits.getVisited(c) != NO_GROUP })
Data.visits.setVisited(itc, AUTO_GROUP) AUTO_GROUP
else else
Data.visits.setVisited(itc, NO_GROUP) NO_GROUP
if (Data.visits.getVisited(itc) != newState) {
Data.visits.setVisited(itc, newState)
changed = true
}
} }
} }
if(Data.visits.getVisited(tt) in listOf(AUTO_GROUP,NO_GROUP)) { if(Data.visits.getVisited(tt) in listOf(AUTO_GROUP,NO_GROUP)) {
if(tt.children.any { itc -> Data.visits.getVisited(itc) != NO_GROUP }) val newState = if(tt.children.any { itc -> Data.visits.getVisited(itc) != NO_GROUP })
Data.visits.setVisited(tt, AUTO_GROUP) AUTO_GROUP
else else
Data.visits.setVisited(tt, NO_GROUP) NO_GROUP
if (Data.visits.getVisited(tt) != newState) {
Data.visits.setVisited(tt, newState)
changed = true
}
} }
} }
// Sync World from Continents
if (loc != null && Data.visits.getVisited(loc) in listOf(AUTO_GROUP, NO_GROUP)) {
val newState = if(loc.children.any { Data.visits.getVisited(it) != NO_GROUP })
AUTO_GROUP
else
NO_GROUP
if (Data.visits.getVisited(loc) != newState) {
Data.visits.setVisited(loc, newState)
changed = true
}
}
return changed
} }
@Composable @Composable
fun EditPlaceScreen(loc: GeoLoc, onExit:()->Unit={}) { fun EditPlaceScreen(loc: GeoLoc, onExit:()->Unit={}) {
val visits by Data.visits.visitsFlow.collectAsState()
var showEdit by remember { mutableStateOf(false) } var showEdit by remember { mutableStateOf(false) }
val tabs : SnapshotStateList<GeoLoc> = remember { mutableStateListOf(loc) } val tabs : SnapshotStateList<GeoLoc> = remember { mutableStateListOf(loc) }
val ctx = LocalContext.current val ctx = LocalContext.current
@@ -84,7 +108,12 @@ fun EditPlaceScreen(loc: GeoLoc, onExit:()->Unit={}) {
selectedTab = tabs.lastIndex selectedTab = tabs.lastIndex
} }
SideEffect { SideEffect {
syncVisited() // visits is used to trigger sync whenever data changes
if (visits.isNotEmpty() || true) {
if (syncVisited()) {
Data.saveData()
}
}
} }
BackHandler { BackHandler {
if (tabs.size > 1) tabs.removeAt(tabs.lastIndex) if (tabs.size > 1) tabs.removeAt(tabs.lastIndex)
@@ -95,6 +124,7 @@ fun EditPlaceScreen(loc: GeoLoc, onExit:()->Unit={}) {
showEdit = false showEdit = false
if (it) { if (it) {
Data.visits.setVisited(Data.selected_geoloc, NO_GROUP) Data.visits.setVisited(Data.selected_geoloc, NO_GROUP)
syncVisited()
Data.saveData() Data.saveData()
if (Data.selected_geoloc!=null && Data.selected_geoloc!!.children.any { itc-> Data.visits.getVisited(itc) != NO_GROUP }) { if (Data.selected_geoloc!=null && Data.selected_geoloc!!.children.any { itc-> Data.visits.getVisited(itc) != NO_GROUP }) {
@@ -103,6 +133,7 @@ fun EditPlaceScreen(loc: GeoLoc, onExit:()->Unit={}) {
} }
if (Data.selected_group != null && Data.selected_geoloc != null) { if (Data.selected_group != null && Data.selected_geoloc != null) {
Data.visits.setVisited(Data.selected_geoloc, Data.selected_group!!.key) Data.visits.setVisited(Data.selected_geoloc, Data.selected_group!!.key)
syncVisited()
Data.saveData() Data.saveData()
} }
Data.selected_geoloc = null Data.selected_geoloc = null
@@ -144,12 +175,14 @@ fun EditPlaceScreen(loc: GeoLoc, onExit:()->Unit={}) {
Data.visits.getVisited(itc)!= NO_GROUP } == true) AUTO_GROUP Data.visits.getVisited(itc)!= NO_GROUP } == true) AUTO_GROUP
else NO_GROUP else NO_GROUP
) )
Data.saveData()
Data.selected_group = null Data.selected_group = null
} else { } else {
Data.selected_group = null Data.selected_group = null
showEdit=true showEdit=true
} }
syncVisited()
Data.saveData()
}) })
} }

View File

@@ -43,14 +43,14 @@ object Data {
if (groups.size() == 0) { if (groups.size() == 0) {
groups.setGroup(DEFAULT_GROUP, "Visited", groups.setGroup(DEFAULT_GROUP, "Visited",
ContextCompat.getColor(ctx, R.color.blue).toDrawable()) ContextCompat.getColor(ctx, R.color.blue).toDrawable())
saveData()
} }
saveData()
} }
fun saveData() { fun saveData() {
if(groups.id != visits.id) return if(groups.id != visits.id) return
val id = groups.id val id = groups.id
sharedPreferences.edit { sharedPreferences.edit(commit=true) {
putString("groups_$id", groupsSerial.writeTo(groups)) putString("groups_$id", groupsSerial.writeTo(groups))
putString("visits_$id", visitsSerial.writeTo(visits)) putString("visits_$id", visitsSerial.writeTo(visits))
} }

View File

@@ -3,6 +3,7 @@ package net.helcel.beans.helper
import android.graphics.Color import android.graphics.Color
import android.graphics.drawable.ColorDrawable import android.graphics.drawable.ColorDrawable
import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.Serializer import kotlinx.serialization.Serializer
import kotlinx.serialization.json.Json import kotlinx.serialization.json.Json
@@ -24,19 +25,25 @@ const val AUTO_GROUP = -1
@Serializable @Serializable
class Groups(val id: Int, private val groups: HashMap<Int, Group>) { class Groups(val id: Int, @SerialName("grps") private val groups: HashMap<Int, Group>) {
@kotlinx.serialization.Transient @kotlinx.serialization.Transient
private val _groupsFlow = MutableStateFlow<List<Group>>(groups.values.toList()) private val _groupsFlow = MutableStateFlow<List<Group>>(groups.values.toList())
@kotlinx.serialization.Transient @kotlinx.serialization.Transient
val groupsFlow: StateFlow<List<Group>> = _groupsFlow.asStateFlow() val groupsFlow: StateFlow<List<Group>> = _groupsFlow.asStateFlow()
fun setGroup(key: Int, name: String, col: ColorDrawable) { fun setGroup(key: Int, name: String, col: ColorDrawable) {
val old = groups[key]
if (old != null && old.name == name && old.color.color == col.color) return
groups[key] = Group(key, name, col) groups[key] = Group(key, name, col)
_groupsFlow.value = groups.values.toList() updateFlow()
} }
fun deleteGroup(key: Int) { fun deleteGroup(key: Int) {
groups.remove(key) groups.remove(key)
updateFlow()
}
private fun updateFlow() {
_groupsFlow.value = groups.values.toList() _groupsFlow.value = groups.values.toList()
} }

View File

@@ -19,24 +19,25 @@ class Visits(val id: Int, private val locs: HashMap<String, Int>) {
val visitsFlow: StateFlow<Map<String,Int>> = _visitsFlow val visitsFlow: StateFlow<Map<String,Int>> = _visitsFlow
fun setVisited(key: GeoLoc?, b: Int) { fun setVisited(key: GeoLoc?, b: Int) {
if (key == null) if (key == null || locs[key.code] == b)
return return
_visitsFlow.value = _visitsFlow.value.toMutableMap().apply {
this[key.code] = b
}
locs[key.code] = b locs[key.code] = b
updateFlow()
}
private fun updateFlow() {
_visitsFlow.value = locs.toMap()
} }
fun deleteVisited(key: Int) { fun deleteVisited(key: Int) {
val keysToDelete = locs val keysToDelete = locs
.filter { it.value == key } .filter { it.value == key }
.map { it.key } .map { it.key }
_visitsFlow.value = _visitsFlow.value.toMutableMap().apply { if (keysToDelete.isEmpty()) return
keysToDelete.forEach { this.remove(it)}
}
keysToDelete.forEach { keysToDelete.forEach {
locs.remove(it) locs.remove(it)
} }
updateFlow()
} }
fun getVisited(key: GeoLoc): Int { fun getVisited(key: GeoLoc): Int {
@@ -60,13 +61,19 @@ class Visits(val id: Int, private val locs: HashMap<String, Int>) {
} }
fun reassignAllVisitedToGroup(group: Int) { fun reassignAllVisitedToGroup(group: Int) {
var changed = false
val keys = locs.filter { (_, grp) -> val keys = locs.filter { (_, grp) ->
grp !in listOf(NO_GROUP, AUTO_GROUP) grp !in listOf(NO_GROUP, AUTO_GROUP)
}.keys }.keys
keys.forEach { keys.forEach {
locs[it] = group if (locs[it] != group) {
locs[it] = group
changed = true
}
}
if (changed) {
updateFlow()
} }
_visitsFlow.value = locs
} }
@OptIn(ExperimentalSerializationApi::class) @OptIn(ExperimentalSerializationApi::class)

View File

@@ -0,0 +1,50 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="128"
android:viewportHeight="128">
<group android:scaleX="0.8918919"
android:scaleY="0.8918919"
android:translateX="6.918919"
android:translateY="6.918919">
<group
android:scaleX="1.5"
android:scaleY="1.5"
android:translateX="10"
android:translateY="10">
<path
android:pathData="M36,36m-28,0a28,28 0,1 1,56 0a28,28 0,1 1,-56 0"
android:strokeLineJoin="round"
android:strokeWidth="2"
android:fillColor="@color/blue"
android:strokeColor="#000000"
android:strokeLineCap="round"/>
</group>
<group
android:scaleX="1.25"
android:scaleY="1.25"
android:translateX="18"
android:translateY="18">
<path
android:pathData="M56.803,45.75c0.599,-0.299 1.157,-0.672 1.663,-1.11 0.804,-0.698 1.463,-1.546 1.94,-2.497 0.599,-1.303 0.883,-2.728 0.829,-4.161 0.034,-1.498 -0.154,-2.994 -0.558,-4.437 -0.451,-1.645 -1.104,-3.229 -1.944,-4.714 -0.967,-2.141 -2.28,-4.108 -3.887,-5.822 -1.242,-1.326 -2.757,-2.366 -4.44,-3.048 -0.877,-0.372 -1.821,-0.56 -2.774,-0.553 -1.402,0.074 -2.729,0.697 -3.882,1.389 -1.285,0.81 -2.244,1.735 -2.771,3.053 -0.739,2.362 0.827,4.821 1.113,5.269 0.003,0.005 0.187,0.281 0.555,0.832 1.512,2.264 1.589,2.358 1.666,2.495 0.646,1.221 1.114,2.528 1.389,3.882 1.043,4.001 1.565,6.001 2.223,6.932 1.208,1.71 3.455,3.414 5.826,3.325 1.059,-0.088 2.093,-0.371 3.05,-0.835Z"
android:strokeWidth="2"
android:fillColor="@color/white"
android:strokeColor="#000000"
android:strokeLineCap="round"/>
<path
android:pathData="M22,41c-1.54,0.554 -2.83,1.642 -3.636,3.066 -0.714,1.365 -0.957,2.928 -0.693,4.445 0.178,1.247 0.632,2.439 1.329,3.488 2.032,3.228 5.383,4.423 7,5 1.613,0.561 3.295,0.897 5,1 2.387,0.205 6.923,0.535 11,-2 1.287,-0.665 2.335,-1.713 3,-3 0.661,-1.601 0.661,-3.399 0,-5 -0.389,-1.156 -1.121,-2.165 -2.099,-2.894 -0.919,-0.599 -1.974,-0.956 -3.069,-1.039 -2.057,-0.313 -2.756,0.139 -5.014,0.057 -1.271,-0.019 -2.534,-0.214 -3.753,-0.577 -3.036,-0.95 -3.33,-2.457 -5.889,-2.829 -1.066,-0.158 -2.155,-0.061 -3.177,0.282Z"
android:strokeWidth="2"
android:fillColor="@color/white"
android:strokeColor="#000000"
android:strokeLineCap="round"/>
<path
android:pathData="M12.7,26.975c1.758,-3.604 5.311,-3.191 9.58,-7.091 2.701,-2.469 2.858,-4.078 5.613,-5.202 1.407,-0.644 2.984,-0.819 4.498,-0.5 2.053,0.475 3.761,1.891 4.61,3.819 1.116,2.742 -0.314,5.437 -1.398,7.482 -0.951,1.689 -2.167,3.215 -3.602,4.518 -1.479,1.552 -3.161,2.898 -5,4 -2.629,1.541 -6.332,3.711 -9.989,2.43 -1.481,-0.548 -2.768,-1.521 -3.699,-2.796 -1.496,-1.906 -1.735,-4.512 -0.612,-6.659Z"
android:strokeWidth="2"
android:fillColor="@color/white"
android:strokeColor="#000000"
android:strokeLineCap="round"/>
</group>
</group>
</vector>

View File

@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Theme.Beans" parent="Theme.MaterialComponents.DayNight.NoActionBar">
<!-- Status bar color in dark mode -->
<item name="android:statusBarColor">@color/blue</item>
<!-- Window background in dark mode -->
<item name="android:windowBackground">@color/darkgray</item>
<item name="android:windowLightStatusBar">false</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<item name="colorPrimary">@color/blue</item>
<item name="colorPrimaryDark">@color/blue</item>
<item name="colorAccent">@color/blue</item>
</style>
</resources>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Theme.Beans" parent="android:Theme.Material.Light.NoActionBar">
<item name="android:statusBarColor">@color/blue</item>
<item name="android:windowBackground">@color/blue</item>
</style>
</resources>

View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Theme.Beans" parent="Theme.MaterialComponents.DayNight.NoActionBar">
<!-- Status bar color -->
<item name="android:statusBarColor">@color/blue</item>
<!-- Window background - shows through statusBarsPadding() area -->
<item name="android:windowBackground">@color/blue</item>
<item name="android:windowLightStatusBar">false</item>
<item name="android:windowDrawsSystemBarBackgrounds">true</item>
<!-- Optional: Primary colors for the theme -->
<item name="colorPrimary">@color/blue</item>
<item name="colorPrimaryDark">@color/blue</item>
<item name="colorAccent">@color/blue</item>
</style>
</resources>

View File

@@ -2,5 +2,5 @@
plugins { plugins {
id 'com.android.application' version '9.2.1' apply false id 'com.android.application' version '9.2.1' apply false
id 'com.android.library' version '9.2.1' apply false id 'com.android.library' version '9.2.1' apply false
id 'org.jetbrains.kotlin.android' version '2.3.21' apply false id 'org.jetbrains.kotlin.android' version '2.4.0' apply false
} }

View File

@@ -1,8 +1,10 @@
#!/bin/node #!/bin/node
import {readFileSync, existsSync} from 'fs' import {readFileSync,writeFileSync,existsSync} from 'fs'
import area from '@turf/area' import area from '@turf/area'
import * as turf from '@turf/turf' import * as turf from '@turf/turf'
import * as path from 'path';
import { JSDOM } from 'jsdom';
const countries = const countries =
@@ -24,7 +26,7 @@ const countries =
const groups = { const groups = {
"EEE":["ALB","AND","AUT","BLR","BEL","BIH","BGR","HRV","CYP","CZE","DNK","EST","FIN","FRA","DEU","GRC","HUN","ISL","IRL","ITA","KAZ","XKO","LVA","LIE","LTU","LUX","MLT","MDA","MCO","MNE","NLD","MKD","NOR","POL","PRT","ROU","RUS","SMR","SRB","SVK","SVN","ESP","SWE","CHE","UKR","GBR","VAT","XAD"], "EEE":["ALA","ALB","AND","AUT","BLR","BEL","BIH","BGR","HRV","CYP","CZE","DNK","EST","FIN","FRA","DEU","GIB","GGY","GRC","HUN","ISL","IRL","IMN","JEY","ITA","KAZ","XKO","LVA","LIE","LTU","LUX","MLT","MDA","MCO","MNE","NLD","MKD","NOR","SJM","POL","PRT","ROU","RUS","SMR","SRB","SVK","SVN","ESP","SWE","CHE","UKR","GBR","VAT","XAD"],
"ABB":["AFG","ARM","AZE","BHR","BGD","BTN","BRN","KHM","CHN","GEO","HKG","IND","IDN","IRN","IRQ","ISR","JPN","JOR","KWT","KGZ","LAO","LBN","MAC","MYS","MDV","MNG","MMR","NPL","PRK","OMN","PAK","PSE","PHL","QAT","SAU","SGP","KOR","LKA","SYR","TWN","TJK","THA","TLS","TUR","TKM","ARE","UZB","VNM","YEM","ZNC"], "ABB":["AFG","ARM","AZE","BHR","BGD","BTN","BRN","KHM","CHN","GEO","HKG","IND","IDN","IRN","IRQ","ISR","JPN","JOR","KWT","KGZ","LAO","LBN","MAC","MYS","MDV","MNG","MMR","NPL","PRK","OMN","PAK","PSE","PHL","QAT","SAU","SGP","KOR","LKA","SYR","TWN","TJK","THA","TLS","TUR","TKM","ARE","UZB","VNM","YEM","ZNC"],
"FFF":["DZA","AGO","BDI","BEN","BWA","BFA","BDI","CPV","CMR","CAF","TCD","COM","COG","COD","CIV","DJI","EGY","GNQ","ERI","SWZ","ETH","GAB","GMB","GHA","GIN","GNB","KEN","LSO","LBR","LBY","MDG","MWI","MLI","MRT","MUS","MYT","MAR","MOZ","NAM","NER","NGA","COD","REU","RWA","STP","SEN","SYC","SLE","SOM","ZAF","SSD","SHN","SDN","TZA","TGO","TUN","UGA","COD","ZMB","ZWE","ESH"], "FFF":["DZA","AGO","BDI","BEN","BWA","BFA","BDI","CPV","CMR","CAF","TCD","COM","COG","COD","CIV","DJI","EGY","GNQ","ERI","SWZ","ETH","GAB","GMB","GHA","GIN","GNB","KEN","LSO","LBR","LBY","MDG","MWI","MLI","MRT","MUS","MYT","MAR","MOZ","NAM","NER","NGA","COD","REU","RWA","STP","SEN","SYC","SLE","SOM","ZAF","SSD","SHN","SDN","TZA","TGO","TUN","UGA","COD","ZMB","ZWE","ESH"],
"NNN":["ABW","AIA","ATG","BHS","BRB","BLZ","BMU","VGB","CAN","CYM","CRI","CUB","CUW","DMA","DOM","SLV","GRL","GRD","GLP","GTM","HTI","HND","JAM","MTQ","MEX","MSR","ANT","CUW","NIC","PAN","PRI","KNA","LCA","MAF","SPM","VCT","TTO","TCA","USA","XCL"], "NNN":["ABW","AIA","ATG","BHS","BRB","BLZ","BMU","VGB","CAN","CYM","CRI","CUB","CUW","DMA","DOM","SLV","GRL","GRD","GLP","GTM","HTI","HND","JAM","MTQ","MEX","MSR","ANT","CUW","NIC","PAN","PRI","KNA","LCA","MAF","SPM","VCT","TTO","TCA","USA","XCL"],
@@ -32,7 +34,6 @@ const groups = {
"UUU":["ASM","AUS","COK","FJI","PYF","GUM","KIR","MHL","FSM","NRU","NCL","NZL","NIU","NFK","MNP","PLW","PNG","PCN","SLB","TKL","TON","TUV","VUT","WLF"], "UUU":["ASM","AUS","COK","FJI","PYF","GUM","KIR","MHL","FSM","NRU","NCL","NZL","NIU","NFK","MNP","PLW","PNG","PCN","SLB","TKL","TON","TUV","VUT","WLF"],
"XXX":[ "XXX":[
"ATA", // Antarctica: not in any other region "ATA", // Antarctica: not in any other region
"ALA",// Åland Islands: an autonomous region of Finland, but not a member of the EU or UN
"BES",// Bonaire, Sint Eustatius and Saba: special municipalities of the Netherlands in the Caribbean "BES",// Bonaire, Sint Eustatius and Saba: special municipalities of the Netherlands in the Caribbean
"BVT",// Bouvet Island: an uninhabited territory of Norway in the South Atlantic "BVT",// Bouvet Island: an uninhabited territory of Norway in the South Atlantic
"IOT",// British Indian Ocean Territory: a British overseas territory in the Indian Ocean "IOT",// British Indian Ocean Territory: a British overseas territory in the Indian Ocean
@@ -40,16 +41,11 @@ const groups = {
"CCK",// Cocos (Keeling) Islands: an Australian external territory in the Indian Ocean "CCK",// Cocos (Keeling) Islands: an Australian external territory in the Indian Ocean
"FRO",// Faroe Islands: an autonomous region of Denmark "FRO",// Faroe Islands: an autonomous region of Denmark
"ATF",// French Southern and Antarctic Lands: a territory of France located in the southern Indian Ocean "ATF",// French Southern and Antarctic Lands: a territory of France located in the southern Indian Ocean
"GIB",// Gibraltar: a British overseas territory located at the southern tip of the Iberian Peninsula
"GGY",// Guernsey: a British Crown dependency in the English Channel
"HMD",// Heard Island and McDonald Islands: an uninhabited Australian external territory in the southern Indian Ocean "HMD",// Heard Island and McDonald Islands: an uninhabited Australian external territory in the southern Indian Ocean
"IMN",// Isle of Man: a British Crown dependency located in the Irish Sea
"JEY",// Jersey: a British Crown dependency located in the English Channel
"BLM",// Saint Barthélemy: an overseas collectivity of France in the Caribbean "BLM",// Saint Barthélemy: an overseas collectivity of France in the Caribbean
"WSM",// Samoa: an independent island nation in the South Pacific "WSM",// Samoa: an independent island nation in the South Pacific
"SXM",// Sint Maarten: a constituent country of the Kingdom of the Netherlands in the Caribbean "SXM",// Sint Maarten: a constituent country of the Kingdom of the Netherlands in the Caribbean
"SGS",// South Georgia and the South Sandwich Islands: a British overseas territory in the southern Atlantic Ocean "SGS",// South Georgia and the South Sandwich Islands: a British overseas territory in the southern Atlantic Ocean
"SJM",// Svalbard and Jan Mayen: an archipelago administered by Norway
"UMI",// United States Minor Outlying Islands: a collection of nine insular areas of the United States "UMI",// United States Minor Outlying Islands: a collection of nine insular areas of the United States
"VIR",// United States Virgin Islands: an unincorporated territory of the United States in the Caribbean "VIR",// United States Virgin Islands: an unincorporated territory of the United States in the Caribbean
] ]
@@ -166,4 +162,52 @@ async function run(){
} }
} }
function fixSvg(svgPath) {
const countryToRegion = {};
for (const [region, countries] of Object.entries(groups)) {
countries.forEach(country => countryToRegion[country] = region);
}
const absoluteInputPath = path.resolve(svgPath);
if (!existsSync(absoluteInputPath)) {
throw new Error(`Input file not found at: ${absoluteInputPath}`);
}
const svgContent = readFileSync(absoluteInputPath, 'utf8');
const dom = new JSDOM(svgContent, { contentType: 'image/svg+xml' });
const document = dom.window.document;
const svgRoot = document.querySelector('svg');
if (!svgRoot) {
throw new Error("Invalid or empty SVG structure encountered.");
}
if (svgRoot.getAttribute('data-processed') === 'true') {
console.log(`Skipping: File at "${svgPath}" has already been processed.`);
return;
}
const elementGroups = Array.from(svgRoot.querySelectorAll('g'));
elementGroups.forEach(group => {
const currentId = group.getAttribute('id') || '';
const baseIsoCode = currentId.replace(/\d+$/, '');
const regionKey = countryToRegion[baseIsoCode] || 'XXXX';
let regionGroup = svgRoot.querySelector(`g[id="${regionKey}"]`);
if (!regionGroup) {
regionGroup = document.createElementNS('http://w3.org', 'g');
regionGroup.setAttribute('id', regionKey);
svgRoot.appendChild(regionGroup);
}
regionGroup.appendChild(group);
});
svgRoot.setAttribute('data-processed', 'true');
const absoluteOutputPath = path.resolve(svgPath);
let cleanXmlString = svgRoot.outerHTML;
cleanXmlString = cleanXmlString.replace(/[\r\n]+/g, '');
cleanXmlString = cleanXmlString.replace(/xmlns="http:\/\/w3\.org"\s?/g, '');
cleanXmlString = cleanXmlString.replace(/xmlns="http:\/\/www\.w3\.org\/2000\/svg"\s?/g, '');
cleanXmlString = cleanXmlString.replace('<svg', '<svg xmlns="http://www.w3.org/2000/svg"');
writeFileSync(absoluteOutputPath, cleanXmlString, 'utf8');
}
run() run()
fixSvg("./app/src/main/assets/loxim01.svg")
fixSvg("./app/src/main/assets/webmercator01.svg")
fixSvg("./app/src/main/assets/aeqd01.svg")

View File

@@ -8,10 +8,11 @@ GADM_BASEPATH="https://geodata.ucdavis.edu/gadm"
mapshaper="./node_modules/mapshaper/bin/mapshaper" mapshaper="./node_modules/mapshaper/bin/mapshaper"
ATA_URL="https://media.githubusercontent.com/media/wmgeolab/geoBoundaries/905b0baf5f4fb3b9ccf45293647dcacdb2b799d4/releaseData/gbOpen/ATA/ADM0/geoBoundaries-ATA-ADM0_simplified.geojson" ATA_URL="https://media.githubusercontent.com/media/wmgeolab/geoBoundaries/905b0baf5f4fb3b9ccf45293647dcacdb2b799d4/releaseData/gbOpen/ATA/ADM0/geoBoundaries-ATA-ADM0_simplified.geojson"
# Caspian Sea: "XCA"
countries=( countries=(
"AFG" "XAD" "ALA" "ALB" "DZA" "ASM" "AND" "AGO" "AIA" "ATG" "ARG" "ARM" "ABW" "AUS" "AUT" "AZE" "AFG" "XAD" "ALA" "ALB" "DZA" "ASM" "AND" "AGO" "AIA" "ATG" "ARG" "ARM" "ABW" "AUS" "AUT" "AZE"
"BHS" "BHR" "BGD" "BRB" "BLR" "BEL" "BLZ" "BEN" "BMU" "BTN" "BOL" "BES" "BIH" "BWA" "BVT" "BRA" "IOT" "VGB" "BRN" "BGR" "BFA" "BDI" "KHM" "BHS" "BHR" "BGD" "BRB" "BLR" "BEL" "BLZ" "BEN" "BMU" "BTN" "BOL" "BES" "BIH" "BWA" "BVT" "BRA" "IOT" "VGB" "BRN" "BGR" "BFA" "BDI" "KHM"
"CMR" "CAN" "CPV" "XCA" "CYM" "CAF" "TCD" "CHL" "CHN" "CXR" "XCL" "CCK" "COL" "COM" "COK" "CRI" "CIV" "HRV" "CUB" "CUW" "CYP" "CZE" "COD" "CMR" "CAN" "CPV" "CYM" "CAF" "TCD" "CHL" "CHN" "CXR" "XCL" "CCK" "COL" "COM" "COK" "CRI" "CIV" "HRV" "CUB" "CUW" "CYP" "CZE" "COD"
"DNK" "DJI" "DMA" "DOM" "ECU" "EGY" "SLV" "GNQ" "ERI" "EST" "ETH" "FLK" "FRO" "FJI" "FIN" "FRA" "GUF" "PYF" "ATF" "DNK" "DJI" "DMA" "DOM" "ECU" "EGY" "SLV" "GNQ" "ERI" "EST" "ETH" "FLK" "FRO" "FJI" "FIN" "FRA" "GUF" "PYF" "ATF"
"GAB" "GMB" "GEO" "DEU" "GHA" "GIB" "GRC" "GRL" "GRD" "GLP" "GUM" "GTM" "GGY" "GIN" "GNB" "GUY" "HTI" "HMD" "HND" "HUN" "GAB" "GMB" "GEO" "DEU" "GHA" "GIB" "GRC" "GRL" "GRD" "GLP" "GUM" "GTM" "GGY" "GIN" "GNB" "GUY" "HTI" "HMD" "HND" "HUN"
"ISL" "IND" "IDN" "IRN" "IRQ" "IRL" "IMN" "ISR" "ITA" "JAM" "JPN" "JEY" "JOR" "KAZ" "KEN" "KIR" "XKO" "KWT" "KGZ" "ISL" "IND" "IDN" "IRN" "IRQ" "IRL" "IMN" "ISR" "ITA" "JAM" "JPN" "JEY" "JOR" "KAZ" "KEN" "KIR" "XKO" "KWT" "KGZ"
@@ -115,6 +116,47 @@ toSVG_1() {
"$mapshaper" -i combine-files ${input_files[@]} -proj aeqd +lat_0=90 -simplify 0.005 weighted keep-shapes resolution=1200x1200 -o ./app/src/main/assets/aeqd1.svg svg-data=GID_0,COUNTRY,GID,NAME id-field=GID "$mapshaper" -i combine-files ${input_files[@]} -proj aeqd +lat_0=90 -simplify 0.005 weighted keep-shapes resolution=1200x1200 -o ./app/src/main/assets/aeqd1.svg svg-data=GID_0,COUNTRY,GID,NAME id-field=GID
} }
generate_svg_map() {
local OUT_FILE="$1" # First argument: Output destination path
local PROJ_ARGS="$2" # Second argument: Projection parameters
shift 2 # Remove the first two arguments, leaving only the files
local FILES_TO_RUN=("$@") # Capture all remaining arguments as the file array
echo "Generating: $OUT_FILE using projection [$PROJ_ARGS]"
echo "Processing ${#FILES_TO_RUN[@]} files..."
local JS_PIPELINE_LOGIC="
const conflicts = {
'Z01': 'IND', 'Z04': 'IND', 'Z05': 'IND', 'Z07': 'IND', 'Z09': 'IND',
'Z02': 'CHN', 'Z03': 'CHN','Z08': 'CHN',
'Z06': 'PAK'
};
let rawCode = GID_0 || 'UNK';
let cCode = conflicts[rawCode] ? conflicts[rawCode] : rawCode;
let isGidMissing = (!GID || GID === 'undefined' || GID === 'null' || GID === '');
if (isGidMissing) {
COUNTRY_GROUP = cCode+'2';
} else {
COUNTRY_GROUP = cCode+'1';
}
"
"$mapshaper" -i "${FILES_TO_RUN[@]}" combine-files \
-snap \
-merge-layers force\
-proj $PROJ_ARGS densify \
-simplify 2% weighted keep-shapes \
-filter-islands min-area=0 \
-sort 'this.area' ascending \
-each "$JS_PIPELINE_LOGIC" \
-split COUNTRY_GROUP \
-o "$OUT_FILE" \
format=svg \
id-field=GID \
precision=0.1 \
target=*
}
toSVG_01() { toSVG_01() {
input_files=() input_files=()
@@ -136,9 +178,9 @@ toSVG_01() {
fi fi
done done
"$mapshaper" -i combine-files ${input_files[@]} snap -proj loxim densify -simplify 0.001 weighted keep-shapes -o ./app/src/main/assets/loxim01.svg svg-data=GID_0,COUNTRY,GID,NAME id-field=GID generate_svg_map "./app/src/main/assets/loxim01.svg" "loxim" "${input_files[@]}"
"$mapshaper" -i combine-files ${input_files[@]} snap -proj webmercator densify -simplify 0.001 weighted keep-shapes -o ./app/src/main/assets/webmercator01.svg svg-data=GID_0,COUNTRY,GID,NAME id-field=GID generate_svg_map "./app/src/main/assets/webmercator01.svg" "webmercator" "${input_files[@]}"
"$mapshaper" -i combine-files ${input_files[@]} snap -proj aeqd +lat_0=90 densify -simplify 0.001 weighted keep-shapes -o ./app/src/main/assets/aeqd01.svg svg-data=GID_0,COUNTRY,GID,NAME id-field=GID generate_svg_map "./app/src/main/assets/aeqd01.svg" "aeqd +lat_0=90" "${input_files[@]}"
} }
do_1() { do_1() {
@@ -153,10 +195,12 @@ do_0() {
do do
download_0 "$country" download_0 "$country"
done done
wget -q -O "./temp/1/ATA.json" "$ATA_URL" wget -q -O "./temp/0/ATA.json" "$ATA_URL"
} }
# do_0 # do_0
# do_1 # do_1
# toSVG_0 # toSVG_0
# toSVG_1 # toSVG_1
toSVG_01 toSVG_01
#CUW, CCK, XCL, CXR, IOT, BVT, ABW, FLK, GIB, HMD, KIR, SXM, MDV, MCO, NIU, NFK, PCN, MAF, SGS, VAT

View File

@@ -3,7 +3,7 @@
"@turf/area": "^7.3.5", "@turf/area": "^7.3.5",
"@turf/turf": "^7.3.5", "@turf/turf": "^7.3.5",
"jsdom": "^29.1.1", "jsdom": "^29.1.1",
"mapshaper": "^0.7.19" "mapshaper": "^0.7.22"
}, },
"type": "module" "type": "module"
} }

View File

@@ -3061,9 +3061,9 @@ __metadata:
linkType: hard linkType: hard
"hyparquet@npm:^1.25.6": "hyparquet@npm:^1.25.6":
version: 1.25.8 version: 1.26.0
resolution: "hyparquet@npm:1.25.8" resolution: "hyparquet@npm:1.26.0"
checksum: 10c0/79037cbc8f943af5e95cc56677a94dd2667e73d51feca02b58ec416026e0dfd05e9e71db2a754f8e7be542779e951e3eef88e226a62de4daa21f6dfc8b090a31 checksum: 10c0/fbb8043436e8cd58897c853152816397548a5c5d3962a70b5e2c6f04745e574f4c4c556e535ea56042e6a7310f5eac64f3c32a551e416cb5b56243dc14abea9a
languageName: node languageName: node
linkType: hard linkType: hard
@@ -3315,9 +3315,9 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"mapshaper@npm:^0.7.19": "mapshaper@npm:^0.7.22":
version: 0.7.19 version: 0.7.22
resolution: "mapshaper@npm:0.7.19" resolution: "mapshaper@npm:0.7.22"
dependencies: dependencies:
"@bokuweb/zstd-wasm": "npm:^0.0.27" "@bokuweb/zstd-wasm": "npm:^0.0.27"
"@ngageoint/geopackage": "npm:^4.2.6" "@ngageoint/geopackage": "npm:^4.2.6"
@@ -3347,7 +3347,7 @@ __metadata:
idb-keyval: "npm:^6.2.0" idb-keyval: "npm:^6.2.0"
jpeg-js: "npm:^0.4.4" jpeg-js: "npm:^0.4.4"
kdbush: "npm:^3.0.0" kdbush: "npm:^3.0.0"
mproj: "npm:0.1.2" mproj: "npm:0.1.3"
msgpackr: "npm:^1.10.1" msgpackr: "npm:^1.10.1"
open: "npm:^11.0.0" open: "npm:^11.0.0"
pngjs: "npm:^7.0.0" pngjs: "npm:^7.0.0"
@@ -3360,7 +3360,7 @@ __metadata:
mapshaper: bin/mapshaper mapshaper: bin/mapshaper
mapshaper-gui: bin/mapshaper-gui mapshaper-gui: bin/mapshaper-gui
mapshaper-xl: bin/mapshaper-xl mapshaper-xl: bin/mapshaper-xl
checksum: 10c0/124f409e3235ee4a38208c06fe77dfdd9cc32e23836b56fb7adc5b3a995cc0ef5dca18dc569b7169e5033ba2662b43dee3f8f411b9b1419c96b4200b9b051b9a checksum: 10c0/cdb6a5c2b342ebfcb56fefa7141023f956253874d0db2adaf496a17f46162c3ef7a0ff057746fdeb68f52d795c571c4e35c2df191d570ac7107edba46dad7f42
languageName: node languageName: node
linkType: hard linkType: hard
@@ -3422,16 +3422,16 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"mproj@npm:0.1.2": "mproj@npm:0.1.3":
version: 0.1.2 version: 0.1.3
resolution: "mproj@npm:0.1.2" resolution: "mproj@npm:0.1.3"
dependencies: dependencies:
geographiclib: "npm:1.48.0" geographiclib: "npm:1.48.0"
rw: "npm:~1.3.2" rw: "npm:~1.3.2"
bin: bin:
mcs2cs: bin/mcs2cs mcs2cs: bin/mcs2cs
mproj: bin/mproj mproj: bin/mproj
checksum: 10c0/014fb9963a843f761930172fad9b82d202480d1f058def951982acfcef85e7fb65edf315260a881ba1961728e8352d92c6ba37b343d2fd6b62d75ebc876b75e8 checksum: 10c0/b3209f0d19f70c907ba51d91e1dc94785c768ca0bf5b43f218c51fde9a4471e6e9888acef1877209c40a742a9800fbe60dcbdb703a89a99d72473e8c5f52f977
languageName: node languageName: node
linkType: hard linkType: hard
@@ -3515,8 +3515,8 @@ __metadata:
linkType: hard linkType: hard
"node-gyp@npm:latest": "node-gyp@npm:latest":
version: 12.3.0 version: 12.4.0
resolution: "node-gyp@npm:12.3.0" resolution: "node-gyp@npm:12.4.0"
dependencies: dependencies:
env-paths: "npm:^2.2.0" env-paths: "npm:^2.2.0"
exponential-backoff: "npm:^3.1.1" exponential-backoff: "npm:^3.1.1"
@@ -3530,7 +3530,7 @@ __metadata:
which: "npm:^6.0.0" which: "npm:^6.0.0"
bin: bin:
node-gyp: bin/node-gyp.js node-gyp: bin/node-gyp.js
checksum: 10c0/9d9032b405cbe42f72a105259d9eb679376470c102df4a2dbaa51e07d59bf741dcffb85897087ea9d8318b9cabb824a8978af51508ae142f0239ae1e6a3c2329 checksum: 10c0/9acb7c798e124275a6f9c1f7eb64b5abd6196bb885a3945fb44ee0dccf435514e88cdfb0f228ee7ff76ef25107c1f39ff37a067bf92fd00b9aff9234db29ff9e
languageName: node languageName: node
linkType: hard linkType: hard
@@ -3974,7 +3974,7 @@ __metadata:
"@turf/area": "npm:^7.3.5" "@turf/area": "npm:^7.3.5"
"@turf/turf": "npm:^7.3.5" "@turf/turf": "npm:^7.3.5"
jsdom: "npm:^29.1.1" jsdom: "npm:^29.1.1"
mapshaper: "npm:^0.7.19" mapshaper: "npm:^0.7.22"
languageName: unknown languageName: unknown
linkType: soft linkType: soft
@@ -4230,15 +4230,15 @@ __metadata:
linkType: hard linkType: hard
"tar@npm:^7.5.4": "tar@npm:^7.5.4":
version: 7.5.15 version: 7.5.16
resolution: "tar@npm:7.5.15" resolution: "tar@npm:7.5.16"
dependencies: dependencies:
"@isaacs/fs-minipass": "npm:^4.0.0" "@isaacs/fs-minipass": "npm:^4.0.0"
chownr: "npm:^3.0.0" chownr: "npm:^3.0.0"
minipass: "npm:^7.1.2" minipass: "npm:^7.1.2"
minizlib: "npm:^3.1.0" minizlib: "npm:^3.1.0"
yallist: "npm:^5.0.0" yallist: "npm:^5.0.0"
checksum: 10c0/8f039edb1d12fdd7df6c6f9877d125afe9f3da3f5f9317df326fdd090d48793d6998cede1506a1471f3e3a250db270a89dace28005eb5e99c5a9132d704ac956 checksum: 10c0/4f37f3c4bd2ca2755fd736a5df1d573c1a868ec1b1e893346aeafa95ac510f9e2fd1469420bd866cc7904799e5bd4ac62b5d4f03fe27747d6e1e373b44505c5c
languageName: node languageName: node
linkType: hard linkType: hard
@@ -4250,12 +4250,12 @@ __metadata:
linkType: hard linkType: hard
"tinyglobby@npm:^0.2.12": "tinyglobby@npm:^0.2.12":
version: 0.2.16 version: 0.2.17
resolution: "tinyglobby@npm:0.2.16" resolution: "tinyglobby@npm:0.2.17"
dependencies: dependencies:
fdir: "npm:^6.5.0" fdir: "npm:^6.5.0"
picomatch: "npm:^4.0.4" picomatch: "npm:^4.0.4"
checksum: 10c0/f2e09fd93dd95c41e522113b686ff6f7c13020962f8698a864a257f3d7737599afc47722b7ab726e12f8a813f779906187911ff8ee6701ede65072671a7e934b checksum: 10c0/7f7bb0f197c88bc4b20c231e0deca4240ca3bf313a88f5a7fee93a872b84966a4d50220947c0455ad07a60b3b360961c5b7fd979222aeb716a9f99b412002e4c
languageName: node languageName: node
linkType: hard linkType: hard
@@ -4273,21 +4273,21 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"tldts-core@npm:^7.0.30": "tldts-core@npm:^7.1.0":
version: 7.0.30 version: 7.1.0
resolution: "tldts-core@npm:7.0.30" resolution: "tldts-core@npm:7.1.0"
checksum: 10c0/e3cd730e96b0e9c0332fcaab44d0257b668f9089644508e4f6f870d37bbf5c218243b7e83aa39690c87b386d1b0ad577772a5994969c4c81cc25a476f783ccd7 checksum: 10c0/e380f601e0b73105ef2add60f296fd001543e93e4c70cebf4f779717fae609680a8a0f77f1bec72043ce7597acab5f1d54769e8b3d07d20996d84c124d8e90f1
languageName: node languageName: node
linkType: hard linkType: hard
"tldts@npm:^7.0.5": "tldts@npm:^7.0.5":
version: 7.0.30 version: 7.1.0
resolution: "tldts@npm:7.0.30" resolution: "tldts@npm:7.1.0"
dependencies: dependencies:
tldts-core: "npm:^7.0.30" tldts-core: "npm:^7.1.0"
bin: bin:
tldts: bin/cli.js tldts: bin/cli.js
checksum: 10c0/c36f7b480f09128303158e4738a82426c33e8da9f77d4fb57a2d5ef5896c803d7a3c1d53ade965712f9cb4946935139b6d192a18698665556ca504493c7c265e checksum: 10c0/ff3b87a16ef96fde6e6eac745078cb87f0614cd2b854322245b98595efafb63fafbef23ea1f719105a77f7ee8c8d51ca21a42c030d4e9d5a50fdd5bca4da57a6
languageName: node languageName: node
linkType: hard linkType: hard
@@ -4404,9 +4404,9 @@ __metadata:
linkType: hard linkType: hard
"undici@npm:^6.25.0": "undici@npm:^6.25.0":
version: 6.25.0 version: 6.26.0
resolution: "undici@npm:6.25.0" resolution: "undici@npm:6.26.0"
checksum: 10c0/2597cc6689bdb02c210c557b1f85febbfda65becae6e6fc1061508e2f33734d25207f81cd8af56ada9956329eb3a7bd7431e87dcfeceba20ee87059b57dcf985 checksum: 10c0/cf2b4caf58c33d6582970991290cc7a6486d6e738845f25dcdd16952d708ec844815c6d30362919764fcaf30f719891289341f1ada496f003ce2700310453a47
languageName: node languageName: node
linkType: hard linkType: hard