server-db-stats.jsp 20.1 KB
Newer Older
1
<%--
2 3
  -	$Revision: 10204 $
  -	$Date: 2008-04-11 18:44:25 -0400 (Fri, 11 Apr 2008) $
4
  -
5 6
  - Copyright (C) 2004-2008 Jive Software. All rights reserved.
  -
7 8 9 10 11 12 13 14 15 16 17
  - Licensed under the Apache License, Version 2.0 (the "License");
  - you may not use this file except in compliance with the License.
  - You may obtain a copy of the License at
  -
  -     http://www.apache.org/licenses/LICENSE-2.0
  -
  - Unless required by applicable law or agreed to in writing, software
  - distributed under the License is distributed on an "AS IS" BASIS,
  - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  - See the License for the specific language governing permissions and
  - limitations under the License.
18 19 20 21 22 23 24 25 26 27 28 29
--%>

<%@ page import="java.text.*"
    errorPage="error.jsp"
%>
<%@ page import="org.jivesoftware.database.DbConnectionManager"%>
<%@ page import="org.jivesoftware.util.JiveGlobals"%>
<%@ page import="org.jivesoftware.database.ProfiledConnection"%>
<%@ page import="org.jivesoftware.database.ProfiledConnectionEntry"%>
<%@ page import="org.jivesoftware.util.ParamUtils"%>
<%@ page import="org.jivesoftware.util.LocaleUtils"%>

30 31
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
32

33 34 35
<jsp:useBean id="webManager" class="org.jivesoftware.util.WebManager"  />
<% webManager.init(request, response, session, application, out ); %>

36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
<%! // Global methods, vars

    // Default refresh values
    static final int[] REFRESHES = {10,30,60,90};
%>

<%
    // Get parameters
    boolean doClear = request.getParameter("doClear") != null;
    String enableStats = ParamUtils.getParameter(request,"enableStats");
    int refresh = ParamUtils.getIntParameter(request,"refresh", -1);
    boolean doSortByTime = ParamUtils.getBooleanParameter(request,"doSortByTime");

    // Var for the alternating colors
    int rowColor = 0;

    // Clear the statistics
    if (doClear) {
        ProfiledConnection.resetStatistics();
        // Reload the page without params.
Matt Tucker's avatar
Matt Tucker committed
56
        response.sendRedirect("server-db-stats.jsp");
57 58 59
    }

    // Enable/disable stats
60
    if ("true".equals(enableStats) && ! DbConnectionManager.isProfilingEnabled()) {
61
        DbConnectionManager.setProfilingEnabled(true);
62 63
        // Log the event
        webManager.logEvent("enabled db profiling", null);
64
    }
65
    else if ("false".equals(enableStats) && DbConnectionManager.isProfilingEnabled()) {
66
        DbConnectionManager.setProfilingEnabled(false);
67 68
        // Log the event
        webManager.logEvent("disabled db profiling", null);
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
    }

    boolean showQueryStats = DbConnectionManager.isProfilingEnabled();

    // Number intFormat for pretty printing of large number values and decimals:
    NumberFormat intFormat = NumberFormat.getInstance(JiveGlobals.getLocale());
    DecimalFormat decFormat = new DecimalFormat("#,##0.00");
%>

<html>
    <head>
        <title><fmt:message key="server.db_stats.title" /></title>
        <meta name="pageID" content="server-db"/>
    <%  // Enable refreshing if specified
        if (refresh >= 10) {
    %>
        <meta http-equiv="refresh" content="<%= refresh %>;URL=server-db-stats.jsp?refresh=<%= refresh %>">

    <%  } %>
</head>
<body>

<p>
<fmt:message key="server.db_stats.description" />
</p>

95 96 97 98 99



<div class="jive-contentBox jive-contentBoxGrey" style="width: 732px;">
<h3><fmt:message key="server.db_stats.status" /></h3>
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121

<form action="server-db-stats.jsp">
    <table cellpadding="3" cellspacing="1" border="0">
    <tr>
        <td>
            <input type="radio" name="enableStats" value="true" id="rb01" <%= ((showQueryStats) ? "checked":"") %>>
            <label for="rb01"><%= ((showQueryStats) ? "<b>" +
                    LocaleUtils.getLocalizedString("server.db_stats.enabled") + "</b>": LocaleUtils.getLocalizedString("server.db_stats.enabled")) %></label>
        </td>
        <td>
            <input type="radio" name="enableStats" value="false" id="rb02" <%= ((!showQueryStats) ? "checked":"") %>>
            <label for="rb02"><%= ((!showQueryStats) ? "<b>" +
                     LocaleUtils.getLocalizedString("server.db_stats.disabled") + "</b>":  LocaleUtils.getLocalizedString("server.db_stats.disabled")) %></label>
        </td>
        <td>
            <input type="submit" name="" value="<fmt:message key="server.db_stats.update" />">
        </td>
    </tr>
    </table>
</form>

<%  if (showQueryStats) { %>
122 123
	<br>
	<h3><fmt:message key="server.db_stats.settings" /></h3>
124 125

    <form action="server-db-stats.jsp">
126
        <table cellpadding="3" cellspacing="5" border="0">
127 128 129 130 131 132
        <tr>
            <td>
                <fmt:message key="server.db_stats.refresh" />:
                <select size="1" name="refresh" onchange="this.form.submit();">
                <option value="none"><fmt:message key="server.db_stats.none" />

133 134
                <%  for(int aREFRESHES: REFRESHES){
                        String selected = ((aREFRESHES == refresh) ? " selected" : "");
135
                %>
136 137 138
                    <option value="<%= aREFRESHES %>"<%= selected %>
                     ><%= aREFRESHES
                            %> <fmt:message key="server.db_stats.seconds" />
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157

                <%  } %>
                </select>
            </td>
            <td>
                <input type="submit" name="" value="<fmt:message key="server.db_stats.set" />">
            </td>
            <td>|</td>
            <td>
                <input type="submit" name="" value="<fmt:message key="server.db_stats.update" />">
            </td>
            <td>|</td>
            <td>
                <input type="submit" name="doClear" value="<fmt:message key="server.db_stats.clear_stats" />">
            </td>
        </tr>
        </table>
    </form>

158
</div>
159 160


161
    <b><fmt:message key="server.db_stats.select_stats" /></b>
162

163
    <ul>
164

165
    <table bgcolor="#aaaaaa" cellpadding="0" cellspacing="0" border="0" width="600">
166 167 168 169
    <tr><td>
    <table bgcolor="#aaaaaa" cellpadding="3" cellspacing="1" border="0" width="100%">
    <tr bgcolor="#ffffff">
        <td><fmt:message key="server.db_stats.operations" /></td>
170
        <td><%= intFormat.format(ProfiledConnection.getQueryCount(ProfiledConnection.Type.select)) %></td>
171 172 173
    </tr>
    <tr bgcolor="#ffffff">
        <td><fmt:message key="server.db_stats.total_time" /></td>
174
        <td><%= intFormat.format(ProfiledConnection.getTotalQueryTime(ProfiledConnection.Type.select)) %></td>
175 176 177
    </tr>
    <tr bgcolor="#ffffff">
        <td><fmt:message key="server.db_stats.avg_rate" /></td>
178
        <td><%= decFormat.format(ProfiledConnection.getAverageQueryTime(ProfiledConnection.Type.select)) %></td>
179 180 181
    </tr>
    <tr bgcolor="#ffffff">
        <td><fmt:message key="server.db_stats.total_rate" /></td>
182
        <td><%= decFormat.format(ProfiledConnection.getQueriesPerSecond(ProfiledConnection.Type.select)) %></td>
183 184 185 186
    </tr>
    <tr bgcolor="#ffffff">
        <td><fmt:message key="server.db_stats.queries" /></td>
        <td bgcolor="#ffffff"><%
187
                    ProfiledConnectionEntry[] list = ProfiledConnection.getSortedQueries(ProfiledConnection.Type.select, doSortByTime);
188 189 190 191 192 193 194 195 196 197 198 199 200 201

                    if (list == null || list.length < 1) {
                        out.println(LocaleUtils.getLocalizedString("server.db_stats.no_queries"));
                    }
                    else { %>
                &nbsp;
         </td>
    </tr>
    </table>
    </td></tr>
    </table>

    <br />

202
    <table bgcolor="#aaaaaa" cellpadding="0" cellspacing="0" border="0" width="600">
203 204 205
    <tr><td>
    <table bgcolor="#aaaaaa" cellpadding="3" cellspacing="0" border="0" width="100%">
    <tr bgcolor="#ffffff"><td>
206
    <%      out.println("<table width=\"100%\" cellpadding=\"3\" cellspacing=\"1\" border=\"0\" bgcolor=\"#aaaaaa\"><tr><td bgcolor=\"#ffffff\" align=\"left\"><b>" + LocaleUtils.getLocalizedString("server.db_stats.query") + "</b></td>");
Matt Tucker's avatar
Matt Tucker committed
207
            out.println("<td bgcolor=\"#ffffff\"><b><a href=\"javascript:location.href='server-db-stats.jsp?doSortByTime=false&refresh=" + refresh + ";'\">" + LocaleUtils.getLocalizedString("server.db_stats.count") + "</a></b></td>");
208
            out.println("<td nowrap bgcolor=\"#ffffff\"><b>" + LocaleUtils.getLocalizedString("server.db_stats.time") + "</b></td>");
Matt Tucker's avatar
Matt Tucker committed
209
            out.println("<td nowrap bgcolor=\"#ffffff\"><b><a href=\"javascript:location.href='server-db-stats.jsp?doSortByTime=true&refresh=" + refresh + ";'\">" + LocaleUtils.getLocalizedString("server.db_stats.average_time") + "</a></b></td></tr>");
210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225

            for (int i = 0; i < ((list.length > 20) ? 20 : list.length); i++) {
                ProfiledConnectionEntry pce = list[i];
                out.println("<tr><td bgcolor=\"" + ((rowColor%2 == 0) ? "#efefef" : "#ffffff") + "\">" + pce.sql + "</td>");
                out.println("<td bgcolor=\"" + ((rowColor%2 == 0) ? "#efefef" : "#ffffff") + "\">" + intFormat.format(pce.count) + "</td>");
                out.println("<td bgcolor=\"" + ((rowColor%2 == 0) ? "#efefef" : "#ffffff") + "\">" + intFormat.format(pce.totalTime) + "</td>");
                out.println("<td bgcolor=\"" + ((rowColor++%2 == 0) ? "#efefef" : "#ffffff") + "\">" + intFormat.format(pce.totalTime/pce.count) + "</td></tr>");
            }
            out.println("</table>");
        }
     %></td>
    </tr>
    </table>
    </td></tr>
    </table>

226
    </ul>
227 228 229 230 231 232 233 234 235 236

    <b><fmt:message key="server.db_stats.insert_stats" /></b>

    <ul>

    <table bgcolor="#aaaaaa" cellpadding="0" cellspacing="0" border="0" width="600">
    <tr><td>
    <table bgcolor="#aaaaaa" cellpadding="3" cellspacing="1" border="0" width="100%">
    <tr bgcolor="#ffffff">
        <td><fmt:message key="server.db_stats.operations" /></td>
237
        <td><%= intFormat.format(ProfiledConnection.getQueryCount(ProfiledConnection.Type.insert)) %></td>
238 239 240
    </tr>
    <tr bgcolor="#ffffff">
        <td><fmt:message key="server.db_stats.total_time" /></td>
241
        <td><%= intFormat.format(ProfiledConnection.getTotalQueryTime(ProfiledConnection.Type.insert)) %></td>
242 243 244
    </tr>
    <tr bgcolor="#ffffff">
        <td><fmt:message key="server.db_stats.avg_rate" /></td>
245
        <td><%= decFormat.format(ProfiledConnection.getAverageQueryTime(ProfiledConnection.Type.insert)) %></td>
246 247 248
    </tr>
    <tr bgcolor="#ffffff">
        <td><fmt:message key="server.db_stats.total_rate" /></td>
249
        <td><%= decFormat.format(ProfiledConnection.getQueriesPerSecond(ProfiledConnection.Type.insert)) %></td>
250 251 252 253
    </tr>
    <tr bgcolor="#ffffff">
        <td><fmt:message key="server.db_stats.queries" /></td>
        <td bgcolor="#ffffff"><%
254
                    list = ProfiledConnection.getSortedQueries(ProfiledConnection.Type.insert, doSortByTime);
255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273

                    if (list == null || list.length < 1) {
                        out.println(LocaleUtils.getLocalizedString("server.db_stats.no_queries"));
                    }
                    else { %>
                &nbsp;
         </td>
    </tr>
    </table>
    </td></tr>
    </table>

    <br />

    <table bgcolor="#aaaaaa" cellpadding="0" cellspacing="0" border="0" width="600">
    <tr><td>
    <table bgcolor="#aaaaaa" cellpadding="3" cellspacing="0" border="0" width="100%">
    <tr bgcolor="#ffffff"><td>
    <%      out.println("<table width=\"100%\" cellpadding=\"3\" cellspacing=\"1\" border=\"0\" bgcolor=\"#aaaaaa\"><tr><td bgcolor=\"#ffffff\" align=\"middle\"><b>" + LocaleUtils.getLocalizedString("server.db_stats.query") + "</b></td>");
Matt Tucker's avatar
Matt Tucker committed
274
            out.println("<td bgcolor=\"#ffffff\"><b><a href=\"javascript:location.href='server-db-stats.jsp?doSortByTime=false&refresh=" + refresh + ";'\">" + LocaleUtils.getLocalizedString("server.db_stats.count") + "</a></b></td>");
275
            out.println("<td nowrap bgcolor=\"#ffffff\"><b>" + LocaleUtils.getLocalizedString("server.db_stats.time") + "</b></td>");
Matt Tucker's avatar
Matt Tucker committed
276
            out.println("<td nowrap bgcolor=\"#ffffff\"><b><a href=\"javascript:location.href='server-db-stats.jsp?doSortByTime=true&refresh=" + refresh + ";'\">" + LocaleUtils.getLocalizedString("server.db_stats.average_time") + "</a></b></td></tr>");
277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303

            for (int i = 0; i < ((list.length > 10) ? 10 : list.length); i++) {
                ProfiledConnectionEntry pce = list[i];
                out.println("<tr><td bgcolor=\"" + ((rowColor%2 == 0) ? "#efefef" : "#ffffff") + "\">" + pce.sql + "</td>");
                out.println("<td bgcolor=\"" + ((rowColor%2 == 0) ? "#efefef" : "#ffffff") + "\">" + intFormat.format(pce.count) + "</td>");
                out.println("<td bgcolor=\"" + ((rowColor%2 == 0) ? "#efefef" : "#ffffff") + "\">" + intFormat.format(pce.totalTime) + "</td>");
                out.println("<td bgcolor=\"" + ((rowColor++%2 == 0) ? "#efefef" : "#ffffff") + "\">" + intFormat.format(pce.totalTime/pce.count) + "</td></tr>");
            }
            out.println("</table>");
        }
     %></td>
    </tr>
    </table>
    </td></tr>
    </table>

    </ul>

    <b><fmt:message key="server.db_stats.update_stats" /></b>

    <ul>

    <table bgcolor="#aaaaaa" cellpadding="0" cellspacing="0" border="0" width="600">
    <tr><td>
    <table bgcolor="#aaaaaa" cellpadding="3" cellspacing="1" border="0" width="100%">
    <tr bgcolor="#ffffff">
        <td><fmt:message key="server.db_stats.operations" /></td>
304
        <td><%= intFormat.format(ProfiledConnection.getQueryCount(ProfiledConnection.Type.update)) %></td>
305 306 307
    </tr>
    <tr bgcolor="#ffffff">
        <td><fmt:message key="server.db_stats.total_time" /></td>
308
        <td><%= intFormat.format(ProfiledConnection.getTotalQueryTime(ProfiledConnection.Type.update)) %></td>
309 310 311
    </tr>
    <tr bgcolor="#ffffff">
        <td><fmt:message key="server.db_stats.avg_rate" /></td>
312
        <td><%= decFormat.format(ProfiledConnection.getAverageQueryTime(ProfiledConnection.Type.update)) %></td>
313 314 315
    </tr>
    <tr bgcolor="#ffffff">
        <td><fmt:message key="server.db_stats.total_rate" /></td>
316
        <td><%= decFormat.format(ProfiledConnection.getQueriesPerSecond(ProfiledConnection.Type.update)) %></td>
317 318 319 320
    </tr>
    <tr bgcolor="#ffffff">
        <td><fmt:message key="server.db_stats.queries" /></td>
        <td bgcolor="#ffffff"><%
321
                    list = ProfiledConnection.getSortedQueries(ProfiledConnection.Type.update, doSortByTime);
322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340

                    if (list == null || list.length < 1) {
                        out.println(LocaleUtils.getLocalizedString("server.db_stats.no_queries"));
                    }
                    else { %>
                &nbsp;
         </td>
    </tr>
    </table>
    </td></tr>
    </table>

    <br />

    <table bgcolor="#aaaaaa" cellpadding="0" cellspacing="0" border="0" width="600">
    <tr><td>
    <table bgcolor="#aaaaaa" cellpadding="3" cellspacing="0" border="0" width="100%">
    <tr bgcolor="#ffffff"><td>
    <%      out.println("<table width=\"100%\" cellpadding=\"3\" cellspacing=\"1\" border=\"0\" bgcolor=\"#aaaaaa\"><tr><td bgcolor=\"#ffffff\" align=\"middle\"><b>" + LocaleUtils.getLocalizedString("server.db_stats.query") + "</b></td>");
Matt Tucker's avatar
Matt Tucker committed
341
            out.println("<td bgcolor=\"#ffffff\"><b><a href=\"javascript:location.href='server-db-stats.jsp?doSortByTime=false&refresh=" + refresh + ";'\">" + LocaleUtils.getLocalizedString("server.db_stats.count") + "</a></b></td>");
342
            out.println("<td nowrap bgcolor=\"#ffffff\"><b>" + LocaleUtils.getLocalizedString("server.db_stats.time") + "</b></td>");
Matt Tucker's avatar
Matt Tucker committed
343
            out.println("<td nowrap bgcolor=\"#ffffff\"><b><a href=\"javascript:location.href='server-db-stats.jsp?doSortByTime=true&refresh=" + refresh + ";'\">" + LocaleUtils.getLocalizedString("server.db_stats.average_time") + "</a></b></td></tr>");
344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370

            for (int i = 0; i < ((list.length > 10) ? 10 : list.length); i++) {
                ProfiledConnectionEntry pce = list[i];
                out.println("<tr><td bgcolor=\"" + ((rowColor%2 == 0) ? "#efefef" : "#ffffff") + "\">" + pce.sql + "</td>");
                out.println("<td bgcolor=\"" + ((rowColor%2 == 0) ? "#efefef" : "#ffffff") + "\">" + intFormat.format(pce.count) + "</td>");
                out.println("<td bgcolor=\"" + ((rowColor%2 == 0) ? "#efefef" : "#ffffff") + "\">" + intFormat.format(pce.totalTime) + "</td>");
                out.println("<td bgcolor=\"" + ((rowColor++%2 == 0) ? "#efefef" : "#ffffff") + "\">" + intFormat.format(pce.totalTime/pce.count) + "</td></tr>");
            }
            out.println("</table>");
        }
     %></td>
    </tr>
    </table>
    </td></tr>
    </table>

    </ul>

    <b><fmt:message key="server.db_stats.delete_stats" /></b>

    <ul>

    <table bgcolor="#aaaaaa" cellpadding="0" cellspacing="0" border="0" width="600">
    <tr><td>
    <table bgcolor="#aaaaaa" cellpadding="3" cellspacing="1" border="0" width="100%">
    <tr bgcolor="#ffffff">
        <td><fmt:message key="server.db_stats.operations" /></td>
371
        <td><%= intFormat.format(ProfiledConnection.getQueryCount(ProfiledConnection.Type.delete)) %></td>
372 373 374
    </tr>
    <tr bgcolor="#ffffff">
        <td><fmt:message key="server.db_stats.total_time" /></td>
375
        <td><%= intFormat.format(ProfiledConnection.getTotalQueryTime(ProfiledConnection.Type.delete)) %></td>
376 377 378
    </tr>
    <tr bgcolor="#ffffff">
        <td><fmt:message key="server.db_stats.avg_rate" /></td>
379
        <td><%= decFormat.format(ProfiledConnection.getAverageQueryTime(ProfiledConnection.Type.delete)) %></td>
380 381 382
    </tr>
    <tr bgcolor="#ffffff">
        <td><fmt:message key="server.db_stats.total_rate" /></td>
383
        <td><%= decFormat.format(ProfiledConnection.getQueriesPerSecond(ProfiledConnection.Type.delete)) %></td>
384 385 386 387
    </tr>
    <tr bgcolor="#ffffff">
        <td><fmt:message key="server.db_stats.queries" /></td>
        <td bgcolor="#ffffff"><%
388
                    list = ProfiledConnection.getSortedQueries(ProfiledConnection.Type.delete, doSortByTime);
389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407

                    if (list == null || list.length < 1) {
                        out.println(LocaleUtils.getLocalizedString("server.db_stats.no_queries"));
                    }
                    else { %>
                &nbsp;
         </td>
    </tr>
    </table>
    </td></tr>
    </table>

    <br />

    <table bgcolor="#aaaaaa" cellpadding="0" cellspacing="0" border="0" width="600">
    <tr><td>
    <table bgcolor="#aaaaaa" cellpadding="3" cellspacing="0" border="0" width="100%">
    <tr bgcolor="#ffffff"><td>
    <%      out.println("<table width=\"100%\" cellpadding=\"3\" cellspacing=\"1\" border=\"0\" bgcolor=\"#aaaaaa\"><tr><td bgcolor=\"#ffffff\" align=\"middle\"><b>" + LocaleUtils.getLocalizedString("server.db_stats.query") + "</b></td>");
Matt Tucker's avatar
Matt Tucker committed
408
            out.println("<td bgcolor=\"#ffffff\"><b><a href=\"javascript:location.href='server-db-stats.jsp?doSortByTime=false&refresh=" + refresh + ";'\">" + LocaleUtils.getLocalizedString("server.db_stats.count") + "</a></b></td>");
409
            out.println("<td nowrap bgcolor=\"#ffffff\"><b>" + LocaleUtils.getLocalizedString("server.db_stats.time") + "</b></td>");
Matt Tucker's avatar
Matt Tucker committed
410
            out.println("<td nowrap bgcolor=\"#ffffff\"><b><a href=\"javascript:location.href='server-db-stats.jsp?doSortByTime=true&refresh=" + refresh + ";'\">" + LocaleUtils.getLocalizedString("server.db_stats.average_time") + "</a></b></td></tr>");
411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431

            for (int i = 0; i < ((list.length > 10) ? 10 : list.length); i++) {
                ProfiledConnectionEntry pce = list[i];
                out.println("<tr><td bgcolor=\"" + ((rowColor%2 == 0) ? "#efefef" : "#ffffff") + "\">" + pce.sql + "</td>");
                out.println("<td bgcolor=\"" + ((rowColor%2 == 0) ? "#efefef" : "#ffffff") + "\">" + intFormat.format(pce.count) + "</td>");
                out.println("<td bgcolor=\"" + ((rowColor%2 == 0) ? "#efefef" : "#ffffff") + "\">" + intFormat.format(pce.totalTime) + "</td>");
                out.println("<td bgcolor=\"" + ((rowColor++%2 == 0) ? "#efefef" : "#ffffff") + "\">" + intFormat.format(pce.totalTime/pce.count) + "</td></tr>");
            }
            out.println("</table>");
        }
     %></td>
    </tr>
    </table>
    </td></tr>
    </table>

    </ul>

<% } %>


432
</body></html>