Jena SPARQL for Mac and RDF Queries

undefined
10/3/2024
1
J
e
n
a
 
S
p
a
r
q
l
 
(
f
o
r
 
M
a
c
)
 
10/3/2024
2
J
e
n
a
 
S
P
A
R
Q
L
SPARQL queries RDF graphs (a set of
triples):
RDF graphs – models (in Jena)
RDF triples – statements (in Jena)
It is the triples that SPARQL cares, not the
serialization.
The serialization is just a way to write the triples
down
Here we use Turtle
10/3/2024
3
v
c
-
d
b
-
1
.
r
d
f
 
i
n
 
T
u
r
t
l
e
@prefix vCard:   <http://www.w3.org/2001/vcard-rdf/3.0#> .
@prefix rdf:     <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
<http://somewhere/MattJones/>  vCard:FN   "Matt Jones" .
<http://somewhere/MattJones/>  vCard:N    _:b0 .
_:b0  vCard:Family "Jones" .
_:b0  vCard:Given  "Matthew" .
<http://somewhere/RebeccaSmith/> vCard:FN    "Becky Smith" .
<http://somewhere/RebeccaSmith/> vCard:N     _:b1 .
_:b1 vCard:Family "Smith" .
_:b1 vCard:Given  "Rebecca" .
<http://somewhere/JohnSmith/>    vCard:FN    "John Smith" .
<http://somewhere/JohnSmith/>    vCard:N     _:b2 .
_:b2 vCard:Family "Smith" .
_:b2 vCard:Given  "John"  .
<http://somewhere/SarahJones/>   vCard:FN    "Sarah Jones" .
<http://somewhere/SarahJones/>   vCard:N     _:b3 .
_:b3 vCard:Family  "Jones" .
_:b3 vCard:Given   "Sarah" .
10/3/2024
4
A
R
Q
ARQ is a query engine for Jena that supports the
SPARQL RDF Query language.
ARQ Features:
Multiple query languages
SPARQL (.rq – file extension)
RDQL (.rdql)
ARQ, the engine’s own language (.arq)
Multiple query engines
General purpose engine
Remote access engines
Rewriter to SQL
I
n
s
t
a
l
l
 
A
R
Q
Set ARQROOT
export ARQROOT=“/Users/
username
/
somewhere
/Jena/ARQ-2.2/ARQ-2.2”
Replace 
username
 with 
your own username
; replace 
somewhere
 with 
the
file path where you save Jena folder
 (Jena folder is saved in Desktop in this
screenshot)
10/3/2024
5
Q
u
e
r
y
 
1
SPARQL file: “~/Desktop/Jena/ARQ-2.2/ARQ-2.2/bin/sparql”
Data file: “~/Desktop/Jena/Tutorial/vc-db-1.rdf”
Query file: “~/Desktop/Jena/Tutorial/arq/q1.rq”
Execute query q1.rq
ARQ-2.2/ARQ-2.2/bin/sparql --data=Tutorial/vc-db-1.rdf --query=Tutorial/arq/q1.rq
The working directory in all the examples is “~/Desktop/Jena”.  If you are not in the same directory, you have to
modify the path of the SPARQL file, the data file, and the query file.
10/3/2024
6
SELECT ?x
WHERE
 { ?x <http://www.w3.org/2001/vcard-rdf/3.0#FN> "John Smith" }
Q
u
e
r
y
 
2
Data file: “~/Desktop/Jena/Tutorial/vc-db-1.rdf”
Query file: “~/Desktop/Jena/Tutorial/arq/q2.rq”
10/3/2024
7
PREFIX vcard:      <http://www.w3.org/2001/vcard-rdf/3.0#>
SELECT ?y ?givenName
WHERE { ?y vcard:Family "Smith" .
   
 
?y vcard:Given  ?givenName . }
Q
u
e
r
y
 
3
 
-
 
F
i
l
t
e
r
Data file: “~/Desktop/Jena/Tutorial/vc-db-1.rdf”
Query file: “~/Desktop/Jena/Tutorial/arq/q3.rq”
10/3/2024
8
PREFIX vcard: <http://www.w3.org/2001/vcard-rdf/3.0#>
SELECT ?g
WHERE
{ ?y vcard:Given ?g .
  FILTER regex(?g, "r", "i") }
Q
u
e
r
y
 
4
 
-
 
O
P
T
I
O
N
A
L
Data file: “~/Desktop/Jena/Tutorial/vc-db-2.rdf”
Query file: “~/Desktop/Jena/Tutorial/arq/q4.rq”
10/3/2024
9
PREFIX info:    <http://somewhere/peopleInfo#>
PREFIX vcard:   <http://www.w3.org/2001/vcard-rdf/3.0#>
SELECT ?name ?age
WHERE
{    ?person vcard:FN  ?name .
    OPTIONAL { ?person info:age ?age }  }
Q
u
e
r
y
 
5
Data file: “~/Desktop/Jena/Tutorial/vc-db-2.rdf”
Query file: “~/Desktop/Jena/Tutorial/arq/q5.rq”
10/3/2024
10
PREFIX info:    <http://somewhere/peopleInfo#>
PREFIX vcard:   <http://www.w3.org/2001/vcard-rdf/3.0#>
SELECT ?name ?age
WHERE
{    ?person vcard:FN  ?name .
     ?person info:age ?age .  }
Q
u
e
r
y
 
6
 
 
O
p
t
i
o
n
a
l
 
a
n
d
 
F
i
l
t
e
r
Data file: “~/Desktop/Jena/Tutorial/vc-db-2.rdf”
Query file: “~/Desktop/Jena/Tutorial/arq/q6.rq”
10/3/2024
11
PREFIX info:        <http://somewhere/peopleInfo#>
PREFIX vcard:      <http://www.w3.org/2001/vcard-rdf/3.0#>
SELECT ?name ?age
WHERE
{
    ?person vcard:FN  ?name .
    OPTIONAL { ?person info:age ?age . FILTER ( ?age > “24” ) }
}
10/3/2024
12
Q
u
e
r
y
 
7
 
-
 
U
n
i
o
n
Data: ~/Desktop/Jena/Tutorial/name.rdf
@prefix foaf: <http://xmlns.com/foaf/0.1/> .
@prefix vcard: <http://www.w3.org/2001/vcard-rdf/3.0#> .
_:a foaf:name   "Matt Jones" .
_:b foaf:name   "Sarah Jones" .
_:c vcard:FN    "Becky Smith" .
_:d vcard:FN    "John Smith" .
Q
u
e
r
y
 
7
 
 
U
n
i
o
n
Data file: “~/Desktop/Jena/Tutorial/name.rdf”
Query file: “~/Desktop/Jena/Tutorial/arq/q7.rq”
10/3/2024
13
PREFIX info:        <http://somewhere/peopleInfo#>
PREFIX vcard:      <http://www.w3.org/2001/vcard-rdf/3.0#>
SELECT ?name ?age
WHERE
{
    ?person vcard:FN  ?name .
    OPTIONAL { ?person info:age ?age . FILTER ( ?age > “24” ) }
}
10/3/2024
14
Q
u
e
r
y
 
8
 
 
N
a
m
e
d
 
G
r
a
p
h
s
@prefix dc: <http://purl.org/dc/elements/1.1/> .
[] dc:title "Harry Potter and the Philospher's Stone" .
[] dc:title "Harry Potter and the Chamber of Secrets" .
@prefix dc: <http://purl.org/dc/elements/1.1/> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
<ds-ng-1.ttl> dc:date "2005-07-14T03:18:56+0100"^^xsd:dateTime .
<ds-ng-2.ttl> dc:date "2005-09-22T05:53:05+0100"^^xsd:dateTime .
@prefix dc: <http://purl.org/dc/elements/1.1/> .
[] dc:title "Harry Potter and the Sorcerer's Stone" .
[] dc:title "Harry Potter and the Chamber of Secrets" .
Default graph:
ds-dft.ttl
Named graph:
ds-ng-1.ttl
Named graph:
ds-ng-2.ttl
10/3/2024
15
Q
u
e
r
y
 
8
 
 
N
a
m
e
d
 
G
r
a
p
h
s
Data file: ~/Desktop/Jena/Tutorial
Query file: ~/Desktop/Jena/Tutorial/arq/q8.rq
PREFIX  xsd:    <http://www.w3.org/2001/XMLSchema#>
PREFIX  dc:     <http://purl.org/dc/elements/1.1/>
PREFIX :    <.>
SELECT ?title ?graph
FROM
   
<ds-dft.ttl>
FROM NAMED
  
<ds-ng-1.ttl>
FROM NAMED
  
<ds-ng-2.ttl>
WHERE {
  GRAPH ?graph {
 
?x dc:title ?title . }
}
10/3/2024
16
Q
u
e
r
y
 
8
 
 
N
a
m
e
d
 
G
r
a
p
h
s
10/3/2024
17
E
x
e
c
u
t
i
n
g
 
S
P
A
R
Q
L
 
q
u
e
r
i
e
s
 
v
i
a
J
e
n
a
 
A
P
I
SPARQL queries are created and executed with Jena via classes
in the com.hp.hpl.jena.query package.
Using QueryFactory is the simplest approach.
Create() methods are used to read a textual query from a file or
from a String.
Create() returns a query object with a parsed query
Create an instance of QueryExecution to perform a different type
of query
Call QueryExecutionFactory.create(query, model)
Because the data for the query is provided programmatically, the
query does not need a FROM clause.
ResultSet allows you to iterate over QuerySolution providing
access to each bound variable’s value.
10/3/2024
18
B
l
o
g
g
e
r
s
.
r
d
f
10/3/2024
19
Q
u
e
r
y
 
b
l
o
g
g
e
r
s
Data file: ~/Desktop/Jena/Tutorial/arq/bloggers.rdf
Query file: ~/Desktop/Jena/Tutorial/arq/bloggers1.rq
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?url
FROM 
 
<bloggers.rdf>
WHERE  {
    ?contributor foaf:name "Jon Foobar" .
    ?contributor foaf:weblog ?url .
}
10/3/2024
20
 
 
import com.hp.hpl.jena.rdf.model.*;
import com.hp.hpl.jena.util.FileManager;
import com.hp.hpl.jena.query.* ;
import com.hp.hpl.jena.query.ARQ;
import com.hp.hpl.jena.sparql.*;
import java.io.*;
public class Bloggers extends Object {
 
  static final String inputFileName = "bloggers.rdf";
  public static void main (String args[]) {
  // Create an empty in-memory model
  Model model = ModelFactory.createDefaultModel();
  
  // use the FileManager to open the bloggers RDF graph from the filesystem
  InputStream in = FileManager.get().open(inputFileName);
   if (in == null) {
    throw new IllegalArgumentException( "File: " + inputFileName + " not found");
        }
  // read the RDF/XML file
  model.read( in, "" );
  
Bloggers.java
10/3/2024
21
 
 
// Create a new query
String queryString =
 
"PREFIX foaf: <http://xmlns.com/foaf/0.1/> " +
 
"SELECT ?url " +
 
"WHERE {" +
 
"      ?contributor foaf:name \"Jon Foobar\" . " +
 
"      ?contributor foaf:weblog ?url . " +
 
"      }";
Query query = QueryFactory.create(queryString);
// Execute the query and obtain results
QueryExecution qe = QueryExecutionFactory.create(query, model);
ResultSet results = qe.execSelect();
// Output query results
 
ResultSetFormatter.out(System.out, results, query);
// Important - free up resources used running the query
qe.close();
}
 
}
Bloggers.java
10/3/2024
22
E
x
e
c
u
t
i
n
g
 
S
P
A
R
Q
L
 
q
u
e
r
i
e
s
 
v
i
a
J
e
n
a
 
A
P
I
Set up CLASSPATH for Jena API
CLASSPATH=“.:/Users/usersname/somewhere/Jena/Jena-2.5.5/lib/*”
export CLASSPATH
Replace 
username
 with 
your own username
; replace 
somewhere
 with 
the file path
where you save Jena folder
 (Jena folder is saved in Desktop in this screenshot)
10/3/2024
23
E
x
e
c
u
t
i
n
g
 
S
P
A
R
Q
L
 
q
u
e
r
i
e
s
 
v
i
a
J
e
n
a
 
A
P
I
Store bloggers.java in ~\Desktop\Jena\Tutorial\arq
Compile
Run
The working directory in this examples is “~/Desktop/Jena/Tutorial/arq”.  If you are not in the same
directory, you have to modify the file path.
10/3/2024
24
E
x
e
c
u
t
i
n
g
 
S
P
A
R
Q
L
 
q
u
e
r
i
e
s
 
v
i
a
J
e
n
a
 
A
P
I
Store bloggers1.java in ~/Desktop/Jena/Tutorial/arq
Compile and run
PREFIX foaf: <http://xmlns.com/foaf/0.1/>
SELECT ?name ?url
FROM 
 
<bloggers.rdf>
WHERE  {
    ?x foaf:name ?name .
    ?x foaf:weblog ?url .
}
Bloggers1.java
S
u
m
m
a
r
y
Practicing and mastering all the Jena Sparql
tutorials on your own.
Be able to create similar tutorials using your
own examples.
10/3/2024
25
Slide Note
Embed
Share

Jena SPARQL for Mac is a powerful tool for querying RDF graphs using SPARQL. Learn about RDF graphs, models, triples, and how SPARQL queries work. Explore ARQ, a query engine that supports the SPARQL RDF Query language and features multiple query languages. Discover how to install ARQ and execute SPARQL queries effectively in Jena.

  • Jena SPARQL
  • RDF queries
  • ARQ
  • Query engine
  • RDF graphs

Uploaded on Oct 03, 2024 | 0 Views


Download Presentation

Please find below an Image/Link to download the presentation.

The content on the website is provided AS IS for your information and personal use only. It may not be sold, licensed, or shared on other websites without obtaining consent from the author. Download presentation by click this link. If you encounter any issues during the download, it is possible that the publisher has removed the file from their server.

E N D

Presentation Transcript


  1. Jena Sparql (for Mac) 10/3/2024 1

  2. Jena SPARQL SPARQL queries RDF graphs (a set of triples): RDF graphs models (in Jena) RDF triples statements (in Jena) It is the triples that SPARQL cares, not the serialization. The serialization is just a way to write the triples down Here we use Turtle 10/3/2024 2

  3. vc-db-1.rdf in Turtle @prefix vCard: <http://www.w3.org/2001/vcard-rdf/3.0#> . @prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> . <http://somewhere/MattJones/> vCard:FN "Matt Jones" . <http://somewhere/MattJones/> vCard:N _:b0 . _:b0 vCard:Family "Jones" . _:b0 vCard:Given "Matthew" . <http://somewhere/RebeccaSmith/> vCard:FN "Becky Smith" . <http://somewhere/RebeccaSmith/> vCard:N _:b1 . _:b1 vCard:Family "Smith" . _:b1 vCard:Given "Rebecca" . <http://somewhere/JohnSmith/> vCard:FN "John Smith" . <http://somewhere/JohnSmith/> vCard:N _:b2 . _:b2 vCard:Family "Smith" . _:b2 vCard:Given "John" . <http://somewhere/SarahJones/> vCard:FN "Sarah Jones" . <http://somewhere/SarahJones/> vCard:N _:b3 . _:b3 vCard:Family "Jones" . _:b3 vCard:Given "Sarah" . 10/3/2024 3

  4. ARQ ARQ is a query engine for Jena that supports the SPARQL RDF Query language. ARQ Features: Multiple query languages SPARQL (.rq file extension) RDQL (.rdql) ARQ, the engine s own language (.arq) Multiple query engines General purpose engine Remote access engines Rewriter to SQL 10/3/2024 4

  5. Install ARQ Set ARQROOT export ARQROOT= /Users/username/somewhere/Jena/ARQ-2.2/ARQ-2.2 Replace username with your own username; replace somewhere with the file path where you save Jena folder (Jena folder is saved in Desktop in this screenshot) 10/3/2024 5

  6. Query 1 SPARQL file: ~/Desktop/Jena/ARQ-2.2/ARQ-2.2/bin/sparql Data file: ~/Desktop/Jena/Tutorial/vc-db-1.rdf Query file: ~/Desktop/Jena/Tutorial/arq/q1.rq SELECT ?x WHERE { ?x <http://www.w3.org/2001/vcard-rdf/3.0#FN> "John Smith" } Execute query q1.rq ARQ-2.2/ARQ-2.2/bin/sparql --data=Tutorial/vc-db-1.rdf --query=Tutorial/arq/q1.rq The working directory in all the examples is ~/Desktop/Jena . If you are not in the same directory, you have to modify the path of the SPARQL file, the data file, and the query file. 10/3/2024 6

  7. Query 2 Data file: ~/Desktop/Jena/Tutorial/vc-db-1.rdf Query file: ~/Desktop/Jena/Tutorial/arq/q2.rq PREFIX vcard: <http://www.w3.org/2001/vcard-rdf/3.0#> SELECT ?y ?givenName WHERE { ?y vcard:Family "Smith" . ?y vcard:Given ?givenName . } 10/3/2024 7

  8. Query 3 - Filter Data file: ~/Desktop/Jena/Tutorial/vc-db-1.rdf Query file: ~/Desktop/Jena/Tutorial/arq/q3.rq PREFIX vcard: <http://www.w3.org/2001/vcard-rdf/3.0#> SELECT ?g WHERE { ?y vcard:Given ?g . FILTER regex(?g, "r", "i") } 10/3/2024 8

  9. Query 4 - OPTIONAL Data file: ~/Desktop/Jena/Tutorial/vc-db-2.rdf Query file: ~/Desktop/Jena/Tutorial/arq/q4.rq PREFIX info: <http://somewhere/peopleInfo#> PREFIX vcard: <http://www.w3.org/2001/vcard-rdf/3.0#> SELECT ?name ?age WHERE { ?person vcard:FN OPTIONAL { ?person info:age ?age } } ?name . 10/3/2024 9

  10. Query 5 Data file: ~/Desktop/Jena/Tutorial/vc-db-2.rdf Query file: ~/Desktop/Jena/Tutorial/arq/q5.rq PREFIX info: <http://somewhere/peopleInfo#> PREFIX vcard: <http://www.w3.org/2001/vcard-rdf/3.0#> SELECT ?name ?age WHERE { ?person vcard:FN ?person info:age ?age . } ?name . 10/3/2024 10

  11. Query 6 Optional and Filter Data file: ~/Desktop/Jena/Tutorial/vc-db-2.rdf Query file: ~/Desktop/Jena/Tutorial/arq/q6.rq PREFIX info: <http://somewhere/peopleInfo#> PREFIX vcard: <http://www.w3.org/2001/vcard-rdf/3.0#> SELECT ?name ?age WHERE { ?person vcard:FN OPTIONAL { ?person info:age ?age . FILTER ( ?age > 24 ) } } ?name . 10/3/2024 11

  12. Query 7 - Union Data: ~/Desktop/Jena/Tutorial/name.rdf @prefix foaf: <http://xmlns.com/foaf/0.1/> . @prefix vcard: <http://www.w3.org/2001/vcard-rdf/3.0#> . _:a foaf:name "Matt Jones" . _:b foaf:name "Sarah Jones" . _:c vcard:FN "Becky Smith" . _:d vcard:FN "John Smith" . 10/3/2024 12

  13. Query 7 Union Data file: ~/Desktop/Jena/Tutorial/name.rdf Query file: ~/Desktop/Jena/Tutorial/arq/q7.rq PREFIX info: <http://somewhere/peopleInfo#> PREFIX vcard: <http://www.w3.org/2001/vcard-rdf/3.0#> SELECT ?name ?age WHERE { ?person vcard:FN OPTIONAL { ?person info:age ?age . FILTER ( ?age > 24 ) } } ?name . 10/3/2024 13

  14. Query 8 Named Graphs Default graph: ds-dft.ttl @prefix dc: <http://purl.org/dc/elements/1.1/> . @prefix xsd: <http://www.w3.org/2001/XMLSchema#> . <ds-ng-1.ttl> dc:date "2005-07-14T03:18:56+0100"^^xsd:dateTime . <ds-ng-2.ttl> dc:date "2005-09-22T05:53:05+0100"^^xsd:dateTime . Named graph: ds-ng-1.ttl @prefix dc: <http://purl.org/dc/elements/1.1/> . [] dc:title "Harry Potter and the Philospher's Stone" . [] dc:title "Harry Potter and the Chamber of Secrets" . Named graph: ds-ng-2.ttl @prefix dc: <http://purl.org/dc/elements/1.1/> . [] dc:title "Harry Potter and the Sorcerer's Stone" . [] dc:title "Harry Potter and the Chamber of Secrets" . 10/3/2024 14

  15. Query 8 Named Graphs Data file: ~/Desktop/Jena/Tutorial Query file: ~/Desktop/Jena/Tutorial/arq/q8.rq PREFIX xsd: <http://www.w3.org/2001/XMLSchema#> PREFIX dc: <http://purl.org/dc/elements/1.1/> PREFIX : <.> SELECT ?title ?graph FROM FROM NAMED FROM NAMED WHERE { GRAPH ?graph { ?x dc:title ?title . } } <ds-dft.ttl> <ds-ng-1.ttl> <ds-ng-2.ttl> 10/3/2024 15

  16. Query 8 Named Graphs 10/3/2024 16

  17. Executing SPARQL queries via Jena API SPARQL queries are created and executed with Jena via classes in the com.hp.hpl.jena.query package. Using QueryFactory is the simplest approach. Create() methods are used to read a textual query from a file or from a String. Create() returns a query object with a parsed query Create an instance of QueryExecution to perform a different type of query Call QueryExecutionFactory.create(query, model) Because the data for the query is provided programmatically, the query does not need a FROM clause. ResultSet allows you to iterate over QuerySolution providing access to each bound variable s value. 10/3/2024 17

  18. Bloggers.rdf 10/3/2024 18

  19. Query bloggers Data file: ~/Desktop/Jena/Tutorial/arq/bloggers.rdf Query file: ~/Desktop/Jena/Tutorial/arq/bloggers1.rq PREFIX foaf: <http://xmlns.com/foaf/0.1/> SELECT ?url FROM <bloggers.rdf> WHERE { ?contributor foaf:name "Jon Foobar" . ?contributor foaf:weblog ?url . } 10/3/2024 19

  20. import com.hp.hpl.jena.rdf.model.*; import com.hp.hpl.jena.util.FileManager; import com.hp.hpl.jena.query.* ; import com.hp.hpl.jena.query.ARQ; import com.hp.hpl.jena.sparql.*; import java.io.*; public class Bloggers extends Object { static final String inputFileName = "bloggers.rdf"; public static void main (String args[]) { // Create an empty in-memory model Model model = ModelFactory.createDefaultModel(); // use the FileManager to open the bloggers RDF graph from the filesystem InputStream in = FileManager.get().open(inputFileName); if (in == null) { throw new IllegalArgumentException( "File: " + inputFileName + " not found"); } // read the RDF/XML file model.read( in, "" ); Bloggers.java 10/3/2024 20

  21. // Create a new query String queryString = "PREFIX foaf: <http://xmlns.com/foaf/0.1/> " + "SELECT ?url " + "WHERE {" + " ?contributor foaf:name \"Jon Foobar\" . " + " ?contributor foaf:weblog ?url . " + " }"; Query query = QueryFactory.create(queryString); // Execute the query and obtain results QueryExecution qe = QueryExecutionFactory.create(query, model); ResultSet results = qe.execSelect(); // Output query results ResultSetFormatter.out(System.out, results, query); // Important - free up resources used running the query qe.close(); } } Bloggers.java 10/3/2024 21

  22. Executing SPARQL queries via Jena API Set up CLASSPATH for Jena API CLASSPATH= .:/Users/usersname/somewhere/Jena/Jena-2.5.5/lib/* export CLASSPATH Replace username with your own username; replace somewhere with the file path where you save Jena folder (Jena folder is saved in Desktop in this screenshot) 10/3/2024 22

  23. Executing SPARQL queries via Jena API Store bloggers.java in ~\Desktop\Jena\Tutorial\arq Compile Run The working directory in this examples is ~/Desktop/Jena/Tutorial/arq . If you are not in the same directory, you have to modify the file path. 10/3/2024 23

  24. Executing SPARQL queries via Jena API PREFIX foaf: <http://xmlns.com/foaf/0.1/> SELECT ?name ?url FROM <bloggers.rdf> WHERE { ?x foaf:name ?name . ?x foaf:weblog ?url . } Bloggers1.java Store bloggers1.java in ~/Desktop/Jena/Tutorial/arq Compile and run 10/3/2024 24

  25. Summary Practicing and mastering all the Jena Sparql tutorials on your own. Be able to create similar tutorials using your own examples. 10/3/2024 25

More Related Content

giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#giItT1WQy@!-/#