Skip to Content.
Sympa Menu

perfsonar-dev - perfsonar: r3409 - in branches/WebAdmin: . perfSONARWebAdmin/admin/service perfSONARWebAdmin/admin/sqlma perfSONARWebAdmin/admin/wizard/services perfSONARWebAdmin/auxiliary perfSONARWebAdmin/test tip_balloon

Subject: perfsonar development work

List archive

perfsonar: r3409 - in branches/WebAdmin: . perfSONARWebAdmin/admin/service perfSONARWebAdmin/admin/sqlma perfSONARWebAdmin/admin/wizard/services perfSONARWebAdmin/auxiliary perfSONARWebAdmin/test tip_balloon


Chronological Thread 
  • From:
  • To:
  • Subject: perfsonar: r3409 - in branches/WebAdmin: . perfSONARWebAdmin/admin/service perfSONARWebAdmin/admin/sqlma perfSONARWebAdmin/admin/wizard/services perfSONARWebAdmin/auxiliary perfSONARWebAdmin/test tip_balloon
  • Date: Tue, 26 Feb 2008 07:25:15 -0500

Author: michalis
Date: 2008-02-26 07:25:14 -0500 (Tue, 26 Feb 2008)
New Revision: 3409

Added:
branches/WebAdmin/Service_Admin.js
branches/WebAdmin/perfSONARWebAdmin/admin/sqlma/TestAdmin.java
branches/WebAdmin/perfSONARWebAdmin/auxiliary/PerfsonarProperties.java
branches/WebAdmin/perfSONARWebAdmin/auxiliary/PerfsonarPropertiesImpl.java
branches/WebAdmin/perfSONARWebAdmin/auxiliary/PerfsonarProperty.java
branches/WebAdmin/tip_balloon.js
branches/WebAdmin/tip_balloon/
branches/WebAdmin/tip_balloon/Thumbs.db
branches/WebAdmin/tip_balloon/b.gif
branches/WebAdmin/tip_balloon/background.gif
branches/WebAdmin/tip_balloon/l.gif
branches/WebAdmin/tip_balloon/lb.gif
branches/WebAdmin/tip_balloon/lt.gif
branches/WebAdmin/tip_balloon/r.gif
branches/WebAdmin/tip_balloon/rb.gif
branches/WebAdmin/tip_balloon/rt.gif
branches/WebAdmin/tip_balloon/stemb.gif
branches/WebAdmin/tip_balloon/stemt.gif
branches/WebAdmin/tip_balloon/t.gif
branches/WebAdmin/tip_centerwindow.js
branches/WebAdmin/tip_followscroll.js
branches/WebAdmin/wz_tooltip.js
Modified:
branches/WebAdmin/main.css
branches/WebAdmin/perfSONARWebAdmin/admin/service/Admin.java
branches/WebAdmin/perfSONARWebAdmin/admin/wizard/services/RRDMA.java
branches/WebAdmin/perfSONARWebAdmin/test/Tester.java
Log:
Updating code. Adding grouping and tooltip decription functionality to
service properties Admin

Added: branches/WebAdmin/Service_Admin.js

Modified: branches/WebAdmin/main.css
===================================================================
--- branches/WebAdmin/main.css 2008-02-26 11:06:19 UTC (rev 3408)
+++ branches/WebAdmin/main.css 2008-02-26 12:25:14 UTC (rev 3409)
@@ -79,8 +79,6 @@
}
.sidebar td{
color: #000000;
- width: 99px;
- word-spacing:100px;
text-align: right;
background-color: #ffffff;
padding: 10px;

Modified: branches/WebAdmin/perfSONARWebAdmin/admin/service/Admin.java
===================================================================
--- branches/WebAdmin/perfSONARWebAdmin/admin/service/Admin.java
2008-02-26 11:06:19 UTC (rev 3408)
+++ branches/WebAdmin/perfSONARWebAdmin/admin/service/Admin.java
2008-02-26 12:25:14 UTC (rev 3409)
@@ -1,9 +1,13 @@
package perfSONARWebAdmin.admin.service;

import java.io.File;
+import java.io.FileInputStream;
import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Iterator;
import java.util.Properties;

import javax.servlet.ServletContext;
@@ -18,10 +22,15 @@

import perfSONARWebAdmin.auxiliary.Authenticator;
import perfSONARWebAdmin.auxiliary.AuthenticatorImpl;
+import perfSONARWebAdmin.auxiliary.PerfsonarProperties;
+import perfSONARWebAdmin.auxiliary.PerfsonarPropertiesImpl;
+import perfSONARWebAdmin.auxiliary.PerfsonarProperty;
import perfSONARWebAdmin.auxiliary.ServiceProperties;
import perfSONARWebAdmin.auxiliary.ServicePropertiesImpl;
import perfSONARWebAdmin.auxiliary.ServletProperties;
import perfSONARWebAdmin.auxiliary.ServletPropertiesImpl;
+import perfSONARWebAdmin.auxiliary.wizard.WizardProperties;
+import perfSONARWebAdmin.auxiliary.wizard.WizardProperty;
import sun.misc.BASE64Decoder;

/**
@@ -106,7 +115,7 @@
ServletContext sc = getServletContext();
// Getting the service path
servicePath = sc.getRealPath("/");
- ServiceProperties properties;
+ PerfsonarProperties properties;
// Loading the servlet properties
ServletProperties servletProperties = new
ServletPropertiesImpl(
servicePath + ServletPropertiesPath);
@@ -147,7 +156,8 @@

// Checking firstly if the files really exists
if ((new File(filePath)).exists()) {
- properties = new
ServicePropertiesImpl(filePath);
+ properties = new PerfsonarPropertiesImpl();
+ properties.loadProperties(new
FileInputStream(filePath));
session.setAttribute("properties",
properties);
}
// Other wise we have a problem
@@ -160,7 +170,8 @@
}
// Else get the properties from the session
else {
- properties = (ServiceProperties)
session.getAttribute("properties");
+ properties = (PerfsonarProperties) session
+ .getAttribute("properties");
}

// If the user wants to lock the table then authenticated is
false
@@ -217,21 +228,23 @@
&& ((Boolean)
session.getAttribute("authenticated"))
.booleanValue()) {
Enumeration parameters = request.getParameterNames();
- Properties newProperties = new Properties();

// Creating the new Properties object
while (parameters.hasMoreElements()) {
- String property = (String)
parameters.nextElement();
- String value = (String)
request.getParameter(property);
- if (!property.equals("store")) {
- newProperties.put(property, value);
+ String key = (String)
parameters.nextElement();
+ String value = (String)
request.getParameter(key);
+ if (!key.equals("store")) {
+ PerfsonarProperty property =
properties.getProperty(key);
+ if (property != null) {
+ property.setValue(value);
+ properties.setProperty(key,
property);
+ }
}
}
if (properties != null) {
// Setting the new properties
- properties.setProperties(newProperties);
// Modifying file
- if (modifyFile(properties)) {
+ if (modifyFile(properties, filePath)) {
// clearing up session and
ivalidating it
session.setAttribute("authenticated",
false);
session.removeAttribute("properties");
@@ -258,19 +271,20 @@
// In this case the user wants to add a new
property
if ((request.getParameter("add") != null)) {
// Stroring the new property to
properties
- properties.setProperty(
-
request.getParameter("propertyName"), request
-
.getParameter("propertyValue"));
+ PerfsonarProperty property = new
PerfsonarProperty(request
+
.getParameter("propertyName"), request
+
.getParameter("propertyValue"), "", "");
+
properties.setProperty(property.getKey(), property);
}
// Te user wants to remove a property
if ((request.getParameter("remove") != null))
{
// Removing property from properties
- properties.getProperties().remove(
-
request.getParameter("property"));
+
properties.removeProperty(request.getParameter("property"));
}
// Showing the properties and user options
if (properties != null) {
- main_page(out, properties, lock);
+
+ main_page(out,
groupProperies(properties), lock);
} else {
String path;
if (Type.equals("loggingProperties"))
{
@@ -289,6 +303,56 @@
// private methods

/**
+ * @param properties
+ * @return
+ */
+ private Hashtable<String, PerfsonarProperties> groupProperies(
+ PerfsonarProperties properties) {
+
+ // Check to see if any property was actually loaded
+ if (!properties.isEmpty()) {
+
+ // Creating new hashtable
+ Hashtable<String, PerfsonarProperties> groupTable =
new Hashtable<String, PerfsonarProperties>();
+ Iterator it = properties.getKeysIterator();
+ // Iterating through the properties so that we can
divide them into
+ // groups
+ while (it.hasNext()) {
+ // Get the property
+ PerfsonarProperty property =
properties.getProperty((String) it
+ .next());
+ // If the property group has not been set
then it is placed in a
+ // generic "Other" group
+ if (property.getGroup() == null) {
+
+ if (!groupTable.containsKey("Other"))
{
+
+ groupTable.put("Other", new
PerfsonarPropertiesImpl());
+ }
+
+ ((PerfsonarProperties)
groupTable.get("Other"))
+
.setProperty(property.getKey(), property);
+ } else {
+ // If the property group does not
exist as a key yet, we
+ // create a new key(group)
value(WizardProperties) pair
+ if
(!groupTable.containsKey(property.getGroup())) {
+
groupTable.put(property.getGroup(),
+ new
PerfsonarPropertiesImpl());
+ }
+ // We add the property to the
WizardProperties of that group
+ ((PerfsonarProperties)
groupTable.get(property.getGroup()))
+
.setProperty(property.getKey(), property);
+ }
+
+ }
+ return groupTable;
+
+ } else {
+ return null;
+ }
+ }
+
+ /**
* Method for sending back a http request requesting authentication
*
* @param response
@@ -358,31 +422,40 @@
}

private void main_page(ServletOutputStream out,
- ServiceProperties properties, String lock) throws
IOException {
+ Hashtable<String, PerfsonarProperties>
groupedProperties,
+ String lock) throws IOException {

preempt(out);
out.println("<div class=\"tablessContent\" >");
- out.println("<br/><p> </p>");
out.println("</div>");
out.println("<div class=\"manage\">");
out
- .println("<h3>perfSONAR service properties
Administration page</h3>");
- out.println("<h4>Service Properties Table</h4>");
+ .println("<h4>perfSONAR service properties
Administration page</h4><br/>");
+
// Different output depending on the user unlocking or
locking the table
if (!lock.equals("enabled")) {
+
out.println("<form action=\"ServiceAdmin\"
method=\"POST\"> ");
+ out.println("<table>");
+ out.println("<tr>");
out
- .println("<p><input type=\"submit\"
name=\"enable\" value=\"Unlock\"/ > Enter username and password to
unlock</p>");
+ .println("<th>Service Properties
Table</th><td><input type=\"submit\" name=\"enable\" value=\"Unlock\"/ >
Enter username and password to unlock</td>");
+ out.println("</tr>");
+ out.println("</table>");
out.println("</form>");
} else {
-
- out.println("<h3>");
- out
- .println("Edit the right column of
the Service Properties Table and then press 'Apply'");
- out.println("</h3>");
out.println("<form action=\"ServiceAdmin\"
method=\"POST\"> ");
+ out.println("<table>");
+ out.println("<tr>");
out
- .println("<p><input type=\"submit\"
name=\"Lock\" value=\"Lock\"/ ></p>");
+ .println("<th>Service Properties
Table</th><td><input type=\"submit\" name=\"Lock\" value=\"Lock\"/
></td><td/>");
+ out.println("</tr>");
+ out.println("<tr/>");
+ out.println("<tr>");
+ out
+ .println("<th>Edit the right column
of the Service Properties Table and then press 'Apply'</th><td/><td/>");
+ out.println("</tr>");
+ out.println("</table>");
out.println("</form>");

}
@@ -391,37 +464,85 @@
if (lock.equals("enabled")) {
out.println("<form action=\"ServiceAdmin\"
method=\"POST\"> ");
}
+
out.println("<table>");
out.println("<tr>");
- out.println("<td><b>Service Property</b></td>");
- out.println("<td><b>Service Property Value</b><td>");
+ out.println("<th>Group</th>");
+ out.println("<th>Service Property</th>");
+ out.println("<th>Service Property Value</th>");
out.println("</tr>");
+ out.println("<tr/>");

// Populating the table
- Enumeration en = properties.getProperties().keys();
- while (en.hasMoreElements()) {
- String property = (String) en.nextElement();
+ Iterator it = groupedProperties.keySet().iterator();
+ while (it.hasNext()) {
+ String group = (String) it.next();
+ PerfsonarProperties properties =
groupedProperties.get(group);
+ Iterator propIt = properties.getKeysIterator();
+
+ String key = (String) propIt.next();
+ PerfsonarProperty property =
properties.getProperty(key);
out.println("<tr>");
- out.println("<td>");
- out.println(property);
+ out.println("<th>" + group + "</th><td/><td/>");
+ out.println("</tr>");
+ out.println("<tr>");
+ out.println("<th/>");
+ group=group.replace("'", "\\'");
+ group=group.replace("(", "[").replace(")", "]");
+ String
description=property.getDescription().replace("'", "\\'");
+ description=description.replace(")", "]");
+ description=description.replace("(", "[");
+ description=description.replace("#", "");
+ out.println("<td onmouseover=\"setTip('" + group +
"','"
+ + description + "')\" >");
+ out.println(property.getKey());
out.println("</td>");
out.println("<td>");
- out.println("<input " + lock + " type=\"text\"
size=80 name=\""
- + property + "\" value=\""
- + (String)
properties.getProperty(property) + "\" />");
+ out.println("<input " + lock + " type=\"text\"
size=70 name=\""
+ + property.getKey() + "\" value=\"" +
property.getValue()
+ + "\" />");
out.println();
out.println("</td>");
out.println("</tr>");
+
+ while (propIt.hasNext()) {
+ key = (String) propIt.next();
+ property = properties.getProperty(key);
+
description=property.getDescription().replace("'", "\\'");
+ description=description.replace(")", "]");
+ description=description.replace("(", "[");
+ description=description.replace("#", "");
+ out.println("<tr>");
+ out.println("<td/>");
+ out.println("<td onmouseover=\"setTip('" +
group+ "','"
+ + description + "')\">");
+ out.println(property.getKey());
+ out.println("</td>");
+ out.println("<td>");
+ out.println("<input " + lock
+ + " type=\"text\" size=70
name=\"" + property.getKey()
+ + "\" value=\"" +
property.getValue() + "\" />");
+ out.println();
+ out.println("</td>");
+ out.println("</tr>");
+ }
}
- out.println("</table>");

if (lock.equals("enabled")) {
- out.println("<p><input " + lock
- + " type=\"submit\" name=\"store\"
value=\"Apply\" /> ");
+ out.println("<tr/>");
+ out.println("<tr>");
+ out.println("<td>");
+ out
+ .println("<input "
+ + lock
+ + " type=\"submit\"
name=\"store\" value=\"Apply\" /></td><td><input type=\"reset\"
value=\"Cancel\" /></td><td/>");
+ out.println("</tr>");
+ out.println("</table>");
out.println("</form>");
- out.println("<input type=\"reset\" value=\"Cancel\"
/> ");
+ } else {
+ out.println("</table>");
}
- out.println("</p>");
+
if (lock.equals("enabled") &&
extraFunctionalities.equals("on")) {
// Options foa adding and deleting a property are
added

@@ -439,7 +560,7 @@
.println("<input type=\"text\"
size=60 name=\"propertyName\" value=\" \" />");
out.println("</td><td>");
out
- .println("<input type=\"text\"
name=\"propertyValue\" size=80 value=\" \" />");
+ .println("<input type=\"text\"
name=\"propertyValue\" size=70 value=\" \" />");
out.println("</td>");
out.println("</tr>");
out.println("</table>");
@@ -452,11 +573,18 @@
out.println("<form action=\"ServiceAdmin\"
method=\"POST\"> ");
out.println("<p>");
out.println("<select name=\"property\">");
- en = properties.getProperties().keys();
- while (en.hasMoreElements()) {
- String property = (String) en.nextElement();
- out.println("<option value=\"" + property +
"\">" + property
- + "</option>");
+ it = groupedProperties.keySet().iterator();
+ while (it.hasNext()) {
+ String group = (String) it.next();
+ PerfsonarProperties pr =
groupedProperties.get(group);
+ out.println("<optgroup label=\"" + group +
"\" >");
+ Iterator propIt = pr.getKeysIterator();
+ while (propIt.hasNext()) {
+ String property = (String) it.next();
+ out.println("<option value=\"" +
property + "\">"
+ + property +
"</option>");
+ }
+ out.println("</optgroup>");
}
out.println("</select>");
out
@@ -481,6 +609,18 @@
out.println("</title>");
out.println("</head>");
out.println("<body>");
+ out.println("<script src=\"Service_Admin.js\">\n" +
"</script>\n");
+ out.println("<script src=\"wz_tooltip.js\">\n" +
"</script>\n");
+ out.println("<div style=\"display:none;\" id=\"tooltip\"
>");
+ out.println("<table>");
+ out.println("<tr style=\"text-align: left ;\">");
+ out.println("<th>Group:</th><td id=\"groupName\"></td>");
+ out.println("</tr>");
+ out.println("<tr>");
+ out.println("<th>Description:</th><td
id=\"description\"></td>");
+ out.println("<tr>");
+ out.println("</table>");
+ out.println("</div>");
}

/**
@@ -490,10 +630,11 @@
* The properties to be stored object
* @return True if successful false if something went wrong
*/
- private synchronized boolean modifyFile(ServiceProperties properties)
{
+ private synchronized boolean modifyFile(PerfsonarProperties
properties,
+ String filePath) {

try {
- properties.storeProperties();
+ properties.storeProperties(new
FileOutputStream(filePath));
return true;
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block

Added: branches/WebAdmin/perfSONARWebAdmin/admin/sqlma/TestAdmin.java


Property changes on:
branches/WebAdmin/perfSONARWebAdmin/admin/sqlma/TestAdmin.java
___________________________________________________________________
Name: svn:keywords
+ Author Date Id Revision
Name: svn:eol-style
+ native

Modified: branches/WebAdmin/perfSONARWebAdmin/admin/wizard/services/RRDMA.java
===================================================================
--- branches/WebAdmin/perfSONARWebAdmin/admin/wizard/services/RRDMA.java
2008-02-26 11:06:19 UTC (rev 3408)
+++ branches/WebAdmin/perfSONARWebAdmin/admin/wizard/services/RRDMA.java
2008-02-26 12:25:14 UTC (rev 3409)
@@ -3,11 +3,9 @@
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
-import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
-import java.util.Calendar;
import java.util.Hashtable;
import java.util.Iterator;

@@ -43,14 +41,17 @@
private static final String LoggingPropertiesPath = confPath
+ "log4j.properties";

+ @SuppressWarnings("unused")
private static final String ComponentsPropertiesPath = confPath
+ "components.properties";

private static final String ObjectsConfigPath = confPath +
"objects.config";

+ @SuppressWarnings("unused")
private static final String WizardPropertiesPath = confPath
+ "wizard.properties";

+ @SuppressWarnings("unused")
private static final String ServletPropertiesPath = confPath
+ "servlet.properties";


Added: branches/WebAdmin/perfSONARWebAdmin/auxiliary/PerfsonarProperties.java


Property changes on:
branches/WebAdmin/perfSONARWebAdmin/auxiliary/PerfsonarProperties.java
___________________________________________________________________
Name: svn:keywords
+ Author Date Id Revision
Name: svn:eol-style
+ native

Added:
branches/WebAdmin/perfSONARWebAdmin/auxiliary/PerfsonarPropertiesImpl.java


Property changes on:
branches/WebAdmin/perfSONARWebAdmin/auxiliary/PerfsonarPropertiesImpl.java
___________________________________________________________________
Name: svn:keywords
+ Author Date Id Revision
Name: svn:eol-style
+ native

Added: branches/WebAdmin/perfSONARWebAdmin/auxiliary/PerfsonarProperty.java


Property changes on:
branches/WebAdmin/perfSONARWebAdmin/auxiliary/PerfsonarProperty.java
___________________________________________________________________
Name: svn:keywords
+ Author Date Id Revision
Name: svn:eol-style
+ native

Modified: branches/WebAdmin/perfSONARWebAdmin/test/Tester.java
===================================================================
--- branches/WebAdmin/perfSONARWebAdmin/test/Tester.java 2008-02-26
11:06:19 UTC (rev 3408)
+++ branches/WebAdmin/perfSONARWebAdmin/test/Tester.java 2008-02-26
12:25:14 UTC (rev 3409)
@@ -12,7 +12,7 @@
public static void main(String[] args) throws UnknownHostException,
IOException {

- Enumeration<NetworkInterface> e = NetworkInterface
+ /* Enumeration<NetworkInterface> e = NetworkInterface
.getNetworkInterfaces();
while (e.hasMoreElements()) {
NetworkInterface netface = (NetworkInterface)
e.nextElement();
@@ -26,21 +26,19 @@
if(!ip.getHostAddress().contains(":")){

System.out.println(ip.getHostAddress());
}
- /*String[] pieces =
ip.getHostAddress().split(":");
- if (pieces.length == 2) {
- String location = ip.getHostAddress();
- System.out.println("Real address: " +
location);
- }*/
+
}

// }

- }
+ }

Socket local = new Socket("localhost", 8080);
InetAddress address = local.getLocalAddress();
System.out.println(address.getHostAddress());
- local.close();
+ local.close();
+ */
+ System.out.println("Adminitrator's password of xml db
eXist((()".replace("(","["));

}


Added: branches/WebAdmin/tip_balloon/Thumbs.db


Property changes on: branches/WebAdmin/tip_balloon/Thumbs.db
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream

Added: branches/WebAdmin/tip_balloon/b.gif


Property changes on: branches/WebAdmin/tip_balloon/b.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream

Added: branches/WebAdmin/tip_balloon/background.gif


Property changes on: branches/WebAdmin/tip_balloon/background.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream

Added: branches/WebAdmin/tip_balloon/l.gif


Property changes on: branches/WebAdmin/tip_balloon/l.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream

Added: branches/WebAdmin/tip_balloon/lb.gif


Property changes on: branches/WebAdmin/tip_balloon/lb.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream

Added: branches/WebAdmin/tip_balloon/lt.gif


Property changes on: branches/WebAdmin/tip_balloon/lt.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream

Added: branches/WebAdmin/tip_balloon/r.gif


Property changes on: branches/WebAdmin/tip_balloon/r.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream

Added: branches/WebAdmin/tip_balloon/rb.gif


Property changes on: branches/WebAdmin/tip_balloon/rb.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream

Added: branches/WebAdmin/tip_balloon/rt.gif


Property changes on: branches/WebAdmin/tip_balloon/rt.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream

Added: branches/WebAdmin/tip_balloon/stemb.gif


Property changes on: branches/WebAdmin/tip_balloon/stemb.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream

Added: branches/WebAdmin/tip_balloon/stemt.gif


Property changes on: branches/WebAdmin/tip_balloon/stemt.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream

Added: branches/WebAdmin/tip_balloon/t.gif


Property changes on: branches/WebAdmin/tip_balloon/t.gif
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream

Added: branches/WebAdmin/tip_balloon.js

Added: branches/WebAdmin/tip_centerwindow.js

Added: branches/WebAdmin/tip_followscroll.js

Added: branches/WebAdmin/wz_tooltip.js



  • perfsonar: r3409 - in branches/WebAdmin: . perfSONARWebAdmin/admin/service perfSONARWebAdmin/admin/sqlma perfSONARWebAdmin/admin/wizard/services perfSONARWebAdmin/auxiliary perfSONARWebAdmin/test tip_balloon, svnlog, 02/26/2008

Archive powered by MHonArc 2.6.16.

Top of Page