diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 0e9bd2ba..970a63f0 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -3,7 +3,7 @@ updates: - package-ecosystem: github-actions labels: [] directory: / - target-branch: main + target-branch: dev schedule: interval: daily timezone: Asia/Jakarta @@ -11,7 +11,7 @@ updates: - package-ecosystem: gradle labels: [] directory: / - target-branch: main + target-branch: dev schedule: interval: daily timezone: Asia/Jakarta @@ -19,7 +19,7 @@ updates: - package-ecosystem: gomod labels: [] directory: /AndroidLibXrayLite - target-branch: main + target-branch: dev schedule: interval: daily timezone: Asia/Jakarta diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3dd58883..c25322e6 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -3,7 +3,7 @@ name: Build and Test on: pull_request: branches: - - main + - dev workflow_dispatch: branches: - dev diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 53f06c38..84417678 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -2,6 +2,8 @@ name: Release on: push: + branches: + - main tags: - "v*.*.*" diff --git a/.github/workflows/static.yml b/.github/workflows/static.yml index 088a0702..b06e3b20 100644 --- a/.github/workflows/static.yml +++ b/.github/workflows/static.yml @@ -4,6 +4,8 @@ name: Deploy static content to Pages on: # Allows you to run this workflow manually from the Actions tab workflow_dispatch: + branches: + - dev # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages permissions: diff --git a/.github/workflows/update-gradle-wrapper.yml b/.github/workflows/update-gradle-wrapper.yml index 7031cb5f..a302b16a 100644 --- a/.github/workflows/update-gradle-wrapper.yml +++ b/.github/workflows/update-gradle-wrapper.yml @@ -3,6 +3,8 @@ name: Update Gradle wrapper on: schedule: [{cron: "0 16 * * *"}] workflow_dispatch: + branches: + - dev permissions: contents: write # to be able to publish a GitHub release diff --git a/AndroidLibXrayLite/go.mod b/AndroidLibXrayLite/go.mod index 182a1a79..e9d3fc62 100644 --- a/AndroidLibXrayLite/go.mod +++ b/AndroidLibXrayLite/go.mod @@ -4,7 +4,7 @@ go 1.22.4 require ( github.com/xtls/xray-core v1.8.25-0.20240907003027-3d9137cb6fdd - golang.org/x/mobile v0.0.0-20240506190922-a1a533f289d3 + golang.org/x/mobile v0.0.0-20240930194658-c6794c95c70b golang.org/x/sys v0.25.0 ) @@ -27,7 +27,7 @@ require ( github.com/quic-go/quic-go v0.46.0 // indirect github.com/refraction-networking/utls v1.6.7 // indirect github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 // indirect - github.com/sagernet/sing v0.4.1 // indirect + github.com/sagernet/sing v0.4.3 // indirect github.com/sagernet/sing-shadowsocks v0.2.7 // indirect github.com/seiflotfy/cuckoofilter v0.0.0-20240715131351-a2f2c23f1771 // indirect github.com/v2fly/ss-bloomring v0.0.0-20210312155135-28617310f63e // indirect @@ -38,17 +38,20 @@ require ( go4.org/netipx v0.0.0-20231129151722-fdeea329fbba // indirect golang.org/x/crypto v0.27.0 // indirect golang.org/x/exp v0.0.0-20240531132922-fd00a4e0eefc // indirect - golang.org/x/mod v0.18.0 // indirect + golang.org/x/mod v0.21.0 // indirect golang.org/x/net v0.29.0 // indirect + golang.org/x/sync v0.8.0 // indirect golang.org/x/text v0.18.0 // indirect golang.org/x/time v0.5.0 // indirect - golang.org/x/tools v0.22.0 // indirect + golang.org/x/tools v0.25.0 // indirect golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117 // indirect - google.golang.org/grpc v1.66.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect + google.golang.org/grpc v1.67.0 // indirect google.golang.org/protobuf v1.34.2 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gvisor.dev/gvisor v0.0.0-20231202080848-1f7806d17489 // indirect lukechampine.com/blake3 v1.3.0 // indirect ) + +replace google.golang.org/grpc v1.67.0 => google.golang.org/grpc v1.66.1 diff --git a/AndroidLibXrayLite/go.sum b/AndroidLibXrayLite/go.sum index 16729f99..87dd19a1 100644 --- a/AndroidLibXrayLite/go.sum +++ b/AndroidLibXrayLite/go.sum @@ -50,8 +50,8 @@ github.com/refraction-networking/utls v1.6.7 h1:zVJ7sP1dJx/WtVuITug3qYUq034cDq9B github.com/refraction-networking/utls v1.6.7/go.mod h1:BC3O4vQzye5hqpmDTWUqi4P5DDhzJfkV1tdqtawQIH0= github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 h1:f/FNXud6gA3MNr8meMVVGxhp+QBTqY91tM8HjEuMjGg= github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3/go.mod h1:HgjTstvQsPGkxUsCd2KWxErBblirPizecHcpD3ffK+s= -github.com/sagernet/sing v0.4.1 h1:zVlpE+7k7AFoC2pv6ReqLf0PIHjihL/jsBl5k05PQFk= -github.com/sagernet/sing v0.4.1/go.mod h1:ieZHA/+Y9YZfXs2I3WtuwgyCZ6GPsIR7HdKb1SdEnls= +github.com/sagernet/sing v0.4.3 h1:Ty/NAiNnVd6844k7ujlL5lkzydhcTH5Psc432jXA4Y8= +github.com/sagernet/sing v0.4.3/go.mod h1:ieZHA/+Y9YZfXs2I3WtuwgyCZ6GPsIR7HdKb1SdEnls= github.com/sagernet/sing-shadowsocks v0.2.7 h1:zaopR1tbHEw5Nk6FAkM05wCslV6ahVegEZaKMv9ipx8= github.com/sagernet/sing-shadowsocks v0.2.7/go.mod h1:0rIKJZBR65Qi0zwdKezt4s57y/Tl1ofkaq6NlkzVuyE= github.com/seiflotfy/cuckoofilter v0.0.0-20240715131351-a2f2c23f1771 h1:emzAzMZ1L9iaKCTxdy3Em8Wv4ChIAGnfiz18Cda70g4= @@ -68,8 +68,8 @@ github.com/vishvananda/netns v0.0.4 h1:Oeaw1EM2JMxD51g9uhtC0D7erkIjgmj8+JZc26m1Y github.com/vishvananda/netns v0.0.4/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM= github.com/xtls/reality v0.0.0-20240712055506-48f0b2d5ed6d h1:+B97uD9uHLgAAulhigmys4BVwZZypzK7gPN3WtpgRJg= github.com/xtls/reality v0.0.0-20240712055506-48f0b2d5ed6d/go.mod h1:dm4y/1QwzjGaK17ofi0Vs6NpKAHegZky8qk6J2JJZAE= -github.com/xtls/xray-core v1.8.25-0.20240907003027-3d9137cb6fdd h1:SOBm0pxdipWhP8E4GbOOS0JZtRUE4NF6/3RKjdMHjGc= -github.com/xtls/xray-core v1.8.25-0.20240907003027-3d9137cb6fdd/go.mod h1:fJZjuOpUJXPMrZj7agA8lMkz34U2ziEybL/+ABblwE8= +github.com/xtls/xray-core v1.8.25-0.20240930152013-3b06af882de4 h1:gJX434Hl4x1vM/NXxXfstWDEND09+RAVvg2OhL17dc8= +github.com/xtls/xray-core v1.8.25-0.20240930152013-3b06af882de4/go.mod h1:5lT1S32jgjJaqE9UoFhi05nudRYcGrUd/bLuaa8mWJM= go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc= go4.org/netipx v0.0.0-20231129151722-fdeea329fbba h1:0b9z3AuHCjxk0x/opv64kcgZLBseWJUpBw5I82+2U4M= @@ -78,10 +78,10 @@ golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= golang.org/x/exp v0.0.0-20240531132922-fd00a4e0eefc h1:O9NuF4s+E/PvMIy+9IUZB9znFwUIXEWSstNjek6VpVg= golang.org/x/exp v0.0.0-20240531132922-fd00a4e0eefc/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc= -golang.org/x/mobile v0.0.0-20240506190922-a1a533f289d3 h1:lXH7reX0gtet9FgdXR0WDs3t1nt0QTjDLt1rrBQ/Qgs= -golang.org/x/mobile v0.0.0-20240506190922-a1a533f289d3/go.mod h1:EiXZlVfUTaAyySFVJb9rsODuiO+WXu8HrUuySb7nYFw= -golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0= -golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mobile v0.0.0-20240930194658-c6794c95c70b h1:vxPknApl9Z0hxiwF2MqAC8pI9Vr79/qaUj+6g6GE4gE= +golang.org/x/mobile v0.0.0-20240930194658-c6794c95c70b/go.mod h1:5EJr05J3jS1A5hwVNxs4vC0pIRxtWmwM15D1ZxCj93s= +golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0= +golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= @@ -95,16 +95,16 @@ golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= -golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA= -golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c= +golang.org/x/tools v0.25.0 h1:oFU9pkj/iJgs+0DT+VMHrx+oBKs/LJMV+Uvg78sl+fE= +golang.org/x/tools v0.25.0/go.mod h1:/vtpO8WL1N9cQC3FN5zPqb//fRXskFHbLKk4OW1Q7rg= golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 h1:B82qJJgjvYKsXS9jeunTOisW56dUokqW/FOteYJJ/yg= golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2/go.mod h1:deeaetjYA+DHMHg+sMSMI58GrEteJUUzzw7en6TJQcI= golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173 h1:/jFs0duh4rdb8uIfPMv78iAJGcPKDeqAFnaLBropIC4= golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173/go.mod h1:tkCQ4FQXmpAgYVh++1cq16/dH4QJtmvpRv19DWGAHSA= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117 h1:1GBuWVLM/KMVUv1t1En5Gs+gFZCNd360GGb4sSxtrhU= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240604185151-ef581f913117/go.mod h1:EfXuqaE1J41VCDicxHzUDm+8rk+7ZdXzHV0IhO/I6s0= -google.golang.org/grpc v1.66.0 h1:DibZuoBznOxbDQxRINckZcUvnCEvrW9pcWIE2yF9r1c= -google.golang.org/grpc v1.66.0/go.mod h1:s3/l6xSSCURdVfAnL+TqCNMyTDAGN6+lZeVxnZR128Y= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 h1:e7S5W7MGGLaSu8j3YjdezkZ+m1/Nm0uRVRMEMGk26Xs= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/grpc v1.66.1 h1:hO5qAXR19+/Z44hmvIM4dQFMSYX9XcWsByfoxutBpAM= +google.golang.org/grpc v1.66.1/go.mod h1:s3/l6xSSCURdVfAnL+TqCNMyTDAGN6+lZeVxnZR128Y= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= diff --git a/app/src/main/assets/custom_routing_black b/app/src/main/assets/custom_routing_black index 747e281e..757fc441 100644 --- a/app/src/main/assets/custom_routing_black +++ b/app/src/main/assets/custom_routing_black @@ -15,7 +15,7 @@ ] }, { - "remarks": "Block udp443", + "remarks": "Blocking udp 443", "outboundTag": "block", "port": "443", "network": "udp" @@ -28,17 +28,17 @@ ] }, { - "remarks": "Bypass LAN domain name", + "remarks": "Bypass LAN IP", "outboundTag": "direct", - "domain": [ - "geosite:private" + "ip": [ + "geoip:private" ] }, { - "remarks": "Bypass LAN IP", + "remarks": "Bypass LAN domain name", "outboundTag": "direct", - "ip": [ - "geoip:private" + "domain": [ + "geosite:private" ] }, { @@ -70,4 +70,4 @@ "port": "0-65535", "outboundTag": "direct" } -] \ No newline at end of file +] diff --git a/app/src/main/assets/custom_routing_global b/app/src/main/assets/custom_routing_global index 536b9ca5..b04900a6 100644 --- a/app/src/main/assets/custom_routing_global +++ b/app/src/main/assets/custom_routing_global @@ -1,6 +1,6 @@ [ { - "remarks": "Block udp443", + "remarks": "Block udp 443", "outboundTag": "block", "port": "443", "network": "udp" @@ -13,17 +13,17 @@ ] }, { - "remarks": "Bypass LAN domain name", + "remarks": "Bypass LAN IP", "outboundTag": "direct", - "domain": [ - "geosite:private" + "ip": [ + "geoip:private" ] }, { - "remarks": "Bypass LAN IP", + "remarks": "Bypass LAN domain name", "outboundTag": "direct", - "ip": [ - "geoip:private" + "domain": [ + "geosite:private" ] }, { @@ -31,4 +31,4 @@ "port": "0-65535", "outboundTag": "proxy" } -] \ No newline at end of file +] diff --git a/app/src/main/assets/custom_routing_white b/app/src/main/assets/custom_routing_white index 3cb8ea73..ccd331f2 100644 --- a/app/src/main/assets/custom_routing_white +++ b/app/src/main/assets/custom_routing_white @@ -8,7 +8,7 @@ ] }, { - "remarks": "Block udp443", + "remarks": "Block udp 443", "outboundTag": "block", "port": "443", "network": "udp" @@ -21,17 +21,17 @@ ] }, { - "remarks": "Bypass LAN domain name", + "remarks": "Bypass LAN IP", "outboundTag": "direct", - "domain": [ - "geosite:private" + "ip": [ + "geoip:private" ] }, { - "remarks": "Bypass LAN IP", + "remarks": "Bypass LAN domain name", "outboundTag": "direct", - "ip": [ - "geoip:private" + "domain": [ + "geosite:private" ] }, { @@ -78,4 +78,4 @@ "port": "0-65535", "outboundTag": "proxy" } -] \ No newline at end of file +] diff --git a/app/src/main/java/com/neko/uwu/TambahActivity.kt b/app/src/main/java/com/neko/uwu/TambahActivity.kt index 46e71795..513e4bc4 100644 --- a/app/src/main/java/com/neko/uwu/TambahActivity.kt +++ b/app/src/main/java/com/neko/uwu/TambahActivity.kt @@ -40,7 +40,7 @@ class TambahActivity : BaseActivity() { val toolbar = findViewById(R.id.toolbar) val toolbarLayout = findViewById(R.id.collapsing_toolbar) setSupportActionBar(toolbar) - supportActionBar?.setDisplayHomeAsUpEnabled(true) + supportActionBar?.setDisplayHomeAsUpEnabled(false) softInputAssist = SoftInputAssist(this) etName = findViewById(R.id.et_name) diff --git a/app/src/main/kotlin/com/neko/v2ray/AppConfig.kt b/app/src/main/kotlin/com/neko/v2ray/AppConfig.kt index 7b9f3f95..8cbe9c4c 100644 --- a/app/src/main/kotlin/com/neko/v2ray/AppConfig.kt +++ b/app/src/main/kotlin/com/neko/v2ray/AppConfig.kt @@ -108,7 +108,10 @@ object AppConfig { const val DNS_PROXY = "1.1.1.1" const val DNS_DIRECT = "223.5.5.5" const val DNS_VPN = "1.1.1.1" - + const val GEOSITE_PRIVATE = "geosite:private" + const val GEOSITE_CN = "geosite:cn" + const val GEOIP_PRIVATE = "geoip:private" + const val GEOIP_CN = "geoip:cn" /** Ports and addresses for various services. */ const val PORT_LOCAL_DNS = "10853" diff --git a/app/src/main/kotlin/com/neko/v2ray/util/SettingsManager.kt b/app/src/main/kotlin/com/neko/v2ray/util/SettingsManager.kt index 1a2348d5..615b5dd7 100644 --- a/app/src/main/kotlin/com/neko/v2ray/util/SettingsManager.kt +++ b/app/src/main/kotlin/com/neko/v2ray/util/SettingsManager.kt @@ -2,7 +2,10 @@ package com.neko.v2ray.util import android.content.Context import android.text.TextUtils + import com.neko.v2ray.AppConfig +import com.neko.v2ray.AppConfig.GEOIP_PRIVATE +import com.neko.v2ray.AppConfig.GEOSITE_PRIVATE import com.neko.v2ray.dto.RulesetItem import com.neko.v2ray.dto.ServerConfig import com.neko.v2ray.util.MmkvManager.decodeProfileConfig @@ -108,7 +111,11 @@ object SettingsManager { fun routingRulesetsBypassLan(): Boolean { val rulesetItems = MmkvManager.decodeRoutingRulesets() - val exist = rulesetItems?.any { it.enabled && it.domain?.contains(":private") == true } + val exist = rulesetItems?.any { + it.enabled + && (it.domain?.contains(GEOSITE_PRIVATE) == true + || it.ip?.contains(GEOIP_PRIVATE) == true) + } return exist == true } diff --git a/app/src/main/kotlin/com/neko/v2ray/util/V2rayConfigUtil.kt b/app/src/main/kotlin/com/neko/v2ray/util/V2rayConfigUtil.kt index c7993449..dd6bbebb 100644 --- a/app/src/main/kotlin/com/neko/v2ray/util/V2rayConfigUtil.kt +++ b/app/src/main/kotlin/com/neko/v2ray/util/V2rayConfigUtil.kt @@ -3,9 +3,13 @@ package com.neko.v2ray.util import android.content.Context import android.text.TextUtils import android.util.Log + import com.neko.v2ray.AppConfig import com.neko.v2ray.AppConfig.ANG_PACKAGE +import com.neko.v2ray.AppConfig.GEOIP_CN +import com.neko.v2ray.AppConfig.GEOSITE_CN import com.neko.v2ray.AppConfig.LOOPBACK +import com.neko.v2ray.AppConfig.GEOSITE_PRIVATE import com.neko.v2ray.AppConfig.PROTOCOL_FREEDOM import com.neko.v2ray.AppConfig.TAG_BLOCKED import com.neko.v2ray.AppConfig.TAG_DIRECT @@ -221,7 +225,9 @@ object V2rayConfigUtil { rulesetItems?.forEach { key -> if (key != null && key.enabled && key.outboundTag == tag && !key.domain.isNullOrEmpty()) { key.domain?.forEach { - if (it.startsWith("geosite:") || it.startsWith("domain:")) { + if (it != GEOSITE_PRIVATE + && (it.startsWith("geosite:") || it.startsWith("domain:")) + ) { domain.add(it) } } @@ -234,7 +240,7 @@ object V2rayConfigUtil { private fun customLocalDns(v2rayConfig: V2rayConfig): Boolean { try { if (settingsStorage?.decodeBool(AppConfig.PREF_FAKE_DNS_ENABLED) == true) { - val geositeCn = arrayListOf("geosite:cn") + val geositeCn = arrayListOf(GEOSITE_CN) val proxyDomain = userRule2Domain(TAG_PROXY) val directDomain = userRule2Domain(TAG_DIRECT) // fakedns with all domains to make it always top priority @@ -325,8 +331,8 @@ object V2rayConfigUtil { // domestic DNS val domesticDns = Utils.getDomesticDnsServers() val directDomain = userRule2Domain(TAG_DIRECT) - val isCnRoutingMode = directDomain.contains("geosite:cn") - val geoipCn = arrayListOf("geoip:cn") + val isCnRoutingMode = directDomain.contains(GEOSITE_CN) + val geoipCn = arrayListOf(GEOIP_CN) if (directDomain.size > 0) { servers.add( V2rayConfig.DnsBean.ServersBean( diff --git a/build.gradle.kts b/build.gradle.kts index 94deedae..8180108b 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,7 +1,7 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. plugins { - id("com.android.application") version "8.6.1" apply false - id("com.android.library") version "8.6.1" apply false + id("com.android.application") version "8.7.0" apply false + id("com.android.library") version "8.7.0" apply false id("org.jetbrains.kotlin.android") version "2.0.20" apply false id("com.mikepenz.aboutlibraries.plugin") version "11.2.3" apply false }