Chapter 27 – Macromedia
ColdFusion MX
Outline
27.1
27.2
27.3
27.4
27.5
27.6
27.7
27.8
27.9
27.10
Introduction
Simple ColdFusion Example: Clock
Using Variables and Expressions
Variable Scoping
Form Processing
Creating a Data Source Name
Bookstore Case Study: Interface and Database
Bookstore Case Study: Shopping Cart
Advanced Topics for ColdFusion Developers
Web Resources
 2004 Prentice Hall, Inc. All rights reserved.
Objectives
• In this lesson, you will learn:
– To create basic ColdFusion templates.
– To use ColdFusion Markup Language tags and functions to
add dynamic functionality to Web pages.
– To use information collected from Web forms.
– To create a database-driven bookstore application.
– To create a shopping cart for the bookstore that follows a
user through the site.
 2004 Prentice Hall, Inc. All rights reserved.
27.1 Introduction
• ColdFusion
– Widely used server-side markup language
– Developed by Allaire
– ColdFusion Markup Language (CFML)
•
•
•
•
Based around a set of tags that work like XHTML tags
Supports XML, ColdFusion Components and Web services
Saved with a .cfm extension
ColdFusion template
 2004 Prentice Hall, Inc. All rights reserved.
27.2 Simple ColdFusion Example: Clock
• CFML comment
– <!--- CFML Comment --->
• cfoutput tag
• Variables and functions are enclosed in #’s
– dateFormat
– timeFormat
– now
 2004 Prentice Hall, Inc. All rights reserved.
1
<?xml version = "1.0"?>
2
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
3
Outline
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
4
5
<!--- Fig. 27.1 : clock.cfm
--->
6
<!--- A simple ColdFusion example --->
clock.cfm
(1 of 2)
7
8
<!--- CFML comment tag --->
9
<!-- XHTML comment tag
-->
10
11
12
13
<html xmlns = "http://www.w3.org/1999/xhtml">
<head>
<title>A Simple ColdFusion Example</title>
14
15
<style type = "text/css">
16
p
17
td { background-color: black; color: yellow }
18
19
{ font-size: 14pt; color: blue }
</style>
</head>
20
21
<body>
22
23
<p>A Simple ColdFusion Example</p>
24
25
<table border = "1">
 2004 Prentice Hall, Inc.
All rights reserved.
<tr>
26
<td>
27
Outline
28
29
<!--- #’s between cfoutput tags are processed --->
30
<!--- Display the current date --->
31
<cfoutput>#dateFormat( now(), "mmmm dd, yyyy" )#</cfoutput>
clock.cfm
(2 of 2)
</td>
32
33
<td>
34
35
36
<!--- Display the current time --->
37
<cfoutput>#timeFormat( now(), "hh:mm:ss tt" )#</cfoutput>
</td>
38
</tr>
39
40
<tr>
41
<td colspan = "2">
42
43
44
<!--- Display the output of now() --->
45
<cfoutput>Date/Time: #now()#</cfoutput>
</td>
46
47
</tr>
48
</table>
49
50
</body>
</html>
 2004 Prentice Hall, Inc.
All rights reserved.
 2004 Prentice Hall, Inc. All rights reserved.
1
<?xml version = "1.0"?>
2
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
3
Outline
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
4
5
<!-- XHTML comment tag
-->
6
7
8
9
<html xmlns = "http://www.w3.org/1999/xhtml">
Generated XHTML
code
(1 of 2)
<head>
<title>A Simple ColdFusion Example</title>
10
11
<style type = "text/css">
12
p
13
td { background-color: black; color: yellow }
14
15
{ font-size: 14pt; color: blue }
</style>
</head>
16
17
<body>
18
19
<p><strong>A Simple ColdFusion Example</strong></p>
20
21
22
23
24
25
<table border = "1">
<tr>
<td>
July 24, 2003
</td>
 2004 Prentice Hall, Inc.
All rights reserved.
26
<td>
27
</td>
29
Generated XHTML
code
(2 of 2)
</tr>
30
31
<tr>
32
<td colspan = "2">
33
Date/Time: {ts '2003 -07-24 13:56:33'}
34
</td>
35
36
</tr>
37
</table>
38
39
Outline
01:56:33 PM
28
</body>
</html>
 2004 Prentice Hall, Inc.
All rights reserved.
27.3 Using Variables and Expressions
• CFML also supports creating and manipulating
variables
 2004 Prentice Hall, Inc. All rights reserved.
1
<?xml version = "1.0"?>
2
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
3
Outline
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd" >
4
5
<!--- Fig. 27.3 : variables.cfm
--->
6
<!--- Expressions using Variables and Operators. --->
variables.cfm
(1 of 2)
7
8
9
10
<html xmlns = "http://www.w3.org/1999/xhtml" >
<head>
<title>Expressions using Variables and Operators </title>
11
12
<style type = "text/css" >
p { font-family: arial, sans-serif;
13
font-size: 12pt; color: blue }
14
15
16
</style>
</head>
17
18
<body>
19
20
<!--- Define variables using cfset --->
21
<cfset firstString = "One">
22
<cfset secondString = "Four">
23
<cfset firstNumber = 1>
24
<cfset secondNumber = 4>
25
 2004 Prentice Hall, Inc.
All rights reserved.
26
<!--- Concatenate two strings --->
27
<cfset combinedStrings = firstString & secondString>
Outline
28
29
<!--- Add two numbers --->
30
<cfset addedNumbers = firstNumber + secondNumber>
31
32
variables.cfm
(2 of 2)
<p><strong>Expressions using Variables and Operators</strong></p>
33
34
<p>
<cfoutput>
35
36
Concatenation Example: #combinedStrings#
37
<br />
38
Addition Example: #addedNumbers#
</cfoutput>
39
40
</p>
41
42
43
</body>
</html>
 2004 Prentice Hall, Inc.
All rights reserved.
 2004 Prentice Hall, Inc. All rights reserved.
27.3.1 Variables and Data Types
• Variables much like variables in most other
languages
• cfset
– Does not produce any output
– No close tag
 2004 Prentice Hall, Inc. All rights reserved.
27.3.1 Variables and Data Types
D a ta typ e
A rray
B o o lean
D ate/T im e
L ist
N u m b er
Q u ery
D e s c rip tio n
In d ex ed g ro u p of elem en ts (o n e to th ree d im en sio n s).
T ru e o r false.
A n y d ate o r tim e.
A strin g w ith tex t v alu es an d d elim iters.
A n y in teg er o r real n u m b er.
F o rm at sim ilar to a d atab ase tab le w ith n am ed
co lu m n s an d n u m b ered ro w s.
S trin g
T ex t en clo sed in eith er sin g le (’ ’ ) o r d o u b le (" " )
q u o tes.
S tru ctu re
G ro u p o f asso ciated d ata u sin g k ey -v alu e p airs.
F ig . 2 7 .4 C o ld F u s io n d a ta typ e s .
 2004 Prentice Hall, Inc. All rights reserved.
27.3.2 Expressions and Operators
O p e ra to r
+
^
*
/
\
MOD
+
&
EQ
NEQ
LT
LTE
GT
GTE
CONTAINS
DOES NOT
CONTAIN
NOT
AND
OR
XOR
EQV
IMP
F ig . 2 7 .5
T yp e
unary positive
unary negative
exponent
m u ltiplication
division
integer division
m o dulus
addition
subtraction
concatenatio n
equal
not equal
less than
less than or equal
greater than
g reater than or equal
contains
does not co ntain
not
and
or
exclusive or
equivalence
im plication
C o ld F u sio n o p e ra to r p re ce d e n ce .
 2004 Prentice Hall, Inc. All rights reserved.
27.4 Variable Scoping
• Scope
– Defines from where the variable can be accessed
– Refers to the named space where the variable is stored
• cfif tag
– Behaves just like if statements in other languages
– cfelseif
– cdelse
• isDefined function
– Returns true or false
• NOT operator
– Reverses the truth or falsity of entire expression
 2004 Prentice Hall, Inc. All rights reserved.
27.4 Variable Scoping
S c o p e p re fix
variables
form
url
request
cgi
cookie
client
session
application
server
flash
P re fix re q u ire d R e fe re n c e s
No
L o cal v ariab le
No
F o rm
No
URL
Y es
H T T P req u est
No
C G I v ariab le
No
C o o k ie
No
A p p licatio n
Y es
A p p licatio n
Y es
A p p licatio n
Y es
S erv er
Y es
M acro m ed ia F lash
q u eryn a m e
No
Q u ery
F ig . 2 7 .6 C o ld F u s io n v a ria b le s c o p e s .
 2004 Prentice Hall, Inc. All rights reserved.
1
<?xml version = "1.0"?>
2
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
3
Outline
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
4
5
<!--- Fig. 27.7 : name.cfm
--->
6
<!--- Using url scope variables --->
name.cfm
(1 of 2)
7
8
9
10
<html xmlns = "http://www.w3.org/1999/xhtml">
<head>
<title>Hello</title>
11
12
<style type = "text/css">
p { font-family: arial, sans-serif;
13
font-size: 14pt; color: navy }
14
15
16
</style>
</head>
17
18
<body>
19
20
<!--- IF Control Structure --->
21
<cfif NOT isDefined( "url.name" )>
22
23
<!--- Create default if name variable is not in the URL --->
24
<cfset url.name = "Guest">
25
</cfif>
 2004 Prentice Hall, Inc.
All rights reserved.
26
27
<!--- Display URL Variable --->
28
<p>Hello <cfoutput>#url.name#</cfoutput></p>
29
30
Outline
</body>
</html>
name.cfm
(2 of 2)
 2004 Prentice Hall, Inc.
All rights reserved.
27.5 Form Processing
• form variable scope
– Gather information from the user
• isNumeric function
–
–
–
–
Similar to isDefined function
Returns boolean value
Returns true if parameter is number
False otherwise
 2004 Prentice Hall, Inc. All rights reserved.
1
<?xml version = "1.0"?>
2
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
3
Outline
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd" >
4
5
<!-- Fig. 27.8 : form.html
-->
6
<!-- A simple auction bid form -->
form.html
(1 of 2)
7
8
9
10
<html xmlns = "http://www.w3.org/1999/xhtml">
<head>
<title>Simple Auction</title>
11
12
<style type = "text/css">
p { font-family: arial, sans-serif;
13
font-size: 14pt; color: navy }
14
15
16
</style>
</head>
17
18
<body>
19
20
<!-- Form variables created using post method -->
21
<form action = "form_process.cfm" method = "post">
22
<p>Enter your bid:</p>
23
24
<p>
25
 2004 Prentice Hall, Inc.
All rights reserved.
26
<!--- name attribute becomes variable name --->
27
$<input name = "bidPrice" type = "text" size = "20" />
28
<input type = "submit" value = "Enter" />
29
</p>
30
</form>
31
32
</body>
Outline
form.html
(2 of 2)
</html>
 2004 Prentice Hall, Inc.
All rights reserved.
1
<?xml version = "1.0"?>
2
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
3
Outline
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd" >
4
5
<!--- Fig. 27.9 : form_process.cfm
--->
6
<!--- A simple auction bid processing form --->
form_process.cfm
(1 of 2)
7
8
9
10
<html xmlns = "http://www.w3.org/1999/xhtml" >
<head>
<title>Simple Auction</title>
11
12
<style type = "text/css">
p { font-family: arial, sans-serif;
13
font-size: 14pt; color: navy }
14
15
16
</style>
</head>
17
18
<body>
19
20
<!--- Determine if bidPrice exists --->
21
<cfif isDefined( "form.bidPrice" )>
22
23
<!--- Determine if bidPrice is a number --->
24
<cfif isNumeric( form.bidPrice )>
25
 2004 Prentice Hall, Inc.
All rights reserved.
26
<!--- Determine is bidPrice is GTE 0 --->
27
<cfif form.bidPrice GTE 0>
Outline
28
29
<!--- Display bid from form field --->
30
<p>
31
Your bid is:
32
<cfoutput>$#form.bidPrice#</cfoutput>
form_process.cfm
(2 of 2)
</p>
33
<cfelse>
34
<p>Your bid must be greater then or equal to $0.00! </p>
35
</cfif>
36
37
<cfelse>
38
<p>Your bid must be a valid numeric dollar amount! </p>
39
</cfif>
40
41
42
<cfelse>
<p>Error, no bid found. </p>
43
44
</cfif>
45
46
47
</body>
</html>
 2004 Prentice Hall, Inc.
All rights reserved.
 2004 Prentice Hall, Inc. All rights reserved.
27.6 Creating a Data Source Name
Fig. 27.10
Data source registration in the ColdFusion Administrator.
 2004 Prentice Hall, Inc. All rights reserved.
27.7 Bookstore Case Study: Interface and
Database
• cfquery tag
• cflocation tag
– Redirects the user to another CFML template
• cfabort tag
– Instructs CFML interpreter to stop and not finish processing
page
• cfloop tag
– Outputs the code between its opening and closing tags once
 2004 Prentice Hall, Inc. All rights reserved.
1
<?xml version = "1.0"?>
2
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
3
Outline
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
4
5
<!--- Fig. 27.11 : booklist.cfm --->
6
<!--- Bookstore - List of Books --->
booklist.cfm
(1 of 3)
7
8
9
10
<html xmlns = "http://www.w3.org/1999/xhtml">
<head>
<title>Book List</title>
11
12
<style type = "text/css">
13
p
14
h1 { text-align: center }
15
16
{ text-align: center }
</style>
</head>
17
18
<body>
19
20
<!--- CFML Query using SQL on 'books' Data Source Name --->
21
<cfquery name = "bookList" datasource = "books">
22
SELECT ISBN, Title, EditionNumber
23
FROM Titles
24
ORDER BY Title ASC, EditionNumber DESC
25
</cfquery>
 2004 Prentice Hall, Inc.
All rights reserved.
26
27
<h1>Available Books</h1>
Outline
28
29
<hr />
30
31
32
<p>Select a book from this list and click the button to
booklist.cfm
(2 of 3)
view the selected book's information.</p>
33
34
35
<form action = "bookinfo.cfm" method = "post">
<p>
36
37
<!--- Dynamically build select box from database --->
38
<select name = "ISBN" size = "5">
39
40
<!--- Looping results of query using cfoutput --->
41
<cfoutput query = "bookList">
42
<option value = "#bookList.ISBN#">#bookList.Title#
43
(Edition #bookList.EditionNumber#)</option>
</cfoutput>
44
45
46
</select>
</p>
47
 2004 Prentice Hall, Inc.
All rights reserved.
<p><input type = "submit" value = "View Information" /></p>
48
49
50
51
</form>
Outline
</body>
</html>
booklist.cfm
(3 of 3)
 2004 Prentice Hall, Inc.
All rights reserved.
1
<?xml version = "1.0"?>
2
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
3
Outline
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd" >
4
5
<!--- Fig. 27.12 : bookinfo.cfm
--->
6
<!--- Bookstore - Detailed Book Information --->
bookinfo.cfm
(1 of 5)
7
8
9
10
<html xmlns = "http://www.w3.org/1999/xhtml">
<head>
<title>Book Info</title>
11
12
<style type = "text/css">
13
table { border-collapse: collapse }
14
td
padding: 5px }
15
16
17
{ border: 2px solid lightgray;
</style>
</head>
18
19
<body>
20
21
<!--- Make sure that an ISBN was submitted to this page --->
22
<cfif NOT isDefined( "form.ISBN" )>
23
24
<!--- CFML URL Forwarder --->
25
<cflocation url = "booklist.cfm" addtoken = "no">
 2004 Prentice Hall, Inc.
All rights reserved.
26
27
<cfabort>
Outline
</cfif>
28
29
<!--- CFML Query using SQL on 'books' DSN --->
30
<!--- Dynamically insert form.ISBN variable --->
31
<cfquery name = "bookInfo" datasource = "books">
32
SELECT ISBN, Title, EditionNumber, Copyright, Description,
ImageFile, PublisherName
33
34
FROM Titles, Publishers
35
WHERE Titles.ISBN = '#form.ISBN#'
36
AND Titles.PublisherID = Publishers.PublisherID
37
bookinfo.cfm
(2 of 5)
</cfquery>
38
39
<!--- Using cfoutput with a query to loop result set --->
40
<cfoutput query = "bookInfo">
41
42
<!--- Based on ISBN, use SQL to retrieve authors --->
43
<cfquery name = "authorInfo" datasource = "books">
44
SELECT FirstName, LastName
45
FROM AuthorISBN, Authors
46
WHERE AuthorISBN.isbn = '#bookInfo.ISBN#'
47
AND AuthorISBN.AuthorID = Authors.AuthorID
48
</cfquery>
49
50
<h1>#bookInfo.Title#</h1>
 2004 Prentice Hall, Inc.
All rights reserved.
51
52
Outline
<hr />
53
54
<p>
55
56
<!--- Display authors by using a CFML Loop --->
57
<cfloop query = "authorInfo">
#authorInfo.FirstName # #authorInfo.LastName# <br />
58
59
60
bookinfo.cfm
(3 of 5)
</cfloop>
</p>
61
62
<!---Output information from database about book --->
63
<table>
64
<tr>
65
<td>ISBN:</td>
66
<td>#bookInfo.ISBN#</td>
67
<td rowspan ="4">
68
69
<!--- Dynamically insert the filename into the tag --->
70
<img src = "images/#bookInfo.ImageFile #"
alt = "Image File" />
71
72
73
</td>
</tr>
74
 2004 Prentice Hall, Inc.
All rights reserved.
75
<tr>
76
<td>Edition:</td>
77
<td>#bookInfo.EditionNumber #</td>
78
</tr>
bookinfo.cfm
(4 of 5)
79
80
<tr>
81
<td>Copyright:</td>
82
<td>#bookInfo.Copyright #</td>
83
Outline
</tr>
84
85
<tr>
86
<td>Publisher:</td>
87
<td>#bookInfo.PublisherName #</td>
88
</tr>
89
</table>
90
<p>#bookInfo.Description #</p>
91
92
<!--- Used in Section 27.8 --->
93
<!--- Button to add book to shopping cart --->
94
<form action = "shoppingcart.cfm" method = "post">
95
96
97
<p>
<input type = "hidden" name = "ISBN"
value = "#bookInfo.ISBN #" />
98
 2004 Prentice Hall, Inc.
All rights reserved.
<input type = "hidden" name = "title"
99
value = "#bookInfo.Title#" />
100
Outline
101
<input type = "hidden" name = "edition"
102
value = "#bookInfo.EditionNumber#" />
103
104
<input type = "submit" value = "Add To Cart"
105
disabled = "disabled" />
106
107
</p>
108
</form>
109
bookinfo.cfm
(5 of 5)
</cfoutput>
110
111
<!--- Button to go back to the book list --->
112
<form action = "booklist.cfm" method = "post">
<p>
113
<input type = "submit" value = "Book List" />
114
115
</p>
116
</form>
117
</body>
118 </html>
 2004 Prentice Hall, Inc.
All rights reserved.
 2004 Prentice Hall, Inc. All rights reserved.
27.8 Bookstore Case Study: Shopping Cart
• cfapplication
tag
– Access the variable scopes related to applications
– client variables
• Can be stored as cookies on user’s computer or in server’s
registery
– session variables
• Store contents of user’s shopping cart as user makes selections
– application variables
 2004 Prentice Hall, Inc. All rights reserved.
1
<!--- Fig. 27.13 : Application.cfm
--->
2
<!--- Bookstore - Application Framework --->
Outline
3
4
<!--- Initialize the application framework --->
5
<cfapplication name = "bookStore"
6
clientmanagement = "Yes"
7
sessionmanagement = "Yes"
8
s e s s i o n t i m e o u t = " # c r e a t e T i m e S p a n ( 0 , 0 , 2 0 , 0 )# "
9
applicationtimeout = "#createTimeSpan( 2,0,0,0 )#"
Application.cfm
(1 of 1)
clientstorage = "cookie">
10
11
12
<!--- Make sure the shopping cart exists or create one --->
13
<cfif NOT isDefined( "session.shoppingCart" )>
14
15
<cfset session.shoppingCart = arrayNew( 2 )>
</cfif>
 2004 Prentice Hall, Inc.
All rights reserved.
1
<?xml version = "1.0"?>
2
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
3
Outline
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
4
5
<!--- Fig. 27.14 : shoppingcart.cfm
--->
6
<!--- Bookstore - Simple Shopping Cart--->
shoppingcart.cfm
(1 of 3)
7
8
<cfif isDefined( "form.ISBN" )>
9
10
<!--- Add a new book to the shopping cart. --->
11
<cfif arrayAppend( session.shoppingCart[ 1 ], form.ISBN )></cfif>
12
<cfif arrayAppend( session.shoppingCart[ 2 ], form.title )></cfif>
13
<cfif arrayAppend( session.shoppingCart[ 3 ], form.edition )></cfif>
14
<cfelseif isDefined( "form.clearCart" )>
15
16
<!--- Empty the shopping cart. --->
17
<cfif arrayClear( session.shoppingCart )></cfif>
18
</cfif>
19
20
21
22
<html xmlns = "http://www.w3.org/1999/xhtml">
<head>
<title>Bookstore Shopping Cart</title>
23
24
25
<style type = "text/css">
table { border-collapse: collapse }
 2004 Prentice Hall, Inc.
All rights reserved.
td
26
{ border: 2px solid lightgray;
padding: 5px }
27
28
29
</head>
shoppingcart.cfm
(2 of 3)
30
31
32
Outline
</style>
<body>
<h1>Shopping Cart</h1>
33
34
<!--- Check the size of the shopping cart --->
35
<cfset arraySize = arrayLen( session.shoppingCart[ 1 ] )>
36
37
38
<cfif arraySize GTE 1>
<table>
39
40
<!--- Display the items in the shopping cart --->
41
<cfloop index="i" from="1" to="#arraySize#" step="1">
42
<cfoutput>
43
<tr>
44
<td>#session.shoppingCart[ 1 ][ i ]#</td>
45
<td>#session.shoppingCart[ 2 ][ i ]#</td>
46
<td>Edition #session.shoppingCart[ 3 ][ i ]#</td>
47
</tr>
48
</cfoutput>
49
50
</cfloop>
</table>
 2004 Prentice Hall, Inc.
All rights reserved.
51
<cfelse>
<p>Empty Shopping Cart. </p>
52
53
Outline
</cfif>
54
55
<!--- Button back to the book list --->
56
<form action = "booklist.cfm" method = "post">
<p><input type = "submit" value = "Book List" /></p>
57
58
shoppingcart.cfm
(3 of 3)
</form>
59
60
<!--- Button to clear the shopping cart --->
61
<form action = "shoppingcart.cfm" method = "post">
<p>
62
<input name = "clearCart" type = "submit"
63
value = "Empty Cart" />
64
65
</p>
66
</form>
67
68
</body>
</html>
 2004 Prentice Hall, Inc.
All rights reserved.
 2004 Prentice Hall, Inc. All rights reserved.
27.9 Advanced Topics for ColdFusion
Developers
• Ability to create custom tags and user-defined
functions
• Set of built-in CFML tags for working with XML
and for interacting with Web services
 2004 Prentice Hall, Inc. All rights reserved.
27.10 Web Resources
•
•
•
•
•
www.macromedia.com/software/coldfusion
www.macromedia.com/support/coldfusion/documentation.html
www.macromedia.com/cfusion/exchange/index.cfm?view=sn130
www.forta.com
www.sys-con.com/coldfusion
 2004 Prentice Hall, Inc. All rights reserved.
Descargar

Document