No changes between revisions
/WebSVN/form.php |
---|
File deleted |
/WebSVN/templates.txt |
---|
File deleted |
/WebSVN/wsvn.php |
---|
File deleted |
/WebSVN/install.txt |
---|
File deleted |
/WebSVN/licence.txt |
---|
File deleted |
/WebSVN/README.md |
---|
0,0 → 1,9 |
# WebSVN - Online Subversion repository browser |
This is a Fork from WebSVN |
WebSVN offers a view onto your Subversion repositories that's been designed to reflect the Subversion methodology. |
You can view the log of any file or directory and see a list of all the files changed, added or deleted in any given revision. |
You can also view the differences between two versions of a file so as to see exactly what was changed in a particular revision. |
More information in project site. https://websvnphp.github.io/ |
/WebSVN/blame.php |
---|
1,8 → 1,6 |
<?php |
# vim:et:ts=3:sts=3:sw=3:fdm=marker: |
// WebSVN - Subversion repository viewing via the web using PHP |
// Copyright © 2004-2006 Tim Armes, Matt Sicker |
// Copyright (C) 2004-2006 Tim Armes |
// |
// This program is free software; you can redistribute it and/or modify |
// it under the terms of the GNU General Public License as published by |
11,12 → 9,12 |
// |
// This program is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License |
// along with this program; if not, write to the Free Software |
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
// |
// -- |
// |
25,107 → 23,241 |
// Show the blame information of a file. |
// |
require_once 'include/setup.inc'; |
require_once 'include/svnlook.inc'; |
require_once 'include/utils.inc'; |
require_once 'include/template.inc'; |
require_once 'include/setup.php'; |
require_once 'include/svnlook.php'; |
require_once 'include/utils.php'; |
require_once 'include/template.php'; |
$vars['action'] = $lang['BLAME']; |
// Make sure that we have a repository |
if (!$rep) |
{ |
renderTemplate404('blame','NOREP'); |
} |
$svnrep = new SVNRepository($rep); |
// If there's no revision info, go to the lastest revision for this path |
$history = $svnrep->getLog($path, '', '', true); |
$youngest = $history->entries[0]->rev; |
$history = $svnrep->getLog($path, 'HEAD', 1, false, 2, ($path == '/') ? '' : $peg); |
if (empty($rev)) |
$rev = $youngest; |
if (!$history) |
{ |
unset($vars['error']); |
$history = $svnrep->getLog($path, '', '', false, 2, ($path == '/') ? '' : $peg); |
if ($path{0} != '/') |
$ppath = '/'.$path; |
else |
$ppath = $path; |
if (!$history) |
{ |
renderTemplate404('blame','NOPATH'); |
} |
} |
$youngest = ($history && isset($history->entries[0])) ? $history->entries[0]->rev : false; |
if (empty($rev)) |
{ |
$rev = $youngest; |
} |
else |
{ |
$history = $svnrep->getLog($path, $rev, '', false, 2, $peg); |
if (!$history) |
{ |
renderTemplate404('blame','NOPATH'); |
} |
} |
if ($path[0] != '/') |
{ |
$ppath = '/'.$path; |
} |
else |
{ |
$ppath = $path; |
} |
// Find the parent path (or the whole path if it's already a directory) |
$pos = strrpos($ppath, '/'); |
$parent = substr($ppath, 0, $pos + 1); |
$vars['repname'] = $rep->getDisplayName(); |
$vars['rev'] = $rev; |
$vars['path'] = $ppath; |
$vars['peg'] = $peg; |
$vars['path'] = str_replace('%2F', '/', rawurlencode($ppath)); |
$vars['safepath'] = escape($ppath); |
createDirLinks($rep, $ppath, $rev, $showchanged); |
if (isset($history->entries[0])) |
{ |
$vars['log'] = xml_entities($history->entries[0]->msg); |
$vars['date'] = $history->entries[0]->date; |
$vars['age'] = datetimeFormatDuration(time() - strtotime($history->entries[0]->date)); |
$vars['author'] = $history->entries[0]->author; |
} |
$listing = array(); |
createPathLinks($rep, $ppath, $passrev, $peg); |
$passRevString = createRevAndPegString($rev, $peg); |
// Get the contents of the file |
$tfname = tempnam('temp', ''); |
$svnrep->getFileContents($path, $tfname, $rev, '', true); |
if ($rev != $youngest) |
{ |
$vars['goyoungesturl'] = $config->getURL($rep, $path, 'blame').createRevAndPegString('', $peg); |
$vars['goyoungestlink'] = '<a href="'.$vars['goyoungesturl'].'"'.($youngest ? ' title="'.$lang['REV'].' '.$youngest.'"' : '').'>'.$lang['GOYOUNGEST'].'</a>'; |
} |
$filecache = array(); |
$revurl = $config->getURL($rep, $path, 'blame'); |
if ($file = fopen($tfname, 'r')) |
if ($rev < $youngest) |
{ |
// Get the blame info |
$tbname = tempnam('temp', ''); |
$svnrep->getBlameDetails($path, $tbname, $rev); |
$ent = true; |
$extension = strrchr(basename($path), '.'); |
if (($extension && isset($extEnscript[$extension]) && ('php' == $extEnscript[$extension])) || ($config->useEnscript)) |
$ent = false; |
$history2 = $svnrep->getLog($path, $rev, $youngest, true, 2, $peg); |
if ($blame = fopen($tbname, 'r')) |
{ |
// Create an array of version/author/line |
$index = 0; |
while (!feof($blame) && !feof($file)) |
{ |
$blameline = fgets($blame); |
if ($blameline != '') |
{ |
list($revision, $author) = sscanf($blameline, '%d %s'); |
$listing[$index]['lineno'] = $index + 1; |
$url = $config->getURL($rep, $parent, 'dir'); |
$listing[$index]['revision'] = "<a href=\"${url}rev=$revision&sc=1\">$revision</a>"; |
if (isset($history2->entries[1])) |
{ |
$nextRev = $history2->entries[1]->rev; |
if ($nextRev != $youngest) |
{ |
$vars['nextrev'] = $nextRev; |
$vars['nextrevurl'] = $revurl.createRevAndPegString($nextRev, $peg); |
} |
} |
$listing[$index]['author'] = $author; |
if ($ent) |
$line = replaceEntities(rtrim(fgets($file)), $rep); |
else |
$line = rtrim(fgets($file)); |
unset($vars['error']); |
} |
$listing[$index]['line'] = hardspace($line); |
if (trim($listing[$index]['line']) == '') |
$listing[$index]['line'] = ' '; |
$index++; |
} |
} |
fclose($blame); |
} |
fclose($file); |
if (isset($history->entries[1])) |
{ |
$prevRev = $history->entries[1]->rev; |
$prevPath = $history->entries[1]->path; |
$vars['prevrev'] = $prevRev; |
$vars['prevrevurl'] = $revurl.createRevAndPegString($prevRev, $peg); |
} |
unlink($tfname); |
unlink($tbname); |
$vars['revurl'] = $config->getURL($rep, $path, 'revision').$passRevString; |
$vars['revlink'] = '<a href="'.$vars['revurl'].'">'.$lang['LASTMOD'].'</a>'; |
$vars['version'] = $version; |
$vars['logurl'] = $config->getURL($rep, $path, 'log').$passRevString; |
$vars['loglink'] = '<a href="'.$vars['logurl'].'">'.$lang['VIEWLOG'].'</a>'; |
if (!$rep->hasReadAccess($path, false)) |
$vars['noaccess'] = true; |
$vars['filedetailurl'] = $config->getURL($rep, $path, 'file').$passRevString; |
$vars['filedetaillink'] = '<a href="'.$vars['filedetailurl'].'">'.$lang['FILEDETAIL'].'</a>'; |
parseTemplate($rep->getTemplatePath().'header.tmpl', $vars, $listing); |
parseTemplate($rep->getTemplatePath().'blame.tmpl', $vars, $listing); |
parseTemplate($rep->getTemplatePath().'footer.tmpl', $vars, $listing); |
?> |
if ($history == null || count($history->entries) > 1) |
{ |
$vars['diffurl'] = $config->getURL($rep, $path, 'diff').$passRevString; |
$vars['difflink'] = '<a href="'.$vars['diffurl'].'">'.$lang['DIFFPREV'].'</a>'; |
} |
if ($rep->isRssEnabled()) |
{ |
$vars['rssurl'] = $config->getURL($rep, $path, 'rss').createRevAndPegString('', $peg); |
$vars['rsslink'] = '<a href="'.$vars['rssurl'].'">'.$lang['RSSFEED'].'</a>'; |
} |
// Check for binary file type before grabbing blame information. |
$svnMimeType = $svnrep->getProperty($path, 'svn:mime-type', $rev, $peg); |
if (!$rep->getIgnoreSvnMimeTypes() && preg_match('~application/*~', $svnMimeType)) |
{ |
$vars['warning'] = 'Cannot display blame info for binary file. (svn:mime-type = '.$svnMimeType.')'; |
$vars['javascript'] = ''; |
} |
else |
{ |
// Get the contents of the file |
$tfname = tempnamWithCheck($config->getTempDir(), ''); |
$highlighted = $svnrep->getFileContents($path, $tfname, $rev, $peg, '', 'line'); |
if ($file = fopen($tfname, 'r')) |
{ |
// Get the blame info |
$tbname = tempnamWithCheck($config->getTempDir(), ''); |
$svnrep->getBlameDetails($path, $tbname, $rev, $peg); |
if ($blame = fopen($tbname, 'r')) |
{ |
// Create an array of version/author/line |
$index = 0; |
$seen_rev = array(); |
$last_rev = ''; |
$row_class = ''; |
while (!feof($blame) && !feof($file)) |
{ |
$blameline = rtrim(fgets($blame), "\n\r"); |
if ($blameline != '') |
{ |
list($revision, $author, $remainder) = sscanf($blameline, '%d %s %s'); |
$empty = !$remainder; |
$listvar = &$listing[$index]; |
$listvar['lineno'] = $index + 1; |
if ($last_rev != $revision) |
{ |
$listvar['revision'] = '<a id="l'.$index.'-rev" class="blame-revision" href="'.$config->getURL($rep, $path, 'blame').createRevAndPegString($revision, $peg ? $peg : $rev).'">'.$revision.'</a>'; |
$seen_rev[$revision] = 1; |
$row_class = ($row_class == 'light') ? 'dark' : 'light'; |
$listvar['author'] = $author; |
} |
else |
{ |
$listvar['revision'] = ''; |
$listvar['author'] = ''; |
} |
$listvar['row_class'] = $row_class; |
$last_rev = $revision; |
$line = rtrim(fgets($file), "\n\r"); |
if (!$highlighted) |
{ |
$line = escape(toOutputEncoding($line)); |
} |
$listvar['line'] = ($empty) ? ' ' : wrapInCodeTagIfNecessary($line); |
$index++; |
} |
} |
fclose($blame); |
} |
fclose($file); |
@unlink($tbname); |
} |
@unlink($tfname); |
// Build the necessary JavaScript as an array of lines, then join them with \n |
$javascript = array(); |
$javascript[] = '<script type="text/javascript" src="'.$locwebsvnhttp.'/javascript/blame-popup.js"></script>'; |
$javascript[] = '<script type="text/javascript">'; |
$javascript[] = '/* <![CDATA[ */'; |
$javascript[] = 'var rev = new Array();'; |
ksort($seen_rev); // Sort revisions in descending order by key |
if (empty($peg)) |
{ |
$peg = $rev; |
} |
if (!isset($vars['warning'])) |
{ |
foreach ($seen_rev as $key => $val) |
{ |
$history = $svnrep->getLog($path, $key, $key, false, 1, $peg); |
if ($history && $history->curEntry) |
{ |
$javascript[] = 'rev['.$key.'] = \'<div class="date">'.$history->curEntry->date.'</div><div class="msg">'.addslashes(preg_replace('/\n/', ' ', $history->curEntry->msg)).'</div>\';'; |
} |
} |
} |
$javascript[] = '/* ]]> */'; |
$javascript[] = '</script>'; |
$vars['javascript'] = implode("\n", $javascript); |
} |
if (!$rep->hasReadAccess($path, false)) |
{ |
$vars['error'] = $lang['NOACCESS']; |
sendHeaderForbidden(); |
} |
renderTemplate('blame'); |
/WebSVN/browse.php |
---|
0,0 → 1,40 |
<?php |
// WebSVN - Subversion repository viewing via the web using PHP |
// Copyright (C) 2004-2006 Tim Armes |
// |
// This program is free software; you can redistribute it and/or modify |
// it under the terms of the GNU General Public License as published by |
// the Free Software Foundation; either version 2 of the License, or |
// (at your option) any later version. |
// |
// This program is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License |
// along with this program; if not, write to the Free Software |
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
// |
// -- |
// |
// browse.php |
// |
// Stub for MultiViewsIndex |
// --- CONFIGURE THESE VARIABLES --- |
// Location of websvn directory via HTTP |
// |
// e.g. For "http://www.example.com/websvn" use '/websvn' |
// |
// Note that browse.php need not be in the /websvn directory (and often isn't). |
// If you want to use the root server directory, just use a blank string (''). |
$locwebsvnhttp = !empty($_SERVER['CONTEXT_PREFIX']) ? $_SERVER['CONTEXT_PREFIX'] : '/websvn'; |
// Physical location of websvn directory. Change this if your browse.php is not in |
// the same directory as the rest of the distribution |
$locwebsvnreal = dirname(__FILE__); |
require $locwebsvnreal.'/multiviews.php'; |
/WebSVN/cache/tmp |
---|
1,0 → 0,0 |
This file is here so that the directory gets included in the ZIP files |
This file is here so that the directory gets included in the ZIP files. |
/WebSVN/changes.txt |
---|
1,20 → 1,147 |
2.1 alpha 1 |
2.4.0+ |
* Changed: many cleanups and optimisations. |
* Added: more documentation for *.inc files. |
* Removed: extraneous bits. |
* New: PHP_Compat usage to allow some new PHP5 functionality and remain |
backwards-compatible. |
* Changed: line endings now use UNIX-style across the board. |
This file is discontinued in favor of using milestones per release on GitHub. |
https://github.com/websvnphp/websvn/releases |
https://github.com/websvnphp/websvn/issues/29 |
2.3.3 |
* Fixed security issue (only affecting Windows with enabled downloads) |
* Added option to override bugtraq properties in config file (#315) |
* Added support for using complete filenames (instead of extensions only) for enscript and GeSHi highlighting (e.g. CMakeLists.txt) |
* Added option to ignore whitespaces in diff as default |
* Added proper notification if temporary folder is not writable |
* Improved path-column in log-view to show most precise path containing all modifications of revision (#313) |
* Improved handling of non-existing resources, returning HTTP status code 404 with an error message not containing SVN commands (#321) |
* Fixed URLs when using revision form and listing view (partially #314) |
* Fixed downloading folders containing whitespaces (#308) |
* Fixed inline diff when ignoring whitespaces with PHP 4 (#309) |
* Fixed keeping flag to regard/ignore whitespaces in diff when moving to previous/next/youngest revision |
* Updated translation: Swedish (#320) |
2.3.2 |
* Added ability to use plain PHP for creating templates |
* Added config option to show last modification in repository list |
* Added config option to trust all server certificates |
* Added support for using multiple access files |
* Added translation: Macedonian, Russian |
* Improved navigation through items deleted in recent revision |
* Improved ignoring whitespaces (including different newlines) in compare-view |
* Updated translation: Dutch |
* Updated libraries: GeSHi 1.0.8.9 |
* Fixed parsing SVN version |
* Fixed comparing two revisions |
* Fixed regression in revision form |
* Fixed issues: 292, 294, 296, 298, 302, 304, 306, 307 |
2.3.1 |
* Added in-line highlighting of diff |
* Added links to previous/next revision in various views |
* Added config option to block bots from indexing |
* Added returning correct http status 403/404 in some cases |
* Improved check for path-based authorization |
* Fixed usage of Enscript |
* Fixed diff of just moved/renamed files |
* Fixed strict messages when using PHP 5.3 |
* Updated libraries: GeSHi 1.0.8.6, PEAR Archive_Tar 1.3.6, PEAR Text_Diff 1.1.1 |
* Updated install documentation |
* Updated translations: Hindi, Marathi, Slovenian |
* Fixed issues: 98, 235, 250, 260, 262, 263, 264, 265, 266, 267, 268, 269, |
270, 271, 273, 274, 275, 276, 278, 280, 283, 284, 285, 287, 288, 290 |
2.3.0 |
* Better support for moved, renamed and deleted items. |
* Improved handling of errors, show useful messages without exposing auth data. |
* Improved handling of different character encodings. |
Replaced manual per-repository configuration with automatic handling |
(using either multibyte string or iconv extension). |
* Modified various things in templates (see doc/templates.html). |
* Added new theme called "Elegant". |
* Added combobox to select template on a per-user base. |
* Fixed plain file downloading. |
* Added http header 500 for errors with downloading archives/files. |
* Updated rss generation. |
* Updated french translation. |
* Fixed issues: 64, 84, 151, 155, 236, 240, 242, 243, 244, 245, 246, 247, 248, |
251, 253, 254, 255, 256, 257, 259 |
2.2.1 |
* Fixed downloading tar-gz-archives when using .gz extension. |
* Improved output when svn-command could not be executed correctly. |
* Added config option to fully alphabetize, independent of folder or file type. |
* Fixed multiple links and minor issues. |
* Fixed issues: 212, 213, 214, 215, 216, 217, 219, 222, 223, 224, 225, 227, 228, |
229, 230, 231, 232, 234, 237, 238 |
2.2.0 |
* Fixed revision handling to use PEG revision instead of OPERATIVE revision. |
* This fixes many (but not all) cases of viewing moved/renamed/deleted files. |
* Removed dependencies to external command. |
* Added PEAR Archive_Tar. |
* Added PEAR Text_Diff. |
* Added usage of gzip (.gz extension) if available. |
* Added usage of PHP touch function. |
* Improved scalability of parent path handling. |
* Added support for upcoming PHP 5.3 release. |
* Added separate customizable extension mapping for GeSHi. |
* Added links for choosing whether to ignore whitespace on compare and diff. |
* Added support for aliases in auth file; handles continuation lines correctly. |
* Added config option to set custom config path. |
* Added config option to exclude repositories from those included by parentPath. |
* Added config option to add a subpath of a repository (not just at root level). |
* Added config option to switch between showing age and date in log and listing |
view (the other is displayed in the title attribute and shown when hovering). |
* Added auto detection of Windows. |
* Added message when config file does not exist. |
* Added new logo and favicon. |
* Fixed some broken links when navigating through a repository. |
* Fixed created archive to be identical (for the same revision) across requests. |
* This works under Linux with any PHP version and under Windows with PHP 5.3. |
* Fixed parsing of access file to support usernames containing equal characters. |
* Updated translations |
* Dutch |
* French |
* Italian |
2.1.0 |
* Fixed: Several security fixes. |
* Added: Added GeSHi for code highlighting. |
* Added: New languages. |
* Changed: Separated modified files and directory listing. |
* Changed: Updated used libraries. |
CHANGES |
FIX: Patched several XSS vulnerabilities. (Issue 179) |
FIX: Hide modified files in revision view based on authentication. |
FIX: Numerous other security problems. |
NEW: Added translations: hungarian, indonesian, slovak, uzbek. |
CHANGED: Some code cleanup. |
NEW: Template files may now be specified on a per repository basis |
NEW: Add RSS 'alternate' <link> elements to the HTML headers in |
directory listings. This lets you, for example, easily create a |
'live bookmark' in Firefox to monitor commits to a particular SVN path. |
NEW: Russian translation. |
2.0 |
* Added: More documentation for *.php files. |
* Removed: Extraneous bits. |
* Changed: Many cleanups and optimisations. |
* Changed: Line endings now use UNIX-style across the board. |
CHANGES |
NEW: New default template theme offered by Erik Pöhler. |
NEW: Template files may now be specified on a per repository basis. |
NEW: RSS 'alternate' <link> elements in HTML headers links to directory listing. |
This lets you, for example, easily create an RSS 'live bookmark' to monitor |
commits to a particular SVN path. |
NEW: Russian translation |
CHANGE: Bugtraq handling has been updated to account for the latest spec. |
FIX: Syntax highlighting across lines has been fixed (Issue 85) |
21,181 → 148,174 |
2.00 beta 8 |
CHANGE: Remove path comparison boxes when using the flat view display |
CHANGE: Tidy up URLs generated from the listing view (Remove default parameters). |
CHANGE: wsvn now selectes either the listing or file view automatically when the op parameter |
isn't present. This allows for nicer URLS (eg. /http://example.com/wsvn/repo1/myfile.doc) |
FIX: Fix warnings when using an access file that didn't define a groups section |
FIX: Fix tarballing of directories with spaces |
CHANGE: Remove path comparison boxes when using the flat view display. |
CHANGE: Tidied URLs generated from the listing view (remove default parameters). |
CHANGE: wsvn now selects either the listing or file view automatically when the |
"op" parameter isn't present. This allows for simpler, shorter URLS. |
(eg. /http://example.com/wsvn/repo1/myfile.txt) |
FIX: Fix warnings when using an access file that didn't define a groups section. |
FIX: Fix tarballing of directories with spaces. |
FIX: Path history information in the log view of a file was incorrect. |
2.00 beta 7 |
NEW: Projects may now be assigned to groups, to simplify the index view |
NEW: The index may be displayed as a collapsable tree of groups |
NEW: Projects may now be assigned to groups to simplify the index view. |
NEW: The index may be displayed as a collapsible tree of groups. |
CHANGE: The syntax for the per repository configurations has changed. It's now much simpler and |
will work on all versions of PHP |
CHANGE: The syntax for per-repository configurations has changed is now much |
simpler and will work on all versions of PHP. |
FIX: Various bug fixes for the access rights module |
FIX: Language choice selection with MultiViews enabled didn't work |
FIX: Various small bugs introduced during 2.0 development |
FIX: Various bug fixes for the access rights module. |
FIX: Language choice selection with MultiViews enabled didn't work. |
FIX: Various small bugs introduced during 2.0 development. |
2.00 beta 6 |
Note: the $config->addRepository command now takes a URL and not a filesystem path! |
Note: $config->addRepository() now takes a URL, not a filesystem path! |
NEW: WebSVN can now host remote repositories! |
FIX: The access rights handling didn't work if you had give a repository a display name |
different from it's "real" svn name. |
FIX: The deleted file list no longer links to non-existant files! |
FIX: Neaten the directory display when the download/compare links aren't available |
FIX: The access rights handling didn't work if you had give a repository a |
display name different from it's "real" svn name. |
FIX: The deleted file list no longer links to nonexistent files. |
FIX: Tidied the directory display when download/compare links aren't available. |
2.00 beta 5 |
NEW: Access rights files can now be specified on a per repository basis |
NEW: Access rights files can now be specified on a per-repository basis. |
CHANGE: Further improvements have been made to character encoding handling. In particular, |
it is now possible to specify the encoding of the repository contents separately |
from the system encoding. This is the case for windows users, whereby the command |
line tools typically returning CP850 encoded strings, whereas the source files are |
encoded as iso-8859-1. Now, when displaying text files, WebSVN will convert them |
from the content encoding to the output encoding (UTF-8). |
CHANGE: Further improvements have been made to character encoding handling. In |
particular, it is now possible to specify the encoding of the repository |
contents separately from the system encoding. This is the case for |
Windows users; the command line tools typically returning CP850-encoded |
strings, whereas the source files are encoded as iso-8859-1. Now, when |
displaying text files, WebSVN will convert from the content encoding to |
the output encoding (UTF-8). |
CHANGE: Updated Danish translation. |
CHANGE: The log display has a "max number of revisions to show" filter option, |
which defaults to 30. This significantly improves log view performance. |
CHANGE: Update Danish translation |
CHANGE: The log display has a "max number of revisions to show" fiter option, which defaults |
to 30. This significantly improves performance of the log display. |
FIX: Correctly display the contents of a file which had brackets in the name. |
FIX: Correct problem with download of tarballs containing special characters. |
FIX: Improve time display. |
FIX: Remove non-UTF8 language options from distconfig.php. |
FIX: Fix recent bug where the log messages contained unnecessary blank lines. |
FIX: Auth file section groups without a trailing / are now treated correctly. |
FIX: It wasn't possible to display the contents of a file which had brackets in the name. |
FIX: Correct problem with download of tarballs containing special characters |
FIX: Improve time display |
FIX: Remove non-UTF8 language options from distconfig.inc |
FIX: Fix recent bug whereby the log messages would contain unnecessary blank lines |
FIX: Access right file section groups without a trailing / are no correctly treated |
2.00 beta 4 |
NEW: The log display may now be filtered to show a range of revisions |
NEW: You can now have control over the specification of directories that can or |
cannot be tarball'ed. Tarballing can be turned on only after a certain directory |
depth and directories can be allow/disallowed on a per directory/repository basis. |
NEW: The user can now choose their language via a drop down box |
NEW: The log display may now be filtered to show a range of revisions. |
NEW: You can now specify directories that can or cannot be tarballed. Tarballing |
can be enabled after only a certain directory depth, and directories can be |
(dis)allowed on a per-directory/per-repository basis. |
NEW: The user can now choose their language via a drop down box. |
CHANGE: Character encodings are now handled differently. The output encoding is ALWAYS |
defined as UTF-8, and the setOutputEncoding option has been removed. |
CHANGE: Character encodings are now handled differently. The output encoding is |
always UTF-8, and the setOutputEncoding option has been removed. |
FIX: Diff had been broken by 1.70 beta 2 |
FIX: Download of tarballs is prohibited if the user doesn't have read access to the directory |
AND all of its subdirectories |
FIX: The character set type is now sent in the HTTP header. No need to hack the Apache config |
FIX: Diff was broken by 1.70 beta 2. |
FIX: Download of a directory is prohibited if the user doesn't have read access |
to the directory AND all of its subdirectories. |
FIX: The character set type is now sent in the HTTP header automatically. |
2.00 beta 3 |
NEW: WebSVN may now be configured to display a flat view rather than a tree view |
NEW: Config option to display a flat view rather than a tree view. |
FIX: Only use --limit option on svn 1.2 or greater |
FIX: Correct spelling of "danish" in distconfig |
FIX: Fix RSS, previously broken 1.7 beta 1 |
FIX: Only use --limit option on SVN 1.2 or greater. |
FIX: Correct spelling of "danish" in distconfig.php. |
FIX: RSS was previously broken in 1.7 beta 1. |
2.00 beta 2 |
CHANGE: WebSVN no longer requires the entire revision history when accessing a directory, |
resulting in a faster access for large repositories |
CHANGE: No longer requires entire revision history when accessing a directory, |
resulting in a faster access for large repositories. |
FIX: The new access rights module didn't always hide directories |
FIX: Tree icons have been fixed (broken in 1.70 beta 1) |
FIX: The new access rights module didn't always hide directories. |
FIX: Tree icons have been fixed (broken in 1.70 beta 1). |
2.00 beta 1 |
NEW: Access rights module (Finally!) - see install.txt for details |
NEW: Added language file for Danish, Finnish, Turkish, Norwegian and Simplified Chinese |
NEW: The "View Log" link is now available for templates to use from the file view |
NEW: Added bugtraq:logregex support |
NEW: The "View Log" link is now available for templates to use in the file view. |
NEW: Added support for "bugtraq:logregex" property. |
NEW: Translations for Danish, Finnish, Turkish, Norwegian, Simplified Chinese. |
CHANGE: Ages are now displayed with higher resolution |
CHANGE: Update German translation |
CHANGE: Tex file are no longer delivered as binary by defaut, but displayed by enscript |
CHANGE: The last modified files display now shows the most recently modified files of |
the current directory |
CHANGE: Improve diff colours of Blue Grey Scheme for better readability |
CHANGE: WebSVN no longer requires the entire revision history when accessing a directory, |
resulting in a faster access for large repositories |
CHANGE: Ages are now displayed with higher resolution. |
CHANGE: Updated German translation. |
CHANGE: Text files are no longer delivered as binary by default, but displayed |
by Enscript. |
CHANGE: The last modified files display now shows the most recently modified |
files of the current directory. |
CHANGE: Improved diff colours of BlueGrey template for better readability. |
FIX: Directories containing accents weren't always displayed |
FIX: File version can be compared via the log display (as oppoed to just directories) |
FIX: Corrected RSS encoding issue |
FIX: Corrected bug whereby diff lines would be displayed twice |
FIX: svn: Can't check path '/root/.subversion': Permission denied |
FIX: Sometimes files delivered (as opposed to disaplyed) by WebSVN were empty |
FIX: Fix problem with large tarball delivery |
FIX: Compare with previous always used HEAD |
FIX: .sh files are now viewable |
FIX: Allow special characters in repository names |
FIX: It wasn't possible to go into a module if another module starts with the same name. |
FIX: Directories containing accents weren't always displayed. |
FIX: File revisions can be compared via the log display (not just directories). |
FIX: Corrected RSS encoding issue. |
FIX: Corrected bug where diff lines would be displayed twice. |
FIX: "svn: Can't check path '/root/.subversion': Permission denied" |
FIX: Sometimes files delivered (as opposed to displayed) by WebSVN were empty. |
FIX: Fix problem with large tarball delivery. |
FIX: Compare with previous always used HEAD. |
FIX: .sh files are now viewable. |
FIX: Allow special characters in repository names. |
FIX: Now able to go into a module if another module starts with the same name. |
FIX: Remove hard-coded timezone from the RSS feed creator. |
FIX: Caching of RSS feeds wasn't working |
FIX: Caching of RSS feeds wasn't working. |
1.62 |
NEW: RSS feed can now list changed files |
NEW: Templates can now show an open folder icon |
NEW: RSS feed can now list changed files. |
NEW: Templates can now show an open folder icon. |
NEW: Polish translation |
NEW: Dutch translation |
CHANGE: Window is scrolled to appropriate location when opening a new directory |
CHANGE: Window is scrolled to appropriate location when opening a new directory. |
FIX: Allow repository names containing '/' |
FIX: Fixed sloppy HTML in diff templates |
FIX: Fix problems with the diff output |
FIX: Allow repository names containing '/'. |
FIX: Fixed sloppy HTML in diff templates. |
FIX: Fix problems with the diff output. |
FIX: Repositories on Windows network shares can now be accessed. |
FIX: Accented characters weren't shown correctly in the directory comparison |
view. |
FIX: Remove error when only one revision was available |
FIX: Accented characters now display correctly in the directory comparison view. |
FIX: Remove error when only one revision was available. |
1.61 |
NEW: Multibyte encodings are considered when urlencoding path names |
NEW: Multibyte encodings are considered when urlencoding path names. |
CHANGE: The listing view will now always show the revision asked for |
(HEAD by default), but the log message will show the log |
string for the latest modification to the current directory). |
This means the the parent directory structure won't change as you |
browse through old directories. |
CHANGE: The listing view will now always show the requested revision (HEAD by |
default), but the log message will show the log string for the latest |
modification to the current directory). This means the parent directory |
structure won't change as you browse through old directories. |
FIX: A bug prevented downloading of tarballs from working |
FIX: A bug prevented downloading of tarballs from working. |
1.60 |
1.60 |
NEW: Directory displays are now shown in tree view (so that it's harder |
to get lost). Many thanks to Brent Lu for this excellent patch. |
The prettiest result are available in the BlueGrey scheme. |
NEW: Comparison of entire directories |
NEW: Directory displays are now shown in tree view (so that it's harder to get |
lost). Many thanks to Brent Lu for this excellent patch. |
NEW: Comparison of entire directories. |
NEW: Tarballs of directories may now be downloaded. |
Set $config->allowdownload(); in config.inc to allow this. |
NEW: New style 'Zinn' based on the templates created for |
http://www.projectzinn.org/. Thanks to Justin Doran. |
NEW: File delivery now looks at the defined Mime-Type. Thanks to |
Peter Valdemar Mørch for this patch. |
NEW: Various configuration options may now be applied on a per project |
basis. Look in distconfig for instructions. |
Set $config->allowdownload(); in config.php to allow this. |
NEW: New 'Zinn' template from http://projectzinn.org/. Thanks to Justin Doran. |
NEW: File delivery now looks at the defined Mime-Type. Thanks to |
Peter Valdemar Mřrch for this patch. |
NEW: Various configuration options may now be applied on a per-project basis. |
NEW: Support for using 'bugtraq' properties when display log entries. |
See http://svn.collab.net/repos/tortoisesvn/trunk/doc/issuetrackers.txt |
NEW: Traditional Chinese translation |
NEW: Spanish translation |
CHANGE: Style information removed from RSS feed |
CHANGE: Changed files are now hidden by defaut (since the directory |
CHANGE: Changed files are now hidden by default (since the directory |
comparison link is far more useful) |
FIX: File listing were't being shown with the correct accented characters |
under windows. |
FIX: File listing sometimes failed when there were spaces in the filename |
FIX: Some setups wouldn't allow diff generations with enscript |
enabled. |
FIX: Filenames are URL encoded correctly before calling svn file:/// |
FIX: Keywords weren't expanded in file view when enscript was disabled |
FIX: File listing are now shown with the correct accented characters on Windows. |
FIX: File listing sometimes failed when there were spaces in the filename. |
FIX: Some setups wouldn't allow diff generations with Enscript enabled. |
FIX: Filenames are URL encoded correctly before calling "svn file:///". |
FIX: Keywords weren't expanded in file view when Enscript was disabled. |
1.51 |
202,159 → 322,141 |
NEW: Korean translation |
NEW: Russian translation |
FIX: Repositories may now have spaces in their path (eg: c:\my reps) |
FIX: Diff now works when the file name has changed between versions |
FIX: RSS feed now generates Content-Type header for XML so that IE can display |
the contents |
FIX: Diff and Blame didn't work properly for php files when enscript wasn't used |
FIX: Use svn --non-interactive to ensure that svn doesn't prompt WebSVN for input |
FIX: Corrections to the French translation |
FIX: Display an explanatory message when the user hasn't configured any |
repository paths |
FIX: When using Multiviews, change to the WebSVN directory before executing |
commands so that tempnam works. This used to cause problems on some |
systems when running diff and blame. |
FIX: Repositories may now have spaces in their path. (eg: c:\my reps) |
FIX: Diff now works when the file name has changed between versions. |
FIX: RSS feed now generates Content-Type header for XML so IE can display it. |
FIX: Diff and blame now work properly for PHP files when Enscript isn't used. |
FIX: Use 'svn --non-interactive' so that SVN never prompts WebSVN for input. |
FIX: Corrections to the French translation. |
FIX: Display a message when no repository paths have been configured. |
FIX: Under Multiviews, change to the WebSVN directory before executing commands |
so that tempnam() works, so diff and blame work correctly on all systems. |
1.50 |
Notes: Before installing this version you should delete all the existing |
cache files. |
wsvn.php has changed. You should redo any appropriate configuration |
Notes: Before installing this version you should delete existing cache files. |
wsvn.php has changed. You should redo any appropriate configuration |
changes inside this file. |
NEW: Blame information for a file can now be viewed |
NEW: The cached files are now compressed |
NEW: The project selection box shows the current project by default |
NEW: Blame information for a file can now be viewed. |
NEW: The cached files are now compressed. |
NEW: The project selection box shows the current project by default. |
NEW: Swedish translation |
NEW: Japanese translation |
NEW: The install file explains how to set up permission based repository |
access such that access via the web interface is the same as access |
via a client (assuming Apache2). |
NEW: SVN keywords are now expanded in file listings |
NEW: The install file explains how to set up permission-based repository access, |
such that access via the web interface is the same as access via a client. |
NEW: SVN keywords are now expanded in file listings. |
CHANGE: The extraction of the directory listings is now accomplished using |
the svn command via file:/// access rather than svnlook. This has |
the advantage of being non-recursive, and thereby eliminates the need |
for caching the entire directory listing, and is much quicker on |
complex direcory structures. No more 50Mb directory caches! |
CHANGE: The extraction of the directory listings is now accomplished using the |
'svn' command via file:/// access rather than 'svnlook'. This has the |
advantage of being non-recursive, and thereby eliminates the need for |
caching the entire directory listing, and is much quicker on complex |
directory structures. (Also, no more 50MB directory caches!) |
FIX: Deleted directories are now viewable. |
FIX: SHOWALL was being redefined in the language files |
FIX: The directory listing view sometimes showed [lang:DELETEDFILES |
FIX: SHOWALL was being redefined in the language files. |
FIX: The directory listing view sometimes showed [lang:DELETEDFILES]. |
FIX: Under Windows, links in the RSS output would start with "\" if WebSVN |
was installed in the server's root directory. |
FIX: Sed wouldn't work under all versions of Windows due to the use of single |
quotes around the paramters |
quotes around the parameters. |
FIX: Improved character encoding support for log messages etc. |
FIX: Paths passed by URL are encoded |
FIX: Generated HTML code is strictly 4.01 |
FIX: Paths passed by URL are encoded. |
FIX: Generated HTML code is strictly 4.01. |
1.40 |
NEW: RSS feed support (thanks to Lübbe Onken for his work on this) |
NEW: Translatations for French and Portuguese |
NEW: .exe is recognised by default as having content-type |
application/x-msdownload |
NEW: Recognised links are now 'linkified' in the log messages |
NEW: Tabs in file/diff listings are now expanded by a user |
configurable number of spaces. |
NEW: WebSVN URLs now access the repository by name rather than number. |
This means that bookmarks will stay the same when new projects |
are added. The old behaviour can be configured in config.inc. |
NEW: RSS feed support. (Thanks to Lübbe Onken for his work on this.) |
NEW: Translatations for French and Portuguese. |
NEW: .exe files now default to content-type "application/x-msdownload". |
NEW: Recognised links are now 'linkified' in the log messages. |
NEW: Option to change number of spaces to use for tabs in file/diff listings. |
NEW: URLs now access the repository by name rather than number. This means that |
bookmarks will stay the same when new projects are added. The old behaviour |
can be configured in config.php. |
FIX: Removed the revision 0 that has appeared since the previous version |
FIX: Repositories were not sorted alphabetically when using ParentPath |
FIX: The PNG support script needed for IE (and the BlueGrey scheme) is |
now only loaded with IE |
FIX: Removed the revision 0 that has appeared since the previous version. |
FIX: Repositories were not sorted alphabetically when using ParentPath. |
FIX: The PNG support script (and the BlueGrey scheme) is now only loaded for IE. |
1.39 |
CHANGE: In the human-readable date strings, display up to 119 minutes, |
47 hours, 13 days or 23 months before moving up to the next |
quantity, like ViewCVS. |
CHANGE: In the human-readable date strings, display up to 119 minutes, 47 hours, |
13 days or 23 months before moving up to the next unit, like ViewCVS. |
FIX: Links followed after viewing the contents of a file go to the |
revision of the repository previously being viewed |
FIX: Paths with spaces are now correctly showed in the log view |
FIX: Blank lines in the diff output are set to so the browser |
won't compress them |
FIX: Links from file detail view now go to the current (not previous) revision. |
FIX: Paths with spaces are now correctly showed in the log view. |
FIX: Blank lines in diff output are set to so browsers will display them. |
FIX: A blank author field is set to an cell. |
FIX: A year is 365 days, not 356. |
FIX: Base ages correctly upon GMT |
FIX: The diff output did not escape html entities when enscript was |
enabled and the file extension was not recognised for enscript. |
FIX: distconfig.inc has a few minor errors in the examples. |
FIX: It wasn't possible to call ParentPath multiple times |
FIX: Base ages correctly upon GMT. |
FIX: The diff output did not escape html entities when Enscript was enabled and |
the file extension was not recognised for Enscript. |
FIX: distconfig.php had a few minor errors in the examples. |
FIX: It wasn't possible to call ParentPath multiple times. |
1.38 |
NEW: Templates can now define icons for particular file types |
(see BlueGrey scheme for an example) |
NEW: Display of PHP files with syntax highlighting |
NEW: Improve site navigation with links to each directory level on all |
pages. |
NEW: Templates can now define icons for particular file types (see BlueGrey). |
NEW: Display of PHP files with syntax highlighting. |
NEW: Improve site navigation with links to each directory level on all pages. |
1.37 |
NEW: Display a message when there are no results found |
NEW: Display a message when there are no results found. |
CHANGE: Aesthetic changes to the BlueGrey scheme |
CHANGE: Sort entries more naturally |
CHANGE: Aesthetic changes to the BlueGrey scheme. |
CHANGE: Sort entries more naturally. |
FIX: Really make sure that we redirect to the right place when using the |
drop-down box to select projects. |
FIX: Nested [webtest]'s didn't always work |
FIX: Fixed use of "standard" and "Standard", which caused problems on |
non-windows machines |
FIX: Redirect to the right URL when using the drop-down box to select projects. |
FIX: Nested [websvn-test] elements didn't always work. |
FIX: Fixed use of "standard" vs "Standard", problematic on non-Windows machines. |
1.36 |
NEW: Log message search feature |
NEW: Diff display tries to display changed lines as changed, rather than |
showing the line deleted then added. |
NEW: Log message search feature. |
NEW: Diff display tries to display changed lines as changed, rather than showing |
the line as deleted then added. |
FIX: Problem surrounding the quoting of commands and command line arguments |
on Windows machines. |
FIX: Problem with quoting of commands and command line arguments on Windows. |
1.35 |
NEW: You can now specify a list of file types (extensions) for files which |
should be delivered to the user in a GZIP'd archive rather than |
displayed as ASCII in the browser window. |
NEW: You can now specify a list of file types (extensions) for files that should |
be delivered to the user in a GZIP'd archive rather than displayed as ASCII |
in the browser window. |
CHANGE: Files delived with a MIME Content type are now sent as "inline". |
The browser will try to display them in the browser window, offering |
a save box only if they can't be displayed in this mannor. |
CHANGE: Files delivered with a MIME Content type are now sent as "inline". The |
browser will try to display them in the browser window, offering a save |
box only if they can't be displayed in this manner. |
FIX: Detect use of the HTTPS protocol when using the drop-down box to |
select projects. (-- FIX INCORRECT. USE v1.36 -- ) |
FIX: The PNGs in the BlueGrey style are now transparent under Internet |
Explorer 5.5 and higher. |
FIX: Detect use of the HTTPS protocol when using the drop-down box to select |
projects. (-- FIX INCORRECT. USE v1.36 -- ) |
FIX: The PNGs in the BlueGrey style are now transparent under IE 5.5 and higher. |
1.34 |
NEW: Support for switching between projects using a drop-down box control |
(MultiViews users - note that wsvn.php has been changed) |
NEW: Sort the repositories alphabetically when using parentPath |
NEW: Better support for internationalisation |
(Template writers: Please note the use of the new variable 'charset') |
NEW: More useful info in browser titles with the standard templates |
NEW: Support for switching between projects using a drop-down box control. |
(MultiViews users - note that wsvn.php has been changed.) |
NEW: Sort the repositories alphabetically when using parentPath. |
NEW: Better support for internationalisation. |
(Template writers: Please note the use of the new variable 'charset'.) |
NEW: More useful info in browser titles with the standard templates. |
FIX: Accented characters should now be displayed correctly (I hope). |
FIX: HTML files now display correcly on all machines |
FIX: Removed spurious BRs from the file listings |
FIX: HTML files now display correctly on all machines. |
FIX: Removed spurious BRs from the file listings. |
1.33 |
There are a few changes to the config file in this release. Copy |
distconfig.inc to config.inc and redo any configuration changes that you |
had made. |
There are a few changes to the config file in this release. Copy distconfig.php |
to config.php and redo any configuration changes that you had made. |
NEW: Recognised non-text files are now delivered to the user as attachments. |
The list of files types to be sent back to the user (rather than displayed |
using WebSVN) is user configurable. |
NEW: File comparisons are now colourised based on the file extension |
NEW: The list of files types to be sent to the user (rather than displayed with |
WebSVN) is now user-configurable. |
NEW: File comparisons are now colourised based on the file extension. |
CHANGE: Only the Enscript file extensions that the user wishes to override are |
now listed in the config file. |
361,102 → 463,94 |
1.32 |
FIX: Links no longer functionned correctly when used in basic |
(non-multiviews) mode. |
FIX: Links now function correctly when used in basic (not multiviews) mode. |
FIX: Stop diff from comparing space changes |
1.31 |
FIX: Directory view had disappeared! |
FIX: Included missing file setup.inc |
FIX: Handle spaces in filenames |
FIX: Included missing setup.php file. |
FIX: Handle spaces in filenames. |
1.30 |
There are a few changes to the config file in this release. Copy |
distconfig.inc to config.inc and redo any configuration changes that you |
had made. |
There are a few changes to the config file in this release. Copy distconfig.php |
to config.php and redo any configuration changes that you had made. |
NEW: MultiViews support. You can now set up WebSVN to access the |
repositories using a URL such as: |
NEW: MultiViews support allows access to repositories using a URL such as: |
http://server/wsvn/repname/path/to/rep |
NEW: Colourisation support using Enscript |
NEW: [websvn-test] function can now be nested |
NEW: locwebsvnhttp variable added in template system |
NEW: Bluegrey scheme now has show/hide changed link |
NEW: Colourisation support using Enscript. |
NEW: [websvn-test] function can now be nested. |
NEW: locwebsvnhttp variable added in template system. |
NEW: BlueGrey scheme now has show/hide changed link. |
FIX: Possible security hole with abuse of popen |
FIX: WebSVN should now function correctly (again) on non windows servers. |
FIX: First character of diff listing was missing |
FIX: Possible security hole with abuse of popen(). |
FIX: Should now function correctly (again) on non-Windows servers. |
FIX: First character of diff listing was missing. |
1.20 |
NEW: Comprehensive templating solution |
NEW: Show the age of a revision in the log view |
NEW: Comprehensive templating solution. |
NEW: Show the age of a revision in the log view. |
CHANGE: The youngest revision of the current directory is now shown by |
default (as opposed to the head revision of the entire repository. |
This means that clicking on a directory will show the lastest |
changes associated with it. A specific revision can still be |
selected from a log view |
CHANGE: The youngest revision of the current directory is now shown by default |
(as opposed to the head revision of the entire repository). This means |
that clicking a directory shows the latest changes associated with it. |
Specific revisions can still be selected from a log view. |
CHANGE: Only show the leaf name when viewing directory contents |
FIX: Fixed error concerning use of pclose |
FIX: Fixed error concerning use of pclose() |
1.10/1.10a |
There are a few changes to the config file in this release. Copy |
distconfig.inc to config.inc and redo any configuration changes that you |
had made. |
There are a few changes to the config file in this release. Copy distconfig.php |
to config.php and redo any configuration changes that you had made. |
NEW: WebSVN now caches information on the repositories. Once a revision |
has been viewed subsequent revisions use the cached infomation to |
display the directory structure. This significantly improves the |
browsing speed. |
NEW: WebSVN now caches information on the repositories. Once a revision has been |
viewed, subsequent revisions use the cached information to display the |
directory structure. This significantly improves the browsing speed. |
NEW: German language file (thanks to Stephan Stapel) |
1.04/1.04a |
Please note that the config file is now stored in include/ |
Please note that the config file is now stored in the "include" subdirectory. |
FIX: Directories in the log view lacked their trailing slashes. |
FIX: Diff is now far more efficient with Apache's memory, |
and shows the corrrect line numbers. |
FIX: Diff is now far more memory-efficient, and shows the correct line numbers. |
FIX: setDiffPath now works. |
FIX: Bug introduced in 1.03 whereby the revision number always showed '1' |
corrected. |
FIX: Bug introduced in 1.03 whereby the revision number always showed '1'. |
Note that you can't view logs with 1.04! Use 1.04a. |
Note that you can't view logs with 1.04! Use 1.04a instead. |
1.03 |
Note that the config.inc file has completely changed in this release, in |
order to make it more "future proof" and resiliant. You'll need to copy |
distconfig.inc to config.inc redo the appropriate changes are described. |
Note that the config.php file has completely changed in this release, in order |
to make it more "future proof" and resilient. You'll need to copy distconfig.php |
to config.php redo the appropriate changes as described. |
NEW: A 'ParentPath' can now be specified, rather than having to specify the |
directories by hand. |
FIX: Rewrite of the file list code. Should now be quite a bit faster |
FIX: Use a more memory efficient algorithm to list file contents |
FIX: Spaces in Windows path to svnlook and diff are now handled properly |
FIX: Calls to external commands such as svnlook no longer require Windows |
style line endings. |
FIX: Rewrite of the file list code. Should now be quite a bit faster. |
FIX: Use a more memory efficient algorithm to list file contents. |
FIX: Spaces in Windows path to svnlook and diff are now handled properly. |
FIX: Calls to external commands such as svnlook no longer require Windows-style |
line endings. |
1.02 |
NEW: Improved command handling to report returned errors. Considerably helps |
NEW: Improved command handling to report returned errors. Considerably helps |
initial installation problems. |
NEW: Show the author of each revision in the log view |
NEW: Show the author of each revision in the log view. |
FIX: Removed the spurious   that some people were seeing |
FIX: Removed the spurious that some people were seeing. |
1.01 (5 Feb 2004) |
FIX: Files with HTML content are now shown correcty |
FIX: The diff output had the revision lables the wrong way round |
FIX: Files with HTML content are now shown correctly. |
FIX: The diff output had the revision labels the wrong way round. |
1.00 (4 Feb 2004) |
/WebSVN/comp.php |
---|
1,8 → 1,6 |
<?php |
# vim:et:ts=3:sts=3:sw=3:fdm=marker: |
// WebSVN - Subversion repository viewing via the web using PHP |
// Copyright © 2004-2006 Tim Armes, Matt Sicker |
// Copyright (C) 2004-2006 Tim Armes |
// |
// This program is free software; you can redistribute it and/or modify |
// it under the terms of the GNU General Public License as published by |
11,345 → 9,618 |
// |
// This program is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License |
// along with this program; if not, write to the Free Software |
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
// |
// -- |
// |
// comp.php |
// |
// Compare two paths using "svn diff" |
// Compare two paths using `svn diff` |
// |
require_once("include/setup.inc"); |
require_once("include/svnlook.inc"); |
require_once("include/utils.inc"); |
require_once("include/template.inc"); |
require_once 'include/setup.php'; |
require_once 'include/svnlook.php'; |
require_once 'include/utils.php'; |
require_once 'include/template.php'; |
$svnrep = new SVNRepository($rep); |
function checkRevision($rev) |
{ |
if (is_numeric($rev) && ((int)$rev > 0)) |
{ |
return $rev; |
} |
return 'HEAD'; |
} |
function checkRevision($rev) |
// Make sure that we have a repository |
if (!$rep) |
{ |
if (is_numeric($rev) && ((int)$rev > 0)) |
return $rev; |
$rev = strtoupper($rev); |
switch($rev) |
{ |
case "HEAD": |
case "PREV": |
case "COMMITTED": |
return $rev; |
} |
return "HEAD"; |
renderTemplate404('compare','NOREP'); |
} |
$svnrep = new SVNRepository($rep); |
// Retrieve the request information |
$path1 = @$_REQUEST["compare"][0]; |
$path2 = @$_REQUEST["compare"][1]; |
$rev1 = @$_REQUEST["compare_rev"][0]; |
$rev2 = @$_REQUEST["compare_rev"][1]; |
$path1 = @$_REQUEST['compare'][0]; |
$path2 = @$_REQUEST['compare'][1]; |
$rev1 = (int)@$_REQUEST['compare_rev'][0]; |
$rev2 = (int)@$_REQUEST['compare_rev'][1]; |
$manualorder = (@$_REQUEST['manualorder'] == 1); |
$ignoreWhitespace = $config->getIgnoreWhitespacesInDiff(); |
if (array_key_exists('ignorews', $_REQUEST)) |
{ |
$ignoreWhitespace = (bool)$_REQUEST['ignorews']; |
} |
// Some page links put the revision with the path... |
if (strpos($path1, "@")) list($path1, $rev1) = explode("@", $path1); |
if (strpos($path2, "@")) list($path2, $rev2) = explode("@", $path2); |
if ($path1 && strpos($path1, '@')) |
{ |
list($path1, $rev1) = explode('@', $path1); |
} |
else if ($path1 && (strpos($path1, '@') === 0)) |
{ |
// Something went wrong. The path is missing. |
$rev1 = substr($path1, 1); |
$path1 = '/'; |
} |
if ($path2 && strpos($path2, '@')) |
{ |
list($path2, $rev2) = explode('@', $path2); |
} |
else if ($path2 && (strpos($path2, '@') === 0)) |
{ |
$rev2 = substr($path2, 1); |
$path2 = '/'; |
} |
$rev1 = checkRevision($rev1); |
$rev2 = checkRevision($rev2); |
// Choose a sensible comparison order unless told not to |
if (!@$_REQUEST["manualorder"] && is_numeric($rev1) && is_numeric($rev2)) |
if (!$manualorder && is_numeric($rev1) && is_numeric($rev2) && $rev1 > $rev2) |
{ |
if ($rev1 > $rev2) |
{ |
$temppath = $path1; |
$temprev = $rev1; |
$path1 = $path2; |
$rev1 = $rev2; |
$path2 = $temppath; |
$rev2 = $temprev; |
} |
$temppath = $path1; |
$path1 = $path2; |
$path2 = $temppath; |
$temprev = $rev1; |
$rev1 = $rev2; |
$rev2 = $temprev; |
} |
$url = $config->getURL($rep, "/", "comp"); |
$vars["revlink"] = "<a href=\"${url}compare%5B%5D=".urlencode($path2)."@$rev2&compare%5B%5D=".urlencode($path1)."@$rev1&manualorder=1\">${lang["REVCOMP"]}</a>"; |
$vars['rev1url'] = $config->getURL($rep, $path1, 'dir').createRevAndPegString($rev1, $rev1); |
$vars['rev2url'] = $config->getURL($rep, $path2, 'dir').createRevAndPegString($rev2, $rev2); |
if ($rev1 == 0) $rev1 = "HEAD"; |
if ($rev2 == 0) $rev2 = "HEAD"; |
$url = $config->getURL($rep, '', 'comp'); |
$vars['reverselink'] = '<a href="'.$url.'compare%5B%5D='.rawurlencode($path2 ?? '').'@'.$rev2.'&compare%5B%5D='.rawurlencode($path1 ?? '').'@'.$rev1.'&manualorder=1'.($ignoreWhitespace ? '&ignorews=1' : '').'">'.$lang['REVCOMP'].'</a>'; |
$toggleIgnoreWhitespace = ''; |
$vars["repname"] = $rep->getDisplayName(); |
$vars["action"] = $lang["PATHCOMPARISON"]; |
$vars["compare_form"] = "<form action=\"$url\" method=\"post\" name=\"compareform\">"; |
$vars["compare_path1input"] = "<input type=\"text\" size=\"40\" name=\"compare[0]\" value=\"$path1\" />"; |
$vars["compare_rev1input"] = "<input type=\"text\" size=\"5\" name=\"compare_rev[0]\" value=\"$rev1\" />"; |
$vars["compare_path2input"] = "<input type=\"text\" size=\"40\" name=\"compare[1]\" value=\"$path2\" />"; |
$vars["compare_rev2input"] = "<input type=\"text\" size=\"5\" name=\"compare_rev[1]\" value=\"$rev2\" />"; |
$vars["compare_submit"] = "<input name=\"comparesubmit\" type=\"submit\" value=\"${lang["COMPAREPATHS"]}\" />"; |
$vars["compare_endform"] = "<input type=\"hidden\" name=\"op\" value=\"comp\" /><input type=\"hidden\" name=\"manualorder\" value=\"1\" /><input type=\"hidden\" name=\"sc\" value=\"$showchanged\" /></form>"; |
if ($ignoreWhitespace == $config->getIgnoreWhitespacesInDiff()) |
{ |
$toggleIgnoreWhitespace = '&ignorews='.($ignoreWhitespace ? '0' : '1'); |
} |
# safe paths are a hack for fixing XSS sploit |
$vars["path1"] = $path1; |
$vars['safepath1'] = htmlentities($path1); |
$vars["path2"] = $path2; |
$vars['safepath2'] = htmlentities($path2); |
if (!$ignoreWhitespace) |
{ |
$vars['ignorewhitespacelink'] = '<a href="'.$url.'compare%5B%5D='.rawurlencode($path1 ?? '').'@'.$rev1.'&compare%5B%5D='.rawurlencode($path2 ?? '').'@'.$rev2.($manualorder ? '&manualorder=1' : '').$toggleIgnoreWhitespace.'">'.$lang['IGNOREWHITESPACE'].'</a>'; |
} |
else |
{ |
$vars['regardwhitespacelink'] = '<a href="'.$url.'compare%5B%5D='.rawurlencode($path1 ?? '').'@'.$rev1.'&compare%5B%5D='.rawurlencode($path2 ?? '').'@'.$rev2.($manualorder ? '&manualorder=1' : '').$toggleIgnoreWhitespace.'">'.$lang['REGARDWHITESPACE'].'</a>'; |
} |
$vars["rev1"] = $rev1; |
$vars["rev2"] = $rev2; |
if ($rev1 == 0) $rev1 = 'HEAD'; |
if ($rev2 == 0) $rev2 = 'HEAD'; |
$vars['repname'] = escape($rep->getDisplayName()); |
$vars['action'] = $lang['PATHCOMPARISON']; |
$hidden = '<input type="hidden" name="manualorder" value="1" />'; |
if ($config->multiViews) |
{ |
$hidden .= '<input type="hidden" name="op" value="comp"/>'; |
} |
else |
{ |
$hidden .= '<input type="hidden" name="repname" value="'.$repname.'" />'; |
} |
$vars['compare_form'] = '<form method="get" action="'.$url.'" id="compare">'.$hidden; |
$vars['compare_path1input'] = '<input type="text" size="40" name="compare[0]" value="'.escape($path1).'" />'; |
$vars['compare_path2input'] = '<input type="text" size="40" name="compare[1]" value="'.escape($path2).'" />'; |
$vars['compare_rev1input'] = '<input type="text" size="5" name="compare_rev[0]" value="'.$rev1.'" />'; |
$vars['compare_rev2input'] = '<input type="text" size="5" name="compare_rev[1]" value="'.$rev2.'" />'; |
$vars['compare_submit'] = '<input name="comparesubmit" type="submit" value="'.$lang['COMPAREPATHS'].'" />'; |
$vars['compare_endform'] = '</form>'; |
$vars['safepath1'] = escape($path1); |
$vars['safepath2'] = escape($path2); |
$vars['rev1'] = $rev1; |
$vars['rev2'] = $rev2; |
$history1 = $svnrep->getLog($path1, $rev1, 0, false, 1); |
if (!$history1) |
{ |
renderTemplate404('compare','NOPATH'); |
} |
else |
{ |
$history2 = $svnrep->getLog($path2, $rev2, 0, false, 1); |
if (!$history2) |
{ |
renderTemplate404('compare','NOPATH'); |
} |
} |
// Set variables used for the more recent of the two revisions |
$history = ($rev1 >= $rev2 ? $history1 : $history2); |
if ($history && $history->curEntry) |
{ |
$logEntry = $history->curEntry; |
$vars['rev'] = $logEntry->rev; |
$vars['peg'] = $peg; |
$vars['date'] = $logEntry->date; |
$vars['age'] = datetimeFormatDuration(time() - strtotime($logEntry->date)); |
$vars['author'] = $logEntry->author; |
$vars['log'] = xml_entities($logEntry->msg); |
} |
else |
{ |
$vars['warning'] = 'Problem with comparison.'; |
} |
$noinput = empty($path1) || empty($path2); |
$listing = array(); |
// Generate the diff listing |
$path1 = encodepath(str_replace(DIRECTORY_SEPARATOR, "/", $svnrep->repConfig->path.$path1)); |
$path2 = encodepath(str_replace(DIRECTORY_SEPARATOR, "/", $svnrep->repConfig->path.$path2)); |
$relativePath1 = $path1; |
$relativePath2 = $path2; |
$svnpath1 = encodepath($svnrep->getSvnPath(str_replace(DIRECTORY_SEPARATOR, '/', $path1 ?? ''))); |
$svnpath2 = encodepath($svnrep->getSvnPath(str_replace(DIRECTORY_SEPARATOR, '/', $path2 ?? ''))); |
$debug = false; |
if (!$noinput) |
if (!$noinput) |
{ |
$rawcmd = $config->svn." diff ".$rep->svnParams().quote($path1."@".$rev1)." ".quote($path2."@".$rev2); |
$cmd = quoteCommand($rawcmd, true); |
if ($debug) echo "$cmd\n"; |
$cmd = $config->getSvnCommand().$rep->svnCredentials().' diff '.($ignoreWhitespace ? '-x "-w --ignore-eol-style" ' : '').quote($svnpath1.'@'.$rev1).' '.quote($svnpath2.'@'.$rev2); |
} |
function clearVars() |
function clearVars() |
{ |
global $listing, $index; |
$listing[$index]["newpath"] = null; |
$listing[$index]["endpath"] = null; |
$listing[$index]["info"] = null; |
$listing[$index]["diffclass"] = null; |
$listing[$index]["difflines"] = null; |
$listing[$index]["enddifflines"] = null; |
$listing[$index]["properties"] = null; |
} |
global $ignoreWhitespace, $listing, $index; |
$vars["success"] = false; |
if ($ignoreWhitespace && $index > 1) |
{ |
$endBlock = false; |
$previous = $index - 1; |
if ($listing[$previous]['endpath']) $endBlock = 'newpath'; |
else if ($listing[$previous]['enddifflines']) $endBlock = 'difflines'; |
if (!$noinput) |
{ |
if ($diff = popen($cmd, "r")) |
{ |
$index = 0; |
$indiff = false; |
$indiffproper = false; |
$getLine = true; |
$node = null; |
$vars["success"] = true; |
while (!feof($diff)) |
{ |
if ($getLine) |
$line = fgets($diff); |
clearVars(); |
$getLine = true; |
if ($debug) print "Line = '$line'<br />" ; |
if ($indiff) |
{ |
// If we're in a diff proper, just set up the line |
if ($indiffproper) |
{ |
if ($line[0] == " " || $line[0] == "+" || $line[0] == "-") |
{ |
switch ($line[0]) |
{ |
case " ": |
$listing[$index]["diffclass"] = "diff"; |
$subline = hardspace(replaceEntities(rtrim(substr($line, 1)), $rep)); |
if (empty($subline)) $subline = " "; |
$listing[$index++]["line"] = $subline; |
if ($debug) print "Including as diff: $subline<br />"; |
break; |
case "+": |
$listing[$index]["diffclass"] = "diffadded"; |
$subline = hardspace(replaceEntities(rtrim(substr($line, 1)), $rep)); |
if (empty($subline)) $subline = " "; |
$listing[$index++]["line"] = $subline; |
if ($debug) print "Including as added: $subline<br />"; |
break; |
case "-": |
$listing[$index]["diffclass"] = "diffdeleted"; |
$subline = hardspace(replaceEntities(rtrim(substr($line, 1)), $rep)); |
if (empty($subline)) $subline = " "; |
$listing[$index++]["line"] = $subline; |
if ($debug) print "Including as removed: $subline<br />"; |
break; |
} |
continue; |
} |
else |
{ |
$indiffproper = false; |
$listing[$index++]["enddifflines"] = true; |
$getLine = false; |
if ($debug) print "Ending lines<br />"; |
continue; |
} |
} |
// Check for the start of a new diff area |
if (!strncmp($line, "@@", 2)) |
{ |
$pos = strpos($line, "+"); |
$posline = substr($line, $pos); |
sscanf($posline, "+%d,%d", $sline, $eline); |
if ($debug) print "sline = '$sline', eline = '$eline'<br />"; |
// Check that this isn't a file deletion |
if ($sline == 0 && $eline == 0) |
{ |
$line = fgets($diff); |
if ($debug) print "Ignoring: $line<br />" ; |
while ($line[0] == " " || $line[0] == "+" || $line[0] == "-") |
{ |
$line = fgets($diff); |
if ($debug) print "Ignoring: $line<br />" ; |
} |
$getLine = false; |
if ($debug) print "Unignoring previous - marking as deleted<b>"; |
$listing[$index++]["info"] = $lang["FILEDELETED"]; |
} |
else |
{ |
$listing[$index++]["difflines"] = $line; |
$indiffproper = true; |
} |
continue; |
} |
else |
{ |
$indiff = false; |
if ($debug) print "Ending diff"; |
} |
} |
// Check for a new node entry |
if (strncmp(trim($line), "Index: ", 7) == 0) |
{ |
// End the current node |
if ($node) |
{ |
$listing[$index++]["endpath"] = true; |
clearVars(); |
} |
$node = trim($line); |
$node = substr($node, 7); |
$listing[$index]["newpath"] = $node; |
if ($debug) echo "Creating node $node<br />"; |
// Skip past the line of ='s |
$line = fgets($diff); |
if ($debug) print "Skipping: $line<br />" ; |
// Check for a file addition |
$line = fgets($diff); |
if ($debug) print "Examining: $line<br />" ; |
if (strpos($line, "(revision 0)")) |
$listing[$index]["info"] = $lang["FILEADDED"]; |
if (strncmp(trim($line), "Cannot display:", 15) == 0) |
{ |
$index++; |
clearVars(); |
$listing[$index++]["info"] = $line; |
continue; |
} |
// Skip second file info |
$line = fgets($diff); |
if ($debug) print "Skipping: $line<br />" ; |
$indiff = true; |
$index++; |
continue; |
} |
if (strncmp(trim($line), "Property changes on: ", 21) == 0) |
{ |
$propnode = trim($line); |
$propnode = substr($propnode, 21); |
if ($debug) print "Properties on $propnode (cur node $ $node)"; |
if ($propnode != $node) |
{ |
if ($node) |
{ |
$listing[$index++]["endpath"] = true; |
clearVars(); |
} |
$node = $propnode; |
$listing[$index++]["newpath"] = $node; |
clearVars(); |
} |
$listing[$index++]["properties"] = true; |
clearVars(); |
if ($debug) echo "Creating node $node<br />"; |
// Skip the row of underscores |
$line = fgets($diff); |
if ($debug) print "Skipping: $line<br />" ; |
while ($line = trim(fgets($diff))) |
{ |
$listing[$index++]["info"] = $line; |
clearVars(); |
} |
continue; |
} |
// Check for error messages |
if (strncmp(trim($line), "svn: ", 5) == 0) |
{ |
$listing[$index++]["info"] = urldecode($line); |
$vars["success"] = false; |
continue; |
} |
$listing[$index++]["info"] = $line; |
} |
if ($node) |
{ |
clearVars(); |
$listing[$index++]["endpath"] = true; |
} |
if ($debug) print_r($listing); |
} |
if ($endBlock !== false) |
{ |
// check if block ending at previous contains real diff data |
$i = $previous; |
$containsOnlyEqualDiff = true; |
$addedLines = array(); |
$removedLines = array(); |
while ($i >= 0 && !$listing[$i - 1][$endBlock]) |
{ |
$diffclass = $listing[$i - 1]['diffclass']; |
if ($diffclass !== 'diffadded' && $diffclass !== 'diffdeleted') |
{ |
if ($addedLines !== $removedLines) |
{ |
$containsOnlyEqualDiff = false; |
break; |
} |
} |
if (count($addedLines) > 0 && $addedLines === $removedLines) |
{ |
$addedLines = array(); |
$removedLines = array(); |
} |
if ($diffclass === 'diff') |
{ |
$i--; |
continue; |
} |
if ($diffclass === null) |
{ |
$containsOnlyEqualDiff = false; |
break;; |
} |
if ($diffclass === 'diffdeleted') |
{ |
if (count($addedLines) <= count($removedLines)) |
{ |
$containsOnlyEqualDiff = false; |
break;; |
} |
array_unshift($removedLines, $listing[$i - 1]['line']); |
$i--; |
continue; |
} |
if ($diffclass === 'diffadded') |
{ |
if (count($removedLines) > 0) |
{ |
$containsOnlyEqualDiff = false; |
break;; |
} |
array_unshift($addedLines, $listing[$i - 1]['line']); |
$i--; |
continue; |
} |
assert(false); |
} |
if ($containsOnlyEqualDiff) |
{ |
$containsOnlyEqualDiff = $addedLines === $removedLines; |
} |
// remove blocks which only contain diffclass=diff and equal removes and adds |
if ($containsOnlyEqualDiff) |
{ |
for ($j = $i - 1; $j < $index; $j++) |
{ |
unset($listing[$j]); |
} |
$index = $i - 1; |
} |
} |
} |
$listvar = &$listing[$index]; |
$listvar['newpath'] = null; |
$listvar['endpath'] = null; |
$listvar['info'] = null; |
$listvar['diffclass'] = null; |
$listvar['difflines'] = null; |
$listvar['enddifflines'] = null; |
$listvar['properties'] = null; |
} |
$vars["version"] = $version; |
$vars['success'] = false; |
if (!$rep->hasUnrestrictedReadAccess($path1) || !$rep->hasUnrestrictedReadAccess($path2, false)) |
$vars["noaccess"] = true; |
if (!$noinput) |
{ |
// TODO: Report warning/error if comparison encounters any problems |
if ($diff = popenCommand($cmd, 'r')) |
{ |
$listing = array(); |
$index = 0; |
$indiff = false; |
$indiffproper = false; |
$getLine = true; |
$node = null; |
$bufferedLine = false; |
parseTemplate($rep->getTemplatePath()."header.tmpl", $vars, $listing); |
parseTemplate($rep->getTemplatePath()."compare.tmpl", $vars, $listing); |
parseTemplate($rep->getTemplatePath()."footer.tmpl", $vars, $listing); |
?> |
$vars['success'] = true; |
while (!feof($diff)) |
{ |
if ($getLine) |
{ |
if ($bufferedLine === false) |
{ |
$bufferedLine = rtrim(fgets($diff), "\n\r"); |
} |
$newlineR = strpos($bufferedLine, "\r"); |
$newlineN = strpos($bufferedLine, "\n"); |
if ($newlineR === false && $newlineN === false) |
{ |
$line = $bufferedLine; |
$bufferedLine = false; |
} |
else |
{ |
$newline = ($newlineR < $newlineN ? $newlineR : $newlineN); |
$line = substr($bufferedLine, 0, $newline); |
$bufferedLine = substr($bufferedLine, $newline + 1); |
} |
} |
clearVars(); |
$getLine = true; |
if ($debug) print 'Line = "'.$line.'"<br />'; |
if ($indiff) |
{ |
// If we're in a diff proper, just set up the line |
if ($indiffproper) |
{ |
if (strlen($line) > 0 && ($line[0] == ' ' || $line[0] == '+' || $line[0] == '-')) |
{ |
$subline = escape(toOutputEncoding(substr($line, 1))); |
$subline = rtrim($subline, "\n\r"); |
$subline = ($subline) ? expandTabs($subline) : ' '; |
$listvar = &$listing[$index]; |
$listvar['line'] = $subline; |
switch ($line[0]) |
{ |
case ' ': |
$listvar['diffclass'] = 'diff'; |
if ($debug) print 'Including as diff: '.$subline.'<br />'; |
break; |
case '+': |
$listvar['diffclass'] = 'diffadded'; |
if ($debug) print 'Including as added: '.$subline.'<br />'; |
break; |
case '-': |
$listvar['diffclass'] = 'diffdeleted'; |
if ($debug) print 'Including as removed: '.$subline.'<br />'; |
break; |
} |
$index++; |
} |
else if ($line != '\ No newline at end of file') |
{ |
$indiffproper = false; |
$listing[$index++]['enddifflines'] = true; |
$getLine = false; |
if ($debug) print 'Ending lines<br />'; |
} |
continue; |
} |
// Check for the start of a new diff area |
if (!strncmp($line, '@@', 2)) |
{ |
$pos = strpos($line, '+'); |
$posline = substr($line, $pos); |
$sline = 0; |
$eline = 0; |
sscanf($posline, '+%d,%d', $sline, $eline); |
if ($debug) print 'sline = "'.$sline.'", eline = "'.$eline.'"<br />'; |
// Check that this isn't a file deletion |
if ($sline == 0 && $eline == 0) |
{ |
$line = fgets($diff); |
if ($debug) print 'Ignoring: "'.$line.'"<br />'; |
while ($line && ($line[0] == ' ' || $line[0] == '+' || $line[0] == '-')) |
{ |
$line = fgets($diff); |
if ($debug) print 'Ignoring: "'.$line.'"<br />'; |
} |
$getLine = false; |
if ($debug) print 'Unignoring previous - marking as deleted<br />'; |
$listing[$index++]['info'] = $lang['FILEDELETED']; |
} |
else |
{ |
$listvar = &$listing[$index]; |
$listvar['difflines'] = $line; |
$sline = 0; |
$slen = 0; |
$eline = 0; |
$elen = 0; |
sscanf($line, '@@ -%d,%d +%d,%d @@', $sline, $slen, $eline, $elen); |
$listvar['rev1line'] = $sline; |
$listvar['rev1len'] = $slen; |
$listvar['rev2line'] = $eline; |
$listvar['rev2len'] = $elen; |
$indiffproper = true; |
$index++; |
} |
continue; |
} |
else |
{ |
$indiff = false; |
if ($debug) print 'Ending diff'; |
} |
} |
// Check for a new node entry |
if (strncmp(trim($line), 'Index: ', 7) == 0) |
{ |
// End the current node |
if ($node) |
{ |
$listing[$index++]['endpath'] = true; |
clearVars(); |
} |
$node = trim(toOutputEncoding($line)); |
$node = substr($node, 7); |
if ($node == '' || $node[0] != '/') $node = '/'.$node; |
if (substr($path2, -strlen($node)) === $node) |
{ |
$absnode = $path2; |
} |
else |
{ |
$absnode = $path2; |
if (substr($absnode, -1) == '/') $absnode = substr($absnode, 0, -1); |
$absnode .= $node; |
} |
$listvar = &$listing[$index]; |
$listvar['newpath'] = escape($absnode); |
$listvar['fileurl'] = $config->getURL($rep, $absnode, 'file').'rev='.$rev2; |
if ($debug) echo 'Creating node '.$node.'<br />'; |
// Skip past the line of ='s |
$line = fgets($diff); |
if ($debug) print 'Skipping: '.$line.'<br />'; |
// Check for a file addition |
$line = fgets($diff); |
if ($debug) print 'Examining: '.$line.'<br />'; |
if (strpos($line, '(revision 0)')) |
{ |
$listvar['info'] = $lang['FILEADDED']; |
} |
if (strncmp(trim($line), 'Cannot display:', 15) == 0) |
{ |
$index++; |
clearVars(); |
$listing[$index++]['info'] = escape(toOutputEncoding(rtrim($line, "\n\r"))); |
continue; |
} |
// Skip second file info |
$line = fgets($diff); |
if ($debug) print 'Skipping: '.$line.'<br />'; |
$indiff = true; |
$index++; |
continue; |
} |
if (strncmp(trim($line), 'Property changes on: ', 21) == 0) |
{ |
$propnode = trim($line); |
$propnode = substr($propnode, 21); |
if ($propnode == '' || $propnode[0] != '/') $propnode = '/'.$propnode; |
if ($debug) print 'Properties on '.$propnode.' (cur node $ '.$node.')'; |
if ($propnode != $node) |
{ |
if ($node) |
{ |
$listing[$index++]['endpath'] = true; |
clearVars(); |
} |
$node = $propnode; |
$listing[$index++]['newpath'] = escape(toOutputEncoding($node)); |
clearVars(); |
} |
$listing[$index++]['properties'] = true; |
clearVars(); |
if ($debug) echo 'Creating node '.$node.'<br />'; |
// Skip the row of underscores |
$line = fgets($diff); |
if ($debug) print 'Skipping: '.$line.'<br />'; |
while ($line = rtrim(fgets($diff), "\n\r")) |
{ |
if (!strncmp(trim($line), 'Index: ', 7)) |
{ |
break; |
} |
if (!strncmp(trim($line), '##', 2) || $line == '\ No newline at end of file') |
{ |
continue; |
} |
$listing[$index++]['info'] = escape(toOutputEncoding($line)); |
clearVars(); |
} |
$getLine = false; |
continue; |
} |
// Check for error messages |
if (strncmp(trim($line), 'svn: ', 5) == 0) |
{ |
$listing[$index++]['info'] = urldecode($line); |
$vars['success'] = false; |
continue; |
} |
$listing[$index++]['info'] = escape(toOutputEncoding($line)); |
if (strlen($line) === 0) |
{ |
if (!isset($vars['warning'])) |
{ |
$vars['warning'] = "No changes between revisions"; |
} |
} |
} |
if ($node) |
{ |
clearVars(); |
$listing[$index++]['endpath'] = true; |
} |
if ($debug) print_r($listing); |
if (!$rep->hasUnrestrictedReadAccess($relativePath1) || !$rep->hasUnrestrictedReadAccess($relativePath2, false)) |
{ |
// check every item for access and remove it if read access is not allowed |
$restricted = array(); |
$inrestricted = false; |
foreach ($listing as $i => $item) |
{ |
if ($item['newpath'] !== null) |
{ |
$newpath = $item['newpath']; |
$inrestricted = !$rep->hasReadAccess($newpath, false); |
} |
if ($inrestricted) |
{ |
$restricted[] = $i; |
} |
if ($item['endpath'] !== null) |
{ |
$inrestricted = false; |
} |
} |
foreach ($restricted as $i) |
{ |
unset($listing[$i]); |
} |
if (count($restricted) && !count($listing)) |
{ |
$vars['error'] = $lang['NOACCESS']; |
sendHeaderForbidden(); |
} |
} |
pclose($diff); |
} |
} |
renderTemplate('compare'); |
/WebSVN/composer.json |
---|
0,0 → 1,13 |
{ |
"name": "websvnphp/websvn", |
"description": "Online Subversion repository browser", |
"keywords": ["subversion", "svn", "websvn"], |
"type": "project", |
"require": { |
"geshi/geshi": "^1.0.9.1", |
"pear/archive_tar": "^1.4.14", |
"horde/text_diff": "^3.0.0", |
"erusev/parsedown": "1.7.4" |
}, |
"minimum-stability": "alpha" |
} |
/WebSVN/diff.php |
---|
1,8 → 1,6 |
<?php |
# vim:et:ts=3:sts=3:sw=3:fdm=marker: |
// WebSVN - Subversion repository viewing via the web using PHP |
// Copyright © 2004-2006 Tim Armes, Matt Sicker |
// Copyright (C) 2004-2006 Tim Armes |
// |
// This program is free software; you can redistribute it and/or modify |
// it under the terms of the GNU General Public License as published by |
11,12 → 9,12 |
// |
// This program is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License |
// along with this program; if not, write to the Free Software |
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
// |
// -- |
// |
25,334 → 23,212 |
// Show the differences between 2 revisions of a file. |
// |
require_once("include/setup.inc"); |
require_once("include/svnlook.inc"); |
require_once("include/utils.inc"); |
require_once("include/template.inc"); |
require_once 'include/setup.php'; |
require_once 'include/svnlook.php'; |
require_once 'include/utils.php'; |
require_once 'include/template.php'; |
$context = 5; |
require_once 'include/diff_inc.php'; |
$vars["action"] = $lang["DIFF"]; |
$all = (@$_REQUEST["all"] == 1)?1:0; |
$vars['action'] = $lang['DIFF']; |
$all = (@$_REQUEST['all'] == 1); |
$ignoreWhitespace = $config->getIgnoreWhitespacesInDiff(); |
if (array_key_exists('ignorews', $_REQUEST)) |
{ |
$ignoreWhitespace = (bool)$_REQUEST['ignorews']; |
} |
// Make sure that we have a repository |
if (!isset($rep)) |
if (!$rep) |
{ |
echo $lang["NOREP"]; |
exit; |
renderTemplate404('diff','NOREP'); |
} |
$svnrep = new SVNRepository($rep); |
// If there's no revision info, go to the lastest revision for this path |
$history = $svnrep->getLog($path, "", "", true); |
$youngest = $history->entries[0]->rev; |
$history = $svnrep->getLog($path, 'HEAD', 1, true, 2, ($path == '/') ? '' : $peg); |
if (empty($rev)) |
$rev = $youngest; |
if (!$history) |
{ |
unset($vars['error']); |
$history = $svnrep->getLog($path, '', '', true, 2, ($path == '/') ? '' : $peg); |
} |
$history = $svnrep->getLog($path, $rev); |
$youngest = ($history && isset($history->entries[0])) ? $history->entries[0]->rev : false; |
if ($path{0} != "/") |
$ppath = "/".$path; |
else |
$ppath = $path; |
if (empty($rev)) |
{ |
$rev = $youngest; |
} |
$history = $svnrep->getLog($path, $rev, 1, false, 2, $peg); |
if ($path[0] != '/') |
{ |
$ppath = '/'.$path; |
} |
else |
{ |
$ppath = $path; |
} |
$prevrev = @$history->entries[1]->rev; |
$vars["repname"] = $rep->getDisplayName(); |
$vars["rev"] = $rev; |
$vars["path"] = $ppath; |
$vars["prevrev"] = $prevrev; |
$vars['path'] = str_replace('%2F', '/', rawurlencode($ppath)); |
$vars['safepath'] = escape($ppath); |
$vars['rev1'] = $rev; |
$vars['rev2'] = $prevrev; |
$vars['prevrev'] = $prevrev; |
$vars["rev1"] = $history->entries[0]->rev; |
$vars["rev2"] = $prevrev; |
if (isset($history->entries[0])) |
{ |
$vars['log'] = xml_entities($history->entries[0]->msg); |
$vars['date'] = $history->entries[0]->date; |
$vars['age'] = datetimeFormatDuration(time() - strtotime($history->entries[0]->date)); |
$vars['author'] = $history->entries[0]->author; |
$vars['rev'] = $vars['rev1'] = $history->entries[0]->rev; |
$vars['peg'] = $peg; |
} |
createDirLinks($rep, $ppath, $rev, $showchanged); |
createPathLinks($rep, $ppath, $passrev, $peg); |
$passRevString = createRevAndPegString($rev, $peg); |
$listing = array(); |
$passIgnoreWhitespace = ''; |
if ($ignoreWhitespace != $config->getIgnoreWhitespacesInDiff()) |
{ |
$passIgnoreWhitespace = '&ignorews='.($ignoreWhitespace ? '1' : '0'); |
} |
if ($prevrev) |
if ($rev != $youngest) |
{ |
$url = $config->getURL($rep, $path, "diff"); |
if (!$all) |
{ |
$vars["showalllink"] = "<a href=\"${url}rev=$rev&sc=$showchanged&all=1\">${lang["SHOWENTIREFILE"]}</a>"; |
$vars["showcompactlink"] = ""; |
} |
else |
{ |
$vars["showcompactlink"] = "<a href=\"${url}rev=$rev&sc=$showchanged&all=0\">${lang["SHOWCOMPACT"]}</a>"; |
$vars["showalllink"] = ""; |
} |
$vars['goyoungesturl'] = $config->getURL($rep, $path, 'diff').createRevAndPegString('', $peg).$passIgnoreWhitespace; |
$vars['goyoungestlink'] = '<a href="'.$vars['goyoungesturl'].'"'.($youngest ? ' title="'.$lang['REV'].' '.$youngest.'"' : '').'>'.$lang['GOYOUNGEST'].'</a>'; |
} |
// Get the contents of the two files |
$newtname = tempnam("temp", ""); |
$new = $svnrep->getFileContents($history->entries[0]->path, $newtname, $history->entries[0]->rev, "", true); |
$revurl = $config->getURL($rep, $path, 'diff'); |
$oldtname = tempnam("temp", ""); |
$old = $svnrep->getFileContents($history->entries[1]->path, $oldtname, $history->entries[1]->rev, "", true); |
$ent = true; |
$extension = strrchr(basename($path), "."); |
if (($extension && isset($extEnscript[$extension]) && ('php' == $extEnscript[$extension])) || ($config->useEnscript)) |
$ent = false; |
if ($rev < $youngest) |
{ |
$history2 = $svnrep->getLog($path, $rev, $youngest, true, 2, $peg ? $peg : 'HEAD'); |
$file1cache = array(); |
if (isset($history2->entries[1])) |
{ |
$nextRev = $history2->entries[1]->rev; |
if ($nextRev != $youngest) |
{ |
$vars['nextrev'] = $nextRev; |
$vars['nextrevurl'] = $revurl.createRevAndPegString($nextRev, $peg).$passIgnoreWhitespace; |
} |
} |
if ($all) |
$context = 1; // Setting the context to 0 makes diff generate the wrong line numbers! |
unset($vars['error']); |
} |
// Open a pipe to the diff command with $context lines of context |
$cmd = quoteCommand($config->diff." --ignore-all-space -U $context $oldtname $newtname", false); |
if ($all) |
{ |
$ofile = fopen($oldtname, "r"); |
$nfile = fopen($newtname, "r"); |
} |
if (isset($history->entries[1])) |
{ |
$prevRev = $history->entries[1]->rev; |
$prevPath = $history->entries[1]->path; |
$vars['prevrev'] = $prevRev; |
$vars['prevrevurl'] = $revurl.createRevAndPegString($prevRev, $peg).$passIgnoreWhitespace; |
} |
if ($diff = popen($cmd, "r")) |
{ |
// Ignore the 3 header lines |
$line = fgets($diff); |
$line = fgets($diff); |
$vars['revurl'] = $config->getURL($rep, $path, 'revision').$passRevString; |
$vars['revlink'] = '<a href="'.$vars['revurl'].'">'.$lang['LASTMOD'].'</a>'; |
// Get the first real line |
$line = fgets($diff); |
$index = 0; |
$listing = array(); |
$curoline = 1; |
$curnline = 1; |
while (!feof($diff)) |
{ |
// Get the first line of this range |
sscanf($line, "@@ -%d", $oline); |
$line = substr($line, strpos($line, "+")); |
sscanf($line, "+%d", $nline); |
if ($all) |
{ |
while ($curoline < $oline || $curnline < $nline) |
{ |
$listing[$index]["rev1diffclass"] = "diff"; |
$listing[$index]["rev2diffclass"] = "diff"; |
if ($curoline < $oline) |
{ |
$nl = fgets($ofile); |
if ($ent) |
$line = replaceEntities(rtrim($nl), $rep); |
else |
$line = rtrim($nl); |
$listing[$index]["rev1line"] = hardspace($line); |
$vars['logurl'] = $config->getURL($rep, $path, 'log').$passRevString; |
$vars['loglink'] = '<a href="'.$vars['logurl'].'">'.$lang['VIEWLOG'].'</a>'; |
$curoline++; |
} |
else |
$listing[$index]["rev1line"] = " "; |
if ($curnline < $nline) |
{ |
$nl = fgets($nfile); |
$vars['filedetailurl'] = $config->getURL($rep, $path, 'file').$passRevString; |
$vars['filedetaillink'] = '<a href="'.$vars['filedetailurl'].'">'.$lang['FILEDETAIL'].'</a>'; |
if ($ent) |
$line = replaceEntities(rtrim($nl), $rep); |
else |
$line = rtrim($nl); |
$listing[$index]["rev2line"] = hardspace($line); |
$curnline++; |
} |
else |
$listing[$index]["rev2line"] = " "; |
$listing[$index]["rev1lineno"] = 0; |
$listing[$index]["rev2lineno"] = 0; |
$vars['blameurl'] = $config->getURL($rep, $path, 'blame').$passRevString; |
$vars['blamelink'] = '<a href="'.$vars['blameurl'].'">'.$lang['BLAME'].'</a>'; |
$index++; |
} |
} |
else |
{ |
// Output the line numbers |
$listing[$index]["rev1lineno"] = "$oline"; |
$listing[$index]["rev2lineno"] = "$nline"; |
$index++; |
} |
$fin = false; |
while (!feof($diff) && !$fin) |
{ |
$listing[$index]["rev1lineno"] = 0; |
$listing[$index]["rev2lineno"] = 0; |
if ($rep->isRssEnabled()) |
{ |
$vars['rssurl'] = $config->getURL($rep, $path, 'rss').createRevAndPegString('', $peg); |
$vars['rsslink'] = '<a href="'.$vars['rssurl'].'">'.$lang['RSSFEED'].'</a>'; |
} |
$line = fgets($diff); |
if (!strncmp($line, "@@", 2)) |
{ |
$fin = true; |
} |
else |
{ |
$mod = $line{0}; |
// Check for binary file type before diffing. |
$svnMimeType = $svnrep->getProperty($path, 'svn:mime-type', $rev); |
if ($ent) |
$line = replaceEntities(rtrim(substr($line, 1)), $rep); |
else |
$line = rtrim(substr($line, 1)); |
$listing[$index]["rev1line"] = hardspace($line); |
// If no previous revision exists, bail out before diffing |
if (!$rep->getIgnoreSvnMimeTypes() && preg_match('~application/*~', $svnMimeType)) |
{ |
$vars['warning'] = 'Cannot display diff of binary file. (svn:mime-type = '.$svnMimeType.')'; |
$text = hardspace($line); |
if ($text == "") $text = " "; |
switch ($mod) |
{ |
case "-": |
$listing[$index]["rev1diffclass"] = "diffdeleted"; |
$listing[$index]["rev2diffclass"] = "diff"; |
$listing[$index]["rev1line"] = $text; |
$listing[$index]["rev2line"] = " "; |
if ($all) |
{ |
fgets($ofile); |
$curoline++; |
} |
break; |
} |
else if (!$prevrev) |
{ |
$vars['noprev'] = 1; |
} |
else |
{ |
$diff = $config->getURL($rep, $path, 'diff').$passRevString; |
case "+": |
// Try to mark "changed" line sensibly |
if (!empty($listing[$index-1]) && empty($listing[$index-1]["rev1lineno"]) && @$listing[$index-1]["rev1diffclass"] == "diffdeleted" && @$listing[$index-1]["rev2diffclass"] == "diff") |
{ |
$i = $index - 1; |
while (!empty($listing[$i-1]) && empty($listing[$i-1]["rev1lineno"]) && $listing[$i-1]["rev1diffclass"] == "diffdeleted" && $listing[$i-1]["rev2diffclass"] == "diff") |
$i--; |
$listing[$i]["rev1diffclass"] = "diffchanged"; |
$listing[$i]["rev2diffclass"] = "diffchanged"; |
$listing[$i]["rev2line"] = $text; |
if ($all) |
{ |
fgets($nfile); |
$curnline++; |
} |
if ($all) |
{ |
$vars['showcompactlink'] = '<a href="'.$diff.$passIgnoreWhitespace.'">'.$lang['SHOWCOMPACT'].'</a>'; |
} |
else |
{ |
$vars['showalllink'] = '<a href="'.$diff.$passIgnoreWhitespace.'&all=1'.'">'.$lang['SHOWENTIREFILE'].'</a>'; |
} |
// Don't increment the current index count |
$index--; |
} |
else |
{ |
$listing[$index]["rev1diffclass"] = "diff"; |
$listing[$index]["rev2diffclass"] = "diffadded"; |
$listing[$index]["rev1line"] = " "; |
$listing[$index]["rev2line"] = $text; |
$passShowAll = ($all ? '&all=1' : ''); |
$toggleIgnoreWhitespace = ''; |
if ($all) |
{ |
fgets($nfile); |
$curnline++; |
} |
} |
break; |
default: |
$listing[$index]["rev1diffclass"] = "diff"; |
$listing[$index]["rev2diffclass"] = "diff"; |
$listing[$index]["rev1line"] = $text; |
$listing[$index]["rev2line"] = $text; |
if ($all) |
{ |
fgets($ofile); |
fgets($nfile); |
$curoline++; |
$curnline++; |
} |
if ($ignoreWhitespace == $config->getIgnoreWhitespacesInDiff()) |
{ |
$toggleIgnoreWhitespace = '&ignorews='.($ignoreWhitespace ? '0' : '1'); |
} |
break; |
} |
} |
if (!$fin) |
$index++; |
} |
} |
// Output the rest of the files |
if ($all) |
{ |
while (!feof($ofile) || !feof($nfile)) |
{ |
$listing[$index]["rev1diffclass"] = "diff"; |
$listing[$index]["rev2diffclass"] = "diff"; |
if ($ent) |
$line = replaceEntities(rtrim(fgets($ofile)), $rep); |
else |
$line = rtrim(fgets($ofile)); |
if ($ignoreWhitespace) |
{ |
$vars['regardwhitespacelink'] = '<a href="'.$diff.$passShowAll.$toggleIgnoreWhitespace.'">'.$lang['REGARDWHITESPACE'].'</a>'; |
} |
else |
{ |
$vars['ignorewhitespacelink'] = '<a href="'.$diff.$passShowAll.$toggleIgnoreWhitespace.'">'.$lang['IGNOREWHITESPACE'].'</a>'; |
} |
if (!feof($ofile)) |
$listing[$index]["rev1line"] = hardspace($line); |
else |
$listing[$index]["rev1line"] = " "; |
if ($ent) |
$line = replaceEntities(rtrim(fgets($nfile)), $rep); |
else |
$line = rtrim(fgets($nfile)); |
// Get the contents of the two files |
$newerFile = tempnamWithCheck($config->getTempDir(), ''); |
$newerFileHl = $newerFile.'highlight'; |
$normalNew = $svnrep->getFileContents($history->entries[0]->path, $newerFile, $history->entries[0]->rev, $peg, '', 'no'); |
$highlightedNew = $svnrep->getFileContents($history->entries[0]->path, $newerFileHl, $history->entries[0]->rev, $peg, '', 'line'); |
if (!feof($nfile)) |
$listing[$index]["rev2line"] = hardspace($line); |
else |
$listing[$index]["rev2line"] = " "; |
$listing[$index]["rev1lineno"] = 0; |
$listing[$index]["rev2lineno"] = 0; |
$olderFile = tempnamWithCheck($config->getTempDir(), ''); |
$olderFileHl = $olderFile.'highlight'; |
$normalOld = $svnrep->getFileContents($history->entries[0]->path, $olderFile, $history->entries[1]->rev, $peg, '', 'no'); |
$highlightedOld = $svnrep->getFileContents($history->entries[0]->path, $olderFileHl, $history->entries[1]->rev, $peg, '', 'line'); |
// TODO: Figured out why diffs across a move/rename are currently broken. |
$index++; |
} |
} |
pclose($diff); |
} |
if ($all) |
{ |
fclose($ofile); |
fclose($nfile); |
} |
$highlighted = ($highlightedNew && $highlightedOld); |
// Remove our temporary files |
unlink($oldtname); |
unlink($newtname); |
if ($highlighted) |
{ |
$listing = do_diff($all, $ignoreWhitespace, $highlighted, $newerFile, $olderFile, $newerFileHl, $olderFileHl); |
} |
else |
{ |
$listing = do_diff($all, $ignoreWhitespace, $highlighted, $newerFile, $olderFile, null, null); |
} |
// Remove our temporary files |
@unlink($newerFile); |
@unlink($olderFile); |
@unlink($newerFileHl); |
@unlink($olderFileHl); |
} |
else |
if (!$rep->hasReadAccess($path, false)) |
{ |
$vars["noprev"] = 1; |
$vars['error'] = $lang['NOACCESS']; |
sendHeaderForbidden(); |
} |
$vars["version"] = $version; |
if (!$rep->hasReadAccess($path, false)) |
$vars["noaccess"] = true; |
parseTemplate($rep->getTemplatePath()."header.tmpl", $vars, $listing); |
parseTemplate($rep->getTemplatePath()."diff.tmpl", $vars, $listing); |
parseTemplate($rep->getTemplatePath()."footer.tmpl", $vars, $listing); |
?> |
renderTemplate('diff'); |
/WebSVN/dl.php |
---|
1,122 → 1,326 |
<?php |
# vim:et:ts=3:sts=3:sw=3:fdm=marker: |
// WebSVN - Subversion repository viewing via the web using PHP |
// Copyright © 2004-2006 Tim Armes, Matt Sicker |
// |
// This program is free software; you can redistribute it and/or modify |
// it under the terms of the GNU General Public License as published by |
// the Free Software Foundation; either version 2 of the License, or |
// (at your option) any later version. |
// |
// This program is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License |
// along with this program; if not, write to the Free Software |
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
// |
// -- |
// |
// dl.php |
// |
// Create gz/tar files of the requested item |
require_once("include/setup.inc"); |
require_once("include/svnlook.inc"); |
require_once("include/utils.inc"); |
// Make sure that this operation is allowed |
if (!$rep->isDownloadAllowed($path)) |
exit; |
$svnrep = new SVNRepository($rep); |
if ($path{0} != "/") |
$ppath = "/".$path; |
else |
$ppath = $path; |
// If there's no revision info, go to the lastest revision for this path |
$history = $svnrep->getLog($path, "", "", true); |
$youngest = $history->entries[0]->rev; |
if (empty($rev)) |
$rev = $youngest; |
// Create a temporary directory. Here we have an unavoidable but highly |
// unlikely to occure race condition |
if (count(glob("/tmp/wsvn-*"))<=40) // Omezeni na pocet soucasne stahovanych souboru |
{ |
// Ošetření doběhnutí skriptu i když klient klikne jinam (smazání tmp) |
ignore_user_abort(true); |
$tmpname1 = tempnam("temp", "wsvn-"); |
$tmpname = $tmpname1; |
$tmpname .= "dir"; |
if (mkdir($tmpname)) |
{ |
// Get the name of the directory being archived |
$arcname = substr($path, 0, -1); |
$arcname = basename($arcname); |
if (empty($arcname)) |
$arcname = $rep->name; |
$svnrep->exportDirectory($path, $tmpname.DIRECTORY_SEPARATOR.$arcname, $rev); |
// ZIP it up |
chdir($tmpname); |
if (! connection_aborted()) |
exec("zip -r ".quote("$arcname")." ."); |
$size = filesize("$arcname.zip"); |
// Give the file to the browser |
if (!connection_aborted() && $fp = @fopen("$arcname.zip","rb")) |
{ |
header("Content-Type: application/zip"); |
header("Content-Length: $size"); |
header("Content-Disposition: attachment; filename=\"".$rep->name."-$arcname.zip\""); |
// Use a loop to transfer the data 4KB at a time. |
while(!feof($fp)) |
{ |
echo fread($fp, 4096); |
ob_flush(); |
} |
} |
else |
{ |
print "Unable to open file $arcname.zip"; |
} |
fclose($fp); |
chdir(".."); |
// Delete the directory. Why doesn't PHP have a generic recursive directory |
// deletion command? It's stupid. |
// if ($config->serverIsWindows) |
// { |
// $cmd = quoteCommand("rmdir /S /Q ".quote($tmpname), false); |
// } |
// else |
// { |
$cmd = quoteCommand("rm -fr ".quote($tmpname), false); |
// } |
@exec($cmd); |
} |
unlink($tmpname1); // Pomocny soubor smazeme az po smazani adresare |
} |
else |
{ |
print "We are sorry. The server is overloaded..."; |
} |
?> |
<?php |
// WebSVN - Subversion repository viewing via the web using PHP |
// Copyright (C) 2004-2006 Tim Armes |
// |
// This program is free software; you can redistribute it and/or modify |
// it under the terms of the GNU General Public License as published by |
// the Free Software Foundation; either version 2 of the License, or |
// (at your option) any later version. |
// |
// This program is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License |
// along with this program; if not, write to the Free Software |
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
// |
// -- |
// |
// dl.php |
// |
// Allow for file and directory downloads, creating zip/tar/gz files if needed. |
require_once 'include/setup.php'; |
require_once 'include/svnlook.php'; |
require_once 'include/utils.php'; |
if (!defined('USE_AUTOLOADER')) { |
@include_once 'Archive/Tar.php'; |
} |
function setDirectoryTimestamp($dir, $timestamp) { |
global $config; |
// Changing the timestamp of a directory in Windows is only supported in PHP 5.3.0+ |
touch($dir, $timestamp); |
if (is_dir($dir)) { |
// Set timestamp for all contents, recursing into subdirectories |
$handle = opendir($dir); |
if ($handle) { |
while (($file = readdir($handle)) !== false) { |
if ($file == '.' || $file == '..') { |
continue; |
} |
$f = $dir.DIRECTORY_SEPARATOR.$file; |
if (is_dir($f)) { |
setDirectoryTimestamp($f, $timestamp); |
} |
} |
closedir($handle); |
} |
} |
} |
// Make sure that downloading the specified file/directory is permitted |
if (!$rep) |
{ |
http_response_code(404); |
exit; |
} |
if (!$rep->isDownloadAllowed($path)) { |
http_response_code(403); |
error_log('Unable to download resource at path: '.$path); |
print 'Unable to download resource at path: '.xml_entities($path); |
exit; |
} |
$svnrep = new SVNRepository($rep); |
// Fetch information about a revision (if unspecified, the latest) for this path |
if (empty($rev)) |
{ |
$history = $svnrep->getLog($path, 'HEAD', '', true, 1, $peg); |
} |
else if ($rev == $peg) |
{ |
$history = $svnrep->getLog($path, '', 1, true, 1, $peg); |
} |
else |
{ |
$history = $svnrep->getLog($path, $rev, $rev - 1, true, 1, $peg); |
} |
$logEntry = ($history && !empty($history->entries)) ? $history->entries[0] : null; |
if (!$logEntry) |
{ |
http_response_code(404); |
error_log('Unable to download resource at path: '.$path); |
print 'Unable to download resource at path: '.xml_entities($path); |
exit(0); |
} |
if (empty($rev)) |
{ |
$rev = $logEntry->rev; |
} |
// Create a temporary filename to be used for a directory to archive a download. |
// Here we have an unavoidable but highly unlikely to occur race condition. |
$tempDir = tempnamWithCheck($config->getTempDir(), 'websvn'); |
@unlink($tempDir); |
mkdir($tempDir); |
// Create the name of the directory being archived |
$archiveName = $path; |
$isDir = (substr($archiveName, -1) == '/'); |
if ($isDir) |
{ |
$archiveName = substr($archiveName, 0, -1); |
} |
$archiveName = basename($archiveName); |
if ($archiveName == '') |
{ |
$archiveName = $rep->name; |
} |
$plainfilename = $archiveName; |
$archiveName .= '.r'.$rev; |
// Export the requested path from SVN repository to the temp directory |
$svnExportResult = $svnrep->exportRepositoryPath($path, $tempDir.DIRECTORY_SEPARATOR.$archiveName, $rev, $peg); |
if ($svnExportResult != 0) |
{ |
http_response_code(500); |
error_log('svn export failed for: '.$archiveName); |
print 'svn export failed for "'.xml_entities($archiveName).'".'; |
removeDirectory($tempDir); |
exit(0); |
} |
// For security reasons, disallow direct downloads of filenames that |
// are a symlink, since they may be a symlink to anywhere (/etc/passwd) |
// Deciding whether the symlink is relative and legal within the |
// repository would be nice but seems to error prone at this moment. |
if ( is_link($tempDir.DIRECTORY_SEPARATOR.$archiveName) ) |
{ |
http_response_code(500); |
error_log('to be downloaded file is symlink, aborting: '.$archiveName); |
print 'Download of symlinks disallowed: "'.xml_entities($archiveName).'".'; |
removeDirectory($tempDir); |
exit(0); |
} |
// Set timestamp of exported directory (and subdirectories) to timestamp of |
// the revision so every archive of a given revision has the same timestamp. |
$revDate = $logEntry->date; |
$timestamp = mktime(substr($revDate, 11, 2), // hour |
substr($revDate, 14, 2), // minute |
substr($revDate, 17, 2), // second |
substr($revDate, 5, 2), // month |
substr($revDate, 8, 2), // day |
substr($revDate, 0, 4)); // year |
setDirectoryTimestamp($tempDir, $timestamp); |
// Change to temp directory so that only relative paths are stored in archive. |
$oldcwd = getcwd(); |
chdir($tempDir); |
if ($isDir) |
{ |
$downloadMode = $config->getDefaultDirectoryDlMode(); |
} |
else |
{ |
$downloadMode = $config->getDefaultFileDlMode(); |
} |
// $_REQUEST parameter can override dlmode |
if (!empty($_REQUEST['dlmode'])) |
{ |
$downloadMode = $_REQUEST['dlmode']; |
if (substr($logEntry->path, -1) == '/') |
{ |
if (!in_array($downloadMode, $config->validDirectoryDlModes)) |
{ |
$downloadMode = $config->getDefaultDirectoryDlMode(); |
} |
} |
else |
{ |
if (!in_array($downloadMode, $config->validFileDlModes)) |
{ |
$downloadMode = $config->getDefaultFileDlMode(); |
} |
} |
} |
$downloadArchive = $archiveName; |
if ($downloadMode == 'plain') |
{ |
$downloadMimeType = 'application/octet-stream'; |
} |
else if ($downloadMode == 'zip') |
{ |
$downloadMimeType = 'application/zip'; |
$downloadArchive .= '.zip'; |
// Create zip file |
$cmd = $config->zip.' --symlinks -r '.quote($downloadArchive).' '.quote($archiveName); |
execCommand($cmd, $retcode); |
if ($retcode != 0) |
{ |
error_log('Unable to call zip command: '.$cmd); |
print 'Unable to call zip command. See webserver error log for details.'; |
} |
} |
else |
{ |
$downloadMimeType = 'application/gzip'; |
$downloadArchive .= '.tar.gz'; |
$tarArchive = $archiveName.'.tar'; |
// Create the tar file |
$retcode = 0; |
if (class_exists('Archive_Tar')) |
{ |
$tar = new Archive_Tar($tarArchive); |
$created = $tar->create(array($archiveName)); |
if (!$created) |
{ |
$retcode = 1; |
http_response_code(500); |
print 'Unable to create tar archive.'; |
} |
} |
else |
{ |
$cmd = $config->tar.' -cf '.quote($tarArchive).' '.quote($archiveName); |
execCommand($cmd, $retcode); |
if ($retcode != 0) |
{ |
http_response_code(500); |
error_log('Unable to call tar command: '.$cmd); |
print 'Unable to call tar command. See webserver error log for details.'; |
} |
} |
if ($retcode != 0) |
{ |
chdir($oldcwd); |
removeDirectory($tempDir); |
exit(0); |
} |
// Set timestamp of tar file to timestamp of revision |
touch($tarArchive, $timestamp); |
// GZIP it up |
if (function_exists('gzopen')) |
{ |
$srcHandle = fopen($tarArchive, 'rb'); |
$dstHandle = gzopen($downloadArchive, 'wb'); |
if (!$srcHandle || !$dstHandle) |
{ |
http_response_code(500); |
print 'Unable to open file for gz-compression.'; |
chdir($oldcwd); |
removeDirectory($tempDir); |
exit(0); |
} |
while (!feof($srcHandle)) |
{ |
gzwrite($dstHandle, fread($srcHandle, 1024 * 512)); |
} |
fclose($srcHandle); |
gzclose($dstHandle); |
} |
else |
{ |
$cmd = $config->gzip.' '.quote($tarArchive); |
$retcode = 0; |
execCommand($cmd, $retcode); |
if ($retcode != 0) |
{ |
http_response_code(500); |
error_log('Unable to call gzip command: '.$cmd); |
print 'Unable to call gzip command. See webserver error log for details.'; |
chdir($oldcwd); |
removeDirectory($tempDir); |
exit(0); |
} |
} |
} |
// Give the file to the browser |
if (is_readable($downloadArchive)) |
{ |
if ($downloadMode == 'plain') |
{ |
$downloadFilename = $plainfilename; |
} |
else |
{ |
$downloadFilename = $rep->name.'-'.$downloadArchive; |
} |
header('Content-Type: '.$downloadMimeType); |
header('Content-Length: '.filesize($downloadArchive)); |
header("Content-Disposition: attachment; filename*=UTF-8''".rawurlencode($downloadFilename)); |
readfile($downloadArchive); |
} |
else |
{ |
http_response_code(404); |
print 'Unable to open file: '.xml_entities($downloadArchive); |
} |
chdir($oldcwd); |
removeDirectory($tempDir); |
/WebSVN/filedetails.php |
---|
1,8 → 1,6 |
<?php |
# vim:et:ts=3:sts=3:sw=3:fdm=marker: |
// WebSVN - Subversion repository viewing via the web using PHP |
// Copyright © 2004-2006 Tim Armes, Matt Sicker |
// Copyright (C) 2004-2006 Tim Armes |
// |
// This program is free software; you can redistribute it and/or modify |
// it under the terms of the GNU General Public License as published by |
11,12 → 9,12 |
// |
// This program is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License |
// along with this program; if not, write to the Free Software |
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
// |
// -- |
// |
24,151 → 22,227 |
// |
// Simply lists the contents of a file |
require_once("include/setup.inc"); |
require_once("include/svnlook.inc"); |
require_once("include/utils.inc"); |
require_once("include/template.inc"); |
require_once 'include/setup.php'; |
require_once 'include/svnlook.php'; |
require_once 'include/utils.php'; |
require_once 'include/template.php'; |
// Make sure that we have a repository |
if (!isset($rep)) |
if (!$rep) |
{ |
echo $lang["NOREP"]; |
exit; |
renderTemplate404('file','NOREP'); |
} |
$svnrep = new SVNRepository($rep); |
if ($path{0} != "/") |
$ppath = "/".$path; |
else |
$ppath = $path; |
if ($path[0] != '/') |
{ |
$ppath = '/'.$path; |
} |
else |
{ |
$ppath = $path; |
} |
$passrev = $rev; |
$useMime = false; |
// If there's no revision info, go to the lastest revision for this path |
$history = $svnrep->getLog($path, "", "", true); |
$youngest = $history->entries[0]->rev; |
$history = $svnrep->getLog($path, 'HEAD', 1, false, 2, ($path == '/') ? '' : $peg); |
if (empty($rev)) |
$rev = $youngest; |
if (!$history) |
{ |
unset($vars['error']); |
$history = $svnrep->getLog($path, '', '', false, 2, ($path == '/') ? '' : $peg); |
if (!$history) |
{ |
renderTemplate404('file','NOPATH'); |
} |
} |
$extn = strrchr($path, "."); |
$youngest = ($history && isset($history->entries[0])) ? $history->entries[0]->rev : false; |
if (empty($rev)) |
{ |
$rev = !$peg ? $youngest : min($peg, $youngest); |
} |
$extn = strtolower(strrchr($path, '.')); |
// Check to see if the user has requested that this type be zipped and sent |
// to the browser as an attachment |
if (in_array($extn, $zipped)) |
if ($history && isset($zipped) && in_array($extn, $zipped) && $rep->hasReadAccess($path, false)) |
{ |
$base = basename($path); |
header("Content-Type: application/x-gzip"); |
header("Content-Disposition: attachment; filename=".urlencode($base).".gz"); |
$base = basename($path); |
header('Content-Type: application/gzip'); |
header("Content-Disposition: attachment; filename*=UTF-8''".rawurlencode($base).'.gz'); |
// Get the file contents and pipe into gzip. All this without creating |
// a temporary file. Damn clever. |
$svnrep->getFileContents($path, "", $rev, "| ".$config->gzip." -n -f"); |
exit; |
// Get the file contents and pipe into gzip. All this without creating |
// a temporary file. Damn clever. |
$svnrep->getFileContents($path, '', $rev, $peg, '| '.$config->gzip.' -n -f'); |
exit; |
} |
// Check to see if we should serve it with a particular content-type. |
// The content-type could come from an svn:mime-type property on the |
// file, or from the $contentType array in setup.inc. |
// file, or from the $contentType array in setup.php. |
if (!$rep->getIgnoreSvnMimeTypes()) |
{ |
$svnMimeType = $svnrep->getProperty($path, 'svn:mime-type', $rev); |
$svnMimeType = $svnrep->getProperty($path, 'svn:mime-type', $rev); |
} |
if (!$rep->getIgnoreWebSVNContentTypes()) |
{ |
$setupContentType = @$contentType[$extn]; |
$setupContentType = @$contentType[$extn]; |
} |
// Use this set of priorities when establishing what content-type to |
// actually use. |
// Use the documented priorities when establishing what content-type to use. |
if (!empty($svnMimeType) && $svnMimeType != 'application/octet-stream') |
{ |
$cont = $svnMimeType; |
$mimeType = $svnMimeType; |
} |
else if (!empty($setupContentType)) |
else if (!empty($setupContentType)) |
{ |
$cont = $setupContentType; |
} |
else if (!empty($svnMimeType)) |
$mimeType = $setupContentType; |
} |
else if (!empty($svnMimeType)) |
{ |
// It now is equal to application/octet-stream due to logic |
// above.... |
$cont = $svnMimeType; |
$mimeType = $svnMimeType; // Use SVN's default of 'application/octet-stream' |
} |
else |
{ |
$mimeType = ''; |
} |
// If there's a MIME type associated with this format, then we deliver it |
// with this information |
$useMime = ($mimeType) ? @$_REQUEST['usemime'] : false; |
if (!empty($cont)) |
if ($history && !empty($mimeType) && !$useMime) |
{ |
$base = basename($path); |
header("Content-Type: $cont"); |
//header("Content-Length: $size"); |
header("Content-Disposition: inline; filename=".urlencode($base)); |
$svnrep->getFileContents($path, "", $rev); |
exit; |
$useMime = $mimeType; // Save MIME type for later before possibly clobbering |
// If a MIME type exists but is set to be ignored, set it to an empty string. |
foreach ($config->inlineMimeTypes as $inlineType) |
{ |
if (preg_match('|'.$inlineType.'|', $mimeType)) |
{ |
$mimeType = ''; |
break; |
} |
} |
} |
// Explicitly requested file as attachment |
if (isset($_REQUEST['getfile'])) |
// If a MIME type is associated with the file, deliver with Content-Type header. |
if ($history && !empty($mimeType) && $rep->hasReadAccess($path, false)) |
{ |
$base = basename($path); |
$base = basename($path); |
header('Content-Type: '.$mimeType); |
//header('Content-Length: '.$size); |
header("Content-Disposition: inline; filename*=UTF-8''".rawurlencode($base)); |
$svnrep->getFileContents($path, '', $rev, $peg); |
exit; |
} |
header("Content-Type: application/octet-stream"); |
header("Content-Length: $size"); |
header("Content-Disposition: inline; filename=".urlencode($base)); |
// Display the file inline using WebSVN. |
$svnrep->getFileContents($path, "", $rev); |
$vars['action'] = ''; |
$vars['path'] = str_replace('%2F', '/', rawurlencode($ppath)); |
$vars['safepath'] = escape($ppath); |
exit; |
if (isset($history->entries[0])) |
{ |
$vars['log'] = xml_entities($history->entries[0]->msg); |
$vars['date'] = $history->entries[0]->date; |
$vars['age'] = datetimeFormatDuration(time() - strtotime($history->entries[0]->date)); |
$vars['author'] = $history->entries[0]->author; |
} |
// There's no associated MIME type. Show the file using WebSVN. |
createPathLinks($rep, $ppath, !$passrev && $peg ? $rev : $passrev, $peg); |
$passRevString = createRevAndPegString($rev, $peg); |
$url = $config->getURL($rep, $path, "file"); |
if ($rev != $youngest) |
{ |
$vars['goyoungesturl'] = $config->getURL($rep, $path, 'file').createRevAndPegString($youngest, $peg); |
$vars['goyoungestlink'] = '<a href="'.$vars['goyoungesturl'].'"'.($youngest ? ' title="'.$lang['REV'].' '.$youngest.'"' : '').'>'.$lang['GOYOUNGEST'].'</a>'; |
} |
if ($rev != $youngest) |
$vars["goyoungestlink"] = "<a href=\"${url}sc=1\">${lang["GOYOUNGEST"]}</a>"; |
else |
$vars["goyoungestlink"] = ""; |
$revurl = $config->getURL($rep, $path, 'file'); |
$vars["action"] = ""; |
$vars["repname"] = $rep->getDisplayName(); |
$vars["rev"] = $rev; |
$vars["path"] = $ppath; |
if ($rev < $youngest) |
{ |
$history2 = $svnrep->getLog($path, $rev, $youngest, true, 2, $peg ? $peg : 'HEAD'); |
createDirLinks($rep, $ppath, $passrev, $showchanged); |
if (isset($history2->entries[1])) |
{ |
$nextRev = $history2->entries[1]->rev; |
if ($nextRev != $youngest) |
{ |
$vars['nextrev'] = $nextRev; |
$vars['nextrevurl'] = $revurl.createRevAndPegString($nextRev, $peg); |
} |
} |
$url = $config->getURL($rep, $path, "log"); |
$vars["fileviewloglink"] = "<a href=\"${url}rev=$passrev&sc=$showchanged&isdir=0\">${lang["VIEWLOG"]}</a>"; |
unset($vars['error']); |
} |
$url = $config->getURL($rep, $path, "diff"); |
$vars["prevdifflink"] = "<a href=\"${url}rev=$passrev&sc=$showchanged\">${lang["DIFFPREV"]}</a>"; |
$history3 = $svnrep->getLog($path, $rev, 1, true, 2, $peg ? $peg : 'HEAD'); |
$url = $config->getURL($rep, $path, "blame"); |
$vars["blamelink"] = "<a href=\"${url}rev=$passrev&sc=$showchanged\">${lang["BLAME"]}</a>"; |
if (isset($history3->entries[1])) |
{ |
$prevRev = $history3->entries[1]->rev; |
$prevPath = $history3->entries[1]->path; |
$vars['prevrev'] = $prevRev; |
$vars['prevrevurl'] = $revurl.createRevAndPegString($prevRev, $peg); |
} |
#$url = $config->getURL($rep, $path, "get"); |
$url = $config->getURL($rep, $path, "file"); |
$vars["getfile"] = "<a href=\"${url}getfile&rev=$passrev&sc=$showchanged\">${lang["GETFILE"]}</a>"; |
unset($vars['error']); |
$listing = array (); |
$vars['revurl'] = $config->getURL($rep, $path, 'revision').$passRevString; |
$vars['revlink'] = '<a href="'.$vars['revurl'].'">'.$lang['LASTMOD'].'</a>'; |
$vars["version"] = $version; |
$vars['logurl'] = $config->getURL($rep, $path, 'log').$passRevString; |
$vars['loglink'] = '<a href="'.$vars['logurl'].'">'.$lang['VIEWLOG'].'</a>'; |
if (!$rep->hasReadAccess($path, false)) |
$vars["noaccess"] = true; |
$vars['blameurl'] = $config->getURL($rep, $path, 'blame').$passRevString; |
$vars['blamelink'] = '<a href="'.$vars['blameurl'].'">'.$lang['BLAME'].'</a>'; |
parseTemplate($rep->getTemplatePath()."header.tmpl", $vars, $listing); |
parseTemplate($rep->getTemplatePath()."file.tmpl", $vars, $listing); |
parseTemplate($rep->getTemplatePath()."footer.tmpl", $vars, $listing); |
?> |
if ($history == null || count($history->entries) > 1) |
{ |
$vars['diffurl'] = $config->getURL($rep, $path, 'diff').$passRevString; |
$vars['difflink'] = '<a href="'.$vars['diffurl'].'">'.$lang['DIFFPREV'].'</a>'; |
} |
if ($rep->isDownloadAllowed($path)) |
{ |
$vars['downloadlurl'] = $config->getURL($rep, $path, 'dl').$passRevString; |
$vars['downloadlink'] = '<a href="'.$vars['downloadlurl'].'">'.$lang['DOWNLOAD'].'</a>'; |
} |
if ($rep->isRssEnabled()) |
{ |
$vars['rssurl'] = $config->getURL($rep, $path, 'rss').createRevAndPegString('', $peg); |
$vars['rsslink'] = '<a href="'.$vars['rssurl'].'">'.$lang['RSSFEED'].'</a>'; |
} |
$mimeType = $useMime; // Restore preserved value to use for 'mimelink' variable. |
// If there was a MIME type, create a link to display file with that type. |
if ($mimeType && !isset($vars['warning'])) |
{ |
$vars['mimeurl'] = $config->getURL($rep, $path, 'file').'usemime=1&'.$passRevString; |
$vars['mimelink'] = '<a href="'.$vars['mimeurl'].'">'.$lang['VIEWAS'].' "'.$mimeType.'"</a>'; |
} |
$vars['rev'] = $rev; |
$vars['peg'] = $peg; |
if (!$rep->hasReadAccess($path)) |
{ |
$vars['error'] = $lang['NOACCESS']; |
sendHeaderForbidden(); |
} |
else if (!$svnrep->isFile($path, $rev, $peg)) |
{ |
renderTemplate404('file','NOPATH'); |
} |
// $listing is populated with file data when file.tmpl calls [websvn-getlisting] |
renderTemplate('file'); |
/WebSVN/include/auth.inc |
---|
File deleted |
/WebSVN/include/command.inc |
---|
File deleted |
/WebSVN/include/svnlook.inc |
---|
File deleted |
/WebSVN/include/feedcreator.class.php |
---|
File deleted |
/WebSVN/include/distconfig.inc |
---|
File deleted |
/WebSVN/include/configclass.inc |
---|
File deleted |
/WebSVN/include/PHP/Compat.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Function/image_type_to_mime_type.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Function/get_include_path.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Function/str_rot13.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Function/array_uintersect_uassoc.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Function/clone.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Function/ob_get_clean.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Function/ob_flush.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Function/restore_include_path.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Function/ini_get_all.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Function/fprintf.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Function/set_include_path.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Function/str_ireplace.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Function/pg_unescape_bytea.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Function/mime_content_type.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Function/array_udiff_assoc.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Function/array_walk_recursive.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Function/scandir.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Function/md5_file.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Function/php_strip_whitespace.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Function/array_change_key_case.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Function/vprintf.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Function/constant.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Function/version_compare.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Function/inet_pton.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Function/mhash.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Function/time_sleep_until.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Function/ob_clean.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Function/floatval.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Function/array_combine.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Function/bcpowmod.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Function/array_uintersect_assoc.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Function/is_a.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Function/str_shuffle.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Function/strripos.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Function/idate.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Function/array_intersect_assoc.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Function/strpbrk.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Function/array_udiff.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Function/array_intersect_ukey.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Function/convert_uudecode.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Function/array_diff_assoc.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Function/pg_affected_rows.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Function/array_diff_ukey.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Function/stripos.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Function/array_intersect_key.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Function/array_chunk.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Function/pg_escape_bytea.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Function/get_headers.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Function/str_word_count.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Function/bcinvert.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Function/array_product.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Function/array_diff_key.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Function/http_build_query.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Function/str_split.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Function/array_uintersect.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Function/file_put_contents.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Function/array_key_exists.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Function/substr_compare.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Function/htmlspecialchars_decode.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Function/fputcsv.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Function/file_get_contents.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Function/inet_ntop.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Function/ob_get_flush.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Function/debug_print_backtrace.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Function/array_search.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Function/html_entity_decode.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Function/convert_uuencode.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Function/array_udiff_uassoc.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Function/ibase_timefmt.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Function/array_intersect_uassoc.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Function/vsprintf.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Function/call_user_func_array.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Function/array_diff_uassoc.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Function/var_export.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Constant/STD.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Constant/E_STRICT.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Constant/PATH_SEPARATOR.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Constant/UPLOAD_ERR.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Constant/FILE.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Constant/T.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Constant/DIRECTORY_SEPARATOR.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Constant/PHP_EOL.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/PHP/Compat/Components.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/include/version.inc |
---|
File deleted |
/WebSVN/include/php5compat.inc |
---|
File deleted |
/WebSVN/include/config.inc |
---|
File deleted |
/WebSVN/include/accessfile.inc |
---|
File deleted |
/WebSVN/include/utils.inc |
---|
File deleted |
/WebSVN/include/setup.inc |
---|
File deleted |
/WebSVN/include/template.inc |
---|
File deleted |
/WebSVN/include/bugtraq.inc |
---|
File deleted |
/WebSVN/include/.gitignore |
---|
0,0 → 1,0 |
/config.php |
/WebSVN/include/authz.php |
---|
0,0 → 1,132 |
<?php |
// WebSVN - Subversion repository viewing via the web using PHP |
// Copyright (C) 2004-2006 Tim Armes |
// |
// This program is free software; you can redistribute it and/or modify |
// it under the terms of the GNU General Public License as published by |
// the Free Software Foundation; either version 2 of the License, or |
// (at your option) any later version. |
// |
// This program is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License |
// along with this program; if not, write to the Free Software |
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
// |
// -- |
// |
// authz.php |
// |
// Handle SVN access file |
class Authorization { |
var $accessCache = array(); |
var $accessFile = null; |
var $user = null; |
// {{{ __construct |
function __construct() { |
$this->setUsername(); |
} |
// }}} |
function hasUsername() { |
return $this->user !== null; |
} |
function addAccessFile($accessFile) { |
$this->accessFile = $accessFile; |
} |
// {{{ setUsername() |
// |
// Set the username from the current http session |
function setUsername() { |
if (isset($_SERVER['REMOTE_USER'])) { |
$this->user = $_SERVER['REMOTE_USER']; |
} else if (isset($_SERVER['REDIRECT_REMOTE_USER'])) { |
$this->user = $_SERVER['REDIRECT_REMOTE_USER']; |
} else if (isset($_SERVER['PHP_AUTH_USER'])) { |
$this->user = $_SERVER['PHP_AUTH_USER']; |
} |
} |
// }}} |
// Private function to simplify creation of common SVN authz command string text. |
function svnAuthzCommandString($repo, $path, $checkSubDirs = false) { |
global $config; |
$cmd = $config->getSvnAuthzCommand(); |
$repoAndPath = '--repository ' . quote($repo) . ' --path ' . quote($path); |
$username = !$this->hasUsername() ? '' : '--username ' . quote($this->user); |
$subDirs = !$checkSubDirs ? '' : '-R'; |
$authzFile = quote($this->accessFile); |
$retVal = "{$cmd} {$repoAndPath} {$username} {$subDirs} {$authzFile}"; |
return $retVal; |
} |
// {{{ hasReadAccess |
// |
// Returns true if the user has read access to the given path |
function hasReadAccess($repos, $path, $checkSubDirs = false) { |
if ($this->accessFile == null) |
return false; |
if ($path == '' || $path[0] != '/') { |
$path = '/'.$path; |
} |
$cmd = $this->svnAuthzCommandString($repos, $path, $checkSubDirs); |
$result = 'no'; |
// Access checks might be issued multiple times for the same repos and paths within one and |
// the same request, introducing a lot of overhead because of "svnauthz" especially with |
// many repos under Windows. The easiest way to somewhat optimize it for different scenarios |
// is using a cache. |
// |
// https://github.com/websvnphp/websvn/issues/78#issuecomment-489306169 |
$cache =& $this->accessCache; |
$cached = isset($cache[$cmd]) ? $cache[$cmd] : null; |
$cachedWhen = isset($cached) ? $cached['when'] : 0; |
$cachedExpired = (time() - 60) > $cachedWhen; |
if ($cachedExpired) { |
// Sorting by "when" should be established somehow to only remove the oldest element |
// instead of an arbitrary first one, which might be the newest added last time. |
if (count($cache) >= 1000) { |
array_shift($cache); |
} |
$result = runCommand($cmd)[0]; |
$cache[$cmd] = array('when' => time(), |
'result' => $result); |
} else { |
$result = $cached['result']; |
} |
return $result != 'no'; |
} |
// }}} |
// {{{ hasUnrestrictedReadAccess |
// |
// Returns true if the user has read access to the given path and too |
// all subdirectories |
function hasUnrestrictedReadAccess($repos, $path) { |
return $this->hasReadAccess($repos, $path, true); |
} |
// }}} |
} |
/WebSVN/include/bugtraq.php |
---|
0,0 → 1,371 |
<?php |
// WebSVN - Subversion repository viewing via the web using PHP |
// Copyright (C) 2004-2006 Tim Armes |
// |
// This program is free software; you can redistribute it and/or modify |
// it under the terms of the GNU General Public License as published by |
// the Free Software Foundation; either version 2 of the License, or |
// (at your option) any later version. |
// |
// This program is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License |
// along with this program; if not, write to the Free Software |
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
// |
// -- |
// |
// bugtraq.php |
// |
// Functions for accessing the bugtraq properties and replacing issue IDs |
// with URLs. |
// |
// For more information about bugtraq, see |
// http://svn.collab.net/repos/tortoisesvn/trunk/doc/issuetrackers.txt |
class Bugtraq { |
// {{{ Properties |
var $msgstring; |
var $urlstring; |
var $logregex; |
var $append; |
var $firstPart; |
var $firstPartLen; |
var $lastPart; |
var $lastPartLen; |
var $propsfound = false; |
// }}} |
// {{{ __construct($rep, $svnrep, $path) |
function __construct($rep, $svnrep, $path) { |
global $config; |
if ($rep->isBugtraqEnabled()) { |
$enoughdata = false; |
if (($properties = $rep->getBugtraqProperties()) !== null) { |
$this->msgstring = $properties['bugtraq:message']; |
$this->logregex = $properties['bugtraq:logregex']; |
$this->urlstring = $properties['bugtraq:url']; |
$this->append = $properties['bugtraq:append']; |
$enoughdata = true; |
} else { |
$pos = strrpos($path, '/'); |
$parent = substr($path, 0, $pos + 1); |
$this->append = true; |
while (!$enoughdata && (strpos($parent, '/') !== false)) { |
$properties = $svnrep->getProperties($parent); |
if (empty($this->msgstring) && in_array('bugtraq:message', $properties)) $this->msgstring = $svnrep->getProperty($parent, 'bugtraq:message'); |
if (empty($this->logregex) && in_array('bugtraq:logregex', $properties)) $this->logregex = $svnrep->getProperty($parent, 'bugtraq:logregex'); |
if (empty($this->urlstring) && in_array('bugtraq:url', $properties)) $this->urlstring = $svnrep->getProperty($parent, 'bugtraq:url'); |
if (in_array('bugtraq:append', $properties) && $svnrep->getProperty($parent, 'bugtraq:append') == 'false') $this->append = false; |
$parent = substr($parent, 0, -1); // Remove the trailing slash |
$pos = strrpos($parent, '/'); // Find the last trailing slash |
$parent = substr($parent, 0, $pos + 1); // Find the previous parent directory |
$enoughdata = ((!empty($this->msgstring) || !empty($this->logregex)) && !empty($this->urlstring)); |
} |
} |
$this->msgstring = trim(@$this->msgstring); |
$this->urlstring = trim(@$this->urlstring); |
if ($enoughdata && !empty($this->msgstring)) { |
$this->initPartInfo(); |
} |
if ($enoughdata) { |
$this->propsfound = true; |
} |
} |
} |
// }}} |
// {{{ initPartInfo() |
function initPartInfo() { |
if (($bugidpos = strpos($this->msgstring, '%BUGID%')) !== false && strpos($this->urlstring, '%BUGID%') !== false) { |
// Get the textual parts of the message string for comparison purposes |
$this->firstPart = substr($this->msgstring, 0, $bugidpos); |
$this->firstPartLen = strlen($this->firstPart); |
$this->lastPart = substr($this->msgstring, $bugidpos + 7); |
$this->lastPartLen = strlen($this->lastPart); |
} |
} |
// }}} |
// {{{ replaceIDs($message) |
function replaceIDs($message) { |
if (!$this->propsfound) return $message; |
// First we search for the message string |
$logmsg = ''; |
$message = rtrim($message); |
if ($this->append) { |
// Just compare the last line |
if (($offset = strrpos($message, "\n")) !== false) { |
$logmsg = substr($message, 0, $offset + 1); |
$bugLine = substr($message, $offset + 1); |
} else { |
$bugLine = $message; |
} |
} else { |
if (($offset = strpos($message, "\n")) !== false) { |
$bugLine = substr($message, 0, $offset); |
$logmsg = substr($message, $offset); |
} else { |
$bugLine = $message; |
} |
} |
// Make sure that our line really is an issue tracker message |
if (isset($this->firstPart) && isset($this->lastPart) && ((strncmp($bugLine, $this->firstPart, $this->firstPartLen) == 0)) && strcmp(substr($bugLine, -$this->lastPartLen, $this->lastPartLen), $this->lastPart) == 0) { |
// Get the issues list |
if ($this->lastPartLen > 0) { |
$issues = substr($bugLine, $this->firstPartLen, -$this->lastPartLen); |
} else { |
$issues = substr($bugLine, $this->firstPartLen); |
} |
// Add each reference to the first part of the line |
$line = $this->firstPart; |
while ($pos = strpos($issues, ',')) { |
$issue = trim(substr($issues, 0, $pos)); |
$issues = substr($issues, $pos + 1); |
$line .= '<a href="'.str_replace('%BUGID%', $issue, $this->urlstring).'">'.$issue.'</a>, '; |
} |
$line .= '<a href="'.str_replace('%BUGID%', trim($issues), $this->urlstring).'">'.trim($issues).'</a>'.$this->lastPart; |
if ($this->append) { |
$message = $logmsg.$line; |
} else { |
$message = $line.$logmsg; |
} |
} |
// Now replace all other instances of bug IDs that match the regex |
if ($this->logregex) { |
$message = rtrim($message); |
$line = ''; |
$allissues = ''; |
$lines = explode("\n", $this->logregex); |
$regex_all = '~'.$lines[0].'~'; |
$regex_single = @$lines[1]; |
if (empty($regex_single)) { |
// If the property only contains one line, then the pattern is only designed |
// to find one issue number at a time. e.g. [Ii]ssue #?(\d+). In this case |
// we need to replace the matched issue ID with the link. |
if ($numMatches = preg_match_all($regex_all, $message, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE)) { |
$addedOffset = 0; |
for ($match = 0; $match < $numMatches; $match++) { |
$issue = $matches[$match][1][0]; |
$issueOffset = $matches[$match][1][1]; |
$issueLink = '<a href="'.str_replace('%BUGID%', $issue, $this->urlstring).'">'.$issue.'</a>'; |
$message = substr_replace($message, $issueLink, $issueOffset + $addedOffset, strlen($issue)); |
$addedOffset += strlen($issueLink) - strlen($issue); |
} |
} |
} else { |
// It the property contains two lines, then the first is a pattern for extracting |
// multiple issue numbers, and the second is a pattern extracting each issue |
// number from the multiple match. e.g. [Ii]ssue #?(\d+)(,? ?#?(\d+))+ and (\d+) |
while (preg_match($regex_all, $message, $matches, PREG_OFFSET_CAPTURE)) { |
$completeMatch = $matches[0][0]; |
$completeMatchOffset = $matches[0][1]; |
$replacement = $completeMatch; |
if ($numMatches = preg_match_all('~'.$regex_single.'~', $replacement, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE)) { |
$addedOffset = 0; |
for ($match = 0; $match < $numMatches; $match++) { |
$issue = $matches[$match][1][0]; |
$issueOffset = $matches[$match][1][1]; |
$issueLink = '<a href="'.str_replace('%BUGID%', $issue, $this->urlstring).'">'.$issue.'</a>'; |
$replacement = substr_replace($replacement, $issueLink, $issueOffset + $addedOffset, strlen($issue)); |
$addedOffset += strlen($issueLink) - strlen($issue); |
} |
} |
$message = substr_replace($message, $replacement, $completeMatchOffset, strlen($completeMatch)); |
} |
} |
} |
return $message; |
} |
// }}} |
} |
// The BugtraqTestable class is a derived class that is used to test the matching |
// abilities of the Bugtraq class. In particular, it allows for the initialisation of the |
// class without the need for a repository. |
class BugtraqTestable extends Bugtraq { |
// {{{ __construct() |
function __construct() { |
// This constructor serves to assure that the parent constructor is not |
// called. |
} |
// }}} |
// {{{ setUpVars($message, $url, $regex, $append) |
function setUpVars($message, $url, $regex, $append) { |
$this->msgstring = $message; |
$this->urlstring = $url; |
$this->logregex = $regex; |
$this->append = $append; |
$this->propsfound = true; |
$this->initPartInfo(); |
} |
// }}} |
// {{{ setMessage($message) |
function setMessage($message) { |
$this->msgstring = $message; |
} |
// }}} |
// {{{ setUrl($url) |
function setUrl($url) { |
$this->urlstring = $url; |
} |
// }}} |
// {{{ setRegex($regex) |
function setRegEx($regex) { |
$this->logregex = $regex; |
} |
// }}} |
// {{{ setAppend($append) |
function setAppend($append) { |
$this->append = $append; |
} |
// }}} |
// {{{ printVars() |
function printVars() { |
echo 'msgstring = '.$this->msgstring."\n"; |
echo 'urlstring = '.$this->urlstring."\n"; |
echo 'logregex = '.$this->logregex."\n"; |
echo 'append = '.$this->append."\n"; |
echo 'firstPart = '.$this->firstPart."\n"; |
echo 'firstPartLen = '.$this->firstPartLen."\n"; |
echo 'lastPart = '.$this->lastPart."\n"; |
echo 'lastPartLen = '.$this->lastPartLen."\n"; |
} |
// }}} |
} |
// {{{ test_bugtraq() |
function test_bugtraq() { |
$tester = new BugtraqTestable; |
$tester->setUpVars('BugID: %BUGID%', |
'http://bugtracker/?id=%BUGID%', |
'[Ii]ssue #?(\d+)', |
true |
); |
//$tester->printVars(); |
$res = $tester->replaceIDs('BugID: 789'."\n". |
'This is a test message that refers to issue #123 and'."\n". |
'issue #456.'."\n". |
'BugID: 789' |
); |
echo nl2br($res).'<p>'; |
$res = $tester->replaceIDs('BugID: 789, 101112'."\n". |
'This is a test message that refers to issue #123 and'."\n". |
'issue #456.'."\n". |
'BugID: 789, 101112' |
); |
echo nl2br($res).'<p>'; |
$tester->setAppend(false); |
$res = $tester->replaceIDs('BugID: 789'."\n". |
'This is a test message that refers to issue #123 and'."\n". |
'issue #456.'."\n". |
'BugID: 789' |
); |
echo nl2br($res).'<p>'; |
$res = $tester->replaceIDs('BugID: 789, 101112'."\n". |
'This is a test message that refers to issue #123 and'."\n". |
'issue #456.'."\n". |
'BugID: 789, 101112' |
); |
echo nl2br($res).'<p>'; |
$tester->setUpVars('BugID: %BUGID%', |
'http://bugtracker/?id=%BUGID%', |
'[Ii]ssues?:?(\s*(,|and)?\s*#\d+)+\n(\d+)', |
true |
); |
$res = $tester->replaceIDs('BugID: 789, 101112'."\n". |
'This is a test message that refers to issue #123 and'."\n". |
'issues #456, #654 and #321.'."\n". |
'BugID: 789, 101112' |
); |
echo nl2br($res).'<p>'; |
$tester->setUpVars('Test: %BUGID%', |
'http://bugtracker/?id=%BUGID%', |
'\s*[Cc]ases*\s*[IDs]*\s*[#: ]+((\d+[ ,:;#]*)+)\n(\d+)', |
true |
); |
$res = $tester->replaceIDs('Cosmetic change'."\n". |
'CaseIDs: 48' |
); |
echo nl2br($res).'<p>'; |
} |
// }}} |
/WebSVN/include/command.php |
---|
0,0 → 1,209 |
<?php |
// WebSVN - Subversion repository viewing via the web using PHP |
// Copyright (C) 2004-2006 Tim Armes |
// |
// This program is free software; you can redistribute it and/or modify |
// it under the terms of the GNU General Public License as published by |
// the Free Software Foundation; either version 2 of the License, or |
// (at your option) any later version. |
// |
// This program is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License |
// along with this program; if not, write to the Free Software |
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
// |
// -- |
// |
// command.php |
// |
// External command handling |
function detectCharacterEncoding($str) { |
$list = array('UTF-8', 'ISO-8859-1', 'windows-1252'); |
if (function_exists('mb_detect_encoding')) { |
foreach ($list as $item) { |
if (mb_check_encoding($str, $item)) return $item; |
} |
} else if (function_exists('iconv')) { |
foreach ($list as $item) { |
$encstr = iconv($item, $item.'//TRANSLIT//IGNORE', $str); |
if (md5($encstr) == md5($str)) return $item; |
} |
} |
return null; |
} |
// {{{ toOutputEncoding |
function toOutputEncoding($str) { |
$enc = detectCharacterEncoding($str); |
if ($enc !== null && function_exists('mb_convert_encoding')) { |
$str = mb_convert_encoding($str, 'UTF-8', $enc); |
} else if ($enc !== null && function_exists('iconv')) { |
$str = iconv($enc, 'UTF-8//TRANSLIT//IGNORE', $str); |
} else { |
// @see http://w3.org/International/questions/qa-forms-utf-8.html |
$isUtf8 = preg_match('%^(?: |
[\x09\x0A\x0D\x20-\x7E] # ASCII |
| [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte |
| \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs |
| [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2} # straight 3-byte |
| \xED[\x80-\x9F][\x80-\xBF] # excluding surrogates |
| \xF0[\x90-\xBF][\x80-\xBF]{2} # planes 1-3 |
| [\xF1-\xF3][\x80-\xBF]{3} # planes 4-15 |
| \xF4[\x80-\x8F][\x80-\xBF]{2} # plane 16 |
)*$%xs', $str |
); |
if (!$isUtf8) $str = utf8_encode($str); |
} |
return $str; |
} |
// }}} |
// {{{ escape |
// |
// Escape a string to output |
function escape($str) { |
$entities = array(); |
$entities['&'] = '&'; |
$entities['<'] = '<'; |
$entities['>'] = '>'; |
$entities['"'] = '"'; |
$entities['\''] = '''; |
return str_replace(array_keys($entities), array_values($entities), $str ?? ''); |
} |
// }}} |
// {{{ execCommand |
function execCommand($cmd, &$retcode) { |
return @exec($cmd, $tmp, $retcode); |
} |
// }}} |
// {{{ popenCommand |
function popenCommand($cmd, $mode) { |
return popen($cmd, $mode); |
} |
// }}} |
// {{{ passthruCommand |
function passthruCommand($cmd) { |
return passthru($cmd); |
} |
// }}} |
// {{{ runCommand |
function runCommand($cmd, $mayReturnNothing = false, &$errorIf = 'NOT_USED') { |
global $config, $lang; |
$output = array(); |
$error = ''; |
$opts = null; |
// https://github.com/websvnphp/websvn/issues/75 |
// https://github.com/websvnphp/websvn/issues/78 |
if ($config->serverIsWindows) { |
if (!strpos($cmd, '>') && !strpos($cmd, '|')) { |
$opts = array('bypass_shell' => true); |
} else { |
$cmd = '"'.$cmd.'"'; |
} |
} |
$descriptorspec = array(0 => array('pipe', 'r'), 1 => array('pipe', 'w'), 2 => array('pipe', 'w')); |
$resource = proc_open($cmd, $descriptorspec, $pipes, null, null, $opts); |
if (!is_resource($resource)) { |
echo '<p>'.$lang['BADCMD'].': <code>'.stripCredentialsFromCommand($cmd).'</code></p>'; |
exit; |
} |
$handle = $pipes[1]; |
$firstline = true; |
while (!feof($handle)) { |
$line = rtrim(fgets($handle), "\n\r"); |
if ($firstline && empty($line) && !$mayReturnNothing) { |
$error = 'No output on STDOUT.'; |
break; |
} |
$firstline = false; |
$output[] = toOutputEncoding($line); |
} |
while (!feof($pipes[2])) { |
$error .= fgets($pipes[2]); |
} |
$error = toOutputEncoding(trim($error)); |
fclose($pipes[0]); |
fclose($pipes[1]); |
fclose($pipes[2]); |
proc_close($resource); |
# Some commands are expected to return no output, but warnings on STDERR. |
if ((count($output) > 0) || $mayReturnNothing) { |
return $output; |
} |
if ($errorIf != 'NOT_USED') { |
$errorIf = $error; |
return $output; |
} |
echo '<p>'.$lang['BADCMD'].': <code>'.stripCredentialsFromCommand($cmd).'</code></p>'; |
echo '<p>'.nl2br($error).'</p>'; |
exit; |
} |
// }}} |
function stripCredentialsFromCommand($cmd) { |
global $config; |
$quotingChar = ($config->serverIsWindows ? '"' : "'"); |
$quotedString = $quotingChar.'([^'.$quotingChar.'\\\\]*(\\\\.[^'.$quotingChar.'\\\\]*)*)'.$quotingChar; |
$patterns = array('|--username '.$quotedString.' |U', '|--password '.$quotedString.' |U'); |
$replacements = array('--username '.quote('***').' ', '--password '.quote('***').' '); |
$cmd = preg_replace($patterns, $replacements, $cmd, 1); |
return $cmd; |
} |
// {{{ quote |
// |
// Quote a string to send to the command line |
function quote($str) { |
global $config; |
if ($config->serverIsWindows) { |
return '"'.$str.'"'; |
} else { |
return escapeshellarg($str); |
} |
} |
// }}} |
/WebSVN/include/configclass.php |
---|
0,0 → 1,1702 |
<?php |
// WebSVN - Subversion repository viewing via the web using PHP |
// Copyright (C) 2004-2006 Tim Armes |
// |
// This program is free software; you can redistribute it and/or modify |
// it under the terms of the GNU General Public License as published by |
// the Free Software Foundation; either version 2 of the License, or |
// (at your option) any later version. |
// |
// This program is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License |
// along with this program; if not, write to the Free Software |
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
// |
// -- |
// |
// configclass.php |
// |
// General class for handling configuration options |
require_once 'include/command.php'; |
require_once 'include/authz.php'; |
require_once 'include/version.php'; |
// Auxillary functions used to sort repositories by name/group |
// {{{ cmpReps($a, $b) |
function cmpReps($a, $b) { |
// First, sort by group |
$g = strcasecmp((string) $a->group, (string) $b->group); |
if ($g) return $g; |
// Same group? Sort by name |
return strcasecmp($a->name, $b->name); |
} |
// }}} |
// {{{ cmpGroups($a, $b) |
function cmpGroups($a, $b) { |
$g = strcasecmp((string) $a->group, (string) $b->group); |
if ($g) return $g; |
return 0; |
} |
// }}} |
// {{{ mergesort(&$array, [$cmp_function]) |
function mergesort(&$array, $cmp_function = 'strcmp') { |
// Arrays of size < 2 require no action |
if (count($array) < 2) return; |
// Split the array in half |
$halfway = count($array) / 2; |
$array1 = array_slice($array, 0, $halfway); |
$array2 = array_slice($array, $halfway); |
// Recurse to sort the two halves |
mergesort($array1, $cmp_function); |
mergesort($array2, $cmp_function); |
// If all of $array1 is <= all of $array2, just append them. |
if (call_user_func($cmp_function, end($array1), $array2[0]) < 1) { |
$array = array_merge($array1, $array2); |
return; |
} |
// Merge the two sorted arrays into a single sorted array |
$array = array(); |
$array1count = count($array1); |
$array2count = count($array2); |
$ptr1 = 0; |
$ptr2 = 0; |
while ($ptr1 < $array1count && $ptr2 < $array2count) { |
if (call_user_func($cmp_function, $array1[$ptr1], $array2[$ptr2]) < 1) { |
$array[] = $array1[$ptr1++]; |
} else { |
$array[] = $array2[$ptr2++]; |
} |
} |
// Merge the remainder |
while ($ptr1 < $array1count) $array[] = $array1[$ptr1++]; |
while ($ptr2 < $array2count) $array[] = $array2[$ptr2++]; |
return; |
} |
// }}} |
// A Repository parent path configuration class |
class ParentPath { |
// {{{ Properties |
var $path; |
var $group; |
var $pattern; |
var $skipAlreadyAdded; |
var $clientRootURL; |
// }}} |
// {{{ __construct($path [, $group [, $pattern [, $skipAlreadyAdded [, $clientRootURL]]]]) |
function __construct($path, $group = null, $pattern = false, $skipAlreadyAdded = true, $clientRootURL = '') { |
$this->path = $path; |
$this->group = $group; |
$this->pattern = $pattern; |
$this->skipAlreadyAdded = $skipAlreadyAdded; |
$this->clientRootURL = rtrim($clientRootURL, '/'); |
} |
// }}} |
// {{{ findRepository($name) |
// look for a repository with $name |
function &findRepository($name) { |
global $config; |
if ($this->group != null) { |
$prefix = $this->group.'.'; |
if (substr($name, 0, strlen($prefix)) == $prefix) { |
$name = substr($name, strlen($prefix)); |
} else { |
$null = null; |
return $null; |
} |
} |
// is there a directory named $name? |
$fullpath = $this->path.DIRECTORY_SEPARATOR.$name; |
if (is_dir($fullpath) && is_readable($fullpath)) { |
// And that contains a db directory (in an attempt to not include non svn repositories. |
$dbfullpath = $fullpath.DIRECTORY_SEPARATOR.'db'; |
if (is_dir($dbfullpath) && is_readable($dbfullpath)) { |
// And matches the pattern if specified |
if ($this->pattern === false || preg_match($this->pattern, $name)) { |
$url = $config->fileUrlPrefix.$fullpath; |
$url = str_replace(DIRECTORY_SEPARATOR, '/', $url); |
if ($url[ strlen($url) - 1 ] == '/') { |
$url = substr($url, 0, -1); |
} |
if (!in_array($url, $config->_excluded, true)) { |
$clientRootURL = ($this->clientRootURL) ? $this->clientRootURL.'/'.$name : ''; |
$rep = new Repository($name, $name, $url, $this->group, null, null, null, $clientRootURL); |
return $rep; |
} |
} |
} |
} |
$null = null; |
return $null; |
} |
// }}} |
// {{{ getRepositories() |
// return all repositories in the parent path matching pattern |
function &getRepositories() { |
global $config; |
$repos = array(); |
$handle = @opendir($this->path); |
if (!$handle) return $repos; |
// For each file... |
while (false !== ($name = readdir($handle))) { |
$fullpath = $this->path.DIRECTORY_SEPARATOR.$name; |
if ($name[0] != '.' && is_dir($fullpath) && is_readable($fullpath)) { |
// And that contains a db directory (in an attempt to not include non svn repositories. |
$dbfullpath = $fullpath.DIRECTORY_SEPARATOR.'db'; |
if (is_dir($dbfullpath) && is_readable($dbfullpath)) { |
// And matches the pattern if specified |
if ($this->pattern === false || preg_match($this->pattern, $name)) { |
$url = $config->fileUrlPrefix.$fullpath; |
$url = str_replace(DIRECTORY_SEPARATOR, '/', $url); |
if ($url[strlen($url) - 1] == '/') { |
$url = substr($url, 0, -1); |
} |
$clientRootURL = ($this->clientRootURL) ? $this->clientRootURL.'/'.$name : ''; |
$repos[] = new Repository($name, $name, $url, $this->group, null, null, null, $clientRootURL); |
} |
} |
} |
} |
closedir($handle); |
// Sort the repositories into alphabetical order |
if (!empty($repos)) { |
usort($repos, 'cmpReps'); |
} |
return $repos; |
} |
// }}} |
// {{{ getSkipAlreadyAdded() |
// Return if we should skip already added repos for this parent path. |
function getSkipAlreadyAdded() { |
return $this->skipAlreadyAdded; |
} |
// }}} |
} |
// A Repository configuration class |
class Repository { |
// {{{ Properties |
var $name; |
var $svnName; |
var $path; |
var $subpath; |
var $group; |
var $username = null; |
var $password = null; |
var $clientRootURL; |
// Local configuration options must start off unset |
var $allowDownload; |
var $minDownloadLevel; |
var $allowedExceptions = array(); |
var $disallowedExceptions = array(); |
var $logsShowChanges; |
var $rss; |
var $rssCaching; |
var $rssMaxEntries; |
var $spaces; |
var $ignoreSvnMimeTypes; |
var $ignoreWebSVNContentTypes; |
var $bugtraq; |
var $bugtraqProperties; |
var $authz = null; |
var $templatePath = false; |
// }}} |
// {{{ __construct($name, $svnName, $serverRootURL [, $group [, $username [, $password [, $clientRootURL]]]]) |
function __construct($name, $svnName, $serverRootURL, $group = null, $username = null, $password = null, $subpath = null, $clientRootURL = null) { |
$this->name = $name; |
$this->svnName = $svnName; |
$this->path = $serverRootURL; |
$this->subpath = $subpath; |
$this->group = $group; |
$this->username = $username; |
$this->password = $password; |
$this->clientRootURL = rtrim($clientRootURL, '/'); |
} |
// }}} |
// {{{ getDisplayName() |
function getDisplayName() { |
if (!empty($this->group)) { |
return $this->group.'.'.$this->name; |
} |
return $this->name; |
} |
// }}} |
// {{{ svnCredentials |
function svnCredentials() { |
$params = ''; |
if ($this->username !== null && $this->username !== '') { |
$params .= ' --username '.quote($this->username); |
} |
if ($this->password !== null) { |
$params .= ' --password '.quote($this->password); |
} |
return $params; |
} |
// }}} |
// Local configuration accessors |
function setLogsShowChanges($enabled = true) { |
$this->logsShowChanges = $enabled; |
} |
function logsShowChanges() { |
global $config; |
if (isset($this->logsShowChanges)) |
return $this->logsShowChanges; |
else |
return $config->logsShowChanges(); |
} |
// {{{ RSS Feed |
function setRssEnabled($enabled) { |
$this->rss = $enabled; |
} |
function isRssEnabled() { |
global $config; |
if (isset($this->rss)) |
return $this->rss; |
else |
return $config->isRssEnabled(); |
} |
function setRssCachingEnabled($enabled = true) { |
$this->rssCaching = $enabled; |
} |
function isRssCachingEnabled() { |
global $config; |
if (isset($this->rssCaching)) |
return $this->rssCaching; |
else |
return $config->isRssCachingEnabled(); |
} |
function setRssMaxEntries($max) { |
$this->rssMaxEntries = $max; |
} |
function getRssMaxEntries() { |
global $config; |
if (isset($this->rssMaxEntries)) |
return $this->rssMaxEntries; |
else |
return $config->getRssMaxEntries(); |
} |
// }}} |
// {{{ Download |
function allowDownload() { |
$this->allowDownload = true; |
} |
function disallowDownload() { |
$this->allowDownload = false; |
} |
function getAllowDownload() { |
global $config; |
if (isset($this->allowDownload)) { |
return $this->allowDownload; |
} |
return $config->getAllowDownload(); |
} |
function setMinDownloadLevel($level) { |
$this->minDownloadLevel = $level; |
} |
function getMinDownloadLevel() { |
global $config; |
if (isset($this->minDownloadLevel)) { |
return $this->minDownloadLevel; |
} |
return $config->getMinDownloadLevel(); |
} |
function addAllowedDownloadException($path) { |
if ($path[strlen($path) - 1] != '/') $path .= '/'; |
$this->allowedExceptions[] = $path; |
} |
function addDisallowedDownloadException($path) { |
if ($path[strlen($path) - 1] != '/') $path .= '/'; |
$this->disallowedExceptions[] = $path; |
} |
function isDownloadAllowed($path) { |
global $config; |
// Check global download option |
if (!$this->getAllowDownload()) { |
return false; |
} |
// Check with access module |
if (!$this->hasUnrestrictedReadAccess($path)) { |
return false; |
} |
$subs = explode('/', $path); |
$level = count($subs) - 2; |
if ($level >= $this->getMinDownloadLevel()) { |
// Level OK, search for disallowed exceptions |
if ($config->findException($path, $this->disallowedExceptions)) { |
return false; |
} |
if ($config->findException($path, $config->disallowedExceptions)) { |
return false; |
} |
return true; |
} else { |
// Level not OK, search for disallowed exceptions |
if ($config->findException($path, $this->allowedExceptions)) { |
return true; |
} |
if ($config->findException($path, $config->allowedExceptions)) { |
return true; |
} |
return false; |
} |
} |
// }}} |
// {{{ Templates |
function setTemplatePath($path) { |
$this->templatePath = $path; |
} |
function getTemplatePath() { |
global $config; |
if (!empty($this->templatePath)) { |
return $this->templatePath; |
} |
return $config->getTemplatePath(); |
} |
// }}} |
// {{{ Tab expansion |
function expandTabsBy($sp) { |
$this->spaces = $sp; |
} |
function getExpandTabsBy() { |
global $config; |
if (isset($this->spaces)) { |
return $this->spaces; |
} |
return $config->getExpandTabsBy(); |
} |
// }}} |
// {{{ MIME-Type Handing |
function ignoreSvnMimeTypes() { |
$this->ignoreSvnMimeTypes = true; |
} |
function useSvnMimeTypes() { |
$this->ignoreSvnMimeTypes = false; |
} |
function getIgnoreSvnMimeTypes() { |
global $config; |
if (isset($this->ignoreSvnMimeTypes)) { |
return $this->ignoreSvnMimeTypes; |
} |
return $config->getIgnoreSvnMimeTypes(); |
} |
function ignoreWebSVNContentTypes() { |
$this->ignoreWebSVNContentTypes = true; |
} |
function useWebSVNContentTypes() { |
$this->ignoreWebSVNContentTypes = false; |
} |
function getIgnoreWebSVNContentTypes() { |
global $config; |
if (isset($this->ignoreWebSVNContentTypes)) { |
return $this->ignoreWebSVNContentTypes; |
} |
return $config->getIgnoreWebSVNContentTypes(); |
} |
// }}} |
// {{{ Bugtraq issue tracking |
function setBugtraqEnabled($enabled) { |
$this->bugtraq = $enabled; |
} |
function isBugtraqEnabled() { |
global $config; |
if (isset($this->bugtraq)) |
return $this->bugtraq; |
else |
return $config->isBugtraqEnabled(); |
} |
function setBugtraqProperties($properties) { |
$this->bugtraqProperties = $properties; |
} |
function getBugtraqProperties() { |
global $config; |
if (isset($this->bugtraqProperties)) |
return $this->bugtraqProperties; |
else |
return $config->getBugtraqProperties(); |
} |
// }}} |
// {{{ Authorization |
function useAccessFile($file) { |
if (is_readable($file)) { |
if ($this->authz === null) { |
$this->authz = new Authorization(); |
} |
$this->authz->addAccessFile($file); |
} else { |
die('Unable to read access file "'.$file.'"'); |
} |
} |
function &getAuthz() { |
global $config; |
$a = null; |
if ($this->authz !== null) { |
$a =& $this->authz; |
} else { |
$a =& $config->getAuthz(); |
} |
return $a; |
} |
function _getPathWithSubIf($pathWoSub) { |
if (!$this->subpath) { |
return $pathWoSub; |
} |
return '/' . $this->subpath . $pathWoSub; |
} |
function hasReadAccess($pathWoSub, $checkSubDirs = false) { |
$path = $this->_getPathWithSubIf($pathWoSub); |
$a =& $this->getAuthz(); |
if (!empty($a)) { |
return $a->hasReadAccess($this->svnName, $path, $checkSubDirs); |
} |
// No access file - free access... |
return true; |
} |
function hasLogReadAccess($pathWithSub) { |
$path = $pathWithSub; |
$a =& $this->getAuthz(); |
if (!empty($a)) { |
return $a->hasReadAccess($this->svnName, $path, false); |
} |
// No access file - free access... |
return true; |
} |
function hasUnrestrictedReadAccess($pathWoSub) { |
$path = $this->_getPathWithSubIf($pathWoSub); |
$a =& $this->getAuthz(); |
if (!empty($a)) { |
return $a->hasUnrestrictedReadAccess($this->svnName, $path); |
} |
// No access file - free access... |
return true; |
} |
// }}} |
} |
// The general configuration class |
class WebSvnConfig { |
// {{{ Properties |
// Tool path locations |
var $_svnCommandPath = ''; |
var $_svnConfigDir = '/tmp/websvn'; |
var $_svnTrustServerCert = false; |
var $svn = 'svn --non-interactive --config-dir /tmp/websvn'; |
var $svnAuthz = 'svnauthz accessof'; |
var $diff = 'diff'; |
var $enscript = 'enscript -q'; |
var $sed = 'sed'; |
var $gzip = 'gzip'; |
var $tar = 'tar'; |
var $zip = 'zip'; |
var $locale = ''; |
// different modes for file and directory download |
var $defaultFileDlMode = 'plain'; |
var $defaultDirectoryDlMode = 'gzip'; |
var $validFileDlModes = array( 'gzip', 'zip', 'plain' ); |
var $validDirectoryDlModes = array( 'gzip', 'zip' ); |
// Other configuration items |
var $treeView = true; |
var $flatIndex = true; |
var $openTree = false; |
var $alphabetic = false; |
var $showLastModInIndex = true; |
var $showLastModInListing = true; |
var $showAgeInsteadOfDate = true; |
var $_showRepositorySelectionForm = true; |
var $_ignoreWhitespacesInDiff = false; |
var $serverIsWindows = false; |
var $multiViews = false; |
var $multiViewsIndex = 'browse'; |
var $useEnscript = false; |
var $useEnscriptBefore_1_6_3 = false; |
var $useGeshi = false; |
var $geshiScript = 'geshi.php'; |
var $useParsedown = false; |
var $parsedownScript = 'Parsedown.php'; |
var $inlineMimeTypes = array(); |
var $allowDownload = false; |
var $tempDir = ''; |
var $minDownloadLevel = 0; |
var $allowedExceptions = array(); |
var $disallowedExceptions = array(); |
var $logsShowChanges = false; |
var $rss = true; |
var $rssCaching = false; |
var $rssMaxEntries = 40; |
var $spaces = 8; |
var $bugtraq = false; |
var $bugtraqProperties = null; |
var $authz = null; |
var $blockRobots = false; |
var $loadAllRepos = false; |
var $templatePaths = array(); |
var $userTemplate = false; |
var $ignoreSvnMimeTypes = false; |
var $ignoreWebSVNContentTypes = false; |
var $subversionVersion = ''; |
var $subversionMajorVersion = ''; |
var $subversionMinorVersion = ''; |
var $defaultLanguage = 'en'; |
var $ignoreAcceptedLanguages = false; |
var $quote = "'"; |
var $pathSeparator = ':'; |
var $fileUrlPrefix = 'file://'; |
var $breadcrumbRepoRootAsRepo = false; |
var $_repositories = array(); |
var $_parentPaths = array(); // parent paths to load |
var $_parentPathsLoaded = false; |
var $_excluded = array(); |
// }}} |
// {{{ __construct() |
function __construct() { |
} |
// }}} |
// {{{ Repository configuration |
function addRepository($name, $serverRootURL, $group = null, $username = null, $password = null, $clientRootURL = null) { |
$this->addRepositorySubpath($name, $serverRootURL, null, $group, $username, $password, $clientRootURL); |
} |
function addRepositorySubpath($name, $serverRootURL, $subpath, $group = null, $username = null, $password = null, $clientRootURL = null) { |
if (DIRECTORY_SEPARATOR != '/') { |
$serverRootURL = str_replace(DIRECTORY_SEPARATOR, '/', $serverRootURL); |
if ($subpath !== null) { |
$subpath = str_replace(DIRECTORY_SEPARATOR, '/', $subpath); |
} |
} |
$serverRootURL = trim($serverRootURL, '/'); |
$svnName = substr($serverRootURL, strrpos($serverRootURL, '/') + 1); |
$this->_repositories[] = new Repository($name, $svnName, $serverRootURL, $group, $username, $password, $subpath, $clientRootURL); |
} |
// Automatically set up the repositories based on a parent path |
function parentPath($path, $group = null, $pattern = false, $skipAlreadyAdded = true, $clientRootURL = '') { |
$this->_parentPaths[] = new ParentPath($path, $group, $pattern, $skipAlreadyAdded, $clientRootURL); |
} |
function addExcludedPath($path) { |
$url = $this->fileUrlPrefix.$path; |
$url = str_replace(DIRECTORY_SEPARATOR, '/', $url); |
if ($url[strlen($url) - 1] == '/') { |
$url = substr($url, 0, -1); |
} |
$this->_excluded[] = $url; |
} |
function getRepositories() { |
// lazily load parent paths |
if ($this->_parentPathsLoaded) return $this->_repositories; |
$this->_parentPathsLoaded = true; |
foreach ($this->_parentPaths as $parentPath) { |
$parentRepos = $parentPath->getRepositories(); |
foreach ($parentRepos as $repo) { |
if (!$parentPath->getSkipAlreadyAdded()) { |
$this->_repositories[] = $repo; |
} else { |
// we have to check if we already have a repo with the same svn name |
$duplicate = false; |
foreach ($this->_repositories as $knownRepos) { |
if ($knownRepos->path == $repo->path && $knownRepos->subpath == $repo->subpath) { |
$duplicate = true; |
break; |
} |
} |
if (!$duplicate && !in_array($repo->path, $this->_excluded, true)) { |
$this->_repositories[] = $repo; |
} |
} |
} |
} |
return $this->_repositories; |
} |
function &findRepository($name) { |
// first look in the "normal repositories" |
foreach ($this->_repositories as $index => $rep) { |
if (strcmp($rep->getDisplayName(), $name) == 0) { |
$repref =& $this->_repositories[$index]; |
return $repref; |
} |
} |
// now if the parent repos have not already been loaded |
// check them |
if (!$this->_parentPathsLoaded) { |
foreach ($this->_parentPaths as $parentPath) { |
$repref =& $parentPath->findRepository($name); |
if ($repref != null) { |
$this->_repositories[] = $repref; |
return $repref; |
} |
} |
} |
// Hack to return a string by reference; value retrieved at setup.php:414 |
$str = 'Unable to find repository "'.escape($name).'".'; |
$error =& $str; |
return $error; |
} |
// }}} |
// {{{ setServerIsWindows |
// |
// The server is running on Windows |
function setServerIsWindows() { |
$this->serverIsWindows = true; |
// On Windows machines, use double quotes around command line parameters |
$this->quote = '"'; |
// On Windows, semicolon separates path entries in a list rather than colon. |
$this->pathSeparator = ';'; |
$this->fileUrlPrefix = 'file:///'; |
} |
// }}} |
// {{{ MultiViews |
// useMultiViews |
// |
// Use MultiViews to access the repository |
function useMultiViews($multiViewsIndex = 'browse') { |
$this->multiViews = true; |
$this->multiViewsIndex = $multiViewsIndex; |
} |
function getUseMultiViews() { |
return $this->multiViews; |
} |
function getMultiViewsIndex() { |
return $this->multiViewsIndex; |
} |
// }}} |
// {{{ Enscript |
// useEnscript |
// |
// Use Enscript to colourise listings |
function useEnscript($before_1_6_3 = false) { |
$this->useEnscript = true; |
$this->useEnscriptBefore_1_6_3 = $before_1_6_3; |
} |
function getUseEnscript() { |
return $this->useEnscript; |
} |
function getUseEnscriptBefore_1_6_3() { |
return $this->useEnscriptBefore_1_6_3; |
} |
// }}} |
// {{{ GeSHi |
function setGeshiPath($path) { |
$this->_setPath($this->geshiScript, $path, 'geshi.php'); |
} |
function getGeshiScript() { |
return $this->geshiScript; |
} |
// useGeshi |
// |
// Use GeSHi to colourise listings |
function useGeshi() { |
$this->useGeshi = true; |
} |
function getUseGeshi() { |
return $this->useGeshi; |
} |
// }}} |
// {{{ Parsedown |
function setParsedownPath($path) { |
$this->_setPath($this->parsedownScript, $path, 'Parsedown.php'); |
} |
function getParsedownScript() { |
return $this->parsedownScript; |
} |
// useParsedown |
// |
// Use Parsedown to render README.md |
function useParsedown() { |
$this->useParsedown = true; |
} |
function getUseParsedown() { |
return $this->useParsedown; |
} |
// }}} |
// {{{ Inline MIME Types |
// inlineMimeTypes |
// |
// Specify MIME types to display inline in WebSVN pages |
function addInlineMimeType($type) { |
if (!in_array($type, $this->inlineMimeTypes)) { |
$this->inlineMimeTypes[] = $type; |
} |
} |
// }}} |
// {{{ Show changed files by default on log.php |
function setLogsShowChanges($enabled = true, $myrep = 0) { |
if (empty($myrep)) { |
$this->logsShowChanges = $enabled; |
} else { |
$repo =& $this->findRepository($myrep); |
$repo->logsShowChanges = $enabled; |
} |
} |
function logsShowChanges() { |
return $this->logsShowChanges; |
} |
// }}} |
// {{{ RSS |
function setRssEnabled($enabled = true, $myrep = 0) { |
if (empty($myrep)) { |
$this->rss = $enabled; |
} else { |
$repo =& $this->findRepository($myrep); |
$repo->setRssEnabled($enabled); |
} |
} |
function isRssEnabled() { |
return $this->rss; |
} |
function setRssCachingEnabled($enabled = true, $myrep = 0) { |
if (empty($myrep)) { |
$this->rssCaching = true; |
} else { |
$repo =& $this->findRepository($myrep); |
$repo->setRssCachingEnabled($enabled); |
} |
} |
function isRssCachingEnabled() { |
return $this->rssCaching; |
} |
// Maximum number of entries in RSS feed |
function setRssMaxEntries($max, $myrep = 0) { |
if (empty($myrep)) { |
$this->rssMaxEntries = $max; |
} else { |
$repo =& $this->findRepository($myrep); |
$repo->setRssMaxEntries($max); |
} |
} |
function getRssMaxEntries() { |
return $this->rssMaxEntries; |
} |
function getHideRSS() { |
return $this->rss; |
} |
// cacheRSS |
// |
// Enable caching of RSS feeds |
function enableRSSCaching($myrep = 0) { |
if (empty($myrep)) { |
$this->rssCaching = true; |
} else { |
$repo =& $this->findRepository($myrep); |
$repo->enableRSSCaching(); |
} |
} |
function getRSSCaching() { |
return $this->rssCaching; |
} |
// }}} |
// {{{ Downloads |
// allowDownload |
// |
// Allow download of tarballs |
function allowDownload($myrep = 0) { |
if (empty($myrep)) { |
$this->allowDownload = true; |
} else { |
$repo =& $this->findRepository($myrep); |
$repo->allowDownload(); |
} |
} |
function disallowDownload($myrep = 0) { |
if (empty($myrep)) { |
$this->allowDownload = false; |
} else { |
$repo =& $this->findRepository($myrep); |
$repo->disallowDownload(); |
} |
} |
function getAllowDownload() { |
return $this->allowDownload; |
} |
function setTempDir($tempDir) { |
$this->tempDir = $tempDir; |
} |
function getTempDir() { |
if (empty($this->tempDir)) { |
$this->tempDir = sys_get_temp_dir(); |
} |
return $this->tempDir; |
} |
function setMinDownloadLevel($level, $myrep = 0) { |
if (empty($myrep)) { |
$this->minDownloadLevel = $level; |
} else { |
$repo =& $this->findRepository($myrep); |
$repo->setMinDownloadLevel($level); |
} |
} |
function getMinDownloadLevel() { |
return $this->minDownloadLevel; |
} |
function addAllowedDownloadException($path, $myrep = 0) { |
if ($path[strlen($path) - 1] != '/') { |
$path .= '/'; |
} |
if (empty($myrep)) { |
$this->allowedExceptions[] = $path; |
} else { |
$repo =& $this->findRepository($myrep); |
$repo->addAllowedDownloadException($path); |
} |
} |
function addDisallowedDownloadException($path, $myrep = 0) { |
if ($path[strlen($path) - 1] != '/') { |
$path .= '/'; |
} |
if (empty($myrep)) { |
$this->disallowedExceptions[] = $path; |
} else { |
$repo =& $this->findRepository($myrep); |
$repo->addDisallowedDownloadException($path); |
} |
} |
function findException($path, $exceptions) { |
foreach ($exceptions as $key => $exc) { |
if (strncmp($exc, $path, strlen($exc)) == 0) { |
return true; |
} |
} |
return false; |
} |
// }}} |
// {{{ getURL |
// |
// Get the URL to a path name based on the current config |
function getURL($rep, $path, $op) { |
list($base, $params) = $this->getUrlParts($rep, $path, $op); |
$url = $base.'?'; |
foreach ($params as $k => $v) { |
$url .= $k.'='.rawurlencode($v).'&'; |
} |
return $url; |
} |
// }}} |
// {{{ getUrlParts |
// |
// Get the URL and parameters for a path name based on the current config |
function getUrlParts($rep, $path, $op) { |
$params = array(); |
if ($this->multiViews) { |
$url = $_SERVER['SCRIPT_NAME']; |
if (preg_match('|\.php$|i', $url)) { |
// remove the .php extension |
$url = substr($url, 0, -4); |
} |
if ($path && $path[0] != '/') { |
$path = '/'.$path; |
} |
if (substr($url, -5) == 'index') { |
$url = substr($url, 0, -5).$this->multiViewsIndex; |
} |
if ($op == 'index') { |
$url .= '/'; |
} else if (is_object($rep)) { |
$url .= '/'.$rep->getDisplayName().str_replace('%2F', '/', rawurlencode($path ?? '')); |
if ($op && $op != 'dir' && $op != 'file') { |
$params['op'] = $op; |
} |
} |
} else { |
switch ($op) { |
case 'index': |
$url = '.'; |
break; |
case 'dir': |
$url = 'listing.php'; |
break; |
case 'revision': |
$url = 'revision.php'; |
break; |
case 'file': |
$url = 'filedetails.php'; |
break; |
case 'log': |
$url = 'log.php'; |
break; |
case 'diff': |
$url = 'diff.php'; |
break; |
case 'blame': |
$url = 'blame.php'; |
break; |
case 'form': |
$url = 'form.php'; |
break; |
case 'rss': |
$url = 'rss.php'; |
break; |
case 'dl': |
$url = 'dl.php'; |
break; |
case 'comp': |
$url = 'comp.php'; |
break; |
case 'search': |
$url = 'search.php'; |
break; |
} |
if (is_object($rep) && $op != 'index') { |
$params['repname'] = $rep->getDisplayName(); |
} |
if (!empty($path)) { |
$params['path'] = $path; |
} |
} |
return array($url, $params); |
} |
// }}} |
// {{{ Paths and Commands |
// setPath |
// |
// Set the location of the given path |
function _setPath(&$var, $path, $name, $params = '') { |
if ($path == '') { |
// Search in system search path. No check for existence possible |
$var = $name; |
} else { |
$lastchar = substr($path, -1, 1); |
$isDir = ($lastchar == DIRECTORY_SEPARATOR || $lastchar == '/' || $lastchar == '\\'); |
if (!$isDir) $path .= DIRECTORY_SEPARATOR; |
if (($this->serverIsWindows && !file_exists($path.$name.'.exe')) || (!$this->serverIsWindows && !file_exists($path.$name))) { |
echo 'Unable to find "'.$name.'" tool at location "'.$path.$name.'"'; |
exit; |
} |
// On a windows machine we need to put quotes around the |
// entire command to allow for spaces in the path |
if ($this->serverIsWindows) { |
$var = '"'.$path.$name.'"'; |
} else { |
$var = $path.$name; |
} |
} |
// Append parameters |
if ($params != '') $var .= ' '.$params; |
} |
// Define directory path to use for --config-dir parameter |
function setSvnConfigDir($path) { |
$this->_svnConfigDir = $path; |
$this->_updateSvnCommand(); |
} |
// Define flag to use --trust-server-cert parameter |
function setTrustServerCert() { |
$this->_svnTrustServerCert = true; |
$this->_updateSvnCommand(); |
} |
// Define the location of the svn command (e.g. '/usr/bin') |
function setSvnCommandPath($path) { |
$this->_svnCommandPath = $path; |
$this->_updateSvnCommand(); |
} |
// Define the location of the svnauthz command (e.g. '/usr/bin') |
function setSvnAuthzCommandPath($path) { |
$this->_setPath($this->svnAuthz, $path, 'svnauthz', 'accessof'); |
} |
function _updateSvnCommand() { |
$this->_setPath($this->svn, $this->_svnCommandPath, 'svn', '--non-interactive --config-dir '.$this->_svnConfigDir.($this->_svnTrustServerCert ? ' --trust-server-cert' : '')); |
} |
function getSvnCommand() { |
return $this->svn; |
} |
function getSvnAuthzCommand() { |
return $this->svnAuthz; |
} |
// setDiffPath |
// |
// Define the location of the diff command |
function setDiffPath($path) { |
$this->_setPath($this->diff, $path, 'diff'); |
} |
function getDiffCommand() { |
return $this->diff; |
} |
// setEnscriptPath |
// |
// Define the location of the enscript command |
function setEnscriptPath($path) { |
$this->_setPath($this->enscript, $path, 'enscript', '-q'); |
} |
function getEnscriptCommand() { |
return $this->enscript; |
} |
// setSedPath |
// |
// Define the location of the sed command |
function setSedPath($path) { |
$this->_setPath($this->sed, $path, 'sed'); |
} |
function getSedCommand() { |
return $this->sed; |
} |
// setTarPath |
// |
// Define the location of the tar command |
function setTarPath($path) { |
$this->_setPath($this->tar, $path, 'tar'); |
} |
function getTarCommand() { |
return $this->tar; |
} |
// setGzipPath |
// |
// Define the location of the GZip command |
function setGzipPath($path) { |
$this->_setPath($this->gzip, $path, 'gzip'); |
} |
function getGzipCommand() { |
return $this->gzip; |
} |
// setZipPath |
// |
// Define the location of the zip command |
function setZipPath($path) { |
$this->_setPath($this->zip, $path, 'zip'); |
} |
function getZipPath() { |
return $this->zip; |
} |
// setLocale |
// |
// Set the locale for PHP and all spawned processes |
function setLocale($locale) { |
$this->locale = $locale; |
} |
function getLocale() { |
return $this->locale; |
} |
// setDefaultFileDlMode |
// |
// Define the default file download mode - one of [gzip, zip, plain] |
function setDefaultFileDlMode($dlmode) { |
if (in_array($dlmode, $this->validFileDlModes)) { |
$this->defaultFileDlMode = $dlmode; |
} else { |
echo 'Setting default file download mode to an invalid value "'.$dlmode.'"'; |
exit; |
} |
} |
function getDefaultFileDlMode() { |
return $this->defaultFileDlMode; |
} |
// setDefaultDirectoryDlMode |
// |
// Define the default directory download mode - one of [gzip, zip] |
function setDefaultDirectoryDlMode($dlmode) { |
if (in_array($dlmode, $this->validDirectoryDlModes)) { |
$this->defaultDirectoryDlMode = $dlmode; |
} else { |
echo 'Setting default directory download mode to an invalid value "'.$dlmode.'"'; |
exit; |
} |
} |
function setDefaultFolderDlMode($dlmode) { |
$this->setDefaultDirectoryDlMode($dlmode); |
} |
function getDefaultDirectoryDlMode() { |
return $this->defaultDirectoryDlMode; |
} |
function getDefaultFolderDlMode() { |
return $this->getDefaultDirectoryDlMode(); |
} |
// Templates |
function addTemplatePath($path) { |
$lastchar = substr($path, -1, 1); |
if ($lastchar != '/' && $lastchar != '\\') { |
$path .= DIRECTORY_SEPARATOR; |
} |
if (!in_array($path, $this->templatePaths)) { |
$this->templatePaths[] = $path; |
} |
} |
function setTemplatePath($path, $myrep = null) { |
$lastchar = substr($path, -1, 1); |
if ($lastchar != '/' && $lastchar != '\\') { |
$path .= DIRECTORY_SEPARATOR; |
} |
if ($myrep !== null) { |
// fixed template for specific repository |
$repo =& $this->findRepository($myrep); |
$repo->setTemplatePath($path); |
} else { |
// for backward compatibility |
if (in_array($path, $this->templatePaths)) { |
array_splice($this->templatePaths, array_search($path, $this->templatePaths), 1); |
} |
array_unshift($this->templatePaths, $path); |
} |
} |
function getTemplatePath() { |
if (count($this->templatePaths) == 0) { |
echo 'No template path added in config file'; |
exit; |
} |
if ($this->userTemplate !== false) |
return $this->userTemplate; |
else |
return $this->templatePaths[0]; |
} |
// }}} |
function setDefaultLanguage($language) { |
$this->defaultLanguage = $language; |
} |
function getDefaultLanguage() { |
return $this->defaultLanguage; |
} |
function ignoreUserAcceptedLanguages() { |
$this->ignoreAcceptedLanguages = true; |
} |
function useAcceptedLanguages() { |
return !$this->ignoreAcceptedLanguages; |
} |
// {{{ Tab expansion functions |
function expandTabsBy($sp, $myrep = 0) { |
if (empty($myrep)) { |
$this->spaces = $sp; |
} else { |
$repo =& $this->findRepository($myrep); |
$repo->expandTabsBy($sp); |
} |
} |
function getExpandTabsBy() { |
return $this->spaces; |
} |
// }}} |
// {{{ Bugtraq issue tracking |
function setBugtraqEnabled($enabled, $myrep = 0) { |
if (empty($myrep)) { |
$this->bugtraq = $enabled; |
} else { |
$repo =& $this->findRepository($myrep); |
$repo->setBugtraqEnabled($enabled); |
} |
} |
function isBugtraqEnabled() { |
return $this->bugtraq; |
} |
function setBugtraqProperties($message, $logregex, $url, $append = true, $myrep = null) { |
$properties = array(); |
$properties['bugtraq:message'] = $message; |
$properties['bugtraq:logregex'] = $logregex; |
$properties['bugtraq:url'] = $url; |
$properties['bugtraq:append'] = (bool)$append; |
if ($myrep === null) { |
$this->bugtraqProperties = $properties; |
} else { |
$repo =& $this->findRepository($myrep); |
$repo->setBugtraqProperties($properties); |
} |
} |
function getBugtraqProperties() { |
return $this->bugtraqProperties; |
} |
// }}} |
// {{{ Misc settings |
function ignoreSvnMimeTypes() { |
$this->ignoreSvnMimeTypes = true; |
} |
function getIgnoreSvnMimeTypes() { |
return $this->ignoreSvnMimeTypes; |
} |
function ignoreWebSVNContentTypes() { |
$this->ignoreWebSVNContentTypes = true; |
} |
function getIgnoreWebSVNContentTypes() { |
return $this->ignoreWebSVNContentTypes; |
} |
function useAccessFile($file, $myrep = 0) { |
if (empty($myrep)) { |
if (is_readable($file)) { |
if ($this->authz === null) { |
$this->authz = new Authorization(); |
} |
$this->authz->addAccessFile($file); |
} else { |
echo 'Unable to read access file "'.$file.'"'; |
exit; |
} |
} else { |
$repo =& $this->findRepository($myrep); |
$repo->useAccessFile($file); |
} |
} |
function &getAuthz() { |
return $this->authz; |
} |
function areRobotsBlocked() { |
return $this->blockRobots; |
} |
function setBlockRobots($value = true) { |
$this->blockRobots = $value; |
} |
function useTreeView() { |
$this->treeView = true; |
} |
function getUseTreeView() { |
return $this->treeView; |
} |
function useFlatView() { |
$this->treeView = false; |
} |
function useTreeIndex($open) { |
$this->flatIndex = false; |
$this->openTree = $open; |
} |
function getUseFlatIndex() { |
return $this->flatIndex; |
} |
function getOpenTree() { |
return $this->openTree; |
} |
function setLoadAllRepos($flag) { |
$this->loadAllRepos = $flag; |
} |
function showLoadAllRepos() { |
return $this->loadAllRepos; |
} |
function setAlphabeticOrder($flag) { |
$this->alphabetic = $flag; |
} |
function isAlphabeticOrder() { |
return $this->alphabetic; |
} |
function showLastModInIndex() { |
return $this->showLastModInIndex; |
} |
function setShowLastModInIndex($show) { |
$this->showLastModInIndex = $show; |
} |
function showLastModInListing() { |
return $this->showLastModInListing; |
} |
function setShowLastModInListing($show) { |
$this->showLastModInListing = $show; |
} |
function showAgeInsteadOfDate() { |
return $this->showAgeInsteadOfDate; |
} |
function setShowAgeInsteadOfDate($show) { |
$this->showAgeInsteadOfDate = $show; |
} |
function showRepositorySelectionForm() { |
return $this->_showRepositorySelectionForm; |
} |
function setShowRepositorySelectionForm($show) { |
$this->_showRepositorySelectionForm = $show; |
} |
function getIgnoreWhitespacesInDiff() { |
return $this->_ignoreWhitespacesInDiff; |
} |
function setIgnoreWhitespacesInDiff($ignore) { |
$this->_ignoreWhitespacesInDiff = $ignore; |
} |
// Methods for storing version information for the command-line svn tool |
function setSubversionVersion($subversionVersion) { |
$this->subversionVersion = $subversionVersion; |
} |
function getSubversionVersion() { |
return $this->subversionVersion; |
} |
function setSubversionMajorVersion($subversionMajorVersion) { |
$this->subversionMajorVersion = $subversionMajorVersion; |
} |
function getSubversionMajorVersion() { |
return $this->subversionMajorVersion; |
} |
function setSubversionMinorVersion($subversionMinorVersion) { |
$this->subversionMinorVersion = $subversionMinorVersion; |
} |
function getSubversionMinorVersion() { |
return $this->subversionMinorVersion; |
} |
// }}} |
// {{{ Sort the repostories |
// |
// This function sorts the repositories by group name. The contents of the |
// group are left in there original order, which will either be sorted if the |
// group was added using the parentPath function, or defined for the order in |
// which the repositories were included in the user's config file. |
// |
// Note that as of PHP 4.0.6 the usort command no longer preserves the order |
// of items that are considered equal (in our case, part of the same group). |
// The mergesort function preserves this order. |
function sortByGroup() { |
if (!empty($this->_repositories)) { |
mergesort($this->_repositories, 'cmpGroups'); |
} |
} |
// }}} |
// {{{ Change the name of the breadcrumb root-phrase to that of the current repo? |
function setBreadcrumbRepoRootAsRepo($newValue) { |
$this->breadcrumbRepoRootAsRepo = $newValue; |
} |
function getBreadcrumbRepoRootAsRepo() { |
return $this->breadcrumbRepoRootAsRepo; |
} |
// }}} |
} |
/WebSVN/include/diff_inc.php |
---|
0,0 → 1,349 |
<?php |
// WebSVN - Subversion repository viewing via the web using PHP |
// Copyright (C) 2004-2006 Tim Armes |
// |
// This program is free software; you can redistribute it and/or modify |
// it under the terms of the GNU General Public License as published by |
// the Free Software Foundation; either version 2 of the License, or |
// (at your option) any later version. |
// |
// This program is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License |
// along with this program; if not, write to the Free Software |
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
// |
// -- |
// |
// diff_inc.php |
// |
// Diff to files |
if (!defined('USE_AUTOLOADER')) { |
@include_once 'Horde/String.php'; |
@include_once 'Horde/Text/Diff.php'; |
@include_once 'Horde/Text/Diff/Mapped.php'; |
@include_once 'Horde/Text/Diff/Engine/Native.php'; |
@include_once 'Horde/Text/Diff/Op/Base.php'; |
@include_once 'Horde/Text/Diff/Op/Copy.php'; |
@include_once 'Horde/Text/Diff/Op/Delete.php'; |
@include_once 'Horde/Text/Diff/Op/Add.php'; |
@include_once 'Horde/Text/Diff/Op/Change.php'; |
@include_once 'Horde/Text/Diff/Renderer.php'; |
@include_once 'Horde/Text/Diff/Renderer/Unified.php'; |
} |
include_once 'include/diff_util.php'; |
$arrayBased = false; |
$fileBased = false; |
class ListingHelper { |
var $_listing = array(); |
var $_index = 0; |
var $_blockStart = false; |
function _add($text1, $lineno1, $class1, $text2, $lineno2, $class2) { |
$listing = &$this->_listing; |
$index = &$this->_index; |
$listvar = &$listing[$index]; |
$listvar['rev1diffclass'] = $class1; |
$listvar['rev2diffclass'] = $class2; |
$listvar['rev1line'] = $text1; |
$listvar['rev2line'] = $text2; |
$listvar['rev1lineno'] = $lineno1; |
$listvar['rev2lineno'] = $lineno2; |
$listvar['startblock'] = $this->_blockStart; |
$this->_blockStart = false; |
$index++; |
} |
function addDeletedLine($text, $lineno) { |
$this->_add($text, $lineno, 'diffdeleted', ' ', '-', 'diffempty'); |
} |
function addAddedLine($text, $lineno) { |
$this->_add(' ', '-', 'diffempty', $text, $lineno, 'diffadded'); |
} |
function addChangedLine($text1, $lineno1, $text2, $lineno2) { |
$this->_add($text1, $lineno1, 'diffchanged', $text2, $lineno2, 'diffchanged'); |
} |
// note that $text1 do not need to be equal $text2 if $ignoreWhitespace is true |
function addLine($text1, $lineno1, $text2, $lineno2) { |
$this->_add($text1, $lineno1, 'diff', $text2, $lineno2, 'diff'); |
} |
function startNewBlock() { |
$this->_blockStart = true; |
} |
function getListing() { |
return $this->_listing; |
} |
} |
function nextLine(&$obj) { |
global $arrayBased, $fileBased; |
if ($arrayBased) return array_shift($obj); |
if ($fileBased) return fgets($obj); |
return ''; |
} |
function endOfFile(&$obj) { |
global $arrayBased, $fileBased; |
if ($arrayBased) return count($obj) == 0; |
if ($fileBased) return feof($obj); |
return true; |
} |
function getWrappedLineFromFile($file, $is_highlighted) { |
$line = fgets($file); |
if ($line === false) return false; |
$line = toOutputEncoding($line); |
if (!$is_highlighted) { |
$line = escape($line); |
} |
$line = rtrim($line, "\n\r"); |
if (strip_tags($line) === '') $line = ' '; |
return wrapInCodeTagIfNecessary($line); |
} |
function diff_result($all, $highlighted, $newtname, $oldtname, $obj, $ignoreWhitespace) { |
$ofile = fopen($oldtname, 'r'); |
$nfile = fopen($newtname, 'r'); |
// Get the first real line |
$line = nextLine($obj); |
$index = 0; |
$listingHelper = new ListingHelper(); |
$curoline = 1; |
$curnline = 1; |
$sensibleLineChanges = new SensibleLineChanges(new LineDiff($ignoreWhitespace)); |
while (!endOfFile($obj)) { |
// Get the first line of this range |
$oline = 0; |
sscanf($line, '@@ -%d', $oline); |
$line = substr($line, strpos($line, '+')); |
$nline = 0; |
sscanf($line, '+%d', $nline); |
while ($curoline < $oline || $curnline < $nline) { |
if ($curoline < $oline) { |
$text1 = getWrappedLineFromFile($ofile, $highlighted); |
$tmpoline = $curoline; |
$curoline++; |
} else { |
$tmpoline = '?'; |
$text1 = ' '; |
} |
if ($curnline < $nline) { |
$text2 = getWrappedLineFromFile($nfile, $highlighted); |
$tmpnline = $curnline; |
$curnline++; |
} else { |
$tmpnline = '?'; |
$text2 = ' '; |
} |
if ($all) { |
$listingHelper->addLine($text1, $tmpoline, $text2, $tmpnline); |
} |
} |
if (!$all && $line !== false) { |
$listingHelper->startNewBlock(); |
} |
$fin = false; |
while (!endOfFile($obj) && !$fin) { |
$line = nextLine($obj); |
if ($line === false || $line === '' || strncmp($line, '@@', 2) == 0) { |
$sensibleLineChanges->addChangesToListing($listingHelper, $highlighted); |
$fin = true; |
} else { |
$mod = $line[0]; |
$line = substr($line, 1); |
switch ($mod) { |
case '-': |
$text = getWrappedLineFromFile($ofile, $highlighted); |
$sensibleLineChanges->addDeletedLine($line, $text, $curoline); |
$curoline++; |
break; |
case '+': |
$text = getWrappedLineFromFile($nfile, $highlighted); |
$sensibleLineChanges->addAddedLine($line, $text, $curnline); |
$curnline++; |
break; |
default: |
$sensibleLineChanges->addChangesToListing($listingHelper, $highlighted); |
$text1 = getWrappedLineFromFile($ofile, $highlighted); |
$text2 = getWrappedLineFromFile($nfile, $highlighted); |
$listingHelper->addLine($text1, $curoline, $text2, $curnline); |
$curoline++; |
$curnline++; |
break; |
} |
} |
if (!$fin) { |
$index++; |
} |
} |
} |
$sensibleLineChanges->addChangesToListing($listingHelper, $highlighted); |
// Output the rest of the files |
if ($all) { |
while (!feof($ofile) || !feof($nfile)) { |
$noneof = false; |
$text1 = getWrappedLineFromFile($ofile, $highlighted); |
if ($text1 !== false) { |
$tmpoline = $curoline; |
$curoline++; |
$noneof = true; |
} else { |
$tmpoline = '-'; |
$text1 = ' '; |
} |
$text2 = getWrappedLineFromFile($nfile, $highlighted); |
if ($text2 !== false) { |
$tmpnline = $curnline; |
$curnline++; |
$noneof = true; |
} else { |
$tmpnline = '-'; |
$text2 = ' '; |
} |
if ($noneof) { |
$listingHelper->addLine($text1, $tmpoline, $text2, $tmpnline); |
} |
} |
} |
fclose($ofile); |
fclose($nfile); |
return $listingHelper->getListing(); |
} |
function command_diff($all, $ignoreWhitespace, $highlighted, $newtname, $oldtname, $newhlname, $oldhlname) { |
global $config, $lang, $arrayBased, $fileBased; |
$context = 5; |
if ($all) { |
// Setting the context to 0 makes diff generate the wrong line numbers! |
$context = 1; |
} |
if ($ignoreWhitespace) { |
$whitespaceFlag = ' -w'; |
} else { |
$whitespaceFlag = ''; |
} |
// Open a pipe to the diff command with $context lines of context: |
$cmd = $config->diff.$whitespaceFlag.' -U '.$context.' "'.$oldtname.'" "'.$newtname.'"'; |
$diff = runCommand($cmd, true); |
// Ignore the 3 header lines: |
$line = array_shift($diff); |
$line = array_shift($diff); |
$arrayBased = true; |
$fileBased = false; |
if ($highlighted) { |
$listing = diff_result($all, $highlighted, $newhlname, $oldhlname, $diff, $ignoreWhitespace); |
} else { |
$listing = diff_result($all, $highlighted, $newtname, $oldtname, $diff, $ignoreWhitespace); |
} |
return $listing; |
} |
function inline_diff($all, $ignoreWhitespace, $highlighted, $newtname, $oldtname, $newhlname, $oldhlname) { |
global $arrayBased, $fileBased; |
$context = 5; |
if ($all) { |
// Setting the context to 0 makes diff generate the wrong line numbers! |
$context = 1; |
} |
// modify error reporting level to suppress deprecated/strict warning "Assigning the return value of new by reference" |
$bckLevel = error_reporting(); |
$removeLevel = E_DEPRECATED; |
$modLevel = $bckLevel & (~$removeLevel); |
error_reporting($modLevel); |
// Create the diff class |
$fromLines = file($oldtname); |
$toLines = file($newtname); |
if (!$ignoreWhitespace) { |
$diff = new Horde_Text_Diff('Native', array($fromLines, $toLines)); |
} else { |
$whitespaces = array(' ', "\t", "\n", "\r"); |
$mappedFromLines = array(); |
foreach ($fromLines as $k => $line) { |
$line = rtrim($line, "\n\r"); |
$fromLines[$k] = $line; |
$mappedFromLines[] = str_replace($whitespaces, array(), $line); |
} |
$mappedToLines = array(); |
foreach ($toLines as $k => $line) { |
$line = rtrim($line, "\n\r"); |
$toLines[$k] = $line; |
$mappedToLines[] = str_replace($whitespaces, array(), $line); |
} |
$diff = new Horde_Text_Diff_Mapped('Native', array($fromLines, $toLines, $mappedFromLines, $mappedToLines)); |
} |
$renderer = new Horde_Text_Diff_Renderer_Unified(array('leading_context_lines' => $context, 'trailing_context_lines' => $context)); |
$rendered = explode("\n", $renderer->render($diff)); |
// restore previous error reporting level |
error_reporting($bckLevel); |
$arrayBased = true; |
$fileBased = false; |
if ($highlighted) { |
$listing = diff_result($all, $highlighted, $newhlname, $oldhlname, $rendered, $ignoreWhitespace); |
} else { |
$listing = diff_result($all, $highlighted, $newtname, $oldtname, $rendered, $ignoreWhitespace); |
} |
return $listing; |
} |
function do_diff($all, $ignoreWhitespace, $highlighted, $newtname, $oldtname, $newhlname, $oldhlname) { |
if ((!$ignoreWhitespace ? class_exists('Horde_Text_Diff') : class_exists('Horde_Text_Diff_Mapped')) |
&& class_exists('Horde_Text_Diff_Renderer_Unified')) { |
return inline_diff($all, $ignoreWhitespace, $highlighted, $newtname, $oldtname, $newhlname, $oldhlname); |
} else { |
return command_diff($all, $ignoreWhitespace, $highlighted, $newtname, $oldtname, $newhlname, $oldhlname); |
} |
} |
/WebSVN/include/diff_util.php |
---|
0,0 → 1,364 |
<?php |
// WebSVN - Subversion repository viewing via the web using PHP |
// Copyright (C) 2004-2006 Tim Armes |
// |
// This program is free software; you can redistribute it and/or modify |
// it under the terms of the GNU General Public License as published by |
// the Free Software Foundation; either version 2 of the License, or |
// (at your option) any later version. |
// |
// This program is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License |
// along with this program; if not, write to the Free Software |
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
// |
// -- |
// |
// diff_util.php |
// |
// help diff_inc.php to make sensible changes from added and deleted diff lines |
// These lines are automatically paired and also inline diff is performed to show |
// insertions/deletions on one line. diff_inc.php must have all Horde_Text_Diff |
// requirements met (include_once statements). |
// Interface for diffing function |
class LineDiffInterface { |
// similarity 1 means that strings are very close to each other |
// 0 means totally different |
function lineSimilarity($text1, $text2) { |
assert(false); |
} |
// return array($left, $right) annotated with <ins> and <del> |
function inlineDiff($text1, $highlighted1, $text2, $highlighted2, $highlighted) { |
assert(false); |
} |
} |
// Default line diffing function |
class LineDiff extends LineDiffInterface { |
private bool $ignoreWhitespace; |
function __construct($ignoreWhitespace) { |
$this->ignoreWhitespace = $ignoreWhitespace; |
} |
// {{{ levenshtein2 |
// levenshtein edit distance, on small strings use php function |
// on large strings approximate distance using words |
// computed by dynamic programming |
function levenshtein2($str1, $str2) { |
if (strlen($str1) < 255 && strlen($str2) < 255) { |
return levenshtein($str1, $str2); |
} |
$l1 = explode(' ', $str1); |
$l2 = explode(' ', $str2); |
$n = count($l1); |
$m = count($l2); |
$d = array_fill(0, $n + 1, array_fill(0, $m + 1, 0)); |
for ($i = 1; $i < $n + 1; $i++) { |
$d[$i][0] = $i; |
} |
for ($j = 1; $j < $m + 1; $j++) { |
$d[0][$j] = $j; |
} |
for ($i = 1; $i < $n + 1; $i++) { |
for ($j = 1; $j < $m + 1; $j++) { |
$c = ($l1[$i - 1] == $l2[$j - 1]) ? 0 : strlen($l1[$i - 1]) + strlen($l2[$j - 1]); |
$d[$i][$j] = min($d[$i - 1][$j] + 1, $d[$i][$j - 1] + 1, $d[$i - 1][$j - 1] + $c); |
} |
} |
return $d[$n][$m]; |
} |
// }}} |
// {{{ lineSimilarity |
function lineSimilarity($text1, $text2) { |
$distance = $this->levenshtein2($text1, $text2); |
return max(0.0, 1.0 - $distance / (strlen($text1) + strlen($text2) + 4)); |
} |
// }}} |
// {{{ tokenize whole line into words |
// note that separators are returned as tokens of length 1 |
// and if $ignoreWhitespace is true, consecutive whitespaces are returned as one token |
function tokenize($string, $highlighted, $ignoreWhitespace) { |
$html = array('<' => '>', '&' => ';'); |
$whitespaces = array("\t","\n","\r",' '); |
$separators = array('.','-','+','*','/','<','>','?','(',')','&','/','{','}','[',']',':',';'); |
$data = array(); |
$segment = ''; |
$segmentIsWhitespace = true; |
$count = strlen($string); |
for ($i = 0; $i < $count; $i++) { |
$c = $string[$i]; |
if ($highlighted && array_key_exists($c, $html)) { |
if ($segment != '') { |
$data[] = $segment; |
} |
// consider html tags and entities as a single token |
$endchar = $html[$c]; |
$segment = $c; |
do { |
$i++; |
$c = $string[$i]; |
$segment .= $c; |
} while ($c != $endchar && $i < $count - 1); |
$data[] = $segment; |
$segment = ''; |
$segmentIsWhitespace = false; |
} else if (in_array($c, $separators) || (!$ignoreWhitespace && in_array($c, $whitespaces))) { |
// if it is separator or whitespace and we do not consider consecutive whitespaces |
if ($segment != '') { |
$data[] = $segment; |
} |
$data[] = $c; |
$segment = ''; |
$segmentIsWhitespace = true; |
} else if (in_array($c, $whitespaces)) { |
// if it is whitespace and we consider consecutive whitespaces as one token |
if (!$segmentIsWhitespace) { |
$data[] = $segment; |
$segment = ''; |
$segmentIsWhitespace = true; |
} |
$segment .= $c; |
} else { |
// no separator or whitespace |
if ($segmentIsWhitespace && $segment != '') { |
$data[] = $segment; |
$segment = ''; |
} |
$segment .= $c; |
$segmentIsWhitespace = false; |
} |
} |
if ($segment != '') { |
$data[] = $segment; |
} |
return $data; |
} |
// }}} |
// {{{ lineDiff |
function inlineDiff($text1, $highlighted1, $text2, $highlighted2, $highlighted) { |
$whitespaces = array(' ', "\t", "\n", "\r"); |
$do_diff = true; |
if ($text1 == '' || $text2 == '') { |
$do_diff = false; |
} |
if ($this->ignoreWhitespace && (str_replace($whitespaces, array(), $text1) == str_replace($whitespaces, array(), $text2))) { |
$do_diff = false; |
} |
// Exit gracefully if loading of Horde_Text_Diff failed |
if (!class_exists('Horde_Text_Diff') || !class_exists('Horde_Text_Diff_Mapped')) { |
$do_diff = false; |
} |
// Return highlighted lines without doing inline diff |
if (!$do_diff) { |
return array($highlighted1, $highlighted2); |
} |
$tokens1 = $this->tokenize($highlighted1, $highlighted, $this->ignoreWhitespace); |
$tokens2 = $this->tokenize($highlighted2, $highlighted, $this->ignoreWhitespace); |
if (!$this->ignoreWhitespace) { |
$diff = new Horde_Text_Diff('Native', array($tokens1, $tokens2)); |
} else { |
// we need to create mapped parts for MappedDiff |
$mapped1 = array(); |
foreach ($tokens1 as $token) { |
$mapped1[] = str_replace($whitespaces, array(), $token); |
} |
$mapped2 = array(); |
foreach ($tokens2 as $token) { |
$mapped2[] = str_replace($whitespaces, array(), $token); |
} |
$diff = new Horde_Text_Diff_Mapped('Native', array($tokens1, $tokens2, $mapped1, $mapped2)); |
} |
// now, get the diff and annotate text |
$edits = $diff->getDiff(); |
$line1 = ''; |
$line2 = ''; |
foreach ($edits as $edit) { |
if ($edit instanceof Horde_Text_Diff_Op_Copy) { |
$line1 .= implode('', $edit->orig); |
$line2 .= implode('', $edit->final); |
} else if ($edit instanceof Horde_Text_Diff_Op_Delete) { |
$line1 .= '<del>'.implode('', $edit->orig).'</del>'; |
} else if ($edit instanceof Horde_Text_Diff_Op_Add) { |
$line2 .= '<ins>'.implode('', $edit->final).'</ins>'; |
} else if ($edit instanceof Horde_Text_Diff_Op_Change) { |
$line1 .= '<del>'.implode('', $edit->orig).'</del>'; |
$line2 .= '<ins>'.implode('', $edit->final).'</ins>'; |
} else { |
assert(false); |
} |
} |
return array($line1, $line2); |
} |
// }}} |
} |
// Class for computing sensibly added/deleted block of lines. |
class SensibleLineChanges { |
var $_added = array(); |
var $_deleted = array(); |
var $_lineDiff = null; |
function __construct($lineDiff) { |
$this->_lineDiff = $lineDiff; |
} |
function addDeletedLine($text, $highlighted_text, $lineno) { |
$this->_deleted[] = array($text, $highlighted_text, $lineno); |
} |
function addAddedLine($text, $highlighted_text, $lineno) { |
$this->_added[] = array($text, $highlighted_text, $lineno); |
} |
// this function computes simple match - first min(deleted,added) lines are marked as changed |
// it is intended to be run instead of _computeBestMatching if the diff is too big |
function _computeFastMatching($n, $m) { |
$result = array(); |
$q = 0; |
while ($q < $n && $q < $m) { |
$result[] = array($this->_deleted[$q], $this->_added[$q]); |
$q++; |
} |
while ($q < $n) { |
$result[] = array($this->_deleted[$q], null); |
$q++; |
} |
while ($q < $m) { |
$result[] = array(null, $this->_added[$q]); |
$q++; |
} |
return $result; |
} |
// {{{ _computeBestMatching |
// dynamically compute best matching |
// note that this is O(n*m) * O(line similarity) |
function _computeBestMatching() { |
$n = count($this->_deleted); |
$m = count($this->_added); |
// if the computation will be slow, just run fast algorithm |
if ($n * $m > 10000) { |
return $this->_computeFastMatching($n, $m); |
} |
// dyn[$i][$j] holds best sum of similarities we can obtain if we match |
// first $i deleted lines and first $j added lines |
$dyn = array_fill(0, $n + 1, array_fill(0, $m + 1, 0.0)); |
// backlinks, so we can reconstruct best layout easily |
$back = array_fill(0, $n + 1, array_fill(0, $m + 1, -1)); |
// if there is no similarity, prefer adding/deleting lines |
$value_del = 0.1; |
$value_add = 0.1; |
// initialize arrays |
for ($i = 1; $i <= $n; $i++) { |
$back[$i][0] = 0; |
$dyn[$i][0] = $value_del * $i; |
} |
for ($j = 1; $j <= $m; $j++) { |
$back[0][$j] = 1; |
$dyn[0][$j] = $value_add * $j; |
} |
// main dynamic programming |
for ($i = 1; $i <= $n; $i++) { |
for ($j = 1; $j <= $m; $j++) { |
$best = - 1.0; |
$b = -1; |
if ($dyn[$i - 1][$j] + $value_del >= $best) { |
$b = 0; |
$best = $dyn[$i - 1][$j] + $value_del; |
} |
if ($dyn[$i][$j - 1] + $value_add >= $best) { |
$b = 1; |
$best = $dyn[$i][$j - 1] + $value_add; |
} |
$sim = $this->_lineDiff->lineSimilarity($this->_deleted[$i - 1][0], $this->_added[$j - 1][0]); |
if ($dyn[$i - 1][$j - 1] + $sim >= $best) { |
$b = 2; |
$best = $dyn[$i - 1][$j - 1] + $sim; |
} |
$back[$i][$j] = $b; |
$dyn[$i][$j] = $best; |
} |
} |
// compute layout for best result |
$i = $n; |
$j = $m; |
$result = array(); |
while ($i + $j >= 1) { |
switch($back[$i][$j]) { |
case 2: array_push($result, array($this->_deleted[$i - 1], $this->_added[$j - 1])); |
$i--; |
$j--; |
break; |
case 1: array_push($result, array(null, $this->_added[$j - 1])); |
$j--; |
break; |
case 0: array_push($result, array($this->_deleted[$i - 1], null)); |
$i--; |
break; |
default: |
assert(false); |
} |
} |
return array_reverse($result); |
} |
// }}} |
// {{{ addChangesToListing |
// add computed changes to the listing |
function addChangesToListing(&$listingHelper, $highlighted) { |
$matching = $this->_computeBestMatching(); |
foreach ($matching as $change) { |
if ($change[1] == null) { |
// deleted -- preserve original highlighted text |
$listingHelper->addDeletedLine($change[0][1], $change[0][2]); |
} else if ($change[0] == null) { |
// added -- preserve original highlighted text |
$listingHelper->addAddedLine($change[1][1], $change[1][2]); |
} else { |
// this is fully changed line, make inline diff |
$diff = $this->_lineDiff->inlineDiff($change[0][0], $change[0][1], $change[1][0], $change[1][1], $highlighted); |
$listingHelper->addChangedLine($diff[0], $change[0][2], $diff[1], $change[1][2]); |
} |
} |
$this->clear(); |
} |
// }}} |
function clear() { |
$this->_added = array(); |
$this->_deleted = array(); |
} |
} |
/WebSVN/include/distconfig.php |
---|
0,0 → 1,528 |
<?php |
// WebSVN - Subversion repository viewing via the web using PHP |
// Copyright (C) 2004-2006 Tim Armes |
// |
// This program is free software; you can redistribute it and/or modify |
// it under the terms of the GNU General Public License as published by |
// the Free Software Foundation; either version 2 of the License, or |
// (at your option) any later version. |
// |
// This program is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License |
// along with this program; if not, write to the Free Software |
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
// |
// -- |
// |
// config.php |
// |
// Configuration parameters |
// --- FOLLOW THE INSTRUCTIONS BELOW TO CONFIGURE YOUR SETUP --- |
// {{{ PLATFORM CONFIGURATION --- |
// Configure a UTF-8 aware locale to properly convert bytes to characters. |
// Otherwise files and directories with non-ASCII encoding are deemed to fail |
// with native commands. |
// $config->setLocale('C.UTF-8'); |
// Configure the path for Subversion to use for --config-dir |
// (e.g. if accepting certificates is required when using repositories via https) |
// $config->setSvnConfigDir('/tmp/websvn'); |
// Configure these lines if your commands aren't on your path. |
// |
// $config->setSvnCommandPath('/path/to/svn/command/'); // e.g. c:\\program files\\subversion\\bin |
// $config->setSvnAuthzCommandPath('/path/to/svnauthz/command/'); // e.g. c:\\program files\\subversion\\bin\tools |
// $config->setDiffPath('/path/to/diff/command/'); |
// For syntax colouring, if option enabled... |
// $config->setEnscriptPath('/path/to/enscript/command/'); |
// $config->setSedPath('/path/to/sed/command/'); |
// For delivered tarballs, if option enabled... |
// $config->setTarPath('/path/to/tar/command/'); |
// For delivered GZIP'd files and tarballs, if option enabled... |
// $config->setGZipPath('/path/to/gzip/command/'); |
// download directory/file zipped ... |
// $config->setZipPath('/path/to/zip/command/'); |
// Uncomment this line to trust server certificates |
// This may useful if you use self-signed certificates and have no chance to accept the certificate once via cli |
// $config->setTrustServerCert(); |
// }}} |
// {{{ REPOSITORY SETUP --- |
// There are 2 methods for defining the repositiories available on the system. |
// Either you list them by hand, in which case you can give each one the name of |
// your choice, or you use the parent path function, in which case the name of |
// the directory is used as the repository name. |
// |
// In all cases, you may optionally supply a group name to the repositories. |
// This is useful in the case that you need to separate your projects. Grouped |
// repositories are referred to using the convention GroupName.RepositoryName |
// |
// You may also optionally specify the URL that clients should use to check out |
// a working copy. If used, it must be specified after the group, username, and |
// password; if these arguments are not needed, then pass null instead. Consult |
// the WebSvnConfig class in include/configclass.php for function details. |
// |
// Performance is much better on local repositories (e.g. accessed by file://). |
// However, you can also provide an interface onto a remote repository. In this |
// case you should supply the username and password needed to access it. |
// |
// To configure the repositories by hand, copy the appropriate line below, |
// uncomment it and replace the name and URL of your repository. |
// Local repositories (without and with optional group): |
// Note that the local URL to the repository depends on your platform: |
// Unix-like: file:///path/to/rep |
// Windows: file:///c:/svn/proj |
// |
// $config->addRepository('NameToDisplay', 'local URL'); |
// $config->addRepository('NameToDisplay', 'local URL', 'group'); |
// |
// Remote repositories (without and with optional group): |
// A remote URL looks like http://domain.tld/path/to/rep |
// |
// $config->addRepository('NameToDisplay', 'remote URL', null, 'username', 'password'); |
// $config->addRepository('NameToDisplay', 'remote URL', 'group', 'username', 'password'); |
// |
// Display Part of a repository as if it was a repository. |
// |
// Local repositories (without and with optional group): |
// |
// $config->addRepositorySubpath('NameToDisplay', 'local URL', 'subpath'); |
// $config->addRepositorySubpath('NameToDisplay', 'local URL', 'subpath', 'group'); |
// |
// Remote repositories (without and with optional group): |
// |
// $config->addRepositorySubpath('NameToDisplay', 'remote URL', 'subpath', null, 'username', 'password'); |
// $config->addRepositorySubpath('NameToDisplay', 'remote URL', 'subpath', 'group', 'username', 'password'); |
// |
// To use the parent path method (without and with optional group), uncomment the next line |
// and replace the path with your one. You can call the function several times if you have several parent paths. |
// Note that in this case the path is a filesystem path and depends on your platform: |
// Unix-like: /path/to/parent |
// Windows: c:\\svn |
// |
// $config->parentPath('filesystem path'); |
// $config->parentPath('filesystem path', 'group'); |
// |
// To exclude a repository from being added by the parentPath method uncomment the next line |
// and replace the path with your one. You can call the function several times if you have several paths to exclude. |
// |
// $config->addExcludedPath('filesystem path of excluded rep'); |
// |
// To add only a subset of repositories specified by the parent path you can call the function with a pattern. |
// |
// $config->parentPath('filesystem path', 'group', '/^beginwith/'); |
// }}} |
// {{{ LOOK AND FEEL --- |
// |
// Add custom template paths or comment out templates to modify the list of user selectable templates. |
// The first added template serves as a default. |
$config->addTemplatePath($locwebsvnreal.'/templates/calm/'); |
$config->addTemplatePath($locwebsvnreal.'/templates/BlueGrey/'); |
$config->addTemplatePath($locwebsvnreal.'/templates/Elegant/'); |
// You may also specify a default template by uncommenting and changing the following line as necessary. |
// If no default template is set the first added template is used. |
// $config->setTemplatePath($locwebsvnreal.'/templates/Elegant/'); |
// You may also specify a per repository fixed template by uncommenting and changing the following |
// line as necessary. Use the convention 'groupname.myrep' if your repository is in a group. |
// $config->setTemplatePath($locwebsvnreal.'/templates/Elegant/', 'myrep'); |
// The index page containing the projects may either be displayed as a flat view (the default), |
// where grouped repositories are displayed as 'GroupName.RepName' or as a tree view. |
// In the case of a tree view, you may choose whether the entire tree is open by default. |
// $config->useTreeIndex(false); // Tree index, closed by default |
// $config->useTreeIndex(true); // Tree index, open by default |
// By default, WebSVN displays a tree view onto the current directory. You can however |
// choose to display a flat view of the current directory only, which may make the display |
// load faster. Uncomment this line if you want that. |
// $config->useFlatView(); |
// By default, WebSVN displays subdirectories first and than the files of a directory, |
// both alphabetically sorted. |
// To use alphabetic order independent of directories and files uncomment this line. |
// $config->setAlphabeticOrder(true); |
// By default, WebSVN loads parent path directories and then on user click other, |
// This options loads the entire directory in one go and allows to browse without delay. |
// By default all will be collapsed to root directory and can be expanded. |
// The performance will be impacted as it takes time to load up all the things in the |
// repository. Once loaded directory exapansion is instantaneous. |
// The alphabetical order is applied to all directory and files. |
// This means that grouping of all dirs together and all files together is NOT supported currently! |
// The files and directories are shown as is with a mixture of files and folders. |
// $config->setLoadAllRepos(true); |
// By default, WebSVN displays the information of the last modification |
// (revision, age and author) for each repository in an extra column. |
// To disable that uncomment this line. |
// $config->setShowLastModInIndex(false); |
// By default, WebSVN displays the information of the last modification |
// (revision, age and author) for each file and directory in an extra column. |
// To disable that uncomment this line. |
// $config->setShowLastModInListing(false); |
// By default, WebSVN displays the age of the last modification. |
// Alternativly the date of the last modification can be shown. |
// To show dates instead of ages uncomment this line. |
// $config->setShowAgeInsteadOfDate(false); |
// By default, WebSVN displays the a form to select an other repository. |
// If you have a lot of repositories this slows done the script considerably. |
// To disable that uncomment this line. |
// $config->setShowRepositorySelectionForm(false); |
// By default, WebSVN does not ignore whitespaces when showing diffs. |
// To enable ignoring whitespaces in diffs per default uncomment this line. |
// $config->setIgnoreWhitespacesInDiff(true); |
// }}} |
// {{{ LANGUAGE SETUP --- |
// Set the default language. If you want English then don't do anything here. |
// |
// $config->setDefaultLanguage('en'); |
// Ignore the user supplied accepted languages to choose reasonable default language. |
// If you want to force the default language - regardless of the client - uncomment the following line. |
// |
// $config->ignoreUserAcceptedLanguages(); |
// }}} |
// {{{ MULTIVIEWS --- |
// Uncomment this line if you want to use MultiView to access the repository by, for example: |
// |
// http://servername/browse/repname/path/in/repository |
// |
// Note: The websvn directory will need to have Multiviews turned on in Apache, and you'll need to configure browse.php |
// $config->useMultiViews(); |
// }}} |
// {{{ ACCESS RIGHTS --- |
// Uncomment this line if you want to use your Subversion access file to control access |
// rights via WebSVN. For this to work, you'll need to set up the same Apache based authentication |
// to the WebSVN (or browse) directory as you have for Subversion itself. More information can be |
// found in install.txt |
// $config->useAccessFile('/path/to/accessfile'); // Global access file |
// You may also specify a per repository access file by uncommenting and copying the following |
// line as necessary. Use the convention 'groupname.myrep' if your repository is in a group. |
// $config->useAccessFile('/path/to/accessfile', 'myrep'); // Access file for myrep |
// Uncomment this line if you want to prevent search bots to index the WebSVN pages. |
// $config->setBlockRobots(); |
// }}} |
// {{{ FILE CONTENT --- |
// |
// You may wish certain file types to be GZIP'd and delieved to the user when clicked apon. |
// This is useful for binary files and the like that don't display well in a browser window! |
// Copy, uncomment and modify this line for each extension to which this rule should apply. |
// (Don't forget the . before the extension. You don't need an index between the []'s). |
// If you'd rather that the files were delivered uncompressed with the associated MIME type, |
// then read below. |
// |
// $zipped[] = '.dll'; |
// Subversion controlled files have an svn:mime-type property that can |
// be set on a file indicating its mime type. By default binary files |
// are set to the generic appcliation/octet-stream, and other files |
// don't have it set at all. WebSVN also has a built-in list of |
// associations from file extension to MIME content type. (You can |
// view this list in setup.php). |
// |
// Determining the content-type: By default, if the svn:mime-type |
// property exists and is different from application/octet-stream, it |
// is used. Otherwise, if the built-in list has a contentType entry |
// for the extension of the file, that is used. Otherwise, if the |
// svn:mime-type property exists has the generic binary value of |
// application/octet-stream, the file will be served as a binary |
// file. Otherwise, the file will be brought up as ASCII text in the |
// browser window (although this text may optionally be colourised. |
// See below). |
// |
// Uncomment this if you want to ignore any svn:mime-type property on your |
// files. |
// |
// $config->ignoreSvnMimeTypes(); |
// |
// Uncomment this if you want skip WebSVN's custom mime-type handling |
// |
// $config->ignoreWebSVNContentTypes(); |
// |
// Following the examples below, you can add new associations, modify |
// the default ones or even delete them entirely (to show them in |
// ASCII via WebSVN). |
// $contentType['.c'] = 'text/plain'; // Create a new association |
// $contentType['.doc'] = 'text/plain'; // Modify an existing one |
// unset($contentType['.m']); // Remove a default association |
// If you want to selectively override one or more MIME types to display inline |
// (e.g., the svn:mime-type property is something like text/plain or text/xml, or |
// the file extension matches an entry in $contentType), you can choose to ignore |
// one or more specific MIME types. This approach is finer-grained than ignoring |
// all svn:mime-type properties, and displaying matching files inline such that |
// they are highlighted correctly. (Regular expression matching is used.) |
$config->addInlineMimeType('text/plain'); |
// $config->addInlineMimeType('text/*'); |
// }}} |
// {{{ TARBALLS --- |
// You need tar and gzip installed on your system. Set the paths above if necessary |
// |
// Uncomment the line below to offer a tarball download option across all your |
// repositories. |
// |
// $config->allowDownload(); |
// |
// Set download modes |
// $config->setDefaultFileDlMode('plain'); |
// $config->setDefaultDirectoryDlMode('gzip'); |
// |
// To change the global option for individual repositories, uncomment and replicate |
// the appropriate line below (replacing 'myrep' with the name of the repository). |
// Use the convention 'groupname.myrep' if your repository is in a group. |
// $config->allowDownload('myrep'); // Specifically allow downloading for 'myrep' |
// $config->disallowDownload('myrep'); // Specifically disallow downloading for 'myrep' |
// You can also choose the minimum directory level from which you'll allow downloading. |
// A value of zero will allow downloading from the root. 1 will allow downloding of directories |
// in the root, etc. |
// |
// If your project is arranged with trunk, tags and branches at the root level, then a value of 2 |
// would allow the downloading of directories within branches/tags while disallowing the download |
// of the entire branches or tags directories. This would also stop downloading of the trunk, but |
// see after for path exceptions. |
// |
// Change the line below to set the download level across all your repositories. |
$config->setMinDownloadLevel(2); |
// To change the level for individual repositories, uncomment and replicate |
// the appropriate line below (replacing 'myrep' with the name of the repository). |
// Use the convention 'groupname.myrep' if your repository is in a group. |
// $config->setMinDownloadLevel(2, 'myrep'); |
// Finally, you may add or remove certain directories (and their contents) either globally |
// or on a per repository basis. Uncomment and copy the following lines as necessary. Note |
// that the these are searched in the order than you give them until a match is made (with the |
// exception that all the per repository exceptions are tested before the global ones). This means |
// that you must disallow /a/b/c/ before you allow /a/b/ otherwise the allowed match on /a/b/ will |
// stop any further searching, thereby allowing downloads on /a/b/c/. |
// Global exceptions possibilties: |
// |
// $config->addAllowedDownloadException('/path/to/allowed/directory/'); |
// $config->addDisAllowedDownloadException('/path/to/disallowed/directory/'); |
// |
// Per repository exception possibilties: |
// Use the convention 'groupname.myrep' if your repository is in a group. |
// |
// $config->addAllowedDownloadException('/path/to/allowed/directory/', 'myrep'); |
// $config->addDisAllowedDownloadException('/path/to/disallowed/directory/', 'myrep'); |
// }}} |
// {{{ COLOURISATION --- |
// Uncomment this line if you want to use Enscript to colourise your file listings |
// |
// You'll need Enscript version 1.6 or higher AND Sed installed to use this feature. |
// Set the path above. |
// |
// If you have version 1.6.3 or newer use the following line. |
// |
// $config->useEnscript(); |
// |
// If you have version 1.6.2 or older use the following line. |
// |
// $config->useEnscript(true); |
// Enscript need to be told what the contents of a file are so that it can be colourised |
// correctly. WebSVN includes a predefined list of mappings from file extension to Enscript |
// file type (viewable in setup.php). |
// |
// Here you should add and other extensions not already listed or redefine the default ones. eg: |
// |
// $extEnscript['.pas'] = 'pascal'; |
// |
// Note that extensions are case sensitive. |
// Uncomment this line if you want to use GeSHi to colourise your file listings |
// |
// $config->useGeshi(); |
// $config->setGeshiPath('/usr/share/php-geshi'); // optional. Use if you have Geshi installed without PEAR/Composer |
// GeSHi need to be told what the contents of a file are so that it can be colourised |
// correctly. WebSVN includes a predefined list of mappings from file extension to GeSHi |
// languages (viewable in setup.php). |
// |
// Here you should add and other extensions not already listed or redefine the default ones. eg: |
// |
// $extGeshi['pascal'] = array('p', 'pas'); |
// |
// Note that extensions are case sensitive. |
// }}} |
// {{{ Markdown Render |
// Uncomment this line if you want to enable Markdown Rendering of README.md file in the path. |
// You will need the Parsedown.php (https://github.com/erusev/parsedown) library for this to work. |
// This will look for README.md file on the path and render it. |
// The name of "README.md" isn't configurable for now to simply follow GitHub's conventions. |
// $config->useParsedown(); |
// $config->setParsedownPath('/usr/share/php/Parsedown/'); // optional. Use if you have Parsedown installed without PEAR/Composer |
// }}} |
// {{{ RSSFEED --- |
// Uncomment this line to hide the RSS feed links across all repositories |
// $config->setRssEnabled(false); |
// To override the global setting for individual repositories, uncomment and replicate |
// the appropriate line below (replacing 'myrep' with the name of the repository). |
// Use the convention 'groupname.myrep' if your repository is in a group. |
// $config->setRssEnabled(false, 'myrep'); |
// $config->setRssEnabled(true, 'myrep'); |
// Uncomment this line to enable caching RSS feeds across all repositories |
// This may create a large number of cache files which are currently not garbaged automatically |
// $config->setRssCachingEnabled(true); |
// To override the global setting for individual repositories, uncomment and replicate |
// the appropriate line below (replacing 'myrep' with the name of the repository). |
// Use the convention 'groupname.myrep' if your repository is in a group. |
// $config->setRssCachingEnabled(true, 'myrep'); |
// $config->setRssCachingEnabled(false, 'myrep'); |
// Uncomment this line to change the maximum number of RSS entries to display across all repositories |
// $config->setRssMaxEntries(50); |
// To override the global setting for individual repositories, uncomment and replicate |
// the line below (replacing 'myrep' with the name of the repository). |
// Use the convention 'groupname.myrep' if your repository is in a group. |
// $config->setRssMaxEntries(50, 'myrep'); |
// }}} |
// {{{ SHOW CHANGED FILES IN LOG --- |
// Uncomment this line to show changed files on log.php by default. The normal |
// behavior is to do this only if the "Show changed files" link is clicked. This |
// setting reverses the default action but still allows hiding changed files. |
// $config->setLogsShowChanges(true); |
// To override the global setting for individual repositories, uncomment and replicate |
// the appropriate line below (replacing 'myrep' with the name of the repository). |
// Use the convention 'groupname.myrep' if your repository is in a group. |
// $config->setLogsShowChanges(true, 'myrep'); |
// $config->setLogsShowChanges(false, 'myrep'); |
// }}} |
// {{{ BUGTRAQ --- |
// Uncomment this line to use bugtraq: properties to show links to your BugTracker |
// from log messages. |
// $config->setBugtraqEnabled(true); |
// To override the global setting for individual repositories, uncomment and replicate |
// the appropriate line below (replacing 'myrep' with the name of the repository). |
// Use the convention 'groupname.myrep' if your repository is in a group. |
// $config->setBugtraqEnabled(true, 'myrep'); |
// $config->setBugtraqEnabled(false, 'myrep'); |
// Usually the information to extract the bugtraq information and generate links are |
// stored in SVN properties starting with 'bugtraq:': |
// namely 'bugtraq:message', 'bugtraq:logregex', 'bugtraq:url' and 'bugtraq:append'. |
// To override the SVN properties globally or for individual repositories, uncomment |
// the appropriate line below (replacing 'myrep' with the name of the repository). |
// $config->setBugtraqProperties('bug #%BUGID%', 'issues? (\d+)([, ] *(\d+))*'."\n".'(\d+)', 'http://www.example.com/issues/show_bug.cgi?id=%BUGID%', false); |
// $config->setBugtraqProperties('bug #%BUGID%', 'issues? (\d+)([, ] *(\d+))*'."\n".'(\d+)', 'http://www.example.com/issues/show_bug.cgi?id=%BUGID%', false, 'myrep'); |
// }}} |
// {{{ MISCELLANEOUS --- |
// Comment out this if you don't have the right to use it. Be warned that you may need it however! |
set_time_limit(0); |
// Change the line below to specify a temporary directory other than the one PHP uses. |
// $config->setTempDir('temp'); |
// Number of spaces to expand tabs to in diff/listing view across all repositories |
$config->expandTabsBy(8); |
// To override the global setting for individual repositories, uncomment and replicate |
// the line below (replacing 'myrep' with the name of the repository). |
// Use the convention 'groupname.myrep' if your repository is in a group. |
// $config->expandTabsBy(3, 'myrep'); // Expand Tabs by 3 for repository 'myrep' |
// Change the name of the breadcrumb root-phrase to that of the current repo? |
// $config->setBreadcrumbRepoRootAsRepo(true); |
// }}} |
/WebSVN/include/header |
---|
1,7 → 1,5 |
# vim:et:ts=3:sts=3:sw=3:fdm=marker: |
// WebSVN - Subversion repository viewing via the web using PHP |
// Copyright © 2004-2006 Tim Armes, Matt Sicker |
// Copyright (C) 2004-2006 Tim Armes |
// |
// This program is free software; you can redistribute it and/or modify |
// it under the terms of the GNU General Public License as published by |
10,12 → 8,12 |
// |
// This program is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License |
// along with this program; if not, write to the Free Software |
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
// |
// -- |
// |
/WebSVN/include/setup.php |
---|
0,0 → 1,620 |
<?php |
// WebSVN - Subversion repository viewing via the web using PHP |
// Copyright (C) 2004-2006 Tim Armes |
// |
// This program is free software; you can redistribute it and/or modify |
// it under the terms of the GNU General Public License as published by |
// the Free Software Foundation; either version 2 of the License, or |
// (at your option) any later version. |
// |
// This program is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License |
// along with this program; if not, write to the Free Software |
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
// |
// -- |
// |
// setup.php |
// |
// Global setup |
// --- DON'T CHANGE THIS FILE --- |
// |
// User changes should be done in config.php |
// Include the configuration class |
require_once 'include/configclass.php'; |
// Register Composer autoloader if available |
if (file_exists(__DIR__ . '/../vendor/autoload.php')) { |
require_once __DIR__ . '/../vendor/autoload.php'; |
define('USE_AUTOLOADER', true); |
} |
// Create the config |
$config = new WebSvnConfig(); |
if (DIRECTORY_SEPARATOR == '\\') { |
$config->setServerIsWindows(); |
} |
// Set up locwebsvnhttp |
// Note: we will use nothing in MultiViews mode so that the URLs use the root |
// directory by default. |
if (empty($locwebsvnhttp)) { |
$locwebsvnhttp = defined('WSVN_MULTIVIEWS') ? '' : '.'; |
} |
if (empty($locwebsvnreal)) { |
$locwebsvnreal = '.'; |
} |
$vars['locwebsvnhttp'] = $locwebsvnhttp; |
// {{{ Content Types |
// Set up the default content-type extension handling |
$contentType = array( |
'.dwg' => 'application/acad', // AutoCAD Drawing files |
'.arj' => 'application/arj', |
'.ccad' => 'application/clariscad', // ClarisCAD files |
'.drw' => 'application/drafting', // MATRA Prelude drafting |
'.dxf' => 'application/dxf', // DXF (AutoCAD) |
'.xls' => 'application/excel', // Microsoft Excel |
'.unv' => 'application/i-deas', //SDRC I-DEAS files |
'.igs' => 'application/iges', // IGES graphics format |
'.iges' => 'application/iges', // IGES graphics format |
'.hqx' => 'application/mac-binhex40', // Macintosh BinHex format |
'.word' => 'application/msword', // Microsoft Word |
'.w6w' => 'application/msword', // Microsoft Word |
'.doc' => 'application/msword', // Microsoft Word |
'.wri' => 'application/mswrite', // Microsoft Write |
'.bin' => 'application/octet-stream', // Uninterpreted binary |
'.exe' => 'application/x-msdownload', // Windows EXE |
'.oda' => 'application/oda', |
'.pdf' => 'application/pdf', // PDF (Adobe Acrobat) |
'.ai' => 'application/postscript', // PostScript |
'.ps' => 'application/postscript', // PostScript |
'.eps' => 'application/postscript', // PostScript |
'.prt' => 'application/pro_eng', // PTC Pro/ENGINEER |
'.part' => 'application/pro_eng', // PTC Pro/ENGINEER |
'.rtf' => 'application/rtf', // Rich Text Format |
'.set' => 'application/set', // SET (French CAD standard) |
'.stl' => 'application/sla', // Stereolithography |
'.sol' => 'application/solids', // MATRA Prelude Solids |
'.stp' => 'application/STEP', // ISO-10303 STEP data files |
'.step' => 'application/STEP', // ISO-10303 STEP data files |
'.vda' => 'application/vda', // VDA-FS Surface data |
'.dir' => 'application/x-director', // Macromedia Director |
'.dcr' => 'application/x-director', // Macromedia Director |
'.dxr' => 'application/x-director', // Macromedia Director |
'.mif' => 'application/x-mif', // FrameMaker MIF Format |
'.csh' => 'application/x-csh', // C-shell script |
'.dvi' => 'application/x-dvi', // TeX DVI |
'.gz' => 'application/gzip', // GNU Zip |
'.gzip' => 'application/gzip', // GNU Zip |
'.hdf' => 'application/x-hdf', // ncSA HDF Data File |
'.latex' => 'application/x-latex', // LaTeX source |
'.nc' => 'application/x-netcdf', // Unidata netCDF |
'.cdf' => 'application/x-netcdf', // Unidata netCDF |
'.sit' => 'application/x-stuffit', // Stiffut Archive |
'.tcl' => 'application/x-tcl', // TCL script |
'.texinfo' => 'application/x-texinfo', // Texinfo (Emacs) |
'.texi' => 'application/x-texinfo', // Texinfo (Emacs) |
'.t' => 'application/x-troff', // Troff |
'.tr' => 'application/x-troff', // Troff |
'.roff' => 'application/x-troff', // Troff |
'.man' => 'application/x-troff-man', // Troff with MAN macros |
'.me' => 'application/x-troff-me', // Troff with ME macros |
'.ms' => 'application/x-troff-ms', // Troff with MS macros |
'.src' => 'application/x-wais-source', // WAIS source |
'.bcpio' => 'application/x-bcpio', // Old binary CPIO |
'.cpio' => 'application/x-cpio', // POSIX CPIO |
'.gtar' => 'application/x-gtar', // GNU tar |
'.shar' => 'application/x-shar', // Shell archive |
'.sv4cpio' => 'application/x-sv4cpio', // SVR4 CPIO |
'.sv4crc' => 'application/x-sv4crc', // SVR4 CPIO with CRC |
'.tar' => 'application/x-tar', // 4.3BSD tar format |
'.ustar' => 'application/x-ustar', // POSIX tar format |
'.hlp' => 'application/x-winhelp', // Windows Help |
'.zip' => 'application/zip', // ZIP archive |
'.au' => 'audio/basic', // Basic audio (usually m-law) |
'.snd' => 'audio/basic', // Basic audio (usually m-law) |
'.aif' => 'audio/x-aiff', // AIFF audio |
'.aiff' => 'audio/x-aiff', // AIFF audio |
'.aifc' => 'audio/x-aiff', // AIFF audio |
'.ra' => 'audio/x-pn-realaudio', // RealAudio |
'.ram' => 'audio/x-pn-realaudio', // RealAudio |
'.rpm' => 'audio/x-pn-realaudio-plugin', // RealAudio (plug-in) |
'.wav' => 'audio/x-wav', // Windows WAVE audio |
'.mp3' => 'audio/x-mp3', // MP3 files |
'.gif' => 'image/gif', // gif image |
'.ief' => 'image/ief', // Image Exchange Format |
'.jpg' => 'image/jpeg', // JPEG image |
'.jpe' => 'image/jpeg', // JPEG image |
'.jpeg' => 'image/jpeg', // JPEG image |
'.pict' => 'image/pict', // Macintosh PICT |
'.png' => 'image/png', // PNG image |
'.svg' => 'image/svg+xml', // Scalable vector graphics |
'.tiff' => 'image/tiff', // TIFF image |
'.tif' => 'image/tiff', // TIFF image |
'.ras' => 'image/x-cmu-raster', // CMU raster |
'.pnm' => 'image/x-portable-anymap', // PBM Anymap format |
'.pbm' => 'image/x-portable-bitmap', // PBM Bitmap format |
'.pgm' => 'image/x-portable-graymap', // PBM Graymap format |
'.ppm' => 'image/x-portable-pixmap', // PBM Pixmap format |
'.rgb' => 'image/x-rgb', // RGB Image |
'.xbm' => 'image/x-xbitmap', // X Bitmap |
'.xpm' => 'image/x-xpixmap', // X Pixmap |
'.xwd' => 'image/x-xwindowdump', // X Windows dump (xwd) format |
'.mpeg' => 'video/mpeg', // MPEG video |
'.mpg' => 'video/mpeg', // MPEG video |
'.mpe' => 'video/mpeg', // MPEG video |
'.mpeg' => 'video/mpeg', // MPEG video |
'.qt' => 'video/quicktime', // QuickTime Video |
'.mov' => 'video/quicktime', // QuickTime Video |
'.avi' => 'video/msvideo', // Microsoft Windows Video |
'.movie' => 'video/x-sgi-movie', // SGI Movieplayer format |
'.wrl' => 'x-world/x-vrml', // VRML Worlds |
'.ods' => 'application/vnd.oasis.opendocument.spreadsheet', // OpenDocument Spreadsheet |
'.ots' => 'application/vnd.oasis.opendocument.spreadsheet-template', // OpenDocument Spreadsheet Template |
'.odp' => 'application/vnd.oasis.opendocument.presentation', // OpenDocument Presentation |
'.otp' => 'application/vnd.oasis.opendocument.presentation-template', // OpenDocument Presentation Template |
'.odg' => 'application/vnd.oasis.opendocument.graphics', // OpenDocument Drawing |
'.otg' => 'application/vnd.oasis.opendocument.graphics-template', // OpenDocument Drawing Template |
'.odc' => 'application/vnd.oasis.opendocument.chart', // OpenDocument Chart |
'.otc' => 'application/vnd.oasis.opendocument.chart-template', // OpenDocument Chart Template |
'.odf' => 'application/vnd.oasis.opendocument.formula', // OpenDocument Formula |
'.otf' => 'application/vnd.oasis.opendocument.formula-template', // OpenDocument Formula Template |
'.odi' => 'application/vnd.oasis.opendocument.image', // OpenDocument Image |
'.oti' => 'application/vnd.oasis.opendocument.image-template', // OpenDocument Image Template |
'.odb' => 'application/vnd.oasis.opendocument.database', // OpenDocument Database |
'.odt' => 'application/vnd.oasis.opendocument.text', // OpenDocument Text |
'.ott' => 'application/vnd.oasis.opendocument.text-template', // OpenDocument Text Template |
'.odm' => 'application/vnd.oasis.opendocument.text-master', // OpenDocument Master Document |
'.oth' => 'application/vnd.oasis.opendocument.text-web', // OpenDocument HTML Template |
); |
// }}} |
// {{{ Enscript file extensions |
// List of extensions recognised by enscript. |
$extEnscript = array( |
'.ada' => 'ada', |
'.adb' => 'ada', |
'.ads' => 'ada', |
'.awk' => 'awk', |
'.c' => 'c', |
'.c++' => 'cpp', |
'.cc' => 'cpp', |
'.cmake' => 'cmake', |
'CMakeLists.txt' => 'cmake', |
'.cpp' => 'cpp', |
'.csh' => 'csh', |
'.cxx' => 'cpp', |
'.diff' => 'diffu', |
'.dpr' => 'delphi', |
'.e' => 'eiffel', |
'.el' => 'elisp', |
'.eps' => 'postscript', |
'.f' => 'fortran', |
'.for' => 'fortran', |
'.gs' => 'haskell', |
'.h' => 'c', |
'.hpp' => 'cpp', |
'.hs' => 'haskell', |
'.htm' => 'html', |
'.html' => 'html', |
'.idl' => 'idl', |
'.java' => 'java', |
'.js' => 'javascript', |
'.json' => 'javascript', |
'.lgs' => 'haskell', |
'.lhs' => 'haskell', |
'.m' => 'objc', |
'.m4' => 'm4', |
'.man' => 'nroff', |
'.nr' => 'nroff', |
'.p' => 'pascal', |
'.pas' => 'delphi', |
'.patch' => 'diffu', |
'.pkg' => 'sql', |
'.pl' => 'perl', |
'.pm' => 'perl', |
'.pp' => 'pascal', |
'.ps' => 'postscript', |
'.s' => 'asm', |
'.scheme' => 'scheme', |
'.scm' => 'scheme', |
'.scr' => 'synopsys', |
'.sh' => 'sh', |
'.shtml' => 'html', |
'.sql' => 'sql', |
'.st' => 'states', |
'.syn' => 'synopsys', |
'.synth' => 'synopsys', |
'.tcl' => 'tcl', |
'.tex' => 'tex', |
'.texi' => 'tex', |
'.texinfo' => 'tex', |
'.v' => 'verilog', |
'.vba' => 'vba', |
'.vh' => 'verilog', |
'.vhd' => 'vhdl', |
'.vhdl' => 'vhdl', |
'.py' => 'python', |
); |
// }}} |
// {{{ GeSHi file extensions |
// List of extensions recognised by GeSHi. |
$extGeshi = array( |
'actionscript3' => array('as'), |
'ada' => array('ada', 'adb', 'ads'), |
'asm' => array('ash', 'asi', 'asm'), |
'asp' => array('asp'), |
'bash' => array('sh'), |
'bibtex' => array('bib'), |
'c' => array('c'), |
'cfm' => array('cfm', 'cfml'), |
'cmake' => array('cmake', 'CMakeLists.txt'), |
'cobol' => array('cbl'), |
'cpp' => array('cc', 'cpp', 'cxx', 'c++', 'h', 'hpp'), |
'csharp' => array('cs'), |
'css' => array('css'), |
'd' => array('d'), |
'delphi' => array('dpk', 'dpr', 'pas'), |
'diff' => array('diff', 'patch'), |
'dos' => array('bat', 'cmd'), |
'eiffel' => array('e'), |
'erlang' => array('erl'), |
'email' => array('eml'), |
'fortran' => array('f', 'for', 'f90'), |
'gettext' => array('po', 'pot'), |
'gml' => array('gml'), |
'gnuplot' => array('plt'), |
'groovy' => array('groovy'), |
'haskell' => array('gs', 'hs', 'lgs', 'lhs'), |
'html4strict' => array('html', 'htm'), |
'idl' => array('idl'), |
'ini' => array('desktop', 'ini'), |
'java5' => array('java'), |
'javascript' => array('js', 'json'), |
'latex' => array('tex'), |
'lisp' => array('lisp'), |
'lua' => array('lua'), |
'make' => array('make'), |
'matlab' => array('m'), |
'perl' => array('pl', 'pm'), |
'php' => array('php', 'php3', 'php4', 'php5', 'phps', 'phtml'), |
'povray' => array('pov'), |
'properties' => array('properties'), |
'providex' => array('pvc', 'pvx'), |
'python' => array('py'), |
'reg' => array('reg'), |
'ruby' => array('rb'), |
'scala' => array('scala'), |
'scheme' => array('scm', 'scheme'), |
'scilab' => array('sci'), |
'smalltalk' => array('st'), |
'sql' => array('sql'), |
'tcl' => array('tcl'), |
'vb' => array('bas'), |
'vbnet' => array('vb'), |
'vh' => array('v', 'verilog'), |
'vhdl' => array('vhd', 'vhdl'), |
'vim' => array('vim'), |
'whitespace' => array('ws'), |
'xml' => array('xml', 'xsl', 'xsd', 'xib', 'wsdl', 'svg', 'plist', 'jmx'), |
'z80' => array('z80'), |
); |
// }}} |
// Loads English localized strings by default (must go before config.php) |
require 'languages/english.php'; |
// Support one WebSVN installation hosting multiple different SVNParentPaths, distinguished by their |
// location. Per location, the web server needs to set some environment variable providing the path |
// to the config to either exclusively or additionally include, implementing a simple layered config |
// this way. That allows, e.g., changing paths to repos per location only and share everything else. |
// |
// The following implementation deals with multiple most likely problems in such an environment, like |
// HTTP redirects influencing the name of the environment variable set and "preg_grep" indexing its |
// results depending on the input, so optionally changing between requests. |
// |
// https://stackoverflow.com/q/3050444/696632 |
// https://bz.apache.org/bugzilla/show_bug.cgi?id=58739 |
$confSuccess = 0; |
$envPathConf = preg_grep('/^(?:REDIRECT_)*WEBSVN_PATH_CONF$/', array_keys($_SERVER)); |
$envPathConf = array_values($envPathConf); |
$envPathConf = array_key_exists(0, $envPathConf) |
? $_SERVER[$envPathConf[0]] |
: ''; |
// Get the user's personalised config (requires the locwebsvnhttp stuff above). |
if (file_exists('include/config.php')) { |
require_once 'include/config.php'; |
$confSuccess = 1; |
} |
if (!empty($envPathConf)) { |
require_once $envPathConf; |
$confSuccess = 1; |
} |
if (!$confSuccess) { |
die('No config applied, either create "include/config.php" or use environment variable ' . |
'"WEBSVN_PATH_CONF". The example file "include/distconfig.php" should be copied and ' . |
'modified as needed.'); |
} |
// Make sure that the input locale is set up correctly |
putenv("LANG=".setlocale(LC_ALL, $config->getLocale())); |
$vars['showageinsteadofdate'] = $config->showAgeInsteadOfDate(); |
// Initialize the version of SVN that is being used by WebSVN internally. |
require_once 'include/svnlook.php'; |
$vars['svnversion'] = $config->getSubversionVersion(); |
// Initialize an array with all query parameters except language and template. |
$queryParams = $_GET + $_POST; |
unset($queryParams['language']); |
unset($queryParams['template']); |
$hidden = ''; |
foreach ($queryParams as $key => $value) { |
if (is_array($value)) { |
for ($i = 0; $i < count($value); $i++) { |
$hidden .= '<input type="hidden" name="'.escape($key).'[]" value="'.escape($value[$i]).'"/>'; |
} |
} else { |
$hidden .= '<input type="hidden" name="'.escape($key).'" value="'.escape($value).'"/>'; |
} |
} |
// If the request specifies a language, store in a cookie. Otherwise, check for cookies specifying a |
// particular language already. |
$language = ''; // RFC 4646 language tag for representing the selected language. |
if (!empty($_REQUEST['language'])) { |
$language = $_REQUEST['language']; |
setcookie('storedlang', $language, time() + (60 * 60 * 24 * 356 * 10)); |
setcookie('storedsesslang', $language); |
} else if (isset($_COOKIE['storedlang'])) { |
$language = $_COOKIE['storedlang']; |
} else if (isset($_COOKIE['storedsesslang'])) { |
$language = $_COOKIE['storedsesslang']; |
} |
// Load available languages (populates $languages array) |
require 'languages/languages.php'; |
// Get the default language as defined by config.php |
$defaultLanguage = $config->getDefaultLanguage(); |
if (!isset($languages[$defaultLanguage])) |
$defaultLanguage = 'en'; |
// Determine which language to actually use |
$language = getUserLanguage($languages, $defaultLanguage, $language); |
$vars['language_code'] = $language; |
// For languages other than English, load translated strings over existing ones. |
if ($language != 'en') |
require 'languages/'.$languages[$language][0].'.php'; |
// Generate the HTML form for selecting a different language |
$vars['language_form'] = '<form method="get" action="" id="language">'.$hidden; |
$vars['language_select'] = '<select name="language" onchange="javascript:this.form.submit();">'; |
foreach ($languages as $code => $names) { |
$sel = ($code == $language) ? '" selected="selected' : ''; |
$vars['language_select'] .= '<option value="'.$code.$sel.'">'.$names[2].' – '.$names[1].'</option>'; |
} |
$vars['language_select'] .= '</select>'; |
$vars['language_submit'] = '<noscript><input type="submit" value="'.$lang['GO'].'" /></noscript>'; |
$vars['language_endform'] = '</form>'; |
// Load repository if possible |
if ($config->multiViews) { |
$rep = null; // MultiViews has custom code to load a repository |
} else { |
// Load repository matching 'repname' parameter (if set) or the default. |
$repname = @$_REQUEST['repname']; |
if (isset($repname)) { |
$rep = $config->findRepository($repname); |
} else { |
$reps = $config->getRepositories(); |
$rep = (isset($reps[0]) ? $reps[0] : null); |
} |
// Make sure that the user has set up a repository |
if ($rep == null) { |
$vars['error'] = $lang['SUPPLYREP']; |
} else if (is_string($rep)) { |
$vars['error'] = $rep; |
$rep = null; |
} else { |
$vars['repurl'] = $config->getURL($rep, '', 'dir'); |
$vars['clientrooturl'] = $rep->clientRootURL; |
$vars['repname'] = escape($rep->getDisplayName()); |
$vars['allowdownload'] = $rep->getAllowDownload(); |
} |
} |
// If the request specifies a template, store in a cookie. Otherwise, check for cookies specifying a |
// particular template already. |
$template = ''; |
if (!empty($_REQUEST['template'])) { |
$template = $_REQUEST['template']; |
setcookie('storedtemplate', $template, time() + (60 * 60 * 24 * 365 * 10)); |
setcookie('storedsesstemplate', $template); |
} else if (isset($_COOKIE['storedtemplate'])) { |
$template = $_COOKIE['storedtemplate']; |
} else if (isset($_COOKIE['storedsesstemplate'])) { |
$template = $_COOKIE['storedsesstemplate']; |
} |
$templates = array(); |
// Skip creating template list when selected repository has specific template. |
if ($rep == null || $rep->templatePath === false) { |
// Get all templates defined in config.php; use last path component as name. |
foreach ($config->templatePaths as $path) { |
$templates[$path] = basename($path); |
} |
$selectedTemplatePath = $config->getTemplatePath(); |
if ($template != '' && in_array($template, $templates)) { |
$selectedTemplatePath = array_search($template, $templates); |
$config->userTemplate = $selectedTemplatePath; |
} |
} |
// Generate the HTML form for selecting a different template |
if (count($templates) > 1) { |
$vars['template_form'] = '<form method="get" action="" id="template">'.$hidden; |
$vars['template_select'] = '<select name="template" onchange="javascript:this.form.submit();">'; |
natcasesort($templates); |
foreach ($templates as $path => $name) { |
$sel = ($path == $selectedTemplatePath) ? ' selected="selected"' : ''; |
$vars['template_select'] .= '<option value="'.$name.'"'.$sel.'>'.$name.'</option>'; |
} |
$vars['template_select'] .= '</select>'; |
$vars['template_submit'] = '<noscript><input type="submit" value="'.$lang['GO'].'" /></noscript>'; |
$vars['template_endform'] = '</form>'; |
} else { |
$vars['template_form'] = ''; |
$vars['template_select'] = ''; |
$vars['template_submit'] = ''; |
$vars['template_endform'] = ''; |
} |
$vars['indexurl'] = $config->getURL('', '', 'index'); |
$vars['validationurl'] = getFullURL($_SERVER['SCRIPT_NAME']).'?'.buildQuery($queryParams + array('template' => $template, 'language' => $language), '%26'); |
$path = !empty($_REQUEST['path']) ? $_REQUEST['path'] : null; |
if ($path === null || $path === '') |
$path = '/'; |
$vars['path'] = str_replace('%2F', '/', rawurlencode($path)); |
$vars['safepath'] = escape($path); |
// Set operative and peg revisions (if specified) and save passed-in revision |
$rev = (int)@$_REQUEST['rev']; |
$peg = (int)@$_REQUEST['peg']; |
$search = (string)@$_REQUEST['search']; |
if ($peg === 0) |
$peg = ''; |
$passrev = $rev; |
if (!$config->multiViews) { |
// With MultiViews, browse creates the form once the current project is found. |
createProjectSelectionForm(); |
createRevisionSelectionForm(); |
createSearchSelectionForm(); |
} |
// set flag if robots should be blocked |
$vars['blockrobots'] = $config->areRobotsBlocked(); |
$listing = array(); |
// Set up response headers |
header('Content-Type: text/html; charset=UTF-8'); |
header('Content-Language: '.$language); |
// Function to create the project selection HTML form |
function createProjectSelectionForm() { |
global $config, $vars, $rep, $lang; |
$vars['projects_form'] = ''; |
$vars['projects_select'] = ''; |
$vars['projects_submit'] = ''; |
$vars['projects_endform'] = ''; |
if (!$config->showRepositorySelectionForm() || count($config->getRepositories()) < 2) |
return; |
if ($rep) { |
$currentRepoName = $rep->getDisplayName(); |
$options = ''; |
} else { |
$currentRepoName = ''; |
$options = '<option value="" selected="selected"></option>'; |
} |
foreach ($config->getRepositories() as $repository) { |
if ($repository->hasReadAccess('/')) { |
$repoName = $repository->getDisplayName(); |
$sel = ($repoName == $currentRepoName) ? ' selected="selected"' : ''; |
$options .= '<option value="'.escape($repoName).'"'.$sel.'>'.escape($repoName).'</option>'; |
} |
} |
if (strlen($options) === 0) |
return; |
$vars['projects_form'] = '<form method="get" action="" id="project">'; |
if ($config->multiViews) |
$vars['projects_form'] .= '<input type="hidden" name="op" value="rep" />'; |
$vars['projects_select'] = '<select name="repname" onchange="javascript:this.form.submit();">'.$options.'</select>'; |
$vars['projects_submit'] = '<noscript><input type="submit" value="'.$lang['GO'].'" /></noscript>'; |
$vars['projects_endform'] = '</form>'; |
} |
// Function to create the revision selection HTML form |
function createRevisionSelectionForm() { |
global $config, $lang, $vars, $rep, $path, $rev, $peg; |
if ($rep == null) |
return; |
$params = array(); |
if (!$config->multiViews) { |
$params['repname'] = $rep->getDisplayName(); |
if ($path === null) |
$path = !empty($_REQUEST['path']) ? $_REQUEST['path'] : null; |
if ($path && $path != '/') |
$params['path'] = $path; |
} |
if ($peg || $rev) |
$params['peg'] = ($peg ? $peg : $rev); |
$hidden = ''; |
foreach ($params as $key => $value) { |
$hidden .= '<input type="hidden" name="'.$key.'" value="'.escape($value).'" />'; |
} |
// The blank "action" attribute makes form link back to the containing page. |
$vars['revision_form'] = '<form method="get" action="" id="revision">'.$hidden; |
if ($rev === null) |
$rev = (int)@$_REQUEST['rev']; |
$vars['revision_input'] = '<input type="text" size="5" name="rev" placeholder="'.($rev ? $rev : 'HEAD').'" />'; |
$vars['revision_submit'] = '<input type="submit" value="'.$lang['GO'].'" />'; |
$vars['revision_endform'] = '</form>'; |
} |
function createSearchSelectionForm() { |
global $config, $lang, $vars, $rep, $path, $rev, $peg, $search; |
if ($rep === null) |
return; |
$params = array(); |
if (!$config->multiViews) { |
$params['repname'] = $rep->getDisplayName(); |
if ($path === null) |
$path = !empty($_REQUEST['path']) ? $_REQUEST['path'] : null; |
if ($path && $path != '/') |
$params['path'] = $path; |
} |
if ($peg || $rev) |
$params['rev'] = ($peg ? $peg : $rev); |
$hidden = ''; |
foreach ($params as $key => $value) { |
$hidden .= '<input type="hidden" name="'.$key.'" value="'.escape($value).'" />'; |
} |
$vars['search'] = true; |
$vars['search_form'] = '<form method="get" action="'.$config->getURL($rep, '', 'search').'" id="search">'.$hidden; |
$search = $search? $search : $lang['SEARCH_PLACEHOLDER']; |
$vars['search_input'] = '<input type="text" size="20" name="search" placeholder="'.$search.'" />'; |
$vars['search_submit'] = '<input type="submit" value="'.$lang['SEARCH'].'" />'; |
$vars['search_endform'] = '</form>'; |
} |
function sendHeaderForbidden() { |
http_response_code(403); |
} |
/WebSVN/include/svnlook.php |
---|
0,0 → 1,1270 |
<?php |
// WebSVN - Subversion repository viewing via the web using PHP |
// Copyright (C) 2004-2006 Tim Armes |
// |
// This program is free software; you can redistribute it and/or modify |
// it under the terms of the GNU General Public License as published by |
// the Free Software Foundation; either version 2 of the License, or |
// (at your option) any later version. |
// |
// This program is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License |
// along with this program; if not, write to the Free Software |
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
// |
// -- |
// |
// svn-look.php |
// |
// Svn bindings |
// |
// These binding currently use the svn command line to achieve their goal. Once a proper |
// SWIG binding has been produced for PHP, there'll be an option to use that instead. |
require_once 'include/utils.php'; |
// {{{ Classes for retaining log information --- |
$debugxml = false; |
class SVNInfoEntry { |
var $rev = 1; |
var $path = ''; |
var $isdir = null; |
} |
class SVNMod { |
var $action = ''; |
var $copyfrom = ''; |
var $copyrev = ''; |
var $path = ''; |
var $isdir = null; |
} |
class SVNListEntry { |
var $rev = 1; |
var $author = ''; |
var $date = ''; |
var $committime; |
var $age = ''; |
var $file = ''; |
var $isdir = null; |
} |
class SVNList { |
var $entries; // Array of entries |
var $curEntry; // Current entry |
var $path = ''; // The path of the list |
} |
class SVNLogEntry { |
var $rev = 1; |
var $author = ''; |
var $date = ''; |
var $committime; |
var $age = ''; |
var $msg = ''; |
var $path = ''; |
var $precisePath = ''; |
var $mods; |
var $curMod; |
} |
function SVNLogEntry_compare($a, $b) { |
return strnatcasecmp($a->path, $b->path); |
} |
class SVNLog { |
var $entries; // Array of entries |
var $curEntry; // Current entry |
var $path = ''; // Temporary variable used to trace path history |
// findEntry |
// |
// Return the entry for a given revision |
function findEntry($rev) { |
foreach ($this->entries as $index => $entry) { |
if ($entry->rev == $rev) { |
return $index; |
} |
} |
} |
} |
// }}} |
// {{{ XML parsing functions--- |
$curTag = ''; |
$curInfo = 0; |
// {{{ infoStartElement |
function infoStartElement($parser, $name, $attrs) { |
global $curInfo, $curTag, $debugxml; |
switch ($name) { |
case 'INFO': |
if ($debugxml) print 'Starting info'."\n"; |
break; |
case 'ENTRY': |
if ($debugxml) print 'Creating info entry'."\n"; |
if (count($attrs)) { |
foreach ($attrs as $k => $v) { |
switch ($k) { |
case 'KIND': |
if ($debugxml) print 'Kind '.$v."\n"; |
$curInfo->isdir = ($v == 'dir'); |
break; |
case 'REVISION': |
if ($debugxml) print 'Revision '.$v."\n"; |
$curInfo->rev = $v; |
break; |
} |
} |
} |
break; |
default: |
$curTag = $name; |
break; |
} |
} |
// }}} |
// {{{ infoEndElement |
function infoEndElement($parser, $name) { |
global $curInfo, $debugxml, $curTag; |
switch ($name) { |
case 'ENTRY': |
if ($debugxml) print 'Ending info entry'."\n"; |
if ($curInfo->isdir) { |
$curInfo->path .= '/'; |
} |
break; |
} |
$curTag = ''; |
} |
// }}} |
// {{{ infoCharacterData |
function infoCharacterData($parser, $data) { |
global $curInfo, $curTag, $debugxml; |
switch ($curTag) { |
case 'URL': |
if ($debugxml) print 'URL: '.$data."\n"; |
$curInfo->path = $data; |
break; |
case 'ROOT': |
if ($debugxml) print 'Root: '.$data."\n"; |
$curInfo->path = urldecode(substr($curInfo->path, strlen($data))); |
break; |
} |
} |
// }}} |
$curList = 0; |
// {{{ listStartElement |
function listStartElement($parser, $name, $attrs) { |
global $curList, $curTag, $debugxml; |
switch ($name) { |
case 'LIST': |
if ($debugxml) print 'Starting list'."\n"; |
if (count($attrs)) { |
foreach ($attrs as $k => $v) { |
switch ($k) { |
case 'PATH': |
if ($debugxml) print 'Path '.$v."\n"; |
$curList->path = $v; |
break; |
} |
} |
} |
break; |
case 'ENTRY': |
if ($debugxml) print 'Creating new entry'."\n"; |
$curList->curEntry = new SVNListEntry; |
if (count($attrs)) { |
foreach ($attrs as $k => $v) { |
switch ($k) { |
case 'KIND': |
if ($debugxml) print 'Kind '.$v."\n"; |
$curList->curEntry->isdir = ($v == 'dir'); |
break; |
} |
} |
} |
break; |
case 'COMMIT': |
if ($debugxml) print 'Commit'."\n"; |
if (count($attrs)) { |
foreach ($attrs as $k => $v) { |
switch ($k) { |
case 'REVISION': |
if ($debugxml) print 'Revision '.$v."\n"; |
$curList->curEntry->rev = $v; |
break; |
} |
} |
} |
break; |
default: |
$curTag = $name; |
break; |
} |
} |
// }}} |
// {{{ listEndElement |
function listEndElement($parser, $name) { |
global $curList, $debugxml, $curTag; |
switch ($name) { |
case 'ENTRY': |
if ($debugxml) print 'Ending new list entry'."\n"; |
if ($curList->curEntry->isdir) { |
$curList->curEntry->file .= '/'; |
} |
$curList->entries[] = $curList->curEntry; |
$curList->curEntry = null; |
break; |
} |
$curTag = ''; |
} |
// }}} |
// {{{ listCharacterData |
function listCharacterData($parser, $data) { |
global $curList, $curTag, $debugxml; |
switch ($curTag) { |
case 'NAME': |
if ($debugxml) print 'Name: '.$data."\n"; |
if ($data === false || $data === '') return; |
$curList->curEntry->file .= $data; |
break; |
case 'AUTHOR': |
if ($debugxml) print 'Author: '.$data."\n"; |
if ($data === false || $data === '') return; |
if (function_exists('mb_detect_encoding') && function_exists('mb_convert_encoding')) |
$data = mb_convert_encoding($data, 'UTF-8', mb_detect_encoding($data)); |
$curList->curEntry->author .= $data; |
break; |
case 'DATE': |
if ($debugxml) print 'Date: '.$data."\n"; |
if ($data === false || $data === '') return; |
$committime = parseSvnTimestamp($data); |
$curList->curEntry->committime = $committime; |
$curList->curEntry->date = date('Y-m-d H:i:s', $committime); |
$curList->curEntry->age = datetimeFormatDuration(max(time() - $committime, 0), true, true); |
break; |
} |
} |
// }}} |
$curLog = 0; |
// {{{ logStartElement |
function logStartElement($parser, $name, $attrs) { |
global $curLog, $curTag, $debugxml; |
switch ($name) { |
case 'LOGENTRY': |
if ($debugxml) print 'Creating new log entry'."\n"; |
$curLog->curEntry = new SVNLogEntry; |
$curLog->curEntry->mods = array(); |
$curLog->curEntry->path = $curLog->path; |
if (count($attrs)) { |
foreach ($attrs as $k => $v) { |
switch ($k) { |
case 'REVISION': |
if ($debugxml) print 'Revision '.$v."\n"; |
$curLog->curEntry->rev = $v; |
break; |
} |
} |
} |
break; |
case 'PATH': |
if ($debugxml) print 'Creating new path'."\n"; |
$curLog->curEntry->curMod = new SVNMod; |
if (count($attrs)) { |
foreach ($attrs as $k => $v) { |
switch ($k) { |
case 'ACTION': |
if ($debugxml) print 'Action '.$v."\n"; |
$curLog->curEntry->curMod->action = $v; |
break; |
case 'COPYFROM-PATH': |
if ($debugxml) print 'Copy from: '.$v."\n"; |
$curLog->curEntry->curMod->copyfrom = $v; |
break; |
case 'COPYFROM-REV': |
$curLog->curEntry->curMod->copyrev = $v; |
break; |
case 'KIND': |
if ($debugxml) print 'Kind '.$v."\n"; |
$curLog->curEntry->curMod->isdir = ($v == 'dir'); |
break; |
} |
} |
} |
$curTag = $name; |
break; |
default: |
$curTag = $name; |
break; |
} |
} |
// }}} |
// {{{ logEndElement |
function logEndElement($parser, $name) { |
global $curLog, $debugxml, $curTag; |
switch ($name) { |
case 'LOGENTRY': |
if ($debugxml) print 'Ending new log entry'."\n"; |
$curLog->entries[] = $curLog->curEntry; |
break; |
case 'PATH': |
// The XML returned when a file is renamed/branched in inconsistent. |
// In the case of a branch, the path doesn't include the leafname. |
// In the case of a rename, it does. Ludicrous. |
if (!empty($curLog->path)) { |
$pos = strrpos($curLog->path, '/'); |
$curpath = substr($curLog->path, 0, $pos); |
$leafname = substr($curLog->path, $pos + 1); |
} else { |
$curpath = ''; |
$leafname = ''; |
} |
$curMod = $curLog->curEntry->curMod; |
if ($curMod->action == 'A') { |
if ($debugxml) print 'Examining added path "'.$curMod->copyfrom.'" - Current path = "'.$curpath.'", leafname = "'.$leafname.'"'."\n"; |
if ($curMod->path == $curLog->path) { |
// For directories and renames |
$curLog->path = $curMod->copyfrom; |
} else if ($curMod->path == $curpath || $curMod->path == $curpath.'/') { |
// Logs of files that have moved due to branching |
$curLog->path = $curMod->copyfrom.'/'.$leafname; |
} else { |
$curLog->path = str_replace($curMod->path, $curMod->copyfrom, $curLog->path); |
} |
if ($debugxml) print 'New path for comparison: "'.$curLog->path.'"'."\n"; |
} |
if ($debugxml) print 'Ending path'."\n"; |
$curLog->curEntry->mods[] = $curLog->curEntry->curMod; |
break; |
case 'MSG': |
$curLog->curEntry->msg = trim($curLog->curEntry->msg); |
if ($debugxml) print 'Completed msg = "'.$curLog->curEntry->msg.'"'."\n"; |
break; |
} |
$curTag = ''; |
} |
// }}} |
// {{{ logCharacterData |
function logCharacterData($parser, $data) { |
global $curLog, $curTag, $debugxml; |
switch ($curTag) { |
case 'AUTHOR': |
if ($debugxml) print 'Author: '.$data."\n"; |
if ($data === false || $data === '') return; |
if (function_exists('mb_detect_encoding') && function_exists('mb_convert_encoding')) |
$data = mb_convert_encoding($data, 'UTF-8', mb_detect_encoding($data)); |
$curLog->curEntry->author .= $data; |
break; |
case 'DATE': |
if ($debugxml) print 'Date: '.$data."\n"; |
if ($data === false || $data === '') return; |
$committime = parseSvnTimestamp($data); |
$curLog->curEntry->committime = $committime; |
$curLog->curEntry->date = date('Y-m-d H:i:s', $committime); |
$curLog->curEntry->age = datetimeFormatDuration(max(time() - $committime, 0), true, true); |
break; |
case 'MSG': |
if ($debugxml) print 'Msg: '.$data."\n"; |
if (function_exists('mb_detect_encoding') && function_exists('mb_convert_encoding')) |
$data = mb_convert_encoding($data, 'UTF-8', mb_detect_encoding($data)); |
$curLog->curEntry->msg .= $data; |
break; |
case 'PATH': |
if ($debugxml) print 'Path name: '.$data."\n"; |
if ($data === false || $data === '') return; |
$curLog->curEntry->curMod->path .= $data; |
break; |
} |
} |
// }}} |
// }}} |
// {{{ internal functions (_topLevel and _listSort) |
// Function returns true if the give entry in a directory tree is at the top level |
function _topLevel($entry) { |
// To be at top level, there must be one space before the entry |
return (strlen($entry) > 1 && $entry[0] == ' ' && $entry[ 1 ] != ' '); |
} |
// Function to sort two given directory entries. |
// Directories go at the top if config option alphabetic is not set |
function _listSort($e1, $e2) { |
global $config; |
$file1 = $e1->file; |
$file2 = $e2->file; |
$isDir1 = ($file1[strlen($file1) - 1] == '/'); |
$isDir2 = ($file2[strlen($file2) - 1] == '/'); |
if (!$config->isAlphabeticOrder()) { |
if ($isDir1 && !$isDir2) return -1; |
if ($isDir2 && !$isDir1) return 1; |
} |
if ($isDir1) $file1 = substr($file1, 0, -1); |
if ($isDir2) $file2 = substr($file2, 0, -1); |
return strnatcasecmp($file1, $file2); |
} |
// }}} |
// {{{ encodePath |
// Function to encode a URL without encoding the /'s |
function encodePath($uri) { |
global $config; |
$uri = str_replace(DIRECTORY_SEPARATOR, '/', $uri); |
if (function_exists('mb_detect_encoding') && function_exists('mb_convert_encoding')) { |
$uri = mb_convert_encoding($uri, 'UTF-8', mb_detect_encoding($uri)); |
} |
$parts = explode('/', $uri); |
$partscount = count($parts); |
for ($i = 0; $i < $partscount; $i++) { |
// do not rawurlencode the 'svn+ssh://' part! |
if ($i != 0 || $parts[$i] != 'svn+ssh:') { |
$parts[$i] = rawurlencode($parts[$i]); |
} |
} |
$uri = implode('/', $parts); |
// Quick hack. Subversion seems to have a bug surrounding the use of %3A instead of : |
$uri = str_replace('%3A', ':', $uri); |
// Correct for Window share names |
if ($config->serverIsWindows) { |
if (substr($uri, 0, 2) == '//') { |
$uri = '\\'.substr($uri, 2, strlen($uri)); |
} |
if (substr($uri, 0, 10) == 'file://///' ) { |
$uri = 'file:///\\'.substr($uri, 10, strlen($uri)); |
} |
} |
return $uri; |
} |
// }}} |
function _equalPart($str1, $str2) { |
$len1 = strlen($str1); |
$len2 = strlen($str2); |
$i = 0; |
while ($i < $len1 && $i < $len2) { |
if (strcmp($str1[$i], $str2[$i]) != 0) { |
break; |
} |
$i++; |
} |
if ($i == 0) { |
return ''; |
} |
return substr($str1, 0, $i); |
} |
function _logError($string) { |
$string = preg_replace("/--password '.*'/", "--password '[...]'", $string); |
error_log($string); |
} |
// The SVNRepository class |
class SVNRepository { |
var $repConfig; |
var $geshi = null; |
function __construct($repConfig) { |
$this->repConfig = $repConfig; |
} |
// {{{ highlightLine |
// |
// Distill line-spanning syntax highlighting so that each line can stand alone |
// (when invoking on the first line, $attributes should be an empty array) |
// Invoked to make sure all open syntax highlighting tags (<font>, <i>, <b>, etc.) |
// are closed at the end of each line and re-opened on the next line |
function highlightLine($line, &$attributes) { |
$hline = ''; |
// Apply any highlighting in effect from the previous line |
foreach ($attributes as $attr) { |
$hline .= $attr['text']; |
} |
// append the new line |
$hline .= $line; |
// update attributes |
for ($line = strstr($line, '<'); $line; $line = strstr(substr($line, 1), '<')) { |
if (substr($line, 1, 1) == '/') { |
// if this closes a tag, remove most recent corresponding opener |
$tagNamLen = strcspn($line, '> '."\t", 2); |
$tagNam = substr($line, 2, $tagNamLen); |
foreach (array_reverse(array_keys($attributes)) as $k) { |
if ($attributes[$k]['tag'] == $tagNam) { |
unset($attributes[$k]); |
break; |
} |
} |
} else { |
// if this opens a tag, add it to the list |
$tagNamLen = strcspn($line, '> '."\t", 1); |
$tagNam = substr($line, 1, $tagNamLen); |
$tagLen = strcspn($line, '>') + 1; |
$attributes[] = array('tag' => $tagNam, 'text' => substr($line, 0, $tagLen)); |
} |
} |
// close any still-open tags |
foreach (array_reverse($attributes) as $attr) { |
$hline .= '</'.$attr['tag'].'>'; |
} |
// XXX: this just simply replaces [ and ] with their entities to prevent |
// it from being parsed by the template parser; maybe something more |
// elegant is in order? |
$hline = str_replace('[', '[', str_replace(']', ']', $hline) ); |
return $hline; |
} |
// }}} |
// Private function to simplify creation of common SVN command string text. |
function svnCommandString($command, $path, $rev, $peg) { |
global $config; |
return $config->getSvnCommand().$this->repConfig->svnCredentials().' '.$command.' '.($rev ? '-r '.$rev.' ' : '').quote(encodePath($this->getSvnPath($path)).'@'.($peg ? $peg : '')); |
} |
// Private function to simplify creation of enscript command string text. |
function enscriptCommandString($path) { |
global $config, $extEnscript; |
$filename = basename($path); |
$ext = strrchr($path, '.'); |
$lang = false; |
if (array_key_exists($filename, $extEnscript)) { |
$lang = $extEnscript[$filename]; |
} else if ($ext && array_key_exists(strtolower($ext), $extEnscript)) { |
$lang = $extEnscript[strtolower($ext)]; |
} |
$cmd = $config->enscript.' --language=html'; |
if ($lang !== false) { |
$cmd .= ' --color --'.(!$config->getUseEnscriptBefore_1_6_3() ? 'highlight' : 'pretty-print').'='.$lang; |
} |
$cmd .= ' -o -'; |
return $cmd; |
} |
// {{{ getFileContents |
// |
// Dump the content of a file to the given filename |
function getFileContents($path, $filename, $rev = 0, $peg = '', $pipe = '', $highlight = 'file') { |
global $config; |
assert ($highlight == 'file' || $highlight == 'no' || $highlight == 'line'); |
$highlighted = false; |
// If there's no filename, just deliver the contents as-is to the user |
if ($filename == '') { |
$cmd = $this->svnCommandString('cat', $path, $rev, $peg); |
passthruCommand($cmd.' '.$pipe); |
return $highlighted; |
} |
// Get the file contents info |
$tempname = $filename; |
if ($highlight == 'line') { |
$tempname = tempnamWithCheck($config->getTempDir(), ''); |
} |
$highlighted = true; |
$shouldTrimOutput = false; |
$explodeStr = "\n"; |
if ($highlight != 'no' && $config->useGeshi && $geshiLang = $this->highlightLanguageUsingGeshi($path)) { |
$this->applyGeshi($path, $tempname, $geshiLang, $rev, $peg, false, $highlight); |
// Geshi outputs in HTML format, enscript does not |
$shouldTrimOutput = true; |
$explodeStr = "<br />"; |
} else if ($highlight != 'no' && $config->useEnscript) { |
// Get the files, feed it through enscript, then remove the enscript headers using sed |
// Note that the sed command returns only the part of the file between <PRE> and </PRE>. |
// It's complicated because it's designed not to return those lines themselves. |
$cmd = $this->svnCommandString('cat', $path, $rev, $peg); |
$cmd = $cmd.' | '.$this->enscriptCommandString($path).' | '. |
$config->sed.' -n '.$config->quote.'1,/^<PRE.$/!{/^<\\/PRE.$/,/^<PRE.$/!p;}'.$config->quote.' > '.$tempname; |
} else { |
$highlighted = false; |
$cmd = $this->svnCommandString('cat', $path, $rev, $peg); |
$cmd = $cmd.' > '.quote($filename); |
} |
if (isset($cmd)) { |
$error = ''; |
$output = runCommand($cmd, true, $error); |
if (!empty($error)) { |
global $lang; |
_logError($lang['BADCMD'].': '.$cmd); |
_logError($error); |
global $vars; |
$vars['warning'] = nl2br(escape(toOutputEncoding($error))); |
} |
} |
if ($highlighted && $highlight == 'line') { |
// If we need each line independently highlighted (e.g. for diff or blame) |
// then we'll need to filter the output of the highlighter |
// to make sure tags like <font>, <i> or <b> don't span lines |
$dst = fopen($filename, 'w'); |
if ($dst) { |
$content = file_get_contents($tempname); |
$content = explode($explodeStr, $content); |
// $attributes is used to remember what highlighting attributes |
// are in effect from one line to the next |
$attributes = array(); // start with no attributes in effect |
foreach ($content as $line) { |
if ($shouldTrimOutput) { |
$line = trim($line); |
} |
fputs($dst, $this->highlightLine($line, $attributes)."\n"); |
} |
fclose($dst); |
} |
} |
if ($tempname != $filename) { |
@unlink($tempname); |
} |
return $highlighted; |
} |
// }}} |
// {{{ highlightLanguageUsingGeshi |
// |
// check if geshi can highlight the given extension and return the language |
function highlightLanguageUsingGeshi($path) { |
global $config; |
global $extGeshi; |
$filename = basename($path); |
$ext = strrchr($path, '.'); |
if (substr($ext, 0, 1) == '.') $ext = substr($ext, 1); |
foreach ($extGeshi as $language => $extensions) { |
if (in_array($filename, $extensions) || in_array(strtolower($ext), $extensions)) { |
if ($this->geshi === null) { |
if (!defined('USE_AUTOLOADER')) { |
require_once $config->getGeshiScript(); |
} |
$this->geshi = new GeSHi(); |
} |
$this->geshi->set_language($language); |
if ($this->geshi->error() === false) { |
return $language; |
} |
} |
} |
return ''; |
} |
// }}} |
// {{{ applyGeshi |
// |
// perform syntax highlighting using geshi |
function applyGeshi($path, $filename, $language, $rev, $peg = '', $return = false, $highlight = 'file') { |
global $config; |
// Output the file to the filename |
$error = ''; |
$cmd = $this->svnCommandString('cat', $path, $rev, $peg).' > '.quote($filename); |
$output = runCommand($cmd, true, $error); |
if (!empty($error)) { |
global $lang; |
_logError($lang['BADCMD'].': '.$cmd); |
_logError($error); |
global $vars; |
$vars['warning'] = 'Unable to cat file: '.nl2br(escape(toOutputEncoding($error))); |
return; |
} |
$source = file_get_contents($filename); |
if ($this->geshi === null) { |
if (!defined('USE_AUTOLOADER')) { |
require_once $config->getGeshiScript(); |
} |
$this->geshi = new GeSHi(); |
} |
$this->geshi->set_source($source); |
$this->geshi->set_language($language); |
$this->geshi->set_header_type(GESHI_HEADER_NONE); |
$this->geshi->set_overall_class('geshi'); |
$this->geshi->set_tab_width($this->repConfig->getExpandTabsBy()); |
if ($highlight == 'file') { |
$this->geshi->enable_line_numbers(GESHI_FANCY_LINE_NUMBERS); |
$this->geshi->set_overall_id('geshi'); |
$this->geshi->enable_ids(true); |
} |
if ($return) { |
return $this->geshi->parse_code(); |
} else { |
$f = @fopen($filename, 'w'); |
fwrite($f, $this->geshi->parse_code()); |
fclose($f); |
} |
} |
// }}} |
// {{{ listFileContents |
// |
// Print the contents of a file without filling up Apache's memory |
function listFileContents($path, $rev = 0, $peg = '') { |
global $config; |
if ($config->useGeshi && $geshiLang = $this->highlightLanguageUsingGeshi($path)) { |
$tempname = tempnamWithCheck($config->getTempDir(), 'websvn'); |
if ($tempname !== false) { |
print toOutputEncoding($this->applyGeshi($path, $tempname, $geshiLang, $rev, $peg, true)); |
@unlink($tempname); |
} |
} else { |
$pre = false; |
$cmd = $this->svnCommandString('cat', $path, $rev, $peg); |
if ($config->useEnscript) { |
$cmd .= ' | '.$this->enscriptCommandString($path).' | '. |
$config->sed.' -n '.$config->quote.'/^<PRE.$/,/^<\\/PRE.$/p'.$config->quote; |
} else { |
$pre = true; |
} |
if ($result = popenCommand($cmd, 'r')) { |
if ($pre) |
echo '<pre>'; |
while (!feof($result)) { |
$line = fgets($result, 1024); |
$line = toOutputEncoding($line); |
if ($pre) { |
$line = escape($line); |
} |
print hardspace($line); |
} |
if ($pre) |
echo '</pre>'; |
pclose($result); |
} |
} |
} |
// }}} |
// {{{ listReadmeContents |
// |
// Parse the README.md file |
function listReadmeContents($path, $rev = 0, $peg = '') { |
global $config; |
$file = "README.md"; |
if ($this->isFile($path.$file) != True) |
{ |
return; |
} |
if (!$config->getUseParsedown()) |
{ |
return; |
} |
// Autoloader handles most of the time |
if (!defined('USE_AUTOLOADER')) { |
require_once $config->getParsedownScript(); |
} |
$mdParser = new Parsedown(); |
$cmd = $this->svnCommandString('cat', $path.$file, $rev, $peg); |
if (!($result = popenCommand($cmd, 'r'))) |
{ |
return; |
} |
echo('<div id="wrap">'); |
while (!feof($result)) |
{ |
$line = fgets($result, 1024); |
echo $mdParser->text($line); |
} |
echo('</div>'); |
pclose($result); |
} |
// }}} |
// {{{ getBlameDetails |
// |
// Dump the blame content of a file to the given filename |
function getBlameDetails($path, $filename, $rev = 0, $peg = '') { |
$error = ''; |
$cmd = $this->svnCommandString('blame', $path, $rev, $peg).' > '.quote($filename); |
$output = runCommand($cmd, true, $error); |
if (!empty($error)) { |
global $lang; |
_logError($lang['BADCMD'].': '.$cmd); |
_logError($error); |
global $vars; |
$vars['warning'] = 'No blame info: '.nl2br(escape(toOutputEncoding($error))); |
} |
} |
// }}} |
function getProperties($path, $rev = 0, $peg = '') { |
$cmd = $this->svnCommandString('proplist', $path, $rev, $peg); |
$ret = runCommand($cmd, true); |
$properties = array(); |
if (is_array($ret)) { |
foreach ($ret as $line) { |
if (substr($line, 0, 1) == ' ') { |
$properties[] = ltrim($line); |
} |
} |
} |
return $properties; |
} |
// {{{ getProperty |
function getProperty($path, $property, $rev = 0, $peg = '') { |
$cmd = $this->svnCommandString('propget '.$property, $path, $rev, $peg); |
$ret = runCommand($cmd, true); |
// Remove the surplus newline |
if (count($ret)) { |
unset($ret[count($ret) - 1]); |
} |
return implode("\n", $ret); |
} |
// }}} |
// {{{ exportDirectory |
// |
// Exports the directory to the given location |
function exportRepositoryPath($path, $filename, $rev = 0, $peg = '') { |
$cmd = $this->svnCommandString('export', $path, $rev, $peg).' '.quote($filename.'@'); |
$retcode = 0; |
execCommand($cmd, $retcode); |
if ($retcode != 0) { |
global $lang; |
_logError($lang['BADCMD'].': '.$cmd); |
} |
return $retcode; |
} |
// }}} |
// {{{ _xmlParseCmdOutput |
function _xmlParseCmdOutput($cmd, $startElem, $endElem, $charData) { |
$error = ''; |
$lines = runCommand($cmd, false, $error); |
$linesCnt = count($lines); |
$xml_parser = xml_parser_create('UTF-8'); |
xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING, true); |
xml_set_element_handler($xml_parser, $startElem, $endElem); |
xml_set_character_data_handler($xml_parser, $charData); |
for ($i = 0; $i < $linesCnt; ++$i) { |
$line = $lines[$i] . "\n"; |
$isLast = $i == ($linesCnt - 1); |
if (xml_parse($xml_parser, $line, $isLast)) { |
continue; |
} |
$errorMsg = sprintf('XML error: %s (%d) at line %d column %d byte %d'."\n".'cmd: %s', |
xml_error_string(xml_get_error_code($xml_parser)), |
xml_get_error_code($xml_parser), |
xml_get_current_line_number($xml_parser), |
xml_get_current_column_number($xml_parser), |
xml_get_current_byte_index($xml_parser), |
$cmd); |
if (xml_get_error_code($xml_parser) == 5) { |
break; |
} |
// errors can contain sensitive info! don't echo this ~J |
_logError($errorMsg); |
exit; |
} |
xml_parser_free($xml_parser); |
if (empty($error)) { |
return; |
} |
$error = toOutputEncoding(nl2br(str_replace('svn: ', '', $error))); |
global $lang; |
_logError($lang['BADCMD'].': '.$cmd); |
_logError($error); |
global $vars; |
if (strstr($error, 'found format')) { |
$vars['error'] = 'Repository uses a newer format than Subversion '.$config->getSubversionVersion().' can read. ("'.nl2br(escape(toOutputEncoding(substr($error, strrpos($error, 'Expected'))))).'.")'; |
} else if (strstr($error, 'No such revision')) { |
$vars['warning'] = 'Revision '.$rev.' of this resource does not exist.'; |
} else { |
$vars['error'] = $lang['BADCMD'].': <code>'.escape(stripCredentialsFromCommand($cmd)).'</code><br />'.nl2br(escape(toOutputEncoding($error))); |
} |
} |
// }}} |
// {{{ getInfo |
function getInfo($path, $rev = 0, $peg = '') { |
global $config, $curInfo; |
// Since directories returned by svn log don't have trailing slashes (:-(), we need to remove |
// the trailing slash from the path for comparison purposes |
if ($path[strlen($path) - 1] == '/' && $path != '/') { |
$path = substr($path, 0, -1); |
} |
$curInfo = new SVNInfoEntry; |
// Get the svn info |
if ($rev == 0) { |
$headlog = $this->getLog('/', '', '', true, 1); |
if ($headlog && isset($headlog->entries[0])) |
$rev = $headlog->entries[0]->rev; |
} |
$cmd = $this->svnCommandString('info --xml', $path, $rev, $peg); |
$this->_xmlParseCmdOutput($cmd, 'infoStartElement', 'infoEndElement', 'infoCharacterData'); |
if ($this->repConfig->subpath !== null) { |
if (substr($curInfo->path, 0, strlen($this->repConfig->subpath) + 1) === '/'. $this->repConfig->subpath) { |
$curInfo->path = substr($curInfo->path, strlen($this->repConfig->subpath) + 1); |
} else { |
// hide entry when file is outside of subpath |
return null; |
} |
} |
return $curInfo; |
} |
// }}} |
// {{{ getList |
function getList($path, $rev = 0, $peg = '') { |
global $config, $curList; |
// Since directories returned by svn log don't have trailing slashes (:-(), we need to remove |
// the trailing slash from the path for comparison purposes |
if ($path[strlen($path) - 1] == '/' && $path != '/') { |
$path = substr($path, 0, -1); |
} |
$curList = new SVNList; |
$curList->entries = array(); |
$curList->path = $path; |
// Get the list info |
if ($rev == 0) { |
$headlog = $this->getLog('/', '', '', true, 1); |
if ($headlog && isset($headlog->entries[0])) |
$rev = $headlog->entries[0]->rev; |
} |
if ($config->showLoadAllRepos()) { |
$cmd = $this->svnCommandString('list -R --xml', $path, $rev, $peg); |
$this->_xmlParseCmdOutput($cmd, 'listStartElement', 'listEndElement', 'listCharacterData'); |
} |
else { |
$cmd = $this->svnCommandString('list --xml', $path, $rev, $peg); |
$this->_xmlParseCmdOutput($cmd, 'listStartElement', 'listEndElement', 'listCharacterData'); |
usort($curList->entries, '_listSort'); |
} |
return $curList; |
} |
// }}} |
// {{{ getListSearch |
function getListSearch($path, $term = '', $rev = 0, $peg = '') { |
global $config, $curList; |
// Since directories returned by "svn log" don't have trailing slashes (:-(), we need to |
// remove the trailing slash from the path for comparison purposes. |
if (($path[strlen($path) - 1] == '/') && ($path != '/')) { |
$path = substr($path, 0, -1); |
} |
$curList = new SVNList; |
$curList->entries = array(); |
$curList->path = $path; |
// Get the list info |
if ($rev == 0) { |
$headlog = $this->getLog('/', '', '', true, 1); |
if ($headlog && isset($headlog->entries[0])) |
$rev = $headlog->entries[0]->rev; |
} |
$term = escapeshellarg($term); |
$cmd = 'list -R --search ' . $term . ' --xml'; |
$cmd = $this->svnCommandString($cmd, $path, $rev, $peg); |
$this->_xmlParseCmdOutput($cmd, 'listStartElement', 'listEndElement', 'listCharacterData'); |
return $curList; |
} |
// }}} |
// {{{ getLog |
function getLog($path, $brev = '', $erev = 1, $quiet = false, $limit = 2, $peg = '', $verbose = false) { |
global $config, $curLog; |
// Since directories returned by svn log don't have trailing slashes (:-(), |
// we must remove the trailing slash from the path for comparison purposes. |
if (!empty($path) && $path != '/' && $path[strlen($path) - 1] == '/') { |
$path = substr($path, 0, -1); |
} |
$curLog = new SVNLog; |
$curLog->entries = array(); |
$curLog->path = $path; |
// Get the log info |
$effectiveRev = ($brev && $erev ? $brev.':'.$erev : ($brev ? $brev.':1' : '')); |
$effectivePeg = ($peg ? $peg : ($brev ? $brev : '')); |
$cmd = $this->svnCommandString('log --xml '.($verbose ? '--verbose' : ($quiet ? '--quiet' : '')).($limit != 0 ? ' --limit '.$limit : ''), $path, $effectiveRev, $effectivePeg); |
$this->_xmlParseCmdOutput($cmd, 'logStartElement', 'logEndElement', 'logCharacterData'); |
foreach ($curLog->entries as $entryKey => $entry) { |
$fullModAccess = true; |
$anyModAccess = (count($entry->mods) == 0); |
$precisePath = null; |
foreach ($entry->mods as $modKey => $mod) { |
$access = $this->repConfig->hasLogReadAccess($mod->path); |
if ($access) { |
$anyModAccess = true; |
// find path which is parent of all modification but more precise than $curLogEntry->path |
$modpath = $mod->path; |
if (!$mod->isdir || $mod->action == 'D') { |
$pos = strrpos($modpath, '/'); |
$modpath = substr($modpath, 0, $pos + 1); |
} |
if (strlen($modpath) == 0 || substr($modpath, -1) !== '/') { |
$modpath .= '/'; |
} |
//compare with current precise path |
if ($precisePath === null) { |
$precisePath = $modpath; |
} else { |
$equalPart = _equalPart($precisePath, $modpath); |
if (substr($equalPart, -1) !== '/') { |
$pos = strrpos($equalPart, '/'); |
$equalPart = substr($equalPart, 0, $pos + 1); |
} |
$precisePath = $equalPart; |
} |
// fix paths if command was for a subpath repository |
if ($this->repConfig->subpath !== null) { |
if (substr($mod->path, 0, strlen($this->repConfig->subpath) + 1) === '/'. $this->repConfig->subpath) { |
$curLog->entries[$entryKey]->mods[$modKey]->path = substr($mod->path, strlen($this->repConfig->subpath) + 1); |
} else { |
// hide modified entry when file is outside of subpath |
unset($curLog->entries[$entryKey]->mods[$modKey]); |
} |
} |
} else { |
// hide modified entry when access is prohibited |
unset($curLog->entries[$entryKey]->mods[$modKey]); |
$fullModAccess = false; |
} |
} |
if (!$fullModAccess) { |
// hide commit message when access to any of the entries is prohibited |
$curLog->entries[$entryKey]->msg = ''; |
} |
if (!$anyModAccess) { |
// hide author and date when access to all of the entries is prohibited |
$curLog->entries[$entryKey]->author = ''; |
$curLog->entries[$entryKey]->date = ''; |
$curLog->entries[$entryKey]->committime = ''; |
$curLog->entries[$entryKey]->age = ''; |
} |
if ($precisePath !== null) { |
$curLog->entries[$entryKey]->precisePath = $precisePath; |
} else { |
$curLog->entries[$entryKey]->precisePath = $curLog->entries[$entryKey]->path; |
} |
} |
return $curLog; |
} |
// }}} |
function isFile($path, $rev = 0, $peg = '') { |
$cmd = $this->svnCommandString('info --xml', $path, $rev, $peg); |
return strpos(implode(' ', runCommand($cmd, true)), 'kind="file"') !== false; |
} |
// {{{ getSvnPath |
function getSvnPath($path) { |
if ($this->repConfig->subpath === null) { |
return $this->repConfig->path.$path; |
} else { |
return $this->repConfig->path.'/'.$this->repConfig->subpath.$path; |
} |
} |
// }}} |
} |
// Initialize SVN version information by parsing from command-line output. |
$cmd = $config->getSvnCommand(); |
$cmd = str_replace(array('--non-interactive', '--trust-server-cert'), array('', ''), $cmd); |
$cmd .= ' --version -q'; |
$ret = runCommand($cmd, false); |
if (preg_match('~([0-9]+)\.([0-9]+)\.([0-9]+)~', $ret[0], $matches)) { |
$config->setSubversionVersion($matches[0]); |
$config->setSubversionMajorVersion($matches[1]); |
$config->setSubversionMinorVersion($matches[2]); |
} |
/WebSVN/include/template.php |
---|
0,0 → 1,321 |
<?php |
// WebSVN - Subversion repository viewing via the web using PHP |
// Copyright (C) 2004-2006 Tim Armes |
// |
// This program is free software; you can redistribute it and/or modify |
// it under the terms of the GNU General Public License as published by |
// the Free Software Foundation; either version 2 of the License, or |
// (at your option) any later version. |
// |
// This program is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License |
// along with this program; if not, write to the Free Software |
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
// |
// -- |
// |
// templates.php |
// |
// Templating system to allow advanced page customisation |
$vars['version'] = $version; // Set WebSVN version for all template files |
$vars['currentyear'] = date('Y'); |
$ignore = false; |
// Stack of previous test results |
$ignorestack = array(); |
// Number of test levels currently ignored |
$ignorelevel = 0; |
// parseCommand |
// |
// Parse a special command |
function parseCommand($line, $vars, $handle) { |
global $ignore, $ignorestack, $ignorelevel, $config, $listing, $vars; |
// process content of included file |
if (strncmp(trim($line), '[websvn-include:', 16) == 0) { |
if (!$ignore) { |
$line = trim($line); |
$file = substr($line, 16, -1); |
parseTemplate($file); |
} |
return true; |
} |
// Check for test conditions |
if (strncmp(trim($line), '[websvn-test:', 13) == 0) { |
if (!$ignore) { |
$line = trim($line); |
$var = substr($line, 13, -1); |
$neg = ($var[0] == '!'); |
if ($neg) $var = substr($var, 1); |
if (empty($vars[$var]) ^ $neg) { |
array_push($ignorestack, $ignore); |
$ignore = true; |
} |
} else { |
$ignorelevel++; |
} |
return true; |
} |
if (strncmp(trim($line), '[websvn-else]', 13) == 0) { |
if ($ignorelevel == 0) { |
$ignore = !$ignore; |
} |
return true; |
} |
if (strncmp(trim($line), '[websvn-endtest]', 16) == 0) { |
if ($ignorelevel > 0) { |
$ignorelevel--; |
} else { |
$ignore = array_pop($ignorestack); |
} |
return true; |
} |
if (strncmp(trim($line), '[websvn-getlisting]', 19) == 0) { |
global $svnrep, $path, $rev, $peg; |
if (!$ignore) { |
$svnrep->listFileContents($path, $rev, $peg); |
} |
return true; |
} |
if (strncmp(trim($line), '[websvn-defineicons]', 19) == 0) { |
global $icons; |
if (!isset($icons)) { |
$icons = array(); |
} |
// Read all the lines until we reach the end of the definition, storing |
// each one... |
if (!$ignore) { |
while (!feof($handle)) { |
$line = trim(fgets($handle)); |
if (strncmp($line, '[websvn-enddefineicons]', 22) == 0) { |
return true; |
} |
$eqsign = strpos($line, '='); |
$match = substr($line, 0, $eqsign); |
$def = substr($line, $eqsign + 1); |
$icons[$match] = $def; |
} |
} |
return true; |
} |
if (strncmp(trim($line), '[websvn-icon]', 13) == 0) { |
global $icons, $vars; |
if (!$ignore) { |
// The current filetype should be defined my $vars['filetype'] |
if (!empty($icons[$vars['filetype']])) { |
echo parseTags($icons[$vars['filetype']], $vars); |
} else if (!empty($icons['*'])) { |
echo parseTags($icons['*'], $vars); |
} |
} |
return true; |
} |
if (strncmp(trim($line), '[websvn-treenode]', 17) == 0) { |
global $icons, $vars; |
if (!$ignore) { |
if ((!empty($icons['i-node'])) && (!empty($icons['t-node'])) && (!empty($icons['l-node']))) { |
for ($n = 1; $n < $vars['level']; $n++) { |
if ($vars['last_i_node'][$n]) { |
echo parseTags($icons['e-node'], $vars); |
} else { |
echo parseTags($icons['i-node'], $vars); |
} |
} |
if ($vars['level'] != 0) { |
if ($vars['node'] == 0) { |
echo parseTags($icons['t-node'], $vars); |
} else { |
echo parseTags($icons['l-node'], $vars); |
$vars['last_i_node'][$vars['level']] = true; |
} |
} |
} |
} |
return true; |
} |
return false; |
} |
// parseTemplate |
// |
// Parse the given template, replacing the variables with the values passed |
function parseTemplate($file) { |
global $ignore, $rep, $config, $vars, $listing; |
$template = (($rep) ? $rep->getTemplatePath() : $config->getTemplatePath()).$file; |
if (!is_file($template)) { |
print 'No template file found ('.$template.')'; |
exit; |
} |
$handle = fopen($template, 'r'); |
$inListing = false; |
$ignore = false; |
$listLines = array(); |
while (!feof($handle)) { |
$line = fgets($handle); |
// Check for the end of the file list |
if ($inListing) { |
if (strcmp(trim($line), '[websvn-endlisting]') == 0) { |
$inListing = false; |
// For each item in the list |
foreach ($listing as $listvars) { |
// Copy the value for this list item into the $vars array |
foreach ($listvars as $id => $value) { |
$vars[$id] = $value; |
} |
// Output the list item |
foreach ($listLines as $line) { |
if (!parseCommand($line, $vars, $handle) && !$ignore) { |
print parseTags($line, $vars); |
} |
} |
} |
} else if ($ignore == false) { |
$listLines[] = $line; |
} |
} else if (parseCommand($line, $vars, $handle)) { |
continue; |
} else { |
// Check for the start of the file list |
if (strncmp(trim($line), '[websvn-startlisting]', 21) == 0) { |
$inListing = true; |
} else { |
if ($ignore == false) { |
print parseTags($line, $vars); |
} |
} |
} |
} |
fclose($handle); |
} |
// parseTags |
// |
// Replace all occurences of [websvn:varname] with the give variable |
function parseTags($line, $vars) { |
global $lang; |
// Replace the language strings |
while (preg_match('|\[lang:([a-zA-Z0-9_]+)\]|', $line, $matches)) { |
// Make sure that the variable exists |
if (!isset($lang[$matches[1]])) { |
$lang[$matches[1]] = '?${matches[1]}?'; |
} |
$line = str_replace($matches[0], $lang[$matches[1]], $line); |
} |
$l = ''; |
// Replace the websvn variables |
while (preg_match('|\[websvn:([a-zA-Z0-9_]+)\]|', $line, $matches)) { |
// Find beginning |
$p = strpos($line, $matches[0]); |
// add everything up to beginning |
if ($p > 0) { |
$l .= substr($line, 0, $p); |
} |
// Replace variable (special token, if not exists) |
$l .= isset($vars[$matches[1]]) ? $vars[$matches[1]]: ('?'.$matches[1].'?'); |
// Remove allready processed part of line |
$line = substr($line, $p + strlen($matches[0])); |
} |
// Rebuild line, add remaining part of line |
$line = $l.$line; |
return $line; |
} |
// renderTemplate |
// |
// Renders the templates for the given view |
function renderTemplate($view, $readmePath = null) |
{ |
global $config, $rep, $vars, $listing, $lang, $locwebsvnhttp; |
// Set the view in the templates variables |
$vars['template'] = $view; |
// Check if we are using a PHP powered template or the standard one |
$path = !empty($rep) ? $rep->getTemplatePath() : $config->getTemplatePath(); |
$path = $path . 'template.php'; |
if (is_readable($path)) |
{ |
$vars['templateentrypoint'] = $path; |
executePlainPhpTemplate($vars); |
} |
else |
{ |
parseTemplate('header.tmpl'); |
flush(); // http://developer.yahoo.com/performance/rules.html#flush |
parseTemplate($view . '.tmpl'); |
if (($view === 'directory') || ($view === 'log')) |
{ |
print '<script type="text/javascript" src="'.$locwebsvnhttp.'/javascript/compare-checkboxes.js"></script>'; |
} |
if ($readmePath == null) |
{ |
parseTemplate('footer.tmpl'); |
return; |
} |
$svnrep = new SVNRepository($rep); |
$svnrep->listReadmeContents($readmePath); |
parseTemplate('footer.tmpl'); |
} |
} |
function executePlainPhpTemplate($vars) { |
require_once $vars['templateentrypoint']; |
} |
// {{{ renderTemplate404 |
function renderTemplate404($view, $errorDetail="") |
{ |
global $vars, $lang; |
http_response_code(404); |
$vars['error'] = "WebSVN 404 ".$lang[$errorDetail]; |
renderTemplate($view); |
exit(0); |
} |
// }}} |
/WebSVN/include/utils.php |
---|
0,0 → 1,477 |
<?php |
// WebSVN - Subversion repository viewing via the web using PHP |
// Copyright (C) 2004-2006 Tim Armes |
// |
// This program is free software; you can redistribute it and/or modify |
// it under the terms of the GNU General Public License as published by |
// the Free Software Foundation; either version 2 of the License, or |
// (at your option) any later version. |
// |
// This program is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License |
// along with this program; if not, write to the Free Software |
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
// |
// -- |
// |
// utils.php |
// |
// General utility commands |
// {{{ createDirLinks |
// |
// Create a list of links to the current path that'll be available from the template |
function createPathLinks($rep, $path, $rev, $peg = '') { |
global $config, $lang, $vars; |
$pathComponents = explode('/', $path); |
$count = count($pathComponents); |
// The number of links depends on the last item. It's empty if we're looking |
// at a directory, and non-empty if we're looking at a file. |
if (empty($pathComponents[$count - 1])) { |
$limit = $count - 2; |
$dir = true; |
} else { |
$limit = $count - 1; |
$dir = false; |
} |
$passRevString = createRevAndPegString($rev, $peg); |
$pathSoFar = '/'; |
$pathSoFarURL = $config->getURL($rep, $pathSoFar, 'dir').$passRevString; |
$repoName = $rep->getDisplayName(); |
$rootName = $lang['BREADCRUMB_REPO_ROOT']; |
$vars['path_links'] = ''; |
$vars['path_links_root_root'] = "<a href=\"{$pathSoFarURL}\" class=\"root\"><span>{$rootName}</span></a>"; |
$vars['path_links_root_repo'] = "<a href=\"{$pathSoFarURL}\" class=\"root\"><span>{$repoName}</span></a>"; |
$vars['path_links_root_config'] = $config->getBreadcrumbRepoRootAsRepo() |
? $vars['path_links_root_repo'] |
: $vars['path_links_root_root']; |
for ($n = 1; $n < $limit; $n++) { |
$pathSoFar .= $pathComponents[$n].'/'; |
$pathSoFarURL = $config->getURL($rep, $pathSoFar, 'dir').$passRevString; |
$vars['path_links'] .= '<a href="'.$pathSoFarURL.'#'.anchorForPath($pathSoFar).'">'.escape($pathComponents[$n]).'</a>/'; |
} |
if (!empty($pathComponents[$n])) { |
$pegrev = ($peg && $peg != $rev) ? ' <a class="peg" href="'.'?'.escape(str_replace('&peg='.$peg, '', $_SERVER['QUERY_STRING'])).'">@ '.$peg.'</a>' : ''; |
if ($dir) { |
$vars['path_links'] .= '<span class="dir">'.escape($pathComponents[$n]).'/'.$pegrev.'</span>'; |
} else { |
$vars['path_links'] .= '<span class="file">'.escape($pathComponents[$n]).$pegrev.'</span>'; |
} |
} |
} |
// }}} |
function createRevAndPegString($rev, $peg) { |
$params = array(); |
if ($rev) $params[] = 'rev='.$rev; |
if ($peg) $params[] = 'peg='.$peg; |
return implode('&', $params); |
} |
function createDifferentRevAndPegString($rev, $peg) { |
$params = array(); |
if ($rev && (!$peg || $rev != $peg)) $params[] = 'rev='.$rev; |
if ($peg) $params[] = 'peg='.$peg; |
return implode('&', $params); |
} |
function anchorForPath($path) { |
global $config; |
// (X)HMTL id/name attribute must be this format: [A-Za-z][A-Za-z0-9-_.:]* |
// MD5 hashes are 32 characters, deterministic, quite collision-resistant, |
// and work for any string, regardless of encoding or special characters. |
if ($config->treeView) |
return 'a'.md5($path); |
else |
return ''; |
} |
// {{{ create_anchors |
// |
// Create links out of http:// and mailto: tags |
// TODO: the target="_blank" nonsense should be optional (or specified by the template) |
function create_anchors($text) { |
$ret = $text; |
// Match correctly formed URLs that aren't already links |
$ret = preg_replace('#\b(?<!href=")([a-z]+?)://(\S*)([\w/]+)#i', |
'<a href="\\1://\\2\\3" target="_blank">\\1://\\2\\3</a>', |
$ret); |
// Now match anything beginning with www, as long as it's not //www since they were matched above |
$ret = preg_replace('#\b(?<!//)www\.(\S*)([\w/]+)#i', |
'<a href="http://www.\\1\\2" target="_blank">www.\\1\\2</a>', |
$ret); |
// Match email addresses |
$ret = preg_replace('#\b([\w\-_.]+)@([\w\-.]+)\.(\w{2,})\b#i', |
'<a href="mailto:\\1@\\2.\\3">\\1@\\2.\\3</a>', |
$ret); |
return $ret; |
} |
// }}} |
// {{{ getFullURL |
function getFullURL($loc) { |
$protocol = 'http'; |
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO'])) { |
$protocol = $_SERVER['HTTP_X_FORWARDED_PROTO']; |
} else if (isset($_SERVER['HTTPS']) && (strtolower($_SERVER['HTTPS']) != 'off')) { |
$protocol = 'https'; |
} |
$port = ':'.$_SERVER['SERVER_PORT']; |
if ((':80' == $port && 'http' == $protocol) || (':443' == $port && 'https' == $protocol)) { |
$port = ''; |
} |
if (isset($_SERVER['HTTP_X_FORWARDED_HOST'])) { |
$host = $_SERVER['HTTP_X_FORWARDED_HOST']; |
} else if (isset($_SERVER['HTTP_HOST'])) { |
$host = $_SERVER['HTTP_HOST']; |
} else if (isset($_SERVER['SERVER_NAME'])) { |
$host = $_SERVER['SERVER_NAME'].$port; |
} else if (isset($_SERVER['SERVER_ADDR'])) { |
$host = $_SERVER['SERVER_ADDR'].$port; |
} else { |
print 'Unable to redirect'; |
exit; |
} |
// make sure we have a directory to go to |
if (empty($loc)) { |
$loc = '/'; |
} else if ($loc[0] != '/') { |
$loc = '/'.$loc; |
} |
$url = $protocol . '://' . $host . $loc; |
return $url; |
} |
// }}} |
function xml_entities($str) { |
$entities = array(); |
$entities['&'] = '&'; |
$entities['<'] = '<'; |
$entities['>'] = '>'; |
$entities['"'] = '"'; |
$entities['\''] = '''; |
return str_replace(array_keys($entities), array_values($entities), $str); |
} |
// {{{ hardspace |
// |
// Replace the spaces at the front of a line with hard spaces |
// XXX: this is an unnecessary function; you can prevent whitespace from being |
// trimmed via CSS (use the "white-space: pre;" properties). ~J |
// in the meantime, here's an improved function (does nothing) |
function hardspace($s) { |
return '<code>' . expandTabs($s) . '</code>'; |
} |
// }}} |
function wrapInCodeTagIfNecessary($string) { |
global $config; |
return ($config->getUseGeshi()) ? $string : '<code>'.$string.'</code>'; |
} |
// {{{ expandTabs |
/** |
* Expands the tabs in a line that may or may not include HTML. |
* |
* Enscript generates code with HTML, so we need to take that into account. |
* |
* @param string $s Line of possibly HTML-encoded text to expand |
* @param int $tabwidth Tab width, -1 to use repository's default, 0 to collapse |
* all tabs. |
* @return string The expanded line. |
* @since 2.1 |
*/ |
function expandTabs($s, $tabwidth = - 1) { |
global $rep; |
if ($tabwidth == -1) { |
$tabwidth = $rep->getExpandTabsBy(); |
} |
$pos = 0; |
// Parse the string into chunks that are either 1 of: HTML tag, tab char, run of any other stuff |
$chunks = preg_split('/((?:<.+?>)|(?:&.+?;)|(?:\t))/', $s, -1, PREG_SPLIT_DELIM_CAPTURE); |
// Count the sizes of the chunks and replace tabs as we go |
$chunkscount = count($chunks); |
for ($i = 0; $i < $chunkscount; $i++) { |
// make sure we're not dealing with an empty string |
if (empty($chunks[$i])) continue; |
switch ($chunks[$i][0]) { |
case '<': // HTML tag: ignore its width by doing nothing |
break; |
case '&': // HTML entity: count its width as 1 char |
$pos++; |
break; |
case "\t": // Tab char: replace it with a run of spaces between length tabwidth and 1 |
$tabsize = $tabwidth - ($pos % $tabwidth); |
$chunks[$i] = str_repeat(' ', $tabsize); |
$pos += $tabsize; |
break; |
default: // Anything else: just keep track of its width |
$pos += strlen($chunks[$i]); |
break; |
} |
} |
// Put the chunks back together and we've got the original line, detabbed. |
return join('', $chunks); |
} |
// }}} |
// {{{ datetimeFormatDuration |
// |
// Formats a duration of seconds for display. |
// |
// $seconds the number of seconds until something |
// $nbsp true if spaces should be replaced by nbsp |
// $skipSeconds true if seconds should be omitted |
// |
// return the formatted duration (e.g. @c "8h 6m 1s") |
function datetimeFormatDuration($seconds, $nbsp = false, $skipSeconds = false) { |
global $lang; |
$neg = false; |
if ($seconds < 0) { |
$seconds = 0 - $seconds; |
$neg = true; |
} |
$qty = array(); |
$names = array($lang['DAYLETTER'], $lang['HOURLETTER'], $lang['MINUTELETTER']); |
$qty[] = (int)($seconds / (60 * 60 * 24)); |
$seconds %= 60 * 60 * 24; |
$qty[] = (int)($seconds / (60 * 60)); |
$seconds %= 60 * 60; |
$qty[] = (int)($seconds / 60); |
if (!$skipSeconds) { |
$qty[] = (int)($seconds % 60); |
$names[] = $lang['SECONDLETTER']; |
} |
$text = $neg ? '-' : ''; |
$any = false; |
$count = count($names); |
$parts = 0; |
for ($i = 0; $i < $count; $i++) { |
// If a "higher valued" time slot had a value or this time slot |
// has a value or this is the very last entry (i.e. all values |
// are 0 and we still want to print seconds) |
if ($any || $qty[$i] > 0 || $i == $count - 1) { |
if ($any) $text .= $nbsp ? ' ' : ' '; |
$text .= $qty[$i].' '.$names[$i]; |
$any = true; |
$parts++; |
if ($parts >= 2) break; |
} |
} |
return $text; |
} |
// }}} |
function parseSvnTimestamp($dateString) { |
// Try the simple approach of a built-in PHP function first. |
$date = strtotime($dateString); |
// If the resulting timestamp isn't sane, try parsing manually. |
if ($date <= 0) { |
$y = 0; |
$mo = 0; |
$d = 0; |
$h = 0; |
$m = 0; |
$s = 0; |
sscanf($dateString, '%d-%d-%dT%d:%d:%d.', $y, $mo, $d, $h, $m, $s); |
$mo = substr('00'.$mo, -2); |
$d = substr('00'.$d, -2); |
$h = substr('00'.$h, -2); |
$m = substr('00'.$m, -2); |
$s = substr('00'.$s, -2); |
$date = strtotime($y.'-'.$mo.'-'.$d.' '.$h.':'.$m.':'.$s.' GMT'); |
} |
return $date; |
} |
// {{{ buildQuery |
// |
// Build parameters for url query part |
function buildQuery($data, $separator = '&', $key = '') { |
if (is_object($data)) |
$data = get_object_vars($data); |
$p = array(); |
foreach ($data as $k => $v) { |
$k = rawurlencode($k); |
if (!empty($key)) |
$k = $key.'['.$k.']'; |
if (is_array($v) || is_object($v)) { |
$p[] = buildQuery($v, $separator, $k); |
} else { |
$p[] = $k.'='.rawurlencode($v); |
} |
} |
return implode($separator, $p); |
} |
// }}} |
// {{{ getUserLanguage |
function getUserLanguage($languages, $default, $userchoice) { |
global $config; |
if (!$config->useAcceptedLanguages()) return $default; |
$acceptlangs = isset($_SERVER['HTTP_ACCEPT_LANGUAGE']) ? $_SERVER['HTTP_ACCEPT_LANGUAGE'] : false; |
if (!$acceptlangs) |
return $default; |
$langs = array(); |
$sublangs = array(); |
foreach (explode(',', $acceptlangs) as $str) { |
$a = explode(';', $str, 2); |
$lang = trim($a[0]); |
$pos = strpos($lang, '-'); |
if ($pos !== false) |
$sublangs[] = substr($lang, 0, $pos); |
$q = 1.0; |
if (count($a) == 2) { |
$v = trim($a[1]); |
if (substr($v, 0, 2) == 'q=') |
$q = doubleval(substr($v, 2)); |
} |
if ($userchoice) |
$q *= 0.9; |
$langs[$lang] = $q; |
} |
foreach ($sublangs as $l) |
if (!isset($langs[$l])) |
$langs[$l] = 0.1; |
if ($userchoice) |
$langs[$userchoice] = 1.0; |
arsort($langs); |
foreach ($langs as $code => $q) { |
if (isset($languages[$code])) { |
return $code; |
} |
} |
return $default; |
} |
// }}} |
// {{{ removeDirectory |
function removeDirectory($dir) |
{ |
if (!is_dir($dir)) |
{ |
return false; |
} |
$dir = rtrim($dir, '/'); |
$handle = dir($dir); |
while (($file = $handle->read()) !== false) |
{ |
if (($file == '.') || ($file == '..')) |
{ |
continue; |
} |
$f = $dir.DIRECTORY_SEPARATOR.$file; |
if (!is_link($f) && is_dir($f)) |
{ |
removeDirectory($f); |
} |
else |
{ |
@unlink($f); |
} |
} |
$handle->close(); |
@rmdir($dir); |
return true; |
} |
// }}} |
// {{{ tempnameWithCheck |
function tempnamWithCheck($dir, $prefix, $rmOnShutdown = true) { |
$tmp = tempnam($dir, $prefix); |
if ($tmp && !$rmOnShutdown) |
{ |
return $tmp; |
} |
if ($tmp && $rmOnShutdown) |
{ |
register_shutdown_function('removeDirectory', $tmp); |
return $tmp; |
} |
if (!$tmp && !headers_sent()) |
{ |
http_response_code(500); |
error_log('Unable to create a temporary file. Either make the currently used directory ("' . $dir . '") writable for WebSVN or change the directory in the configuration.'); |
print 'Unable to create a temporary file. Either make the currently used directory writable for WebSVN or change the directory in the configuration.'; |
exit(0); |
} |
global $vars; |
$vars['warning'] = 'Unable to create a temporary file. Either make the currently used directory writable for WebSVN or change the directory in the configuration.'; |
return $tmp; |
} |
// }}} |
/WebSVN/include/version.php |
---|
0,0 → 1,25 |
<?php |
// WebSVN - Subversion repository viewing via the web using PHP |
// Copyright (C) 2004-2006 Tim Armes |
// |
// This program is free software; you can redistribute it and/or modify |
// it under the terms of the GNU General Public License as published by |
// the Free Software Foundation; either version 2 of the License, or |
// (at your option) any later version. |
// |
// This program is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License |
// along with this program; if not, write to the Free Software |
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
// |
// -- |
// |
// version.php |
// |
// Version information |
$version = '2.8.3'; |
/WebSVN/index.php |
---|
1,8 → 1,6 |
<?php |
# vim:et:ts=3:sts=3:sw=3:fdm=marker: |
// WebSVN - Subversion repository viewing via the web using PHP |
// Copyright © 2004-2006 Tim Armes, Matt Sicker |
// Copyright (C) 2004-2006 Tim Armes |
// |
// This program is free software; you can redistribute it and/or modify |
// it under the terms of the GNU General Public License as published by |
11,102 → 9,111 |
// |
// This program is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License |
// along with this program; if not, write to the Free Software |
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
// |
// -- |
// |
// index.php |
// |
// Main page. Lists all the projects |
// Main page which lists all configured repositories (optionally by groups). |
require_once("include/setup.inc"); |
require_once("include/svnlook.inc"); |
require_once("include/template.inc"); |
require_once 'include/setup.php'; |
require_once 'include/svnlook.php'; |
require_once 'include/template.php'; |
$vars["action"] = $lang["PROJECTS"]; |
$vars["repname"] = ""; |
$vars["rev"] = 0; |
$vars["path"] = ""; |
$vars['action'] = $lang['PROJECTS']; |
$vars['repname'] = ''; |
$vars['rev'] = 0; |
$vars['path'] = ''; |
$vars['safepath'] = escape(''); |
$vars['showlastmod'] = $config->showLastModInIndex(); |
// Sort the repositories by group |
$config->sortByGroup(); |
$projects = $config->getRepositories(); |
if ($config->flatIndex) |
{ |
// Create the flat view |
$projects = $config->getRepositories(); |
$i = 0; |
$listing = array (); |
foreach ($projects as $project) |
{ |
if ($project->hasReadAccess("/", true)) |
{ |
$url = $config->getURL($project, "/", "dir"); |
$listing[$i]["rowparity"] = $i % 2; |
$listing[$i++]["projlink"] = "<a href=\"${url}sc=0\">".$project->getDisplayName()."</a>"; |
} |
} |
$vars["flatview"] = true; |
$vars["treeview"] = false; |
if (count($projects) == 1 && $projects[0]->hasReadAccess('/')) { |
header('Location: '.str_replace('&', '', $config->getURL($projects[0], '', 'dir'))); |
exit; |
} |
else |
{ |
// Create the tree view |
$projects = $config->getRepositories(); |
reset($projects); |
$i = 0; |
$listing = array (); |
$curgroup = NULL; |
$parity = 0; |
foreach ($projects as $project) |
{ |
if ($project->hasReadAccess("/", true)) |
{ |
$listing[$i]["rowparity"] = $parity % 2; |
$url = $config->getURL($project, "/", "dir"); |
if ($curgroup != $project->group) |
{ |
# TODO: this should be de-soupified |
if (!empty($curgroup)) |
$listing[$i]["listitem"] = "</div>\n"; // Close the switchcontent div |
else |
$listing[$i]["listitem"] = ""; |
$listing[$i]["isprojlink"] = false; |
$listing[$i]["isgrouphead"] = true; |
$curgroup = $project->group; |
$listing[$i++]["listitem"] .= "<div class=\"groupname\" onclick=\"expandcontent(this, '$curgroup');\" style=\"cursor:hand; cursor:pointer\"><div class=\"a\"><span class=\"showstate\"></span>$curgroup</div></div>\n<div id=\"$curgroup\" class=\"switchcontent\">"; |
} |
$i = 0; |
$parity = 0; // Alternates between every entry, whether it is a group or project |
$groupparity = 0; // The first project (and first of any group) resets this to 0 |
$curgroup = null; |
$groupcount = 0; |
$parity++; |
$listing[$i]["isgrouphead"] = false; |
$listing[$i]["isprojlink"] = true; |
$listing[$i++]["listitem"] = "<a href=\"${url}sc=0\">".$project->name."</a>\n"; |
} |
} |
// Create listing of all configured projects (includes groups if they are used). |
foreach ($projects as $project) { |
if (!$project->hasReadAccess('/')) |
continue; |
if (!empty($curgroup)) |
$listing[$i]["isprojlink"] = false; |
$listing[$i]["isgrouphead"] = false; |
$listing[$i]["listitem"] = "</div>"; // Close the switchcontent div |
$listvar = &$listing[$i]; |
// If this is the first project in a group, add an entry for the group. |
if ($curgroup != $project->group) { |
$groupcount++; |
$groupparity = 0; |
$listvar['notfirstgroup'] = !empty($curgroup); |
$curgroup = $project->group; |
$listvar['groupname'] = $curgroup; // Applies until next group is set. |
$listvar['groupid'] = strtr(base64_encode('grp'.$curgroup), array('+' => '-', '/' => '_', '=' => '')); |
$vars["flatview"] = false; |
$vars["treeview"] = true; |
$vars["opentree"] = $config->openTree; |
// setting to null because template.php won't unset them |
$listvar['projectlink'] = null; |
$listvar['projectname'] = null; |
$listvar['projecturl'] = null; |
$i++; // Causes the subsequent lines to store data in the next array slot. |
$listvar = &$listing[$i]; |
$listvar['groupid'] = null; |
} |
$listvar['clientrooturl'] = $project->clientRootURL; |
// Populate variables for latest modification to the current repository |
if ($config->showLastModInIndex()) { |
$svnrep = new SVNRepository($project); |
$log = $svnrep->getLog('/', '', '', true, 1); |
if (isset($log->entries[0])) { |
$head = $log->entries[0]; |
$listvar['revision'] = $head->rev; |
$listvar['date'] = $head->date; |
$listvar['age'] = datetimeFormatDuration(time() - strtotime($head->date)); |
$listvar['author'] = $head->author; |
} else { |
$listvar['revision'] = 0; |
$listvar['date'] = ''; |
$listvar['age'] = ''; |
$listvar['author'] = ''; |
} |
} |
// Create project (repository) listing |
$url = str_replace('&', '', $config->getURL($project, '', 'dir')); |
$name = ($config->flatIndex) ? $project->getDisplayName() : $project->name; |
$listvar['projectlink'] = '<a href="'.$url.'">'.escape($name).'</a>'; |
$listvar['projectname'] = escape($name); |
$listvar['projecturl'] = $url; |
$listvar['rowparity'] = $parity % 2; |
$parity++; |
$listvar['groupparity'] = $groupparity % 2; |
$groupparity++; |
$listvar['groupname'] = ($curgroup != null) ? $curgroup : ''; |
$i++; |
} |
$vars["version"] = $version; |
parseTemplate($config->getTemplatePath()."header.tmpl", $vars, $listing); |
parseTemplate($config->getTemplatePath()."index.tmpl", $vars, $listing); |
parseTemplate($config->getTemplatePath()."footer.tmpl", $vars, $listing); |
if (empty($listing) && !empty($projects)) { |
$vars['error'] = $lang['NOACCESS']; |
sendHeaderForbidden(); |
} |
?> |
$vars['flatview'] = $config->flatIndex; |
$vars['treeview'] = !$config->flatIndex; |
$vars['opentree'] = $config->openTree; |
$vars['groupcount'] = $groupcount; // Indicates whether any groups were present. |
renderTemplate('index'); |
/WebSVN/javascript/blame-popup.js |
---|
0,0 → 1,40 |
// Find all tags that match <a class="blame-revision" ...> and add events. |
var a = document.getElementsByTagName('a'); |
for (var i = 0; i < a.length; i++) { |
if (a[i].className == 'blame-revision') { |
addEvent(a[i], 'mouseover', function() { mouseover(this) } ); |
addEvent(a[i], 'mouseout', function() { mouseout(this) } ); |
} |
} |
function addEvent(obj, type, func) { |
if (obj.addEventListener) { |
obj.addEventListener(type, func, false); |
return true; |
} else if (obj.attachEvent) { |
return obj.attachEvent('on'+type, func); |
} else { |
return false; |
} |
} |
function mouseover(a) { |
// Find the revision number within the hyperlink text |
var m = /rev=(\d+)/.exec(a.href); |
var r = m[1]; |
if (rev[r]) { |
var div = document.createElement('div'); |
div.className = 'blame-popup'; |
div.innerHTML = rev[r]; |
a.parentNode.appendChild(div); |
} |
} |
function mouseout(a) { |
var div = a.parentNode.parentNode.getElementsByTagName('div'); |
for (var i = 0; i < div.length; i++) { |
if (div[i].className = 'blame-popup') { |
div[i].parentNode.removeChild(div[i]); |
} |
} |
} |
/WebSVN/javascript/collapsible.js |
---|
0,0 → 1,209 |
var tableRows = document.getElementsByTagName('tr'); |
function toggleGroup(groupName) |
{ |
for (var i = 0; i < tableRows.length; i++) |
{ |
if (tableRows[i].title == groupName) |
{ |
if (tableRows[i].style.display == 'none') |
{ |
tableRows[i].style.display = 'table-row'; |
} |
else |
{ |
tableRows[i].style.display = 'none'; |
} |
} |
} |
} |
function collapseAllGroups() |
{ |
for (var i = 0; i < tableRows.length; i++) |
{ |
if (tableRows[i].title != '') |
{ |
tableRows[i].style.display = 'none'; |
} |
} |
} |
$("table.collapsible thead").find("th").on("click", function() |
{ |
let oldClass = $(this).get(0).className; |
let newClass = (oldClass == 'open') ? 'closed' : 'open'; |
$(this).get(0).className = newClass; |
$(this).closest("table").find("tbody").toggle(); |
}); |
/** |
* Hide all non-root entries currently visible. |
* <p> |
* Depending on the config, the site is able to load ALL files and directories of the current repo |
* recursively to prevent additional requests. The use case is to hide all of the root-dirs and let |
* users simply toggle the next level of interest without additional waiting. This is implemented by |
* using the {@code title}-attribute and the {@code /}-character to represent some path and ONLY the |
* root-dirs themself to show DON'T contain such. All other entries have some, either because they |
* belong to a subdir or file within some parent dir. |
* </p> |
* <p> |
* There's currently no additional config necessary to apply this JS or not, because the rows worked |
* on are only generated in case recursive loading is enabled already! |
* </p> |
*/ |
$('table#listing > tbody > tr[title*="/"]').each(function() |
{ |
// "visibility: collapse" leaves some space at the bottom of the whole list, resulting in not |
// wanted scrollbars being shown by default. |
$(this).hide(); |
}); |
/** |
* Select all direct children for the given parent. |
* <p> |
* The markup doesn't model parent-child relationships currently, but instead all directories, |
* files etc. are maintained as individual rows one after each other. In theory not even the order |
* of those rows needs to be alphabetically or fit the parent-child-order in the repo or else, all |
* can be mixed-up. So this function searches all rows of the given {@code body} for DIRECT children |
* of the given parent row, which can be identified by their paths maintained in the {@code title}- |
* attribute. Such filtering is non-trivial and one can't use CSS-selectors only, because those |
* paths need to fulfill certain conditions. |
* </p> |
* @param[in] body |
* @param[in] rowParent |
* @return Array with direct children of the given parent. |
*/ |
function recursiveLoadDirectChildrenSelect(body, rowParent) |
{ |
// The parent title is used in some reg exp, so properly escape/quote it. Sadly "\Q...\E" does |
// not work and JS doesn't seem to provide anythign else on its own as well. |
// https://stackoverflow.com/a/3561711/2055163 |
let titleParent = rowParent.attr('title') || ''; |
titleParent = titleParent.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'); |
let selector = 'tr[title^="' + titleParent + '/"]'; |
let directChildren = []; |
// Selectors don't support regular expressions, but direct children not only start with the |
// parent, but don't contain additional children in their title as well. One can't select |
// that condition easily, so find ALL children and filter later to direct ones only. |
body.children(selector).each(function() |
{ |
let rowChild = $(this); |
let titleChild = rowChild.attr('title') || ''; |
let ptChildDirs = titleParent + '/$'; |
let ptChildFiles = titleParent + '/[^/]+$'; |
let pattern = ptChildDirs + '|' + ptChildFiles; |
if (titleChild.match(pattern)) |
{ |
directChildren.push(rowChild); |
} |
}); |
return directChildren; |
} |
/** |
* Click-handler for some parent directory. |
* <p> |
* What needs to happen depends on the visibility of the direct children associated with some parent |
* and therefore given: If children are NOT visible, simply show them and ONLY those, as showing |
* should not be recursive currently. If children are visible OTOH, ALL of those need to be hidden |
* or otherwise some lower level children would still be shown. This is because of the currently |
* used markup, which doesn't model parent-child-relationships properly, but places everything at |
* one level. Someone needs to take care of hiding children of children of children, when hiding |
* associated markup itself only hides some of those. To hide recursively, a custom event named |
* {@code hide_children} seems the easiest approach currently, which is then simply handled by the |
* parent directory again. |
* </p> |
* @param[in] directChildren |
* @return {@code false} to stop propagation of the current event. |
*/ |
function recursiveLoadRowParentOnClick(directChildren) |
{ |
$.each(directChildren, function() |
{ |
let self = $(this); |
let isVisible = self.is(':visible'); |
if (!isVisible) |
{ |
self.show(); |
return true; |
} |
self.trigger('hide_children'); |
self.hide(); |
}); |
return false; |
} |
/** |
* Handler to hide direct children. |
* <p> |
* While showing only the next level of children is wanted, when hiding ALL levels need to be hidden |
* instead. This can not easily be achieved with the current markup placing ALL directories, files |
* etc. regardless of their depth on the same level. So a special event is registered on each dir |
* to simply hide ALL of it's own children and that event is triggered on ALL children of some dir |
* as necessary. |
* </p> |
* @param[in] directChildren |
* @return {@code false} to stop propagation of the current event. |
*/ |
function recursiveLoadRowParentOnHideChildren(directChildren) |
{ |
$.each(directChildren, function() |
{ |
let self = $(this); |
self.trigger('hide_children'); |
self.hide(); |
}); |
return false; |
} |
/** |
* Process one row when loading all directories and files of some repo recursively. |
* <p> |
* Markup currently doesn't proiperly model parent-child-relationships, so the current approach is |
* to iterated all rows of some rendered table to find direct children on our own. Those children |
* are the once to show or hide in the end any by iterating all rows and search the whole body for |
* children, all of those can be found easily to register necessary event handlers. |
* </p> |
* @param[in] body |
* @param[in] rowParent |
*/ |
function recursiveLoadRowProc(body, rowParent) |
{ |
let directChildren = recursiveLoadDirectChildrenSelect(body, rowParent); |
rowParent.find('td.path a[href^="listing.php?"]').on('click', function() |
{ |
return recursiveLoadRowParentOnClick(directChildren); |
}); |
rowParent.on('hide_children', function() |
{ |
return recursiveLoadRowParentOnHideChildren(directChildren); |
}); |
} |
/** |
* Register event handlers to hide and show children of root-directories. |
*/ |
$('table#listing > tbody').each(function() |
{ |
let body = $(this); |
// Each row needs to be checked for its direct children, so that only those can be toggled. The |
// "tbody" is necessary so that one can find direct children per row as well, because all those |
// are maintained on the same level and only distinguished by their textual path. So we either |
// need to search the "tbody" per row for all children or implement some other approach mapping |
// things by only iterating rows once. The current approach seems easier for now. |
body.children('tr').each(function() { recursiveLoadRowProc(body, $(this)); }); |
}); |
/WebSVN/javascript/compare-checkboxes.js |
---|
0,0 → 1,18 |
// Enforce only two compare boxes being checked at once. |
function enforceOnlyTwoChecked(clickedCheckbox) { |
count = 0; |
first = null; |
form = clickedCheckbox.form; |
for (i = 0; i < form.elements.length; i++) { |
if (form.elements[i].type == 'checkbox' && form.elements[i].checked) { |
if (first == null && form.elements[i] != clickedCheckbox) { |
first = form.elements[i]; |
} |
count += 1; |
} |
} |
if (count > 2) { |
first.checked = false; |
count -= 1; |
} |
} |
/WebSVN/javascript/ie-png-transparency.js |
---|
0,0 → 1,39 |
// correctly handle PNG transparency in Win IE 5.5 or higher. |
function correctPNG() |
{ |
for(var i = 0; i < document.images.length; i++) |
{ |
var img = document.images[i] |
var imgName = img.src.toUpperCase() |
if (imgName.substring(imgName.length-3, imgName.length) == "PNG") |
{ |
var imgID = (img.id) ? "id='" + img.id + "' " : "" |
var imgClass = (img.className) ? "class='" + img.className + "' " : "" |
var imgTitle = (img.title) ? "title='" + img.title + "' " : "title='" + img.alt + "' " |
var imgStyle = "display:inline-block;" + img.style.cssText |
var imgAttribs = img.attributes; |
for (var j=0; j<imgAttribs.length; j++) |
{ |
var imgAttrib = imgAttribs[j]; |
if (imgAttrib.nodeName == "align") |
{ |
if (imgAttrib.nodeValue == "left") imgStyle = "float:left;" + imgStyle |
if (imgAttrib.nodeValue == "right") imgStyle = "float:right;" + imgStyle |
break |
} |
} |
var strNewHTML = "<span " + imgID + imgClass + imgTitle |
strNewHTML += " style=\"" + "width:" + img.width + "px; height:" + img.height + "px;" + imgStyle + ";" |
strNewHTML += "filter:progid:DXImageTransform.Microsoft.AlphaImageLoader" |
strNewHTML += "(src=\'" + img.src + "\', sizingMethod='scale');\"></span>" |
img.outerHTML = strNewHTML |
i = i-1 |
} |
} |
} |
var supported = /MSIE (5\.5)|[6789]/.test(navigator.userAgent) && navigator.platform == "Win32"; |
if (supported) |
window.attachEvent("onload", correctPNG); |
/WebSVN/javascript/jquery.min.1.9.1.js |
---|
0,0 → 1,5 |
/*! jQuery v1.9.1 | (c) 2005, 2012 jQuery Foundation, Inc. | jquery.org/license |
//@ sourceMappingURL=jquery.min.map |
*/(function(e,t){var n,r,i=typeof t,o=e.document,a=e.location,s=e.jQuery,u=e.$,l={},c=[],p="1.9.1",f=c.concat,d=c.push,h=c.slice,g=c.indexOf,m=l.toString,y=l.hasOwnProperty,v=p.trim,b=function(e,t){return new b.fn.init(e,t,r)},x=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,w=/\S+/g,T=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,N=/^(?:(<[\w\W]+>)[^>]*|#([\w-]*))$/,C=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,k=/^[\],:{}\s]*$/,E=/(?:^|:|,)(?:\s*\[)+/g,S=/\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,A=/"[^"\\\r\n]*"|true|false|null|-?(?:\d+\.|)\d+(?:[eE][+-]?\d+|)/g,j=/^-ms-/,D=/-([\da-z])/gi,L=function(e,t){return t.toUpperCase()},H=function(e){(o.addEventListener||"load"===e.type||"complete"===o.readyState)&&(q(),b.ready())},q=function(){o.addEventListener?(o.removeEventListener("DOMContentLoaded",H,!1),e.removeEventListener("load",H,!1)):(o.detachEvent("onreadystatechange",H),e.detachEvent("onload",H))};b.fn=b.prototype={jquery:p,constructor:b,init:function(e,n,r){var i,a;if(!e)return this;if("string"==typeof e){if(i="<"===e.charAt(0)&&">"===e.charAt(e.length-1)&&e.length>=3?[null,e,null]:N.exec(e),!i||!i[1]&&n)return!n||n.jquery?(n||r).find(e):this.constructor(n).find(e);if(i[1]){if(n=n instanceof b?n[0]:n,b.merge(this,b.parseHTML(i[1],n&&n.nodeType?n.ownerDocument||n:o,!0)),C.test(i[1])&&b.isPlainObject(n))for(i in n)b.isFunction(this[i])?this[i](n[i]):this.attr(i,n[i]);return this}if(a=o.getElementById(i[2]),a&&a.parentNode){if(a.id!==i[2])return r.find(e);this.length=1,this[0]=a}return this.context=o,this.selector=e,this}return e.nodeType?(this.context=this[0]=e,this.length=1,this):b.isFunction(e)?r.ready(e):(e.selector!==t&&(this.selector=e.selector,this.context=e.context),b.makeArray(e,this))},selector:"",length:0,size:function(){return this.length},toArray:function(){return h.call(this)},get:function(e){return null==e?this.toArray():0>e?this[this.length+e]:this[e]},pushStack:function(e){var t=b.merge(this.constructor(),e);return t.prevObject=this,t.context=this.context,t},each:function(e,t){return b.each(this,e,t)},ready:function(e){return b.ready.promise().done(e),this},slice:function(){return this.pushStack(h.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(0>e?t:0);return this.pushStack(n>=0&&t>n?[this[n]]:[])},map:function(e){return this.pushStack(b.map(this,function(t,n){return e.call(t,n,t)}))},end:function(){return this.prevObject||this.constructor(null)},push:d,sort:[].sort,splice:[].splice},b.fn.init.prototype=b.fn,b.extend=b.fn.extend=function(){var e,n,r,i,o,a,s=arguments[0]||{},u=1,l=arguments.length,c=!1;for("boolean"==typeof s&&(c=s,s=arguments[1]||{},u=2),"object"==typeof s||b.isFunction(s)||(s={}),l===u&&(s=this,--u);l>u;u++)if(null!=(o=arguments[u]))for(i in o)e=s[i],r=o[i],s!==r&&(c&&r&&(b.isPlainObject(r)||(n=b.isArray(r)))?(n?(n=!1,a=e&&b.isArray(e)?e:[]):a=e&&b.isPlainObject(e)?e:{},s[i]=b.extend(c,a,r)):r!==t&&(s[i]=r));return s},b.extend({noConflict:function(t){return e.$===b&&(e.$=u),t&&e.jQuery===b&&(e.jQuery=s),b},isReady:!1,readyWait:1,holdReady:function(e){e?b.readyWait++:b.ready(!0)},ready:function(e){if(e===!0?!--b.readyWait:!b.isReady){if(!o.body)return setTimeout(b.ready);b.isReady=!0,e!==!0&&--b.readyWait>0||(n.resolveWith(o,[b]),b.fn.trigger&&b(o).trigger("ready").off("ready"))}},isFunction:function(e){return"function"===b.type(e)},isArray:Array.isArray||function(e){return"array"===b.type(e)},isWindow:function(e){return null!=e&&e==e.window},isNumeric:function(e){return!isNaN(parseFloat(e))&&isFinite(e)},type:function(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?l[m.call(e)]||"object":typeof e},isPlainObject:function(e){if(!e||"object"!==b.type(e)||e.nodeType||b.isWindow(e))return!1;try{if(e.constructor&&!y.call(e,"constructor")&&!y.call(e.constructor.prototype,"isPrototypeOf"))return!1}catch(n){return!1}var r;for(r in e);return r===t||y.call(e,r)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},error:function(e){throw Error(e)},parseHTML:function(e,t,n){if(!e||"string"!=typeof e)return null;"boolean"==typeof t&&(n=t,t=!1),t=t||o;var r=C.exec(e),i=!n&&[];return r?[t.createElement(r[1])]:(r=b.buildFragment([e],t,i),i&&b(i).remove(),b.merge([],r.childNodes))},parseJSON:function(n){return e.JSON&&e.JSON.parse?e.JSON.parse(n):null===n?n:"string"==typeof n&&(n=b.trim(n),n&&k.test(n.replace(S,"@").replace(A,"]").replace(E,"")))?Function("return "+n)():(b.error("Invalid JSON: "+n),t)},parseXML:function(n){var r,i;if(!n||"string"!=typeof n)return null;try{e.DOMParser?(i=new DOMParser,r=i.parseFromString(n,"text/xml")):(r=new ActiveXObject("Microsoft.XMLDOM"),r.async="false",r.loadXML(n))}catch(o){r=t}return r&&r.documentElement&&!r.getElementsByTagName("parsererror").length||b.error("Invalid XML: "+n),r},noop:function(){},globalEval:function(t){t&&b.trim(t)&&(e.execScript||function(t){e.eval.call(e,t)})(t)},camelCase:function(e){return e.replace(j,"ms-").replace(D,L)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,t,n){var r,i=0,o=e.length,a=M(e);if(n){if(a){for(;o>i;i++)if(r=t.apply(e[i],n),r===!1)break}else for(i in e)if(r=t.apply(e[i],n),r===!1)break}else if(a){for(;o>i;i++)if(r=t.call(e[i],i,e[i]),r===!1)break}else for(i in e)if(r=t.call(e[i],i,e[i]),r===!1)break;return e},trim:v&&!v.call("\ufeff\u00a0")?function(e){return null==e?"":v.call(e)}:function(e){return null==e?"":(e+"").replace(T,"")},makeArray:function(e,t){var n=t||[];return null!=e&&(M(Object(e))?b.merge(n,"string"==typeof e?[e]:e):d.call(n,e)),n},inArray:function(e,t,n){var r;if(t){if(g)return g.call(t,e,n);for(r=t.length,n=n?0>n?Math.max(0,r+n):n:0;r>n;n++)if(n in t&&t[n]===e)return n}return-1},merge:function(e,n){var r=n.length,i=e.length,o=0;if("number"==typeof r)for(;r>o;o++)e[i++]=n[o];else while(n[o]!==t)e[i++]=n[o++];return e.length=i,e},grep:function(e,t,n){var r,i=[],o=0,a=e.length;for(n=!!n;a>o;o++)r=!!t(e[o],o),n!==r&&i.push(e[o]);return i},map:function(e,t,n){var r,i=0,o=e.length,a=M(e),s=[];if(a)for(;o>i;i++)r=t(e[i],i,n),null!=r&&(s[s.length]=r);else for(i in e)r=t(e[i],i,n),null!=r&&(s[s.length]=r);return f.apply([],s)},guid:1,proxy:function(e,n){var r,i,o;return"string"==typeof n&&(o=e[n],n=e,e=o),b.isFunction(e)?(r=h.call(arguments,2),i=function(){return e.apply(n||this,r.concat(h.call(arguments)))},i.guid=e.guid=e.guid||b.guid++,i):t},access:function(e,n,r,i,o,a,s){var u=0,l=e.length,c=null==r;if("object"===b.type(r)){o=!0;for(u in r)b.access(e,n,u,r[u],!0,a,s)}else if(i!==t&&(o=!0,b.isFunction(i)||(s=!0),c&&(s?(n.call(e,i),n=null):(c=n,n=function(e,t,n){return c.call(b(e),n)})),n))for(;l>u;u++)n(e[u],r,s?i:i.call(e[u],u,n(e[u],r)));return o?e:c?n.call(e):l?n(e[0],r):a},now:function(){return(new Date).getTime()}}),b.ready.promise=function(t){if(!n)if(n=b.Deferred(),"complete"===o.readyState)setTimeout(b.ready);else if(o.addEventListener)o.addEventListener("DOMContentLoaded",H,!1),e.addEventListener("load",H,!1);else{o.attachEvent("onreadystatechange",H),e.attachEvent("onload",H);var r=!1;try{r=null==e.frameElement&&o.documentElement}catch(i){}r&&r.doScroll&&function a(){if(!b.isReady){try{r.doScroll("left")}catch(e){return setTimeout(a,50)}q(),b.ready()}}()}return n.promise(t)},b.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(e,t){l["[object "+t+"]"]=t.toLowerCase()});function M(e){var t=e.length,n=b.type(e);return b.isWindow(e)?!1:1===e.nodeType&&t?!0:"array"===n||"function"!==n&&(0===t||"number"==typeof t&&t>0&&t-1 in e)}r=b(o);var _={};function F(e){var t=_[e]={};return b.each(e.match(w)||[],function(e,n){t[n]=!0}),t}b.Callbacks=function(e){e="string"==typeof e?_[e]||F(e):b.extend({},e);var n,r,i,o,a,s,u=[],l=!e.once&&[],c=function(t){for(r=e.memory&&t,i=!0,a=s||0,s=0,o=u.length,n=!0;u&&o>a;a++)if(u[a].apply(t[0],t[1])===!1&&e.stopOnFalse){r=!1;break}n=!1,u&&(l?l.length&&c(l.shift()):r?u=[]:p.disable())},p={add:function(){if(u){var t=u.length;(function i(t){b.each(t,function(t,n){var r=b.type(n);"function"===r?e.unique&&p.has(n)||u.push(n):n&&n.length&&"string"!==r&&i(n)})})(arguments),n?o=u.length:r&&(s=t,c(r))}return this},remove:function(){return u&&b.each(arguments,function(e,t){var r;while((r=b.inArray(t,u,r))>-1)u.splice(r,1),n&&(o>=r&&o--,a>=r&&a--)}),this},has:function(e){return e?b.inArray(e,u)>-1:!(!u||!u.length)},empty:function(){return u=[],this},disable:function(){return u=l=r=t,this},disabled:function(){return!u},lock:function(){return l=t,r||p.disable(),this},locked:function(){return!l},fireWith:function(e,t){return t=t||[],t=[e,t.slice?t.slice():t],!u||i&&!l||(n?l.push(t):c(t)),this},fire:function(){return p.fireWith(this,arguments),this},fired:function(){return!!i}};return p},b.extend({Deferred:function(e){var t=[["resolve","done",b.Callbacks("once memory"),"resolved"],["reject","fail",b.Callbacks("once memory"),"rejected"],["notify","progress",b.Callbacks("memory")]],n="pending",r={state:function(){return n},always:function(){return i.done(arguments).fail(arguments),this},then:function(){var e=arguments;return b.Deferred(function(n){b.each(t,function(t,o){var a=o[0],s=b.isFunction(e[t])&&e[t];i[o[1]](function(){var e=s&&s.apply(this,arguments);e&&b.isFunction(e.promise)?e.promise().done(n.resolve).fail(n.reject).progress(n.notify):n[a+"With"](this===r?n.promise():this,s?[e]:arguments)})}),e=null}).promise()},promise:function(e){return null!=e?b.extend(e,r):r}},i={};return r.pipe=r.then,b.each(t,function(e,o){var a=o[2],s=o[3];r[o[1]]=a.add,s&&a.add(function(){n=s},t[1^e][2].disable,t[2][2].lock),i[o[0]]=function(){return i[o[0]+"With"](this===i?r:this,arguments),this},i[o[0]+"With"]=a.fireWith}),r.promise(i),e&&e.call(i,i),i},when:function(e){var t=0,n=h.call(arguments),r=n.length,i=1!==r||e&&b.isFunction(e.promise)?r:0,o=1===i?e:b.Deferred(),a=function(e,t,n){return function(r){t[e]=this,n[e]=arguments.length>1?h.call(arguments):r,n===s?o.notifyWith(t,n):--i||o.resolveWith(t,n)}},s,u,l;if(r>1)for(s=Array(r),u=Array(r),l=Array(r);r>t;t++)n[t]&&b.isFunction(n[t].promise)?n[t].promise().done(a(t,l,n)).fail(o.reject).progress(a(t,u,s)):--i;return i||o.resolveWith(l,n),o.promise()}}),b.support=function(){var t,n,r,a,s,u,l,c,p,f,d=o.createElement("div");if(d.setAttribute("className","t"),d.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",n=d.getElementsByTagName("*"),r=d.getElementsByTagName("a")[0],!n||!r||!n.length)return{};s=o.createElement("select"),l=s.appendChild(o.createElement("option")),a=d.getElementsByTagName("input")[0],r.style.cssText="top:1px;float:left;opacity:.5",t={getSetAttribute:"t"!==d.className,leadingWhitespace:3===d.firstChild.nodeType,tbody:!d.getElementsByTagName("tbody").length,htmlSerialize:!!d.getElementsByTagName("link").length,style:/top/.test(r.getAttribute("style")),hrefNormalized:"/a"===r.getAttribute("href"),opacity:/^0.5/.test(r.style.opacity),cssFloat:!!r.style.cssFloat,checkOn:!!a.value,optSelected:l.selected,enctype:!!o.createElement("form").enctype,html5Clone:"<:nav></:nav>"!==o.createElement("nav").cloneNode(!0).outerHTML,boxModel:"CSS1Compat"===o.compatMode,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0,boxSizingReliable:!0,pixelPosition:!1},a.checked=!0,t.noCloneChecked=a.cloneNode(!0).checked,s.disabled=!0,t.optDisabled=!l.disabled;try{delete d.test}catch(h){t.deleteExpando=!1}a=o.createElement("input"),a.setAttribute("value",""),t.input=""===a.getAttribute("value"),a.value="t",a.setAttribute("type","radio"),t.radioValue="t"===a.value,a.setAttribute("checked","t"),a.setAttribute("name","t"),u=o.createDocumentFragment(),u.appendChild(a),t.appendChecked=a.checked,t.checkClone=u.cloneNode(!0).cloneNode(!0).lastChild.checked,d.attachEvent&&(d.attachEvent("onclick",function(){t.noCloneEvent=!1}),d.cloneNode(!0).click());for(f in{submit:!0,change:!0,focusin:!0})d.setAttribute(c="on"+f,"t"),t[f+"Bubbles"]=c in e||d.attributes[c].expando===!1;return d.style.backgroundClip="content-box",d.cloneNode(!0).style.backgroundClip="",t.clearCloneStyle="content-box"===d.style.backgroundClip,b(function(){var n,r,a,s="padding:0;margin:0;border:0;display:block;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;",u=o.getElementsByTagName("body")[0];u&&(n=o.createElement("div"),n.style.cssText="border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px",u.appendChild(n).appendChild(d),d.innerHTML="<table><tr><td></td><td>t</td></tr></table>",a=d.getElementsByTagName("td"),a[0].style.cssText="padding:0;margin:0;border:0;display:none",p=0===a[0].offsetHeight,a[0].style.display="",a[1].style.display="none",t.reliableHiddenOffsets=p&&0===a[0].offsetHeight,d.innerHTML="",d.style.cssText="box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;",t.boxSizing=4===d.offsetWidth,t.doesNotIncludeMarginInBodyOffset=1!==u.offsetTop,e.getComputedStyle&&(t.pixelPosition="1%"!==(e.getComputedStyle(d,null)||{}).top,t.boxSizingReliable="4px"===(e.getComputedStyle(d,null)||{width:"4px"}).width,r=d.appendChild(o.createElement("div")),r.style.cssText=d.style.cssText=s,r.style.marginRight=r.style.width="0",d.style.width="1px",t.reliableMarginRight=!parseFloat((e.getComputedStyle(r,null)||{}).marginRight)),typeof d.style.zoom!==i&&(d.innerHTML="",d.style.cssText=s+"width:1px;padding:1px;display:inline;zoom:1",t.inlineBlockNeedsLayout=3===d.offsetWidth,d.style.display="block",d.innerHTML="<div></div>",d.firstChild.style.width="5px",t.shrinkWrapBlocks=3!==d.offsetWidth,t.inlineBlockNeedsLayout&&(u.style.zoom=1)),u.removeChild(n),n=d=a=r=null)}),n=s=u=l=r=a=null,t}();var O=/(?:\{[\s\S]*\}|\[[\s\S]*\])$/,B=/([A-Z])/g;function P(e,n,r,i){if(b.acceptData(e)){var o,a,s=b.expando,u="string"==typeof n,l=e.nodeType,p=l?b.cache:e,f=l?e[s]:e[s]&&s;if(f&&p[f]&&(i||p[f].data)||!u||r!==t)return f||(l?e[s]=f=c.pop()||b.guid++:f=s),p[f]||(p[f]={},l||(p[f].toJSON=b.noop)),("object"==typeof n||"function"==typeof n)&&(i?p[f]=b.extend(p[f],n):p[f].data=b.extend(p[f].data,n)),o=p[f],i||(o.data||(o.data={}),o=o.data),r!==t&&(o[b.camelCase(n)]=r),u?(a=o[n],null==a&&(a=o[b.camelCase(n)])):a=o,a}}function R(e,t,n){if(b.acceptData(e)){var r,i,o,a=e.nodeType,s=a?b.cache:e,u=a?e[b.expando]:b.expando;if(s[u]){if(t&&(o=n?s[u]:s[u].data)){b.isArray(t)?t=t.concat(b.map(t,b.camelCase)):t in o?t=[t]:(t=b.camelCase(t),t=t in o?[t]:t.split(" "));for(r=0,i=t.length;i>r;r++)delete o[t[r]];if(!(n?$:b.isEmptyObject)(o))return}(n||(delete s[u].data,$(s[u])))&&(a?b.cleanData([e],!0):b.support.deleteExpando||s!=s.window?delete s[u]:s[u]=null)}}}b.extend({cache:{},expando:"jQuery"+(p+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(e){return e=e.nodeType?b.cache[e[b.expando]]:e[b.expando],!!e&&!$(e)},data:function(e,t,n){return P(e,t,n)},removeData:function(e,t){return R(e,t)},_data:function(e,t,n){return P(e,t,n,!0)},_removeData:function(e,t){return R(e,t,!0)},acceptData:function(e){if(e.nodeType&&1!==e.nodeType&&9!==e.nodeType)return!1;var t=e.nodeName&&b.noData[e.nodeName.toLowerCase()];return!t||t!==!0&&e.getAttribute("classid")===t}}),b.fn.extend({data:function(e,n){var r,i,o=this[0],a=0,s=null;if(e===t){if(this.length&&(s=b.data(o),1===o.nodeType&&!b._data(o,"parsedAttrs"))){for(r=o.attributes;r.length>a;a++)i=r[a].name,i.indexOf("data-")||(i=b.camelCase(i.slice(5)),W(o,i,s[i]));b._data(o,"parsedAttrs",!0)}return s}return"object"==typeof e?this.each(function(){b.data(this,e)}):b.access(this,function(n){return n===t?o?W(o,e,b.data(o,e)):null:(this.each(function(){b.data(this,e,n)}),t)},null,n,arguments.length>1,null,!0)},removeData:function(e){return this.each(function(){b.removeData(this,e)})}});function W(e,n,r){if(r===t&&1===e.nodeType){var i="data-"+n.replace(B,"-$1").toLowerCase();if(r=e.getAttribute(i),"string"==typeof r){try{r="true"===r?!0:"false"===r?!1:"null"===r?null:+r+""===r?+r:O.test(r)?b.parseJSON(r):r}catch(o){}b.data(e,n,r)}else r=t}return r}function $(e){var t;for(t in e)if(("data"!==t||!b.isEmptyObject(e[t]))&&"toJSON"!==t)return!1;return!0}b.extend({queue:function(e,n,r){var i;return e?(n=(n||"fx")+"queue",i=b._data(e,n),r&&(!i||b.isArray(r)?i=b._data(e,n,b.makeArray(r)):i.push(r)),i||[]):t},dequeue:function(e,t){t=t||"fx";var n=b.queue(e,t),r=n.length,i=n.shift(),o=b._queueHooks(e,t),a=function(){b.dequeue(e,t)};"inprogress"===i&&(i=n.shift(),r--),o.cur=i,i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,a,o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return b._data(e,n)||b._data(e,n,{empty:b.Callbacks("once memory").add(function(){b._removeData(e,t+"queue"),b._removeData(e,n)})})}}),b.fn.extend({queue:function(e,n){var r=2;return"string"!=typeof e&&(n=e,e="fx",r--),r>arguments.length?b.queue(this[0],e):n===t?this:this.each(function(){var t=b.queue(this,e,n);b._queueHooks(this,e),"fx"===e&&"inprogress"!==t[0]&&b.dequeue(this,e)})},dequeue:function(e){return this.each(function(){b.dequeue(this,e)})},delay:function(e,t){return e=b.fx?b.fx.speeds[e]||e:e,t=t||"fx",this.queue(t,function(t,n){var r=setTimeout(t,e);n.stop=function(){clearTimeout(r)}})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,n){var r,i=1,o=b.Deferred(),a=this,s=this.length,u=function(){--i||o.resolveWith(a,[a])};"string"!=typeof e&&(n=e,e=t),e=e||"fx";while(s--)r=b._data(a[s],e+"queueHooks"),r&&r.empty&&(i++,r.empty.add(u));return u(),o.promise(n)}});var I,z,X=/[\t\r\n]/g,U=/\r/g,V=/^(?:input|select|textarea|button|object)$/i,Y=/^(?:a|area)$/i,J=/^(?:checked|selected|autofocus|autoplay|async|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped)$/i,G=/^(?:checked|selected)$/i,Q=b.support.getSetAttribute,K=b.support.input;b.fn.extend({attr:function(e,t){return b.access(this,b.attr,e,t,arguments.length>1)},removeAttr:function(e){return this.each(function(){b.removeAttr(this,e)})},prop:function(e,t){return b.access(this,b.prop,e,t,arguments.length>1)},removeProp:function(e){return e=b.propFix[e]||e,this.each(function(){try{this[e]=t,delete this[e]}catch(n){}})},addClass:function(e){var t,n,r,i,o,a=0,s=this.length,u="string"==typeof e&&e;if(b.isFunction(e))return this.each(function(t){b(this).addClass(e.call(this,t,this.className))});if(u)for(t=(e||"").match(w)||[];s>a;a++)if(n=this[a],r=1===n.nodeType&&(n.className?(" "+n.className+" ").replace(X," "):" ")){o=0;while(i=t[o++])0>r.indexOf(" "+i+" ")&&(r+=i+" ");n.className=b.trim(r)}return this},removeClass:function(e){var t,n,r,i,o,a=0,s=this.length,u=0===arguments.length||"string"==typeof e&&e;if(b.isFunction(e))return this.each(function(t){b(this).removeClass(e.call(this,t,this.className))});if(u)for(t=(e||"").match(w)||[];s>a;a++)if(n=this[a],r=1===n.nodeType&&(n.className?(" "+n.className+" ").replace(X," "):"")){o=0;while(i=t[o++])while(r.indexOf(" "+i+" ")>=0)r=r.replace(" "+i+" "," ");n.className=e?b.trim(r):""}return this},toggleClass:function(e,t){var n=typeof e,r="boolean"==typeof t;return b.isFunction(e)?this.each(function(n){b(this).toggleClass(e.call(this,n,this.className,t),t)}):this.each(function(){if("string"===n){var o,a=0,s=b(this),u=t,l=e.match(w)||[];while(o=l[a++])u=r?u:!s.hasClass(o),s[u?"addClass":"removeClass"](o)}else(n===i||"boolean"===n)&&(this.className&&b._data(this,"__className__",this.className),this.className=this.className||e===!1?"":b._data(this,"__className__")||"")})},hasClass:function(e){var t=" "+e+" ",n=0,r=this.length;for(;r>n;n++)if(1===this[n].nodeType&&(" "+this[n].className+" ").replace(X," ").indexOf(t)>=0)return!0;return!1},val:function(e){var n,r,i,o=this[0];{if(arguments.length)return i=b.isFunction(e),this.each(function(n){var o,a=b(this);1===this.nodeType&&(o=i?e.call(this,n,a.val()):e,null==o?o="":"number"==typeof o?o+="":b.isArray(o)&&(o=b.map(o,function(e){return null==e?"":e+""})),r=b.valHooks[this.type]||b.valHooks[this.nodeName.toLowerCase()],r&&"set"in r&&r.set(this,o,"value")!==t||(this.value=o))});if(o)return r=b.valHooks[o.type]||b.valHooks[o.nodeName.toLowerCase()],r&&"get"in r&&(n=r.get(o,"value"))!==t?n:(n=o.value,"string"==typeof n?n.replace(U,""):null==n?"":n)}}}),b.extend({valHooks:{option:{get:function(e){var t=e.attributes.value;return!t||t.specified?e.value:e.text}},select:{get:function(e){var t,n,r=e.options,i=e.selectedIndex,o="select-one"===e.type||0>i,a=o?null:[],s=o?i+1:r.length,u=0>i?s:o?i:0;for(;s>u;u++)if(n=r[u],!(!n.selected&&u!==i||(b.support.optDisabled?n.disabled:null!==n.getAttribute("disabled"))||n.parentNode.disabled&&b.nodeName(n.parentNode,"optgroup"))){if(t=b(n).val(),o)return t;a.push(t)}return a},set:function(e,t){var n=b.makeArray(t);return b(e).find("option").each(function(){this.selected=b.inArray(b(this).val(),n)>=0}),n.length||(e.selectedIndex=-1),n}}},attr:function(e,n,r){var o,a,s,u=e.nodeType;if(e&&3!==u&&8!==u&&2!==u)return typeof e.getAttribute===i?b.prop(e,n,r):(a=1!==u||!b.isXMLDoc(e),a&&(n=n.toLowerCase(),o=b.attrHooks[n]||(J.test(n)?z:I)),r===t?o&&a&&"get"in o&&null!==(s=o.get(e,n))?s:(typeof e.getAttribute!==i&&(s=e.getAttribute(n)),null==s?t:s):null!==r?o&&a&&"set"in o&&(s=o.set(e,r,n))!==t?s:(e.setAttribute(n,r+""),r):(b.removeAttr(e,n),t))},removeAttr:function(e,t){var n,r,i=0,o=t&&t.match(w);if(o&&1===e.nodeType)while(n=o[i++])r=b.propFix[n]||n,J.test(n)?!Q&&G.test(n)?e[b.camelCase("default-"+n)]=e[r]=!1:e[r]=!1:b.attr(e,n,""),e.removeAttribute(Q?n:r)},attrHooks:{type:{set:function(e,t){if(!b.support.radioValue&&"radio"===t&&b.nodeName(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(e,n,r){var i,o,a,s=e.nodeType;if(e&&3!==s&&8!==s&&2!==s)return a=1!==s||!b.isXMLDoc(e),a&&(n=b.propFix[n]||n,o=b.propHooks[n]),r!==t?o&&"set"in o&&(i=o.set(e,r,n))!==t?i:e[n]=r:o&&"get"in o&&null!==(i=o.get(e,n))?i:e[n]},propHooks:{tabIndex:{get:function(e){var n=e.getAttributeNode("tabindex");return n&&n.specified?parseInt(n.value,10):V.test(e.nodeName)||Y.test(e.nodeName)&&e.href?0:t}}}}),z={get:function(e,n){var r=b.prop(e,n),i="boolean"==typeof r&&e.getAttribute(n),o="boolean"==typeof r?K&&Q?null!=i:G.test(n)?e[b.camelCase("default-"+n)]:!!i:e.getAttributeNode(n);return o&&o.value!==!1?n.toLowerCase():t},set:function(e,t,n){return t===!1?b.removeAttr(e,n):K&&Q||!G.test(n)?e.setAttribute(!Q&&b.propFix[n]||n,n):e[b.camelCase("default-"+n)]=e[n]=!0,n}},K&&Q||(b.attrHooks.value={get:function(e,n){var r=e.getAttributeNode(n);return b.nodeName(e,"input")?e.defaultValue:r&&r.specified?r.value:t},set:function(e,n,r){return b.nodeName(e,"input")?(e.defaultValue=n,t):I&&I.set(e,n,r)}}),Q||(I=b.valHooks.button={get:function(e,n){var r=e.getAttributeNode(n);return r&&("id"===n||"name"===n||"coords"===n?""!==r.value:r.specified)?r.value:t},set:function(e,n,r){var i=e.getAttributeNode(r);return i||e.setAttributeNode(i=e.ownerDocument.createAttribute(r)),i.value=n+="","value"===r||n===e.getAttribute(r)?n:t}},b.attrHooks.contenteditable={get:I.get,set:function(e,t,n){I.set(e,""===t?!1:t,n)}},b.each(["width","height"],function(e,n){b.attrHooks[n]=b.extend(b.attrHooks[n],{set:function(e,r){return""===r?(e.setAttribute(n,"auto"),r):t}})})),b.support.hrefNormalized||(b.each(["href","src","width","height"],function(e,n){b.attrHooks[n]=b.extend(b.attrHooks[n],{get:function(e){var r=e.getAttribute(n,2);return null==r?t:r}})}),b.each(["href","src"],function(e,t){b.propHooks[t]={get:function(e){return e.getAttribute(t,4)}}})),b.support.style||(b.attrHooks.style={get:function(e){return e.style.cssText||t},set:function(e,t){return e.style.cssText=t+""}}),b.support.optSelected||(b.propHooks.selected=b.extend(b.propHooks.selected,{get:function(e){var t=e.parentNode;return t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex),null}})),b.support.enctype||(b.propFix.enctype="encoding"),b.support.checkOn||b.each(["radio","checkbox"],function(){b.valHooks[this]={get:function(e){return null===e.getAttribute("value")?"on":e.value}}}),b.each(["radio","checkbox"],function(){b.valHooks[this]=b.extend(b.valHooks[this],{set:function(e,n){return b.isArray(n)?e.checked=b.inArray(b(e).val(),n)>=0:t}})});var Z=/^(?:input|select|textarea)$/i,et=/^key/,tt=/^(?:mouse|contextmenu)|click/,nt=/^(?:focusinfocus|focusoutblur)$/,rt=/^([^.]*)(?:\.(.+)|)$/;function it(){return!0}function ot(){return!1}b.event={global:{},add:function(e,n,r,o,a){var s,u,l,c,p,f,d,h,g,m,y,v=b._data(e);if(v){r.handler&&(c=r,r=c.handler,a=c.selector),r.guid||(r.guid=b.guid++),(u=v.events)||(u=v.events={}),(f=v.handle)||(f=v.handle=function(e){return typeof b===i||e&&b.event.triggered===e.type?t:b.event.dispatch.apply(f.elem,arguments)},f.elem=e),n=(n||"").match(w)||[""],l=n.length;while(l--)s=rt.exec(n[l])||[],g=y=s[1],m=(s[2]||"").split(".").sort(),p=b.event.special[g]||{},g=(a?p.delegateType:p.bindType)||g,p=b.event.special[g]||{},d=b.extend({type:g,origType:y,data:o,handler:r,guid:r.guid,selector:a,needsContext:a&&b.expr.match.needsContext.test(a),namespace:m.join(".")},c),(h=u[g])||(h=u[g]=[],h.delegateCount=0,p.setup&&p.setup.call(e,o,m,f)!==!1||(e.addEventListener?e.addEventListener(g,f,!1):e.attachEvent&&e.attachEvent("on"+g,f))),p.add&&(p.add.call(e,d),d.handler.guid||(d.handler.guid=r.guid)),a?h.splice(h.delegateCount++,0,d):h.push(d),b.event.global[g]=!0;e=null}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,p,f,d,h,g,m=b.hasData(e)&&b._data(e);if(m&&(c=m.events)){t=(t||"").match(w)||[""],l=t.length;while(l--)if(s=rt.exec(t[l])||[],d=g=s[1],h=(s[2]||"").split(".").sort(),d){p=b.event.special[d]||{},d=(r?p.delegateType:p.bindType)||d,f=c[d]||[],s=s[2]&&RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),u=o=f.length;while(o--)a=f[o],!i&&g!==a.origType||n&&n.guid!==a.guid||s&&!s.test(a.namespace)||r&&r!==a.selector&&("**"!==r||!a.selector)||(f.splice(o,1),a.selector&&f.delegateCount--,p.remove&&p.remove.call(e,a));u&&!f.length&&(p.teardown&&p.teardown.call(e,h,m.handle)!==!1||b.removeEvent(e,d,m.handle),delete c[d])}else for(d in c)b.event.remove(e,d+t[l],n,r,!0);b.isEmptyObject(c)&&(delete m.handle,b._removeData(e,"events"))}},trigger:function(n,r,i,a){var s,u,l,c,p,f,d,h=[i||o],g=y.call(n,"type")?n.type:n,m=y.call(n,"namespace")?n.namespace.split("."):[];if(l=f=i=i||o,3!==i.nodeType&&8!==i.nodeType&&!nt.test(g+b.event.triggered)&&(g.indexOf(".")>=0&&(m=g.split("."),g=m.shift(),m.sort()),u=0>g.indexOf(":")&&"on"+g,n=n[b.expando]?n:new b.Event(g,"object"==typeof n&&n),n.isTrigger=!0,n.namespace=m.join("."),n.namespace_re=n.namespace?RegExp("(^|\\.)"+m.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,n.result=t,n.target||(n.target=i),r=null==r?[n]:b.makeArray(r,[n]),p=b.event.special[g]||{},a||!p.trigger||p.trigger.apply(i,r)!==!1)){if(!a&&!p.noBubble&&!b.isWindow(i)){for(c=p.delegateType||g,nt.test(c+g)||(l=l.parentNode);l;l=l.parentNode)h.push(l),f=l;f===(i.ownerDocument||o)&&h.push(f.defaultView||f.parentWindow||e)}d=0;while((l=h[d++])&&!n.isPropagationStopped())n.type=d>1?c:p.bindType||g,s=(b._data(l,"events")||{})[n.type]&&b._data(l,"handle"),s&&s.apply(l,r),s=u&&l[u],s&&b.acceptData(l)&&s.apply&&s.apply(l,r)===!1&&n.preventDefault();if(n.type=g,!(a||n.isDefaultPrevented()||p._default&&p._default.apply(i.ownerDocument,r)!==!1||"click"===g&&b.nodeName(i,"a")||!b.acceptData(i)||!u||!i[g]||b.isWindow(i))){f=i[u],f&&(i[u]=null),b.event.triggered=g;try{i[g]()}catch(v){}b.event.triggered=t,f&&(i[u]=f)}return n.result}},dispatch:function(e){e=b.event.fix(e);var n,r,i,o,a,s=[],u=h.call(arguments),l=(b._data(this,"events")||{})[e.type]||[],c=b.event.special[e.type]||{};if(u[0]=e,e.delegateTarget=this,!c.preDispatch||c.preDispatch.call(this,e)!==!1){s=b.event.handlers.call(this,e,l),n=0;while((o=s[n++])&&!e.isPropagationStopped()){e.currentTarget=o.elem,a=0;while((i=o.handlers[a++])&&!e.isImmediatePropagationStopped())(!e.namespace_re||e.namespace_re.test(i.namespace))&&(e.handleObj=i,e.data=i.data,r=((b.event.special[i.origType]||{}).handle||i.handler).apply(o.elem,u),r!==t&&(e.result=r)===!1&&(e.preventDefault(),e.stopPropagation()))}return c.postDispatch&&c.postDispatch.call(this,e),e.result}},handlers:function(e,n){var r,i,o,a,s=[],u=n.delegateCount,l=e.target;if(u&&l.nodeType&&(!e.button||"click"!==e.type))for(;l!=this;l=l.parentNode||this)if(1===l.nodeType&&(l.disabled!==!0||"click"!==e.type)){for(o=[],a=0;u>a;a++)i=n[a],r=i.selector+" ",o[r]===t&&(o[r]=i.needsContext?b(r,this).index(l)>=0:b.find(r,this,null,[l]).length),o[r]&&o.push(i);o.length&&s.push({elem:l,handlers:o})}return n.length>u&&s.push({elem:this,handlers:n.slice(u)}),s},fix:function(e){if(e[b.expando])return e;var t,n,r,i=e.type,a=e,s=this.fixHooks[i];s||(this.fixHooks[i]=s=tt.test(i)?this.mouseHooks:et.test(i)?this.keyHooks:{}),r=s.props?this.props.concat(s.props):this.props,e=new b.Event(a),t=r.length;while(t--)n=r[t],e[n]=a[n];return e.target||(e.target=a.srcElement||o),3===e.target.nodeType&&(e.target=e.target.parentNode),e.metaKey=!!e.metaKey,s.filter?s.filter(e,a):e},props:"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(e,t){return null==e.which&&(e.which=null!=t.charCode?t.charCode:t.keyCode),e}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(e,n){var r,i,a,s=n.button,u=n.fromElement;return null==e.pageX&&null!=n.clientX&&(i=e.target.ownerDocument||o,a=i.documentElement,r=i.body,e.pageX=n.clientX+(a&&a.scrollLeft||r&&r.scrollLeft||0)-(a&&a.clientLeft||r&&r.clientLeft||0),e.pageY=n.clientY+(a&&a.scrollTop||r&&r.scrollTop||0)-(a&&a.clientTop||r&&r.clientTop||0)),!e.relatedTarget&&u&&(e.relatedTarget=u===e.target?n.toElement:u),e.which||s===t||(e.which=1&s?1:2&s?3:4&s?2:0),e}},special:{load:{noBubble:!0},click:{trigger:function(){return b.nodeName(this,"input")&&"checkbox"===this.type&&this.click?(this.click(),!1):t}},focus:{trigger:function(){if(this!==o.activeElement&&this.focus)try{return this.focus(),!1}catch(e){}},delegateType:"focusin"},blur:{trigger:function(){return this===o.activeElement&&this.blur?(this.blur(),!1):t},delegateType:"focusout"},beforeunload:{postDispatch:function(e){e.result!==t&&(e.originalEvent.returnValue=e.result)}}},simulate:function(e,t,n,r){var i=b.extend(new b.Event,n,{type:e,isSimulated:!0,originalEvent:{}});r?b.event.trigger(i,null,t):b.event.dispatch.call(t,i),i.isDefaultPrevented()&&n.preventDefault()}},b.removeEvent=o.removeEventListener?function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n,!1)}:function(e,t,n){var r="on"+t;e.detachEvent&&(typeof e[r]===i&&(e[r]=null),e.detachEvent(r,n))},b.Event=function(e,n){return this instanceof b.Event?(e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||e.returnValue===!1||e.getPreventDefault&&e.getPreventDefault()?it:ot):this.type=e,n&&b.extend(this,n),this.timeStamp=e&&e.timeStamp||b.now(),this[b.expando]=!0,t):new b.Event(e,n)},b.Event.prototype={isDefaultPrevented:ot,isPropagationStopped:ot,isImmediatePropagationStopped:ot,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=it,e&&(e.preventDefault?e.preventDefault():e.returnValue=!1)},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=it,e&&(e.stopPropagation&&e.stopPropagation(),e.cancelBubble=!0)},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=it,this.stopPropagation()}},b.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(e,t){b.event.special[e]={delegateType:t,bindType:t,handle:function(e){var n,r=this,i=e.relatedTarget,o=e.handleObj; |
return(!i||i!==r&&!b.contains(r,i))&&(e.type=o.origType,n=o.handler.apply(this,arguments),e.type=t),n}}}),b.support.submitBubbles||(b.event.special.submit={setup:function(){return b.nodeName(this,"form")?!1:(b.event.add(this,"click._submit keypress._submit",function(e){var n=e.target,r=b.nodeName(n,"input")||b.nodeName(n,"button")?n.form:t;r&&!b._data(r,"submitBubbles")&&(b.event.add(r,"submit._submit",function(e){e._submit_bubble=!0}),b._data(r,"submitBubbles",!0))}),t)},postDispatch:function(e){e._submit_bubble&&(delete e._submit_bubble,this.parentNode&&!e.isTrigger&&b.event.simulate("submit",this.parentNode,e,!0))},teardown:function(){return b.nodeName(this,"form")?!1:(b.event.remove(this,"._submit"),t)}}),b.support.changeBubbles||(b.event.special.change={setup:function(){return Z.test(this.nodeName)?(("checkbox"===this.type||"radio"===this.type)&&(b.event.add(this,"propertychange._change",function(e){"checked"===e.originalEvent.propertyName&&(this._just_changed=!0)}),b.event.add(this,"click._change",function(e){this._just_changed&&!e.isTrigger&&(this._just_changed=!1),b.event.simulate("change",this,e,!0)})),!1):(b.event.add(this,"beforeactivate._change",function(e){var t=e.target;Z.test(t.nodeName)&&!b._data(t,"changeBubbles")&&(b.event.add(t,"change._change",function(e){!this.parentNode||e.isSimulated||e.isTrigger||b.event.simulate("change",this.parentNode,e,!0)}),b._data(t,"changeBubbles",!0))}),t)},handle:function(e){var n=e.target;return this!==n||e.isSimulated||e.isTrigger||"radio"!==n.type&&"checkbox"!==n.type?e.handleObj.handler.apply(this,arguments):t},teardown:function(){return b.event.remove(this,"._change"),!Z.test(this.nodeName)}}),b.support.focusinBubbles||b.each({focus:"focusin",blur:"focusout"},function(e,t){var n=0,r=function(e){b.event.simulate(t,e.target,b.event.fix(e),!0)};b.event.special[t]={setup:function(){0===n++&&o.addEventListener(e,r,!0)},teardown:function(){0===--n&&o.removeEventListener(e,r,!0)}}}),b.fn.extend({on:function(e,n,r,i,o){var a,s;if("object"==typeof e){"string"!=typeof n&&(r=r||n,n=t);for(a in e)this.on(a,n,r,e[a],o);return this}if(null==r&&null==i?(i=n,r=n=t):null==i&&("string"==typeof n?(i=r,r=t):(i=r,r=n,n=t)),i===!1)i=ot;else if(!i)return this;return 1===o&&(s=i,i=function(e){return b().off(e),s.apply(this,arguments)},i.guid=s.guid||(s.guid=b.guid++)),this.each(function(){b.event.add(this,e,i,r,n)})},one:function(e,t,n,r){return this.on(e,t,n,r,1)},off:function(e,n,r){var i,o;if(e&&e.preventDefault&&e.handleObj)return i=e.handleObj,b(e.delegateTarget).off(i.namespace?i.origType+"."+i.namespace:i.origType,i.selector,i.handler),this;if("object"==typeof e){for(o in e)this.off(o,n,e[o]);return this}return(n===!1||"function"==typeof n)&&(r=n,n=t),r===!1&&(r=ot),this.each(function(){b.event.remove(this,e,r,n)})},bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},trigger:function(e,t){return this.each(function(){b.event.trigger(e,t,this)})},triggerHandler:function(e,n){var r=this[0];return r?b.event.trigger(e,n,r,!0):t}}),function(e,t){var n,r,i,o,a,s,u,l,c,p,f,d,h,g,m,y,v,x="sizzle"+-new Date,w=e.document,T={},N=0,C=0,k=it(),E=it(),S=it(),A=typeof t,j=1<<31,D=[],L=D.pop,H=D.push,q=D.slice,M=D.indexOf||function(e){var t=0,n=this.length;for(;n>t;t++)if(this[t]===e)return t;return-1},_="[\\x20\\t\\r\\n\\f]",F="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",O=F.replace("w","w#"),B="([*^$|!~]?=)",P="\\["+_+"*("+F+")"+_+"*(?:"+B+_+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+O+")|)|)"+_+"*\\]",R=":("+F+")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|"+P.replace(3,8)+")*)|.*)\\)|)",W=RegExp("^"+_+"+|((?:^|[^\\\\])(?:\\\\.)*)"+_+"+$","g"),$=RegExp("^"+_+"*,"+_+"*"),I=RegExp("^"+_+"*([\\x20\\t\\r\\n\\f>+~])"+_+"*"),z=RegExp(R),X=RegExp("^"+O+"$"),U={ID:RegExp("^#("+F+")"),CLASS:RegExp("^\\.("+F+")"),NAME:RegExp("^\\[name=['\"]?("+F+")['\"]?\\]"),TAG:RegExp("^("+F.replace("w","w*")+")"),ATTR:RegExp("^"+P),PSEUDO:RegExp("^"+R),CHILD:RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+_+"*(even|odd|(([+-]|)(\\d*)n|)"+_+"*(?:([+-]|)"+_+"*(\\d+)|))"+_+"*\\)|)","i"),needsContext:RegExp("^"+_+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+_+"*((?:-\\d)?\\d*)"+_+"*\\)|)(?=[^-]|$)","i")},V=/[\x20\t\r\n\f]*[+~]/,Y=/^[^{]+\{\s*\[native code/,J=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,G=/^(?:input|select|textarea|button)$/i,Q=/^h\d$/i,K=/'|\\/g,Z=/\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g,et=/\\([\da-fA-F]{1,6}[\x20\t\r\n\f]?|.)/g,tt=function(e,t){var n="0x"+t-65536;return n!==n?t:0>n?String.fromCharCode(n+65536):String.fromCharCode(55296|n>>10,56320|1023&n)};try{q.call(w.documentElement.childNodes,0)[0].nodeType}catch(nt){q=function(e){var t,n=[];while(t=this[e++])n.push(t);return n}}function rt(e){return Y.test(e+"")}function it(){var e,t=[];return e=function(n,r){return t.push(n+=" ")>i.cacheLength&&delete e[t.shift()],e[n]=r}}function ot(e){return e[x]=!0,e}function at(e){var t=p.createElement("div");try{return e(t)}catch(n){return!1}finally{t=null}}function st(e,t,n,r){var i,o,a,s,u,l,f,g,m,v;if((t?t.ownerDocument||t:w)!==p&&c(t),t=t||p,n=n||[],!e||"string"!=typeof e)return n;if(1!==(s=t.nodeType)&&9!==s)return[];if(!d&&!r){if(i=J.exec(e))if(a=i[1]){if(9===s){if(o=t.getElementById(a),!o||!o.parentNode)return n;if(o.id===a)return n.push(o),n}else if(t.ownerDocument&&(o=t.ownerDocument.getElementById(a))&&y(t,o)&&o.id===a)return n.push(o),n}else{if(i[2])return H.apply(n,q.call(t.getElementsByTagName(e),0)),n;if((a=i[3])&&T.getByClassName&&t.getElementsByClassName)return H.apply(n,q.call(t.getElementsByClassName(a),0)),n}if(T.qsa&&!h.test(e)){if(f=!0,g=x,m=t,v=9===s&&e,1===s&&"object"!==t.nodeName.toLowerCase()){l=ft(e),(f=t.getAttribute("id"))?g=f.replace(K,"\\$&"):t.setAttribute("id",g),g="[id='"+g+"'] ",u=l.length;while(u--)l[u]=g+dt(l[u]);m=V.test(e)&&t.parentNode||t,v=l.join(",")}if(v)try{return H.apply(n,q.call(m.querySelectorAll(v),0)),n}catch(b){}finally{f||t.removeAttribute("id")}}}return wt(e.replace(W,"$1"),t,n,r)}a=st.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return t?"HTML"!==t.nodeName:!1},c=st.setDocument=function(e){var n=e?e.ownerDocument||e:w;return n!==p&&9===n.nodeType&&n.documentElement?(p=n,f=n.documentElement,d=a(n),T.tagNameNoComments=at(function(e){return e.appendChild(n.createComment("")),!e.getElementsByTagName("*").length}),T.attributes=at(function(e){e.innerHTML="<select></select>";var t=typeof e.lastChild.getAttribute("multiple");return"boolean"!==t&&"string"!==t}),T.getByClassName=at(function(e){return e.innerHTML="<div class='hidden e'></div><div class='hidden'></div>",e.getElementsByClassName&&e.getElementsByClassName("e").length?(e.lastChild.className="e",2===e.getElementsByClassName("e").length):!1}),T.getByName=at(function(e){e.id=x+0,e.innerHTML="<a name='"+x+"'></a><div name='"+x+"'></div>",f.insertBefore(e,f.firstChild);var t=n.getElementsByName&&n.getElementsByName(x).length===2+n.getElementsByName(x+0).length;return T.getIdNotName=!n.getElementById(x),f.removeChild(e),t}),i.attrHandle=at(function(e){return e.innerHTML="<a href='#'></a>",e.firstChild&&typeof e.firstChild.getAttribute!==A&&"#"===e.firstChild.getAttribute("href")})?{}:{href:function(e){return e.getAttribute("href",2)},type:function(e){return e.getAttribute("type")}},T.getIdNotName?(i.find.ID=function(e,t){if(typeof t.getElementById!==A&&!d){var n=t.getElementById(e);return n&&n.parentNode?[n]:[]}},i.filter.ID=function(e){var t=e.replace(et,tt);return function(e){return e.getAttribute("id")===t}}):(i.find.ID=function(e,n){if(typeof n.getElementById!==A&&!d){var r=n.getElementById(e);return r?r.id===e||typeof r.getAttributeNode!==A&&r.getAttributeNode("id").value===e?[r]:t:[]}},i.filter.ID=function(e){var t=e.replace(et,tt);return function(e){var n=typeof e.getAttributeNode!==A&&e.getAttributeNode("id");return n&&n.value===t}}),i.find.TAG=T.tagNameNoComments?function(e,n){return typeof n.getElementsByTagName!==A?n.getElementsByTagName(e):t}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},i.find.NAME=T.getByName&&function(e,n){return typeof n.getElementsByName!==A?n.getElementsByName(name):t},i.find.CLASS=T.getByClassName&&function(e,n){return typeof n.getElementsByClassName===A||d?t:n.getElementsByClassName(e)},g=[],h=[":focus"],(T.qsa=rt(n.querySelectorAll))&&(at(function(e){e.innerHTML="<select><option selected=''></option></select>",e.querySelectorAll("[selected]").length||h.push("\\["+_+"*(?:checked|disabled|ismap|multiple|readonly|selected|value)"),e.querySelectorAll(":checked").length||h.push(":checked")}),at(function(e){e.innerHTML="<input type='hidden' i=''/>",e.querySelectorAll("[i^='']").length&&h.push("[*^$]="+_+"*(?:\"\"|'')"),e.querySelectorAll(":enabled").length||h.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),h.push(",.*:")})),(T.matchesSelector=rt(m=f.matchesSelector||f.mozMatchesSelector||f.webkitMatchesSelector||f.oMatchesSelector||f.msMatchesSelector))&&at(function(e){T.disconnectedMatch=m.call(e,"div"),m.call(e,"[s!='']:x"),g.push("!=",R)}),h=RegExp(h.join("|")),g=RegExp(g.join("|")),y=rt(f.contains)||f.compareDocumentPosition?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},v=f.compareDocumentPosition?function(e,t){var r;return e===t?(u=!0,0):(r=t.compareDocumentPosition&&e.compareDocumentPosition&&e.compareDocumentPosition(t))?1&r||e.parentNode&&11===e.parentNode.nodeType?e===n||y(w,e)?-1:t===n||y(w,t)?1:0:4&r?-1:1:e.compareDocumentPosition?-1:1}:function(e,t){var r,i=0,o=e.parentNode,a=t.parentNode,s=[e],l=[t];if(e===t)return u=!0,0;if(!o||!a)return e===n?-1:t===n?1:o?-1:a?1:0;if(o===a)return ut(e,t);r=e;while(r=r.parentNode)s.unshift(r);r=t;while(r=r.parentNode)l.unshift(r);while(s[i]===l[i])i++;return i?ut(s[i],l[i]):s[i]===w?-1:l[i]===w?1:0},u=!1,[0,0].sort(v),T.detectDuplicates=u,p):p},st.matches=function(e,t){return st(e,null,null,t)},st.matchesSelector=function(e,t){if((e.ownerDocument||e)!==p&&c(e),t=t.replace(Z,"='$1']"),!(!T.matchesSelector||d||g&&g.test(t)||h.test(t)))try{var n=m.call(e,t);if(n||T.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(r){}return st(t,p,null,[e]).length>0},st.contains=function(e,t){return(e.ownerDocument||e)!==p&&c(e),y(e,t)},st.attr=function(e,t){var n;return(e.ownerDocument||e)!==p&&c(e),d||(t=t.toLowerCase()),(n=i.attrHandle[t])?n(e):d||T.attributes?e.getAttribute(t):((n=e.getAttributeNode(t))||e.getAttribute(t))&&e[t]===!0?t:n&&n.specified?n.value:null},st.error=function(e){throw Error("Syntax error, unrecognized expression: "+e)},st.uniqueSort=function(e){var t,n=[],r=1,i=0;if(u=!T.detectDuplicates,e.sort(v),u){for(;t=e[r];r++)t===e[r-1]&&(i=n.push(r));while(i--)e.splice(n[i],1)}return e};function ut(e,t){var n=t&&e,r=n&&(~t.sourceIndex||j)-(~e.sourceIndex||j);if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function lt(e){return function(t){var n=t.nodeName.toLowerCase();return"input"===n&&t.type===e}}function ct(e){return function(t){var n=t.nodeName.toLowerCase();return("input"===n||"button"===n)&&t.type===e}}function pt(e){return ot(function(t){return t=+t,ot(function(n,r){var i,o=e([],n.length,t),a=o.length;while(a--)n[i=o[a]]&&(n[i]=!(r[i]=n[i]))})})}o=st.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=o(e)}else if(3===i||4===i)return e.nodeValue}else for(;t=e[r];r++)n+=o(t);return n},i=st.selectors={cacheLength:50,createPseudo:ot,match:U,find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(et,tt),e[3]=(e[4]||e[5]||"").replace(et,tt),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||st.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&st.error(e[0]),e},PSEUDO:function(e){var t,n=!e[5]&&e[2];return U.CHILD.test(e[0])?null:(e[4]?e[2]=e[4]:n&&z.test(n)&&(t=ft(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){return"*"===e?function(){return!0}:(e=e.replace(et,tt).toLowerCase(),function(t){return t.nodeName&&t.nodeName.toLowerCase()===e})},CLASS:function(e){var t=k[e+" "];return t||(t=RegExp("(^|"+_+")"+e+"("+_+"|$)"))&&k(e,function(e){return t.test(e.className||typeof e.getAttribute!==A&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r){var i=st.attr(r,e);return null==i?"!="===t:t?(i+="","="===t?i===n:"!="===t?i!==n:"^="===t?n&&0===i.indexOf(n):"*="===t?n&&i.indexOf(n)>-1:"$="===t?n&&i.slice(-n.length)===n:"~="===t?(" "+i+" ").indexOf(n)>-1:"|="===t?i===n||i.slice(0,n.length+1)===n+"-":!1):!0}},CHILD:function(e,t,n,r,i){var o="nth"!==e.slice(0,3),a="last"!==e.slice(-4),s="of-type"===t;return 1===r&&0===i?function(e){return!!e.parentNode}:function(t,n,u){var l,c,p,f,d,h,g=o!==a?"nextSibling":"previousSibling",m=t.parentNode,y=s&&t.nodeName.toLowerCase(),v=!u&&!s;if(m){if(o){while(g){p=t;while(p=p[g])if(s?p.nodeName.toLowerCase()===y:1===p.nodeType)return!1;h=g="only"===e&&!h&&"nextSibling"}return!0}if(h=[a?m.firstChild:m.lastChild],a&&v){c=m[x]||(m[x]={}),l=c[e]||[],d=l[0]===N&&l[1],f=l[0]===N&&l[2],p=d&&m.childNodes[d];while(p=++d&&p&&p[g]||(f=d=0)||h.pop())if(1===p.nodeType&&++f&&p===t){c[e]=[N,d,f];break}}else if(v&&(l=(t[x]||(t[x]={}))[e])&&l[0]===N)f=l[1];else while(p=++d&&p&&p[g]||(f=d=0)||h.pop())if((s?p.nodeName.toLowerCase()===y:1===p.nodeType)&&++f&&(v&&((p[x]||(p[x]={}))[e]=[N,f]),p===t))break;return f-=i,f===r||0===f%r&&f/r>=0}}},PSEUDO:function(e,t){var n,r=i.pseudos[e]||i.setFilters[e.toLowerCase()]||st.error("unsupported pseudo: "+e);return r[x]?r(t):r.length>1?(n=[e,e,"",t],i.setFilters.hasOwnProperty(e.toLowerCase())?ot(function(e,n){var i,o=r(e,t),a=o.length;while(a--)i=M.call(e,o[a]),e[i]=!(n[i]=o[a])}):function(e){return r(e,0,n)}):r}},pseudos:{not:ot(function(e){var t=[],n=[],r=s(e.replace(W,"$1"));return r[x]?ot(function(e,t,n,i){var o,a=r(e,null,i,[]),s=e.length;while(s--)(o=a[s])&&(e[s]=!(t[s]=o))}):function(e,i,o){return t[0]=e,r(t,null,o,n),!n.pop()}}),has:ot(function(e){return function(t){return st(e,t).length>0}}),contains:ot(function(e){return function(t){return(t.textContent||t.innerText||o(t)).indexOf(e)>-1}}),lang:ot(function(e){return X.test(e||"")||st.error("unsupported lang: "+e),e=e.replace(et,tt).toLowerCase(),function(t){var n;do if(n=d?t.getAttribute("xml:lang")||t.getAttribute("lang"):t.lang)return n=n.toLowerCase(),n===e||0===n.indexOf(e+"-");while((t=t.parentNode)&&1===t.nodeType);return!1}}),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===f},focus:function(e){return e===p.activeElement&&(!p.hasFocus||p.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:function(e){return e.disabled===!1},disabled:function(e){return e.disabled===!0},checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeName>"@"||3===e.nodeType||4===e.nodeType)return!1;return!0},parent:function(e){return!i.pseudos.empty(e)},header:function(e){return Q.test(e.nodeName)},input:function(e){return G.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||t.toLowerCase()===e.type)},first:pt(function(){return[0]}),last:pt(function(e,t){return[t-1]}),eq:pt(function(e,t,n){return[0>n?n+t:n]}),even:pt(function(e,t){var n=0;for(;t>n;n+=2)e.push(n);return e}),odd:pt(function(e,t){var n=1;for(;t>n;n+=2)e.push(n);return e}),lt:pt(function(e,t,n){var r=0>n?n+t:n;for(;--r>=0;)e.push(r);return e}),gt:pt(function(e,t,n){var r=0>n?n+t:n;for(;t>++r;)e.push(r);return e})}};for(n in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})i.pseudos[n]=lt(n);for(n in{submit:!0,reset:!0})i.pseudos[n]=ct(n);function ft(e,t){var n,r,o,a,s,u,l,c=E[e+" "];if(c)return t?0:c.slice(0);s=e,u=[],l=i.preFilter;while(s){(!n||(r=$.exec(s)))&&(r&&(s=s.slice(r[0].length)||s),u.push(o=[])),n=!1,(r=I.exec(s))&&(n=r.shift(),o.push({value:n,type:r[0].replace(W," ")}),s=s.slice(n.length));for(a in i.filter)!(r=U[a].exec(s))||l[a]&&!(r=l[a](r))||(n=r.shift(),o.push({value:n,type:a,matches:r}),s=s.slice(n.length));if(!n)break}return t?s.length:s?st.error(e):E(e,u).slice(0)}function dt(e){var t=0,n=e.length,r="";for(;n>t;t++)r+=e[t].value;return r}function ht(e,t,n){var i=t.dir,o=n&&"parentNode"===i,a=C++;return t.first?function(t,n,r){while(t=t[i])if(1===t.nodeType||o)return e(t,n,r)}:function(t,n,s){var u,l,c,p=N+" "+a;if(s){while(t=t[i])if((1===t.nodeType||o)&&e(t,n,s))return!0}else while(t=t[i])if(1===t.nodeType||o)if(c=t[x]||(t[x]={}),(l=c[i])&&l[0]===p){if((u=l[1])===!0||u===r)return u===!0}else if(l=c[i]=[p],l[1]=e(t,n,s)||r,l[1]===!0)return!0}}function gt(e){return e.length>1?function(t,n,r){var i=e.length;while(i--)if(!e[i](t,n,r))return!1;return!0}:e[0]}function mt(e,t,n,r,i){var o,a=[],s=0,u=e.length,l=null!=t;for(;u>s;s++)(o=e[s])&&(!n||n(o,r,i))&&(a.push(o),l&&t.push(s));return a}function yt(e,t,n,r,i,o){return r&&!r[x]&&(r=yt(r)),i&&!i[x]&&(i=yt(i,o)),ot(function(o,a,s,u){var l,c,p,f=[],d=[],h=a.length,g=o||xt(t||"*",s.nodeType?[s]:s,[]),m=!e||!o&&t?g:mt(g,f,e,s,u),y=n?i||(o?e:h||r)?[]:a:m;if(n&&n(m,y,s,u),r){l=mt(y,d),r(l,[],s,u),c=l.length;while(c--)(p=l[c])&&(y[d[c]]=!(m[d[c]]=p))}if(o){if(i||e){if(i){l=[],c=y.length;while(c--)(p=y[c])&&l.push(m[c]=p);i(null,y=[],l,u)}c=y.length;while(c--)(p=y[c])&&(l=i?M.call(o,p):f[c])>-1&&(o[l]=!(a[l]=p))}}else y=mt(y===a?y.splice(h,y.length):y),i?i(null,a,y,u):H.apply(a,y)})}function vt(e){var t,n,r,o=e.length,a=i.relative[e[0].type],s=a||i.relative[" "],u=a?1:0,c=ht(function(e){return e===t},s,!0),p=ht(function(e){return M.call(t,e)>-1},s,!0),f=[function(e,n,r){return!a&&(r||n!==l)||((t=n).nodeType?c(e,n,r):p(e,n,r))}];for(;o>u;u++)if(n=i.relative[e[u].type])f=[ht(gt(f),n)];else{if(n=i.filter[e[u].type].apply(null,e[u].matches),n[x]){for(r=++u;o>r;r++)if(i.relative[e[r].type])break;return yt(u>1&>(f),u>1&&dt(e.slice(0,u-1)).replace(W,"$1"),n,r>u&&vt(e.slice(u,r)),o>r&&vt(e=e.slice(r)),o>r&&dt(e))}f.push(n)}return gt(f)}function bt(e,t){var n=0,o=t.length>0,a=e.length>0,s=function(s,u,c,f,d){var h,g,m,y=[],v=0,b="0",x=s&&[],w=null!=d,T=l,C=s||a&&i.find.TAG("*",d&&u.parentNode||u),k=N+=null==T?1:Math.random()||.1;for(w&&(l=u!==p&&u,r=n);null!=(h=C[b]);b++){if(a&&h){g=0;while(m=e[g++])if(m(h,u,c)){f.push(h);break}w&&(N=k,r=++n)}o&&((h=!m&&h)&&v--,s&&x.push(h))}if(v+=b,o&&b!==v){g=0;while(m=t[g++])m(x,y,u,c);if(s){if(v>0)while(b--)x[b]||y[b]||(y[b]=L.call(f));y=mt(y)}H.apply(f,y),w&&!s&&y.length>0&&v+t.length>1&&st.uniqueSort(f)}return w&&(N=k,l=T),x};return o?ot(s):s}s=st.compile=function(e,t){var n,r=[],i=[],o=S[e+" "];if(!o){t||(t=ft(e)),n=t.length;while(n--)o=vt(t[n]),o[x]?r.push(o):i.push(o);o=S(e,bt(i,r))}return o};function xt(e,t,n){var r=0,i=t.length;for(;i>r;r++)st(e,t[r],n);return n}function wt(e,t,n,r){var o,a,u,l,c,p=ft(e);if(!r&&1===p.length){if(a=p[0]=p[0].slice(0),a.length>2&&"ID"===(u=a[0]).type&&9===t.nodeType&&!d&&i.relative[a[1].type]){if(t=i.find.ID(u.matches[0].replace(et,tt),t)[0],!t)return n;e=e.slice(a.shift().value.length)}o=U.needsContext.test(e)?0:a.length;while(o--){if(u=a[o],i.relative[l=u.type])break;if((c=i.find[l])&&(r=c(u.matches[0].replace(et,tt),V.test(a[0].type)&&t.parentNode||t))){if(a.splice(o,1),e=r.length&&dt(a),!e)return H.apply(n,q.call(r,0)),n;break}}}return s(e,p)(r,t,d,n,V.test(e)),n}i.pseudos.nth=i.pseudos.eq;function Tt(){}i.filters=Tt.prototype=i.pseudos,i.setFilters=new Tt,c(),st.attr=b.attr,b.find=st,b.expr=st.selectors,b.expr[":"]=b.expr.pseudos,b.unique=st.uniqueSort,b.text=st.getText,b.isXMLDoc=st.isXML,b.contains=st.contains}(e);var at=/Until$/,st=/^(?:parents|prev(?:Until|All))/,ut=/^.[^:#\[\.,]*$/,lt=b.expr.match.needsContext,ct={children:!0,contents:!0,next:!0,prev:!0};b.fn.extend({find:function(e){var t,n,r,i=this.length;if("string"!=typeof e)return r=this,this.pushStack(b(e).filter(function(){for(t=0;i>t;t++)if(b.contains(r[t],this))return!0}));for(n=[],t=0;i>t;t++)b.find(e,this[t],n);return n=this.pushStack(i>1?b.unique(n):n),n.selector=(this.selector?this.selector+" ":"")+e,n},has:function(e){var t,n=b(e,this),r=n.length;return this.filter(function(){for(t=0;r>t;t++)if(b.contains(this,n[t]))return!0})},not:function(e){return this.pushStack(ft(this,e,!1))},filter:function(e){return this.pushStack(ft(this,e,!0))},is:function(e){return!!e&&("string"==typeof e?lt.test(e)?b(e,this.context).index(this[0])>=0:b.filter(e,this).length>0:this.filter(e).length>0)},closest:function(e,t){var n,r=0,i=this.length,o=[],a=lt.test(e)||"string"!=typeof e?b(e,t||this.context):0;for(;i>r;r++){n=this[r];while(n&&n.ownerDocument&&n!==t&&11!==n.nodeType){if(a?a.index(n)>-1:b.find.matchesSelector(n,e)){o.push(n);break}n=n.parentNode}}return this.pushStack(o.length>1?b.unique(o):o)},index:function(e){return e?"string"==typeof e?b.inArray(this[0],b(e)):b.inArray(e.jquery?e[0]:e,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){var n="string"==typeof e?b(e,t):b.makeArray(e&&e.nodeType?[e]:e),r=b.merge(this.get(),n);return this.pushStack(b.unique(r))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),b.fn.andSelf=b.fn.addBack;function pt(e,t){do e=e[t];while(e&&1!==e.nodeType);return e}b.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return b.dir(e,"parentNode")},parentsUntil:function(e,t,n){return b.dir(e,"parentNode",n)},next:function(e){return pt(e,"nextSibling")},prev:function(e){return pt(e,"previousSibling")},nextAll:function(e){return b.dir(e,"nextSibling")},prevAll:function(e){return b.dir(e,"previousSibling")},nextUntil:function(e,t,n){return b.dir(e,"nextSibling",n)},prevUntil:function(e,t,n){return b.dir(e,"previousSibling",n)},siblings:function(e){return b.sibling((e.parentNode||{}).firstChild,e)},children:function(e){return b.sibling(e.firstChild)},contents:function(e){return b.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:b.merge([],e.childNodes)}},function(e,t){b.fn[e]=function(n,r){var i=b.map(this,t,n);return at.test(e)||(r=n),r&&"string"==typeof r&&(i=b.filter(r,i)),i=this.length>1&&!ct[e]?b.unique(i):i,this.length>1&&st.test(e)&&(i=i.reverse()),this.pushStack(i)}}),b.extend({filter:function(e,t,n){return n&&(e=":not("+e+")"),1===t.length?b.find.matchesSelector(t[0],e)?[t[0]]:[]:b.find.matches(e,t)},dir:function(e,n,r){var i=[],o=e[n];while(o&&9!==o.nodeType&&(r===t||1!==o.nodeType||!b(o).is(r)))1===o.nodeType&&i.push(o),o=o[n];return i},sibling:function(e,t){var n=[];for(;e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n}});function ft(e,t,n){if(t=t||0,b.isFunction(t))return b.grep(e,function(e,r){var i=!!t.call(e,r,e);return i===n});if(t.nodeType)return b.grep(e,function(e){return e===t===n});if("string"==typeof t){var r=b.grep(e,function(e){return 1===e.nodeType});if(ut.test(t))return b.filter(t,r,!n);t=b.filter(t,r)}return b.grep(e,function(e){return b.inArray(e,t)>=0===n})}function dt(e){var t=ht.split("|"),n=e.createDocumentFragment();if(n.createElement)while(t.length)n.createElement(t.pop());return n}var ht="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",gt=/ jQuery\d+="(?:null|\d+)"/g,mt=RegExp("<(?:"+ht+")[\\s/>]","i"),yt=/^\s+/,vt=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,bt=/<([\w:]+)/,xt=/<tbody/i,wt=/<|&#?\w+;/,Tt=/<(?:script|style|link)/i,Nt=/^(?:checkbox|radio)$/i,Ct=/checked\s*(?:[^=]|=\s*.checked.)/i,kt=/^$|\/(?:java|ecma)script/i,Et=/^true\/(.*)/,St=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,At={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],area:[1,"<map>","</map>"],param:[1,"<object>","</object>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:b.support.htmlSerialize?[0,"",""]:[1,"X<div>","</div>"]},jt=dt(o),Dt=jt.appendChild(o.createElement("div"));At.optgroup=At.option,At.tbody=At.tfoot=At.colgroup=At.caption=At.thead,At.th=At.td,b.fn.extend({text:function(e){return b.access(this,function(e){return e===t?b.text(this):this.empty().append((this[0]&&this[0].ownerDocument||o).createTextNode(e))},null,e,arguments.length)},wrapAll:function(e){if(b.isFunction(e))return this.each(function(t){b(this).wrapAll(e.call(this,t))});if(this[0]){var t=b(e,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstChild&&1===e.firstChild.nodeType)e=e.firstChild;return e}).append(this)}return this},wrapInner:function(e){return b.isFunction(e)?this.each(function(t){b(this).wrapInner(e.call(this,t))}):this.each(function(){var t=b(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=b.isFunction(e);return this.each(function(n){b(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(){return this.parent().each(function(){b.nodeName(this,"body")||b(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(e){(1===this.nodeType||11===this.nodeType||9===this.nodeType)&&this.appendChild(e)})},prepend:function(){return this.domManip(arguments,!0,function(e){(1===this.nodeType||11===this.nodeType||9===this.nodeType)&&this.insertBefore(e,this.firstChild)})},before:function(){return this.domManip(arguments,!1,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return this.domManip(arguments,!1,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},remove:function(e,t){var n,r=0;for(;null!=(n=this[r]);r++)(!e||b.filter(e,[n]).length>0)&&(t||1!==n.nodeType||b.cleanData(Ot(n)),n.parentNode&&(t&&b.contains(n.ownerDocument,n)&&Mt(Ot(n,"script")),n.parentNode.removeChild(n)));return this},empty:function(){var e,t=0;for(;null!=(e=this[t]);t++){1===e.nodeType&&b.cleanData(Ot(e,!1));while(e.firstChild)e.removeChild(e.firstChild);e.options&&b.nodeName(e,"select")&&(e.options.length=0)}return this},clone:function(e,t){return e=null==e?!1:e,t=null==t?e:t,this.map(function(){return b.clone(this,e,t)})},html:function(e){return b.access(this,function(e){var n=this[0]||{},r=0,i=this.length;if(e===t)return 1===n.nodeType?n.innerHTML.replace(gt,""):t;if(!("string"!=typeof e||Tt.test(e)||!b.support.htmlSerialize&&mt.test(e)||!b.support.leadingWhitespace&&yt.test(e)||At[(bt.exec(e)||["",""])[1].toLowerCase()])){e=e.replace(vt,"<$1></$2>");try{for(;i>r;r++)n=this[r]||{},1===n.nodeType&&(b.cleanData(Ot(n,!1)),n.innerHTML=e);n=0}catch(o){}}n&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(e){var t=b.isFunction(e);return t||"string"==typeof e||(e=b(e).not(this).detach()),this.domManip([e],!0,function(e){var t=this.nextSibling,n=this.parentNode;n&&(b(this).remove(),n.insertBefore(e,t))})},detach:function(e){return this.remove(e,!0)},domManip:function(e,n,r){e=f.apply([],e);var i,o,a,s,u,l,c=0,p=this.length,d=this,h=p-1,g=e[0],m=b.isFunction(g);if(m||!(1>=p||"string"!=typeof g||b.support.checkClone)&&Ct.test(g))return this.each(function(i){var o=d.eq(i);m&&(e[0]=g.call(this,i,n?o.html():t)),o.domManip(e,n,r)});if(p&&(l=b.buildFragment(e,this[0].ownerDocument,!1,this),i=l.firstChild,1===l.childNodes.length&&(l=i),i)){for(n=n&&b.nodeName(i,"tr"),s=b.map(Ot(l,"script"),Ht),a=s.length;p>c;c++)o=l,c!==h&&(o=b.clone(o,!0,!0),a&&b.merge(s,Ot(o,"script"))),r.call(n&&b.nodeName(this[c],"table")?Lt(this[c],"tbody"):this[c],o,c);if(a)for(u=s[s.length-1].ownerDocument,b.map(s,qt),c=0;a>c;c++)o=s[c],kt.test(o.type||"")&&!b._data(o,"globalEval")&&b.contains(u,o)&&(o.src?b.ajax({url:o.src,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0}):b.globalEval((o.text||o.textContent||o.innerHTML||"").replace(St,"")));l=i=null}return this}});function Lt(e,t){return e.getElementsByTagName(t)[0]||e.appendChild(e.ownerDocument.createElement(t))}function Ht(e){var t=e.getAttributeNode("type");return e.type=(t&&t.specified)+"/"+e.type,e}function qt(e){var t=Et.exec(e.type);return t?e.type=t[1]:e.removeAttribute("type"),e}function Mt(e,t){var n,r=0;for(;null!=(n=e[r]);r++)b._data(n,"globalEval",!t||b._data(t[r],"globalEval"))}function _t(e,t){if(1===t.nodeType&&b.hasData(e)){var n,r,i,o=b._data(e),a=b._data(t,o),s=o.events;if(s){delete a.handle,a.events={};for(n in s)for(r=0,i=s[n].length;i>r;r++)b.event.add(t,n,s[n][r])}a.data&&(a.data=b.extend({},a.data))}}function Ft(e,t){var n,r,i;if(1===t.nodeType){if(n=t.nodeName.toLowerCase(),!b.support.noCloneEvent&&t[b.expando]){i=b._data(t);for(r in i.events)b.removeEvent(t,r,i.handle);t.removeAttribute(b.expando)}"script"===n&&t.text!==e.text?(Ht(t).text=e.text,qt(t)):"object"===n?(t.parentNode&&(t.outerHTML=e.outerHTML),b.support.html5Clone&&e.innerHTML&&!b.trim(t.innerHTML)&&(t.innerHTML=e.innerHTML)):"input"===n&&Nt.test(e.type)?(t.defaultChecked=t.checked=e.checked,t.value!==e.value&&(t.value=e.value)):"option"===n?t.defaultSelected=t.selected=e.defaultSelected:("input"===n||"textarea"===n)&&(t.defaultValue=e.defaultValue)}}b.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,t){b.fn[e]=function(e){var n,r=0,i=[],o=b(e),a=o.length-1;for(;a>=r;r++)n=r===a?this:this.clone(!0),b(o[r])[t](n),d.apply(i,n.get());return this.pushStack(i)}});function Ot(e,n){var r,o,a=0,s=typeof e.getElementsByTagName!==i?e.getElementsByTagName(n||"*"):typeof e.querySelectorAll!==i?e.querySelectorAll(n||"*"):t;if(!s)for(s=[],r=e.childNodes||e;null!=(o=r[a]);a++)!n||b.nodeName(o,n)?s.push(o):b.merge(s,Ot(o,n));return n===t||n&&b.nodeName(e,n)?b.merge([e],s):s}function Bt(e){Nt.test(e.type)&&(e.defaultChecked=e.checked)}b.extend({clone:function(e,t,n){var r,i,o,a,s,u=b.contains(e.ownerDocument,e);if(b.support.html5Clone||b.isXMLDoc(e)||!mt.test("<"+e.nodeName+">")?o=e.cloneNode(!0):(Dt.innerHTML=e.outerHTML,Dt.removeChild(o=Dt.firstChild)),!(b.support.noCloneEvent&&b.support.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||b.isXMLDoc(e)))for(r=Ot(o),s=Ot(e),a=0;null!=(i=s[a]);++a)r[a]&&Ft(i,r[a]);if(t)if(n)for(s=s||Ot(e),r=r||Ot(o),a=0;null!=(i=s[a]);a++)_t(i,r[a]);else _t(e,o);return r=Ot(o,"script"),r.length>0&&Mt(r,!u&&Ot(e,"script")),r=s=i=null,o},buildFragment:function(e,t,n,r){var i,o,a,s,u,l,c,p=e.length,f=dt(t),d=[],h=0;for(;p>h;h++)if(o=e[h],o||0===o)if("object"===b.type(o))b.merge(d,o.nodeType?[o]:o);else if(wt.test(o)){s=s||f.appendChild(t.createElement("div")),u=(bt.exec(o)||["",""])[1].toLowerCase(),c=At[u]||At._default,s.innerHTML=c[1]+o.replace(vt,"<$1></$2>")+c[2],i=c[0];while(i--)s=s.lastChild;if(!b.support.leadingWhitespace&&yt.test(o)&&d.push(t.createTextNode(yt.exec(o)[0])),!b.support.tbody){o="table"!==u||xt.test(o)?"<table>"!==c[1]||xt.test(o)?0:s:s.firstChild,i=o&&o.childNodes.length;while(i--)b.nodeName(l=o.childNodes[i],"tbody")&&!l.childNodes.length&&o.removeChild(l) |
}b.merge(d,s.childNodes),s.textContent="";while(s.firstChild)s.removeChild(s.firstChild);s=f.lastChild}else d.push(t.createTextNode(o));s&&f.removeChild(s),b.support.appendChecked||b.grep(Ot(d,"input"),Bt),h=0;while(o=d[h++])if((!r||-1===b.inArray(o,r))&&(a=b.contains(o.ownerDocument,o),s=Ot(f.appendChild(o),"script"),a&&Mt(s),n)){i=0;while(o=s[i++])kt.test(o.type||"")&&n.push(o)}return s=null,f},cleanData:function(e,t){var n,r,o,a,s=0,u=b.expando,l=b.cache,p=b.support.deleteExpando,f=b.event.special;for(;null!=(n=e[s]);s++)if((t||b.acceptData(n))&&(o=n[u],a=o&&l[o])){if(a.events)for(r in a.events)f[r]?b.event.remove(n,r):b.removeEvent(n,r,a.handle);l[o]&&(delete l[o],p?delete n[u]:typeof n.removeAttribute!==i?n.removeAttribute(u):n[u]=null,c.push(o))}}});var Pt,Rt,Wt,$t=/alpha\([^)]*\)/i,It=/opacity\s*=\s*([^)]*)/,zt=/^(top|right|bottom|left)$/,Xt=/^(none|table(?!-c[ea]).+)/,Ut=/^margin/,Vt=RegExp("^("+x+")(.*)$","i"),Yt=RegExp("^("+x+")(?!px)[a-z%]+$","i"),Jt=RegExp("^([+-])=("+x+")","i"),Gt={BODY:"block"},Qt={position:"absolute",visibility:"hidden",display:"block"},Kt={letterSpacing:0,fontWeight:400},Zt=["Top","Right","Bottom","Left"],en=["Webkit","O","Moz","ms"];function tn(e,t){if(t in e)return t;var n=t.charAt(0).toUpperCase()+t.slice(1),r=t,i=en.length;while(i--)if(t=en[i]+n,t in e)return t;return r}function nn(e,t){return e=t||e,"none"===b.css(e,"display")||!b.contains(e.ownerDocument,e)}function rn(e,t){var n,r,i,o=[],a=0,s=e.length;for(;s>a;a++)r=e[a],r.style&&(o[a]=b._data(r,"olddisplay"),n=r.style.display,t?(o[a]||"none"!==n||(r.style.display=""),""===r.style.display&&nn(r)&&(o[a]=b._data(r,"olddisplay",un(r.nodeName)))):o[a]||(i=nn(r),(n&&"none"!==n||!i)&&b._data(r,"olddisplay",i?n:b.css(r,"display"))));for(a=0;s>a;a++)r=e[a],r.style&&(t&&"none"!==r.style.display&&""!==r.style.display||(r.style.display=t?o[a]||"":"none"));return e}b.fn.extend({css:function(e,n){return b.access(this,function(e,n,r){var i,o,a={},s=0;if(b.isArray(n)){for(o=Rt(e),i=n.length;i>s;s++)a[n[s]]=b.css(e,n[s],!1,o);return a}return r!==t?b.style(e,n,r):b.css(e,n)},e,n,arguments.length>1)},show:function(){return rn(this,!0)},hide:function(){return rn(this)},toggle:function(e){var t="boolean"==typeof e;return this.each(function(){(t?e:nn(this))?b(this).show():b(this).hide()})}}),b.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Wt(e,"opacity");return""===n?"1":n}}}},cssNumber:{columnCount:!0,fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":b.support.cssFloat?"cssFloat":"styleFloat"},style:function(e,n,r,i){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var o,a,s,u=b.camelCase(n),l=e.style;if(n=b.cssProps[u]||(b.cssProps[u]=tn(l,u)),s=b.cssHooks[n]||b.cssHooks[u],r===t)return s&&"get"in s&&(o=s.get(e,!1,i))!==t?o:l[n];if(a=typeof r,"string"===a&&(o=Jt.exec(r))&&(r=(o[1]+1)*o[2]+parseFloat(b.css(e,n)),a="number"),!(null==r||"number"===a&&isNaN(r)||("number"!==a||b.cssNumber[u]||(r+="px"),b.support.clearCloneStyle||""!==r||0!==n.indexOf("background")||(l[n]="inherit"),s&&"set"in s&&(r=s.set(e,r,i))===t)))try{l[n]=r}catch(c){}}},css:function(e,n,r,i){var o,a,s,u=b.camelCase(n);return n=b.cssProps[u]||(b.cssProps[u]=tn(e.style,u)),s=b.cssHooks[n]||b.cssHooks[u],s&&"get"in s&&(a=s.get(e,!0,r)),a===t&&(a=Wt(e,n,i)),"normal"===a&&n in Kt&&(a=Kt[n]),""===r||r?(o=parseFloat(a),r===!0||b.isNumeric(o)?o||0:a):a},swap:function(e,t,n,r){var i,o,a={};for(o in t)a[o]=e.style[o],e.style[o]=t[o];i=n.apply(e,r||[]);for(o in t)e.style[o]=a[o];return i}}),e.getComputedStyle?(Rt=function(t){return e.getComputedStyle(t,null)},Wt=function(e,n,r){var i,o,a,s=r||Rt(e),u=s?s.getPropertyValue(n)||s[n]:t,l=e.style;return s&&(""!==u||b.contains(e.ownerDocument,e)||(u=b.style(e,n)),Yt.test(u)&&Ut.test(n)&&(i=l.width,o=l.minWidth,a=l.maxWidth,l.minWidth=l.maxWidth=l.width=u,u=s.width,l.width=i,l.minWidth=o,l.maxWidth=a)),u}):o.documentElement.currentStyle&&(Rt=function(e){return e.currentStyle},Wt=function(e,n,r){var i,o,a,s=r||Rt(e),u=s?s[n]:t,l=e.style;return null==u&&l&&l[n]&&(u=l[n]),Yt.test(u)&&!zt.test(n)&&(i=l.left,o=e.runtimeStyle,a=o&&o.left,a&&(o.left=e.currentStyle.left),l.left="fontSize"===n?"1em":u,u=l.pixelLeft+"px",l.left=i,a&&(o.left=a)),""===u?"auto":u});function on(e,t,n){var r=Vt.exec(t);return r?Math.max(0,r[1]-(n||0))+(r[2]||"px"):t}function an(e,t,n,r,i){var o=n===(r?"border":"content")?4:"width"===t?1:0,a=0;for(;4>o;o+=2)"margin"===n&&(a+=b.css(e,n+Zt[o],!0,i)),r?("content"===n&&(a-=b.css(e,"padding"+Zt[o],!0,i)),"margin"!==n&&(a-=b.css(e,"border"+Zt[o]+"Width",!0,i))):(a+=b.css(e,"padding"+Zt[o],!0,i),"padding"!==n&&(a+=b.css(e,"border"+Zt[o]+"Width",!0,i)));return a}function sn(e,t,n){var r=!0,i="width"===t?e.offsetWidth:e.offsetHeight,o=Rt(e),a=b.support.boxSizing&&"border-box"===b.css(e,"boxSizing",!1,o);if(0>=i||null==i){if(i=Wt(e,t,o),(0>i||null==i)&&(i=e.style[t]),Yt.test(i))return i;r=a&&(b.support.boxSizingReliable||i===e.style[t]),i=parseFloat(i)||0}return i+an(e,t,n||(a?"border":"content"),r,o)+"px"}function un(e){var t=o,n=Gt[e];return n||(n=ln(e,t),"none"!==n&&n||(Pt=(Pt||b("<iframe frameborder='0' width='0' height='0'/>").css("cssText","display:block !important")).appendTo(t.documentElement),t=(Pt[0].contentWindow||Pt[0].contentDocument).document,t.write("<!doctype html><html><body>"),t.close(),n=ln(e,t),Pt.detach()),Gt[e]=n),n}function ln(e,t){var n=b(t.createElement(e)).appendTo(t.body),r=b.css(n[0],"display");return n.remove(),r}b.each(["height","width"],function(e,n){b.cssHooks[n]={get:function(e,r,i){return r?0===e.offsetWidth&&Xt.test(b.css(e,"display"))?b.swap(e,Qt,function(){return sn(e,n,i)}):sn(e,n,i):t},set:function(e,t,r){var i=r&&Rt(e);return on(e,t,r?an(e,n,r,b.support.boxSizing&&"border-box"===b.css(e,"boxSizing",!1,i),i):0)}}}),b.support.opacity||(b.cssHooks.opacity={get:function(e,t){return It.test((t&&e.currentStyle?e.currentStyle.filter:e.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":t?"1":""},set:function(e,t){var n=e.style,r=e.currentStyle,i=b.isNumeric(t)?"alpha(opacity="+100*t+")":"",o=r&&r.filter||n.filter||"";n.zoom=1,(t>=1||""===t)&&""===b.trim(o.replace($t,""))&&n.removeAttribute&&(n.removeAttribute("filter"),""===t||r&&!r.filter)||(n.filter=$t.test(o)?o.replace($t,i):o+" "+i)}}),b(function(){b.support.reliableMarginRight||(b.cssHooks.marginRight={get:function(e,n){return n?b.swap(e,{display:"inline-block"},Wt,[e,"marginRight"]):t}}),!b.support.pixelPosition&&b.fn.position&&b.each(["top","left"],function(e,n){b.cssHooks[n]={get:function(e,r){return r?(r=Wt(e,n),Yt.test(r)?b(e).position()[n]+"px":r):t}}})}),b.expr&&b.expr.filters&&(b.expr.filters.hidden=function(e){return 0>=e.offsetWidth&&0>=e.offsetHeight||!b.support.reliableHiddenOffsets&&"none"===(e.style&&e.style.display||b.css(e,"display"))},b.expr.filters.visible=function(e){return!b.expr.filters.hidden(e)}),b.each({margin:"",padding:"",border:"Width"},function(e,t){b.cssHooks[e+t]={expand:function(n){var r=0,i={},o="string"==typeof n?n.split(" "):[n];for(;4>r;r++)i[e+Zt[r]+t]=o[r]||o[r-2]||o[0];return i}},Ut.test(e)||(b.cssHooks[e+t].set=on)});var cn=/%20/g,pn=/\[\]$/,fn=/\r?\n/g,dn=/^(?:submit|button|image|reset|file)$/i,hn=/^(?:input|select|textarea|keygen)/i;b.fn.extend({serialize:function(){return b.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=b.prop(this,"elements");return e?b.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!b(this).is(":disabled")&&hn.test(this.nodeName)&&!dn.test(e)&&(this.checked||!Nt.test(e))}).map(function(e,t){var n=b(this).val();return null==n?null:b.isArray(n)?b.map(n,function(e){return{name:t.name,value:e.replace(fn,"\r\n")}}):{name:t.name,value:n.replace(fn,"\r\n")}}).get()}}),b.param=function(e,n){var r,i=[],o=function(e,t){t=b.isFunction(t)?t():null==t?"":t,i[i.length]=encodeURIComponent(e)+"="+encodeURIComponent(t)};if(n===t&&(n=b.ajaxSettings&&b.ajaxSettings.traditional),b.isArray(e)||e.jquery&&!b.isPlainObject(e))b.each(e,function(){o(this.name,this.value)});else for(r in e)gn(r,e[r],n,o);return i.join("&").replace(cn,"+")};function gn(e,t,n,r){var i;if(b.isArray(t))b.each(t,function(t,i){n||pn.test(e)?r(e,i):gn(e+"["+("object"==typeof i?t:"")+"]",i,n,r)});else if(n||"object"!==b.type(t))r(e,t);else for(i in t)gn(e+"["+i+"]",t[i],n,r)}b.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(e,t){b.fn[t]=function(e,n){return arguments.length>0?this.on(t,null,e,n):this.trigger(t)}}),b.fn.hover=function(e,t){return this.mouseenter(e).mouseleave(t||e)};var mn,yn,vn=b.now(),bn=/\?/,xn=/#.*$/,wn=/([?&])_=[^&]*/,Tn=/^(.*?):[ \t]*([^\r\n]*)\r?$/gm,Nn=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Cn=/^(?:GET|HEAD)$/,kn=/^\/\//,En=/^([\w.+-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,Sn=b.fn.load,An={},jn={},Dn="*/".concat("*");try{yn=a.href}catch(Ln){yn=o.createElement("a"),yn.href="",yn=yn.href}mn=En.exec(yn.toLowerCase())||[];function Hn(e){return function(t,n){"string"!=typeof t&&(n=t,t="*");var r,i=0,o=t.toLowerCase().match(w)||[];if(b.isFunction(n))while(r=o[i++])"+"===r[0]?(r=r.slice(1)||"*",(e[r]=e[r]||[]).unshift(n)):(e[r]=e[r]||[]).push(n)}}function qn(e,n,r,i){var o={},a=e===jn;function s(u){var l;return o[u]=!0,b.each(e[u]||[],function(e,u){var c=u(n,r,i);return"string"!=typeof c||a||o[c]?a?!(l=c):t:(n.dataTypes.unshift(c),s(c),!1)}),l}return s(n.dataTypes[0])||!o["*"]&&s("*")}function Mn(e,n){var r,i,o=b.ajaxSettings.flatOptions||{};for(i in n)n[i]!==t&&((o[i]?e:r||(r={}))[i]=n[i]);return r&&b.extend(!0,e,r),e}b.fn.load=function(e,n,r){if("string"!=typeof e&&Sn)return Sn.apply(this,arguments);var i,o,a,s=this,u=e.indexOf(" ");return u>=0&&(i=e.slice(u,e.length),e=e.slice(0,u)),b.isFunction(n)?(r=n,n=t):n&&"object"==typeof n&&(a="POST"),s.length>0&&b.ajax({url:e,type:a,dataType:"html",data:n}).done(function(e){o=arguments,s.html(i?b("<div>").append(b.parseHTML(e)).find(i):e)}).complete(r&&function(e,t){s.each(r,o||[e.responseText,t,e])}),this},b.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){b.fn[t]=function(e){return this.on(t,e)}}),b.each(["get","post"],function(e,n){b[n]=function(e,r,i,o){return b.isFunction(r)&&(o=o||i,i=r,r=t),b.ajax({url:e,type:n,dataType:o,data:r,success:i})}}),b.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:yn,type:"GET",isLocal:Nn.test(mn[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Dn,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":e.String,"text html":!0,"text json":b.parseJSON,"text xml":b.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?Mn(Mn(e,b.ajaxSettings),t):Mn(b.ajaxSettings,e)},ajaxPrefilter:Hn(An),ajaxTransport:Hn(jn),ajax:function(e,n){"object"==typeof e&&(n=e,e=t),n=n||{};var r,i,o,a,s,u,l,c,p=b.ajaxSetup({},n),f=p.context||p,d=p.context&&(f.nodeType||f.jquery)?b(f):b.event,h=b.Deferred(),g=b.Callbacks("once memory"),m=p.statusCode||{},y={},v={},x=0,T="canceled",N={readyState:0,getResponseHeader:function(e){var t;if(2===x){if(!c){c={};while(t=Tn.exec(a))c[t[1].toLowerCase()]=t[2]}t=c[e.toLowerCase()]}return null==t?null:t},getAllResponseHeaders:function(){return 2===x?a:null},setRequestHeader:function(e,t){var n=e.toLowerCase();return x||(e=v[n]=v[n]||e,y[e]=t),this},overrideMimeType:function(e){return x||(p.mimeType=e),this},statusCode:function(e){var t;if(e)if(2>x)for(t in e)m[t]=[m[t],e[t]];else N.always(e[N.status]);return this},abort:function(e){var t=e||T;return l&&l.abort(t),k(0,t),this}};if(h.promise(N).complete=g.add,N.success=N.done,N.error=N.fail,p.url=((e||p.url||yn)+"").replace(xn,"").replace(kn,mn[1]+"//"),p.type=n.method||n.type||p.method||p.type,p.dataTypes=b.trim(p.dataType||"*").toLowerCase().match(w)||[""],null==p.crossDomain&&(r=En.exec(p.url.toLowerCase()),p.crossDomain=!(!r||r[1]===mn[1]&&r[2]===mn[2]&&(r[3]||("http:"===r[1]?80:443))==(mn[3]||("http:"===mn[1]?80:443)))),p.data&&p.processData&&"string"!=typeof p.data&&(p.data=b.param(p.data,p.traditional)),qn(An,p,n,N),2===x)return N;u=p.global,u&&0===b.active++&&b.event.trigger("ajaxStart"),p.type=p.type.toUpperCase(),p.hasContent=!Cn.test(p.type),o=p.url,p.hasContent||(p.data&&(o=p.url+=(bn.test(o)?"&":"?")+p.data,delete p.data),p.cache===!1&&(p.url=wn.test(o)?o.replace(wn,"$1_="+vn++):o+(bn.test(o)?"&":"?")+"_="+vn++)),p.ifModified&&(b.lastModified[o]&&N.setRequestHeader("If-Modified-Since",b.lastModified[o]),b.etag[o]&&N.setRequestHeader("If-None-Match",b.etag[o])),(p.data&&p.hasContent&&p.contentType!==!1||n.contentType)&&N.setRequestHeader("Content-Type",p.contentType),N.setRequestHeader("Accept",p.dataTypes[0]&&p.accepts[p.dataTypes[0]]?p.accepts[p.dataTypes[0]]+("*"!==p.dataTypes[0]?", "+Dn+"; q=0.01":""):p.accepts["*"]);for(i in p.headers)N.setRequestHeader(i,p.headers[i]);if(p.beforeSend&&(p.beforeSend.call(f,N,p)===!1||2===x))return N.abort();T="abort";for(i in{success:1,error:1,complete:1})N[i](p[i]);if(l=qn(jn,p,n,N)){N.readyState=1,u&&d.trigger("ajaxSend",[N,p]),p.async&&p.timeout>0&&(s=setTimeout(function(){N.abort("timeout")},p.timeout));try{x=1,l.send(y,k)}catch(C){if(!(2>x))throw C;k(-1,C)}}else k(-1,"No Transport");function k(e,n,r,i){var c,y,v,w,T,C=n;2!==x&&(x=2,s&&clearTimeout(s),l=t,a=i||"",N.readyState=e>0?4:0,r&&(w=_n(p,N,r)),e>=200&&300>e||304===e?(p.ifModified&&(T=N.getResponseHeader("Last-Modified"),T&&(b.lastModified[o]=T),T=N.getResponseHeader("etag"),T&&(b.etag[o]=T)),204===e?(c=!0,C="nocontent"):304===e?(c=!0,C="notmodified"):(c=Fn(p,w),C=c.state,y=c.data,v=c.error,c=!v)):(v=C,(e||!C)&&(C="error",0>e&&(e=0))),N.status=e,N.statusText=(n||C)+"",c?h.resolveWith(f,[y,C,N]):h.rejectWith(f,[N,C,v]),N.statusCode(m),m=t,u&&d.trigger(c?"ajaxSuccess":"ajaxError",[N,p,c?y:v]),g.fireWith(f,[N,C]),u&&(d.trigger("ajaxComplete",[N,p]),--b.active||b.event.trigger("ajaxStop")))}return N},getScript:function(e,n){return b.get(e,t,n,"script")},getJSON:function(e,t,n){return b.get(e,t,n,"json")}});function _n(e,n,r){var i,o,a,s,u=e.contents,l=e.dataTypes,c=e.responseFields;for(s in c)s in r&&(n[c[s]]=r[s]);while("*"===l[0])l.shift(),o===t&&(o=e.mimeType||n.getResponseHeader("Content-Type"));if(o)for(s in u)if(u[s]&&u[s].test(o)){l.unshift(s);break}if(l[0]in r)a=l[0];else{for(s in r){if(!l[0]||e.converters[s+" "+l[0]]){a=s;break}i||(i=s)}a=a||i}return a?(a!==l[0]&&l.unshift(a),r[a]):t}function Fn(e,t){var n,r,i,o,a={},s=0,u=e.dataTypes.slice(),l=u[0];if(e.dataFilter&&(t=e.dataFilter(t,e.dataType)),u[1])for(i in e.converters)a[i.toLowerCase()]=e.converters[i];for(;r=u[++s];)if("*"!==r){if("*"!==l&&l!==r){if(i=a[l+" "+r]||a["* "+r],!i)for(n in a)if(o=n.split(" "),o[1]===r&&(i=a[l+" "+o[0]]||a["* "+o[0]])){i===!0?i=a[n]:a[n]!==!0&&(r=o[0],u.splice(s--,0,r));break}if(i!==!0)if(i&&e["throws"])t=i(t);else try{t=i(t)}catch(c){return{state:"parsererror",error:i?c:"No conversion from "+l+" to "+r}}}l=r}return{state:"success",data:t}}b.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(e){return b.globalEval(e),e}}}),b.ajaxPrefilter("script",function(e){e.cache===t&&(e.cache=!1),e.crossDomain&&(e.type="GET",e.global=!1)}),b.ajaxTransport("script",function(e){if(e.crossDomain){var n,r=o.head||b("head")[0]||o.documentElement;return{send:function(t,i){n=o.createElement("script"),n.async=!0,e.scriptCharset&&(n.charset=e.scriptCharset),n.src=e.url,n.onload=n.onreadystatechange=function(e,t){(t||!n.readyState||/loaded|complete/.test(n.readyState))&&(n.onload=n.onreadystatechange=null,n.parentNode&&n.parentNode.removeChild(n),n=null,t||i(200,"success"))},r.insertBefore(n,r.firstChild)},abort:function(){n&&n.onload(t,!0)}}}});var On=[],Bn=/(=)\?(?=&|$)|\?\?/;b.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=On.pop()||b.expando+"_"+vn++;return this[e]=!0,e}}),b.ajaxPrefilter("json jsonp",function(n,r,i){var o,a,s,u=n.jsonp!==!1&&(Bn.test(n.url)?"url":"string"==typeof n.data&&!(n.contentType||"").indexOf("application/x-www-form-urlencoded")&&Bn.test(n.data)&&"data");return u||"jsonp"===n.dataTypes[0]?(o=n.jsonpCallback=b.isFunction(n.jsonpCallback)?n.jsonpCallback():n.jsonpCallback,u?n[u]=n[u].replace(Bn,"$1"+o):n.jsonp!==!1&&(n.url+=(bn.test(n.url)?"&":"?")+n.jsonp+"="+o),n.converters["script json"]=function(){return s||b.error(o+" was not called"),s[0]},n.dataTypes[0]="json",a=e[o],e[o]=function(){s=arguments},i.always(function(){e[o]=a,n[o]&&(n.jsonpCallback=r.jsonpCallback,On.push(o)),s&&b.isFunction(a)&&a(s[0]),s=a=t}),"script"):t});var Pn,Rn,Wn=0,$n=e.ActiveXObject&&function(){var e;for(e in Pn)Pn[e](t,!0)};function In(){try{return new e.XMLHttpRequest}catch(t){}}function zn(){try{return new e.ActiveXObject("Microsoft.XMLHTTP")}catch(t){}}b.ajaxSettings.xhr=e.ActiveXObject?function(){return!this.isLocal&&In()||zn()}:In,Rn=b.ajaxSettings.xhr(),b.support.cors=!!Rn&&"withCredentials"in Rn,Rn=b.support.ajax=!!Rn,Rn&&b.ajaxTransport(function(n){if(!n.crossDomain||b.support.cors){var r;return{send:function(i,o){var a,s,u=n.xhr();if(n.username?u.open(n.type,n.url,n.async,n.username,n.password):u.open(n.type,n.url,n.async),n.xhrFields)for(s in n.xhrFields)u[s]=n.xhrFields[s];n.mimeType&&u.overrideMimeType&&u.overrideMimeType(n.mimeType),n.crossDomain||i["X-Requested-With"]||(i["X-Requested-With"]="XMLHttpRequest");try{for(s in i)u.setRequestHeader(s,i[s])}catch(l){}u.send(n.hasContent&&n.data||null),r=function(e,i){var s,l,c,p;try{if(r&&(i||4===u.readyState))if(r=t,a&&(u.onreadystatechange=b.noop,$n&&delete Pn[a]),i)4!==u.readyState&&u.abort();else{p={},s=u.status,l=u.getAllResponseHeaders(),"string"==typeof u.responseText&&(p.text=u.responseText);try{c=u.statusText}catch(f){c=""}s||!n.isLocal||n.crossDomain?1223===s&&(s=204):s=p.text?200:404}}catch(d){i||o(-1,d)}p&&o(s,c,p,l)},n.async?4===u.readyState?setTimeout(r):(a=++Wn,$n&&(Pn||(Pn={},b(e).unload($n)),Pn[a]=r),u.onreadystatechange=r):r()},abort:function(){r&&r(t,!0)}}}});var Xn,Un,Vn=/^(?:toggle|show|hide)$/,Yn=RegExp("^(?:([+-])=|)("+x+")([a-z%]*)$","i"),Jn=/queueHooks$/,Gn=[nr],Qn={"*":[function(e,t){var n,r,i=this.createTween(e,t),o=Yn.exec(t),a=i.cur(),s=+a||0,u=1,l=20;if(o){if(n=+o[2],r=o[3]||(b.cssNumber[e]?"":"px"),"px"!==r&&s){s=b.css(i.elem,e,!0)||n||1;do u=u||".5",s/=u,b.style(i.elem,e,s+r);while(u!==(u=i.cur()/a)&&1!==u&&--l)}i.unit=r,i.start=s,i.end=o[1]?s+(o[1]+1)*n:n}return i}]};function Kn(){return setTimeout(function(){Xn=t}),Xn=b.now()}function Zn(e,t){b.each(t,function(t,n){var r=(Qn[t]||[]).concat(Qn["*"]),i=0,o=r.length;for(;o>i;i++)if(r[i].call(e,t,n))return})}function er(e,t,n){var r,i,o=0,a=Gn.length,s=b.Deferred().always(function(){delete u.elem}),u=function(){if(i)return!1;var t=Xn||Kn(),n=Math.max(0,l.startTime+l.duration-t),r=n/l.duration||0,o=1-r,a=0,u=l.tweens.length;for(;u>a;a++)l.tweens[a].run(o);return s.notifyWith(e,[l,o,n]),1>o&&u?n:(s.resolveWith(e,[l]),!1)},l=s.promise({elem:e,props:b.extend({},t),opts:b.extend(!0,{specialEasing:{}},n),originalProperties:t,originalOptions:n,startTime:Xn||Kn(),duration:n.duration,tweens:[],createTween:function(t,n){var r=b.Tween(e,l.opts,t,n,l.opts.specialEasing[t]||l.opts.easing);return l.tweens.push(r),r},stop:function(t){var n=0,r=t?l.tweens.length:0;if(i)return this;for(i=!0;r>n;n++)l.tweens[n].run(1);return t?s.resolveWith(e,[l,t]):s.rejectWith(e,[l,t]),this}}),c=l.props;for(tr(c,l.opts.specialEasing);a>o;o++)if(r=Gn[o].call(l,e,c,l.opts))return r;return Zn(l,c),b.isFunction(l.opts.start)&&l.opts.start.call(e,l),b.fx.timer(b.extend(u,{elem:e,anim:l,queue:l.opts.queue})),l.progress(l.opts.progress).done(l.opts.done,l.opts.complete).fail(l.opts.fail).always(l.opts.always)}function tr(e,t){var n,r,i,o,a;for(i in e)if(r=b.camelCase(i),o=t[r],n=e[i],b.isArray(n)&&(o=n[1],n=e[i]=n[0]),i!==r&&(e[r]=n,delete e[i]),a=b.cssHooks[r],a&&"expand"in a){n=a.expand(n),delete e[r];for(i in n)i in e||(e[i]=n[i],t[i]=o)}else t[r]=o}b.Animation=b.extend(er,{tweener:function(e,t){b.isFunction(e)?(t=e,e=["*"]):e=e.split(" ");var n,r=0,i=e.length;for(;i>r;r++)n=e[r],Qn[n]=Qn[n]||[],Qn[n].unshift(t)},prefilter:function(e,t){t?Gn.unshift(e):Gn.push(e)}});function nr(e,t,n){var r,i,o,a,s,u,l,c,p,f=this,d=e.style,h={},g=[],m=e.nodeType&&nn(e);n.queue||(c=b._queueHooks(e,"fx"),null==c.unqueued&&(c.unqueued=0,p=c.empty.fire,c.empty.fire=function(){c.unqueued||p()}),c.unqueued++,f.always(function(){f.always(function(){c.unqueued--,b.queue(e,"fx").length||c.empty.fire()})})),1===e.nodeType&&("height"in t||"width"in t)&&(n.overflow=[d.overflow,d.overflowX,d.overflowY],"inline"===b.css(e,"display")&&"none"===b.css(e,"float")&&(b.support.inlineBlockNeedsLayout&&"inline"!==un(e.nodeName)?d.zoom=1:d.display="inline-block")),n.overflow&&(d.overflow="hidden",b.support.shrinkWrapBlocks||f.always(function(){d.overflow=n.overflow[0],d.overflowX=n.overflow[1],d.overflowY=n.overflow[2]}));for(i in t)if(a=t[i],Vn.exec(a)){if(delete t[i],u=u||"toggle"===a,a===(m?"hide":"show"))continue;g.push(i)}if(o=g.length){s=b._data(e,"fxshow")||b._data(e,"fxshow",{}),"hidden"in s&&(m=s.hidden),u&&(s.hidden=!m),m?b(e).show():f.done(function(){b(e).hide()}),f.done(function(){var t;b._removeData(e,"fxshow");for(t in h)b.style(e,t,h[t])});for(i=0;o>i;i++)r=g[i],l=f.createTween(r,m?s[r]:0),h[r]=s[r]||b.style(e,r),r in s||(s[r]=l.start,m&&(l.end=l.start,l.start="width"===r||"height"===r?1:0))}}function rr(e,t,n,r,i){return new rr.prototype.init(e,t,n,r,i)}b.Tween=rr,rr.prototype={constructor:rr,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||"swing",this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(b.cssNumber[n]?"":"px")},cur:function(){var e=rr.propHooks[this.prop];return e&&e.get?e.get(this):rr.propHooks._default.get(this)},run:function(e){var t,n=rr.propHooks[this.prop];return this.pos=t=this.options.duration?b.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):rr.propHooks._default.set(this),this}},rr.prototype.init.prototype=rr.prototype,rr.propHooks={_default:{get:function(e){var t;return null==e.elem[e.prop]||e.elem.style&&null!=e.elem.style[e.prop]?(t=b.css(e.elem,e.prop,""),t&&"auto"!==t?t:0):e.elem[e.prop]},set:function(e){b.fx.step[e.prop]?b.fx.step[e.prop](e):e.elem.style&&(null!=e.elem.style[b.cssProps[e.prop]]||b.cssHooks[e.prop])?b.style(e.elem,e.prop,e.now+e.unit):e.elem[e.prop]=e.now}}},rr.propHooks.scrollTop=rr.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},b.each(["toggle","show","hide"],function(e,t){var n=b.fn[t];b.fn[t]=function(e,r,i){return null==e||"boolean"==typeof e?n.apply(this,arguments):this.animate(ir(t,!0),e,r,i)}}),b.fn.extend({fadeTo:function(e,t,n,r){return this.filter(nn).css("opacity",0).show().end().animate({opacity:t},e,n,r)},animate:function(e,t,n,r){var i=b.isEmptyObject(e),o=b.speed(t,n,r),a=function(){var t=er(this,b.extend({},e),o);a.finish=function(){t.stop(!0)},(i||b._data(this,"finish"))&&t.stop(!0)};return a.finish=a,i||o.queue===!1?this.each(a):this.queue(o.queue,a)},stop:function(e,n,r){var i=function(e){var t=e.stop;delete e.stop,t(r)};return"string"!=typeof e&&(r=n,n=e,e=t),n&&e!==!1&&this.queue(e||"fx",[]),this.each(function(){var t=!0,n=null!=e&&e+"queueHooks",o=b.timers,a=b._data(this);if(n)a[n]&&a[n].stop&&i(a[n]);else for(n in a)a[n]&&a[n].stop&&Jn.test(n)&&i(a[n]);for(n=o.length;n--;)o[n].elem!==this||null!=e&&o[n].queue!==e||(o[n].anim.stop(r),t=!1,o.splice(n,1));(t||!r)&&b.dequeue(this,e)})},finish:function(e){return e!==!1&&(e=e||"fx"),this.each(function(){var t,n=b._data(this),r=n[e+"queue"],i=n[e+"queueHooks"],o=b.timers,a=r?r.length:0;for(n.finish=!0,b.queue(this,e,[]),i&&i.cur&&i.cur.finish&&i.cur.finish.call(this),t=o.length;t--;)o[t].elem===this&&o[t].queue===e&&(o[t].anim.stop(!0),o.splice(t,1));for(t=0;a>t;t++)r[t]&&r[t].finish&&r[t].finish.call(this);delete n.finish})}});function ir(e,t){var n,r={height:e},i=0;for(t=t?1:0;4>i;i+=2-t)n=Zt[i],r["margin"+n]=r["padding"+n]=e;return t&&(r.opacity=r.width=e),r}b.each({slideDown:ir("show"),slideUp:ir("hide"),slideToggle:ir("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(e,t){b.fn[e]=function(e,n,r){return this.animate(t,e,n,r)}}),b.speed=function(e,t,n){var r=e&&"object"==typeof e?b.extend({},e):{complete:n||!n&&t||b.isFunction(e)&&e,duration:e,easing:n&&t||t&&!b.isFunction(t)&&t};return r.duration=b.fx.off?0:"number"==typeof r.duration?r.duration:r.duration in b.fx.speeds?b.fx.speeds[r.duration]:b.fx.speeds._default,(null==r.queue||r.queue===!0)&&(r.queue="fx"),r.old=r.complete,r.complete=function(){b.isFunction(r.old)&&r.old.call(this),r.queue&&b.dequeue(this,r.queue)},r},b.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2}},b.timers=[],b.fx=rr.prototype.init,b.fx.tick=function(){var e,n=b.timers,r=0;for(Xn=b.now();n.length>r;r++)e=n[r],e()||n[r]!==e||n.splice(r--,1);n.length||b.fx.stop(),Xn=t},b.fx.timer=function(e){e()&&b.timers.push(e)&&b.fx.start()},b.fx.interval=13,b.fx.start=function(){Un||(Un=setInterval(b.fx.tick,b.fx.interval))},b.fx.stop=function(){clearInterval(Un),Un=null},b.fx.speeds={slow:600,fast:200,_default:400},b.fx.step={},b.expr&&b.expr.filters&&(b.expr.filters.animated=function(e){return b.grep(b.timers,function(t){return e===t.elem}).length}),b.fn.offset=function(e){if(arguments.length)return e===t?this:this.each(function(t){b.offset.setOffset(this,e,t)});var n,r,o={top:0,left:0},a=this[0],s=a&&a.ownerDocument;if(s)return n=s.documentElement,b.contains(n,a)?(typeof a.getBoundingClientRect!==i&&(o=a.getBoundingClientRect()),r=or(s),{top:o.top+(r.pageYOffset||n.scrollTop)-(n.clientTop||0),left:o.left+(r.pageXOffset||n.scrollLeft)-(n.clientLeft||0)}):o},b.offset={setOffset:function(e,t,n){var r=b.css(e,"position");"static"===r&&(e.style.position="relative");var i=b(e),o=i.offset(),a=b.css(e,"top"),s=b.css(e,"left"),u=("absolute"===r||"fixed"===r)&&b.inArray("auto",[a,s])>-1,l={},c={},p,f;u?(c=i.position(),p=c.top,f=c.left):(p=parseFloat(a)||0,f=parseFloat(s)||0),b.isFunction(t)&&(t=t.call(e,n,o)),null!=t.top&&(l.top=t.top-o.top+p),null!=t.left&&(l.left=t.left-o.left+f),"using"in t?t.using.call(e,l):i.css(l)}},b.fn.extend({position:function(){if(this[0]){var e,t,n={top:0,left:0},r=this[0];return"fixed"===b.css(r,"position")?t=r.getBoundingClientRect():(e=this.offsetParent(),t=this.offset(),b.nodeName(e[0],"html")||(n=e.offset()),n.top+=b.css(e[0],"borderTopWidth",!0),n.left+=b.css(e[0],"borderLeftWidth",!0)),{top:t.top-n.top-b.css(r,"marginTop",!0),left:t.left-n.left-b.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent||o.documentElement;while(e&&!b.nodeName(e,"html")&&"static"===b.css(e,"position"))e=e.offsetParent;return e||o.documentElement})}}),b.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(e,n){var r=/Y/.test(n);b.fn[e]=function(i){return b.access(this,function(e,i,o){var a=or(e);return o===t?a?n in a?a[n]:a.document.documentElement[i]:e[i]:(a?a.scrollTo(r?b(a).scrollLeft():o,r?o:b(a).scrollTop()):e[i]=o,t)},e,i,arguments.length,null)}});function or(e){return b.isWindow(e)?e:9===e.nodeType?e.defaultView||e.parentWindow:!1}b.each({Height:"height",Width:"width"},function(e,n){b.each({padding:"inner"+e,content:n,"":"outer"+e},function(r,i){b.fn[i]=function(i,o){var a=arguments.length&&(r||"boolean"!=typeof i),s=r||(i===!0||o===!0?"margin":"border");return b.access(this,function(n,r,i){var o;return b.isWindow(n)?n.document.documentElement["client"+e]:9===n.nodeType?(o=n.documentElement,Math.max(n.body["scroll"+e],o["scroll"+e],n.body["offset"+e],o["offset"+e],o["client"+e])):i===t?b.css(n,r,s):b.style(n,r,i,s)},n,a?i:t,a,null)}})}),e.jQuery=e.$=b,"function"==typeof define&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return b})})(window); |
/WebSVN/languages/NotUsed/finnish.inc |
---|
File deleted |
/WebSVN/languages/NotUsed/slovenian.inc |
---|
File deleted |
/WebSVN/languages/NotUsed/polish.inc |
---|
File deleted |
/WebSVN/languages/NotUsed/schinese.inc |
---|
File deleted |
/WebSVN/languages/NotUsed/tchinese.inc |
---|
File deleted |
/WebSVN/languages/NotUsed/portuguese.inc |
---|
File deleted |
/WebSVN/languages/NotUsed/catalan.inc |
---|
File deleted |
/WebSVN/languages/NotUsed/spanish.inc |
---|
File deleted |
/WebSVN/languages/NotUsed/french.inc |
---|
File deleted |
/WebSVN/languages/NotUsed/danish.inc |
---|
File deleted |
/WebSVN/languages/NotUsed/swedish.inc |
---|
File deleted |
/WebSVN/languages/NotUsed/dutch.inc |
---|
File deleted |
/WebSVN/languages/NotUsed/german.inc |
---|
File deleted |
/WebSVN/languages/NotUsed/korean.inc |
---|
File deleted |
/WebSVN/languages/NotUsed/russian.inc |
---|
File deleted |
/WebSVN/languages/NotUsed/japanese.inc |
---|
File deleted |
/WebSVN/languages/NotUsed/norwegian.inc |
---|
File deleted |
/WebSVN/languages/NotUsed/turkish.inc |
---|
File deleted |
/WebSVN/languages/czech.inc |
---|
File deleted |
/WebSVN/languages/english.inc |
---|
File deleted |
/WebSVN/languages/czech.php |
---|
0,0 → 1,124 |
<?php |
// WebSVN - Subversion repository viewing via the web using PHP |
// Copyright (C) 2004 Tim Armes |
// |
// This program is free software; you can redistribute it and/or modify |
// it under the terms of the GNU General Public License as published by |
// the Free Software Foundation; either version 2 of the License, or |
// (at your option) any later version. |
// |
// This program is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License |
// along with this program; if not, write to the Free Software |
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
// |
// -- |
// |
// czech.php |
// |
// Czech language strings |
$lang["LANGUAGETAG"] = "cs"; // Language tag (RFC 4646) for this translation. |
$lang["LANGUAGENAMEENGLISH"] = "Czech"; |
$lang["LANGUAGENAMENATIVE"] = "Česky"; |
$lang["LANGUAGENAMEHTML"] = "Česky"; |
$lang['BREADCRUMB_REPO_ROOT'] = '(root)'; |
$lang["LOG"] = "Záznam"; |
// $lang["DIFF"] = "Diff"; |
$lang["NOREP"] = "Není určen žádný repozitář"; |
$lang["NOPATH"] = "Cesta nebyla nalezena"; |
$lang["NOACCESS"] = "Nemáte dostatečná přístupová práva pro čtení adresáře"; |
$lang["RESTRICTED"] = "Omezený přístup"; |
$lang["SUPPLYREP"] = "Nastavte prosím cestu k repozitáři v include/config.php pomocí \$config->parentPath nebo \$config->addRepository<p>Podívejte se do insatlační příručky pro podrobnější informace"; |
$lang["DIFFREVS"] = "Rozdíly mezi revizemi"; |
$lang["AND"] = "a"; |
$lang["REV"] = "Revize"; |
// $lang["LINE"] = "Line"; |
$lang["LINENO"] = "Číslo řádky"; |
$lang["SHOWENTIREFILE"] = "Zobraz celý soubor"; |
$lang["SHOWCOMPACT"] = "Zobraz pouze rozdílné části"; |
// $lang["IGNOREWHITESPACE"] = "Ignore whitespace"; |
// $lang["REGARDWHITESPACE"] = "Regard whitespace"; |
// $lang["LISTING"] = "Directory listing"; |
// $lang["FILEDETAIL"] = "Details"; |
// $lang["VIEWAS"] = "View as"; |
$lang["DIFFPREV"] = "Porovnej s předchozí"; |
// $lang["BLAME"] = "Blame"; |
// $lang["BLAMEFOR"] = "Blame information for rev"; |
$lang["REVINFO"] = "Informace o revizi"; |
$lang["GOYOUNGEST"] = "Přejdi na současnou revizi"; |
$lang["LASTMOD"] = "Poslední změna"; |
$lang["LOGMSG"] = "Záznam"; |
$lang["CHANGES"] = "Změny"; |
$lang["SHOWCHANGED"] = "Zobraz změněné soubory"; |
$lang["HIDECHANGED"] = "Schovej změněné soubory"; |
$lang["NEWFILES"] = "Nové soubory"; |
$lang["CHANGEDFILES"] = "Změněné soubory"; |
$lang["DELETEDFILES"] = "Smazané soubory"; |
$lang["VIEWLOG"] = "Ukaž"; |
$lang["PATH"] = "Cesta"; |
$lang["AUTHOR"] = "Autor"; |
$lang["AGE"] = "Stáří"; |
$lang["CURDIR"] = "Aktuální adresář"; |
// $lang["TARBALL"] = "Tarball"; |
// $lang["DOWNLOAD"] = "Download"; |
$lang["PREV"] = "Předchozí"; |
$lang["NEXT"] = "Následující"; |
$lang["SHOWALL"] = "Ukaž všechny"; |
$lang["BADCMD"] = "Nepodařilo se spustit tento příkaz"; |
$lang["UNKNOWNREVISION"] = "Revize nebyla nalezena"; |
$lang["POWERED"] = "Poháněno <a href=\"https://websvnphp.github.io/\">WebSVN</a>"; |
$lang["PROJECTS"] = "Subversion Repozitáře"; |
$lang["SERVER"] = "Subversion Servery"; |
$lang["FILTER"] = "Nastavení filtrování"; |
$lang["STARTLOG"] = "Od revize"; |
$lang["ENDLOG"] = "Do revize"; |
$lang["MAXLOG"] = "Max revizí"; |
$lang["SEARCHLOG"] = "Hledat"; |
$lang["CLEARLOG"] = "Zruš aktuální filtr"; |
$lang["MORERESULTS"] = "Najdi další..."; |
$lang["NORESULTS"] = "Nejsou tu žádné zázanmy odpovídající vašim požadavkům"; |
$lang["NOMORERESULTS"] = "Nejsou tu žádné další záznamy odpovídající vašim požadavkům"; |
$lang["NOPREVREV"] = "Není předchozí revize."; |
$lang["RSSFEEDTITLE"] = "WebSVN RSS feed"; |
$lang["FILESMODIFIED"] = "soubor(y) změněn(y)"; |
$lang["RSSFEED"] = "RSS"; |
$lang["DAYLETTER"] = "d"; |
$lang["HOURLETTER"] = "h"; |
$lang["MINUTELETTER"] = "m"; |
$lang["SECONDLETTER"] = "s"; |
$lang["GO"] = "Go"; |
$lang["PATHCOMPARISON"] = "Porovnání cest"; |
$lang["COMPAREPATHS"] = "Porovnej cesty"; |
$lang["COMPAREREVS"] = "Porovnej revize"; |
$lang["PROPCHANGES"] = "Změněné vlastnosti:"; |
$lang["CONVFROM"] = "Toto porovnání ukazuje změny pro převedení"; |
$lang["TO"] = "na"; |
$lang["REVCOMP"] = "Reverzní porovnání"; |
$lang["COMPPATH"] = "Porovnej cestu:"; |
$lang["WITHPATH"] = "S umístěním:"; |
$lang["FILEDELETED"] = "Soubor smazán"; |
$lang["FILEADDED"] = "Nový soubor"; |
$lang['SEARCH'] = "Vyhledávání"; |
$lang['SEARCH_PLACEHOLDER'] = "Vyhledejte položky zde"; |
$lang['NOITEMSFOUND'] = "Žádné předměty nenalezeny"; |
/WebSVN/languages/english.php |
---|
0,0 → 1,125 |
<?php |
// WebSVN - Subversion repository viewing via the web using PHP |
// Copyright (C) 2004 Tim Armes |
// |
// This program is free software; you can redistribute it and/or modify |
// it under the terms of the GNU General Public License as published by |
// the Free Software Foundation; either version 2 of the License, or |
// (at your option) any later version. |
// |
// This program is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License |
// along with this program; if not, write to the Free Software |
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
// |
// -- |
// |
// english.php |
// |
// English language strings |
$lang["LANGUAGETAG"] = "en"; // Language tag (RFC 4646) for this translation. |
$lang["LANGUAGENAMEENGLISH"] = "English"; |
$lang["LANGUAGENAMENATIVE"] = "English"; |
$lang["LANGUAGENAMEHTML"] = "English"; |
$lang['BREADCRUMB_REPO_ROOT'] = '(root)'; |
$lang["LOG"] = "Log"; |
$lang["DIFF"] = "Diff"; |
$lang["NOREP"] = "No repository given."; |
$lang["NOPATH"] = "Path not found."; |
$lang["NOACCESS"] = "You do not have the necessary permissions to view this content."; |
$lang["RESTRICTED"] = "Restricted access."; |
$lang["SUPPLYREP"] = "Please set up a repository in include/config.php using <code>\$config->parentPath</code> or <code>\$config->addRepository</code>. See the installation guide for more details."; |
$lang["DIFFREVS"] = "Diff between revs"; |
$lang["AND"] = "and"; |
$lang["REV"] = "Rev"; |
$lang["LINE"] = "Line"; |
$lang["LINENO"] = "Line No."; |
$lang["SHOWENTIREFILE"] = "Show entire file"; |
$lang["SHOWCOMPACT"] = "Only display areas with differences"; |
$lang["IGNOREWHITESPACE"] = "Ignore whitespace"; |
$lang["REGARDWHITESPACE"] = "Regard whitespace"; |
$lang["LISTING"] = "Directory listing"; |
$lang["FILEDETAIL"] = "Details"; |
$lang["VIEWAS"] = "View as"; |
$lang["DIFFPREV"] = "Compare with Previous"; |
$lang["BLAME"] = "Blame"; |
$lang["BLAMEFOR"] = "Blame information for rev"; |
$lang["REVINFO"] = "Revision Information"; |
$lang["GOYOUNGEST"] = "Go to most recent revision"; |
$lang["LASTMOD"] = "Last modification"; |
$lang["LOGMSG"] = "Log message"; |
$lang["CHANGES"] = "Changes"; |
$lang["SHOWCHANGED"] = "Show changed files"; |
$lang["HIDECHANGED"] = "Hide changed files"; |
$lang["NEWFILES"] = "New Files"; |
$lang["CHANGEDFILES"] = "Modified files"; |
$lang["DELETEDFILES"] = "Deleted files"; |
$lang["VIEWLOG"] = "View Log"; |
$lang["PATH"] = "Path"; |
$lang["AUTHOR"] = "Author"; |
$lang["AGE"] = "Age"; |
$lang["CURDIR"] = "Current Directory"; |
$lang["TARBALL"] = "Tarball"; |
$lang["DOWNLOAD"] = "Download"; |
$lang["PREV"] = "Prev"; |
$lang["NEXT"] = "Next"; |
$lang["SHOWALL"] = "Show All"; |
$lang["BADCMD"] = "Error running this command"; |
$lang["UNKNOWNREVISION"] = "Revision not found"; |
$lang["POWERED"] = "Powered by <a href=\"https://websvnphp.github.io/\">WebSVN</a>"; |
$lang["PROJECTS"] = "Subversion Repositories"; |
$lang["SERVER"] = "Subversion Server"; |
$lang["FILTER"] = "Filtering Options"; |
$lang["STARTLOG"] = "From rev"; |
$lang["ENDLOG"] = "To rev"; |
$lang["MAXLOG"] = "Max revs"; |
$lang["SEARCHLOG"] = "Search history for"; |
$lang["CLEARLOG"] = "Clear current filter"; |
$lang["MORERESULTS"] = "Find more matches..."; |
$lang["NORESULTS"] = "There are no logs matching your query"; |
$lang["NOMORERESULTS"] = "There are no more logs matching your query"; |
$lang["NOPREVREV"] = "No previous revision"; |
$lang["RSSFEEDTITLE"] = "WebSVN RSS feed"; |
$lang["FILESMODIFIED"] = "file(s) modified"; |
$lang["RSSFEED"] = "RSS feed"; |
$lang["DAYLETTER"] = "d"; |
$lang["HOURLETTER"] = "h"; |
$lang["MINUTELETTER"] = "m"; |
$lang["SECONDLETTER"] = "s"; |
$lang["GO"] = "Go"; |
$lang["PATHCOMPARISON"] = "Path Comparison"; |
$lang["COMPAREPATHS"] = "Compare Paths"; |
$lang["COMPAREREVS"] = "Compare Revisions"; |
$lang["PROPCHANGES"] = "Property changes:"; |
$lang["CONVFROM"] = "This comparison shows the changes necessary to convert path "; |
$lang["TO"] = "to"; |
$lang["REVCOMP"] = "Reverse comparison"; |
$lang["COMPPATH"] = "Compare Path:"; |
$lang["WITHPATH"] = "With Path:"; |
$lang["FILEDELETED"] = "File deleted"; |
$lang["FILEADDED"] = "New file"; |
$lang['NOSEARCHTERM'] = "No search term provided"; |
$lang['SEARCH'] = "Search"; |
$lang['SEARCH_PLACEHOLDER'] = "Search for items here"; |
$lang['NOITEMSFOUND'] = "No Items Found"; |
/WebSVN/license.txt |
---|
0,0 → 1,280 |
GNU GENERAL PUBLIC LICENSE |
Version 2, June 1991 |
Copyright (C) 1989, 1991 Free Software Foundation, Inc. |
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
Everyone is permitted to copy and distribute verbatim copies |
of this license document, but changing it is not allowed. |
Preamble |
The licenses for most software are designed to take away your |
freedom to share and change it. By contrast, the GNU General Public |
License is intended to guarantee your freedom to share and change free |
software--to make sure the software is free for all its users. This |
General Public License applies to most of the Free Software |
Foundation's software and to any other program whose authors commit to |
using it. (Some other Free Software Foundation software is covered by |
the GNU Library General Public License instead.) You can apply it to |
your programs, too. |
When we speak of free software, we are referring to freedom, not |
price. Our General Public Licenses are designed to make sure that you |
have the freedom to distribute copies of free software (and charge for |
this service if you wish), that you receive source code or can get it |
if you want it, that you can change the software or use pieces of it |
in new free programs; and that you know you can do these things. |
To protect your rights, we need to make restrictions that forbid |
anyone to deny you these rights or to ask you to surrender the rights. |
These restrictions translate to certain responsibilities for you if you |
distribute copies of the software, or if you modify it. |
For example, if you distribute copies of such a program, whether |
gratis or for a fee, you must give the recipients all the rights that |
you have. You must make sure that they, too, receive or can get the |
source code. And you must show them these terms so they know their |
rights. |
We protect your rights with two steps: (1) copyright the software, and |
(2) offer you this license which gives you legal permission to copy, |
distribute and/or modify the software. |
Also, for each author's protection and ours, we want to make certain |
that everyone understands that there is no warranty for this free |
software. If the software is modified by someone else and passed on, we |
want its recipients to know that what they have is not the original, so |
that any problems introduced by others will not reflect on the original |
authors' reputations. |
Finally, any free program is threatened constantly by software |
patents. We wish to avoid the danger that redistributors of a free |
program will individually obtain patent licenses, in effect making the |
program proprietary. To prevent this, we have made it clear that any |
patent must be licensed for everyone's free use or not licensed at all. |
The precise terms and conditions for copying, distribution and |
modification follow. |
GNU GENERAL PUBLIC LICENSE |
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION |
0. This License applies to any program or other work which contains |
a notice placed by the copyright holder saying it may be distributed |
under the terms of this General Public License. The "Program", below, |
refers to any such program or work, and a "work based on the Program" |
means either the Program or any derivative work under copyright law: |
that is to say, a work containing the Program or a portion of it, |
either verbatim or with modifications and/or translated into another |
language. (Hereinafter, translation is included without limitation in |
the term "modification".) Each licensee is addressed as "you". |
Activities other than copying, distribution and modification are not |
covered by this License; they are outside its scope. The act of |
running the Program is not restricted, and the output from the Program |
is covered only if its contents constitute a work based on the |
Program (independent of having been made by running the Program). |
Whether that is true depends on what the Program does. |
1. You may copy and distribute verbatim copies of the Program's |
source code as you receive it, in any medium, provided that you |
conspicuously and appropriately publish on each copy an appropriate |
copyright notice and disclaimer of warranty; keep intact all the |
notices that refer to this License and to the absence of any warranty; |
and give any other recipients of the Program a copy of this License |
along with the Program. |
You may charge a fee for the physical act of transferring a copy, and |
you may at your option offer warranty protection in exchange for a fee. |
2. You may modify your copy or copies of the Program or any portion |
of it, thus forming a work based on the Program, and copy and |
distribute such modifications or work under the terms of Section 1 |
above, provided that you also meet all of these conditions: |
a) You must cause the modified files to carry prominent notices |
stating that you changed the files and the date of any change. |
b) You must cause any work that you distribute or publish, that in |
whole or in part contains or is derived from the Program or any |
part thereof, to be licensed as a whole at no charge to all third |
parties under the terms of this License. |
c) If the modified program normally reads commands interactively |
when run, you must cause it, when started running for such |
interactive use in the most ordinary way, to print or display an |
announcement including an appropriate copyright notice and a |
notice that there is no warranty (or else, saying that you provide |
a warranty) and that users may redistribute the program under |
these conditions, and telling the user how to view a copy of this |
License. (Exception: if the Program itself is interactive but |
does not normally print such an announcement, your work based on |
the Program is not required to print an announcement.) |
These requirements apply to the modified work as a whole. If |
identifiable sections of that work are not derived from the Program, |
and can be reasonably considered independent and separate works in |
themselves, then this License, and its terms, do not apply to those |
sections when you distribute them as separate works. But when you |
distribute the same sections as part of a whole which is a work based |
on the Program, the distribution of the whole must be on the terms of |
this License, whose permissions for other licensees extend to the |
entire whole, and thus to each and every part regardless of who wrote it. |
Thus, it is not the intent of this section to claim rights or contest |
your rights to work written entirely by you; rather, the intent is to |
exercise the right to control the distribution of derivative or |
collective works based on the Program. |
In addition, mere aggregation of another work not based on the Program |
with the Program (or with a work based on the Program) on a volume of |
a storage or distribution medium does not bring the other work under |
the scope of this License. |
3. You may copy and distribute the Program (or a work based on it, |
under Section 2) in object code or executable form under the terms of |
Sections 1 and 2 above provided that you also do one of the following: |
a) Accompany it with the complete corresponding machine-readable |
source code, which must be distributed under the terms of Sections |
1 and 2 above on a medium customarily used for software interchange; or, |
b) Accompany it with a written offer, valid for at least three |
years, to give any third party, for a charge no more than your |
cost of physically performing source distribution, a complete |
machine-readable copy of the corresponding source code, to be |
distributed under the terms of Sections 1 and 2 above on a medium |
customarily used for software interchange; or, |
c) Accompany it with the information you received as to the offer |
to distribute corresponding source code. (This alternative is |
allowed only for noncommercial distribution and only if you |
received the program in object code or executable form with such |
an offer, in accord with Subsection b above.) |
The source code for a work means the preferred form of the work for |
making modifications to it. For an executable work, complete source |
code means all the source code for all modules it contains, plus any |
associated interface definition files, plus the scripts used to |
control compilation and installation of the executable. However, as a |
special exception, the source code distributed need not include |
anything that is normally distributed (in either source or binary |
form) with the major components (compiler, kernel, and so on) of the |
operating system on which the executable runs, unless that component |
itself accompanies the executable. |
If distribution of executable or object code is made by offering |
access to copy from a designated place, then offering equivalent |
access to copy the source code from the same place counts as |
distribution of the source code, even though third parties are not |
compelled to copy the source along with the object code. |
4. You may not copy, modify, sublicense, or distribute the Program |
except as expressly provided under this License. Any attempt |
otherwise to copy, modify, sublicense or distribute the Program is |
void, and will automatically terminate your rights under this License. |
However, parties who have received copies, or rights, from you under |
this License will not have their licenses terminated so long as such |
parties remain in full compliance. |
5. You are not required to accept this License, since you have not |
signed it. However, nothing else grants you permission to modify or |
distribute the Program or its derivative works. These actions are |
prohibited by law if you do not accept this License. Therefore, by |
modifying or distributing the Program (or any work based on the |
Program), you indicate your acceptance of this License to do so, and |
all its terms and conditions for copying, distributing or modifying |
the Program or works based on it. |
6. Each time you redistribute the Program (or any work based on the |
Program), the recipient automatically receives a license from the |
original licensor to copy, distribute or modify the Program subject to |
these terms and conditions. You may not impose any further |
restrictions on the recipients' exercise of the rights granted herein. |
You are not responsible for enforcing compliance by third parties to |
this License. |
7. If, as a consequence of a court judgment or allegation of patent |
infringement or for any other reason (not limited to patent issues), |
conditions are imposed on you (whether by court order, agreement or |
otherwise) that contradict the conditions of this License, they do not |
excuse you from the conditions of this License. If you cannot |
distribute so as to satisfy simultaneously your obligations under this |
License and any other pertinent obligations, then as a consequence you |
may not distribute the Program at all. For example, if a patent |
license would not permit royalty-free redistribution of the Program by |
all those who receive copies directly or indirectly through you, then |
the only way you could satisfy both it and this License would be to |
refrain entirely from distribution of the Program. |
If any portion of this section is held invalid or unenforceable under |
any particular circumstance, the balance of the section is intended to |
apply and the section as a whole is intended to apply in other |
circumstances. |
It is not the purpose of this section to induce you to infringe any |
patents or other property right claims or to contest validity of any |
such claims; this section has the sole purpose of protecting the |
integrity of the free software distribution system, which is |
implemented by public license practices. Many people have made |
generous contributions to the wide range of software distributed |
through that system in reliance on consistent application of that |
system; it is up to the author/donor to decide if he or she is willing |
to distribute software through any other system and a licensee cannot |
impose that choice. |
This section is intended to make thoroughly clear what is believed to |
be a consequence of the rest of this License. |
8. If the distribution and/or use of the Program is restricted in |
certain countries either by patents or by copyrighted interfaces, the |
original copyright holder who places the Program under this License |
may add an explicit geographical distribution limitation excluding |
those countries, so that distribution is permitted only in or among |
countries not thus excluded. In such case, this License incorporates |
the limitation as if written in the body of this License. |
9. The Free Software Foundation may publish revised and/or new versions |
of the General Public License from time to time. Such new versions will |
be similar in spirit to the present version, but may differ in detail to |
address new problems or concerns. |
Each version is given a distinguishing version number. If the Program |
specifies a version number of this License which applies to it and "any |
later version", you have the option of following the terms and conditions |
either of that version or of any later version published by the Free |
Software Foundation. If the Program does not specify a version number of |
this License, you may choose any version ever published by the Free Software |
Foundation. |
10. If you wish to incorporate parts of the Program into other free |
programs whose distribution conditions are different, write to the author |
to ask for permission. For software which is copyrighted by the Free |
Software Foundation, write to the Free Software Foundation; we sometimes |
make exceptions for this. Our decision will be guided by the two goals |
of preserving the free status of all derivatives of our free software and |
of promoting the sharing and reuse of software generally. |
NO WARRANTY |
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY |
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN |
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES |
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED |
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS |
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE |
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, |
REPAIR OR CORRECTION. |
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING |
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR |
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, |
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING |
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED |
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY |
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER |
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE |
POSSIBILITY OF SUCH DAMAGES. |
END OF TERMS AND CONDITIONS |
/WebSVN/listing.php |
---|
1,8 → 1,6 |
<?php |
# vim:et:ts=3:sts=3:sw=3:fdm=marker: |
// WebSVN - Subversion repository viewing via the web using PHP |
// Copyright © 2004-2006 Tim Armes, Matt Sicker |
// Copyright (C) 2004-2006 Tim Armes |
// |
// This program is free software; you can redistribute it and/or modify |
// it under the terms of the GNU General Public License as published by |
11,12 → 9,12 |
// |
// This program is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License |
// along with this program; if not, write to the Free Software |
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
// |
// -- |
// |
24,446 → 22,621 |
// |
// Show the listing for the given repository/path/revision |
require_once("include/setup.inc"); |
require_once("include/svnlook.inc"); |
require_once("include/utils.inc"); |
require_once("include/template.inc"); |
require_once("include/bugtraq.inc"); |
require_once 'include/setup.php'; |
require_once 'include/svnlook.php'; |
require_once 'include/utils.php'; |
require_once 'include/template.php'; |
require_once 'include/bugtraq.php'; |
function removeURLSeparator($url) |
{ |
return preg_replace('#(\?|&(amp;)?)$#', '', $url); |
return preg_replace('#(\?|&(amp;)?)$#', '', $url); |
} |
function fileLink($path, $file, $returnjoin = false) |
function urlForPath($fullpath, $passRevString) |
{ |
global $rep, $passrev, $showchanged, $config; |
if ($path == "" || $path{0} != "/") |
$ppath = "/".$path; |
else |
$ppath = $path; |
global $config, $rep; |
if ($ppath{strlen($ppath)-1} != "/") |
$ppath .= "/"; |
if ($file{0} == "/") |
$pfile = substr($file, 1); |
else |
$pfile = $file; |
$isDir = $fullpath[strlen($fullpath) - 1] == '/'; |
if ($returnjoin) |
return $ppath.$pfile; |
if ($isDir) |
{ |
if ($config->treeView) |
{ |
$url = $config->getURL($rep, $fullpath, 'dir').$passRevString; |
$id = anchorForPath($fullpath); |
$url .= '#'.$id.'" id="'.$id; |
} |
else |
{ |
$url = $config->getURL($rep, $fullpath, 'dir').$passRevString; |
} |
} |
else |
{ |
$url = $config->getURL($rep, $fullpath, 'file').$passRevString; |
} |
return removeURLSeparator($url); |
} |
$isDir = $pfile{strlen($pfile) - 1} == "/"; |
if ($passrev) $passrevstr = "rev=$passrev&"; else $passrevstr = ""; |
if ($showchanged) $showchangedstr = "sc=$showchanged"; else $showchangedstr = ""; |
function showDirFiles($svnrep, $subs, $level, $limit, $rev, $peg, $listing, $index, $treeview = true) |
{ |
global $config, $lang, $rep, $passrev, $peg, $passRevString; |
if ($isDir) |
{ |
$url = $config->getURL($rep, $ppath.$pfile, "dir"); |
$path = ''; |
// XHTML doesn't allow slashes in IDs ~J |
$id = str_replace('/', '_', $ppath.$pfile); |
$url = "<a id='$id' href=\"${url}$passrevstr$showchangedstr"; |
if (!$treeview) |
{ |
$level = $limit; |
} |
$url = removeURLSeparator($url); |
if ($config->treeView) $url .= "#$id"; |
$url .= "\">$pfile</a>"; |
} |
else |
{ |
$url = $config->getURL($rep, $ppath.$pfile, "file"); |
$url .= $passrevstr.$showchangedstr; |
$url = removeURLSeparator($url); |
$url = "<a href=\"${url}\">$pfile</a>"; |
} |
// TODO: Fix node links to use the path and number of peg revision (if exists) |
// This applies to file detail, log, and RSS -- leave the download link as-is |
for ($n = 0; $n <= $level; $n++) |
{ |
$path .= $subs[$n].'/'; |
} |
return $url; |
} |
// List each file in the current directory |
$loop = 0; |
$last_index = 0; |
$accessToThisDir = $rep->hasReadAccess($path, false); |
function fileLinkGetFile($path, $file) |
{ |
global $rep, $passrev, $showchanged, $config; |
// If using flat view and not at the root, create a '..' entry at the top. |
if (!$treeview && count($subs) > 2) |
{ |
$parentPath = $subs; |
unset($parentPath[count($parentPath) - 2]); |
$parentPath = implode('/', $parentPath); |
if ($path == "" || $path{0} != "/") |
$ppath = "/".$path; |
else |
$ppath = $path; |
if ($rep->hasReadAccess($parentPath, false)) |
{ |
$listvar = &$listing[$index]; |
$listvar['rowparity'] = $index % 2; |
$listvar['path'] = str_replace('%2F', '/', rawurlencode($parentPath)); |
$listvar['filetype'] = 'dir'; |
$listvar['filename'] = '..'; |
$listvar['fileurl'] = urlForPath($parentPath, $passRevString); |
$listvar['filelink'] = '<a href="'.$listvar['fileurl'].'">'.$listvar['filename'].'</a>'; |
$listvar['level'] = 0; |
$listvar['node'] = 0; // t-node |
$listvar['revision'] = $rev; |
$listvar['revurl'] = $config->getURL($rep, $parentPath, 'revision').'rev='.$rev.'&isdir=1'; |
global $vars; |
$listvar['date'] = $vars['date']; |
$listvar['age'] = datetimeFormatDuration(time() - strtotime($vars['date']), true, true); |
$index++; |
} |
} |
if ($ppath{strlen($ppath)-1} != "/") |
$ppath .= "/"; |
$openDir = false; |
$logList = $svnrep->getList($path, $rev, $peg); |
if ($file{0} == "/") |
$pfile = substr($file, 1); |
else |
$pfile = $file; |
if (!$logList) |
{ |
return $listing; |
} |
$isDir = $pfile{strlen($pfile) - 1} == "/"; |
$downloadRevAndPeg = createRevAndPegString($rev, $peg ? $peg : $rev); |
foreach ($logList->entries as $entry) |
{ |
$isDir = $entry->isdir; |
if (!$isDir && $level != $limit) |
{ |
continue; // Skip any files outside the current directory |
} |
$file = $entry->file; |
$isDirString = ($isDir) ? 'isdir=1&' : ''; |
if (!$isDir) |
{ |
$url = $config->getURL($rep, $ppath.$pfile, "file"); |
$url = removeURLSeparator($url); |
$url = "<a href=\"${url}&getfile\">Get</a>"; |
} |
// Only list files/directories that are not designated as off-limits |
$access = ($isDir) ? $rep->hasReadAccess($path.$file, false) |
: $accessToThisDir; |
return $url; |
if (!$access) |
{ |
continue; |
} |
$listvar = &$listing[$index]; |
$listvar['rowparity'] = $index % 2; |
if ($isDir) |
{ |
$openDir = isset($subs[$level + 1]) && (!strcmp($subs[$level + 1].'/', $file) || !strcmp($subs[$level + 1], $file)); |
$listvar['filetype'] = ($openDir) ? 'diropen' : 'dir'; |
} |
else |
{ |
$openDir = false; |
$listvar['filetype'] = strtolower(strrchr($file, '.')); |
} |
$listvar['isDir'] = $isDir; |
$listvar['openDir'] = $openDir; |
$listvar['level'] = ($treeview) ? $level : 0; |
$listvar['node'] = 0; // t-node |
$listvar['path'] = str_replace('%2F', '/', rawurlencode($path.$file)); |
$listvar['filename'] = escape($file); |
if ($isDir) |
{ |
$listvar['fileurl'] = urlForPath($path.$file, $passRevString); |
} |
else |
{ |
$listvar['fileurl'] = urlForPath($path.$file, createDifferentRevAndPegString($passrev, $peg)); |
} |
$listvar['filelink'] = '<a href="'.$listvar['fileurl'].'">'.$listvar['filename'].'</a>'; |
if ($isDir) |
{ |
$listvar['logurl'] = $config->getURL($rep, $path.$file, 'log').$isDirString.$passRevString; |
} |
else |
{ |
$listvar['logurl'] = $config->getURL($rep, $path.$file, 'log').$isDirString.createDifferentRevAndPegString($passrev, $peg); |
} |
if ($treeview) |
{ |
$listvar['compare_box'] = '<input type="checkbox" name="compare[]" value="'.escape($path.$file).'@'.$passrev.'" onclick="enforceOnlyTwoChecked(this)" />'; |
} |
if ($config->showLastModInListing()) |
{ |
$listvar['committime'] = $entry->committime; |
$listvar['revision'] = $entry->rev; |
$listvar['author'] = $entry->author; |
$listvar['age'] = $entry->age; |
$listvar['date'] = $entry->date; |
$listvar['revurl'] = $config->getURL($rep, $path.$file, 'revision').$isDirString.createRevAndPegString($entry->rev, $peg ? $peg : $rev); |
} |
if ($rep->isDownloadAllowed($path.$file)) |
{ |
$downloadurl = $config->getURL($rep, $path.$file, 'dl').$isDirString.$downloadRevAndPeg; |
if ($isDir) |
{ |
$listvar['downloadurl'] = $downloadurl; |
$listvar['downloadplainurl'] = ''; |
} |
else |
{ |
$listvar['downloadplainurl'] = $downloadurl; |
$listvar['downloadurl'] = ''; |
} |
} |
else |
{ |
$listvar['downloadplainurl'] = ''; |
$listvar['downloadurl'] = ''; |
} |
if ($rep->isRssEnabled()) |
{ |
// RSS should always point to the latest revision, so don't include rev |
$listvar['rssurl'] = $config->getURL($rep, $path.$file, 'rss').$isDirString.createRevAndPegString('', $peg); |
} |
$loop++; |
$index++; |
$last_index = $index; |
if ($isDir && ($level != $limit)) |
{ |
// @todo remove the alternate check with htmlentities when assured that there are not side effects |
if (isset($subs[$level + 1]) && (!strcmp($subs[$level + 1].'/', $file) || !strcmp(htmlentities($subs[$level + 1], ENT_QUOTES).'/', htmlentities($file)))) |
{ |
$listing = showDirFiles($svnrep, $subs, $level + 1, $limit, $rev, $peg, $listing, $index); |
$index = count($listing); |
} |
} |
} |
// For an expanded tree, give the last entry an "L" node to close the grouping |
if ($treeview && $last_index != 0) |
{ |
$listing[$last_index - 1]['node'] = 1; // l-node |
} |
return $listing; |
} |
function showDirFiles($svnrep, $subs, $level, $limit, $rev, $listing, $index, $treeview = true) |
function showAllDirFiles($svnrep, $path, $rev, $peg, $listing, $index, $treeView = true) |
{ |
global $rep, $passrev, $showchanged, $config, $lang; |
global $config, $lang, $rep, $passrev, $peg, $passRevString; |
$path = ""; |
// List each file in the current directory |
$loop = 0; |
$last_index = 0; |
$accessToThisDir = $rep->hasReadAccess($path, false); |
// Explicitly requested file as attachment |
if (isset($_REQUEST['getfile'])) |
{ |
$base = basename($path); |
// If using flat view and not at the root, create a '..' entry at the top. |
if (!$treeView && count($subs) > 2) |
{ |
$parentPath = $subs; |
unset($parentPath[count($parentPath) - 2]); |
$parentPath = implode('/', $parentPath); |
header("Content-Type: application/octet-stream"); |
header("Content-Length: $size"); |
header("Content-Disposition: inline; filename=".urlencode($base)); |
if ($rep->hasReadAccess($parentPath, false)) |
{ |
$listvar = &$listing[$index]; |
$listvar['rowparity'] = $index % 2; |
$listvar['path'] = str_replace('%2F', '/', rawurlencode($parentPath)); |
$listvar['filetype'] = 'dir'; |
$listvar['filename'] = '..'; |
$listvar['fileurl'] = urlForPath($parentPath, $passRevString); |
$listvar['filelink'] = '<a href="'.$listvar['fileurl'].'">'.$listvar['filename'].'</a>'; |
$listvar['level'] = 0; |
$listvar['node'] = 0; // t-node |
$listvar['revision'] = $rev; |
$listvar['revurl'] = $config->getURL($rep, $parentPath, 'revision').'rev='.$rev.'&isdir=1'; |
global $vars; |
$listvar['date'] = $vars['date']; |
$listvar['age'] = datetimeFormatDuration(time() - strtotime($vars['date']), true, true); |
$index++; |
} |
} |
$svnrep->getFileContents($path, "", $rev); |
$openDir = false; |
$logList = $svnrep->getList($path, $rev, $peg); |
exit; |
} |
if (!$logList) |
{ |
return $listing; |
} |
if (!$treeview) |
$level = $limit; |
$downloadRevAndPeg = createRevAndPegString($rev, $peg ? $peg : $rev); |
for ($n = 0; $n <= $level; $n++) |
{ |
$path .= $subs[$n]."/"; |
} |
foreach ($logList->entries as $entry) |
{ |
$isDir = $entry->isdir; |
$contents = $svnrep->dirContents($path, $rev); |
$file = $entry->file; |
$isDirString = ($isDir) ? 'isdir=1&' : ''; |
// List each file in the current directory |
$loop = 0; |
$last_index = 0; |
$openDir = false; |
$fullaccess = $rep->hasReadAccess($path, false); |
foreach($contents as $file) |
{ |
$isDir = ($file{strlen($file) - 1} == "/"?1:0); |
$access = false; |
// Only list files/directories that are not designated as off-limits |
$access = ($isDir) ? $rep->hasReadAccess($path.$file, false) |
: $accessToThisDir; |
if ($isDir) |
{ |
if ($rep->hasReadAccess($path.$file, true)) |
{ |
$access = true; |
$openDir = (!strcmp($subs[$level+1]."/", $file) || !strcmp($subs[$level+1], $file)); |
if (!$access) |
{ |
continue; |
} |
if ($openDir) |
$listing[$index]["filetype"] = "diropen"; |
else |
$listing[$index]["filetype"] = "dir"; |
$listvar = &$listing[$index]; |
$listvar['rowparity'] = $index % 2; |
if ($rep->isDownloadAllowed($path.$file)) |
{ |
$dlurl = $config->getURL($rep, $path.$file, "dl"); |
$listing[$index]["fileviewdllink"] = "<a href=\"${dlurl}rev=$passrev&isdir=1\">${lang["TARBALL"]}</a>"; |
} |
else |
$listing[$index]["fileviewdllink"] = " "; |
} |
} |
else |
{ |
if ($fullaccess) |
{ |
$access = true; |
if ($level != $limit) |
{ |
// List directories only, skip all files |
continue; |
} |
$listing[$index]["fileviewdllink"] = " "; |
$listing[$index]["filetype"] = strrchr($file, "."); |
} |
} |
if ($isDir) |
{ |
$listvar['filetype'] = 'dir'; |
$openDir = true; |
} |
else |
{ |
$listvar['filetype'] = strtolower(strrchr($file, '.')); |
$openDir = false; |
} |
if ($access) |
{ |
$listing[$index]["rowparity"] = ($index % 2)?"L1":"L0"; |
if ($treeview) |
$listing[$index]["compare_box"] = "<input type=\"checkbox\" name=\"compare[]\" value=\"".fileLink($path, $file, true)."@$passrev\" onclick=\"checkCB(this)\" />"; |
else |
$listing[$index]["compare_box"] = ""; |
$listvar['isDir'] = $isDir; |
$listvar['openDir'] = $openDir; |
$listvar['path'] = str_replace('%2F', '/', rawurlencode($path.$file)); |
$tempelements = explode('/',$file); |
if ($openDir) |
$listing[$index]["filelink"] = "<b>".fileLink($path, $file)."</b>"; |
else |
$listing[$index]["filelink"] = fileLink($path, $file); |
if ($tempelements[count($tempelements)-1] === "") |
{ |
$lastindexfile = count($tempelements)-1 - 1; |
$listvar['node'] = $lastindexfile; // t-node |
$listvar['level'] = ($treeView) ? $lastindexfile : 0; |
$listvar['filename'] = escape($tempelements[$lastindexfile]); |
$listvar['classname'] = ''; |
if ($isDir) |
$listing[$index]["filelinkgetfile"] = ""; |
else |
$listing[$index]["filelinkgetfile"] = fileLinkGetFile($path, $file); |
for ($n = 0; $n < $lastindexfile; ++$n) |
{ |
$listvar['last_i_node'][$n] = false; |
$listvar['classname'] = $listvar['classname'].$tempelements[$n].'/'; |
} |
// The history command doesn't return with a trailing slash. We need to remember here if the |
// file is a directory or not! |
$listvar['classname'] = $listvar['classname'].$tempelements[$lastindexfile]; |
$listvar['last_i_node'][$lastindexfile] = true; |
} |
else |
{ |
$lastindexfile = count($tempelements)-1; |
$listvar['node'] = $lastindexfile; // t-node |
$listvar['level'] = ($treeView) ? $lastindexfile : 0; |
$listvar['filename'] = escape($tempelements[$lastindexfile]); |
$listvar['classname'] = ''; |
$listing[$index]["isDir"] = $isDir; |
for ($n=0; $n < $lastindexfile; ++$n) |
{ |
$listvar['last_i_node'][$n] = false; |
$listvar['classname'] = $listvar['classname'].$tempelements[$n].'/'; |
} |
if ($treeview) |
$listing[$index]["level"] = $level; |
else |
$listing[$index]["level"] = 0; |
$listvar['last_i_node'][$lastindexfile] = true; |
} |
$listing[$index]["node"] = 0; // t-node |
if ($isDir) |
{ |
$listvar['fileurl'] = urlForPath($path.$file, $passRevString); |
} |
else |
{ |
$listvar['fileurl'] = urlForPath($path.$file, createDifferentRevAndPegString($passrev, $peg)); |
} |
$fileurl = $config->getURL($rep, $path.$file, "log"); |
$listing[$index]["fileviewloglink"] = "<a href=\"${fileurl}rev=$passrev&sc=$showchanged&isdir=$isDir\">${lang["VIEWLOG"]}</a>"; |
$listvar['filelink'] = '<a href="'.$listvar['fileurl'].'">'.$listvar['filename'].'</a>'; |
$rssurl = $config->getURL($rep, $path.$file, "rss"); |
if ($rep->getHideRss()) |
{ |
$listing[$index]["rsslink"] = "<a href=\"${rssurl}rev=$passrev&sc=$showchanged&isdir=$isDir\">${lang["RSSFEED"]}</a>"; |
$listing[$index]["rssanchor"] = "<a href=\"${rssurl}rev=$passrev&sc=$showchanged&isdir=$isDir\">"; |
} |
if ($isDir) |
{ |
$listvar['logurl'] = $config->getURL($rep, $path.$file, 'log').$isDirString.$passRevString; |
} |
else |
{ |
$listvar['logurl'] = $config->getURL($rep, $path.$file, 'log').$isDirString.createDifferentRevAndPegString($passrev, $peg); |
} |
$index++; |
$loop++; |
$last_index = $index; |
if ($treeView) |
{ |
$listvar['compare_box'] = '<input type="checkbox" name="compare[]" value="'.escape($path.$file).'@'.$passrev.'" onclick="enforceOnlyTwoChecked(this)" />'; |
} |
if (($level != $limit) && ($isDir)) |
{ |
if (!strcmp($subs[$level + 1]."/", $file)) |
{ |
$listing = showDirFiles($svnrep, $subs, $level + 1, $limit, $rev, $listing, $index); |
$index = count($listing); |
} |
} |
if ($config->showLastModInListing()) |
{ |
$listvar['committime'] = $entry->committime; |
$listvar['revision'] = $entry->rev; |
$listvar['author'] = $entry->author; |
$listvar['age'] = $entry->age; |
$listvar['date'] = $entry->date; |
$listvar['revurl'] = $config->getURL($rep, $path.$file, 'revision').$isDirString.createRevAndPegString($entry->rev, $peg ? $peg : $rev); |
} |
} |
} |
if ($rep->isDownloadAllowed($path.$file)) |
{ |
$downloadurl = $config->getURL($rep, $path.$file, 'dl').$isDirString.$downloadRevAndPeg; |
if ($last_index != 0 && $treeview) |
{ |
$listing[$last_index - 1]["node"] = 1; // l-node |
} |
if ($isDir) |
{ |
$listvar['downloadurl'] = $downloadurl; |
$listvar['downloadplainurl'] = ''; |
} |
else |
{ |
$listvar['downloadplainurl'] = $downloadurl; |
$listvar['downloadurl'] = ''; |
} |
} |
else |
{ |
$listvar['downloadplainurl'] = ''; |
$listvar['downloadurl'] = ''; |
} |
return $listing; |
if ($rep->isRssEnabled()) |
{ |
// RSS should always point to the latest revision, so don't include rev |
$listvar['rssurl'] = $config->getURL($rep, $path.$file, 'rss').$isDirString.createRevAndPegString('', $peg); |
} |
$loop++; |
$index++; |
$last_index = $index; |
} |
return $listing; |
} |
function showTreeDir($svnrep, $path, $rev, $listing) |
function showTreeDir($svnrep, $path, $rev, $peg, $listing) |
{ |
global $vars, $config; |
global $vars, $config; |
$subs = explode("/", $path); |
if ($config->showLoadAllRepos()) |
{ |
$vars['compare_box'] = ''; // Set blank once in case tree view is not enabled. |
return showAllDirFiles($svnrep, $path, $rev, $peg, $listing, 0, $config->treeView); |
} |
// For directory, the last element in the subs is empty. |
// For file, the last element in the subs is the file name. |
// Therefore, it is always count($subs) - 2 |
$limit = count($subs) - 2; |
$subs = explode('/', $path); |
for ($n = 0; $n < $limit; $n++) |
{ |
$vars["last_i_node"][$n] = FALSE; |
} |
// The last element in "$subs" is empty for directories, some file name for files, but ALWAYS |
// exists as an additional element. Hence, "-2" is necessary. |
// |
// Additionally, level and limit are conceptually different things, first to e.g. start access |
// checks FROM, latter to process UNTIL. So don't merge those values too easily, especially as |
// both values needed to be different in some environments in the past for some unkown reason. |
// |
// https://github.com/websvnphp/websvn/issues/146#issuecomment-913353366 |
$limit = count($subs) - 2; |
$level = $limit; |
$level = $level <= 0 ? 0 : $level; |
return showDirFiles($svnrep, $subs, 0, $limit, $rev, $listing, 0, $config->treeView); |
for ($n = 0; $n < $limit; $n++) |
{ |
$vars['last_i_node'][$n] = false; |
} |
$vars['compare_box'] = ''; // Set blank once in case tree view is not enabled. |
return showDirFiles($svnrep, $subs, $level, $limit, $rev, $peg, $listing, 0, $config->treeView); |
} |
// Make sure that we have a repository |
if (!isset($rep)) |
if (!$rep) |
{ |
echo $lang["NOREP"]; |
exit; |
renderTemplate404('directory','NOREP'); |
} |
$svnrep = new SVNRepository($rep); |
// Revision info to pass along chain |
$passrev = $rev; |
if (!empty($rev)) |
{ |
$info = $svnrep->getInfo($path, $rev, $peg); |
// Get the directory contents of the given revision, or HEAD if not defined |
$contents = $svnrep->dirContents($path, @$rev); |
if ($info) |
{ |
$path = $info->path; |
$peg = (int)$info->rev; |
} |
} |
// If there's no revision info, go to the lastest revision for this path |
$history = $svnrep->getLog($path, "", "", false); |
$history = $svnrep->getLog($path, 'HEAD', 1, false, 2, ($path == '/') ? '' : $peg); |
if (!empty($history->entries[0])) |
$youngest = $history->entries[0]->rev; |
else |
$youngest = -1; |
if (!$history) |
{ |
unset($vars['error']); |
$history = $svnrep->getLog($path, '', '', false, 2, ($path == '/') ? '' : $peg); |
if (!$history) |
{ |
renderTemplate404('directory','NOPATH'); |
} |
} |
$youngest = ($history && isset($history->entries[0])) ? $history->entries[0]->rev : 0; |
// Unless otherwise specified, we get the log details of the latest change |
if (empty($rev)) |
$logrev = $youngest; |
else |
$logrev = $rev; |
$lastChangedRev = ($passrev) ? $passrev : $youngest; |
if ($logrev != $youngest) |
if ($lastChangedRev != $youngest) |
{ |
$logEntry = $svnrep->getLog($path, $logrev, $logrev, false); |
$logEntry = $logEntry->entries[0]; |
$history = $svnrep->getLog($path, $lastChangedRev, 1, false, 2, $peg); |
} |
else |
$logEntry = $history->entries[0]; |
$headlog = $svnrep->getLog("/", "", "", true, 1); |
$headrev = $headlog->entries[0]->rev; |
$logEntry = ($history && isset($history->entries[0])) ? $history->entries[0] : 0; |
$headlog = $svnrep->getLog('/', '', '', true, 1); |
$headrev = ($headlog && isset($headlog->entries[0])) ? $headlog->entries[0]->rev : 0; |
// If we're not looking at a specific revision, get the HEAD revision number |
// (the revision of the rest of the tree display) |
if (empty($rev)) |
{ |
$rev = $headrev; |
$rev = $headrev; |
} |
if ($path == "" || $path{0} != "/") |
$ppath = "/".$path; |
if ($path == '' || $path[0] != '/') |
{ |
$ppath = '/'.$path; |
} |
else |
$ppath = $path; |
{ |
$ppath = $path; |
} |
$vars["repname"] = $rep->getDisplayName(); |
createPathLinks($rep, $ppath, $passrev, $peg); |
$passRevString = createRevAndPegString($passrev, $peg); |
$isDirString = 'isdir=1&'; |
$dirurl = $config->getURL($rep, $path, "dir"); |
$logurl = $config->getURL($rep, $path, "log"); |
$rssurl = $config->getURL($rep, $path, "rss"); |
$dlurl = $config->getURL($rep, $path, "dl"); |
$compurl = $config->getURL($rep, "/", "comp"); |
$revurl = $config->getURL($rep, $path != '/' ? $path : '', 'dir'); |
$revurlSuffix = $path != '/' ? '#'.anchorForPath($path) : ''; |
if ($passrev != 0 && $passrev != $headrev && $youngest != -1) |
$vars["goyoungestlink"] = "<a href=\"${dirurl}opt=dir&sc=1\">${lang["GOYOUNGEST"]}</a>"; |
else |
$vars["goyoungestlink"] = ""; |
if ($rev < $youngest) |
{ |
if ($path == '/') |
{ |
$vars['goyoungesturl'] = $config->getURL($rep, '', 'dir'); |
} |
else |
{ |
$vars['goyoungesturl'] = $config->getURL($rep, $path, 'dir').createRevAndPegString($youngest, $peg ? $peg: $rev).$revurlSuffix; |
} |
$bugtraq = new Bugtraq($rep, $svnrep, $ppath); |
$vars['goyoungestlink'] = '<a href="'.$vars['goyoungesturl'].'"'.($youngest ? ' title="'.$lang['REV'].' '.$youngest.'"' : '').'>'.$lang['GOYOUNGEST'].'</a>'; |
$vars["action"] = ""; |
$vars["rev"] = $rev; |
$vars["path"] = $ppath; |
$vars["lastchangedrev"] = $logrev; |
$vars["date"] = $logEntry->date; |
$vars["author"] = $logEntry->author; |
$vars["log"] = nl2br($bugtraq->replaceIDs(create_anchors($logEntry->msg))); |
$history2 = $svnrep->getLog($path, $rev, $youngest, true, 2, $peg); |
if (!$showchanged) |
{ |
$vars["showchangeslink"] = "<a href=\"${dirurl}rev=$passrev&sc=1\">${lang["SHOWCHANGED"]}</a>"; |
$vars["hidechangeslink"] = ""; |
if (isset($history2->entries[1])) |
{ |
$nextRev = $history2->entries[1]->rev; |
if ($nextRev != $youngest) |
{ |
$vars['nextrev'] = $nextRev; |
$vars['nextrevurl'] = $revurl.createRevAndPegString($nextRev, $peg).$revurlSuffix; |
} |
} |
$vars["hidechanges"] = true; |
$vars["showchanges"] = false; |
unset($vars['error']); |
} |
else |
if (isset($history->entries[1])) |
{ |
$vars["showchangeslink"] = ""; |
$changes = $logEntry->mods; |
$firstAdded = true; |
$firstModded = true; |
$firstDeleted = true; |
$prevRev = $history->entries[1]->rev; |
$prevPath = $history->entries[1]->path; |
$vars['prevrev'] = $prevRev; |
$vars['prevrevurl'] = $revurl.createRevAndPegString($prevRev, $peg).$revurlSuffix; |
} |
$vars["newfilesbr"] = ""; |
$vars["newfiles"] = ""; |
$vars["changedfilesbr"] = ""; |
$vars["changedfiles"] = ""; |
$vars["deletedfilesbr"] = ""; |
$vars["deletedfiles"] = ""; |
$bugtraq = new Bugtraq($rep, $svnrep, $ppath); |
foreach ($changes as $file) |
{ |
switch ($file->action) |
{ |
case "A": |
if (!$firstAdded) $vars["newfilesbr"] .= "<br />"; |
$firstAdded = false; |
$vars["newfilesbr"] .= fileLink("", $file->path); |
$vars["newfiles"] .= " ".fileLink("", $file->path); |
break; |
$vars['action'] = ''; |
$vars['rev'] = $rev; |
$vars['peg'] = $peg; |
$vars['path'] = str_replace('%2F', '/', rawurlencode($ppath)); |
$vars['safepath'] = escape($ppath); |
$vars['lastchangedrev'] = $lastChangedRev; |
case "M": |
if (!$firstModded) $vars["changedfilesbr"] .= "<br />"; |
$firstModded = false; |
$vars["changedfilesbr"] .= fileLink("", $file->path); |
$vars["changedfiles"] .= " ".fileLink("", $file->path); |
break; |
if ($logEntry) |
{ |
$vars['date'] = $logEntry->date; |
$vars['age'] = datetimeFormatDuration(time() - strtotime($logEntry->date)); |
$vars['author'] = $logEntry->author; |
$vars['log'] = nl2br($bugtraq->replaceIDs(create_anchors(xml_entities($logEntry->msg)))); |
} |
case "D": |
if (!$firstDeleted) $vars["deletedfilesbr"] .= "<br />"; |
$firstDeleted = false; |
$vars["deletedfilesbr"] .= $file->path; |
$vars["deletedfiles"] .= " ".$file->path; |
break; |
} |
} |
$vars['revurl'] = $config->getURL($rep, ($path == '/' ? '' : $path), 'revision').$isDirString.$passRevString; |
$vars['revlink'] = '<a href="'.$vars['revurl'].'">'.$lang['LASTMOD'].'</a>'; |
$vars["hidechangeslink"] = "<a href=\"${dirurl}rev=$passrev&sc=0\">${lang["HIDECHANGED"]}</a>"; |
if ($history && count($history->entries) > 1) |
{ |
$vars['compareurl'] = $config->getURL($rep, '', 'comp').'compare[]='.rawurlencode($history->entries[1]->path).'@'.$history->entries[1]->rev. '&compare[]='.rawurlencode($history->entries[0]->path).'@'.$history->entries[0]->rev; |
$vars['comparelink'] = '<a href="'.$vars['compareurl'].'">'.$lang['DIFFPREV'].'</a>'; |
} |
$vars["hidechanges"] = false; |
$vars["showchanges"] = true; |
$vars['logurl'] = $config->getURL($rep, $path, 'log').$isDirString.$passRevString; |
$vars['loglink'] = '<a href="'.$vars['logurl'].'">'.$lang['VIEWLOG'].'</a>'; |
if ($rep->isRssEnabled()) |
{ |
$vars['rssurl'] = $config->getURL($rep, $path, 'rss').$isDirString.createRevAndPegString('', $peg); |
$vars['rsslink'] = '<a href="'.$vars['rssurl'].'">'.$lang['RSSFEED'].'</a>'; |
} |
createDirLinks($rep, $ppath, $passrev, $showchanged); |
$vars["curdirloglink"] = "<a href=\"${logurl}rev=$passrev&sc=$showchanged&isdir=1\">${lang["VIEWLOG"]}</a>"; |
// Set up the tarball link |
$subs = explode('/', $path); |
$level = count($subs) - 2; |
if ($rev != $headrev) |
if ($rep->isDownloadAllowed($path) && !isset($vars['warning'])) |
{ |
$history = $svnrep->getLog($path, $rev, "", false); |
$vars['downloadurl'] = $config->getURL($rep, $path, 'dl').$isDirString.$passRevString; |
} |
if (isset($history->entries[1]->rev)) |
$vars['compare_form'] = '<form method="get" action="'.$config->getURL($rep, '', 'comp').'" id="compare">'; |
if ($config->multiViews) |
{ |
$vars["curdircomplink"] = "<a href=\"${compurl}compare[]=". |
urlencode($history->entries[1]->path)."@".$history->entries[1]->rev. |
"&compare[]=".urlencode($history->entries[0]->path)."@".$history->entries[0]->rev. |
"\">${lang["DIFFPREV"]}</a>"; |
$vars['compare_form'] .= '<input type="hidden" name="op" value="comp"/>'; |
} |
else |
{ |
$vars["curdircomplink"] = ""; |
} |
if ($rep->getHideRss()) |
{ |
$vars["curdirrsslink"] = "<a href=\"${rssurl}rev=$passrev&sc=$showchanged&isdir=1\">${lang["RSSFEED"]}</a>"; |
$vars["curdirrsshref"] = "${rssurl}rev=$passrev&sc=$showchanged&isdir=1"; |
$vars["curdirrssanchor"] = "<a href=\"${rssurl}rev=$passrev&sc=$showchanged&isdir=1\">"; |
$vars['compare_form'] .= '<input type="hidden" name="repname" value="'.$repname.'" />'; |
} |
// Set up the tarball link |
$vars['compare_submit'] = '<input type="submit" value="'.$lang['COMPAREPATHS'].'" />'; |
$vars['compare_endform'] = '</form>'; |
$subs = explode("/", $path); |
$level = count($subs) - 2; |
if ($rep->isDownloadAllowed($path)) |
$vars["curdirdllink"] = "<a href=\"${dlurl}rev=$passrev&isdir=1\">${lang["TARBALL"]}</a>"; |
else |
$vars["curdirdllink"] = ""; |
$url = $config->getURL($rep, "/", "comp"); |
$vars['showlastmod'] = $config->showLastModInListing(); |
$vars["compare_form"] = "<form action=\"$url\" method=\"post\" name=\"compareform\">"; |
$vars["compare_submit"] = "<input name=\"comparesubmit\" type=\"submit\" value=\"${lang["COMPAREPATHS"]}\" />"; |
$vars["compare_endform"] = "<input type=\"hidden\" name=\"op\" value=\"comp\" /><input type=\"hidden\" name=\"sc\" value=\"$showchanged\" /></form>"; |
$vars['loadalldir'] = $config->showLoadAllRepos(); |
$listing = showTreeDir($svnrep, $path, $rev, $peg, array()); |
$listing = array(); |
$listing = showTreeDir($svnrep, $path, $rev, $listing); |
if (!$rep->hasReadAccess($path)) |
{ |
$vars['error'] = $lang['NOACCESS']; |
sendHeaderForbidden(); |
} |
$vars["version"] = $version; |
if (!$rep->hasReadAccess($path, true)) |
$vars["noaccess"] = true; |
if (!$rep->hasReadAccess($path, false)) |
$vars["restricted"] = true; |
parseTemplate($rep->getTemplatePath()."header.tmpl", $vars, $listing); |
parseTemplate($rep->getTemplatePath()."directory.tmpl", $vars, $listing); |
parseTemplate($rep->getTemplatePath()."footer.tmpl", $vars, $listing); |
?> |
$vars['restricted'] = !$rep->hasReadAccess($path, false); |
renderTemplate('directory', $path); |
/WebSVN/log.php |
---|
1,8 → 1,6 |
<?php |
# vim:et:ts=3:sts=3:sw=3:fdm=marker: |
// WebSVN - Subversion repository viewing via the web using PHP |
// Copyright © 2004-2006 Tim Armes, Matt Sicker |
// Copyright (C) 2004-2006 Tim Armes |
// |
// This program is free software; you can redistribute it and/or modify |
// it under the terms of the GNU General Public License as published by |
11,12 → 9,12 |
// |
// This program is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License |
// along with this program; if not, write to the Free Software |
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
// |
// -- |
// |
24,310 → 22,537 |
// |
// Show the logs for the given path |
require_once("include/setup.inc"); |
require_once("include/svnlook.inc"); |
require_once("include/utils.inc"); |
require_once("include/template.inc"); |
require_once("include/bugtraq.inc"); |
require_once 'include/setup.php'; |
require_once 'include/svnlook.php'; |
require_once 'include/utils.php'; |
require_once 'include/template.php'; |
require_once 'include/bugtraq.php'; |
$page = (int)@$_REQUEST["page"]; |
$all = (@$_REQUEST["all"] == 1)?1:0; |
$isDir = (@$_REQUEST["isdir"] == 1)?1:0; |
$dosearch = (@$_REQUEST["logsearch"] == 1)?1:0; |
$search = trim(@$_REQUEST["search"]); |
$page = (int)@$_REQUEST['page']; |
$all = @$_REQUEST['all'] == 1; |
$isDir = @$_REQUEST['isdir'] == 1 || $path == '' || $path == '/'; |
// Make sure that we have a repository |
if (!$rep) |
{ |
renderTemplate404('log','NOREP'); |
} |
if (isset($_REQUEST['showchanges'])) |
{ |
$showchanges = @$_REQUEST['showchanges'] == 1; |
} |
else |
{ |
$showchanges = $rep->logsShowChanges(); |
} |
$search = trim((string) @$_REQUEST['search']); |
$dosearch = strlen($search) > 0; |
$words = preg_split('#\s+#', $search); |
$fromRev = (int)@$_REQUEST["fr"]; |
$startrev = strtoupper(trim(@$_REQUEST["sr"])); |
$endrev = strtoupper(trim(@$_REQUEST["er"])); |
$max = @$_REQUEST["max"]; |
$fromRev = (int)@$_REQUEST['fr']; |
$startrev = strtoupper(trim((string) @$_REQUEST['sr'])); |
$endrev = strtoupper(trim((string) @$_REQUEST['er'])); |
$max = isset($_REQUEST['max']) ? (int)$_REQUEST['max'] : false; |
// Max number of results to find at a time |
$numSearchResults = 15; |
$numSearchResults = 20; |
if ($search == "") |
$dosearch = false; |
if ($search == '') |
{ |
$dosearch = false; |
} |
// removeAccents |
// |
// Remove all the accents from a string. This function doesn't seem |
// Remove all the accents from a string. This function doesn't seem |
// ideal, but expecting everyone to install 'unac' seems a little |
// excessive as well... |
function removeAccents($string) |
{ |
return strtr($string, |
"ÀÁÂÃÄÅàáâãäåÒÓÔÕÖØòóôõöøÈÉÊËèéêëÇçÌÍÎÏìíîïÙÚÛÜùúûüÿÑñ", |
"AAAAAAaaaaaaOOOOOOooooooEEEEeeeeCcIIIIiiiiUUUUuuuuyNn"); |
} |
function removeAccents($string) |
{ |
$string = htmlentities($string, ENT_QUOTES, 'ISO-8859-1'); |
$string = preg_replace('/&([A-Za-z])(acute|uml|circ|grave|ring|cedil|slash|tilde|caron);/', '$1', $string); |
return $string; |
} |
// Normalise the search words |
foreach ($words as $index => $word) |
foreach ($words as $index => $word) |
{ |
$words[$index] = strtolower(removeAccents($word)); |
// Remove empty string introduced by multiple spaces |
if (empty($words[$index])) |
unset($words[$index]); |
$words[$index] = strtolower(removeAccents($word)); |
// Remove empty string introduced by multiple spaces |
if (empty($words[$index])) |
unset($words[$index]); |
} |
if (empty($page)) $page = 1; |
if (empty($page)) |
{ |
$page = 1; |
} |
// If searching, display all the results |
$all = (bool) $dosearch; |
if ($dosearch) |
{ |
$all = true; |
} |
$maxperpage = 20; |
// Make sure that we have a repository |
if (!isset($rep)) |
$svnrep = new SVNRepository($rep); |
$history = $svnrep->getLog($path, 'HEAD', '', false, 1, ($path == '/') ? '' : $peg); |
if (!$history) |
{ |
echo $lang["NOREP"]; |
exit; |
unset($vars['error']); |
$history = $svnrep->getLog($path, '', '', false, 1, ($path == '/') ? '' : $peg); |
if (!$history) |
{ |
renderTemplate404('log','NOPATH'); |
} |
} |
$svnrep = new SVNRepository($rep); |
$youngest = ($history && isset($history->entries[0])) ? $history->entries[0]->rev : 0; |
$passrev = $rev; |
if (empty($startrev)) |
{ |
//$startrev = ($rev) ? $rev : 'HEAD'; |
$startrev = $rev; |
} |
else if ($startrev != 'HEAD' && $startrev != 'BASE' && $startrev != 'PREV' && $startrev != 'COMMITTED') |
{ |
$startrev = (int)$startrev; |
} |
// If there's no revision info, go to the lastest revision for this path |
$history = $svnrep->getLog($path, "", "", true); |
$youngest = $history->entries[0]->rev; |
if (empty($endrev)) |
{ |
$endrev = 1; |
} |
else if ($endrev != 'HEAD' && $endrev != 'BASE' && $endrev != 'PREV' && $endrev != 'COMMITTED') |
{ |
$endrev = (int)$endrev; |
} |
if (empty($rev)) |
$rev = $youngest; |
if (empty($rev)) |
{ |
$rev = $youngest; |
} |
if (empty($startrev)) |
{ |
$startrev = $rev; |
} |
// make sure path is prefixed by a / |
$ppath = $path; |
if ($path == "" || $path{0} != "/") |
$ppath = "/".$path; |
$vars["action"] = $lang["LOG"]; |
$vars["repname"] = $rep->getDisplayName(); |
$vars["rev"] = $rev; |
$vars["path"] = $ppath; |
if ($path == '' || $path[0] != '/') |
{ |
$ppath = '/'.$path; |
} |
createDirLinks($rep, $ppath, $passrev, $showchanged); |
$vars['action'] = $lang['LOG']; |
$vars['rev'] = $rev; |
$vars['peg'] = $peg; |
$vars['path'] = str_replace('%2F', '/', rawurlencode($ppath)); |
$vars['safepath'] = escape($ppath); |
$logurl = $config->getURL($rep, $path, "log"); |
if ($history && isset($history->entries[0])) |
{ |
$vars['log'] = xml_entities($history->entries[0]->msg); |
$vars['date'] = $history->entries[0]->date; |
$vars['age'] = datetimeFormatDuration(time() - strtotime($history->entries[0]->date)); |
$vars['author'] = $history->entries[0]->author; |
} |
if ($rev != $youngest) |
$vars["goyoungestlink"] = "<a href=\"${logurl}sc=1\">${lang["GOYOUNGEST"]}</a>"; |
if ($max === false) |
{ |
$max = ($dosearch) ? 0 : 40; |
} |
else if ($max < 0) |
{ |
$max = 40; |
} |
// TODO: If the rev is less than the head, get the path (may have been renamed!) |
// Will probably need to call `svn info`, parse XML output, and substring a path |
createPathLinks($rep, $ppath, $passrev, $peg); |
$passRevString = createRevAndPegString($rev, $peg); |
$isDirString = ($isDir) ? 'isdir=1&' : ''; |
unset($queryParams['repname']); |
unset($queryParams['path']); |
// Toggle 'showchanges' param for link to switch from the current behavior |
if ($showchanges == $rep->logsShowChanges()) |
{ |
$queryParams['showchanges'] = (int)!$showchanges; |
} |
else |
$vars["goyoungestlink"] = ""; |
{ |
unset($queryParams['showchanges']); |
} |
$vars['changesurl'] = $config->getURL($rep, $path, 'log').buildQuery($queryParams); |
$vars['changeslink'] = '<a href="'.$vars['changesurl'].'">'.$lang[($showchanges ? 'HIDECHANGED' : 'SHOWCHANGED')].'</a>'; |
$vars['showchanges'] = $showchanges; |
// Revert 'showchanges' param to propagate the current behavior |
if ($showchanges == $rep->logsShowChanges()) |
{ |
unset($queryParams['showchanges']); |
} |
else |
{ |
$queryParams['showchanges'] = (int)$showchanges; |
} |
$vars['revurl'] = $config->getURL($rep, $path, 'revision').$isDirString.$passRevString; |
if ($isDir) |
{ |
$vars['directoryurl'] = $config->getURL($rep, $path, 'dir').$passRevString.'#'.anchorForPath($path); |
$vars['directorylink'] = '<a href="'.$vars['directoryurl'].'">'.$lang['LISTING'].'</a>'; |
} |
else |
{ |
$vars['filedetailurl'] = $config->getURL($rep, $path, 'file').$passRevString; |
$vars['filedetaillink'] = '<a href="'.$vars['filedetailurl'].'">'.$lang['FILEDETAIL'].'</a>'; |
$vars['blameurl'] = $config->getURL($rep, $path, 'blame').$passRevString; |
$vars['blamelink'] = '<a href="'.$vars['blameurl'].'">'.$lang['BLAME'].'</a>'; |
$vars['diffurl'] = $config->getURL($rep, $path, 'diff').$passRevString; |
$vars['difflink'] = '<a href="'.$vars['diffurl'].'">'.$lang['DIFFPREV'].'</a>'; |
} |
if ($rep->isRssEnabled()) |
{ |
$vars['rssurl'] = $config->getURL($rep, $path, 'rss').$isDirString.createRevAndPegString('', $peg); |
$vars['rsslink'] = '<a href="'.$vars['rssurl'].'">'.$lang['RSSFEED'].'</a>'; |
} |
if ($rev != $youngest) |
{ |
if ($path == '/') |
{ |
$vars['goyoungesturl'] = $config->getURL($rep, '', 'log').$isDirString; |
} |
else |
{ |
$vars['goyoungesturl'] = $config->getURL($rep, $path, 'log').$isDirString.'peg='.($peg ? $peg : $rev); |
} |
$vars['goyoungestlink'] = '<a href="'.$vars['goyoungesturl'].'"'.($youngest ? ' title="'.$lang['REV'].' '.$youngest.'"' : '').'>'.$lang['GOYOUNGEST'].'</a>'; |
} |
// We get the bugtraq variable just once based on the HEAD |
$bugtraq = new Bugtraq($rep, $svnrep, $ppath); |
if ($startrev != "HEAD") $startrev = (int)$startrev; |
if (empty($startrev)) $startrev = $rev; |
if (empty($endrev)) $endrev = 1; |
$vars['logsearch_moreresultslink'] = ''; |
$vars['pagelinks'] = ''; |
$vars['showalllink'] = ''; |
if (empty($_REQUEST["max"])) |
if ($history) |
{ |
if (empty($_REQUEST["logsearch"])) |
$max = 30; |
else |
$max = 0; |
$history = $svnrep->getLog($path, $startrev, $endrev, true, $max, $peg); |
if (empty($history)) |
{ |
unset($vars['error']); |
$vars['warning'] = 'Revision '.$startrev.' of this resource does not exist.'; |
} |
} |
else |
if (!empty($history)) |
{ |
$max = (int)$max; |
if ($max < 0) $max = 30; |
// Get the number of separate revisions |
$revisions = count($history->entries); |
if ($all) |
{ |
$firstrevindex = 0; |
$lastrevindex = $revisions - 1; |
$pages = 1; |
} |
else |
{ |
// Calculate the number of pages |
$pages = floor($revisions / $maxperpage); |
if (($revisions % $maxperpage) > 0) $pages++; |
if ($page > $pages) $page = $pages; |
// Work out where to start and stop |
$firstrevindex = ($page - 1) * $maxperpage; |
$lastrevindex = min($firstrevindex + $maxperpage - 1, $revisions - 1); |
} |
$frev = isset($history->entries[0]) ? $history->entries[0]->rev : false; |
$brev = isset($history->entries[$firstrevindex]) ? $history->entries[$firstrevindex]->rev : false; |
$erev = isset($history->entries[$lastrevindex]) ? $history->entries[$lastrevindex]->rev : false; |
$entries = array(); |
if ($brev && $erev) |
{ |
$history = $svnrep->getLog($path, $brev, $erev, false, 0, $peg, true); |
if ($history) |
{ |
$entries = $history->entries; |
} |
} |
$row = 0; |
$index = 0; |
$found = false; |
foreach ($entries as $revision) |
{ |
// Assume a good match |
$match = true; |
$thisrev = $revision->rev; |
// Check the log for the search words, if searching |
if ($dosearch) |
{ |
if ((empty($fromRev) || $fromRev > $thisrev)) |
{ |
// Turn all the HTML entities into real characters. |
// Make sure that each word in the search in also in the log |
foreach ($words as $word) |
{ |
if (strpos(strtolower(removeAccents($revision->msg)), $word) === false && strpos(strtolower(removeAccents($revision->author)), $word) === false) |
{ |
$match = false; |
break; |
} |
} |
if ($match) |
{ |
$numSearchResults--; |
$found = true; |
} |
} |
else |
{ |
$match = false; |
} |
} |
$thisRevString = createRevAndPegString($thisrev, ($peg ? $peg : $thisrev)); |
if ($match) |
{ |
// Add the trailing slash if we need to (svnlook history doesn't return trailing slashes!) |
$rpath = $revision->path; |
if (empty($rpath)) |
{ |
$rpath = '/'; |
} |
else if ($isDir && $rpath[strlen($rpath) - 1] != '/') |
{ |
$rpath .= '/'; |
} |
$precisePath = $revision->precisePath; |
if (empty($precisePath)) |
{ |
$precisePath = '/'; |
} |
else if ($isDir && $precisePath[strlen($precisePath) - 1] != '/') |
{ |
$precisePath .= '/'; |
} |
// Find the parent path (or the whole path if it's already a directory) |
$pos = strrpos($rpath, '/'); |
$parent = substr($rpath, 0, $pos + 1); |
$compareValue = (($isDir) ? $parent : $rpath).'@'.$thisrev; |
$listvar = &$listing[$index]; |
$listvar['compare_box'] = '<input type="checkbox" name="compare[]" value="'.$compareValue.'" onclick="enforceOnlyTwoChecked(this)" />'; |
$url = $config->getURL($rep, $rpath, 'revision').$thisRevString; |
$listvar['revlink'] = '<a href="'.$url.'">'.$thisrev.'</a>'; |
$url = $config->getURL($rep, $precisePath, ($isDir ? 'dir' : 'file')).$thisRevString; |
$listvar['revpathlink'] = '<a href="'.$url.'">'.escape($precisePath).'</a>'; |
$listvar['revpath'] = escape($precisePath); |
$listvar['revauthor'] = $revision->author; |
$listvar['revdate'] = $revision->date; |
$listvar['revage'] = $revision->age; |
$listvar['revlog'] = nl2br($bugtraq->replaceIDs(create_anchors(xml_entities($revision->msg)))); |
$listvar['rowparity'] = $row; |
$listvar['compareurl'] = $config->getURL($rep, '', 'comp').'compare[]='.urlencode($rpath).'@'.($thisrev - 1).'&compare[]='.urlencode($rpath).'@'.$thisrev; |
if ($showchanges) |
{ |
// Aggregate added/deleted/modified paths for display in table |
$modpaths = array(); |
foreach ($revision->mods as $mod) |
{ |
$modpaths[$mod->action][] = $mod->path; |
} |
ksort($modpaths); |
foreach ($modpaths as $action => $paths) |
{ |
sort($paths); |
$modpaths[$action] = $paths; |
} |
$listvar['revadded'] = (isset($modpaths['A'])) ? implode('<br/>', escape($modpaths['A'])) : ''; |
$listvar['revdeleted'] = (isset($modpaths['D'])) ? implode('<br/>', escape($modpaths['D'])) : ''; |
$listvar['revmodified'] = (isset($modpaths['M'])) ? implode('<br/>', escape($modpaths['M'])) : ''; |
} |
$row = 1 - $row; |
$index++; |
} |
// If we've reached the search limit, stop here... |
if (!$numSearchResults) |
{ |
$url = $config->getURL($rep, $path, 'log').$isDirString.$thisRevString; |
$vars['logsearch_moreresultslink'] = '<a href="'.$url.'&search='.$search.'&fr='.$thisrev.'">'.$lang['MORERESULTS'].'</a>'; |
break; |
} |
} |
$vars['logsearch_resultsfound'] = true; |
if ($dosearch && !$found) |
{ |
if ($fromRev == 0) |
{ |
$vars['logsearch_nomatches'] = true; |
$vars['logsearch_resultsfound'] = false; |
} |
else |
{ |
$vars['logsearch_nomorematches'] = true; |
} |
} |
else if ($dosearch && $numSearchResults > 0) |
{ |
$vars['logsearch_nomorematches'] = true; |
} |
// Work out the paging options, create links to pages of results |
if ($pages > 1) |
{ |
$prev = $page - 1; |
$next = $page + 1; |
unset($queryParams['page']); |
$logurl = $config->getURL($rep, $path, 'log').buildQuery($queryParams); |
if ($page > 1) |
{ |
$vars['pagelinks'] .= '<a href="'.$logurl.(!$peg && $frev && $prev != 1 ? '&peg='.$frev : '').'&page='.$prev.'">←'.$lang['PREV'].'</a>'; |
} |
else |
{ |
$vars['pagelinks'] .= '<span>←'.$lang['PREV'].'</span>'; |
} |
for ($p = 1; $p <= $pages; $p++) |
{ |
if ($p != $page) |
{ |
$vars['pagelinks'] .= '<a href="'.$logurl.(!$peg && $frev && $p != 1 ? '&peg='.$frev : '').'&page='.$p.'">'.$p.'</a>'; |
} |
else |
{ |
$vars['pagelinks'] .= '<span id="curpage">'.$p.'</span>'; |
} |
} |
if ($page < $pages) |
{ |
$vars['pagelinks'] .= '<a href="'.$logurl.(!$peg && $frev ? '&peg='.$frev : '').'&page='.$next.'">'.$lang['NEXT'].'→</a>'; |
} |
else |
{ |
$vars['pagelinks'] .= '<span>'.$lang['NEXT'].'→</span>'; |
} |
$vars['showalllink'] = '<a href="'.$logurl.'&all=1">'.$lang['SHOWALL'].'</a>'; |
} |
} |
$history = $svnrep->getLog($path, $startrev, $endrev, true, $max); |
$vars["logsearch_moreresultslink"] = ""; |
$vars["pagelinks"] = ""; |
$vars["showalllink"] = ""; |
$listing = array(); |
// Create form elements for filtering and searching log messages |
if ($config->multiViews) |
{ |
$hidden = '<input type="hidden" name="op" value="log" />'; |
} |
else |
{ |
$hidden = '<input type="hidden" name="repname" value="'.$repname.'" />'; |
$hidden .= '<input type="hidden" name="path" value="'.$path.'" />'; |
} |
if (!empty($history)) |
if ($isDir) |
{ |
// Get the number of separate revisions |
$revisions = count($history->entries); |
if ($all) |
{ |
$firstrevindex = 0; |
$lastrevindex = $revisions - 1; |
$pages = 1; |
} |
else |
{ |
// Calculate the number of pages |
$pages = floor($revisions / $maxperpage); |
if (($revisions % $maxperpage) > 0) $pages++; |
if ($page > $pages) $page = $pages; |
// Word out where to start and stop |
$firstrevindex = ($page - 1) * $maxperpage; |
$lastrevindex = $firstrevindex + $maxperpage - 1; |
if ($lastrevindex > $revisions - 1) $lastrevindex = $revisions - 1; |
} |
$history = $svnrep->getLog($path, $history->entries[$firstrevindex ]->rev, $history->entries[$lastrevindex]->rev, false, 0); |
$row = 0; |
$index = 0; |
$listing = array(); |
$found = false; |
foreach ($history->entries as $r) |
{ |
// Assume a good match |
$match = true; |
$thisrev = $r->rev; |
// Check the log for the search words, if searching |
if ($dosearch) |
{ |
if ((empty($fromRev) || $fromRev > $thisrev)) |
{ |
// Turn all the HTML entities into real characters. |
// Make sure that each word in the search in also in the log |
foreach($words as $word) |
{ |
if (strpos(strtolower(removeAccents($r->msg)), $word) === false) |
{ |
$match = false; |
break; |
} |
} |
if ($match) |
{ |
$numSearchResults--; |
$found = true; |
} |
} |
else |
$match = false; |
} |
if ($match) |
{ |
// Add the trailing slash if we need to (svnlook history doesn't return trailing slashes!) |
$rpath = $r->path; |
if (empty($rpath)) |
$rpath = "/"; |
else if ($isDir && $rpath{strlen($rpath) - 1} != "/") |
$rpath .= "/"; |
// Find the parent path (or the whole path if it's already a directory) |
$pos = strrpos($rpath, "/"); |
$parent = substr($rpath, 0, $pos + 1); |
$url = $config->getURL($rep, $parent, "dir"); |
$listing[$index]["revlink"] = "<a href=\"${url}rev=$thisrev&sc=1\">$thisrev</a>"; |
if ($isDir) |
{ |
$listing[$index]["compare_box"] = "<input type=\"checkbox\" name=\"compare[]\" value=\"$parent@$thisrev\" onclick=\"checkCB(this)\" />"; |
$url = $config->getURL($rep, $rpath, "dir"); |
$listing[$index]["revpathlink"] = "<a href=\"${url}rev=$thisrev&sc=$showchanged\">$rpath</a>"; |
} |
else |
{ |
$listing[$index]["compare_box"] = "<input type=\"checkbox\" name=\"compare[]\" value=\"$rpath@$thisrev\" onclick=\"checkCB(this)\" />"; |
$url = $config->getURL($rep, $rpath, "file"); |
$listing[$index]["revpathlink"] = "<a href=\"${url}rev=$thisrev&sc=$showchanged\">$rpath</a>"; |
} |
$listing[$index]["revauthor"] = $r->author; |
$listing[$index]["revage"] = $r->age; |
$listing[$index]["revlog"] = nl2br($bugtraq->replaceIDs(create_anchors($r->msg))); |
$listing[$index]["rowparity"] = "$row"; |
$row = 1 - $row; |
$index++; |
} |
// If we've reached the search limit, stop here... |
if (!$numSearchResults) |
{ |
$url = $config->getURL($rep, $path, "log"); |
$vars["logsearch_moreresultslink"] = "<a href=\"${url}rev=$rev&sc=$showchanged&isdir=$isDir&logsearch=1&search=$search&fr=$thisrev\">${lang["MORERESULTS"]}</a>"; |
break; |
} |
} |
$vars["logsearch_resultsfound"] = true; |
if ($dosearch && !$found) |
{ |
if ($fromRev == 0) |
{ |
$vars["logsearch_nomatches"] = true; |
$vars["logsearch_resultsfound"] = false; |
} |
else |
$vars["logsearch_nomorematches"] = true; |
} |
else if ($dosearch && $numSearchResults > 0) |
{ |
$vars["logsearch_nomorematches"] = true; |
} |
// Work out the paging options |
if ($pages > 1) |
{ |
$prev = $page - 1; |
$next = $page + 1; |
echo "<p><center>"; |
if ($page > 1) $vars["pagelinks"] .= "<a href=\"${logurl}rev=$rev&sr=$startrev&er=$endrev&sc=$showchanged&max=$max&page=$prev\">< ${lang["PREV"]}</a> "; |
for ($p = 1; $p <= $pages; $p++) |
{ |
if ($p != $page) |
$vars["pagelinks"].= "<a href=\"${logurl}rev=$rev&sr=$startrev&er=$endrev&sc=$showchanged&max=$max&page=$p\">$p</a> "; |
else |
$vars["pagelinks"] .= "<b>$p </b>"; |
} |
if ($page < $pages) $vars["pagelinks"] .=" <a href=\"${logurl}rev=$rev&sr=$startrev&er=$endrev&sc=$showchanged&max=$max&page=$next\">${lang["NEXT"]} ></a>"; |
$vars["showalllink"] = "<a href=\"${logurl}rev=$rev&sr=$startrev&er=$endrev&sc=$showchanged&all=1&max=$max\">${lang["SHOWALL"]}</a>"; |
echo "</center>"; |
} |
$hidden .= '<input type="hidden" name="isdir" value="'.$isDir.'" />'; |
} |
// Create the project change combo box |
$url = $config->getURL($rep, $path, "log"); |
# XXX: forms don't have the name attribute, but _everything_ has the id attribute, |
# so what you're trying to do (if anything?) should be done via that ~J |
$vars["logsearch_form"] = "<form action=\"$url\" method=\"post\" name=\"logsearchform\">"; |
if ($peg) |
{ |
$hidden .= '<input type="hidden" name="peg" value="'.$peg.'" />'; |
} |
$vars["logsearch_startbox"] = "<input name=\"sr\" size=\"5\" value=\"$startrev\" />"; |
$vars["logsearch_endbox" ] = "<input name=\"er\" size=\"5\" value=\"$endrev\" />"; |
$vars["logsearch_maxbox" ] = "<input name=\"max\" size=\"5\" value=\"".($max==0?"":$max)."\" />"; |
$vars["logsearch_inputbox"] = "<input name=\"search\" value=\"$search\" />"; |
if ($showchanges != $rep->logsShowChanges()) |
{ |
$hidden .= '<input type="hidden" name="showchanges" value="'.$showchanges.'" />'; |
} |
$vars["logsearch_submit"] = "<input type=\"submit\" value=\"${lang["GO"]}\" />"; |
$vars["logsearch_endform"] = "<input type=\"hidden\" name=\"logsearch\" value=\"1\" />". |
"<input type=\"hidden\" name=\"op\" value=\"log\" />". |
"<input type=\"hidden\" name=\"rev\" value=\"$rev\" />". |
"<input type=\"hidden\" name=\"sc\" value=\"$showchanged\" />". |
"<input type=\"hidden\" name=\"isdir\" value=\"$isDir\" />". |
"</form>"; |
$vars['logsearch_form'] = '<form method="get" action="'.$config->getURL($rep, $path, 'log').'" id="search">'.$hidden; |
$vars['logsearch_startbox'] = '<input name="sr" size="5" value="'.$startrev.'" />'; |
$vars['logsearch_endbox'] = '<input name="er" size="5" value="'.$endrev.'" />'; |
$vars['logsearch_maxbox'] = '<input name="max" size="5" value="'.($max == 0 ? 40 : $max).'" />'; |
$vars['logsearch_inputbox'] = '<input name="search" value="'.escape($search).'" />'; |
$vars['logsearch_showall'] = '<input type="checkbox" name="all" value="1"'.($all ? ' checked="checked"' : '').' />'; |
$vars['logsearch_submit'] = '<input type="submit" value="'.$lang['GO'].'" />'; |
$vars['logsearch_endform'] = '</form>'; |
$url = $config->getURL($rep, $path, "log"); |
$vars["logsearch_clearloglink"] = "<a href=\"${url}rev=$rev&sc=$showchanged&isdir=$isDir\">${lang["CLEARLOG"]}</a>"; |
// If a filter is in place, produce a link to clear all filter parameters |
if ($page !== 1 || $all || $dosearch || $fromRev || $startrev !== $rev || $endrev !== 1 || $max !== 40) |
{ |
$url = $config->getURL($rep, $path, 'log').$isDirString.$passRevString; |
$vars['logsearch_clearloglink'] = '<a href="'.$url.'">'.$lang['CLEARLOG'].'</a>'; |
} |
$url = $config->getURL($rep, "/", "comp"); |
$vars["compare_form"] = "<form action=\"$url\" method=\"post\" name=\"compareform\">"; |
$vars["compare_submit"] = "<input name=\"comparesubmit\" type=\"submit\" value=\"${lang["COMPAREREVS"]}\" />"; |
$vars["compare_endform"] = "<input type=\"hidden\" name=\"op\" value=\"comp\" /><input type=\"hidden\" name=\"sc\" value=\"$showchanged\" /></form>"; |
// Create form elements for comparing selected revisions |
$vars['compare_form'] = '<form method="get" action="'.$config->getURL($rep, '', 'comp').'" id="compare">'; |
$vars["version"] = $version; |
if ($config->multiViews) |
{ |
$vars['compare_form'] .= '<input type="hidden" name="op" value="comp" />'; |
} |
else |
{ |
$vars['compare_form'] .= '<input type="hidden" name="repname" value="'.$repname.'" />'; |
} |
if (!$rep->hasReadAccess($path, false)) |
$vars["noaccess"] = true; |
$vars['compare_submit'] = '<input type="submit" value="'.$lang['COMPAREREVS'].'" />'; |
$vars['compare_endform'] = '</form>'; |
parseTemplate($rep->getTemplatePath()."header.tmpl", $vars, $listing); |
parseTemplate($rep->getTemplatePath()."log.tmpl", $vars, $listing); |
parseTemplate($rep->getTemplatePath()."footer.tmpl", $vars, $listing); |
if (!$rep->hasReadAccess($path, false)) |
{ |
$vars['error'] = $lang['NOACCESS']; |
sendHeaderForbidden(); |
} |
?> |
renderTemplate('log'); |
/WebSVN/multiviews.php |
---|
0,0 → 1,139 |
<?php |
// WebSVN - Subversion repository viewing via the web using PHP |
// Copyright (C) 2004-2006 Tim Armes |
// |
// This program is free software; you can redistribute it and/or modify |
// it under the terms of the GNU General Public License as published by |
// the Free Software Foundation; either version 2 of the License, or |
// (at your option) any later version. |
// |
// This program is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License |
// along with this program; if not, write to the Free Software |
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
// |
// -- |
// |
// multiviews.php |
// |
// Glue for MultiViews |
chdir($locwebsvnreal); |
// Tell files that we are using multiviews if they are unable to access $config. |
if (!defined('WSVN_MULTIVIEWS')) { |
define('WSVN_MULTIVIEWS', 1); |
} |
require_once 'include/setup.php'; |
require_once 'include/svnlook.php'; |
if (!isset($_REQUEST['sc'])) { |
$_REQUEST['sc'] = 1; |
} |
if (!$config->multiViews) { |
$vars['error'] = 'MultiViews must be enabled in <code>include/config.php</code> in order to use <code>browse.php</code>. See <a href="'.$locwebsvnhttp.'/doc/install.html#multiviews">the install docs</a> for details, or use <a href="'.$locwebsvnhttp.'">this path</a> instead.'; |
include $locwebsvnreal.'/index.php'; |
exit; |
} |
$op = @$_REQUEST['op']; |
// This means the user wants to browse another project, so we switch to it and exit. |
if ($op == 'rep') { |
$rep =& $config->findRepository(@$_REQUEST['repname']); |
if ($rep != null) { |
header('Location: '.$config->getURL($rep, '', 'dir')); |
} else { |
include $locwebsvnreal.'/index.php'; |
} |
exit; |
} |
$origPathInfo = isset($_SERVER['ORIG_PATH_INFO']) ? $_SERVER['ORIG_PATH_INFO'] : ''; |
$pathInfo = isset($_SERVER['PATH_INFO']) ? $_SERVER['PATH_INFO'] : ''; |
$path = trim(empty($pathInfo) ? $origPathInfo : $pathInfo); |
// Remove initial slash |
$path = substr($path, 1); |
if (empty($path)) { |
include $locwebsvnreal.'/index.php'; |
exit; |
} |
// Split the path into repository and path elements |
// Note: we have to cope with the repository name having a slash in it |
$pos = strpos($path, '/'); |
if ($pos === false) { |
$pos = strlen($path); |
} |
$name = substr($path, 0, $pos); |
$rep =& $config->findRepository($name); |
if ($rep != null && is_object($rep)) { |
$path = substr($path, $pos); |
if ($path == '') { |
$path = '/'; |
} |
$repname = $name; |
} else { |
include $locwebsvnreal.'/index.php'; |
exit; |
} |
createProjectSelectionForm(); |
createRevisionSelectionForm(); |
$vars['repurl'] = $config->getURL($rep, '', 'dir'); |
$vars['clientrooturl'] = $rep->clientRootURL; |
$vars['allowdownload'] = $rep->getAllowDownload(); |
$vars['repname'] = escape($rep->getDisplayName()); |
// find the operation type |
switch ($op) { |
case 'dir': |
$file = 'listing.php'; |
break; |
case 'revision': |
$file = 'revision.php'; |
break; |
case 'file': |
$file = 'filedetails.php'; |
break; |
case 'log': |
$file = 'log.php'; |
break; |
case 'diff': |
$file = 'diff.php'; |
break; |
case 'blame': |
$file = 'blame.php'; |
break; |
case 'rss': |
$file = 'rss.php'; |
break; |
case 'dl': |
$file = 'dl.php'; |
break; |
case 'comp': |
$file = 'comp.php'; |
break; |
case 'search': |
$file = 'search.php'; |
break; |
default: |
$svnrep = new SVNRepository($rep); |
if ($svnrep->isFile($path, $rev, $peg)) { |
$file = 'filedetails.php'; |
} else { |
$file = 'listing.php'; |
} |
break; |
} |
// Now include the file that handles it |
include $locwebsvnreal.'/'.$file; |
/WebSVN/revision.php |
---|
0,0 → 1,222 |
<?php |
// WebSVN - Subversion repository viewing via the web using PHP |
// Copyright (C) 2004-2006 Tim Armes |
// |
// This program is free software; you can redistribute it and/or modify |
// it under the terms of the GNU General Public License as published by |
// the Free Software Foundation; either version 2 of the License, or |
// (at your option) any later version. |
// |
// This program is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License |
// along with this program; if not, write to the Free Software |
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
// |
// -- |
// |
// revision.php |
// |
// Show the details for a given revision |
require_once 'include/setup.php'; |
require_once 'include/svnlook.php'; |
require_once 'include/utils.php'; |
require_once 'include/template.php'; |
require_once 'include/bugtraq.php'; |
// Make sure that we have a repository |
if (!$rep) |
{ |
renderTemplate404('revision','NOREP'); |
} |
$svnrep = new SVNRepository($rep); |
$ppath = ($path == '' || $path[0] != '/') ? '/'.$path : $path; |
createPathLinks($rep, $ppath, $rev, $peg); |
$passRevString = createRevAndPegString($rev, $peg); |
// Find the youngest revision containing changes for the given path |
$history = $svnrep->getLog($path, 'HEAD', 1, true, 2, ($path == '/') ? '' : $peg); |
if (!$history) |
{ |
unset($vars['error']); |
$history = $svnrep->getLog($path, '', '', true, 2, ($path == '/') ? '' : $peg); |
if (!$history) |
{ |
renderTemplate404('revision','NOPATH'); |
} |
} |
$youngest = ($history && isset($history->entries[0])) ? $history->entries[0]->rev : 0; |
$vars['youngestrev'] = $youngest; |
// TODO The "youngest" rev is often incorrect when both path and rev are specified. |
// If a path was last modified at rev M and the URL contains rev N, it uses rev N. |
// Unless otherwise specified, we get the log details of the latest change |
$lastChangedRev = ($rev) ? $rev : $youngest; |
$history = $svnrep->getLog($path, $lastChangedRev, 1, false, 2, $peg, true); |
if (!$history) |
{ |
renderTemplate404('revision','NOPATH'); |
} |
if (empty($rev)) |
{ |
$rev = $lastChangedRev; |
} |
// Generate links to newer and older revisions |
$revurl = $config->getURL($rep, $path, 'revision'); |
if ($rev < $youngest) |
{ |
$vars['goyoungesturl'] = $config->getURL($rep, $path, 'revision'); |
$vars['goyoungestlink'] = '<a href="'.$vars['goyoungesturl'].'"'.($youngest ? ' title="'.$lang['REV'].' '.$youngest.'"' : '').'>'.$lang['GOYOUNGEST'].'</a>'; |
$history2 = $svnrep->getLog($path, $rev, $youngest, true, 2, $peg); |
if (isset($history2->entries[1])) |
{ |
$nextRev = $history2->entries[1]->rev; |
if ($nextRev != $youngest) |
{ |
$vars['nextrev'] = $nextRev; |
$vars['nextrevurl'] = $revurl.createRevAndPegString($nextRev, $path != '/' ? $peg ? $peg : $rev : ''); |
//echo 'NEXT='.$vars['nextrevurl'].'<br/>'; |
} |
} |
unset($vars['error']); |
} |
if (isset($history->entries[1])) |
{ |
$prevRev = $history->entries[1]->rev; |
$prevPath = $history->entries[1]->path; |
$vars['prevrev'] = $prevRev; |
$vars['prevrevurl'] = $revurl.createRevAndPegString($prevRev, $path != '/' ? ($peg ? $peg : $rev) : ''); |
//echo 'PREV='.$vars['prevrevurl'].'<br/>'; |
} |
// Save the entry from which we pull information for the current revision. |
$logEntry = (isset($history->entries[0])) ? $history->entries[0] : null; |
$bugtraq = new Bugtraq($rep, $svnrep, $ppath); |
$vars['action'] = ''; |
$vars['rev'] = $rev; |
$vars['peg'] = $peg; |
$vars['path'] = str_replace('%2F', '/', rawurlencode($ppath)); |
$vars['safepath'] = escape($ppath); |
if ($logEntry) |
{ |
$vars['date'] = $logEntry->date; |
$vars['age'] = datetimeFormatDuration(time() - strtotime($logEntry->date)); |
$vars['author'] = $logEntry->author; |
$vars['log'] = nl2br($bugtraq->replaceIDs(create_anchors(xml_entities($logEntry->msg)))); |
} |
$isDir = @$_REQUEST['isdir'] == 1 || $path == '' || $path == '/'; |
$vars['logurl'] = $config->getURL($rep, $path, 'log').$passRevString.($isDir ? '&isdir=1' : ''); |
$vars['loglink'] = '<a href="'.$vars['logurl'].'">'.$lang['VIEWLOG'].'</a>'; |
$dirPath = $isDir ? $path : dirname($path).'/'; |
$vars['directoryurl'] = $config->getURL($rep, $dirPath, 'dir').$passRevString.'#'.anchorForPath($dirPath); |
$vars['directorylink'] = '<a href="'.$vars['directoryurl'].'">'.$lang['LISTING'].'</a>'; |
if ($path != $dirPath) |
{ |
$vars['filedetailurl'] = $config->getURL($rep, $path, 'file').$passRevString; |
$vars['filedetaillink'] = '<a href="'.$vars['filedetailurl'].'">'.$lang['FILEDETAIL'].'</a>'; |
$vars['blameurl'] = $config->getURL($rep, $path, 'blame').$passRevString; |
$vars['blamelink'] = '<a href="'.$vars['blameurl'].'">'.$lang['BLAME'].'</a>'; |
} |
if ($rep->isRssEnabled()) |
{ |
$vars['rssurl'] = $config->getURL($rep, $path, 'rss').createRevAndPegString('', $peg); |
$vars['rsslink'] = '<a href="'.$vars['rssurl'].'">'.$lang['RSSFEED'].'</a>'; |
} |
$changes = $logEntry ? $logEntry->mods : array(); |
if (!is_array($changes)) |
{ |
$changes = array(); |
} |
usort($changes, 'SVNLogEntry_compare'); |
$row = 0; |
$prevRevString = createRevAndPegString($rev - 1, $rev - 1); |
$thisRevString = createRevAndPegString($rev, $rev); |
foreach ($changes as $change) |
{ |
$linkRevString = ($change->action == 'D') ? $prevRevString : $thisRevString; |
$isDir = $change->isdir; |
if ($isDir !== null) |
{ |
$isFile = !$isDir; |
} |
else |
{ |
// NOTE: This is a hack (runs `svn info` on each path) to see if it's a file. |
// `svn log --verbose --xml` should really provide this info, but does only in recent version? |
$lastSeenRev = ($change->action == 'D') ? $rev - 1 : $rev; |
$isFile = $svnrep->isFile($change->path, $lastSeenRev, $lastSeenRev); |
} |
if (!$isFile && $change->path != '/') |
{ |
$change->path .= '/'; |
} |
$resourceExisted = $change->action == 'M' || $change->copyfrom; |
$listing[] = array( |
'path' => str_replace('%2F', '/', rawurlencode($change->path)), |
'safepath' => escape($change->path), |
'oldpath' => str_replace('%2F', '/', rawurlencode($change->copyfrom)).($change->copyfrom ? '@'.$change->copyrev : ''), |
'oldsafepath' => escape($change->copyfrom ? $change->copyfrom.'@'.$change->copyrev : ''), |
'action' => $change->action, |
'added' => $change->action == 'A', |
'deleted' => $change->action == 'D', |
'modified' => $change->action == 'M', |
'detailurl' => $config->getURL($rep, $change->path, ($isFile ? 'file' : 'dir')).$linkRevString, |
// For deleted resources, the log link points to the previous revision. |
'logurl' => $config->getURL($rep, $change->path, 'log').$linkRevString.($isFile ? '' : '&isdir=1'), |
'diffurl' => $resourceExisted ? $config->getURL($rep, $change->path, 'diff').$linkRevString : '', |
'blameurl' => $resourceExisted ? $config->getURL($rep, $change->path, 'blame').$linkRevString : '', |
'rowparity' => $row, |
'notinpath' => substr($change->path, 0, strlen($path)) != $path, |
); |
$row = 1 - $row; |
} |
if (isset($prevRev)) |
{ |
$vars['compareurl'] = $config->getURL($rep, '', 'comp').'compare[]='.rawurlencode($prevPath).'@'.$prevRev. '&compare[]='.rawurlencode($path).'@'.$rev; |
$vars['comparelink'] = '<a href="'.$vars['compareurl'].'">'.$lang['DIFFPREV'].'</a>'; |
} |
if (!$rep->hasReadAccess($path)) |
{ |
$vars['error'] = $lang['NOACCESS']; |
sendHeaderForbidden(); |
} |
$vars['restricted'] = !$rep->hasReadAccess($path, false); |
renderTemplate('revision'); |
/WebSVN/rss.php |
---|
1,8 → 1,6 |
<?php |
# vim:et:ts=3:sts=3:sw=3:fdm=marker: |
// WebSVN - Subversion repository viewing via the web using PHP |
// Copyright © 2004-2006 Tim Armes, Matt Sicker |
// Copyright (C) 2004-2006 Tim Armes |
// |
// This program is free software; you can redistribute it and/or modify |
// it under the terms of the GNU General Public License as published by |
11,12 → 9,12 |
// |
// This program is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License |
// along with this program; if not, write to the Free Software |
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
// |
// -- |
// |
24,147 → 22,140 |
// |
// Creates an rss feed for the given repository number |
include("include/feedcreator.class.php"); |
require_once 'include/setup.php'; |
require_once 'include/svnlook.php'; |
require_once 'include/utils.php'; |
require_once 'include/template.php'; |
require_once 'include/bugtraq.php'; |
require_once("include/setup.inc"); |
require_once("include/svnlook.inc"); |
require_once("include/utils.inc"); |
require_once("include/template.inc"); |
$max = (int)@$_REQUEST['max']; |
if ($max == 0) |
$max = $config->getRssMaxEntries(); |
$quiet = (isset($_REQUEST['quiet'])); |
$isDir = (@$_REQUEST["isdir"] == 1)?1:0; |
$maxmessages = 20; |
// Find the base URL name |
if ($config->multiViews) |
{ |
$baseurl = ""; |
if ($config->multiViews) { |
$baseurl = ''; |
} else { |
$baseurl = dirname($_SERVER['PHP_SELF']); |
if ($baseurl != '' && $baseurl != DIRECTORY_SEPARATOR && $baseurl != '\\' && $baseurl != '/') { |
$baseurl .= '/'; |
} else { |
$baseurl = '/'; |
} |
} |
else |
{ |
$baseurl = dirname($_SERVER["PHP_SELF"]); |
if ($baseurl != "" && $baseurl != DIRECTORY_SEPARATOR && $baseurl != "\\" && $baseurl != "/" ) |
$baseurl .= "/"; |
else |
$baseurl = "/"; |
if ($path == '' || $path[0] != '/') { |
$ppath = '/'.$path; |
} else { |
$ppath = $path; |
} |
$svnrep = new SVNRepository($rep); |
if ($path == "" || $path{0} != "/") |
$ppath = "/".$path; |
else |
$ppath = $path; |
if (!$rep) { |
http_response_code(404); |
print 'Unable to access resource at path: '.xml_entities($path); |
exit; |
} |
// Make sure that the user has full access to the specified directory |
if (!$rep->hasReadAccess($path, false)) |
exit; |
if (!$rep->hasReadAccess($path, false)) { |
http_response_code(403); |
print 'Unable to access resource at path: '.xml_entities($path); |
exit; |
} |
$url = $config->getURL($rep, $path, "log"); |
$listurl = $config->getURL($rep, $path, "dir"); |
// If there's no revision info, go to the lastest revision for this path |
$history = $svnrep->getLog($path, $rev, "", false, 20); |
$youngest = $history->entries[0]->rev; |
$svnrep = new SVNRepository($rep); |
$history = $svnrep->getLog($path, $rev, '', false, $max, $peg, !$quiet); |
if (!$history) { |
http_response_code(404); |
echo $lang['NOPATH']; |
exit; |
} |
// Cachename reflecting full path to and rev for rssfeed. Must end with xml to work |
$cachename = strtr(getFullURL($listurl), ":/\\?", "____"); |
$cachename = $locwebsvnreal.DIRECTORY_SEPARATOR."cache".DIRECTORY_SEPARATOR.$cachename.@$_REQUEST["rev"]."_rssfeed.xml"; |
header('Content-Type: application/xml; charset=utf-8'); |
$rss = new UniversalFeedCreator(); |
$rss->useCached("RSS2.0", $cachename); |
$rss->title = $rep->getDisplayName(); |
$rss->description = "${lang["RSSFEEDTITLE"]} - $repname"; |
$rss->link = html_entity_decode(getFullURL($baseurl.$listurl)); |
$rss->syndicationURL = $rss->link; |
$rss->xslStyleSheet = ""; //required for UniversalFeedCreator since 1.7 |
$rss->cssStyleSheet = ""; //required for UniversalFeedCreator since 1.7 |
if ($rep->isRssCachingEnabled()) { |
// Filename for storing a cached RSS feed for this particular path/revision |
$cache = $locwebsvnreal.DIRECTORY_SEPARATOR.'cache'.DIRECTORY_SEPARATOR.strtr($rep->getDisplayName().$path, '\\/:*?"<>|.', '__________').($peg ? '@'.$peg : '').($rev ? '_r'.$rev : '').'m'.$max.($quiet ? 'q' : '').'.rss.xml'; |
// If a recent-enough cached version exists, use it and avoid the work below |
if (file_exists($cache) && filemtime($cache) >= $history->curEntry->committime) { |
readfile($cache); |
exit(); |
} |
} |
//$divbox = "<div>"; |
//$divfont = "<span>"; |
$bugtraq = new Bugtraq($rep, $svnrep, $ppath); |
foreach ($history->entries as $r) |
{ |
$thisrev = $r->rev; |
$changes = $r->mods; |
$files = count($changes); |
// Generate RSS 2.0 feed |
$rss = '<?xml version="1.0" encoding="utf-8"?>'; |
$rss .= '<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom"><channel>'; |
$rss .= '<title>'.escape($rep->getDisplayName()).($path ? ' – '.$path : '').'</title>'; |
$rss .= '<description>'.escape($lang['RSSFEEDTITLE']).' – '.escape($repname).'</description>'; |
$rss .= '<lastBuildDate>'.date('r').'</lastBuildDate>'; // RFC 2822 date format |
$rss .= '<generator>WebSVN '.$vars['version'].'</generator>'; |
$rss .= '<language>'.$lang['LANGUAGETAG'].'</language>'; |
// URL for matching WebSVN log page |
$rss .= '<link>'.getFullURL($baseurl.$config->getURL($rep, $path, 'log').(@$_REQUEST['isdir'] == 1 ? 'isdir=1&' : '').'max='.$max.'&'.createRevAndPegString($passrev, $peg)).'</link>'; |
// URL where this original RSS feed can be found |
$rss .= '<atom:link href="'.escape(getFullURL($_SERVER['REQUEST_URI'])).'" rel="self" type="application/rss+xml" />'."\n"; |
if (is_array($history->entries)) { |
$itemURL = $baseurl.$config->getURL($rep, $path, 'revision'); |
if (@$_REQUEST['isdir'] == 1 || $path == '' || $path == '/') |
$itemURL .= 'isdir=1&'; |
foreach ($history->entries as $r) { |
$wordLimit = 10; // Display only up to the first 10 words of the log message |
$title = trim(explode('\n', $r->msg)[0]); |
$title = str_replace(array("\r\n", "\r", "\n", "\t"), ' ', $title); |
$words = explode(' ', $title, $wordLimit + 1); |
if (count($words) > $wordLimit) { |
$title = implode(' ', array_slice($words, 0, $wordLimit)).' ...'; |
} |
$title = $lang['REV'].' '.$r->rev.' '.mb_convert_encoding('–', 'UTF-8', 'HTML-ENTITIES').' '.$title; |
$description = '<div><strong>'.$r->author; |
if (!$quiet) { |
$description .= ' '.mb_convert_encoding('–', 'UTF-8', 'HTML-ENTITIES').' '.count($r->mods).' '.$lang['FILESMODIFIED']; |
} |
$description .= '</strong><br/>'.nl2br($bugtraq->replaceIDs(create_anchors(str_replace('<', '<', $r->msg)))).'</div>'; |
if (!$quiet) { |
usort($r->mods, 'SVNLogEntry_compare'); |
foreach ($r->mods as $modifiedResource) { |
switch ($modifiedResource->action) { |
case 'A': $description .= '+ '; break; |
case 'M': $description .= '~ '; break; |
case 'D': $description .= 'x '; break; |
} |
$description .= $modifiedResource->path; |
if ($modifiedResource->copyfrom != '') { |
$description .= ' <i>(copied from '.$modifiedResource->copyfrom.'@'.$modifiedResource->copyrev.')</i>'; |
} |
$description .= '<br />'; |
} |
} |
// Add the trailing slash if we need to (svnlook history doesn't return trailing slashes!) |
$rpath = $r->path; |
if ($isDir && $rpath{strlen($rpath) - 1} != "/") |
$rpath .= "/"; |
// Find the parent path (or the whole path if it's already a directory) |
$pos = strrpos($rpath, "/"); |
$parent = substr($rpath, 0, $pos + 1); |
$url = $config->getURL($rep, $parent, "dir"); |
$desc = $r->msg; |
$item = new FeedItem(); |
// For the title, we show the first 10 words of the description |
$pos = 0; |
$len = strlen($desc); |
for ($i = 0; $i < 10; $i++) |
{ |
if ($pos >= $len) break; |
$pos = strpos($desc, " ", $pos); |
if ($pos === FALSE) break; |
$pos++; |
} |
if ($pos !== FALSE) |
{ |
$sdesc = substr($desc, 0, $pos) . "..."; |
} |
else |
{ |
$sdesc = $desc; |
} |
if ($desc == "") $sdesc = "${lang["REV"]} $thisrev"; |
$item->title = "$sdesc"; |
$item->link = html_entity_decode(getFullURL($baseurl."${url}rev=$thisrev&sc=$showchanged")); |
$item->description = "<div><strong>${lang["REV"]} $thisrev - ".$r->author."</strong> ($files ${lang["FILESMODIFIED"]})</div><div>".nl2br(create_anchors($desc))."</div>"; |
// skip items with no access |
if ($r->committime) { |
$rss .= '<item>'; |
$rss .= '<pubDate>'.date('r', $r->committime).'</pubDate>'; |
$rss .= '<dc:creator>'.escape($r->author).'</dc:creator>'; |
$rss .= '<title>'.escape($title).'</title>'; |
$rss .= '<description>'.escape($description).'</description>'; |
$itemLink = getFullURL($itemURL.createRevAndPegString($r->rev,$peg)); |
$rss .= '<link>'.$itemLink.'</link>'; |
$rss .= '<guid>'.$itemLink.'</guid>'; |
$rss .= '</item>'."\n"; |
} |
} |
} |
$rss .= '</channel></rss>'; |
if ($showchanged) |
{ |
foreach ($changes as $file) |
{ |
switch ($file->action) |
{ |
case "A": |
$item->description .= "+ ".$file->path."<br />"; |
break; |
case "M": |
$item->description .= "~ ".$file->path."<br />"; |
break; |
case "D": |
$item->description .= "-".$file->path."<br />"; |
break; |
} |
} |
} |
$item->date = $r->committime; |
$item->author = $r->author; |
$rss->addItem($item); |
if ($rep->isRssCachingEnabled()) { |
$file = fopen($cache, 'w+'); |
if ($file) { |
fputs($file, $rss); |
fclose($file); |
touch($cache, $history->curEntry->committime); // set timestamp to commit time |
} else { |
echo 'Error creating RSS cache file, please check write permissions.'; |
} |
} |
// valid format strings are: RSS0.91, RSS1.0, RSS2.0, PIE0.1, MBOX, OPML |
// Save the feed |
$rss->saveFeed("RSS2.0",$cachename, false); |
header("Content-Type: application/xml"); |
echo $rss->createFeed("RSS2.0"); |
?> |
echo $rss; |
/WebSVN/search.php |
---|
0,0 → 1,393 |
<?php |
// WebSVN - Subversion repository viewing via the web using PHP |
// Copyright (C) 2004-2006 Tim Armes |
// |
// This program is free software; you can redistribute it and/or modify |
// it under the terms of the GNU General Public License as published by |
// the Free Software Foundation; either version 2 of the License, or |
// (at your option) any later version. |
// |
// This program is distributed in the hope that it will be useful, |
// but WITHOUT ANY WARRANTY; without even the implied warranty of |
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
// GNU General Public License for more details. |
// |
// You should have received a copy of the GNU General Public License |
// along with this program; if not, write to the Free Software |
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
// |
// -- |
// |
// search.php |
// |
// Show the search listing for the given term in repository/path/revision |
require_once 'include/setup.php'; |
require_once 'include/svnlook.php'; |
require_once 'include/utils.php'; |
require_once 'include/template.php'; |
require_once 'include/bugtraq.php'; |
function removeURLSeparator($url) |
{ |
return preg_replace('#(\?|&(amp;)?)$#', '', $url); |
} |
function urlForPath($fullpath, $passRevString) |
{ |
global $config, $rep; |
$isDir = $fullpath[strlen($fullpath) - 1] == '/'; |
if ($isDir) |
{ |
if ($config->treeView) |
{ |
$url = $config->getURL($rep, $fullpath, 'dir').$passRevString; |
$id = anchorForPath($fullpath); |
$url .= '#'.$id.'" id="'.$id; |
} |
else |
{ |
$url = $config->getURL($rep, $fullpath, 'dir').$passRevString; |
} |
} |
else |
{ |
$url = $config->getURL($rep, $fullpath, 'file').$passRevString; |
} |
return removeURLSeparator($url); |
} |
function showSearchResults($svnrep, $path, $searchstring, $rev, $peg, $listing, $index=0, $treeview = true) |
{ |
global $config, $lang, $rep, $passrev, $peg, $passRevString; |
// List each file in the current directory |
$loop = 0; |
$last_index = 0; |
$accessToThisDir = $rep->hasReadAccess($path, false); |
$openDir = false; |
$logList = $svnrep->getListSearch($path, $searchstring, $rev, $peg); |
if (!$logList) |
{ |
return $listing; |
} |
$downloadRevAndPeg = createRevAndPegString($rev, $peg ? $peg : $rev); |
foreach ($logList->entries as $entry) |
{ |
$isDir = $entry->isdir; |
$file = $entry->file; |
$isDirString = ($isDir) ? 'isdir=1&' : ''; |
// Only list files/directories that are not designated as off-limits |
$access = ($isDir) ? $rep->hasReadAccess($path.$file, false) |
: $accessToThisDir; |
if (!$access) |
{ |
continue; |
} |
$listvar = &$listing[$index]; |
$listvar['rowparity'] = $index % 2; |
if ($isDir) |
{ |
$listvar['filetype'] = ($openDir) ? 'diropen' : 'dir'; |
$openDir = true; |
} |
else |
{ |
$listvar['filetype'] = strtolower(strrchr($file, '.')); |
$openDir = false; |
} |
$listvar['isDir'] = $isDir; |
$listvar['openDir'] = $openDir; |
$listvar['path'] = str_replace('%2F', '/', rawurlencode($path.$file)); |
$tempelements = explode('/',$file); |
if ($tempelements[count($tempelements)-1] === "") |
{ |
$lastindexfile = count($tempelements)-1 - 1; |
$listvar['node'] = $lastindexfile; // t-node |
$listvar['level'] = ($treeview) ? $lastindexfile : 0; |
$listvar['filename'] = escape($tempelements[$lastindexfile]); |
} |
else |
{ |
$lastindexfile = count($tempelements)-1; |
$listvar['node'] = $lastindexfile; // t-node |
$listvar['level'] = ($treeview) ? $lastindexfile : 0; |
$listvar['filename'] = escape($tempelements[$lastindexfile]); |
} |
for ($j=1;$j<=$lastindexfile;$j++) |
{ |
$listvar['last_i_node'][$j] = false; |
} |
if ($isDir) |
{ |
$listvar['fileurl'] = urlForPath($path.$file, $passRevString); |
} |
else |
{ |
$listvar['fileurl'] = urlForPath($path.$file, createDifferentRevAndPegString($passrev, $peg)); |
} |
$listvar['filelink'] = '<a href="'.$listvar['fileurl'].'">'.$listvar['filename'].'</a>'; |
if ($isDir) |
{ |
$listvar['logurl'] = $config->getURL($rep, $path.$file, 'log').$isDirString.$passRevString; |
} |
else |
{ |
$listvar['logurl'] = $config->getURL($rep, $path.$file, 'log').$isDirString.createDifferentRevAndPegString($passrev, $peg); |
} |
if ($treeview) |
{ |
$listvar['compare_box'] = '<input type="checkbox" name="compare[]" value="'.escape($path.$file).'@'.$passrev.'" onclick="enforceOnlyTwoChecked(this)" />'; |
} |
if ($config->showLastModInListing()) |
{ |
$listvar['committime'] = $entry->committime; |
$listvar['revision'] = $entry->rev; |
$listvar['author'] = $entry->author; |
$listvar['age'] = $entry->age; |
$listvar['date'] = $entry->date; |
$listvar['revurl'] = $config->getURL($rep, $path.$file, 'revision').$isDirString.createRevAndPegString($entry->rev, $peg ? $peg : $rev); |
} |
if ($rep->isDownloadAllowed($path.$file)) |
{ |
$downloadurl = $config->getURL($rep, $path.$file, 'dl').$isDirString.$downloadRevAndPeg; |
if ($isDir) |
{ |
$listvar['downloadurl'] = $downloadurl; |
$listvar['downloadplainurl'] = ''; |
} |
else |
{ |
$listvar['downloadplainurl'] = $downloadurl; |
$listvar['downloadurl'] = ''; |
} |
} |
else |
{ |
$listvar['downloadplainurl'] = ''; |
$listvar['downloadurl'] = ''; |
} |
if ($rep->isRssEnabled()) |
{ |
// RSS should always point to the latest revision, so don't include rev |
$listvar['rssurl'] = $config->getURL($rep, $path.$file, 'rss').$isDirString.createRevAndPegString('', $peg); |
} |
$loop++; |
$index++; |
$last_index = $index; |
} |
return $listing; |
} |
// Make sure that we have a repository |
if (!$rep) |
{ |
renderTemplate404('directory','NOREP'); |
} |
$svnrep = new SVNRepository($rep); |
if (!empty($rev)) |
{ |
$info = $svnrep->getInfo($path, $rev, $peg); |
if ($info) |
{ |
$path = $info->path; |
$peg = (int)$info->rev; |
} |
} |
$history = $svnrep->getLog($path, 'HEAD', 1, false, 2, ($path == '/') ? '' : $peg); |
if (!$history) |
{ |
unset($vars['error']); |
$history = $svnrep->getLog($path, '', '', false, 2, ($path == '/') ? '' : $peg); |
if (!$history) |
{ |
renderTemplate404('directory','NOPATH'); |
} |
} |
$youngest = ($history && isset($history->entries[0])) ? $history->entries[0]->rev : 0; |
// Unless otherwise specified, we get the log details of the latest change |
$lastChangedRev = ($passrev) ? $passrev : $youngest; |
if ($lastChangedRev != $youngest) |
{ |
$history = $svnrep->getLog($path, $lastChangedRev, 1, false, 2, $peg); |
} |
$logEntry = ($history && isset($history->entries[0])) ? $history->entries[0] : 0; |
$headlog = $svnrep->getLog('/', '', '', true, 1); |
$headrev = ($headlog && isset($headlog->entries[0])) ? $headlog->entries[0]->rev : 0; |
// If we're not looking at a specific revision, get the HEAD revision number |
// (the revision of the rest of the tree display) |
if (empty($rev)) |
{ |
$rev = $headrev; |
} |
if ($path == '' || $path[0] != '/') |
{ |
$ppath = '/'.$path; |
} |
else |
{ |
$ppath = $path; |
} |
createPathLinks($rep, $ppath, $passrev, $peg); |
$passRevString = createRevAndPegString($passrev, $peg); |
$isDirString = 'isdir=1&'; |
$revurl = $config->getURL($rep, $path != '/' ? $path : '', 'dir'); |
$revurlSuffix = $path != '/' ? '#'.anchorForPath($path) : ''; |
if ($rev < $youngest) |
{ |
if ($path == '/') |
{ |
$vars['goyoungesturl'] = $config->getURL($rep, '', 'dir'); |
} |
else |
{ |
$vars['goyoungesturl'] = $config->getURL($rep, $path, 'dir').createRevAndPegString($youngest, $peg ? $peg: $rev).$revurlSuffix; |
} |
$vars['goyoungestlink'] = '<a href="'.$vars['goyoungesturl'].'"'.($youngest ? ' title="'.$lang['REV'].' '.$youngest.'"' : '').'>'.$lang['GOYOUNGEST'].'</a>'; |
$history2 = $svnrep->getLog($path, $rev, $youngest, true, 2, $peg); |
if (isset($history2->entries[1])) |
{ |
$nextRev = $history2->entries[1]->rev; |
if ($nextRev != $youngest) |
{ |
$vars['nextrev'] = $nextRev; |
$vars['nextrevurl'] = $revurl.createRevAndPegString($nextRev, $peg).$revurlSuffix; |
} |
} |
unset($vars['error']); |
} |
if (isset($history->entries[1])) |
{ |
$prevRev = $history->entries[1]->rev; |
$prevPath = $history->entries[1]->path; |
$vars['prevrev'] = $prevRev; |
$vars['prevrevurl'] = $revurl.createRevAndPegString($prevRev, $peg).$revurlSuffix; |
} |
$bugtraq = new Bugtraq($rep, $svnrep, $ppath); |
$vars['action'] = ''; |
$vars['rev'] = $rev; |
$vars['peg'] = $peg; |
$vars['path'] = str_replace('%2F', '/', rawurlencode($ppath)); |
$vars['safepath'] = escape($ppath); |
$vars['lastchangedrev'] = $lastChangedRev; |
if ($logEntry) |
{ |
$vars['date'] = $logEntry->date; |
$vars['age'] = datetimeFormatDuration(time() - strtotime($logEntry->date)); |
$vars['author'] = $logEntry->author; |
$vars['log'] = nl2br($bugtraq->replaceIDs(create_anchors(xml_entities($logEntry->msg)))); |
} |
$vars['revurl'] = $config->getURL($rep, ($path == '/' ? '' : $path), 'revision').$isDirString.$passRevString; |
$vars['revlink'] = '<a href="'.$vars['revurl'].'">'.$lang['LASTMOD'].'</a>'; |
if ($history && count($history->entries) > 1) |
{ |
$vars['compareurl'] = $config->getURL($rep, '', 'comp').'compare[]='.rawurlencode($history->entries[1]->path).'@'.$history->entries[1]->rev. '&compare[]='.rawurlencode($history->entries[0]->path).'@'.$history->entries[0]->rev; |
$vars['comparelink'] = '<a href="'.$vars['compareurl'].'">'.$lang['DIFFPREV'].'</a>'; |
} |
$vars['logurl'] = $config->getURL($rep, $path, 'log').$isDirString.$passRevString; |
$vars['loglink'] = '<a href="'.$vars['logurl'].'">'.$lang['VIEWLOG'].'</a>'; |
if ($rep->isRssEnabled()) |
{ |
$vars['rssurl'] = $config->getURL($rep, $path, 'rss').$isDirString.createRevAndPegString('', $peg); |
$vars['rsslink'] = '<a href="'.$vars['rssurl'].'">'.$lang['RSSFEED'].'</a>'; |
} |
// Set up the tarball link |
$subs = explode('/', $path); |
$level = count($subs) - 2; |
if ($rep->isDownloadAllowed($path) && !isset($vars['warning'])) |
{ |
$vars['downloadurl'] = $config->getURL($rep, $path, 'dl').$isDirString.$passRevString; |
} |
$vars['compare_form'] = '<form method="get" action="'.$config->getURL($rep, '', 'comp').'" id="compare">'; |
if ($config->multiViews) |
{ |
$vars['compare_form'] .= '<input type="hidden" name="op" value="comp"/>'; |
} |
else |
{ |
$vars['compare_form'] .= '<input type="hidden" name="repname" value="'.$repname.'" />'; |
} |
$vars['compare_submit'] = '<input type="submit" value="'.$lang['COMPAREPATHS'].'" />'; |
$vars['compare_endform'] = '</form>'; |
$vars['showlastmod'] = $config->showLastModInListing(); |
if (empty($_GET["search"])) |
{ |
$vars['warning'] = $lang['NOSEARCHTERM']; |
createSearchSelectionForm(); |
} |
else |
{ |
createSearchSelectionForm(); |
$vars['compare_box'] = ''; |
$listing = showSearchResults($svnrep, $path, $_GET["search"], $rev, $peg, array(),0,$config->treeView); |
} |
if (!$rep->hasReadAccess($path)) |
{ |
$vars['error'] = $lang['NOACCESS']; |
sendHeaderForbidden(); |
} |
$vars['restricted'] = !$rep->hasReadAccess($path, false); |
renderTemplate('directory'); |
/WebSVN/templates/Standard/footer.tmpl |
---|
File deleted |
/WebSVN/templates/Standard/styles.css |
---|
File deleted |
/WebSVN/templates/Standard/file.tmpl |
---|
File deleted |
\ No newline at end of file |
/WebSVN/templates/Standard/blame.tmpl |
---|
File deleted |
\ No newline at end of file |
/WebSVN/templates/Standard/log.tmpl |
---|
File deleted |
\ No newline at end of file |
/WebSVN/templates/Standard/collapse.js |
---|
File deleted |
/WebSVN/templates/Standard/directory.tmpl |
---|
File deleted |
\ No newline at end of file |
/WebSVN/templates/Standard/compare.tmpl |
---|
File deleted |
/WebSVN/templates/Standard/index.tmpl |
---|
File deleted |
/WebSVN/templates/Standard/diff.tmpl |
---|
File deleted |
/WebSVN/templates/Standard/header.tmpl |
---|
File deleted |
/WebSVN/templates/Standard/xml.gif |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Deleted: svn:mime-type |
-application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/Zinn/styles.css |
---|
File deleted |
/WebSVN/templates/Zinn/file.tmpl |
---|
File deleted |
\ No newline at end of file |
/WebSVN/templates/Zinn/blame.tmpl |
---|
File deleted |
/WebSVN/templates/Zinn/log.tmpl |
---|
File deleted |
\ No newline at end of file |
/WebSVN/templates/Zinn/collapse.js |
---|
File deleted |
/WebSVN/templates/Zinn/directory.tmpl |
---|
File deleted |
/WebSVN/templates/Zinn/compare.tmpl |
---|
File deleted |
/WebSVN/templates/Zinn/index.tmpl |
---|
File deleted |
\ No newline at end of file |
/WebSVN/templates/Zinn/diff.tmpl |
---|
File deleted |
/WebSVN/templates/Zinn/header.tmpl |
---|
File deleted |
/WebSVN/templates/Zinn/footer.tmpl |
---|
File deleted |
/WebSVN/templates/StandardNG/log.tmpl |
---|
File deleted |
\ No newline at end of file |
/WebSVN/templates/StandardNG/collapse.js |
---|
File deleted |
/WebSVN/templates/StandardNG/directory.tmpl |
---|
File deleted |
\ No newline at end of file |
/WebSVN/templates/StandardNG/compare.tmpl |
---|
File deleted |
/WebSVN/templates/StandardNG/index.tmpl |
---|
File deleted |
/WebSVN/templates/StandardNG/diff.tmpl |
---|
File deleted |
/WebSVN/templates/StandardNG/header.tmpl |
---|
File deleted |
/WebSVN/templates/StandardNG/xml.gif |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Deleted: svn:mime-type |
-application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/StandardNG/ie7/ie7-css2-selectors.js |
---|
File deleted |
/WebSVN/templates/StandardNG/ie7/ie7-css3-selectors.js |
---|
File deleted |
/WebSVN/templates/StandardNG/ie7/ie7-squish.js |
---|
File deleted |
/WebSVN/templates/StandardNG/ie7/ie7-content.htc |
---|
File deleted |
/WebSVN/templates/StandardNG/ie7/ie7-layout.js |
---|
File deleted |
/WebSVN/templates/StandardNG/ie7/ie7-quirks.js |
---|
File deleted |
/WebSVN/templates/StandardNG/ie7/ie7-load.htc |
---|
File deleted |
/WebSVN/templates/StandardNG/ie7/ie7-server.css |
---|
File deleted |
/WebSVN/templates/StandardNG/ie7/ie7-ie5.js |
---|
File deleted |
/WebSVN/templates/StandardNG/ie7/ie7-core.js |
---|
File deleted |
/WebSVN/templates/StandardNG/ie7/ie7-html4.js |
---|
File deleted |
/WebSVN/templates/StandardNG/ie7/ie7-recalc.js |
---|
File deleted |
/WebSVN/templates/StandardNG/ie7/ie7-standard-p.js |
---|
File deleted |
/WebSVN/templates/StandardNG/ie7/ie7-css-strict.js |
---|
File deleted |
/WebSVN/templates/StandardNG/ie7/blank.gif |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Deleted: svn:mime-type |
-application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/StandardNG/ie7/ie7-base64.php |
---|
File deleted |
\ No newline at end of file |
/WebSVN/templates/StandardNG/ie7/ie7-fixed.js |
---|
File deleted |
\ No newline at end of file |
/WebSVN/templates/StandardNG/ie7/ie7-graphics.js |
---|
File deleted |
/WebSVN/templates/StandardNG/ie7/ie7-overflow.js |
---|
File deleted |
/WebSVN/templates/StandardNG/ie7/ie7-xml-extras.js |
---|
File deleted |
/WebSVN/templates/StandardNG/ie7/ie7-object.htc |
---|
File deleted |
/WebSVN/templates/StandardNG/ie7/ie7-dynamic-attributes.js |
---|
File deleted |
/WebSVN/templates/StandardNG/ie7/ie7-dhtml.js |
---|
File deleted |
/WebSVN/templates/StandardNG/footer.tmpl |
---|
File deleted |
/WebSVN/templates/StandardNG/styles.css |
---|
File deleted |
/WebSVN/templates/StandardNG/file.tmpl |
---|
File deleted |
\ No newline at end of file |
/WebSVN/templates/StandardNG/blame.tmpl |
---|
File deleted |
/WebSVN/templates/BlueGrey/png.js |
---|
File deleted |
/WebSVN/templates/BlueGrey/file.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Deleted: svn:mime-type |
-application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/BlueGrey/fileh.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Deleted: svn:mime-type |
-application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/BlueGrey/folder-open.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Deleted: svn:mime-type |
-application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/BlueGrey/xml.gif |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Deleted: svn:mime-type |
-application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/BlueGrey/filejava.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Deleted: svn:mime-type |
-application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/BlueGrey/filem.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Deleted: svn:mime-type |
-application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/BlueGrey/e-node.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Deleted: svn:mime-type |
-application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/BlueGrey/folder.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Deleted: svn:mime-type |
-application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/BlueGrey/files.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Deleted: svn:mime-type |
-application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/BlueGrey/repo.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Deleted: svn:mime-type |
-application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/BlueGrey/i-node.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Deleted: svn:mime-type |
-application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/BlueGrey/l-node.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Deleted: svn:mime-type |
-application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/BlueGrey/filepy.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Deleted: svn:mime-type |
-application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/BlueGrey/t-node.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Deleted: svn:mime-type |
-application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/BlueGrey/filecpp.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Deleted: svn:mime-type |
-application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/BlueGrey/subversion.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Deleted: svn:mime-type |
-application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/BlueGrey/filec.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Deleted: svn:mime-type |
-application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/BlueGrey/collapse.js |
---|
File deleted |
/WebSVN/templates/BlueGrey/filehtml.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Deleted: svn:mime-type |
-application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/BlueGrey/blame.tmpl |
---|
1,32 → 1,62 |
<table cellspacing="0" cellpadding="0" border="0" width="100%"> |
<tr> |
<td align="left"><h1>[websvn:repname]</h1></td> |
<td align="right"><b>[lang:PROJECTS]:</b> [websvn:projects_form][websvn:projects_select][websvn:projects_submit][websvn:projects_endform]</td> |
</tr> |
</table> |
[websvn:curdirlinks] - <h2> [lang:BLAMEFOR] [websvn:rev]</h2> |
<p> |
[websvn-test:noaccess] |
[lang:NOACCESS] |
<h1>[websvn:repname] – [lang:BLAMEFOR] [websvn:rev]</h1> |
<div id="projects">[websvn:projects_form]<b>[lang:PROJECTS]:</b> [websvn:projects_select][websvn:projects_submit][websvn:projects_endform]</div> |
[websvn-test:error] |
<div id="error">[websvn:error]</div> |
[websvn-else] |
<table cellpadding="2px" cellspacing="0" width="100%"> |
<div id="revjump">[websvn:revision_form]<b>[lang:REV]:</b>[websvn:revision_input][websvn:revision_submit][websvn:revision_endform]</div> |
<div id="path_links">[websvn:path_links_root_config]/[websvn:path_links]</div> |
<div id="nav"> |
[websvn-test:prevrevurl] |
<a href="[websvn:prevrevurl]">[lang:REV] [websvn:prevrev]</a> – |
[websvn-endtest] |
[websvn-test:nextrevurl] |
<a href="[websvn:nextrevurl]">[lang:REV] [websvn:nextrev]</a> – |
[websvn-endtest] |
[websvn-test:goyoungestlink] |
[websvn:goyoungestlink] – |
[websvn-endtest] |
[websvn-test:mimelink] |
[websvn:mimelink] – |
[websvn-endtest] |
[websvn:filedetaillink] – |
[websvn-test:difflink] |
[websvn:difflink] – |
[websvn-endtest] |
[websvn-test:downloadlink] |
[websvn:downloadlink] – |
[websvn-endtest] |
[websvn:revlink] – |
[websvn:loglink] |
[websvn-test:clientrooturl] |
– <a href="[websvn:clientrooturl][websvn:path]">SVN</a> |
[websvn-endtest] |
[websvn-test:rssurl] |
– <a href="[websvn:rssurl]"><img src="[websvn:locwebsvnhttp]/templates/BlueGrey/images/rss.gif" width="27" height="15" alt="[lang:RSSFEED]"/></a> |
[websvn-endtest] |
</div> |
[websvn-test:warning] |
<div id="warning">[websvn:warning]</div> |
[websvn-else] |
<table> |
<thead> |
<tr> |
<th class="HdrClmn"><b>[lang:LINENO]</b></th> |
<th class="HdrClmn"><b>[lang:REV]</b></th> |
<th class="HdrClmn"><b>[lang:AUTHOR]</b></th> |
<th class="HdrClmnEnd"><b>[lang:LINE]</b></th> |
<th>[lang:REV]</th> |
<th>[lang:AUTHOR]</th> |
<th>[lang:LINENO]</th> |
<th>[lang:LINE]</th> |
</tr> |
</thead> |
<tbody style="font-size: 90%;"> |
[websvn-startlisting] |
<tr> |
<td class="CatClmn0" style="border-right: 1px solid black" valign="top">[websvn:lineno]</td> |
<td class="CatClmn0" style="border-right: 1px solid black" valign="top">[websvn:revision]</td> |
<td class="CatClmn0" style="border-right: 1px solid black" valign="top">[websvn:author]</td> |
<td style="border-right: 1px solid black" valign="top">[websvn:line]</td> |
</tr> |
<tr class="[websvn:row_class]"> |
<th>[websvn:revision]</th> |
<th>[websvn:author]</th> |
<th><a name="l[websvn:lineno]" href="#l[websvn:lineno]">[websvn:lineno]</a></th> |
<td>[websvn:line]</td> |
</tr> |
[websvn-endlisting] |
</table> |
</tbody> |
</table> |
[websvn:javascript] |
[websvn-endtest] |
[websvn-endtest] |
/WebSVN/templates/BlueGrey/compare.tmpl |
---|
1,65 → 1,63 |
<table cellspacing="0" cellpadding="0" border="0" width="100%"> |
<tr> |
<td align="left"><h1>[websvn:repname]</h1></td> |
<td align="right"><b>[lang:PROJECTS]:</b> [websvn:projects_form][websvn:projects_select][websvn:projects_submit][websvn:projects_endform]</td> |
</tr> |
</table> |
[websvn-test:noaccess] |
[lang:NOACCESS] |
<h1>[websvn:repname]</h1> |
<div id="projects">[websvn:projects_form]<b>[lang:PROJECTS]:</b> [websvn:projects_select][websvn:projects_submit][websvn:projects_endform]</div> |
[websvn-test:error] |
<div id="error">[websvn:error]</div> |
[websvn-else] |
[websvn:compare_form] |
<table> |
<tr><td>[lang:COMPPATH] </td><td>[websvn:compare_path1input] [lang:REV] [websvn:compare_rev1input]</td></tr> |
<tr><td>[lang:WITHPATH]</td><td>[websvn:compare_path2input] [lang:REV] [websvn:compare_rev2input]</td></tr> |
</table> |
[websvn:compare_submit] |
[websvn:compare_endform] |
[websvn-test:success] |
<hr> |
<p>[lang:CONVFROM] <b>[websvn:path1] ([lang:REV] [websvn:rev1])</b> [lang:TO] <b>[websvn:path2] ([lang:REV] [websvn:rev2])</b> |
<p> |
[websvn:revlink] |
<p> |
[websvn-endtest] |
[websvn-startlisting] |
<center> |
[websvn:compare_form] |
<table id="params"> |
<tr> |
<td>[lang:COMPPATH]</td> |
<td>[websvn:compare_path1input] [lang:REV] [websvn:compare_rev1input]</td> |
<td rowspan="2">[websvn:compare_submit]</td> |
</tr> |
<tr> |
<td>[lang:WITHPATH]</td> |
<td>[websvn:compare_path2input] [lang:REV] [websvn:compare_rev2input]</td> |
</tr> |
</table> |
[websvn:compare_endform] |
[websvn-test:warning] |
<div id="warning">[websvn:warning]</div> |
[websvn-endtest] |
[websvn-test:success] |
<div id="nav"> |
[websvn:reverselink] | |
[websvn-test:regardwhitespacelink] |
[websvn:regardwhitespacelink] |
[websvn-else] |
[websvn:ignorewhitespacelink] |
[websvn-endtest] |
</div> |
<div><a href="[websvn:rev1url]">[websvn:safepath1] @ [websvn:rev1]</a> → <a href="[websvn:rev2url]">[websvn:safepath2] @ [websvn:rev2]</a></div> |
[websvn-endtest] |
</center> |
[websvn-startlisting] |
[websvn-test:newpath] |
<p> |
<div class="newpath"> |
<b>[websvn:newpath]</b><br> |
<table class="comparison collapsible"> |
<thead> |
<tr><th><a href="[websvn:fileurl]">[websvn:newpath]</a></th></tr> |
</thead> |
[websvn-endtest] |
[websvn-test:info] |
[websvn:info]<br> |
[websvn:info]<br /> |
[websvn-endtest] |
[websvn-test:difflines] |
<div class="difflines"> |
<p> |
[websvn:difflines]<br> |
<table class="diff" cellspacing="0"> |
<tr class="row1"><th>[websvn:difflines]</th></tr> |
[websvn-endtest] |
[websvn-test:diffclass] |
<tr><td class="[websvn:diffclass]">[websvn:line]</td></tr> |
<tr><td class="[websvn:diffclass]">[websvn:line]</td></tr> |
[websvn-endtest] |
[websvn-test:enddifflines] |
</table> |
</div> |
[websvn-test:endpath] |
</table> |
[websvn-endtest] |
[websvn-test:endpath] |
</div> |
<p><hr> |
[websvn-endtest] |
[websvn-test:properties] |
<p><i>[lang:PROPCHANGES]</i><p> |
<p><i>[lang:PROPCHANGES]</i><p> |
[websvn-endtest] |
[websvn-endlisting] |
</table> |
[websvn-endtest] |
[websvn-endlisting] |
[websvn-endtest] |
<script type="text/javascript" src="[websvn:locwebsvnhttp]/javascript/jquery.min.1.9.1.js"></script> |
<script type="text/javascript" src="[websvn:locwebsvnhttp]/javascript/collapsible.js"></script> |
[websvn-endtest] |
/WebSVN/templates/BlueGrey/diff.tmpl |
---|
1,46 → 1,85 |
[websvn-test:noaccess] |
[lang:NOACCESS] |
[websvn-test:rev2] |
<h1>[websvn:repname] – [lang:DIFFREVS] [websvn:rev2] [lang:AND] [websvn:rev1]</h1> |
[websvn-else] |
<h1>[websvn:repname] – [lang:DIFF]</h1> |
[websvn-endtest] |
<div id="projects">[websvn:projects_form]<b>[lang:PROJECTS]:</b> [websvn:projects_select][websvn:projects_submit][websvn:projects_endform]</div> |
[websvn-test:error] |
<div id="error">[websvn:error]</div> |
[websvn-else] |
[websvn-test:noprev] |
[lang:NOPREVREV] |
[websvn-else] |
<table cellspacing="0" cellpadding="0" border="0" width="100%"> |
<tr> |
<td align="left"><h1>[websvn:repname]</h1></td> |
<td align="right"><b>[lang:PROJECTS]:</b> [websvn:projects_form][websvn:projects_select][websvn:projects_submit][websvn:projects_endform]</td> |
</tr> |
</table> |
[websvn:curdirlinks] - [lang:DIFFREVS] <b>[websvn:rev2]</b> [lang:AND] <b>[websvn:rev1]</b> |
<p> |
<p><center> |
[websvn:showcompactlink] |
[websvn:showalllink] |
</center> |
<p> |
<table class="diff" width="100%" cellspacing="0"> |
<tr> |
<th class="HdrClmnEnd" style="padding-bottom: 5px" width="50%" align="left"><b>[lang:REV] [websvn:rev2]</b></th> |
<th width="5"></th> |
<th class="HdrClmnEnd" style="padding-bottom: 5px" width="50%" align="left"><b>[lang:REV] [websvn:rev1]</b></th> |
</tr> |
[websvn-startlisting] |
[websvn-test:rev1lineno] |
<tr> |
<td width="50%" style="padding: 3px 0 3px 0" align="center" class="row1"><b>[lang:LINE] [websvn:rev1lineno]...</b></td> |
<td width="5"></td> |
<td width="50%" style="padding: 3px 0 3px 0" align="center" class="row1"><b>[lang:LINE] [websvn:rev2lineno]...</b></td> |
<tr> |
[websvn-else] |
<tr><td class="[websvn:rev1diffclass]">[websvn:rev1line]</td> |
<td width="5"></td> |
<td class="[websvn:rev2diffclass]">[websvn:rev2line]</td></tr> |
[websvn-endtest] |
[websvn-endlisting] |
</table> |
[websvn-endtest] |
<div id="revjump">[websvn:revision_form]<b>[lang:REV]:</b>[websvn:revision_input][websvn:revision_submit][websvn:revision_endform]</div> |
<div id="path_links">[websvn:path_links_root_config]/[websvn:path_links]</div> |
<div id="nav"> |
[websvn-test:prevrevurl] |
<a href="[websvn:prevrevurl]">[lang:REV] [websvn:prevrev]</a> – |
[websvn-endtest] |
[websvn-test:nextrevurl] |
<a href="[websvn:nextrevurl]">[lang:REV] [websvn:nextrev]</a> – |
[websvn-endtest] |
[websvn-test:goyoungestlink] |
[websvn:goyoungestlink] – |
[websvn-endtest] |
[websvn:filedetaillink] – |
[websvn:blamelink] – |
[websvn-test:downloadlink] |
[websvn:downloadlink] – |
[websvn-endtest] |
[websvn:revlink] – |
[websvn:loglink] |
[websvn-test:clientrooturl] |
– <a href="[websvn:clientrooturl][websvn:path]">SVN</a> |
[websvn-endtest] |
[websvn-test:rssurl] |
– <a href="[websvn:rssurl]"><img src="[websvn:locwebsvnhttp]/templates/BlueGrey/images/rss.gif" width="27" height="15" alt="[lang:RSSFEED]"/></a> |
[websvn-endtest] |
</div> |
[websvn-test:warning] |
<div id="warning">[websvn:warning]</div> |
[websvn-else] |
[websvn-test:noprev] |
<div id="warning">[lang:NOPREVREV].</div> |
[websvn-else] |
<center> |
[websvn-test:showcompactlink] |
[websvn:showcompactlink] – |
[websvn-endtest] |
[websvn-test:showalllink] |
[websvn:showalllink] – |
[websvn-endtest] |
[websvn-test:regardwhitespacelink] |
[websvn:regardwhitespacelink] |
[websvn-endtest] |
[websvn-test:ignorewhitespacelink] |
[websvn:ignorewhitespacelink] |
[websvn-endtest] |
</center> |
<table class="diff" cellspacing="0"> |
<thead> |
<tr> |
<th width="50%" colspan="2"><a href="[websvn:prevrevurl]">[lang:REV] [websvn:rev2]</a></th> |
<td width="5"></td> |
<th width="50%" colspan="2"><a href="[websvn:revurl]">[lang:REV] [websvn:rev1]</a></th> |
</tr> |
</thead> |
[websvn-startlisting] |
[websvn-test:startblock] |
<tr> |
<th class="row1" colspan="2">[lang:LINE] [websvn:rev1lineno]...</th> |
<td width="5" style="background: none;"></td> |
<th class="row1" colspan="2">[lang:LINE] [websvn:rev2lineno]...</th> |
</tr> |
[websvn-endtest] |
<tr> |
<td class="lineno">[websvn:rev1lineno]</td> |
<td class="[websvn:rev1diffclass]">[websvn:rev1line]</td> |
<td width="5"></td> |
<td class="lineno">[websvn:rev2lineno]</td> |
<td class="[websvn:rev2diffclass]">[websvn:rev2line]</td> |
</tr> |
[websvn-endlisting] |
</table> |
[websvn-endtest] |
[websvn-endtest] |
[websvn-endtest] |
[websvn-endtest] |
/WebSVN/templates/BlueGrey/directory.tmpl |
---|
1,142 → 1,142 |
<table cellspacing="0" cellpadding="0" border="0" width="100%"> |
<tr> |
<td align="left"><h1>[websvn:repname]</h1></td> |
<td align="right"><b>[lang:PROJECTS]:</b> [websvn:projects_form][websvn:projects_select][websvn:projects_submit][websvn:projects_endform]</td> |
</tr> |
</table> |
[websvn-test:noaccess] |
[lang:NOACCESS] |
<h1>[websvn:repname] – [lang:REV] [websvn:rev]</h1> |
<div id="projects">[websvn:projects_form]<b>[lang:PROJECTS]:</b> [websvn:projects_select][websvn:projects_submit][websvn:projects_endform]</div> |
[websvn-test:error] |
<div id="error">[websvn:error]</div> |
[websvn-else] |
<table cellpadding="2px" cellspacing="0px" class="outline"> |
<tr><th colspan=2 class="HdrClmnEnd">[lang:REVINFO]</th></tr> |
<tr><td class="CatClmn1" valign="top">[lang:CURDIR]:</td><td class="row1">[websvn:path]</td></tr> |
<tr><td class="CatClmn0">[lang:REV] & [lang:AUTHOR]:</td><td class="row0">[lang:REV] [websvn:rev] - [websvn:author] |
[websvn-test:goyoungestlink] |
- [websvn:goyoungestlink] |
[websvn-endtest] |
</td></tr> |
[websvn-test:restricted] |
[websvn-else] |
<tr><td class="CatClmn1" valign="top">[lang:LASTMOD]:</td><td class="row1">[lang:REV] [websvn:lastchangedrev] - [websvn:date]</td></tr> |
<tr><td class="CatClmn0" valign="top">[lang:LOGMSG]:</td><td class="row0">[websvn:log]</td></tr> |
[websvn-test:hidechanges] |
<tr><td class="CatClmn1" valign="top"> </td><td class="row1">([websvn:showchangeslink])</td></tr> |
<div id="revjump">[websvn:revision_form]<b>[lang:REV]:</b>[websvn:revision_input][websvn:revision_submit][websvn:revision_endform]</div> |
[websvn-test:search] |
<div id="searchcss">[websvn:search_form]<div>[lang:SEARCH] [websvn:search_input]<span class="submit">[websvn:search_submit]</span></div>[websvn:search_endform]</div> |
[websvn-endtest] |
<div id="path_links">[websvn:path_links_root_config]/[websvn:path_links]</div> |
[websvn-test:warning] |
[websvn-else] |
<table cellpadding="2" cellspacing="0" class="outline"> |
<thead> |
<tr><th colspan="2">[lang:REVINFO]</th></tr> |
</thead> |
[websvn-test:restricted] |
[websvn-else] |
[websvn:showchangeslink] |
<tr><td class="CatClmn1" valign="top"> </td><td class="row1">([websvn:hidechangeslink])</td></tr> |
[websvn-test:changedfilesbr] |
<tr><td class="CatClmn0" valign="top">[lang:CHANGEDFILES]:</td><td class="row0">[websvn:changedfilesbr]</td></tr> |
[websvn-endtest] |
[websvn-test:newfilesbr] |
[websvn-test:changedfilesbr] |
<tr><td class="CatClmn1" valign="top">[lang:NEWFILES]:</td><td class="row1">[websvn:newfilesbr]</td></tr> |
[websvn-else] |
<tr><td class="CatClmn0" valign="top">[lang:NEWFILES]:</td><td class="row0">[websvn:newfilesbr]</td></tr> |
[websvn-endtest] |
[websvn-endtest] |
[websvn-test:deletedfilesbr] |
[websvn-test:changedfilesbr] |
[websvn-test:newfilesbr] |
<tr><td class="CatClmn0" valign="top">[lang:DELETEDFILES]:</td><td class="row0">[websvn:deletedfilesbr]</td></tr> |
[websvn-else] |
<tr><td class="CatClmn1" valign="top">[lang:DELETEDFILES]:</td><td class="row1">[websvn:deletedfilesbr]</td></tr> |
[websvn-endtest] |
[websvn-else] |
[websvn-test:newfilesbr] |
<tr><td class="CatClmn1" valign="top">[lang:DELETEDFILES]:</td><td class="row1">[websvn:deletedfilesbr]</td></tr> |
[websvn-else] |
<tr><td class="CatClmn0" valign="top">[lang:DELETEDFILES]:</td><td class="row0">[websvn:deletedfilesbr]</td></tr> |
[websvn-endtest] |
[websvn-endtest] |
[websvn-endtest] |
<tr class="row0"><th>[lang:LASTMOD]:</th><td>[lang:REV] [websvn:lastchangedrev] – [websvn:author] – [websvn:date] |
[websvn-test:prevrevurl] |
– <a href="[websvn:prevrevurl]">[lang:REV] [websvn:prevrev]</a> |
[websvn-endtest] |
[websvn-endtest] |
</table> |
[websvn-defineicons] |
dir=<img align="middle" valign="center" src="[websvn:locwebsvnhttp]/templates/BlueGrey/folder.png" alt="[FOLDER]"> |
diropen=<img align="middle" valign="center" src="[websvn:locwebsvnhttp]/templates/BlueGrey/folder.png" alt="[OPEN-FOLDER]"> |
*=<img align="middle" src="[websvn:locwebsvnhttp]/templates/BlueGrey/file.png" alt="[FILE]"> |
.c=<img align="middle" src="[websvn:locwebsvnhttp]/templates/BlueGrey/filec.png" alt="[C-FILE]"> |
.cpp=<img align="middle" src="[websvn:locwebsvnhttp]/templates/BlueGrey/filecpp.png" alt="[CPP-FILE]"> |
.h=<img align="middle" src="[websvn:locwebsvnhttp]/templates/BlueGrey/fileh.png" alt="[H-FILE]"> |
.html=<img align="middle" src="[websvn:locwebsvnhttp]/templates/BlueGrey/filehtml.png" alt="[HTML-FILE]"> |
.java=<img align="middle" src="[websvn:locwebsvnhttp]/templates/BlueGrey/filejava.png" alt="[JAVA-FILE]"> |
.m=<img align="middle" src="[websvn:locwebsvnhttp]/templates/BlueGrey/filem.png" alt="[M-FILE]"> |
.py=<img align="middle" src="[websvn:locwebsvnhttp]/templates/BlueGrey/filepy.png" alt="[PY-FILE]"> |
.s=<img align="middle" src="[websvn:locwebsvnhttp]/templates/BlueGrey/files.png" alt="[S-FILE]"> |
i-node=<img align="middle" border="0" width="24" height="22" src="[websvn:locwebsvnhttp]/templates/BlueGrey/i-node.png" alt="[NODE]"> |
t-node=<img align="middle" border="0" width="24" height="22" src="[websvn:locwebsvnhttp]/templates/BlueGrey/t-node.png" alt="[NODE]"> |
l-node=<img align="middle" border="0" width="24" height="22" src="[websvn:locwebsvnhttp]/templates/BlueGrey/l-node.png" alt="[NODE]"> |
e-node=<img align="middle" border="0" width="24" height="22" src="[websvn:locwebsvnhttp]/templates/BlueGrey/e-node.png" alt="[NODE]"> |
[websvn-enddefineicons] |
<p><hr> |
[websvn:curdirlinks] - [websvn:curdirloglink] |
[websvn-test:curdircomplink] |
- [websvn:curdircomplink] |
[websvn-endtest] |
[websvn-test:curdirdllink] |
- [websvn:curdirdllink] |
[websvn-endtest] |
[websvn-test:curdirrsslink] |
- [websvn:curdirrssanchor]<img style="border: 0;" src="[websvn:locwebsvnhttp]/templates/BlueGrey/xml.gif" width="36" height="14" alt="[lang:RSSFEED]"></a> |
[websvn-endtest] |
<p> |
[websvn:compare_form] |
<table cellpadding="2px" cellspacing="0px" width="100%" class="outline"> |
<tr> |
<th class="HdrClmn" width="100%"><b>[lang:PATH]</b></th> |
[websvn-test:allowdownload] |
[websvn-test:curdirrsslink] |
<th class="HdrClmn"><b>[lang:NOBR][lang:LOG][lang:ENDNOBR]</b></th> |
<th class="HdrClmn"><b>[lang:TARBALL]</b></th> |
<th class="HdrClmnEnd"><b>RSS</b></th> |
[websvn-else] |
<th class="HdrClmn"><b>[lang:NOBR][lang:LOG][lang:ENDNOBR]</b></th> |
<th class="HdrClmnEnd"><b>[lang:TARBALL]</b></th> |
[websvn-endtest] |
[websvn-else] |
[websvn-test:curdirrsslink] |
<th class="HdrClmn"><b>[lang:LOG]</b></th> |
<th class="HdrClmnEnd"><b>RSS</b></th> |
[websvn-else] |
<th class="HdrClmnEnd"><b>[lang:NOBR][lang:LOG][lang:ENDNOBR]</b></th> |
[websvn-endtest] |
[websvn-endtest] |
</tr> |
[websvn-startlisting] |
<tr> |
<td valign="middle" style="border-right: 1px solid black; padding: 0 2px 0 2px;" class="row[websvn:rowparity]"> |
[websvn:compare_box] |
[websvn-treenode] |
[websvn-icon] |
[websvn:filelink] |
</td> |
[websvn-test:allowdownload] |
[websvn-test:curdirrsslink] |
<td style="border-right: 1px solid black; padding: 0 2px 0 2px;" class="row[websvn:rowparity]">[lang:NOBR][websvn:fileviewloglink][lang:ENDNOBR]</td> |
<td style="border-right: 1px solid black; padding: 0 2px 0 2px;" class="row[websvn:rowparity]">[websvn:fileviewdllink]</td> |
<td style="padding: 0 2px 0 2px;" class="row[websvn:rowparity]">[websvn:rssanchor]<img style="border: 0;" src="[websvn:locwebsvnhttp]/templates/BlueGrey/xml.gif" width="36" height="14" alt="[lang:RSSFEED]"></a></td> |
[websvn-else] |
<td style="border-right: 1px solid black; padding: 0 2px 0 2px;" class="row[websvn:rowparity]">[lang:NOBR][websvn:fileviewloglink][lang:ENDNOBR]</td> |
<td style="padding: 0 2px 0 2px;" class="row[websvn:rowparity]">[websvn:fileviewdllink]</td> |
[websvn-endtest] |
[websvn-else] |
[websvn-test:curdirrsslink] |
<td style="border-right: 1px solid black; padding: 0 2px 0 2px;" class="row[websvn:rowparity]">[lang:NOBR][websvn:fileviewloglink][lang:ENDNOBR]</td> |
<td style="padding: 0 2px 0 2px;" class="row[websvn:rowparity]">[websvn:rssanchor]<img style="border: 0;" src="[websvn:locwebsvnhttp]/templates/BlueGrey/xml.gif" width="36" height="14" alt="[lang:RSSFEED]"></a></td> |
[websvn-else] |
<td style="padding: 0 2px 0 2px;" class="row[websvn:rowparity]">[lang:NOBR][websvn:fileviewloglink][lang:ENDNOBR]</td> |
[websvn-endtest] |
[websvn-endtest] |
</tr> |
[websvn-endlisting] |
[websvn-test:nextrevurl] |
– <a href="[websvn:nextrevurl]">[lang:REV] [websvn:nextrev]</a> |
[websvn-endtest] |
[websvn-test:goyoungestlink] |
– [websvn:goyoungestlink] |
[websvn-endtest] |
</td></tr> |
<tr class="row1"><th>[lang:LOGMSG]:</th><td>[websvn:log]</td></tr> |
[websvn-endtest] |
</table> |
[websvn-endtest] |
<div id="nav"> |
[websvn:revlink] – |
[websvn-test:comparelink] |
[websvn:comparelink] – |
[websvn-endtest] |
[websvn:loglink] |
[websvn-test:downloadurl] |
– <a href="[websvn:downloadurl]" rel="nofollow">[lang:DOWNLOAD]</a> |
[websvn-endtest] |
[websvn-test:clientrooturl] |
– <a href="[websvn:clientrooturl][websvn:path]">SVN</a> |
[websvn-endtest] |
[websvn-test:rssurl] |
– <a href="[websvn:rssurl]"><img src="[websvn:locwebsvnhttp]/templates/BlueGrey/images/rss.gif" width="27" height="15" alt="[lang:RSSFEED]"/></a> |
[websvn-endtest] |
</div> |
[websvn-test:warning] |
<div id="warning">[websvn:warning]</div> |
[websvn-else] |
[websvn-defineicons] |
dir=<img class="icon" src="[websvn:locwebsvnhttp]/templates/BlueGrey/images/directory.png" alt="[DIRECTORY]"/> |
diropen=<img class="icon" src="[websvn:locwebsvnhttp]/templates/BlueGrey/images/directory.png" alt="[OPEN-DIRECTORY]"/> |
*=<img class="icon" src="[websvn:locwebsvnhttp]/templates/BlueGrey/images/file.png" alt="[FILE]"/> |
.c=<img class="icon" src="[websvn:locwebsvnhttp]/templates/BlueGrey/images/filec.png" alt="[C-FILE]"/> |
.cpp=<img class="icon" src="[websvn:locwebsvnhttp]/templates/BlueGrey/images/filecpp.png" alt="[CPP-FILE]"/> |
.h=<img class="icon" src="[websvn:locwebsvnhttp]/templates/BlueGrey/images/fileh.png" alt="[H-FILE]"/> |
.html=<img class="icon" src="[websvn:locwebsvnhttp]/templates/BlueGrey/images/filehtml.png" alt="[HTML-FILE]"/> |
.java=<img class="icon" src="[websvn:locwebsvnhttp]/templates/BlueGrey/images/filejava.png" alt="[JAVA-FILE]"/> |
.m=<img class="icon" src="[websvn:locwebsvnhttp]/templates/BlueGrey/images/filem.png" alt="[M-FILE]"/> |
.py=<img class="icon" src="[websvn:locwebsvnhttp]/templates/BlueGrey/images/filepy.png" alt="[PY-FILE]"/> |
i-node=<img class="icon" border="0" width="24" height="22" src="[websvn:locwebsvnhttp]/templates/BlueGrey/images/i-node.png" alt="[NODE]"/> |
t-node=<img class="icon" border="0" width="24" height="22" src="[websvn:locwebsvnhttp]/templates/BlueGrey/images/t-node.png" alt="[NODE]"/> |
l-node=<img class="icon" border="0" width="24" height="22" src="[websvn:locwebsvnhttp]/templates/BlueGrey/images/l-node.png" alt="[NODE]"/> |
e-node=<img class="icon" border="0" width="24" height="22" src="[websvn:locwebsvnhttp]/templates/BlueGrey/images/e-node.png" alt="[NODE]"/> |
[websvn-enddefineicons] |
[websvn:compare_form] |
<table cellpadding="2" cellspacing="0" id="listing"> |
<thead> |
<tr> |
<th class="path">[lang:PATH]</th> |
[websvn-test:showlastmod] |
<th class="last_mod" scope="col" colspan="3">[lang:LASTMOD]</th> |
[websvn-endtest] |
<th class="view_log" nowrap="nowrap">[lang:VIEWLOG]</th> |
[websvn-test:allowdownload] |
<th class="download">[lang:DOWNLOAD]</th> |
[websvn-endtest] |
[websvn-test:clientrooturl] |
<th>SVN</th> |
[websvn-endtest] |
[websvn-test:rssurl] |
<th>RSS</th> |
[websvn-endtest] |
</tr> |
</thead> |
<tbody> |
[websvn-startlisting] |
<tr class="row[websvn:rowparity]" |
[websvn-test:loadalldir] |
title="[websvn:classname]" |
[websvn-endtest] |
> |
<td class="path" valign="middle"> |
[websvn:compare_box] |
[websvn-treenode] |
<a href="[websvn:fileurl]"> |
[websvn-icon] |
[websvn:filename] |
</a> |
</td> |
[websvn-test:showlastmod] |
<td class="rev"><a href="[websvn:revurl]">[websvn:revision]</a> </td> |
[websvn-test:showageinsteadofdate] |
<td class="age" title="[websvn:date]">[websvn:age]</td> |
[websvn-else] |
<td class="date" title="[websvn:age]">[websvn:date]</td> |
[websvn-endtest] |
<td class="author">[websvn:author]</td> |
[websvn-endtest] |
<td><a href="[websvn:logurl]">[lang:LOG]</a></td> |
[websvn-test:allowdownload] |
<td> |
[websvn-test:downloadurl] |
<a href="[websvn:downloadurl]" rel="nofollow">[lang:DOWNLOAD]</a> |
[websvn-endtest] |
[websvn-test:downloadplainurl] |
<a href="[websvn:downloadplainurl]" rel="nofollow">[lang:DOWNLOAD]</a> |
[websvn-endtest] |
</td> |
[websvn-endtest] |
[websvn-test:clientrooturl] |
<td><a href="[websvn:clientrooturl][websvn:path]">SVN</a></td> |
[websvn-endtest] |
[websvn-test:rssurl] |
<td><a href="[websvn:rssurl]"><img src="[websvn:locwebsvnhttp]/templates/BlueGrey/images/rss.gif" width="27" height="15" alt="[lang:RSSFEED]"/></a></td> |
[websvn-endtest] |
</tr> |
[websvn-endlisting] |
</tbody> |
</table> |
<p> |
[websvn:compare_submit] |
[websvn:compare_endform] |
<hr> |
[websvn:compare_submit][websvn:compare_endform] |
[websvn-endtest] |
[websvn-test:loadalldir] |
<script type="text/javascript" src="[websvn:locwebsvnhttp]/javascript/jquery.min.1.9.1.js"></script> |
<script type="text/javascript" src="[websvn:locwebsvnhttp]/javascript/collapsible.js"></script> |
[websvn-endtest] |
[websvn-endtest] |
/WebSVN/templates/BlueGrey/file.tmpl |
---|
1,19 → 1,48 |
<table cellspacing="0" cellpadding="0" border="0" width="100%"> |
<tr> |
<td align="left"><h1>[websvn:repname]</h1></td> |
<td align="right"><b>[lang:PROJECTS]:</b> [websvn:projects_form][websvn:projects_select][websvn:projects_submit][websvn:projects_endform]</td> |
</tr> |
</table> |
[websvn-test:noaccess] |
[lang:NOACCESS] |
<h1>[websvn:repname] – [lang:REV] [websvn:rev]</h1> |
<div id="projects">[websvn:projects_form]<b>[lang:PROJECTS]:</b> [websvn:projects_select][websvn:projects_submit][websvn:projects_endform]</div> |
[websvn-test:error] |
<div id="error">[websvn:error]</div> |
[websvn-else] |
[websvn:curdirlinks] - [lang:REV] [websvn:rev] |
[websvn-test:goyoungestlink] |
[websvn:goyoungestlink]<p> |
[websvn-endtest] |
<p>[websvn:prevdifflink] - [websvn:blamelink]</p> |
<hr /> |
[websvn-getlisting] |
<hr /> |
<div id="revjump">[websvn:revision_form]<b>[lang:REV]:</b>[websvn:revision_input][websvn:revision_submit][websvn:revision_endform]</div> |
<div id="path_links">[websvn:path_links_root_config]/[websvn:path_links]</div> |
<div id="nav"> |
[websvn-test:prevrevurl] |
<a href="[websvn:prevrevurl]">[lang:REV] [websvn:prevrev]</a> – |
[websvn-endtest] |
[websvn-test:nextrevurl] |
<a href="[websvn:nextrevurl]">[lang:REV] [websvn:nextrev]</a> – |
[websvn-endtest] |
[websvn-test:goyoungestlink] |
[websvn:goyoungestlink] – |
[websvn-endtest] |
[websvn-test:mimelink] |
[websvn:mimelink] – |
[websvn-endtest] |
[websvn:blamelink] – |
[websvn-test:difflink] |
[websvn:difflink] – |
[websvn-endtest] |
[websvn:revlink] – |
[websvn:loglink] |
[websvn-test:downloadlink] |
– [websvn:downloadlink] |
[websvn-endtest] |
[websvn-test:clientrooturl] |
– <a href="[websvn:clientrooturl][websvn:path]">SVN</a> |
[websvn-endtest] |
[websvn-test:rssurl] |
– <a href="[websvn:rssurl]"><img src="[websvn:locwebsvnhttp]/templates/BlueGrey/images/rss.gif" width="27" height="15" alt="[lang:RSSFEED]"/></a> |
[websvn-endtest] |
</div> |
[websvn-test:warning] |
<div id="warning">[websvn:warning]</div> |
[websvn-else] |
<div id="listing"> |
[websvn-getlisting] |
</div> |
[websvn-test:warning] |
<!-- check for warnings generated by getlisting --> |
<div id="warning">[websvn:warning]</div> |
[websvn-endtest] |
[websvn-endtest] |
[websvn-endtest] |
/WebSVN/templates/BlueGrey/footer.tmpl |
---|
1,3 → 1,4 |
<p><center><font size="-1"><i><b>[lang:POWERED] v[websvn:version]</b></i></font></center> |
</body> |
</div> |
<div id="footer">[lang:POWERED] [websvn:version] [lang:AND] <a href="http://subversion.apache.org">Apache Subversion</a> [websvn:svnversion] ✓ <a href="http://validator.w3.org/check?uri=[websvn:validationurl]">XHTML</a> & <a href="http://jigsaw.w3.org/css-validator/validator?uri=[websvn:validationurl]">CSS</a></div> |
</body> |
</html> |
/WebSVN/templates/BlueGrey/header.tmpl |
---|
1,73 → 1,58 |
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> |
<html> |
<head> |
<meta http-equiv="content-type" content="text/html;charset=[websvn:charset]"> |
<link href="[websvn:locwebsvnhttp]/templates/BlueGrey/styles.css" rel="stylesheet" media="screen"> |
<!--[if lt IE 7]> |
<script type="text/javascript" src="[websvn:locwebsvnhttp]/templates/BlueGrey/png.js"></script> |
<![endif]--> |
<script type="text/javascript" src="[websvn:locwebsvnhttp]/templates/BlueGrey/collapse.js"></script> |
<title> |
WebSVN |
[websvn-test:repname] |
- [websvn:repname] |
[websvn-endtest] |
[websvn-test:action] |
- [websvn:action] |
[websvn-endtest] |
[websvn-test:rev2] |
[websvn-test:path2] |
- [websvn:safepath1] [lang:REV] [websvn:rev1] [lang:AND] [websvn:safepath2] [lang:REV] [websvn:rev2] |
[websvn-else] |
- [lang:REV] [websvn:rev1] [lang:AND] [websvn:rev2] |
[websvn-endtest] |
[websvn-else] |
[websvn-test:rev] |
- [lang:REV] [websvn:rev] |
[websvn-endtest] |
[websvn-endtest] |
[websvn-test:path] |
- [websvn:safepath] |
[websvn-endtest] |
</title> |
<script type="text/javascript"> |
function checkCB(chBox) |
{ |
count = 0 |
first = null |
f = chBox.form |
for (i = 0 ; i < f.elements.length ; i++) |
if (f.elements[i].type == 'checkbox' && f.elements[i].checked) |
{ |
if (first == null && f.elements[i] != chBox) |
first = f.elements[i] |
count += 1 |
} |
if (count > 2) |
{ |
first.checked = false |
count -= 1 |
} |
} |
[websvn-test:opentree] |
expandonload = true |
[websvn-endtest] |
</script> |
[websvn-test:curdirrsslink] |
<link rel="alternate" type="application/rss+xml" title="WebSVN RSS" href="[websvn:curdirrsshref]"> |
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> |
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="[websvn:language_code]" lang="[websvn:language_code]"> |
<head> |
<title> |
WebSVN |
[websvn-test:repname] |
– [websvn:repname] |
[websvn-endtest] |
[websvn-test:error] |
– ERROR |
[websvn-else] |
[websvn-test:action] |
– [websvn:action] |
[websvn-endtest] |
[websvn-test:rev2] |
[websvn-test:safepath2] |
– [websvn:safepath1] [lang:REV] [websvn:rev1] [lang:AND] [websvn:safepath2] [lang:REV] [websvn:rev2] |
[websvn-else] |
– [lang:REV] [websvn:rev1] [lang:AND] [websvn:rev2] |
[websvn-endtest] |
[websvn-else] |
[websvn-test:rev] |
– [lang:REV] [websvn:rev] |
[websvn-endtest] |
[websvn-endtest] |
[websvn-test:safepath] |
– [websvn:safepath] |
[websvn-endtest] |
[websvn-endtest] |
</title> |
<meta http-equiv="content-type" content="text/html;charset=UTF-8"/> |
<meta http-equiv="generator" content="WebSVN [websvn:version]"/> <!-- leave this for stats --> |
[websvn-test:blockrobots] |
<meta name="robots" content="noindex,nofollow"/> |
[websvn-endtest] |
<link rel="shortcut icon" type="image/x-icon" href="[websvn:locwebsvnhttp]/templates/BlueGrey/images/favicon.ico"/> |
<link type="text/css" href="[websvn:locwebsvnhttp]/templates/BlueGrey/styles.css" rel="stylesheet" media="screen"/> |
[websvn-test:rssurl] |
<link rel="alternate" type="application/rss+xml" title="WebSVN RSS" href="[websvn:rssurl]"/> |
[websvn-endtest] |
<!--[if lt IE 7]> |
<script type="text/javascript" src="[websvn:locwebsvnhttp]/javascript/ie-png-transparency.js"></script> |
<![endif]--> |
</head> |
<body> |
<table width="100%" border="0"> |
<tr> |
<td width="33%"> </td> |
<td width="33%" align="center"><a href="http://subversion.tigris.org/"><img style="border: 0; width: 468px; height: 64px;" src="[websvn:locwebsvnhttp]/templates/BlueGrey/subversion.png" alt="Subversion" /></a></td> |
<td width="33%"><div style="float: right">[websvn:lang_form][websvn:lang_select][websvn:lang_submit][websvn:lang_endform]</div></td> |
</tr> |
</table> |
<hr /> |
<body id="[websvn:template]"> |
<div id="header"> |
<table border="0"> |
<tr> |
<td width="33%"> </td> |
<td width="33%" align="center"><a href="[websvn:indexurl]" title="[lang:PROJECTS]"><img style="border: 0; width: 272px; height: 64px;" src="[websvn:locwebsvnhttp]/templates/BlueGrey/images/websvn.png" alt="WebSVN" /></a></td> |
<td width="33%"><div style="float: right"> |
[websvn:language_form][websvn:language_select][websvn:language_submit][websvn:language_endform] |
[websvn:template_form][websvn:template_select][websvn:template_submit][websvn:template_endform] |
</div></td> |
</tr> |
</table> |
</div> |
<div id="content"> |
/WebSVN/templates/BlueGrey/images/directory-open.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/BlueGrey/images/directory.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/BlueGrey/images/e-node.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/BlueGrey/images/favicon.ico |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/BlueGrey/images/file.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/BlueGrey/images/filec.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/BlueGrey/images/filecpp.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/BlueGrey/images/fileh.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/BlueGrey/images/filehtml.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/BlueGrey/images/filejava.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/BlueGrey/images/filem.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/BlueGrey/images/filepy.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/BlueGrey/images/i-node.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/BlueGrey/images/l-node.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/BlueGrey/images/repo.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/BlueGrey/images/rss.gif |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/BlueGrey/images/t-node.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/BlueGrey/images/websvn.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/BlueGrey/index.tmpl |
---|
1,26 → 1,69 |
<p> |
[websvn-test:flatview] |
<table align="center" cellspacing="0" cellpadding="0" width="50%"> |
<tr><th align="center" colspan=2 class="HdrClmnEnd">[lang:PROJECTS]</th></tr> |
[websvn-startlisting] |
<tr><td class="row[websvn:rowparity]"><img align="middle" src="[websvn:locwebsvnhttp]/templates/BlueGrey/repo.png" alt="[FOLDER]"> [websvn:projlink]</td> |
</tr> |
[websvn-endlisting] |
</table> |
[websvn-else] |
<table align="center" cellspacing=0 cellpadding=0 width="50%"> |
<tr><th align="left" colspan=2 class="HdrClmnEnd">[lang:PROJECTS]</th></tr> |
<td> |
[websvn-startlisting] |
[websvn-test:isprojlink] |
<div class="row[websvn:rowparity]"><img align="middle" src="[websvn:locwebsvnhttp]/templates/BlueGrey/repo.png" alt="[FOLDER]"> [websvn:listitem]</div> |
[websvn-else] |
[websvn:listitem] |
[websvn-endtest] |
[websvn-endlisting] |
</td> |
</tr> |
</table> |
[websvn-endtest] |
<hr /> |
[websvn-test:error] |
<div id="error">[websvn:error]</div> |
[websvn-else] |
<table> |
[websvn-test:showlastmod] |
<thead><tr><th colspan="4">[lang:PROJECTS]</th></tr></thead> |
[websvn-else] |
<thead><tr><th>[lang:PROJECTS]</th></tr></thead> |
[websvn-endtest] |
[websvn-test:flatview] |
[websvn-startlisting] |
[websvn-test:groupid] |
[websvn-else] |
<tr class="row[websvn:rowparity]"> |
<td class="project"><a href="[websvn:projecturl]">[websvn:projectname]</a></td> |
[websvn-test:showlastmod] |
<td>[lang:REV] [websvn:revision]</td> |
[websvn-test:showageinsteadofdate] |
<td title="[websvn:date]">[websvn:age]</td> |
[websvn-else] |
<td title="[websvn:age]">[websvn:date]</td> |
[websvn-endtest] |
<td>[websvn:author]</td> |
[websvn-endtest] |
</tr> |
[websvn-endtest] |
[websvn-endlisting] |
[websvn-else] |
[websvn-startlisting] |
[websvn-test:groupid] |
[websvn-test:showlastmod] |
<tr><th onclick="toggleGroup('[websvn:groupname]');" colspan="4">[websvn:groupname]</th></tr> |
[websvn-else] |
<tr><th onclick="toggleGroup('[websvn:groupname]');">[websvn:groupname]</th></tr> |
[websvn-endtest] |
[websvn-else] |
<tr title="[websvn:groupname]" class="row[websvn:groupparity]"> |
[websvn-test:groupname] |
<td class="project group"><a href="[websvn:projecturl]">[websvn:projectname]</a></td> |
[websvn-else] |
<td class="project"><a href="[websvn:projecturl]">[websvn:projectname]</a></td> |
[websvn-endtest] |
[websvn-test:showlastmod] |
<td>[lang:REV] [websvn:revision]</td> |
[websvn-test:showageinsteadofdate] |
<td title="[websvn:date]">[websvn:age]</td> |
[websvn-else] |
<td title="[websvn:age]">[websvn:date]</td> |
[websvn-endtest] |
<td>[websvn:author]</td> |
[websvn-endtest] |
</tr> |
[websvn-endtest] |
[websvn-endlisting] |
[websvn-endtest] |
</table> |
[websvn-test:treeview] |
<script type="text/javascript" src="[websvn:locwebsvnhttp]/javascript/jquery.min.1.9.1.js"></script> |
<script type="text/javascript" src="[websvn:locwebsvnhttp]/javascript/collapsible.js"></script> |
[websvn-test:opentree] |
[websvn-else] |
<script type="text/javascript"> |
//<![CDATA[ |
collapseAllGroups(); |
//]]> |
</script> |
[websvn-endtest] |
[websvn-endtest] |
[websvn-endtest] |
/WebSVN/templates/BlueGrey/log.tmpl |
---|
1,70 → 1,96 |
<table cellspacing="0" cellpadding="0" border="0" width="100%"> |
<tr> |
<td align="left"><h1>[websvn:repname] - [lang:REV] [websvn:rev]</h1></td> |
<td align="right"><b>[lang:PROJECTS]:</b> [websvn:projects_form][websvn:projects_select][websvn:projects_submit][websvn:projects_endform]</td> |
</tr> |
</table> |
[websvn:curdirlinks]<p> |
[websvn-test:goyoungestlink] |
[websvn:goyoungestlink]<p> |
[websvn-endtest] |
<hr> |
[websvn-test:noaccess] |
[lang:NOACCESS] |
<h1>[websvn:repname]</h1> |
<div id="projects">[websvn:projects_form]<b>[lang:PROJECTS]:</b> [websvn:projects_select][websvn:projects_submit][websvn:projects_endform]</div> |
[websvn-test:error] |
<div id="error">[websvn:error]</div> |
[websvn-else] |
<center> |
[websvn:logsearch_form] |
<b>[lang:FILTER]</b><p> |
[lang:STARTLOG]:[websvn:logsearch_startbox] [lang:ENDLOG]:[websvn:logsearch_endbox] [lang:MAXLOG]:[websvn:logsearch_maxbox] [lang:SEARCHLOG]:[websvn:logsearch_inputbox] |
[websvn:logsearch_submit] |
[websvn-test:logsearch_clearloglink] |
<p><font size="-1">[websvn:logsearch_clearloglink]</font><p> |
<div id="revjump">[websvn:revision_form]<b>[lang:REV]:</b>[websvn:revision_input][websvn:revision_submit][websvn:revision_endform]</div> |
<div id="path_links">[websvn:path_links_root_config]/[websvn:path_links]</div> |
<div id="nav"> |
[websvn-test:goyoungestlink] |
[websvn:goyoungestlink] – |
[websvn-endtest] |
[websvn:logsearch_endform] |
</center> |
[websvn-test:logsearch_nomatches] |
<center>[lang:NORESULTS]</center> |
[websvn-endtest] |
[websvn-test:error] |
<center>[websvn:error]</center> |
[websvn-endtest] |
[websvn:changeslink] – |
[websvn-test:filedetaillink] |
[websvn:filedetaillink] – |
[websvn:blamelink] – |
[websvn:difflink] |
[websvn-else] |
[websvn:directorylink] |
[websvn-endtest] |
[websvn-test:clientrooturl] |
– <a href="[websvn:clientrooturl][websvn:path]">SVN</a> |
[websvn-endtest] |
[websvn-test:rsslink] |
– <a href="[websvn:rssurl]"><img src="[websvn:locwebsvnhttp]/templates/BlueGrey/images/rss.gif" width="27" height="15" alt="[lang:RSSFEED]"/></a> |
[websvn-endtest] |
</div> |
[websvn-test:warning] |
<div id="warning">[websvn:warning]</div> |
[websvn-else] |
<center> |
[websvn:logsearch_form] |
[lang:STARTLOG]:[websvn:logsearch_startbox] [lang:ENDLOG]:[websvn:logsearch_endbox] [lang:MAXLOG]:[websvn:logsearch_maxbox] [lang:SEARCHLOG]:[websvn:logsearch_inputbox] [lang:SHOWALL]:[websvn:logsearch_showall] |
[websvn:logsearch_submit] |
[websvn-test:logsearch_clearloglink] |
<br/>[websvn:logsearch_clearloglink] |
[websvn-endtest] |
[websvn:logsearch_endform] |
[websvn-test:logsearch_nomatches] |
<p>[lang:NORESULTS]</p> |
[websvn-endtest] |
[websvn-test:logsearch_nomorematches] |
<p>[lang:NOMORERESULTS]</p> |
[websvn-endtest] |
[websvn:logsearch_moreresultslink] |
<span id="logpagelinks">[websvn:pagelinks]</span> [websvn:showalllink] |
</center> |
[websvn-test:logsearch_resultsfound] |
[websvn:compare_form] |
<table cellpadding="2px" cellspacing="0" width="100%"> |
<tr> |
<th class="HdrClmn">[lang:REV]</th> |
<th class="HdrClmn">[lang:PATH]</th> |
<th class="HdrClmn">[lang:AUTHOR]</th> |
<th class="HdrClmn">[lang:AGE]</th> |
<th class="HdrClmnEnd">[lang:LOGMSG]</th> |
</tr> |
[websvn-startlisting] |
<tr> |
<td style="border-right: 1px solid black" valign="top" class="row[websvn:rowparity]"><nobr>[websvn:compare_box][websvn:revlink]</nobr></td> |
<td style="border-right: 1px solid black" valign="top" class="row[websvn:rowparity]">[websvn:revpathlink]</td> |
<td style="border-right: 1px solid black" valign="top" class="row[websvn:rowparity]">[websvn:revauthor]</td> |
<td style="border-right: 1px solid black" valign="top" class="row[websvn:rowparity]">[websvn:revage]</td> |
<td valign="top" class="row[websvn:rowparity]">[websvn:revlog]</td> |
</tr> |
[websvn-endlisting] |
</table> |
<p> |
[websvn:compare_submit] |
[websvn:compare_endform] |
[websvn-endtest] |
[websvn-test:logsearch_nomorematches] |
<p><center>[lang:NOMORERESULTS]</center> |
[websvn-endtest] |
<p><center>[websvn:logsearch_moreresultslink]</center> |
<hr> |
<p><center>[websvn:pagelinks]<p>[websvn:showalllink]</center> |
[websvn-test:logsearch_resultsfound] |
[websvn:compare_form] |
<table cellpadding="2" cellspacing="0"> |
<thead> |
<tr> |
<th>[lang:REV]</th> |
<th>[lang:AGE]</th> |
<th>[lang:AUTHOR]</th> |
<th>[lang:PATH]</th> |
<th>[lang:LOGMSG]</th> |
<th>[lang:DIFF]</th> |
[websvn-test:showchanges] |
<th>[lang:CHANGES]</th> |
[websvn-endtest] |
</tr> |
</thead> |
[websvn-startlisting] |
<tr class="row[websvn:rowparity]"> |
<td style="white-space: nowrap;">[websvn:compare_box][websvn:revlink]</td> |
[websvn-test:showageinsteadofdate] |
<td title="[websvn:revdate]">[websvn:revage]</td> |
[websvn-else] |
<td title="[websvn:revage]">[websvn:revdate]</td> |
[websvn-endtest] |
<td>[websvn:revauthor]</td> |
<td>[websvn:revpathlink]</td> |
<td valign="top">[websvn:revlog]</td> |
<td><a href="[websvn:compareurl]" title="[lang:DIFFPREV]">[lang:DIFF]</a></td> |
[websvn-test:showchanges] |
<td class="changes"><table> |
[websvn-test:revadded] |
<tr><td>A</td><td>[websvn:revadded]</td></tr> |
[websvn-endtest] |
[websvn-test:revdeleted] |
<tr><td>D</td><td>[websvn:revdeleted]</td></tr> |
[websvn-endtest] |
[websvn-test:revmodified] |
<tr><td>M</td><td>[websvn:revmodified]</td></tr> |
[websvn-endtest] |
</table></td> |
[websvn-endtest] |
</tr> |
[websvn-endlisting] |
</table> |
<center>[websvn:compare_submit]</center> |
[websvn:compare_endform] |
[websvn-endtest] |
[websvn-endtest] |
[websvn-endtest] |
/WebSVN/templates/BlueGrey/revision.tmpl |
---|
0,0 → 1,102 |
<h1>[websvn:repname] – [lang:REV] [websvn:rev]</h1> |
<div id="projects">[websvn:projects_form]<b>[lang:PROJECTS]:</b> [websvn:projects_select][websvn:projects_submit][websvn:projects_endform]</div> |
[websvn-test:error] |
<div id="error">[websvn:error]</div> |
[websvn-else] |
<div id="revjump">[websvn:revision_form]<b>[lang:REV]:</b>[websvn:revision_input][websvn:revision_submit][websvn:revision_endform]</div> |
<div id="path_links">[websvn:path_links_root_config]/[websvn:path_links]</div> |
[websvn-test:warning] |
[websvn-else] |
<table cellpadding="2" cellspacing="0" class="outline"> |
<thead> |
<tr><th colspan="2">[lang:REVINFO]</th></tr> |
</thead> |
[websvn-test:restricted] |
[websvn-else] |
<tr class="row0"><th>[lang:LASTMOD]:</th><td>[lang:REV] [websvn:rev] – [websvn:author] |
[websvn-test:showageinsteadofdate] |
– <span title="[websvn:date]">[websvn:age]</span> |
[websvn-else] |
– <span title="[websvn:age]">[websvn:date]</span> |
[websvn-endtest] |
[websvn-test:prevrevurl] |
– <a href="[websvn:prevrevurl]">[lang:REV] [websvn:prevrev]</a> |
[websvn-endtest] |
[websvn-test:nextrevurl] |
– <a href="[websvn:nextrevurl]">[lang:REV] [websvn:nextrev]</a> |
[websvn-endtest] |
[websvn-test:goyoungestlink] |
– [websvn:goyoungestlink] |
[websvn-endtest] |
</td></tr> |
<tr class="row1"><th>[lang:LOGMSG]:</th><td>[websvn:log]</td></tr> |
[websvn-endtest] |
</table> |
[websvn-endtest] |
<div id="nav"> |
[websvn-test:comparelink] |
[websvn:comparelink] – |
[websvn-endtest] |
[websvn:directorylink] – |
[websvn:loglink] |
[websvn-test:filedetaillink] |
– [websvn:filedetaillink] |
[websvn-endtest] |
[websvn-test:blamelink] |
– [websvn:blamelink] |
[websvn-endtest] |
[websvn-test:clientrooturl] |
– <a href="[websvn:clientrooturl][websvn:path]">SVN</a> |
[websvn-endtest] |
[websvn-test:rssurl] |
– <a href="[websvn:rssurl]"><img src="[websvn:locwebsvnhttp]/templates/BlueGrey/images/rss.gif" width="27" height="15" alt="[lang:RSSFEED]"/></a> |
[websvn-endtest] |
</div> |
[websvn-test:warning] |
<div id="warning">[websvn:warning]</div> |
[websvn-else] |
<table cellpadding="2" cellspacing="0" class="outline"> |
<thead> |
<tr> |
<th>[lang:PATH]</th> |
<th>[lang:BLAME]</th> |
<th>[lang:DIFF]</th> |
<th>[lang:VIEWLOG]</th> |
[websvn-test:clientrooturl] |
<th>SVN</th> |
[websvn-endtest] |
</tr> |
</thead> |
<tbody> |
[websvn-startlisting] |
<tr class="[websvn:action] row[websvn:rowparity]"> |
<td>[websvn:action] |
[websvn-test:notinpath] |
<a href="[websvn:detailurl]" class="notinpath">[websvn:safepath]</a> |
[websvn-else] |
<a href="[websvn:detailurl]">[websvn:safepath]</a> |
[websvn-endtest] |
[websvn-test:oldsafepath] |
<br/> <del>[websvn:oldsafepath] ([lang:PREV])</del> |
[websvn-endtest] |
</td> |
[websvn-test:blameurl] |
<td><a href="[websvn:blameurl]">[lang:BLAME]</a></td> |
[websvn-else] |
<td></td> |
[websvn-endtest] |
[websvn-test:diffurl] |
<td><a href="[websvn:diffurl]">[lang:DIFF]</a></td> |
[websvn-else] |
<td></td> |
[websvn-endtest] |
<td><a href="[websvn:logurl]">[lang:LOG]</a></td> |
[websvn-test:clientrooturl] |
<td><a href="[websvn:clientrooturl][websvn:path]">SVN</a></td> |
[websvn-endtest] |
</tr> |
[websvn-endlisting] |
</tbody> |
</table> |
[websvn-endtest] |
[websvn-endtest] |
/WebSVN/templates/BlueGrey/styles.css |
---|
1,131 → 1,401 |
body |
{ |
font-family: verdana, sans-serif; |
color: black; |
background-color: white |
/* @group General Styles */ |
body { |
margin: 0; |
font-family: Verdana, Helvetica, Arial, sans-serif; |
font-size: 10pt; |
color: black; |
background-color: white; |
} |
body * |
{ |
font-size: 10pt; |
h1 { |
font-size: 150%; |
margin: 0; |
float: left; |
} |
h1 |
{ |
font-size: 150%; |
h2 { |
font-size: 125%; |
} |
h2 |
{ |
font-size: 125%; |
h3 { |
font-size: 105%; |
} |
hr |
{ |
border: 0px; |
padding: 0px; |
height: 1px; |
background-color: #808080 |
a:link, a:visited { |
color: #004080; |
text-decoration: none; |
} |
a:link, a:visited |
{ |
color: #004080; |
text-decoration: none; |
a:hover, a:active { |
text-decoration: underline; |
} |
a:hover, a:active |
{ |
text-decoration: underline; |
thead th a:link, thead th a:visited { |
color: white; |
} |
.HdrClmn, |
.HdrClmnEnd |
{ |
border: black 1px solid; |
font-weight: bold; |
color: white; |
background-color: #809cc8 |
a img { |
border: none; |
} |
table |
{ |
border-width:0px; |
border-collapse:collapse; |
table { |
border-width: 0px; |
border-collapse: collapse; |
width: 100%; |
} |
.row0, |
.row1 |
{ |
height:22px; |
border-width:0px; |
pre { |
padding: 4px; |
background-color: #eee; |
border: solid 1px #ccc; |
} |
.row0 img, |
.row1 img { |
padding: 0px; |
margin: 0px; |
vertical-align:middle; |
code { |
white-space: pre-wrap; |
} |
.row0 |
{ |
background-color: #f0f0f0; |
/* Semantic sections */ |
#header { |
padding: 5px 0; |
border-bottom: 1px solid #555; |
} |
.row1 |
{ |
background-color: #e0e0e0; |
#projects, #revjump { |
float: right; |
} |
.CatClmn0 |
{ |
border-right: black 1px solid; |
background-color: #e0e0ff |
#revjump, #error { |
clear: both; |
} |
.CatClmn1 |
{ |
border-right: black 1px solid; |
background-color: #d0d0ee |
#path_links { |
clear: left; |
padding-top: 5px; |
} |
#nav { |
margin: 10px 0; |
} |
table.outline |
{ |
border-collapse:collapse; |
border: 1px black solid; |
#content { |
margin: 10px; |
} |
#content table { |
border: 1px solid #555; |
margin: 10px 0; |
} |
#content th, #content td { |
padding: 0 3px; |
} |
#content thead th { |
border: 1px solid #555; |
font-weight: bold; |
color: white; |
background-color: #809cc8; |
padding: 1px 4px 2px 1px; |
} |
#content thead th.path { |
text-align: left; |
width: 60%; |
} |
#content thead th.last_mod { |
width: 25%; |
} |
#content thead th.view_log, |
#content thead th.download, |
#content thead th.rss { |
width: 5%; |
} |
td.diffdeleted |
{ |
font-size: 11px; |
background-color: #ff8888; |
.row0, .row1 { |
border-width: 0px; |
} |
.row0 img, .row1 img { |
padding: 0px; |
margin: 0px; |
vertical-align: middle; |
} |
.row0 { |
background-color: #f0f0f0; |
} |
.row1 { |
background-color: #e0e0e0; |
} |
td.diffchanged |
{ |
font-size: 11px; |
background-color: #ffff88; |
tr.row0 th, tr.row1 th, #content td { |
font-weight: normal; |
text-align: left; |
vertical-align: top; |
border-right: 1px solid #555; |
} |
tr.row0 th { |
background-color: #e0e0ff |
} |
tr.row1 th { |
background-color: #d0d0ee; |
} |
th.row1 { |
background-color: #d0d0ee; |
border-right: 1px solid #555; |
} |
div.clearer { |
clear: both; |
height: 0; |
} |
td.diffadded |
{ |
font-size: 11px; |
background-color: #88ff88; |
#footer { |
padding: 3px; |
text-align: center; |
font-size: 80%; |
font-weight: bold; |
background-color: #e5e9fe; |
border: solid #555; |
border-width: 1px 0; |
} |
td.diff |
{ |
font-size: 11px; |
background-color: #F0F0F0; |
div#error, div#warning { |
font-weight: bold; |
display: table; |
padding: 5px; |
margin: 10px auto; |
border: 1px solid; |
} |
div.newpath |
{ |
padding: 10px; |
background-color: #d0d0ee |
div#error { |
border-color: #b2595a; |
background-color: #ffe2e2; |
} |
div.difflines |
{ |
div#warning { |
border-color: #b2ac00; |
background-color: #ffd; |
} |
.plusbox { float: left; clear: both; position: relative; top: -3px; font-size: 13px; font-weight: bold; width: 16px; text-indent: 0; height: 16px; color: black; background-color: #D0D0D0; text-align: center; padding: 0px 2px 0px 3px; border: black solid 1px; margin-right: 5px; } |
.minusbox { float: left; clear: both; position: relative; top: -3px; font-size: 13px; font-weight: bold; width: 16px; text-indent: 0; height: 16px; color: black; background-color: #809cc8; text-align: center; padding: 0px 2px 0px 3px; border: black solid 1px; margin-right: 5px; } |
/* @end */ |
.groupname { padding-left: 0px; text-indent: -25px; margin: 3px 0 3px 0;} |
.switchcontent { margin: 3px 0 0 20px; } |
.project { padding: 2px; } |
/* @group blame.tmpl */ |
code |
{ |
white-space: pre-wrap; |
} |
#blame #content table { |
width: 100%; |
} |
#blame #content table tbody th { |
font-weight: normal; |
text-align: right; |
} |
#blame #content table tbody .light th { |
border-right: black 1px solid; |
background-color: #e0e0ff; |
} |
#blame #content table tbody .dark th { |
border-right: black 1px solid; |
background-color: #d0d0ee; |
} |
div.blame-popup { |
position: absolute; |
text-align: left; |
background-color: white; |
border: solid 2px #809cc8; |
padding: 5px; |
max-width: 600px; |
} |
div.blame-popup .date { |
font-weight: bold; |
} |
/* @end */ |
/* @group compare.tmpl */ |
#compare #params, #params td { |
border-width: 0; |
} |
#compare #params td { |
vertical-align: middle; |
} |
#compare .comparison { |
width: 100%; |
margin: 20px 0 10px; |
} |
#compare .comparison tbody th { |
text-align: center; |
font-weight: bold; |
border: 1px solid #555; |
} |
#compare .comparison td { |
font-family: monospace; |
font-size: 90%; |
white-space: pre-wrap; |
} |
/* Whitespace hacks for IE 4-7 */ |
* html #compare .comparison td { |
white-space: pre; |
} |
*:first-child+html #compare .comparison td { |
white-space: pre; |
} |
/* @end */ |
/* @group diff.tmpl */ |
#diff td { |
font-size: 90%; |
} |
#diff td.lineno { |
text-align: right; |
vertical-align: top; |
} |
td.diffdeleted { |
background-color: #ff8888; |
} |
td.diffchanged { |
background-color: #ffff88; |
} |
td.diffchanged ins { |
background-color: #88ff88; |
text-decoration: none; |
} |
td.diffchanged del { |
background-color: #ff8888; |
text-decoration: none; |
} |
td.diffadded { |
background-color: #88ff88; |
} |
td.diff { |
background-color: #f0f0f0; |
} |
div.newpath { |
padding: 10px; |
background-color: #d0d0ee; |
} |
div.difflines { |
} |
#diff th.row1 { |
border: solid 1px #555; |
} |
/* @end */ |
/* @group directory.tmpl */ |
#directory table#listing tbody tr { |
height: 22px; |
} |
#directory td.age, #directory td.date, #directory td.rev { |
border-right-width: 0; |
} |
img.icon { |
vertical-align: middle; |
} |
/* @end */ |
/* @group file.tmpl */ |
#file #listing { |
font-size: 90%; |
border: 1px solid #999; |
padding: 5px; |
background-color: #f0f0f0; |
} |
/* @end */ |
/* @group index.tmpl */ |
#index #content table { |
margin: 0 auto; |
} |
#index #content th { |
padding: 4px; |
} |
#index #content td { |
padding: 0px; |
vertical-align: middle; |
padding-right: 6px; |
border-width: 0; |
text-align: right; |
} |
#index #content td.project { |
text-align: left; |
} |
#index #content td a { |
background: url(images/repo.png) no-repeat 3px 3px; |
width: 100%; |
display: block; |
padding-top: 6px; |
padding-bottom: 6px; |
} |
#index #content td a, #index #content td.group, #index #content tbody th { |
padding-left: 32px; |
text-align: left; |
} |
#index #content tbody th { |
background-color: #D0D0D0; |
text-decoration: underline; |
} |
.groupname { |
font-weight: bold; |
padding-left: 0px; |
text-indent: 4px; |
margin: 3px 0 3px 0; |
} |
.switchcontent { |
margin: 3px 0 0 20px; |
} |
/* @end */ |
/* @group log.tmpl */ |
#logpagelinks > * { |
padding: 0 3px; |
} |
#content td.changes table { |
margin: 0; |
} |
#content td.changes * { |
border-width: 0; |
} |
/* @end */ |
/* @group revision.tmpl */ |
#revision del { |
color: #555; |
text-decoration: none; |
} |
#revision a.notinpath { |
color: #8d0208; |
} |
/* @end */ |
/WebSVN/templates/Elegant/blame.tmpl |
---|
0,0 → 1,65 |
[websvn-test:error] |
</div> |
[websvn-else] |
<h2 id="path_links">[websvn:path_links_root_config]/[websvn:path_links]</h2> |
<div id="revjump">[websvn:revision_form][websvn:revision_input]<span class="submit">[websvn:revision_submit]</span>[websvn:revision_endform]</div> |
<h2 id="revnum"><a href="[websvn:revurl]">[lang:REV] [websvn:rev]</a></h2> |
<div class="clearer"></div> |
</div> |
<ul id="links"> |
[websvn-test:prevrevurl] |
<li class="prev"><a href="[websvn:prevrevurl]">[lang:REV] [websvn:prevrev]</a></li> |
[websvn-endtest] |
[websvn-test:nextrevurl] |
<li class="next"><a href="[websvn:nextrevurl]">[lang:REV] [websvn:nextrev]</a></li> |
[websvn-endtest] |
[websvn-test:goyoungestlink] |
<li class="youngest">[websvn:goyoungestlink]</li> |
[websvn-endtest] |
<li class="file">[websvn:filedetaillink]</li> |
[websvn-test:difflink] |
<li class="diff">[websvn:difflink]</li> |
[websvn-endtest] |
<li class="rev">[websvn:revlink]</li> |
<li class="log">[websvn:loglink]</li> |
[websvn-test:clientrooturl] |
<li class="svn"><a href="[websvn:clientrooturl][websvn:path]">SVN</a></li> |
[websvn-endtest] |
[websvn-test:rsslink] |
<li class="rss">[websvn:rsslink]</li> |
[websvn-endtest] |
</ul> |
[websvn-endtest] |
</div> |
<div id="content"> |
[websvn-test:error] |
<div class="error"><span>[websvn:error]</span></div> |
[websvn-else] |
[websvn-test:warning] |
<div class="warning"><span>[websvn:warning]</span></div> |
[websvn-else] |
<table> |
<thead> |
<tr> |
<th>[lang:REV]</th> |
<th>[lang:AUTHOR]</th> |
<th>[lang:LINENO]</th> |
<th>[lang:LINE]</th> |
</tr> |
</thead> |
<tbody> |
[websvn-startlisting] |
<tr class="[websvn:row_class]"> |
<td class="rev">[websvn:revision]</td> |
<td class="author">[websvn:author]</td> |
<td class="line"><a name="l[websvn:lineno]" href="#l[websvn:lineno]"></a>[websvn:lineno]</td> |
<td class="code">[websvn:line]</td> |
</tr> |
[websvn-endlisting] |
</tbody> |
</table> |
[websvn-endtest] |
[websvn-endtest] |
[websvn-test:javascript] |
[websvn:javascript] |
[websvn-endtest] |
/WebSVN/templates/Elegant/compare.tmpl |
---|
0,0 → 1,68 |
[websvn-test:error] |
</div> |
[websvn-else] |
<h2><a href="[websvn:rev1url]">[websvn:safepath1] @ [websvn:rev1]</a> → <a href="[websvn:rev2url]">[websvn:safepath2] @ [websvn:rev2]</a></h2> |
<div class="clearer"></div> |
</div> |
<ul id="links"> |
<li class="reverse">[websvn:reverselink]</li> |
[websvn-test:ignorewhitespacelink] |
<li class="ignore">[websvn:ignorewhitespacelink]</li> |
[websvn-else] |
<li class="regard">[websvn:regardwhitespacelink]</li> |
[websvn-endtest] |
</ul> |
[websvn-endtest] |
</div> |
<div id="content"> |
[websvn-test:error] |
<div class="error"><span>[websvn:error]</span></div> |
[websvn-else] |
<div id="compare_form"> |
[websvn:compare_form] |
<table> |
<tr> |
<td class="path"><label>[lang:COMPPATH]</label> [websvn:compare_path1input]</td> |
<td><label>[lang:REV]</label> [websvn:compare_rev1input]</td> |
<td rowspan="2">[websvn:compare_submit]</td> |
</tr> |
<tr> |
<td class="path"><label>[lang:WITHPATH]</label> [websvn:compare_path2input]</td> |
<td><label>[lang:REV]</label> [websvn:compare_rev2input]</td> |
</tr> |
</table> |
[websvn:compare_endform] |
</div> |
[websvn-test:warning] |
<div id="warning">[websvn:warning]</div> |
[websvn-endtest] |
<div id="comparisons"> |
[websvn-startlisting] |
[websvn-test:newpath] |
<table class="collapsible"> |
<thead> |
<tr><th><a href="[websvn:fileurl]">[websvn:newpath]</a></th></tr> |
</thead> |
<tbody> |
[websvn-endtest] |
[websvn-test:info] |
<tr><th class="info">[websvn:info]</th></tr> |
[websvn-endtest] |
[websvn-test:difflines] |
<tr><th>[websvn:rev1line],[websvn:rev1len] → [websvn:rev2line],[websvn:rev2len]</th></tr> |
[websvn-endtest] |
[websvn-test:diffclass] |
<tr><td class="[websvn:diffclass]">[websvn:line]</td></tr> |
[websvn-endtest] |
[websvn-test:properties] |
<tr><th>[lang:PROPCHANGES]</th></tr> |
[websvn-endtest] |
[websvn-test:endpath] |
</tbody> |
</table> |
[websvn-endtest] |
[websvn-endlisting] |
</div> |
<script type="text/javascript" src="[websvn:locwebsvnhttp]/javascript/jquery.min.1.9.1.js"></script> |
<script type="text/javascript" src="[websvn:locwebsvnhttp]/javascript/collapsible.js"></script> |
[websvn-endtest] |
/WebSVN/templates/Elegant/diff.tmpl |
---|
0,0 → 1,84 |
[websvn-test:error] |
</div> |
[websvn-else] |
<h2 id="path_links">[websvn:path_links_root_config]/[websvn:path_links]</h2> |
<div id="revjump">[websvn:revision_form][websvn:revision_input]<span class="submit">[websvn:revision_submit]</span>[websvn:revision_endform]</div> |
[websvn-test:noprev] |
<h2 id="revnum"><a href="[websvn:revurl]">[lang:REV] [websvn:rev1]</a></h2> |
[websvn-else] |
<h2 id="revnum"><a href="[websvn:revurl]">[lang:REV] [websvn:rev2] → [lang:REV] [websvn:rev1]</a></h2> |
[websvn-endtest] |
<div class="clearer"></div> |
</div> |
<ul id="links"> |
[websvn-test:prevrevurl] |
<li class="prev"><a href="[websvn:prevrevurl]">[lang:REV] [websvn:prevrev]</a></li> |
[websvn-endtest] |
[websvn-test:nextrevurl] |
<li class="next"><a href="[websvn:nextrevurl]">[lang:REV] [websvn:nextrev]</a></li> |
[websvn-endtest] |
[websvn-test:goyoungestlink] |
<li class="youngest">[websvn:goyoungestlink]</li> |
[websvn-endtest] |
[websvn-test:showalllink] |
<li class="entire">[websvn:showalllink]</li> |
[websvn-endtest] |
[websvn-test:showcompactlink] |
<li class="compact">[websvn:showcompactlink]</li> |
[websvn-endtest] |
[websvn-test:ignorewhitespacelink] |
<li class="ignore">[websvn:ignorewhitespacelink]</li> |
[websvn-endtest] |
[websvn-test:regardwhitespacelink] |
<li class="regard">[websvn:regardwhitespacelink]</li> |
[websvn-endtest] |
<li class="file">[websvn:filedetaillink]</li> |
<li class="blame">[websvn:blamelink]</li> |
<li class="rev">[websvn:revlink]</li> |
<li class="log">[websvn:loglink]</li> |
[websvn-test:clientrooturl] |
<li class="svn"><a href="[websvn:clientrooturl][websvn:path]">SVN</a></li> |
[websvn-endtest] |
[websvn-test:rsslink] |
<li class="rss">[websvn:rsslink]</li> |
[websvn-endtest] |
</ul> |
[websvn-endtest] |
</div> |
<div id="content"> |
[websvn-test:error] |
<div class="error"><span>[websvn:error]</span></div> |
[websvn-else] |
[websvn-test:warning] |
<div class="warning"><span>[websvn:warning]</span></div> |
[websvn-else] |
[websvn-test:noprev] |
<div class="warning"><span>[lang:NOPREVREV]</span></div> |
[websvn-else] |
<table> |
<thead> |
<tr> |
<th colspan="2">[lang:REV] [websvn:rev2]</th> |
<th colspan="2">[lang:REV] [websvn:rev1]</th> |
</tr> |
</thead> |
<tbody> |
[websvn-startlisting] |
[websvn-test:startblock] |
<tr> |
<th colspan="2">[lang:LINE] [websvn:rev1lineno]...</th> |
<th colspan="2">[lang:LINE] [websvn:rev2lineno]...</th> |
</tr> |
[websvn-endtest] |
<tr> |
<td class="line">[websvn:rev1lineno]</td> |
<td class="[websvn:rev1diffclass]">[websvn:rev1line]</td> |
<td class="line">[websvn:rev2lineno]</td> |
<td class="[websvn:rev2diffclass]">[websvn:rev2line]</td> |
</tr> |
[websvn-endlisting] |
</tbody> |
</table> |
[websvn-endtest] <!-- noprev --> |
[websvn-endtest] <!-- warning --> |
[websvn-endtest] <!-- noaccess --> |
/WebSVN/templates/Elegant/directory.tmpl |
---|
0,0 → 1,150 |
[websvn-test:error] |
</div> |
[websvn-else] |
<h2 id="path_links">[websvn:path_links_root_config]/[websvn:path_links]</h2> |
<div id="revjump">[websvn:revision_form][websvn:revision_input]<span class="submit">[websvn:revision_submit]</span>[websvn:revision_endform]</div> |
[websvn-test:search] |
<div id="searchcss">[websvn:search_form]<div>[lang:SEARCH] [websvn:search_input]<span class="submit">[websvn:search_submit]</span></div>[websvn:search_endform]</div> |
[websvn-endtest] |
<h2 id="revnum"><a href="[websvn:revurl]">[lang:REV] [websvn:rev]</a></h2> |
<div class="clearer"></div> |
</div> |
<ul id="links"> |
[websvn-test:prevrevurl] |
<li class="prev"><a href="[websvn:prevrevurl]">[lang:REV] [websvn:prevrev]</a></li> |
[websvn-endtest] |
[websvn-test:nextrevurl] |
<li class="next"><a href="[websvn:nextrevurl]">[lang:REV] [websvn:nextrev]</a></li> |
[websvn-endtest] |
[websvn-test:goyoungestlink] |
<li class="youngest">[websvn:goyoungestlink]</li> |
[websvn-endtest] |
[websvn-test:comparelink] |
<li class="diff">[websvn:comparelink]</li> |
[websvn-endtest] |
<li class="rev">[websvn:revlink]</li> |
<li class="log">[websvn:loglink]</li> |
[websvn-test:downloadurl] |
<li class="download"><a href="[websvn:downloadurl]" rel="nofollow">[lang:DOWNLOAD]</a></li> |
[websvn-endtest] |
[websvn-test:clientrooturl] |
<li class="svn"><a href="[websvn:clientrooturl][websvn:path]">SVN</a></li> |
[websvn-endtest] |
[websvn-test:rsslink] |
<li class="rss">[websvn:rsslink]</li> |
[websvn-endtest] |
</ul> |
[websvn-endtest] |
</div> |
<div id="content"> |
[websvn-test:error] |
<div class="error"><span>[websvn:error]</span></div> |
[websvn-else] |
[websvn-test:warning] |
<div class="warning"><span>[websvn:warning]</span></div> |
[websvn-else] |
[websvn-defineicons] |
*=<img src="[websvn:locwebsvnhttp]/templates/Elegant/images/file.png" alt="file" /> |
.c=<img src="[websvn:locwebsvnhttp]/templates/Elegant/images/file-c.png" alt=".c file" /> |
.cpp=<img src="[websvn:locwebsvnhttp]/templates/Elegant/images/file-cpp.png" alt=".cpp FILE" /> |
.h=<img src="[websvn:locwebsvnhttp]/templates/Elegant/images/file-h.png" alt=".h file" /> |
.m=<img src="[websvn:locwebsvnhttp]/templates/Elegant/images/file-m.png" alt=".m file" /> |
.java=<img src="[websvn:locwebsvnhttp]/templates/Elegant/images/file-java.png" alt=".java file" /> |
.py=<img src="[websvn:locwebsvnhttp]/templates/Elegant/images/file-py.png" alt=".py file" /> |
.png=<img src="[websvn:locwebsvnhttp]/templates/Elegant/images/file-image.png" alt="PNG image" /> |
.gif=<img src="[websvn:locwebsvnhttp]/templates/Elegant/images/file-image.png" alt="GIF image" /> |
.bmp=<img src="[websvn:locwebsvnhttp]/templates/Elegant/images/file-image.png" alt="BMP image" /> |
.jpg=<img src="[websvn:locwebsvnhttp]/templates/Elegant/images/file-image.png" alt="JPG image" /> |
.jpeg=<img src="[websvn:locwebsvnhttp]/templates/Elegant/images/file-image.png" alt="JPG image" /> |
.html=<img src="[websvn:locwebsvnhttp]/templates/Elegant/images/file-html.png" alt="HTML file" /> |
.htm=<img src="[websvn:locwebsvnhttp]/templates/Elegant/images/file-html.png" alt="HTML file" /> |
.xml=<img src="[websvn:locwebsvnhttp]/templates/Elegant/images/file-xml.png" alt="XML file" /> |
.php=<img src="[websvn:locwebsvnhttp]/templates/Elegant/images/file-php.png" alt="PHP file" /> |
.css=<img src="[websvn:locwebsvnhttp]/templates/Elegant/images/file-css.png" alt="CSS file" /> |
dir=<img src="[websvn:locwebsvnhttp]/templates/Elegant/images/directory.png" alt="[DIRECTORY]" /> |
diropen=<img src="[websvn:locwebsvnhttp]/templates/Elegant/images/directory.png" alt="[DIRECTORY]" /> |
i-node=<img src="[websvn:locwebsvnhttp]/templates/Elegant/images/blank.png" alt="node" /> |
t-node=<img src="[websvn:locwebsvnhttp]/templates/Elegant/images/blank.png" alt="node" /> |
l-node=<img src="[websvn:locwebsvnhttp]/templates/Elegant/images/blank.png" alt="node" /> |
e-node=<img src="[websvn:locwebsvnhttp]/templates/Elegant/images/blank.png" alt="node" /> |
[websvn-enddefineicons] |
[websvn:compare_form] |
<table id="listing"> |
<thead> |
<tr> |
<th>[lang:PATH]</th> |
[websvn-test:showlastmod] |
<th colspan="3">[lang:LASTMOD]</th> |
[websvn-endtest] |
<th>[lang:LOG]</th> |
[websvn-test:allowdownload] |
<th>[lang:DOWNLOAD]</th> |
[websvn-endtest] |
[websvn-test:clientrooturl] |
<th>SVN</th> |
[websvn-endtest] |
[websvn-test:rssurl] |
<th>[lang:RSSFEED]</th> |
[websvn-endtest] |
</tr> |
</thead> |
<tbody> |
[websvn-startlisting] |
[websvn-test:rowparity] |
<tr class="shaded" |
[websvn-test:loadalldir] |
title="[websvn:classname]" |
[websvn-endtest] |
> |
[websvn-else] |
<tr [websvn-test:loadalldir]customaction="closed" title="[websvn:classname]"[websvn-endtest]> |
[websvn-endtest] |
<td class="path" valign="middle"> |
[websvn:compare_box] |
[websvn-treenode] |
<a href="[websvn:fileurl]"> |
[websvn-icon] |
[websvn:filename] |
</a> |
</td> |
[websvn-test:showlastmod] |
<td class="rev"><a href="[websvn:revurl]" title="[lang:REV] [websvn:revision]">[websvn:revision]</a> </td> |
[websvn-test:showageinsteadofdate] |
<td class="date" title="[websvn:date]">[websvn:age]</td> |
[websvn-else] |
<td class="date" title="[websvn:age]">[websvn:date]</td> |
[websvn-endtest] |
<td class="author">[websvn:author]</td> |
[websvn-endtest] |
<td class="log"><a href="[websvn:logurl]" title="[lang:LOG]">[lang:LOG]</a></td> |
[websvn-test:allowdownload] |
<td class="download"> |
[websvn-test:downloadurl] |
<a href="[websvn:downloadurl]" rel="nofollow" title="[lang:DOWNLOAD]">[lang:DOWNLOAD]</a> |
[websvn-endtest] |
[websvn-test:downloadplainurl] |
<a href="[websvn:downloadplainurl]" rel="nofollow" title="[lang:DOWNLOAD]">[lang:DOWNLOAD]</a> |
[websvn-endtest] |
</td> |
[websvn-endtest] |
[websvn-test:clientrooturl] |
<td class="svn"><a href="[websvn:clientrooturl][websvn:path]" title="SVN">SVN</a></td> |
[websvn-endtest] |
[websvn-test:rssurl] |
<td class="rss"><a href="[websvn:rssurl]" title="[lang:RSSFEED]">[lang:RSSFEED]</a></td> |
[websvn-endtest] |
</tr> |
[websvn-endlisting] |
</tbody> |
</table> |
<div id="compare-submit">[websvn:compare_submit]</div> |
[websvn:compare_endform] |
[websvn-endtest] |
[websvn-test:loadalldir] |
<script type="text/javascript" src="[websvn:locwebsvnhttp]/javascript/jquery.min.1.9.1.js"></script> |
<script type="text/javascript" src="[websvn:locwebsvnhttp]/javascript/collapsible.js"></script> |
[websvn-endtest] |
[websvn-endtest] |
/WebSVN/templates/Elegant/file.tmpl |
---|
0,0 → 1,55 |
[websvn-test:error] |
</div> |
[websvn-else] |
<h2 id="path_links">[websvn:path_links_root_config]/[websvn:path_links]</h2> |
<div id="revjump">[websvn:revision_form][websvn:revision_input]<span class="submit">[websvn:revision_submit]</span>[websvn:revision_endform]</div> |
<h2 id="revnum"><a href="[websvn:revurl]">[lang:REV] [websvn:rev]</a></h2> |
<div class="clearer"></div> |
</div> |
<ul id="links"> |
[websvn-test:prevrevurl] |
<li class="prev"><a href="[websvn:prevrevurl]">[lang:REV] [websvn:prevrev]</a></li> |
[websvn-endtest] |
[websvn-test:nextrevurl] |
<li class="next"><a href="[websvn:nextrevurl]">[lang:REV] [websvn:nextrev]</a></li> |
[websvn-endtest] |
[websvn-test:goyoungestlink] |
<li class="youngest">[websvn:goyoungestlink]</li> |
[websvn-endtest] |
[websvn-test:mimelink] |
<li class="mime">[websvn:mimelink]</li> |
[websvn-endtest] |
<li class="blame">[websvn:blamelink]</li> |
[websvn-test:difflink] |
<li class="diff">[websvn:difflink]</li> |
[websvn-endtest] |
<li class="rev">[websvn:revlink]</li> |
<li class="log">[websvn:loglink]</li> |
[websvn-test:downloadlink] |
<li class="download">[websvn:downloadlink]</li> |
[websvn-endtest] |
[websvn-test:clientrooturl] |
<li class="svn"><a href="[websvn:clientrooturl][websvn:path]">SVN</a></li> |
[websvn-endtest] |
[websvn-test:rsslink] |
<li class="rss">[websvn:rsslink]</li> |
[websvn-endtest] |
</ul> |
[websvn-endtest] |
</div> |
<div id="content"> |
[websvn-test:error] |
<div class="error"><span>[websvn:error]</span></div> |
[websvn-else] |
[websvn-test:warning] |
<div class="warning"><span>[websvn:warning]</span></div> |
[websvn-else] |
<div id="listing"> |
[websvn-getlisting] |
</div> |
[websvn-test:warning] |
<!-- check for warnings generated by getlisting --> |
<div class="warning"><span>[websvn:warning]</span></div> |
[websvn-endtest] |
[websvn-endtest] |
[websvn-endtest] |
/WebSVN/templates/Elegant/footer.tmpl |
---|
0,0 → 1,17 |
</div> <!-- content --> |
</div> <!-- wrapper --> |
<div id="footer"> |
<div id="valid"> |
<a href="http://validator.w3.org/check?uri=[websvn:validationurl]">XHTML</a> | |
<a href="http://jigsaw.w3.org/css-validator/validator?uri=[websvn:validationurl]">CSS</a> |
[websvn-test:rssurl] |
| <a href="http://feedvalidator.org/check.cgi?url=[websvn:validationurl]">RSS</a> |
[websvn-endtest] |
</div> |
<div id="poweredby">[lang:POWERED] [websvn:version] [lang:AND] <a href="http://subversion.apache.org">Apache Subversion</a> [websvn:svnversion]</div> |
</div> |
[websvn-test:repname] |
<script type="text/javascript" src="[websvn:locwebsvnhttp]/templates/Elegant/revision-popup.js"></script> |
[websvn-endtest] |
</body> |
</html> |
/WebSVN/templates/Elegant/header.tmpl |
---|
0,0 → 1,77 |
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> |
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="[websvn:language_code]" lang="[websvn:language_code]"> |
<head> |
<title> |
WebSVN |
[websvn-test:repname] |
– [websvn:repname] |
[websvn-endtest] |
[websvn-test:error] |
– ERROR |
[websvn-else] |
[websvn-test:rev2] |
[websvn-test:safepath2] |
– [websvn:safepath1] [lang:REV] [websvn:rev1] [lang:AND] [websvn:safepath2] [lang:REV] [websvn:rev2] |
[websvn-else] |
– [lang:REV] [websvn:rev1] [lang:AND] [websvn:rev2] |
[websvn-endtest] |
[websvn-else] |
[websvn-test:rev] |
– [lang:REV] [websvn:rev] |
[websvn-endtest] |
[websvn-endtest] |
[websvn-test:action] |
– [websvn:action] |
[websvn-endtest] |
[websvn-test:safepath] |
– [websvn:safepath] |
[websvn-endtest] |
[websvn-endtest] |
</title> |
<meta http-equiv="content-type" content="text/html;charset=UTF-8" /> |
<meta http-equiv="generator" content="WebSVN [websvn:version]" /> <!-- leave this for stats --> |
[websvn-test:blockrobots] |
<meta name="robots" content="noindex,nofollow" /> |
[websvn-endtest] |
<link rel="stylesheet" type="text/css" href="[websvn:locwebsvnhttp]/templates/Elegant/styles.css" /> |
<link rel="shortcut icon" type="image/x-icon" href="[websvn:locwebsvnhttp]/templates/Elegant/images/favicon.ico" /> |
[websvn-test:rssurl] |
<link rel="alternate" type="application/rss+xml" title="WebSVN RSS" href="[websvn:rssurl]" /> |
[websvn-endtest] |
<!--[if lt IE 7]> |
<script type="text/javascript" src="[websvn:locwebsvnhttp]/javascript/ie-png-transparency.js"></script> |
<![endif]--> |
</head> |
<body id="[websvn:template]"> |
<div id="wrapper"> |
[websvn-test:repname] |
<div id="rev-popup" style="display: none;"> |
[websvn-test:lastchangedrev] |
<div class="info">[lang:REV] [websvn:lastchangedrev] |
[websvn-else] |
<div class="info">[lang:REV] [websvn:rev] |
[websvn-endtest] |
– [websvn:author] |
[websvn-test:showageinsteadofdate] |
– [websvn:age] ([websvn:date]) |
[websvn-else] |
– [websvn:date] ([websvn:age]) |
[websvn-endtest] |
</div> |
<div class="msg">[websvn:log]</div> |
</div> |
[websvn-endtest] |
<div id="header"> |
<div id="info"> |
<h1><a href="[websvn:indexurl]" title="[lang:PROJECTS]">[lang:PROJECTS]</a> |
[websvn-test:repname] |
– <a href="[websvn:repurl]">[websvn:repname]</a> |
[websvn-endtest] |
</h1> |
<div id="menus"> |
[websvn-test:projects_form] |
[websvn:projects_form][websvn:projects_select][websvn:projects_submit][websvn:projects_endform] |
[websvn-endtest] |
[websvn:template_form][websvn:template_select][websvn:template_submit][websvn:template_endform] |
[websvn:language_form][websvn:language_select][websvn:language_submit][websvn:language_endform] |
</div> |
/WebSVN/templates/Elegant/images/README.txt |
---|
0,0 → 1,9 |
Icons have been selected (and sometimes adapted) from the following icon sets: |
Fugue - http://www.pinvoke.com |
Led - http://led24.de/iconset/ |
RSS Icons - http://www.icojoy.com/articles/23/ |
Splashyfish - http://splashyfish.com/icons/ |
Vaga - http://www.edmerritt.com |
Some of the icons have been drawn from or influenced by Mac OS X. |
/WebSVN/templates/Elegant/images/added.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/Elegant/images/arrow-in.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/Elegant/images/arrow-out.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/Elegant/images/bg-gray-dark.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/Elegant/images/bg-gray-light.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/Elegant/images/bg-page-header.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/Elegant/images/bg-table-divider.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/Elegant/images/bg-table-header.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/Elegant/images/blame.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/Elegant/images/blank.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/Elegant/images/cube-blue.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/Elegant/images/deleted.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/Elegant/images/detail.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/Elegant/images/diff.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/Elegant/images/directory.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/Elegant/images/download.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/Elegant/images/eye.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/Elegant/images/favicon.ico |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/Elegant/images/file-c.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/Elegant/images/file-cpp.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/Elegant/images/file-css.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/Elegant/images/file-h.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/Elegant/images/file-html.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/Elegant/images/file-image.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/Elegant/images/file-java.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/Elegant/images/file-m.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/Elegant/images/file-php.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/Elegant/images/file-py.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/Elegant/images/file-xml.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/Elegant/images/file.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/Elegant/images/home.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/Elegant/images/information.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/Elegant/images/log.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/Elegant/images/modified.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/Elegant/images/next.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/Elegant/images/parent.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/Elegant/images/pilcrow.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/Elegant/images/previous.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/Elegant/images/remove.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/Elegant/images/repository.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/Elegant/images/repository24.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/Elegant/images/reverse.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/Elegant/images/revision.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/Elegant/images/rss.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/Elegant/images/stop.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/Elegant/images/subversion-s.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/Elegant/images/valid.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/Elegant/images/warning.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/Elegant/images/youngest.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/Elegant/index.tmpl |
---|
0,0 → 1,85 |
</div> |
</div> |
<!-- |
NOTE: This template file is not compatible with WebSVN 2.2.x and earlier since |
the information passed from index.php uses drastically different organization. |
--> |
<div id="content"> |
[websvn-include:user_greeting.tmpl] |
[websvn-test:error] |
<div class="error"><span>[websvn:error]</span></div> |
[websvn-else] |
<table> |
[websvn-test:showlastmod] |
<thead><tr><th colspan="4">[lang:PROJECTS]</th></tr></thead> |
[websvn-else] |
<thead><tr><th>[lang:PROJECTS]</th></tr></thead> |
[websvn-endtest] |
[websvn-test:flatview] |
[websvn-startlisting] |
[websvn-test:groupid] |
[websvn-else] |
[websvn-test:rowparity] |
<tr class="shaded"> |
[websvn-else] |
<tr> |
[websvn-endtest] |
<td class="project"><a href="[websvn:projecturl]">[websvn:projectname]</a></td> |
[websvn-test:showlastmod] |
<td>[lang:REV] [websvn:revision]</td> |
[websvn-test:showageinsteadofdate] |
<td title="[websvn:date]">[websvn:age]</td> |
[websvn-else] |
<td title="[websvn:age]">[websvn:date]</td> |
[websvn-endtest] |
<td>[websvn:author]</td> |
[websvn-endtest] |
</tr> |
[websvn-endtest] |
[websvn-endlisting] |
[websvn-else] |
[websvn-startlisting] |
[websvn-test:groupid] |
<tr><th onclick="toggleGroup('[websvn:groupname]');" |
[websvn-test:showlastmod] |
colspan="4" |
[websvn-endtest] |
>[websvn:groupname]</th></tr> |
[websvn-else] |
[websvn-test:groupparity] |
<tr title="[websvn:groupname]" class="shaded"> |
[websvn-else] |
<tr title="[websvn:groupname]"> |
[websvn-endtest] |
[websvn-test:groupname] |
<td class="project group"><a href="[websvn:projecturl]">[websvn:projectname]</a></td> |
[websvn-else] |
<td class="project"><a href="[websvn:projecturl]">[websvn:projectname]</a></td> |
[websvn-endtest] |
[websvn-test:showlastmod] |
<td>[lang:REV] [websvn:revision]</td> |
[websvn-test:showageinsteadofdate] |
<td title="[websvn:date]">[websvn:age]</td> |
[websvn-else] |
<td title="[websvn:age]">[websvn:date]</td> |
[websvn-endtest] |
<td>[websvn:author]</td> |
[websvn-endtest] |
</tr> |
[websvn-endtest] |
[websvn-endlisting] |
[websvn-endtest] |
</table> |
[websvn-test:treeview] |
<script type="text/javascript" src="[websvn:locwebsvnhttp]/javascript/jquery.min.1.9.1.js"></script> |
<script type="text/javascript" src="[websvn:locwebsvnhttp]/javascript/collapsible.js"></script> |
[websvn-test:opentree] |
[websvn-else] |
<script type="text/javascript"> |
//<![CDATA[ |
collapseAllGroups(); |
//]]> |
</script> |
[websvn-endtest] |
[websvn-endtest] |
[websvn-endtest] |
/WebSVN/templates/Elegant/log.tmpl |
---|
0,0 → 1,125 |
[websvn-test:error] |
</div> |
[websvn-else] |
<h2 id="path_links">[websvn:path_links_root_config]/[websvn:path_links]</h2> |
<div id="revjump">[websvn:revision_form][websvn:revision_input]<span class="submit">[websvn:revision_submit]</span>[websvn:revision_endform]</div> |
<h2 id="revnum"><a href="[websvn:revurl]">[lang:REV] [websvn:rev]</a></h2> |
<div class="clearer"></div> |
</div> |
<ul id="links"> |
[websvn-test:goyoungestlink] |
<li class="youngest">[websvn:goyoungestlink]</li> |
[websvn-endtest] |
<li class="rev">[websvn:changeslink]</li> |
[websvn-test:filedetaillink] |
<li class="file">[websvn:filedetaillink]</li> |
<li class="blame">[websvn:blamelink]</li> |
<li class="diff">[websvn:difflink]</li> |
[websvn-else] |
<li class="dir">[websvn:directorylink]</li> |
[websvn-endtest] |
[websvn-test:clientrooturl] |
<li class="svn"><a href="[websvn:clientrooturl][websvn:path]">SVN</a></li> |
[websvn-endtest] |
[websvn-test:rsslink] |
<li class="rss">[websvn:rsslink]</li> |
[websvn-endtest] |
</ul> |
[websvn-endtest] |
</div> |
<div id="content"> |
[websvn-test:error] |
<div class="error"><span>[websvn:error]</span></div> |
[websvn-else] |
[websvn-test:warning] |
<div class="warning"><span>[websvn:warning]</span></div> |
[websvn-else] |
<div id="filter"> |
[websvn:logsearch_form] |
[lang:STARTLOG]:[websvn:logsearch_startbox] |
[lang:ENDLOG]:[websvn:logsearch_endbox] |
[lang:MAXLOG]:[websvn:logsearch_maxbox] |
[lang:SEARCHLOG]:[websvn:logsearch_inputbox] |
<!-- [lang:SHOWALL]:[websvn:logsearch_showall] --> |
[websvn:logsearch_submit] |
[websvn:logsearch_endform] |
</div> |
<div id="filternav"> |
<span id="pagelinks">[websvn:pagelinks]</span> |
[websvn-test:showalllink] |
<span id="showall">[websvn:showalllink]</span> |
[websvn-endtest] |
[websvn-test:logsearch_moreresultslink] |
<span id="moreresuls">[websvn:logsearch_moreresultslink]</span> |
[websvn-endtest] |
[websvn-test:logsearch_clearloglink] |
<span id="clearlog">[websvn:logsearch_clearloglink]</span> |
[websvn-endtest] |
</div> |
[websvn-test:logsearch_nomatches] |
[lang:NORESULTS] |
[websvn-endtest] |
[websvn-test:logsearch_nomorematches] |
<p>[lang:NOMORERESULTS]</p> |
[websvn-endtest] |
[websvn-test:logsearch_resultsfound] |
[websvn:compare_form] |
<table id="logs"> |
<thead> |
<tr> |
<th>[lang:REV]</th> |
[websvn-test:showageinsteadofdate] |
<th>[lang:AGE]</th> |
[websvn-else] |
<th>[lang:AGE]</th> |
<!-- <th>[lang:DATE]</th> Note: [lang:DATE] doesn't exist yet... --> |
[websvn-endtest] |
<th>[lang:AUTHOR]</th> |
<th>[lang:PATH]</th> |
<th>[lang:LOGMSG]</th> |
<th>[lang:DIFF]</th> |
[websvn-test:showchanges] |
<th>[lang:CHANGES]</th> |
[websvn-endtest] |
</tr> |
</thead> |
<tbody> |
[websvn-startlisting] |
[websvn-test:rowparity] |
<tr class="shaded"> |
[websvn-else] |
<tr> |
[websvn-endtest] |
<td class="rev">[websvn:compare_box][websvn:revlink]</td> |
[websvn-test:showageinsteadofdate] |
<td class="age" title="[websvn:revdate]">[websvn:revage]</td> |
[websvn-else] |
<td class="date" title="[websvn:revage]">[websvn:revdate]</td> |
[websvn-endtest] |
<td class="author">[websvn:revauthor]</td> |
<td class="path">[websvn:revpathlink]</td> |
<td class="logmsg">[websvn:revlog]</td> |
<td class="diff"><a href="[websvn:compareurl]" title="[lang:DIFFPREV]">[lang:DIFF]</a></td> |
[websvn-test:showchanges] |
<td class="changes"><table> |
[websvn-test:revadded] |
<tr><td class="add">[websvn:revadded]</td></tr> |
[websvn-endtest] |
[websvn-test:revdeleted] |
<tr><td class="del">[websvn:revdeleted]</td></tr> |
[websvn-endtest] |
[websvn-test:revmodified] |
<tr><td class="mod">[websvn:revmodified]</td></tr> |
[websvn-endtest] |
</table></td> |
[websvn-endtest] |
</tr> |
[websvn-endlisting] |
</tbody> |
</table> |
<div id="comparesubmit">[websvn:compare_submit]</div> |
[websvn:compare_endform] |
[websvn-endtest] |
[websvn-endtest] |
[websvn-endtest] |
/WebSVN/templates/Elegant/revision-popup.js |
---|
0,0 → 1,20 |
// This div is generated by header.tmpl; remove it to display only on mouseover |
var popup = document.getElementById('rev-popup'); |
document.getElementById('wrapper').removeChild(popup); |
popup.style.display = 'block'; |
// Add event listeners to display/hide the popup when hovering the revnum header |
var revnum = document.getElementById('revnum'); |
addEvent(revnum, 'mouseover', function() {this.parentNode.appendChild(popup)}); |
addEvent(revnum, 'mouseout', function() {this.parentNode.removeChild(popup)}); |
function addEvent(obj, type, func) { |
if (obj.addEventListener) { |
obj.addEventListener(type, func, false); |
return true; |
} else if (obj.attachEvent) { |
return obj.attachEvent('on'+type, func); |
} else { |
return false; |
} |
} |
/WebSVN/templates/Elegant/revision.tmpl |
---|
0,0 → 1,102 |
[websvn-test:error] |
</div> |
[websvn-else] |
<h2 id="path_links">[websvn:path_links_root_config]/[websvn:path_links]</h2> |
<div id="revjump">[websvn:revision_form][websvn:revision_input]<span class="submit">[websvn:revision_submit]</span>[websvn:revision_endform]</div> |
<h2 id="revnum">[lang:REV] [websvn:rev]</h2> |
<div class="clearer"></div> |
</div> |
<ul id="links"> |
[websvn-test:prevrevurl] |
<li class="prev"><a href="[websvn:prevrevurl]">[lang:REV] [websvn:prevrev]</a></li> |
[websvn-endtest] |
[websvn-test:nextrevurl] |
<li class="next"><a href="[websvn:nextrevurl]">[lang:REV] [websvn:nextrev]</a></li> |
[websvn-endtest] |
[websvn-test:goyoungestlink] |
<li class="youngest">[websvn:goyoungestlink]</li> |
[websvn-endtest] |
[websvn-test:comparelink] |
<li class="diff">[websvn:comparelink]</li> |
[websvn-endtest] |
<li class="dir">[websvn:directorylink]</li> |
[websvn-test:filedetaillink] |
<li class="file">[websvn:filedetaillink]</li> |
<li class="blame">[websvn:blamelink]</li> |
[websvn-endtest] |
<li class="log">[websvn:loglink]</li> |
[websvn-test:clientrooturl] |
<li class="svn"><a href="[websvn:clientrooturl][websvn:path]">SVN</a></li> |
[websvn-endtest] |
[websvn-test:rsslink] |
<li class="rss">[websvn:rsslink]</li> |
[websvn-endtest] |
</ul> |
[websvn-endtest] |
</div> |
<div id="content"> |
[websvn-test:error] |
<div class="error"><span>[websvn:error]</span></div> |
[websvn-else] |
[websvn-test:warning] |
<div class="warning"><span>[websvn:warning]</span></div> |
[websvn-else] |
<dl> |
<dt>[lang:LASTMOD]</dt><dd>[lang:REV] [websvn:rev] – [websvn:author] – |
[websvn-test:showageinsteadofdate] |
<span title="[websvn:date]">[websvn:age]</span></dd> |
[websvn-else] |
<span title="[websvn:age]">[websvn:date]</span></dd> |
[websvn-endtest] |
<dt>[lang:LOGMSG]</dt> |
<dd>[websvn:log]</dd> |
</dl> |
<table id="changes"> |
<thead> |
<tr align="left" valign="middle"> |
<th>[lang:PATH]</th> |
<th>[lang:BLAME]</th> |
<th>[lang:DIFF]</th> |
<th>[lang:LOG]</th> |
[websvn-test:clientrooturl] |
<th>SVN</th> |
[websvn-endtest] |
</tr> |
</thead> |
<tbody> |
[websvn-startlisting] |
[websvn-test:rowparity] |
<tr class="[websvn:action] shaded"> |
[websvn-else] |
<tr class="[websvn:action]"> |
[websvn-endtest] |
<td class="path"> |
[websvn-test:notinpath] |
<a href="[websvn:detailurl]" class="notinpath">[websvn:safepath]</a> |
[websvn-else] |
<a href="[websvn:detailurl]">[websvn:safepath]</a> |
[websvn-endtest] |
[websvn-test:oldsafepath] |
<br/><del>[websvn:oldsafepath] ([lang:PREV])</del> |
[websvn-endtest] |
</td> |
[websvn-test:blameurl] |
<td class="blame"><a href="[websvn:blameurl]" title="[lang:BLAME]">[lang:BLAME]</a></td> |
[websvn-else] |
<td></td> |
[websvn-endtest] |
[websvn-test:diffurl] |
<td class="diff"><a href="[websvn:diffurl]" title="[lang:DIFFPREV]">[lang:DIFF]</a></td> |
[websvn-else] |
<td></td> |
[websvn-endtest] |
<td class="log"><a href="[websvn:logurl]" title="[lang:LOG]">[lang:LOG]</a></td> |
[websvn-test:clientrooturl] |
<td class="svn"><a href="[websvn:clientrooturl][websvn:path]" title="SVN">SVN</a></td> |
[websvn-endtest] |
</tr> |
[websvn-endlisting] |
</tbody> |
</table> |
[websvn-endtest] |
[websvn-endtest] |
/WebSVN/templates/Elegant/styles.css |
---|
0,0 → 1,1001 |
/* @group Global Styles */ |
/* @group Common Elements */ |
html, body { |
margin: 0; |
padding: 0; |
height: 100%; |
} |
body { |
font-family: "Lucida Grande", "Lucida Sans Unicode", Helvetica, Arial, sans-serif; |
font-size: 8pt; |
background-color: white; |
} |
@media print { |
body { |
font-size: 7pt; |
} |
} |
h1 { |
font-size: 2em; |
margin-top: 0; |
padding-top: 8px; |
} |
h2 { |
font-size: 1.5em; |
margin: 5px 0; |
} |
dt { |
font-weight: bold; |
margin-top: 6px; |
} |
a { |
color: black; |
text-decoration: none; |
} |
a:hover { |
text-decoration: underline; |
} |
a img { |
border: none; |
} |
form { |
margin: 0; |
} |
/* @end */ |
/* @group Header */ |
#header { |
margin: 0; |
padding: 0; |
} |
#header #info { |
font-size: 85%; |
margin: 0; |
padding: 0 10px; |
background: url(images/bg-page-header.png) repeat-x 0 top; |
border-bottom: solid 1px #4b4b4b; |
} |
#header #info, #header #info * { |
position: relative; |
} |
#header #info, h1, h2 { |
font-weight: normal; |
} |
#header #info, #header #info a { |
color: white; |
} |
#header #info a { |
-webkit-border-radius: 4px; |
-moz-border-radius: 4px; |
} |
#header h1 { |
margin: 0; |
padding: 8px 0; |
} |
* html #header h1 { |
padding-bottom: 15px; |
} |
#header h1 a { |
padding: 0 2px; |
} |
#header #info a:hover, #header #info h2#path_links a:hover { |
background-color: rgba(63,63,63,0.35); |
} |
#header h2 { |
float: left; |
margin: 1px 1px 5px; |
} |
#header h2#revnum { |
float: right; |
background: url(images/information.png) no-repeat 0 1px; |
padding-left: 22px; |
} |
#header #menus { |
position: absolute; |
top: 0; |
right: 0; |
padding: 9px; |
} |
#header #menus form { |
display: inline; |
} |
#header #menus * { |
margin: 0; |
padding: 0; |
} |
@media print { |
#header #menus { |
display: none; |
} |
} |
#header #revjump { |
float: right; |
clear: none; |
margin: -3px -3px 0 15px; |
} |
#header #revjump span input { |
margin: 2px; |
padding: 0 8px; |
} |
* html #header #revjump { |
padding-right: 5px; |
} |
* html #header #revjump form { |
margin: 0; |
} |
#header #searchcss { |
float: center; |
clear: none; |
margin: -3px -3px 0 15px; |
} |
#header #searchcss span input { |
margin: 2px; |
padding: 0 8px; |
} |
* html #header #searchcss { |
padding-right: 5px; |
} |
* html #header #searchcss form { |
margin: 0; |
} |
#header div { |
clear: both; |
} |
#header h2#path_links > * { |
padding: 1px; |
} |
#header h2#path_links a.root { |
background: url(images/home.png) no-repeat 0 1px; |
padding-left: 16px; |
} |
#header h2#path_links a.root span { |
display: none; |
} |
#header h2#path_links a.peg { |
background: url(images/remove.png) no-repeat right 1px; |
padding-right: 20px; |
} |
/* @end */ |
/* @group Revision Pop-ups */ |
#revnum:hover { |
cursor: default; |
} |
#header #rev-popup, .blame-popup { |
font-size: 11px; |
color: black; |
background-color: rgba(255,255,255,0.9); |
padding: 4px; |
white-space: normal; |
-webkit-border-radius: 6px; |
-moz-border-radius: 6px; |
position: absolute; |
border: solid 1px #4b4b4b; |
max-width: 600px; |
} |
#rev-popup { |
top: 5.5em; |
right: 10px; |
margin-left: 10px; |
z-index: 1; |
} |
.blame-popup { |
text-align: left; |
margin-top: 4px; |
} |
#rev-popup .info, .blame-popup .date { |
font-weight: bold; |
} |
#rev-popup .msg, .blame-popup .msg { |
margin-top: 6px; |
} |
#header #info #rev-popup a { |
color: black; |
} |
#revision #rev-popup { |
display: none; |
} |
/* @end */ |
/* @group Navigation Links */ |
#links { |
padding: 0; |
margin: 0; |
text-align: center; |
background: url(images/bg-gray-light.png) repeat-x 0 top; |
border-bottom: solid 1px #a1a5a9; |
white-space: nowrap; |
} |
#links li { |
font-size: 110%; |
display: inline-block; |
padding: 0; |
margin: 0; |
white-space: nowrap; |
} |
* html #links li { |
display: inline; |
} |
#links li:hover { |
background: url(images/bg-gray-dark.png) repeat-x 0 top; |
} |
#links a:hover { |
text-decoration: none; |
} |
#links li a { |
padding: 4px 3px 4px 22px; |
display: block; |
background-position: 3px 4px; |
background-repeat: no-repeat; |
} |
#links li.entire a { |
background-image: url(images/arrow-out.png); |
} |
#links li.compact a { |
background-image: url(images/arrow-in.png); |
} |
#links li.regard a, #links li.ignore a { |
background-image: url(images/pilcrow.png); |
} |
#links li.blame a { |
background-image: url(images/blame.png); |
} |
#links li.file a { |
background-image: url(images/detail.png); |
} |
#links li.diff a { |
background-image: url(images/diff.png); |
} |
#links li.download a { |
background-image: url(images/download.png); |
} |
#links li.dir a { |
background-image: url(images/parent.png); |
} |
#links li.log a { |
background-image: url(images/log.png); |
} |
#links li.mime a { |
background-image: url(images/eye.png); |
} |
#links li.next a { |
background-image: url(images/next.png); |
} |
#links li.prev a { |
background-image: url(images/previous.png); |
} |
#links li.rev a { |
background-image: url(images/revision.png); |
} |
#links li.reverse a { |
background-image: url(images/reverse.png); |
} |
#links li.rss a { |
background-image: url(images/rss.png); |
} |
#links li.svn a { |
background-image: url(images/subversion-s.png); |
} |
#links li.youngest a { |
background-image: url(images/youngest.png); |
} |
@media print { |
#dropdowns, #links { |
display: none; |
} |
} |
/* @end */ |
#content { |
padding: 10px; |
border-top: 1px solid #cfcfcf; |
} |
#wrapper { |
margin: 0; |
} |
/* @group Notification Bubbles */ |
.error, .warning, .information { |
display: table; |
font-weight: bold; |
margin: 0 auto; |
padding: 5px 7px 3px 10px; |
border: solid 1px; |
vertical-align: middle; |
background-repeat: no-repeat; |
background-position: 6px 4px; |
-webkit-border-radius: 8px; |
-moz-border-radius: 8px; |
} |
.error span, .warning span, .information span { |
display: block; |
max-width: 400px; |
margin-left: 33px; |
padding: 10px 0; |
position: relative; |
top: -2px; |
} |
.error a, .warning a, .information a { |
text-decoration: underline; |
} |
.error a:hover, .warning a:hover, .information a:hover { |
text-decoration: none; |
} |
.error { |
border-color: red; |
background-color: #fcc; |
background-image: url(images/stop.png); |
} |
.warning { |
border-color: #d5ce00; |
background-color: #ffc; |
background-image: url(images/warning.png); |
} |
.information { |
border-color: #4467aa; |
background-color: #d5e0ee; |
background-image: url(images/information.png); |
} |
/* @end */ |
/* @group Table Elements */ |
table { |
border-collapse: collapse; |
margin: 0 auto; |
} |
table, th, td { |
border-style: solid; |
border-color: #ccc; |
border-width: 1px; |
} |
th, td { |
vertical-align: middle; |
white-space: nowrap; |
padding: 0 5px; |
} |
th { |
height: 16px; |
text-align: center; |
border-width: 1px; |
} |
td { |
border-top-width: 0; |
border-bottom-width: 0; |
overflow: hidden; |
} |
td a { |
padding: 1px 0; |
} |
td.path a { |
display: inline-block; |
width: 100%; |
} |
td input { |
position: relative; |
top: -2px; |
} |
thead * { |
color: white; |
} |
thead th { |
background-image: url(images/bg-table-header.png); |
border-color: #73a2be; |
} |
tbody th { |
background-image: url(images/bg-table-divider.png); |
} |
tbody tr.shaded, tbody tr.dark { |
background-color: #ecf3fe; |
} |
tbody tr:hover { |
background-color: #d6dde5; |
} |
@media print { |
tbody tr.shaded { |
border-width: 1px; |
} |
tbody tr:hover { |
background-color: white; |
} |
} |
/* @end */ |
/* @group Image-Only table links */ |
/* directory / revision */ |
td.blame a, td.download a, #log td.diff a, #revision td.diff a, td.log a, td.rss a, td.svn a { |
text-indent: -5000px; |
overflow: hidden; |
display: block; |
width: 100%; |
min-width: 16px; |
min-height: 16px; |
margin: 0 auto; |
padding: 0; |
background-position: center; |
background-repeat: no-repeat; |
} |
td.download a { |
background-image: url(images/download.png); |
} |
td.blame a { |
background-image: url(images/blame.png); |
} |
#log td.diff a, #revision td.diff a { |
background-image: url(images/diff.png); |
} |
td.log a { |
background-image: url(images/log.png); |
} |
td.rss a { |
background-image: url(images/rss.png); |
} |
td.svn a { |
background-image: url(images/subversion-s.png); |
} |
/* @end */ |
#comparesubmit { |
margin-top: 10px; |
text-align: center; |
} |
#comparesubmit input { |
margin: 0; |
} |
/* @group Footer */ |
#footer { |
text-align: center; |
clear: both; |
} |
#footer a { |
font-weight: bold; |
} |
#footer #poweredby { |
padding: 3px 3px 4px; |
border-top: solid 1px #a1a5a9; |
background: #f0f0f0 url(images/bg-gray-light.png) repeat-x 0 top; |
} |
#footer #valid { |
padding: 4px 5px 4px 16px; |
vertical-align: middle; |
position: absolute; |
border: 0; |
right: 0; |
background: url(images/valid.png) no-repeat 0 5px; |
} |
/* @group Sticky Footer */ |
html, body, #wrapper { |
height: 100%; |
} |
body > #wrapper { |
height: auto; |
min-height: 100%; |
} |
#content { |
padding-bottom: 3em; |
} |
#footer { |
clear: both; |
height: 2em; |
margin-top: -2em; |
} |
/* @end */ |
/* @end */ |
@media print { |
#header { |
border: solid 1px #4b4b4b; |
} |
#footer, #comparesubmit { |
display: none; |
} |
} |
/* @end */ |
/* @group blame.tmpl */ |
#blame td { |
vertical-align: top; |
text-align: right; |
} |
#blame td.author, #blame td.line { |
color: #777; |
} |
#blame td.author { |
text-align: center; |
} |
#blame td.code { |
text-align: left; |
white-space: pre-wrap; |
} |
#blame td.code, #blame td.line { |
font-family: Consolas, Menlo, Monaco, monospace; |
} |
/* @end */ |
/* @group compare.tmpl */ |
#compare #header h2 { |
float: none; |
text-align: center; |
} |
#compare #header h2 span { |
white-space: pre; |
} |
#compare_form table { |
border: none; |
} |
#compare_form table td { |
border: none; |
text-align: right; |
} |
#compare_form table tr:hover { |
background: none; |
} |
#comparisons { |
margin: 0 auto; |
display: table; |
} |
#comparisons h3 { |
text-align: center; |
margin-bottom: 0; |
} |
#comparisons table { |
margin: 10px 0 15px; |
width: 100%; |
} |
#comparisons td { |
padding: 1px 3px; |
white-space: pre-wrap; |
font-family: Consolas, Menlo, Monaco, monospace; |
} |
#comparisons th.info, #comparisons tr:hover th.info { |
background-image: none; |
background-color: #cde; |
} |
/* @end */ |
/* @group diff.tmpl */ |
#diff td { |
white-space: normal; |
vertical-align: top; |
font-family: Consolas, Menlo, Monaco, monospace; |
} |
#diff td.line { |
text-align: right; |
padding: 0 2px; |
color: #777; |
} |
ins, del { |
text-decoration: none; |
} |
td.diffadded, ins { |
background-color: #bfb; |
} |
td.diffchanged { |
background-color: #ffc; |
} |
td.diffdeleted, del { |
background-color: #f88; |
} |
@media screen { |
tr:hover td.diffadded, tr:hover ins { |
background-color: #5f5; |
} |
tr:hover td.diffchanged { |
background-color: #ff5; |
} |
tr:hover td.diffdeleted, tr:hover del { |
background-color: #f55; |
} |
} |
/* @end */ |
/* @group directory.tmpl */ |
#listing td { |
text-align: center; |
color: #777; |
} |
#listing td.rev, #listing td.date, #listing td.author { |
text-align: right; |
border-width: 0; |
} |
@media print { |
#listing td.rev, #listing td.date, #listing td.author { |
border-width: 1px 0; |
} |
} |
#listing td.path { |
text-align: left; |
padding-bottom: 4px; |
} |
#listing td img { |
position: relative; |
top: 3px; |
} |
#listing td.rev a { |
padding-right: 18px; |
background: url(images/revision.png) no-repeat right; |
} |
#listing td input { |
position: relative; |
top: -1px; |
margin: 0; |
margin-right: 3px; |
} |
#compare-submit { |
text-align: center; |
margin-top: 10px; |
} |
/* @end */ |
/* @group file.tmpl */ |
#file #listing { |
font-family: Consolas, Menlo, Monaco, monospace; |
} |
#file #listing pre { |
white-space: pre-wrap; |
} |
/* @end */ |
/* @group index.tmpl */ |
#index #menus #projectform { |
display: none; |
} |
#index .information { |
margin: 10px auto 20px; |
} |
#index table { |
margin: 10px auto; |
} |
#index tr.shaded { |
background-color: #ecf3fe; |
} |
#index tr.shaded:hover { |
background-color: #d6dde5; |
} |
#index td a { |
padding: 5px 6px 6px; |
} |
#index tbody th { |
border-bottom-color: #bbb; |
background-image: url(images/bg-gray-light.png); |
text-align: left; |
} |
#index tbody th:hover { |
background-image: url(images/bg-gray-dark.png); |
text-decoration: underline; |
} |
#index td { |
border-width: 0; |
color: #777; |
text-align: right; |
} |
#index td.project { |
text-align: left; |
} |
#index td a { |
background: url(images/cube-blue.png) no-repeat 0 4px; |
display: block; |
padding-left: 20px; |
width: 100%; |
} |
#index tbody th, #index td.group { |
padding-left: 25px; |
} |
/* @end */ |
/* @group log.tmpl */ |
#filter, #filternav { |
text-align: center; |
margin-bottom: 8px; |
} |
table#logs { |
clear: both; |
} |
#logs td { |
vertical-align: text-top; |
padding-top: 2px; |
padding-bottom: 2px; |
} |
#logs td.rev a { |
margin-left: 3px; |
padding-left: 18px; |
background: url(images/revision.png) no-repeat; |
} |
#logs td.author, #logs td.age, #logs td.date { |
text-align: center; |
color: #777; |
} |
#logs td.logmsg { |
white-space: normal; |
} |
#logs td.changes { |
color: #777; |
padding: 0; |
} |
#logs td.changes table { |
border-width: 0; |
width: 100%; |
margin-bottom: 2px; |
} |
#logs td.changes td { |
border-width: 0; |
padding-left: 20px; |
background: url(images/added.png) no-repeat 3px 3px; |
} |
#logs td.changes td.add { |
background-image: url(images/added.png); |
} |
#logs td.changes td.del { |
background-image: url(images/deleted.png); |
} |
#logs td.changes td.mod { |
background-image: url(images/modified.png); |
} |
#filternav { |
font-weight: bold; |
} |
#filternav > * { |
margin: 0 10px; |
} |
#filternav #pagelinks > * { |
padding: 0 2px; |
} |
#filternav #pagelinks span { |
color: #999; |
} |
#filternav #pagelinks span#curpage { |
background-color: #999; |
color: white; |
padding-bottom: 1px; |
padding-left: 3px; |
-webkit-border-radius: 3px; |
-moz-border-radius: 3px; |
} |
@media print { |
#filter, #filternav, #logs td.rev input { |
display: none; |
} |
} |
/* @end */ |
/* @group revision.tmpl */ |
#revision dl, #revision dl dt:first-child { |
margin-top: 0; |
} |
#revision dl dt { |
font-size: 120%; |
} |
#revision #changes td { |
text-align: center; |
padding-top: 3px; |
padding-bottom: 4px; |
} |
#revision #changes td.path { |
text-align: left; |
white-space: normal; |
} |
#revision #changes td.path a { |
background-repeat: no-repeat; |
background-position: 0 1px; |
padding: 1px 0; |
padding-left: 18px; |
overflow: visible; |
} |
#revision #changes td.path a.notinpath { |
color: #b70000; |
} |
#revision #changes tr.A td.path a { |
background-image: url(images/added.png); |
} |
#revision #changes tr.D td.path a { |
background-image: url(images/deleted.png); |
} |
#revision #changes tr.M td.path a { |
background-image: url(images/modified.png); |
} |
#revision del { |
background: none; |
color: gray; |
padding-left: 18px; |
} |
/* @end */ |
/WebSVN/templates/Elegant/user_greeting.tmpl |
---|
0,0 → 1,6 |
<div class="information"> |
<span> |
You can customize this message in 'templates/Elegant/user_greeting.tmpl' to tell your |
visitors what they'll find in your repositories. |
</span> |
</div> |
/WebSVN/templates/calm/README.txt |
---|
0,0 → 1,61 |
______________________________________________________________________________ |
| | |
| "CALM" THEME FOR WEBSVN | |
| | |
| (Theme : http://calm-theme-for-websvn.devjavu.com) | |
|______________________________________________________________________________| |
______________________________________________________________________________ |
| | |
| Copyright 2007 Erik Poehler (email : iroybot@gmail.com) | |
| (blog : http://contactsheet.de) | |
| | |
| This program is free software; you can redistribute it and/or modify | |
| it under the terms of the GNU General Public License as published by | |
| the Free Software Foundation; either version 2 of the License, or | |
| (at your option) any later version. | |
| | |
| This program is distributed in the hope that it will be useful, | |
| but WITHOUT ANY WARRANTY; without even the implied warranty of | |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
| GNU General Public License for more details. | |
| | |
| You should have received a copy of the GNU General Public License | |
| along with this program; if not, write to the Free Software | |
| Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
|______________________________________________________________________________| |
______________________________________________________________________________ |
| | |
| INSTALLATION | |
|______________________________________________________________________________| |
1) Place the complete directory "calm" in your "templates" directory/ |
2) Open include/config.php and look for a line similar to the following: |
$config->setTemplatePath("$locwebsvnreal/templates/Standard/"); |
and change it into: |
$config->setTemplatePath("$locwebsvnreal/templates/calm/"); |
3) Enjoy. |
If you like the template, please feel free to donate |
some cents via paypal to erikpoehler@gmx.de. |
In case you found errors, bugs or have improvement suggestions, |
send me a email or visit: |
http://calm-theme-for-websvn.devjavu.com |
Please keep the backlink in the footer intact. Thanks. |
______________________________________________________________________________ |
| | |
| CREDITS | |
|______________________________________________________________________________| |
1. Icons picked from: "Sweetie", "Silk" and "Tango" Iconsets. Much Thanks to the creators. |
2. Dean Edwards for making his "star-light" Syntax Highlighting available. |
3. You for developing (hopefully good) software. |
/WebSVN/templates/calm/blame.tmpl |
---|
0,0 → 1,56 |
[websvn-test:error] |
<div id="error">[websvn:error]</div> |
[websvn-else] |
<h2 id="path_links">[websvn:path_links_root_config]/[websvn:path_links] – [lang:REV] [websvn:rev]</h2> |
<div id="revjump">[websvn:revision_form][lang:REV] [websvn:revision_input]<span class="submit">[websvn:revision_submit]</span>[websvn:revision_endform]</div> |
<p> |
[websvn-test:prevrevurl] |
<span class="prev"><a href="[websvn:prevrevurl]">[lang:REV] [websvn:prevrev]</a></span> | |
[websvn-endtest] |
[websvn-test:nextrevurl] |
<span class="next"><a href="[websvn:nextrevurl]">[lang:REV] [websvn:nextrev]</a></span> | |
[websvn-endtest] |
[websvn-test:goyoungestlink] |
<span class="goyoungest">[websvn:goyoungestlink]</span> | |
[websvn-endtest] |
<span class="detail">[websvn:filedetaillink]</span> | |
[websvn-test:difflink] |
<span class="diff">[websvn:difflink]</span> | |
[websvn-endtest] |
<span class="changes">[websvn:revlink]</span> | |
<span class="log">[websvn:loglink]</span> |
[websvn-test:clientrooturl] |
| <span class="svn"><a href="[websvn:clientrooturl][websvn:path]">SVN</a></span> |
[websvn-endtest] |
[websvn-test:rsslink] |
| <span class="feed">[websvn:rsslink]</span> |
[websvn-endtest] |
</p> |
[websvn-test:warning] |
<div id="warning">[websvn:warning]</div> |
[websvn-else] |
<div style="margin:0 2%"> |
<table> |
<thead> |
<tr> |
<th scope="col" class="colrev">[lang:REV]</th> |
<th scope="col" class="colauth">[lang:AUTHOR]</th> |
<th scope="col" class="collno">[lang:LINENO]</th> |
<th scope="col" class="colcode">[lang:LINE]</th> |
</tr> |
</thead> |
<tbody> |
[websvn-startlisting] |
<tr valign="middle"> |
<td>[websvn:revision]</td> |
<td>[websvn:author]</td> |
<td><a name="l[websvn:lineno]" href="#l[websvn:lineno]">[websvn:lineno]</a></td> |
<td class="code"><pre>[websvn:line]</pre></td> |
</tr> |
[websvn-endlisting] |
</tbody> |
</table> |
[websvn:javascript] |
</div> |
[websvn-endtest] |
[websvn-endtest] |
/WebSVN/templates/calm/compare.tmpl |
---|
0,0 → 1,75 |
[websvn-test:error] |
<div id="error">[websvn:error]</div> |
[websvn-else] |
<div id="info"> |
<h2>[lang:COMPAREREVS]</h2> |
<ul><li><dl> |
<dt>[lang:CONVFROM]</dt> |
<dd><span style="visibility: hidden">→</span> <a href="[websvn:rev1url]">[websvn:safepath1] @ [websvn:rev1]</a></dd> |
<dd>→ <a href="[websvn:rev2url]">[websvn:safepath2] @ [websvn:rev2]</a></dd> |
<dd>↔ [websvn:reverselink]</dd> |
</dl></li> |
<li> |
[websvn:compare_form] |
<table> |
<tbody> |
<tr><th scope="col"><label>[lang:COMPPATH]</label></th><th scope="col"><label>Rev</label></th></tr> |
<tr><td>[websvn:compare_path1input]</td><td class="revcomp">[websvn:compare_rev1input]</td></tr> |
</tbody> |
</table> |
<table> |
<tbody> |
<tr><th scope="col"><label>[lang:WITHPATH]</label></th><th scope="col"><label>Rev</label></th></tr> |
<tr><td>[websvn:compare_path2input]</td><td class="revcomp">[websvn:compare_rev2input]</td></tr> |
</tbody> |
</table> |
<p class="submit">[websvn:compare_submit]</p> |
[websvn:compare_endform] |
</li></ul> |
</div> |
[websvn-test:warning] |
<div id="warning">[websvn:warning]</div> |
[websvn-endtest] |
<div id="wrap"> |
<h2 class="regular"> |
<span class="links"> |
[websvn-test:ignorewhitespacelink] |
<span class="ignorews">[websvn:ignorewhitespacelink]</span> |
[websvn-endtest] |
[websvn-test:regardwhitespacelink] |
<span class="regardws">[websvn:regardwhitespacelink]</span> |
[websvn-endtest] |
</span> |
[lang:REV] [websvn:rev1] → [lang:REV] [websvn:rev2] |
</h2> |
[websvn-startlisting] |
[websvn-test:newpath] |
<table class="diff collapsible"> |
<thead> |
<tr><th class="open"><a href="[websvn:fileurl]">[websvn:newpath]</a></th></tr> |
</thead> |
<tbody> |
[websvn-endtest] |
[websvn-test:info] |
<tr><th class="info">[websvn:info]</th></tr> |
[websvn-endtest] |
[websvn-test:difflines] |
<tr><th>[websvn:rev1line],[websvn:rev1len] → [websvn:rev2line],[websvn:rev2len]</th></tr> |
[websvn-endtest] |
[websvn-test:diffclass] |
<tr><td class="[websvn:diffclass]">[websvn:line]</td></tr> |
[websvn-endtest] |
[websvn-test:properties] |
<tr><th>[lang:PROPCHANGES]</th></tr> |
[websvn-endtest] |
[websvn-test:endpath] |
</tbody> |
</table> |
[websvn-endtest] |
[websvn-endlisting] |
</div> |
<script type="text/javascript" src="[websvn:locwebsvnhttp]/javascript/jquery.min.1.9.1.js"></script> |
<script type="text/javascript" src="[websvn:locwebsvnhttp]/javascript/collapsible.js"></script> |
[websvn-endtest] |
/WebSVN/templates/calm/diff.tmpl |
---|
0,0 → 1,75 |
[websvn-test:error] |
<div id="error">[websvn:error]</div> |
[websvn-else] |
<h2 id="path_links">[websvn:path_links_root_config]/[websvn:path_links] – [lang:REV] [websvn:rev2] → [websvn:rev1]</h2> |
<div id="revjump">[websvn:revision_form][lang:REV] [websvn:revision_input]<span class="submit">[websvn:revision_submit]</span>[websvn:revision_endform]</div> |
<p> |
[websvn-test:prevrevurl] |
<span class="prev"><a href="[websvn:prevrevurl]">[lang:REV] [websvn:prevrev]</a></span> | |
[websvn-endtest] |
[websvn-test:nextrevurl] |
<span class="next"><a href="[websvn:nextrevurl]">[lang:REV] [websvn:nextrev]</a></span> | |
[websvn-endtest] |
[websvn-test:goyoungestlink] |
<span class="goyoungest">[websvn:goyoungestlink]</span> | |
[websvn-endtest] |
[websvn-test:showalllink] |
<span class="full">[websvn:showalllink]</span> | |
[websvn-endtest] |
[websvn-test:showcompactlink] |
<span class="compact">[websvn:showcompactlink]</span> | |
[websvn-endtest] |
[websvn-test:ignorewhitespacelink] |
<span class="ignorews">[websvn:ignorewhitespacelink]</span> | |
[websvn-endtest] |
[websvn-test:regardwhitespacelink] |
<span class="regardws">[websvn:regardwhitespacelink]</span> | |
[websvn-endtest] |
<span class="detail">[websvn:filedetaillink]</span> | |
<span class="blame">[websvn:blamelink]</span> | |
<span class="changes">[websvn:revlink]</span> | |
<span class="log">[websvn:loglink]</span> |
[websvn-test:clientrooturl] |
| <span class="svn"><a href="[websvn:clientrooturl][websvn:path]">SVN</a></span> |
[websvn-endtest] |
[websvn-test:rsslink] |
| <span class="feed">[websvn:rsslink]</span> |
[websvn-endtest] |
</p> |
[websvn-test:warning] |
<div id="warning">[websvn:warning]</div> |
[websvn-else] |
<div style="margin:0 2%"> |
[websvn-test:noprev] |
<p>[lang:NOPREVREV]</p> |
[websvn-else] |
<table> |
<thead> |
<tr> |
<th colspan="2"><a href="[websvn:prevrevurl]">[lang:REV] [websvn:rev2]</a></th> |
<th colspan="2"><a href="[websvn:revurl]">[lang:REV] [websvn:rev1]</a></th> |
</tr> |
</thead> |
<tbody> |
[websvn-startlisting] |
[websvn-test:startblock] |
<tr> |
<th colspan="2">[lang:LINE] [websvn:rev1lineno]...</th> |
<th colspan="2">[lang:LINE] [websvn:rev2lineno]...</th> |
</tr> |
[websvn-endtest] |
<tr> |
<td class="lineno">[websvn:rev1lineno]</td> |
<td class="[websvn:rev1diffclass]"><pre>[websvn:rev1line]</pre></td> |
<td class="lineno">[websvn:rev2lineno]</td> |
<td class="[websvn:rev2diffclass]"><pre>[websvn:rev2line]</pre></td> |
</tr> |
[websvn-endlisting] |
</tbody> |
</table> |
[websvn-endtest] |
[websvn-endtest] |
</div> |
[websvn-endtest] |
[websvn-endtest] |
/WebSVN/templates/calm/directory.tmpl |
---|
0,0 → 1,152 |
[websvn-test:error] |
<div id="error">[websvn:error]</div> |
[websvn-else] |
<h2 id="path_links">[websvn:path_links_root_config]/[websvn:path_links] – [lang:REV] [websvn:rev]</h2> |
<div id="revjump">[websvn:revision_form]<div>[lang:REV] [websvn:revision_input]<span class="submit">[websvn:revision_submit]</span></div>[websvn:revision_endform]</div> |
[websvn-test:search] |
<div id="searchcss">[websvn:search_form]<div>[lang:SEARCH] [websvn:search_input]<span class="submit">[websvn:search_submit]</span></div>[websvn:search_endform]</div> |
[websvn-endtest] |
<p> |
[websvn-test:prevrevurl] |
<span class="prev"><a href="[websvn:prevrevurl]">[lang:REV] [websvn:prevrev]</a></span> | |
[websvn-endtest] |
[websvn-test:nextrevurl] |
<span class="next"><a href="[websvn:nextrevurl]">[lang:REV] [websvn:nextrev]</a></span> | |
[websvn-endtest] |
[websvn-test:goyoungestlink] |
<span class="goyoungest">[websvn:goyoungestlink]</span> | |
[websvn-endtest] |
<span class="changes">[websvn:revlink]</span> | |
[websvn-test:comparelink] |
<span class="diff">[websvn:comparelink]</span> | |
[websvn-endtest] |
<span class="log">[websvn:loglink]</span> |
[websvn-test:downloadurl] |
| <span class="compress"><a href="[websvn:downloadurl]" rel="nofollow">[lang:DOWNLOAD]</a></span> |
[websvn-endtest] |
[websvn-test:clientrooturl] |
| <span class="svn"><a href="[websvn:clientrooturl][websvn:path]">SVN</a></span> |
[websvn-endtest] |
[websvn-test:rsslink] |
| <span class="feed">[websvn:rsslink]</span> |
[websvn-endtest] |
</p> |
[websvn-test:warning] |
<div id="warning">[websvn:warning]</div> |
[websvn-else] |
<div id="info"> |
<h2>[lang:LASTMOD]</h2> |
<ul> |
<li>[lang:REV] [websvn:lastchangedrev] [websvn:date]</li> |
<li><strong>[lang:AUTHOR]:</strong> [websvn:author]</li> |
<li><dl><dt><strong>[lang:LOGMSG]:</strong></dt><dd>[websvn:log]</dd></dl></li> |
</ul> |
</div> |
[websvn-defineicons] |
dir=<img src="[websvn:locwebsvnhttp]/templates/calm/images/directory.png" alt="[DIRECTORY]" class="icon" /> |
diropen=<img src="[websvn:locwebsvnhttp]/templates/calm/images/directory.png" alt="[DIRECTORY]" class="icon" /> |
*=<img src="[websvn:locwebsvnhttp]/templates/calm/images/file.png" alt="[FILE]" class="icon" /> |
.c=<img src="[websvn:locwebsvnhttp]/templates/calm/images/filec.png" alt="[C-FILE]" class="icon" /> |
.h=<img src="[websvn:locwebsvnhttp]/templates/calm/images/fileh.png" alt="[H-FILE]" class="icon" /> |
.db=<img src="[websvn:locwebsvnhttp]/templates/calm/images/filedb.png" alt="[DB-FILE]" class="icon" /> |
.png=<img src="[websvn:locwebsvnhttp]/templates/calm/images/filepaint.png" alt="[DB-FILE]" class="icon" /> |
.gif=<img src="[websvn:locwebsvnhttp]/templates/calm/images/filepaint.png" alt="[DB-FILE]" class="icon" /> |
.bmp=<img src="[websvn:locwebsvnhttp]/templates/calm/images/filepaint.png" alt="[DB-FILE]" class="icon" /> |
.jpg=<img src="[websvn:locwebsvnhttp]/templates/calm/images/filepaint.png" alt="[DB-FILE]" class="icon" /> |
.jpeg=<img src="[websvn:locwebsvnhttp]/templates/calm/images/filepaint.png" alt="[DB-FILE]" class="icon" /> |
.js=<img src="[websvn:locwebsvnhttp]/templates/calm/images/script.png" alt="[DB-FILE]" class="icon" /> |
.css=<img src="[websvn:locwebsvnhttp]/templates/calm/images/css.png" alt="[DB-FILE]" class="icon" /> |
.htm=<img src="[websvn:locwebsvnhttp]/templates/calm/images/html.png" alt="[DB-FILE]" class="icon" /> |
.html=<img src="[websvn:locwebsvnhttp]/templates/calm/images/html.png" alt="[DB-FILE]" class="icon" /> |
.php=<img src="[websvn:locwebsvnhttp]/templates/calm/images/filephp.png" alt="[DB-FILE]" class="icon" /> |
.txt=<img src="[websvn:locwebsvnhttp]/templates/calm/images/filetxt.png" alt="[DB-FILE]" class="icon" /> |
.xml=<img src="[websvn:locwebsvnhttp]/templates/calm/images/filexml.png" alt="[DB-FILE]" class="icon" /> |
i-node=<img src="[websvn:locwebsvnhttp]/templates/calm/images/i-node.png" alt="[NODE]" class="icon" /> |
t-node=<img src="[websvn:locwebsvnhttp]/templates/calm/images/t-node.png" alt="[NODE]" class="icon" /> |
l-node=<img src="[websvn:locwebsvnhttp]/templates/calm/images/l-node.png" alt="[NODE]" class="icon" /> |
e-node=<img src="[websvn:locwebsvnhttp]/templates/calm/images/e-node.png" alt="[NODE]" class="icon" /> |
[websvn-enddefineicons] |
<div id="wrap"> |
[websvn:compare_form] |
<div class="table-responsive"> |
<table id="listing"> |
<thead> |
<tr align="left" valign="middle"> |
<th scope="col" class="path">[lang:PATH]</th> |
[websvn-test:showlastmod] |
<th scope="col" colspan="3">[lang:LASTMOD]</th> |
[websvn-endtest] |
<th scope="col">[lang:LOG]</th> |
[websvn-test:allowdownload] |
<th scope="col">[lang:DOWNLOAD]</th> |
[websvn-endtest] |
[websvn-test:clientrooturl] |
<th scope="col">SVN</th> |
[websvn-endtest] |
[websvn-test:rssurl] |
<th scope="col">RSS</th> |
[websvn-endtest] |
</tr> |
</thead> |
<tbody> |
[websvn-startlisting] |
<tr class="row[websvn:rowparity]" valign="middle" |
[websvn-test:loadalldir] |
title="[websvn:classname]" |
[websvn-endtest] |
> |
<td class="path" valign="middle"> |
[websvn:compare_box] |
[websvn-treenode] |
<a href="[websvn:fileurl]"> |
[websvn-icon] |
[websvn:filename] |
</a> |
</td> |
[websvn-test:showlastmod] |
<td class="rev"><a href="[websvn:revurl]">[websvn:revision]</a> </td> |
[websvn-test:showageinsteadofdate] |
<td class="age" title="[websvn:date]">[websvn:age]</td> |
[websvn-else] |
<td class="date" title="[websvn:age]">[websvn:date]</td> |
[websvn-endtest] |
<td class="author">[websvn:author]</td> |
[websvn-endtest] |
<td class="log"><a href="[websvn:logurl]">[lang:LOG]</a></td> |
[websvn-test:allowdownload] |
<td class="compress"> |
[websvn-test:downloadurl] |
<a href="[websvn:downloadurl]" rel="nofollow">[lang:DOWNLOAD]</a> |
[websvn-endtest] |
[websvn-test:downloadplainurl] |
<a href="[websvn:downloadplainurl]" rel="nofollow">[lang:DOWNLOAD]</a> |
[websvn-endtest] |
</td> |
[websvn-endtest] |
[websvn-test:clientrooturl] |
<td class="svn"><a href="[websvn:clientrooturl][websvn:path]">SVN</a></td> |
[websvn-endtest] |
[websvn-test:rssurl] |
<td class="feed"><a href="[websvn:rssurl]">RSS</a></td> |
[websvn-endtest] |
</tr> |
[websvn-endlisting] |
</tbody> |
</table> |
</div> |
<p class="submit"> |
[websvn:compare_submit] |
</p> |
[websvn:compare_endform] |
</div> |
[websvn-endtest] |
[websvn-test:loadalldir] |
<script type="text/javascript" src="[websvn:locwebsvnhttp]/javascript/jquery.min.1.9.1.js"></script> |
<script type="text/javascript" src="[websvn:locwebsvnhttp]/javascript/collapsible.js"></script> |
[websvn-endtest] |
[websvn-endtest] |
/WebSVN/templates/calm/file.tmpl |
---|
0,0 → 1,46 |
[websvn-test:error] |
<div id="error">[websvn:error]</div> |
[websvn-else] |
<h2 id="path_links">[websvn:path_links_root_config]/[websvn:path_links] – [lang:REV] [websvn:rev]</h2> |
<div id="revjump">[websvn:revision_form][lang:REV] [websvn:revision_input]<span class="submit">[websvn:revision_submit]</span>[websvn:revision_endform]</div> |
<p> |
[websvn-test:prevrevurl] |
<span class="prev"><a href="[websvn:prevrevurl]">[lang:REV] [websvn:prevrev]</a></span> | |
[websvn-endtest] |
[websvn-test:nextrevurl] |
<span class="next"><a href="[websvn:nextrevurl]">[lang:REV] [websvn:nextrev]</a></span> | |
[websvn-endtest] |
[websvn-test:goyoungestlink] |
<span class="goyoungest">[websvn:goyoungestlink]</span> | |
[websvn-endtest] |
[websvn-test:mimelink] |
<span class="mime">[websvn:mimelink]</span> | |
[websvn-endtest] |
<span class="blame">[websvn:blamelink]</span> | |
[websvn-test:difflink] |
<span class="diff">[websvn:difflink]</span> | |
[websvn-endtest] |
<span class="changes">[websvn:revlink]</span> | |
<span class="log">[websvn:loglink]</span> |
[websvn-test:downloadlink] |
| <span class="compress">[websvn:downloadlink]</span> |
[websvn-endtest] |
[websvn-test:clientrooturl] |
| <span class="svn"><a href="[websvn:clientrooturl][websvn:path]">SVN</a></span> |
[websvn-endtest] |
[websvn-test:rsslink] |
| <span class="feed">[websvn:rsslink]</span> |
[websvn-endtest] |
</p> |
[websvn-test:warning] |
<div id="warning">[websvn:warning]</div> |
[websvn-else] |
<div class="listing"> |
[websvn-getlisting] |
</div> |
[websvn-test:warning] |
<!-- check for warnings generated by getlisting --> |
<div id="warning">[websvn:warning]</div> |
[websvn-endtest] |
[websvn-endtest] |
[websvn-endtest] |
/WebSVN/templates/calm/footer.tmpl |
---|
0,0 → 1,6 |
</div> |
<div id="footer"> |
<p style="padding:0; margin:0"><small>[lang:POWERED] [websvn:version] [lang:AND] <a href="http://subversion.apache.org">Apache Subversion</a> [websvn:svnversion] ✓ <a href="http://validator.w3.org/check?uri=[websvn:validationurl]">XHTML</a> & <a href="http://jigsaw.w3.org/css-validator/validator?uri=[websvn:validationurl]">CSS</a></small></p> |
</div> |
</body> |
</html> |
/WebSVN/templates/calm/header.tmpl |
---|
0,0 → 1,63 |
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> |
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="[websvn:language_code]" lang="[websvn:language_code]"> |
<head> |
<meta http-equiv="content-type" content="text/html;charset=UTF-8" /> |
<meta http-equiv="generator" content="WebSVN [websvn:version]" /> <!-- leave this for stats --> |
<meta name="viewport" content="width=device-width, initial-scale=1"> |
[websvn-test:blockrobots] |
<meta name="robots" content="noindex,nofollow" /> |
[websvn-endtest] |
<link rel="shortcut icon" type="image/x-icon" href="[websvn:locwebsvnhttp]/templates/calm/images/favicon.ico" /> |
<link type="text/css" href="[websvn:locwebsvnhttp]/templates/calm/styles.css" rel="stylesheet" media="screen" /> |
[websvn-test:rssurl] |
<link rel='alternate' type='application/rss+xml' title='WebSVN RSS' href='[websvn:rssurl]' /> |
[websvn-endtest] |
<!--[if gte IE 5.5000]> |
<script type="text/javascript" src="[websvn:locwebsvnhttp]/javascript/ie-png-transparency.js"></script> |
<style type="text/css" media="screen"> |
tbody tr td { padding:1px 0 } |
#wrap h2 { padding:10px 5px 0 5px; margin-bottom:-8px } |
</style> |
<![endif]--> |
<title> |
WebSVN |
[websvn-test:repname] |
– [websvn:repname] |
[websvn-endtest] |
[websvn-test:error] |
– ERROR |
[websvn-else] |
[websvn-test:action] |
– [websvn:action] |
[websvn-endtest] |
[websvn-test:safepath] |
– [websvn:safepath] |
[websvn-endtest] |
[websvn-test:rev2] |
[websvn-test:safepath2] |
– [websvn:safepath1] [lang:REV] [websvn:rev1] [lang:AND] [websvn:safepath2] [lang:REV] [websvn:rev2] |
[websvn-else] |
– [lang:REV] [websvn:rev2] [lang:AND] [websvn:rev1] |
[websvn-endtest] |
[websvn-else] |
[websvn-test:rev] |
– [lang:REV] [websvn:rev] |
[websvn-endtest] |
[websvn-endtest] |
[websvn-endtest] |
</title> |
</head> |
<body id="[websvn:template]"> |
<div id="container"> |
<div id="select"> |
[websvn-test:projects_form] |
[websvn:projects_form][websvn:projects_select][websvn:projects_submit][websvn:projects_endform] |
[websvn-endtest] |
[websvn:template_form][websvn:template_select][websvn:template_submit][websvn:template_endform] |
[websvn:language_form][websvn:language_select][websvn:language_submit][websvn:language_endform] |
</div> |
<h1><a href="[websvn:indexurl]" title="[lang:PROJECTS]">[lang:PROJECTS]</a> |
[websvn-test:repname] |
<span><a href="[websvn:repurl]">[websvn:repname]</a></span> |
[websvn-endtest] |
</h1> |
/WebSVN/templates/calm/images/add.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/calm/images/arrow_in.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/calm/images/arrow_out.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/calm/images/blame.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/calm/images/bullet_add.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/calm/images/bullet_delete.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/calm/images/bullet_yellow.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/calm/images/compress.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/calm/images/css.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/calm/images/cube_green.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/calm/images/delete.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/calm/images/diff.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/calm/images/directory.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/calm/images/e-node.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/calm/images/exclamation.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/calm/images/eye.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/calm/images/favicon.ico |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/calm/images/file.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/calm/images/filec.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/calm/images/filedb.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/calm/images/fileh.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/calm/images/filepaint.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/calm/images/filephp.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/calm/images/filetxt.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/calm/images/filexml.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/calm/images/html.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/calm/images/i-node.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/calm/images/l-node.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/calm/images/link.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/calm/images/log.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/calm/images/next.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/calm/images/page_white_add.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/calm/images/page_white_delete.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/calm/images/page_white_edit.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/calm/images/pilcrow.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/calm/images/pilcrow_delete.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/calm/images/previous.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/calm/images/script.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/calm/images/sitemap_color.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/calm/images/submitbg.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/calm/images/t-node.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/calm/images/textbg.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/calm/images/toggle-down.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/calm/images/toggle-up.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/calm/images/up.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/calm/images/xml.gif |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/WebSVN/templates/calm/index.tmpl |
---|
0,0 → 1,73 |
[websvn-include:user_greeting.tmpl] |
[websvn-test:error] |
<div id="error">[websvn:error]</div> |
[websvn-else] |
<div id="wrap"> |
<h2 class="regular">[lang:PROJECTS]</h2> |
<table> |
[websvn-test:flatview] |
[websvn-startlisting] |
[websvn-test:groupid] |
[websvn-else] |
<tr> |
<td class="project"><a href="[websvn:projecturl]">[websvn:projectname]</a></td> |
[websvn-test:showlastmod] |
<td>[lang:REV] [websvn:revision]</td> |
[websvn-test:showageinsteadofdate] |
<td title="[websvn:date]">[websvn:age]</td> |
[websvn-else] |
<td title="[websvn:age]">[websvn:date]</td> |
[websvn-endtest] |
<td>[websvn:author]</td> |
[websvn-endtest] |
</tr> |
[websvn-endtest] |
[websvn-endlisting] |
[websvn-else] |
[websvn-startlisting] |
[websvn-test:groupid] |
<tr><th onclick="toggleGroup('[websvn:groupname]'); this.className = (this.className == 'open') ? 'closed' : 'open';" |
[websvn-test:opentree] |
class="open" |
[websvn-else] |
class="closed" |
[websvn-endtest] |
[websvn-test:showlastmod] |
colspan="4" |
[websvn-endtest] |
>[websvn:groupname]</th></tr> |
[websvn-else] |
<tr title="[websvn:groupname]"> |
[websvn-test:groupname] |
<td class="project group"><a href="[websvn:projecturl]">[websvn:projectname]</a></td> |
[websvn-else] |
<td class="project"><a href="[websvn:projecturl]">[websvn:projectname]</a></td> |
[websvn-endtest] |
[websvn-test:showlastmod] |
<td>[lang:REV] [websvn:revision]</td> |
[websvn-test:showageinsteadofdate] |
<td title="[websvn:date]">[websvn:age]</td> |
[websvn-else] |
<td title="[websvn:age]">[websvn:date]</td> |
[websvn-endtest] |
<td>[websvn:author]</td> |
[websvn-endtest] |
</tr> |
[websvn-endtest] |
[websvn-endlisting] |
[websvn-endtest] |
</table> |
</div> |
[websvn-test:treeview] |
<script type="text/javascript" src="[websvn:locwebsvnhttp]/javascript/jquery.min.1.9.1.js"></script> |
<script type="text/javascript" src="[websvn:locwebsvnhttp]/javascript/collapsible.js"></script> |
[websvn-test:opentree] |
[websvn-else] |
<script type="text/javascript"> |
//<![CDATA[ |
collapseAllGroups(); |
//]]> |
</script> |
[websvn-endtest] |
[websvn-endtest] |
[websvn-endtest] |
/WebSVN/templates/calm/log.tmpl |
---|
0,0 → 1,124 |
[websvn-test:error] |
<div id="error">[websvn:error]</div> |
[websvn-else] |
<h2 id="path_links">[websvn:path_links_root_config]/[websvn:path_links] – [lang:REV] [websvn:rev]</h2> |
<div id="revjump">[websvn:revision_form]<div>[lang:REV] [websvn:revision_input]<span class="submit">[websvn:revision_submit]</span></div>[websvn:revision_endform]</div> |
<p> |
[websvn-test:goyoungestlink] |
<span class="goyoungest">[websvn:goyoungestlink]</span> | |
[websvn-endtest] |
<span class="changes">[websvn:changeslink]</span> | |
[websvn-test:filedetaillink] |
<span class="detail">[websvn:filedetaillink]</span> | |
<span class="diff">[websvn:difflink]</span> | |
<span class="blame">[websvn:blamelink]</span> |
[websvn-else] |
<span class="listing">[websvn:directorylink]</span> |
[websvn-endtest] |
[websvn-test:clientrooturl] |
| <span class="svn"><a href="[websvn:clientrooturl][websvn:path]">SVN</a></span> |
[websvn-endtest] |
[websvn-test:rsslink] |
| <span class="feed">[websvn:rsslink]</span> |
[websvn-endtest] |
</p> |
[websvn-test:warning] |
<div id="warning">[websvn:warning]</div> |
[websvn-else] |
<div id="info"> |
<h2>[lang:FILTER]</h2> |
[websvn:logsearch_form] |
<table> |
<tbody> |
<tr> |
<th scope="col"><label>[lang:STARTLOG]</label></th> |
<th scope="col"><label>[lang:ENDLOG]</label></th> |
<th scope="col"><label>[lang:MAXLOG]</label></th> |
</tr> |
<tr> |
<td class="revcomp">[websvn:logsearch_startbox]</td> |
<td class="revcomp">[websvn:logsearch_endbox]</td> |
<td class="revcomp">[websvn:logsearch_maxbox]</td> |
</tr> |
<tr><th scope="col" colspan="3"><label>[lang:SEARCHLOG]</label></th></tr> |
<tr><td colspan="3">[websvn:logsearch_inputbox]</td></tr> |
<tr><th scope="col" colspan="3"><label>[lang:SHOWALL]</label></th></tr> |
<tr><td colspan="3" class="all">[websvn:logsearch_showall]</td></tr> |
</tbody> |
</table> |
<p class="submit">[websvn:logsearch_submit] |
[websvn-test:logsearch_clearloglink] |
[websvn:logsearch_clearloglink] |
[websvn-endtest] |
</p> |
[websvn:logsearch_endform] |
</div> |
<div id="wrap"> |
[websvn-test:logsearch_nomatches] |
[lang:NORESULTS] |
[websvn-endtest] |
[websvn-test:logsearch_resultsfound] |
[websvn:compare_form] |
<table> |
<thead> |
<tr> |
<th class="HdrClmn">[lang:REV]</th> |
<th class="HdrClmn">[lang:AGE]</th> |
<th class="HdrClmn">[lang:AUTHOR]</th> |
<th class="HdrClmn">[lang:PATH]</th> |
<th class="HdrClmnEnd">[lang:LOGMSG]</th> |
<th class="HdrClmn">[lang:DIFF]</th> |
[websvn-test:showchanges] |
<th class="HdrClmnEnd">[lang:CHANGES]</th> |
[websvn-endtest] |
</tr> |
</thead> |
[websvn-startlisting] |
<tr class="row[websvn:rowparity]"> |
<td class="rev">[websvn:compare_box][websvn:revlink]</td> |
[websvn-test:showageinsteadofdate] |
<td title="[websvn:revdate]">[websvn:revage]</td> |
[websvn-else] |
<td class="date" title="[websvn:revage]">[websvn:revdate]</td> |
[websvn-endtest] |
<td>[websvn:revauthor]</td> |
<td>[websvn:revpathlink]</td> |
<td valign="middle" class="logmsg">[websvn:revlog]</td> |
<td><span class="diff"><a href="[websvn:compareurl]" title="[lang:DIFFPREV]"> </a></span></td> |
[websvn-test:showchanges] |
<td class="changes"> |
[websvn-test:revadded] |
<div class="add">[websvn:revadded]</div> |
[websvn-endtest] |
[websvn-test:revdeleted] |
<div class="del">[websvn:revdeleted]</div> |
[websvn-endtest] |
[websvn-test:revmodified] |
<div class="mod">[websvn:revmodified]</div> |
[websvn-endtest] |
</td> |
[websvn-endtest] |
</tr> |
[websvn-endlisting] |
</table> |
<p class="submit"> |
[websvn:compare_submit] |
</p> |
[websvn:compare_endform] |
[websvn-endtest] |
[websvn-test:logsearch_nomorematches] |
<p>[lang:NOMORERESULTS]</p> |
[websvn-endtest] |
[websvn-test:logsearch_moreresultslink] |
<p>[websvn:logsearch_moreresultslink]</p> |
[websvn-endtest] |
<p class="pagelinks">[websvn:pagelinks]</p> |
<p>[websvn:showalllink]</p> |
[websvn-endtest] |
</div> |
[websvn-endtest] |
/WebSVN/templates/calm/revision.tmpl |
---|
0,0 → 1,96 |
[websvn-test:error] |
<div id="error">[websvn:error]</div> |
[websvn-else] |
<h2 id="path_links">[websvn:path_links_root_config]/[websvn:path_links] – [lang:REV] [websvn:rev]</h2> |
<div id="revjump">[websvn:revision_form][lang:REV] [websvn:revision_input]<span class="submit">[websvn:revision_submit]</span>[websvn:revision_endform]</div> |
<p> |
[websvn-test:prevrevurl] |
<span class="prev"><a href="[websvn:prevrevurl]">[lang:REV] [websvn:prevrev]</a></span> | |
[websvn-endtest] |
[websvn-test:nextrevurl] |
<span class="next"><a href="[websvn:nextrevurl]">[lang:REV] [websvn:nextrev]</a></span> | |
[websvn-endtest] |
[websvn-test:goyoungestlink] |
<span class="goyoungest">[websvn:goyoungestlink]</span> | |
[websvn-endtest] |
[websvn-test:comparelink] |
<span class="diff">[websvn:comparelink]</span> | |
[websvn-endtest] |
<span class="listing">[websvn:directorylink]</span> | |
[websvn-test:filedetaillink] |
<span class="detail">[websvn:filedetaillink]</span> | |
<span class="blame">[websvn:blamelink]</span> | |
[websvn-endtest] |
<span class="log">[websvn:loglink]</span> |
[websvn-test:clientrooturl] |
| <span class="svn"><a href="[websvn:clientrooturl][websvn:path]">SVN</a></span> |
[websvn-endtest] |
[websvn-test:rsslink] |
| <span class="feed">[websvn:rsslink]</span> |
[websvn-endtest] |
</p> |
[websvn-test:warning] |
<div id="warning">[websvn:warning]</div> |
[websvn-else] |
<div id="info"> |
<h2>[lang:LASTMOD]</h2> |
<ul> |
[websvn-test:showageinsteadofdate] |
<li>[lang:REV] [websvn:rev] – <span title="[websvn:date]">[websvn:age]</span></li> |
[websvn-else] |
<li>[lang:REV] [websvn:rev] – <span title="[websvn:age]">[websvn:date]</span></li> |
[websvn-endtest] |
<li><strong>[lang:AUTHOR]:</strong> [websvn:author]</li> |
<li><dl><dt><strong>[lang:LOGMSG]:</strong></dt><dd>[websvn:log]</dd></dl></li> |
</ul> |
</div> |
<div id="wrap"> |
<table> |
<thead> |
<tr align="left" valign="middle"> |
<th scope="col" class="path">[lang:PATH]</th> |
<th scope="col">[lang:BLAME]</th> |
<th scope="col">[lang:DIFF]</th> |
<th scope="col">[lang:LOG]</th> |
[websvn-test:clientrooturl] |
<th scope="col">SVN</th> |
[websvn-endtest] |
</tr> |
</thead> |
<tbody> |
[websvn-startlisting] |
<tr class="[websvn:action] row[websvn:rowparity]"> |
<td class="path"> |
[websvn-test:notinpath] |
<a href="[websvn:detailurl]" class="notinpath">[websvn:safepath]</a> |
[websvn-else] |
<a href="[websvn:detailurl]">[websvn:safepath]</a> |
[websvn-endtest] |
[websvn-test:oldsafepath] |
<br/><del>[websvn:oldsafepath] ([lang:PREV])</del> |
[websvn-endtest] |
</td> |
<td> |
[websvn-test:blameurl] |
<a href="[websvn:blameurl]" title="[lang:BLAME]"><img src="[websvn:locwebsvnhttp]/templates/calm/images/blame.png" class="icon" alt="" /></a> |
[websvn-endtest] |
</td> |
<td> |
[websvn-test:diffurl] |
<a href="[websvn:diffurl]" title="[lang:DIFFPREV]"><img src="[websvn:locwebsvnhttp]/templates/calm/images/diff.png" class="icon" alt="" /></a> |
[websvn-endtest] |
</td> |
<td><a href="[websvn:logurl]" title="[lang:VIEWLOG]"><img src="[websvn:locwebsvnhttp]/templates/calm/images/log.png" class="icon" alt="" /></a></td> |
[websvn-test:clientrooturl] |
<td><a href="[websvn:clientrooturl][websvn:path]" title="SVN"><img src="[websvn:locwebsvnhttp]/templates/calm/images/link.png" class="icon" alt="" /></a></td> |
[websvn-endtest] |
</tr> |
[websvn-endlisting] |
</tbody> |
</table> |
</div> |
[websvn-endtest] |
[websvn-endtest] |
/WebSVN/templates/calm/styles.css |
---|
0,0 → 1,938 |
html,body { |
background:#FFF; |
color:gray; |
font-family: 'Trebuchet MS', Verdana, sans-serif; |
font-size:13px; |
line-height:1.3em; |
margin:0; padding:0; |
text-align:center; |
height: 95%; |
} |
#container { |
position: relative; |
min-height: 100%; |
padding-bottom:40px; |
} |
* html #container { |
height: 95%; |
} |
#footer { |
height:40px; |
position: relative; |
margin:0;padding:0; |
margin-top: -40px; |
} |
a { |
color:#000; |
text-decoration:none; |
outline: none !important; |
} |
a:hover { |
background-color:#F0E68C; |
} |
a img { |
border:0; |
} |
#select { |
margin:1em 2% 0 2%; |
text-align:right; |
padding:10px 10px 0 10px; |
min-height:2em; |
} |
#select form, #select div { |
display: inline; |
} |
#revjump { |
text-align:right; |
height:2em; |
padding: 10px 10px 0; |
} |
#wrap { |
text-align:left; |
background:#FFF; |
padding:5px 0; |
} |
#index #wrap tr { |
border-top:1px dotted lightgrey; |
} |
#index #wrap tr:first-child { |
border-width:0; |
} |
#index #wrap td, #index #wrap th { |
border-width:0; |
padding:4px; |
text-align:right; |
white-space:pre; |
} |
#index #wrap td.project { |
text-align:left; |
width:100%; |
} |
#index #wrap td.project a { |
background-image:url(images/cube_green.png); |
background-repeat:no-repeat; |
background-position:2px 50%; |
} |
#index #wrap td.project a, #index #wrap td.group { |
padding-left:22px; |
} |
#index #wrap th { |
background-color:white; |
background-repeat:no-repeat; |
background-position:6px 50%; |
padding-left:26px; |
text-align:left; |
} |
#index #wrap th.closed { |
background-image:url(images/toggle-up.png); |
} |
#index #wrap th.open { |
background-image:url(images/toggle-down.png); |
} |
#index #info dl { |
margin:2px 0; |
} |
#index #info dl dd:first-child { |
border-width: 0; |
} |
#info { |
margin-left:2%; |
text-align:left; |
padding:5px 0; |
} |
h1, h2 { |
color:gray; |
text-align:left; |
text-transform:uppercase; |
line-height:1em; |
font-weight:normal; |
} |
h1 { |
line-height:1.7em; |
font-size:1.7em; |
border-bottom:1px solid gray; |
padding:10px 5px 10px 5px; |
text-align:left; |
font-weight:normal; |
letter-spacing: -0.018em; |
} |
h1 span { |
padding-left:22px; |
background:url(images/cube_green.png) no-repeat 0 50%; |
} |
h1 span a, h1 span a:link { |
color:gray; |
} |
h2 a { |
background:#FFF; |
margin:0; |
} |
h2 a:link, |
h2 a:visited { |
font-weight:normal; |
letter-spacing: -0.018em; |
color: #b00 |
} |
h2 a:hover { |
background:#f2f2f2; |
} |
h2 { |
font-weight:normal; |
letter-spacing: -0.018em; |
color:#666; |
padding:0 .1em; |
} |
#info h2 { |
border-bottom:1px solid gray; |
padding:0 5px 10px; |
margin:0; |
text-align:left; |
font-size:1.7em; |
font-weight:normal; |
letter-spacing: -0.018em; |
} |
#wrap h2 { |
padding:0 0 10px 0; |
margin:0; |
text-align:left; |
font-size:1.7em; |
text-transform:none; |
letter-spacing: -0.018em; |
} |
#wrap h2.regular { |
padding:0 5px 10px 5px; |
margin:0; |
text-align:left; |
font-size:1.7em; |
text-transform:uppercase; |
border-bottom:1px solid gray; |
} |
#wrap h2.regular .links { |
float:right; |
padding:0 5px 10px 5px; |
margin:0; |
text-align:right; |
font-size:13px; |
text-transform:none; |
} |
#wrap h2.regular .links a { |
color: #000000; |
font-weight: normal; |
letter-spacing: 0; |
} |
/* |
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Forms |
*/ |
input, select { |
padding:1px; |
margin:1px; |
font-family:'Trebuchet MS', 'Lucida Grande', Verdana, Arial, sans-serif; |
border-right:1px solid #000; |
border-bottom:1px solid #000; |
border-left:1px solid #b2b2b2; |
border-top:1px solid #b2b2b2; |
background-color:#FFF8DC; |
} |
input { |
padding:2px 5px; |
font-size:1.1em; |
background-color:#FFF; |
background-image:url(images/textbg.png); |
background-repeat:repeat-x; |
background-position:0 100%; |
border:1px solid #b2b2b2; |
} |
input:hover, |
input:active, |
input:focus { |
border:1px solid #666; |
background-color:#FFF; |
} |
#info ul li input { |
background-color:#FFF; |
background-image:url(images/textbg.png); |
background-repeat:repeat-x; |
background-position:0 100%; |
border:1px solid #b2b2b2; |
} |
span.submit input, |
#info span.submit input, |
#info p.submit input, |
#wrap p.submit input { |
background-image:url(images/submitbg.png); |
} |
#info table tr td input { |
font-size:1em; |
width:92%; |
background:#FFF url(images/textbg.png) repeat-x 0 0; |
} |
#info table tr td.revcomp input { |
width:50px; |
} |
#info table tr td.all input { |
width:auto; |
} |
select { |
padding:2px 2px 2px 21px; |
border:1px solid #cccccc; |
background-color:#FFF; |
background-image:url(images/cube_green.png); |
background-repeat:no-repeat; |
background-position:2px 50%; |
} |
select:hover, |
select:active, |
select:focus { |
border:1px solid #666; |
background-color:#F5F5DC; |
background-repeat:no-repeat; |
background-position:2px 50%; |
background-image:url(images/cube_green.png); |
} |
option, |
option:hover, |
option:focus, |
option:active { |
padding-left:25px; |
background-image:url(images/cube_green.png); |
background-repeat:no-repeat; |
background-position:2px 50%; |
} |
#index #projectform { |
display: none; |
} |
/* |
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Left Column |
*/ |
/* index elements */ |
#info dl { |
margin-left:0; |
} |
#info dt, #wrap dt { |
margin:0; |
padding:0 0 5px 0; |
} |
#info dd, #wrap dd { |
margin:0; |
padding:3px 0 5px 10px; |
border-top:1px dotted #D3D3D3; |
} |
#info ul { |
list-style-type:none; |
padding:0 0; |
margin:0; |
} |
#info ul li { |
padding:5px; |
margin:3px 0; |
border-bottom:1px dotted #D3D3D3; |
overflow:hidden; |
} |
li.mod a, li.new a, #info li.del { |
padding:5px 5px 5px 26px; |
margin:2px 0 2px -2px; |
background-position:5px 50%; |
background-repeat:no-repeat; |
} |
li.mod a { |
display:block; |
color:#545400; |
border:1px solid #f2f2c7; |
background-color:#FFFFE0; |
background-image:url(images/page_white_edit.png); |
} |
li.mod a:hover { |
color:#000; |
border:1px solid #BDB76B; |
background-color:#F0E68C; |
} |
li.new a { |
display:block; |
color:#545400; |
border:1px solid #d5f2c7; |
background-color:#f2ffd9; |
background-image:url(images/page_white_add.png); |
} |
li.new a:hover { |
color:#000; |
border:1px solid #669900; |
background-color:#9ACD32; |
} |
#info ul li.del { |
display:block; |
color:#BC8F8F; |
border:1px solid #BC8F8F; |
padding:5px 5px 5px 26px; |
margin:5px; |
background-color:#FFEFD5; |
background-image:url(images/page_white_delete.png); |
background-position:5px 5px; |
text-align:left; |
} |
#info ul li a { |
overflow:hidden; |
} |
/* |
++++++++++++++++++++++++++++++++++++++++++++++++++++++ main content: Directories |
*/ |
table { |
border-collapse:collapse; |
width:100%; |
} |
td { |
padding:0; |
text-align:left; |
} |
th { |
text-align:center; |
} |
td, th { |
border: 1px solid #eeeeee; |
} |
#info th, #info td { |
border: none; |
text-align: left; |
} |
#diff td, #blame td, table.diff td { |
vertical-align:top; |
} |
thead th a { |
color:white; |
} |
thead th a:hover { |
text-decoration:underline; |
color:white; |
background:none; |
} |
thead tr { |
background:#4d4d4d; |
} |
thead th { |
background:#4d4d4d; |
border-bottom:2px solid #000; |
border-top:2px solid #808080; |
border-right:1px solid #808080; |
color:#FFF; |
margin:3px 2px; |
padding:3px 5px; |
} |
thead th.open { |
background-image:url(images/toggle-down.png); |
background-repeat:no-repeat; |
} |
thead th.closed { |
background-image:url(images/toggle-up.png); |
background-repeat:no-repeat; |
} |
thead th.path { |
text-align:left; |
width:50%; |
} |
thead th.collno, thead th.colrev, thead th.colauth { |
width:6%; |
} |
thead th.colcode { |
width:73%; |
} |
tbody th { |
background-color: #ddd; |
} |
tbody th.info { |
background-color: #d0dfea; |
} |
tr td.code { |
text-align:left; |
} |
td.code, td td.diff { |
border: 1px solid #eee; |
} |
tr td.code pre { |
padding: 1px 2px 0; |
background-color:#f8f8f8; |
} |
tr:hover td.code pre { |
background-color:#e8e8e8; |
} |
tr:hover td.code { |
background-color:#FFF; |
} |
tr td.path, tr th.path { |
text-align:left; |
width: 100%; |
} |
tr td.path { |
padding:0; |
} |
tr.row0 td { |
background-color:#f0f0f0; |
} |
tr.row1 td { |
background-color:#f8f8f8; |
} |
tr.row0:hover td, tr.row1:hover td { |
background-color:#e8e8e8; |
} |
span.listing a, a.listing { |
padding-left:22px; |
background-image:url(images/sitemap_color.png); |
background-repeat:no-repeat; |
background-position:3px 50%; |
} |
span.detail a { |
padding-left:22px; |
background-image:url(images/file.png); |
background-repeat:no-repeat; |
background-position:3px 50%; |
} |
span.changes a { |
padding-left:22px; |
background-image:url(images/page_white_edit.png); |
background-repeat:no-repeat; |
background-position:3px 50%; |
} |
span.compact a { |
padding-left:22px; |
background-image:url(images/arrow_in.png); |
background-repeat:no-repeat; |
background-position:3px 50%; |
} |
span.full a { |
padding-left:22px; |
background-image:url(images/arrow_out.png); |
background-repeat:no-repeat; |
background-position:3px 50%; |
} |
span.ignorews a { |
padding-left:22px; |
background-image:url(images/pilcrow_delete.png); |
background-repeat:no-repeat; |
background-position:3px 50%; |
} |
span.regardws a { |
padding-left:22px; |
background-image:url(images/pilcrow.png); |
background-repeat:no-repeat; |
background-position:3px 50%; |
} |
span.log a, |
td.log a { |
padding-left:22px; |
background-image:url(images/log.png); |
background-repeat:no-repeat; |
background-position:3px 50%; |
} |
span.blame a, |
td.blame a { |
padding-left:22px; |
background-image:url(images/blame.png); |
background-repeat:no-repeat; |
background-position:3px 50%; |
} |
span.mime a, |
td.mime a { |
padding-left:22px; |
background-image:url(images/eye.png); |
background-repeat:no-repeat; |
background-position:3px 50%; |
} |
span.svn a, |
td.svn a { |
padding-left:22px; |
background-image:url(images/link.png); |
background-repeat:no-repeat; |
background-position:3px 50%; |
} |
span.next a, |
td.next a { |
padding-left:15px; |
background-image:url(images/next.png); |
background-repeat:no-repeat; |
background-position:0px 50%; |
} |
span.prev a, |
td.prev a { |
padding-left:15px; |
background-image:url(images/previous.png); |
background-repeat:no-repeat; |
background-position:0px 50%; |
} |
li.compress a, |
span.compress a, |
tr td.compress a:link, |
tr td.compress a:visited, |
tr td.compress a:link { |
padding-left:22px; |
background-image:url(images/compress.png); |
background-repeat:no-repeat; |
background-position:3px 50%; |
} |
li.feed a, |
span.feed a, |
tr td.feed a, |
tr td.feed a:link, |
tr td.feed a:visited, |
tr td.feed a:link { |
padding-left:22px; |
background-image:url(images/xml.gif); |
background-repeat:no-repeat; |
background-position:3px 50%; |
} |
.goyoungest a { |
color:#e25f53; |
padding-left:22px; |
background-image:url(images/exclamation.png); |
background-repeat:no-repeat; |
background-position:3px 50%; |
} |
.goyoungest a:hover { |
background-color:#fad4c8; |
color:#000; |
} |
.icon { |
vertical-align: middle; |
} |
/* |
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ File, Blame, Diff |
*/ |
h2#path_links { |
text-transform:none; |
margin:0 2% 15px; |
} |
div.listing { |
overflow:auto; |
border:1px solid #D3D3D3; |
text-align:left; |
margin:0 2%; |
padding:3px; |
background:#f8f8f8; |
} |
pre a, td.code pre a { |
color:blue; |
font-style:italic; |
} |
pre { |
margin: 0; |
white-space: pre-wrap; |
} |
code, pre, table.diff td, #file div.listing { |
font-family:Consolas, monospace; |
} |
.new a {color:green} |
.del a {color:red} |
.toggleup a:link, |
.toggleup a:visited, |
.toggleup a:focus { |
padding-left:22px; |
background:url(images/toggle-up.png) no-repeat 2px 50%; |
} |
.toggleup a:hover { |
background:#F0E68C url(images/toggle-up.png) no-repeat 2px 50%; |
} |
.toggledown a:link, |
.toggledown a:visited, |
.toggledown a:focus { |
padding-left:22px; |
background:url(images/toggle-down.png) no-repeat 2px 50%; |
} |
.toggledown a:hover { |
background:#F0E68C url(images/toggle-down.png) no-repeat 2px 50%; |
} |
span.diff a:link, |
span.diff a:visited, |
span.diff a:focus { |
padding-left:22px; |
background:url(images/diff.png) no-repeat 2px 50%; |
} |
span.diff a:hover { |
background:#F0E68C url(images/diff.png) no-repeat 2px 50%; |
} |
.geshi a:link, |
.geshi a:visited, |
.geshi a:focus, |
.geshi a:hover { |
padding-left:0; |
background: none; |
} |
.geshi a:hover { |
text-decoration: underline; |
} |
tr td.lineno { |
text-align: right; |
vertical-align: top; |
padding: 0 2px; |
} |
tr td.row1 { |
padding: 3px; |
border: none; |
} |
tr td code, tr td pre { |
display:block; |
height:100%; |
} |
/* compare table */ |
table.diff { |
margin:10px 0 20px; |
border-spacing:0; |
border-collapse:separate; |
} |
table.diff td { |
color:black; |
padding:0; |
margin:0; |
border-color:#f0f0f0; |
} |
table.diff td, table td pre { |
padding-left:16px; |
background-position: 0 0; |
background-repeat:no-repeat; |
white-space:pre-wrap; |
} |
table td pre { |
border:1px solid white; |
} |
table tr:hover { |
background:white; |
} |
td.diffempty { |
background-color:#f8f8f8; |
} |
table tr:hover td.diff, table tr:hover td.diffempty { |
background-color:#e8e8e8; |
} |
table td.diff pre { |
background-position:2px 50%; |
background-repeat:no-repeat; |
} |
table.diff td.diffdeleted, |
table td.diffdeleted pre { |
background-color:#f8e4cc; |
background-image:url(images/bullet_delete.png); |
border:1px solid #e8d4bc; |
} |
table.diff tr:hover td.diffdeleted, |
table tr:hover td.diffdeleted pre { |
background-color:#ffccaa; |
border-color:#bb9977; |
} |
table.diff td.diffadded, |
table td.diffadded pre { |
border:1px solid #cdf0cd; |
background-color:#ddffdd; |
background-image:url(images/bullet_add.png); |
} |
table.diff tr:hover td.diffadded, |
table tr:hover td.diffadded pre { |
background-color:#bbffbb; |
border-color:#88bb88; |
} |
table td.diffchanged pre { |
border:1px solid #f0f0bc; |
background-color:#ffffcc; |
background-image:url(images/bullet_yellow.png); |
} |
table tr:hover td.diffchanged pre { |
background-color:#ffff99; |
border-color:#bbbb55; |
} |
ins { |
background-color: #bbffbb; |
text-decoration: none; |
} |
tr:hover ins { |
background-color: #99ff99; |
} |
del { |
background-color: #ffccaa; |
text-decoration: none; |
} |
tr:hover del { |
background-color: #ffaa88; |
} |
code { |
white-space: pre-wrap; |
} |
/* Whitespace hacks for IE 4-7 */ |
* html code, *:first-child+html code { |
white-space: pre; |
} |
* html table.diff td, *:first-child+html table.diff td { |
white-space: pre; |
} |
/* Log View */ |
table tr td.logmsg { |
text-align:left; |
padding: 3px 0 3px 3px; |
} |
/* sidebar form without css-bg-colors */ |
#info table tr td, |
#info table tr th { |
background:#FFF; |
padding:0; |
margin:0; |
font-weight:normal; |
} |
#info table tr:hover td, |
#info table tr:hover th { |
background:#FFF; |
padding:0; |
margin:0; |
} |
/* inputs see -> forms */ |
div.blame-popup { |
position: absolute; |
text-align: left; |
background-color: white; |
padding: 5px; |
border:1px solid #BDB76B; |
background-color: #F0E68C; |
max-width: 600px; |
} |
div.blame-popup .date { |
font-weight: bold; |
} |
#wrap td.log, #wrap td.feed { |
white-space: nowrap; |
} |
#wrap td.age, #wrap td.date { |
padding-left: 3px; |
padding-right: 8px; |
} |
#wrap td.age, #wrap td.date, #wrap td.rev { |
text-align: right; |
white-space: nowrap; |
} |
#wrap p.pagelinks > * { |
padding: 0 3px; |
} |
div#error, div#warning { |
font-weight: bold; |
display: table; |
padding: 5px; |
margin: 0 auto; |
border: 1px solid; |
} |
div#error { |
border-color: #cb6565; |
background-color: #ffe2e2; |
} |
div#warning { |
border-color: #d5ce00; |
background-color: #ffd; |
} |
table td { |
vertical-align: top; |
padding: 2px; |
} |
div#wrap table td.changes div { |
background-repeat: no-repeat; |
padding-left: 18px; |
} |
td.changes .add { |
background-image: url(images/add.png); |
} |
td.changes .del { |
background-image: url(images/delete.png); |
} |
td.changes .mod { |
background-image: url(images/page_white_edit.png); |
} |
#blame table td { |
text-align: right; |
padding-right: 4px; |
border-color: white; |
} |
#blame table td.code { |
text-align: left; |
padding: 0; |
border-color: #eeeeee; |
} |
#blame table td.code pre { |
border: none; |
} |
#revision td.path a { |
background-position:5px 50%; |
background-repeat:no-repeat; |
padding-left: 26px; |
top: 2px; |
position: relative; |
} |
#revision td.path a.notinpath { |
color: #b00; |
} |
#revision tr.M td.path a { |
background-image:url(images/page_white_edit.png); |
} |
#revision tr.A td.path a { |
background-image:url(images/page_white_add.png); |
} |
#revision tr.D td.path a { |
background-image:url(images/page_white_delete.png); |
} |
#revision del { |
padding-left: 26px; |
background: none; |
} |
.table-responsive { |
display: block; |
width: 100%; |
overflow-x: auto; |
-webkit-overflow-scrolling: touch; |
} |
/* |
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Media Queries (responsivity) |
*/ |
/* every screens excepts small ones */ |
@media only screen and (min-width: 800px) { |
#info { |
float:left; |
width:28%; |
} |
#wrap { |
margin:0 2% 0 32%; |
width:65%; |
} |
h1 { |
margin:-1.7em 2% 1em 2%; |
} |
#revjump { |
margin:-3.7em 2% 0; |
} |
} |
/* small screens only */ |
@media only screen and (max-width: 799px) { |
tr td.path { |
white-space: nowrap; |
} |
h2#path_links { |
overflow-x: auto; |
overflow-y: hidden; |
} |
#wrap { |
margin:1em 2% 0 2%; |
} |
h1 { |
margin:0 2% 1em 2%; |
} |
/*** Always show scrollbar on webkit mobiles */ |
::-webkit-scrollbar { |
-webkit-appearance: none; |
width: .5rem; |
height: .5rem; |
} |
::-webkit-scrollbar-thumb { |
border-radius: 4px; |
background-color: rgba(0, 0, 0, .25); |
} |
} |
/WebSVN/templates/calm/user_greeting.tmpl |
---|
0,0 → 1,16 |
<div id="info"> |
<h2>About</h2> |
<dl> |
<dd> |
You can customize this message in 'templates/calm/user_greeting.tmpl' to tell your |
visitors what they'll find in your repositories. |
</dd> |
<dd> |
Visit <a href="https://websvnphp.github.io">websvnphp.github.io</a> for more information |
about WebSVN. |
</dd> |
<dd> |
Learn more about Apache Subversion at <a href="https://subversion.apache.org">subversion.apache.org</a>. |
</dd> |
</dl> |
</div> |
/rector.php |
---|
14,7 → 14,7 |
]); |
// Uncomment and set this to your target PHP version |
$rectorConfig->phpVersion(PHP_VERSION_ID); // for PHP 8, this might be 80000 for 8.0 |
$rectorConfig->phpVersion(80100); // for PHP 8, this might be 80000 for 8.0 |
// Include sets of rules for PHP version upgrades |
// For upgrading to PHP 8.0 |