mirror of
https://github.com/ragestudio/comty.git
synced 2025-06-09 10:34:17 +00:00
added open source libraries page
This commit is contained in:
parent
d5c6a40208
commit
f24f489abd
@ -9,6 +9,7 @@ export default {
|
||||
author: "RageStudio©",
|
||||
fundingLink: "https://www.paypal.com/donate/?hosted_button_id=S4TWMAN79KC76",
|
||||
githubRepoLink: "https://github.com/ragestudio/comty",
|
||||
ossLicensesUrl: "/oss-licenses.json",
|
||||
locations: {
|
||||
terms: "/terms",
|
||||
privacy: "/privacy",
|
||||
|
491
packages/app/public/oss-licenses.json
Normal file
491
packages/app/public/oss-licenses.json
Normal file
@ -0,0 +1,491 @@
|
||||
[
|
||||
{
|
||||
"name": "@ant-design/icons",
|
||||
"version": "5.4.0",
|
||||
"license": "MIT"
|
||||
},
|
||||
{
|
||||
"name": "@capacitor/android",
|
||||
"version": "5.7.8",
|
||||
"license": "MIT",
|
||||
"author": "Ionic Team <hi@ionic.io> (https://ionic.io)"
|
||||
},
|
||||
{
|
||||
"name": "@capacitor/app",
|
||||
"version": "5.0.8",
|
||||
"license": "MIT",
|
||||
"author": "Ionic <hi@ionicframework.com>"
|
||||
},
|
||||
{
|
||||
"name": "@capacitor/assets",
|
||||
"version": "2.0.4",
|
||||
"license": "MIT",
|
||||
"author": "Ionic Team <hi@ionicframework.com>"
|
||||
},
|
||||
{
|
||||
"name": "@capacitor/cli",
|
||||
"version": "5.7.8",
|
||||
"license": "MIT",
|
||||
"author": "Ionic Team <hi@ionic.io> (https://ionic.io)"
|
||||
},
|
||||
{
|
||||
"name": "@capacitor/core",
|
||||
"version": "5.7.8",
|
||||
"license": "MIT",
|
||||
"author": "Ionic Team <hi@ionic.io> (https://ionic.io)"
|
||||
},
|
||||
{
|
||||
"name": "@capacitor/haptics",
|
||||
"version": "1.1.4",
|
||||
"license": "MIT",
|
||||
"author": "Ionic <hi@ionicframework.com>"
|
||||
},
|
||||
{
|
||||
"name": "@capacitor/ios",
|
||||
"version": "5.7.8",
|
||||
"license": "MIT",
|
||||
"author": "Ionic Team <hi@ionic.io> (https://ionic.io)"
|
||||
},
|
||||
{
|
||||
"name": "@capacitor/push-notifications",
|
||||
"version": "5.1.2",
|
||||
"license": "MIT",
|
||||
"author": "Ionic <hi@ionicframework.com>"
|
||||
},
|
||||
{
|
||||
"name": "@capacitor/splash-screen",
|
||||
"version": "5.0.8",
|
||||
"license": "MIT",
|
||||
"author": "Ionic <hi@ionicframework.com>"
|
||||
},
|
||||
{
|
||||
"name": "@capacitor/status-bar",
|
||||
"version": "5.0.8",
|
||||
"license": "MIT",
|
||||
"author": "Ionic <hi@ionicframework.com>"
|
||||
},
|
||||
{
|
||||
"name": "@capacitor/storage",
|
||||
"version": "1.2.5",
|
||||
"license": "MIT",
|
||||
"author": "Ionic <hi@ionicframework.com>"
|
||||
},
|
||||
{
|
||||
"name": "@capgo/capacitor-updater",
|
||||
"version": "5.9.5",
|
||||
"license": "MPL-2.0",
|
||||
"author": "Martin Donadieu"
|
||||
},
|
||||
{
|
||||
"name": "@dnd-kit/core",
|
||||
"version": "6.1.0",
|
||||
"license": "MIT",
|
||||
"author": "Claudéric Demers"
|
||||
},
|
||||
{
|
||||
"name": "@dnd-kit/sortable",
|
||||
"version": "7.0.2",
|
||||
"license": "MIT",
|
||||
"author": "Claudéric Demers"
|
||||
},
|
||||
{
|
||||
"name": "@emotion/react",
|
||||
"version": "11.13.3",
|
||||
"license": "MIT",
|
||||
"author": "Emotion Contributors"
|
||||
},
|
||||
{
|
||||
"name": "@emotion/styled",
|
||||
"version": "11.13.0",
|
||||
"license": "MIT"
|
||||
},
|
||||
{
|
||||
"name": "@ffmpeg/ffmpeg",
|
||||
"version": "0.12.10",
|
||||
"license": "MIT",
|
||||
"author": "Jerome Wu <jeromewus@gmail.com>"
|
||||
},
|
||||
{
|
||||
"name": "@ffmpeg/util",
|
||||
"version": "0.12.1",
|
||||
"license": "MIT",
|
||||
"author": "Jerome Wu <jeromewus@gmail.com>"
|
||||
},
|
||||
{
|
||||
"name": "@loadable/component",
|
||||
"version": "5.15.2",
|
||||
"license": "MIT",
|
||||
"author": "Greg Bergé <berge.greg@gmail.com>"
|
||||
},
|
||||
{
|
||||
"name": "@mui/material",
|
||||
"version": "5.16.7",
|
||||
"license": "MIT",
|
||||
"author": "MUI Team"
|
||||
},
|
||||
{
|
||||
"name": "@ragestudio/cordova-nfc",
|
||||
"version": "1.2.0",
|
||||
"license": "MIT",
|
||||
"author": "Don Coleman <don.coleman@gmail.com>"
|
||||
},
|
||||
{
|
||||
"name": "@sentry/browser",
|
||||
"version": "7.119.0",
|
||||
"license": "MIT",
|
||||
"author": "Sentry"
|
||||
},
|
||||
{
|
||||
"name": "@tauri-apps/api",
|
||||
"version": "1.6.0",
|
||||
"license": "Apache-2.0 OR MIT"
|
||||
},
|
||||
{
|
||||
"name": "@tsmx/human-readable",
|
||||
"version": "1.0.9",
|
||||
"license": "MIT",
|
||||
"author": "tsmx <dev@tsmx.net>"
|
||||
},
|
||||
{
|
||||
"name": "antd",
|
||||
"version": "5.20.6",
|
||||
"license": "MIT"
|
||||
},
|
||||
{
|
||||
"name": "antd-mobile",
|
||||
"version": "5.37.1",
|
||||
"license": "MIT"
|
||||
},
|
||||
{
|
||||
"name": "axios",
|
||||
"version": "1.7.7",
|
||||
"license": "MIT",
|
||||
"author": "Matt Zabriskie"
|
||||
},
|
||||
{
|
||||
"name": "bear-react-carousel",
|
||||
"version": "4.0.30",
|
||||
"license": "MIT"
|
||||
},
|
||||
{
|
||||
"name": "capacitor-music-controls-plugin-v3",
|
||||
"version": "1.1.3",
|
||||
"license": "MIT",
|
||||
"author": "Ingage"
|
||||
},
|
||||
{
|
||||
"name": "classnames",
|
||||
"version": "2.3.1",
|
||||
"license": "MIT",
|
||||
"author": "Jed Watson"
|
||||
},
|
||||
{
|
||||
"name": "dompurify",
|
||||
"version": "3.1.6",
|
||||
"license": "(MPL-2.0 OR Apache-2.0)",
|
||||
"author": "Dr.-Ing. Mario Heiderich, Cure53 <mario@cure53.de> (https://cure53.de/)"
|
||||
},
|
||||
{
|
||||
"name": "evite",
|
||||
"version": "0.17.0",
|
||||
"license": "MIT",
|
||||
"author": "RageStudio"
|
||||
},
|
||||
{
|
||||
"name": "fast-average-color",
|
||||
"version": "9.4.0",
|
||||
"license": "MIT",
|
||||
"author": {
|
||||
"name": "Denis Seleznev",
|
||||
"email": "hcodes@yandex.ru",
|
||||
"url": "https://github.com/fast-average-color/fast-average-color"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "feather-reactjs",
|
||||
"version": "2.0.13",
|
||||
"license": "MIT"
|
||||
},
|
||||
{
|
||||
"name": "framer-motion",
|
||||
"version": "10.18.0",
|
||||
"license": "MIT",
|
||||
"author": "Framer"
|
||||
},
|
||||
{
|
||||
"name": "fuse.js",
|
||||
"version": "6.5.3",
|
||||
"license": "Apache-2.0",
|
||||
"author": {
|
||||
"name": "Kiro Risk",
|
||||
"email": "kirollos@gmail.com",
|
||||
"url": "http://kiro.me"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "hls.js",
|
||||
"version": "1.5.15",
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
{
|
||||
"name": "howler",
|
||||
"version": "2.2.3",
|
||||
"license": "MIT",
|
||||
"author": "James Simpson <james@goldfirestudios.com> (http://goldfirestudios.com)"
|
||||
},
|
||||
{
|
||||
"name": "i18next",
|
||||
"version": "21.6.6",
|
||||
"license": "MIT",
|
||||
"author": "Jan Mühlemann <jan.muehlemann@gmail.com> (https://github.com/jamuhl)"
|
||||
},
|
||||
{
|
||||
"name": "js-cookie",
|
||||
"version": "3.0.1",
|
||||
"license": "MIT",
|
||||
"author": "Klaus Hartl"
|
||||
},
|
||||
{
|
||||
"name": "jsmediatags",
|
||||
"version": "3.9.7",
|
||||
"license": "BSD-3-Clause",
|
||||
"author": {
|
||||
"name": "António Afonso",
|
||||
"email": "antonio.afonso@gmail.com"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "less",
|
||||
"version": "4.1.2",
|
||||
"license": "Apache-2.0",
|
||||
"author": {
|
||||
"name": "Alexis Sellier",
|
||||
"email": "self@cloudhead.net"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "lottie-react",
|
||||
"version": "2.4.0",
|
||||
"license": "MIT",
|
||||
"author": "David Gamote"
|
||||
},
|
||||
{
|
||||
"name": "luxon",
|
||||
"version": "3.5.0",
|
||||
"license": "MIT",
|
||||
"author": "Isaac Cambron"
|
||||
},
|
||||
{
|
||||
"name": "million",
|
||||
"version": "2.6.4",
|
||||
"license": "MIT",
|
||||
"author": {
|
||||
"name": "Aiden Bai",
|
||||
"email": "hello@aidenybai.com",
|
||||
"url": "https://aidenybai.com"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "mime",
|
||||
"version": "3.0.0",
|
||||
"license": "MIT",
|
||||
"author": {
|
||||
"name": "Robert Kieffer",
|
||||
"url": "http://github.com/broofa",
|
||||
"email": "robert@broofa.com"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "moment",
|
||||
"version": "2.29.4",
|
||||
"license": "MIT",
|
||||
"author": "Iskren Ivov Chernev <iskren.chernev@gmail.com> (https://github.com/ichernev)"
|
||||
},
|
||||
{
|
||||
"name": "mpegts.js",
|
||||
"version": "1.7.3",
|
||||
"license": "Apache-2.0",
|
||||
"author": "zheng qian <xqq@xqq.im>"
|
||||
},
|
||||
{
|
||||
"name": "nprogress",
|
||||
"version": "0.2.0",
|
||||
"license": "MIT",
|
||||
"author": "Rico Sta. Cruz <hi@ricostacruz.com>"
|
||||
},
|
||||
{
|
||||
"name": "plyr",
|
||||
"version": "3.7.8",
|
||||
"license": "MIT",
|
||||
"author": "Sam Potts <sam@potts.es>"
|
||||
},
|
||||
{
|
||||
"name": "plyr-react",
|
||||
"version": "3.2.1",
|
||||
"license": "MIT",
|
||||
"author": "Chintan Prajapati"
|
||||
},
|
||||
{
|
||||
"name": "prop-types",
|
||||
"version": "15.8.1",
|
||||
"license": "MIT"
|
||||
},
|
||||
{
|
||||
"name": "react",
|
||||
"version": "18.3.1",
|
||||
"license": "MIT"
|
||||
},
|
||||
{
|
||||
"name": "react-beautiful-dnd",
|
||||
"version": "13.1.1",
|
||||
"license": "Apache-2.0",
|
||||
"author": "Alex Reardon <areardon@atlassian.com>"
|
||||
},
|
||||
{
|
||||
"name": "react-color",
|
||||
"version": "2.19.3",
|
||||
"license": "MIT",
|
||||
"author": "case <case@casesandberg.com>"
|
||||
},
|
||||
{
|
||||
"name": "react-countup",
|
||||
"version": "6.5.3",
|
||||
"license": "MIT",
|
||||
"author": "Glenn Reyes <glenn@glennreyes.com> (https://twitter.com/glnnrys)"
|
||||
},
|
||||
{
|
||||
"name": "react-dom",
|
||||
"version": "18.2.0",
|
||||
"license": "MIT"
|
||||
},
|
||||
{
|
||||
"name": "react-fast-marquee",
|
||||
"version": "1.6.5",
|
||||
"license": "MIT",
|
||||
"author": "justin-chu <justinchu252@gmail.com>"
|
||||
},
|
||||
{
|
||||
"name": "react-helmet",
|
||||
"version": "6.1.0",
|
||||
"license": "MIT",
|
||||
"author": "NFL <engineers@nfl.com>"
|
||||
},
|
||||
{
|
||||
"name": "react-i18next",
|
||||
"version": "11.15.3",
|
||||
"license": "MIT",
|
||||
"author": "Jan Mühlemann <jan.muehlemann@gmail.com> (https://github.com/jamuhl)"
|
||||
},
|
||||
{
|
||||
"name": "react-icons",
|
||||
"version": "4.12.0",
|
||||
"license": "MIT",
|
||||
"author": "Goran Gajic"
|
||||
},
|
||||
{
|
||||
"name": "react-lazy-load-image-component",
|
||||
"version": "1.6.2",
|
||||
"license": "MIT",
|
||||
"author": {
|
||||
"name": "Albert Juhé Lluveras",
|
||||
"email": "contact@albertjuhe.com"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "react-markdown",
|
||||
"version": "8.0.7",
|
||||
"license": "MIT",
|
||||
"author": "Espen Hovlandsdal <espen@hovlandsdal.com>"
|
||||
},
|
||||
{
|
||||
"name": "react-modal-image",
|
||||
"version": "2.6.0",
|
||||
"license": "MIT",
|
||||
"author": "Ari Autio <ari.autio@iki.fi>"
|
||||
},
|
||||
{
|
||||
"name": "react-motion",
|
||||
"version": "0.5.2",
|
||||
"license": "MIT",
|
||||
"author": [
|
||||
"nkbt",
|
||||
"chenglou"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "react-rnd",
|
||||
"version": "10.3.5",
|
||||
"license": "MIT",
|
||||
"author": "bokuweb"
|
||||
},
|
||||
{
|
||||
"name": "react-router-dom",
|
||||
"version": "6.26.2",
|
||||
"license": "MIT",
|
||||
"author": "Remix Software <hello@remix.run>"
|
||||
},
|
||||
{
|
||||
"name": "react-ticker",
|
||||
"version": "1.3.2",
|
||||
"license": "MIT",
|
||||
"author": "https://github.com/AndreasFaust"
|
||||
},
|
||||
{
|
||||
"name": "react-transition-group",
|
||||
"version": "4.4.5",
|
||||
"license": "BSD-3-Clause",
|
||||
"author": ""
|
||||
},
|
||||
{
|
||||
"name": "react-useanimations",
|
||||
"version": "2.10.0",
|
||||
"license": "MIT",
|
||||
"author": "Tuan Phung, Marek Feikus"
|
||||
},
|
||||
{
|
||||
"name": "realtime-bpm-analyzer",
|
||||
"version": "3.3.0",
|
||||
"license": "MIT",
|
||||
"author": {
|
||||
"name": "David Lepaux",
|
||||
"email": "d.lepaux@gmail.com",
|
||||
"url": "https://github.com/dlepaux"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "remark-gfm",
|
||||
"version": "3.0.1",
|
||||
"license": "MIT",
|
||||
"author": "Titus Wormer <tituswormer@gmail.com> (https://wooorm.com)"
|
||||
},
|
||||
{
|
||||
"name": "rxjs",
|
||||
"version": "7.8.1",
|
||||
"license": "Apache-2.0",
|
||||
"author": "Ben Lesh <ben@benlesh.com>"
|
||||
},
|
||||
{
|
||||
"name": "store",
|
||||
"version": "2.0.12",
|
||||
"license": "MIT",
|
||||
"author": "Marcus Westin <narcvs@gmail.com>"
|
||||
},
|
||||
{
|
||||
"name": "ua-parser-js",
|
||||
"version": "1.0.38",
|
||||
"license": "MIT",
|
||||
"author": "Faisal Salman <f@faisalman.com> (http://faisalman.com)"
|
||||
},
|
||||
{
|
||||
"name": "vaul",
|
||||
"version": "0.9.2",
|
||||
"license": "MIT",
|
||||
"author": "Emil Kowalski <e@emilkowal.ski>"
|
||||
},
|
||||
{
|
||||
"name": "vite",
|
||||
"version": "5.4.4",
|
||||
"license": "MIT",
|
||||
"author": "Evan You"
|
||||
}
|
||||
]
|
44
packages/app/scripts/dump-licenses.js
Normal file
44
packages/app/scripts/dump-licenses.js
Normal file
@ -0,0 +1,44 @@
|
||||
import fs from "node:fs"
|
||||
import path from "node:path"
|
||||
|
||||
async function main() {
|
||||
const cwd = process.cwd()
|
||||
const outputFilePath = path.resolve(process.cwd(), "public", "oss-licenses.json")
|
||||
|
||||
if (await fs.promises.stat(outputFilePath).then(() => true, () => false)) {
|
||||
fs.unlinkSync(outputFilePath)
|
||||
}
|
||||
|
||||
const rootPkgJson = JSON.parse(fs.readFileSync(path.resolve(cwd, "package.json")))
|
||||
|
||||
const modules = Object.entries(rootPkgJson.dependencies).map(([name, version]) => ({ name, version }))
|
||||
|
||||
let licenses = []
|
||||
|
||||
for await (const mod of modules) {
|
||||
const pkgJsonPath = path.resolve(cwd, "node_modules", mod.name, "package.json")
|
||||
|
||||
if (!await fs.promises.stat(pkgJsonPath).then(() => true, () => false)) {
|
||||
continue
|
||||
}
|
||||
|
||||
const pkgJson = JSON.parse(fs.readFileSync(pkgJsonPath))
|
||||
|
||||
console.log(`Computing license for [${mod}]`)
|
||||
|
||||
licenses.push({
|
||||
name: pkgJson.name,
|
||||
version: pkgJson.version,
|
||||
license: pkgJson.license,
|
||||
author: pkgJson.author,
|
||||
})
|
||||
}
|
||||
|
||||
licenses = licenses.sort((a, b) => a.name.localeCompare(b.name))
|
||||
|
||||
fs.writeFileSync(outputFilePath, JSON.stringify(licenses, null, 4))
|
||||
|
||||
console.log(`Wrote [${licenses.length}] licenses to > ${outputFilePath}`)
|
||||
}
|
||||
|
||||
main()
|
@ -1,34 +1,72 @@
|
||||
import React from "react"
|
||||
import axios from "axios"
|
||||
|
||||
import config from "@config"
|
||||
|
||||
import "./index.less"
|
||||
|
||||
export default () => {
|
||||
const [licenses, setLicenses] = React.useState([])
|
||||
async function readLicenses() {
|
||||
const { data } = await axios.get(config.ossLicensesUrl)
|
||||
|
||||
const loadLicenses = async () => {
|
||||
const deps = Object.entries(config.package.dependencies).reduce((acc, [name, version]) => {
|
||||
acc.push({
|
||||
name,
|
||||
version,
|
||||
})
|
||||
return data
|
||||
}
|
||||
|
||||
return acc
|
||||
}, [])
|
||||
const PackageItem = (props) => {
|
||||
const { name, version, author, license } = props.pkg
|
||||
|
||||
setLicenses(deps)
|
||||
async function openLicenseView(id) {
|
||||
const { data } = await axios.get(`https://licenses.opendefinition.org/licenses/${id}.json`)
|
||||
|
||||
window.open(data.url, "_blank")
|
||||
}
|
||||
|
||||
return <div className="tdp-page-list-item">
|
||||
<h2>{name}</h2>
|
||||
|
||||
<div className="tdp-page-list-item-info">
|
||||
<p>Version: {version}</p>
|
||||
{
|
||||
author && (author.name ? <p>Author: {author.name}</p> : <p>Author: {author}</p>)
|
||||
}
|
||||
<p>License: {license}</p>
|
||||
</div>
|
||||
|
||||
<a onClick={() => openLicenseView(license)}>View License</a>
|
||||
</div>
|
||||
}
|
||||
|
||||
const OpenSourceLibrariesPage = () => {
|
||||
const [libraries, setLibraries] = React.useState([])
|
||||
|
||||
async function initialize() {
|
||||
setLibraries(await readLicenses())
|
||||
}
|
||||
|
||||
React.useEffect(() => {
|
||||
loadLicenses()
|
||||
initialize()
|
||||
}, [])
|
||||
|
||||
return <div className="tpd_list">
|
||||
{licenses.map((license) => {
|
||||
return <div className="item">
|
||||
<h3>{license.name}</h3>
|
||||
<p>{license.version}</p>
|
||||
</div>
|
||||
})}
|
||||
return <div className="tpd-page">
|
||||
<div className="tpd-page-header">
|
||||
<h1>
|
||||
Open Source Libraries
|
||||
</h1>
|
||||
<p>
|
||||
❤️ {config.app.siteName} works thanks to all the amazing following open source libraries. ❤️
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="tdp-page-list">
|
||||
{
|
||||
libraries.map((pkg, index) => {
|
||||
return <PackageItem
|
||||
key={index}
|
||||
pkg={pkg}
|
||||
/>
|
||||
})
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
export default OpenSourceLibrariesPage
|
@ -1,9 +1,48 @@
|
||||
.tpd_list {
|
||||
display: inline-flex;
|
||||
.tpd-page {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow-y: scroll!important;
|
||||
|
||||
.item {
|
||||
gap: 10px;
|
||||
|
||||
width: 100%;
|
||||
|
||||
.tdp-page-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
width: 100%;
|
||||
|
||||
gap: 7px;
|
||||
}
|
||||
|
||||
.tdp-page-list-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
background-color: var(--background-color-accent);
|
||||
|
||||
border-radius: 12px;
|
||||
|
||||
padding: 10px;
|
||||
|
||||
gap: 10px;
|
||||
|
||||
.tdp-page-list-item-info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
gap: 3px;
|
||||
}
|
||||
|
||||
h1,
|
||||
h2,
|
||||
h3,
|
||||
h4,
|
||||
h5,
|
||||
h6,
|
||||
p,
|
||||
span {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
}
|
@ -263,6 +263,23 @@ export default {
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
<div className="inline_field">
|
||||
<div className="field_header">
|
||||
<div className="field_icon">
|
||||
<Icons.MdInfo />
|
||||
</div>
|
||||
|
||||
<p>View Open Source Licenses</p>
|
||||
</div>
|
||||
|
||||
<div className="field_value">
|
||||
<antd.Button
|
||||
icon={<Icons.MdOpenInNew />}
|
||||
onClick={() => app.location.push("/licenses")}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user