Subversion Repositories DevTools

Rev

Rev 6181 | Rev 6268 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
5670 dpurdie 1
<% @LANGUAGE = VBScript %>
5623 dpurdie 2
<%
3
'=====================================================
4
'
5
'  Build Status and Plan Information
6
'
7
'=====================================================
8
%>
9
<%
10
Option explicit
11
' Good idea to set when using redirect
12
Response.Expires = 0  ' always load the page, dont store
13
%>
14
<!--#include file="common/conf.asp"-->
15
<!--#include file="common/globals.asp"-->
16
<!--#include file="common/formating.asp"-->
17
<!--#include file="common/qstr.asp"-->
18
<!--#include file="common/common_subs.asp"-->
19
<!--#include file="common/_form_window_common.asp"-->
20
<!--#include file="_action_buttons.asp"-->
21
<!--#include file="class/classActionButtonControl.asp"-->
22
<!--#include file="common/daemon_instructions.asp"-->
6166 dpurdie 23
<!--#include file="common/common_daemon.asp"-->
6048 dpurdie 24
<% '------------ ACCESS CONTROL ------------------ %>
6181 dpurdie 25
<!--#include file="_access_control_login_optional.asp"-->
6070 dpurdie 26
<!--#include file="_access_control_general.asp"-->
6052 dpurdie 27
<!--#include file="_access_control_action_project.asp"-->
5623 dpurdie 28
<% '------------ Scripts -------------------------- %>
29
<%
30
'------------ Variable Definition -------------
31
Dim objSortHelper
32
Dim rsQry
33
Dim parRtagId
34
Dim query_string
35
Dim rcon_id
36
Dim rsQry2
37
'------------ Constants Declaration -----------
38
'------------ Variable Init -------------------
39
parRtagId = Request("rtag_id")
40
objPMod.PersistInQryString("rtag_id")
41
 
42
'----------------------------------------------
43
%>
44
<html>
45
   <head>
46
      <title>Release Manager</title>
47
      <link rel="shortcut icon" href="<%=FavIcon%>"/>
48
      <meta http-equiv="Pragma" content="no-cache">
49
      <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
50
      <link rel="stylesheet" href="images/release_manager_style.css" type="text/css">
51
      <link rel="stylesheet" href="images/navigation.css" type="text/css">
52
      <script language="JavaScript" src="images/common.js"></script>
53
      <!--#include file="_jquery_includes.asp"-->
54
      <!-- TIPS -->
55
      <script type="text/javascript" src="scripts/json2.js"></script>
56
      <script language="JavaScript" src="images/tipster.js"></script>
57
      <script language="JavaScript" src="images/_help_tips.js"></script>
58
      <script language="JavaScript" type="text/JavaScript">
59
      formTips.tips.h_buildplan       = stdTip(300, 'Build Plan', 'The build plan is a guess as to the order in which packages will be built.' +
60
                                                                  '<p>It will be recalculated before each build.' + 
61
                                                                  '<p>The plan includes test builds, new builds and resultant ripples.' 
62
                                                                  );
5670 dpurdie 63
      formTips.tips.h_buildDuration    = stdTip(300, 'Planned Duration', 'The build duration (seconds) of the last build of this package - if known.' +
5635 dpurdie 64
                                                                  '<p>This is used as a guess as to the duration of the planned build.' 
65
                                                                  );
5670 dpurdie 66
      formTips.tips.h_buildEnd         = stdTip(300, 'Planned Completion', 'An educated guess as to the build completion time of the package.' +
67
                                                                  '<p>It is based on the start time of the current build and the durations of each preceeding builds.' + 
68
                                                                  '<p>If the duration of a build is not known then a time of 300 seconds will be assumed.' +
69
                                                                  ' It also assumes 20 seconds to plan the next build.'
70
                                                                  );
5623 dpurdie 71
      formTips.tips.h_lastchange       = stdTip(300, 'Last Change', 'This is an indication of the time since the daemon interogated the database.' +
72
                                                                  '<p>Short times will be shown as seconds. Longer times will be shown as a time within ' + 
73
                                                                  'the last 24 hours. Longer times will be shown as a date.' 
74
                                                                  );
75
 
76
      </script>
77
      <!-- DROPDOWN MENUS -->
78
      <!--#include file="_menu_def.asp"-->
79
      <script language="JavaScript1.2" src="images/popup_menu.js"></script>
80
   </head>
81
   <body bgcolor="#FFFFFF" text="#000000" leftmargin="0" topmargin="0" >
82
      <!-- HEADER -->
83
      <!--#include file="_header.asp"-->
84
      <!-- BODY ---->
85
      <table width="100%" border="0" cellspacing="0" cellpadding="0">
86
         <tr>
6175 dpurdie 87
            <td width="146px" class="panel_bg" valign="top"><%Call BuildMenuPane%></td>
5623 dpurdie 88
            <td width="100%" rowspan="2" align="center" valign="top" bgcolor="#EEEFEF">
89
               <table width="10" border="0" cellspacing="0" cellpadding="0">
90
                  <tr>
91
                     <td width="1%"></td>
92
                     <td width="100%">
93
                        <table width="100%" border="0" cellspacing="0" cellpadding="0">
94
                           <tr>
95
                              <td nowrap class="form_ttl"><p>&nbsp;</p>
96
                                 <p>DAEMON STATUS INFORMATION</p>
97
                              </td>
98
                              <td  valign="bottom" class="body_rowg">
99
                                Last Build: <%=GetLastBuildAge(parRtagId)%> [<%=GetModifiedSeqNo(parRtagId)%>]
100
                              </td>
101
                              <td align="right" valign="bottom">
102
                                <a class="txt_linked" href="<%=scriptName%>?rtag_id=<%=parRtagId%>" title="Refresh Page">[Refresh]</a></td>
103
                              </td>
104
                           </tr>
105
                        </table>
106
                     </td>
107
                     <td width="1%"></td>
108
                  </tr>
109
                  <tr>
110
                     <td align="left" valign="top" background="images/lbox_bg_blue.gif"><img src="images/lbox_tl_cnr_b.gif" width="13" height="13"></td>
111
                     <td background="images/lbox_bg_blue.gif" class="lbox_ttl_w"><img src="images/h_trsp_dot.gif" width="600" height="15"></td>
112
                     <td align="right" valign="top" background="images/lbox_bg_blue.gif"><img src="images/lbox_tr_cnr_b.gif" width="13" height="13"></td>
113
                  </tr>
114
                  <tr>
115
                     <td bgcolor="#FFFFFF"><img src="images/h_trsp_dot.gif" width="10" height="100"></td>
116
                     <td bgcolor="#FFFFFF" valign="top">
117
                        <!-- MESSAGE +++++++++++++++++++++++++++++++++++++++++++++++++++ -->
118
                        <!--#include file="messages/_msg_inline.asp"-->
119
                        <!-- +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -->
120
                        <br>
121
                        <table width="100%" border="0" cellspacing="2" cellpadding="0">
122
                           <%
6267 dpurdie 123
                           Dim bInactiveMachine : bInactiveMachine = false
124
                           Dim indefinitelyPaused : indefinitelyPaused = Indefinitely_Paused()
5623 dpurdie 125
                           ' Insert a warning into the page if the build daemons are indefintely paused.
6166 dpurdie 126
                           If indefinitelyPaused Then %>
5623 dpurdie 127
                              <tr>
128
                                 <span class='err_alert'>
129
                                    <font size='2'><b>WARNING: Build Daemons are all stopped - please contact an administrator</b></font>
130
                                 </span>
131
                              </tr>
132
                           <%End If
133
                           %>
134
                           <td width="9%" valign="top"></td>
135
                           <tr>
136
                              <td valign="top" nowrap background="images/bg_table_col.gif" class="body_col">Daemon Host</td>
137
                              <td valign="top" nowrap background="images/bg_table_col.gif" class="body_col">Machine Type</td>
138
                              <td valign="top" nowrap background="images/bg_table_col.gif" class="body_col">Mode</td>
139
                              <td valign="top" nowrap background="images/bg_table_col.gif" class="body_col">Run Level</td>
140
                              <td valign="top" nowrap background="images/bg_table_col.gif" class="body_col">Current Package</td>
141
                              <td valign="top" nowrap background="images/bg_table_col.gif" class="body_col">Last Change<%=Quick_Help("h_lastchange")%></td>
142
                              <td valign="top" nowrap background="images/bg_table_col.gif" class="body_col">Control State</td>
143
                           </tr>
144
                           <%
145
                           ' Get the number of release configurations for this RTAG_ID, and iterate through them
6267 dpurdie 146
                           query_string = " select rc.rcon_id, display_name, gbe_value, daemon_mode, NVL(ACTIVE, 'U') as ACTIVE" &_
147
                                          " from release_config rc, gbe_machtype gm, build_machine_config bm"&_
5623 dpurdie 148
                                          "  where rc.rtag_id = "& parRtagId &_
149
                                          "    and gm.gbe_id = rc.gbe_id"&_
150
                                          "    and rc.bmcon_id=bm.bmcon_id(+)" &_
151
                                          "  order by bm.display_name, rc.rcon_id"
152
 
153
                           Set rsQry = OraDatabase.DbCreateDynaset( query_string, ORADYN_DEFAULT )
154
 
155
                           Do While (NOT rsQry.BOF) AND (NOT rsQry.EOF)
156
                              rcon_id = rsQry("rcon_id")
157
 
158
                              Dim pkgName
159
                              Dim pkgPvid
160
                              Dim currentRunLevel
161
                              Dim daemonState
162
                              Dim delta
163
                              Dim pkgId
6267 dpurdie 164
                              Dim bActive : bActive = rsQry("active")
5623 dpurdie 165
 
166
                              ' For this release configuration, get its entry from the run_level table. This table may not
167
                              ' have an entry so we must handle that outcome too.
168
                              query_string = " select rl.pause, rl.current_run_level, rl.current_pkg_id_being_built, "&_
169
                                             "        TRUNC (86400*(SYSDATE - rl.KEEP_ALIVE)) as delta" &_
170
                                             "   from run_level rl"&_
171
                                             "  where rl.rcon_id = "& rcon_id
172
 
173
                              Set rsQry2 = OraDatabase.DbCreateDynaset( query_string, ORADYN_DEFAULT )
174
 
175
                              currentRunLevel = -1
176
                              pkgId = Null
177
                              pkgName = NULL
178
                              pkgPvid = NULL
179
                              daemonState = 0
180
                              delta = NULL
181
 
182
                              If (rsQry2.RecordCount > 0) Then
183
                                ' Get the run level from the run_level table
184
                                currentRunLevel = rsQry2("current_run_level")
185
                                pkgId = rsQry2("current_pkg_id_being_built")
186
 
187
                                daemonState = rsQry2("pause")
188
                                If IsNull(daemonState) Then daemonState = 0
189
                                If daemonState = "2" Then pkgId = Null
190
 
191
                                delta = rsQry2("delta")
6267 dpurdie 192
 
5623 dpurdie 193
                              End If
194
 
195
                              ' If we got an entry from the run_level table, try and use the pkg_id it contains, to obtain a
196
                              ' package name from the packages table
197
                              Dim rsQry3
198
                              If NOT IsNull(pkgId) Then
199
                                 query_string = " select pkg_name,rl.current_pv_id from run_level rl, packages pk"&_
200
                                                "  where rl.rcon_id = "& rcon_id &_
201
                                                "   and  rl.current_pkg_id_being_built = pk.pkg_id"
202
 
203
                                 Set rsQry3 = OraDatabase.DbCreateDynaset( query_string, ORADYN_DEFAULT )
204
                                 If (rsQry3.RecordCount > 0) Then
205
                                    pkgName = rsQry3("pkg_name")
206
                                    pkgPvid = rsQry3("current_pv_id")
207
                                 End If
208
                                 rsQry3.Close()
209
                                 Set rsQry3 = nothing
210
                              End If
211
 
212
                              ' --- Now render HTML for this release configuration ---
213
                              %>
214
                              <tr>
215
                                 <td colspan="7" background="images/bg_rep_line.gif"><img src="images/spacer.gif" width="1" height="1"></td>
216
                              </tr>
217
                              <tr>
218
                                 <td nowrap class="body_rowg"><%=rsQry("display_name")%></td>
219
                                 <td nowrap class="body_rowg"><%=rsQry("gbe_value")%></td>
220
                                 <td nowrap class="body_rowg"><%=Get_Daemon_Mode(rsQry("daemon_mode"))%></td>
6267 dpurdie 221
                                 <td nowrap class="body_rowg"><%=Get_Run_Level(currentRunLevel, indefinitelyPaused, daemonState, bActive)%></td>
222
                                 <td nowrap class="body_rowg"><%=Get_Package_Name(pkgName,parRtagId,pkgPvid, bActive)%></td>
5623 dpurdie 223
                                 <td nowrap class="body_rowg"><%=PrettyDelta(delta, daemonState,pkgName )%></td>
224
                                 <td nowrap class="body_rowg">
225
                                    <%
226
                                    If (rsQry2.RecordCount > 0) AND NOT indefinitelyPaused  Then
6166 dpurdie 227
                                       If canActionControlInProject("BuildControl") Then
6267 dpurdie 228
                                          If bActive = "U" Then
229
                                          ElseIf bActive = "N" Then
230
                                             Call Action_Buttons ( "Daemon Unavailable" )
231
                                          ElseIf daemonState = 0 Then
5623 dpurdie 232
                                             Call Action_Buttons ( "Daemon Pause" )
233
                                          ElseIf daemonState = 1 Then
234
                                             Call Action_Buttons ( "Daemon Resume" )
235
                                          ElseIf daemonState = 2 Then
236
                                             Call Action_Buttons ( "Daemon Start" )
237
                                          Else
238
                                             Call Action_Buttons ( "Daemon Resume" )
239
                                          End If
240
                                       Else
6267 dpurdie 241
                                          If bActive = "U" Then
242
                                          ElseIf bActive = "N" Then
243
                                             Call Action_Buttons ( "Daemon Unavailable" )
244
                                          ElseIf daemonState = 0 Then
5623 dpurdie 245
                                             Call Action_Buttons ( "Daemon Pause Disabled" )
246
                                          ElseIf daemonState = 1 Then
247
                                             Call Action_Buttons ( "Daemon Resume Disabled" )
248
                                          ElseIf daemonState = 2 Then
249
                                             Call Action_Buttons ( "Daemon Start Disabled" )
250
                                          Else
251
                                             Call Action_Buttons ( "Daemon Resume Disabled" )
252
                                          End If
253
                                       End If
254
                                    Else
255
                                       %>Unavailable<%
256
                                    End If
257
                                    %>
258
                                 </td>
259
                              </tr>
260
                              <%
261
                              rsQry2.Close()
262
                              Set rsQry2 = nothing
263
                              rsQry.MoveNext
264
                           Loop
265
                           %>
266
                           <tr>
6166 dpurdie 267
                             <td nowrap background="images/bg_table_col.gif" class="body_col" colspan=6>
6267 dpurdie 268
                             <%If CheckConfigErrors(parRtagId) OR bInactiveMachine Then%><span class="err_alert">&nbsp;Daemon configuration errors detected</span>
6166 dpurdie 269
                                <a class="txt_linked" href="release_config.asp?rtag_id=<%=parRtagId%>">
270
                                    <img src="images/i_link.gif" hspace="2" border="0" align="absmiddle" title="Goto Configuration">
271
                                </a>
272
                             <%End If%>
273
                             </td>
5623 dpurdie 274
                             <td valign="bottom" nowrap background="images/bg_table_col.gif" class="body_col">
275
                             <%
276
                               If (rsQry.RecordCount > 0) AND NOT indefinitelyPaused  Then
277
                                 If objAccessControl.UserLogedIn AND canActionControlInProject("BuildControl") Then
278
                                   Call Action_Buttons ( "Daemon Control All" )
279
                                 Else 
280
                                   Call Action_Buttons ( "Daemon Control All Disabled" )
281
                                 End If
282
                               Else
283
                                 %>&nbsp<%
284
                               End If
285
                             %>
286
                             </td>
287
                           </tr>
288
                           <%
289
                             rsQry.Close()
290
                             Set rsQry = nothing
291
                           %>
292
                        </table>
293
                     </td>
294
                     <td background="images/lbox_bgside_white.gif">&nbsp;</td>
295
                  </tr>
296
                  <tr>
297
                     <input type="hidden" name="action" value="true">
298
                     <%=objPMod.ComposeHiddenTags()%>
299
                     <td background="images/lbox_bg_blue.gif" valign="bottom"><img src="images/lbox_bl_cnr_b.gif" width="13" height="13"></td>
300
                     <td background="images/lbox_bg_blue.gif"></td>
301
                     <td background="images/lbox_bg_blue.gif" valign="bottom" align="right"><img src="images/lbox_br_cnr_b.gif" width="13" height="13"></td>
302
                  </tr>
303
               </table>
304
 
305
               <!-- Planned Builds Display -->
5670 dpurdie 306
               <%
307
               Set rsQry = OraDatabase.DbCreateDynaset( "SELECT TRUNC (86400*(SYSDATE - rl.LAST_BUILD)) as delta, rl.LAST_BUILD as BuildStart, rl.current_pv_id, SYSDATE" &_
308
                                                        " FROM release_config rc,  run_level rl " &_
309
                                                        " WHERE rc.rtag_id   = " & parRtagId &_
310
                                                        " AND rc.daemon_mode = 'M' AND rl.rcon_id = rc.rcon_id", ORADYN_DEFAULT )
311
               Dim BuildStart
312
               Dim BuildDelta
313
               Dim BuildPvId
314
               Dim BuildNow
315
               If (rsQry.RecordCount > 0) Then
316
                    BuildStart = rsQry("BuildStart")
317
                    BuildDelta = rsQry("delta")
318
                    BuildPvId  = rsQry("current_pv_id")
319
                    BuildNow  = rsQry("SYSDATE")
320
               End If
321
               rsQry.Close()
322
               Set rsQry = nothing
323
               %>
5623 dpurdie 324
               <table width="10" border="0" cellspacing="0" cellpadding="0">
325
                  <tr>
326
                     <td width="1%"></td>
327
                     <td width="100%">
328
                        <table width="100%" border="0" cellspacing="0" cellpadding="0">
329
                           <tr>
330
                              <td nowrap class="form_ttl"><p>&nbsp;</p>
331
                                 <p>DAEMON BUILD PLAN<%=Quick_Help("h_buildplan")%></p>
332
                              </td>
5670 dpurdie 333
                              <td  valign="bottom" class="body_rowg">
334
                                Now: <%=DisplayShortDateTimeSecs(BuildNow)%>
335
                              </td>
5623 dpurdie 336
                              <td align="right" valign="bottom"></td>
337
                           </tr>
338
                        </table>
339
                     </td>
340
                     <td width="1%"></td>
341
                  </tr>
342
                  <tr>
343
                     <td align="left" valign="top" background="images/lbox_bg_blue.gif"><img src="images/lbox_tl_cnr_b.gif" width="13" height="13"></td>
344
                     <td background="images/lbox_bg_blue.gif" class="lbox_ttl_w"><img src="images/h_trsp_dot.gif" width="600" height="15"></td>
345
                     <td align="right" valign="top" background="images/lbox_bg_blue.gif"><img src="images/lbox_tr_cnr_b.gif" width="13" height="13"></td>
346
                  </tr>
347
                  <tr>
348
                     <td bgcolor="#FFFFFF"><img src="images/h_trsp_dot.gif" width="10" ></td>
349
                     <td bgcolor="#FFFFFF" valign="top">
350
                        <table width="100%" border="0" cellspacing="2" cellpadding="0">
351
                           <tr>
352
                              <td align="left" nowrap background="images/bg_table_col.gif" class="body_col">Package</td>
353
                              <td align="left" nowrap background="images/bg_table_col.gif" class="body_col">Version</td>
5635 dpurdie 354
                              <td align="left" nowrap background="images/bg_table_col.gif" class="body_col">Duration<%=Quick_Help("h_buildDuration")%></td>
5670 dpurdie 355
                              <td align="left" nowrap background="images/bg_table_col.gif" class="body_col">Build Completion<%=Quick_Help("h_buildEnd")%></td>
5623 dpurdie 356
                           </tr>
357
                           <%
5670 dpurdie 358
                           Dim PkgVersion, buildDuration, durationDisplay, durationText, completionText
5623 dpurdie 359
                           Set rsQry = OraDatabase.DbCreateDynaset( "SELECT p.PKG_NAME," &_
5635 dpurdie 360
                                                                    "  pv.PKG_VERSION, pv.BUILD_TIME," &_
5623 dpurdie 361
                                                                    "  bp.PV_ID" &_
362
                                                                    " FROM build_plan bp," &_
363
                                                                    "  packages p," &_
364
                                                                    "  package_versions pv" &_
365
                                                                    " WHERE bp.PV_ID = pv.pv_id" &_
366
                                                                    " AND RTAG_ID = " & parRtagId &_
367
                                                                    " AND pv.PKG_ID  = p.pkg_id" &_
368
                                                                    " ORDER BY build_order" , ORADYN_DEFAULT )
369
                           While (NOT rsQry.BOF) AND (NOT rsQry.EOF)
5670 dpurdie 370
                               completionText = ""
371
                               buildDuration = rsQry("BUILD_TIME")
372
                               durationDisplay = buildDuration
373
 
374
                               ' If the current package build it taking longer than expected , then bump the build times
375
                               ' and allow another 30 seconds.
376
                               If BuildPvId = rsQry("PV_ID") Then
377
                                   completionText = "&nbsp;<"
378
                                   durationDisplay = durationDisplay & " ["& BuildDelta &"]"
379
                                   If BuildDelta > buildDuration Then
380
                                        buildDuration = BuildDelta + 30
381
                                        completionText = "&nbsp;+"
382
                                   End If
383
                               End If
384
 
385
                               ' If the duration is not known - guess at 300 sconds
386
                               durationText = ""
387
                               If ISNULL(buildDuration)  OR buildDuration = 0 Then
388
                                    buildDuration = 300
389
                                    durationText = "&nbsp;~"
390
                              End If
391
 
392
                              BuildStart = DateAdd("s", buildDuration, BuildStart)
5623 dpurdie 393
                              %>
394
                              <tr>
395
 
396
                                 <td align="left" valign="top" class="body_txt">
397
                                    <%=Get_Package_Name(rsQry("PKG_NAME"), parRtagId, rsQry("PV_ID"))%>
398
                                 </td>
399
                                 <td align="left" valign="top" class="body_txt">
400
                                    <%=rsQry("PKG_VERSION")%>
401
                                 </td>
5635 dpurdie 402
                                 <td align="left" valign="top" class="body_txt">
5670 dpurdie 403
                                    <%=durationDisplay%>
5635 dpurdie 404
                                 </td>
5670 dpurdie 405
                                 <td align="left" valign="top" class="body_txt">
406
                                    <%=DisplayShortDateTimeSecs(BuildStart) & durationText  & completionText%>
407
                                 </td>
5623 dpurdie 408
                              </tr>
409
                              <tr>
410
                                 <td colspan="6" background="images/bg_rep_line.gif"><img src="images/spacer.gif" width="1" height="1"></td>
411
                              </tr>
412
                              <%
5670 dpurdie 413
                              ' Allow for 20 seconds of planning between builds
414
                              BuildStart = DateAdd("s", 20, BuildStart)
5623 dpurdie 415
                              rsQry.MoveNext()
416
                           Wend
417
                           rsQry.Close()
418
                           Set rsQry = nothing
419
                           %>
420
                        </table>
421
                     </td>
422
                     <td background="images/lbox_bgside_white.gif">&nbsp;</td>
423
                  </tr>
424
                  <tr>
425
                     <td background="images/lbox_bg_blue.gif" valign="bottom"><img src="images/lbox_bl_cnr_b.gif" width="13" height="13"></td>
426
                     <td background="images/lbox_bg_blue.gif"></td>
427
                     <td background="images/lbox_bg_blue.gif" valign="bottom" align="right"><img src="images/lbox_br_cnr_b.gif" width="13" height="13"></td>
428
                  </tr>
429
               </table>
430
 
431
            </td>
432
            <td width="1" valign="top"><img src="images/h_trsp_dot.gif" width="1" height="1"></td>
433
         </tr>
434
         <tr>
435
            <td valign="bottom" align="center" background="images/bg_home_orange.gif">
436
                <img src="images/img_gear.gif" width="86" height="99" vspace="20" hspace="30">
437
            </td>
438
            <td background="images/bg_lght_gray.gif" valign="top"><img src="images/h_trsp_dot.gif" width="1" height="350">
439
            </td>
440
         </tr>
441
      </table>
442
      <!-- FOOTER -->
443
      <!--#include file="_footer.asp"-->
444
   </body>
445
</html>