# HG changeset patch # User Marcin Kuzminski # Date 2010-07-24 00:17:48 # Node ID 558eb7c5028f24a90b5466ed16be13b213ba1fc2 # Parent 3581656180b729f365921345298c7c6766434c84 version bump to 0.8 hg app 0.8 new template. Add yui flot and graph into summary page. + various tweeks and patches into look of application diff --git a/pylons_app/__init__.py b/pylons_app/__init__.py --- a/pylons_app/__init__.py +++ b/pylons_app/__init__.py @@ -24,7 +24,7 @@ Hg app, a web based mercurial repository @author: marcink """ -VERSION = (0, 7, 9, 'beta') +VERSION = (0, 8, 0, 'beta') __version__ = '.'.join((str(each) for each in VERSION[:4])) diff --git a/pylons_app/controllers/summary.py b/pylons_app/controllers/summary.py --- a/pylons_app/controllers/summary.py +++ b/pylons_app/controllers/summary.py @@ -2,7 +2,7 @@ # encoding: utf-8 # summary controller for pylons # Copyright (C) 2009-2010 Marcin Kuzminski - +# # 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; version 2 @@ -22,12 +22,18 @@ Created on April 18, 2010 summary controller for pylons @author: marcink """ +from datetime import datetime, timedelta from pylons import tmpl_context as c, request from pylons_app.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator from pylons_app.lib.base import BaseController, render +from pylons_app.lib.helpers import person +from pylons_app.lib.utils import OrderedDict from pylons_app.model.hg_model import HgModel +from time import mktime from webhelpers.paginate import Page +import calendar import logging + log = logging.getLogger(__name__) class SummaryController(BaseController): @@ -56,5 +62,77 @@ class SummaryController(BaseController): c.repo_branches = {} for name, hash in c.repo_info.branches.items()[:10]: c.repo_branches[name] = c.repo_info.get_changeset(hash) - + + c.commit_data = self.__get_commit_stats(c.repo_info) + return render('summary/summary.html') + + + + def __get_commit_stats(self, repo): + aggregate = OrderedDict() + + + #graph range + td = datetime.today() + y = td.year + m = td.month + d = td.day + c.ts_min = mktime((y, (td - timedelta(days=calendar.mdays[m] - 1)).month, d, 0, 0, 0, 0, 0, 0,)) + c.ts_max = mktime((y, m, d, 0, 0, 0, 0, 0, 0,)) + + +# #generate this monhts keys +# dates_range = OrderedDict() +# year_range = range(2010, datetime.today().year + 1) +# month_range = range(1, datetime.today().month + 1) +# +# +# +# for y in year_range: +# for m in month_range: +# for d in range(1, calendar.mdays[m] + 1): +# k = '%s-%s-%s' % (y, m, d) +# timetupple = [int(x) for x in k.split('-')] +# timetupple.extend([0 for _ in xrange(6)]) +# k = mktime(timetupple) +# dates_range[k] = 0 + + def author_key_cleaner(k): + k = person(k) + return k + + for cs in repo: + k = '%s-%s-%s' % (cs.date.timetuple()[0], cs.date.timetuple()[1], + cs.date.timetuple()[2]) + timetupple = [int(x) for x in k.split('-')] + timetupple.extend([0 for _ in xrange(6)]) + k = mktime(timetupple) + if aggregate.has_key(author_key_cleaner(cs.author)): + if aggregate[author_key_cleaner(cs.author)].has_key(k): + aggregate[author_key_cleaner(cs.author)][k] += 1 + else: + #aggregate[author_key_cleaner(cs.author)].update(dates_range) + if k >= c.ts_min and k <= c.ts_max: + aggregate[author_key_cleaner(cs.author)][k] = 1 + else: + if k >= c.ts_min and k <= c.ts_max: + aggregate[author_key_cleaner(cs.author)] = OrderedDict() + #aggregate[author_key_cleaner(cs.author)].update(dates_range) + aggregate[author_key_cleaner(cs.author)][k] = 1 + + d = '' + tmpl0 = u""""%s":%s""" + tmpl1 = u"""{label:"%s",data:%s},""" + for author in aggregate: + d += tmpl0 % (author.decode('utf8'), + tmpl1 \ + % (author.decode('utf8'), + [[x, aggregate[author][x]] for x in aggregate[author]])) + if d == '': + d = '"%s":{label:"%s",data:[[0,0],]}' \ + % (author_key_cleaner(repo.contact), + author_key_cleaner(repo.contact)) + return d + + diff --git a/pylons_app/lib/base.py b/pylons_app/lib/base.py --- a/pylons_app/lib/base.py +++ b/pylons_app/lib/base.py @@ -15,7 +15,7 @@ class BaseController(WSGIController): def __before__(self): c.hg_app_version = __version__ - c.repos_prefix = config['hg_app_name'] + c.hg_app_name = config['hg_app_name'] c.repo_name = get_repo_slug(request) c.hg_app_user = auth.get_user(session) c.cached_repo_list = _get_repos_cached() diff --git a/pylons_app/public/css/colors/blue.css b/pylons_app/public/css/colors/blue.css new file mode 100644 --- /dev/null +++ b/pylons_app/public/css/colors/blue.css @@ -0,0 +1,302 @@ +/* ----------------------------------------------------------- + header +----------------------------------------------------------- */ + +#header #header-inner +{ + background: #b0b0b0 url("../../images/colors/blue/header_inner.png") repeat-x; +} + +/* ----------------------------------------------------------- + header -> home +----------------------------------------------------------- */ + +#header #header-inner #home a +{ + background: url("../../images/colors/blue/button_home.png"); +} + +/* ----------------------------------------------------------- + header -> quick +----------------------------------------------------------- */ + +#header #header-inner #quick li a +{ + background: #336699 url("../../images/colors/blue/quick_l.png") no-repeat top left; +} + +#header #header-inner #quick li span +{ + background: url("../../images/colors/blue/quick_r.png") no-repeat top right; + border-left: 1px solid #3f6f9f; +} + +#header #header-inner #quick li span.icon +{ + background: url("../../images/colors/blue/quick_l.png") no-repeat top left; + border-right: 1px solid #2e5c89; +} + +#header #header-inner #quick li a:hover +{ + background: #4e4e4e url("../../images/colors/blue/quick_l_selected.png") no-repeat top left; +} + +#header #header-inner #quick li a:hover span +{ + background: url("../../images/colors/blue/quick_r_selected.png") no-repeat top right; +} + +#header #header-inner #quick li a:hover span.icon +{ + background: url("../../images/colors/blue/quick_l_selected.png") no-repeat top left; +} + +/* ----------------------------------------------------------- + header corners +----------------------------------------------------------- */ + +#header #header-inner div.corner +{ + background: url("../../images/colors/blue/header_inner_corners.png") no-repeat; +} + +#header #header-inner div.tl +{ + top: 0; + left: 0; + background-position: 0 0; +} + +#header #header-inner div.tr +{ + top: 0; + right: 0; + background-position: -6px 0; +} + +/* ----------------------------------------------------------- + content -> left -> menu +----------------------------------------------------------- */ + +#content #left #menu h6.selected +{ + background: #00376e url("../../images/colors/blue/menu_selected.png") repeat-x; +} + +#content #left #menu h6.selected a +{ + background: url("../../images/colors/blue/menu_l_selected.png") no-repeat top left; +} + +#content #left #menu h6.selected span +{ + background: url("../../images/colors/blue/menu_r_selected.png") no-repeat top right; +} + +#content #left #menu ul +{ + background: #376ea6; +} + +#content #left #menu li +{ + border-top: 1px solid #4377ab; + border-bottom: 1px solid #326395; +} + +#content #left #menu li a +{ + background: url("../../images/colors/blue/menu_arrow.png") no-repeat 0 9px; +} + +#content #left #menu li a:hover +{ + color: #b9dcff; +} + +#content #left #menu li.collapsible +{ + background: url("../../images/colors/blue/menu_border.png") no-repeat top left; +} + +#content #left #menu li.collapsible a.minus +{ + border-bottom: 1px solid #326395; +} + +#content #left #menu li ul +{ + border-left: 18px solid #326395; +} + +#content #left #menu li ul li +{ + background: url("../../images/colors/blue/menu_arrow.png") no-repeat 10px 9px; + border-top: 1px solid #4377ab; + border-bottom: 1px solid #326395; +} + +/* ----------------------------------------------------------- + content -> right -> box / title +----------------------------------------------------------- */ + +#content div.box div.title +{ + background: #336699 url("../../images/colors/blue/title.png") repeat-x; +} + +#content div.box div.title ul.links li a +{ + background: url("../../images/colors/blue/title_link.png") no-repeat top left; + border-left: 1px solid #316293; +} + +#content div.box div.title ul.links li a:hover +{ + background: url("../../images/colors/blue/title_tab_selected.png") no-repeat bottom center; + color: #bfe3ff; +} + +#content div.box div.title ul.links li.ui-tabs-selected a +{ + background: url("../../images/colors/blue/title_tab_selected.png") no-repeat bottom center; + color: #bfe3ff; +} + +/* ----------------------------------------------------------- + content -> right -> box / search +----------------------------------------------------------- */ + +#content div.box div.title div.search +{ + background: url("../../images/colors/blue/title_link.png") no-repeat top left; + border-left: 1px solid #316293; +} + +#content div.box div.title div.search div.input input +{ + border: 1px solid #316293; +} + +#content div.box div.title div.search div.button input.ui-state-default +{ + background: #4e85bb url("../../images/colors/blue/button_highlight.png") repeat-x; + border: 1px solid #316293; + border-left: none; + color: #FFFFFF; +} + +#content div.box div.title div.search div.button input.ui-state-hover +{ + background: #46a0c1 url("../../images/colors/blue/button_highlight_selected.png") repeat-x; + border: 1px solid #316293; + border-left: none; + color: #FFFFFF; +} + +/* ----------------------------------------------------------- + content -> right -> forms -> button +----------------------------------------------------------- */ + +#content div.box div.form div.fields div.field div.highlight .ui-state-default +{ + background: #4e85bb url("../../images/colors/blue/button_highlight.png") repeat-x; + border-top: 1px solid #5c91a4; + border-left: 1px solid #2a6f89; + border-right: 1px solid #2b7089; + border-bottom: 1px solid #1a6480; + color: #ffffff; +} + +#content div.box div.form div.fields div.field div.highlight .ui-state-hover +{ + background: #46a0c1 url("../../images/colors/blue/button_highlight_selected.png") repeat-x; + border-top: 1px solid #78acbf; + border-left: 1px solid #34819e; + border-right: 1px solid #35829f; + border-bottom: 1px solid #257897; + color: #ffffff; +} + +/* ----------------------------------------------------------- + content -> right -> forms -> buttons +----------------------------------------------------------- */ + +#content div.box div.form div.fields div.buttons div.highlight input.ui-state-default +{ + background: #4e85bb url("../../images/colors/blue/button_highlight.png") repeat-x; + border-top: 1px solid #5c91a4; + border-left: 1px solid #2a6f89; + border-right: 1px solid #2b7089; + border-bottom: 1px solid #1a6480; + color: #ffffff; +} + +#content div.box div.form div.fields div.buttons div.highlight input.ui-state-hover +{ + background: #46a0c1 url("../../images/colors/blue/button_highlight_selected.png") repeat-x; + border-top: 1px solid #78acbf; + border-left: 1px solid #34819e; + border-right: 1px solid #35829f; + border-bottom: 1px solid #257897; + color: #ffffff; +} + +/* ----------------------------------------------------------- + login -> title +----------------------------------------------------------- */ + +#login div.title +{ + background: #003367 url("../../images/colors/blue/header_inner.png") repeat-x; +} + +/* ----------------------------------------------------------- + login -> title / corners +----------------------------------------------------------- */ + +#login div.title div.corner +{ + background: url("../../images/colors/blue/login_corners.png") no-repeat; +} + +#login div.title div.tl +{ + top: 0; + left: 0; + background-position: 0 0; +} + +#login div.title div.tr +{ + top: 0; + right: 0; + background-position: -6px 0; +} + +/* ----------------------------------------------------------- + jquery ui -> select styling +----------------------------------------------------------- */ + +.ui-selectmenu-open li.ui-selectmenu-item-focus { background: #376ea6; } +.ui-selectmenu-open li.ui-selectmenu-item-focus a { color: #ffffff; } + +/* ----------------------------------------------------------- + jquery ui -> datepicker +----------------------------------------------------------- */ +.ui-datepicker td span, .ui-datepicker td a:hover { background: #376ea6; color: #ffffff; } +.ui-datepicker td span, .ui-datepicker td.ui-datepicker-current-day a { background: #376ea6; color: #ffffff; } + +/* ----------------------------------------------------------- + jquery ui -> autocomplete +----------------------------------------------------------- */ + +.ui-autocomplete .ui-menu-item a:hover { background: #376ea6; color: #ffffff; } + +/* ----------------------------------------------------------- + jquery ui -> dialog +----------------------------------------------------------- */ + +.ui-dialog { border: 1px solid #336699; } +.ui-dialog .ui-dialog-titlebar { background: #336699 url("../../images/colors/blue/title.png") repeat-x; } \ No newline at end of file diff --git a/pylons_app/public/css/diff.css b/pylons_app/public/css/diff.css --- a/pylons_app/public/css/diff.css +++ b/pylons_app/public/css/diff.css @@ -26,14 +26,22 @@ div.diffblock pre.raw{ color:#000000; } -.code-difftable{ +table.code-difftable{ border-collapse: collapse; width: 99%; } -.code-difftable td:target *{ +table.code-difftable td:target *{ background: repeat scroll 0 0 #FFFFBE !important; text-decoration: underline; } + +table.code-difftable td { + padding: 0 !important; + background: none !important; + border:0 !important; +} + + .code-difftable .context{ background:none repeat scroll 0 0 #DDE7EF; } @@ -82,7 +90,6 @@ div.diffblock pre.raw{ padding:0; } - .code { display: block; width: 100%; diff --git a/pylons_app/public/css/monoblue_custom.css b/pylons_app/public/css/monoblue_custom.css deleted file mode 100644 --- a/pylons_app/public/css/monoblue_custom.css +++ /dev/null @@ -1,952 +0,0 @@ -/*** Initial Settings ***/ -#mainhtml { - margin: 15px 50px; - background: #DBD4C6; - font-family: sans-serif; -} - -#mainhtml .breadcrumbs a:HOVER { - text-decoration: underline; -} - -a { - color: #556CB5; - text-decoration: none; -} - -a:HOVER { - text-decoration: underline; -} - -/*** end of Initial Settings ***/ - -/*** ***/ -.table_disp { - border-left: 0px solid #666666; - border-bottom: 1px solid #666666; - border-right: 1px solid #666666; - padding: 0px; - margin: 0px; - border-spacing: 0px; -} - -.table_disp .header { - border-top: 1px solid #666666; - background-color: #556CB5; - font-weight: bold; - color: white; - vertical-align: middle; - padding: 3px 5px; - text-align: left; - font-size: 0.9em; -} - -.table_disp .header td { - padding: 4px; - vertical-align: middle; - border-top: 1px solid #AAAAAA; - border-bottom: 2px solid #666666; -} - -.table_disp td { - border-left: 1px solid #AAAAAA; - padding-left: 4px; - padding-right: 4px; -} - -table tr.parity0:hover,table tr.parity1:hover { - background: #D5E1E6; -} - -table tr.parity0 { - background: #EAEAE9; -} - -table tr.parity1 { - background: #FFFFFF; -} - -/*** ***/ - -/** COMMON SETTINGS **/ -.add_icon { - background: url("/images/icons/add.png") no-repeat scroll 3px; - height: 16px; - padding-left: 20px; - padding-top: 0px; - text-align: left; -} - -.edit_icon { - background: url("/images/icons/folder_edit.png") no-repeat scroll 3px; - height: 16px; - padding-left: 20px; - padding-top: 0px; - text-align: left; -} - -.delete_icon { - background: url("/images/icons/delete.png") no-repeat scroll 3px; - height: 16px; - padding-left: 20px; - padding-top: 0px; - text-align: left; -} - -.action_button { - border: 0px; - display: block; -} - -.action_button:hover { - border: 0px; - font-style: italic; - cursor: pointer; -} - -.flash_msg ul { - margin: 0; - padding: 25px 0px 0px 0px; -} - -.error_msg { - background-color: #FFCFCF; - background-image: url("/images/icons/error_msg.png"); - border: 1px solid #FF9595; - color: #CC3300; -} - -.warning_msg { - background-color: #FFFBCC; - background-image: url("/images/icons/warning_msg.png"); - border: 1px solid #FFF35E; - color: #C69E00; -} - -.success_msg { - background-color: #D5FFCF; - background-image: url("/images/icons/success_msg.png"); - border: 1px solid #97FF88; - color: #009900; -} - -.notice_msg { - background-color: #DCE3FF; - background-image: url("/images/icons/notice_msg.png"); - border: 1px solid #93A8FF; - color: #556CB5; -} - -.success_msg,.error_msg,.notice_msg,.warning_msg { - background-position: 10px center; - background-repeat: no-repeat; - font-size: 12px; - font-weight: bold; - min-height: 14px; - line-height: 14px; - margin-bottom: 0px; - margin-top: 0px; - padding: 3px 10px 3px 40px; - display: block; - overflow: auto; -} - -#msg_close { - background: transparent url("icons/cross_grey_small.png") no-repeat - scroll 0 0; - cursor: pointer; - height: 16px; - position: absolute; - right: 5px; - top: 5px; - width: 16px; -} - -.error-message { - color: #CC3300; -} - -/**** TOOLTIP ****/ -.yui-overlay,.yui-panel-container { - visibility: hidden; - position: absolute; - z-index: 2; -} - -.yui-tt { - visibility: hidden; - position: absolute; - color: #666666; - background-color: #FFFFFF; - font-family: arial, helvetica, verdana, sans-serif; - padding: 8px; - border: 2px solid #556CB5; - font: 100% sans-serif; - width: auto; - opacity: 1.0; -} - -.yui-tt-shadow { - display: none; -} - -/** END TOOLTIP **/ - -/** AUTOCOMPLETE **/ - -.ac{ - vertical-align: top; - -} -.ac .match { - font-weight:bold; -} - -.ac .yui-ac { - position: relative; - font-family: arial; - font-size: 100%; -} - -.ac .perm_ac{ - width:15em; -} -/* styles for input field */ -.ac .yui-ac-input { - position: absolute; - width: 100%; -} - -/* styles for results container */ -.ac .yui-ac-container { - position: absolute; - top: 1.6em; - width: 100%; -} - -/* styles for header/body/footer wrapper within container */ -.ac .yui-ac-content { - position: absolute; - width: 100%; - border: 1px solid #808080; - background: #fff; - overflow: hidden; - z-index: 9050; -} - -/* styles for container shadow */ -.ac .yui-ac-shadow { - position: absolute; - margin: .3em; - width: 100%; - background: #000; - -moz-opacity: 0.10; - opacity: .10; - filter: alpha(opacity = 10); - z-index: 9049; -} - -/* styles for results list */ -.ac .yui-ac-content ul { - margin: 0; - padding: 0; - width: 100%; -} - -/* styles for result item */ -.ac .yui-ac-content li { - margin: 0; - padding: 2px 5px; - cursor: default; - white-space: nowrap; -} - -/* styles for prehighlighted result item */ -.ac .yui-ac-content li.yui-ac-prehighlight { - background: #B3D4FF; -} - -/* styles for highlighted result item */ -.ac .yui-ac-content li.yui-ac-highlight { - background: #556CB5; - color: #FFF; -} - -/** END AUTOCOMPLETE **/ -div#main { - padding: 5px; -} - -div#container { - background: #FFFFFF; - position: relative; - color: #666; -} - -div.page-header { - padding: 50px 20px 0; - background: #556cb5 top left repeat-x; - position: relative; -} - -div.page-header h1 { - margin: 10px 0 30px; - font-size: 1.8em; - font-weight: bold; - font-family: sans-serif; - letter-spacing: 1px; - color: #FFFFFF; -} - -div.page-header h1 a { - font-weight: bold; - color: #FFFFFF; -} - -div.page-header a { - text-decoration: none; -} - -div.page-header form { - position: absolute; - margin-bottom: 2px; - bottom: 0; - right: 20px; -} - -div.page-header form label { - color: #DDD; -} - -div.page-header form input { - padding: 2px; - border: solid 1px #DDD; -} - -div.page-header form dl { - overflow: hidden; -} - -div.page-header form dl dt { - font-size: 1.2em; -} - -div.page-header form dl dt,div.page-header form dl dd { - margin: 0 0 0 5px; - float: left; - height: 24px; - line-height: 20px; -} - -ul.page-nav { - margin: 10px 0 0 0; - list-style-type: none; - overflow: hidden; - width: 800px; - padding: 0; -} - -ul.page-nav li { - margin: 0 4px 0 0; - float: left; - height: 24px; - font-size: 1.1em; - line-height: 24px; - text-align: center; - background: #556CB5; -} - -ul.page-nav li.current { - background: #FFF; - padding-right: 5px; - padding-left: 5px; -} - -ul.page-nav li.current a { - color: #556CB5; -} - -ul.page-nav li a { - height: 24px; - color: #FFF; - padding-right: 5px; - padding-left: 5px; - display: block; - text-decoration: none; - font-weight: bold; -} - -ul.page-nav li.logout a { - color: #FDAC9D; -} - -ul.page-nav li a:hover { - background: #FFF; - color: #556CB5; -} - -ul.submenu { - margin: 5px 0px -20px 0px; - list-style-type: none; -} - -ul.submenu li { - margin: 0 10px 0 0; - font-size: 0.9em; - font-weight: bold; - display: inline; -} - -ul.submenu .repos { - background: url("/images/icons/folder_edit.png") no-repeat scroll 3px; - height: 16px; - padding-left: 20px; - padding-top: 0px; - text-align: left; -} - -ul.submenu .users { - background: url("/images/icons/user_edit.png") no-repeat scroll 3px; - height: 16px; - padding-left: 20px; - padding-top: 0px; - text-align: left; -} - -ul.submenu .permissions { - background: url("/images/icons/folder_key.png") no-repeat scroll 3px; - height: 16px; - padding-left: 20px; - padding-top: 0px; - text-align: left; -} -ul.submenu .settings { - background: url("/images/icons/cog.png") no-repeat scroll 3px; - height: 16px; - padding-left: 20px; - padding-top: 0px; - text-align: left; -} - -ul.submenu .current_submenu { - border-bottom: 2px solid #556CB5; -} - -h2 { - margin: 20px 0 10px; - height: 30px; - line-height: 30px; - text-indent: 20px; - background: #FFF; - font-size: 1.2em; - border-top: dotted 1px #D5E1E6; - font-weight: bold; - color: #556CB5; -} - -h2.no-link { - color: #006699; -} - -h2.no-border { - color: #FFF; - background: #556CB5; - border: 0; -} - -h2 a { - font-weight: bold; - color: #006699; -} - -div.page-path { - text-align: right; - padding: 20px 30px 10px 0; - border: solid #d9d8d1; - border-width: 0px 0px 1px; - font-size: 1.2em; -} - -div.page-footer { - margin: 50px 0 0; - position: relative; - text-align: center; - font-weight: bold; - font-size: 90%; -} - -div.page-footer p { - position: relative; - left: 20px; - bottom: 5px; - font-size: 1.2em; -} - -ul.rss-logo { - position: absolute; - top: -10px; - right: 20px; - height: 20px; - list-style-type: none; -} - -ul.rss-logo li { - display: inline; -} - -ul.rss-logo li a { - padding: 3px 6px; - line-height: 10px; - border: 1px solid; - border-color: #fcc7a5 #7d3302 #3e1a01 #ff954e; - color: #ffffff; - background-color: #ff6600; - font-weight: bold; - font-family: sans-serif; - font-size: 10px; - text-align: center; - text-decoration: none; -} - -div.rss-logo li a:hover { - background-color: #ee5500; -} - -p.normal { - margin: 20px 0 20px 30px; - font-size: 1.2em; -} - -span.logtags span { - background-repeat: no-repeat; - height: 16px; - padding-left: 20px; - padding-top: 0px; - text-align: left; - font-weight: bold; -} - -span.logtags span.tagtag { - background-image: url("/images/icons/tag_green.png"); -} - -span.logtags span.branchtag { - background-image: url("/images/icons/arrow_branch.png"); - color: #628F53; -} - -span.logtags span.inbranchtag { - background-image: url("/images/icons/arrow_branch.png"); -} - -div.diff pre { - margin: 10px 0 0 0; -} - -div.diff pre span { - font-family: monospace; - white-space: pre; - font-size: 1.2em; - padding: 3px 0; -} - -td.source { - white-space: pre; - font-family: monospace; - margin: 10px 30px 0; - font-size: 1.2em; - font-family: monospace; -} - -div.source div.parity0,div.source div.parity1 { - padding: 1px; - font-size: 1.2em; -} - -div.source div.parity0 { - background: #F1F6F7; -} - -div.source div.parity1 { - background: #FFFFFF; -} - -div.parity0:hover,div.parity1:hover { - background: #D5E1E6; -} - -.linenr { - color: #999; - text-align: right; -} - -.lineno { - text-align: right; -} - -.lineno a { - color: #999; -} - -td.linenr { - width: 60px; -} - -div#powered-by { - position: absolute; - width: 75px; - top: 15px; - right: 20px; - font-size: 1.2em; -} - -div#powered-by a { - color: #EEE; - text-decoration: none; -} - -div#powered-by a:hover { - text-decoration: underline; -} - -dl.overview { - margin: 0 0 0 30px; - font-size: 1.1em; - overflow: hidden; -} - -dl.overview dt,dl.overview dd { - margin: 5px 0; - float: left; -} - -dl.overview dt { - clear: left; - font-weight: bold; - width: 150px; -} - -#clone_url { - border: 0px; -} - -/** end of summary **/ /** chagelog **/ -h3.changelog { - margin: 20px 0 5px 30px; - padding: 0 0 2px; - font-size: 1.4em; - border-bottom: dotted 1px #D5E1E6; -} - -ul.changelog-entry { - margin: 0 0 10px 30px; - list-style-type: none; - position: relative; -} - -ul.changelog-entry li span.revdate { - font-size: 1.1em; -} - -ul.changelog-entry li.age { - position: absolute; - top: -25px; - right: 10px; - font-size: 1.4em; - color: #CCC; - font-weight: bold; - font-style: italic; -} - -ul.changelog-entry li span.name { - font-size: 1.2em; - font-weight: bold; -} - -ul.changelog-entry li.description { - margin: 10px 0 0; - font-size: 1.1em; -} - -/** end of changelog **/ /** file **/ -p.files { - margin: 0 0 0 20px; - font-size: 2.0em; - font-weight: bold; -} - -/** end of file **/ /** changeset **/ -#changeset_content { - border:1px solid #CCCCCC; - padding:5px; -} - -#changeset_content .container .wrapper { - width: 600px; -} - -#changeset_content .container { - height: 120px; -} - -#changeset_content .container .left { - float: left; - width: 70%; - padding-left: 5px; -} - -#changeset_content .container .right { - float: right; - width: 25%; - text-align: right; -} - -#changeset_content .container .left .date { - font-weight: bold; -} - -#changeset_content .container .left .author { - -} - -#changeset_content .container .left .message { - font-style: italic; - color: #556CB5; -} - -.cs_files { - -} - -.cs_files .cs_added { - background: url("/images/icons/page_white_add.png") no-repeat scroll 3px; - /*background-color:#BBFFBB;*/ - height: 16px; - padding-left: 20px; - margin-top: 7px; - text-align: left; -} - -.cs_files .cs_changed { - background: url("/images/icons/page_white_edit.png") no-repeat scroll - 3px; - /*background-color: #FFDD88;*/ - height: 16px; - padding-left: 20px; - margin-top: 7px; - text-align: left; -} - -.cs_files .cs_removed { - background: url("/images/icons/page_white_delete.png") no-repeat scroll - 3px; - /*background-color: #FF8888;*/ - height: 16px; - padding-left: 20px; - margin-top: 7px; - text-align: left; -} - -/** end of changeset **/ /** canvas **/ - -#graph { - overflow: hidden; -} - -#graph_nodes { - width: 160px; - float: left; - margin-left:-50px; - margin-top: 5px; -} - -#graph_content { - width: 800px; - float: left; -} - -#graph_content .container_header { - border: 1px solid #CCCCCC; - height: 30px; - background: #EEEEEE; -} - -#graph_content .container .wrapper { - width: 600px; -} - -#graph_content .container { - border-bottom: 1px solid #CCCCCC; - border-left: 1px solid #CCCCCC; - border-right: 1px solid #CCCCCC; - min-height: 80px; - overflow: hidden; -} - -#graph_content .container .left { - float: left; - width: 70%; - padding-left: 5px; -} - -#graph_content .container .right { - float: right; - width: 25%; - text-align: right; -} - -#graph_content .container .left .date { - font-weight: bold; -} - -#graph_content .container .left .author { - -} - -#graph_content .container .left .message { - font-size: 80%; -} - -.right div { - clear: both; -} - -.right .changes .added,.changed,.removed { - border: 1px solid #DDDDDD; - display: block; - float: right; - font-size: 0.75em; - text-align: center; - min-width: 15px; -} - -.right .changes .added { - background: #BBFFBB; -} - -.right .changes .changed { - background: #FFDD88; -} - -.right .changes .removed { - background: #FF8888; -} - -.right .merge { - vertical-align: top; - font-size: 60%; - font-weight: bold; -} - -.right .merge img { - vertical-align: bottom; -} - -.right .parent { - font-size: 90%; - font-family: monospace; -} - -/** end of canvas **/ /* FILE BROWSER */ -div.browserblock { - overflow: hidden; - padding: 0px; - border: 1px solid #ccc; - background: #f8f8f8; - font-size: 100%; - line-height: 100%; - /* new */ - line-height: 125%; -} - -div.browserblock .browser-header { - border-bottom: 1px solid #CCCCCC; - background: #EEEEEE; - color: blue; - padding: 10px 0 10px 0; -} - -div.browserblock .browser-header span { - margin-left: 25px; - font-weight: bold; -} - -div.browserblock .browser-body { - background: #EEEEEE; -} - -table.code-browser { - border-collapse: collapse; - width: 100%; -} - -table.code-browser tr { - margin: 3px; -} - -table.code-browser thead th { - background-color: #EEEEEE; - height: 20px; - font-size: 1.1em; - font-weight: bold; - text-align: center; - text-align: left; - padding-left: 10px; -} - -table.code-browser tbody tr { - -} - -table.code-browser tbody td { - padding-left: 10px; - height: 20px; -} - -.info-table { - background: none repeat scroll 0 0 #FAFAFA; - border-bottom: 1px solid #DDDDDD; - width: 100%; -} - -.rss_logo { - background: url("/images/icons/rss_16.png") no-repeat scroll 3px; - height: 16px; - padding-left: 20px; - padding-top: 0px; - text-align: left; -} - -.atom_logo { - background: url("/images/icons/atom.png") no-repeat scroll 3px; - height: 16px; - padding-left: 20px; - padding-top: 0px; - text-align: left; -} - -.archive_logo { - background: url("/images/icons/compress.png") no-repeat scroll 3px; - height: 16px; - padding-left: 20px; - text-align: left; -} - -.browser-file { - background: url("/images/icons/document_16.png") no-repeat scroll 3px; - height: 16px; - padding-left: 20px; - text-align: left; -} - -.browser-dir { - background: url("/images/icons/folder_16.png") no-repeat scroll 3px; - height: 16px; - padding-left: 20px; - text-align: left; -} - -#repos_list { - border: 1px solid #556CB5; - background: #FFFFFF; -} \ No newline at end of file diff --git a/pylons_app/public/css/pygments.css b/pylons_app/public/css/pygments.css --- a/pylons_app/public/css/pygments.css +++ b/pylons_app/public/css/pygments.css @@ -22,6 +22,15 @@ div.codeblock .code-header .commit{ margin-left:25px; font-weight: normal; } +div.codeblock .code-body table{ + width: 0 !important; +} + +div.annotatediv{ + margin-left:2px; + margin-right:4px; +} + .code-highlight { padding: 0px; diff --git a/pylons_app/public/css/reset.css b/pylons_app/public/css/reset.css new file mode 100644 --- /dev/null +++ b/pylons_app/public/css/reset.css @@ -0,0 +1,53 @@ +/* http://meyerweb.com/eric/tools/css/reset/ */ +/* v1.0 | 20080212 */ + +html, body, div, span, applet, object, iframe, +h1, h2, h3, h4, h5, h6, p, blockquote, pre, +a, abbr, acronym, address, big, cite, code, +del, dfn, em, font, img, ins, kbd, q, s, samp, +small, strike, strong, sub, sup, tt, var, +b, u, i, center, +dl, dt, dd, ol, ul, li, +fieldset, form, label, legend, +table, caption, tbody, tfoot, thead, tr, th, td { + margin: 0; + padding: 0; + border: 0; + outline: 0; + font-size: 100%; + vertical-align: baseline; + background: transparent; +} +body { + line-height: 1; +} +ol, ul { + list-style: none; +} +blockquote, q { + quotes: none; +} +blockquote:before, blockquote:after, +q:before, q:after { + content: ''; + content: none; +} + +/* remember to define focus styles! */ +:focus { + outline: 0; +} + +/* remember to highlight inserts somehow! */ +ins { + text-decoration: none; +} +del { + text-decoration: line-through; +} + +/* tables still need 'cellspacing="0"' in the markup */ +table { + border-collapse: collapse; + border-spacing: 0; +} \ No newline at end of file diff --git a/pylons_app/public/css/style.css b/pylons_app/public/css/style.css new file mode 100644 --- /dev/null +++ b/pylons_app/public/css/style.css @@ -0,0 +1,3624 @@ +/* ----------------------------------------------------------- + main stylesheet +----------------------------------------------------------- */ + +html +{ + height: 100%; +} + +body +{ + margin: 0; + padding: 0; + height: 100%; + background: #d1d1d1 url("../images/background.png") repeat; + font-family: Lucida Grande, Verdana, Lucida Sans Regular, Lucida Sans Unicode, Arial, sans-serif; + font-size: 11px; +} + +/* ----------------------------------------------------------- + images +----------------------------------------------------------- */ + +img +{ + border: none; +} + +/* ----------------------------------------------------------- + anchors +----------------------------------------------------------- */ + +a +{ + color: #0066CC; + text-decoration: none; + cursor: pointer; +} + +a:hover +{ + color: #000000; + text-decoration: underline; +} + +/* ----------------------------------------------------------- + headings +----------------------------------------------------------- */ + +h1, h2, h3, h4, h5, h6 +{ + color: #292929; + font-weight: bold; +} + +h1 +{ + font-size: 22px; +} + +h2 +{ + font-size: 20px; +} + +h3 +{ + font-size: 18px; +} + +h4 +{ + font-size: 16px; +} + +h5 +{ + font-size: 14px; +} + +h6 +{ + font-size: 11px; +} + +/* ----------------------------------------------------------- + lists +----------------------------------------------------------- */ + +ul.circle { list-style-type: circle; } +ul.disc { list-style-type: disc; } +ul.square { list-style-type: square; } +ol.lower-roman { list-style-type: lower-roman; } +ol.upper-roman { list-style-type: upper-roman; } +ol.lower-alpha { list-style-type: lower-alpha; } +ol.upper-alpha { list-style-type: upper-alpha; } +ol.decimal { list-style-type: decimal; } + +/* ----------------------------------------------------------- + colors +----------------------------------------------------------- */ + +div.color +{ + margin: 7px 0 0 60px; + padding: 1px 1px 1px 0px; + clear: both; + overflow: hidden; + position: absolute; + background: #FFFFFF; +} + +div.color a +{ + margin: 0 0 0 1px; + padding: 0; + width: 15px; + height: 15px; + display: block; + float: left; +} + +div.color a.blue +{ + background: #376ea6; +} + +div.color a.green +{ + background: #85924b; +} + +div.color a.brown +{ + background: #9b6e42; +} + +div.color a.purple +{ + background: #88528b; +} + +div.color a.red +{ + background: #bd3220; +} + +div.color a.greyblue +{ + background: #566e86; +} + +/* ----------------------------------------------------------- + options +----------------------------------------------------------- */ + +div.options +{ + margin: 7px 0 0 162px; + padding: 0; + clear: both; + overflow: hidden; + position: absolute; + background: #FFFFFF; +} + +div.options a +{ + margin: 0; + padding: 3px 8px 3px 8px; + height: 1%; + display: block; + text-decoration: none; +} + +div.options a:hover +{ + text-decoration: none; +} + +/* ----------------------------------------------------------- + header +----------------------------------------------------------- */ + +#header +{ + margin: 0; + padding: 0 60px 0 60px; + background: #b0b0b0 url("../images/header_background.png") repeat; +} + + +/* ----------------------------------------------------------- + header -> user +----------------------------------------------------------- */ + +#header ul#logged-user +{ + margin: 0; + padding: 0; + float: right; +} + +#header ul#logged-user li +{ + margin: 0; + padding: 10px 12px 10px 12px; + list-style: none; + float: left; + border-left: 1px solid #bbbbbb; + border-right: 1px solid #a5a5a5; +} + +#header ul#logged-user li.first +{ + border-left: none; +} + +#header ul#logged-user li.last +{ + border-right: none; +} + +#header ul#logged-user li a +{ + color: #4e4e4e; + font-weight: bold; + text-decoration: none; +} + +#header ul#logged-user li a:hover +{ + color: #376ea6; + text-decoration: underline; +} + +#header ul#logged-user li.highlight a +{ + color: #ffffff; +} + +#header ul#logged-user li.highlight a:hover +{ + color: #376ea6; +} + +#header #header-inner +{ + margin: 0; + padding: 0; + height: 40px; + clear: both; + position: relative; + background: #003367 url("../images/colors/blue/header_inner.png") repeat-x; + border-bottom: 6px solid #ffffff; +} + +/* ----------------------------------------------------------- + header -> home +----------------------------------------------------------- */ + +#header #header-inner #home +{ + float: left; +} + +#header #header-inner #home a +{ + margin: 0; + padding: 0; + height: 40px; + width: 46px; + display: block; + background: url("../images/colors/blue/button_home.png"); + background-position: 0 0; +} + +#header #header-inner #home a:hover +{ + background-position: 0 -40px; +} + +/* ----------------------------------------------------------- + header -> logo +----------------------------------------------------------- */ + +#header #header-inner #logo +{ + float: left; +} + +#header #header-inner #logo h1 +{ + margin: 13px 0 0 13px; + padding: 0; + color: #FFFFFF; + font-size: 14px; + text-transform: uppercase; +} + +#header #header-inner #logo a +{ + color: #ffffff; + text-decoration: none; +} + +#header #header-inner #logo a:hover +{ + color: #dabf29; +} + +/* ----------------------------------------------------------- + header -> quick +----------------------------------------------------------- */ + +#header #header-inner #quick, +#header #header-inner #quick ul +{ + margin: 10px 5px 0 0; + padding: 0; + position: relative; + float: right; + list-style-type: none; + list-style-position: outside; +} + +#header #header-inner #quick li +{ + margin: 0 4px 0 0; + padding: 0; + position: relative; + float: left; +} + +#header #header-inner #quick li a +{ + top: 0; + left: 0; + padding: 0; + height: 1%; + display: block; + clear: both; + overflow: hidden; + background: #336699 url("../images/colors/blue/quick_l.png") no-repeat top left; + color: #FFFFFF; + font-weight: bold; + text-decoration: none; +} + +#header #header-inner #quick li span +{ + top: 0; + right: 0; + margin: 0; + padding: 10px 12px 8px 10px; + height: 1%; + display: block; + float: left; + background: url("../images/colors/blue/quick_r.png") no-repeat top right; + border-left: 1px solid #3f6f9f; +} + +#header #header-inner #quick li span.icon +{ + top: 0; + left: 0; + padding: 8px 8px 4px 8px; + background: url("../images/colors/blue/quick_l.png") no-repeat top left; + border-left: none; + border-right: 1px solid #2e5c89; +} + +#header #header-inner #quick li a:hover +{ + background: #4e4e4e; +} + +#header #header-inner #quick li a:hover span +{ + background: url("../images/colors/blue/quick_r_selected.png") no-repeat top right; + border-left: 1px solid #545454; +} + +#header #header-inner #quick li a:hover span.icon +{ + background: url("../images/colors/blue/quick_l_selected.png") no-repeat top left; + border-left: none; + border-right: 1px solid #464646; +} + +#header #header-inner #quick ul +{ + top: 29px; + right: 0; + margin: 0; + padding: 0; + width: 200px; + display: none; + position: absolute; + background: #FFFFFF; + border: 1px solid #666; + border-top: 1px solid #003367; +} + +#header #header-inner #quick li ul li +{ + border-bottom: 1px solid #dddddd; +} + +#header #header-inner #quick li ul li.last +{ + border: none; +} + +#header #header-inner #quick li ul li a.repos,#header #header-inner #quick li ul li a.repos:hover +{ + margin: 0; + padding: 12px 9px 7px 28px; + width: 167px; + background: #FFFFFF url("../images/icons/folder_edit.png") no-repeat 8px 9px; +} +#header #header-inner #quick li ul li a.users,#header #header-inner #quick li ul li a.users:hover +{ + margin: 0; + padding: 12px 9px 7px 28px; + width: 167px; + background: #FFFFFF url("../images/icons/user_edit.png") no-repeat 8px 9px; +} +#header #header-inner #quick li ul li a.settings,#header #header-inner #quick li ul li a.settings:hover +{ + margin: 0; + padding: 12px 9px 7px 28px; + width: 167px; + background: #FFFFFF url("../images/icons/cog.png") no-repeat 8px 9px; +} + +#header #header-inner #quick li ul li a.permissions,#header #header-inner #quick li ul li a.permissions:hover +{ + margin: 0; + padding: 12px 9px 7px 28px; + width: 167px; + background: #FFFFFF url("../images/icons/key.png") no-repeat 8px 9px; +} + +#header #header-inner #quick li ul li a +{ + margin: 0; + padding: 7px 9px 7px 9px; + height: 1%; + width: 182px; + height: auto; + display: block; + float: left; + background: #FFFFFF; + color: #0066CC; + font-weight: normal; +} + +#header #header-inner #quick li ul li a:hover +{ + color: #000000; + background: #FFFFFF; +} + +#header #header-inner #quick ul ul +{ + top: auto; +} + +#header #header-inner #quick li ul ul +{ + right: 200px; +} + +#header #header-inner #quick li:hover ul ul, +#header #header-inner #quick li:hover ul ul ul, +#header #header-inner #quick li:hover ul ul ul ul +{ + display: none; +} + +#header #header-inner #quick li:hover ul, +#header #header-inner #quick li li:hover ul, +#header #header-inner #quick li li li:hover ul, +#header #header-inner #quick li li li li:hover ul +{ + display: block; +} + +/* ----------------------------------------------------------- + header corners +----------------------------------------------------------- */ + +#header #header-inner div.corner +{ + height: 6px; + width: 6px; + position: absolute; + background: url("../images/colors/blue/header_inner_corners.png") no-repeat; +} + +#header #header-inner div.tl +{ + top: 0; + left: 0; + background-position: 0 0; +} + +#header #header-inner div.tr +{ + top: 0; + right: 0; + background-position: -6px 0; +} + +/* ----------------------------------------------------------- + content +----------------------------------------------------------- */ + +#content +{ + margin: 10px 0 0 0; + padding: 0; + min-height: 100%; + clear: both; + overflow: hidden; + background: url("../images/content.png") repeat-y top left; +} + +/* ----------------------------------------------------------- + content -> left +----------------------------------------------------------- */ + +#content #left +{ + left: 0; + width: 280px; + position: absolute; +} + +/* ----------------------------------------------------------- + content -> left -> menu +----------------------------------------------------------- */ + +#content #left #menu +{ + margin: 5px 10px 0 60px; + padding: 0; + clear: both; + overflow: hidden; +} + +/* ----------------------------------------------------------- + content -> left -> menu / heading +----------------------------------------------------------- */ + +#content #left #menu h6 +{ + margin: 5px 0 0 0; + padding: 0; + clear: both; + overflow: hidden; + background: #dfdfdf url("../images/menu.png") repeat-x; + color: #6e6e6e; +} + +#content #left #menu h6 a +{ + margin: 0; + padding: 0; + height: 1%; + display: block; + clear: both; + overflow: hidden; + background: url("../images/menu_l.png") no-repeat top left; + color: #6e6e6e; + text-decoration: none; +} + +#content #left #menu h6 span +{ + margin: 0; + padding: 9px 10px 10px 10px; + height: 1%; + display: block; + background: url("../images/menu_r.png") no-repeat top right; +} + +#content #left #menu h6.selected +{ + background: #00376e url("../images/colors/blue/menu_selected.png") repeat-x; + color: #FFFFFF; +} + +#content #left #menu h6.selected a +{ + background: url("../images/colors/blue/menu_l_selected.png") no-repeat top left; + color: #ffffff; +} + +#content #left #menu h6.selected span +{ + background: url("../images/colors/blue/menu_r_selected.png") no-repeat top right; +} + +/* ----------------------------------------------------------- + content -> left -> menu / links +----------------------------------------------------------- */ + +#content #left #menu ul +{ + margin: 0; + padding: 0; + background: #376ea6; +} + +#content #left #menu ul.opened +{ + display: block; +} + +#content #left #menu ul.closed +{ + display: none; +} + +#content #left #menu li +{ + margin: 0; + padding: 0; + clear: both; + overflow: hidden; + list-style: none; + border-bottom: 1px solid #5f8bb7; + color: #ffffff; +} + +#content #left #menu li a +{ + margin: 0 0 0 6px; + padding: 8px 0 8px 18px; + height: 1%; + display: block; + float: left; + background: url("../images/colors/colors/blue/menu_arrow.png") no-repeat 0 9px; + color: #ffffff; + text-decoration: none; +} + +#content #left #menu li a:hover +{ + color: #b9dcff; +} + +/* ----------------------------------------------------------- + content -> left -> menu / collapsible +----------------------------------------------------------- */ + +#content #left #menu li.collapsible +{ + background: url("../images/colors/blue/menu_border.png") no-repeat top left; +} + +#content #left #menu li.collapsible a +{ + margin: 0 0 0 6px; + padding: 8px 0 8px 0; + height: 1%; + display: block; + background: transparent; + float: left; + font-weight: bold; +} + +#content #left #menu li.collapsible a.plus +{ + margin: 0; + padding: 8px 0 9px 24px; + height: 10px; + width: 10px; + display: block; + float: left; + background: url("../images/menu_plus.png") no-repeat 5px 10px; + border: none; +} + +#content #left #menu li.collapsible a.minus +{ + margin: 0; + padding: 8px 0 9px 24px; + height: 10px; + width: 10px; + display: block; + float: left; + background: url("../images/menu_minus.png") no-repeat 5px 10px; + border: none; +} + +#content #left #menu li ul +{ + margin: 0; + padding: 0; + border-left: 18px solid #285889; +} + +#content #left #menu li ul.expanded +{ + display: block; +} + +#content #left #menu li ul.collapsed +{ + display: none; +} + +#content #left #menu li ul li +{ + margin: 0; + padding: 0; + clear: both; + overflow: hidden; + list-style: none; + border-bottom: 1px solid #5f8bb7; + color: #ffffff; +} + +#content #left #menu li.collapsible ul li a +{ + font-weight: normal; +} + +#content #left #menu li.last +{ + border-bottom: none; +} + +/* ----------------------------------------------------------- + content -> left -> date picker +----------------------------------------------------------- */ + +#content #left #date-picker +{ + margin: 10px 10px 0 60px; + padding: 0; + clear: both; + overflow: hidden; +} + +#content #left #date-picker .ui-datepicker +{ + width: auto; + padding: 0; + clear: both; + overflow: hidden; + background: #FFFFFF; + border: 1px solid #d1d1d1; +} + +#content #left #date-picker .ui-datepicker .ui-datepicker-header +{ + padding: 5px 0; +} + +#content #left #date-picker .ui-datepicker .ui-datepicker-prev +{ + top: 5px; + left: 4px; +} + +#content #left #date-picker .ui-datepicker .ui-datepicker-next +{ + top: 5px; + right: 4px; +} + +#content #left #date-picker .ui-datepicker .ui-datepicker-prev-hover +{ + top: 5px; + left: 4px; +} + +#content #left #date-picker .ui-datepicker .ui-datepicker-next-hover +{ + top: 5px; + right: 4px; +} + +/* ----------------------------------------------------------- + content -> right +----------------------------------------------------------- */ + +#content #right +{ + margin: 0 60px 10px 290px; +} + +/* ----------------------------------------------------------- + content -> right -> box +----------------------------------------------------------- */ + +#content div.box +{ + margin: 0 0 10px 0; + padding: 0 0 10px 0; + clear: both; + overflow: hidden; + background: #ffffff; +} + +#content div.box-left +{ + margin: 0 0 10px; + width: 49%; + clear: none; + float: left; +} + +#content div.box-right +{ + margin: 0 0 10px; + width: 49%; + clear: none; + float: right; +} + +/* ----------------------------------------------------------- + content -> right -> box / title +----------------------------------------------------------- */ + +#content div.box div.title +{ + margin: 0 0 20px 0; + padding: 0; + clear: both; + overflow: hidden; + background: #336699 url("../images/colors/blue/title.png") repeat-x; +} + +#content div.box div.title h5 +{ + margin: 0; + padding: 11px 0 11px 10px; + float: left; + border: none; + color: #ffffff; + text-transform: uppercase; +} + +#content div.box div.title ul.links +{ + margin: 0; + padding: 0; + float: right; +} + +#content div.box div.title ul.links li +{ + margin: 0; + padding: 0; + list-style: none; + float: left; +} + +#content div.box div.title ul.links li a +{ + margin: 0; + padding: 13px 16px 12px 16px; + height: 1%; + display: block; + float: left; + background: url("../images/colors/blue/title_link.png") no-repeat top left; + border-left: 1px solid #316293; + color: #ffffff; + font-size: 11px; + font-weight: bold; + text-decoration: none; +} + +#content div.box div.title ul.links li a:hover +{ + color: #bfe3ff; +} + +#content div.box div.title ul.links li.ui-tabs-selected a +{ + background: url("../../../resources/images/colors/blue/title_tab_selected.png") no-repeat bottom center; + color: #bfe3ff; +} + +/* ----------------------------------------------------------- + content -> right -> box / headings +----------------------------------------------------------- */ + +#content div.box h1, +#content div.box h2, +#content div.box h3, +#content div.box h4, +#content div.box h5, +#content div.box h6 +{ + margin: 10px 20px 10px 20px; + padding: 0 0 15px 0; + clear: both; + overflow: hidden; + border-bottom: 1px solid #DDDDDD; +} + +/* ----------------------------------------------------------- + content -> right -> box / paragraphs +----------------------------------------------------------- */ + +#content div.box p +{ + margin: 0 24px 10px 24px; + padding: 0; + color: #5f5f5f; + font-size: 12px; + line-height: 150%; +} + +#content div.box blockquote +{ + margin: 0 34px 0 34px; + padding: 0 0 0 14px; + border-left: 4px solid #DDDDDD; + color: #5f5f5f; + font-size: 11px; + line-height: 150%; +} + +#content div.box blockquote p +{ + margin: 10px 0 10px 0; + padding: 0; +} + +/* ----------------------------------------------------------- + content -> right -> box / lists +----------------------------------------------------------- */ + +#content div.box dl +{ + margin: 10px 24px 10px 24px; +} + +#content div.box dt +{ + margin: 0; + font-size: 12px; +} + +#content div.box dd +{ + margin: 0; + padding: 8px 0 8px 15px; + font-size: 12px; +} + +#content div.box ul.left +{ + float: left; +} + +#content div.box ol.left +{ + float: left; +} + +#content div.box li +{ + padding: 4px 0 4px 0; + font-size: 12px; +} + +#content div.box ol.lower-roman, +#content div.box ol.upper-roman +{ + margin: 10px 24px 10px 44px; +} + +#content div.box ol.lower-alpha, +#content div.box ol.upper-alpha +{ + margin: 10px 24px 10px 44px; +} + +#content div.box ol.decimal +{ + margin: 10px 24px 10px 44px; +} + +#content div.box ul.disc, +#content div.box ul.circle +{ + margin: 10px 24px 10px 38px; +} + +#content div.box ul.square +{ + margin: 10px 24px 10px 40px; +} + +/* ----------------------------------------------------------- + content -> right -> box / images +----------------------------------------------------------- */ + +#content div.box img.left +{ + margin: 10px 10px 10px 0; + border: none; + float: left; +} + +#content div.box img.right +{ + margin: 10px 0 10px 10px; + border: none; + float: right; +} + +/* ----------------------------------------------------------- + content -> right -> box / messages +----------------------------------------------------------- */ + +#content div.box div.messages +{ + margin: 0 20px 0 20px; + padding: 0; + clear: both; + overflow: hidden; +} + +#content div.box div.message +{ + margin: 0 0 10px 0; + padding: 0; + clear: both; + overflow: hidden; +} + +#content div.box div.message div.image +{ + margin: 9px 0 0 5px; + padding: 6px; + float: left; +} + +#content div.box div.message div.image img +{ + margin: 0; + vertical-align: middle; +} + +#content div.box div.message div.text +{ + margin: 0; + padding: 9px 6px 9px 6px; + float: left; +} + +#content div.box div.message div.dismiss +{ + margin: 0; + padding: 0; + float: right; +} + +#content div.box div.message div.dismiss a +{ + margin: 15px 14px 0 0; + padding: 0; + height: 16px; + width: 16px; + display: block; + background: url("../images/icons/cross.png") no-repeat; +} + +#content div.box div.message div.text h1, +#content div.box div.message div.text h2, +#content div.box div.message div.text h3, +#content div.box div.message div.text h4, +#content div.box div.message div.text h5, +#content div.box div.message div.text h6 +{ + margin: 0; + padding: 0px; + border: none; +} + +#content div.box div.message div.text span +{ + margin: 0; + padding: 5px 0 0 0; + height: 1%; + display: block; +} + +#content div.box div.message-error +{ + height: 1%; + clear: both; + overflow: hidden; + background: #FBE3E4; + border: 1px solid #FBC2C4; + color: #860006; +} + +#content div.box div.message-error h6 +{ + color: #860006; +} + +#content div.box div.message-warning +{ + height: 1%; + clear: both; + overflow: hidden; + background: #FFF6BF; + border: 1px solid #FFD324; + color: #5f5200; +} + +#content div.box div.message-warning h6 +{ + color: #5f5200; +} + +#content div.box div.message-notice +{ + height: 1%; + clear: both; + overflow: hidden; + background: #8FBDE0; + border: 1px solid #6BACDE; + color: #003863; +} + +#content div.box div.message-notice h6 +{ + color: #003863; +} + +#content div.box div.message-success +{ + height: 1%; + clear: both; + overflow: hidden; + background: #E6EFC2; + border: 1px solid #C6D880; + color: #4e6100; +} + +#content div.box div.message-success h6 +{ + color: #4e6100; +} + +/* ----------------------------------------------------------- + content -> right -> box / forms +----------------------------------------------------------- */ + +#content div.box div.form +{ + margin: 0; + padding: 0 20px 10px 20px; + clear: both; + overflow: hidden; +} + +#content div.box div.form div.fields +{ + margin: 0; + padding: 0; + clear: both; + overflow: hidden; +} + +#content div.box div.form div.fields div.field +{ + margin: 0; + padding: 10px 0 10px 0; + height: 1%; + border-bottom: 1px solid #DDDDDD; + clear: both; + overflow: hidden; +} + +#content div.box div.form div.fields div.field-first +{ + padding: 0 0 10px 0; +} + +#content div.box div.form div.fields div.field span.error-message +{ + margin: 8px 0 0 0; + padding: 0; + height: 1%; + display: block; + color: #FF0000; +} + +#content div.box div.form div.fields div.field span.success +{ + margin: 8px 0 0 0; + padding: 0; + height: 1%; + display: block; + color: #316309; +} + +/* ----------------------------------------------------------- + content -> right -> forms -> labels +----------------------------------------------------------- */ + +#content div.box div.form div.fields div.field div.label +{ + left: 310px; + margin: 0; + padding: 8px 0 0 5px; + width: auto; + position: absolute; +} + +#content div.box-left div.form div.fields div.field div.label, +#content div.box-right div.form div.fields div.field div.label +{ + left: 0; + margin: 0; + padding: 0 0 8px 0; + width: auto; + position: relative; +} + +/* ----------------------------------------------------------- + content -> right -> forms -> label (select) +----------------------------------------------------------- */ + +#content div.box div.form div.fields div.field div.label-select +{ + padding: 2px 0 0 5px; +} + +#content div.box-left div.form div.fields div.field div.label-select, +#content div.box-right div.form div.fields div.field div.label-select +{ + padding: 0 0 8px 0; +} + +/* ----------------------------------------------------------- + content -> right -> forms -> label (checkbox) +----------------------------------------------------------- */ + +#content div.box div.form div.fields div.field div.label-checkbox +{ + padding: 0 0 0 5px; +} + +/* ----------------------------------------------------------- + content -> right -> forms -> label (radio) +----------------------------------------------------------- */ + +#content div.box div.form div.fields div.field div.label-radio +{ + padding: 0 0 0 5px; +} + +/* ----------------------------------------------------------- + content -> right -> forms -> label (textarea) +----------------------------------------------------------- */ + +#content div.box div.form div.fields div.field div.label-textarea +{ + padding: 0 0 0 5px; +} + +#content div.box-left div.form div.fields div.field div.label-textarea, +#content div.box-right div.form div.fields div.field div.label-textarea +{ + padding: 0 0 8px 0; +} + +/* ----------------------------------------------------------- + content -> right -> forms -> labels (label) +----------------------------------------------------------- */ + +#content div.box div.form div.fields div.field div.label label +{ + color: #393939; + font-weight: bold; +} + +#content div.box div.form div.fields div.field div.label span +{ + margin: 0; + padding: 2px 0 0 0; + height: 1%; + display: block; + color: #363636; +} + +/* ----------------------------------------------------------- + content -> right -> forms -> input +----------------------------------------------------------- */ + +#content div.box div.form div.fields div.field div.input +{ + margin: 0 0 0 200px; + padding: 0; +} + +#content div.box-left div.form div.fields div.field div.input, +#content div.box-right div.form div.fields div.field div.input +{ + margin: 0; + padding: 7px 7px 6px 7px; + border-top: 1px solid #b3b3b3; + border-left: 1px solid #b3b3b3; + border-right: 1px solid #eaeaea; + border-bottom: 1px solid #eaeaea; +} + +#content div.box div.form div.fields div.field div.input input +{ + margin: 0; + padding: 7px 7px 6px 7px; + background: #FFFFFF; + border-top: 1px solid #b3b3b3; + border-left: 1px solid #b3b3b3; + border-right: 1px solid #eaeaea; + border-bottom: 1px solid #eaeaea; + color: #000000; + font-family: Lucida Grande, Verdana, Lucida Sans Regular, Lucida Sans Unicode, Arial, sans-serif; + font-size: 11px; +} + +#content div.box-left div.form div.fields div.field div.input input, +#content div.box-right div.form div.fields div.field div.input input +{ + width: 100%; + padding: 0; + border: none; +} + +#content div.box div.form div.fields div.field div.input input.small +{ + width: 30%; +} + +#content div.box div.form div.fields div.field div.input input.medium +{ + width: 55%; +} + +#content div.box div.form div.fields div.field div.input input.large +{ + width: 85%; +} + +#content div.box div.form div.fields div.field div.input input.date +{ + width: 177px; +} + +#content div.box div.form div.fields div.field div.input input.button +{ + margin: 0; + padding: 4px 8px 4px 8px; + background: #D4D0C8; + border-top: 1px solid #FFFFFF; + border-left: 1px solid #FFFFFF; + border-right: 1px solid #404040; + border-bottom: 1px solid #404040; + color: #000000; +} + +#content div.box div.form div.fields div.field div.input input.error +{ + background: #FBE3E4; + border-top: 1px solid #e1b2b3; + border-left: 1px solid #e1b2b3; + border-right: 1px solid #FBC2C4; + border-bottom: 1px solid #FBC2C4; +} + +#content div.box div.form div.fields div.field div.input input.success +{ + background: #E6EFC2; + border-top: 1px solid #cebb98; + border-left: 1px solid #cebb98; + border-right: 1px solid #c6d880; + border-bottom: 1px solid #c6d880; +} + +#content div.box div.form div.fields div.field div.input img.ui-datepicker-trigger +{ + margin: 0 0 0 6px; +} + +/* ----------------------------------------------------------- + content -> right -> forms -> input (file styling) +----------------------------------------------------------- */ + +#content div.box div.form div.fields div.field div.input a.ui-input-file +{ + margin: 0 0 0 6px; + padding: 0; + width: 28px; + height: 28px; + display: inline; + position: absolute; + overflow: hidden; + cursor: pointer; + background: #e5e3e3 url("../images/button_browse.png") no-repeat; + border: none; + text-decoration: none; +} + +#content div.box div.form div.fields div.field div.input a:hover.ui-input-file +{ + background: #e5e3e3 url("../images/button_browse_selected.png") no-repeat; +} + +/* ----------------------------------------------------------- + content -> right -> forms -> textarea +----------------------------------------------------------- */ + +#content div.box div.form div.fields div.field div.textarea +{ + margin: 0 0 0 200px; + padding: 10px; + border-top: 1px solid #b3b3b3; + border-left: 1px solid #b3b3b3; + border-right: 1px solid #eaeaea; + border-bottom: 1px solid #eaeaea; +} + +#content div.box div.form div.fields div.field div.textarea-editor +{ + padding: 0; + border: 1px solid #dddddd; +} + +#content div.box-left div.form div.fields div.field div.textarea, +#content div.box-right div.form div.fields div.field div.textarea +{ + margin: 0; +} + +#content div.box div.form div.fields div.field div.textarea textarea +{ + margin: 0; + padding: 0; + width: 100%; + height: 220px; + overflow: hidden; + background: #FFFFFF; + border-width: 0; + color: #000000; + font-family: Lucida Grande, Verdana, Lucida Sans Regular, Lucida Sans Unicode, Arial, sans-serif; + font-size: 11px; + outline: none; +} + +#content div.box-left div.form div.fields div.field div.textarea textarea, +#content div.box-right div.form div.fields div.field div.textarea textarea +{ + width: 100%; + height: 100px; +} + +#content div.box div.form div.fields div.field div.textarea textarea.error +{ + padding: 3px 10px 10px 23px; + background-color: #FBE3E4; + background-image: url("../../../resources/images/icons/exclamation.png"); + background-repeat: no-repeat; + background-position: 3px 3px; + border: 1px solid #FBC2C4; +} + +#content div.box div.form div.fields div.field div.textarea textarea.success +{ + padding: 3px 10px 10px 23px; + background-color: #E6EFC2; + background-image: url("../../../resources/images/icons/accept.png"); + background-repeat: no-repeat; + background-position: 3px 3px; + border: 1px solid #C6D880; +} + +/* ----------------------------------------------------------- + content -> right -> forms -> textarea (tinymce editor) +----------------------------------------------------------- */ + +#content div.box div.form div.fields div.field div.textarea table +{ + margin: 0; + padding: 0; + width: 100%; + border: none; +} + +#content div.box div.form div.fields div.field div.textarea table td +{ + padding: 0; + background: #DDDDDD; + border: none; +} + +#content div.box div.form div.fields div.field div.textarea table td table +{ + margin: 0; + padding: 0; + width: auto; + border: none; +} + +#content div.box div.form div.fields div.field div.textarea table td table td +{ + padding: 5px 5px 5px 0; + font-family: Lucida Grande, Verdana, Lucida Sans Regular, Lucida Sans Unicode, Arial, sans-serif; + font-size: 11px; +} + +#content div.box div.form div.fields div.field div.textarea table td table td a +{ + border: none; +} + +#content div.box div.form div.fields div.field div.textarea table td table td a.mceButtonActive +{ + background: #b1b1b1; +} + +/* ----------------------------------------------------------- + content -> right -> forms -> select +----------------------------------------------------------- */ + +#content div.box div.form div.fields div.field div.select +{ + margin: 0 0 0 200px; + padding: 0; +} + +#content div.box div.form div.fields div.field div.select a:hover +{ + color: #000000; + text-decoration: none; +} + +#content div.box div.form div.fields div.field div.select select +{ + margin: 0; +} + +/* ----------------------------------------------------------- + content -> right -> forms -> select (jquery styling) +----------------------------------------------------------- */ + +#content div.box div.form div.fields div.field div.select a.ui-selectmenu-focus +{ + border: 1px solid #666666; +} + +#content div.box div.form div.fields div.field div.select a.ui-selectmenu +{ + color: #565656; + text-decoration: none; +} + +#content div.box div.form div.fields div.field div.select a.ui-selectmenu:hover +{ + color: #000000; + text-decoration: none; +} + +#content div.box div.form div.fields div.field div.select a.ui-selectmenu-focus span.ui-icon +{ + background-image: url(../images/ui/ui-icons_222222_256x240.png); +} + +/* ----------------------------------------------------------- + content -> right -> forms -> element focus +----------------------------------------------------------- */ + +#content div.box div.form div.fields div.field input[type=text]:focus, +#content div.box div.form div.fields div.field input[type=password]:focus, +#content div.box div.form div.fields div.field input[type=file]:focus, +#content div.box div.form div.fields div.field textarea:focus, +#content div.box div.form div.fields div.field select:focus +{ + background: #f6f6f6; + border-color: #666; +} + +/* ----------------------------------------------------------- + content -> right -> forms -> checkboxes +----------------------------------------------------------- */ + +#content div.box div.form div.fields div.field div.checkboxes +{ + margin: 0 0 0 200px; + padding: 0; +} + +#content div.box div.form div.fields div.field div.checkboxes div.checkbox +{ + margin: 0; + padding: 2px 0 2px 0; + clear: both; + overflow: hidden; +} + +#content div.box div.form div.fields div.field div.checkboxes div.checkbox input +{ + margin: 0; + float: left; +} + +#content div.box div.form div.fields div.field div.checkboxes div.checkbox label +{ + margin: 3px 0 0 4px; + height: 1%; + display: block; + float: left; +} + +/* ----------------------------------------------------------- + content -> right -> forms -> radios +----------------------------------------------------------- */ + +#content div.box div.form div.fields div.field div.radios +{ + margin: 0 0 0 200px; + padding: 0; +} + +#content div.box div.form div.fields div.field div.radios div.radio +{ + margin: 0; + padding: 2px 0 2px 0; + clear: both; + overflow: hidden; +} + +#content div.box div.form div.fields div.field div.radios div.radio input +{ + margin: 0; + float: left; +} + +#content div.box div.form div.fields div.field div.radios div.radio label +{ + margin: 3px 0 0 4px; + height: 1%; + display: block; + float: left; +} + +/* ----------------------------------------------------------- + content -> right -> forms -> buttons +----------------------------------------------------------- */ + +#content div.box div.form div.fields div.buttons +{ + margin: 10px 0 0 200px; + padding: 0; +} + +#content div.box-left div.form div.fields div.buttons, +#content div.box-right div.form div.fields div.buttons +{ + margin: 10px 0 0 0; +} + +#content div.box div.form div.fields div.buttons input +{ + margin: 0; + color: #000000; + font-family: Lucida Grande, Verdana, Lucida Sans Regular, Lucida Sans Unicode, Arial, sans-serif; + font-size: 11px; + font-weight: bold; +} + +/* ----------------------------------------------------------- + content -> right -> forms -> buttons (jquery styling) +----------------------------------------------------------- */ + +#content div.box div.form div.fields div.buttons input.ui-state-default +{ + margin: 0; + padding: 6px 12px 6px 12px; + background: #e5e3e3 url("../images/button.png") repeat-x; + border-top: 1px solid #DDDDDD; + border-left: 1px solid #c6c6c6; + border-right: 1px solid #DDDDDD; + border-bottom: 1px solid #c6c6c6; + color: #515151; + outline: none; +} + +#content div.box div.form div.fields div.buttons input.ui-state-hover +{ + margin: 0; + padding: 6px 12px 6px 12px; + background: #b4b4b4 url("../images/button_selected.png") repeat-x; + border-top: 1px solid #cccccc; + border-left: 1px solid #bebebe; + border-right: 1px solid #b1b1b1; + border-bottom: 1px solid #afafaf; + color: #515151; + outline: none; +} + +#content div.box div.form div.fields div.buttons div.highlight +{ + display: inline; +} + +#content div.box div.form div.fields div.buttons div.highlight input.ui-state-default +{ + margin: 0; + padding: 6px 12px 6px 12px; + background: #4e85bb url("../images/colors/blue/button_highlight.png") repeat-x; + border-top: 1px solid #5c91a4; + border-left: 1px solid #2a6f89; + border-right: 1px solid #2b7089; + border-bottom: 1px solid #1a6480; + color: #FFFFFF; +} + +#content div.box div.form div.fields div.buttons div.highlight input.ui-state-hover +{ + margin: 0; + padding: 6px 12px 6px 12px; + background: #46a0c1 url("../images/colors/blue/button_highlight_selected.png") repeat-x; + border-top: 1px solid #78acbf; + border-left: 1px solid #34819e; + border-right: 1px solid #35829f; + border-bottom: 1px solid #257897; + color: #FFFFFF; +} + +/* ----------------------------------------------------------- + content -> right -> box / tables +----------------------------------------------------------- */ + +#content div.box div.table +{ + margin: 0; + padding: 0 20px 10px 20px; + clear: both; + overflow: hidden; +} + +#content div.box table +{ + margin: 0; + padding: 0; + width: 100%; + border-collapse: collapse; +} + +#content div.box table th +{ + padding: 10px; + background: #eeeeee; + border-bottom: 1px solid #dddddd; +} + +#content div.box table th.left +{ + text-align: left; +} + +#content div.box table th.right +{ + text-align: right; +} + +#content div.box table th.center +{ + text-align: center; +} + +#content div.box table th.selected +{ + padding: 0; + vertical-align: middle; +} + +#content div.box table th.selected input +{ + margin: 0; +} + +#content div.box table td +{ + padding: 5px; + background: #ffffff; + border-bottom: 1px solid #cdcdcd; +} + +#content div.box table tr.selected td +{ + background: #FFFFCC; +} + +#content div.box table td.selected +{ + padding: 0; + width: 3%; + text-align: center; + vertical-align: middle; +} + +#content div.box table td.selected input +{ + margin: 0; +} + +#content div.box table td.action +{ + width: 45%; + text-align: left; +} + +#content div.box table td.user +{ + width: 10%; + text-align: center; +} + +#content div.box table td.date +{ + width: 33%; + text-align: center; +} + +#content div.box table td.address +{ + width: 10%; + text-align: center; +} + +/* ----------------------------------------------------------- + content -> right -> box / table action +----------------------------------------------------------- */ + +#content div.box div.action +{ + margin: 10px 0 0 0; + padding: 0; + float: right; + background: #FFFFFF; + text-align: right; +} + +#content div.box div.action a:hover +{ + color: #000000; + text-decoration: none; +} + +#content div.box div.action select +{ + margin: 0; + font-family: Lucida Grande, Verdana, Lucida Sans Regular, Lucida Sans Unicode, Arial, sans-serif; + font-size: 11px; +} + +#content div.box div.action div.button +{ + margin: 6px 0 0 0; + padding: 0; + text-align: right; +} + +#content div.box div.action div.button input +{ + margin: 0; + color: #000000; + font-family: Lucida Grande, Verdana, Lucida Sans Regular, Lucida Sans Unicode, Arial, sans-serif; + font-size: 11px; + font-weight: bold; +} + +#content div.box div.action div.button input.ui-state-default +{ + margin: 0; + padding: 6px 12px 6px 12px; + background: #e5e3e3 url("../images/button.png") repeat-x; + border-top: 1px solid #DDDDDD; + border-left: 1px solid #c6c6c6; + border-right: 1px solid #DDDDDD; + border-bottom: 1px solid #c6c6c6; + color: #515151; +} + +#content div.box div.action div.button input.ui-state-hover +{ + margin: 0; + padding: 6px 12px 6px 12px; + background: #b4b4b4 url("../images/button_selected.png") repeat-x; + border-top: 1px solid #cccccc; + border-left: 1px solid #bebebe; + border-right: 1px solid #b1b1b1; + border-bottom: 1px solid #afafaf; + color: #515151; +} + +#content div.box div.action .ui-selectmenu +{ + margin: 0; + padding: 0; +} + +#content div.box div.action a.ui-selectmenu-focus +{ + border: 1px solid #666666; +} + +#content div.box div.action a.ui-selectmenu-focus span.ui-icon +{ + background-image: url(../images/ui/ui-icons_222222_256x240.png); +} + +/* ----------------------------------------------------------- + content -> right -> pagination +----------------------------------------------------------- */ + +#content div.box div.pagination +{ + margin: 10px 0 0 0; + padding: 0; + height: 1%; + clear: both; + overflow: hidden; +} + +#content div.box div.pagination div.results +{ + margin: 0; + padding: 0; + text-align: left; + float: left +} + +#content div.box div.pagination div.results span +{ + margin: 0; + padding: 6px 8px 6px 8px; + height: 1%; + display: block; + float: left; + background: #ebebeb url("../images/pager.png") repeat-x; + border-top: 1px solid #dedede; + border-left: 1px solid #cfcfcf; + border-right: 1px solid #c4c4c4; + border-bottom: 1px solid #c4c4c4; + color: #4A4A4A; + font-weight: bold; +} + +#content div.box div.pagination ul.pager +{ + margin: 0; + padding: 0; + float: right; + text-align: right; +} + +#content div.box div.pagination ul.pager li +{ + margin: 0 0 0 4px; + padding: 0; + height: 1%; + float: left; + list-style: none; + background: #ebebeb url("../images/pager.png") repeat-x; + border-top: 1px solid #dedede; + border-left: 1px solid #cfcfcf; + border-right: 1px solid #c4c4c4; + border-bottom: 1px solid #c4c4c4; + color: #4A4A4A; + font-weight: bold; +} + +#content div.box div.pagination ul.pager li.separator +{ + padding: 6px; +} + +#content div.box div.pagination ul.pager li.current +{ + padding: 6px; + background: #b4b4b4 url("../images/pager_selected.png") repeat-x; + border-top: 1px solid #cccccc; + border-left: 1px solid #bebebe; + border-right: 1px solid #b1b1b1; + border-bottom: 1px solid #afafaf; + color: #515151; +} + +#content div.box div.pagination ul.pager li.disabled +{ + padding: 6px; + color: #B4B4B4; +} + +#content div.box div.pagination ul.pager li a +{ + margin: 0; + padding: 6px; + height: 1%; + display: block; + float: left; + color: #515151; + text-decoration: none; +} + +#content div.box div.pagination ul.pager li a:hover, +#content div.box div.pagination ul.pager li a:active +{ + margin: -1px; + background: #b4b4b4 url("../images/pager_selected.png") repeat-x; + border-top: 1px solid #cccccc; + border-left: 1px solid #bebebe; + border-right: 1px solid #b1b1b1; + border-bottom: 1px solid #afafaf; +} + +/* ----------------------------------------------------------- + content -> webhelpers pagination +----------------------------------------------------------- */ + +#content div.box div.pagination-wh +{ + margin: 10px 0 0 0; + padding: 0; + height: 1%; + clear: both; + overflow: hidden; + text-align: right; +} + +#content div.box div.pagination-wh div.results +{ + margin: 0; + padding: 0; + text-align: left; + float: left +} + +#content div.box div.pagination-wh div.results span +{ + margin: 0; + padding: 6px 8px 6px 8px; + height: 1%; + display: block; + float: left; + background: #ebebeb url("../images/pager.png") repeat-x; + border-top: 1px solid #dedede; + border-left: 1px solid #cfcfcf; + border-right: 1px solid #c4c4c4; + border-bottom: 1px solid #c4c4c4; + color: #4A4A4A; + font-weight: bold; +} + +#content div.box div.pagination-left{ + float:left; +} +#content div.box div.pagination-right{ + float:right; +} + +#content div.box div.pagination-wh a, +#content div.box div.pagination-wh span.pager_dotdot +{ + margin: 0 0 0 4px; + padding: 6px; + height: 1%; + float: left; + background: #ebebeb url("../images/pager.png") repeat-x; + border-top: 1px solid #dedede; + border-left: 1px solid #cfcfcf; + border-right: 1px solid #c4c4c4; + border-bottom: 1px solid #c4c4c4; + color: #4A4A4A; + font-weight: bold; +} +#content div.box div.pagination-wh span.pager_curpage +{ + margin: 0 0 0 4px; + padding: 6px; + height: 1%; + float: left; + background: #b4b4b4 url("../images/pager_selected.png") repeat-x; + border-top: 1px solid #cccccc; + border-left: 1px solid #bebebe; + border-right: 1px solid #b1b1b1; + border-bottom: 1px solid #afafaf; + color: #515151; + font-weight: bold; +} + +#content div.box div.pagination-wh a.disabled +{ + padding: 6px; + color: #B4B4B4; +} + + +#content div.box div.pagination-wh a:hover, +#content div.box div.pagination-wh a:active +{ + background: #b4b4b4 url("../images/pager_selected.png") repeat-x; + border-top: 1px solid #cccccc; + border-left: 1px solid #bebebe; + border-right: 1px solid #b1b1b1; + border-bottom: 1px solid #afafaf; + text-decoration: none; +} + + +/* ----------------------------------------------------------- + content -> right -> traffic chart +----------------------------------------------------------- */ + +#content div.box div.traffic +{ + margin: 0; + padding: 0 20px 10px 20px; + clear: both; + overflow: hidden; +} + +#content div.box div.traffic div.legend +{ + margin: 0 0 10px 0; + padding: 0 0 10px 0; + clear: both; + overflow: hidden; + border-bottom: 1px solid #dddddd; +} + +#content div.box div.traffic div.legend h6 +{ + margin: 0; + padding: 0; + float: left; + border: none; +} + +#content div.box div.traffic div.legend ul +{ + margin: 0; + padding: 0; + float: right; +} + +#content div.box div.traffic div.legend li +{ + margin: 0; + padding: 0 8px 0 4px; + list-style: none; + float: left; + font-size: 11px; +} + +#content div.box div.traffic div.legend li.visits +{ + border-left: 12px solid #edc240; +} + +#content div.box div.traffic div.legend li.pageviews +{ + border-left: 12px solid #afd8f8; +} + +#content div.box div.traffic table +{ + width: auto; +} + +#content div.box div.traffic table td +{ + padding: 2px 3px 3px 3px; + background: transparent; + border: none; +} + +#content div.box div.traffic table td.legendLabel +{ + padding: 0 3px 2px 3px; +} + +/* ----------------------------------------------------------- + footer +----------------------------------------------------------- */ + +#footer +{ + margin: 0; + padding: 5px 0 5px 0; + clear: both; + overflow: hidden; + background: #2a2a2a; + text-align: right; +} + +#footer p +{ + margin: 0 80px 0 80px; + padding: 10px 0 10px 0; + color: #ffffff; +} + +/* ----------------------------------------------------------- + login +----------------------------------------------------------- */ + +#login +{ + margin: 10% auto 0 auto; + padding: 0; + width: 420px; +} + +/* ----------------------------------------------------------- + login -> colors +----------------------------------------------------------- */ + +#login div.color +{ + margin: 10px auto 0 auto; + padding: 3px 3px 3px 0; + clear: both; + overflow: hidden; + background: #FFFFFF; +} + +#login div.color a +{ + margin: 0 0 0 3px; + padding: 0; + width: 20px; + height: 20px; + display: block; + float: left; +} + +/* ----------------------------------------------------------- + login -> title +----------------------------------------------------------- */ + +#login div.title +{ + margin: 0 auto; + padding: 0; + width: 420px; + clear: both; + overflow: hidden; + position: relative; + background: #003367 url("../images/colors/blue/header_inner.png") repeat-x; +} + +#login div.title h5 +{ + margin: 10px; + padding: 0; + color: #ffffff; +} + +/* ----------------------------------------------------------- + login -> title / corners +----------------------------------------------------------- */ + +#login div.title div.corner +{ + height: 6px; + width: 6px; + position: absolute; + background: url("../images/colors/blue/login_corners.png") no-repeat; +} + +#login div.title div.tl +{ + top: 0; + left: 0; + background-position: 0 0; +} + +#login div.title div.tr +{ + top: 0; + right: 0; + background-position: -6px 0; +} + +#login div.inner +{ + margin: 0 auto; + padding: 20px; + width: 380px; + background: #FFFFFF url("../images/login.png") no-repeat top left; + border-top: none; + border-bottom: none; +} + +/* ----------------------------------------------------------- + login -> form +----------------------------------------------------------- */ + +#login div.form +{ + margin: 0; + padding: 0; + clear: both; + overflow: hidden; +} + +#login div.form div.fields +{ + margin: 0; + padding: 0; + clear: both; + overflow: hidden; +} + +#login div.form div.fields div.field +{ + margin: 0; + padding: 0 0 10px 0; + clear: both; + overflow: hidden; +} + +#login div.form div.fields div.field span.error-message +{ + margin: 8px 0 0 0; + padding: 0; + height: 1%; + display: block; + color: #FF0000; +} + +#login div.form div.fields div.field div.label +{ + margin: 2px 10px 0 0; + padding: 5px 0 0 5px; + width: 173px; + float: left; + text-align: right; +} + +#login div.form div.fields div.field div.label label +{ + color: #000000; + font-weight: bold; +} + +#login div.form div.fields div.field div.label span +{ + margin: 0; + padding: 2px 0 0 0; + height: 1%; + display: block; + color: #363636; +} + +#login div.form div.fields div.field div.input +{ + margin: 0; + padding: 0; + float: left; +} + +#login div.form div.fields div.field div.input input +{ + margin: 0; + padding: 7px 7px 6px 7px; + width: 176px; + background: #FFFFFF; + border-top: 1px solid #b3b3b3; + border-left: 1px solid #b3b3b3; + border-right: 1px solid #eaeaea; + border-bottom: 1px solid #eaeaea; + color: #000000; + font-family: Lucida Grande, Verdana, Lucida Sans Regular, Lucida Sans Unicode, Arial, sans-serif; + font-size: 11px; +} + +#login div.form div.fields div.field div.input input.error +{ + background: #FBE3E4; + border-top: 1px solid #e1b2b3; + border-left: 1px solid #e1b2b3; + border-right: 1px solid #FBC2C4; + border-bottom: 1px solid #FBC2C4; +} + +#login div.form div.fields div.field div.input input.success +{ + background: #E6EFC2; + border-top: 1px solid #cebb98; + border-left: 1px solid #cebb98; + border-right: 1px solid #c6d880; + border-bottom: 1px solid #c6d880; +} + +#login div.form div.fields div.field div.input div.link +{ + margin: 6px 0 0 0; + padding: 0; + text-align: right; +} + +#login div.form div.fields div.field div.checkbox +{ + margin: 0 0 0 184px; + padding: 0; +} + +#login div.form div.fields div.field div.checkbox label +{ + color: #565656; + font-weight: bold; +} + +#login div.form div.fields div.buttons +{ + margin: 0; + padding: 10px 0 0 0; + clear: both; + overflow: hidden; + border-top: 1px solid #DDDDDD; + text-align: right; +} + +#login div.form div.fields div.buttons input +{ + margin: 0; + color: #000000; + font-size: 1.0em; + font-weight: bold; + font-family: Verdana, Helvetica, Sans-Serif; +} + +#login div.form div.fields div.buttons input.ui-state-default +{ + margin: 0; + padding: 6px 12px 6px 12px; + background: #e5e3e3 url("../images/button.png") repeat-x; + border-top: 1px solid #DDDDDD; + border-left: 1px solid #c6c6c6; + border-right: 1px solid #DDDDDD; + border-bottom: 1px solid #c6c6c6; + color: #515151; +} + +#login div.form div.fields div.buttons input.ui-state-hover +{ + margin: 0; + padding: 6px 12px 6px 12px; + background: #b4b4b4 url("../images/button_selected.png") repeat-x; + border-top: 1px solid #cccccc; + border-left: 1px solid #bebebe; + border-right: 1px solid #b1b1b1; + border-bottom: 1px solid #afafaf; + color: #515151; +} + +/* ----------------------------------------------------------- + login -> links +----------------------------------------------------------- */ + +#login div.form div.links +{ + margin: 10px 0 0 0; + padding: 0 0 2px 0; + clear: both; + overflow: hidden; +} + +/* ----------------------------------------------------------- + register +----------------------------------------------------------- */ + +#register +{ + margin: 10% auto 0 auto; + padding: 0; + width: 420px; +} + +/* ----------------------------------------------------------- + register -> colors +----------------------------------------------------------- */ + +#register div.color +{ + margin: 10px auto 0 auto; + padding: 3px 3px 3px 0; + clear: both; + overflow: hidden; + background: #FFFFFF; +} + +#register div.color a +{ + margin: 0 0 0 3px; + padding: 0; + width: 20px; + height: 20px; + display: block; + float: left; +} + +/* ----------------------------------------------------------- + register -> title +----------------------------------------------------------- */ + +#register div.title +{ + margin: 0 auto; + padding: 0; + width: 420px; + clear: both; + overflow: hidden; + position: relative; + background: #003367 url("../images/colors/blue/header_inner.png") repeat-x; +} + +#register div.title h5 +{ + margin: 10px; + padding: 0; + color: #ffffff; +} + +/* ----------------------------------------------------------- + register -> inner +----------------------------------------------------------- */ +#register div.title div.corner +{ + height: 6px; + width: 6px; + position: absolute; + background: url("../images/colors/blue/login_corners.png") no-repeat; +} + +#register div.title div.tl +{ + top: 0; + left: 0; + background-position: 0 0; +} + +#register div.title div.tr +{ + top: 0; + right: 0; + background-position: -6px 0; + +} +#register div.inner +{ + margin: 0 auto; + padding: 20px; + width: 380px; + background: #FFFFFF; + border-top: none; + border-bottom: none; +} + +/* ----------------------------------------------------------- + register -> form +----------------------------------------------------------- */ + +#register div.form +{ + margin: 0; + padding: 0; + clear: both; + overflow: hidden; +} + +#register div.form div.fields +{ + margin: 0; + padding: 0; + clear: both; + overflow: hidden; +} + +#register div.form div.fields div.field +{ + margin: 0; + padding: 0 0 10px 0; + clear: both; + overflow: hidden; +} + +#register div.form div.fields div.field span.error-message +{ + margin: 8px 0 0 0; + padding: 0; + height: 1%; + display: block; + color: #FF0000; +} + +#register div.form div.fields div.field div.label +{ + margin: 2px 10px 0 0; + padding: 5px 0 0 5px; + width: 82px; + float: left; + text-align: right; +} + +#register div.form div.fields div.field div.label label +{ + color: #000000; + font-weight: bold; +} + +#register div.form div.fields div.field div.label span +{ + margin: 0; + padding: 2px 0 0 0; + height: 1%; + display: block; + color: #363636; +} + +#register div.form div.fields div.field div.input +{ + margin: 0; + padding: 0; + float: left; +} + +#register div.form div.fields div.field div.input input +{ + margin: 0; + padding: 7px 7px 6px 7px; + width: 266px; + background: #FFFFFF; + border-top: 1px solid #b3b3b3; + border-left: 1px solid #b3b3b3; + border-right: 1px solid #eaeaea; + border-bottom: 1px solid #eaeaea; + color: #000000; + font-family: Lucida Grande, Verdana, Lucida Sans Regular, Lucida Sans Unicode, Arial, sans-serif; + font-size: 11px; +} + +#register div.form div.fields div.field div.input input.error +{ + background: #FBE3E4; + border-top: 1px solid #e1b2b3; + border-left: 1px solid #e1b2b3; + border-right: 1px solid #FBC2C4; + border-bottom: 1px solid #FBC2C4; +} + +#register div.form div.fields div.field div.input input.success +{ + background: #E6EFC2; + border-top: 1px solid #cebb98; + border-left: 1px solid #cebb98; + border-right: 1px solid #c6d880; + border-bottom: 1px solid #c6d880; +} + +#register div.form div.fields div.field div.input div.link +{ + margin: 6px 0 0 0; + padding: 0; + text-align: right; +} + +#register div.form div.fields div.field div.checkbox +{ + margin: 0 0 0 184px; + padding: 0; +} + +#register div.form div.fields div.field div.checkbox label +{ + color: #565656; + font-weight: bold; +} + +#register div.form div.fields div.buttons +{ + margin: 0; + padding: 10px 0 0 97px; + clear: both; + overflow: hidden; + border-top: 1px solid #DDDDDD; + text-align: left; +} + +#register div.form div.fields div.buttons input +{ + margin: 0; + color: #000000; + font-size: 1.0em; + font-weight: bold; + font-family: Verdana, Helvetica, Sans-Serif; +} + +#register div.form div.fields div.buttons input.ui-state-default +{ + margin: 0; + padding: 6px 12px 6px 12px; + background: #e5e3e3 url("../images/button.png") repeat-x; + border-top: 1px solid #DDDDDD; + border-left: 1px solid #c6c6c6; + border-right: 1px solid #DDDDDD; + border-bottom: 1px solid #c6c6c6; + color: #515151; +} +#register div.form div.fields div.buttons div.highlight input.ui-state-default +{ + background:url("../images/colors/blue/button_highlight.png") repeat-x scroll 0 0 #4E85BB; + border-color:#5C91A4 #2B7089 #1A6480 #2A6F89; + border-style:solid; + border-width:1px; + color:#FFFFFF; +} + + + +#register div.form div.fields div.buttons input.ui-state-hover +{ + margin: 0; + padding: 6px 12px 6px 12px; + background: #b4b4b4 url("../images/button_selected.png") repeat-x; + border-top: 1px solid #cccccc; + border-left: 1px solid #bebebe; + border-right: 1px solid #b1b1b1; + border-bottom: 1px solid #afafaf; + color: #515151; +} + + +/* ----------------------------------------------------------- + CHANGESETS +----------------------------------------------------------- */ +#changeset_content { + border:1px solid #CCCCCC; + padding:5px; +} + +#changeset_content .container .wrapper { + width: 600px; +} + +#changeset_content .container { + height: 120px; +} + +#changeset_content .container .left { + float: left; + width: 70%; + padding-left: 5px; +} + +#changeset_content .container .right { + float: right; + width: 25%; + text-align: right; +} + +#changeset_content .container .left .date { + font-weight: bold; +} + +#changeset_content .container .left .author { + +} + +#changeset_content .container .left .message { + font-style: italic; + color: #556CB5; +} + +.cs_files { + +} + +.cs_files .cs_added { + background: url("/images/icons/page_white_add.png") no-repeat scroll 3px; + /*background-color:#BBFFBB;*/ + height: 16px; + padding-left: 20px; + margin-top: 7px; + text-align: left; +} + +.cs_files .cs_changed { + background: url("/images/icons/page_white_edit.png") no-repeat scroll + 3px; + /*background-color: #FFDD88;*/ + height: 16px; + padding-left: 20px; + margin-top: 7px; + text-align: left; +} + +.cs_files .cs_removed { + background: url("/images/icons/page_white_delete.png") no-repeat scroll + 3px; + /*background-color: #FF8888;*/ + height: 16px; + padding-left: 20px; + margin-top: 7px; + text-align: left; +} + + + +/* ----------------------------------------------------------- + CHANGESETS - CANVAS +----------------------------------------------------------- */ + +#graph { + overflow: hidden; +} + +#graph_nodes { + width: 160px; + float: left; + margin-left:-50px; + margin-top: 5px; +} + +#graph_content { + width: 800px; + float: left; +} + +#graph_content .container_header { + border: 1px solid #CCCCCC; + padding:10px; +} + +#graph_content .container .wrapper { + width: 600px; +} + +#graph_content .container { + border-bottom: 1px solid #CCCCCC; + border-left: 1px solid #CCCCCC; + border-right: 1px solid #CCCCCC; + min-height: 80px; + overflow: hidden; +} + +#graph_content .container .left { + float: left; + width: 70%; + padding-left: 5px; +} + +#graph_content .container .right { + float: right; + width: 25%; + text-align: right; +} + +#graph_content .container .left .date { + font-weight: bold; +} + +#graph_content .container .left .author { + +} + +#graph_content .container .left .message { + font-size: 80%; +} + +.right div { + clear: both; +} + +.right .changes .added,.changed,.removed { + border: 1px solid #DDDDDD; + display: block; + float: right; + font-size: 0.75em; + text-align: center; + min-width: 15px; +} + +.right .changes .added { + background: #BBFFBB; +} + +.right .changes .changed { + background: #FFDD88; +} + +.right .changes .removed { + background: #FF8888; +} + +.right .merge { + vertical-align: top; + font-size: 60%; + font-weight: bold; +} + +.right .merge img { + vertical-align: bottom; +} + +.right .parent { + font-size: 90%; + font-family: monospace; +} + + + +/* ----------------------------------------------------------- + FILE BROWSER +----------------------------------------------------------- */ +div.browserblock { + overflow: hidden; + padding: 0px; + border: 1px solid #ccc; + background: #f8f8f8; + font-size: 100%; + line-height: 100%; + /* new */ + line-height: 125%; +} + +div.browserblock .browser-header { + border-bottom: 1px solid #CCCCCC; + background: #FFFFFF; + color: blue; + padding: 10px 0 10px 0; +} + +div.browserblock .browser-header span { + margin-left: 25px; + font-weight: bold; +} + +div.browserblock .browser-body { + background: #EEEEEE; +} + +table.code-browser { + border-collapse: collapse; + width: 100%; +} + +table.code-browser tr { + margin: 3px; +} + +table.code-browser thead th { + background-color: #EEEEEE; + height: 20px; + font-size: 1.1em; + font-weight: bold; + text-align: center; + text-align: left; + padding-left: 10px; +} + +table.code-browser tbody tr { + +} + +table.code-browser tbody td { + padding-left: 10px; + height: 20px; +} +table.code-browser .browser-file { + background: url("/images/icons/document_16.png") no-repeat scroll 3px; + height: 16px; + padding-left: 20px; + text-align: left; +} + +table.code-browser .browser-dir { + background: url("/images/icons/folder_16.png") no-repeat scroll 3px; + height: 16px; + padding-left: 20px; + text-align: left; +} + + +/* ----------------------------------------------------------- + INFOBOX +----------------------------------------------------------- */ +.info_box *{ + background:url("../../images/pager.png") repeat-x scroll 0 0 #EBEBEB; + border-color:#DEDEDE #C4C4C4 #C4C4C4 #CFCFCF; + border-style:solid; + border-width:1px; + color:#4A4A4A; + display:block; + font-weight:bold; + height:1%; + padding:4px 6px; + display: inline; +} +.info_box span{ + margin-left:3px; + margin-righ:3px; +} +.info_box input { + padding:3px 6px; +} + +/* ----------------------------------------------------------- + TOOLTIP +----------------------------------------------------------- */ +.yui-overlay,.yui-panel-container { + visibility: hidden; + position: absolute; + z-index: 2; +} + +.yui-tt { + visibility: hidden; + position: absolute; + color: #666666; + background-color: #FFFFFF; + font-family: arial, helvetica, verdana, sans-serif; + padding: 8px; + border: 2px solid #556CB5; + font: 100% sans-serif; + width: auto; + opacity: 1.0; +} + +.yui-tt-shadow { + display: none; +} + +/* ----------------------------------------------------------- + AUTOCOMPLETE +----------------------------------------------------------- */ + +.ac{ + vertical-align: top; + +} +.ac .match { + font-weight:bold; +} + +.ac .yui-ac { + position: relative; + font-family: arial; + font-size: 100%; +} + +.ac .perm_ac{ + width:15em; +} +/* styles for input field */ +.ac .yui-ac-input { + width: 100%; +} + +/* styles for results container */ +.ac .yui-ac-container { + position: absolute; + top: 1.6em; + width: 100%; +} + +/* styles for header/body/footer wrapper within container */ +.ac .yui-ac-content { + position: absolute; + width: 100%; + border: 1px solid #808080; + background: #fff; + overflow: hidden; + z-index: 9050; +} + +/* styles for container shadow */ +.ac .yui-ac-shadow { + position: absolute; + margin: .3em; + width: 100%; + background: #000; + -moz-opacity: 0.10; + opacity: .10; + filter: alpha(opacity = 10); + z-index: 9049; +} + +/* styles for results list */ +.ac .yui-ac-content ul { + margin: 0; + padding: 0; + width: 100%; +} + +/* styles for result item */ +.ac .yui-ac-content li { + margin: 0; + padding: 2px 5px; + cursor: default; + white-space: nowrap; +} + +/* styles for prehighlighted result item */ +.ac .yui-ac-content li.yui-ac-prehighlight { + background: #B3D4FF; +} + +/* styles for highlighted result item */ +.ac .yui-ac-content li.yui-ac-highlight { + background: #556CB5; + color: #FFF; +} + + +/* ----------------------------------------------------------- + ACTION ICONS +----------------------------------------------------------- */ +.add_icon { + background: url("/images/icons/add.png") no-repeat scroll 3px ; + height: 16px; + padding-left: 20px; + padding-top: 1px; + text-align: left; +} + +.edit_icon { + background: url("/images/icons/folder_edit.png") no-repeat scroll 3px; + height: 16px; + padding-left: 20px; + padding-top: 1px; + text-align: left; +} + +.delete_icon { + background: url("/images/icons/delete.png") no-repeat scroll 3px; + height: 16px; + padding-left: 20px; + padding-top: 1px; + text-align: left; +} + +.rss_icon { + background: url("/images/icons/rss_16.png") no-repeat scroll 3px; + height: 16px; + padding-left: 20px; + padding-top: 1px; + text-align: left; +} + +.atom_icon { + background: url("/images/icons/atom.png") no-repeat scroll 3px; + height: 16px; + padding-left: 20px; + padding-top: 1px; + text-align: left; +} + +.archive_icon { + background: url("/images/icons/compress.png") no-repeat scroll 3px; + height: 16px; + padding-left: 20px; + text-align: left; + padding-top: 1px; +} + + + + +.action_button { + border: 0px; + display: block; +} + +.action_button:hover { + border: 0px; + font-style: italic; + cursor: pointer; +} + +/* ----------------------------------------------------------- + BREADCRUMBS +----------------------------------------------------------- */ + +.breadcrumbs{ + border:medium none; + color:#FFFFFF; + float:left; + margin:0; + padding:11px 0 11px 10px; + text-transform:uppercase; + font-weight: bold; + font-size: 14px; +} +.breadcrumbs a{ + color: #FFFFFF; +} + + +/* ----------------------------------------------------------- + FLASH MSG +----------------------------------------------------------- */ +.flash_msg ul { + margin: 0; + padding: 0px 0px 10px 0px; +} + +.error_msg { + background-color: #FFCFCF; + background-image: url("/images/icons/error_msg.png"); + border: 1px solid #FF9595; + color: #CC3300; +} + +.warning_msg { + background-color: #FFFBCC; + background-image: url("/images/icons/warning_msg.png"); + border: 1px solid #FFF35E; + color: #C69E00; +} + +.success_msg { + background-color: #D5FFCF; + background-image: url("/images/icons/success_msg.png"); + border: 1px solid #97FF88; + color: #009900; +} + +.notice_msg { + background-color: #DCE3FF; + background-image: url("/images/icons/notice_msg.png"); + border: 1px solid #93A8FF; + color: #556CB5; +} + +.success_msg,.error_msg,.notice_msg,.warning_msg { + background-position: 10px center; + background-repeat: no-repeat; + font-size: 12px; + font-weight: bold; + min-height: 14px; + line-height: 14px; + margin-bottom: 0px; + margin-top: 0px; + padding: 6px 10px 6px 40px; + display: block; + overflow: auto; +} + +#msg_close { + background: transparent url("icons/cross_grey_small.png") no-repeat + scroll 0 0; + cursor: pointer; + height: 16px; + position: absolute; + right: 5px; + top: 5px; + width: 16px; +} +/* ----------------------------------------------------------- + YUI FLOT +----------------------------------------------------------- */ + +div#commit_history{ + float: left; +} +div#legend_data{ + float:left; + +} +div#legend_container { + float: left; +} + +div#legend_container table,div#legend_choices table{ + width:auto !important; +} + +div#legend_container table td{ + border: none !important; + padding: 2px !important; +} + +div#legend_choices table td{ + border: none !important; + padding: 0px !important; +} + +div#legend_choices{ + float:left; +} + +/* ----------------------------------------------------------- + PERMISSIONS TABLE +----------------------------------------------------------- */ +table#permissions_manage{ + width: 0 !important; + +} +table#permissions_manage span.private_repo_msg{ + style="font-size: 0.8em" +} +table#permissions_manage tr#add_perm_input td{ + vertical-align:middle; + +} + + +/* ----------------------------------------------------------- + jquery ui +----------------------------------------------------------- */ + +.ui-helper-hidden { display: none; } +.ui-helper-hidden-accessible { position: absolute; left: -99999999px; } +.ui-icon { display: block; text-indent: -99999px; overflow: hidden; background-repeat: no-repeat; } + +/* ----------------------------------------------------------- + jquery ui -> icons +----------------------------------------------------------- */ + +.ui-icon { width: 16px; height: 16px; background-image: url(../images/ui/ui-icons_222222_256x240.png); } +.ui-widget-content .ui-icon {background-image: url(../images/ui/ui-icons_222222_256x240.png); } +.ui-widget-header .ui-icon {background-image: url(../images/ui/ui-icons_222222_256x240.png); } +.ui-state-default .ui-icon { background-image: url(../images/ui/ui-icons_ef8c08_256x240.png); } +.ui-state-hover .ui-icon, .ui-state-focus .ui-icon { background-image: url(../images/ui/ui-icons_ef8c08_256x240.png); } +.ui-state-active .ui-icon {background-image: url(../images/ui/ui-icons_ef8c08_256x240.png); } +.ui-state-highlight .ui-icon {background-image: url(../images/ui/ui-icons_228ef1_256x240.png); } +.ui-state-error .ui-icon, .ui-state-error-text .ui-icon {background-image: url(../images/ui/ui-icons_ffd27a_256x240.png); } + +/* ----------------------------------------------------------- + jquery ui -> icon positioning +----------------------------------------------------------- */ +.ui-icon-carat-1-n { background-position: 0 0; } +.ui-icon-carat-1-ne { background-position: -16px 0; } +.ui-icon-carat-1-e { background-position: -32px 0; } +.ui-icon-carat-1-se { background-position: -48px 0; } +.ui-icon-carat-1-s { background-position: -64px 0; } +.ui-icon-carat-1-sw { background-position: -80px 0; } +.ui-icon-carat-1-w { background-position: -96px 0; } +.ui-icon-carat-1-nw { background-position: -112px 0; } +.ui-icon-carat-2-n-s { background-position: -128px 0; } +.ui-icon-carat-2-e-w { background-position: -144px 0; } +.ui-icon-triangle-1-n { background-position: 0 -16px; } +.ui-icon-triangle-1-ne { background-position: -16px -16px; } +.ui-icon-triangle-1-e { background-position: -32px -16px; } +.ui-icon-triangle-1-se { background-position: -48px -16px; } +.ui-icon-triangle-1-s { background-position: -64px -16px; } +.ui-icon-triangle-1-sw { background-position: -80px -16px; } +.ui-icon-triangle-1-w { background-position: -96px -16px; } +.ui-icon-triangle-1-nw { background-position: -112px -16px; } +.ui-icon-triangle-2-n-s { background-position: -128px -16px; } +.ui-icon-triangle-2-e-w { background-position: -144px -16px; } +.ui-icon-arrow-1-n { background-position: 0 -32px; } +.ui-icon-arrow-1-ne { background-position: -16px -32px; } +.ui-icon-arrow-1-e { background-position: -32px -32px; } +.ui-icon-arrow-1-se { background-position: -48px -32px; } +.ui-icon-arrow-1-s { background-position: -64px -32px; } +.ui-icon-arrow-1-sw { background-position: -80px -32px; } +.ui-icon-arrow-1-w { background-position: -96px -32px; } +.ui-icon-arrow-1-nw { background-position: -112px -32px; } +.ui-icon-arrow-2-n-s { background-position: -128px -32px; } +.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; } +.ui-icon-arrow-2-e-w { background-position: -160px -32px; } +.ui-icon-arrow-2-se-nw { background-position: -176px -32px; } +.ui-icon-arrowstop-1-n { background-position: -192px -32px; } +.ui-icon-arrowstop-1-e { background-position: -208px -32px; } +.ui-icon-arrowstop-1-s { background-position: -224px -32px; } +.ui-icon-arrowstop-1-w { background-position: -240px -32px; } +.ui-icon-arrowthick-1-n { background-position: 0 -48px; } +.ui-icon-arrowthick-1-ne { background-position: -16px -48px; } +.ui-icon-arrowthick-1-e { background-position: -32px -48px; } +.ui-icon-arrowthick-1-se { background-position: -48px -48px; } +.ui-icon-arrowthick-1-s { background-position: -64px -48px; } +.ui-icon-arrowthick-1-sw { background-position: -80px -48px; } +.ui-icon-arrowthick-1-w { background-position: -96px -48px; } +.ui-icon-arrowthick-1-nw { background-position: -112px -48px; } +.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; } +.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; } +.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; } +.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; } +.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; } +.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; } +.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; } +.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; } +.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; } +.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; } +.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; } +.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; } +.ui-icon-arrowreturn-1-w { background-position: -64px -64px; } +.ui-icon-arrowreturn-1-n { background-position: -80px -64px; } +.ui-icon-arrowreturn-1-e { background-position: -96px -64px; } +.ui-icon-arrowreturn-1-s { background-position: -112px -64px; } +.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; } +.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; } +.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; } +.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; } +.ui-icon-arrow-4 { background-position: 0 -80px; } +.ui-icon-arrow-4-diag { background-position: -16px -80px; } +.ui-icon-extlink { background-position: -32px -80px; } +.ui-icon-newwin { background-position: -48px -80px; } +.ui-icon-refresh { background-position: -64px -80px; } +.ui-icon-shuffle { background-position: -80px -80px; } +.ui-icon-transfer-e-w { background-position: -96px -80px; } +.ui-icon-transferthick-e-w { background-position: -112px -80px; } +.ui-icon-folder-collapsed { background-position: 0 -96px; } +.ui-icon-folder-open { background-position: -16px -96px; } +.ui-icon-document { background-position: -32px -96px; } +.ui-icon-document-b { background-position: -48px -96px; } +.ui-icon-note { background-position: -64px -96px; } +.ui-icon-mail-closed { background-position: -80px -96px; } +.ui-icon-mail-open { background-position: -96px -96px; } +.ui-icon-suitcase { background-position: -112px -96px; } +.ui-icon-comment { background-position: -128px -96px; } +.ui-icon-person { background-position: -144px -96px; } +.ui-icon-print { background-position: -160px -96px; } +.ui-icon-trash { background-position: -176px -96px; } +.ui-icon-locked { background-position: -192px -96px; } +.ui-icon-unlocked { background-position: -208px -96px; } +.ui-icon-bookmark { background-position: -224px -96px; } +.ui-icon-tag { background-position: -240px -96px; } +.ui-icon-home { background-position: 0 -112px; } +.ui-icon-flag { background-position: -16px -112px; } +.ui-icon-calendar { background-position: -32px -112px; } +.ui-icon-cart { background-position: -48px -112px; } +.ui-icon-pencil { background-position: -64px -112px; } +.ui-icon-clock { background-position: -80px -112px; } +.ui-icon-disk { background-position: -96px -112px; } +.ui-icon-calculator { background-position: -112px -112px; } +.ui-icon-zoomin { background-position: -128px -112px; } +.ui-icon-zoomout { background-position: -144px -112px; } +.ui-icon-search { background-position: -160px -112px; } +.ui-icon-wrench { background-position: -176px -112px; } +.ui-icon-gear { background-position: -192px -112px; } +.ui-icon-heart { background-position: -208px -112px; } +.ui-icon-star { background-position: -224px -112px; } +.ui-icon-link { background-position: -240px -112px; } +.ui-icon-cancel { background-position: 0 -128px; } +.ui-icon-plus { background-position: -16px -128px; } +.ui-icon-plusthick { background-position: -32px -128px; } +.ui-icon-minus { background-position: -48px -128px; } +.ui-icon-minusthick { background-position: -64px -128px; } +.ui-icon-close { background-position: -80px -128px; } +.ui-icon-closethick { background-position: -96px -128px; } +.ui-icon-key { background-position: -112px -128px; } +.ui-icon-lightbulb { background-position: -128px -128px; } +.ui-icon-scissors { background-position: -144px -128px; } +.ui-icon-clipboard { background-position: -160px -128px; } +.ui-icon-copy { background-position: -176px -128px; } +.ui-icon-contact { background-position: -192px -128px; } +.ui-icon-image { background-position: -208px -128px; } +.ui-icon-video { background-position: -224px -128px; } +.ui-icon-script { background-position: -240px -128px; } +.ui-icon-alert { background-position: 0 -144px; } +.ui-icon-info { background-position: -16px -144px; } +.ui-icon-notice { background-position: -32px -144px; } +.ui-icon-help { background-position: -48px -144px; } +.ui-icon-check { background-position: -64px -144px; } +.ui-icon-bullet { background-position: -80px -144px; } +.ui-icon-radio-off { background-position: -96px -144px; } +.ui-icon-radio-on { background-position: -112px -144px; } +.ui-icon-pin-w { background-position: -128px -144px; } +.ui-icon-pin-s { background-position: -144px -144px; } +.ui-icon-play { background-position: 0 -160px; } +.ui-icon-pause { background-position: -16px -160px; } +.ui-icon-seek-next { background-position: -32px -160px; } +.ui-icon-seek-prev { background-position: -48px -160px; } +.ui-icon-seek-end { background-position: -64px -160px; } +.ui-icon-seek-start { background-position: -80px -160px; } +/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */ +.ui-icon-seek-first { background-position: -80px -160px; } +.ui-icon-stop { background-position: -96px -160px; } +.ui-icon-eject { background-position: -112px -160px; } +.ui-icon-volume-off { background-position: -128px -160px; } +.ui-icon-volume-on { background-position: -144px -160px; } +.ui-icon-power { background-position: 0 -176px; } +.ui-icon-signal-diag { background-position: -16px -176px; } +.ui-icon-signal { background-position: -32px -176px; } +.ui-icon-battery-0 { background-position: -48px -176px; } +.ui-icon-battery-1 { background-position: -64px -176px; } +.ui-icon-battery-2 { background-position: -80px -176px; } +.ui-icon-battery-3 { background-position: -96px -176px; } +.ui-icon-circle-plus { background-position: 0 -192px; } +.ui-icon-circle-minus { background-position: -16px -192px; } +.ui-icon-circle-close { background-position: -32px -192px; } +.ui-icon-circle-triangle-e { background-position: -48px -192px; } +.ui-icon-circle-triangle-s { background-position: -64px -192px; } +.ui-icon-circle-triangle-w { background-position: -80px -192px; } +.ui-icon-circle-triangle-n { background-position: -96px -192px; } +.ui-icon-circle-arrow-e { background-position: -112px -192px; } +.ui-icon-circle-arrow-s { background-position: -128px -192px; } +.ui-icon-circle-arrow-w { background-position: -144px -192px; } +.ui-icon-circle-arrow-n { background-position: -160px -192px; } +.ui-icon-circle-zoomin { background-position: -176px -192px; } +.ui-icon-circle-zoomout { background-position: -192px -192px; } +.ui-icon-circle-check { background-position: -208px -192px; } +.ui-icon-circlesmall-plus { background-position: 0 -208px; } +.ui-icon-circlesmall-minus { background-position: -16px -208px; } +.ui-icon-circlesmall-close { background-position: -32px -208px; } +.ui-icon-squaresmall-plus { background-position: -48px -208px; } +.ui-icon-squaresmall-minus { background-position: -64px -208px; } +.ui-icon-squaresmall-close { background-position: -80px -208px; } +.ui-icon-grip-dotted-vertical { background-position: 0 -224px; } +.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; } +.ui-icon-grip-solid-vertical { background-position: -32px -224px; } +.ui-icon-grip-solid-horizontal { background-position: -48px -224px; } +.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; } +.ui-icon-grip-diagonal-se { background-position: -80px -224px; } + +/* ----------------------------------------------------------- + jquery ui -> tabs +----------------------------------------------------------- */ +.ui-tabs .ui-tabs-hide { display: none; } + +/* ----------------------------------------------------------- + jquery ui -> datepicker +----------------------------------------------------------- */ +.ui-datepicker { width: 17em; padding: .2em .2em 0; background: #FFFFFF; border: 1px solid #000000; border-top: none; } +.ui-datepicker .ui-datepicker-header { position:relative; padding:.2em 0; background: #F6F6F6; } +.ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next { position:absolute; top: 1px; width: 1.8em; height: 1.8em; } +.ui-datepicker .ui-datepicker-prev-hover, .ui-datepicker .ui-datepicker-next-hover { top: 1px; } +.ui-datepicker .ui-datepicker-prev { left: 0; } +.ui-datepicker .ui-datepicker-next { right: 0; } +.ui-datepicker .ui-datepicker-prev-hover { left: 0; } +.ui-datepicker .ui-datepicker-next-hover { right: 0; } +.ui-datepicker .ui-datepicker-prev span, .ui-datepicker .ui-datepicker-next span { display: block; position: absolute; left: 50%; margin-left: -8px; top: 50%; margin-top: -8px; } +.ui-datepicker .ui-datepicker-title { margin: 0 2.3em; line-height: 1.8em; text-align: center; } +.ui-datepicker .ui-datepicker-title select { margin:1px 0; } +.ui-datepicker select.ui-datepicker-month-year {width: 100%;} +.ui-datepicker select.ui-datepicker-month, +.ui-datepicker select.ui-datepicker-year { width: 49%;} +.ui-datepicker table {width: 100%; border-collapse: collapse; margin:0 0 .4em; } +.ui-datepicker th { padding: .7em .3em; text-align: center; border: 0; } +.ui-datepicker td { border: 0; padding: 1px; } +.ui-datepicker td span, .ui-datepicker td a { display: block; padding: 3px; text-align: center; text-decoration: none; } +.ui-datepicker td span, .ui-datepicker td a:hover { background: #376ea6; color: #ffffff; } +.ui-datepicker .ui-datepicker-buttonpane { background-image: none; margin: .7em 0 0 0; padding:0 .2em; border-left: 0; border-right: 0; border-bottom: 0; } +.ui-datepicker .ui-datepicker-buttonpane button { float: right; margin: .5em .2em .4em; cursor: pointer; padding: .2em .6em .3em .6em; width:auto; overflow:visible; } +.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current { float:left; } +.ui-datepicker td span, .ui-datepicker td.ui-datepicker-today a { background: #DDDDDD; color: #585858; } +.ui-datepicker td span, .ui-datepicker td.ui-datepicker-current-day a { background: #376ea6; color: #ffffff; } + +/* ----------------------------------------------------------- + jquery ui -> datepicker / multiple calenders +----------------------------------------------------------- */ +.ui-datepicker.ui-datepicker-multi { width:auto; } +.ui-datepicker-multi .ui-datepicker-group { float:left; } +.ui-datepicker-multi .ui-datepicker-group table { width:95%; margin:0 auto .4em; } +.ui-datepicker-multi-2 .ui-datepicker-group { width:50%; } +.ui-datepicker-multi-3 .ui-datepicker-group { width:33.3%; } +.ui-datepicker-multi-4 .ui-datepicker-group { width:25%; } +.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header { border-left-width:0; } +.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header { border-left-width:0; } +.ui-datepicker-multi .ui-datepicker-buttonpane { clear:left; } +.ui-datepicker-row-break { clear:both; width:100%; } + +/* ----------------------------------------------------------- + jquery ui -> datepicker / rtl support +----------------------------------------------------------- */ +.ui-datepicker-rtl { direction: rtl; } +.ui-datepicker-rtl .ui-datepicker-prev { right: 2px; left: auto; } +.ui-datepicker-rtl .ui-datepicker-next { left: 2px; right: auto; } +.ui-datepicker-rtl .ui-datepicker-prev:hover { right: 1px; left: auto; } +.ui-datepicker-rtl .ui-datepicker-next:hover { left: 1px; right: auto; } +.ui-datepicker-rtl .ui-datepicker-buttonpane { clear:right; } +.ui-datepicker-rtl .ui-datepicker-buttonpane button { float: left; } +.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current { float:right; } +.ui-datepicker-rtl .ui-datepicker-group { float:right; } +.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header { border-right-width:0; border-left-width:1px; } +.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header { border-right-width:0; border-left-width:1px; } + +/* ----------------------------------------------------------- + jquery ui -> select styling +----------------------------------------------------------- */ + +.ui-selectmenu +{ + display: block; + position: relative; + overflow: hidden; + background: #ffffff; + border-top: 1px solid #b3b3b3; + border-left: 1px solid #b3b3b3; + border-right: 1px solid #eaeaea; + border-bottom: 1px solid #eaeaea; + text-align: left; + text-decoration: none; +} + +.ui-selectmenu-icon { position:absolute; right:6px; margin-top:-8px; top: 50%; } +.ui-selectmenu-menu { padding:0; margin:0; list-style:none; position:absolute; top: 0; visibility: hidden; overflow: auto; } +.ui-selectmenu-open { background: #ffffff; border: 1px solid #666666; border-top: none; visibility: visible; } +.ui-selectmenu-menu-popup { margin-top: -1px; } +.ui-selectmenu-menu-dropdown { } +.ui-selectmenu-menu li { padding:0; margin:0; display: block; border-top: 1px dotted transparent; border-bottom: 1px dotted transparent; border-right-width: 0 !important; border-left-width: 0 !important; } +.ui-selectmenu-menu li a,.ui-selectmenu-status {line-height: 1.4em; display:block; padding: 5px 0 5px 8px; outline:none; text-decoration:none; color: #000000; } +.ui-selectmenu-menu li.ui-selectmenu-hasIcon a, +.ui-selectmenu-hasIcon .ui-selectmenu-status { margin-left: 5px; padding-left: 20px; position: relative; } +.ui-selectmenu-menu li .ui-icon, .ui-selectmenu-status .ui-icon { position: absolute; top: 1em; margin-top: -8px; left: 0; } +.ui-selectmenu-status { line-height: 1.4em; } +.ui-selectmenu-open li.ui-selectmenu-item-focus { background: #376ea6; } +.ui-selectmenu-open li.ui-selectmenu-item-focus a { color: #ffffff; } +.ui-selectmenu-open li.ui-selectmenu-item-selected { background: #dfdfdf; } +.ui-selectmenu-open li.ui-selectmenu-item-selected a { color: #000000; } +.ui-selectmenu-menu li span,.ui-selectmenu-status span { display:block; margin-bottom: .2em; } +.ui-selectmenu-menu .ui-selectmenu-group .ui-selectmenu-group-label { line-height: 1.4em; display:block; padding:.6em .5em 0; } +.ui-selectmenu-menu .ui-selectmenu-group ul { margin: 0; padding: 0; } \ No newline at end of file diff --git a/pylons_app/public/css/style_full.css b/pylons_app/public/css/style_full.css new file mode 100644 --- /dev/null +++ b/pylons_app/public/css/style_full.css @@ -0,0 +1,36 @@ +/* ----------------------------------------------------------- + content +----------------------------------------------------------- */ + +#content +{ + margin: 10px 60px 0 60px; + padding: 0; + min-height: 100%; + clear: both; + overflow: hidden; + background: transparent; +} + +/* ----------------------------------------------------------- + content -> right -> forms -> labels +----------------------------------------------------------- */ + +#content div.box div.form div.fields div.field div.label +{ + left: 80px; + margin: 0; + padding: 8px 0 0 5px; + width: auto; + position: absolute; +} + +#content div.box-left div.form div.fields div.field div.label, +#content div.box-right div.form div.fields div.field div.label +{ + left: 0; + margin: 0; + padding: 0 0 8px 0; + width: auto; + position: relative; +} \ No newline at end of file diff --git a/pylons_app/public/images/background.png b/pylons_app/public/images/background.png new file mode 100644 index 0000000000000000000000000000000000000000..1ece980b24b74d7b9fcd196c224a94315d66b8ed GIT binary patch literal 4828 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 bUw{Ds8h`;62Ierg00000NkvXXu0mjfZee9k diff --git a/pylons_app/public/images/colors/blue/button_highlight.png b/pylons_app/public/images/colors/blue/button_highlight.png new file mode 100644 index 0000000000000000000000000000000000000000..ef76eb9a676e2e3f8f7d74fe962c0d9fb49b6a68 GIT binary patch literal 225 zc%17D@N?(olHy`uVBq!ia0vp^j6f{G!3-pMgwkICDajJoh?3y^w370~qErUQl>DSr z1<%~X^wgl##FWaylc_d9MIHe@A+G*yd!lCF4(vP_yWml9@A24q55gv$i<)^esOxa( zgfk)iCyUm;44Zr*Zqd`o8P@|k4#dp8AJlU+dd^+H*4=Rn9|yGWiVMC-u1EbRa`d4bF;wB$mE3w9Jz8+^;`^{wIT_#uJ8yFd+ W{1`>OOr$_s89ZJ6T-G@yGywob?^a*{ diff --git a/pylons_app/public/images/colors/blue/button_highlight_selected.png b/pylons_app/public/images/colors/blue/button_highlight_selected.png new file mode 100644 index 0000000000000000000000000000000000000000..ffd3a38e7d2741563661f91ef0ae0084e3f0f2ac GIT binary patch literal 225 zc%17D@N?(olHy`uVBq!ia0vp^j6f{G!3-pMgwkICDajJoh?3y^w370~qErUQl>DSr z1<%~X^wgl##FWaylc_d9MIHe@A+AoVF1jo^ZnyQJ>!KqL>#jR5KjXIGkmH)m_8afG zE<9|v`F_m77xo)&Ijq0oy7-vm+N-u(AK7hrV87|E)5;4jOHaBjIOx3WwDXE{cbeoQ zfM)7@x;TbZ++sP{%GjX5z_1}wqJdHAfBh@9UA=PcNt07HpYB=}T@%-QIYoR+d;=qc XqbItFDKZ zrl+j2AW(sVf`Wg6goKBR)zs3qwzdE_Z%0yI5l4J-a&ok^w4a}!T488=dwWMtRX}Ep z+S=NjoSf6IdJQ{i4m@h^?(PjkdaSIh_V)H7Iaz3EXz}s!xVX5})6*6{WpQzF;^N|- zo}R*$R#8+}kIICdot>t3J#cb!p=va&emsLxF|mwX%*)CnVr9C6J9&9|SY2U5OjX8} zR2oKd+uGS}Zf>e@GDk~KQ&(Gn!E_W)YH@UUu7FL(kx=2`;WJBLjf;vrZ9a~Vk3WS~ zE^t9&uUVpXN6@Bf8(1`?!J??vp<`xgUTSu+v9X73MUrnqpKwI5dN;kAYk^BGkY75o zgitSUK_z5XHBf7Cba&6JecapGxrICfIBhRdbw`0jmt;6qj8GgwXS9>(Hsj&nV?Q-`J|;0gOv}s56HQyr&d#rKFsyPk zl$4ajkWE)wUAw!xK!#O5OIJvZQloV{r*k-7q*Yj?T5521#FtgBbu`A4QI%yjL5D_1 zWll?NP|>Mwnwpx^u6cdGa(=vaZM0(3t8;L3c4caC-rn9|Vq;}xWmi{MkdKYVlTu=9 zbi#{B!;MRnWISDCX|Z)Ouy!_>n3!UbUec^|)2()fhK7WMgi1_KPESu+W^!<}W_Emn zxq~^zlv2i(Q^J;4HBDb~b$M%Ual2!10ssI4Qb|NXRCwBA2nzS`b`Rwv3Mj}kWctJy z@bM9?+{=lNj|AnO$-+bfpmJXWl9ap25f6aMc}M^>S1wBe04kRz0RWYYkN|KfH{;?m z!=YRe6R_^Ef&>6m&PxKIxpICI0O`u5NB}_Pf+PUam5Q!BCZe8N*Ro&9VZ_erxTdz7cznF64@@8G)>Q%=hFBus>#50#U5>u~oTsn5| zSM|#LK-t)j7Z8 znOQf1>ea@zb1Po$CQz^b{rP9hR!F_NXTidKX@u(4p4m@f^=j|lw1KTx+p8w5n+B;@ zr%yV)0GY@1Q-BM WHn2;}KEt5^00002J<`ylMDv490rR52IDjai+l#lA_kLm z2GcAC>rw`*QU=Rn2FpSQi$Vs|YzC7|2D4lS<8%hAVg^$nJDb5g_pa}WO+Yg(JY5_^ zDsIUf>=tVf5OF=IJL!vn=>PxA&+Rf!;Il3K_E_nqZ{k&7aqA40w>Bw%S61wP?XBX+ a$i`sE!Wb*8H9Hb$27{-opUXO@geCxC$w9jS diff --git a/pylons_app/public/images/colors/blue/header_inner_corners.png b/pylons_app/public/images/colors/blue/header_inner_corners.png new file mode 100644 index 0000000000000000000000000000000000000000..2f7e848ae66dbfa405e0004460ba4be0fbfc1d15 GIT binary patch literal 264 zc%17D@N?(olHy`uVBq!ia0vp^JV4CG!3-o181!!jQj#UE5hcO-X(i=}MX3yqDfvmM z3ZA)%>8U}fi7AzZCsS>JiV^~RLR=ZFOBt-o7_3T}Y|0$cdbVxbwq?r}+m!D1Y0KE` z%d5L)8AP`&U$c?Lwrt0a9V=F^6L729v}sdB=_En-8ijyHtHcgo=c=t+x9UZ-@bi&bj4KFz^dIqyX-t&978H@B_*T^KTi-B6L>mls&LAK$BBt) zEKF%)l3{Fhd2SjLCZtUePi|n+RAduOlW32e)Ht1!&w`POhaoM2NkQGedI8WR22WQ% Jmvv4FO#te*T7Cck diff --git a/pylons_app/public/images/colors/blue/index.sof b/pylons_app/public/images/colors/blue/index.sof new file mode 100644 index 0000000000000000000000000000000000000000..9d5e70297b371506bfedd3aa1630440bce37d49f GIT binary patch literal 834 zc$^bpU|`5dO-xBGiqFi;OD)nX$V=x0ie=^|rl;xyIl|r<|18%&b^wYoa078+X=ZYE zJf^xW+?iO^H!IhRICgFDOw9pMG(Fu#4%=C;LATGhsz_=5kK^BV!+*VCKun#4ka`MwN^Kizh YapQiJWCISzr2L{3ESchR?+v(G0J(J$c>n+a diff --git a/pylons_app/public/images/colors/blue/login_corners.png b/pylons_app/public/images/colors/blue/login_corners.png new file mode 100644 index 0000000000000000000000000000000000000000..4b3bb263a60a3d6fbf151845a6a48286a1e01af8 GIT binary patch literal 267 zc%17D@N?(olHy`uVBq!ia0vp^JV4CG!3-o181!!jQj#UE5hcO-X(i=}MX3yqDfvmM z3ZA)%>8U}fi7AzZCsS>Jijo6-LR=ZFOBt-o7_3S!T)1%Y;zcH#a`(KcZn;xVoIab? zzC5{N#9jjgW ztW~>&J?f61I&rm;!NxoHSIPM8p$(7-+eZpAF+h_T NJYD@<);T3K0RWjIUEcrz diff --git a/pylons_app/public/images/colors/blue/menu_arrow.png b/pylons_app/public/images/colors/blue/menu_arrow.png new file mode 100644 index 0000000000000000000000000000000000000000..1c7622479066da43eaf7bdf480717db72ce81c64 GIT binary patch literal 133 zc%17D@N?(olHy`uVBq!ia0vp^oFL4>3?#4ne^UZdk|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5X*aCb)T+Q>A{r~^}(-L)Cpoplai(^Q|t)v78rkmdKI;Vst00{Uen*aa+ diff --git a/pylons_app/public/images/colors/blue/menu_border.png b/pylons_app/public/images/colors/blue/menu_border.png new file mode 100644 index 0000000000000000000000000000000000000000..4c31e3158c44c431eeb0832720d269d3ac3a3472 GIT binary patch literal 129 zc%17D@N?(olHy`uVBq!ia0vp^LO?9T!3-p$rQ}6{lw^r(L`iUdT1k0gQ7VIDN`6wR zf@f}GdTLN=VoGJ<$y6JlBDMgZ5LbKbLh*2~7a+6# diff --git a/pylons_app/public/images/colors/blue/menu_l_selected.png b/pylons_app/public/images/colors/blue/menu_l_selected.png new file mode 100644 index 0000000000000000000000000000000000000000..e3d14a01149b903aa73cb0cfb533daa0e4122ab9 GIT binary patch literal 300 zc%17D@N?(olHy`uVBq!ia0vp^Y(Ol>!3-oVrqAyIQj#UE5hcO-X(i=}MX3yqDfvmM z3ZA)%>8U}fi7AzZCsS>JigE&cLR=Y4(itp^7)-Mm%yJk^G8n8%7%Yn!jMEt`3K`7v z7%cJ`ED9K`iW$su8O(DTOfwnGvKh?t8B8)6EDIT|N*SzysO;are{2qwKYsn5y!wbi zLceZo?~_*_Y%->@*_Z$P^=I;$qyPW^x6hvOLipfBpuJ(9E{-7;w?dBI7ISi7aJV>m zk+zo9t_iRH|2OP2<^Ohi*-yUt@!pqhojLBrZx`&Za+>c~ael6gT3A!3-oVrqAyIQj#UE5hcO-X(i=}MX3yqDfvmM z3ZA)%>8U}fi7AzZCsS>JiqZmnLR=Y4(iu#%7|e1QOfncOix{j*7|gO6%<~wmiWw{l z7|e1REbmdKI;Vst00pCE6aWAK diff --git a/pylons_app/public/images/colors/blue/menu_selected.png b/pylons_app/public/images/colors/blue/menu_selected.png new file mode 100644 index 0000000000000000000000000000000000000000..ad63d42acd234b444b50c59bbd440430fb581748 GIT binary patch literal 225 zc%17D@N?(olHy`uVBq!ia0vp^j6f{M!3-pCdAEE8Qj#UE5hcO-X(i=}MX3yqDfvmM z3ZA)%>8U}fi7AzZCsS>Jid+MHLR=Y4(iu#%7)&x4EQ=VdN*Jum7|e1QOfnhFa~aHX z8LWyKEDIT|OBu}b7>v^yED9OSvKg#O8BBo+@)<0EsDQz;_y#YBD$qb9PZ!6Kid!NF z*_j*+1Q<3*EKR%m>woZEmq}|@*`14vjS=a;ojTdKts>)5=9Odj|8W{HC?_xquZc*0 Q0MyOk>FVdQ&MBb@0O008g#Z8m diff --git a/pylons_app/public/images/colors/blue/quick_l.png b/pylons_app/public/images/colors/blue/quick_l.png new file mode 100644 index 0000000000000000000000000000000000000000..4f4242e648d14b69f2860eec66ce607f434babaa GIT binary patch literal 177 zc%17D@N?(olHy`uVBq!ia0vp^EI=&B!3-pAlKeLUDajJoh?3y^w370~qErUQl>DSr z1<%~X^wgl##FWaylc_d9MJfS4A+E-0GxZXu=p{~7i|$tl>(-8+%wSn;m@?fUd74q` z3=W4%Zs+R5o5Q++>XkiR978H@B_%vgdY1AaEh!-(fia0KOyHo4(LoR2rn$@t2N=}P WGo;mA*N*`zXYh3Ob6Mw<&;$U2TQ!RS diff --git a/pylons_app/public/images/colors/blue/quick_l_selected.png b/pylons_app/public/images/colors/blue/quick_l_selected.png new file mode 100644 index 0000000000000000000000000000000000000000..f970fa271789d601cd4d205a9a71f0263dd2c3ff GIT binary patch literal 166 zc%17D@N?(olHy`uVBq!ia0vp^EI=&B!3-pAlKeLUDajJoh?3y^w370~qErUQl>DSr z1<%~X^wgl##FWaylc_c!9RWTeu6}-g#_rKPHn|?Yf$rV`95(qT?on<&K@66~p1uL^ zPt5!UQt9d97*cU7=|MtjN_s+4T0%ksa}t|hnDSr z1<%~X^wgl##FWaylc_c!9RWTeuEuFI4O6BYrp_=-nPHGTO*OKQ-@T6Ctxh|BGJ|FD z+KHx4K$WVVE{-7;w~`VbBs@-GU@8+h$fXqFz#=@6#W=BPqQSu?H8z0+1{EiUX#Jg5 RAAlMdJYD@<);T3K0RSxdFuVW& diff --git a/pylons_app/public/images/colors/blue/quick_r_selected.png b/pylons_app/public/images/colors/blue/quick_r_selected.png new file mode 100644 index 0000000000000000000000000000000000000000..a3a8681fab5fef349edb8af79b25755e5e88dd1d GIT binary patch literal 168 zc%17D@N?(olHy`uVBq!ia0vp^EI=&B!3-pAlKeLUDajJoh?3y^w370~qErUQl>DSr z1<%~X^wgl##FWaylc_c!9RWTeu6}-gUcLdQ?vcjs(Hu7UZazUCzJUyu#a_PtytX;v z$8WR&RVsM8IEGZ*N=isgOH5BlNO;U5#N(sTG_mnr19LCGKmvp4Lk7J`2X2J})iQXx L`njxgN@xNA;Gi#a diff --git a/pylons_app/public/images/colors/blue/title.png b/pylons_app/public/images/colors/blue/title.png new file mode 100644 index 0000000000000000000000000000000000000000..94d4b242cf3f362a91e593a282427e5ebf9823cd GIT binary patch literal 247 zc%17D@N?(olHy`uVBq!ia0vp^j6kfy!3-qpS1qsuQj#UE5hcO-X(i=}MX3yqDfvmM z3ZA)%>8U}fi7AzZCsS>Jib4W>LR_s%)|q6?u`FI=k~!BbXOU&mYKwvuCh46c}6&ir*B<6fF8*{VT2F#t+pzD_N7r5?en8 sX}*~g@m1!`8l5j$C6~G#{;)_eSbbugesW>u8K5Byp00i_>zopr0DsU~ZvX%Q diff --git a/pylons_app/public/images/colors/blue/title_link.png b/pylons_app/public/images/colors/blue/title_link.png new file mode 100644 index 0000000000000000000000000000000000000000..fc2ad03721865c546dbbce342a7195f7e1f67178 GIT binary patch literal 224 zc%17D@N?(olHy`uVBq!ia0vp^OhBx{!3-p)%$2qUQj#UE5hcO-X(i=}MX3yqDfvmM z3ZA)%>8U}fi7AzZCsS>JitGb?LR@`n*PG`pHOZJ`nl;}%cZqS@Ow-JHX1R+^GUpnn z&oa+nW}3agBz?A7&LZ=?B_<)U0eU}7oC}+&D#2vIX%B)*GuN<`z}1ZlCb&RtK8;Q?R*~pH4iX2lrox3 T{&Dmz&_E)I!3-ozC9e7dDajJoh?3y^w370~qErUQl>DSr z1<%~X^wgl##FWaylc_d9MLYpMA+G=b|2IjWZJa*KIBnLUhg!FR;MYXlHw6wIhx3{>sxU;jfxw*Nr zva+_ewz|5yu&}VZySuTmv9GVMy}iA>yu7ZiuD-s$t*x!BtgOGkzp1IIz`($(tE;D{ zr>Ll?s;a8O!osDcrJtXlqN1YXC!5s(02Mk(L_t(|+ANxhmLoZi1bH8ENy@D5ncbQF z|KD6QsH=~crIdms;BdHuN@cb*a!Re%d#zPl9wYbUi!HY+%`{p`snnEe$}N?AjxkG1 zHRtjAT(7o&T1#ov((8TP$Fa)moVAr)DjzPH-*pH#I$zhWbJes~9=*(i+_evR%y${9=40h{?y-Dw zN)JKkb={n#vR6(r5=S6hW#&E7NiIuzHInRc$TXNZ&&FBP$iT?r&TEkRnHM=o zZH}@@cwG;%D(jdvgNQZKL5K>Q=Yi&uN3_=jPxC$&OXcI}zdoWLeT?h6n)q@%DHC`= zH34}O7@U$lmHRnd7vKYs)Il$~uD>-IG!7_6$jo_le*OorKnLKZ0q{2k)Xesa=UwAs zw*-(!0>T8Y&VU)gndA!WmE70rU~N2oSOQ1QaI~viD_i z?%c{~9xUg*&*J*~HPR>TeAJP8JvzyHFVf%{`n!YqS)LQVe4qoT+bsZqpu!?=&wGQ&gFBXBmh)K_pzA|bz~WIlgsJ{6=!0ASCJ-qhPudtWK!AiCKON!;IcBGMXgiGWLymJ&gcExsVX8@*Rrrn zZLc%MC+7t@<;;5N9!8~{Bw(CiUCi=MGCwBe&c7m?Sda-a04D=oX^)NY<^}xnk$$qA zbxD6&rnyNoLE%XiY8Zr#Pz_iK9uWUy=Ew%e7JwDDhYHFMyNZow9(j2#9R+*x5-0z_MP* zpZKH265!VUkg;w_2^rQSyZv5YML`uM)9A-LA%kjU*0R+l_O}W7(g|UdeNIaY_PC%s z$&BtukPaS5*@8R*pQI+9H!M^FQNAoBP^y~e+@MNTLp*^2&jn5V0wF*UfFOw-d;k1w z8ymaf1C7%_<2FP%W)T*IiKGa+tlwmni~$jyB(hwmQHBq5L(^~!Iph+4Wzx4^5*(ZC ztkf!ao0bl{nu9z7q`Dy0Y(!CL(`u*mte!O~t?~LHDU>>#j0{UBTQJGz>3d8DDUi`P zlhm_8oK3As+_Wor7@&ndr2ID}G4~a<3hUAJ&8YDFzw591gdUR{w z$zwL@xJF1k1*}ox!B8eDH602WV$zO$&2vNN(B^r;eJpH~|4`FxKe9?@E}&ASTzbVa z2@oN=3@H;@kg9Uy<=adt!zHJwnpI&nr7zCKj+;2J(D+jfx==e!Lv(Od zDoy;MD|)UeECI=|SRmKdU+J&{$u(NzuzwL#RZ?ZKdaI+*yO-L*b;e8L=75T!Yuh4) zD(CEIG?|kF>>n#HwGXv*UBU!*ob!2-RLvj7GiM}p2TG3afo8J#y{_C(y@z3DmB0UW z6$J3-bDiogdzs9yf+ywBXsHx$s)6)S*8|7SDECOQL!iKQk)6%q)oU}ODmTqDjU-c=|&h!^n!6(9y_zQYd zm5%2*Z7sB;xy;O*KVd;zO$mSm_ID^scTZWLF4^LDM5< z<3f+&Fosq+MHsT7meZ%q$4)o9POmX7H0Vp0oYd@#ZlS)fe7f8S3X2Cf zg1vB)R1CeZ+_IX|!AS=X*z1?ZLvtSD5Ch>3SnH~%U5}vQB-eo@x=_?3WPxsu4~bjF z3rIW;dNl>0mNX!ENuLvR3Rl&;h8k6CpyC=bobaso`+XmDV)i^K(c{EGN6LIAv^JI7 z7KeB|@m&oksq)r0R81a2_0(vM+>5%fd31g7YT3rzlj$~mvHd)!lE^2rKy@6mX~2#n6ng`;h}?5;5)C~o2o&wsa45V|56oK| z!AePkJ?CBU7PZG-0^WG4%F1aNl!{FSw62>3KL!69^5?ay^yU*8`NuG=q)FK;dz_7V$h5*CX{Jyp_<^k9oEoQ5C^;dMo?;HMr_5x1w{Ed2(K-DlJ=-zXI-3q1@m z75nawQ-+v!Q9D_4EGv>FDOXvBBqO)@UEO9CnIj)D@!*3h#%wS2G!X~(p;AoW5dw&r z_$i4(&T>jt-c}we8#Wl~eSH44ktkQwqhvdPVxGrE&IurCCNKP^q0y^8CT3w67El|* zWZ-goW`CG*-9TEM*^3hrKsqA0r{bd@k0X~EtkVYY)=FTw9qDSL z={zZ9A2cELJMydNtBI3l+pGEGBo7Y(B~Mz_c4m-8J{dl~;}(a-_F{lq=4;zlFBR|U z=gGYX1=aj#FF}?`=%i4K=e>ZMz*Us&7L?kU$WuPDKuz(yQ(>07gl|Y_o%-~-sTju* zovk||##Vu6TPq3%>ih~h=gyAr=z-({7)5XnR4|+c^%hAX35AW$I5&|N(VyHtDee=N zhPY)8H^;Zhy7eDE=oBtAQ=_29QAs%Hm_pvMV{vFF!qK$#jaRduIn_E}q#?II!crGO zV9%HyL7^8m#>pi>s@2K-fb0RZLlM%4{X4tI>2w;J{Uf||op9d0AREfPJWJtDRngc% zSoW4h1wp>x%x3RCNAL~;s(-6redGL_bkZT_3@8KYm?y)2&U{zDsV9)-H2ctkydNjk z4*Rpyv#rivk6y$%xiNqLD=%?+bPk~wPssSir_0!?yOmZOQn(N%^M5tJ}Rgk)0s{G zecqvGyg&jmQ2^GM{!AyOwl4NZeRs{fuP<|g6EosN=!EIvQ43yQ`Y@#ti_xFFD7ha* z^i4;TKgZ^szX0MnhI41V`pRKk5eMW+qCmaagOUX!@paZlo~Da6&?Wkrx`pKKvYs7!+f$tpjauKSEY-kNc^#R-yE zuuEc4RZLyo-IYdnm#DTkhTd{UZ~Mw+ry{4*im9vNyxDt*+deDvy3J}aa6I*$67QxN zgII$d9U|@&)rzt!Yo1C1ezC$S3?(d-2w&d%?$TdaL#oBh6q<{a1RJT7JHQs#@8h^p zaVmc&FU?LGgK0vD)0>q0m;1{1-n^dPRUnIg95=^6a4wzGvfUvCx`0t%rYQ0C7mz2r z$8*Mv4(os?OZJ*=uTn2T$`j{J5`;l_tjJHjI>K)b{?+T%%VSc`b`dJ-08rIL5otPp z-)Nt?9!D_F$)=)rDq!>^H9A>L+WqFhLoh3(Sq*#D%8qk{d5ih9cg_T}IT(K4PZV$W zZtrSw-<%!Om;xFi;l&D!h+Nl!*t6+pg!GnmbBs50v@!+y9m>J`8cmqJx-|zpHN0KY z2kQ=bWyV#Ndzf)aN92?^BGs{gVn{6MfPKZt&p}ntvmD}VoGLyov~{aq2Kn+-47x3#xVqG0 z#WbM)&S2wZhj%~TLHX^E&?6x{j`tS*IG#Q!{dZ!>eft@ z(e1TR@hW+G#h7EZFrELQfO{k%3Pm05oa7u^HSO0Hz)y{>@(SU!x~<#`1OkV&m?3d2Zu2^bdC-NzF4q{ z#Y9}45MBisM5|8?w^+1Bn$GXsN^lRzMg29LvhhM*@g)H2+}W@K=``8?2FF$c00s54EzY9vIMu1)RLrr$J>vbZQEkZPY7qg#K~%G*%@8j7w%4Q)|rYI)>! zezpxKE~8sqA+I*RHy6BVD9%~2RS&bWH!qMtd^sb&`+}qDug}H%L^ec{y~|SC$|Bw| z&q=$|MB`0Ji`P_o2R?a3C5u0rM)M0CWD%Ypevu$uL4$s^soqt8?rj}^Rl~J;UEL|+ z(9d1o<;2LtOM1+)a}*@-eqH-Sbk&P!Zx)OZzZKbRj+7w16kCTbr-3$6=bU!OB_9S8 zDr>LdjFB3}L>Ky$lT#$5q7n6F$jS=+tE5 zK$L6r-gBIBe=dCi^Zr}X9rrL(0SN~!FI!^jvh#U1y|sSdtAU4E`u__s Y0BuCEE)>X9f&c&j07*qoM6N<$f;6b#MF0Q* diff --git a/pylons_app/public/images/icons/cross.png b/pylons_app/public/images/icons/cross.png index 1514d51a3cf1b67e1c5b9ada36f1fd474e2d214a..11a184511f74d2181389f488d7099da2416af5b9 GIT binary patch literal 3812 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 diff --git a/pylons_app/public/images/icons/success.png b/pylons_app/public/images/icons/success.png new file mode 100644 index 0000000000000000000000000000000000000000..c9fc7ba4958f7f9bb9b8afcc9a1720663b5ab5a7 GIT binary patch literal 7793 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 ND3P=X(YKoq{RJh=9(e!& diff --git a/pylons_app/public/images/menu.png b/pylons_app/public/images/menu.png new file mode 100644 index 0000000000000000000000000000000000000000..f61b1d3a4a80ba466abed59877038bf2b457a08c GIT binary patch literal 210 zc$@*!04@KCP)0000PbVXQnQ*UN; zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBUyIZ#YgMc3BW-{0Tf-rm{R*xTFN-QC^T z*Vo|S;Mv*P+uGXP+uPjS+}hdM;^N}3udmwL+Sb!_Uvp|NsBX%gfc& z)cyVa?(XiszP|hW``_N)^Yio6)YR40)zi|_`1ts*udmL|&dA8f)6>)AFMd^<>i@13@`uy0BlJ_K~#9!RK-OS!!Q&?!DlJ(6^@Ky#`_;I8ZT6p-ZWO*;q%0H z-xwnnT?m1V56(GUk4NZZUnEfc+nlkw^X2s?zyO*o2Rt4a+j#&0002ovPDHLkV1g;Tx*Grh diff --git a/pylons_app/public/images/menu_minus.png b/pylons_app/public/images/menu_minus.png new file mode 100644 index 0000000000000000000000000000000000000000..c31dcfb365f9e95321c8476088aa2c99eb1e38f4 GIT binary patch literal 146 zc%17D@N?(olHy`uVBq!ia0vp^93afW3?x5a^xFxfBuiW)N`mv#O3D+9QW+dm@{>{( zJaZG%Q-e|yQz{EjrrH1%u?6^qxc&!&(3-C~KoO>rAiv=M3{STkcma7Lo-U3d6}OTS kTA0{;*whZJl~6dqz|O&7SXpJW11Qhn>FVdQ&MBb@0IXFk3;+NC diff --git a/pylons_app/public/images/menu_plus.png b/pylons_app/public/images/menu_plus.png new file mode 100644 index 0000000000000000000000000000000000000000..1ae9adb501faeece358bb468e52d8f9f0312b93d GIT binary patch literal 150 zc%17D@N?(olHy`uVBq!ia0vp^93afW3?x5a^xFxfBuiW)N`mv#O3D+9QW+dm@{>{( zJaZG%Q-e|yQz{EjrrH1%u?6^qxc&!&(3-C~KoO>rAiv=M3{STkcma75o-U3d6}OTS oQc_Y97zAhV_%uWtIy5jcutqSbGF|C94phV7>FVdQ&MBb@0BUG0g8%>k diff --git a/pylons_app/public/images/menu_r.png b/pylons_app/public/images/menu_r.png new file mode 100644 index 0000000000000000000000000000000000000000..3c359458368aaa556cdfbb322a30d49aa9778ea1 GIT binary patch literal 350 zc$@)V0iphhP)k$ z%f7z8!otGU)YSO+`1AAg*4Ebh`}?o2ujS?C{r&yl-rnQmV6%gf8d!^79t*T=`l z$jHd)>FLnV&*tXl=esK#0001ONkl zXCIv-gm5}Ky!R$Vj4|HcRFd;8RdOL$m8_Je0yBZJKwnA=fw{m$U?k9!(o$fUJeyqI wFi5@!wSE6m_3IvKSL?^l(QWM6xxWAd0HJvYa9CMI{{R3007*qoM6N<$f)xwIF#rGn diff --git a/pylons_app/public/images/pager.png b/pylons_app/public/images/pager.png new file mode 100644 index 0000000000000000000000000000000000000000..590e5d40ef9e8c309e771d07b73bc545ecd11aa4 GIT binary patch literal 184 zc%17D@N?(olHy`uVBq!ia0vp^j6f{G!3-pMgwkICDajJoh?3y^w370~qErUQl>DSr z1<%~X^wgl##FWaylc_d9Md|@QA+E1qzyA2~BPzh3jM)vj4FC3$?? gdQK*NsAl3};5p7vb9&uPFQ66%Pgg&ebxsLQ0AeOiXaE2J diff --git a/pylons_app/public/images/pager_selected.png b/pylons_app/public/images/pager_selected.png new file mode 100644 index 0000000000000000000000000000000000000000..61becc3e9164459115d362cff81493bb38d98554 GIT binary patch literal 225 zc$@*@03QE|P)lqHw6w^`$k^D}-rnA}wzj#sxx>T5%*@Qay}i}d)z{b8#>U3GySv53 z#h6Vd*Z=?kFG)l}RCwA1!G!^UAOHZcSr~u;BL9EtW|t+eYO)w?9zoP}x7DopTt+93 bUw{Ds8h`;62Ierg00000NkvXXu0mjfZee9k diff --git a/pylons_app/public/js/excanvas.min.js b/pylons_app/public/js/excanvas.min.js new file mode 100644 --- /dev/null +++ b/pylons_app/public/js/excanvas.min.js @@ -0,0 +1,1 @@ +if(!document.createElement("canvas").getContext){(function(){var R=Math;var S=R.round;var O=R.sin;var a=R.cos;var J=R.abs;var Y=R.sqrt;var A=10;var K=A/2;function G(){return this.context_||(this.context_=new M(this))}var Q=Array.prototype.slice;function b(c,d,e){var Z=Q.call(arguments,2);return function(){return c.apply(d,Z.concat(Q.call(arguments)))}}var H={init:function(Z){if(/MSIE/.test(navigator.userAgent)&&!window.opera){var c=Z||document;c.createElement("canvas");c.attachEvent("onreadystatechange",b(this.init_,this,c))}},init_:function(e){if(!e.namespaces.g_vml_){e.namespaces.add("g_vml_","urn:schemas-microsoft-com:vml","#default#VML")}if(!e.namespaces.g_o_){e.namespaces.add("g_o_","urn:schemas-microsoft-com:office:office","#default#VML")}if(!e.styleSheets.ex_canvas_){var d=e.createStyleSheet();d.owningElement.id="ex_canvas_";d.cssText="canvas{display:inline-block;overflow:hidden;text-align:left;width:300px;height:150px}g_vml_\\:*{behavior:url(#default#VML)}g_o_\\:*{behavior:url(#default#VML)}"}var c=e.getElementsByTagName("canvas");for(var Z=0;Z','","");this.element_.insertAdjacentHTML("BeforeEnd",z.join(""))};I.stroke=function(AE){var j=[];var k=false;var AP=C(AE?this.fillStyle:this.strokeStyle);var AA=AP.color;var AK=AP.alpha*this.globalAlpha;var f=10;var m=10;j.push("w.x){w.x=AI.x}if(AO.y==null||AI.yw.y){w.y=AI.y}}}j.push(' ">');if(!AE){var v=this.lineScale_*this.lineWidth;if(v<1){AK*=v}j.push("')}else{if(typeof this.fillStyle=="object"){var n=this.fillStyle;var t=0;var AH={x:0,y:0};var AB=0;var r=1;if(n.type_=="gradient"){var q=n.x0_/this.arcScaleX_;var d=n.y0_/this.arcScaleY_;var o=n.x1_/this.arcScaleX_;var AQ=n.y1_/this.arcScaleY_;var AM=this.getCoords_(q,d);var AL=this.getCoords_(o,AQ);var h=AL.x-AM.x;var g=AL.y-AM.y;t=Math.atan2(h,g)*180/Math.PI;if(t<0){t+=360}if(t<0.000001){t=0}}else{var AM=this.getCoords_(n.x0_,n.y0_);var Z=w.x-AO.x;var e=w.y-AO.y;AH={x:(AM.x-AO.x)/Z,y:(AM.y-AO.y)/e};Z/=this.arcScaleX_*A;e/=this.arcScaleY_*A;var AG=R.max(Z,e);AB=2*n.r0_/AG;r=2*n.r1_/AG-AB}var z=n.colors_;z.sort(function(i,c){return i.offset-c.offset});var u=z.length;var y=z[0].color;var x=z[u-1].color;var AD=z[0].alpha*this.globalAlpha;var AC=z[u-1].alpha*this.globalAlpha;var AF=[];for(var AJ=0;AJ')}else{j.push('')}}j.push("");this.element_.insertAdjacentHTML("beforeEnd",j.join(""))};I.fill=function(){this.stroke(true)};I.closePath=function(){this.currentPath_.push({type:"close"})};I.getCoords_=function(d,c){var Z=this.m_;return{x:A*(d*Z[0][0]+c*Z[1][0]+Z[2][0])-K,y:A*(d*Z[0][1]+c*Z[1][1]+Z[2][1])-K}};I.save=function(){var Z={};T(this,Z);this.aStack_.push(Z);this.mStack_.push(this.m_);this.m_=D(N(),this.m_)};I.restore=function(){T(this.aStack_.pop(),this);this.m_=this.mStack_.pop()};I.translate=function(d,c){var Z=[[1,0,0],[0,1,0],[d,c,1]];this.m_=D(Z,this.m_)};I.rotate=function(d){var f=a(d);var e=O(d);var Z=[[f,e,0],[-e,f,0],[0,0,1]];this.m_=D(Z,this.m_)};I.scale=function(f,e){this.arcScaleX_*=f;this.arcScaleY_*=e;var c=[[f,0,0],[0,e,0],[0,0,1]];var Z=this.m_=D(c,this.m_);var d=Z[0][0]*Z[1][1]-Z[0][1]*Z[1][0];this.lineScale_=Y(J(d))};I.clip=function(){};I.arcTo=function(){};I.createPattern=function(){return new F};function W(Z){this.type_=Z;this.x0_=0;this.y0_=0;this.r0_=0;this.x1_=0;this.y1_=0;this.r1_=0;this.colors_=[]}W.prototype.addColorStop=function(c,Z){Z=C(Z);this.colors_.push({offset:c,color:Z.color,alpha:Z.alpha})};function F(){}G_vmlCanvasManager=H;CanvasRenderingContext2D=M;CanvasGradient=W;CanvasPattern=F})()}; \ No newline at end of file diff --git a/pylons_app/public/js/yui.flot.js b/pylons_app/public/js/yui.flot.js new file mode 100644 --- /dev/null +++ b/pylons_app/public/js/yui.flot.js @@ -0,0 +1,2483 @@ +/** +\file yui.flot.js +\brief Javascript plotting library for YUI based on Flot v. 0.5. +\details +This file contains a port of Flot for YUI + +Copyright (c) 2009 Yahoo! Inc. All rights reserved. The copyrights embodied +in the content of this file are licenced by Yahoo! Inc. under the BSD (revised) +open source license. + +Requires yahoo-dom-event and datasource which you can get here: + + +Datasource is optional, you only need it if one of your axes has its mode set to "time" +*/ + +(function() { + var L = YAHOO.lang; + var UA = YAHOO.env.ua; + var DOM = YAHOO.util.Dom; + var E = YAHOO.util.Event; + + if(!DOM.createElementFromMarkup) { + DOM.createElementFromMarkup = function(markup) { + var p=document.createElement('div'); + p.innerHTML = markup; + var e = p.firstChild; + return p.removeChild(e); + }; + } + + if(!DOM.removeElement) { + DOM.removeElement = function(el) { + return el.parentNode.removeChild(el); + }; + } + + function Plot(target_, data_, options_) { + // data is on the form: + // [ series1, series2 ... ] + // where series is either just the data as [ [x1, y1], [x2, y2], ... ] + // or { data: [ [x1, y1], [x2, y2], ... ], label: "some label" } + + var series = [], + options = { + // the color theme used for graphs + colors: ["#edc240", "#afd8f8", "#cb4b4b", "#4da74d", "#9440ed"], + locale: "en", + legend: { + show: true, + noColumns: 1, // number of colums in legend table + labelFormatter: null, // fn: string -> string + labelBoxBorderColor: "#ccc", // border color for the little label boxes + container: null, // container (as jQuery object) to put legend in, null means default on top of graph + position: "ne", // position of default legend container within plot + margin: 5, // distance from grid edge to default legend container within plot + backgroundColor: null, // null means auto-detect + backgroundOpacity: 0.85 // set to 0 to avoid background + }, + xaxis: { + mode: null, // null or "time" + min: null, // min. value to show, null means set automatically + max: null, // max. value to show, null means set automatically + autoscaleMargin: null, // margin in % to add if auto-setting min/max + ticks: null, // either [1, 3] or [[1, "a"], 3] or (fn: axis info -> ticks) or app. number of ticks for auto-ticks + tickFormatter: null, // fn: number -> string + label: null, + labelWidth: null, // size of tick labels in pixels + labelHeight: null, + + scaleType: 'linear', // may be 'linear' or 'log' + + // mode specific options + tickDecimals: null, // no. of decimals, null means auto + tickSize: null, // number or [number, "unit"] + minTickSize: null, // number or [number, "unit"] + timeformat: null // format string to use + }, + yaxis: { + label: null, + autoscaleMargin: 0.02 + }, + x2axis: { + label: null, + autoscaleMargin: null + }, + y2axis: { + label: null, + autoscaleMargin: 0.02 + }, + points: { + show: false, + radius: 3, + lineWidth: 2, // in pixels + fill: true, + fillColor: "#ffffff" + }, + lines: { + // we don't put in show: false so we can see + // whether lines were actively disabled + lineWidth: 2, // in pixels + fill: false, + fillColor: null + }, + bars: { + show: false, + lineWidth: 2, // in pixels + barWidth: 1, // in units of the x axis + fill: true, + fillColor: null, + align: "left" // or "center" + }, + grid: { + show: true, + showLines: true, + color: "#545454", // primary color used for outline and labels + backgroundColor: null, // null for transparent, else color + tickColor: "#dddddd", // color used for the ticks + labelMargin: 5, // in pixels + labelFontSize: 16, + borderWidth: 2, // in pixels + borderColor: null, // set if different from the grid color + markings: null, // array of ranges or fn: axes -> array of ranges + markingsColor: "#f4f4f4", + markingsLineWidth: 2, + // interactive stuff + clickable: false, + hoverable: false, + autoHighlight: true, // highlight in case mouse is near + mouseActiveRadius: 10 // how far the mouse can be away to activate an item + }, + selection: { + mode: null, // one of null, "x", "y" or "xy" + color: "#e8cfac" + }, + crosshair: { + mode: null, // one of null, "x", "y" or "xy", + color: "#aa0000" + }, + shadowSize: 3 + }, + canvas = null, // the canvas for the plot itself + overlay = null, // canvas for interactive stuff on top of plot + eventHolder = null, // jQuery object that events should be bound to + ctx = null, octx = null, + target = DOM.get(target_), + axes = { xaxis: {}, yaxis: {}, x2axis: {}, y2axis: {} }, + plotOffset = { left: 0, right: 0, top: 0, bottom: 0}, + canvasWidth = 0, canvasHeight = 0, + plotWidth = 0, plotHeight = 0, + // dedicated to storing data for buggy standard compliance cases + workarounds = {}; + + this.setData = setData; + this.setupGrid = setupGrid; + this.draw = draw; + this.clearSelection = clearSelection; + this.setSelection = setSelection; + this.getCanvas = function() { return canvas; }; + this.getPlotOffset = function() { return plotOffset; }; + this.getData = function() { return series; }; + this.getAxes = function() { return axes; }; + this.setCrosshair = setCrosshair; + this.clearCrosshair = function () { setCrosshair(null); }; + this.highlight = highlight; + this.unhighlight = unhighlight; + + // initialize + parseOptions(options_); + setData(data_); + constructCanvas(); + setupGrid(); + draw(); + + var plot = this; + + plot.createEvent('plotclick'); + plot.createEvent('plothover'); + plot.createEvent('plotselected'); + plot.createEvent('plotunselected'); + + + + function setData(d) { + series = parseData(d); + + fillInSeriesOptions(); + processData(); + } + + function normalizeData(d) { + var possible_controls = ['x', 'time', 'date']; + + if (L.isArray(d)) { + d = { data: d }; + } else { + d = L.merge(d); + } + + if(d.disabled) { + return undefined; + } + + if (d.data.length === 0) { + return undefined; + } + + var j, k; + + // Make a copy so we don't obliterate the caller's data + var _data = []; + + if (L.isArray(d.data[0])) { + for(j=0; j 1); + if(s.dropped[j]) { + drops-=1; + } + + if(!isNaN(x) && !isNaN(x)) + drops+=dropperiod; + else { + drops=0; // bonus for a null point + points--; + dropperiod=1-canvasWidth/10/points; + } + } + + return s; + } + + function splitSeries(s) { + var res = []; + + for(var k=0; k= options.colors.length) { + i = 0; + ++variation; + } + } + + // fill in the options + var colori = 0, s; + for (i = 0; i < series.length; ++i) { + s = series[i]; + + // assign colors + if (s.color == null) { + s.color = colors[colori].toString(); + ++colori; + } + else if (typeof s.color == "number") + s.color = colors[s.color].toString(); + + // copy the rest + s.lines = L.merge(options.lines, s.lines || {}); + s.points = L.merge(options.points, s.points || {}); + s.bars = L.merge(options.bars, s.bars || {}); + + // turn on lines automatically in case nothing is set + if (s.lines.show == null && !s.bars.show && !s.points.show) + s.lines.show = true; + + if (s.shadowSize == null) + s.shadowSize = options.shadowSize; + + if (s.xaxis && s.xaxis == 2) + s.xaxis = axes.x2axis; + else + s.xaxis = axes.xaxis; + if (s.yaxis && s.yaxis >= 2) { + if(!axes['y' + s.yaxis + 'axis']) + axes['y' + s.yaxis + 'axis'] = {}; + if(!options['y' + s.yaxis + 'axis']) + options['y' + s.yaxis + 'axis'] = { autoscaleMargin: 0.02 }; + s.yaxis = axes['y' + s.yaxis + 'axis']; + } + else + s.yaxis = axes.yaxis; + } + } + + function processData() { + var topSentry = Number.POSITIVE_INFINITY, + bottomSentry = Number.NEGATIVE_INFINITY, + axis; + + for (axis in axes) { + axes[axis].datamin = topSentry; + axes[axis].datamax = bottomSentry; + axes[axis].min = options[axis].min; + axes[axis].max = options[axis].max; + axes[axis].used = false; + } + + for (var i = 0; i < series.length; ++i) { + var s = series[i]; + var data = s.data, + axisx = s.xaxis, axisy = s.yaxis, + xmin = topSentry, xmax = bottomSentry, + ymin = topSentry, ymax = bottomSentry, + x, y, p; + + axisx.used = axisy.used = true; + + if (s.bars.show) { + // make sure we got room for the bar + var delta = s.bars.align == "left" ? 0 : -s.bars.barWidth/2; + xmin += delta; + xmax += delta + s.bars.barWidth; + } + + for (var j = 0; j < data.length; ++j) { + p = data[j]; + + if(data[j] === null) + continue; + + x = p.x; + y = p.y; + + if(L.isObject(x) && x.getTime) { // this is a Date object + x = x.getTime()/1000; + } + + if(L.isObject(y) && y.getTime) { // this is a Date object + y = y.getTime()/1000; + } + + // convert to number + if (x != null && !isNaN(x = +x)) { + if (x < xmin) + xmin = x; + if (x > xmax) + xmax = x; + } + else + x = null; + + if (y != null && !isNaN(y = +y)) { + if (y < ymin) + ymin = y; + if (y > ymax) + ymax = y; + } + else + y = null; + + if (x == null || y == null) + data[j] = x = y = null; // mark this point invalid + } + + axisx.datamin = Math.min(axisx.datamin, xmin); + axisx.datamax = Math.max(axisx.datamax, xmax); + axisy.datamin = Math.min(axisy.datamin, ymin); + axisy.datamax = Math.max(axisy.datamax, ymax); + } + } + + function constructCanvas() { + function makeCanvas(width, height, container, style) { + var c = document.createElement('canvas'); + c.width = width; + c.height = height; + if (typeof G_vmlCanvasManager !== 'undefined') // excanvas hack + c = G_vmlCanvasManager.initElement(c); + + if(style) { + for(var k in style) { + c.style[k] = style[k]; + } + } + container.appendChild(c); + + return c; + } + + canvasWidth = parseInt(DOM.getStyle(target, 'width'), 10); + canvasHeight = parseInt(DOM.getStyle(target, 'height'), 10); + target.innerHTML = ""; // clear target + target.style.position = "relative"; // for positioning labels and overlay + + if (canvasWidth <= 0 || canvasHeight <= 0) + throw "Invalid dimensions for plot, width = " + canvasWidth + ", height = " + canvasHeight; + + if (YAHOO.env.ua.ie) { + G_vmlCanvasManager.init_(document); + } + + // the canvas + canvas = makeCanvas(canvasWidth, canvasHeight, target); + ctx = canvas.getContext("2d"); + + // overlay canvas for interactive features + overlay = makeCanvas(canvasWidth, canvasHeight, target, { position: 'absolute', left: '0px', top: '0px' }); + octx = overlay.getContext("2d"); + + // we include the canvas in the event holder too, because IE 7 + // sometimes has trouble with the stacking order + eventHolder = [overlay, canvas]; + + // bind events + if (options.selection.mode != null || options.crosshair.mode != null || options.grid.hoverable) { + E.on(eventHolder, 'mousemove', onMouseMove); + + if (options.selection.mode != null) + E.on(eventHolder, "mousedown", onMouseDown); + } + + if (options.crosshair.mode != null) + E.on(eventHolder, "mouseout", onMouseOut); + + if (options.grid.clickable) + E.on(eventHolder, "click", onClick); + } + + function setupGrid() { + function setupAxis(axis, options, type) { + setRange(axis, options); + prepareTickGeneration(axis, options); + setTicks(axis, options); + // add transformation helpers + if (type == 'x') { + // data point to canvas coordinate + axis.p2c = function (p) { return (p - axis.min) * axis.scale; }; + // canvas coordinate to data point + axis.c2p = function (c) { return axis.min + c / axis.scale; }; + } + else { + axis.p2c = function (p) { return (axis.max - p) * axis.scale; }; + axis.c2p = function (c) { return axis.max - c / axis.scale; }; + } + } + + for (var axis in axes) + setupAxis(axes[axis], options[axis], axis.charAt(0)); + + setSpacing(); + if(options.grid.show) + insertLabels(); + insertLegend(); + insertAxisLabels(); + } + + function setRange(axis, axisOptions) { + var min = axisOptions.min != null ? (axisOptions.scaleType == 'log' ? Math.log(axisOptions.min<=0?1:axisOptions.min) * Math.LOG10E : axisOptions.min) : axis.datamin; + var max = axisOptions.max != null ? (axisOptions.scaleType == 'log' ? Math.log(axisOptions.max) * Math.LOG10E : axisOptions.max) : axis.datamax; + + if(axisOptions.mode === 'time') { + if(L.isObject(min) && min.getTime) min = min.getTime()/1000; + if(L.isObject(max) && max.getTime) max = max.getTime()/1000; + } + + // degenerate case + if (min == Number.POSITIVE_INFINITY) + min = 0; + if (max == Number.NEGATIVE_INFINITY) + max = 1; + + if (max - min == 0.0) { + // degenerate case + var widen = max == 0 ? 1 : 0.01; + + if (axisOptions.min == null) + min -= widen; + // alway widen max if we couldn't widen min to ensure we + // don't fall into min == max which doesn't work + if (axisOptions.max == null || axisOptions.min != null) + max += widen; + } + else { + // consider autoscaling + var margin = axisOptions.autoscaleMargin; + if (margin != null) { + if (axisOptions.min == null) { + min -= (max - min) * margin; + // make sure we don't go below zero if all values + // are positive + if (min < 0 && axis.datamin >= 0) + min = 0; + } + if (axisOptions.max == null) { + max += (max - min) * margin; + if (max > 0 && axis.datamax <= 0) + max = 0; + } + } + } + axis.min = min; + axis.max = max; + } + + function prepareTickGeneration(axis, axisOptions) { + // estimate number of ticks + var noTicks; + if (typeof axisOptions.ticks == "number" && axisOptions.ticks > 0) + noTicks = axisOptions.ticks; + else if (axis == axes.xaxis || axis == axes.x2axis) + noTicks = canvasWidth / 100; + else + noTicks = canvasHeight / 60; + + var delta = (axis.max - axis.min) / noTicks; + var size, generator, unit, formatter, magn, norm; + + if (axisOptions.mode == "time") { + // pretty handling of time + + delta*=1000; + + // map of app. size of time units in milliseconds + var timeUnitSize = { + "second": 1000, + "minute": 60 * 1000, + "hour": 60 * 60 * 1000, + "day": 24 * 60 * 60 * 1000, + "month": 30 * 24 * 60 * 60 * 1000, + "year": 365.2425 * 24 * 60 * 60 * 1000 + }; + + + // the allowed tick sizes, after 1 year we use + // an integer algorithm + var spec = [ + [1, "second"], [2, "second"], [5, "second"], [10, "second"], + [30, "second"], + [1, "minute"], [2, "minute"], [5, "minute"], [10, "minute"], + [30, "minute"], + [1, "hour"], [2, "hour"], [4, "hour"], + [8, "hour"], [12, "hour"], + [1, "day"], [2, "day"], [3, "day"], + [0.25, "month"], [0.5, "month"], [1, "month"], + [2, "month"], [3, "month"], [6, "month"], + [1, "year"] + ]; + + var minSize = 0; + if (axisOptions.minTickSize != null) { + if (typeof axisOptions.tickSize == "number") + minSize = axisOptions.tickSize; + else + minSize = axisOptions.minTickSize[0] * timeUnitSize[axisOptions.minTickSize[1]]; + } + + for (var i = 0; i < spec.length - 1; ++i) + if (delta < (spec[i][0] * timeUnitSize[spec[i][1]] + + spec[i + 1][0] * timeUnitSize[spec[i + 1][1]]) / 2 + && spec[i][0] * timeUnitSize[spec[i][1]] >= minSize) + break; + size = spec[i][0]; + unit = spec[i][1]; + + // special-case the possibility of several years + if (unit == "year") { + magn = Math.pow(10, Math.floor(Math.log(delta / timeUnitSize.year) / Math.LN10)); + norm = (delta / timeUnitSize.year) / magn; + if (norm < 1.5) + size = 1; + else if (norm < 3) + size = 2; + else if (norm < 7.5) + size = 5; + else + size = 10; + + size *= magn; + } + + if (axisOptions.tickSize) { + size = axisOptions.tickSize[0]; + unit = axisOptions.tickSize[1]; + } + + generator = function(axis) { + var ticks = [], + tickSize = axis.tickSize[0], unit = axis.tickSize[1], + d = new Date(axis.min*1000); + + var step = tickSize * timeUnitSize[unit]; + + if (unit == "second") + d.setUTCSeconds(floorInBase(d.getUTCSeconds(), tickSize)); + if (unit == "minute") + d.setUTCMinutes(floorInBase(d.getUTCMinutes(), tickSize)); + if (unit == "hour") + d.setUTCHours(floorInBase(d.getUTCHours(), tickSize)); + if (unit == "month") + d.setUTCMonth(floorInBase(d.getUTCMonth(), tickSize)); + if (unit == "year") + d.setUTCFullYear(floorInBase(d.getUTCFullYear(), tickSize)); + + // reset smaller components + d.setUTCMilliseconds(0); + if (step >= timeUnitSize.minute) + d.setUTCSeconds(0); + if (step >= timeUnitSize.hour) + d.setUTCMinutes(0); + if (step >= timeUnitSize.day) + d.setUTCHours(0); + if (step >= timeUnitSize.day * 4) + d.setUTCDate(1); + if (step >= timeUnitSize.year) + d.setUTCMonth(0); + + + var carry = 0, v = Number.NaN, prev; + do { + prev = v; + v = d.getTime(); + ticks.push({ v: v/1000, label: axis.tickFormatter(v, axis) }); + if (unit == "month") { + if (tickSize < 1) { + // a bit complicated - we'll divide the month + // up but we need to take care of fractions + // so we don't end up in the middle of a day + d.setUTCDate(1); + var start = d.getTime(); + d.setUTCMonth(d.getUTCMonth() + 1); + var end = d.getTime(); + d.setTime(v + carry * timeUnitSize.hour + (end - start) * tickSize); + carry = d.getUTCHours(); + d.setUTCHours(0); + } + else + d.setUTCMonth(d.getUTCMonth() + tickSize); + } + else if (unit == "year") { + d.setUTCFullYear(d.getUTCFullYear() + tickSize); + } + else + d.setTime(v + step); + } while (v < axis.max*1000 && v != prev); + + return ticks; + }; + + formatter = function (v, axis) { + var d = new Date(v); + + // first check global format + if (axisOptions.timeformat != null) + return YAHOO.util.Date.format(d, {format: axisOptions.timeformat}, options.locale); + + var t = axis.tickSize[0] * timeUnitSize[axis.tickSize[1]]; + var span = axis.max - axis.min; + span*=1000; + + if (t < timeUnitSize.minute) + var fmt = "%k:%M:%S"; + else if (t < timeUnitSize.day) { + if (span < 2 * timeUnitSize.day) + fmt = "%k:%M"; + else + fmt = "%b %d %k:%M"; + } + else if (t < timeUnitSize.month) + fmt = "%b %d"; + else if (t < timeUnitSize.year) { + if (span < timeUnitSize.year/2) + fmt = "%b"; + else + fmt = "%b %Y"; + } + else + fmt = "%Y"; + + return YAHOO.util.Date.format(d, {format: fmt}, axisOptions.timelang); + }; + } + else { + // pretty rounding of base-10 numbers + var maxDec = axisOptions.tickDecimals; + var dec = -Math.floor(Math.log(delta) / Math.LN10); + if (maxDec != null && dec > maxDec) + dec = maxDec; + + magn = Math.pow(10, -dec); + norm = delta / magn; // norm is between 1.0 and 10.0 + + if (norm < 1.5) + size = 1; + else if (norm < 3) { + size = 2; + // special case for 2.5, requires an extra decimal + if (norm > 2.25 && (maxDec == null || dec + 1 <= maxDec)) { + size = 2.5; + ++dec; + } + } + else if (norm < 7.5) + size = 5; + else + size = 10; + + size *= magn; + + if (axisOptions.minTickSize != null && size < axisOptions.minTickSize) + size = axisOptions.minTickSize; + + if (axisOptions.tickSize != null) + size = axisOptions.tickSize; + + axis.tickDecimals = Math.max(0, (maxDec != null) ? maxDec : dec); + + generator = function (axis) { + var ticks = []; + + // spew out all possible ticks + var start = floorInBase(axis.min, axis.tickSize), + i = 0, v = Number.NaN, prev; + do { + prev = v; + v = start + i * axis.tickSize; + var t=v; + if(axis.scaleType == 'log') { + t = Math.exp(t / Math.LOG10E); + } + ticks.push({ v: v, label: axis.tickFormatter(t, axis) }); + ++i; + } while (v < axis.max && v != prev); + return ticks; + }; + + formatter = function (v, axis) { + return v.toFixed(axis.tickDecimals); + }; + } + + axis.scaleType = axisOptions.scaleType; + axis.tickSize = unit ? [size, unit] : size; + axis.tickGenerator = generator; + if (L.isFunction(axisOptions.tickFormatter)) + axis.tickFormatter = function (v, axis) { return "" + axisOptions.tickFormatter(v, axis); }; + else + axis.tickFormatter = formatter; + if (axisOptions.labelWidth != null) + axis.labelWidth = axisOptions.labelWidth; + if (axisOptions.labelHeight != null) + axis.labelHeight = axisOptions.labelHeight; + } + + function setTicks(axis, axisOptions) { + axis.ticks = []; + + if (!axis.used) + return; + + if (axisOptions.ticks == null) + axis.ticks = axis.tickGenerator(axis); + else if (typeof axisOptions.ticks == "number") { + if (axisOptions.ticks > 0) + axis.ticks = axis.tickGenerator(axis); + } + else if (axisOptions.ticks) { + var ticks = axisOptions.ticks; + + if (L.isFunction(ticks)) + // generate the ticks + ticks = ticks({ min: axis.min, max: axis.max }); + + // clean up the user-supplied ticks, copy them over + var v; + for (var i = 0; i < ticks.length; ++i) { + var label = null; + var t = ticks[i]; + if (typeof t == "object") { + v = t[0]; + if (t.length > 1) + label = t[1]; + } + else + v = t; + if (axisOptions.scaleType == 'log') { + if (label == null) + label = v; + v = Math.log(v) * Math.LOG10E; + } + + if (label == null) + label = axis.tickFormatter(v, axis); + axis.ticks[i] = { v: v, label: label }; + } + } + + if (axisOptions.autoscaleMargin != null && axis.ticks.length > 0) { + // snap to ticks + if (axisOptions.min == null) + axis.min = Math.min(axis.min, axis.ticks[0].v); + if (axisOptions.max == null && axis.ticks.length > 1) + axis.max = Math.min(axis.max, axis.ticks[axis.ticks.length - 1].v); + } + } + + function setSpacing() { + function measureXLabels(axis) { + if(options.grid.show){ + // to avoid measuring the widths of the labels, we + // construct fixed-size boxes and put the labels inside + // them, we don't need the exact figures and the + // fixed-size box content is easy to center + if (axis.labelWidth == null) + axis.labelWidth = canvasWidth / 6; + + // measure x label heights + if (axis.labelHeight == null) { + var labels = []; + for (var i = 0; i < axis.ticks.length; ++i) { + var l = axis.ticks[i].label; + if (l) + labels.push('
' + l + '
'); + } + + axis.labelHeight = 0; + if (labels.length > 0) { + var dummyDiv = target.appendChild(DOM.createElementFromMarkup('
' + + labels.join("") + '
')); + axis.labelHeight = dummyDiv.offsetHeight; + target.removeChild(dummyDiv); + } + } + } + else{ + axis.labelHeight = 0; + axis.labelWidth = 0; + } + } + + function measureYLabels(axis) { + if(options.grid.show){ + if (axis.labelWidth == null || axis.labelHeight == null) { + var labels = [], l; + // calculate y label dimensions + for (var i = 0; i < axis.ticks.length; ++i) { + l = axis.ticks[i].label; + if (l) + labels.push('
' + l + '
'); + } + + if (labels.length > 0) { + var dummyDiv = target.appendChild(DOM.createElementFromMarkup('
' + + labels.join("") + '
')); + if (axis.labelWidth == null) + axis.labelWidth = dummyDiv.offsetWidth; + if (axis.labelHeight == null) + axis.labelHeight = dummyDiv.firstChild.offsetHeight; + target.removeChild(dummyDiv); + } + + if (axis.labelWidth == null) + axis.labelWidth = 0; + if (axis.labelHeight == null) + axis.labelHeight = 0; + } + } + else{ + axis.labelHeight = 0; + axis.labelWidth = 0; + } + } + + measureXLabels(axes.xaxis); + measureYLabels(axes.yaxis); + measureXLabels(axes.x2axis); + measureYLabels(axes.y2axis); + // get the most space needed around the grid for things + // that may stick out + var maxOutset = (options.grid.show) ? options.grid.borderWidth : 0; + for (var i = 0; i < series.length; ++i) + maxOutset = (Math.max(maxOutset, 2 * (((series[i].points.show) ? series[i].points.radius : 0 ) + series[i].points.lineWidth/2))); + + plotOffset.left = plotOffset.right = plotOffset.top = plotOffset.bottom = maxOutset; + + var margin = options.grid.labelMargin + options.grid.borderWidth; + + if (axes.xaxis.labelHeight > 0) + plotOffset.bottom = Math.max(maxOutset, axes.xaxis.labelHeight + margin); + if (axes.yaxis.labelWidth > 0) + plotOffset.left = Math.max(maxOutset, axes.yaxis.labelWidth + margin); + + if (axes.x2axis.labelHeight > 0) + plotOffset.top = Math.max(maxOutset, axes.x2axis.labelHeight + margin); + + if (axes.y2axis.labelWidth > 0) + plotOffset.right = Math.max(maxOutset, axes.y2axis.labelWidth + margin); + + plotWidth = canvasWidth - plotOffset.left - plotOffset.right; + plotHeight = canvasHeight - plotOffset.bottom - plotOffset.top; + + // precompute how much the axis is scaling a point in canvas space + for(var axis in axes) { + axes[axis].scale = (axis.charAt(0) == 'x' ? plotWidth : plotHeight) / (axes[axis].max - axes[axis].min); + } + } + + function draw() { + drawGrid(); + for (var i = 0; i < series.length; i++) { + drawSeries(series[i]); + } + } + + function extractRange(ranges, coord) { + var firstAxis = coord + "axis", + secondaryAxis = coord + "2axis", + axis, from, to, reverse; + + if (ranges[firstAxis]) { + axis = firstAxis; + } + else if (ranges[secondaryAxis]) { + axis = secondaryAxis; + } + else { + return { from: null, to: null, axis: axes[firstAxis] }; + } + + from = ranges[axis].from; + to = ranges[axis].to; + + if (options[axis].scaleType == 'log') { + if (from != null) + from = Math.log(from) * Math.LOG10E; + if (to != null) + to = Math.log(to) * Math.LOG10E; + } + + axis = axes[axis]; + + // auto-reverse as an added bonus + if (from != null && to != null && from > to) + return { from: to, to: from, axis: axis }; + + return { from: from, to: to, axis: axis }; + } + + function drawGrid() { + var i; + + ctx.save(); + ctx.clearRect(0, 0, canvasWidth, canvasHeight); + ctx.translate(plotOffset.left, plotOffset.top); + + // draw background, if any + if (options.grid.backgroundColor) { + ctx.fillStyle = getColorOrGradient(options.grid.backgroundColor, plotHeight, 0, "rgba(255, 255, 255, 0)"); + ctx.fillRect(0, 0, plotWidth, plotHeight); + } + + // draw markings + var markings = options.grid.markings; + if (markings) { + if (L.isFunction(markings)) + markings = markings({ xaxis: axes.xaxis, yaxis: axes.yaxis, x2axis: axes.x2axis, y2axis: axes.y2axis }); + + for (i = 0; i < markings.length; ++i) { + var m = markings[i], + xrange = extractRange(m, "x"), + yrange = extractRange(m, "y"); + + // fill in missing + if (xrange.from == null) + xrange.from = xrange.axis.min; + if (xrange.to == null) + xrange.to = xrange.axis.max; + if (yrange.from == null) + yrange.from = yrange.axis.min; + if (yrange.to == null) + yrange.to = yrange.axis.max; + + // clip + if (xrange.to < xrange.axis.min || xrange.from > xrange.axis.max || + yrange.to < yrange.axis.min || yrange.from > yrange.axis.max) + continue; + + xrange.from = Math.max(xrange.from, xrange.axis.min); + xrange.to = Math.min(xrange.to, xrange.axis.max); + yrange.from = Math.max(yrange.from, yrange.axis.min); + yrange.to = Math.min(yrange.to, yrange.axis.max); + + if (xrange.from == xrange.to && yrange.from == yrange.to) + continue; + + // then draw + xrange.from = xrange.axis.p2c(xrange.from); + xrange.to = xrange.axis.p2c(xrange.to); + yrange.from = yrange.axis.p2c(yrange.from); + yrange.to = yrange.axis.p2c(yrange.to); + + if (xrange.from == xrange.to || yrange.from == yrange.to) { + // draw line + ctx.strokeStyle = m.color || options.grid.markingsColor; + ctx.beginPath(); + ctx.lineWidth = m.lineWidth || options.grid.markingsLineWidth; + ctx.moveTo(xrange.from, yrange.from); + ctx.lineTo(xrange.to, yrange.to); + ctx.stroke(); + } + else { + // fill area + ctx.fillStyle = m.color || options.grid.markingsColor; + ctx.fillRect(xrange.from, yrange.to, + xrange.to - xrange.from, + yrange.from - yrange.to); + } + } + } + + if(options.grid.show && options.grid.showLines) { + // draw the inner grid + ctx.lineWidth = 1; + ctx.strokeStyle = options.grid.tickColor; + ctx.beginPath(); + var v, axis = axes.xaxis; + for (i = 0; i < axis.ticks.length; ++i) { + v = axis.ticks[i].v; + if (v <= axis.min || v >= axes.xaxis.max) + continue; // skip those lying on the axes + + ctx.moveTo(Math.floor(axis.p2c(v)) + ctx.lineWidth/2, 0); + ctx.lineTo(Math.floor(axis.p2c(v)) + ctx.lineWidth/2, plotHeight); + } + + axis = axes.yaxis; + for (i = 0; i < axis.ticks.length; ++i) { + v = axis.ticks[i].v; + if (v <= axis.min || v >= axis.max) + continue; + + ctx.moveTo(0, Math.floor(axis.p2c(v)) + ctx.lineWidth/2); + ctx.lineTo(plotWidth, Math.floor(axis.p2c(v)) + ctx.lineWidth/2); + } + + axis = axes.x2axis; + for (i = 0; i < axis.ticks.length; ++i) { + v = axis.ticks[i].v; + if (v <= axis.min || v >= axis.max) + continue; + + ctx.moveTo(Math.floor(axis.p2c(v)) + ctx.lineWidth/2, -5); + ctx.lineTo(Math.floor(axis.p2c(v)) + ctx.lineWidth/2, 5); + } + + axis = axes.y2axis; + for (i = 0; i < axis.ticks.length; ++i) { + v = axis.ticks[i].v; + if (v <= axis.min || v >= axis.max) + continue; + + ctx.moveTo(plotWidth-5, Math.floor(axis.p2c(v)) + ctx.lineWidth/2); + ctx.lineTo(plotWidth+5, Math.floor(axis.p2c(v)) + ctx.lineWidth/2); + } + + ctx.stroke(); + } + + if (options.grid.show && options.grid.borderWidth) { + // draw border + var bw = options.grid.borderWidth; + ctx.lineWidth = bw; + ctx.strokeStyle = options.grid.borderColor; + ctx.lineJoin = "round"; + ctx.strokeRect(-bw/2, -bw/2, plotWidth + bw, plotHeight + bw); + } + + ctx.restore(); + } + + function insertLabels() { + DOM.getElementsByClassName("tickLabels", "div", target, DOM.removeElement); + + var html = ['
']; + + function addLabels(axis, labelGenerator) { + for (var i = 0; i < axis.ticks.length; ++i) { + var tick = axis.ticks[i]; + if (!tick.label || tick.v < axis.min || tick.v > axis.max) + continue; + html.push(labelGenerator(tick, axis)); + } + } + + var margin = options.grid.labelMargin + options.grid.borderWidth; + + addLabels(axes.xaxis, function (tick, axis) { + return '
' + tick.label + "
"; + }); + + + addLabels(axes.yaxis, function (tick, axis) { + return '
' + tick.label + "
"; + }); + + addLabels(axes.x2axis, function (tick, axis) { + return '
' + tick.label + "
"; + }); + + addLabels(axes.y2axis, function (tick, axis) { + return '
' + tick.label + "
"; + }); + + html.push('
'); + + target.appendChild(DOM.createElementFromMarkup(html.join(""))); + } + + function insertAxisLabels() { + var xLocation, yLocation; + if( options.xaxis.label ) { + yLocation = plotOffset.top + plotHeight + ( axes.xaxis.labelHeight * 1.5 ); + xLocation = plotOffset.left; + DOM.getElementsByClassName("xaxislabel", "div", target, DOM.removeElement); + target.appendChild( + DOM.createElementFromMarkup( + "
" + + options.xaxis.label + "
" + ) + ); + } + if( options.yaxis.label ) { + xLocation = plotOffset.left - ( axes.yaxis.labelWidth * 2 ) - options.grid.labelFontSize; + yLocation = plotOffset.top + plotHeight/2; + DOM.getElementsByClassName("yaxislabel", "div", target, DOM.removeElement); + + target.appendChild( + DOM.createElementFromMarkup( + "
" + + options.yaxis.label + "
") + ); + } + } + + function drawSeries(series) { + if (series.lines.show) + drawSeriesLines(series); + if (series.bars.show) + drawSeriesBars(series); + if (series.points.show) + drawSeriesPoints(series); + } + + function drawSeriesLines(series) { + function plotLine(data, xoffset, yoffset, axisx, axisy) { + var prev = null, cur=null, drawx = null, drawy = null; + + ctx.beginPath(); + for (var i = 0; i < data.length; i++) { + prev = cur; + cur = data[i]; + + if(prev == null || cur == null) + continue; + + var x1 = prev.x, y1 = prev.y, + x2 = cur.x, y2 = cur.y; + + // clip with ymin + if (y1 <= y2 && y1 < axisy.min) { + if (y2 < axisy.min) + continue; // line segment is outside + // compute new intersection point + x1 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1; + y1 = axisy.min; + } + else if (y2 <= y1 && y2 < axisy.min) { + if (y1 < axisy.min) + continue; + x2 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1; + y2 = axisy.min; + } + + // clip with ymax + if (y1 >= y2 && y1 > axisy.max) { + if (y2 > axisy.max) + continue; + x1 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1; + y1 = axisy.max; + } + else if (y2 >= y1 && y2 > axisy.max) { + if (y1 > axisy.max) + continue; + x2 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1; + y2 = axisy.max; + } + + // clip with xmin + if (x1 <= x2 && x1 < axisx.min) { + if (x2 < axisx.min) + continue; + y1 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1; + x1 = axisx.min; + } + else if (x2 <= x1 && x2 < axisx.min) { + if (x1 < axisx.min) + continue; + y2 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1; + x2 = axisx.min; + } + + // clip with xmax + if (x1 >= x2 && x1 > axisx.max) { + if (x2 > axisx.max) + continue; + y1 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1; + x1 = axisx.max; + } + else if (x2 >= x1 && x2 > axisx.max) { + if (x1 > axisx.max) + continue; + y2 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1; + x2 = axisx.max; + } + + if (drawx != axisx.p2c(x1) + xoffset || drawy != axisy.p2c(y1) + yoffset) + ctx.moveTo(axisx.p2c(x1) + xoffset, axisy.p2c(y1) + yoffset); + + drawx = axisx.p2c(x2) + xoffset; + drawy = axisy.p2c(y2) + yoffset; + ctx.lineTo(axisx.p2c(x2) + xoffset, axisy.p2c(y2) + yoffset); + } + ctx.stroke(); + } + + function plotLineArea(data, axisx, axisy) { + var prev, cur = null, + bottom = Math.min(Math.max(0, axisy.min), axisy.max), + top, lastX = 0, areaOpen = false; + + for (var i = 0; i < data.length; i++) { + prev = cur; + cur = data[i]; + + if (areaOpen && x1 != null && x2 == null) { + // close area + ctx.lineTo(axisx.p2c(lastX), axisy.p2c(bottom)); + ctx.fill(); + areaOpen = false; + continue; + } + + if (prev == null || cur == null) { + if(areaOpen) { + ctx.lineTo(axisx.p2c(lastX), axisy.p2c(bottom)); + ctx.fill(); + } + areaOpen = false; + continue; + } + + var x1 = prev.x, y1 = prev.y, + x2 = cur.x, y2 = cur.y; + + // clip x values + + // clip with xmin + if (x1 <= x2 && x1 < axisx.min) { + if (x2 < axisx.min) + continue; + y1 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1; + x1 = axisx.min; + } + else if (x2 <= x1 && x2 < axisx.min) { + if (x1 < axisx.min) + continue; + y2 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1; + x2 = axisx.min; + } + + // clip with xmax + if (x1 >= x2 && x1 > axisx.max) { + if (x2 > axisx.max) + continue; + y1 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1; + x1 = axisx.max; + } + else if (x2 >= x1 && x2 > axisx.max) { + if (x1 > axisx.max) + continue; + y2 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1; + x2 = axisx.max; + } + + if (!areaOpen) { + // open area + ctx.beginPath(); + ctx.moveTo(axisx.p2c(x1), axisy.p2c(bottom)); + areaOpen = true; + } + + // now first check the case where both is outside + if (y1 >= axisy.max && y2 >= axisy.max) { + ctx.lineTo(axisx.p2c(x1), axisy.p2c(axisy.max)); + ctx.lineTo(axisx.p2c(x2), axisy.p2c(axisy.max)); + lastX = x2; + continue; + } + else if (y1 <= axisy.min && y2 <= axisy.min) { + ctx.lineTo(axisx.p2c(x1), axisy.p2c(axisy.min)); + ctx.lineTo(axisx.p2c(x2), axisy.p2c(axisy.min)); + lastX = x2; + continue; + } + + // else it's a bit more complicated, there might + // be two rectangles and two triangles we need to fill + // in; to find these keep track of the current x values + var x1old = x1, x2old = x2; + + // and clip the y values, without shortcutting + + // clip with ymin + if (y1 <= y2 && y1 < axisy.min && y2 >= axisy.min) { + x1 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1; + y1 = axisy.min; + } + else if (y2 <= y1 && y2 < axisy.min && y1 >= axisy.min) { + x2 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1; + y2 = axisy.min; + } + + // clip with ymax + if (y1 >= y2 && y1 > axisy.max && y2 <= axisy.max) { + x1 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1; + y1 = axisy.max; + } + else if (y2 >= y1 && y2 > axisy.max && y1 <= axisy.max) { + x2 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1; + y2 = axisy.max; + } + + + // if the x value was changed we got a rectangle + // to fill + if (x1 != x1old) { + if (y1 <= axisy.min) + top = axisy.min; + else + top = axisy.max; + + ctx.lineTo(axisx.p2c(x1old), axisy.p2c(top)); + ctx.lineTo(axisx.p2c(x1), axisy.p2c(top)); + } + + // fill the triangles + ctx.lineTo(axisx.p2c(x1), axisy.p2c(y1)); + ctx.lineTo(axisx.p2c(x2), axisy.p2c(y2)); + + // fill the other rectangle if it's there + if (x2 != x2old) { + if (y2 <= axisy.min) + top = axisy.min; + else + top = axisy.max; + + ctx.lineTo(axisx.p2c(x2), axisy.p2c(top)); + ctx.lineTo(axisx.p2c(x2old), axisy.p2c(top)); + } + + lastX = Math.max(x2, x2old); + } + + if (areaOpen) { + ctx.lineTo(axisx.p2c(lastX), axisy.p2c(bottom)); + ctx.fill(); + } + } + + ctx.save(); + ctx.translate(plotOffset.left, plotOffset.top); + ctx.lineJoin = "round"; + + var lw = series.lines.lineWidth, + sw = series.shadowSize; + // FIXME: consider another form of shadow when filling is turned on + if (lw > 0 && sw > 0) { + // draw shadow as a thick and thin line with transparency + ctx.lineWidth = sw; + ctx.strokeStyle = "rgba(0,0,0,0.1)"; + var xoffset = 1; + plotLine(series.data, xoffset, Math.sqrt((lw/2 + sw/2)*(lw/2 + sw/2) - xoffset*xoffset), series.xaxis, series.yaxis); + ctx.lineWidth = sw/2; + plotLine(series.data, xoffset, Math.sqrt((lw/2 + sw/4)*(lw/2 + sw/4) - xoffset*xoffset), series.xaxis, series.yaxis); + } + + ctx.lineWidth = lw; + ctx.strokeStyle = series.color; + var fillStyle = getFillStyle(series.lines, series.color, 0, plotHeight); + if (fillStyle) { + ctx.fillStyle = fillStyle; + plotLineArea(series.data, series.xaxis, series.yaxis); + } + + if (lw > 0) + plotLine(series.data, 0, 0, series.xaxis, series.yaxis); + ctx.restore(); + } + + function drawSeriesPoints(series) { + function plotPoints(data, radius, fillStyle, offset, circumference, axisx, axisy) { + for (var i = 0; i < data.length; i++) { + if (data[i] == null || series.dropped[i]) + continue; + + var x = data[i].x, y = data[i].y; + if (x < axisx.min || x > axisx.max || y < axisy.min || y > axisy.max) + continue; + + ctx.beginPath(); + ctx.arc(axisx.p2c(x), axisy.p2c(y) + offset, radius, 0, circumference, true); + if (fillStyle) { + ctx.fillStyle = fillStyle; + ctx.fill(); + } + ctx.stroke(); + } + } + + ctx.save(); + ctx.translate(plotOffset.left, plotOffset.top); + + var lw = series.lines.lineWidth, + sw = series.shadowSize, + radius = series.points.radius; + if (lw > 0 && sw > 0) { + // draw shadow in two steps + var w = sw / 2; + ctx.lineWidth = w; + ctx.strokeStyle = "rgba(0,0,0,0.1)"; + plotPoints(series.data, radius, null, w + w/2, 2 * Math.PI, + series.xaxis, series.yaxis); + + ctx.strokeStyle = "rgba(0,0,0,0.2)"; + plotPoints(series.data, radius, null, w/2, 2 * Math.PI, + series.xaxis, series.yaxis); + } + + ctx.lineWidth = lw; + ctx.strokeStyle = series.color; + plotPoints(series.data, radius, + getFillStyle(series.points, series.color), 0, 2 * Math.PI, + series.xaxis, series.yaxis); + ctx.restore(); + } + + function drawBar(x, y, barLeft, barRight, offset, fill, axisx, axisy, c) { + var drawLeft = true, drawRight = true, + drawTop = true, drawBottom = false, + left = x + barLeft, right = x + barRight, + bottom = 0, top = y; + + // account for negative bars + if (top < bottom) { + top = 0; + bottom = y; + drawBottom = true; + drawTop = false; + } + + // clip + if (right < axisx.min || left > axisx.max || + top < axisy.min || bottom > axisy.max) + return; + + if (left < axisx.min) { + left = axisx.min; + drawLeft = false; + } + + if (right > axisx.max) { + right = axisx.max; + drawRight = false; + } + + if (bottom < axisy.min) { + bottom = axisy.min; + drawBottom = false; + } + + if (top > axisy.max) { + top = axisy.max; + drawTop = false; + } + + left = axisx.p2c(left); + bottom = axisy.p2c(bottom); + right = axisx.p2c(right); + top = axisy.p2c(top); + + // fill the bar + if (fill) { + c.beginPath(); + c.moveTo(left, bottom); + c.lineTo(left, top); + c.lineTo(right, top); + c.lineTo(right, bottom); + if(typeof fill === 'function') { + c.fillStyle = fill(bottom, top); + } else if(typeof fill === 'string') { + c.fillStyle = fill; + } + c.fill(); + } + + // draw outline + if (drawLeft || drawRight || drawTop || drawBottom) { + c.beginPath(); + + // FIXME: inline moveTo is buggy with excanvas + c.moveTo(left, bottom + offset); + if (drawLeft) + c.lineTo(left, top + offset); + else + c.moveTo(left, top + offset); + if (drawTop) + c.lineTo(right, top + offset); + else + c.moveTo(right, top + offset); + if (drawRight) + c.lineTo(right, bottom + offset); + else + c.moveTo(right, bottom + offset); + if (drawBottom) + c.lineTo(left, bottom + offset); + else + c.moveTo(left, bottom + offset); + c.stroke(); + } + } + + function drawSeriesBars(series) { + function plotBars(data, barLeft, barRight, offset, fill, axisx, axisy) { + + for (var i = 0; i < data.length; i++) { + if (data[i] == null) + continue; + drawBar(data[i].x, data[i].y, barLeft, barRight, offset, fill, axisx, axisy, ctx); + } + } + + ctx.save(); + ctx.translate(plotOffset.left, plotOffset.top); + + // FIXME: figure out a way to add shadows (for instance along the right edge) + ctx.lineWidth = series.bars.lineWidth; + ctx.strokeStyle = series.color; + var barLeft = series.bars.align == "left" ? 0 : -series.bars.barWidth/2; + var fill = series.bars.fill ? function (bottom, top) { return getFillStyle(series.bars, series.color, bottom, top); } : null; + plotBars(series.data, barLeft, barLeft + series.bars.barWidth, 0, fill, series.xaxis, series.yaxis); + ctx.restore(); + } + + function getFillStyle(filloptions, seriesColor, bottom, top) { + var fill = filloptions.fill; + if (!fill) + return null; + + if (filloptions.fillColor) + return getColorOrGradient(filloptions.fillColor, bottom, top, seriesColor); + + var c = parseColor(seriesColor); + c.a = typeof fill == "number" ? fill : 0.4; + c.normalize(); + return c.toString(); + } + + function insertLegend() { + DOM.getElementsByClassName("legend", "div", target, DOM.removeElement); + + if (!options.legend.show) + return; + + var fragments = [], rowStarted = false, + lf = options.legend.labelFormatter, s, label; + for (var i = 0; i < series.length; ++i) { + s = series[i]; + label = s.label; + if (!label) + continue; + + if (i % options.legend.noColumns == 0) { + if (rowStarted) + fragments.push(''); + fragments.push(''); + rowStarted = true; + } + + if (lf) + label = lf(label, s); + + fragments.push( + '
' + + '' + label + ''); + } + if (rowStarted) + fragments.push(''); + + if (fragments.length == 0) + return; + + var table = '' + fragments.join("") + '
'; + if (options.legend.container != null) + DOM.get(options.legend.container).innerHTML = table; + else { + var pos = "", + p = options.legend.position, + m = options.legend.margin; + if (m[0] == null) + m = [m, m]; + if (p.charAt(0) == "n") + pos += 'top:' + (m[1] + plotOffset.top) + 'px;'; + else if (p.charAt(0) == "s") + pos += 'bottom:' + (m[1] + plotOffset.bottom) + 'px;'; + if (p.charAt(1) == "e") + pos += 'right:' + (m[0] + plotOffset.right) + 'px;'; + else if (p.charAt(1) == "w") + pos += 'left:' + (m[0] + plotOffset.left) + 'px;'; + var legend = target.appendChild(DOM.createElementFromMarkup('
' + table.replace('style="', 'style="position:absolute;' + pos +';') + '
')); + if (options.legend.backgroundOpacity != 0.0) { + // put in the transparent background + // separately to avoid blended labels and + // label boxes + var c = options.legend.backgroundColor; + if (c == null) { + var tmp; + if (options.grid.backgroundColor && typeof options.grid.backgroundColor == "string") + tmp = options.grid.backgroundColor; + else + tmp = extractColor(legend); + c = parseColor(tmp).adjust(null, null, null, 1).toString(); + } + var div = legend.firstChild; + var _el = DOM.insertBefore( + DOM.createElementFromMarkup('
'), + legend + ); + DOM.setStyle(_el, 'opacity', options.legend.backgroundOpacity); + } + } + } + + + // interactive features + + var lastMousePos = { pageX: null, pageY: null }, + selection = { + first: { x: -1, y: -1}, second: { x: -1, y: -1}, + show: false, active: false }, + crosshair = { pos: { x: -1, y: -1 } }, + highlights = [], + clickIsMouseUp = false, + redrawTimeout = null, + hoverTimeout = null; + + // Returns the data item the mouse is over, or null if none is found + function findNearbyItem(mouseX, mouseY) { + var maxDistance = options.grid.mouseActiveRadius, + lowestDistance = maxDistance * maxDistance + 1, + item = null, foundPoint = false, j, x, y; + + function result(i, j) { + return { + datapoint: series[i].data[j], + dataIndex: j, + series: series[i], + seriesIndex: i + }; + } + + for (var i = 0; i < series.length; ++i) { + var s = series[i], + axisx = s.xaxis, + axisy = s.yaxis, + mx = axisx.c2p(mouseX), // precompute some stuff to make the loop faster + my = axisy.c2p(mouseY), + maxx = maxDistance / axisx.scale, + maxy = maxDistance / axisy.scale; + + var data = s.data; + + if (s.lines.show || s.points.show) { + for (j = 0; j < data.length; j++ ) { + if (data[j] == null) + continue; + + x = data[j].x; + y = data[j].y; + + // For points and lines, the cursor must be within a + // certain distance to the data point + if (x - mx > maxx || x - mx < -maxx || + y - my > maxy || y - my < -maxy) + continue; + + // We have to calculate distances in pixels, not in + // data units, because the scales of the axes may be different + var dx = Math.abs(axisx.p2c(x) - mouseX), + dy = Math.abs(axisy.p2c(y) - mouseY), + dist = dx * dx + dy * dy; // no idea in taking sqrt + if (dist < lowestDistance) { + lowestDistance = dist; + item = result(i, j); + } + } + } + + if (s.bars.show && !item) { // no other point can be nearby + var barLeft = s.bars.align == "left" ? 0 : -s.bars.barWidth/2, + barRight = barLeft + s.bars.barWidth; + + for (j = 0; j < data.length; j++) { + x = data[j].x; + y = data[j].y; + if (x == null) + continue; + + // for a bar graph, the cursor must be inside the bar + if ((mx >= x + barLeft && mx <= x + barRight && + my >= Math.min(0, y) && my <= Math.max(0, y))) + item = result(i, j); + } + } + } + + return item; + } + + function onMouseMove(e) { + lastMousePos.pageX = E.getPageX(e); + lastMousePos.pageY = E.getPageY(e); + + if (options.grid.hoverable) + triggerClickHoverEvent("plothover", lastMousePos); + + if (options.crosshair.mode != null) { + if (!selection.active) { + setPositionFromEvent(crosshair.pos, lastMousePos); + triggerRedrawOverlay(); + } + else + crosshair.pos.x = -1; // hide the crosshair while selecting + } + + if (selection.active) { + updateSelection(lastMousePos); + } + } + + function onMouseDown(e) { + var button = e.which || e.button; + if (button != 1) // only accept left-click + return; + + // cancel out any text selections + document.body.focus(); + + // prevent text selection and drag in old-school browsers + if (document.onselectstart !== undefined && workarounds.onselectstart == null) { + workarounds.onselectstart = document.onselectstart; + document.onselectstart = function () { return false; }; + } + if (document.ondrag !== undefined && workarounds.ondrag == null) { + workarounds.ondrag = document.ondrag; + document.ondrag = function () { return false; }; + } + + var mousePos = {pageX: E.getPageX(e), pageY: E.getPageY(e)}; + setSelectionPos(selection.first, mousePos); + + lastMousePos.pageX = null; + selection.active = true; + E.on(document, "mouseup", onSelectionMouseUp); + } + + function onMouseOut(e) { + if (options.crosshair.mode != null && crosshair.pos.x != -1) { + crosshair.pos.x = -1; + triggerRedrawOverlay(); + } + } + + function onClick(e) { + if (clickIsMouseUp) { + clickIsMouseUp = false; + return; + } + + var mousePos = {pageX: E.getPageX(e), pageY: E.getPageY(e)}; + triggerClickHoverEvent("plotclick", mousePos); + } + + // trigger click or hover event (they send the same parameters + // so we share their code) + function triggerClickHoverEvent(eventname, event) { + var offset = DOM.getXY(eventHolder[0]), + pos = { pageX: event.pageX, pageY: event.pageY }, + canvasX = event.pageX - offset[0] - plotOffset.left, + canvasY = event.pageY - offset[1] - plotOffset.top; + + for(var axis in axes) + if(axes[axis].used) + pos[axis.replace(/axis$/, '')] = axes[axis].c2p(axis.charAt(0) == 'x' ? canvasX : canvasY); + + var item = findNearbyItem(canvasX, canvasY); + + if (item) { + // fill in mouse pos for any listeners out there + item.pageX = parseInt(item.series.xaxis.p2c(item.datapoint.x) + offset[0] + plotOffset.left, 10); + item.pageY = parseInt(item.series.yaxis.p2c(item.datapoint.y) + offset[1] + plotOffset.top, 10); + } + + if (options.grid.autoHighlight) { + // clear auto-highlights + for (var i = 0; i < highlights.length; ++i) { + var h = highlights[i]; + if (h.auto == eventname && + !(item && h.series == item.series && h.point == item.datapoint)) + unhighlight(h.series, h.point); + } + + if (item) + highlight(item.series, item.datapoint, eventname); + } + + plot.fireEvent(eventname, {pos: pos, item: item }); + } + + function triggerRedrawOverlay() { + if (!redrawTimeout) + redrawTimeout = setTimeout(redrawOverlay, 30); + } + + function redrawOverlay() { + redrawTimeout = null; + + // redraw highlights + octx.save(); + octx.clearRect(0, 0, canvasWidth, canvasHeight); + octx.translate(plotOffset.left, plotOffset.top); + + var hi; + for (var i = 0; i < highlights.length; ++i) { + hi = highlights[i]; + + if (hi.series.bars.show) + drawBarHighlight(hi.series, hi.point); + else + drawPointHighlight(hi.series, hi.point); + } + + // redraw selection + if (selection.show && selectionIsSane()) { + octx.strokeStyle = parseColor(options.selection.color).scale(null, null, null, 0.8).toString(); + octx.lineWidth = 1; + ctx.lineJoin = "round"; + octx.fillStyle = parseColor(options.selection.color).scale(null, null, null, 0.4).toString(); + + var x = Math.min(selection.first.x, selection.second.x), + y = Math.min(selection.first.y, selection.second.y), + w = Math.abs(selection.second.x - selection.first.x), + h = Math.abs(selection.second.y - selection.first.y); + + octx.fillRect(x, y, w, h); + octx.strokeRect(x, y, w, h); + } + + // redraw crosshair + var pos = crosshair.pos, mode = options.crosshair.mode; + if (mode != null && pos.x != -1) { + octx.strokeStyle = parseColor(options.crosshair.color).scale(null, null, null, 0.8).toString(); + octx.lineWidth = 1; + ctx.lineJoin = "round"; + + octx.beginPath(); + if (mode.indexOf("x") != -1) { + octx.moveTo(pos.x, 0); + octx.lineTo(pos.x, plotHeight); + } + if (mode.indexOf("y") != -1) { + octx.moveTo(0, pos.y); + octx.lineTo(plotWidth, pos.y); + } + octx.stroke(); + + } + octx.restore(); + } + + function highlight(s, point, auto) { + if (typeof s == "number") + s = series[s]; + + if (typeof point == "number") + point = s.data[point]; + + var i = indexOfHighlight(s, point); + if (i == -1) { + highlights.push({ series: s, point: point, auto: auto }); + + triggerRedrawOverlay(); + } + else if (!auto) + highlights[i].auto = false; + } + + function unhighlight(s, point) { + if (typeof s == "number") + s = series[s]; + + if (typeof point == "number") + point = s.data[point]; + + var i = indexOfHighlight(s, point); + if (i != -1) { + highlights.splice(i, 1); + + triggerRedrawOverlay(); + } + } + + function indexOfHighlight(s, p) { + for (var i = 0; i < highlights.length; ++i) { + var h = highlights[i]; + if (h.series == s && h.point[0] == p[0] + && h.point[1] == p[1]) + return i; + } + return -1; + } + + function drawPointHighlight(series, point) { + var x = point.x, y = point.y, + axisx = series.xaxis, axisy = series.yaxis; + + if (x < axisx.min || x > axisx.max || y < axisy.min || y > axisy.max) + return; + + var pointRadius = series.points.radius + series.points.lineWidth / 2; + octx.lineWidth = pointRadius; + octx.strokeStyle = parseColor(series.color).scale(1, 1, 1, 0.5).toString(); + var radius = 1.5 * pointRadius; + octx.beginPath(); + octx.arc(axisx.p2c(x), axisy.p2c(y), radius, 0, 2 * Math.PI, true); + octx.stroke(); + } + + function drawBarHighlight(series, point) { + octx.lineJoin = "round"; + octx.lineWidth = series.bars.lineWidth; + octx.strokeStyle = parseColor(series.color).scale(1, 1, 1, 0.5).toString(); + var fillStyle = parseColor(series.color).scale(1, 1, 1, 0.5).toString(); + var barLeft = series.bars.align == "left" ? 0 : -series.bars.barWidth/2; + drawBar(point.x, point.y, barLeft, barLeft + series.bars.barWidth, + 0, function () { return fillStyle; }, series.xaxis, series.yaxis, octx); + } + + function setPositionFromEvent(pos, e) { + var offset = DOM.getXY(eventHolder[0]); + pos.x = clamp(0, e.pageX - offset[0] - plotOffset.left, plotWidth); + pos.y = clamp(0, e.pageY - offset[1] - plotOffset.top, plotHeight); + } + + function setCrosshair(pos) { + if (pos == null) + crosshair.pos.x = -1; + else { + crosshair.pos.x = clamp(0, pos.x != null ? axes.xaxis.p2c(pos.x) : axes.x2axis.p2c(pos.x2), plotWidth); + crosshair.pos.y = clamp(0, pos.y != null ? axes.yaxis.p2c(pos.y) : axes.y2axis.p2c(pos.y2), plotHeight); + } + triggerRedrawOverlay(); + } + + function getSelectionForEvent() { + var x1 = Math.min(selection.first.x, selection.second.x), + x2 = Math.max(selection.first.x, selection.second.x), + y1 = Math.max(selection.first.y, selection.second.y), + y2 = Math.min(selection.first.y, selection.second.y); + + var r = {}; + if (axes.xaxis.used) + r.xaxis = { from: axes.xaxis.c2p(x1), to: axes.xaxis.c2p(x2) }; + if (axes.x2axis.used) + r.x2axis = { from: axes.x2axis.c2p(x1), to: axes.x2axis.c2p(x2) }; + if (axes.yaxis.used) + r.yaxis = { from: axes.yaxis.c2p(y1), to: axes.yaxis.c2p(y2) }; + if (axes.y2axis.used) + r.y2axis = { from: axes.y2axis.c2p(y1), to: axes.y2axis.c2p(y2) }; + return r; + } + + function triggerSelectedEvent() { + var r = getSelectionForEvent(); + + plot.fireEvent("plotselected", r); + } + + function onSelectionMouseUp(e) { + // revert drag stuff for old-school browsers + if (document.onselectstart !== undefined) + document.onselectstart = workarounds.onselectstart; + if (document.ondrag !== undefined) + document.ondrag = workarounds.ondrag; + + // no more draggy-dee-drag + selection.active = false; + var mousePos = {pageX: E.getPageX(e), pageY: E.getPageY(e)}; + updateSelection(mousePos); + + if (selectionIsSane()) { + triggerSelectedEvent(); + clickIsMouseUp = true; + } + else { + // this counts as a clear + plot.fireEvent("plotunselected", {}); + } + + E.removeListener(document, "mouseup", onSelectionMouseUp); + return false; + } + + function setSelectionPos(pos, e) { + setPositionFromEvent(pos, e); + + if (options.selection.mode == "y") { + if (pos == selection.first) + pos.x = 0; + else + pos.x = plotWidth; + } + + if (options.selection.mode == "x") { + if (pos == selection.first) + pos.y = 0; + else + pos.y = plotHeight; + } + } + + function updateSelection(pos) { + if (pos.pageX == null) + return; + + setSelectionPos(selection.second, pos); + if (selectionIsSane()) { + selection.show = true; + triggerRedrawOverlay(); + } + else + clearSelection(true); + } + + function clearSelection(preventEvent) { + if (selection.show) { + selection.show = false; + triggerRedrawOverlay(); + if (!preventEvent) + plot.fireEvent("plotunselected", {}); + } + } + + function setSelection(ranges, preventEvent) { + var range; + + if (options.selection.mode == "y") { + selection.first.x = 0; + selection.second.x = plotWidth; + } + else { + range = extractRange(ranges, "x"); + + selection.first.x = range.axis.p2c(range.from); + selection.second.x = range.axis.p2c(range.to); + } + + if (options.selection.mode == "x") { + selection.first.y = 0; + selection.second.y = plotHeight; + } + else { + range = extractRange(ranges, "y"); + + selection.first.y = range.axis.p2c(range.from); + selection.second.y = range.axis.p2c(range.to); + } + + selection.show = true; + triggerRedrawOverlay(); + if (!preventEvent) + triggerSelectedEvent(); + } + + function selectionIsSane() { + var minSize = 5; + return Math.abs(selection.second.x - selection.first.x) >= minSize && + Math.abs(selection.second.y - selection.first.y) >= minSize; + } + + function getColorOrGradient(spec, bottom, top, defaultColor) { + if (typeof spec == "string") + return spec; + else { + // assume this is a gradient spec; IE currently only + // supports a simple vertical gradient properly, so that's + // what we support too + var gradient = ctx.createLinearGradient(0, top, 0, bottom); + + for (var i = 0, l = spec.colors.length; i < l; ++i) { + var c = spec.colors[i]; + gradient.addColorStop(i / (l - 1), typeof c == "string" ? c : parseColor(defaultColor).scale(c.brightness, c.brightness, c.brightness, c.opacity)); + } + + return gradient; + } + } + } + + L.augment(Plot, YAHOO.util.EventProvider); + + YAHOO.widget.Flot = function(target, data, options) { + return new Plot(target, data, options); + }; + + // round to nearby lower multiple of base + function floorInBase(n, base) { + return base * Math.floor(n / base); + } + + function clamp(min, value, max) { + if (value < min) + return min; + else if (value > max) + return max; + else + return value; + } + + // color helpers, inspiration from the jquery color animation + // plugin by John Resig + function Color (r, g, b, a) { + + var rgba = ['r','g','b','a']; + var x = 4; //rgba.length + + while (-1<--x) { + this[rgba[x]] = arguments[x] || ((x==3) ? 1.0 : 0); + } + + this.toString = function() { + if (this.a >= 1.0) { + return "rgb("+[this.r,this.g,this.b].join(",")+")"; + } else { + return "rgba("+[this.r,this.g,this.b,this.a].join(",")+")"; + } + }; + + this.scale = function(rf, gf, bf, af) { + x = 4; //rgba.length + while (-1<--x) { + if (arguments[x] != null) + this[rgba[x]] *= arguments[x]; + } + return this.normalize(); + }; + + this.adjust = function(rd, gd, bd, ad) { + x = 4; //rgba.length + while (-1<--x) { + if (arguments[x] != null) + this[rgba[x]] += arguments[x]; + } + return this.normalize(); + }; + + this.clone = function() { + return new Color(this.r, this.b, this.g, this.a); + }; + + var limit = function(val,minVal,maxVal) { + return Math.max(Math.min(val, maxVal), minVal); + }; + + this.normalize = function() { + this.r = clamp(0, parseInt(this.r, 10), 255); + this.g = clamp(0, parseInt(this.g, 10), 255); + this.b = clamp(0, parseInt(this.b, 10), 255); + this.a = clamp(0, this.a, 1); + return this; + }; + + this.normalize(); + } + + var lookupColors = { + aqua:[0,255,255], + azure:[240,255,255], + beige:[245,245,220], + black:[0,0,0], + blue:[0,0,255], + brown:[165,42,42], + cyan:[0,255,255], + darkblue:[0,0,139], + darkcyan:[0,139,139], + darkgrey:[169,169,169], + darkgreen:[0,100,0], + darkkhaki:[189,183,107], + darkmagenta:[139,0,139], + darkolivegreen:[85,107,47], + darkorange:[255,140,0], + darkorchid:[153,50,204], + darkred:[139,0,0], + darksalmon:[233,150,122], + darkviolet:[148,0,211], + fuchsia:[255,0,255], + gold:[255,215,0], + green:[0,128,0], + indigo:[75,0,130], + khaki:[240,230,140], + lightblue:[173,216,230], + lightcyan:[224,255,255], + lightgreen:[144,238,144], + lightgrey:[211,211,211], + lightpink:[255,182,193], + lightyellow:[255,255,224], + lime:[0,255,0], + magenta:[255,0,255], + maroon:[128,0,0], + navy:[0,0,128], + olive:[128,128,0], + orange:[255,165,0], + pink:[255,192,203], + purple:[128,0,128], + violet:[128,0,128], + red:[255,0,0], + silver:[192,192,192], + white:[255,255,255], + yellow:[255,255,0] + }; + + function extractColor(element) { + var color, elem = element; + do { + color = DOM.getStyle(elem, 'backgroundColor').toLowerCase(); + // keep going until we find an element that has color, or + // we hit the body + if (color != '' && color != 'transparent') + break; + elem = elem.parentNode; + } while (!elem.nodeName == "body"); + + // catch Safari's way of signalling transparent + if (color == "rgba(0, 0, 0, 0)") + return "transparent"; + + return color; + } + + // parse string, returns Color + function parseColor(str) { + var result; + + // Look for rgb(num,num,num) + if (result = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(str)) + return new Color(parseInt(result[1], 10), parseInt(result[2], 10), parseInt(result[3], 10)); + + // Look for rgba(num,num,num,num) + if (result = /rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(str)) + return new Color(parseInt(result[1], 10), parseInt(result[2], 10), parseInt(result[3], 10), parseFloat(result[4])); + + // Look for rgb(num%,num%,num%) + if (result = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(str)) + return new Color(parseFloat(result[1])*2.55, parseFloat(result[2])*2.55, parseFloat(result[3])*2.55); + + // Look for rgba(num%,num%,num%,num) + if (result = /rgba\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(str)) + return new Color(parseFloat(result[1])*2.55, parseFloat(result[2])*2.55, parseFloat(result[3])*2.55, parseFloat(result[4])); + + // Look for #a0b1c2 + if (result = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(str)) + return new Color(parseInt(result[1], 16), parseInt(result[2], 16), parseInt(result[3], 16)); + + // Look for #fff + if (result = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(str)) + return new Color(parseInt(result[1]+result[1], 16), parseInt(result[2]+result[2], 16), parseInt(result[3]+result[3], 16)); + + // Otherwise, we're most likely dealing with a named color + var name = L.trim(str).toLowerCase(); + if (name == "transparent") + return new Color(255, 255, 255, 0); + else { + result = lookupColors[name]; + return new Color(result[0], result[1], result[2]); + } + } + +})(); diff --git a/pylons_app/templates/admin/admin.html b/pylons_app/templates/admin/admin.html --- a/pylons_app/templates/admin/admin.html +++ b/pylons_app/templates/admin/admin.html @@ -4,18 +4,25 @@ <%def name="title()"> ${_('Administration')} -<%def name="breadcrumbs()"> - ${h.link_to(u'Admin',h.url('admin_home'))} + +<%def name="breadcrumbs_links()"> + ${_('Admin dashboard - journal')} + <%def name="page_nav()"> ${self.menu('admin')} - ${self.submenu('')} <%def name="main()"> -
-

Welcome ${c.hg_app_user.username}

-
- ${c.log_data} -
-
+
+ +
+ ${self.breadcrumbs()} +
+ +
+
+ ${c.log_data} +
+
+
\ No newline at end of file diff --git a/pylons_app/templates/admin/admin_log.html b/pylons_app/templates/admin/admin_log.html --- a/pylons_app/templates/admin/admin_log.html +++ b/pylons_app/templates/admin/admin_log.html @@ -1,12 +1,12 @@ ## -*- coding: utf-8 -*- %if c.users_log: - - - - - - - +
${_('Username')}${_('Repository')}${_('Action')}${_('Date')}${_('From IP')}
+ + + + + + %for cnt,l in enumerate(c.users_log): @@ -18,22 +18,23 @@ %endfor +
${_('Username')}${_('Repository')}${_('Action')}${_('Date')}${_('From IP')}
${l.user_ip}
- -
- -

${c.users_log.pager('$link_previous ~2~ $link_next', - onclick="""YAHOO.util.Connect.asyncRequest('GET','$partial_url',{ - success:function(o){YAHOO.util.Dom.get(data_div).innerHTML=o.responseText; - YAHOO.util.Event.addListener(YAHOO.util.Dom.getElementsByClassName('pager_link'),"click",function(){ - YAHOO.util.Dom.setStyle(data_div,'opacity','0.3');}); - YAHOO.util.Dom.setStyle(data_div,'opacity','1');}},null); return false;""")} -

+ + + +
+${c.users_log.pager('$link_previous ~2~ $link_next', +onclick="""YAHOO.util.Connect.asyncRequest('GET','$partial_url',{ +success:function(o){YAHOO.util.Dom.get(data_div).innerHTML=o.responseText; +YAHOO.util.Event.addListener(YAHOO.util.Dom.getElementsByClassName('pager_link'),"click",function(){ + YAHOO.util.Dom.setStyle(data_div,'opacity','0.3');}); +YAHOO.util.Dom.setStyle(data_div,'opacity','1');}},null); return false;""")}
%else: ${_('No actions yet')} diff --git a/pylons_app/templates/admin/permissions/permissions.html b/pylons_app/templates/admin/permissions/permissions.html --- a/pylons_app/templates/admin/permissions/permissions.html +++ b/pylons_app/templates/admin/permissions/permissions.html @@ -4,18 +4,25 @@ <%def name="title()"> ${_('Permissions administration')} -<%def name="breadcrumbs()"> - ${h.link_to(u'Admin',h.url('admin_home'))} - / - ${_('Permissions')} + +<%def name="breadcrumbs_links()"> + ${h.link_to(_('Admin'),h.url('admin_home'))} + » + ${_('Permissions')} + <%def name="page_nav()"> ${self.menu('admin')} - ${self.submenu('permissions')} <%def name="main()"> -
-

${_('Permissions')}

- +
+ +
+ ${self.breadcrumbs()}
+ +
+ To implement +
+
diff --git a/pylons_app/templates/admin/repos/repo_add.html b/pylons_app/templates/admin/repos/repo_add.html --- a/pylons_app/templates/admin/repos/repo_add.html +++ b/pylons_app/templates/admin/repos/repo_add.html @@ -4,41 +4,57 @@ <%def name="title()"> ${_('Repositories administration')} -<%def name="breadcrumbs()"> - ${h.link_to(u'Admin',h.url('admin_home'))} - / - ${_('Repos')} + +<%def name="breadcrumbs_links()"> + ${h.link_to(_('Admin'),h.url('admin_home'))} + » + ${h.link_to(_('Repositories'),h.url('repos'))} + » + ${_('add new')} + <%def name="page_nav()"> ${self.menu('admin')} - ${self.submenu('repos')} <%def name="main()"> -
-

${_('Repositories')} - ${_('add new')}

- ${h.form(url('repos'))} - - - - - - - - - - - - - - - - - - - - - -
${_('Name')}${h.text('repo_name',c.new_repo)}${self.get_form_error('repo_name')}
${_('Description')}${h.textarea('description',cols=23,rows=5)}${self.get_form_error('description')}
${_('Private')}${h.checkbox('private',value="True")}${self.get_form_error('private')}
${h.submit('add','add')}
- ${h.end_form()} +
+ +
+ ${self.breadcrumbs()}
+ ${h.form(url('repos'))} +
+ +
+
+
+ +
+
+ ${h.text('repo_name',c.new_repo)} +
+
+
+
+ +
+
+ ${h.textarea('description',cols=23,rows=5)} +
+
+
+
+ +
+
+ ${h.checkbox('private',value="True")} +
+
+
+ ${h.submit('add','add',class_="ui-button ui-widget ui-state-default ui-corner-all")} +
+
+
+ ${h.end_form()} +
diff --git a/pylons_app/templates/admin/repos/repo_edit.html b/pylons_app/templates/admin/repos/repo_edit.html --- a/pylons_app/templates/admin/repos/repo_edit.html +++ b/pylons_app/templates/admin/repos/repo_edit.html @@ -4,245 +4,271 @@ <%def name="title()"> ${_('Repositories administration')} -<%def name="breadcrumbs()"> - ${h.link_to(u'Admin',h.url('admin_home'))} - / - ${_('Repos')} + +<%def name="breadcrumbs_links()"> + ${h.link_to(_('Admin'),h.url('admin_home'))} + » + ${h.link_to(_('Repositories'),h.url('repos'))} + » + ${_('edit')} "${c.repo_name}" + <%def name="page_nav()"> ${self.menu('admin')} - ${self.submenu('repos')} + <%def name="main()"> -
-

${_('Repositories')} - ${_('edit')} "${c.repo_name}"

- ${h.form(url('repo', repo_name=c.repo_info.repo_name),method='put')} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
${_('Name')}${h.text('repo_name',size="28")}${self.get_form_error('repo_name')}
${_('Description')}${h.textarea('description',cols=32,rows=5)}${self.get_form_error('description')}
${_('Private')}${h.checkbox('private',value="True")}${self.get_form_error('private')}
${_('Owner')} -
- ${h.text('user',class_='yui-ac-input')} -
-
-
${self.get_form_error('user')}
${_('Permissions')} - - - - - - - - - - %for r2p in c.repo_info.repo2perm: - %if r2p.user.username =='default' and c.repo_info.private: - - - - - %else: - - - - - - - - - %endif - %endfor - <% - if not hasattr(c,'form_errors'): - d = 'display:none;' - else: - d='' - %> +
+ +
+ ${self.breadcrumbs()} +
+ ${h.form(url('repo', repo_name=c.repo_info.repo_name),method='put')} +
+ +
+
+
+ +
+
+ ${h.text('repo_name')} +
+
+ +
+
+ +
+
+ ${h.textarea('description',cols=23,rows=5)} +
+
+ +
+
+ +
+
+ ${h.checkbox('private',value="True")} +
+
+ +
+
+ +
+
+
+ ${h.text('user',class_='yui-ac-input')} +
+
+
+
+ +
+
+ +
+
+
${_('none')}${_('read')}${_('write')}${_('admin')}${_('user')}
- ${_('disabled for private repository')}${r2p.user.username}
${h.radio('perm_%s' % r2p.user.username,'repository.none')}${h.radio('perm_%s' % r2p.user.username,'repository.read')}${h.radio('perm_%s' % r2p.user.username,'repository.write')}${h.radio('perm_%s' % r2p.user.username,'repository.admin')}${r2p.user.username} - %if r2p.user.username !='default': - - - - %endif -
+ + + + + + + + + + %for r2p in c.repo_info.repo2perm: + %if r2p.user.username =='default' and c.repo_info.private: + + + + + %else: + + + + + + + + + %endif + %endfor - - - - - - - - - - - -
${_('none')}${_('read')}${_('write')}${_('admin')}${_('user')}
+ + ${_('disabled for private repository')} + + ${r2p.user.username}
${h.radio('perm_%s' % r2p.user.username,'repository.none')}${h.radio('perm_%s' % r2p.user.username,'repository.read')}${h.radio('perm_%s' % r2p.user.username,'repository.write')}${h.radio('perm_%s' % r2p.user.username,'repository.admin')}${r2p.user.username} + %if r2p.user.username !='default': + + + + %endif +
${h.radio('perm_new_user','repository.none')}${h.radio('perm_new_user','repository.read')}${h.radio('perm_new_user','repository.write')}${h.radio('perm_new_user','repository.admin')} -
- ${h.text('perm_new_user_name',class_='yui-ac-input')} -
-
-
${self.get_form_error('perm_new_user_name')}
- - ${_('Add another user')} - -
-
${h.submit('update','update')}
- ${h.end_form()} + + ${h.radio('perm_new_user','repository.none')} + ${h.radio('perm_new_user','repository.read')} + ${h.radio('perm_new_user','repository.write')} + ${h.radio('perm_new_user','repository.admin')} + +
+ ${h.text('perm_new_user_name',class_='yui-ac-input')} +
+
+ + + + + + + ${_('Add another user')} + + + + +
+ +
+ ${h.submit('save','save',class_="ui-button ui-widget ui-state-default ui-corner-all")} +
+
+
+
+ ${h.end_form()} - - - + oAC_perms.itemSelectEvent.subscribe(myHandler); + oAC_owner.itemSelectEvent.subscribe(myHandler); + + return { + oDS: oDS, + oAC_perms: oAC_perms, + oAC_owner: oAC_owner, + }; + }(); + + + + + \ No newline at end of file diff --git a/pylons_app/templates/admin/repos/repos.html b/pylons_app/templates/admin/repos/repos.html --- a/pylons_app/templates/admin/repos/repos.html +++ b/pylons_app/templates/admin/repos/repos.html @@ -4,42 +4,52 @@ <%def name="title()"> ${_('Repositories administration')} -<%def name="breadcrumbs()"> - ${h.link_to(u'Admin',h.url('admin_home'))} - / - ${_('Repos')} + + +<%def name="breadcrumbs_links()"> + ${h.link_to(_('Admin'),h.url('admin_home'))} » ${_('Repositories')} <%def name="page_nav()"> ${self.menu('admin')} - ${self.submenu('repos')} <%def name="main()"> -
+ + + diff --git a/pylons_app/templates/shortlog/shortlog.html b/pylons_app/templates/shortlog/shortlog.html --- a/pylons_app/templates/shortlog/shortlog.html +++ b/pylons_app/templates/shortlog/shortlog.html @@ -2,23 +2,32 @@ <%inherit file="/base/base.html"/> <%def name="title()"> - ${_('Repository managment')} + ${_('Shortlog')} -<%def name="breadcrumbs()"> + + +<%def name="breadcrumbs_links()"> ${h.link_to(u'Home',h.url('/'))} - / - ${h.link_to(c.repo_name,h.url('shortlog_home',repo_name=c.repo_name))} - / + » + ${h.link_to(c.repo_name,h.url('summary_home',repo_name=c.repo_name))} + » ${_('shortlog')} + <%def name="page_nav()"> - ${self.menu('shortlog')} + ${self.menu('shortlog')} <%def name="main()"> - - - -
- ${c.shortlog_data} -
- \ No newline at end of file +
+ +
+ ${self.breadcrumbs()} +
+ +
+
+ ${c.shortlog_data} +
+
+
+ \ No newline at end of file diff --git a/pylons_app/templates/shortlog/shortlog_data.html b/pylons_app/templates/shortlog/shortlog_data.html --- a/pylons_app/templates/shortlog/shortlog_data.html +++ b/pylons_app/templates/shortlog/shortlog_data.html @@ -1,15 +1,14 @@ ## -*- coding: utf-8 -*- % if c.repo_changesets: - - - - - - - - - - +
${_('date')}${_('author')}${_('revision')}${_('commit message')}${_('branch')}${_('tags')}${_('links')}
+ + + + + + + + %for cnt,cs in enumerate(c.repo_changesets): @@ -43,22 +42,22 @@ %endfor
${_('date')}${_('author')}${_('revision')}${_('commit message')}${_('branch')}${_('tags')}${_('links')}
-
- -

- ${c.repo_changesets.pager('$link_previous ~2~ $link_next', - onclick="""YAHOO.util.Connect.asyncRequest('GET','$partial_url',{ - success:function(o){YAHOO.util.Dom.get(data_div).innerHTML=o.responseText; - YAHOO.util.Event.addListener(YAHOO.util.Dom.getElementsByClassName('pager_link'),"click",function(){ - YAHOO.util.Dom.setStyle(data_div,'opacity','0.3');}); - YAHOO.util.Dom.setStyle(data_div,'opacity','1');}},null); return false;""")} -

-
+ + + +
+${c.repo_changesets.pager('$link_previous ~2~ $link_next', +onclick="""YAHOO.util.Connect.asyncRequest('GET','$partial_url',{ +success:function(o){YAHOO.util.Dom.get(data_div).innerHTML=o.responseText; +YAHOO.util.Event.addListener(YAHOO.util.Dom.getElementsByClassName('pager_link'),"click",function(){ + YAHOO.util.Dom.setStyle(data_div,'opacity','0.3');}); +YAHOO.util.Dom.setStyle(data_div,'opacity','1');}},null); return false;""")} +
%else: - ${_('There are no commits yet')} -%endif \ No newline at end of file + ${_('There are no commits yet')} +%endif diff --git a/pylons_app/templates/summary/summary.html b/pylons_app/templates/summary/summary.html --- a/pylons_app/templates/summary/summary.html +++ b/pylons_app/templates/summary/summary.html @@ -1,71 +1,270 @@ <%inherit file="/base/base.html"/> + <%def name="title()"> - ${_('Repository managment')} + ${_('Mercurial Repository Overview')} -<%def name="breadcrumbs()"> + + + +<%def name="breadcrumbs_links()"> ${h.link_to(u'Home',h.url('/'))} - / + » ${h.link_to(c.repo_name,h.url('summary_home',repo_name=c.repo_name))} - / + » ${_('summary')} + <%def name="page_nav()"> ${self.menu('summary')} -<%def name="js()"> - +<%def name="main()"> - +
+ +
+ ${self.breadcrumbs()} +
+ +
+
+ +
+
+ +
+
+ ${c.repo_info.name} +
+
+ + +
+
+ +
+
+ ${c.repo_info.description} +
+
+ + +
+
+ +
+
+ ${c.repo_info.contact} +
+
+ +
+
+ +
+
+ ${h.age(c.repo_info.last_change)} - ${h.rfc822date(c.repo_info.last_change)} +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+
+ %for cnt,archive in enumerate(c.repo_info._get_archives()): + %if cnt >=1: + | + %endif + ${h.link_to(c.repo_info.name+'.'+archive['type'], + h.url('files_archive_home',repo_name=c.repo_info.name, + revision='tip',fileformat=archive['extension']),class_="archive_icon")} + %endfor +
+
+ +
+
+ +
+
+ ${h.link_to(_('RSS'),h.url('rss_feed_home',repo_name=c.repo_info.name),class_='rss_icon')} + ${h.link_to(_('Atom'),h.url('atom_feed_home',repo_name=c.repo_info.name),class_='atom_icon')} +
+
+
+
+
+ +
+ +
+
${_('Last month commit activity')}
+
+ +
+
+
+
+
+ + +
+
+
+ + +
+
+ +
+
+ +
+
+ <%include file='../shortlog/shortlog_data.html'/> +
+
+
+
+ +
+
+ <%include file='../tags/tags_data.html'/> +
+
+
+
+ +
+
+ <%include file='../branches/branches_data.html'/> +
+
\ No newline at end of file diff --git a/pylons_app/templates/tags/tags.html b/pylons_app/templates/tags/tags.html --- a/pylons_app/templates/tags/tags.html +++ b/pylons_app/templates/tags/tags.html @@ -1,20 +1,31 @@ +## -*- coding: utf-8 -*- <%inherit file="/base/base.html"/> + <%def name="title()"> - ${_('Tags')} + ${_('Administration')} -<%def name="breadcrumbs()"> + + +<%def name="breadcrumbs_links()"> ${h.link_to(u'Home',h.url('/'))} - / + » ${h.link_to(c.repo_name,h.url('summary_home',repo_name=c.repo_name))} - / + » ${_('tags')} + <%def name="page_nav()"> - ${self.menu('tags')} + ${self.menu('tags')} <%def name="main()"> - - - <%include file='tags_data.html'/> - - \ No newline at end of file +
+ +
+ ${self.breadcrumbs()} +
+ +
+ <%include file='tags_data.html'/> +
+
+ \ No newline at end of file diff --git a/pylons_app/templates/tags/tags_data.html b/pylons_app/templates/tags/tags_data.html --- a/pylons_app/templates/tags/tags_data.html +++ b/pylons_app/templates/tags/tags_data.html @@ -1,10 +1,10 @@ %if c.repo_tags: - - - - - - +
${_('date')}${_('revision')}${_('name')}${_('links')}
+ + + + + %for cnt,tag in enumerate(c.repo_tags.items()):
${_('date')}${_('revision')}${_('name')}${_('links')}
-

${_('Repositories administration')}

+
+ +
+ ${self.breadcrumbs()} + +
+ +
- - - + + + - %for cnt,repo in enumerate(c.repos_list): - - - + %for cnt,repo in enumerate(c.repos_list): + + + - - %endfor -
${_('name')}${_('last revision')}${_('action')}${_('name')}${_('last revision')}${_('action')}
- %if repo['repo'].dbrepo.private: - ${_('private')} - %else: - ${_('public')} - %endif - ${h.link_to(repo['name'],h.url('edit_repo',repo_name=repo['name']))}r${repo['rev']}:${repo['tip']}
+ %if repo['repo'].dbrepo.private: + ${_('private')} + %else: + ${_('public')} + %endif + ${h.link_to(repo['name'],h.url('edit_repo',repo_name=repo['name']))}r${repo['rev']}:${repo['tip']} ${h.form(url('repo', repo_name=repo['name']),method='delete')} - ${h.submit('remove','delete',class_="delete_icon action_button",onclick="return confirm('Confirm to delete this repository');")} + ${h.submit('remove','delete',class_="delete_icon action_button",onclick="return confirm('Confirm to delete this repository');")} ${h.end_form()} -
- ${h.link_to(u'add repo',h.url('new_repo'))} + + + %endfor +
+
+ diff --git a/pylons_app/templates/admin/settings/settings.html b/pylons_app/templates/admin/settings/settings.html --- a/pylons_app/templates/admin/settings/settings.html +++ b/pylons_app/templates/admin/settings/settings.html @@ -4,50 +4,81 @@ <%def name="title()"> ${_('Settings administration')} -<%def name="breadcrumbs()"> - ${h.link_to(u'Admin',h.url('admin_home'))} - / - ${_('Settings')} + + + +<%def name="breadcrumbs_links()"> + ${h.link_to(_('Admin'),h.url('admin_home'))} » ${_('Settings')} + <%def name="page_nav()"> ${self.menu('admin')} - ${self.submenu('settings')} -<%def name="main()"> -
-

${_('Settings administration')}

- ${h.form(url('admin_setting', id='mapping'),method='put')} - - - - - - - -
${_('Remap and rescan repositories')}
- ${_('destroy old data')} ${h.checkbox('destroy',True)}${h.submit('rescan','rescan repositories')}
- ${h.end_form()} -
- ${h.form(url('admin_setting', id='global'),method='put')} - - - - - - - - - - - - - - - - -
${_('Global application settings')}
${_('Application name')}${h.text('app_title',size=30)}${self.get_form_error('app_title')}
${_('Realm text')}${h.text('app_auth_realm',size=30)}${self.get_form_error('app_auth_realm')}
${h.submit('save','save settings')}
- ${h.end_form()} +<%def name="main()"> +
+ +
+ ${self.breadcrumbs()} +
+ -
+ ${h.form(url('admin_setting', id='mapping'),method='put')} +
+ +

${_('Remap and rescan repositories')}

+
+
+
+ +
+
+
+ ${h.checkbox('destroy',True)} + +
+
+
+ +
+ ${h.submit('rescan','rescan repositories',class_="ui-button ui-widget ui-state-default ui-corner-all")} +
+
+
+ ${h.end_form()} + + ${h.form(url('admin_setting', id='global'),method='put')} +
+ +

${_('Global application settings')}

+
+ +
+
+ +
+
+ ${h.text('app_title',size=30)} +
+
+ +
+
+ +
+
+ ${h.text('app_auth_realm',size=30)} +
+
+ +
+ ${h.submit('save','save settings',class_="ui-button ui-widget ui-state-default ui-corner-all")} +
+
+
+ ${h.end_form()} + +
diff --git a/pylons_app/templates/admin/users/user_add.html b/pylons_app/templates/admin/users/user_add.html --- a/pylons_app/templates/admin/users/user_add.html +++ b/pylons_app/templates/admin/users/user_add.html @@ -4,55 +4,88 @@ <%def name="title()"> ${_('User administration')} -<%def name="breadcrumbs()"> - ${h.link_to(u'Admin',h.url('admin_home'))} - / - ${_('Users')} +<%def name="breadcrumbs_links()"> + ${h.link_to(_('Admin'),h.url('admin_home'))} + » + ${h.link_to(_('Users'),h.url('users'))} + » + ${_('add new user')} + <%def name="page_nav()"> ${self.menu('admin')} - ${self.submenu('users')} + <%def name="main()"> -
-

${_('User')} - ${_('add new')}

- ${h.form(url('users'))} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
${_('Username')}${h.text('username')}${self.get_form_error('username')}
${_('Password')}${h.password('password')}${self.get_form_error('password')}
${_('Name')}${h.text('name')}${self.get_form_error('name')}
${_('Lastname')}${h.text('lastname')}${self.get_form_error('lastname')}
${_('Email')}${h.text('email')}${self.get_form_error('email')}
${_('Active')}${h.checkbox('active',value=True)}${self.get_form_error('active')}
${h.submit('save','save')}
- ${h.end_form()} +
+ +
+ ${self.breadcrumbs()}
+ + ${h.form(url('users'))} +
+ +
+
+
+ +
+
+ ${h.text('username')} +
+
+ +
+
+ +
+
+ ${h.password('password')} +
+
+ +
+
+ +
+
+ ${h.text('name')} +
+
+ +
+
+ +
+
+ ${h.text('lastname')} +
+
+ +
+
+ +
+
+ ${h.text('email')} +
+
+ +
+
+ +
+
+ ${h.checkbox('active',value=True)} +
+
+ +
+ ${h.submit('save','save',class_="ui-button ui-widget ui-state-default ui-corner-all")} +
+
+
+ ${h.end_form()} +
\ No newline at end of file diff --git a/pylons_app/templates/admin/users/user_edit.html b/pylons_app/templates/admin/users/user_edit.html --- a/pylons_app/templates/admin/users/user_edit.html +++ b/pylons_app/templates/admin/users/user_edit.html @@ -4,61 +4,98 @@ <%def name="title()"> ${_('User administration')} -<%def name="breadcrumbs()"> - ${h.link_to(u'Admin',h.url('admin_home'))} - / - ${_('Users')} + +<%def name="breadcrumbs_links()"> + ${h.link_to(_('Admin'),h.url('admin_home'))} + » + ${h.link_to(_('Users'),h.url('users'))} + » + ${_('edit')} "${c.user.username}" + <%def name="page_nav()"> ${self.menu('admin')} - ${self.submenu('users')} + <%def name="main()"> -
-

${_('User')} - ${c.user.username}

- ${h.form(url('user', id=c.user.user_id),method='put')} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
${_('Username')}${h.text('username')}${self.get_form_error('username')}
${_('New password')}${h.text('new_password')}${self.get_form_error('new_password')}
${_('Name')}${h.text('name')}${self.get_form_error('name')}
${_('Lastname')}${h.text('lastname')}${self.get_form_error('lastname')}
${_('Email')}${h.text('email')}${self.get_form_error('email')}
${_('Active')}${h.checkbox('active',value=True)}${self.get_form_error('active')}
${_('Admin')}${h.checkbox('admin',value=True)}${self.get_form_error('admin')}
${h.submit('save','save')}
- ${h.end_form()} +
+ +
+ ${self.breadcrumbs()}
+ + ${h.form(url('user', id=c.user.user_id),method='put')} +
+ +
+
+
+ +
+
+ ${h.text('username')} +
+
+ +
+
+ +
+
+ ${h.text('new_password')} +
+
+ +
+
+ +
+
+ ${h.text('name')} +
+
+ +
+
+ +
+
+ ${h.password('lastname')} +
+
+ +
+
+ +
+
+ ${h.text('email')} +
+
+ +
+
+ +
+
+ ${h.checkbox('active',value=True)} +
+
+ +
+
+ +
+
+ ${h.checkbox('admin',value=True)} +
+
+ +
+ ${h.submit('save','save',class_="ui-button ui-widget ui-state-default ui-corner-all")} +
+
+
+ ${h.end_form()} +
\ No newline at end of file diff --git a/pylons_app/templates/admin/users/users.html b/pylons_app/templates/admin/users/users.html --- a/pylons_app/templates/admin/users/users.html +++ b/pylons_app/templates/admin/users/users.html @@ -4,42 +4,55 @@ <%def name="title()"> ${_('Users administration')} -<%def name="breadcrumbs()"> - ${h.link_to(u'Admin',h.url('admin_home'))} - / - ${_('Users')} + +<%def name="breadcrumbs_links()"> + ${h.link_to(_('Admin'),h.url('admin_home'))} » ${_('Users')} + <%def name="page_nav()"> ${self.menu('admin')} - ${self.submenu('users')} + <%def name="main()"> -
-

${_('Users administration')}

+
+ +
+ ${self.breadcrumbs()} + +
+ +
- - - - - - - - - %for user in c.users_list: - + + + + + + + + + %for cnt,user in enumerate(c.users_list): + %if user.name !='default': + + ${h.form(url('user', id=user.user_id),method='delete')} + ${h.submit('remove','delete',class_="delete_icon action_button")} + ${h.end_form()} + + %endif %endfor
${_('username')}${_('name')}${_('lastname')}${_('active')}${_('admin')}${_('action')}
${_('username')}${_('name')}${_('lastname')}${_('active')}${_('admin')}${_('action')}
${h.link_to(user.username,h.url('edit_user', id=user.user_id))} ${user.name} ${user.lastname} ${user.active} ${user.admin} - ${h.form(url('user', id=user.user_id),method='delete')} - ${h.submit('remove','delete',class_="delete_icon action_button")} - ${h.end_form()} -
- ${h.link_to(u'add user',h.url('new_user'))}
+
diff --git a/pylons_app/templates/base/base.html b/pylons_app/templates/base/base.html --- a/pylons_app/templates/base/base.html +++ b/pylons_app/templates/base/base.html @@ -2,97 +2,120 @@ + ${next.title()} + - ${next.title()} - ##For future use yui reset for cross browser compatability. - ## + ${self.css()} + ${self.js()} + + +
+ + + +
+
+ <% messages = h.flash.pop_messages() %> + % if messages: +
    + % for message in messages: +
  • ${message}
  • + % endfor +
+ % endif +
+
+ ${next.main()} +
+
+ - -
- - ### MAKO DEFS ### - <%def name="page_nav()"> ${self.menu()} - ${self.submenu()} -<%def name="menu(current)"> -<% -def is_current(selected): - if selected == current: - return "class='current'" -%> +<%def name="menu(current=None)"> + <% + def is_current(selected): + if selected == current: + return "class='current'" + %> %if current not in ['home','admin']: - ##regular menu - -
- -<%def name="submenu(current=None)"> - <% - def is_current(selected): - if selected == current: - return "class='current_submenu'" - %> - %if current != None: -
- -
- %endif <%def name="css()"> - + + + + + + <%def name="js()"> + + - -<%def name="get_form_error(element)"> - %if hasattr(c,'form_errors') and type(c.form_errors) == dict: - %if c.form_errors.get(element,False): - - ${c.form_errors.get(element,'')} - - %endif - %endif +<%def name="breadcrumbs()"> + \ No newline at end of file diff --git a/pylons_app/templates/branches/branches.html b/pylons_app/templates/branches/branches.html --- a/pylons_app/templates/branches/branches.html +++ b/pylons_app/templates/branches/branches.html @@ -1,18 +1,31 @@ +## -*- coding: utf-8 -*- <%inherit file="/base/base.html"/> + <%def name="title()"> - ${_('Branches')} + ${_('Administration')} -<%def name="breadcrumbs()"> + +<%def name="breadcrumbs_links()"> ${h.link_to(u'Home',h.url('/'))} - / + » ${h.link_to(c.repo_name,h.url('summary_home',repo_name=c.repo_name))} - / + » ${_('branches')} + <%def name="page_nav()"> - ${self.menu('branches')} + ${self.menu('branches')} + <%def name="main()"> - - <%include file='branches_data.html'/> - \ No newline at end of file +
+ +
+ ${self.breadcrumbs()} +
+ +
+ <%include file='branches_data.html'/> +
+
+ \ No newline at end of file diff --git a/pylons_app/templates/branches/branches_data.html b/pylons_app/templates/branches/branches_data.html --- a/pylons_app/templates/branches/branches_data.html +++ b/pylons_app/templates/branches/branches_data.html @@ -1,11 +1,11 @@ % if c.repo_branches: - - - - - - + + + + + + %for cnt,branch in enumerate(c.repo_branches.items()): diff --git a/pylons_app/templates/changelog/changelog.html b/pylons_app/templates/changelog/changelog.html --- a/pylons_app/templates/changelog/changelog.html +++ b/pylons_app/templates/changelog/changelog.html @@ -3,106 +3,107 @@ <%def name="title()"> ${_('Changelog - %s') % c.repo_name} -<%def name="breadcrumbs()"> + +<%def name="breadcrumbs_links()"> ${h.link_to(u'Home',h.url('/'))} - / - ${h.link_to(c.repo_name,h.url('changelog_home',repo_name=c.repo_name))} - / - ${_('changelog')} + » + ${h.link_to(c.repo_name,h.url('summary_home',repo_name=c.repo_name))} + » + ${_('Changelog')} - ${_('showing ')} ${c.size if c.size <= c.total_cs else c.total_cs} ${_('out of')} ${c.total_cs} ${_('revisions')} + <%def name="page_nav()"> ${self.menu('changelog')} <%def name="main()"> - - - -% if c.pagination: - -
-
- -
-
-
- ${h.form(h.url.current(),method='get')} -
- ${_('Show')}: - ${h.text('size',size=2,value=c.size)} - ${_('revisions')} - ${h.submit('set',_('set'))} -
- ${h.end_form()} -
- %for cnt,cs in enumerate(c.pagination): -
-
-
${_('commit')} ${cs.revision}: ${cs.raw_id}@${cs.date}
- - ${cs.branch} - %for tag in cs.tags: - ${tag} - %endfor - -
${cs.author}
-
- ${h.link_to(h.wrap_paragraphs(cs.message), - h.url('changeset_home',repo_name=c.repo_name,revision=cs.raw_id))} +
+ +
+ ${self.breadcrumbs()} +
+
+ % if c.pagination: +
+
+
-
-
-
- ${len(cs.removed)} - ${len(cs.changed)} - ${len(cs.added)} -
- %if len(cs.parents)>1: -
- ${_('merge')}merge -
- %endif - %for p_cs in reversed(cs.parents): -
${_('Parent')} ${p_cs.revision}: ${h.link_to(p_cs.raw_id, - h.url('changeset_home',repo_name=c.repo_name,revision=p_cs.raw_id),title=p_cs.message)} +
+
+ + ${h.form(h.url.current(),method='get')} +
+ ${_('Show')}: + ${h.text('size',size=1,value=c.size)} + ${_('revisions')} + ${h.submit('set',_('set'))} +
+ ${h.end_form()} + +
+ %for cnt,cs in enumerate(c.pagination): +
+
+
${_('commit')} ${cs.revision}: ${cs.raw_id}@${cs.date}
+ + ${cs.branch} + %for tag in cs.tags: + ${tag} + %endfor + +
${cs.author}
+
+ ${h.link_to(h.wrap_paragraphs(cs.message), + h.url('changeset_home',repo_name=c.repo_name,revision=cs.raw_id))}
- %endfor -
-
- - %endfor -
-
- - - - -
-

${c.pagination.pager('$link_previous ~2~ $link_next')}

-
-%else: - ${_('There are no changes yet')} -%endif - \ No newline at end of file +
+
+
+ ${len(cs.removed)} + ${len(cs.changed)} + ${len(cs.added)} +
+ %if len(cs.parents)>1: +
+ ${_('merge')}merge +
+ %endif + %for p_cs in reversed(cs.parents): +
${_('Parent')} ${p_cs.revision}: ${h.link_to(p_cs.raw_id, + h.url('changeset_home',repo_name=c.repo_name,revision=p_cs.raw_id),title=p_cs.message)} +
+ %endfor +
+
+ + %endfor +
+ ${c.pagination.pager('$link_previous ~2~ $link_next')} +
+
+
+ + + + %else: + ${_('There are no changes yet')} + %endif +
+
+ \ No newline at end of file diff --git a/pylons_app/templates/changeset/changeset.html b/pylons_app/templates/changeset/changeset.html --- a/pylons_app/templates/changeset/changeset.html +++ b/pylons_app/templates/changeset/changeset.html @@ -3,23 +3,26 @@ <%def name="title()"> ${_('Changeset')} -<%def name="breadcrumbs()"> + +<%def name="breadcrumbs_links()"> ${h.link_to(u'Home',h.url('/'))} - / - ${h.link_to(c.repo_name,h.url('changeset_home',repo_name=c.repo_name))} - / - ${_('changeset')} + » + ${h.link_to(c.repo_name,h.url('summary_home',repo_name=c.repo_name))} + » + ${_('Changeset')} - r${c.changeset.revision}:${c.changeset.raw_id} + <%def name="page_nav()"> ${self.menu('changelog')} -<%def name="css()"> - - - + <%def name="main()"> - - +
+ +
+ ${self.breadcrumbs()} +
+
@@ -84,6 +87,8 @@
%endif - %endfor - - \ No newline at end of file + %endfor +
+
+ + \ No newline at end of file diff --git a/pylons_app/templates/errors/error_document.html b/pylons_app/templates/errors/error_document.html --- a/pylons_app/templates/errors/error_document.html +++ b/pylons_app/templates/errors/error_document.html @@ -1,46 +1,53 @@ ## -*- coding: utf-8 -*- - - - Error - ${c.error_message} - - - %if c.redirect_time: - - %endif - + + Error - ${c.error_message} + + %if c.redirect_time: + + %endif + + + + + + + + - - - - -
-

${c.error_message}

- -

${c.error_explanation}

- %if c.redirect_time: -

${_('You will be redirected to %s in %s seconds') % (c.redirect_module,c.redirect_time)}

- %endif - -
- + + + +
+
+
+

${c.error_message}

+ +

${c.error_explanation}

+ %if c.redirect_time: +

${_('You will be redirected to %s in %s seconds') % (c.redirect_module,c.redirect_time)}

+ %endif + +
+
+ +
+ + - diff --git a/pylons_app/templates/files/file_diff.html b/pylons_app/templates/files/file_diff.html --- a/pylons_app/templates/files/file_diff.html +++ b/pylons_app/templates/files/file_diff.html @@ -3,41 +3,47 @@ <%def name="title()"> ${_('Repository managment')} -<%def name="breadcrumbs()"> +<%def name="breadcrumbs_links()"> ${h.link_to(u'Home',h.url('/'))} - / - ${h.link_to(c.repo_name,h.url('files_home',repo_name=c.repo_name))} - / - ${_('files')} + » + ${h.link_to(c.repo_name,h.url('summary_home',repo_name=c.repo_name))} + » + ${'%s: %s %s %s' % (_('File diff'),c.diff2,'→',c.diff1)|n} + <%def name="page_nav()"> ${self.menu('files')} -<%def name="css()"> - - - <%def name="main()"> - -
-
-
- ${h.link_to(c.f_path,h.url('files_home',repo_name=c.repo_name, - revision=c.diff2.split(':')[1],f_path=c.f_path))} - » ${h.link_to(_('diff'), - h.url.current(diff2=c.diff2.split(':')[-1],diff1=c.diff1.split(':')[-1],diff='diff'))} - » ${h.link_to(_('raw diff'), - h.url.current(diff2=c.diff2.split(':')[-1],diff1=c.diff1.split(':')[-1],diff='raw'))} - » ${h.link_to(_('download diff'), - h.url.current(diff2=c.diff2.split(':')[-1],diff1=c.diff1.split(':')[-1],diff='download'))} -
-
-
- %if c.no_changes: - ${_('No changes')} - %else: - ${c.cur_diff|n} - %endif -
-
- \ No newline at end of file +
+ +
+ ${self.breadcrumbs()} +
+
+
+
+
+ ${h.link_to(c.f_path,h.url('files_home',repo_name=c.repo_name, + revision=c.diff2.split(':')[1],f_path=c.f_path))} + » ${h.link_to(_('diff'), + h.url.current(diff2=c.diff2.split(':')[-1],diff1=c.diff1.split(':')[-1],diff='diff'))} + » ${h.link_to(_('raw diff'), + h.url.current(diff2=c.diff2.split(':')[-1],diff1=c.diff1.split(':')[-1],diff='raw'))} + » ${h.link_to(_('download diff'), + h.url.current(diff2=c.diff2.split(':')[-1],diff1=c.diff1.split(':')[-1],diff='download'))} +
+
+
+ %if c.no_changes: + ${_('No changes')} + %else: + ${c.cur_diff|n} + %endif +
+
+
+
+ + + \ No newline at end of file diff --git a/pylons_app/templates/files/files.html b/pylons_app/templates/files/files.html --- a/pylons_app/templates/files/files.html +++ b/pylons_app/templates/files/files.html @@ -1,38 +1,48 @@ <%inherit file="/base/base.html"/> <%def name="title()"> - ${_('Repository managment')} - -<%def name="breadcrumbs()"> - ${h.link_to(u'Home',h.url('/'))} - / - ${h.link_to(c.repo_name,h.url('files_home',repo_name=c.repo_name))} - / ${_('files')} + +<%def name="breadcrumbs_links()"> + ${h.link_to(u'Home',h.url('/'))} + » + ${h.link_to(c.repo_name,h.url('files_home',repo_name=c.repo_name))} + » + ${_('files')} + %if c.files_list: + @ R${c.rev_nr}:${c.cur_rev} + %endif + + <%def name="page_nav()"> ${self.menu('files')} -<%def name="css()"> - - - + <%def name="main()"> - -
- %if c.files_list: -

${_('Location')}: ${h.files_breadcrumbs(c.repo_name,c.cur_rev,c.files_list.path)}

- %if c.files_list.is_dir(): - <%include file='files_browser.html'/> +
+ +
+ ${self.breadcrumbs()} +
+
+
+ %if c.files_list: +

${_('Location')}: ${h.files_breadcrumbs(c.repo_name,c.cur_rev,c.files_list.path)}

+ %if c.files_list.is_dir(): + <%include file='files_browser.html'/> + %else: + <%include file='files_source.html'/> + %endif %else: - <%include file='files_source.html'/> - %endif - %else: -

- ${_('Go back')} - ${_('No files at given path')}: "${c.f_path or "/"}" -

- %endif - -
+

+ ${_('Go back')} + ${_('No files at given path')}: "${c.f_path or "/"}" +

+ %endif + +
+
+
+ \ No newline at end of file diff --git a/pylons_app/templates/files/files_annotate.html b/pylons_app/templates/files/files_annotate.html --- a/pylons_app/templates/files/files_annotate.html +++ b/pylons_app/templates/files/files_annotate.html @@ -3,44 +3,49 @@ <%def name="title()"> ${_('File annotate')} -<%def name="breadcrumbs()"> + +<%def name="breadcrumbs_links()"> ${h.link_to(u'Home',h.url('/'))} - / - ${h.link_to(c.repo_name,h.url('files_home',repo_name=c.repo_name))} - / - ${_('files')} + » + ${h.link_to(c.repo_name,h.url('summary_home',repo_name=c.repo_name))} + » + ${_('annotate')} + <%def name="page_nav()"> ${self.menu('files')} -<%def name="css()"> - - - <%def name="main()"> - -
-

${_('Location')}: ${h.files_breadcrumbs(c.repo_name,c.cur_rev,c.file.path)}

-
-
${_('Revision')}
-
r${c.file.last_changeset.revision}:${c.file.last_changeset._short}
-
${_('Size')}
-
${h.format_byte_size(c.file.size,binary=True)}
-
${_('Options')}
-
${h.link_to(_('show source'), - h.url('files_home',repo_name=c.repo_name,revision=c.cur_rev,f_path=c.f_path))} - / ${h.link_to(_('download as raw'), - h.url('files_raw_home',repo_name=c.repo_name,revision=c.cur_rev,f_path=c.f_path))} -
-
-
-
-
${c.file.name}@r${c.file.last_changeset.revision}:${c.file.last_changeset._short}
-
"${c.file_msg}"
+
+ +
+ ${self.breadcrumbs()} +
+
+
+

${_('Location')}: ${h.files_breadcrumbs(c.repo_name,c.cur_rev,c.file.path)}

+
+
${_('Revision')}
+
r${c.file.last_changeset.revision}:${c.file.last_changeset._short}
+
${_('Size')}
+
${h.format_byte_size(c.file.size,binary=True)}
+
${_('Options')}
+
${h.link_to(_('show source'), + h.url('files_home',repo_name=c.repo_name,revision=c.cur_rev,f_path=c.f_path))} + / ${h.link_to(_('download as raw'), + h.url('files_raw_home',repo_name=c.repo_name,revision=c.cur_rev,f_path=c.f_path))} +
+
+
+
+
${c.file.name}@r${c.file.last_changeset.revision}:${c.file.last_changeset._short}
+
"${c.file_msg}"
+
+
+ ${h.pygmentize_annotation(c.file,linenos=True,anchorlinenos=True,lineanchors='S',cssclass="code-highlight")} +
-
- ${h.pygmentize_annotation(c.file,linenos=True,anchorlinenos=True,lineanchors='S',cssclass="code-highlight")} -
-
-
- \ No newline at end of file +
+
+
+ \ No newline at end of file diff --git a/pylons_app/templates/files/files_browser.html b/pylons_app/templates/files/files_browser.html --- a/pylons_app/templates/files/files_browser.html +++ b/pylons_app/templates/files/files_browser.html @@ -8,9 +8,13 @@
${h.form(h.url.current())} - ${_('view')}@rev «${h.text('at_rev',value=c.rev_nr,size='5')}» - ${c.cur_rev} - ${h.submit('view','view')} +
+ ${_('view')}@rev + « + ${h.text('at_rev',value=c.rev_nr,size=3)} + » + ${h.submit('view','view')} +
${h.end_form()}
diff --git a/pylons_app/templates/files/files_source.html b/pylons_app/templates/files/files_source.html --- a/pylons_app/templates/files/files_source.html +++ b/pylons_app/templates/files/files_source.html @@ -1,5 +1,5 @@ -
-
${_('Revision')}
+
+
${_('Last revision')}
r${c.files_list.last_changeset.revision}:${c.files_list.last_changeset._short}
${_('Size')}
${h.format_byte_size(c.files_list.size,binary=True)}
@@ -14,11 +14,12 @@ ${h.form(h.url('files_diff_home',repo_name=c.repo_name,f_path=c.f_path),method='GET')} ${h.hidden('diff2',c.files_list.last_changeset._short)} ${h.select('diff1','',c.file_history)} - ${h.submit('diff','diff')} + ${h.submit('diff','diff',class_="ui-button ui-widget ui-state-default ui-corner-all")} ${h.end_form()} - -
+
+ +
${c.files_list.name}@r${c.files_list.last_changeset.revision}:${c.files_list.last_changeset._short}
diff --git a/pylons_app/templates/index.html b/pylons_app/templates/index.html --- a/pylons_app/templates/index.html +++ b/pylons_app/templates/index.html @@ -1,10 +1,10 @@ ## -*- coding: utf-8 -*- <%inherit file="base/base.html"/> <%def name="title()"> - ${c.repos_prefix} + ${c.hg_app_name} <%def name="breadcrumbs()"> - ${c.repos_prefix} + ${c.hg_app_name} <%def name="page_nav()"> ${self.menu('home')} @@ -17,46 +17,61 @@ %else: ${name} %endif - - + + -
${_('date')}${_('revision')}${_('name')}${_('links')}
${_('date')}${_('revision')}${_('name')}${_('links')}
${h.age(branch[1]._ctx.date())}
- - - - - - - - - - %for cnt,repo in enumerate(c.repos_list): - %if h.HasRepoPermissionAny('repository.write','repository.read','repository.admin')(repo['name'],'main page check'): - - - - - - - - - - - %endif - %endfor -
${get_sort(_('Name'))}${get_sort(_('Description'))}${get_sort(_('Last change'))}${get_sort(_('Tip'))}${get_sort(_('Contact'))}${_('RSS')}${_('Atom')}
- %if repo['repo'].dbrepo.private: - ${_('private')} - %else: - ${_('public')} - %endif - ${h.link_to(repo['name'], - h.url('summary_home',repo_name=repo['name']))}${h.truncate(repo['description'],60)}${h.age(repo['last_change'])}${h.link_to_if(repo['rev']>=0,'r%s:%s' % (repo['rev'],repo['tip']), - h.url('changeset_home',repo_name=repo['name'],revision=repo['tip']), - class_="tooltip", - tooltip_title=h.tooltip(repo['last_msg']))}${h.person(repo['contact'])} - - - -
+ + + +
+ +
+
${_('Dashboard')}
+
+ +
+ + + + + + + + + + + + + + %for cnt,repo in enumerate(c.repos_list): + %if h.HasRepoPermissionAny('repository.write','repository.read','repository.admin')(repo['name'],'main page check'): + + + + + + + + + + %endif + %endfor + +
${get_sort(_('Name'))}${get_sort(_('Description'))}${get_sort(_('Last change'))}${get_sort(_('Tip'))}${get_sort(_('Contact'))}${_('RSS')}${_('Atom')}
+ %if repo['repo'].dbrepo.private: + ${_('private')} + %else: + ${_('public')} + %endif + ${h.link_to(repo['name'], + h.url('summary_home',repo_name=repo['name']))}${h.truncate(repo['description'],60)}${h.age(repo['last_change'])}${h.link_to_if(repo['rev']>=0,'r%s:%s' % (repo['rev'],repo['tip']), + h.url('changeset_home',repo_name=repo['name'],revision=repo['tip']), + class_="tooltip", + tooltip_title=h.tooltip(repo['last_msg']))}${h.person(repo['contact'])} + + + +
+
+
diff --git a/pylons_app/templates/login.html b/pylons_app/templates/login.html --- a/pylons_app/templates/login.html +++ b/pylons_app/templates/login.html @@ -1,38 +1,76 @@ ## -*- coding: utf-8 -*- -<%inherit file="base/base.html"/> -<%def name="title()"> - ${c.repos_prefix} - -<%def name="breadcrumbs()"> - ${c.repos_prefix} - -<%def name="page_nav()"> -   -
- -<%def name="main()"> -
-
-

${_('Login to hg app')}

- ${h.form(h.url.current())} - - - - - - - - - - - - - - - -
${_('Username')}${h.text('username')}${self.get_form_error('username')}
${_('Password')}${h.password('password')}${self.get_form_error('password')}
${h.submit('login','login')}
- ${h.end_form()} + + + + ${_('Sign In to hg-app')} + + + + + + + + + + + + + +
+ +
+
${_('Sign In to hg-app')}
+
+
+
+
+ ${h.form(h.url.current())} +
+ + +
+
+
+ +
+
+ ${h.text('username',class_='focus',size=40)} +
+ +
+
+
+ +
+
+ ${h.password('password',class_='focus',size=40)} +
+ +
+ ##
+ ##
+ ## + ## + ##
+ ##
+
+ ${h.submit('sign_in','Sign In',class_="ui-button ui-widget ui-state-default ui-corner-all")} +
+
+ + + + + +
+ ${h.end_form()} +
+
- + + - diff --git a/pylons_app/templates/register.html b/pylons_app/templates/register.html new file mode 100644 --- /dev/null +++ b/pylons_app/templates/register.html @@ -0,0 +1,88 @@ +## -*- coding: utf-8 -*- + + + + ${_('Sign Up to hg-app')} + + + + + + + + + + + + + +
+ +
+
${_('Sign Up to hg-app')}
+
+
+
+
+ ${h.form(url('register'))} +
+ +
+
+
+ +
+
+ ${h.text('username')} +
+
+ +
+
+ +
+
+ ${h.password('password')} +
+
+ +
+
+ +
+
+ ${h.text('name')} +
+
+ +
+
+ +
+
+ ${h.text('lastname')} +
+
+ +
+
+ +
+
+ ${h.text('email')} +
+
+ +
+
+ ${h.submit('sign_up','Sign Up',class_="ui-button ui-widget ui-state-default ui-corner-all")} +
+
+
+
+ ${h.end_form()} +
+
+ + + diff --git a/pylons_app/templates/settings/repo_settings.html b/pylons_app/templates/settings/repo_settings.html --- a/pylons_app/templates/settings/repo_settings.html +++ b/pylons_app/templates/settings/repo_settings.html @@ -2,239 +2,256 @@ <%inherit file="/base/base.html"/> <%def name="title()"> - ${_('Repository settings')} + ${_('Repositories administration')} -<%def name="breadcrumbs()"> - ${h.link_to(u'Home',h.url('/'))} - / - ${h.link_to(c.repo_name,h.url('shortlog_home',repo_name=c.repo_name))} - / - ${_('settings')} + +<%def name="breadcrumbs_links()"> + ${h.link_to(c.repo_info.repo_name,h.url('summary_home',repo_name=c.repo_info.repo_name))} + » + ${_('Settings')} + <%def name="page_nav()"> - ${self.menu('settings')} + ${self.menu('settings')} <%def name="main()"> - -
- ${h.form(url('repo_settings_update', repo_name=c.repo_info.repo_name),method='put')} - - - - - - - - - - - - - - - - - - - - - - - - - - -
${_('Name')}${h.text('repo_name',size="28")}${self.get_form_error('repo_name')}
${_('Description')}${h.textarea('description',cols=32,rows=5)}${self.get_form_error('description')}
${_('Private')}${h.checkbox('private',value="True")}${self.get_form_error('private')}
${_('Permissions')} - - - - - - - - - - %for r2p in c.repo_info.repo2perm: - %if r2p.user.username =='default' and c.repo_info.private: - - - - - %else: - - - - - - - - - %endif - %endfor - <% - if not hasattr(c,'form_errors'): - d = 'display:none;' - else: - d='' - %> +
+ +
+ ${self.breadcrumbs()} +
+ ${h.form(url('repo_settings_update', repo_name=c.repo_info.repo_name),method='put')} +
+ +
+
+
+ +
+
+ ${h.text('repo_name')} +
+
+ +
+
+ +
+
+ ${h.textarea('description',cols=23,rows=5)} +
+
+ +
+
+ +
+
+ ${h.checkbox('private',value="True")} +
+
+ +
+
+ +
+
+
${_('none')}${_('read')}${_('write')}${_('admin')}${_('user')}
- ${_('disabled for private repository')}${r2p.user.username}
${h.radio('perm_%s' % r2p.user.username,'repository.none')}${h.radio('perm_%s' % r2p.user.username,'repository.read')}${h.radio('perm_%s' % r2p.user.username,'repository.write')}${h.radio('perm_%s' % r2p.user.username,'repository.admin')}${r2p.user.username} - %if r2p.user.username !='default': - - - - %endif -
+ + + + + + + + + + %for r2p in c.repo_info.repo2perm: + %if r2p.user.username =='default' and c.repo_info.private: + + + + + %else: + + + + + + + + + %endif + %endfor - - - - - - - - - - - -
${_('none')}${_('read')}${_('write')}${_('admin')}${_('user')}
+ + ${_('disabled for private repository')} + + ${r2p.user.username}
${h.radio('perm_%s' % r2p.user.username,'repository.none')}${h.radio('perm_%s' % r2p.user.username,'repository.read')}${h.radio('perm_%s' % r2p.user.username,'repository.write')}${h.radio('perm_%s' % r2p.user.username,'repository.admin')}${r2p.user.username} + %if r2p.user.username !='default': + + + + %endif +
${h.radio('perm_new_user','repository.none')}${h.radio('perm_new_user','repository.read')}${h.radio('perm_new_user','repository.write')}${h.radio('perm_new_user','repository.admin')} -
- ${h.text('perm_new_user_name',class_='yui-ac-input')} -
-
-
${self.get_form_error('perm_new_user_name')}
- - ${_('Add another user')} - -
-
${h.submit('update','update')}
- ${h.end_form()} + + + ${h.radio('perm_new_user','repository.none')} + ${h.radio('perm_new_user','repository.read')} + ${h.radio('perm_new_user','repository.write')} + ${h.radio('perm_new_user','repository.admin')} + +
+ ${h.text('perm_new_user_name',class_='yui-ac-input')} +
+
+ + + + + + + ${_('Add another user')} + + + + +
+ +
+ ${h.submit('update','update',class_="ui-button ui-widget ui-state-default ui-corner-all")} +
+
+
+ ${h.end_form()} - -
- + oAC_perms.itemSelectEvent.subscribe(myHandler); + //oAC_owner.itemSelectEvent.subscribe(myHandler); + + return { + oDS: oDS, + oAC_perms: oAC_perms, + oAC_owner: oAC_owner, + }; + }(); + + +