| [ Index ] |
PHP Cross Reference of Joomla 1.5.26 DE |
[Summary view] [Print] [Text view]
1 <?PHP 2 /** 3 * Dumps templates as HTML 4 * 5 * $Id: Html.php 10381 2008-06-01 03:35:53Z pasamio $ 6 * 7 * @package patTemplate 8 * @subpackage Dump 9 * @author Sebastian Mordziol <argh@php-tools.net> 10 * @author Stephan Schmidt <schst@php.net> 11 */ 12 13 // Check to ensure this file is within the rest of the framework 14 defined('JPATH_BASE') or die(); 15 16 /** 17 * Dumps templates as HTML 18 * 19 * @package patTemplate 20 * @subpackage Dump 21 * @author Sebastian Mordziol <argh@php-tools.net> 22 * @author Stephan Schmidt <schst@php.net> 23 * 24 * @todo move this into patTemplate_Dump_Dhtml and keep it free from javascript 25 */ 26 class patTemplate_Dump_Html extends patTemplate_Dump 27 { 28 var $colors = array( 29 'borders' => 'C8D3DA', 30 'headerFills' => 'E1E7EB', 31 'subHeaderFills' => 'F0F2F4', 32 'source' => 'F5F7F8', 33 'linkNormal' => '8CA0B4', 34 'linkHover' => '8BC3E0', 35 ); 36 37 var $_useBorders = false; 38 39 /** 40 * display the header 41 * 42 * @access public 43 */ 44 function displayHeader() 45 { 46 echo '<html>'; 47 echo ' <head>'; 48 echo ' <style type="text/css">'; 49 echo ' BODY,TD{'; 50 echo ' font-family: Arial, Tahoma, sans-serif;'; 51 echo ' font-size: 12px;'; 52 echo ' }'; 53 echo ' TABLE.patTemplate{'; 54 echo ' border-collapse:collapse;'; 55 echo ' }'; 56 echo ' A.patTemplate{'; 57 echo ' color:#'.$this->colors['linkNormal'].';'; 58 echo ' }'; 59 echo ' A.patTemplate:hover{'; 60 echo ' color:#'.$this->colors['linkHover'].';'; 61 echo ' }'; 62 echo ' H1.patTemplate{'; 63 echo ' margin: 0px;'; 64 echo ' padding: 4px;'; 65 echo ' font-size: 18px;'; 66 echo ' }'; 67 echo ' I.patTemplate{'; 68 echo ' font-style:italic;'; 69 echo ' color:#777777;'; 70 echo ' }'; 71 echo ' H2.patTemplate{'; 72 echo ' background-color: #'.$this->colors['headerFills'].';'; 73 echo ' margin: 0px;'; 74 echo ' margin-bottom: 15px;'; 75 echo ' padding: 4px;'; 76 echo ' border-bottom: 1px dashed #'.$this->colors['borders'].';'; 77 echo ' border-top: 1px dashed #'.$this->colors['borders'].';'; 78 echo ' font-size: 14px;'; 79 echo ' }'; 80 echo ' H3.patTemplate,H3.patTemplateSub{'; 81 echo ' background-color: #'.$this->colors['headerFills'].';'; 82 echo ' margin: 0px;'; 83 echo ' padding: 4px;'; 84 echo ' border-bottom: 1px dashed #'.$this->colors['borders'].';'; 85 echo ' border-top: 1px dashed #'.$this->colors['borders'].';'; 86 echo ' font-size: 12px;'; 87 echo ' font-weight: bold;'; 88 echo ' }'; 89 echo ' H3.patTemplateSub{'; 90 echo ' background-color: #'.$this->colors['subHeaderFills'].';'; 91 echo ' border:1px dashed #'.$this->colors['borders'].';'; 92 echo ' font-weight:normal;'; 93 echo ' margin-bottom:3px;'; 94 echo ' }'; 95 echo ' #patTemplateContent{'; 96 echo ' width: 100%;'; 97 echo ' background-color:#ffffff;'; 98 echo ' border:dashed 1px #'.$this->colors['borders'].';'; 99 echo ' padding:0px;'; 100 echo ' }'; 101 echo ' .patTemplateSection{'; 102 echo ' margin-bottom:20px;'; 103 echo ' }'; 104 echo ' .patTemplateSubSection{'; 105 echo ' margin-bottom:3px;'; 106 echo ' }'; 107 echo ' .patTemplateData{'; 108 echo ' display:none;'; 109 echo ' }'; 110 echo ' .patTemplatePropBorder{'; 111 echo ' white-space:nowrap;'; 112 echo ' font-weight:bold;'; 113 echo ' color:#333333;'; 114 echo ' border:solid 1px #C8D3DA;'; 115 echo ' }'; 116 echo ' .patTemplateProp{'; 117 echo ' white-space:nowrap;'; 118 echo ' font-weight:bold;'; 119 echo ' color:#333333;'; 120 echo ' }'; 121 echo ' .patTemplateSign{'; 122 echo ' font-family:monospace;'; 123 echo ' }'; 124 echo ' .patTemplateClick{'; 125 echo ' cursor:pointer;'; 126 echo ' }'; 127 echo ' .patTemplateCol{'; 128 echo ' margin-bottom:8px;'; 129 echo ' font-weight:bold;'; 130 echo ' }'; 131 echo ' .patTemplateTblCol{'; 132 echo ' padding:8px;'; 133 echo ' padding-right:15px;'; 134 echo ' border-right:dashed 1px #'.$this->colors['borders'].';'; 135 echo ' }'; 136 echo ' .patTemplateTmplContent{'; 137 echo ' padding:8px;'; 138 echo ' border-top:dashed 1px #'.$this->colors['borders'].';'; 139 echo ' }'; 140 echo ' .patTemplateSource{'; 141 echo ' padding:5px;'; 142 echo ' font-family:monospace;'; 143 echo ' background-color:#'.$this->colors['source'].';'; 144 echo ' margin-bottom:8px;'; 145 echo ' }'; 146 echo ' .patTemplateVar{'; 147 echo ' color: #009900;'; 148 echo ' font-weight:bold;'; 149 echo ' }'; 150 echo ' .patTemplateVarBorder{'; 151 echo ' color: #009900;'; 152 echo ' font-weight:bold;'; 153 echo ' border:solid 1px #C8D3DA;'; 154 echo ' }'; 155 echo ' .patTemplateVal{'; 156 echo ' color:#333333;'; 157 echo ' }'; 158 echo ' .patTemplateValBorder{'; 159 echo ' color: #333333;'; 160 echo ' border:solid 1px #C8D3DA;'; 161 echo ' }'; 162 echo ' .patTemplateTmpl {'; 163 echo ' color: #990000;'; 164 echo ' font-weight:bold;'; 165 echo ' cursor:pointer;'; 166 echo ' }'; 167 echo ' </style>'; 168 echo ' <script language="JavaScript1.2" type="text/javascript">'; 169 echo ' var tmpls = new Array();'; 170 echo ' function patTemplateToggle( tmplName )'; 171 echo ' {'; 172 echo ' var el = document.getElementById( \'tmpl-\' + tmplName );'; 173 echo ' if( el.style.display == \'block\' )'; 174 echo ' patTemplateCollapse( tmplName );'; 175 echo ' else'; 176 echo ' patTemplateExpand( tmplName );'; 177 echo ' }'; 178 echo ' function jump( tmplName )'; 179 echo ' {'; 180 echo ' tmplName = tmplName.toLowerCase();'; 181 echo ' patTemplateExpand( tmplName );'; 182 echo ' document.location = \'#\' + tmplName'; 183 echo ' }'; 184 echo ' function patTemplateExpandAll()'; 185 echo ' {'; 186 echo ' for( var i = 0; i < tmpls.length; i++ )'; 187 echo ' patTemplateExpand( tmpls[i] );'; 188 echo ' }'; 189 echo ' function patTemplateCollapseAll()'; 190 echo ' {'; 191 echo ' for( var i = 0; i < tmpls.length; i++ )'; 192 echo ' patTemplateCollapse( tmpls[i] );'; 193 echo ' }'; 194 echo ' function patTemplateExpand( tmplName )'; 195 echo ' {'; 196 echo ' var el1 = document.getElementById( \'tmpl-\' + tmplName );'; 197 echo ' var el2 = document.getElementById( \'tmpl-\' + tmplName + \'-sign\' );'; 198 echo ' el1.style.display = \'block\';'; 199 echo ' el2.innerHTML = \'[-]\';'; 200 echo ' }'; 201 echo ' function patTemplateCollapse( tmplName )'; 202 echo ' {'; 203 echo ' var el1 = document.getElementById( \'tmpl-\' + tmplName );'; 204 echo ' var el2 = document.getElementById( \'tmpl-\' + tmplName + \'-sign\' );'; 205 echo ' el1.style.display = \'none\';'; 206 echo ' el2.innerHTML = \'[+]\';'; 207 echo ' }'; 208 echo ' function patTemplateAddTmpl( tmplName )'; 209 echo ' {'; 210 echo ' tmpls.push( tmplName );'; 211 echo ' }'; 212 echo ' </script>'; 213 echo ' </head>'; 214 echo '<body>'; 215 echo ' <div id="patTemplateContent">'; 216 echo ' <h1 class="patTemplate">patTemplate Dump</h1>'; 217 } 218 219 /** 220 * dump the global variables 221 * 222 * @access public 223 * @param array array containing all global variables 224 */ 225 function dumpGlobals( $globals ) 226 { 227 echo '<div class="patTemplateSection"><h2 class="patTemplate">Global template variables ('.count( $globals ).')</h2>'; 228 if( !empty( $globals ) ) 229 { 230 echo '<div class="patTemplateSubSection" style="padding:5px;">'; 231 echo ' <table border="0" cellpadding="0" cellpadding="0" class="patTemplate">'; 232 foreach( $globals as $key => $value ) 233 { 234 $this->_displayLine( $key, $value ); 235 } 236 echo ' </table>'; 237 echo '</div></div>'; 238 } 239 } 240 241 /** 242 * dump the templates 243 * 244 * @access public 245 * @param array templates 246 */ 247 function dumpTemplates( $templates, $vars ) 248 { 249 $templates = array_reverse( $templates ); 250 251 echo '<div class="patTemplateSection"><h2 class="patTemplate">Templates ('.count( $templates ).') <span style="font-size:12px;font-weight:normal;"><a href="javascript:patTemplateExpandAll();" class="patTemplate">Expand all</a> | <a href="javascript:patTemplateCollapseAll();" class="patTemplate">Collapse all</a></span></h2>'; 252 echo '<div class="patTemplateData">Dumping selected templates...</div>'; 253 254 foreach( $templates as $name => $tmpl ) 255 { 256 if( !isset( $vars[$name] ) ) 257 $vars[$name] = array(); 258 259 $vars[$name] = $this->_flattenVars( $vars[$name] ); 260 261 echo '<div class="patTemplateSubSection">'; 262 echo ' <h3 class="patTemplate" onclick="patTemplateToggle(\''.$name.'\');" style="cursor:pointer;"><span id="tmpl-'.$name.'-sign" class="patTemplateSign">[+]</span> Template <a name="'.$name.'">"'.$name.'"</a></h3>'; 263 echo ' <div class="patTemplateData" id="tmpl-'.$name.'">'; 264 echo ' <script language="JavaScript1.2" type="text/javascript">'; 265 echo ' patTemplateAddTmpl( \''.$name.'\' );'; 266 echo ' </script>'; 267 echo ' <table cellpadding="0" cellspacing="0" border="0">'; 268 echo ' <tr valign="top">'; 269 echo ' <td style="width:200px;" class="patTemplateTblCol">'; 270 271 $this->_displayAttributes( $tmpl, $name ); 272 273 echo ' </td>'; 274 echo ' <td class="patTemplateTblCol" style="width:130px;">'; 275 276 $this->_displayTemplateState( $tmpl ); 277 278 echo ' </td>'; 279 echo ' <td class="patTemplateTblCol" style="width:130px;">'; 280 echo ' <div class="patTemplateCol">Dependencies</div>'; 281 282 if( !empty( $tmpl['dependencies'] ) ) 283 { 284 $dependencies = array(); 285 foreach( $tmpl['dependencies'] as $dependency ) 286 array_push( $dependencies, '<a href="javascript:jump( \''.$dependency.'\' );" class="patTemplate">'.$dependency.'</a>' ); 287 288 echo implode( '<br>', $dependencies ); 289 } 290 else 291 { 292 echo '<i class="patTemplate">[none]</i>'; 293 } 294 295 echo ' </td>'; 296 echo ' </tr>'; 297 echo ' </table>'; 298 299 300 /** 301 * ------------------------------------------------------------------ 302 * display variables 303 */ 304 $nestedTypes = array( 305 'condition', 306 'modulo', 307 ); 308 309 if( in_array( $tmpl['attributes']['type'], $nestedTypes ) ) 310 { 311 $content = ''; 312 313 foreach( $tmpl['subtemplates'] as $subName => $subDetails ) 314 { 315 $content .= $subDetails['data']; 316 } 317 } 318 else 319 { 320 $content = $tmpl['content']; 321 } 322 323 $setVars = $this->_extractVars( $content ); 324 325 echo '<div class="patTemplateTmplContent">'; 326 echo ' <div class="patTemplateCol">Variables</div>'; 327 $this->_displayVariables( $tmpl, $name, $setVars, $vars ); 328 echo '</div>'; 329 330 if( !empty( $tmpl['comments'] ) ) 331 { 332 echo ' <div class="patTemplateTmplContent">'; 333 echo ' <div class="patTemplateCol">Comments</div>'; 334 echo ' <div style="margin-bottom:7px;">'; 335 echo implode( '<br>', $tmpl['comments'] ); 336 echo ' </div>'; 337 echo ' </div>'; 338 } 339 340 /** 341 * ------------------------------------------------------------------ 342 * display template content 343 */ 344 echo ' <div class="patTemplateTmplContent">'; 345 switch( $tmpl['attributes']['type'] ) 346 { 347 case 'condition': 348 case 'modulo': 349 $this->_displayConditions( $tmpl, $name, $vars ); 350 break; 351 352 default: 353 echo ' <div class="patTemplateCol">Content</div>'; 354 echo ' <div class="patTemplateSource"><pre>'.$this->_highlightVars( htmlspecialchars( $tmpl['content'] ), $vars[$name] ).'</pre></div>'; 355 break; 356 } 357 358 echo ' </div>'; 359 echo ' </div>'; 360 echo '</div>'; 361 } 362 363 echo '</div>'; 364 } 365 366 function _displayVariables( $tmpl, $tmplName, $setVars, $vars ) 367 { 368 if( empty( $setVars ) ) 369 { 370 echo '<i class="patTemplate">[none]</i>'; 371 return true; 372 } 373 374 echo '<table border="0" cellpadding="3" cellpadding="0" class="patTemplate">'; 375 $this->_useBorders( true ); 376 $this->_displayHead( 'Name', 'Assigned value', 'Modifier' ); 377 378 foreach( $setVars as $var ) 379 { 380 if( isset( $vars[$tmplName][$var] ) ) 381 $value = $vars[$tmplName][$var]; 382 else 383 $value = '<i class="patTemplate">[no value set]</i>'; 384 385 if( isset( $tmpl['modifyVars'][$var] ) ) 386 { 387 $params = array(); 388 foreach( $tmpl['modifyVars'][$var]['params'] as $n => $val ) 389 { 390 array_push( $params, $n.'="'.$val.'"' ); 391 } 392 $modifier = sprintf( '%s( %s )', $tmpl['modifyVars'][$var]['mod'], implode( ', ', $params ) ); 393 } 394 else 395 { 396 $modifier = '<i class="patTemplate">[none]</i>'; 397 } 398 399 $this->_displayLine( $var, $value, $modifier ); 400 } 401 echo '</table>'; 402 403 $this->_useBorders( false ); 404 } 405 406 function _displayConditions( $tmpl, $tmplName, $vars ) 407 { 408 foreach( $tmpl['subtemplates'] as $cond => $spec ) 409 { 410 echo ' <h3 class="patTemplateSub" onclick="patTemplateToggle(\'Cond'.$cond.'\');" style="cursor:pointer;"><span id="tmpl-Cond'.$cond.'-sign" class="patTemplateSign">[+]</span> Subtemplate <a name="Cond'.$cond.'">"'.$cond.'"</a></h3>'; 411 echo ' <div class="patTemplateData" id="tmpl-Cond'.$cond.'" style="margin-bottom:15px;">'; 412 echo ' <script language="JavaScript1.2" type="text/javascript">'; 413 echo ' patTemplateAddTmpl( \'Cond'.$cond.'\' );'; 414 echo ' </script>'; 415 416 if( !empty( $spec['comments'] ) ) 417 { 418 echo ' <div class="patTemplateCol">Comments</div>'; 419 echo ' <div style="margin-bottom:7px;">'; 420 echo implode( '<br>', $spec['comments'] ); 421 echo ' </div>'; 422 } 423 424 echo ' <div class="patTemplateCol">Dependencies</div>'; 425 echo ' <div style="margin-bottom:7px;">'; 426 if( !empty( $spec['dependencies'] ) ) 427 { 428 $dependencies = array(); 429 foreach( $spec['dependencies'] as $dependency ) 430 array_push( $dependencies, '<a href="javascript:jump( \''.$dependency.'\' );" class="patTemplate">'.$dependency.'</a>' ); 431 432 echo implode( ', ', $dependencies ); 433 } 434 else 435 { 436 echo '<i class="patTemplate">[none]</i>'; 437 } 438 echo ' </div>'; 439 440 echo ' <div class="patTemplateCol">Content</div>'; 441 echo ' <div class="patTemplateSource"><pre>'.$this->_highlightVars( htmlspecialchars( $spec['data'] ), $vars[$tmplName] ).'</pre></div>'; 442 echo ' </div>'; 443 } 444 } 445 446 /** 447 * display the attributes of a template 448 * 449 * @access private 450 * @param array template data 451 * @param string name of the template 452 */ 453 function _displayAttributes( $tmpl, $tmplName = null ) 454 { 455 echo '<div class="patTemplateCol">Attributes</div>'; 456 echo '<table border="0" cellpadding="0" cellpadding="0">'; 457 458 /** 459 * type 460 */ 461 switch( $tmpl['attributes']['type'] ) 462 { 463 case 'modulo': 464 if( $tmpl['attributes']['modulo'] == 2 ) 465 $type = 'OddEven'; 466 else 467 $type = 'modulo (' . $tmpl['attributes']['modulo'] . ')'; 468 case 'condition': 469 if( !isset( $type ) ) 470 $type = 'condition'; 471 472 $this->_displayLine( 'Type', $tmpl['attributes']['type'] ); 473 /** 474 * condition variable, only used in condition templates 475 */ 476 if( isset( $tmpl['attributes']['conditionvar'] ) ) 477 { 478 if( isset( $tmpl['attributes']['conditiontmpl'] ) ) 479 $this->_displayLine( 'ConditionVar', $tmpl['attributes']['conditiontmpl'].'.'.$tmpl['attributes']['conditionvar'] ); 480 elseif( isset( $tmpl['attributes']['useglobals'] ) && $tmpl['attributes']['useglobals'] == 'yes' ) 481 $this->_displayLine( 'ConditionVar', '__globals.'.$tmpl['attributes']['conditionvar'] ); 482 else 483 $this->_displayLine( 'ConditionVar', $tmpl['attributes']['conditionvar'] ); 484 } 485 break; 486 487 case 'simplecondition': 488 $this->_displayLine( 'Type', 'simplecondition' ); 489 $requiredvars = array(); 490 foreach ($tmpl['attributes']['requiredvars'] as $tmp) { 491 if ($tmp[0] !== $tmplName) { 492 $var = $tmp[0] . '.' . $tmp[1]; 493 } else { 494 $var = $tmp[1]; 495 } 496 if ($tmp[2] !== null) { 497 $var = $var . '='.$tmp[2]; 498 } 499 array_push($requiredvars, $var); 500 } 501 502 $this->_displayLine( 'RequiredVars', implode( ', ', $requiredvars ) ); 503 504 break; 505 default: 506 $this->_displayLine( 'Type', $tmpl['attributes']['type'] ); 507 } 508 509 /** 510 * standard attributes 511 */ 512 $this->_displayLine( 'Visibility', $tmpl['attributes']['visibility'] ); 513 $this->_displayLine( 'WhiteSpace', $tmpl['attributes']['whitespace'] ); 514 $this->_displayLine( 'AddSystemVars', $tmpl['attributes']['addsystemvars'] ); 515 $this->_displayLine( 'UnusedVars', $tmpl['attributes']['unusedvars'] ); 516 517 /** 518 * external source 519 */ 520 if( isset( $tmpl['attributes']['src'] ) ) 521 $this->_displayLine( 'External Src', $tmpl['attributes']['src'] ); 522 /** 523 * varscope 524 */ 525 if (isset($tmpl['attributes']['varscope'])) { 526 if (is_array($tmpl['attributes']['varscope'])) { 527 $this->_displayLine( 'Varscope', implode(', ', $tmpl['attributes']['varscope'] ) ); 528 } else { 529 $this->_displayLine( 'Varscope', $tmpl['attributes']['varscope'] ); 530 } 531 } 532 533 echo ' </table>'; 534 } 535 536 function _displayTemplateState( $tmpl ) 537 { 538 echo ' <div class="patTemplateCol">States</div>'; 539 echo ' <table border="0" cellpadding="0" cellpadding="0">'; 540 $this->_displayLine( 'Loaded', $tmpl['loaded'] ); 541 $this->_displayLine( 'Parsed', $tmpl['parsed'] ); 542 echo ' </table>'; 543 } 544 545 /** 546 * hilight variables in a template 547 * 548 * @access private 549 * @param string template content 550 * @return string template content 551 */ 552 function _highlightVars( $template, $vars ) 553 { 554 $pattern = '/('.$this->_tmpl->getStartTag().'TMPL\:([^a-z]+)'.$this->_tmpl->getEndTag().')/U'; 555 $template = preg_replace( $pattern, '<span class="patTemplateTmpl" onclick="jump(\'\2\')" title="Click to view the dependency \'\2\'.">\1</span>', $template ); 556 557 $pattern = '/('.$this->_tmpl->getStartTag().'([^a-z:]+)'.$this->_tmpl->getEndTag().')/U'; 558 $matches = array(); 559 preg_match_all( $pattern, $template, $matches ); 560 for( $i = 0; $i < count( $matches[1] ); $i++ ) 561 { 562 if( isset( $vars[$matches[2][$i]] ) ) 563 { 564 $value = $vars[$matches[2][$i]]; 565 } 566 else 567 { 568 $value = '[No value set]'; 569 } 570 $replace = '<span class="patTemplateVar" title="'.$value.'">'.$matches[1][$i].'</span>'; 571 $template = str_replace( $matches[1][$i], $replace, $template ); 572 } 573 return $template; 574 } 575 576 /** 577 * display a table header 578 * 579 * @access private 580 * @param string property 581 * @param mixed value, you may pass more than one value 582 */ 583 function _displayHead() 584 { 585 $args = func_get_args(); 586 587 echo ' <tr valign="top">'; 588 foreach( $args as $head ) 589 { 590 printf( ' <td class="'.$this->_getClassName( 'patTemplateProp' ).'">%s</td>', $head ); 591 } 592 echo ' </tr>'; 593 } 594 595 function _getClassName( $class ) 596 { 597 if( !$this->_useBorders ) 598 return $class; 599 600 return $class .= 'Border'; 601 } 602 603 /** 604 * sets whether to draw borders in the tables generated via the 605 * {@link _displayHead()} and {@link _displayLine()} methods. 606 * 607 * @access private 608 * @param bool $state Whether to draw the borders. true=draw, false=don't draw 609 */ 610 function _useBorders( $state ) 611 { 612 $this->_useBorders = $state; 613 } 614 615 /** 616 * display a line in a table 617 * 618 * @access private 619 * @param string property 620 * @param mixed value, you may pass more than one value 621 */ 622 function _displayLine( $prop, $value ) 623 { 624 $args = func_get_args(); 625 $prop = array_shift( $args ); 626 627 echo ' <tr valign="top">'; 628 printf( ' <td class="'.$this->_getClassName( 'patTemplateProp' ).'">%s</td>', $prop ); 629 if( count( $args ) == 1 ) 630 { 631 echo ' <td class="'.$this->_getClassName( 'patTemplateVal' ).'"> : </td>'; 632 } 633 634 foreach( $args as $value ) 635 { 636 if( is_bool( $value ) ) 637 { 638 $value = ( $value === true ) ? 'yes' : 'no'; 639 } 640 641 printf( ' <td class="'.$this->_getClassName( 'patTemplateVal' ).'">%s</td>', $value ); 642 } 643 echo ' </tr>'; 644 } 645 646 /** 647 * display the footer 648 * 649 * @access public 650 */ 651 function displayFooter() 652 { 653 echo ' </div>'; 654 echo ' </body>'; 655 echo '</html>'; 656 } 657 } 658 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Wed Mar 28 15:54:07 2012 | Cross-referenced by PHPXref 0.7.1 |