mirror of
https://github.com/FoggedLens/deflock.git
synced 2026-02-12 15:02:45 +00:00
merge master
This commit is contained in:
2
.env.example
Normal file
2
.env.example
Normal file
@@ -0,0 +1,2 @@
|
||||
# used for getting list of sponsors
|
||||
GITHUB_TOKEN=github_pat_blah-blah-blah
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -49,3 +49,5 @@ serverless/*/src/*
|
||||
!serverless/*/src/requirements.txt
|
||||
|
||||
# TODO: need a better way to handle python packages
|
||||
|
||||
.env
|
||||
|
||||
@@ -12,3 +12,5 @@ services:
|
||||
retries: 3 # Number of retries before marking as unhealthy
|
||||
start_period: 10s # Time to wait before starting health checks
|
||||
stdin_open: true
|
||||
environment:
|
||||
- GITHUB_TOKEN
|
||||
|
||||
@@ -14,6 +14,8 @@ lazy val root = (project in file("."))
|
||||
val PekkoVersion = "1.0.3"
|
||||
val PekkoHttpVersion = "1.0.1"
|
||||
libraryDependencies ++= Seq(
|
||||
"ch.qos.logback" % "logback-classic" % "1.5.6",
|
||||
"org.slf4j" % "slf4j-api" % "2.0.12",
|
||||
"org.apache.pekko" %% "pekko-actor-typed" % PekkoVersion,
|
||||
"org.apache.pekko" %% "pekko-stream" % PekkoVersion,
|
||||
"org.apache.pekko" %% "pekko-http" % PekkoHttpVersion,
|
||||
@@ -21,3 +23,10 @@ libraryDependencies ++= Seq(
|
||||
"org.apache.pekko" %% "pekko-http-cors" % PekkoHttpVersion,
|
||||
"org.apache.pekko" %% "pekko-slf4j" % PekkoVersion,
|
||||
)
|
||||
|
||||
assembly / assemblyMergeStrategy := {
|
||||
case PathList("module-info.class") => MergeStrategy.first
|
||||
case x =>
|
||||
val oldStrategy = (assembly / assemblyMergeStrategy).value
|
||||
oldStrategy(x)
|
||||
}
|
||||
|
||||
12
shotgun/src/main/resources/logback.xml
Normal file
12
shotgun/src/main/resources/logback.xml
Normal file
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<encoder>
|
||||
<pattern>%d{yyyy-MM-dd HH:mm:ss} %-5level %logger{36} - %msg%n</pattern>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<root level="INFO">
|
||||
<appender-ref ref="STDOUT" />
|
||||
</root>
|
||||
</configuration>
|
||||
@@ -17,9 +17,12 @@ import java.net.URLEncoder
|
||||
import java.nio.charset.StandardCharsets
|
||||
import scala.concurrent.ExecutionContextExecutor
|
||||
import scala.io.StdIn
|
||||
import org.slf4j.LoggerFactory
|
||||
|
||||
object ShotgunServer {
|
||||
|
||||
val logger = LoggerFactory.getLogger(getClass)
|
||||
|
||||
def main(args: Array[String]): Unit = {
|
||||
|
||||
implicit val system: ActorSystem = ActorSystem("my-system")
|
||||
@@ -28,6 +31,7 @@ object ShotgunServer {
|
||||
|
||||
val client = new services.OverpassClient()
|
||||
val nominatim = new services.NominatimClient()
|
||||
val githubClient = new services.GithubClient()
|
||||
|
||||
// CORS
|
||||
val allowedOrigins = List(
|
||||
@@ -72,6 +76,13 @@ object ShotgunServer {
|
||||
}
|
||||
}
|
||||
},
|
||||
path("sponsors" / "github") {
|
||||
get {
|
||||
onSuccess(githubClient.getSponsors("frillweeman")) { json =>
|
||||
complete(json)
|
||||
}
|
||||
}
|
||||
},
|
||||
path("oauth2" / "callback") {
|
||||
get {
|
||||
parameters(Symbol("code").?) { (code) =>
|
||||
|
||||
68
shotgun/src/main/scala/services/GithubClient.scala
Normal file
68
shotgun/src/main/scala/services/GithubClient.scala
Normal file
@@ -0,0 +1,68 @@
|
||||
package services
|
||||
|
||||
import org.apache.pekko.actor.ActorSystem
|
||||
import org.apache.pekko.http.javadsl.model.headers.{Authorization, HttpCredentials, UserAgent}
|
||||
import org.apache.pekko.http.scaladsl.Http
|
||||
import org.apache.pekko.http.scaladsl.model.{HttpMethods, HttpRequest, StatusCodes}
|
||||
import org.apache.pekko.http.scaladsl.unmarshalling.Unmarshal
|
||||
import spray.json.JsValue
|
||||
import spray.json._
|
||||
import org.apache.pekko.http.scaladsl.model.ContentTypes
|
||||
import org.apache.pekko.http.scaladsl.model.HttpEntity
|
||||
import org.slf4j.LoggerFactory
|
||||
|
||||
import scala.concurrent.{ExecutionContextExecutor, Future}
|
||||
|
||||
class GithubClient(implicit val system: ActorSystem, implicit val executionContext: ExecutionContextExecutor) {
|
||||
val logger = LoggerFactory.getLogger(getClass)
|
||||
val graphQLEndpoint = "https://api.github.com/graphql"
|
||||
private val githubApiToken = sys.env("GITHUB_TOKEN")
|
||||
|
||||
def getSponsors(username: String): Future[JsArray] = {
|
||||
|
||||
val query = s"""
|
||||
|query {
|
||||
| user(login: "$username") {
|
||||
| sponsorshipsAsMaintainer(first: 100) {
|
||||
| nodes {
|
||||
| sponsor {
|
||||
| login
|
||||
| name
|
||||
| avatarUrl
|
||||
| }
|
||||
| }
|
||||
| }
|
||||
| }
|
||||
|}
|
||||
|""".stripMargin.replace("\n", " ").replace("\"", "\\\"")
|
||||
|
||||
val jsonRequest = s"""{"query": "$query", "variables": ""}"""
|
||||
val jsonEntity = HttpEntity(ContentTypes.`application/json`, jsonRequest)
|
||||
val request = HttpRequest(
|
||||
headers = List(
|
||||
UserAgent.create("Shotgun"),
|
||||
Authorization.create(HttpCredentials.create("Bearer", githubApiToken))
|
||||
),
|
||||
method = HttpMethods.POST,
|
||||
uri = graphQLEndpoint,
|
||||
entity = jsonEntity
|
||||
)
|
||||
|
||||
Http().singleRequest(request).flatMap { response =>
|
||||
response.status match {
|
||||
case StatusCodes.OK =>
|
||||
Unmarshal(response.entity).to[String].map { jsonString =>
|
||||
jsonString.parseJson.asJsObject
|
||||
.fields("data").asJsObject
|
||||
.fields("user").asJsObject
|
||||
.fields("sponsorshipsAsMaintainer")
|
||||
.asJsObject.fields("nodes")
|
||||
.asInstanceOf[JsArray]
|
||||
}
|
||||
case _ =>
|
||||
response.discardEntityBytes()
|
||||
Future.failed(new Exception(s"Failed to get sponsors: ${response.status}"))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,6 @@ import pekko.http.scaladsl.Http
|
||||
import pekko.http.scaladsl.model._
|
||||
import pekko.http.scaladsl.unmarshalling.Unmarshal
|
||||
import spray.json._
|
||||
import DefaultJsonProtocol._
|
||||
import scala.concurrent.{ExecutionContextExecutor, Future}
|
||||
|
||||
case class BoundingBox(minLat: Double, minLng: Double, maxLat: Double, maxLng: Double)
|
||||
|
||||
@@ -6,6 +6,9 @@
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
|
||||
<link rel="manifest" href="/site.webmanifest">
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=PT+Serif:ital,wght@0,400;0,700;1,400;1,700&display=swap" rel="stylesheet">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta property="og:title" content="DeFlock" />
|
||||
<meta property="og:description" content="Your car is being tracked. See where license plate readers are, avoid them, and report new ones. Protect your privacy at Deflock.me." />
|
||||
|
||||
150
webapp/package-lock.json
generated
150
webapp/package-lock.json
generated
@@ -9,6 +9,7 @@
|
||||
"version": "0.0.0",
|
||||
"dependencies": {
|
||||
"@types/leaflet.markercluster": "^1.5.5",
|
||||
"@unhead/vue": "^1.11.14",
|
||||
"axios": "^1.7.7",
|
||||
"countup.js": "^2.8.0",
|
||||
"leaflet.markercluster": "^1.5.3",
|
||||
@@ -702,6 +703,59 @@
|
||||
"undici-types": "~6.19.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@unhead/dom": {
|
||||
"version": "1.11.14",
|
||||
"resolved": "https://registry.npmjs.org/@unhead/dom/-/dom-1.11.14.tgz",
|
||||
"integrity": "sha512-FaHCWo9JR4h7PCpSRaXuMC6ifXOuBzlI0PD1MmUcxND2ayDl1d6DauIbN8TUf9TDRxNkrK1Ehb0OCXjC1ZJtrg==",
|
||||
"dependencies": {
|
||||
"@unhead/schema": "1.11.14",
|
||||
"@unhead/shared": "1.11.14"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/harlan-zw"
|
||||
}
|
||||
},
|
||||
"node_modules/@unhead/schema": {
|
||||
"version": "1.11.14",
|
||||
"resolved": "https://registry.npmjs.org/@unhead/schema/-/schema-1.11.14.tgz",
|
||||
"integrity": "sha512-V9W9u5tF1/+TiLqxu+Qvh1ShoMDkPEwHoEo4DKdDG6ko7YlbzFfDxV6el9JwCren45U/4Vy/4Xi7j8OH02wsiA==",
|
||||
"dependencies": {
|
||||
"hookable": "^5.5.3",
|
||||
"zhead": "^2.2.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/harlan-zw"
|
||||
}
|
||||
},
|
||||
"node_modules/@unhead/shared": {
|
||||
"version": "1.11.14",
|
||||
"resolved": "https://registry.npmjs.org/@unhead/shared/-/shared-1.11.14.tgz",
|
||||
"integrity": "sha512-41Qt4PJKYVrEGOTXgBJLRYrEu3S7n5stoB4TFC6312CIBVedXqg7voHQurn32LVDjpfJftjLa2ggCjpqdqoRDw==",
|
||||
"dependencies": {
|
||||
"@unhead/schema": "1.11.14"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/harlan-zw"
|
||||
}
|
||||
},
|
||||
"node_modules/@unhead/vue": {
|
||||
"version": "1.11.14",
|
||||
"resolved": "https://registry.npmjs.org/@unhead/vue/-/vue-1.11.14.tgz",
|
||||
"integrity": "sha512-6nfi7FsZ936gscmj+1nUB1pybiFMFbnuEFo7B/OY2klpLWsYDUOVvpsJhbu7C3u7wkTlJXglmAk6jdd8I7WgZA==",
|
||||
"dependencies": {
|
||||
"@unhead/schema": "1.11.14",
|
||||
"@unhead/shared": "1.11.14",
|
||||
"defu": "^6.1.4",
|
||||
"hookable": "^5.5.3",
|
||||
"unhead": "1.11.14"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/harlan-zw"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"vue": ">=2.7 || >=3"
|
||||
}
|
||||
},
|
||||
"node_modules/@vitejs/plugin-vue": {
|
||||
"version": "5.1.4",
|
||||
"resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.1.4.tgz",
|
||||
@@ -966,6 +1020,11 @@
|
||||
"integrity": "sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/defu": {
|
||||
"version": "6.1.4",
|
||||
"resolved": "https://registry.npmjs.org/defu/-/defu-6.1.4.tgz",
|
||||
"integrity": "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg=="
|
||||
},
|
||||
"node_modules/delayed-stream": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||
@@ -1083,6 +1142,11 @@
|
||||
"he": "bin/he"
|
||||
}
|
||||
},
|
||||
"node_modules/hookable": {
|
||||
"version": "5.5.3",
|
||||
"resolved": "https://registry.npmjs.org/hookable/-/hookable-5.5.3.tgz",
|
||||
"integrity": "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ=="
|
||||
},
|
||||
"node_modules/isexe": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
|
||||
@@ -1421,6 +1485,20 @@
|
||||
"integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/unhead": {
|
||||
"version": "1.11.14",
|
||||
"resolved": "https://registry.npmjs.org/unhead/-/unhead-1.11.14.tgz",
|
||||
"integrity": "sha512-XmXW0aZyX9kGk9ejCKCSvv/J4T3Rt4hoAe2EofM+nhG+zwZ7AArUMK/0F/fj6FTkfgY0u0/JryE00qUDULgygA==",
|
||||
"dependencies": {
|
||||
"@unhead/dom": "1.11.14",
|
||||
"@unhead/schema": "1.11.14",
|
||||
"@unhead/shared": "1.11.14",
|
||||
"hookable": "^5.5.3"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/harlan-zw"
|
||||
}
|
||||
},
|
||||
"node_modules/vite": {
|
||||
"version": "5.4.7",
|
||||
"resolved": "https://registry.npmjs.org/vite/-/vite-5.4.7.tgz",
|
||||
@@ -1605,6 +1683,14 @@
|
||||
"engines": {
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/zhead": {
|
||||
"version": "2.2.4",
|
||||
"resolved": "https://registry.npmjs.org/zhead/-/zhead-2.2.4.tgz",
|
||||
"integrity": "sha512-8F0OI5dpWIA5IGG5NHUg9staDwz/ZPxZtvGVf01j7vHqSyZ0raHY+78atOVxRqb73AotX22uV1pXt3gYSstGag==",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/harlan-zw"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
@@ -1961,6 +2047,44 @@
|
||||
"undici-types": "~6.19.2"
|
||||
}
|
||||
},
|
||||
"@unhead/dom": {
|
||||
"version": "1.11.14",
|
||||
"resolved": "https://registry.npmjs.org/@unhead/dom/-/dom-1.11.14.tgz",
|
||||
"integrity": "sha512-FaHCWo9JR4h7PCpSRaXuMC6ifXOuBzlI0PD1MmUcxND2ayDl1d6DauIbN8TUf9TDRxNkrK1Ehb0OCXjC1ZJtrg==",
|
||||
"requires": {
|
||||
"@unhead/schema": "1.11.14",
|
||||
"@unhead/shared": "1.11.14"
|
||||
}
|
||||
},
|
||||
"@unhead/schema": {
|
||||
"version": "1.11.14",
|
||||
"resolved": "https://registry.npmjs.org/@unhead/schema/-/schema-1.11.14.tgz",
|
||||
"integrity": "sha512-V9W9u5tF1/+TiLqxu+Qvh1ShoMDkPEwHoEo4DKdDG6ko7YlbzFfDxV6el9JwCren45U/4Vy/4Xi7j8OH02wsiA==",
|
||||
"requires": {
|
||||
"hookable": "^5.5.3",
|
||||
"zhead": "^2.2.4"
|
||||
}
|
||||
},
|
||||
"@unhead/shared": {
|
||||
"version": "1.11.14",
|
||||
"resolved": "https://registry.npmjs.org/@unhead/shared/-/shared-1.11.14.tgz",
|
||||
"integrity": "sha512-41Qt4PJKYVrEGOTXgBJLRYrEu3S7n5stoB4TFC6312CIBVedXqg7voHQurn32LVDjpfJftjLa2ggCjpqdqoRDw==",
|
||||
"requires": {
|
||||
"@unhead/schema": "1.11.14"
|
||||
}
|
||||
},
|
||||
"@unhead/vue": {
|
||||
"version": "1.11.14",
|
||||
"resolved": "https://registry.npmjs.org/@unhead/vue/-/vue-1.11.14.tgz",
|
||||
"integrity": "sha512-6nfi7FsZ936gscmj+1nUB1pybiFMFbnuEFo7B/OY2klpLWsYDUOVvpsJhbu7C3u7wkTlJXglmAk6jdd8I7WgZA==",
|
||||
"requires": {
|
||||
"@unhead/schema": "1.11.14",
|
||||
"@unhead/shared": "1.11.14",
|
||||
"defu": "^6.1.4",
|
||||
"hookable": "^5.5.3",
|
||||
"unhead": "1.11.14"
|
||||
}
|
||||
},
|
||||
"@vitejs/plugin-vue": {
|
||||
"version": "5.1.4",
|
||||
"resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.1.4.tgz",
|
||||
@@ -2196,6 +2320,11 @@
|
||||
"integrity": "sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==",
|
||||
"dev": true
|
||||
},
|
||||
"defu": {
|
||||
"version": "6.1.4",
|
||||
"resolved": "https://registry.npmjs.org/defu/-/defu-6.1.4.tgz",
|
||||
"integrity": "sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg=="
|
||||
},
|
||||
"delayed-stream": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||
@@ -2270,6 +2399,11 @@
|
||||
"integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==",
|
||||
"dev": true
|
||||
},
|
||||
"hookable": {
|
||||
"version": "5.5.3",
|
||||
"resolved": "https://registry.npmjs.org/hookable/-/hookable-5.5.3.tgz",
|
||||
"integrity": "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ=="
|
||||
},
|
||||
"isexe": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
|
||||
@@ -2488,6 +2622,17 @@
|
||||
"integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==",
|
||||
"dev": true
|
||||
},
|
||||
"unhead": {
|
||||
"version": "1.11.14",
|
||||
"resolved": "https://registry.npmjs.org/unhead/-/unhead-1.11.14.tgz",
|
||||
"integrity": "sha512-XmXW0aZyX9kGk9ejCKCSvv/J4T3Rt4hoAe2EofM+nhG+zwZ7AArUMK/0F/fj6FTkfgY0u0/JryE00qUDULgygA==",
|
||||
"requires": {
|
||||
"@unhead/dom": "1.11.14",
|
||||
"@unhead/schema": "1.11.14",
|
||||
"@unhead/shared": "1.11.14",
|
||||
"hookable": "^5.5.3"
|
||||
}
|
||||
},
|
||||
"vite": {
|
||||
"version": "5.4.7",
|
||||
"resolved": "https://registry.npmjs.org/vite/-/vite-5.4.7.tgz",
|
||||
@@ -2557,6 +2702,11 @@
|
||||
"requires": {
|
||||
"isexe": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"zhead": {
|
||||
"version": "2.2.4",
|
||||
"resolved": "https://registry.npmjs.org/zhead/-/zhead-2.2.4.tgz",
|
||||
"integrity": "sha512-8F0OI5dpWIA5IGG5NHUg9staDwz/ZPxZtvGVf01j7vHqSyZ0raHY+78atOVxRqb73AotX22uV1pXt3gYSstGag=="
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
"type-check": "vue-tsc --build --force"
|
||||
},
|
||||
"dependencies": {
|
||||
"@unhead/vue": "^1.11.14",
|
||||
"@types/leaflet.markercluster": "^1.5.5",
|
||||
"axios": "^1.7.7",
|
||||
"countup.js": "^2.8.0",
|
||||
|
||||
BIN
webapp/public/chicago-pd.jpg
Normal file
BIN
webapp/public/chicago-pd.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 108 KiB |
BIN
webapp/public/torches.webp
Normal file
BIN
webapp/public/torches.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 313 KiB |
@@ -15,6 +15,7 @@ const items = [
|
||||
{ title: 'Home', icon: 'mdi-home', to: '/' },
|
||||
{ title: 'Map', icon: 'mdi-map', to: '/map' },
|
||||
{ title: 'What is an ALPR?', icon: 'mdi-cctv', to: '/what-is-an-alpr' },
|
||||
{ title: 'Dangers of ALPRs', icon: 'mdi-shield-alert', to: '/dangers' },
|
||||
{ title: 'Report an ALPR', icon: 'mdi-map-marker-plus', to: '/report' },
|
||||
{ title: 'Known Operators', icon: 'mdi-police-badge', to: '/operators' },
|
||||
// { title: 'About', icon: 'mdi-information', to: '/about' },
|
||||
@@ -25,7 +26,7 @@ const metaItems = [
|
||||
{ title: 'Discord', icon: 'mdi-chat-processing-outline', href: 'https://discord.gg/aV7v4R3sKT'},
|
||||
{ title: 'Contact', icon: 'mdi-email-outline', to: '/contact' },
|
||||
{ title: 'GitHub', icon: 'mdi-github', href: 'https://github.com/frillweeman/deflock'},
|
||||
{ title: 'Donate', icon: 'mdi-heart', href: 'https://github.com/sponsors/frillweeman'},
|
||||
{ title: 'Donate', icon: 'mdi-heart', to: '/donate'},
|
||||
];
|
||||
const drawer = ref(false)
|
||||
|
||||
|
||||
@@ -21,3 +21,12 @@ a:hover {
|
||||
.leaflet-bar a {
|
||||
color: var(--df-text-color) !important;
|
||||
}
|
||||
|
||||
p {
|
||||
font-family: "PT Serif", serif;
|
||||
/* font-size: 1.1em; */
|
||||
}
|
||||
|
||||
.serif {
|
||||
font-family: "PT Serif", serif;
|
||||
}
|
||||
|
||||
@@ -15,7 +15,10 @@
|
||||
</v-list-item>
|
||||
<v-list-item>
|
||||
<v-icon start>mdi-factory</v-icon> <b>
|
||||
<span v-if="alpr.tags.brand">
|
||||
<span v-if="alpr.tags.manufacturer">
|
||||
{{ alpr.tags.manufacturer }}
|
||||
</span>
|
||||
<span v-else-if="alpr.tags.brand">
|
||||
{{ alpr.tags.brand }}
|
||||
</span>
|
||||
<span v-else>
|
||||
|
||||
178
webapp/src/components/Dangers.vue
Normal file
178
webapp/src/components/Dangers.vue
Normal file
@@ -0,0 +1,178 @@
|
||||
<template>
|
||||
<v-expansion-panels multiple>
|
||||
<v-expansion-panel>
|
||||
<v-expansion-panel-title class="font-weight-bold">
|
||||
ALPRs Do Not Reduce Crime
|
||||
</v-expansion-panel-title>
|
||||
<v-expansion-panel-text>
|
||||
<p>
|
||||
There's no independent research proving that ALPRs can reduce crime. Headlines and supporting studies claiming otherwise are often produced by the companies selling ALPRs and the police agencies buying them.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
For example, Flock Safety claims that <a href="https://www.flocksafety.com/articles/10-of-reported-crime-in-the-u-s-is-solved-using-flock-technology" target="_blank">10% of Reported Crime in the U.S. Is Solved Using Flock Technology.</a> The study that Flock cites was conducted by two Flock employees and “given legitimacy with the 'oversight' of two academic researchers whose names are also on the paper” according to <a href="https://www.404media.co/researcher-who-oversaw-flock-surveillance-study-now-has-concerns-about-it/" target="_blank">a report by 404 Media</a>. Flock Safety is using the veneer of an academic study as part of its sales pitch.
|
||||
</p>
|
||||
|
||||
<v-divider class="my-6" />
|
||||
|
||||
<p>
|
||||
What research does exist regarding the ability of ALPRs to reduce crime is inconclusive at best:
|
||||
</p>
|
||||
|
||||
<quoted-source source-url="https://example.com/study" attribution-text="Journal of Experimental Criminology">
|
||||
Our findings indicate that, when small numbers of LPR patrols are used in crime hot spots in the way we have tested them here, they do not seem to generate either a general or offense-specific deterrent effect.
|
||||
</quoted-source>
|
||||
|
||||
<quoted-source source-url="https://www.independent.org/publications/article.asp?id=13893" attribution-text="Automated License Plate Readers: A Study in Failure">
|
||||
There is not even a moderate degree of correlation between ALPRs and stolen vehicle recoveries, let alone any apparent casualty
|
||||
</quoted-source>
|
||||
</v-expansion-panel-text>
|
||||
</v-expansion-panel>
|
||||
|
||||
<v-expansion-panel>
|
||||
<v-expansion-panel-title class="font-weight-bold">
|
||||
ALPRs Are Dragnet Surveillance
|
||||
</v-expansion-panel-title>
|
||||
<v-expansion-panel-text>
|
||||
<p><i>
|
||||
See <a href="https://en.wikipedia.org/wiki/Dragnet_(policing)" target="_blank">Dragnet (Policing)</a> on Wikipedia.
|
||||
</i></p>
|
||||
<p>
|
||||
A study of ALPRs in Piedmont, CA, found that <b>less than 0.3%</b> of ALPR hits might translate into a useful investigative lead. Most license plates recorded were not on a hot list, yet police still logged information on people's movements throughout the day.
|
||||
</p>
|
||||
<p>
|
||||
Flock Safety provides Transparency Portals to their police customers, which allow the public to see the data collected by ALPRs. From these portals, we can see that the vast majority of license plates scanned are not on a hot list (vehicles suspected of being involved in crimes). For example:
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<a href="https://transparency.flocksafety.com/oak-park-il-pd" target="_blank">Oak Park, IL Transparency Portal</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://transparency.flocksafety.com/vallejo-ca-pd" target="_blank">Vallejo, CA Transparency Portal</a>
|
||||
</li>
|
||||
</ul>
|
||||
</v-expansion-panel-text>
|
||||
</v-expansion-panel>
|
||||
|
||||
<v-expansion-panel>
|
||||
<v-expansion-panel-title class="font-weight-bold">
|
||||
ALPR Errors Create Dangerous Police Interactions
|
||||
</v-expansion-panel-title>
|
||||
<v-expansion-panel-text>
|
||||
<p>
|
||||
ALPR misread errors have led to dangerous police encounters, including pulling guns on innocent drivers. Here are just a few examples:
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="https://www.aclu.org/blog/privacy-technology/location-tracking/san-francisco-woman-pulled-out-car-gunpoint-because" target="_blank">San Francisco Woman Pulled Out of Car at Gunpoint Because of License Plate Reader Error</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://gizmodo.com/cops-terrorize-black-family-but-blame-license-plate-rea-1844602731" target="_blank">Cops Terrorize Black Family but Blame License Plate Reader for Misidentifying 'Stolen' Vehicle</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://www.techdirt.com/2019/02/20/deputies-sued-after-false-alpr-hit-leads-to-guns-out-traffic-stop-california-privacy-activist/" target="_blank">Deputies Sued After False ALPR Hit Leads To Guns-Out Traffic Stop Of California Privacy Activist</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://www.ktvu.com/news/privacy-advocate-sues-coco-sheriffs-deputies-after-license-plate-readers-target-his-car-stolen" target="_blank">Privacy advocate sues CoCo sheriff's deputies after license plate readers target his car stolen</a>
|
||||
</li>
|
||||
</ul>
|
||||
</v-expansion-panel-text>
|
||||
</v-expansion-panel>
|
||||
|
||||
<v-expansion-panel>
|
||||
<v-expansion-panel-title class="font-weight-bold">
|
||||
ALPRs Result in Racist Policing
|
||||
</v-expansion-panel-title>
|
||||
<v-expansion-panel-text>
|
||||
<p>
|
||||
ALPRs are more likely to surveil communities with a higher density of Black and brown people, reinforcing systemic racism in policing.
|
||||
</p>
|
||||
<p>
|
||||
The Electronic Frontier Foundation <a href="https://www.eff.org/deeplinks/2015/01/what-we-learned-oakland-raw-alpr-data" target="_blank">reviewed the use of ALPRs by the Oakland Police Department</a> and found that ALPR cameras were more likely to scan license plates in communities with a higher density of Black and brown people than in communities with a higher density of white people.
|
||||
</p>
|
||||
|
||||
<p class="mt-4"><a href="https://www.ap.org/ap-in-the-news/2012/with-cameras-informants-nypd-eyed-mosques" target="_blank">A report by The Associated Press</a> shows that after 9/11, the NYPD used ALPRs to monitor Muslims visiting mosques.</p>
|
||||
|
||||
<p>A study of Flock Safety’s impact in Oak Park, IL found:</p>
|
||||
<quoted-source source-url="https://www.freedomtothriveop.com/blog/zine-analyzes-flock-alpr-cameras-in-oak-park-il" attribution-text="Freedom to Thrive Oak Park">
|
||||
In the first 10 months of their use, 84% of the drivers stopped by Oak Park police because of Flock were Black.
|
||||
</quoted-source>
|
||||
</v-expansion-panel-text>
|
||||
</v-expansion-panel>
|
||||
|
||||
<v-expansion-panel>
|
||||
<v-expansion-panel-title class="font-weight-bold">
|
||||
ALPRs Put Undocumented People at Risk
|
||||
</v-expansion-panel-title>
|
||||
<v-expansion-panel-text>
|
||||
<p>
|
||||
Police agencies frequently share ALPR data with ICE, putting undocumented people at risk, even in states where this is legally prohibited:
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="https://www.latimes.com/business/technology/story/2020-12-21/pasadena-long-beach-police-ice-automated-license-plate-reader-data" target="_blank">Police in Pasadena, Long Beach pledged not to send license plate data to ICE. They shared it anyway.</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://www.aclu-il.org/en/press-releases/ice-targeting-immigrants-based-automatic-license-plate-reader-alpr-data-supplied" target="_blank">Documents Reveal ICE Using Driver Location Data From Local Police for Deportations</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://www.nwpb.org/2022/12/22/new-report-finds-data-sharing-with-federal-immigration-agencies-might-violate-washington-law/" target="_blank">New report finds data sharing with federal immigration agencies might violate Washington law</a>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</v-expansion-panel-text>
|
||||
</v-expansion-panel>
|
||||
|
||||
<v-expansion-panel>
|
||||
<v-expansion-panel-title class="font-weight-bold">
|
||||
ALPRs Are Abused
|
||||
</v-expansion-panel-title>
|
||||
<v-expansion-panel-text>
|
||||
<p>
|
||||
There are many documented cases where police have knowingly used ALPRs to commit crimes and put people in danger. These examples illustrate that it can be difficult to put meaningful restrictions in place that prevent ALPRs from being used for nefarious purposes. It's often only after harm is done that an officer is caught and punished, if at all.
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
<a href="https://inewsource.org/2022/01/06/police-share-license-plate-data/" target="_blank">Police in San Diego County breaking the law sharing drivers' data</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://www.kwch.com/2022/10/31/kechi-police-lieutenant-arrested-using-police-technology-stalk-wife/" target="_blank">A police officer used Flock Safety ALPRs to stalk his estranged wife in Kechi, KS</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://apnews.com/general-news-699236946e3140659fff8a2362e16f43" target="_blank">A police officer accepted a bribe to run a woman's license plate in Georgia</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://apnews.com/general-news-699236946e3140659fff8a2362e16f43" target="_blank">A police officer used ALPRs to stalk his ex-girlfriend in Ohio</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://information.auditor.ca.gov/pdfs/reports/2019-118.pdf" target="_blank">California agencies keeping data longer than necessary and sharing it with unauthorized agencies</a>
|
||||
</li>
|
||||
</ul>
|
||||
</v-expansion-panel-text>
|
||||
</v-expansion-panel>
|
||||
</v-expansion-panels>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import QuotedSource from '@/components/QuotedSource.vue';
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
blockquote {
|
||||
border-left: 4px solid #616161;
|
||||
padding-left: 16px;
|
||||
font-style: italic;
|
||||
margin-top: 16px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
ul {
|
||||
margin-left: 16px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
</style>
|
||||
@@ -1,15 +1,6 @@
|
||||
<template>
|
||||
<v-row style="align-items: center; margin-top: 1.25rem;">
|
||||
<v-col cols="12" sm="6">
|
||||
<!-- <v-select
|
||||
v-model="selectedBrand"
|
||||
return-object
|
||||
:items="alprBrands"
|
||||
item-title="name"
|
||||
item-value="wikidata"
|
||||
label="Select a company"
|
||||
outlined
|
||||
/> -->
|
||||
<h2 class="text-center mb-4">Choose Brand</h2>
|
||||
<v-row>
|
||||
<v-col v-for="brand in alprBrands" :key="brand.wikidata" cols="6">
|
||||
@@ -26,10 +17,6 @@
|
||||
</v-row>
|
||||
</v-col>
|
||||
|
||||
<!-- <v-col cols="12" sm="4">
|
||||
<v-img rounded cover aspect-ratio="1" width="220" :src="selectedBrand.exampleImage" />
|
||||
</v-col> -->
|
||||
|
||||
<v-col cols="12" sm="6">
|
||||
<h3 class="text-center">{{ selectedBrand.nickname }}</h3>
|
||||
<DFCode>
|
||||
@@ -39,8 +26,8 @@
|
||||
camera:type=fixed<br>
|
||||
surveillance=public<br>
|
||||
surveillance:zone=traffic<br>
|
||||
brand=<span class="highlight">{{ selectedBrand.name }}</span><br>
|
||||
brand:wikidata=<span class="highlight">{{ selectedBrand.wikidata }}</span><br>
|
||||
manufacturer=<span class="highlight">{{ selectedBrand.name }}</span><br>
|
||||
manufacturer:wikidata=<span class="highlight">{{ selectedBrand.wikidata }}</span><br>
|
||||
</DFCode>
|
||||
|
||||
<h5 class="text-center mt-4">and if operator is known</h5>
|
||||
|
||||
29
webapp/src/components/QuotedSource.vue
Normal file
29
webapp/src/components/QuotedSource.vue
Normal file
@@ -0,0 +1,29 @@
|
||||
<template>
|
||||
<blockquote class="serif text-grey-darken-2">
|
||||
<slot name="default"></slot>
|
||||
</blockquote>
|
||||
<p style="font-size: 0.9rem;">
|
||||
<a :href="sourceUrl" target="_blank">-{{ attributionText }}</a>
|
||||
</p>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
defineProps({
|
||||
sourceUrl: String,
|
||||
attributionText: {
|
||||
type: String,
|
||||
default: 'Read the full study'
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
blockquote {
|
||||
font-size: 1.05rem;
|
||||
border-left: 4px solid #616161;
|
||||
padding-left: 16px;
|
||||
font-style: italic;
|
||||
margin-top: 16px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
</style>
|
||||
@@ -4,6 +4,7 @@ import { createApp } from 'vue'
|
||||
import { createPinia } from 'pinia'
|
||||
import App from './App.vue'
|
||||
import router from './router'
|
||||
import { createHead } from '@unhead/vue'
|
||||
|
||||
import 'vuetify/styles'
|
||||
import { createVuetify } from 'vuetify'
|
||||
@@ -21,7 +22,7 @@ const vuetify = createVuetify({
|
||||
|
||||
const pinia = createPinia()
|
||||
const app = createApp(App)
|
||||
|
||||
app.use(createHead())
|
||||
app.use(router)
|
||||
app.use(vuetify)
|
||||
app.use(pinia)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { createRouter, createWebHistory } from 'vue-router'
|
||||
import Landing from '../views/Landing.vue'
|
||||
import Map from '../views/Map.vue'
|
||||
import { useHead } from '@unhead/vue'
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHistory(import.meta.env.BASE_URL),
|
||||
@@ -17,12 +18,18 @@ const router = createRouter({
|
||||
{
|
||||
path: '/',
|
||||
name: 'home',
|
||||
component: Landing
|
||||
component: Landing,
|
||||
meta: {
|
||||
title: 'Find Nearby ALPRs | DeFlock'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/map',
|
||||
name: 'map',
|
||||
component: Map
|
||||
component: Map,
|
||||
meta: {
|
||||
title: 'ALPR Map | DeFlock'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/about',
|
||||
@@ -30,53 +37,102 @@ const router = createRouter({
|
||||
// route level code-splitting
|
||||
// this generates a separate chunk (About.[hash].js) for this route
|
||||
// which is lazy-loaded when the route is visited.
|
||||
component: () => import('../views/AboutView.vue')
|
||||
component: () => import('../views/AboutView.vue'),
|
||||
meta: {
|
||||
title: 'About | DeFlock'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/what-is-an-alpr',
|
||||
name: 'what-is-an-alpr',
|
||||
component: () => import('../views/WhatIsAnALPRView.vue')
|
||||
component: () => import('../views/WhatIsAnALPRView.vue'),
|
||||
meta: {
|
||||
title: 'What is an ALPR | DeFlock'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/report',
|
||||
name: 'report',
|
||||
component: () => import('../views/ReportView.vue')
|
||||
component: () => import('../views/ReportView.vue'),
|
||||
meta: {
|
||||
title: 'Report an ALPR | DeFlock'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/operators',
|
||||
name: 'operators',
|
||||
component: () => import('../views/OperatorsView.vue')
|
||||
component: () => import('../views/OperatorsView.vue'),
|
||||
meta: {
|
||||
title: 'Operators | DeFlock'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/contact',
|
||||
name: 'contact',
|
||||
component: () => import('../views/ContactView.vue')
|
||||
component: () => import('../views/ContactView.vue'),
|
||||
meta: {
|
||||
title: 'Contact | DeFlock'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/roadmap',
|
||||
name: 'roadmap',
|
||||
component: () => import('../views/RoadmapView.vue')
|
||||
component: () => import('../views/RoadmapView.vue'),
|
||||
meta: {
|
||||
title: 'Roadmap | DeFlock'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/legal',
|
||||
name: 'legal',
|
||||
component: () => import('../views/LegalView.vue')
|
||||
component: () => import('../views/LegalView.vue'),
|
||||
meta: {
|
||||
title: 'Legal | DeFlock'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/qr',
|
||||
name: 'qr-landing',
|
||||
component: () => import('../views/QRLandingView.vue')
|
||||
component: () => import('../views/QRLandingView.vue'),
|
||||
meta: {
|
||||
title: 'You Found an ALPR | DeFlock'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/donate',
|
||||
name: 'donate',
|
||||
component: () => import('../views/Donate.vue'),
|
||||
meta: {
|
||||
title: 'Donate | DeFlock'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/dangers',
|
||||
name: 'dangers',
|
||||
component: () => import('../views/Dangers.vue'),
|
||||
meta: {
|
||||
title: 'ALPR Dangers | DeFlock'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: '/:pathMatch(.*)*',
|
||||
name: 'not-found',
|
||||
component: () => import('../views/404.vue')
|
||||
component: () => import('../views/404.vue'),
|
||||
meta: {
|
||||
title: 'Not Found | DeFlock'
|
||||
}
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
// backward compatibility with old url scheme
|
||||
router.beforeEach((to, from, next) => {
|
||||
if (to.meta.title) {
|
||||
useHead({
|
||||
title: to.meta.title
|
||||
})
|
||||
}
|
||||
|
||||
if (to.path === '/' && to.hash) {
|
||||
next({ path: '/map', hash: to.hash })
|
||||
} else {
|
||||
|
||||
@@ -65,6 +65,11 @@ export const getALPRs = async (boundingBox: BoundingBox) => {
|
||||
return response.data;
|
||||
}
|
||||
|
||||
export const getSponsors = async () => {
|
||||
const response = await apiService.get("/sponsors/github");
|
||||
return response.data;
|
||||
}
|
||||
|
||||
export const getALPRCounts = async () => {
|
||||
const s3Url = "https://deflock-clusters.s3.us-east-1.amazonaws.com/alpr-counts.json";
|
||||
const response = await apiService.get(s3Url);
|
||||
|
||||
64
webapp/src/views/Dangers.vue
Normal file
64
webapp/src/views/Dangers.vue
Normal file
@@ -0,0 +1,64 @@
|
||||
<template>
|
||||
<v-container class="info-section">
|
||||
<!-- Hero Section -->
|
||||
<v-row justify="center" class="hero-section-harms text-center mb-4">
|
||||
<v-col cols="12" md="8">
|
||||
<h1 class="mb-4">The Dangers of ALPRs</h1>
|
||||
<p class="mb-4 font-weight-bold bigger">
|
||||
ALPRs promise safety but deliver risks to privacy and civil rights.
|
||||
</p>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-row class="mb-4">
|
||||
<v-col cols="12" class="bigger">
|
||||
<p class="mb-4">
|
||||
Thousands of police departments, homeowners associations, and businesses across the country deploy automated license plate readers (ALPRs) with the expectation that these surveillance tools can reduce crime.
|
||||
</p>
|
||||
<p>
|
||||
In reality, ALPRs pose a real threat to the civil rights, liberties, and safety of the communities of people under surveillance.
|
||||
</p>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<dangers />
|
||||
</v-container>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import Dangers from '@/components/Dangers.vue';
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.hero-section-harms {
|
||||
background: url('/chicago-pd.jpg') no-repeat center center;
|
||||
background-size: cover;
|
||||
color: white;
|
||||
padding: 100px 0 !important;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.hero-section-harms::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.hero-section-harms > * {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.info-section {
|
||||
background: var(--df-page-background-color);
|
||||
}
|
||||
</style>
|
||||
89
webapp/src/views/Donate.vue
Normal file
89
webapp/src/views/Donate.vue
Normal file
@@ -0,0 +1,89 @@
|
||||
<template>
|
||||
<v-container class="sponsor-page">
|
||||
<!-- Hero Section -->
|
||||
<v-row justify="center" class="hero-section-sponsor text-center mb-4">
|
||||
<v-col cols="12" md="8">
|
||||
<h1 class="mb-4">Join Us in Protecting Privacy</h1>
|
||||
<p class="mb-4">
|
||||
DeFlock empowers individuals to understand and combat the rise of Automatic License Plate Readers (ALPRs). Your support helps us spread awareness, maintain infrastructure, and advocate for privacy rights.
|
||||
</p>
|
||||
<v-btn href="https://github.com/sponsors/frillweeman" target="_blank" color="rgb(18, 151, 195)" class="mt-4">Donate Now</v-btn>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<!-- GitHub Sponsors Section -->
|
||||
<v-row justify="center" class="sponsors-section text-center">
|
||||
<v-col cols="12" md="10">
|
||||
<h2 class="mb-4">Our Amazing Sponsors</h2>
|
||||
<v-row>
|
||||
<v-col v-for="sponsor in sponsors" :key="sponsor.login" cols="6" md="4" lg="3">
|
||||
<v-card variant="flat" class="text-center py-2">
|
||||
<v-avatar size="64px" class="mb-3">
|
||||
<v-img :src="sponsor.avatarUrl" :alt="sponsor.name" />
|
||||
</v-avatar>
|
||||
<p>{{ sponsor.name ?? sponsor.login }}</p>
|
||||
</v-card>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-container>
|
||||
|
||||
<!-- Footer Section -->
|
||||
<v-footer class="text-center mt-8">
|
||||
<v-row>
|
||||
<v-col>
|
||||
<p>© {{ new Date().getFullYear() }} DeFlock. All rights reserved.</p>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-footer>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted, type Ref } from "vue";
|
||||
import { getSponsors } from "@/services/apiService";
|
||||
|
||||
interface Sponsor {
|
||||
login: string;
|
||||
name: string;
|
||||
avatarUrl: string;
|
||||
}
|
||||
|
||||
const sponsors: Ref<Sponsor[]> = ref([]);
|
||||
|
||||
onMounted(() => {
|
||||
getSponsors()
|
||||
.then((data) => {
|
||||
sponsors.value = data.map((s: any) => s.sponsor);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error(error);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.hero-section-sponsor {
|
||||
background: url('/torches.webp') no-repeat center center;
|
||||
background-size: cover;
|
||||
color: white;
|
||||
padding: 100px 0 !important;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.hero-section-sponsor::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.hero-section-sponsor > * {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
}
|
||||
</style>
|
||||
@@ -1,68 +1,78 @@
|
||||
<template>
|
||||
<!-- Hero Section -->
|
||||
<v-container fluid class="hero-section">
|
||||
<v-row justify="center">
|
||||
<v-col cols="12" md="8" class="text-center">
|
||||
<h1 class="display-1 px-8">You're Being Tracked by ALPRs!</h1>
|
||||
<ALPRCounter class="mt-4" />
|
||||
<p class="subtitle-1 px-8 mt-6 mb-12">
|
||||
Automated License Plate Readers (ALPRs) are monitoring your every move. Learn more about how they work and how you can protect your privacy.
|
||||
</p>
|
||||
<v-btn color="rgb(18, 151, 195)" large @click="goToMap({ withCurrentLocation: true })">
|
||||
Find Nearby ALPRs
|
||||
<v-icon end>mdi-map</v-icon>
|
||||
</v-btn>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-container>
|
||||
|
||||
<!-- Information Section -->
|
||||
<v-container class="info-section py-10">
|
||||
<v-row class="align-center">
|
||||
<v-col cols="12" md="4" class="text-center">
|
||||
<v-card>
|
||||
<v-card-title class="headline">
|
||||
<v-icon x-large class="mr-2">mdi-shield-alert</v-icon>
|
||||
Privacy Violations
|
||||
</v-card-title>
|
||||
<v-card-text>
|
||||
ALPRs track your movements and store your data for long periods of time, creating a detailed record of your location history. They surveil mostly innocent people while claiming to target criminals.
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</v-col>
|
||||
<v-col cols="12" md="4" class="text-center">
|
||||
<v-card>
|
||||
<v-card-title class="headline">
|
||||
<v-icon x-large class="mr-2">mdi-alert-circle</v-icon>
|
||||
Risk of Misuse
|
||||
</v-card-title>
|
||||
<v-card-text>
|
||||
Data from ALPRs has led to <a target="_blank" href="https://www.newsobserver.com/news/state/north-carolina/article287381160.html">wrongful arrests</a>, profiling, and <a target="_blank" href="https://www.kwch.com/2022/10/31/kechi-police-lieutenant-arrested-using-police-technology-stalk-wife/">stalking ex-partners</a> by police officers.
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</v-col>
|
||||
<v-col cols="12" md="4" class="text-center">
|
||||
<v-card>
|
||||
<v-card-title class="headline">
|
||||
<v-icon x-large class="mr-2">mdi-handcuffs</v-icon>
|
||||
Limited Benefits
|
||||
</v-card-title>
|
||||
<v-card-text>
|
||||
There's no substantial evidence that ALPRs effectively prevent crime, despite <a target="_blank" href="https://www.404media.co/researcher-who-oversaw-flock-surveillance-study-now-has-concerns-about-it/">Flock's unethical attempts</a> to prove otherwise.
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-container>
|
||||
|
||||
<!-- Map Section -->
|
||||
<v-container class="map-section py-10 text-center">
|
||||
<h2 class="display-2 mb-4">Explore ALPR Locations Near You</h2>
|
||||
<v-btn color="white" large @click="goToMap">
|
||||
View the Map
|
||||
<v-icon end>mdi-map</v-icon>
|
||||
</v-btn>
|
||||
</v-container>
|
||||
<v-row justify="center">
|
||||
<v-col cols="12" md="8" class="text-center">
|
||||
<h1 class="display-1 px-8">You're Being Tracked by ALPRs!</h1>
|
||||
<ALPRCounter class="mt-4" />
|
||||
<p class="subtitle-1 px-8 mt-6 mb-12 bigger">
|
||||
Automated License Plate Readers (ALPRs) are monitoring your every move. Learn more about how they work and how you can protect your privacy.
|
||||
</p>
|
||||
<v-btn color="rgb(18, 151, 195)" large @click="goToMap({ withCurrentLocation: true })">
|
||||
Find Nearby ALPRs
|
||||
<v-icon end>mdi-map</v-icon>
|
||||
</v-btn>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-container>
|
||||
|
||||
<!-- Dangers Section -->
|
||||
<v-container class="py-10 text-center info-section">
|
||||
<h2 class="display-2 mb-4">The Dangers of ALPRs</h2>
|
||||
<p class="subtitle-1 px-8">
|
||||
ALPRs are a threat to your privacy and civil liberties. They can be used to track your movements, profile you, and even stalk you. Learn more about the dangers of ALPRs and how you can protect yourself.
|
||||
</p>
|
||||
|
||||
<v-row class="align-center mt-4">
|
||||
<v-col cols="12" md="4" class="text-center">
|
||||
<v-card>
|
||||
<v-card-title class="headline">
|
||||
<v-icon x-large class="mr-2">mdi-shield-alert</v-icon>
|
||||
Privacy Violations
|
||||
</v-card-title>
|
||||
<v-card-text>
|
||||
ALPRs track your movements and store your data for long periods of time, creating a detailed record of your location history. They surveil mostly innocent people while claiming to target criminals.
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</v-col>
|
||||
<v-col cols="12" md="4" class="text-center">
|
||||
<v-card>
|
||||
<v-card-title class="headline">
|
||||
<v-icon x-large class="mr-2">mdi-alert-circle</v-icon>
|
||||
Risk of Misuse
|
||||
</v-card-title>
|
||||
<v-card-text>
|
||||
Data from ALPRs has led to <a target="_blank" href="https://www.newsobserver.com/news/state/north-carolina/article287381160.html">wrongful arrests</a>, profiling, and <a target="_blank" href="https://www.kwch.com/2022/10/31/kechi-police-lieutenant-arrested-using-police-technology-stalk-wife/">stalking ex-partners</a> by police officers.
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</v-col>
|
||||
<v-col cols="12" md="4" class="text-center">
|
||||
<v-card>
|
||||
<v-card-title class="headline">
|
||||
<v-icon x-large class="mr-2">mdi-handcuffs</v-icon>
|
||||
Limited Benefits
|
||||
</v-card-title>
|
||||
<v-card-text>
|
||||
There's no substantial evidence that ALPRs effectively prevent crime, despite <a target="_blank" href="https://www.404media.co/researcher-who-oversaw-flock-surveillance-study-now-has-concerns-about-it/">Flock's unethical attempts</a> to prove otherwise.
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-btn class="mt-8" color="rgb(18, 151, 195)" large to="/dangers">
|
||||
See All Dangers
|
||||
<v-icon end>mdi-shield-alert</v-icon>
|
||||
</v-btn>
|
||||
</v-container>
|
||||
|
||||
<!-- Map Section -->
|
||||
<v-container class="map-section py-10 text-center">
|
||||
<h2 class="display-2 mb-4">Explore ALPR Locations Near You</h2>
|
||||
<v-btn color="white" large @click="goToMap">
|
||||
View the Map
|
||||
<v-icon end>mdi-map</v-icon>
|
||||
</v-btn>
|
||||
</v-container>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
@@ -116,6 +126,10 @@
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.bigger {
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<v-container max-width="1000">
|
||||
<v-container class="info-section" max-width="1000">
|
||||
<h1>Known Operators</h1>
|
||||
<p>
|
||||
We regularly scrape Flock's site for cities/counties that have Flock ALPRs. Here is our current list of jurisdictions we've scraped that have ALPRs. Not every Flock operator has opted in to sharing their usage with Flock, so this list is <i>not exhaustive</i>.
|
||||
@@ -125,4 +125,8 @@ code {
|
||||
border-radius: 0.25rem;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.info-section {
|
||||
background: var(--df-page-background-color);
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<v-col cols="12" md="8" class="text-center">
|
||||
<h1 class="display-1 px-8">You're Being Tracked by an ALPR!</h1>
|
||||
<ALPRCounter class="mt-4" />
|
||||
<p class="subtitle-1 px-8 mt-6 mb-12">
|
||||
<p class="subtitle-1 px-8 mt-6 mb-12 bigger">
|
||||
Automated License Plate Readers (ALPRs) are monitoring your every move. Learn more about how they work and how you can protect your privacy.
|
||||
</p>
|
||||
<v-btn color="rgb(18, 151, 195)" large @click="goToMap({ withCurrentLocation: true })">
|
||||
@@ -16,43 +16,53 @@
|
||||
</v-row>
|
||||
</v-container>
|
||||
|
||||
<!-- Information Section -->
|
||||
<v-container class="info-section py-10">
|
||||
<v-row>
|
||||
<v-col cols="12" md="4" class="text-center">
|
||||
<v-card outlined>
|
||||
<v-card-title class="headline">
|
||||
<v-icon x-large class="mr-2">mdi-shield-alert</v-icon>
|
||||
Privacy Violations
|
||||
</v-card-title>
|
||||
<v-card-text>
|
||||
ALPRs track your movements and store your data for long periods of time, creating a detailed record of your location history. They surveil mostly innocent people while claiming to target criminals.
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</v-col>
|
||||
<v-col cols="12" md="4" class="text-center">
|
||||
<v-card outlined>
|
||||
<v-card-title class="headline">
|
||||
<v-icon x-large class="mr-2">mdi-alert-circle</v-icon>
|
||||
Risk of Misuse
|
||||
</v-card-title>
|
||||
<v-card-text>
|
||||
Data from ALPRs has led to <a target="_blank" href="https://www.newsobserver.com/news/state/north-carolina/article287381160.html">wrongful arrests</a>, profiling, and <a target="_blank" href="https://www.kwch.com/2022/10/31/kechi-police-lieutenant-arrested-using-police-technology-stalk-wife/">stalking ex-partners</a> by police officers.
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</v-col>
|
||||
<v-col cols="12" md="4" class="text-center">
|
||||
<v-card outlined>
|
||||
<v-card-title class="headline">
|
||||
<v-icon x-large class="mr-2">mdi-handcuffs</v-icon>
|
||||
Limited Benefits
|
||||
</v-card-title>
|
||||
<v-card-text>
|
||||
There's no substantial evidence that ALPRs effectively prevent crime, despite <a target="_blank" href="https://www.404media.co/researcher-who-oversaw-flock-surveillance-study-now-has-concerns-about-it/">Flock's unethical attempts</a> to prove otherwise.
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</v-col>
|
||||
<!-- Dangers Section -->
|
||||
<v-container class="py-10 text-center info-section">
|
||||
<h2 class="display-2 mb-4">The Dangers of ALPRs</h2>
|
||||
<p class="subtitle-1 px-8">
|
||||
ALPRs are a threat to your privacy and civil liberties. They can be used to track your movements, profile you, and even stalk you. Learn more about the dangers of ALPRs and how you can protect yourself.
|
||||
</p>
|
||||
|
||||
<v-row class="align-center mt-4">
|
||||
<v-col cols="12" md="4" class="text-center">
|
||||
<v-card>
|
||||
<v-card-title class="headline">
|
||||
<v-icon x-large class="mr-2">mdi-shield-alert</v-icon>
|
||||
Privacy Violations
|
||||
</v-card-title>
|
||||
<v-card-text>
|
||||
ALPRs track your movements and store your data for long periods of time, creating a detailed record of your location history. They surveil mostly innocent people while claiming to target criminals.
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</v-col>
|
||||
<v-col cols="12" md="4" class="text-center">
|
||||
<v-card>
|
||||
<v-card-title class="headline">
|
||||
<v-icon x-large class="mr-2">mdi-alert-circle</v-icon>
|
||||
Risk of Misuse
|
||||
</v-card-title>
|
||||
<v-card-text>
|
||||
Data from ALPRs has led to <a target="_blank" href="https://www.newsobserver.com/news/state/north-carolina/article287381160.html">wrongful arrests</a>, profiling, and <a target="_blank" href="https://www.kwch.com/2022/10/31/kechi-police-lieutenant-arrested-using-police-technology-stalk-wife/">stalking ex-partners</a> by police officers.
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</v-col>
|
||||
<v-col cols="12" md="4" class="text-center">
|
||||
<v-card>
|
||||
<v-card-title class="headline">
|
||||
<v-icon x-large class="mr-2">mdi-handcuffs</v-icon>
|
||||
Limited Benefits
|
||||
</v-card-title>
|
||||
<v-card-text>
|
||||
There's no substantial evidence that ALPRs effectively prevent crime, despite <a target="_blank" href="https://www.404media.co/researcher-who-oversaw-flock-surveillance-study-now-has-concerns-about-it/">Flock's unethical attempts</a> to prove otherwise.
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</v-col>
|
||||
</v-row>
|
||||
|
||||
<v-btn class="mt-8" color="rgb(18, 151, 195)" large to="/dangers">
|
||||
See All Dangers
|
||||
<v-icon end>mdi-shield-alert</v-icon>
|
||||
</v-btn>
|
||||
</v-container>
|
||||
|
||||
<!-- Map Section -->
|
||||
@@ -116,6 +126,10 @@
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.bigger {
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<v-container max-width="1000">
|
||||
<v-container class="info-section" max-width="1000">
|
||||
<v-alert
|
||||
variant="tonal"
|
||||
type="info"
|
||||
@@ -118,4 +118,8 @@ code {
|
||||
border-radius: 0.25rem;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.info-section {
|
||||
background: var(--df-page-background-color);
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<v-container max-width="1000">
|
||||
<v-container class="info-section" max-width="1000">
|
||||
<p>
|
||||
<v-img max-height="450" width="100%" cover src="/flock-camera.jpeg" />
|
||||
</p>
|
||||
@@ -12,31 +12,11 @@
|
||||
<p>For a detailed explanation of how ALPRs are a threat to privacy, see this <a href="https://www.aclu.org/issues/privacy-technology/you-are-being-tracked" target="_blank">ACLU article</a> as well as this <a href="https://sls.eff.org/technologies/automated-license-plate-readers-alprs" target="_blank">EFF article</a> on ALPRs.</p>
|
||||
|
||||
<h2>Why Should You Be Concerned</h2>
|
||||
<p>
|
||||
ALPRs can invade your privacy and violate civil liberties in several key ways:
|
||||
<p class="mb-4">
|
||||
ALPRs invade your privacy and violate your civil liberties. Here's how:
|
||||
</p>
|
||||
|
||||
<div class="ml-4">
|
||||
<h3>Mass Surveillance</h3>
|
||||
<p>Your daily movements are tracked and logged, often indefinitely. This creates a detailed record of your daily activities. This information can be used to infer personal details about your life.</p>
|
||||
|
||||
<h3>Data Sharing</h3>
|
||||
<p>ALPR data is often shared with other agencies, including federal law enforcement. This can lead to the creation of a massive database of innocent people's movements.</p>
|
||||
|
||||
<h3>Chilling Effect on Freedoms</h3>
|
||||
<p>The knowledge that you are being watched can have a chilling effect on your freedom of speech and association. People may avoid attending protests or political events for fear of being tracked.</p>
|
||||
|
||||
<h3>Potential for Abuse</h3>
|
||||
<p>Law enforcement officers or other individuals with access could misuse this data, for example, tracking ex-partners, political rivals, or targeting specific communities without oversight.</p>
|
||||
|
||||
<h4 class="mt-4">Examples of Abuse</h4>
|
||||
<ul>
|
||||
<li><a target="_blank" href="https://www.kwch.com/2022/10/31/kechi-police-lieutenant-arrested-using-police-technology-stalk-wife/">Kechi police lieutenant arrested for using police technology to stalk wife</a></li>
|
||||
<li><a target="_blank" href="https://www.kwch.com/2022/11/04/kechi-police-lieutenants-arrest-puts-flock-technology-under-scrutiny/">Kechi police lieutenant's arrest puts Flock technology under scrutiny</a></li>
|
||||
<li><a target="_blank" href="https://www.koat.com/article/espanola-police-license-plate-stolen-cover-traffic-stop/45361740">License plate cover leads to traffic stop mishap</a></li>
|
||||
<li><a href="https://apnews.com/article/handcuffed-black-girls-colorado-settlement-a7a695839b8841e56b7db0d103cc5ed1">Family of Black girls handcuffed by Colorado police, held at gunpoint reach $1.9 million settlement</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<dangers />
|
||||
|
||||
<h2 id="not-alpr" :class="{ highlighted: route.hash === '#not-alpr' }">What They Look Like</h2>
|
||||
<v-carousel class="my-4" hide-delimiters>
|
||||
@@ -87,6 +67,7 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useRoute } from 'vue-router';
|
||||
import Dangers from '@/components/Dangers.vue';
|
||||
const route = useRoute();
|
||||
|
||||
const flockImageCount = 6;
|
||||
@@ -134,4 +115,8 @@ li {
|
||||
padding: 0.5rem;
|
||||
border-radius: 0.25rem;
|
||||
}
|
||||
|
||||
.info-section {
|
||||
background: var(--df-page-background-color);
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user