##// END OF EJS Templates
fixes few bugs...
marcink -
r671:bee56f20 rhodecode-0.0.1.0.1 default
parent child Browse files
Show More
@@ -1,36 +1,46 b''
1 .. _changelog:
1 .. _changelog:
2
2
3 Changelog
3 Changelog
4 =========
4 =========
5
5
6
7 1.0.1 (**2010-11-10**)
8 ----------------------
9
10 - fixed #53 python2.5 incompatible enumerate calls
11 - fixed #52 disable mercurial extension for web
12 - fixed #51 deleting repositories don't delete it's dependent objects
13 - small css updated
14
15
6 1.0.0 (**2010-11-02**)
16 1.0.0 (**2010-11-02**)
7 ----------------------
17 ----------------------
8
18
9 - security bugfix simplehg wasn't checking for permissions on commands
19 - security bugfix simplehg wasn't checking for permissions on commands
10 other than pull or push.
20 other than pull or push.
11 - fixed doubled messages after push or pull in admin journal
21 - fixed doubled messages after push or pull in admin journal
12 - templating and css corrections, fixed repo switcher on chrome, updated titles
22 - templating and css corrections, fixed repo switcher on chrome, updated titles
13 - admin menu accessible from options menu on repository view
23 - admin menu accessible from options menu on repository view
14 - permissions cached queries
24 - permissions cached queries
15
25
16 1.0.0rc4 (**2010-10-12**)
26 1.0.0rc4 (**2010-10-12**)
17 --------------------------
27 --------------------------
18
28
19 - fixed python2.5 missing simplejson imports (thanks to Jens BΓ€ckman)
29 - fixed python2.5 missing simplejson imports (thanks to Jens BΓ€ckman)
20 - removed cache_manager settings from sqlalchemy meta
30 - removed cache_manager settings from sqlalchemy meta
21 - added sqlalchemy cache settings to ini files
31 - added sqlalchemy cache settings to ini files
22 - validated password length and added second try of failure on paster setup-app
32 - validated password length and added second try of failure on paster setup-app
23 - fixed setup database destroy prompt even when there was no db
33 - fixed setup database destroy prompt even when there was no db
24
34
25
35
26 1.0.0rc3 (**2010-10-11**)
36 1.0.0rc3 (**2010-10-11**)
27 -------------------------
37 -------------------------
28
38
29 - fixed i18n during installation.
39 - fixed i18n during installation.
30
40
31 1.0.0rc2 (**2010-10-11**)
41 1.0.0rc2 (**2010-10-11**)
32 -------------------------
42 -------------------------
33
43
34 - Disabled dirsize in file browser, it's causing nasty bug when dir renames
44 - Disabled dirsize in file browser, it's causing nasty bug when dir renames
35 occure. After vcs is fixed it'll be put back again.
45 occure. After vcs is fixed it'll be put back again.
36 - templating/css rewrites, optimized css.
46 - templating/css rewrites, optimized css.
@@ -1,89 +1,90 b''
1 .. _installation:
1 .. _installation:
2
2
3 Installation
3 Installation
4 ============
4 ============
5
5
6 ``RhodeCode`` is written entirely in Python, but in order to use it's full
6 ``RhodeCode`` is written entirely in Python, but in order to use it's full
7 potential there are some third-party requirements. When RhodeCode is used
7 potential there are some third-party requirements. When RhodeCode is used
8 together with celery You have to install some kind of message broker,
8 together with celery_ You have to install some kind of message broker,
9 recommended one is rabbitmq_ to make the async tasks work.
9 recommended one is rabbitmq_ to make the async tasks work.
10
10
11 Of course RhodeCode works in sync mode also, then You don't have to install
11 Of course RhodeCode works in sync mode also, then You don't have to install
12 any third party apps. Celery_ will give You large speed improvement when using
12 any third party apps. Celery_ will give You large speed improvement when using
13 many big repositories. If You plan to use it for 2 or 3 small repositories, it
13 many big repositories. If You plan to use it for 5 or 10 small repositories, it
14 will work just fine without celery running.
14 will work just fine without celery running.
15
15
16 After You decide to Run it with celery make sure You run celeryd and
16 After You decide to Run it with celery make sure You run celeryd and
17 message broker together with the application.
17 message broker together with the application.
18
18
19 Requirements for Celery
19 Requirements for Celery
20 -----------------------
20 -----------------------
21
21
22 **Message Broker**
22 **Message Broker**
23
23
24 - preferred is `RabbitMq <http://www.rabbitmq.com/>`_
24 - preferred is `RabbitMq <http://www.rabbitmq.com/>`_
25 - possible other is `Redis <http://code.google.com/p/redis/>`_
25 - possible other is `Redis <http://code.google.com/p/redis/>`_
26
26
27 For installation instructions You can visit:
27 For installation instructions You can visit:
28 http://ask.github.com/celery/getting-started/index.html
28 http://ask.github.com/celery/getting-started/index.html
29 It's very nice tutorial how to start celery_ with rabbitmq_
29 It's very nice tutorial how to start celery_ with rabbitmq_
30
30
31 Install from Cheese Shop
31 Install from Cheese Shop
32 ------------------------
32 ------------------------
33
33
34 Easiest way to install ``rhodecode`` is to run::
34 Easiest way to install ``rhodecode`` is to run::
35
35
36 easy_install rhodecode
36 easy_install rhodecode
37
37
38 Or::
38 Or::
39
39
40 pip install rhodecode
40 pip install rhodecode
41
41
42 If you prefer to install manually simply grab latest release from
42 If you prefer to install manually simply grab latest release from
43 http://pypi.python.org/pypi/rhodecode, decompres archive and run::
43 http://pypi.python.org/pypi/rhodecode, decompres archive and run::
44
44
45 python setup.py install
45 python setup.py install
46
46
47
47
48 Step by step installation example
48 Step by step installation example
49 ---------------------------------
49 ---------------------------------
50
50
51
51
52 - Assuming You have installed virtualenv_ create one using. The `--no-site-packages`
52 - Assuming You have installed virtualenv_ create one using.
53 will make sure non of Your system libs are linked with this virtualenv_
53 The `--no-site-packages` will make sure non of Your system libs are linked
54 with this virtualenv_
54
55
55 ::
56 ::
56
57
57 virtualenv --no-site-packages /var/www/rhodecode-venv
58 virtualenv --no-site-packages /var/www/rhodecode-venv
58
59
59 - this will install new virtualenv_ into `/var/www/rhodecode-venv`.
60 - this will install new virtualenv_ into `/var/www/rhodecode-venv`.
60 - Activate the virtualenv_ by running
61 - Activate the virtualenv_ by running
61
62
62 ::
63 ::
63
64
64 source activate /var/www/rhodecode-venv/bin/activate
65 source activate /var/www/rhodecode-venv/bin/activate
65
66
66 - Make a folder for rhodecode somewhere on the filesystem for example
67 - Make a folder for rhodecode somewhere on the filesystem for example
67
68
68 ::
69 ::
69
70
70 mkdir /var/www/rhodecode
71 mkdir /var/www/rhodecode
71
72
72
73
73 - Run this command to install rhodecode
74 - Run this command to install rhodecode
74
75
75 ::
76 ::
76
77
77 easy_install rhodecode
78 easy_install rhodecode
78
79
79 - this will install rhodecode together with pylons
80 - this will install rhodecode together with pylons
80 and all other required python libraries
81 and all other required python libraries
81
82
82
83
83 You can now proceed to :ref:`setup`
84 You can now proceed to :ref:`setup`
84
85
85 .. _virtualenv: http://pypi.python.org/pypi/virtualenv
86 .. _virtualenv: http://pypi.python.org/pypi/virtualenv
86 .. _python: http://www.python.org/
87 .. _python: http://www.python.org/
87 .. _mercurial: http://mercurial.selenic.com/
88 .. _mercurial: http://mercurial.selenic.com/
88 .. _celery: http://celeryproject.org/
89 .. _celery: http://celeryproject.org/
89 .. _rabbitmq: http://www.rabbitmq.com/ No newline at end of file
90 .. _rabbitmq: http://www.rabbitmq.com/
@@ -1,129 +1,141 b''
1 .. _setup:
1 .. _setup:
2
2
3 Setup
3 Setup
4 =====
4 =====
5
5
6
6
7 Setting up the application
7 Setting up the application
8 --------------------------
8 --------------------------
9
9
10 ::
10 ::
11
11
12 paster make-config RhodeCode production.ini
12 paster make-config RhodeCode production.ini
13
13
14 - This will create `production.ini` config inside the directory
14 - This will create `production.ini` config inside the directory
15 this config contain various settings for rhodecode, e.g port, email settings
15 this config contain various settings for rhodecode, e.g port, email settings
16 static files, cache and logging.
16 static files, cache and logging.
17
17
18 ::
18 ::
19
19
20 paster setup-app production.ini
20 paster setup-app production.ini
21
21
22 - This command will create all needed tables and an admin account.
22 - This command will create all needed tables and an admin account.
23 When asked for a path You can either use a new location of one with already
23 When asked for a path You can either use a new location of one with already
24 existing ones. RhodeCode will simply add all new found repositories to
24 existing ones. RhodeCode will simply add all new found repositories to
25 it's database. Also make sure You specify correct path to repositories.
25 it's database. Also make sure You specify correct path to repositories.
26 - Remember that the given path for mercurial_ repositories must be write
26 - Remember that the given path for mercurial_ repositories must be write
27 accessible for the application. It's very important since RhodeCode web interface
27 accessible for the application. It's very important since RhodeCode web interface
28 will work even without such an access but, when trying to do a push it'll
28 will work even without such an access but, when trying to do a push it'll
29 eventually fail with permission denied errors.
29 eventually fail with permission denied errors.
30 - Run
30 - Run
31
31
32 ::
32 ::
33
33
34 paster serve production.ini
34 paster serve production.ini
35
35
36 - This command runs the rhodecode server the app should be available at the
36 - This command runs the rhodecode server the app should be available at the
37 127.0.0.1:5000. This ip and port is configurable via the production.ini
37 127.0.0.1:5000. This ip and port is configurable via the production.ini
38 file created in previous step
38 file created in previous step
39 - Use admin account you created to login.
39 - Use admin account you created to login.
40 - Default permissions on each repository is read, and owner is admin. So
40 - Default permissions on each repository is read, and owner is admin. So
41 remember to update these if needed.
41 remember to update these if needed.
42
42
43 Note
44 ----
45
46 RhodeCode when running without the celery it's running all it's task in sync
47 mode, for first few times when visiting summary page You can notice few
48 slow downs, this is due the statistics building it's cache. After all changesets
49 are parsed it'll take the stats from cache and run much faster. Each summary
50 page display parse at most 250 changesets in order to not stress the cpu, so
51 the full stats are going to be loaded after total_number_of_changesets/250
52 summary page visits.
53
54
43
55
44 Setting up Whoosh
56 Setting up Whoosh
45 -----------------
57 -----------------
46
58
47 - For full text search You can either put crontab entry for
59 - For full text search You can either put crontab entry for
48
60
49 ::
61 ::
50
62
51 python /var/www/rhodecode/<rhodecode_installation_path>/lib/indexers/daemon.py incremental <put_here_path_to_repos>
63 python /var/www/rhodecode/<rhodecode_installation_path>/lib/indexers/daemon.py incremental <put_here_path_to_repos>
52
64
53 When using incremental mode whoosh will check last modification date of each file
65 When using incremental mode whoosh will check last modification date of each file
54 and add it to reindex if newer file is available. Also indexing daemon checks
66 and add it to reindex if newer file is available. Also indexing daemon checks
55 for removed files and removes them from index. Sometime You might want to rebuild
67 for removed files and removes them from index. Sometime You might want to rebuild
56 index from scrach, in admin pannel You can check `build from scratch` flag
68 index from scratch, in admin panel You can check `build from scratch` flag
57 and in standalone daemon You can pass `full` instead on incremental to build
69 and in standalone daemon You can pass `full` instead on incremental to build
58 remove previos index and build new one.
70 remove previous index and build new one.
59
71
60 Nginx virtual host example
72 Nginx virtual host example
61 --------------------------
73 --------------------------
62
74
63 Sample config for nginx::
75 Sample config for nginx::
64
76
65 server {
77 server {
66 listen 80;
78 listen 80;
67 server_name hg.myserver.com;
79 server_name hg.myserver.com;
68 access_log /var/log/nginx/rhodecode.access.log;
80 access_log /var/log/nginx/rhodecode.access.log;
69 error_log /var/log/nginx/rhodecode.error.log;
81 error_log /var/log/nginx/rhodecode.error.log;
70 location / {
82 location / {
71 root /var/www/rhodecode/rhodecode/public/;
83 root /var/www/rhodecode/rhodecode/public/;
72 if (!-f $request_filename){
84 if (!-f $request_filename){
73 proxy_pass http://127.0.0.1:5000;
85 proxy_pass http://127.0.0.1:5000;
74 }
86 }
75 #this is important for https !!!
87 #this is important for https !!!
76 proxy_set_header X-Url-Scheme $scheme;
88 proxy_set_header X-Url-Scheme $scheme;
77 include /etc/nginx/proxy.conf;
89 include /etc/nginx/proxy.conf;
78 }
90 }
79 }
91 }
80
92
81 Here's the proxy.conf. It's tuned so it'll not timeout on long
93 Here's the proxy.conf. It's tuned so it'll not timeout on long
82 pushes and also on large pushes::
94 pushes and also on large pushes::
83
95
84 proxy_redirect off;
96 proxy_redirect off;
85 proxy_set_header Host $host;
97 proxy_set_header Host $host;
86 proxy_set_header X-Host $http_host;
98 proxy_set_header X-Host $http_host;
87 proxy_set_header X-Real-IP $remote_addr;
99 proxy_set_header X-Real-IP $remote_addr;
88 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
100 proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
89 proxy_set_header Proxy-host $proxy_host;
101 proxy_set_header Proxy-host $proxy_host;
90 client_max_body_size 400m;
102 client_max_body_size 400m;
91 client_body_buffer_size 128k;
103 client_body_buffer_size 128k;
92 proxy_buffering off;
104 proxy_buffering off;
93 proxy_connect_timeout 3600;
105 proxy_connect_timeout 3600;
94 proxy_send_timeout 3600;
106 proxy_send_timeout 3600;
95 proxy_read_timeout 3600;
107 proxy_read_timeout 3600;
96 proxy_buffer_size 8k;
108 proxy_buffer_size 8k;
97 proxy_buffers 8 32k;
109 proxy_buffers 8 32k;
98 proxy_busy_buffers_size 64k;
110 proxy_busy_buffers_size 64k;
99 proxy_temp_file_write_size 64k;
111 proxy_temp_file_write_size 64k;
100
112
101 Also when using root path with nginx You might set the static files to false
113 Also when using root path with nginx You might set the static files to false
102 in production.ini file::
114 in production.ini file::
103
115
104 [app:main]
116 [app:main]
105 use = egg:rhodecode
117 use = egg:rhodecode
106 full_stack = true
118 full_stack = true
107 static_files = false
119 static_files = false
108 lang=en
120 lang=en
109 cache_dir = %(here)s/data
121 cache_dir = %(here)s/data
110
122
111 To not have the statics served by the application. And improve speed.
123 To not have the statics served by the application. And improve speed.
112
124
113
125
114 Other configuration files
126 Other configuration files
115 -------------------------
127 -------------------------
116
128
117 Some extra configuration files and examples can be found here:
129 Some extra configuration files and examples can be found here:
118 http://hg.python-works.com/rhodecode/files/tip/init.d
130 http://hg.python-works.com/rhodecode/files/tip/init.d
119
131
120 and also an celeryconfig file can be use from here:
132 and also an celeryconfig file can be use from here:
121 http://hg.python-works.com/rhodecode/files/tip/celeryconfig.py
133 http://hg.python-works.com/rhodecode/files/tip/celeryconfig.py
122
134
123
135
124
136
125 .. _virtualenv: http://pypi.python.org/pypi/virtualenv
137 .. _virtualenv: http://pypi.python.org/pypi/virtualenv
126 .. _python: http://www.python.org/
138 .. _python: http://www.python.org/
127 .. _mercurial: http://mercurial.selenic.com/
139 .. _mercurial: http://mercurial.selenic.com/
128 .. _celery: http://celeryproject.org/
140 .. _celery: http://celeryproject.org/
129 .. _rabbitmq: http://www.rabbitmq.com/ No newline at end of file
141 .. _rabbitmq: http://www.rabbitmq.com/
@@ -1,35 +1,35 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 # encoding: utf-8
2 # encoding: utf-8
3 # RhodeCode, a web based repository management based on pylons
3 # RhodeCode, a web based repository management based on pylons
4 # Copyright (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
4 # Copyright (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
5 #
5 #
6 # This program is free software; you can redistribute it and/or
6 # This program is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU General Public License
7 # modify it under the terms of the GNU General Public License
8 # as published by the Free Software Foundation; version 2
8 # as published by the Free Software Foundation; version 2
9 # of the License or (at your opinion) any later version of the license.
9 # of the License or (at your opinion) any later version of the license.
10 #
10 #
11 # This program is distributed in the hope that it will be useful,
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
14 # GNU General Public License for more details.
15 #
15 #
16 # You should have received a copy of the GNU General Public License
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19 # MA 02110-1301, USA.
19 # MA 02110-1301, USA.
20 """
20 """
21 Created on April 9, 2010
21 Created on April 9, 2010
22 RhodeCode, a web based repository management based on pylons
22 RhodeCode, a web based repository management based on pylons
23 versioning implementation: http://semver.org/
23 versioning implementation: http://semver.org/
24 @author: marcink
24 @author: marcink
25 """
25 """
26
26
27 VERSION = (1, 0, 0,)
27 VERSION = (1, 0, 1,)
28
28
29 __version__ = '.'.join((str(each) for each in VERSION[:4]))
29 __version__ = '.'.join((str(each) for each in VERSION[:4]))
30
30
31 def get_version():
31 def get_version():
32 """
32 """
33 Returns shorter version (digit parts only) as string.
33 Returns shorter version (digit parts only) as string.
34 """
34 """
35 return '.'.join((str(each) for each in VERSION[:3]))
35 return '.'.join((str(each) for each in VERSION[:3]))
@@ -1,383 +1,383 b''
1 """Helper functions
1 """Helper functions
2
2
3 Consists of functions to typically be used within templates, but also
3 Consists of functions to typically be used within templates, but also
4 available to Controllers. This module is available to both as 'h'.
4 available to Controllers. This module is available to both as 'h'.
5 """
5 """
6 from pygments.formatters import HtmlFormatter
6 from pygments.formatters import HtmlFormatter
7 from pygments import highlight as code_highlight
7 from pygments import highlight as code_highlight
8 from pylons import url, app_globals as g
8 from pylons import url, app_globals as g
9 from pylons.i18n.translation import _, ungettext
9 from pylons.i18n.translation import _, ungettext
10 from vcs.utils.annotate import annotate_highlight
10 from vcs.utils.annotate import annotate_highlight
11 from webhelpers.html import literal, HTML, escape
11 from webhelpers.html import literal, HTML, escape
12 from webhelpers.html.tools import *
12 from webhelpers.html.tools import *
13 from webhelpers.html.builder import make_tag
13 from webhelpers.html.builder import make_tag
14 from webhelpers.html.tags import auto_discovery_link, checkbox, css_classes, \
14 from webhelpers.html.tags import auto_discovery_link, checkbox, css_classes, \
15 end_form, file, form, hidden, image, javascript_link, link_to, link_to_if, \
15 end_form, file, form, hidden, image, javascript_link, link_to, link_to_if, \
16 link_to_unless, ol, required_legend, select, stylesheet_link, submit, text, \
16 link_to_unless, ol, required_legend, select, stylesheet_link, submit, text, \
17 password, textarea, title, ul, xml_declaration, radio
17 password, textarea, title, ul, xml_declaration, radio
18 from webhelpers.html.tools import auto_link, button_to, highlight, js_obfuscate, \
18 from webhelpers.html.tools import auto_link, button_to, highlight, js_obfuscate, \
19 mail_to, strip_links, strip_tags, tag_re
19 mail_to, strip_links, strip_tags, tag_re
20 from webhelpers.number import format_byte_size, format_bit_size
20 from webhelpers.number import format_byte_size, format_bit_size
21 from webhelpers.pylonslib import Flash as _Flash
21 from webhelpers.pylonslib import Flash as _Flash
22 from webhelpers.pylonslib.secure_form import secure_form
22 from webhelpers.pylonslib.secure_form import secure_form
23 from webhelpers.text import chop_at, collapse, convert_accented_entities, \
23 from webhelpers.text import chop_at, collapse, convert_accented_entities, \
24 convert_misc_entities, lchop, plural, rchop, remove_formatting, \
24 convert_misc_entities, lchop, plural, rchop, remove_formatting, \
25 replace_whitespace, urlify, truncate, wrap_paragraphs
25 replace_whitespace, urlify, truncate, wrap_paragraphs
26
26
27 #Custom helpers here :)
27 #Custom helpers here :)
28 class _Link(object):
28 class _Link(object):
29 '''
29 '''
30 Make a url based on label and url with help of url_for
30 Make a url based on label and url with help of url_for
31 :param label:name of link if not defined url is used
31 :param label:name of link if not defined url is used
32 :param url: the url for link
32 :param url: the url for link
33 '''
33 '''
34
34
35 def __call__(self, label='', *url_, **urlargs):
35 def __call__(self, label='', *url_, **urlargs):
36 if label is None or '':
36 if label is None or '':
37 label = url
37 label = url
38 link_fn = link_to(label, url(*url_, **urlargs))
38 link_fn = link_to(label, url(*url_, **urlargs))
39 return link_fn
39 return link_fn
40
40
41 link = _Link()
41 link = _Link()
42
42
43 class _GetError(object):
43 class _GetError(object):
44
44
45 def __call__(self, field_name, form_errors):
45 def __call__(self, field_name, form_errors):
46 tmpl = """<span class="error_msg">%s</span>"""
46 tmpl = """<span class="error_msg">%s</span>"""
47 if form_errors and form_errors.has_key(field_name):
47 if form_errors and form_errors.has_key(field_name):
48 return literal(tmpl % form_errors.get(field_name))
48 return literal(tmpl % form_errors.get(field_name))
49
49
50 get_error = _GetError()
50 get_error = _GetError()
51
51
52 def recursive_replace(str, replace=' '):
52 def recursive_replace(str, replace=' '):
53 """
53 """
54 Recursive replace of given sign to just one instance
54 Recursive replace of given sign to just one instance
55 :param str: given string
55 :param str: given string
56 :param replace:char to find and replace multiple instances
56 :param replace:char to find and replace multiple instances
57
57
58 Examples::
58 Examples::
59 >>> recursive_replace("Mighty---Mighty-Bo--sstones",'-')
59 >>> recursive_replace("Mighty---Mighty-Bo--sstones",'-')
60 'Mighty-Mighty-Bo-sstones'
60 'Mighty-Mighty-Bo-sstones'
61 """
61 """
62
62
63 if str.find(replace * 2) == -1:
63 if str.find(replace * 2) == -1:
64 return str
64 return str
65 else:
65 else:
66 str = str.replace(replace * 2, replace)
66 str = str.replace(replace * 2, replace)
67 return recursive_replace(str, replace)
67 return recursive_replace(str, replace)
68
68
69 class _ToolTip(object):
69 class _ToolTip(object):
70
70
71 def __call__(self, tooltip_title, trim_at=50):
71 def __call__(self, tooltip_title, trim_at=50):
72 """
72 """
73 Special function just to wrap our text into nice formatted autowrapped
73 Special function just to wrap our text into nice formatted autowrapped
74 text
74 text
75 :param tooltip_title:
75 :param tooltip_title:
76 """
76 """
77
77
78 return wrap_paragraphs(escape(tooltip_title), trim_at)\
78 return wrap_paragraphs(escape(tooltip_title), trim_at)\
79 .replace('\n', '<br/>')
79 .replace('\n', '<br/>')
80
80
81 def activate(self):
81 def activate(self):
82 """
82 """
83 Adds tooltip mechanism to the given Html all tooltips have to have
83 Adds tooltip mechanism to the given Html all tooltips have to have
84 set class tooltip and set attribute tooltip_title.
84 set class tooltip and set attribute tooltip_title.
85 Then a tooltip will be generated based on that
85 Then a tooltip will be generated based on that
86 All with yui js tooltip
86 All with yui js tooltip
87 """
87 """
88
88
89 js = '''
89 js = '''
90 YAHOO.util.Event.onDOMReady(function(){
90 YAHOO.util.Event.onDOMReady(function(){
91 function toolTipsId(){
91 function toolTipsId(){
92 var ids = [];
92 var ids = [];
93 var tts = YAHOO.util.Dom.getElementsByClassName('tooltip');
93 var tts = YAHOO.util.Dom.getElementsByClassName('tooltip');
94
94
95 for (var i = 0; i < tts.length; i++) {
95 for (var i = 0; i < tts.length; i++) {
96 //if element doesn not have and id autgenerate one for tooltip
96 //if element doesn not have and id autgenerate one for tooltip
97
97
98 if (!tts[i].id){
98 if (!tts[i].id){
99 tts[i].id='tt'+i*100;
99 tts[i].id='tt'+i*100;
100 }
100 }
101 ids.push(tts[i].id);
101 ids.push(tts[i].id);
102 }
102 }
103 return ids
103 return ids
104 };
104 };
105 var myToolTips = new YAHOO.widget.Tooltip("tooltip", {
105 var myToolTips = new YAHOO.widget.Tooltip("tooltip", {
106 context: toolTipsId(),
106 context: toolTipsId(),
107 monitorresize:false,
107 monitorresize:false,
108 xyoffset :[0,0],
108 xyoffset :[0,0],
109 autodismissdelay:300000,
109 autodismissdelay:300000,
110 hidedelay:5,
110 hidedelay:5,
111 showdelay:20,
111 showdelay:20,
112 });
112 });
113
113
114 //Mouse Over event disabled for new repositories since they dont
114 //Mouse Over event disabled for new repositories since they dont
115 //have last commit message
115 //have last commit message
116 myToolTips.contextMouseOverEvent.subscribe(
116 myToolTips.contextMouseOverEvent.subscribe(
117 function(type, args) {
117 function(type, args) {
118 var context = args[0];
118 var context = args[0];
119 var txt = context.getAttribute('tooltip_title');
119 var txt = context.getAttribute('tooltip_title');
120 if(txt){
120 if(txt){
121 return true;
121 return true;
122 }
122 }
123 else{
123 else{
124 return false;
124 return false;
125 }
125 }
126 });
126 });
127
127
128
128
129 // Set the text for the tooltip just before we display it. Lazy method
129 // Set the text for the tooltip just before we display it. Lazy method
130 myToolTips.contextTriggerEvent.subscribe(
130 myToolTips.contextTriggerEvent.subscribe(
131 function(type, args) {
131 function(type, args) {
132
132
133
133
134 var context = args[0];
134 var context = args[0];
135
135
136 var txt = context.getAttribute('tooltip_title');
136 var txt = context.getAttribute('tooltip_title');
137 this.cfg.setProperty("text", txt);
137 this.cfg.setProperty("text", txt);
138
138
139
139
140 // positioning of tooltip
140 // positioning of tooltip
141 var tt_w = this.element.clientWidth;
141 var tt_w = this.element.clientWidth;
142 var tt_h = this.element.clientHeight;
142 var tt_h = this.element.clientHeight;
143
143
144 var context_w = context.offsetWidth;
144 var context_w = context.offsetWidth;
145 var context_h = context.offsetHeight;
145 var context_h = context.offsetHeight;
146
146
147 var pos_x = YAHOO.util.Dom.getX(context);
147 var pos_x = YAHOO.util.Dom.getX(context);
148 var pos_y = YAHOO.util.Dom.getY(context);
148 var pos_y = YAHOO.util.Dom.getY(context);
149
149
150 var display_strategy = 'top';
150 var display_strategy = 'top';
151 var xy_pos = [0,0];
151 var xy_pos = [0,0];
152 switch (display_strategy){
152 switch (display_strategy){
153
153
154 case 'top':
154 case 'top':
155 var cur_x = (pos_x+context_w/2)-(tt_w/2);
155 var cur_x = (pos_x+context_w/2)-(tt_w/2);
156 var cur_y = pos_y-tt_h-4;
156 var cur_y = pos_y-tt_h-4;
157 xy_pos = [cur_x,cur_y];
157 xy_pos = [cur_x,cur_y];
158 break;
158 break;
159 case 'bottom':
159 case 'bottom':
160 var cur_x = (pos_x+context_w/2)-(tt_w/2);
160 var cur_x = (pos_x+context_w/2)-(tt_w/2);
161 var cur_y = pos_y+context_h+4;
161 var cur_y = pos_y+context_h+4;
162 xy_pos = [cur_x,cur_y];
162 xy_pos = [cur_x,cur_y];
163 break;
163 break;
164 case 'left':
164 case 'left':
165 var cur_x = (pos_x-tt_w-4);
165 var cur_x = (pos_x-tt_w-4);
166 var cur_y = pos_y-((tt_h/2)-context_h/2);
166 var cur_y = pos_y-((tt_h/2)-context_h/2);
167 xy_pos = [cur_x,cur_y];
167 xy_pos = [cur_x,cur_y];
168 break;
168 break;
169 case 'right':
169 case 'right':
170 var cur_x = (pos_x+context_w+4);
170 var cur_x = (pos_x+context_w+4);
171 var cur_y = pos_y-((tt_h/2)-context_h/2);
171 var cur_y = pos_y-((tt_h/2)-context_h/2);
172 xy_pos = [cur_x,cur_y];
172 xy_pos = [cur_x,cur_y];
173 break;
173 break;
174 default:
174 default:
175 var cur_x = (pos_x+context_w/2)-(tt_w/2);
175 var cur_x = (pos_x+context_w/2)-(tt_w/2);
176 var cur_y = pos_y-tt_h-4;
176 var cur_y = pos_y-tt_h-4;
177 xy_pos = [cur_x,cur_y];
177 xy_pos = [cur_x,cur_y];
178 break;
178 break;
179
179
180 }
180 }
181
181
182 this.cfg.setProperty("xy",xy_pos);
182 this.cfg.setProperty("xy",xy_pos);
183
183
184 });
184 });
185
185
186 //Mouse out
186 //Mouse out
187 myToolTips.contextMouseOutEvent.subscribe(
187 myToolTips.contextMouseOutEvent.subscribe(
188 function(type, args) {
188 function(type, args) {
189 var context = args[0];
189 var context = args[0];
190
190
191 });
191 });
192 });
192 });
193 '''
193 '''
194 return literal(js)
194 return literal(js)
195
195
196 tooltip = _ToolTip()
196 tooltip = _ToolTip()
197
197
198 class _FilesBreadCrumbs(object):
198 class _FilesBreadCrumbs(object):
199
199
200 def __call__(self, repo_name, rev, paths):
200 def __call__(self, repo_name, rev, paths):
201 url_l = [link_to(repo_name, url('files_home',
201 url_l = [link_to(repo_name, url('files_home',
202 repo_name=repo_name,
202 repo_name=repo_name,
203 revision=rev, f_path=''))]
203 revision=rev, f_path=''))]
204 paths_l = paths.split('/')
204 paths_l = paths.split('/')
205
205
206 for cnt, p in enumerate(paths_l, 1):
206 for cnt, p in enumerate(paths_l):
207 if p != '':
207 if p != '':
208 url_l.append(link_to(p, url('files_home',
208 url_l.append(link_to(p, url('files_home',
209 repo_name=repo_name,
209 repo_name=repo_name,
210 revision=rev,
210 revision=rev,
211 f_path='/'.join(paths_l[:cnt]))))
211 f_path='/'.join(paths_l[:cnt + 1]))))
212
212
213 return literal('/'.join(url_l))
213 return literal('/'.join(url_l))
214
214
215 files_breadcrumbs = _FilesBreadCrumbs()
215 files_breadcrumbs = _FilesBreadCrumbs()
216 class CodeHtmlFormatter(HtmlFormatter):
216 class CodeHtmlFormatter(HtmlFormatter):
217
217
218 def wrap(self, source, outfile):
218 def wrap(self, source, outfile):
219 return self._wrap_div(self._wrap_pre(self._wrap_code(source)))
219 return self._wrap_div(self._wrap_pre(self._wrap_code(source)))
220
220
221 def _wrap_code(self, source):
221 def _wrap_code(self, source):
222 for cnt, it in enumerate(source, 1):
222 for cnt, it in enumerate(source):
223 i, t = it
223 i, t = it
224 t = '<div id="#S-%s">%s</div>' % (cnt, t)
224 t = '<div id="#S-%s">%s</div>' % (cnt + 1, t)
225 yield i, t
225 yield i, t
226 def pygmentize(filenode, **kwargs):
226 def pygmentize(filenode, **kwargs):
227 """
227 """
228 pygmentize function using pygments
228 pygmentize function using pygments
229 :param filenode:
229 :param filenode:
230 """
230 """
231 return literal(code_highlight(filenode.content,
231 return literal(code_highlight(filenode.content,
232 filenode.lexer, CodeHtmlFormatter(**kwargs)))
232 filenode.lexer, CodeHtmlFormatter(**kwargs)))
233
233
234 def pygmentize_annotation(filenode, **kwargs):
234 def pygmentize_annotation(filenode, **kwargs):
235 """
235 """
236 pygmentize function for annotation
236 pygmentize function for annotation
237 :param filenode:
237 :param filenode:
238 """
238 """
239
239
240 color_dict = {}
240 color_dict = {}
241 def gen_color():
241 def gen_color():
242 """generator for getting 10k of evenly distibuted colors using hsv color
242 """generator for getting 10k of evenly distibuted colors using hsv color
243 and golden ratio.
243 and golden ratio.
244 """
244 """
245 import colorsys
245 import colorsys
246 n = 10000
246 n = 10000
247 golden_ratio = 0.618033988749895
247 golden_ratio = 0.618033988749895
248 h = 0.22717784590367374
248 h = 0.22717784590367374
249 #generate 10k nice web friendly colors in the same order
249 #generate 10k nice web friendly colors in the same order
250 for c in xrange(n):
250 for c in xrange(n):
251 h += golden_ratio
251 h += golden_ratio
252 h %= 1
252 h %= 1
253 HSV_tuple = [h, 0.95, 0.95]
253 HSV_tuple = [h, 0.95, 0.95]
254 RGB_tuple = colorsys.hsv_to_rgb(*HSV_tuple)
254 RGB_tuple = colorsys.hsv_to_rgb(*HSV_tuple)
255 yield map(lambda x:str(int(x * 256)), RGB_tuple)
255 yield map(lambda x:str(int(x * 256)), RGB_tuple)
256
256
257 cgenerator = gen_color()
257 cgenerator = gen_color()
258
258
259 def get_color_string(cs):
259 def get_color_string(cs):
260 if color_dict.has_key(cs):
260 if color_dict.has_key(cs):
261 col = color_dict[cs]
261 col = color_dict[cs]
262 else:
262 else:
263 col = color_dict[cs] = cgenerator.next()
263 col = color_dict[cs] = cgenerator.next()
264 return "color: rgb(%s)! important;" % (', '.join(col))
264 return "color: rgb(%s)! important;" % (', '.join(col))
265
265
266 def url_func(changeset):
266 def url_func(changeset):
267 tooltip_html = "<div style='font-size:0.8em'><b>Author:</b>" + \
267 tooltip_html = "<div style='font-size:0.8em'><b>Author:</b>" + \
268 " %s<br/><b>Date:</b> %s</b><br/><b>Message:</b> %s<br/></div>"
268 " %s<br/><b>Date:</b> %s</b><br/><b>Message:</b> %s<br/></div>"
269
269
270 tooltip_html = tooltip_html % (changeset.author,
270 tooltip_html = tooltip_html % (changeset.author,
271 changeset.date,
271 changeset.date,
272 tooltip(changeset.message))
272 tooltip(changeset.message))
273 lnk_format = 'r%-5s:%s' % (changeset.revision,
273 lnk_format = 'r%-5s:%s' % (changeset.revision,
274 changeset.short_id)
274 changeset.short_id)
275 uri = link_to(
275 uri = link_to(
276 lnk_format,
276 lnk_format,
277 url('changeset_home', repo_name=changeset.repository.name,
277 url('changeset_home', repo_name=changeset.repository.name,
278 revision=changeset.short_id),
278 revision=changeset.short_id),
279 style=get_color_string(changeset.short_id),
279 style=get_color_string(changeset.short_id),
280 class_='tooltip',
280 class_='tooltip',
281 tooltip_title=tooltip_html
281 tooltip_title=tooltip_html
282 )
282 )
283
283
284 uri += '\n'
284 uri += '\n'
285 return uri
285 return uri
286 return literal(annotate_highlight(filenode, url_func, **kwargs))
286 return literal(annotate_highlight(filenode, url_func, **kwargs))
287
287
288 def repo_name_slug(value):
288 def repo_name_slug(value):
289 """Return slug of name of repository
289 """Return slug of name of repository
290 This function is called on each creation/modification
290 This function is called on each creation/modification
291 of repository to prevent bad names in repo
291 of repository to prevent bad names in repo
292 """
292 """
293 slug = remove_formatting(value)
293 slug = remove_formatting(value)
294 slug = strip_tags(slug)
294 slug = strip_tags(slug)
295
295
296 for c in """=[]\;'"<>,/~!@#$%^&*()+{}|: """:
296 for c in """=[]\;'"<>,/~!@#$%^&*()+{}|: """:
297 slug = slug.replace(c, '-')
297 slug = slug.replace(c, '-')
298 slug = recursive_replace(slug, '-')
298 slug = recursive_replace(slug, '-')
299 slug = collapse(slug, '-')
299 slug = collapse(slug, '-')
300 return slug
300 return slug
301
301
302 def get_changeset_safe(repo, rev):
302 def get_changeset_safe(repo, rev):
303 from vcs.backends.base import BaseRepository
303 from vcs.backends.base import BaseRepository
304 from vcs.exceptions import RepositoryError
304 from vcs.exceptions import RepositoryError
305 if not isinstance(repo, BaseRepository):
305 if not isinstance(repo, BaseRepository):
306 raise Exception('You must pass an Repository '
306 raise Exception('You must pass an Repository '
307 'object as first argument got %s', type(repo))
307 'object as first argument got %s', type(repo))
308
308
309 try:
309 try:
310 cs = repo.get_changeset(rev)
310 cs = repo.get_changeset(rev)
311 except RepositoryError:
311 except RepositoryError:
312 from rhodecode.lib.utils import EmptyChangeset
312 from rhodecode.lib.utils import EmptyChangeset
313 cs = EmptyChangeset()
313 cs = EmptyChangeset()
314 return cs
314 return cs
315
315
316
316
317 flash = _Flash()
317 flash = _Flash()
318
318
319
319
320 #===============================================================================
320 #===============================================================================
321 # MERCURIAL FILTERS available via h.
321 # MERCURIAL FILTERS available via h.
322 #===============================================================================
322 #===============================================================================
323 from mercurial import util
323 from mercurial import util
324 from mercurial.templatefilters import age as _age, person as _person
324 from mercurial.templatefilters import age as _age, person as _person
325
325
326 age = lambda x:_age(x)
326 age = lambda x:_age(x)
327 capitalize = lambda x: x.capitalize()
327 capitalize = lambda x: x.capitalize()
328 date = lambda x: util.datestr(x)
328 date = lambda x: util.datestr(x)
329 email = util.email
329 email = util.email
330 email_or_none = lambda x: util.email(x) if util.email(x) != x else None
330 email_or_none = lambda x: util.email(x) if util.email(x) != x else None
331 person = lambda x: _person(x)
331 person = lambda x: _person(x)
332 hgdate = lambda x: "%d %d" % x
332 hgdate = lambda x: "%d %d" % x
333 isodate = lambda x: util.datestr(x, '%Y-%m-%d %H:%M %1%2')
333 isodate = lambda x: util.datestr(x, '%Y-%m-%d %H:%M %1%2')
334 isodatesec = lambda x: util.datestr(x, '%Y-%m-%d %H:%M:%S %1%2')
334 isodatesec = lambda x: util.datestr(x, '%Y-%m-%d %H:%M:%S %1%2')
335 localdate = lambda x: (x[0], util.makedate()[1])
335 localdate = lambda x: (x[0], util.makedate()[1])
336 rfc822date = lambda x: util.datestr(x, "%a, %d %b %Y %H:%M:%S %1%2")
336 rfc822date = lambda x: util.datestr(x, "%a, %d %b %Y %H:%M:%S %1%2")
337 rfc822date_notz = lambda x: util.datestr(x, "%a, %d %b %Y %H:%M:%S")
337 rfc822date_notz = lambda x: util.datestr(x, "%a, %d %b %Y %H:%M:%S")
338 rfc3339date = lambda x: util.datestr(x, "%Y-%m-%dT%H:%M:%S%1:%2")
338 rfc3339date = lambda x: util.datestr(x, "%Y-%m-%dT%H:%M:%S%1:%2")
339 time_ago = lambda x: util.datestr(_age(x), "%a, %d %b %Y %H:%M:%S %1%2")
339 time_ago = lambda x: util.datestr(_age(x), "%a, %d %b %Y %H:%M:%S %1%2")
340
340
341
341
342 #===============================================================================
342 #===============================================================================
343 # PERMS
343 # PERMS
344 #===============================================================================
344 #===============================================================================
345 from rhodecode.lib.auth import HasPermissionAny, HasPermissionAll, \
345 from rhodecode.lib.auth import HasPermissionAny, HasPermissionAll, \
346 HasRepoPermissionAny, HasRepoPermissionAll
346 HasRepoPermissionAny, HasRepoPermissionAll
347
347
348 #===============================================================================
348 #===============================================================================
349 # GRAVATAR URL
349 # GRAVATAR URL
350 #===============================================================================
350 #===============================================================================
351 import hashlib
351 import hashlib
352 import urllib
352 import urllib
353 from pylons import request
353 from pylons import request
354
354
355 def gravatar_url(email_address, size=30):
355 def gravatar_url(email_address, size=30):
356 ssl_enabled = 'https' == request.environ.get('HTTP_X_URL_SCHEME')
356 ssl_enabled = 'https' == request.environ.get('HTTP_X_URL_SCHEME')
357 default = 'identicon'
357 default = 'identicon'
358 baseurl_nossl = "http://www.gravatar.com/avatar/"
358 baseurl_nossl = "http://www.gravatar.com/avatar/"
359 baseurl_ssl = "https://secure.gravatar.com/avatar/"
359 baseurl_ssl = "https://secure.gravatar.com/avatar/"
360 baseurl = baseurl_ssl if ssl_enabled else baseurl_nossl
360 baseurl = baseurl_ssl if ssl_enabled else baseurl_nossl
361
361
362
362
363 # construct the url
363 # construct the url
364 gravatar_url = baseurl + hashlib.md5(email_address.lower()).hexdigest() + "?"
364 gravatar_url = baseurl + hashlib.md5(email_address.lower()).hexdigest() + "?"
365 gravatar_url += urllib.urlencode({'d':default, 's':str(size)})
365 gravatar_url += urllib.urlencode({'d':default, 's':str(size)})
366
366
367 return gravatar_url
367 return gravatar_url
368
368
369 def safe_unicode(str):
369 def safe_unicode(str):
370 """safe unicode function. In case of UnicodeDecode error we try to return
370 """safe unicode function. In case of UnicodeDecode error we try to return
371 unicode with errors replace, if this failes we return unicode with
371 unicode with errors replace, if this failes we return unicode with
372 string_escape decoding """
372 string_escape decoding """
373
373
374 try:
374 try:
375 u_str = unicode(str)
375 u_str = unicode(str)
376 except UnicodeDecodeError:
376 except UnicodeDecodeError:
377 try:
377 try:
378 u_str = unicode(str, 'utf-8', 'replace')
378 u_str = unicode(str, 'utf-8', 'replace')
379 except UnicodeDecodeError:
379 except UnicodeDecodeError:
380 #incase we have a decode error just represent as byte string
380 #incase we have a decode error just represent as byte string
381 u_str = unicode(str(str).encode('string_escape'))
381 u_str = unicode(str(str).encode('string_escape'))
382
382
383 return u_str
383 return u_str
@@ -1,507 +1,512 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 # encoding: utf-8
2 # encoding: utf-8
3 # Utilities for RhodeCode
3 # Utilities for RhodeCode
4 # Copyright (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
4 # Copyright (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
5 # This program is free software; you can redistribute it and/or
5 # This program is free software; you can redistribute it and/or
6 # modify it under the terms of the GNU General Public License
6 # modify it under the terms of the GNU General Public License
7 # as published by the Free Software Foundation; version 2
7 # as published by the Free Software Foundation; version 2
8 # of the License or (at your opinion) any later version of the license.
8 # of the License or (at your opinion) any later version of the license.
9 #
9 #
10 # This program is distributed in the hope that it will be useful,
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
13 # GNU General Public License for more details.
14 #
14 #
15 # You should have received a copy of the GNU General Public License
15 # You should have received a copy of the GNU General Public License
16 # along with this program; if not, write to the Free Software
16 # along with this program; if not, write to the Free Software
17 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18 # MA 02110-1301, USA.
18 # MA 02110-1301, USA.
19
19
20 """
20 """
21 Created on April 18, 2010
21 Created on April 18, 2010
22 Utilities for RhodeCode
22 Utilities for RhodeCode
23 @author: marcink
23 @author: marcink
24 """
24 """
25 from beaker.cache import cache_region
25 from beaker.cache import cache_region
26 from mercurial import ui, config, hg
26 from mercurial import ui, config, hg
27 from mercurial.error import RepoError
27 from mercurial.error import RepoError
28 from rhodecode.model import meta
28 from rhodecode.model import meta
29 from rhodecode.model.db import Repository, User, RhodeCodeUi, RhodeCodeSettings, UserLog
29 from rhodecode.model.db import Repository, User, RhodeCodeUi, RhodeCodeSettings, UserLog
30 from vcs.backends.base import BaseChangeset
30 from vcs.backends.base import BaseChangeset
31 from vcs.utils.lazy import LazyProperty
31 from vcs.utils.lazy import LazyProperty
32 import logging
32 import logging
33 import datetime
33 import datetime
34 import os
34 import os
35
35
36 log = logging.getLogger(__name__)
36 log = logging.getLogger(__name__)
37
37
38
38
39 def get_repo_slug(request):
39 def get_repo_slug(request):
40 return request.environ['pylons.routes_dict'].get('repo_name')
40 return request.environ['pylons.routes_dict'].get('repo_name')
41
41
42 def is_mercurial(environ):
42 def is_mercurial(environ):
43 """
43 """
44 Returns True if request's target is mercurial server - header
44 Returns True if request's target is mercurial server - header
45 ``HTTP_ACCEPT`` of such request would start with ``application/mercurial``.
45 ``HTTP_ACCEPT`` of such request would start with ``application/mercurial``.
46 """
46 """
47 http_accept = environ.get('HTTP_ACCEPT')
47 http_accept = environ.get('HTTP_ACCEPT')
48 if http_accept and http_accept.startswith('application/mercurial'):
48 if http_accept and http_accept.startswith('application/mercurial'):
49 return True
49 return True
50 return False
50 return False
51
51
52 def is_git(environ):
52 def is_git(environ):
53 """
53 """
54 Returns True if request's target is git server. ``HTTP_USER_AGENT`` would
54 Returns True if request's target is git server. ``HTTP_USER_AGENT`` would
55 then have git client version given.
55 then have git client version given.
56
56
57 :param environ:
57 :param environ:
58 """
58 """
59 http_user_agent = environ.get('HTTP_USER_AGENT')
59 http_user_agent = environ.get('HTTP_USER_AGENT')
60 if http_user_agent.startswith('git'):
60 if http_user_agent.startswith('git'):
61 return True
61 return True
62 return False
62 return False
63
63
64 def action_logger(user, action, repo, ipaddr, sa=None):
64 def action_logger(user, action, repo, ipaddr, sa=None):
65 """
65 """
66 Action logger for various action made by users
66 Action logger for various action made by users
67 """
67 """
68
68
69 if not sa:
69 if not sa:
70 sa = meta.Session
70 sa = meta.Session
71
71
72 try:
72 try:
73 if hasattr(user, 'user_id'):
73 if hasattr(user, 'user_id'):
74 user_id = user.user_id
74 user_id = user.user_id
75 elif isinstance(user, basestring):
75 elif isinstance(user, basestring):
76 user_id = sa.query(User).filter(User.username == user).one()
76 user_id = sa.query(User).filter(User.username == user).one()
77 else:
77 else:
78 raise Exception('You have to provide user object or username')
78 raise Exception('You have to provide user object or username')
79
79
80 repo_name = repo.lstrip('/')
80 repo_name = repo.lstrip('/')
81 user_log = UserLog()
81 user_log = UserLog()
82 user_log.user_id = user_id
82 user_log.user_id = user_id
83 user_log.action = action
83 user_log.action = action
84 user_log.repository_name = repo_name
84 user_log.repository_name = repo_name
85 user_log.repository = sa.query(Repository)\
85 user_log.repository = sa.query(Repository)\
86 .filter(Repository.repo_name == repo_name).one()
86 .filter(Repository.repo_name == repo_name).one()
87 user_log.action_date = datetime.datetime.now()
87 user_log.action_date = datetime.datetime.now()
88 user_log.user_ip = ipaddr
88 user_log.user_ip = ipaddr
89 sa.add(user_log)
89 sa.add(user_log)
90 sa.commit()
90 sa.commit()
91
91
92 log.info('Adding user %s, action %s on %s',
92 log.info('Adding user %s, action %s on %s',
93 user.username, action, repo)
93 user.username, action, repo)
94 except Exception, e:
94 except Exception, e:
95 sa.rollback()
95 sa.rollback()
96 log.error('could not log user action:%s', str(e))
96 log.error('could not log user action:%s', str(e))
97
97
98 def check_repo_dir(paths):
98 def check_repo_dir(paths):
99 repos_path = paths[0][1].split('/')
99 repos_path = paths[0][1].split('/')
100 if repos_path[-1] in ['*', '**']:
100 if repos_path[-1] in ['*', '**']:
101 repos_path = repos_path[:-1]
101 repos_path = repos_path[:-1]
102 if repos_path[0] != '/':
102 if repos_path[0] != '/':
103 repos_path[0] = '/'
103 repos_path[0] = '/'
104 if not os.path.isdir(os.path.join(*repos_path)):
104 if not os.path.isdir(os.path.join(*repos_path)):
105 raise Exception('Not a valid repository in %s' % paths[0][1])
105 raise Exception('Not a valid repository in %s' % paths[0][1])
106
106
107 def check_repo_fast(repo_name, base_path):
107 def check_repo_fast(repo_name, base_path):
108 if os.path.isdir(os.path.join(base_path, repo_name)):return False
108 if os.path.isdir(os.path.join(base_path, repo_name)):return False
109 return True
109 return True
110
110
111 def check_repo(repo_name, base_path, verify=True):
111 def check_repo(repo_name, base_path, verify=True):
112
112
113 repo_path = os.path.join(base_path, repo_name)
113 repo_path = os.path.join(base_path, repo_name)
114
114
115 try:
115 try:
116 if not check_repo_fast(repo_name, base_path):
116 if not check_repo_fast(repo_name, base_path):
117 return False
117 return False
118 r = hg.repository(ui.ui(), repo_path)
118 r = hg.repository(ui.ui(), repo_path)
119 if verify:
119 if verify:
120 hg.verify(r)
120 hg.verify(r)
121 #here we hnow that repo exists it was verified
121 #here we hnow that repo exists it was verified
122 log.info('%s repo is already created', repo_name)
122 log.info('%s repo is already created', repo_name)
123 return False
123 return False
124 except RepoError:
124 except RepoError:
125 #it means that there is no valid repo there...
125 #it means that there is no valid repo there...
126 log.info('%s repo is free for creation', repo_name)
126 log.info('%s repo is free for creation', repo_name)
127 return True
127 return True
128
128
129 def ask_ok(prompt, retries=4, complaint='Yes or no, please!'):
129 def ask_ok(prompt, retries=4, complaint='Yes or no, please!'):
130 while True:
130 while True:
131 ok = raw_input(prompt)
131 ok = raw_input(prompt)
132 if ok in ('y', 'ye', 'yes'): return True
132 if ok in ('y', 'ye', 'yes'): return True
133 if ok in ('n', 'no', 'nop', 'nope'): return False
133 if ok in ('n', 'no', 'nop', 'nope'): return False
134 retries = retries - 1
134 retries = retries - 1
135 if retries < 0: raise IOError
135 if retries < 0: raise IOError
136 print complaint
136 print complaint
137
137
138 @cache_region('super_short_term', 'cached_hg_ui')
138 @cache_region('super_short_term', 'cached_hg_ui')
139 def get_hg_ui_cached():
139 def get_hg_ui_cached():
140 try:
140 try:
141 sa = meta.Session
141 sa = meta.Session
142 ret = sa.query(RhodeCodeUi).all()
142 ret = sa.query(RhodeCodeUi).all()
143 finally:
143 finally:
144 meta.Session.remove()
144 meta.Session.remove()
145 return ret
145 return ret
146
146
147
147
148 def get_hg_settings():
148 def get_hg_settings():
149 try:
149 try:
150 sa = meta.Session
150 sa = meta.Session
151 ret = sa.query(RhodeCodeSettings).all()
151 ret = sa.query(RhodeCodeSettings).all()
152 finally:
152 finally:
153 meta.Session.remove()
153 meta.Session.remove()
154
154
155 if not ret:
155 if not ret:
156 raise Exception('Could not get application settings !')
156 raise Exception('Could not get application settings !')
157 settings = {}
157 settings = {}
158 for each in ret:
158 for each in ret:
159 settings['rhodecode_' + each.app_settings_name] = each.app_settings_value
159 settings['rhodecode_' + each.app_settings_name] = each.app_settings_value
160
160
161 return settings
161 return settings
162
162
163 def get_hg_ui_settings():
163 def get_hg_ui_settings():
164 try:
164 try:
165 sa = meta.Session
165 sa = meta.Session
166 ret = sa.query(RhodeCodeUi).all()
166 ret = sa.query(RhodeCodeUi).all()
167 finally:
167 finally:
168 meta.Session.remove()
168 meta.Session.remove()
169
169
170 if not ret:
170 if not ret:
171 raise Exception('Could not get application ui settings !')
171 raise Exception('Could not get application ui settings !')
172 settings = {}
172 settings = {}
173 for each in ret:
173 for each in ret:
174 k = each.ui_key
174 k = each.ui_key
175 v = each.ui_value
175 v = each.ui_value
176 if k == '/':
176 if k == '/':
177 k = 'root_path'
177 k = 'root_path'
178
178
179 if k.find('.') != -1:
179 if k.find('.') != -1:
180 k = k.replace('.', '_')
180 k = k.replace('.', '_')
181
181
182 if each.ui_section == 'hooks':
182 if each.ui_section == 'hooks':
183 v = each.ui_active
183 v = each.ui_active
184
184
185 settings[each.ui_section + '_' + k] = v
185 settings[each.ui_section + '_' + k] = v
186
186
187 return settings
187 return settings
188
188
189 #propagated from mercurial documentation
189 #propagated from mercurial documentation
190 ui_sections = ['alias', 'auth',
190 ui_sections = ['alias', 'auth',
191 'decode/encode', 'defaults',
191 'decode/encode', 'defaults',
192 'diff', 'email',
192 'diff', 'email',
193 'extensions', 'format',
193 'extensions', 'format',
194 'merge-patterns', 'merge-tools',
194 'merge-patterns', 'merge-tools',
195 'hooks', 'http_proxy',
195 'hooks', 'http_proxy',
196 'smtp', 'patch',
196 'smtp', 'patch',
197 'paths', 'profiling',
197 'paths', 'profiling',
198 'server', 'trusted',
198 'server', 'trusted',
199 'ui', 'web', ]
199 'ui', 'web', ]
200
200
201 def make_ui(read_from='file', path=None, checkpaths=True):
201 def make_ui(read_from='file', path=None, checkpaths=True):
202 """
202 """
203 A function that will read python rc files or database
203 A function that will read python rc files or database
204 and make an mercurial ui object from read options
204 and make an mercurial ui object from read options
205
205
206 :param path: path to mercurial config file
206 :param path: path to mercurial config file
207 :param checkpaths: check the path
207 :param checkpaths: check the path
208 :param read_from: read from 'file' or 'db'
208 :param read_from: read from 'file' or 'db'
209 """
209 """
210
210
211 baseui = ui.ui()
211 baseui = ui.ui()
212
212
213 if read_from == 'file':
213 if read_from == 'file':
214 if not os.path.isfile(path):
214 if not os.path.isfile(path):
215 log.warning('Unable to read config file %s' % path)
215 log.warning('Unable to read config file %s' % path)
216 return False
216 return False
217 log.debug('reading hgrc from %s', path)
217 log.debug('reading hgrc from %s', path)
218 cfg = config.config()
218 cfg = config.config()
219 cfg.read(path)
219 cfg.read(path)
220 for section in ui_sections:
220 for section in ui_sections:
221 for k, v in cfg.items(section):
221 for k, v in cfg.items(section):
222 baseui.setconfig(section, k, v)
222 baseui.setconfig(section, k, v)
223 log.debug('settings ui from file[%s]%s:%s', section, k, v)
223 log.debug('settings ui from file[%s]%s:%s', section, k, v)
224
225 for k, v in baseui.configitems('extensions'):
226 baseui.setconfig('extensions', k, '0')
227 #just enable mq
228 baseui.setconfig('extensions', 'mq', '1')
224 if checkpaths:check_repo_dir(cfg.items('paths'))
229 if checkpaths:check_repo_dir(cfg.items('paths'))
225
230
226
231
227 elif read_from == 'db':
232 elif read_from == 'db':
228 hg_ui = get_hg_ui_cached()
233 hg_ui = get_hg_ui_cached()
229 for ui_ in hg_ui:
234 for ui_ in hg_ui:
230 if ui_.ui_active:
235 if ui_.ui_active:
231 log.debug('settings ui from db[%s]%s:%s', ui_.ui_section, ui_.ui_key, ui_.ui_value)
236 log.debug('settings ui from db[%s]%s:%s', ui_.ui_section, ui_.ui_key, ui_.ui_value)
232 baseui.setconfig(ui_.ui_section, ui_.ui_key, ui_.ui_value)
237 baseui.setconfig(ui_.ui_section, ui_.ui_key, ui_.ui_value)
233
238
234
239
235 return baseui
240 return baseui
236
241
237
242
238 def set_rhodecode_config(config):
243 def set_rhodecode_config(config):
239 hgsettings = get_hg_settings()
244 hgsettings = get_hg_settings()
240
245
241 for k, v in hgsettings.items():
246 for k, v in hgsettings.items():
242 config[k] = v
247 config[k] = v
243
248
244 def invalidate_cache(name, *args):
249 def invalidate_cache(name, *args):
245 """Invalidates given name cache"""
250 """Invalidates given name cache"""
246
251
247 from beaker.cache import region_invalidate
252 from beaker.cache import region_invalidate
248 log.info('INVALIDATING CACHE FOR %s', name)
253 log.info('INVALIDATING CACHE FOR %s', name)
249
254
250 """propagate our arguments to make sure invalidation works. First
255 """propagate our arguments to make sure invalidation works. First
251 argument has to be the name of cached func name give to cache decorator
256 argument has to be the name of cached func name give to cache decorator
252 without that the invalidation would not work"""
257 without that the invalidation would not work"""
253 tmp = [name]
258 tmp = [name]
254 tmp.extend(args)
259 tmp.extend(args)
255 args = tuple(tmp)
260 args = tuple(tmp)
256
261
257 if name == 'cached_repo_list':
262 if name == 'cached_repo_list':
258 from rhodecode.model.hg_model import _get_repos_cached
263 from rhodecode.model.hg_model import _get_repos_cached
259 region_invalidate(_get_repos_cached, None, *args)
264 region_invalidate(_get_repos_cached, None, *args)
260
265
261 if name == 'full_changelog':
266 if name == 'full_changelog':
262 from rhodecode.model.hg_model import _full_changelog_cached
267 from rhodecode.model.hg_model import _full_changelog_cached
263 region_invalidate(_full_changelog_cached, None, *args)
268 region_invalidate(_full_changelog_cached, None, *args)
264
269
265 class EmptyChangeset(BaseChangeset):
270 class EmptyChangeset(BaseChangeset):
266 """
271 """
267 An dummy empty changeset.
272 An dummy empty changeset.
268 """
273 """
269
274
270 revision = -1
275 revision = -1
271 message = ''
276 message = ''
272 author = ''
277 author = ''
273 date = ''
278 date = ''
274 @LazyProperty
279 @LazyProperty
275 def raw_id(self):
280 def raw_id(self):
276 """
281 """
277 Returns raw string identifing this changeset, useful for web
282 Returns raw string identifing this changeset, useful for web
278 representation.
283 representation.
279 """
284 """
280 return '0' * 40
285 return '0' * 40
281
286
282 @LazyProperty
287 @LazyProperty
283 def short_id(self):
288 def short_id(self):
284 return self.raw_id[:12]
289 return self.raw_id[:12]
285
290
286 def get_file_changeset(self, path):
291 def get_file_changeset(self, path):
287 return self
292 return self
288
293
289 def get_file_content(self, path):
294 def get_file_content(self, path):
290 return u''
295 return u''
291
296
292 def get_file_size(self, path):
297 def get_file_size(self, path):
293 return 0
298 return 0
294
299
295 def repo2db_mapper(initial_repo_list, remove_obsolete=False):
300 def repo2db_mapper(initial_repo_list, remove_obsolete=False):
296 """
301 """
297 maps all found repositories into db
302 maps all found repositories into db
298 """
303 """
299 from rhodecode.model.repo_model import RepoModel
304 from rhodecode.model.repo_model import RepoModel
300
305
301 sa = meta.Session
306 sa = meta.Session
302 user = sa.query(User).filter(User.admin == True).first()
307 user = sa.query(User).filter(User.admin == True).first()
303
308
304 rm = RepoModel()
309 rm = RepoModel()
305
310
306 for name, repo in initial_repo_list.items():
311 for name, repo in initial_repo_list.items():
307 if not sa.query(Repository).filter(Repository.repo_name == name).scalar():
312 if not sa.query(Repository).filter(Repository.repo_name == name).scalar():
308 log.info('repository %s not found creating default', name)
313 log.info('repository %s not found creating default', name)
309
314
310 form_data = {
315 form_data = {
311 'repo_name':name,
316 'repo_name':name,
312 'description':repo.description if repo.description != 'unknown' else \
317 'description':repo.description if repo.description != 'unknown' else \
313 'auto description for %s' % name,
318 'auto description for %s' % name,
314 'private':False
319 'private':False
315 }
320 }
316 rm.create(form_data, user, just_db=True)
321 rm.create(form_data, user, just_db=True)
317
322
318
323
319 if remove_obsolete:
324 if remove_obsolete:
320 #remove from database those repositories that are not in the filesystem
325 #remove from database those repositories that are not in the filesystem
321 for repo in sa.query(Repository).all():
326 for repo in sa.query(Repository).all():
322 if repo.repo_name not in initial_repo_list.keys():
327 if repo.repo_name not in initial_repo_list.keys():
323 sa.delete(repo)
328 sa.delete(repo)
324 sa.commit()
329 sa.commit()
325
330
326
331
327 meta.Session.remove()
332 meta.Session.remove()
328
333
329 from UserDict import DictMixin
334 from UserDict import DictMixin
330
335
331 class OrderedDict(dict, DictMixin):
336 class OrderedDict(dict, DictMixin):
332
337
333 def __init__(self, *args, **kwds):
338 def __init__(self, *args, **kwds):
334 if len(args) > 1:
339 if len(args) > 1:
335 raise TypeError('expected at most 1 arguments, got %d' % len(args))
340 raise TypeError('expected at most 1 arguments, got %d' % len(args))
336 try:
341 try:
337 self.__end
342 self.__end
338 except AttributeError:
343 except AttributeError:
339 self.clear()
344 self.clear()
340 self.update(*args, **kwds)
345 self.update(*args, **kwds)
341
346
342 def clear(self):
347 def clear(self):
343 self.__end = end = []
348 self.__end = end = []
344 end += [None, end, end] # sentinel node for doubly linked list
349 end += [None, end, end] # sentinel node for doubly linked list
345 self.__map = {} # key --> [key, prev, next]
350 self.__map = {} # key --> [key, prev, next]
346 dict.clear(self)
351 dict.clear(self)
347
352
348 def __setitem__(self, key, value):
353 def __setitem__(self, key, value):
349 if key not in self:
354 if key not in self:
350 end = self.__end
355 end = self.__end
351 curr = end[1]
356 curr = end[1]
352 curr[2] = end[1] = self.__map[key] = [key, curr, end]
357 curr[2] = end[1] = self.__map[key] = [key, curr, end]
353 dict.__setitem__(self, key, value)
358 dict.__setitem__(self, key, value)
354
359
355 def __delitem__(self, key):
360 def __delitem__(self, key):
356 dict.__delitem__(self, key)
361 dict.__delitem__(self, key)
357 key, prev, next = self.__map.pop(key)
362 key, prev, next = self.__map.pop(key)
358 prev[2] = next
363 prev[2] = next
359 next[1] = prev
364 next[1] = prev
360
365
361 def __iter__(self):
366 def __iter__(self):
362 end = self.__end
367 end = self.__end
363 curr = end[2]
368 curr = end[2]
364 while curr is not end:
369 while curr is not end:
365 yield curr[0]
370 yield curr[0]
366 curr = curr[2]
371 curr = curr[2]
367
372
368 def __reversed__(self):
373 def __reversed__(self):
369 end = self.__end
374 end = self.__end
370 curr = end[1]
375 curr = end[1]
371 while curr is not end:
376 while curr is not end:
372 yield curr[0]
377 yield curr[0]
373 curr = curr[1]
378 curr = curr[1]
374
379
375 def popitem(self, last=True):
380 def popitem(self, last=True):
376 if not self:
381 if not self:
377 raise KeyError('dictionary is empty')
382 raise KeyError('dictionary is empty')
378 if last:
383 if last:
379 key = reversed(self).next()
384 key = reversed(self).next()
380 else:
385 else:
381 key = iter(self).next()
386 key = iter(self).next()
382 value = self.pop(key)
387 value = self.pop(key)
383 return key, value
388 return key, value
384
389
385 def __reduce__(self):
390 def __reduce__(self):
386 items = [[k, self[k]] for k in self]
391 items = [[k, self[k]] for k in self]
387 tmp = self.__map, self.__end
392 tmp = self.__map, self.__end
388 del self.__map, self.__end
393 del self.__map, self.__end
389 inst_dict = vars(self).copy()
394 inst_dict = vars(self).copy()
390 self.__map, self.__end = tmp
395 self.__map, self.__end = tmp
391 if inst_dict:
396 if inst_dict:
392 return (self.__class__, (items,), inst_dict)
397 return (self.__class__, (items,), inst_dict)
393 return self.__class__, (items,)
398 return self.__class__, (items,)
394
399
395 def keys(self):
400 def keys(self):
396 return list(self)
401 return list(self)
397
402
398 setdefault = DictMixin.setdefault
403 setdefault = DictMixin.setdefault
399 update = DictMixin.update
404 update = DictMixin.update
400 pop = DictMixin.pop
405 pop = DictMixin.pop
401 values = DictMixin.values
406 values = DictMixin.values
402 items = DictMixin.items
407 items = DictMixin.items
403 iterkeys = DictMixin.iterkeys
408 iterkeys = DictMixin.iterkeys
404 itervalues = DictMixin.itervalues
409 itervalues = DictMixin.itervalues
405 iteritems = DictMixin.iteritems
410 iteritems = DictMixin.iteritems
406
411
407 def __repr__(self):
412 def __repr__(self):
408 if not self:
413 if not self:
409 return '%s()' % (self.__class__.__name__,)
414 return '%s()' % (self.__class__.__name__,)
410 return '%s(%r)' % (self.__class__.__name__, self.items())
415 return '%s(%r)' % (self.__class__.__name__, self.items())
411
416
412 def copy(self):
417 def copy(self):
413 return self.__class__(self)
418 return self.__class__(self)
414
419
415 @classmethod
420 @classmethod
416 def fromkeys(cls, iterable, value=None):
421 def fromkeys(cls, iterable, value=None):
417 d = cls()
422 d = cls()
418 for key in iterable:
423 for key in iterable:
419 d[key] = value
424 d[key] = value
420 return d
425 return d
421
426
422 def __eq__(self, other):
427 def __eq__(self, other):
423 if isinstance(other, OrderedDict):
428 if isinstance(other, OrderedDict):
424 return len(self) == len(other) and self.items() == other.items()
429 return len(self) == len(other) and self.items() == other.items()
425 return dict.__eq__(self, other)
430 return dict.__eq__(self, other)
426
431
427 def __ne__(self, other):
432 def __ne__(self, other):
428 return not self == other
433 return not self == other
429
434
430
435
431 #===============================================================================
436 #===============================================================================
432 # TEST FUNCTIONS
437 # TEST FUNCTIONS
433 #===============================================================================
438 #===============================================================================
434 def create_test_index(repo_location, full_index):
439 def create_test_index(repo_location, full_index):
435 """Makes default test index
440 """Makes default test index
436 :param repo_location:
441 :param repo_location:
437 :param full_index:
442 :param full_index:
438 """
443 """
439 from rhodecode.lib.indexers.daemon import WhooshIndexingDaemon
444 from rhodecode.lib.indexers.daemon import WhooshIndexingDaemon
440 from rhodecode.lib.pidlock import DaemonLock, LockHeld
445 from rhodecode.lib.pidlock import DaemonLock, LockHeld
441 from rhodecode.lib.indexers import IDX_LOCATION
446 from rhodecode.lib.indexers import IDX_LOCATION
442 import shutil
447 import shutil
443
448
444 if os.path.exists(IDX_LOCATION):
449 if os.path.exists(IDX_LOCATION):
445 shutil.rmtree(IDX_LOCATION)
450 shutil.rmtree(IDX_LOCATION)
446
451
447 try:
452 try:
448 l = DaemonLock()
453 l = DaemonLock()
449 WhooshIndexingDaemon(repo_location=repo_location)\
454 WhooshIndexingDaemon(repo_location=repo_location)\
450 .run(full_index=full_index)
455 .run(full_index=full_index)
451 l.release()
456 l.release()
452 except LockHeld:
457 except LockHeld:
453 pass
458 pass
454
459
455 def create_test_env(repos_test_path, config):
460 def create_test_env(repos_test_path, config):
456 """Makes a fresh database and
461 """Makes a fresh database and
457 install test repository into tmp dir
462 install test repository into tmp dir
458 """
463 """
459 from rhodecode.lib.db_manage import DbManage
464 from rhodecode.lib.db_manage import DbManage
460 import tarfile
465 import tarfile
461 import shutil
466 import shutil
462 from os.path import dirname as dn, join as jn, abspath
467 from os.path import dirname as dn, join as jn, abspath
463 from rhodecode.tests import REPO_PATH, NEW_REPO_PATH
468 from rhodecode.tests import REPO_PATH, NEW_REPO_PATH
464
469
465 log = logging.getLogger('TestEnvCreator')
470 log = logging.getLogger('TestEnvCreator')
466 # create logger
471 # create logger
467 log.setLevel(logging.DEBUG)
472 log.setLevel(logging.DEBUG)
468 log.propagate = True
473 log.propagate = True
469 # create console handler and set level to debug
474 # create console handler and set level to debug
470 ch = logging.StreamHandler()
475 ch = logging.StreamHandler()
471 ch.setLevel(logging.DEBUG)
476 ch.setLevel(logging.DEBUG)
472
477
473 # create formatter
478 # create formatter
474 formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
479 formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
475
480
476 # add formatter to ch
481 # add formatter to ch
477 ch.setFormatter(formatter)
482 ch.setFormatter(formatter)
478
483
479 # add ch to logger
484 # add ch to logger
480 log.addHandler(ch)
485 log.addHandler(ch)
481
486
482 #PART ONE create db
487 #PART ONE create db
483 dbname = config['sqlalchemy.db1.url'].split('/')[-1]
488 dbname = config['sqlalchemy.db1.url'].split('/')[-1]
484 log.debug('making test db %s', dbname)
489 log.debug('making test db %s', dbname)
485
490
486 dbmanage = DbManage(log_sql=True, dbname=dbname, root=config['here'],
491 dbmanage = DbManage(log_sql=True, dbname=dbname, root=config['here'],
487 tests=True)
492 tests=True)
488 dbmanage.create_tables(override=True)
493 dbmanage.create_tables(override=True)
489 dbmanage.config_prompt(repos_test_path)
494 dbmanage.config_prompt(repos_test_path)
490 dbmanage.create_default_user()
495 dbmanage.create_default_user()
491 dbmanage.admin_prompt()
496 dbmanage.admin_prompt()
492 dbmanage.create_permissions()
497 dbmanage.create_permissions()
493 dbmanage.populate_default_permissions()
498 dbmanage.populate_default_permissions()
494
499
495 #PART TWO make test repo
500 #PART TWO make test repo
496 log.debug('making test vcs repo')
501 log.debug('making test vcs repo')
497 if os.path.isdir(REPO_PATH):
502 if os.path.isdir(REPO_PATH):
498 log.debug('REMOVING %s', REPO_PATH)
503 log.debug('REMOVING %s', REPO_PATH)
499 shutil.rmtree(REPO_PATH)
504 shutil.rmtree(REPO_PATH)
500 if os.path.isdir(NEW_REPO_PATH):
505 if os.path.isdir(NEW_REPO_PATH):
501 log.debug('REMOVING %s', NEW_REPO_PATH)
506 log.debug('REMOVING %s', NEW_REPO_PATH)
502 shutil.rmtree(NEW_REPO_PATH)
507 shutil.rmtree(NEW_REPO_PATH)
503
508
504 cur_dir = dn(dn(abspath(__file__)))
509 cur_dir = dn(dn(abspath(__file__)))
505 tar = tarfile.open(jn(cur_dir, 'tests', "vcs_test.tar.gz"))
510 tar = tarfile.open(jn(cur_dir, 'tests', "vcs_test.tar.gz"))
506 tar.extractall('/tmp')
511 tar.extractall('/tmp')
507 tar.close()
512 tar.close()
@@ -1,139 +1,141 b''
1 from rhodecode.model.meta import Base
1 from rhodecode.model.meta import Base
2 from sqlalchemy import *
2 from sqlalchemy import *
3 from sqlalchemy.orm import relation, backref
3 from sqlalchemy.orm import relation, backref
4 from sqlalchemy.orm.session import Session
4 from sqlalchemy.orm.session import Session
5 from vcs.utils.lazy import LazyProperty
5 from vcs.utils.lazy import LazyProperty
6 import logging
6 import logging
7
7
8 log = logging.getLogger(__name__)
8 log = logging.getLogger(__name__)
9
9
10 class RhodeCodeSettings(Base):
10 class RhodeCodeSettings(Base):
11 __tablename__ = 'rhodecode_settings'
11 __tablename__ = 'rhodecode_settings'
12 __table_args__ = (UniqueConstraint('app_settings_name'), {'useexisting':True})
12 __table_args__ = (UniqueConstraint('app_settings_name'), {'useexisting':True})
13 app_settings_id = Column("app_settings_id", INTEGER(), nullable=False, unique=True, default=None, primary_key=True)
13 app_settings_id = Column("app_settings_id", INTEGER(), nullable=False, unique=True, default=None, primary_key=True)
14 app_settings_name = Column("app_settings_name", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
14 app_settings_name = Column("app_settings_name", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
15 app_settings_value = Column("app_settings_value", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
15 app_settings_value = Column("app_settings_value", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
16
16
17 class RhodeCodeUi(Base):
17 class RhodeCodeUi(Base):
18 __tablename__ = 'rhodecode_ui'
18 __tablename__ = 'rhodecode_ui'
19 __table_args__ = {'useexisting':True}
19 __table_args__ = {'useexisting':True}
20 ui_id = Column("ui_id", INTEGER(), nullable=False, unique=True, default=None, primary_key=True)
20 ui_id = Column("ui_id", INTEGER(), nullable=False, unique=True, default=None, primary_key=True)
21 ui_section = Column("ui_section", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
21 ui_section = Column("ui_section", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
22 ui_key = Column("ui_key", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
22 ui_key = Column("ui_key", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
23 ui_value = Column("ui_value", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
23 ui_value = Column("ui_value", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
24 ui_active = Column("ui_active", BOOLEAN(), nullable=True, unique=None, default=True)
24 ui_active = Column("ui_active", BOOLEAN(), nullable=True, unique=None, default=True)
25
25
26
26
27 class User(Base):
27 class User(Base):
28 __tablename__ = 'users'
28 __tablename__ = 'users'
29 __table_args__ = (UniqueConstraint('username'), UniqueConstraint('email'), {'useexisting':True})
29 __table_args__ = (UniqueConstraint('username'), UniqueConstraint('email'), {'useexisting':True})
30 user_id = Column("user_id", INTEGER(), nullable=False, unique=True, default=None, primary_key=True)
30 user_id = Column("user_id", INTEGER(), nullable=False, unique=True, default=None, primary_key=True)
31 username = Column("username", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
31 username = Column("username", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
32 password = Column("password", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
32 password = Column("password", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
33 active = Column("active", BOOLEAN(), nullable=True, unique=None, default=None)
33 active = Column("active", BOOLEAN(), nullable=True, unique=None, default=None)
34 admin = Column("admin", BOOLEAN(), nullable=True, unique=None, default=False)
34 admin = Column("admin", BOOLEAN(), nullable=True, unique=None, default=False)
35 name = Column("name", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
35 name = Column("name", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
36 lastname = Column("lastname", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
36 lastname = Column("lastname", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
37 email = Column("email", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
37 email = Column("email", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
38 last_login = Column("last_login", DATETIME(timezone=False), nullable=True, unique=None, default=None)
38 last_login = Column("last_login", DATETIME(timezone=False), nullable=True, unique=None, default=None)
39
39
40 user_log = relation('UserLog')
40 user_log = relation('UserLog')
41 user_perms = relation('UserToPerm', primaryjoin="User.user_id==UserToPerm.user_id")
41 user_perms = relation('UserToPerm', primaryjoin="User.user_id==UserToPerm.user_id")
42
42
43 @LazyProperty
43 @LazyProperty
44 def full_contact(self):
44 def full_contact(self):
45 return '%s %s <%s>' % (self.name, self.lastname, self.email)
45 return '%s %s <%s>' % (self.name, self.lastname, self.email)
46
46
47 def __repr__(self):
47 def __repr__(self):
48 return "<User('id:%s:%s')>" % (self.user_id, self.username)
48 return "<User('id:%s:%s')>" % (self.user_id, self.username)
49
49
50 def update_lastlogin(self):
50 def update_lastlogin(self):
51 """Update user lastlogin"""
51 """Update user lastlogin"""
52 import datetime
52 import datetime
53
53
54 try:
54 try:
55 session = Session.object_session(self)
55 session = Session.object_session(self)
56 self.last_login = datetime.datetime.now()
56 self.last_login = datetime.datetime.now()
57 session.add(self)
57 session.add(self)
58 session.commit()
58 session.commit()
59 log.debug('updated user %s lastlogin', self.username)
59 log.debug('updated user %s lastlogin', self.username)
60 except Exception:
60 except Exception:
61 session.rollback()
61 session.rollback()
62
62
63
63
64 class UserLog(Base):
64 class UserLog(Base):
65 __tablename__ = 'user_logs'
65 __tablename__ = 'user_logs'
66 __table_args__ = {'useexisting':True}
66 __table_args__ = {'useexisting':True}
67 user_log_id = Column("user_log_id", INTEGER(), nullable=False, unique=True, default=None, primary_key=True)
67 user_log_id = Column("user_log_id", INTEGER(), nullable=False, unique=True, default=None, primary_key=True)
68 user_id = Column("user_id", INTEGER(), ForeignKey(u'users.user_id'), nullable=False, unique=None, default=None)
68 user_id = Column("user_id", INTEGER(), ForeignKey(u'users.user_id'), nullable=False, unique=None, default=None)
69 repository_id = Column("repository_id", INTEGER(length=None, convert_unicode=False, assert_unicode=None), ForeignKey(u'repositories.repo_id'), nullable=False, unique=None, default=None)
69 repository_id = Column("repository_id", INTEGER(length=None, convert_unicode=False, assert_unicode=None), ForeignKey(u'repositories.repo_id'), nullable=False, unique=None, default=None)
70 repository_name = Column("repository_name", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
70 repository_name = Column("repository_name", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
71 user_ip = Column("user_ip", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
71 user_ip = Column("user_ip", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
72 action = Column("action", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
72 action = Column("action", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
73 action_date = Column("action_date", DATETIME(timezone=False), nullable=True, unique=None, default=None)
73 action_date = Column("action_date", DATETIME(timezone=False), nullable=True, unique=None, default=None)
74 revision = Column('revision', TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
74 revision = Column('revision', TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
75
75
76 user = relation('User')
76 user = relation('User')
77 repository = relation('Repository')
77 repository = relation('Repository')
78
78
79 class Repository(Base):
79 class Repository(Base):
80 __tablename__ = 'repositories'
80 __tablename__ = 'repositories'
81 __table_args__ = (UniqueConstraint('repo_name'), {'useexisting':True},)
81 __table_args__ = (UniqueConstraint('repo_name'), {'useexisting':True},)
82 repo_id = Column("repo_id", INTEGER(), nullable=False, unique=True, default=None, primary_key=True)
82 repo_id = Column("repo_id", INTEGER(), nullable=False, unique=True, default=None, primary_key=True)
83 repo_name = Column("repo_name", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=False, unique=True, default=None)
83 repo_name = Column("repo_name", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=False, unique=True, default=None)
84 user_id = Column("user_id", INTEGER(), ForeignKey(u'users.user_id'), nullable=False, unique=False, default=None)
84 user_id = Column("user_id", INTEGER(), ForeignKey(u'users.user_id'), nullable=False, unique=False, default=None)
85 private = Column("private", BOOLEAN(), nullable=True, unique=None, default=None)
85 private = Column("private", BOOLEAN(), nullable=True, unique=None, default=None)
86 description = Column("description", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
86 description = Column("description", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
87 fork_id = Column("fork_id", INTEGER(), ForeignKey(u'repositories.repo_id'), nullable=True, unique=False, default=None)
87 fork_id = Column("fork_id", INTEGER(), ForeignKey(u'repositories.repo_id'), nullable=True, unique=False, default=None)
88
88
89 user = relation('User')
89 user = relation('User')
90 fork = relation('Repository', remote_side=repo_id)
90 fork = relation('Repository', remote_side=repo_id)
91 repo_to_perm = relation('RepoToPerm', cascade='all')
91 repo_to_perm = relation('RepoToPerm', cascade='all')
92
92 stats = relation('Statistics', cascade='all')
93
94
93 def __repr__(self):
95 def __repr__(self):
94 return "<Repository('id:%s:%s')>" % (self.repo_id, self.repo_name)
96 return "<Repository('id:%s:%s')>" % (self.repo_id, self.repo_name)
95
97
96 class Permission(Base):
98 class Permission(Base):
97 __tablename__ = 'permissions'
99 __tablename__ = 'permissions'
98 __table_args__ = {'useexisting':True}
100 __table_args__ = {'useexisting':True}
99 permission_id = Column("permission_id", INTEGER(), nullable=False, unique=True, default=None, primary_key=True)
101 permission_id = Column("permission_id", INTEGER(), nullable=False, unique=True, default=None, primary_key=True)
100 permission_name = Column("permission_name", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
102 permission_name = Column("permission_name", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
101 permission_longname = Column("permission_longname", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
103 permission_longname = Column("permission_longname", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
102
104
103 def __repr__(self):
105 def __repr__(self):
104 return "<Permission('%s:%s')>" % (self.permission_id, self.permission_name)
106 return "<Permission('%s:%s')>" % (self.permission_id, self.permission_name)
105
107
106 class RepoToPerm(Base):
108 class RepoToPerm(Base):
107 __tablename__ = 'repo_to_perm'
109 __tablename__ = 'repo_to_perm'
108 __table_args__ = (UniqueConstraint('user_id', 'repository_id'), {'useexisting':True})
110 __table_args__ = (UniqueConstraint('user_id', 'repository_id'), {'useexisting':True})
109 repo_to_perm_id = Column("repo_to_perm_id", INTEGER(), nullable=False, unique=True, default=None, primary_key=True)
111 repo_to_perm_id = Column("repo_to_perm_id", INTEGER(), nullable=False, unique=True, default=None, primary_key=True)
110 user_id = Column("user_id", INTEGER(), ForeignKey(u'users.user_id'), nullable=False, unique=None, default=None)
112 user_id = Column("user_id", INTEGER(), ForeignKey(u'users.user_id'), nullable=False, unique=None, default=None)
111 permission_id = Column("permission_id", INTEGER(), ForeignKey(u'permissions.permission_id'), nullable=False, unique=None, default=None)
113 permission_id = Column("permission_id", INTEGER(), ForeignKey(u'permissions.permission_id'), nullable=False, unique=None, default=None)
112 repository_id = Column("repository_id", INTEGER(), ForeignKey(u'repositories.repo_id'), nullable=False, unique=None, default=None)
114 repository_id = Column("repository_id", INTEGER(), ForeignKey(u'repositories.repo_id'), nullable=False, unique=None, default=None)
113
115
114 user = relation('User')
116 user = relation('User')
115 permission = relation('Permission')
117 permission = relation('Permission')
116 repository = relation('Repository')
118 repository = relation('Repository')
117
119
118 class UserToPerm(Base):
120 class UserToPerm(Base):
119 __tablename__ = 'user_to_perm'
121 __tablename__ = 'user_to_perm'
120 __table_args__ = (UniqueConstraint('user_id', 'permission_id'), {'useexisting':True})
122 __table_args__ = (UniqueConstraint('user_id', 'permission_id'), {'useexisting':True})
121 user_to_perm_id = Column("user_to_perm_id", INTEGER(), nullable=False, unique=True, default=None, primary_key=True)
123 user_to_perm_id = Column("user_to_perm_id", INTEGER(), nullable=False, unique=True, default=None, primary_key=True)
122 user_id = Column("user_id", INTEGER(), ForeignKey(u'users.user_id'), nullable=False, unique=None, default=None)
124 user_id = Column("user_id", INTEGER(), ForeignKey(u'users.user_id'), nullable=False, unique=None, default=None)
123 permission_id = Column("permission_id", INTEGER(), ForeignKey(u'permissions.permission_id'), nullable=False, unique=None, default=None)
125 permission_id = Column("permission_id", INTEGER(), ForeignKey(u'permissions.permission_id'), nullable=False, unique=None, default=None)
124
126
125 user = relation('User')
127 user = relation('User')
126 permission = relation('Permission')
128 permission = relation('Permission')
127
129
128 class Statistics(Base):
130 class Statistics(Base):
129 __tablename__ = 'statistics'
131 __tablename__ = 'statistics'
130 __table_args__ = (UniqueConstraint('repository_id'), {'useexisting':True})
132 __table_args__ = (UniqueConstraint('repository_id'), {'useexisting':True})
131 stat_id = Column("stat_id", INTEGER(), nullable=False, unique=True, default=None, primary_key=True)
133 stat_id = Column("stat_id", INTEGER(), nullable=False, unique=True, default=None, primary_key=True)
132 repository_id = Column("repository_id", INTEGER(), ForeignKey(u'repositories.repo_id'), nullable=False, unique=True, default=None)
134 repository_id = Column("repository_id", INTEGER(), ForeignKey(u'repositories.repo_id'), nullable=False, unique=True, default=None)
133 stat_on_revision = Column("stat_on_revision", INTEGER(), nullable=False)
135 stat_on_revision = Column("stat_on_revision", INTEGER(), nullable=False)
134 commit_activity = Column("commit_activity", BLOB(), nullable=False)#JSON data
136 commit_activity = Column("commit_activity", BLOB(), nullable=False)#JSON data
135 commit_activity_combined = Column("commit_activity_combined", BLOB(), nullable=False)#JSON data
137 commit_activity_combined = Column("commit_activity_combined", BLOB(), nullable=False)#JSON data
136 languages = Column("languages", BLOB(), nullable=False)#JSON data
138 languages = Column("languages", BLOB(), nullable=False)#JSON data
137
138 repository = relation('Repository')
139
139
140 repository = relation('Repository', single_parent=True)
141
@@ -1,2312 +1,2313 b''
1 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 {
1 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 {
2 border:0;
2 border:0;
3 outline:0;
3 outline:0;
4 font-size:100%;
4 font-size:100%;
5 vertical-align:baseline;
5 vertical-align:baseline;
6 background:transparent;
6 background:transparent;
7 margin:0;
7 margin:0;
8 padding:0;
8 padding:0;
9 }
9 }
10
10
11 body {
11 body {
12 line-height:1;
12 line-height:1;
13 height:100%;
13 height:100%;
14 background:url("../images/background.png") repeat scroll 0 0 #B0B0B0;
14 background:url("../images/background.png") repeat scroll 0 0 #B0B0B0;
15 font-family:Lucida Grande, Verdana, Lucida Sans Regular, Lucida Sans Unicode, Arial, sans-serif;
15 font-family:Lucida Grande, Verdana, Lucida Sans Regular, Lucida Sans Unicode, Arial, sans-serif;
16 font-size:12px;
16 font-size:12px;
17 color:#000;
17 color:#000;
18 margin:0;
18 margin:0;
19 padding:0;
19 padding:0;
20 }
20 }
21
21
22 ol,ul {
22 ol,ul {
23 list-style:none;
23 list-style:none;
24 }
24 }
25
25
26 blockquote,q {
26 blockquote,q {
27 quotes:none;
27 quotes:none;
28 }
28 }
29
29
30 blockquote:before,blockquote:after,q:before,q:after {
30 blockquote:before,blockquote:after,q:before,q:after {
31 content:none;
31 content:none;
32 }
32 }
33
33
34 :focus {
34 :focus {
35 outline:0;
35 outline:0;
36 }
36 }
37
37
38 del {
38 del {
39 text-decoration:line-through;
39 text-decoration:line-through;
40 }
40 }
41
41
42 table {
42 table {
43 border-collapse:collapse;
43 border-collapse:collapse;
44 border-spacing:0;
44 border-spacing:0;
45 }
45 }
46
46
47 html {
47 html {
48 height:100%;
48 height:100%;
49 }
49 }
50
50
51 a {
51 a {
52 color:#003367;
52 color:#003367;
53 text-decoration:none;
53 text-decoration:none;
54 cursor:pointer;
54 cursor:pointer;
55 font-weight:700;
55 font-weight:700;
56 }
56 }
57
57
58 a:hover {
58 a:hover {
59 color:#316293;
59 color:#316293;
60 text-decoration:underline;
60 text-decoration:underline;
61 }
61 }
62
62
63 h1,h2,h3,h4,h5,h6 {
63 h1,h2,h3,h4,h5,h6 {
64 color:#292929;
64 color:#292929;
65 font-weight:700;
65 font-weight:700;
66 }
66 }
67
67
68 h1 {
68 h1 {
69 font-size:22px;
69 font-size:22px;
70 }
70 }
71
71
72 h2 {
72 h2 {
73 font-size:20px;
73 font-size:20px;
74 }
74 }
75
75
76 h3 {
76 h3 {
77 font-size:18px;
77 font-size:18px;
78 }
78 }
79
79
80 h4 {
80 h4 {
81 font-size:16px;
81 font-size:16px;
82 }
82 }
83
83
84 h5 {
84 h5 {
85 font-size:14px;
85 font-size:14px;
86 }
86 }
87
87
88 h6 {
88 h6 {
89 font-size:11px;
89 font-size:11px;
90 }
90 }
91
91
92 ul.circle {
92 ul.circle {
93 list-style-type:circle;
93 list-style-type:circle;
94 }
94 }
95
95
96 ul.disc {
96 ul.disc {
97 list-style-type:disc;
97 list-style-type:disc;
98 }
98 }
99
99
100 ul.square {
100 ul.square {
101 list-style-type:square;
101 list-style-type:square;
102 }
102 }
103
103
104 ol.lower-roman {
104 ol.lower-roman {
105 list-style-type:lower-roman;
105 list-style-type:lower-roman;
106 }
106 }
107
107
108 ol.upper-roman {
108 ol.upper-roman {
109 list-style-type:upper-roman;
109 list-style-type:upper-roman;
110 }
110 }
111
111
112 ol.lower-alpha {
112 ol.lower-alpha {
113 list-style-type:lower-alpha;
113 list-style-type:lower-alpha;
114 }
114 }
115
115
116 ol.upper-alpha {
116 ol.upper-alpha {
117 list-style-type:upper-alpha;
117 list-style-type:upper-alpha;
118 }
118 }
119
119
120 ol.decimal {
120 ol.decimal {
121 list-style-type:decimal;
121 list-style-type:decimal;
122 }
122 }
123
123
124 div.color {
124 div.color {
125 clear:both;
125 clear:both;
126 overflow:hidden;
126 overflow:hidden;
127 position:absolute;
127 position:absolute;
128 background:#FFF;
128 background:#FFF;
129 margin:7px 0 0 60px;
129 margin:7px 0 0 60px;
130 padding:1px 1px 1px 0;
130 padding:1px 1px 1px 0;
131 }
131 }
132
132
133 div.color a {
133 div.color a {
134 width:15px;
134 width:15px;
135 height:15px;
135 height:15px;
136 display:block;
136 display:block;
137 float:left;
137 float:left;
138 margin:0 0 0 1px;
138 margin:0 0 0 1px;
139 padding:0;
139 padding:0;
140 }
140 }
141
141
142 div.options {
142 div.options {
143 clear:both;
143 clear:both;
144 overflow:hidden;
144 overflow:hidden;
145 position:absolute;
145 position:absolute;
146 background:#FFF;
146 background:#FFF;
147 margin:7px 0 0 162px;
147 margin:7px 0 0 162px;
148 padding:0;
148 padding:0;
149 }
149 }
150
150
151 div.options a {
151 div.options a {
152 height:1%;
152 height:1%;
153 display:block;
153 display:block;
154 text-decoration:none;
154 text-decoration:none;
155 margin:0;
155 margin:0;
156 padding:3px 8px;
156 padding:3px 8px;
157 }
157 }
158
158
159 .top-left-rounded-corner {
159 .top-left-rounded-corner {
160 -webkit-border-top-left-radius: 8px;
160 -webkit-border-top-left-radius: 8px;
161 -khtml-border-radius-topleft: 8px;
161 -khtml-border-radius-topleft: 8px;
162 -moz-border-radius-topleft: 8px;
162 -moz-border-radius-topleft: 8px;
163 border-top-left-radius: 8px;
163 border-top-left-radius: 8px;
164 }
164 }
165
165
166 .top-right-rounded-corner {
166 .top-right-rounded-corner {
167 -webkit-border-top-right-radius: 8px;
167 -webkit-border-top-right-radius: 8px;
168 -khtml-border-radius-topright: 8px;
168 -khtml-border-radius-topright: 8px;
169 -moz-border-radius-topright: 8px;
169 -moz-border-radius-topright: 8px;
170 border-top-right-radius: 8px;
170 border-top-right-radius: 8px;
171 }
171 }
172
172
173 .bottom-left-rounded-corner {
173 .bottom-left-rounded-corner {
174 -webkit-border-bottom-left-radius: 8px;
174 -webkit-border-bottom-left-radius: 8px;
175 -khtml-border-radius-bottomleft: 8px;
175 -khtml-border-radius-bottomleft: 8px;
176 -moz-border-radius-bottomleft: 8px;
176 -moz-border-radius-bottomleft: 8px;
177 border-bottom-left-radius: 8px;
177 border-bottom-left-radius: 8px;
178 }
178 }
179
179
180 .bottom-right-rounded-corner {
180 .bottom-right-rounded-corner {
181 -webkit-border-bottom-right-radius: 8px;
181 -webkit-border-bottom-right-radius: 8px;
182 -khtml-border-radius-bottomright: 8px;
182 -khtml-border-radius-bottomright: 8px;
183 -moz-border-radius-bottomright: 8px;
183 -moz-border-radius-bottomright: 8px;
184 border-bottom-right-radius: 8px;
184 border-bottom-right-radius: 8px;
185 }
185 }
186
186
187
187
188 #header {
188 #header {
189 margin:0;
189 margin:0;
190 padding:0 30px;
190 padding:0 30px;
191 }
191 }
192
192
193 #header ul#logged-user li {
193 #header ul#logged-user li {
194 list-style:none;
194 list-style:none;
195 float:left;
195 float:left;
196 border-left:1px solid #bbb;
196 border-left:1px solid #bbb;
197 border-right:1px solid #a5a5a5;
197 border-right:1px solid #a5a5a5;
198 margin:-2px 0 0;
198 margin:-2px 0 0;
199 padding:10px 12px;
199 padding:10px 12px;
200 }
200 }
201
201
202 #header ul#logged-user li.first {
202 #header ul#logged-user li.first {
203 border-left:none;
203 border-left:none;
204 margin:-6px;
204 margin:-6px;
205 }
205 }
206
206
207 #header ul#logged-user li.first div.account {
207 #header ul#logged-user li.first div.account {
208 padding-top:4px;
208 padding-top:4px;
209 float:left;
209 float:left;
210 }
210 }
211
211
212 #header ul#logged-user li.last {
212 #header ul#logged-user li.last {
213 border-right:none;
213 border-right:none;
214 }
214 }
215
215
216 #header ul#logged-user li a {
216 #header ul#logged-user li a {
217 color:#4e4e4e;
217 color:#4e4e4e;
218 font-weight:700;
218 font-weight:700;
219 text-decoration:none;
219 text-decoration:none;
220 }
220 }
221
221
222 #header ul#logged-user li a:hover {
222 #header ul#logged-user li a:hover {
223 color:#376ea6;
223 color:#376ea6;
224 text-decoration:underline;
224 text-decoration:underline;
225 }
225 }
226
226
227 #header ul#logged-user li.highlight a {
227 #header ul#logged-user li.highlight a {
228 color:#fff;
228 color:#fff;
229 }
229 }
230
230
231 #header ul#logged-user li.highlight a:hover {
231 #header ul#logged-user li.highlight a:hover {
232 color:#376ea6;
232 color:#376ea6;
233 }
233 }
234
234
235 #header #header-inner {
235 #header #header-inner {
236 height:40px;
236 height:40px;
237 clear:both;
237 clear:both;
238 position:relative;
238 position:relative;
239 background:#003367 url("../images/header_inner.png") repeat-x;
239 background:#003367 url("../images/header_inner.png") repeat-x;
240 border-bottom:2px solid #fff;
240 border-bottom:2px solid #fff;
241 margin:0;
241 margin:0;
242 padding:0;
242 padding:0;
243 }
243 }
244
244
245 #header #header-inner #home a {
245 #header #header-inner #home a {
246 height:40px;
246 height:40px;
247 width:46px;
247 width:46px;
248 display:block;
248 display:block;
249 background:url("../images/button_home.png");
249 background:url("../images/button_home.png");
250 background-position:0 0;
250 background-position:0 0;
251 margin:0;
251 margin:0;
252 padding:0;
252 padding:0;
253 }
253 }
254
254
255 #header #header-inner #home a:hover {
255 #header #header-inner #home a:hover {
256 background-position:0 -40px;
256 background-position:0 -40px;
257 }
257 }
258
258
259 #header #header-inner #logo h1 {
259 #header #header-inner #logo h1 {
260 color:#FFF;
260 color:#FFF;
261 font-size:14px;
261 font-size:14px;
262 text-transform:uppercase;
262 text-transform:uppercase;
263 margin:13px 0 0 13px;
263 margin:13px 0 0 13px;
264 padding:0;
264 padding:0;
265 }
265 }
266
266
267 #header #header-inner #logo a {
267 #header #header-inner #logo a {
268 color:#fff;
268 color:#fff;
269 text-decoration:none;
269 text-decoration:none;
270 }
270 }
271
271
272 #header #header-inner #logo a:hover {
272 #header #header-inner #logo a:hover {
273 color:#dabf29;
273 color:#bfe3ff;
274 }
274 }
275
275
276 #header #header-inner #quick,#header #header-inner #quick ul {
276 #header #header-inner #quick,#header #header-inner #quick ul {
277 position:relative;
277 position:relative;
278 float:right;
278 float:right;
279 list-style-type:none;
279 list-style-type:none;
280 list-style-position:outside;
280 list-style-position:outside;
281 margin:10px 5px 0 0;
281 margin:10px 5px 0 0;
282 padding:0;
282 padding:0;
283 }
283 }
284
284
285 #header #header-inner #quick li {
285 #header #header-inner #quick li {
286 position:relative;
286 position:relative;
287 float:left;
287 float:left;
288 margin:0 5px 0 0;
288 margin:0 5px 0 0;
289 padding:0;
289 padding:0;
290 }
290 }
291
291
292 #header #header-inner #quick li a {
292 #header #header-inner #quick li a {
293 top:0;
293 top:0;
294 left:0;
294 left:0;
295 height:1%;
295 height:1%;
296 display:block;
296 display:block;
297 clear:both;
297 clear:both;
298 overflow:hidden;
298 overflow:hidden;
299 color:#FFF;
299 color:#FFF;
300 font-weight:700;
300 font-weight:700;
301 text-decoration:none;
301 text-decoration:none;
302 background:#369 url("../../images/quick_l.png") no-repeat top left;
302 background:#369 url("../../images/quick_l.png") no-repeat top left;
303 padding:0;
303 padding:0;
304 }
304 }
305
305
306 #header #header-inner #quick li span {
306 #header #header-inner #quick li span {
307 top:0;
307 top:0;
308 right:0;
308 right:0;
309 height:1%;
309 height:1%;
310 display:block;
310 display:block;
311 float:left;
311 float:left;
312 background:url("../../images/quick_r.png") no-repeat top right;
312 background:url("../../images/quick_r.png") no-repeat top right;
313 border-left:1px solid #3f6f9f;
313 border-left:1px solid #3f6f9f;
314 margin:0;
314 margin:0;
315 padding:10px 12px 8px 10px;
315 padding:10px 12px 8px 10px;
316 }
316 }
317
317
318 #header #header-inner #quick li span.normal {
318 #header #header-inner #quick li span.normal {
319 border:none;
319 border:none;
320 padding:10px 12px 8px;
320 padding:10px 12px 8px;
321 }
321 }
322
322
323 #header #header-inner #quick li span.icon {
323 #header #header-inner #quick li span.icon {
324 top:0;
324 top:0;
325 left:0;
325 left:0;
326 border-left:none;
326 border-left:none;
327 background:url("../../images/quick_l.png") no-repeat top left;
327 background:url("../../images/quick_l.png") no-repeat top left;
328 border-right:1px solid #2e5c89;
328 border-right:1px solid #2e5c89;
329 padding:8px 8px 4px;
329 padding:8px 8px 4px;
330 }
330 }
331
331
332 #header #header-inner #quick li a:hover {
332 #header #header-inner #quick li a:hover {
333 background:#4e4e4e url("../../images/quick_l_selected.png") no-repeat top left;
333 background:#4e4e4e url("../../images/quick_l_selected.png") no-repeat top left;
334 }
334 }
335
335
336 #header #header-inner #quick li a:hover span {
336 #header #header-inner #quick li a:hover span {
337 border-left:1px solid #545454;
337 border-left:1px solid #545454;
338 background:url("../../images/quick_r_selected.png") no-repeat top right;
338 background:url("../../images/quick_r_selected.png") no-repeat top right;
339 }
339 }
340
340
341 #header #header-inner #quick li a:hover span.icon {
341 #header #header-inner #quick li a:hover span.icon {
342 border-left:none;
342 border-left:none;
343 border-right:1px solid #464646;
343 border-right:1px solid #464646;
344 background:url("../../images/quick_l_selected.png") no-repeat top left;
344 background:url("../../images/quick_l_selected.png") no-repeat top left;
345 }
345 }
346
346
347 #header #header-inner #quick ul {
347 #header #header-inner #quick ul {
348 top:29px;
348 top:29px;
349 right:0;
349 right:0;
350 min-width:200px;
350 min-width:200px;
351 display:none;
351 display:none;
352 position:absolute;
352 position:absolute;
353 background:#FFF;
353 background:#FFF;
354 border:1px solid #666;
354 border:1px solid #666;
355 border-top:1px solid #003367;
355 border-top:1px solid #003367;
356 z-index:100;
356 z-index:100;
357 margin:0;
357 margin:0;
358 padding:0;
358 padding:0;
359 }
359 }
360
360
361 #header #header-inner #quick ul.repo_switcher {
361 #header #header-inner #quick ul.repo_switcher {
362 max-height:275px;
362 max-height:275px;
363 overflow-x:hidden;
363 overflow-x:hidden;
364 overflow-y:auto;
364 overflow-y:auto;
365 }
365 }
366
366
367 #header #header-inner #quick li ul li {
367 #header #header-inner #quick li ul li {
368 border-bottom:1px solid #ddd;
368 border-bottom:1px solid #ddd;
369 }
369 }
370
370
371 #header #header-inner #quick li ul li a {
371 #header #header-inner #quick li ul li a {
372 width:182px;
372 width:182px;
373 height:auto;
373 height:auto;
374 display:block;
374 display:block;
375 float:left;
375 float:left;
376 background:#FFF;
376 background:#FFF;
377 color:#003367;
377 color:#003367;
378 font-weight:400;
378 font-weight:400;
379 margin:0;
379 margin:0;
380 padding:7px 9px;
380 padding:7px 9px;
381 }
381 }
382
382
383 #header #header-inner #quick li ul li a:hover {
383 #header #header-inner #quick li ul li a:hover {
384 color:#000;
384 color:#000;
385 background:#FFF;
385 background:#FFF;
386 }
386 }
387
387
388 #header #header-inner #quick ul ul {
388 #header #header-inner #quick ul ul {
389 top:auto;
389 top:auto;
390 }
390 }
391
391
392 #header #header-inner #quick li ul ul {
392 #header #header-inner #quick li ul ul {
393 right:200px;
393 right:200px;
394 max-height:275px;
394 max-height:275px;
395 overflow:auto;
395 overflow:auto;
396 overflow-x:hidden;
396 overflow-x:hidden;
397 white-space:nowrap;
397 white-space:nowrap;
398 }
398 }
399
399
400 #header #header-inner #quick li ul li a.journal,#header #header-inner #quick li ul li a.journal:hover {
400 #header #header-inner #quick li ul li a.journal,#header #header-inner #quick li ul li a.journal:hover {
401 background:url("../images/icons/book.png") no-repeat scroll 4px 9px #FFF;
401 background:url("../images/icons/book.png") no-repeat scroll 4px 9px #FFF;
402 width:167px;
402 width:167px;
403 margin:0;
403 margin:0;
404 padding:12px 9px 7px 24px;
404 padding:12px 9px 7px 24px;
405 }
405 }
406
406
407 #header #header-inner #quick li ul li a.private_repo,#header #header-inner #quick li ul li a.private_repo:hover {
407 #header #header-inner #quick li ul li a.private_repo,#header #header-inner #quick li ul li a.private_repo:hover {
408 background:url("../images/icons/lock.png") no-repeat scroll 4px 9px #FFF;
408 background:url("../images/icons/lock.png") no-repeat scroll 4px 9px #FFF;
409 min-width:167px;
409 min-width:167px;
410 margin:0;
410 margin:0;
411 padding:12px 9px 7px 24px;
411 padding:12px 9px 7px 24px;
412 }
412 }
413
413
414 #header #header-inner #quick li ul li a.public_repo,#header #header-inner #quick li ul li a.public_repo:hover {
414 #header #header-inner #quick li ul li a.public_repo,#header #header-inner #quick li ul li a.public_repo:hover {
415 background:url("../images/icons/lock_open.png") no-repeat scroll 4px 9px #FFF;
415 background:url("../images/icons/lock_open.png") no-repeat scroll 4px 9px #FFF;
416 min-width:167px;
416 min-width:167px;
417 margin:0;
417 margin:0;
418 padding:12px 9px 7px 24px;
418 padding:12px 9px 7px 24px;
419 }
419 }
420
420
421 #header #header-inner #quick li ul li a.repos,#header #header-inner #quick li ul li a.repos:hover {
421 #header #header-inner #quick li ul li a.repos,#header #header-inner #quick li ul li a.repos:hover {
422 background:url("../images/icons/folder_edit.png") no-repeat scroll 4px 9px #FFF;
422 background:url("../images/icons/database_edit.png") no-repeat scroll 4px 9px #FFF;
423 width:167px;
423 width:167px;
424 margin:0;
424 margin:0;
425 padding:12px 9px 7px 24px;
425 padding:12px 9px 7px 24px;
426 }
426 }
427
427
428 #header #header-inner #quick li ul li a.users,#header #header-inner #quick li ul li a.users:hover {
428 #header #header-inner #quick li ul li a.users,#header #header-inner #quick li ul li a.users:hover {
429 background:#FFF url("../images/icons/user_edit.png") no-repeat 4px 9px;
429 background:#FFF url("../images/icons/user_edit.png") no-repeat 4px 9px;
430 width:167px;
430 width:167px;
431 margin:0;
431 margin:0;
432 padding:12px 9px 7px 24px;
432 padding:12px 9px 7px 24px;
433 }
433 }
434
434
435 #header #header-inner #quick li ul li a.settings,#header #header-inner #quick li ul li a.settings:hover {
435 #header #header-inner #quick li ul li a.settings,#header #header-inner #quick li ul li a.settings:hover {
436 background:#FFF url("../images/icons/cog.png") no-repeat 4px 9px;
436 background:#FFF url("../images/icons/cog.png") no-repeat 4px 9px;
437 width:167px;
437 width:167px;
438 margin:0;
438 margin:0;
439 padding:12px 9px 7px 24px;
439 padding:12px 9px 7px 24px;
440 }
440 }
441
441
442 #header #header-inner #quick li ul li a.permissions,#header #header-inner #quick li ul li a.permissions:hover {
442 #header #header-inner #quick li ul li a.permissions,#header #header-inner #quick li ul li a.permissions:hover {
443 background:#FFF url("../images/icons/key.png") no-repeat 4px 9px;
443 background:#FFF url("../images/icons/key.png") no-repeat 4px 9px;
444 width:167px;
444 width:167px;
445 margin:0;
445 margin:0;
446 padding:12px 9px 7px 24px;
446 padding:12px 9px 7px 24px;
447 }
447 }
448
448
449 #header #header-inner #quick li ul li a.fork,#header #header-inner #quick li ul li a.fork:hover {
449 #header #header-inner #quick li ul li a.fork,#header #header-inner #quick li ul li a.fork:hover {
450 background:#FFF url("../images/icons/arrow_divide.png") no-repeat 4px 9px;
450 background:#FFF url("../images/icons/arrow_divide.png") no-repeat 4px 9px;
451 width:167px;
451 width:167px;
452 margin:0;
452 margin:0;
453 padding:12px 9px 7px 24px;
453 padding:12px 9px 7px 24px;
454 }
454 }
455
455
456 #header #header-inner #quick li ul li a.search,#header #header-inner #quick li ul li a.search:hover {
456 #header #header-inner #quick li ul li a.search,#header #header-inner #quick li ul li a.search:hover {
457 background:#FFF url("../images/icons/search_16.png") no-repeat 4px 9px;
457 background:#FFF url("../images/icons/search_16.png") no-repeat 4px 9px;
458 width:167px;
458 width:167px;
459 margin:0;
459 margin:0;
460 padding:12px 9px 7px 24px;
460 padding:12px 9px 7px 24px;
461 }
461 }
462
462
463 #header #header-inner #quick li ul li a.delete,#header #header-inner #quick li ul li a.delete:hover {
463 #header #header-inner #quick li ul li a.delete,#header #header-inner #quick li ul li a.delete:hover {
464 background:#FFF url("../images/icons/delete.png") no-repeat 4px 9px;
464 background:#FFF url("../images/icons/delete.png") no-repeat 4px 9px;
465 width:167px;
465 width:167px;
466 margin:0;
466 margin:0;
467 padding:12px 9px 7px 24px;
467 padding:12px 9px 7px 24px;
468 }
468 }
469
469
470 #header #header-inner #quick li ul li a.branches,#header #header-inner #quick li ul li a.branches:hover {
470 #header #header-inner #quick li ul li a.branches,#header #header-inner #quick li ul li a.branches:hover {
471 background:#FFF url("../images/icons/arrow_branch.png") no-repeat 4px 9px;
471 background:#FFF url("../images/icons/arrow_branch.png") no-repeat 4px 9px;
472 width:167px;
472 width:167px;
473 margin:0;
473 margin:0;
474 padding:12px 9px 7px 24px;
474 padding:12px 9px 7px 24px;
475 }
475 }
476
476
477 #header #header-inner #quick li ul li a.tags,#header #header-inner #quick li ul li a.tags:hover {
477 #header #header-inner #quick li ul li a.tags,#header #header-inner #quick li ul li a.tags:hover {
478 background:#FFF url("../images/icons/tag_blue.png") no-repeat 4px 9px;
478 background:#FFF url("../images/icons/tag_blue.png") no-repeat 4px 9px;
479 width:167px;
479 width:167px;
480 margin:0;
480 margin:0;
481 padding:12px 9px 7px 24px;
481 padding:12px 9px 7px 24px;
482 }
482 }
483
483
484 #header #header-inner #quick li ul li a.admin,#header #header-inner #quick li ul li a.admin:hover {
484 #header #header-inner #quick li ul li a.admin,#header #header-inner #quick li ul li a.admin:hover {
485 background:#FFF url("../images/icons/cog_edit.png") no-repeat 4px 9px;
485 background:#FFF url("../images/icons/cog_edit.png") no-repeat 4px 9px;
486 width:167px;
486 width:167px;
487 margin:0;
487 margin:0;
488 padding:12px 9px 7px 24px;
488 padding:12px 9px 7px 24px;
489 }
489 }
490
490
491 #content #left {
491 #content #left {
492 left:0;
492 left:0;
493 width:280px;
493 width:280px;
494 position:absolute;
494 position:absolute;
495 }
495 }
496
496
497 #content #right {
497 #content #right {
498 margin:0 60px 10px 290px;
498 margin:0 60px 10px 290px;
499 }
499 }
500
500
501 #content div.box {
501 #content div.box {
502 clear:both;
502 clear:both;
503 overflow:hidden;
503 overflow:hidden;
504 background:#fff;
504 background:#fff;
505 margin:0 0 10px;
505 margin:0 0 10px;
506 padding:0 0 10px;
506 padding:0 0 10px;
507 }
507 }
508
508
509 #content div.box-left {
509 #content div.box-left {
510 width:49%;
510 width:49%;
511 clear:none;
511 clear:none;
512 float:left;
512 float:left;
513 margin:0 0 10px;
513 margin:0 0 10px;
514 }
514 }
515
515
516 #content div.box-right {
516 #content div.box-right {
517 width:49%;
517 width:49%;
518 clear:none;
518 clear:none;
519 float:right;
519 float:right;
520 margin:0 0 10px;
520 margin:0 0 10px;
521 }
521 }
522
522
523 #content div.box div.title {
523 #content div.box div.title {
524 clear:both;
524 clear:both;
525 overflow:hidden;
525 overflow:hidden;
526 background:#369 url("../images/header_inner.png") repeat-x;
526 background:#369 url("../images/header_inner.png") repeat-x;
527 margin:0 0 20px;
527 margin:0 0 20px;
528 padding:0;
528 padding:0;
529 }
529 }
530
530
531 #content div.box div.title h5 {
531 #content div.box div.title h5 {
532 float:left;
532 float:left;
533 border:none;
533 border:none;
534 color:#fff;
534 color:#fff;
535 text-transform:uppercase;
535 text-transform:uppercase;
536 margin:0;
536 margin:0;
537 padding:11px 0 11px 10px;
537 padding:11px 0 11px 10px;
538 }
538 }
539
539
540 #content div.box div.title ul.links li {
540 #content div.box div.title ul.links li {
541 list-style:none;
541 list-style:none;
542 float:left;
542 float:left;
543 margin:0;
543 margin:0;
544 padding:0;
544 padding:0;
545 }
545 }
546
546
547 #content div.box div.title ul.links li a {
547 #content div.box div.title ul.links li a {
548 height:1%;
548 height:1%;
549 display:block;
549 display:block;
550 float:left;
550 float:left;
551 border-left:1px solid #316293;
551 border-left:1px solid #316293;
552 color:#fff;
552 color:#fff;
553 font-size:11px;
553 font-size:11px;
554 font-weight:700;
554 font-weight:700;
555 text-decoration:none;
555 text-decoration:none;
556 margin:0;
556 margin:0;
557 padding:13px 16px 12px;
557 padding:13px 16px 12px;
558 }
558 }
559
559
560 #content div.box h1,#content div.box h2,#content div.box h3,#content div.box h4,#content div.box h5,#content div.box h6 {
560 #content div.box h1,#content div.box h2,#content div.box h3,#content div.box h4,#content div.box h5,#content div.box h6 {
561 clear:both;
561 clear:both;
562 overflow:hidden;
562 overflow:hidden;
563 border-bottom:1px solid #DDD;
563 border-bottom:1px solid #DDD;
564 margin:10px 20px;
564 margin:10px 20px;
565 padding:0 0 15px;
565 padding:0 0 15px;
566 }
566 }
567
567
568 #content div.box p {
568 #content div.box p {
569 color:#5f5f5f;
569 color:#5f5f5f;
570 font-size:12px;
570 font-size:12px;
571 line-height:150%;
571 line-height:150%;
572 margin:0 24px 10px;
572 margin:0 24px 10px;
573 padding:0;
573 padding:0;
574 }
574 }
575
575
576 #content div.box blockquote {
576 #content div.box blockquote {
577 border-left:4px solid #DDD;
577 border-left:4px solid #DDD;
578 color:#5f5f5f;
578 color:#5f5f5f;
579 font-size:11px;
579 font-size:11px;
580 line-height:150%;
580 line-height:150%;
581 margin:0 34px;
581 margin:0 34px;
582 padding:0 0 0 14px;
582 padding:0 0 0 14px;
583 }
583 }
584
584
585 #content div.box blockquote p {
585 #content div.box blockquote p {
586 margin:10px 0;
586 margin:10px 0;
587 padding:0;
587 padding:0;
588 }
588 }
589
589
590 #content div.box dl {
590 #content div.box dl {
591 margin:10px 24px;
591 margin:10px 24px;
592 }
592 }
593
593
594 #content div.box dt {
594 #content div.box dt {
595 font-size:12px;
595 font-size:12px;
596 margin:0;
596 margin:0;
597 }
597 }
598
598
599 #content div.box dd {
599 #content div.box dd {
600 font-size:12px;
600 font-size:12px;
601 margin:0;
601 margin:0;
602 padding:8px 0 8px 15px;
602 padding:8px 0 8px 15px;
603 }
603 }
604
604
605 #content div.box li {
605 #content div.box li {
606 font-size:12px;
606 font-size:12px;
607 padding:4px 0;
607 padding:4px 0;
608 }
608 }
609
609
610 #content div.box ul.disc,#content div.box ul.circle {
610 #content div.box ul.disc,#content div.box ul.circle {
611 margin:10px 24px 10px 38px;
611 margin:10px 24px 10px 38px;
612 }
612 }
613
613
614 #content div.box ul.square {
614 #content div.box ul.square {
615 margin:10px 24px 10px 40px;
615 margin:10px 24px 10px 40px;
616 }
616 }
617
617
618 #content div.box img.left {
618 #content div.box img.left {
619 border:none;
619 border:none;
620 float:left;
620 float:left;
621 margin:10px 10px 10px 0;
621 margin:10px 10px 10px 0;
622 }
622 }
623
623
624 #content div.box img.right {
624 #content div.box img.right {
625 border:none;
625 border:none;
626 float:right;
626 float:right;
627 margin:10px 0 10px 10px;
627 margin:10px 0 10px 10px;
628 }
628 }
629
629
630 #content div.box div.messages {
630 #content div.box div.messages {
631 clear:both;
631 clear:both;
632 overflow:hidden;
632 overflow:hidden;
633 margin:0 20px;
633 margin:0 20px;
634 padding:0;
634 padding:0;
635 }
635 }
636
636
637 #content div.box div.message {
637 #content div.box div.message {
638 clear:both;
638 clear:both;
639 overflow:hidden;
639 overflow:hidden;
640 margin:0;
640 margin:0;
641 padding:10px 0;
641 padding:10px 0;
642 }
642 }
643
643
644 #content div.box div.message a {
644 #content div.box div.message a {
645 font-weight:400 !important;
645 font-weight:400 !important;
646 }
646 }
647
647
648 #content div.box div.message div.image {
648 #content div.box div.message div.image {
649 float:left;
649 float:left;
650 margin:9px 0 0 5px;
650 margin:9px 0 0 5px;
651 padding:6px;
651 padding:6px;
652 }
652 }
653
653
654 #content div.box div.message div.image img {
654 #content div.box div.message div.image img {
655 vertical-align:middle;
655 vertical-align:middle;
656 margin:0;
656 margin:0;
657 }
657 }
658
658
659 #content div.box div.message div.text {
659 #content div.box div.message div.text {
660 float:left;
660 float:left;
661 margin:0;
661 margin:0;
662 padding:9px 6px;
662 padding:9px 6px;
663 }
663 }
664
664
665 #content div.box div.message div.dismiss a {
665 #content div.box div.message div.dismiss a {
666 height:16px;
666 height:16px;
667 width:16px;
667 width:16px;
668 display:block;
668 display:block;
669 background:url("../images/icons/cross.png") no-repeat;
669 background:url("../images/icons/cross.png") no-repeat;
670 margin:15px 14px 0 0;
670 margin:15px 14px 0 0;
671 padding:0;
671 padding:0;
672 }
672 }
673
673
674 #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 {
674 #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 {
675 border:none;
675 border:none;
676 margin:0;
676 margin:0;
677 padding:0;
677 padding:0;
678 }
678 }
679
679
680 #content div.box div.message div.text span {
680 #content div.box div.message div.text span {
681 height:1%;
681 height:1%;
682 display:block;
682 display:block;
683 margin:0;
683 margin:0;
684 padding:5px 0 0;
684 padding:5px 0 0;
685 }
685 }
686
686
687 #content div.box div.message-error {
687 #content div.box div.message-error {
688 height:1%;
688 height:1%;
689 clear:both;
689 clear:both;
690 overflow:hidden;
690 overflow:hidden;
691 background:#FBE3E4;
691 background:#FBE3E4;
692 border:1px solid #FBC2C4;
692 border:1px solid #FBC2C4;
693 color:#860006;
693 color:#860006;
694 }
694 }
695
695
696 #content div.box div.message-error h6 {
696 #content div.box div.message-error h6 {
697 color:#860006;
697 color:#860006;
698 }
698 }
699
699
700 #content div.box div.message-warning {
700 #content div.box div.message-warning {
701 height:1%;
701 height:1%;
702 clear:both;
702 clear:both;
703 overflow:hidden;
703 overflow:hidden;
704 background:#FFF6BF;
704 background:#FFF6BF;
705 border:1px solid #FFD324;
705 border:1px solid #FFD324;
706 color:#5f5200;
706 color:#5f5200;
707 }
707 }
708
708
709 #content div.box div.message-warning h6 {
709 #content div.box div.message-warning h6 {
710 color:#5f5200;
710 color:#5f5200;
711 }
711 }
712
712
713 #content div.box div.message-notice {
713 #content div.box div.message-notice {
714 height:1%;
714 height:1%;
715 clear:both;
715 clear:both;
716 overflow:hidden;
716 overflow:hidden;
717 background:#8FBDE0;
717 background:#8FBDE0;
718 border:1px solid #6BACDE;
718 border:1px solid #6BACDE;
719 color:#003863;
719 color:#003863;
720 }
720 }
721
721
722 #content div.box div.message-notice h6 {
722 #content div.box div.message-notice h6 {
723 color:#003863;
723 color:#003863;
724 }
724 }
725
725
726 #content div.box div.message-success {
726 #content div.box div.message-success {
727 height:1%;
727 height:1%;
728 clear:both;
728 clear:both;
729 overflow:hidden;
729 overflow:hidden;
730 background:#E6EFC2;
730 background:#E6EFC2;
731 border:1px solid #C6D880;
731 border:1px solid #C6D880;
732 color:#4e6100;
732 color:#4e6100;
733 }
733 }
734
734
735 #content div.box div.message-success h6 {
735 #content div.box div.message-success h6 {
736 color:#4e6100;
736 color:#4e6100;
737 }
737 }
738
738
739 #content div.box div.form div.fields div.field {
739 #content div.box div.form div.fields div.field {
740 height:1%;
740 height:1%;
741 border-bottom:1px solid #DDD;
741 border-bottom:1px solid #DDD;
742 clear:both;
742 clear:both;
743 margin:0;
743 margin:0;
744 padding:10px 0;
744 padding:10px 0;
745 }
745 }
746
746
747 #content div.box div.form div.fields div.field-first {
747 #content div.box div.form div.fields div.field-first {
748 padding:0 0 10px;
748 padding:0 0 10px;
749 }
749 }
750
750
751 #content div.box div.form div.fields div.field-noborder {
751 #content div.box div.form div.fields div.field-noborder {
752 border-bottom:0 !important;
752 border-bottom:0 !important;
753 }
753 }
754
754
755 #content div.box div.form div.fields div.field span.error-message {
755 #content div.box div.form div.fields div.field span.error-message {
756 height:1%;
756 height:1%;
757 display:inline-block;
757 display:inline-block;
758 color:red;
758 color:red;
759 margin:8px 0 0 4px;
759 margin:8px 0 0 4px;
760 padding:0;
760 padding:0;
761 }
761 }
762
762
763 #content div.box div.form div.fields div.field span.success {
763 #content div.box div.form div.fields div.field span.success {
764 height:1%;
764 height:1%;
765 display:block;
765 display:block;
766 color:#316309;
766 color:#316309;
767 margin:8px 0 0;
767 margin:8px 0 0;
768 padding:0;
768 padding:0;
769 }
769 }
770
770
771 #content div.box div.form div.fields div.field div.label {
771 #content div.box div.form div.fields div.field div.label {
772 left:80px;
772 left:80px;
773 width:auto;
773 width:auto;
774 position:absolute;
774 position:absolute;
775 margin:0;
775 margin:0;
776 padding:8px 0 0 5px;
776 padding:8px 0 0 5px;
777 }
777 }
778
778
779 #content div.box-left div.form div.fields div.field div.label,#content div.box-right div.form div.fields div.field div.label {
779 #content div.box-left div.form div.fields div.field div.label,#content div.box-right div.form div.fields div.field div.label {
780 clear:both;
780 clear:both;
781 overflow:hidden;
781 overflow:hidden;
782 left:0;
782 left:0;
783 width:auto;
783 width:auto;
784 position:relative;
784 position:relative;
785 margin:0;
785 margin:0;
786 padding:0 0 8px;
786 padding:0 0 8px;
787 }
787 }
788
788
789 #content div.box div.form div.fields div.field div.label-select {
789 #content div.box div.form div.fields div.field div.label-select {
790 padding:2px 0 0 5px;
790 padding:2px 0 0 5px;
791 }
791 }
792
792
793 #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 {
793 #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 {
794 padding:0 0 8px;
794 padding:0 0 8px;
795 }
795 }
796
796
797 #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 {
797 #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 {
798 padding:0 0 8px !important;
798 padding:0 0 8px !important;
799 }
799 }
800
800
801 #content div.box div.form div.fields div.field div.label label {
801 #content div.box div.form div.fields div.field div.label label {
802 color:#393939;
802 color:#393939;
803 font-weight:700;
803 font-weight:700;
804 }
804 }
805
805
806 #content div.box div.form div.fields div.field div.input {
806 #content div.box div.form div.fields div.field div.input {
807 margin:0 0 0 200px;
807 margin:0 0 0 200px;
808 }
808 }
809
809
810 #content div.box-left div.form div.fields div.field div.input,#content div.box-right div.form div.fields div.field div.input {
810 #content div.box-left div.form div.fields div.field div.input,#content div.box-right div.form div.fields div.field div.input {
811 clear:both;
811 clear:both;
812 overflow:hidden;
812 overflow:hidden;
813 border-top:1px solid #b3b3b3;
813 border-top:1px solid #b3b3b3;
814 border-left:1px solid #b3b3b3;
814 border-left:1px solid #b3b3b3;
815 border-right:1px solid #eaeaea;
815 border-right:1px solid #eaeaea;
816 border-bottom:1px solid #eaeaea;
816 border-bottom:1px solid #eaeaea;
817 margin:0;
817 margin:0;
818 padding:7px 7px 6px;
818 padding:7px 7px 6px;
819 }
819 }
820
820
821 #content div.box div.form div.fields div.field div.input input {
821 #content div.box div.form div.fields div.field div.input input {
822 background:#FFF;
822 background:#FFF;
823 border-top:1px solid #b3b3b3;
823 border-top:1px solid #b3b3b3;
824 border-left:1px solid #b3b3b3;
824 border-left:1px solid #b3b3b3;
825 border-right:1px solid #eaeaea;
825 border-right:1px solid #eaeaea;
826 border-bottom:1px solid #eaeaea;
826 border-bottom:1px solid #eaeaea;
827 color:#000;
827 color:#000;
828 font-family:Lucida Grande, Verdana, Lucida Sans Regular, Lucida Sans Unicode, Arial, sans-serif;
828 font-family:Lucida Grande, Verdana, Lucida Sans Regular, Lucida Sans Unicode, Arial, sans-serif;
829 font-size:11px;
829 font-size:11px;
830 margin:0;
830 margin:0;
831 padding:7px 7px 6px;
831 padding:7px 7px 6px;
832 }
832 }
833
833
834 #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 {
834 #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 {
835 width:100%;
835 width:100%;
836 border:none;
836 border:none;
837 padding:0;
837 padding:0;
838 }
838 }
839
839
840 #content div.box div.form div.fields div.field div.input input.small {
840 #content div.box div.form div.fields div.field div.input input.small {
841 width:30%;
841 width:30%;
842 }
842 }
843
843
844 #content div.box div.form div.fields div.field div.input input.medium {
844 #content div.box div.form div.fields div.field div.input input.medium {
845 width:55%;
845 width:55%;
846 }
846 }
847
847
848 #content div.box div.form div.fields div.field div.input input.large {
848 #content div.box div.form div.fields div.field div.input input.large {
849 width:85%;
849 width:85%;
850 }
850 }
851
851
852 #content div.box div.form div.fields div.field div.input input.date {
852 #content div.box div.form div.fields div.field div.input input.date {
853 width:177px;
853 width:177px;
854 }
854 }
855
855
856 #content div.box div.form div.fields div.field div.input input.button {
856 #content div.box div.form div.fields div.field div.input input.button {
857 background:#D4D0C8;
857 background:#D4D0C8;
858 border-top:1px solid #FFF;
858 border-top:1px solid #FFF;
859 border-left:1px solid #FFF;
859 border-left:1px solid #FFF;
860 border-right:1px solid #404040;
860 border-right:1px solid #404040;
861 border-bottom:1px solid #404040;
861 border-bottom:1px solid #404040;
862 color:#000;
862 color:#000;
863 margin:0;
863 margin:0;
864 padding:4px 8px;
864 padding:4px 8px;
865 }
865 }
866
866
867 #content div.box div.form div.fields div.field div.input a.ui-input-file {
867 #content div.box div.form div.fields div.field div.input a.ui-input-file {
868 width:28px;
868 width:28px;
869 height:28px;
869 height:28px;
870 display:inline;
870 display:inline;
871 position:absolute;
871 position:absolute;
872 overflow:hidden;
872 overflow:hidden;
873 cursor:pointer;
873 cursor:pointer;
874 background:#e5e3e3 url("../images/button_browse.png") no-repeat;
874 background:#e5e3e3 url("../images/button_browse.png") no-repeat;
875 border:none;
875 border:none;
876 text-decoration:none;
876 text-decoration:none;
877 margin:0 0 0 6px;
877 margin:0 0 0 6px;
878 padding:0;
878 padding:0;
879 }
879 }
880
880
881 #content div.box div.form div.fields div.field div.textarea {
881 #content div.box div.form div.fields div.field div.textarea {
882 border-top:1px solid #b3b3b3;
882 border-top:1px solid #b3b3b3;
883 border-left:1px solid #b3b3b3;
883 border-left:1px solid #b3b3b3;
884 border-right:1px solid #eaeaea;
884 border-right:1px solid #eaeaea;
885 border-bottom:1px solid #eaeaea;
885 border-bottom:1px solid #eaeaea;
886 margin:0 0 0 200px;
886 margin:0 0 0 200px;
887 padding:10px;
887 padding:10px;
888 }
888 }
889
889
890 #content div.box div.form div.fields div.field div.textarea-editor {
890 #content div.box div.form div.fields div.field div.textarea-editor {
891 border:1px solid #ddd;
891 border:1px solid #ddd;
892 padding:0;
892 padding:0;
893 }
893 }
894
894
895 #content div.box div.form div.fields div.field div.textarea textarea {
895 #content div.box div.form div.fields div.field div.textarea textarea {
896 width:100%;
896 width:100%;
897 height:220px;
897 height:220px;
898 overflow:hidden;
898 overflow:hidden;
899 background:#FFF;
899 background:#FFF;
900 color:#000;
900 color:#000;
901 font-family:Lucida Grande, Verdana, Lucida Sans Regular, Lucida Sans Unicode, Arial, sans-serif;
901 font-family:Lucida Grande, Verdana, Lucida Sans Regular, Lucida Sans Unicode, Arial, sans-serif;
902 font-size:11px;
902 font-size:11px;
903 outline:none;
903 outline:none;
904 border-width:0;
904 border-width:0;
905 margin:0;
905 margin:0;
906 padding:0;
906 padding:0;
907 }
907 }
908
908
909 #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 {
909 #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 {
910 width:100%;
910 width:100%;
911 height:100px;
911 height:100px;
912 }
912 }
913
913
914 #content div.box div.form div.fields div.field div.textarea table {
914 #content div.box div.form div.fields div.field div.textarea table {
915 width:100%;
915 width:100%;
916 border:none;
916 border:none;
917 margin:0;
917 margin:0;
918 padding:0;
918 padding:0;
919 }
919 }
920
920
921 #content div.box div.form div.fields div.field div.textarea table td {
921 #content div.box div.form div.fields div.field div.textarea table td {
922 background:#DDD;
922 background:#DDD;
923 border:none;
923 border:none;
924 padding:0;
924 padding:0;
925 }
925 }
926
926
927 #content div.box div.form div.fields div.field div.textarea table td table {
927 #content div.box div.form div.fields div.field div.textarea table td table {
928 width:auto;
928 width:auto;
929 border:none;
929 border:none;
930 margin:0;
930 margin:0;
931 padding:0;
931 padding:0;
932 }
932 }
933
933
934 #content div.box div.form div.fields div.field div.textarea table td table td {
934 #content div.box div.form div.fields div.field div.textarea table td table td {
935 font-family:Lucida Grande, Verdana, Lucida Sans Regular, Lucida Sans Unicode, Arial, sans-serif;
935 font-family:Lucida Grande, Verdana, Lucida Sans Regular, Lucida Sans Unicode, Arial, sans-serif;
936 font-size:11px;
936 font-size:11px;
937 padding:5px 5px 5px 0;
937 padding:5px 5px 5px 0;
938 }
938 }
939
939
940 #content div.box div.form div.fields div.field div.textarea table td table td a.mceButtonActive {
940 #content div.box div.form div.fields div.field div.textarea table td table td a.mceButtonActive {
941 background:#b1b1b1;
941 background:#b1b1b1;
942 }
942 }
943
943
944 #content div.box div.form div.fields div.field div.select a.ui-selectmenu {
944 #content div.box div.form div.fields div.field div.select a.ui-selectmenu {
945 color:#565656;
945 color:#565656;
946 text-decoration:none;
946 text-decoration:none;
947 }
947 }
948
948
949 #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 {
949 #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 {
950 background:#f6f6f6;
950 background:#f6f6f6;
951 border-color:#666;
951 border-color:#666;
952 }
952 }
953
953
954 div.form div.fields div.field div.button {
954 div.form div.fields div.field div.button {
955 margin:0;
955 margin:0;
956 padding:0 0 0 8px;
956 padding:0 0 0 8px;
957 }
957 }
958
958
959 div.form div.fields div.field div.highlight .ui-state-default {
959 div.form div.fields div.field div.highlight .ui-state-default {
960 background:#4e85bb url("../images/button_highlight.png") repeat-x;
960 background:#4e85bb url("../images/button_highlight.png") repeat-x;
961 border-top:1px solid #5c91a4;
961 border-top:1px solid #5c91a4;
962 border-left:1px solid #2a6f89;
962 border-left:1px solid #2a6f89;
963 border-right:1px solid #2b7089;
963 border-right:1px solid #2b7089;
964 border-bottom:1px solid #1a6480;
964 border-bottom:1px solid #1a6480;
965 color:#FFF;
965 color:#FFF;
966 margin:0;
966 margin:0;
967 padding:6px 12px;
967 padding:6px 12px;
968 }
968 }
969
969
970 div.form div.fields div.field div.highlight .ui-state-hover {
970 div.form div.fields div.field div.highlight .ui-state-hover {
971 background:#46a0c1 url("../images/button_highlight_selected.png") repeat-x;
971 background:#46a0c1 url("../images/button_highlight_selected.png") repeat-x;
972 border-top:1px solid #78acbf;
972 border-top:1px solid #78acbf;
973 border-left:1px solid #34819e;
973 border-left:1px solid #34819e;
974 border-right:1px solid #35829f;
974 border-right:1px solid #35829f;
975 border-bottom:1px solid #257897;
975 border-bottom:1px solid #257897;
976 color:#FFF;
976 color:#FFF;
977 margin:0;
977 margin:0;
978 padding:6px 12px;
978 padding:6px 12px;
979 }
979 }
980
980
981 #content div.box div.form div.fields div.buttons div.highlight input.ui-state-default {
981 #content div.box div.form div.fields div.buttons div.highlight input.ui-state-default {
982 background:#4e85bb url("../../images/button_highlight.png") repeat-x;
982 background:#4e85bb url("../../images/button_highlight.png") repeat-x;
983 border-top:1px solid #5c91a4;
983 border-top:1px solid #5c91a4;
984 border-left:1px solid #2a6f89;
984 border-left:1px solid #2a6f89;
985 border-right:1px solid #2b7089;
985 border-right:1px solid #2b7089;
986 border-bottom:1px solid #1a6480;
986 border-bottom:1px solid #1a6480;
987 color:#fff;
987 color:#fff;
988 margin:0;
988 margin:0;
989 padding:6px 12px;
989 padding:6px 12px;
990 }
990 }
991
991
992 #content div.box div.form div.fields div.buttons div.highlight input.ui-state-hover {
992 #content div.box div.form div.fields div.buttons div.highlight input.ui-state-hover {
993 background:#46a0c1 url("../../images/button_highlight_selected.png") repeat-x;
993 background:#46a0c1 url("../../images/button_highlight_selected.png") repeat-x;
994 border-top:1px solid #78acbf;
994 border-top:1px solid #78acbf;
995 border-left:1px solid #34819e;
995 border-left:1px solid #34819e;
996 border-right:1px solid #35829f;
996 border-right:1px solid #35829f;
997 border-bottom:1px solid #257897;
997 border-bottom:1px solid #257897;
998 color:#fff;
998 color:#fff;
999 margin:0;
999 margin:0;
1000 padding:6px 12px;
1000 padding:6px 12px;
1001 }
1001 }
1002
1002
1003 #content div.box table {
1003 #content div.box table {
1004 width:100%;
1004 width:100%;
1005 border-collapse:collapse;
1005 border-collapse:collapse;
1006 margin:0;
1006 margin:0;
1007 padding:0;
1007 padding:0;
1008 }
1008 }
1009
1009
1010 #content div.box table th {
1010 #content div.box table th {
1011 background:#eee;
1011 background:#eee;
1012 border-bottom:1px solid #ddd;
1012 border-bottom:1px solid #ddd;
1013 padding:10px;
1013 padding:5px 0px 5px 5px;
1014 }
1014 }
1015
1015
1016 #content div.box table th.left {
1016 #content div.box table th.left {
1017 text-align:left;
1017 text-align:left;
1018 }
1018 }
1019
1019
1020 #content div.box table th.right {
1020 #content div.box table th.right {
1021 text-align:right;
1021 text-align:right;
1022 }
1022 }
1023
1023
1024 #content div.box table th.center {
1024 #content div.box table th.center {
1025 text-align:center;
1025 text-align:center;
1026 }
1026 }
1027
1027
1028 #content div.box table th.selected {
1028 #content div.box table th.selected {
1029 vertical-align:middle;
1029 vertical-align:middle;
1030 padding:0;
1030 padding:0;
1031 }
1031 }
1032
1032
1033 #content div.box table td {
1033 #content div.box table td {
1034 background:#fff;
1034 background:#fff;
1035 border-bottom:1px solid #cdcdcd;
1035 border-bottom:1px solid #cdcdcd;
1036 vertical-align:middle;
1036 vertical-align:middle;
1037 padding:5px;
1037 padding:5px;
1038 }
1038 }
1039
1039
1040 #content div.box table tr.selected td {
1040 #content div.box table tr.selected td {
1041 background:#FFC;
1041 background:#FFC;
1042 }
1042 }
1043
1043
1044 #content div.box table td.selected {
1044 #content div.box table td.selected {
1045 width:3%;
1045 width:3%;
1046 text-align:center;
1046 text-align:center;
1047 vertical-align:middle;
1047 vertical-align:middle;
1048 padding:0;
1048 padding:0;
1049 }
1049 }
1050
1050
1051 #content div.box table td.action {
1051 #content div.box table td.action {
1052 width:45%;
1052 width:45%;
1053 text-align:left;
1053 text-align:left;
1054 }
1054 }
1055
1055
1056 #content div.box table td.date {
1056 #content div.box table td.date {
1057 width:33%;
1057 width:33%;
1058 text-align:center;
1058 text-align:center;
1059 }
1059 }
1060
1060
1061 #content div.box div.action {
1061 #content div.box div.action {
1062 float:right;
1062 float:right;
1063 background:#FFF;
1063 background:#FFF;
1064 text-align:right;
1064 text-align:right;
1065 margin:10px 0 0;
1065 margin:10px 0 0;
1066 padding:0;
1066 padding:0;
1067 }
1067 }
1068
1068
1069 #content div.box div.action select {
1069 #content div.box div.action select {
1070 font-family:Lucida Grande, Verdana, Lucida Sans Regular, Lucida Sans Unicode, Arial, sans-serif;
1070 font-family:Lucida Grande, Verdana, Lucida Sans Regular, Lucida Sans Unicode, Arial, sans-serif;
1071 font-size:11px;
1071 font-size:11px;
1072 margin:0;
1072 margin:0;
1073 }
1073 }
1074
1074
1075 #content div.box div.action .ui-selectmenu {
1075 #content div.box div.action .ui-selectmenu {
1076 margin:0;
1076 margin:0;
1077 padding:0;
1077 padding:0;
1078 }
1078 }
1079
1079
1080 #content div.box div.pagination {
1080 #content div.box div.pagination {
1081 height:1%;
1081 height:1%;
1082 clear:both;
1082 clear:both;
1083 overflow:hidden;
1083 overflow:hidden;
1084 margin:10px 0 0;
1084 margin:10px 0 0;
1085 padding:0;
1085 padding:0;
1086 }
1086 }
1087
1087
1088 #content div.box div.pagination ul.pager {
1088 #content div.box div.pagination ul.pager {
1089 float:right;
1089 float:right;
1090 text-align:right;
1090 text-align:right;
1091 margin:0;
1091 margin:0;
1092 padding:0;
1092 padding:0;
1093 }
1093 }
1094
1094
1095 #content div.box div.pagination ul.pager li {
1095 #content div.box div.pagination ul.pager li {
1096 height:1%;
1096 height:1%;
1097 float:left;
1097 float:left;
1098 list-style:none;
1098 list-style:none;
1099 background:#ebebeb url("../images/pager.png") repeat-x;
1099 background:#ebebeb url("../images/pager.png") repeat-x;
1100 border-top:1px solid #dedede;
1100 border-top:1px solid #dedede;
1101 border-left:1px solid #cfcfcf;
1101 border-left:1px solid #cfcfcf;
1102 border-right:1px solid #c4c4c4;
1102 border-right:1px solid #c4c4c4;
1103 border-bottom:1px solid #c4c4c4;
1103 border-bottom:1px solid #c4c4c4;
1104 color:#4A4A4A;
1104 color:#4A4A4A;
1105 font-weight:700;
1105 font-weight:700;
1106 margin:0 0 0 4px;
1106 margin:0 0 0 4px;
1107 padding:0;
1107 padding:0;
1108 }
1108 }
1109
1109
1110 #content div.box div.pagination ul.pager li.separator {
1110 #content div.box div.pagination ul.pager li.separator {
1111 padding:6px;
1111 padding:6px;
1112 }
1112 }
1113
1113
1114 #content div.box div.pagination ul.pager li.current {
1114 #content div.box div.pagination ul.pager li.current {
1115 background:#b4b4b4 url("../images/pager_selected.png") repeat-x;
1115 background:#b4b4b4 url("../images/pager_selected.png") repeat-x;
1116 border-top:1px solid #ccc;
1116 border-top:1px solid #ccc;
1117 border-left:1px solid #bebebe;
1117 border-left:1px solid #bebebe;
1118 border-right:1px solid #b1b1b1;
1118 border-right:1px solid #b1b1b1;
1119 border-bottom:1px solid #afafaf;
1119 border-bottom:1px solid #afafaf;
1120 color:#515151;
1120 color:#515151;
1121 padding:6px;
1121 padding:6px;
1122 }
1122 }
1123
1123
1124 #content div.box div.pagination ul.pager li a {
1124 #content div.box div.pagination ul.pager li a {
1125 height:1%;
1125 height:1%;
1126 display:block;
1126 display:block;
1127 float:left;
1127 float:left;
1128 color:#515151;
1128 color:#515151;
1129 text-decoration:none;
1129 text-decoration:none;
1130 margin:0;
1130 margin:0;
1131 padding:6px;
1131 padding:6px;
1132 }
1132 }
1133
1133
1134 #content div.box div.pagination ul.pager li a:hover,#content div.box div.pagination ul.pager li a:active {
1134 #content div.box div.pagination ul.pager li a:hover,#content div.box div.pagination ul.pager li a:active {
1135 background:#b4b4b4 url("../images/pager_selected.png") repeat-x;
1135 background:#b4b4b4 url("../images/pager_selected.png") repeat-x;
1136 border-top:1px solid #ccc;
1136 border-top:1px solid #ccc;
1137 border-left:1px solid #bebebe;
1137 border-left:1px solid #bebebe;
1138 border-right:1px solid #b1b1b1;
1138 border-right:1px solid #b1b1b1;
1139 border-bottom:1px solid #afafaf;
1139 border-bottom:1px solid #afafaf;
1140 margin:-1px;
1140 margin:-1px;
1141 }
1141 }
1142
1142
1143 #content div.box div.pagination-wh {
1143 #content div.box div.pagination-wh {
1144 height:1%;
1144 height:1%;
1145 clear:both;
1145 clear:both;
1146 overflow:hidden;
1146 overflow:hidden;
1147 text-align:right;
1147 text-align:right;
1148 margin:10px 0 0;
1148 margin:10px 0 0;
1149 padding:0;
1149 padding:0;
1150 }
1150 }
1151
1151
1152 #content div.box div.pagination-right {
1152 #content div.box div.pagination-right {
1153 float:right;
1153 float:right;
1154 }
1154 }
1155
1155
1156 #content div.box div.pagination-wh a,#content div.box div.pagination-wh span.pager_dotdot {
1156 #content div.box div.pagination-wh a,#content div.box div.pagination-wh span.pager_dotdot {
1157 height:1%;
1157 height:1%;
1158 float:left;
1158 float:left;
1159 background:#ebebeb url("../images/pager.png") repeat-x;
1159 background:#ebebeb url("../images/pager.png") repeat-x;
1160 border-top:1px solid #dedede;
1160 border-top:1px solid #dedede;
1161 border-left:1px solid #cfcfcf;
1161 border-left:1px solid #cfcfcf;
1162 border-right:1px solid #c4c4c4;
1162 border-right:1px solid #c4c4c4;
1163 border-bottom:1px solid #c4c4c4;
1163 border-bottom:1px solid #c4c4c4;
1164 color:#4A4A4A;
1164 color:#4A4A4A;
1165 font-weight:700;
1165 font-weight:700;
1166 margin:0 0 0 4px;
1166 margin:0 0 0 4px;
1167 padding:6px;
1167 padding:6px;
1168 }
1168 }
1169
1169
1170 #content div.box div.pagination-wh span.pager_curpage {
1170 #content div.box div.pagination-wh span.pager_curpage {
1171 height:1%;
1171 height:1%;
1172 float:left;
1172 float:left;
1173 background:#b4b4b4 url("../images/pager_selected.png") repeat-x;
1173 background:#b4b4b4 url("../images/pager_selected.png") repeat-x;
1174 border-top:1px solid #ccc;
1174 border-top:1px solid #ccc;
1175 border-left:1px solid #bebebe;
1175 border-left:1px solid #bebebe;
1176 border-right:1px solid #b1b1b1;
1176 border-right:1px solid #b1b1b1;
1177 border-bottom:1px solid #afafaf;
1177 border-bottom:1px solid #afafaf;
1178 color:#515151;
1178 color:#515151;
1179 font-weight:700;
1179 font-weight:700;
1180 margin:0 0 0 4px;
1180 margin:0 0 0 4px;
1181 padding:6px;
1181 padding:6px;
1182 }
1182 }
1183
1183
1184 #content div.box div.pagination-wh a:hover,#content div.box div.pagination-wh a:active {
1184 #content div.box div.pagination-wh a:hover,#content div.box div.pagination-wh a:active {
1185 background:#b4b4b4 url("../images/pager_selected.png") repeat-x;
1185 background:#b4b4b4 url("../images/pager_selected.png") repeat-x;
1186 border-top:1px solid #ccc;
1186 border-top:1px solid #ccc;
1187 border-left:1px solid #bebebe;
1187 border-left:1px solid #bebebe;
1188 border-right:1px solid #b1b1b1;
1188 border-right:1px solid #b1b1b1;
1189 border-bottom:1px solid #afafaf;
1189 border-bottom:1px solid #afafaf;
1190 text-decoration:none;
1190 text-decoration:none;
1191 }
1191 }
1192
1192
1193 #content div.box div.traffic div.legend {
1193 #content div.box div.traffic div.legend {
1194 clear:both;
1194 clear:both;
1195 overflow:hidden;
1195 overflow:hidden;
1196 border-bottom:1px solid #ddd;
1196 border-bottom:1px solid #ddd;
1197 margin:0 0 10px;
1197 margin:0 0 10px;
1198 padding:0 0 10px;
1198 padding:0 0 10px;
1199 }
1199 }
1200
1200
1201 #content div.box div.traffic div.legend h6 {
1201 #content div.box div.traffic div.legend h6 {
1202 float:left;
1202 float:left;
1203 border:none;
1203 border:none;
1204 margin:0;
1204 margin:0;
1205 padding:0;
1205 padding:0;
1206 }
1206 }
1207
1207
1208 #content div.box div.traffic div.legend li {
1208 #content div.box div.traffic div.legend li {
1209 list-style:none;
1209 list-style:none;
1210 float:left;
1210 float:left;
1211 font-size:11px;
1211 font-size:11px;
1212 margin:0;
1212 margin:0;
1213 padding:0 8px 0 4px;
1213 padding:0 8px 0 4px;
1214 }
1214 }
1215
1215
1216 #content div.box div.traffic div.legend li.visits {
1216 #content div.box div.traffic div.legend li.visits {
1217 border-left:12px solid #edc240;
1217 border-left:12px solid #edc240;
1218 }
1218 }
1219
1219
1220 #content div.box div.traffic div.legend li.pageviews {
1220 #content div.box div.traffic div.legend li.pageviews {
1221 border-left:12px solid #afd8f8;
1221 border-left:12px solid #afd8f8;
1222 }
1222 }
1223
1223
1224 #content div.box div.traffic table {
1224 #content div.box div.traffic table {
1225 width:auto;
1225 width:auto;
1226 }
1226 }
1227
1227
1228 #content div.box div.traffic table td {
1228 #content div.box div.traffic table td {
1229 background:transparent;
1229 background:transparent;
1230 border:none;
1230 border:none;
1231 padding:2px 3px 3px;
1231 padding:2px 3px 3px;
1232 }
1232 }
1233
1233
1234 #content div.box div.traffic table td.legendLabel {
1234 #content div.box div.traffic table td.legendLabel {
1235 padding:0 3px 2px;
1235 padding:0 3px 2px;
1236 }
1236 }
1237
1237
1238 #footer {
1238 #footer {
1239 clear:both;
1239 clear:both;
1240 overflow:hidden;
1240 overflow:hidden;
1241 text-align:right;
1241 text-align:right;
1242 margin:0;
1242 margin:0;
1243 padding:0 30px 4px;
1243 padding:0 30px 4px;
1244 margin:-10px 0 0;
1244 margin:-10px 0 0;
1245 }
1245 }
1246
1246
1247 #footer div#footer-inner {
1247 #footer div#footer-inner {
1248 background:url("../images/header_inner.png") repeat-x scroll 0 0 #003367;
1248 background:url("../images/header_inner.png") repeat-x scroll 0 0 #003367;
1249 border-top:2px solid #FFFFFF;
1249 border-top:2px solid #FFFFFF;
1250 }
1250 }
1251
1251
1252 #footer div#footer-inner p {
1252 #footer div#footer-inner p {
1253 padding:15px 25px 15px 0;
1253 padding:15px 25px 15px 0;
1254 color:#FFF;
1254 color:#FFF;
1255 font-weight:700;
1255 font-weight:700;
1256 }
1256 }
1257 #footer div#footer-inner .footer-link {
1257 #footer div#footer-inner .footer-link {
1258 float:left;
1258 float:left;
1259 padding-left:10px;
1259 padding-left:10px;
1260 }
1260 }
1261 #footer div#footer-inner .footer-link a {
1261 #footer div#footer-inner .footer-link a {
1262 color:#FFF;
1262 color:#FFF;
1263 }
1263 }
1264
1264
1265 #login div.title {
1265 #login div.title {
1266 width:420px;
1266 width:420px;
1267 clear:both;
1267 clear:both;
1268 overflow:hidden;
1268 overflow:hidden;
1269 position:relative;
1269 position:relative;
1270 background:#003367 url("../../images/header_inner.png") repeat-x;
1270 background:#003367 url("../../images/header_inner.png") repeat-x;
1271 margin:0 auto;
1271 margin:0 auto;
1272 padding:0;
1272 padding:0;
1273 }
1273 }
1274
1274
1275 #login div.inner {
1275 #login div.inner {
1276 width:380px;
1276 width:380px;
1277 background:#FFF url("../images/login.png") no-repeat top left;
1277 background:#FFF url("../images/login.png") no-repeat top left;
1278 border-top:none;
1278 border-top:none;
1279 border-bottom:none;
1279 border-bottom:none;
1280 margin:0 auto;
1280 margin:0 auto;
1281 padding:20px;
1281 padding:20px;
1282 }
1282 }
1283
1283
1284 #login div.form div.fields div.field div.label {
1284 #login div.form div.fields div.field div.label {
1285 width:173px;
1285 width:173px;
1286 float:left;
1286 float:left;
1287 text-align:right;
1287 text-align:right;
1288 margin:2px 10px 0 0;
1288 margin:2px 10px 0 0;
1289 padding:5px 0 0 5px;
1289 padding:5px 0 0 5px;
1290 }
1290 }
1291
1291
1292 #login div.form div.fields div.field div.input input {
1292 #login div.form div.fields div.field div.input input {
1293 width:176px;
1293 width:176px;
1294 background:#FFF;
1294 background:#FFF;
1295 border-top:1px solid #b3b3b3;
1295 border-top:1px solid #b3b3b3;
1296 border-left:1px solid #b3b3b3;
1296 border-left:1px solid #b3b3b3;
1297 border-right:1px solid #eaeaea;
1297 border-right:1px solid #eaeaea;
1298 border-bottom:1px solid #eaeaea;
1298 border-bottom:1px solid #eaeaea;
1299 color:#000;
1299 color:#000;
1300 font-family:Lucida Grande, Verdana, Lucida Sans Regular, Lucida Sans Unicode, Arial, sans-serif;
1300 font-family:Lucida Grande, Verdana, Lucida Sans Regular, Lucida Sans Unicode, Arial, sans-serif;
1301 font-size:11px;
1301 font-size:11px;
1302 margin:0;
1302 margin:0;
1303 padding:7px 7px 6px;
1303 padding:7px 7px 6px;
1304 }
1304 }
1305
1305
1306 #login div.form div.fields div.buttons {
1306 #login div.form div.fields div.buttons {
1307 clear:both;
1307 clear:both;
1308 overflow:hidden;
1308 overflow:hidden;
1309 border-top:1px solid #DDD;
1309 border-top:1px solid #DDD;
1310 text-align:right;
1310 text-align:right;
1311 margin:0;
1311 margin:0;
1312 padding:10px 0 0;
1312 padding:10px 0 0;
1313 }
1313 }
1314
1314
1315 #login div.form div.links {
1315 #login div.form div.links {
1316 clear:both;
1316 clear:both;
1317 overflow:hidden;
1317 overflow:hidden;
1318 margin:10px 0 0;
1318 margin:10px 0 0;
1319 padding:0 0 2px;
1319 padding:0 0 2px;
1320 }
1320 }
1321
1321
1322 #register div.title {
1322 #register div.title {
1323 width:420px;
1323 width:420px;
1324 clear:both;
1324 clear:both;
1325 overflow:hidden;
1325 overflow:hidden;
1326 position:relative;
1326 position:relative;
1327 background:#003367 url("../images/header_inner.png") repeat-x;
1327 background:#003367 url("../images/header_inner.png") repeat-x;
1328 margin:0 auto;
1328 margin:0 auto;
1329 padding:0;
1329 padding:0;
1330 }
1330 }
1331
1331
1332 #register div.inner {
1332 #register div.inner {
1333 width:380px;
1333 width:380px;
1334 background:#FFF;
1334 background:#FFF;
1335 border-top:none;
1335 border-top:none;
1336 border-bottom:none;
1336 border-bottom:none;
1337 margin:0 auto;
1337 margin:0 auto;
1338 padding:20px;
1338 padding:20px;
1339 }
1339 }
1340
1340
1341 #register div.form div.fields div.field div.label {
1341 #register div.form div.fields div.field div.label {
1342 width:100px;
1342 width:100px;
1343 float:left;
1343 float:left;
1344 text-align:right;
1344 text-align:right;
1345 margin:2px 10px 0 0;
1345 margin:2px 10px 0 0;
1346 padding:5px 0 0 5px;
1346 padding:5px 0 0 5px;
1347 }
1347 }
1348
1348
1349 #register div.form div.fields div.field div.input input {
1349 #register div.form div.fields div.field div.input input {
1350 width:245px;
1350 width:245px;
1351 background:#FFF;
1351 background:#FFF;
1352 border-top:1px solid #b3b3b3;
1352 border-top:1px solid #b3b3b3;
1353 border-left:1px solid #b3b3b3;
1353 border-left:1px solid #b3b3b3;
1354 border-right:1px solid #eaeaea;
1354 border-right:1px solid #eaeaea;
1355 border-bottom:1px solid #eaeaea;
1355 border-bottom:1px solid #eaeaea;
1356 color:#000;
1356 color:#000;
1357 font-family:Lucida Grande, Verdana, Lucida Sans Regular, Lucida Sans Unicode, Arial, sans-serif;
1357 font-family:Lucida Grande, Verdana, Lucida Sans Regular, Lucida Sans Unicode, Arial, sans-serif;
1358 font-size:11px;
1358 font-size:11px;
1359 margin:0;
1359 margin:0;
1360 padding:7px 7px 6px;
1360 padding:7px 7px 6px;
1361 }
1361 }
1362
1362
1363 #register div.form div.fields div.buttons {
1363 #register div.form div.fields div.buttons {
1364 clear:both;
1364 clear:both;
1365 overflow:hidden;
1365 overflow:hidden;
1366 border-top:1px solid #DDD;
1366 border-top:1px solid #DDD;
1367 text-align:left;
1367 text-align:left;
1368 margin:0;
1368 margin:0;
1369 padding:10px 0 0 114px;
1369 padding:10px 0 0 114px;
1370 }
1370 }
1371
1371
1372 #register div.form div.fields div.buttons div.highlight input.ui-state-default {
1372 #register div.form div.fields div.buttons div.highlight input.ui-state-default {
1373 background:url("../images/button_highlight.png") repeat-x scroll 0 0 #4E85BB;
1373 background:url("../images/button_highlight.png") repeat-x scroll 0 0 #4E85BB;
1374 color:#FFF;
1374 color:#FFF;
1375 border-color:#5C91A4 #2B7089 #1A6480 #2A6F89;
1375 border-color:#5C91A4 #2B7089 #1A6480 #2A6F89;
1376 border-style:solid;
1376 border-style:solid;
1377 border-width:1px;
1377 border-width:1px;
1378 }
1378 }
1379
1379
1380 #register div.form div.activation_msg {
1380 #register div.form div.activation_msg {
1381 padding-top:4px;
1381 padding-top:4px;
1382 padding-bottom:4px;
1382 padding-bottom:4px;
1383 }
1383 }
1384
1384
1385 .trending_language_tbl,.trending_language_tbl td {
1385 .trending_language_tbl,.trending_language_tbl td {
1386 border:0 !important;
1386 border:0 !important;
1387 margin:0 !important;
1387 margin:0 !important;
1388 padding:0 !important;
1388 padding:0 !important;
1389 }
1389 }
1390
1390
1391 .trending_language {
1391 .trending_language {
1392 background-color:#003367;
1392 background-color:#003367;
1393 color:#FFF;
1393 color:#FFF;
1394 display:block;
1394 display:block;
1395 min-width:20px;
1395 min-width:20px;
1396 max-width:400px;
1397 text-decoration:none;
1396 text-decoration:none;
1398 height:12px;
1397 height:12px;
1399 margin-bottom:4px;
1398 margin-bottom:4px;
1400 margin-left:5px;
1399 margin-left:5px;
1401 white-space:pre;
1400 white-space:pre;
1402 padding:3px;
1401 padding:3px;
1403 }
1402 }
1404
1403
1405 h3.files_location {
1404 h3.files_location {
1406 font-size:1.8em;
1405 font-size:1.8em;
1407 font-weight:700;
1406 font-weight:700;
1408 border-bottom:none !important;
1407 border-bottom:none !important;
1409 margin:10px 0 !important;
1408 margin:10px 0 !important;
1410 }
1409 }
1411
1410
1412 #files_data dl dt {
1411 #files_data dl dt {
1413 float:left;
1412 float:left;
1414 width:115px;
1413 width:115px;
1415 margin:0 !important;
1414 margin:0 !important;
1416 padding:5px;
1415 padding:5px;
1417 }
1416 }
1418
1417
1419 #files_data dl dd {
1418 #files_data dl dd {
1420 margin:0 !important;
1419 margin:0 !important;
1421 padding:5px !important;
1420 padding:5px !important;
1422 }
1421 }
1423
1422
1424 #changeset_content {
1423 #changeset_content {
1425 border:1px solid #CCC;
1424 border:1px solid #CCC;
1426 padding:5px;
1425 padding:5px;
1427 }
1426 }
1428
1427
1429 #changeset_content .container {
1428 #changeset_content .container {
1430 min-height:120px;
1429 min-height:120px;
1431 font-size:1.2em;
1430 font-size:1.2em;
1432 overflow:hidden;
1431 overflow:hidden;
1433 }
1432 }
1434
1433
1435 #changeset_content .container .right {
1434 #changeset_content .container .right {
1436 float:right;
1435 float:right;
1437 width:25%;
1436 width:25%;
1438 text-align:right;
1437 text-align:right;
1439 }
1438 }
1440
1439
1441 #changeset_content .container .left .message {
1440 #changeset_content .container .left .message {
1442 font-style:italic;
1441 font-style:italic;
1443 color:#556CB5;
1442 color:#556CB5;
1444 white-space:pre-wrap;
1443 white-space:pre-wrap;
1445 }
1444 }
1446
1445
1447 .cs_files .cs_added {
1446 .cs_files .cs_added {
1448 background:url("../images/icons/page_white_add.png") no-repeat scroll 3px;
1447 background:url("../images/icons/page_white_add.png") no-repeat scroll 3px;
1449 height:16px;
1448 height:16px;
1450 padding-left:20px;
1449 padding-left:20px;
1451 margin-top:7px;
1450 margin-top:7px;
1452 text-align:left;
1451 text-align:left;
1453 }
1452 }
1454
1453
1455 .cs_files .cs_changed {
1454 .cs_files .cs_changed {
1456 background:url("../images/icons/page_white_edit.png") no-repeat scroll 3px;
1455 background:url("../images/icons/page_white_edit.png") no-repeat scroll 3px;
1457 height:16px;
1456 height:16px;
1458 padding-left:20px;
1457 padding-left:20px;
1459 margin-top:7px;
1458 margin-top:7px;
1460 text-align:left;
1459 text-align:left;
1461 }
1460 }
1462
1461
1463 .cs_files .cs_removed {
1462 .cs_files .cs_removed {
1464 background:url("../images/icons/page_white_delete.png") no-repeat scroll 3px;
1463 background:url("../images/icons/page_white_delete.png") no-repeat scroll 3px;
1465 height:16px;
1464 height:16px;
1466 padding-left:20px;
1465 padding-left:20px;
1467 margin-top:7px;
1466 margin-top:7px;
1468 text-align:left;
1467 text-align:left;
1469 }
1468 }
1470
1469
1471 #graph {
1470 #graph {
1472 overflow:hidden;
1471 overflow:hidden;
1473 }
1472 }
1474
1473
1475 #graph_nodes {
1474 #graph_nodes {
1476 width:160px;
1475 width:160px;
1477 float:left;
1476 float:left;
1478 margin-left:-50px;
1477 margin-left:-50px;
1479 margin-top:5px;
1478 margin-top:5px;
1480 }
1479 }
1481
1480
1482 #graph_content {
1481 #graph_content {
1483 width:800px;
1482 width:800px;
1484 float:left;
1483 float:left;
1485 }
1484 }
1486
1485
1487 #graph_content .container_header {
1486 #graph_content .container_header {
1488 border:1px solid #CCC;
1487 border:1px solid #CCC;
1489 padding:10px;
1488 padding:10px;
1490 }
1489 }
1491
1490
1492 #graph_content .container {
1491 #graph_content .container {
1493 border-bottom:1px solid #CCC;
1492 border-bottom:1px solid #CCC;
1494 border-left:1px solid #CCC;
1493 border-left:1px solid #CCC;
1495 border-right:1px solid #CCC;
1494 border-right:1px solid #CCC;
1496 min-height:80px;
1495 min-height:80px;
1497 overflow:hidden;
1496 overflow:hidden;
1498 font-size:1.2em;
1497 font-size:1.2em;
1499 }
1498 }
1500
1499
1501 #graph_content .container .right {
1500 #graph_content .container .right {
1502 float:right;
1501 float:right;
1503 width:28%;
1502 width:28%;
1504 text-align:right;
1503 text-align:right;
1505 padding-bottom:5px;
1504 padding-bottom:5px;
1506 }
1505 }
1507
1506
1508 #graph_content .container .left .date {
1507 #graph_content .container .left .date {
1509 font-weight:700;
1508 font-weight:700;
1510 padding-bottom:5px;
1509 padding-bottom:5px;
1511 }
1510 }
1512
1511
1513 #graph_content .container .left .message {
1512 #graph_content .container .left .message {
1514 font-size:100%;
1513 font-size:100%;
1515 padding-top:3px;
1514 padding-top:3px;
1516 white-space:pre-wrap;
1515 white-space:pre-wrap;
1517 }
1516 }
1518
1517
1519 .right div {
1518 .right div {
1520 clear:both;
1519 clear:both;
1521 }
1520 }
1522
1521
1523 .right .changes .added,.changed,.removed {
1522 .right .changes .added,.changed,.removed {
1524 border:1px solid #DDD;
1523 border:1px solid #DDD;
1525 display:block;
1524 display:block;
1526 float:right;
1525 float:right;
1527 text-align:center;
1526 text-align:center;
1528 min-width:15px;
1527 min-width:15px;
1529 }
1528 }
1530
1529
1531 .right .changes .added {
1530 .right .changes .added {
1532 background:#BFB;
1531 background:#BFB;
1533 }
1532 }
1534
1533
1535 .right .changes .changed {
1534 .right .changes .changed {
1536 background:#FD8;
1535 background:#FD8;
1537 }
1536 }
1538
1537
1539 .right .changes .removed {
1538 .right .changes .removed {
1540 background:#F88;
1539 background:#F88;
1541 }
1540 }
1542
1541
1543 .right .merge {
1542 .right .merge {
1544 vertical-align:top;
1543 vertical-align:top;
1545 font-size:60%;
1544 font-size:0.75em;
1546 font-weight:700;
1545 font-weight:700;
1547 }
1546 }
1548
1547
1549 .right .parent {
1548 .right .parent {
1550 font-size:90%;
1549 font-size:90%;
1551 font-family:monospace;
1550 font-family:monospace;
1552 }
1551 }
1553
1552
1554 .right .logtags .branchtag {
1553 .right .logtags .branchtag {
1555 background:#FFF url("../images/icons/arrow_branch.png") no-repeat right 6px;
1554 background:#FFF url("../images/icons/arrow_branch.png") no-repeat right 6px;
1556 display:block;
1555 display:block;
1557 padding:8px 16px 0 0;
1556 font-size:0.8em;
1557 padding:11px 16px 0 0;
1558 }
1558 }
1559
1559
1560 .right .logtags .tagtag {
1560 .right .logtags .tagtag {
1561 background:#FFF url("../images/icons/tag_blue.png") no-repeat right 6px;
1561 background:#FFF url("../images/icons/tag_blue.png") no-repeat right 6px;
1562 display:block;
1562 display:block;
1563 padding:6px 18px 0 0;
1563 font-size:0.8em;
1564 padding:11px 16px 0 0;
1564 }
1565 }
1565
1566
1566 div.browserblock {
1567 div.browserblock {
1567 overflow:hidden;
1568 overflow:hidden;
1568 border:1px solid #ccc;
1569 border:1px solid #ccc;
1569 background:#f8f8f8;
1570 background:#f8f8f8;
1570 font-size:100%;
1571 font-size:100%;
1571 line-height:125%;
1572 line-height:125%;
1572 padding:0;
1573 padding:0;
1573 }
1574 }
1574
1575
1575 div.browserblock .browser-header {
1576 div.browserblock .browser-header {
1576 border-bottom:1px solid #CCC;
1577 border-bottom:1px solid #CCC;
1577 background:#FFF;
1578 background:#FFF;
1578 color:blue;
1579 color:blue;
1579 padding:10px 0;
1580 padding:10px 0;
1580 }
1581 }
1581
1582
1582 div.browserblock .browser-header span {
1583 div.browserblock .browser-header span {
1583 margin-left:25px;
1584 margin-left:25px;
1584 font-weight:700;
1585 font-weight:700;
1585 }
1586 }
1586
1587
1587 div.browserblock .browser-body {
1588 div.browserblock .browser-body {
1588 background:#EEE;
1589 background:#EEE;
1589 }
1590 }
1590
1591
1591 table.code-browser {
1592 table.code-browser {
1592 border-collapse:collapse;
1593 border-collapse:collapse;
1593 width:100%;
1594 width:100%;
1594 }
1595 }
1595
1596
1596 table.code-browser tr {
1597 table.code-browser tr {
1597 margin:3px;
1598 margin:3px;
1598 }
1599 }
1599
1600
1600 table.code-browser thead th {
1601 table.code-browser thead th {
1601 background-color:#EEE;
1602 background-color:#EEE;
1602 height:20px;
1603 height:20px;
1603 font-size:1.1em;
1604 font-size:1.1em;
1604 font-weight:700;
1605 font-weight:700;
1605 text-align:left;
1606 text-align:left;
1606 padding-left:10px;
1607 padding-left:10px;
1607 }
1608 }
1608
1609
1609 table.code-browser tbody td {
1610 table.code-browser tbody td {
1610 padding-left:10px;
1611 padding-left:10px;
1611 height:20px;
1612 height:20px;
1612 }
1613 }
1613
1614
1614 table.code-browser .browser-file {
1615 table.code-browser .browser-file {
1615 background:url("../images/icons/document_16.png") no-repeat scroll 3px;
1616 background:url("../images/icons/document_16.png") no-repeat scroll 3px;
1616 height:16px;
1617 height:16px;
1617 padding-left:20px;
1618 padding-left:20px;
1618 text-align:left;
1619 text-align:left;
1619 }
1620 }
1620
1621
1621 table.code-browser .browser-dir {
1622 table.code-browser .browser-dir {
1622 background:url("../images/icons/folder_16.png") no-repeat scroll 3px;
1623 background:url("../images/icons/folder_16.png") no-repeat scroll 3px;
1623 height:16px;
1624 height:16px;
1624 padding-left:20px;
1625 padding-left:20px;
1625 text-align:left;
1626 text-align:left;
1626 }
1627 }
1627
1628
1628 .box .search {
1629 .box .search {
1629 clear:both;
1630 clear:both;
1630 overflow:hidden;
1631 overflow:hidden;
1631 margin:0;
1632 margin:0;
1632 padding:0 20px 10px;
1633 padding:0 20px 10px;
1633 }
1634 }
1634
1635
1635 .box .search div.search_path {
1636 .box .search div.search_path {
1636 background:none repeat scroll 0 0 #EEE;
1637 background:none repeat scroll 0 0 #EEE;
1637 border:1px solid #CCC;
1638 border:1px solid #CCC;
1638 color:blue;
1639 color:blue;
1639 margin-bottom:10px;
1640 margin-bottom:10px;
1640 padding:10px 0;
1641 padding:10px 0;
1641 }
1642 }
1642
1643
1643 .box .search div.search_path div.link {
1644 .box .search div.search_path div.link {
1644 font-weight:700;
1645 font-weight:700;
1645 margin-left:25px;
1646 margin-left:25px;
1646 }
1647 }
1647
1648
1648 .box .search div.search_path div.link a {
1649 .box .search div.search_path div.link a {
1649 color:#003367;
1650 color:#003367;
1650 cursor:pointer;
1651 cursor:pointer;
1651 text-decoration:none;
1652 text-decoration:none;
1652 }
1653 }
1653
1654
1654 #path_unlock {
1655 #path_unlock {
1655 color:red;
1656 color:red;
1656 font-size:1.2em;
1657 font-size:1.2em;
1657 padding-left:4px;
1658 padding-left:4px;
1658 }
1659 }
1659
1660
1660 .info_box * {
1661 .info_box * {
1661 background:url("../../images/pager.png") repeat-x scroll 0 0 #EBEBEB;
1662 background:url("../../images/pager.png") repeat-x scroll 0 0 #EBEBEB;
1662 color:#4A4A4A;
1663 color:#4A4A4A;
1663 font-weight:700;
1664 font-weight:700;
1664 height:1%;
1665 height:1%;
1665 display:inline;
1666 display:inline;
1666 border-color:#DEDEDE #C4C4C4 #C4C4C4 #CFCFCF;
1667 border-color:#DEDEDE #C4C4C4 #C4C4C4 #CFCFCF;
1667 border-style:solid;
1668 border-style:solid;
1668 border-width:1px;
1669 border-width:1px;
1669 padding:4px 6px;
1670 padding:4px 6px;
1670 }
1671 }
1671
1672
1672 .info_box span {
1673 .info_box span {
1673 margin-left:3px;
1674 margin-left:3px;
1674 margin-right:3px;
1675 margin-right:3px;
1675 }
1676 }
1676
1677
1677 .info_box input#at_rev {
1678 .info_box input#at_rev {
1678 text-align:center;
1679 text-align:center;
1679 padding:5px 3px 3px 2px;
1680 padding:5px 3px 3px 2px;
1680 }
1681 }
1681
1682
1682 .info_box input#view {
1683 .info_box input#view {
1683 text-align:center;
1684 text-align:center;
1684 padding:4px 3px 2px 2px;
1685 padding:4px 3px 2px 2px;
1685 }
1686 }
1686
1687
1687 .yui-overlay,.yui-panel-container {
1688 .yui-overlay,.yui-panel-container {
1688 visibility:hidden;
1689 visibility:hidden;
1689 position:absolute;
1690 position:absolute;
1690 z-index:2;
1691 z-index:2;
1691 }
1692 }
1692
1693
1693 .yui-tt {
1694 .yui-tt {
1694 visibility:hidden;
1695 visibility:hidden;
1695 position:absolute;
1696 position:absolute;
1696 color:#666;
1697 color:#666;
1697 background-color:#FFF;
1698 background-color:#FFF;
1698 font-family:arial, helvetica, verdana, sans-serif;
1699 font-family:arial, helvetica, verdana, sans-serif;
1699 border:2px solid #003367;
1700 border:2px solid #003367;
1700 font:100% sans-serif;
1701 font:100% sans-serif;
1701 width:auto;
1702 width:auto;
1702 opacity:1px;
1703 opacity:1px;
1703 padding:8px;
1704 padding:8px;
1705 white-space: pre;
1704 }
1706 }
1705
1707
1706 .ac {
1708 .ac {
1707 vertical-align:top;
1709 vertical-align:top;
1708 }
1710 }
1709
1711
1710 .ac .yui-ac {
1712 .ac .yui-ac {
1711 position:relative;
1713 position:relative;
1712 font-family:arial;
1714 font-family:arial;
1713 font-size:100%;
1715 font-size:100%;
1714 }
1716 }
1715
1717
1716 .ac .perm_ac {
1718 .ac .perm_ac {
1717 width:15em;
1719 width:15em;
1718 }
1720 }
1719
1721
1720 .ac .yui-ac-input {
1722 .ac .yui-ac-input {
1721 width:100%;
1723 width:100%;
1722 }
1724 }
1723
1725
1724 .ac .yui-ac-container {
1726 .ac .yui-ac-container {
1725 position:absolute;
1727 position:absolute;
1726 top:1.6em;
1728 top:1.6em;
1727 width:100%;
1729 width:100%;
1728 }
1730 }
1729
1731
1730 .ac .yui-ac-content {
1732 .ac .yui-ac-content {
1731 position:absolute;
1733 position:absolute;
1732 width:100%;
1734 width:100%;
1733 border:1px solid gray;
1735 border:1px solid gray;
1734 background:#fff;
1736 background:#fff;
1735 overflow:hidden;
1737 overflow:hidden;
1736 z-index:9050;
1738 z-index:9050;
1737 }
1739 }
1738
1740
1739 .ac .yui-ac-shadow {
1741 .ac .yui-ac-shadow {
1740 position:absolute;
1742 position:absolute;
1741 width:100%;
1743 width:100%;
1742 background:#000;
1744 background:#000;
1743 -moz-opacity:0.1px;
1745 -moz-opacity:0.1px;
1744 opacity:.10;
1746 opacity:.10;
1745 filter:alpha(opacity = 10);
1747 filter:alpha(opacity = 10);
1746 z-index:9049;
1748 z-index:9049;
1747 margin:.3em;
1749 margin:.3em;
1748 }
1750 }
1749
1751
1750 .ac .yui-ac-content ul {
1752 .ac .yui-ac-content ul {
1751 width:100%;
1753 width:100%;
1752 margin:0;
1754 margin:0;
1753 padding:0;
1755 padding:0;
1754 }
1756 }
1755
1757
1756 .ac .yui-ac-content li {
1758 .ac .yui-ac-content li {
1757 cursor:default;
1759 cursor:default;
1758 white-space:nowrap;
1760 white-space:nowrap;
1759 margin:0;
1761 margin:0;
1760 padding:2px 5px;
1762 padding:2px 5px;
1761 }
1763 }
1762
1764
1763 .ac .yui-ac-content li.yui-ac-prehighlight {
1765 .ac .yui-ac-content li.yui-ac-prehighlight {
1764 background:#B3D4FF;
1766 background:#B3D4FF;
1765 }
1767 }
1766
1768
1767 .ac .yui-ac-content li.yui-ac-highlight {
1769 .ac .yui-ac-content li.yui-ac-highlight {
1768 background:#556CB5;
1770 background:#556CB5;
1769 color:#FFF;
1771 color:#FFF;
1770 }
1772 }
1771
1773
1772 .add_icon {
1774 .add_icon {
1773 background:url("../images/icons/add.png") no-repeat scroll 3px;
1775 background:url("../images/icons/add.png") no-repeat scroll 3px;
1774 height:16px;
1776 height:16px;
1775 padding-left:20px;
1777 padding-left:20px;
1776 padding-top:1px;
1778 padding-top:1px;
1777 text-align:left;
1779 text-align:left;
1778 }
1780 }
1779
1781
1780 .edit_icon {
1782 .edit_icon {
1781 background:url("../images/icons/folder_edit.png") no-repeat scroll 3px;
1783 background:url("../images/icons/folder_edit.png") no-repeat scroll 3px;
1782 height:16px;
1784 height:16px;
1783 padding-left:20px;
1785 padding-left:20px;
1784 padding-top:1px;
1786 padding-top:1px;
1785 text-align:left;
1787 text-align:left;
1786 }
1788 }
1787
1789
1788 .delete_icon {
1790 .delete_icon {
1789 background:url("../images/icons/delete.png") no-repeat scroll 3px;
1791 background:url("../images/icons/delete.png") no-repeat scroll 3px;
1790 height:16px;
1792 height:16px;
1791 padding-left:20px;
1793 padding-left:20px;
1792 padding-top:1px;
1794 padding-top:1px;
1793 text-align:left;
1795 text-align:left;
1794 }
1796 }
1795
1797
1796 .rss_icon {
1798 .rss_icon {
1797 background:url("../images/icons/rss_16.png") no-repeat scroll 3px;
1799 background:url("../images/icons/rss_16.png") no-repeat scroll 3px;
1798 height:16px;
1800 height:16px;
1799 padding-left:20px;
1801 padding-left:20px;
1800 padding-top:1px;
1802 padding-top:1px;
1801 text-align:left;
1803 text-align:left;
1802 }
1804 }
1803
1805
1804 .atom_icon {
1806 .atom_icon {
1805 background:url("../images/icons/atom.png") no-repeat scroll 3px;
1807 background:url("../images/icons/atom.png") no-repeat scroll 3px;
1806 height:16px;
1808 height:16px;
1807 padding-left:20px;
1809 padding-left:20px;
1808 padding-top:1px;
1810 padding-top:1px;
1809 text-align:left;
1811 text-align:left;
1810 }
1812 }
1811
1813
1812 .archive_icon {
1814 .archive_icon {
1813 background:url("../images/icons/compress.png") no-repeat scroll 3px;
1815 background:url("../images/icons/compress.png") no-repeat scroll 3px;
1814 height:16px;
1816 height:16px;
1815 padding-left:20px;
1817 padding-left:20px;
1816 text-align:left;
1818 text-align:left;
1817 padding-top:1px;
1819 padding-top:1px;
1818 }
1820 }
1819
1821
1820 .action_button {
1822 .action_button {
1821 border:0;
1823 border:0;
1822 display:block;
1824 display:block;
1823 }
1825 }
1824
1826
1825 .action_button:hover {
1827 .action_button:hover {
1826 border:0;
1828 border:0;
1827 text-decoration:underline;
1829 text-decoration:underline;
1828 cursor:pointer;
1830 cursor:pointer;
1829 }
1831 }
1830
1832
1831 #switch_repos {
1833 #switch_repos {
1832 position:absolute;
1834 position:absolute;
1833 height:25px;
1835 height:25px;
1834 z-index:1;
1836 z-index:1;
1835 }
1837 }
1836
1838
1837 #switch_repos select {
1839 #switch_repos select {
1838 min-width:150px;
1840 min-width:150px;
1839 max-height:250px;
1841 max-height:250px;
1840 z-index:1;
1842 z-index:1;
1841 }
1843 }
1842
1844
1843 .breadcrumbs {
1845 .breadcrumbs {
1844 border:medium none;
1846 border:medium none;
1845 color:#FFF;
1847 color:#FFF;
1846 float:left;
1848 float:left;
1847 text-transform:uppercase;
1849 text-transform:uppercase;
1848 font-weight:700;
1850 font-weight:700;
1849 font-size:14px;
1851 font-size:14px;
1850 margin:0;
1852 margin:0;
1851 padding:11px 0 11px 10px;
1853 padding:11px 0 11px 10px;
1852 }
1854 }
1853
1855
1854 .breadcrumbs a {
1856 .breadcrumbs a {
1855 color:#FFF;
1857 color:#FFF;
1856 }
1858 }
1857
1859
1858 .flash_msg ul {
1860 .flash_msg ul {
1859 margin:0;
1861 margin:0;
1860 padding:0 0 10px;
1862 padding:0 0 10px;
1861 }
1863 }
1862
1864
1863 .error_msg {
1865 .error_msg {
1864 background-color:#FFCFCF;
1866 background-color:#FFCFCF;
1865 background-image:url("../../images/icons/error_msg.png");
1867 background-image:url("../../images/icons/error_msg.png");
1866 border:1px solid #FF9595;
1868 border:1px solid #FF9595;
1867 color:#C30;
1869 color:#C30;
1868 }
1870 }
1869
1871
1870 .warning_msg {
1872 .warning_msg {
1871 background-color:#FFFBCC;
1873 background-color:#FFFBCC;
1872 background-image:url("../../images/icons/warning_msg.png");
1874 background-image:url("../../images/icons/warning_msg.png");
1873 border:1px solid #FFF35E;
1875 border:1px solid #FFF35E;
1874 color:#C69E00;
1876 color:#C69E00;
1875 }
1877 }
1876
1878
1877 .success_msg {
1879 .success_msg {
1878 background-color:#D5FFCF;
1880 background-color:#D5FFCF;
1879 background-image:url("../../images/icons/success_msg.png");
1881 background-image:url("../../images/icons/success_msg.png");
1880 border:1px solid #97FF88;
1882 border:1px solid #97FF88;
1881 color:#090;
1883 color:#090;
1882 }
1884 }
1883
1885
1884 .notice_msg {
1886 .notice_msg {
1885 background-color:#DCE3FF;
1887 background-color:#DCE3FF;
1886 background-image:url("../../images/icons/notice_msg.png");
1888 background-image:url("../../images/icons/notice_msg.png");
1887 border:1px solid #93A8FF;
1889 border:1px solid #93A8FF;
1888 color:#556CB5;
1890 color:#556CB5;
1889 }
1891 }
1890
1892
1891 .success_msg,.error_msg,.notice_msg,.warning_msg {
1893 .success_msg,.error_msg,.notice_msg,.warning_msg {
1892 background-position:10px center;
1894 background-position:10px center;
1893 background-repeat:no-repeat;
1895 background-repeat:no-repeat;
1894 font-size:12px;
1896 font-size:12px;
1895 font-weight:700;
1897 font-weight:700;
1896 min-height:14px;
1898 min-height:14px;
1897 line-height:14px;
1899 line-height:14px;
1898 margin-bottom:0;
1900 margin-bottom:0;
1899 margin-top:0;
1901 margin-top:0;
1900 display:block;
1902 display:block;
1901 overflow:auto;
1903 overflow:auto;
1902 padding:6px 10px 6px 40px;
1904 padding:6px 10px 6px 40px;
1903 }
1905 }
1904
1906
1905 #msg_close {
1907 #msg_close {
1906 background:transparent url("../../icons/cross_grey_small.png") no-repeat scroll 0 0;
1908 background:transparent url("../../icons/cross_grey_small.png") no-repeat scroll 0 0;
1907 cursor:pointer;
1909 cursor:pointer;
1908 height:16px;
1910 height:16px;
1909 position:absolute;
1911 position:absolute;
1910 right:5px;
1912 right:5px;
1911 top:5px;
1913 top:5px;
1912 width:16px;
1914 width:16px;
1913 }
1915 }
1914
1916
1915 div#legend_container table,div#legend_choices table {
1917 div#legend_container table,div#legend_choices table {
1916 width:auto !important;
1918 width:auto !important;
1917 }
1919 }
1918
1920
1919 table#permissions_manage {
1921 table#permissions_manage {
1920 width:0 !important;
1922 width:0 !important;
1921 }
1923 }
1922
1924
1923 table#permissions_manage span.private_repo_msg {
1925 table#permissions_manage span.private_repo_msg {
1924 font-size:0.8em;
1926 font-size:0.8em;
1925 opacity:0.6px;
1927 opacity:0.6px;
1926 }
1928 }
1927
1929
1928 table#permissions_manage td.private_repo_msg {
1930 table#permissions_manage td.private_repo_msg {
1929 font-size:0.8em;
1931 font-size:0.8em;
1930 }
1932 }
1931
1933
1932 table#permissions_manage tr#add_perm_input td {
1934 table#permissions_manage tr#add_perm_input td {
1933 vertical-align:middle;
1935 vertical-align:middle;
1934 }
1936 }
1935
1937
1936 div.gravatar {
1938 div.gravatar {
1937 background-color:#FFF;
1939 background-color:#FFF;
1938 border:1px solid #D0D0D0;
1940 border:1px solid #D0D0D0;
1939 float:left;
1941 float:left;
1940 margin-right:0.7em;
1942 margin-right:0.7em;
1941 padding:2px 2px 0;
1943 padding:2px 2px 0;
1942 }
1944 }
1943
1945
1944 #header,#content,#footer {
1946 #header,#content,#footer {
1945 min-width:1224px;
1947 min-width:1224px;
1946 }
1948 }
1947
1949
1948 #content {
1950 #content {
1949 min-height:100%;
1951 min-height:100%;
1950 clear:both;
1952 clear:both;
1951 overflow:hidden;
1953 overflow:hidden;
1952 padding:14px 30px;
1954 padding:14px 30px;
1953 }
1955 }
1954
1956
1955 #content div.box div.title div.search {
1957 #content div.box div.title div.search {
1956 background:url("../../images/title_link.png") no-repeat top left;
1958 background:url("../../images/title_link.png") no-repeat top left;
1957 border-left:1px solid #316293;
1959 border-left:1px solid #316293;
1958 }
1960 }
1959
1961
1960 #content div.box div.title div.search div.input input {
1962 #content div.box div.title div.search div.input input {
1961 border:1px solid #316293;
1963 border:1px solid #316293;
1962 }
1964 }
1963
1965
1964 #content div.box div.title div.search div.button input.ui-state-default {
1966 #content div.box div.title div.search div.button input.ui-state-default {
1965 background:#4e85bb url("../../images/button_highlight.png") repeat-x;
1967 background:#4e85bb url("../../images/button_highlight.png") repeat-x;
1966 border:1px solid #316293;
1968 border:1px solid #316293;
1967 border-left:none;
1969 border-left:none;
1968 color:#FFF;
1970 color:#FFF;
1969 }
1971 }
1970
1972
1971 #content div.box div.title div.search div.button input.ui-state-hover {
1973 #content div.box div.title div.search div.button input.ui-state-hover {
1972 background:#46a0c1 url("../../images/button_highlight_selected.png") repeat-x;
1974 background:#46a0c1 url("../../images/button_highlight_selected.png") repeat-x;
1973 border:1px solid #316293;
1975 border:1px solid #316293;
1974 border-left:none;
1976 border-left:none;
1975 color:#FFF;
1977 color:#FFF;
1976 }
1978 }
1977
1979
1978 #content div.box div.form div.fields div.field div.highlight .ui-state-default {
1980 #content div.box div.form div.fields div.field div.highlight .ui-state-default {
1979 background:#4e85bb url("../../images/button_highlight.png") repeat-x;
1981 background:#4e85bb url("../../images/button_highlight.png") repeat-x;
1980 border-top:1px solid #5c91a4;
1982 border-top:1px solid #5c91a4;
1981 border-left:1px solid #2a6f89;
1983 border-left:1px solid #2a6f89;
1982 border-right:1px solid #2b7089;
1984 border-right:1px solid #2b7089;
1983 border-bottom:1px solid #1a6480;
1985 border-bottom:1px solid #1a6480;
1984 color:#fff;
1986 color:#fff;
1985 }
1987 }
1986
1988
1987 #content div.box div.form div.fields div.field div.highlight .ui-state-hover {
1989 #content div.box div.form div.fields div.field div.highlight .ui-state-hover {
1988 background:#46a0c1 url("../../images/button_highlight_selected.png") repeat-x;
1990 background:#46a0c1 url("../../images/button_highlight_selected.png") repeat-x;
1989 border-top:1px solid #78acbf;
1991 border-top:1px solid #78acbf;
1990 border-left:1px solid #34819e;
1992 border-left:1px solid #34819e;
1991 border-right:1px solid #35829f;
1993 border-right:1px solid #35829f;
1992 border-bottom:1px solid #257897;
1994 border-bottom:1px solid #257897;
1993 color:#fff;
1995 color:#fff;
1994 }
1996 }
1995
1997
1996 ins,div.options a:hover {
1998 ins,div.options a:hover {
1997 text-decoration:none;
1999 text-decoration:none;
1998 }
2000 }
1999
2001
2000 img,#header #header-inner #quick li a:hover span.normal,#header #header-inner #quick li ul li.last,#content div.box div.form div.fields div.field div.textarea table td table td a,#clone_url {
2002 img,#header #header-inner #quick li a:hover span.normal,#header #header-inner #quick li ul li.last,#content div.box div.form div.fields div.field div.textarea table td table td a,#clone_url {
2001 border:none;
2003 border:none;
2002 }
2004 }
2003
2005
2004 img.icon,.right .merge img {
2006 img.icon,.right .merge img {
2005 vertical-align:bottom;
2007 vertical-align:bottom;
2006 }
2008 }
2007
2009
2008 #header ul#logged-user,#content div.box div.title ul.links,#content div.box div.message div.dismiss,#content div.box div.traffic div.legend ul {
2010 #header ul#logged-user,#content div.box div.title ul.links,#content div.box div.message div.dismiss,#content div.box div.traffic div.legend ul {
2009 float:right;
2011 float:right;
2010 margin:0;
2012 margin:0;
2011 padding:0;
2013 padding:0;
2012 }
2014 }
2013
2015
2014 #header #header-inner #home,#header #header-inner #logo,#content div.box ul.left,#content div.box ol.left,#content div.box div.pagination-left,div#commit_history,div#legend_data,div#legend_container,div#legend_choices {
2016 #header #header-inner #home,#header #header-inner #logo,#content div.box ul.left,#content div.box ol.left,#content div.box div.pagination-left,div#commit_history,div#legend_data,div#legend_container,div#legend_choices {
2015 float:left;
2017 float:left;
2016 }
2018 }
2017
2019
2018 #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,#content #left #menu ul.closed,#content #left #menu li ul.collapsed,.yui-tt-shadow {
2020 #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,#content #left #menu ul.closed,#content #left #menu li ul.collapsed,.yui-tt-shadow {
2019 display:none;
2021 display:none;
2020 }
2022 }
2021
2023
2022 #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,#content #left #menu ul.opened,#content #left #menu li ul.expanded {
2024 #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,#content #left #menu ul.opened,#content #left #menu li ul.expanded {
2023 display:block;
2025 display:block;
2024 }
2026 }
2025
2027
2026 #content div.box div.title ul.links li a:hover,#content div.box div.title ul.links li.ui-tabs-selected a {
2028 #content div.box div.title ul.links li a:hover,#content div.box div.title ul.links li.ui-tabs-selected a {
2027 background:url("../../images/title_tab_selected.png") no-repeat bottom center;
2028 color:#bfe3ff;
2029 color:#bfe3ff;
2029 }
2030 }
2030
2031
2031 #content div.box ol.lower-roman,#content div.box ol.upper-roman,#content div.box ol.lower-alpha,#content div.box ol.upper-alpha,#content div.box ol.decimal {
2032 #content div.box ol.lower-roman,#content div.box ol.upper-roman,#content div.box ol.lower-alpha,#content div.box ol.upper-alpha,#content div.box ol.decimal {
2032 margin:10px 24px 10px 44px;
2033 margin:10px 24px 10px 44px;
2033 }
2034 }
2034
2035
2035 #content div.box div.form,#content div.box div.table,#content div.box div.traffic {
2036 #content div.box div.form,#content div.box div.table,#content div.box div.traffic {
2036 clear:both;
2037 clear:both;
2037 overflow:hidden;
2038 overflow:hidden;
2038 margin:0;
2039 margin:0;
2039 padding:0 20px 10px;
2040 padding:0 20px 10px;
2040 }
2041 }
2041
2042
2042 #content div.box div.form div.fields,#login div.form,#login div.form div.fields,#register div.form,#register div.form div.fields {
2043 #content div.box div.form div.fields,#login div.form,#login div.form div.fields,#register div.form,#register div.form div.fields {
2043 clear:both;
2044 clear:both;
2044 overflow:hidden;
2045 overflow:hidden;
2045 margin:0;
2046 margin:0;
2046 padding:0;
2047 padding:0;
2047 }
2048 }
2048
2049
2049 #content div.box div.form div.fields div.field div.label-checkbox,#content div.box div.form div.fields div.field div.label-radio,#content div.box div.form div.fields div.field div.label-textarea {
2050 #content div.box div.form div.fields div.field div.label-checkbox,#content div.box div.form div.fields div.field div.label-radio,#content div.box div.form div.fields div.field div.label-textarea {
2050 padding:0 0 0 5px !important;
2051 padding:0 0 0 5px !important;
2051 }
2052 }
2052
2053
2053 #content div.box div.form div.fields div.field div.label span,#login div.form div.fields div.field div.label span,#register div.form div.fields div.field div.label span {
2054 #content div.box div.form div.fields div.field div.label span,#login div.form div.fields div.field div.label span,#register div.form div.fields div.field div.label span {
2054 height:1%;
2055 height:1%;
2055 display:block;
2056 display:block;
2056 color:#363636;
2057 color:#363636;
2057 margin:0;
2058 margin:0;
2058 padding:2px 0 0;
2059 padding:2px 0 0;
2059 }
2060 }
2060
2061
2061 #content div.box div.form div.fields div.field div.input input.error,#login div.form div.fields div.field div.input input.error,#register div.form div.fields div.field div.input input.error {
2062 #content div.box div.form div.fields div.field div.input input.error,#login div.form div.fields div.field div.input input.error,#register div.form div.fields div.field div.input input.error {
2062 background:#FBE3E4;
2063 background:#FBE3E4;
2063 border-top:1px solid #e1b2b3;
2064 border-top:1px solid #e1b2b3;
2064 border-left:1px solid #e1b2b3;
2065 border-left:1px solid #e1b2b3;
2065 border-right:1px solid #FBC2C4;
2066 border-right:1px solid #FBC2C4;
2066 border-bottom:1px solid #FBC2C4;
2067 border-bottom:1px solid #FBC2C4;
2067 }
2068 }
2068
2069
2069 #content div.box div.form div.fields div.field div.input input.success,#login div.form div.fields div.field div.input input.success,#register div.form div.fields div.field div.input input.success {
2070 #content div.box div.form div.fields div.field div.input input.success,#login div.form div.fields div.field div.input input.success,#register div.form div.fields div.field div.input input.success {
2070 background:#E6EFC2;
2071 background:#E6EFC2;
2071 border-top:1px solid #cebb98;
2072 border-top:1px solid #cebb98;
2072 border-left:1px solid #cebb98;
2073 border-left:1px solid #cebb98;
2073 border-right:1px solid #c6d880;
2074 border-right:1px solid #c6d880;
2074 border-bottom:1px solid #c6d880;
2075 border-bottom:1px solid #c6d880;
2075 }
2076 }
2076
2077
2077 #content div.box-left div.form div.fields div.field div.textarea,#content div.box-right div.form div.fields div.field div.textarea,#content div.box div.form div.fields div.field div.select select,#content div.box table th.selected input,#content div.box table td.selected input {
2078 #content div.box-left div.form div.fields div.field div.textarea,#content div.box-right div.form div.fields div.field div.textarea,#content div.box div.form div.fields div.field div.select select,#content div.box table th.selected input,#content div.box table td.selected input {
2078 margin:0;
2079 margin:0;
2079 }
2080 }
2080
2081
2081 #content div.box div.form div.fields div.field div.select,#content div.box div.form div.fields div.field div.checkboxes,#content div.box div.form div.fields div.field div.radios {
2082 #content div.box div.form div.fields div.field div.select,#content div.box div.form div.fields div.field div.checkboxes,#content div.box div.form div.fields div.field div.radios {
2082 margin:0 0 0 200px;
2083 margin:0 0 0 200px;
2083 padding:0;
2084 padding:0;
2084 }
2085 }
2085
2086
2086 #content div.box div.form div.fields div.field div.select a:hover,#content div.box div.form div.fields div.field div.select a.ui-selectmenu:hover,#content div.box div.action a:hover {
2087 #content div.box div.form div.fields div.field div.select a:hover,#content div.box div.form div.fields div.field div.select a.ui-selectmenu:hover,#content div.box div.action a:hover {
2087 color:#000;
2088 color:#000;
2088 text-decoration:none;
2089 text-decoration:none;
2089 }
2090 }
2090
2091
2091 #content div.box div.form div.fields div.field div.select a.ui-selectmenu-focus,#content div.box div.action a.ui-selectmenu-focus {
2092 #content div.box div.form div.fields div.field div.select a.ui-selectmenu-focus,#content div.box div.action a.ui-selectmenu-focus {
2092 border:1px solid #666;
2093 border:1px solid #666;
2093 }
2094 }
2094
2095
2095 #content div.box div.form div.fields div.field div.checkboxes div.checkbox,#content div.box div.form div.fields div.field div.radios div.radio {
2096 #content div.box div.form div.fields div.field div.checkboxes div.checkbox,#content div.box div.form div.fields div.field div.radios div.radio {
2096 clear:both;
2097 clear:both;
2097 overflow:hidden;
2098 overflow:hidden;
2098 margin:0;
2099 margin:0;
2099 padding:2px 0;
2100 padding:2px 0;
2100 }
2101 }
2101
2102
2102 #content div.box div.form div.fields div.field div.checkboxes div.checkbox input,#content div.box div.form div.fields div.field div.radios div.radio input {
2103 #content div.box div.form div.fields div.field div.checkboxes div.checkbox input,#content div.box div.form div.fields div.field div.radios div.radio input {
2103 float:left;
2104 float:left;
2104 margin:0;
2105 margin:0;
2105 }
2106 }
2106
2107
2107 #content div.box div.form div.fields div.field div.checkboxes div.checkbox label,#content div.box div.form div.fields div.field div.radios div.radio label {
2108 #content div.box div.form div.fields div.field div.checkboxes div.checkbox label,#content div.box div.form div.fields div.field div.radios div.radio label {
2108 height:1%;
2109 height:1%;
2109 display:block;
2110 display:block;
2110 float:left;
2111 float:left;
2111 margin:3px 0 0 4px;
2112 margin:3px 0 0 4px;
2112 }
2113 }
2113
2114
2114 div.form div.fields div.field div.button input,#content div.box div.form div.fields div.buttons input,div.form div.fields div.buttons input,#content div.box div.action div.button input {
2115 div.form div.fields div.field div.button input,#content div.box div.form div.fields div.buttons input,div.form div.fields div.buttons input,#content div.box div.action div.button input {
2115 color:#000;
2116 color:#000;
2116 font-family:Lucida Grande, Verdana, Lucida Sans Regular, Lucida Sans Unicode, Arial, sans-serif;
2117 font-family:Lucida Grande, Verdana, Lucida Sans Regular, Lucida Sans Unicode, Arial, sans-serif;
2117 font-size:11px;
2118 font-size:11px;
2118 font-weight:700;
2119 font-weight:700;
2119 margin:0;
2120 margin:0;
2120 }
2121 }
2121
2122
2122 div.form div.fields div.field div.button .ui-state-default,#content div.box div.form div.fields div.buttons input.ui-state-default {
2123 div.form div.fields div.field div.button .ui-state-default,#content div.box div.form div.fields div.buttons input.ui-state-default {
2123 background:#e5e3e3 url("../images/button.png") repeat-x;
2124 background:#e5e3e3 url("../images/button.png") repeat-x;
2124 border-top:1px solid #DDD;
2125 border-top:1px solid #DDD;
2125 border-left:1px solid #c6c6c6;
2126 border-left:1px solid #c6c6c6;
2126 border-right:1px solid #DDD;
2127 border-right:1px solid #DDD;
2127 border-bottom:1px solid #c6c6c6;
2128 border-bottom:1px solid #c6c6c6;
2128 color:#515151;
2129 color:#515151;
2129 outline:none;
2130 outline:none;
2130 margin:0;
2131 margin:0;
2131 padding:6px 12px;
2132 padding:6px 12px;
2132 }
2133 }
2133
2134
2134 div.form div.fields div.field div.button .ui-state-hover,#content div.box div.form div.fields div.buttons input.ui-state-hover {
2135 div.form div.fields div.field div.button .ui-state-hover,#content div.box div.form div.fields div.buttons input.ui-state-hover {
2135 background:#b4b4b4 url("../images/button_selected.png") repeat-x;
2136 background:#b4b4b4 url("../images/button_selected.png") repeat-x;
2136 border-top:1px solid #ccc;
2137 border-top:1px solid #ccc;
2137 border-left:1px solid #bebebe;
2138 border-left:1px solid #bebebe;
2138 border-right:1px solid #b1b1b1;
2139 border-right:1px solid #b1b1b1;
2139 border-bottom:1px solid #afafaf;
2140 border-bottom:1px solid #afafaf;
2140 color:#515151;
2141 color:#515151;
2141 outline:none;
2142 outline:none;
2142 margin:0;
2143 margin:0;
2143 padding:6px 12px;
2144 padding:6px 12px;
2144 }
2145 }
2145
2146
2146 div.form div.fields div.field div.highlight,#content div.box div.form div.fields div.buttons div.highlight {
2147 div.form div.fields div.field div.highlight,#content div.box div.form div.fields div.buttons div.highlight {
2147 display:inline;
2148 display:inline;
2148 }
2149 }
2149
2150
2150 #content div.box div.form div.fields div.buttons,div.form div.fields div.buttons {
2151 #content div.box div.form div.fields div.buttons,div.form div.fields div.buttons {
2151 margin:10px 0 0 200px;
2152 margin:10px 0 0 200px;
2152 padding:0;
2153 padding:0;
2153 }
2154 }
2154
2155
2155 #content div.box-left div.form div.fields div.buttons,#content div.box-right div.form div.fields div.buttons,div.box-left div.form div.fields div.buttons,div.box-right div.form div.fields div.buttons {
2156 #content div.box-left div.form div.fields div.buttons,#content div.box-right div.form div.fields div.buttons,div.box-left div.form div.fields div.buttons,div.box-right div.form div.fields div.buttons {
2156 margin:10px 0 0;
2157 margin:10px 0 0;
2157 }
2158 }
2158
2159
2159 #content div.box table td.user,#content div.box table td.address {
2160 #content div.box table td.user,#content div.box table td.address {
2160 width:10%;
2161 width:10%;
2161 text-align:center;
2162 text-align:center;
2162 }
2163 }
2163
2164
2164 #content div.box div.action div.button,#login div.form div.fields div.field div.input div.link,#register div.form div.fields div.field div.input div.link {
2165 #content div.box div.action div.button,#login div.form div.fields div.field div.input div.link,#register div.form div.fields div.field div.input div.link {
2165 text-align:right;
2166 text-align:right;
2166 margin:6px 0 0;
2167 margin:6px 0 0;
2167 padding:0;
2168 padding:0;
2168 }
2169 }
2169
2170
2170 #content div.box div.action div.button input.ui-state-default,#login div.form div.fields div.buttons input.ui-state-default,#register div.form div.fields div.buttons input.ui-state-default {
2171 #content div.box div.action div.button input.ui-state-default,#login div.form div.fields div.buttons input.ui-state-default,#register div.form div.fields div.buttons input.ui-state-default {
2171 background:#e5e3e3 url("../images/button.png") repeat-x;
2172 background:#e5e3e3 url("../images/button.png") repeat-x;
2172 border-top:1px solid #DDD;
2173 border-top:1px solid #DDD;
2173 border-left:1px solid #c6c6c6;
2174 border-left:1px solid #c6c6c6;
2174 border-right:1px solid #DDD;
2175 border-right:1px solid #DDD;
2175 border-bottom:1px solid #c6c6c6;
2176 border-bottom:1px solid #c6c6c6;
2176 color:#515151;
2177 color:#515151;
2177 margin:0;
2178 margin:0;
2178 padding:6px 12px;
2179 padding:6px 12px;
2179 }
2180 }
2180
2181
2181 #content div.box div.action div.button input.ui-state-hover,#login div.form div.fields div.buttons input.ui-state-hover,#register div.form div.fields div.buttons input.ui-state-hover {
2182 #content div.box div.action div.button input.ui-state-hover,#login div.form div.fields div.buttons input.ui-state-hover,#register div.form div.fields div.buttons input.ui-state-hover {
2182 background:#b4b4b4 url("../images/button_selected.png") repeat-x;
2183 background:#b4b4b4 url("../images/button_selected.png") repeat-x;
2183 border-top:1px solid #ccc;
2184 border-top:1px solid #ccc;
2184 border-left:1px solid #bebebe;
2185 border-left:1px solid #bebebe;
2185 border-right:1px solid #b1b1b1;
2186 border-right:1px solid #b1b1b1;
2186 border-bottom:1px solid #afafaf;
2187 border-bottom:1px solid #afafaf;
2187 color:#515151;
2188 color:#515151;
2188 margin:0;
2189 margin:0;
2189 padding:6px 12px;
2190 padding:6px 12px;
2190 }
2191 }
2191
2192
2192 #content div.box div.pagination div.results,#content div.box div.pagination-wh div.results {
2193 #content div.box div.pagination div.results,#content div.box div.pagination-wh div.results {
2193 text-align:left;
2194 text-align:left;
2194 float:left;
2195 float:left;
2195 margin:0;
2196 margin:0;
2196 padding:0;
2197 padding:0;
2197 }
2198 }
2198
2199
2199 #content div.box div.pagination div.results span,#content div.box div.pagination-wh div.results span {
2200 #content div.box div.pagination div.results span,#content div.box div.pagination-wh div.results span {
2200 height:1%;
2201 height:1%;
2201 display:block;
2202 display:block;
2202 float:left;
2203 float:left;
2203 background:#ebebeb url("../images/pager.png") repeat-x;
2204 background:#ebebeb url("../images/pager.png") repeat-x;
2204 border-top:1px solid #dedede;
2205 border-top:1px solid #dedede;
2205 border-left:1px solid #cfcfcf;
2206 border-left:1px solid #cfcfcf;
2206 border-right:1px solid #c4c4c4;
2207 border-right:1px solid #c4c4c4;
2207 border-bottom:1px solid #c4c4c4;
2208 border-bottom:1px solid #c4c4c4;
2208 color:#4A4A4A;
2209 color:#4A4A4A;
2209 font-weight:700;
2210 font-weight:700;
2210 margin:0;
2211 margin:0;
2211 padding:6px 8px;
2212 padding:6px 8px;
2212 }
2213 }
2213
2214
2214 #content div.box div.pagination ul.pager li.disabled,#content div.box div.pagination-wh a.disabled {
2215 #content div.box div.pagination ul.pager li.disabled,#content div.box div.pagination-wh a.disabled {
2215 color:#B4B4B4;
2216 color:#B4B4B4;
2216 padding:6px;
2217 padding:6px;
2217 }
2218 }
2218
2219
2219 #login,#register {
2220 #login,#register {
2220 width:420px;
2221 width:420px;
2221 margin:10% auto 0;
2222 margin:10% auto 0;
2222 padding:0;
2223 padding:0;
2223 }
2224 }
2224
2225
2225 #login div.color,#register div.color {
2226 #login div.color,#register div.color {
2226 clear:both;
2227 clear:both;
2227 overflow:hidden;
2228 overflow:hidden;
2228 background:#FFF;
2229 background:#FFF;
2229 margin:10px auto 0;
2230 margin:10px auto 0;
2230 padding:3px 3px 3px 0;
2231 padding:3px 3px 3px 0;
2231 }
2232 }
2232
2233
2233 #login div.color a,#register div.color a {
2234 #login div.color a,#register div.color a {
2234 width:20px;
2235 width:20px;
2235 height:20px;
2236 height:20px;
2236 display:block;
2237 display:block;
2237 float:left;
2238 float:left;
2238 margin:0 0 0 3px;
2239 margin:0 0 0 3px;
2239 padding:0;
2240 padding:0;
2240 }
2241 }
2241
2242
2242 #login div.title h5,#register div.title h5 {
2243 #login div.title h5,#register div.title h5 {
2243 color:#fff;
2244 color:#fff;
2244 margin:10px;
2245 margin:10px;
2245 padding:0;
2246 padding:0;
2246 }
2247 }
2247
2248
2248 #login div.form div.fields div.field,#register div.form div.fields div.field {
2249 #login div.form div.fields div.field,#register div.form div.fields div.field {
2249 clear:both;
2250 clear:both;
2250 overflow:hidden;
2251 overflow:hidden;
2251 margin:0;
2252 margin:0;
2252 padding:0 0 10px;
2253 padding:0 0 10px;
2253 }
2254 }
2254
2255
2255 #login div.form div.fields div.field span.error-message,#register div.form div.fields div.field span.error-message {
2256 #login div.form div.fields div.field span.error-message,#register div.form div.fields div.field span.error-message {
2256 height:1%;
2257 height:1%;
2257 display:block;
2258 display:block;
2258 color:red;
2259 color:red;
2259 margin:8px 0 0;
2260 margin:8px 0 0;
2260 padding:0;
2261 padding:0;
2261 }
2262 }
2262
2263
2263 #login div.form div.fields div.field div.label label,#register div.form div.fields div.field div.label label {
2264 #login div.form div.fields div.field div.label label,#register div.form div.fields div.field div.label label {
2264 color:#000;
2265 color:#000;
2265 font-weight:700;
2266 font-weight:700;
2266 }
2267 }
2267
2268
2268 #login div.form div.fields div.field div.input,#register div.form div.fields div.field div.input {
2269 #login div.form div.fields div.field div.input,#register div.form div.fields div.field div.input {
2269 float:left;
2270 float:left;
2270 margin:0;
2271 margin:0;
2271 padding:0;
2272 padding:0;
2272 }
2273 }
2273
2274
2274 #login div.form div.fields div.field div.checkbox,#register div.form div.fields div.field div.checkbox {
2275 #login div.form div.fields div.field div.checkbox,#register div.form div.fields div.field div.checkbox {
2275 margin:0 0 0 184px;
2276 margin:0 0 0 184px;
2276 padding:0;
2277 padding:0;
2277 }
2278 }
2278
2279
2279 #login div.form div.fields div.field div.checkbox label,#register div.form div.fields div.field div.checkbox label {
2280 #login div.form div.fields div.field div.checkbox label,#register div.form div.fields div.field div.checkbox label {
2280 color:#565656;
2281 color:#565656;
2281 font-weight:700;
2282 font-weight:700;
2282 }
2283 }
2283
2284
2284 #login div.form div.fields div.buttons input,#register div.form div.fields div.buttons input {
2285 #login div.form div.fields div.buttons input,#register div.form div.fields div.buttons input {
2285 color:#000;
2286 color:#000;
2286 font-size:1em;
2287 font-size:1em;
2287 font-weight:700;
2288 font-weight:700;
2288 font-family:Verdana, Helvetica, Sans-Serif;
2289 font-family:Verdana, Helvetica, Sans-Serif;
2289 margin:0;
2290 margin:0;
2290 }
2291 }
2291
2292
2292 #changeset_content .container .wrapper,#graph_content .container .wrapper {
2293 #changeset_content .container .wrapper,#graph_content .container .wrapper {
2293 width:600px;
2294 width:600px;
2294 }
2295 }
2295
2296
2296 #changeset_content .container .left,#graph_content .container .left {
2297 #changeset_content .container .left,#graph_content .container .left {
2297 float:left;
2298 float:left;
2298 width:70%;
2299 width:70%;
2299 padding-left:5px;
2300 padding-left:5px;
2300 }
2301 }
2301
2302
2302 #changeset_content .container .left .date,.ac .match {
2303 #changeset_content .container .left .date,.ac .match {
2303 font-weight:700;
2304 font-weight:700;
2304 padding-top: 5px;
2305 padding-top: 5px;
2305 padding-bottom:5px;
2306 padding-bottom:5px;
2306 }
2307 }
2307
2308
2308 div#legend_container table td,div#legend_choices table td {
2309 div#legend_container table td,div#legend_choices table td {
2309 border:none !important;
2310 border:none !important;
2310 height:20px !important;
2311 height:20px !important;
2311 padding:0 !important;
2312 padding:0 !important;
2312 } No newline at end of file
2313 }
@@ -1,80 +1,80 b''
1 <%def name="file_class(node)">
1 <%def name="file_class(node)">
2 %if node.is_file():
2 %if node.is_file():
3 <%return "browser-file" %>
3 <%return "browser-file" %>
4 %else:
4 %else:
5 <%return "browser-dir"%>
5 <%return "browser-dir"%>
6 %endif
6 %endif
7 </%def>
7 </%def>
8 <div id="body" class="browserblock">
8 <div id="body" class="browserblock">
9 <div class="browser-header">
9 <div class="browser-header">
10 ${h.form(h.url.current())}
10 ${h.form(h.url.current())}
11 <div class="info_box">
11 <div class="info_box">
12 <span >${_('view')}@rev</span>
12 <span >${_('view')}@rev</span>
13 <a href="${c.url_prev}">&laquo;</a>
13 <a href="${c.url_prev}">&laquo;</a>
14 ${h.text('at_rev',value=c.rev_nr,size=3)}
14 ${h.text('at_rev',value=c.rev_nr,size=3)}
15 <a href="${c.url_next}">&raquo;</a>
15 <a href="${c.url_next}">&raquo;</a>
16 ${h.submit('view','view')}
16 ${h.submit('view','view')}
17 </div>
17 </div>
18 ${h.end_form()}
18 ${h.end_form()}
19 </div>
19 </div>
20 <div class="browser-body">
20 <div class="browser-body">
21 <table class="code-browser">
21 <table class="code-browser">
22 <thead>
22 <thead>
23 <tr>
23 <tr>
24 <th>${_('Name')}</th>
24 <th>${_('Name')}</th>
25 <th>${_('Size')}</th>
25 <th>${_('Size')}</th>
26 <th>${_('Mimetype')}</th>
26 <th>${_('Mimetype')}</th>
27 <th>${_('Revision')}</th>
27 <th>${_('Revision')}</th>
28 <th>${_('Last modified')}</th>
28 <th>${_('Last modified')}</th>
29 <th>${_('Last commiter')}</th>
29 <th>${_('Last commiter')}</th>
30 </tr>
30 </tr>
31 </thead>
31 </thead>
32
32
33 % if c.files_list.parent:
33 % if c.files_list.parent:
34 <tr class="parity0">
34 <tr class="parity0">
35 <td>
35 <td>
36 ${h.link_to('..',h.url('files_home',repo_name=c.repo_name,revision=c.cur_rev,f_path=c.files_list.parent.path),class_="browser-dir")}
36 ${h.link_to('..',h.url('files_home',repo_name=c.repo_name,revision=c.cur_rev,f_path=c.files_list.parent.path),class_="browser-dir")}
37 </td>
37 </td>
38 <td></td>
38 <td></td>
39 <td></td>
39 <td></td>
40 <td></td>
40 <td></td>
41 <td></td>
41 <td></td>
42 <td></td>
42 <td></td>
43 </tr>
43 </tr>
44 %endif
44 %endif
45
45
46 %for cnt,node in enumerate(c.files_list,1):
46 %for cnt,node in enumerate(c.files_list):
47 <tr class="parity${cnt%2}">
47 <tr class="parity${(cnt+1)%2}">
48 <td>
48 <td>
49 ${h.link_to(node.name,h.url('files_home',repo_name=c.repo_name,revision=c.cur_rev,f_path=node.path),class_=file_class(node))}
49 ${h.link_to(node.name,h.url('files_home',repo_name=c.repo_name,revision=c.cur_rev,f_path=node.path),class_=file_class(node))}
50 </td>
50 </td>
51 <td>
51 <td>
52 %if node.is_file():
52 %if node.is_file():
53 ${h.format_byte_size(node.size,binary=True)}
53 ${h.format_byte_size(node.size,binary=True)}
54 %endif
54 %endif
55 </td>
55 </td>
56 <td>
56 <td>
57 %if node.is_file():
57 %if node.is_file():
58 ${node.mimetype}
58 ${node.mimetype}
59 %endif
59 %endif
60 </td>
60 </td>
61 <td>
61 <td>
62 %if node.is_file():
62 %if node.is_file():
63 ${node.last_changeset.revision}
63 ${node.last_changeset.revision}
64 %endif
64 %endif
65 </td>
65 </td>
66 <td>
66 <td>
67 %if node.is_file():
67 %if node.is_file():
68 ${h.age(node.last_changeset._ctx.date())} - ${node.last_changeset.date}
68 ${h.age(node.last_changeset._ctx.date())} - ${node.last_changeset.date}
69 %endif
69 %endif
70 </td>
70 </td>
71 <td>
71 <td>
72 %if node.is_file():
72 %if node.is_file():
73 ${node.last_changeset.author}
73 ${node.last_changeset.author}
74 %endif
74 %endif
75 </td>
75 </td>
76 </tr>
76 </tr>
77 %endfor
77 %endfor
78 </table>
78 </table>
79 </div>
79 </div>
80 </div> No newline at end of file
80 </div>
@@ -1,584 +1,586 b''
1 <%inherit file="/base/base.html"/>
1 <%inherit file="/base/base.html"/>
2
2
3 <%def name="title()">
3 <%def name="title()">
4 ${c.repo_name} ${_('Summary')} - ${c.rhodecode_name}
4 ${c.repo_name} ${_('Summary')} - ${c.rhodecode_name}
5 </%def>
5 </%def>
6
6
7 <%def name="breadcrumbs_links()">
7 <%def name="breadcrumbs_links()">
8 ${h.link_to(u'Home',h.url('/'))}
8 ${h.link_to(u'Home',h.url('/'))}
9 &raquo;
9 &raquo;
10 ${h.link_to(c.repo_name,h.url('summary_home',repo_name=c.repo_name))}
10 ${h.link_to(c.repo_name,h.url('summary_home',repo_name=c.repo_name))}
11 &raquo;
11 &raquo;
12 ${_('summary')}
12 ${_('summary')}
13 </%def>
13 </%def>
14
14
15 <%def name="page_nav()">
15 <%def name="page_nav()">
16 ${self.menu('summary')}
16 ${self.menu('summary')}
17 </%def>
17 </%def>
18
18
19 <%def name="main()">
19 <%def name="main()">
20 <script type="text/javascript">
20 <script type="text/javascript">
21 var E = YAHOO.util.Event;
21 var E = YAHOO.util.Event;
22 var D = YAHOO.util.Dom;
22 var D = YAHOO.util.Dom;
23
23
24 E.onDOMReady(function(e){
24 E.onDOMReady(function(e){
25 id = 'clone_url';
25 id = 'clone_url';
26 E.addListener(id,'click',function(e){
26 E.addListener(id,'click',function(e){
27 D.get('clone_url').select();
27 D.get('clone_url').select();
28 })
28 })
29 })
29 })
30 </script>
30 </script>
31 <div class="box box-left">
31 <div class="box box-left">
32 <!-- box / title -->
32 <!-- box / title -->
33 <div class="title">
33 <div class="title">
34 ${self.breadcrumbs()}
34 ${self.breadcrumbs()}
35 </div>
35 </div>
36 <!-- end box / title -->
36 <!-- end box / title -->
37 <div class="form">
37 <div class="form">
38 <div class="fields">
38 <div class="fields">
39
39
40 <div class="field">
40 <div class="field">
41 <div class="label">
41 <div class="label">
42 <label>${_('Name')}:</label>
42 <label>${_('Name')}:</label>
43 </div>
43 </div>
44 <div class="input-short">
44 <div class="input-short">
45 %if c.repo_info.dbrepo.private:
45 %if c.repo_info.dbrepo.private:
46 <img style="margin-bottom:2px" class="icon" title="${_('private repository')}" alt="${_('private')}" src="/images/icons/lock.png"/>
46 <img style="margin-bottom:2px" class="icon" title="${_('private repository')}" alt="${_('private')}" src="/images/icons/lock.png"/>
47 %else:
47 %else:
48 <img style="margin-bottom:2px" class="icon" title="${_('public repository')}" alt="${_('public')}" src="/images/icons/lock_open.png"/>
48 <img style="margin-bottom:2px" class="icon" title="${_('public repository')}" alt="${_('public')}" src="/images/icons/lock_open.png"/>
49 %endif
49 %endif
50 <span style="font-size: 1.6em;font-weight: bold;vertical-align: baseline;">${c.repo_info.name}</span>
50 <span style="font-size: 1.6em;font-weight: bold;vertical-align: baseline;">${c.repo_info.name}</span>
51 <br/>
51 <br/>
52 %if c.repo_info.dbrepo.fork:
52 %if c.repo_info.dbrepo.fork:
53 <span style="margin-top:5px">
53 <span style="margin-top:5px">
54 <a href="${h.url('summary_home',repo_name=c.repo_info.dbrepo.fork.repo_name)}">
54 <a href="${h.url('summary_home',repo_name=c.repo_info.dbrepo.fork.repo_name)}">
55 <img class="icon" alt="${_('public')}"
55 <img class="icon" alt="${_('public')}"
56 title="${_('Fork of')} ${c.repo_info.dbrepo.fork.repo_name}"
56 title="${_('Fork of')} ${c.repo_info.dbrepo.fork.repo_name}"
57 src="/images/icons/arrow_divide.png"/>
57 src="/images/icons/arrow_divide.png"/>
58 ${_('Fork of')} ${c.repo_info.dbrepo.fork.repo_name}
58 ${_('Fork of')} ${c.repo_info.dbrepo.fork.repo_name}
59 </a>
59 </a>
60 </span>
60 </span>
61 %endif
61 %endif
62 </div>
62 </div>
63 </div>
63 </div>
64
64
65
65
66 <div class="field">
66 <div class="field">
67 <div class="label">
67 <div class="label">
68 <label>${_('Description')}:</label>
68 <label>${_('Description')}:</label>
69 </div>
69 </div>
70 <div class="input-short">
70 <div class="input-short">
71 ${c.repo_info.description}
71 ${c.repo_info.description}
72 </div>
72 </div>
73 </div>
73 </div>
74
74
75
75
76 <div class="field">
76 <div class="field">
77 <div class="label">
77 <div class="label">
78 <label>${_('Contact')}:</label>
78 <label>${_('Contact')}:</label>
79 </div>
79 </div>
80 <div class="input-short">
80 <div class="input-short">
81 <div class="gravatar">
81 <div class="gravatar">
82 <img alt="gravatar" src="${h.gravatar_url(c.repo_info.dbrepo.user.email)}"/>
82 <img alt="gravatar" src="${h.gravatar_url(c.repo_info.dbrepo.user.email)}"/>
83 </div>
83 </div>
84 ${_('Username')}: ${c.repo_info.dbrepo.user.username}<br/>
84 ${_('Username')}: ${c.repo_info.dbrepo.user.username}<br/>
85 ${_('Name')}: ${c.repo_info.dbrepo.user.name} ${c.repo_info.dbrepo.user.lastname}<br/>
85 ${_('Name')}: ${c.repo_info.dbrepo.user.name} ${c.repo_info.dbrepo.user.lastname}<br/>
86 ${_('Email')}: <a href="mailto:${c.repo_info.dbrepo.user.email}">${c.repo_info.dbrepo.user.email}</a>
86 ${_('Email')}: <a href="mailto:${c.repo_info.dbrepo.user.email}">${c.repo_info.dbrepo.user.email}</a>
87 </div>
87 </div>
88 </div>
88 </div>
89
89
90 <div class="field">
90 <div class="field">
91 <div class="label">
91 <div class="label">
92 <label>${_('Last change')}:</label>
92 <label>${_('Last change')}:</label>
93 </div>
93 </div>
94 <div class="input-short">
94 <div class="input-short">
95 ${h.age(c.repo_info.last_change)} - ${h.rfc822date_notz(c.repo_info.last_change)}
95 ${h.age(c.repo_info.last_change)} - ${h.rfc822date_notz(c.repo_info.last_change)}
96 ${_('by')} ${h.get_changeset_safe(c.repo_info,'tip').author}
96 ${_('by')} ${h.get_changeset_safe(c.repo_info,'tip').author}
97
97
98 </div>
98 </div>
99 </div>
99 </div>
100
100
101 <div class="field">
101 <div class="field">
102 <div class="label">
102 <div class="label">
103 <label>${_('Clone url')}:</label>
103 <label>${_('Clone url')}:</label>
104 </div>
104 </div>
105 <div class="input-short">
105 <div class="input-short">
106 <input type="text" id="clone_url" readonly="readonly" value="hg clone ${c.clone_repo_url}" size="70"/>
106 <input type="text" id="clone_url" readonly="readonly" value="hg clone ${c.clone_repo_url}" size="70"/>
107 </div>
107 </div>
108 </div>
108 </div>
109
109
110 <div class="field">
110 <div class="field">
111 <div class="label">
111 <div class="label">
112 <label>${_('Trending languages')}:</label>
112 <label>${_('Trending languages')}:</label>
113 </div>
113 </div>
114 <div class="input-short">
114 <div class="input-short">
115 <div id="lang_stats">
115 <div id="lang_stats">
116
116
117 </div>
117 </div>
118 <script type="text/javascript">
118 <script type="text/javascript">
119 var data = ${c.trending_languages|n};
119 var data = ${c.trending_languages|n};
120 var total = 0;
120 var total = 0;
121 var no_data = true;
121 var no_data = true;
122 for (k in data){
122 for (k in data){
123 total += data[k];
123 total += data[k];
124 no_data = false;
124 no_data = false;
125 }
125 }
126 var tbl = document.createElement('table');
126 var tbl = document.createElement('table');
127 tbl.setAttribute('class','trending_language_tbl');
127 tbl.setAttribute('class','trending_language_tbl');
128 for (k in data){
128 for (k in data){
129 var tr = document.createElement('tr');
129 var tr = document.createElement('tr');
130 var percentage = Math.round((data[k]/total*100),2);
130 var percentage = Math.round((data[k]/total*100),2);
131 var value = data[k];
131 var value = data[k];
132 var td1 = document.createElement('td');
132 var td1 = document.createElement('td');
133 td1.width=150;
133 td1.width=150;
134
134 var trending_language_label = document.createElement('div');
135 var trending_language_label = document.createElement('div');
135 trending_language_label.innerHTML = k;
136 trending_language_label.innerHTML = k;
136 td1.appendChild(trending_language_label);
137 td1.appendChild(trending_language_label);
137
138
138 var td2 = document.createElement('td');
139 var td2 = document.createElement('td');
140 td2.setAttribute('style','padding-right: 12px ! important;');
139 var trending_language = document.createElement('div');
141 var trending_language = document.createElement('div');
140 trending_language.title = k;
142 trending_language.title = k;
141 trending_language.innerHTML = "<b>"+percentage+"% "+value+" ${_('files')}</b>";
143 trending_language.innerHTML = "<b>"+percentage+"% "+value+" ${_('files')}</b>";
142 trending_language.setAttribute("class", 'trending_language top-right-rounded-corner bottom-right-rounded-corner');
144 trending_language.setAttribute("class", 'trending_language top-right-rounded-corner bottom-right-rounded-corner');
143 trending_language.style.width=percentage+"%";
145 trending_language.style.width=percentage+"%";
144 td2.appendChild(trending_language);
146 td2.appendChild(trending_language);
145
147
146 tr.appendChild(td1);
148 tr.appendChild(td1);
147 tr.appendChild(td2);
149 tr.appendChild(td2);
148 tbl.appendChild(tr);
150 tbl.appendChild(tr);
149
151
150 }
152 }
151 if(no_data){
153 if(no_data){
152 var tr = document.createElement('tr');
154 var tr = document.createElement('tr');
153 var td1 = document.createElement('td');
155 var td1 = document.createElement('td');
154 td1.innerHTML = "${_('No data loaded yet')}";
156 td1.innerHTML = "${_('No data loaded yet')}";
155 tr.appendChild(td1);
157 tr.appendChild(td1);
156 tbl.appendChild(tr);
158 tbl.appendChild(tr);
157 }
159 }
158 YAHOO.util.Dom.get('lang_stats').appendChild(tbl);
160 YAHOO.util.Dom.get('lang_stats').appendChild(tbl);
159 </script>
161 </script>
160
162
161 </div>
163 </div>
162 </div>
164 </div>
163
165
164 <div class="field">
166 <div class="field">
165 <div class="label">
167 <div class="label">
166 <label>${_('Download')}:</label>
168 <label>${_('Download')}:</label>
167 </div>
169 </div>
168 <div class="input-short">
170 <div class="input-short">
169 %for cnt,archive in enumerate(c.repo_info._get_archives()):
171 %for cnt,archive in enumerate(c.repo_info._get_archives()):
170 %if cnt >=1:
172 %if cnt >=1:
171 |
173 |
172 %endif
174 %endif
173 ${h.link_to(c.repo_info.name+'.'+archive['type'],
175 ${h.link_to(c.repo_info.name+'.'+archive['type'],
174 h.url('files_archive_home',repo_name=c.repo_info.name,
176 h.url('files_archive_home',repo_name=c.repo_info.name,
175 revision='tip',fileformat=archive['extension']),class_="archive_icon")}
177 revision='tip',fileformat=archive['extension']),class_="archive_icon")}
176 %endfor
178 %endfor
177 </div>
179 </div>
178 </div>
180 </div>
179
181
180 <div class="field">
182 <div class="field">
181 <div class="label">
183 <div class="label">
182 <label>${_('Feeds')}:</label>
184 <label>${_('Feeds')}:</label>
183 </div>
185 </div>
184 <div class="input-short">
186 <div class="input-short">
185 ${h.link_to(_('RSS'),h.url('rss_feed_home',repo_name=c.repo_info.name),class_='rss_icon')}
187 ${h.link_to(_('RSS'),h.url('rss_feed_home',repo_name=c.repo_info.name),class_='rss_icon')}
186 ${h.link_to(_('Atom'),h.url('atom_feed_home',repo_name=c.repo_info.name),class_='atom_icon')}
188 ${h.link_to(_('Atom'),h.url('atom_feed_home',repo_name=c.repo_info.name),class_='atom_icon')}
187 </div>
189 </div>
188 </div>
190 </div>
189 </div>
191 </div>
190 </div>
192 </div>
191 </div>
193 </div>
192
194
193 <div class="box box-right" style="min-height:455px">
195 <div class="box box-right" style="min-height:455px">
194 <!-- box / title -->
196 <!-- box / title -->
195 <div class="title">
197 <div class="title">
196 <h5>${_('Commit activity by day / author')}</h5>
198 <h5>${_('Commit activity by day / author')}</h5>
197 </div>
199 </div>
198
200
199 <div class="table">
201 <div class="table">
200 <div id="commit_history" style="width:560px;height:300px;float:left"></div>
202 <div id="commit_history" style="width:560px;height:300px;float:left"></div>
201 <div style="clear: both;height: 10px"></div>
203 <div style="clear: both;height: 10px"></div>
202 <div id="overview" style="width:560px;height:100px;float:left"></div>
204 <div id="overview" style="width:560px;height:100px;float:left"></div>
203
205
204 <div id="legend_data" style="clear:both;margin-top:10px;">
206 <div id="legend_data" style="clear:both;margin-top:10px;">
205 <div id="legend_container"></div>
207 <div id="legend_container"></div>
206 <div id="legend_choices">
208 <div id="legend_choices">
207 <table id="legend_choices_tables" style="font-size:smaller;color:#545454"></table>
209 <table id="legend_choices_tables" style="font-size:smaller;color:#545454"></table>
208 </div>
210 </div>
209 </div>
211 </div>
210 <script type="text/javascript">
212 <script type="text/javascript">
211 /**
213 /**
212 * Plots summary graph
214 * Plots summary graph
213 *
215 *
214 * @class SummaryPlot
216 * @class SummaryPlot
215 * @param {from} initial from for detailed graph
217 * @param {from} initial from for detailed graph
216 * @param {to} initial to for detailed graph
218 * @param {to} initial to for detailed graph
217 * @param {dataset}
219 * @param {dataset}
218 * @param {overview_dataset}
220 * @param {overview_dataset}
219 */
221 */
220 function SummaryPlot(from,to,dataset,overview_dataset) {
222 function SummaryPlot(from,to,dataset,overview_dataset) {
221 var initial_ranges = {
223 var initial_ranges = {
222 "xaxis":{
224 "xaxis":{
223 "from":from,
225 "from":from,
224 "to":to,
226 "to":to,
225 },
227 },
226 };
228 };
227 var dataset = dataset;
229 var dataset = dataset;
228 var overview_dataset = [overview_dataset];
230 var overview_dataset = [overview_dataset];
229 var choiceContainer = YAHOO.util.Dom.get("legend_choices");
231 var choiceContainer = YAHOO.util.Dom.get("legend_choices");
230 var choiceContainerTable = YAHOO.util.Dom.get("legend_choices_tables");
232 var choiceContainerTable = YAHOO.util.Dom.get("legend_choices_tables");
231 var plotContainer = YAHOO.util.Dom.get('commit_history');
233 var plotContainer = YAHOO.util.Dom.get('commit_history');
232 var overviewContainer = YAHOO.util.Dom.get('overview');
234 var overviewContainer = YAHOO.util.Dom.get('overview');
233
235
234 var plot_options = {
236 var plot_options = {
235 bars: {show:true,align:'center',lineWidth:4},
237 bars: {show:true,align:'center',lineWidth:4},
236 legend: {show:true, container:"legend_container"},
238 legend: {show:true, container:"legend_container"},
237 points: {show:true,radius:0,fill:false},
239 points: {show:true,radius:0,fill:false},
238 yaxis: {tickDecimals:0,},
240 yaxis: {tickDecimals:0,},
239 xaxis: {
241 xaxis: {
240 mode: "time",
242 mode: "time",
241 timeformat: "%d/%m",
243 timeformat: "%d/%m",
242 min:from,
244 min:from,
243 max:to,
245 max:to,
244 },
246 },
245 grid: {
247 grid: {
246 hoverable: true,
248 hoverable: true,
247 clickable: true,
249 clickable: true,
248 autoHighlight:true,
250 autoHighlight:true,
249 color: "#999"
251 color: "#999"
250 },
252 },
251 //selection: {mode: "x"}
253 //selection: {mode: "x"}
252 };
254 };
253 var overview_options = {
255 var overview_options = {
254 legend:{show:false},
256 legend:{show:false},
255 bars: {show:true,barWidth: 2,},
257 bars: {show:true,barWidth: 2,},
256 shadowSize: 0,
258 shadowSize: 0,
257 xaxis: {mode: "time", timeformat: "%d/%m/%y",},
259 xaxis: {mode: "time", timeformat: "%d/%m/%y",},
258 yaxis: {ticks: 3, min: 0,},
260 yaxis: {ticks: 3, min: 0,},
259 grid: {color: "#999",},
261 grid: {color: "#999",},
260 selection: {mode: "x"}
262 selection: {mode: "x"}
261 };
263 };
262
264
263 /**
265 /**
264 *get dummy data needed in few places
266 *get dummy data needed in few places
265 */
267 */
266 function getDummyData(label){
268 function getDummyData(label){
267 return {"label":label,
269 return {"label":label,
268 "data":[{"time":0,
270 "data":[{"time":0,
269 "commits":0,
271 "commits":0,
270 "added":0,
272 "added":0,
271 "changed":0,
273 "changed":0,
272 "removed":0,
274 "removed":0,
273 }],
275 }],
274 "schema":["commits"],
276 "schema":["commits"],
275 "color":'#ffffff',
277 "color":'#ffffff',
276 }
278 }
277 }
279 }
278
280
279 /**
281 /**
280 * generate checkboxes accordindly to data
282 * generate checkboxes accordindly to data
281 * @param keys
283 * @param keys
282 * @returns
284 * @returns
283 */
285 */
284 function generateCheckboxes(data) {
286 function generateCheckboxes(data) {
285 //append checkboxes
287 //append checkboxes
286 var i = 0;
288 var i = 0;
287 choiceContainerTable.innerHTML = '';
289 choiceContainerTable.innerHTML = '';
288 for(var pos in data) {
290 for(var pos in data) {
289
291
290 data[pos].color = i;
292 data[pos].color = i;
291 i++;
293 i++;
292 if(data[pos].label != ''){
294 if(data[pos].label != ''){
293 choiceContainerTable.innerHTML += '<tr><td>'+
295 choiceContainerTable.innerHTML += '<tr><td>'+
294 '<input type="checkbox" name="' + data[pos].label +'" checked="checked" />'
296 '<input type="checkbox" name="' + data[pos].label +'" checked="checked" />'
295 +data[pos].label+
297 +data[pos].label+
296 '</td></tr>';
298 '</td></tr>';
297 }
299 }
298 }
300 }
299 }
301 }
300
302
301 /**
303 /**
302 * ToolTip show
304 * ToolTip show
303 */
305 */
304 function showTooltip(x, y, contents) {
306 function showTooltip(x, y, contents) {
305 var div=document.getElementById('tooltip');
307 var div=document.getElementById('tooltip');
306 if(!div) {
308 if(!div) {
307 div = document.createElement('div');
309 div = document.createElement('div');
308 div.id="tooltip";
310 div.id="tooltip";
309 div.style.position="absolute";
311 div.style.position="absolute";
310 div.style.border='1px solid #fdd';
312 div.style.border='1px solid #fdd';
311 div.style.padding='2px';
313 div.style.padding='2px';
312 div.style.backgroundColor='#fee';
314 div.style.backgroundColor='#fee';
313 document.body.appendChild(div);
315 document.body.appendChild(div);
314 }
316 }
315 YAHOO.util.Dom.setStyle(div, 'opacity', 0);
317 YAHOO.util.Dom.setStyle(div, 'opacity', 0);
316 div.innerHTML = contents;
318 div.innerHTML = contents;
317 div.style.top=(y + 5) + "px";
319 div.style.top=(y + 5) + "px";
318 div.style.left=(x + 5) + "px";
320 div.style.left=(x + 5) + "px";
319
321
320 var anim = new YAHOO.util.Anim(div, {opacity: {to: 0.8}}, 0.2);
322 var anim = new YAHOO.util.Anim(div, {opacity: {to: 0.8}}, 0.2);
321 anim.animate();
323 anim.animate();
322 }
324 }
323
325
324 /**
326 /**
325 * This function will detect if selected period has some changesets for this user
327 * This function will detect if selected period has some changesets for this user
326 if it does this data is then pushed for displaying
328 if it does this data is then pushed for displaying
327 Additionally it will only display users that are selected by the checkbox
329 Additionally it will only display users that are selected by the checkbox
328 */
330 */
329 function getDataAccordingToRanges(ranges) {
331 function getDataAccordingToRanges(ranges) {
330
332
331 var data = [];
333 var data = [];
332 var keys = [];
334 var keys = [];
333 for(var key in dataset){
335 for(var key in dataset){
334 var push = false;
336 var push = false;
335 //method1 slow !!
337 //method1 slow !!
336 ///*
338 ///*
337 for(var ds in dataset[key].data){
339 for(var ds in dataset[key].data){
338 commit_data = dataset[key].data[ds];
340 commit_data = dataset[key].data[ds];
339 //console.log(key);
341 //console.log(key);
340 //console.log(new Date(commit_data.time*1000));
342 //console.log(new Date(commit_data.time*1000));
341 //console.log(new Date(ranges.xaxis.from*1000));
343 //console.log(new Date(ranges.xaxis.from*1000));
342 //console.log(new Date(ranges.xaxis.to*1000));
344 //console.log(new Date(ranges.xaxis.to*1000));
343 if (commit_data.time >= ranges.xaxis.from && commit_data.time <= ranges.xaxis.to){
345 if (commit_data.time >= ranges.xaxis.from && commit_data.time <= ranges.xaxis.to){
344 push = true;
346 push = true;
345 break;
347 break;
346 }
348 }
347 }
349 }
348 //*/
350 //*/
349 /*//method2 sorted commit data !!!
351 /*//method2 sorted commit data !!!
350 var first_commit = dataset[key].data[0].time;
352 var first_commit = dataset[key].data[0].time;
351 var last_commit = dataset[key].data[dataset[key].data.length-1].time;
353 var last_commit = dataset[key].data[dataset[key].data.length-1].time;
352
354
353 console.log(first_commit);
355 console.log(first_commit);
354 console.log(last_commit);
356 console.log(last_commit);
355
357
356 if (first_commit >= ranges.xaxis.from && last_commit <= ranges.xaxis.to){
358 if (first_commit >= ranges.xaxis.from && last_commit <= ranges.xaxis.to){
357 push = true;
359 push = true;
358 }
360 }
359 */
361 */
360 if(push){
362 if(push){
361 data.push(dataset[key]);
363 data.push(dataset[key]);
362 }
364 }
363 }
365 }
364 if(data.length >= 1){
366 if(data.length >= 1){
365 return data;
367 return data;
366 }
368 }
367 else{
369 else{
368 //just return dummy data for graph to plot itself
370 //just return dummy data for graph to plot itself
369 return [getDummyData('')];
371 return [getDummyData('')];
370 }
372 }
371
373
372 }
374 }
373
375
374 /**
376 /**
375 * redraw using new checkbox data
377 * redraw using new checkbox data
376 */
378 */
377 function plotchoiced(e,args){
379 function plotchoiced(e,args){
378 var cur_data = args[0];
380 var cur_data = args[0];
379 var cur_ranges = args[1];
381 var cur_ranges = args[1];
380
382
381 var new_data = [];
383 var new_data = [];
382 var inputs = choiceContainer.getElementsByTagName("input");
384 var inputs = choiceContainer.getElementsByTagName("input");
383
385
384 //show only checked labels
386 //show only checked labels
385 for(var i=0; i<inputs.length; i++) {
387 for(var i=0; i<inputs.length; i++) {
386 var checkbox_key = inputs[i].name;
388 var checkbox_key = inputs[i].name;
387
389
388 if(inputs[i].checked){
390 if(inputs[i].checked){
389 for(var d in cur_data){
391 for(var d in cur_data){
390 if(cur_data[d].label == checkbox_key){
392 if(cur_data[d].label == checkbox_key){
391 new_data.push(cur_data[d]);
393 new_data.push(cur_data[d]);
392 }
394 }
393 }
395 }
394 }
396 }
395 else{
397 else{
396 //push dummy data to not hide the label
398 //push dummy data to not hide the label
397 new_data.push(getDummyData(checkbox_key));
399 new_data.push(getDummyData(checkbox_key));
398 }
400 }
399 }
401 }
400
402
401 var new_options = YAHOO.lang.merge(plot_options, {
403 var new_options = YAHOO.lang.merge(plot_options, {
402 xaxis: {
404 xaxis: {
403 min: cur_ranges.xaxis.from,
405 min: cur_ranges.xaxis.from,
404 max: cur_ranges.xaxis.to,
406 max: cur_ranges.xaxis.to,
405 mode:"time",
407 mode:"time",
406 timeformat: "%d/%m",
408 timeformat: "%d/%m",
407 }
409 }
408 });
410 });
409 if (!new_data){
411 if (!new_data){
410 new_data = [[0,1]];
412 new_data = [[0,1]];
411 }
413 }
412 // do the zooming
414 // do the zooming
413 plot = YAHOO.widget.Flot(plotContainer, new_data, new_options);
415 plot = YAHOO.widget.Flot(plotContainer, new_data, new_options);
414
416
415 plot.subscribe("plotselected", plotselected);
417 plot.subscribe("plotselected", plotselected);
416
418
417 //resubscribe plothover
419 //resubscribe plothover
418 plot.subscribe("plothover", plothover);
420 plot.subscribe("plothover", plothover);
419
421
420 // don't fire event on the overview to prevent eternal loop
422 // don't fire event on the overview to prevent eternal loop
421 overview.setSelection(cur_ranges, true);
423 overview.setSelection(cur_ranges, true);
422
424
423 }
425 }
424
426
425 /**
427 /**
426 * plot only selected items from overview
428 * plot only selected items from overview
427 * @param ranges
429 * @param ranges
428 * @returns
430 * @returns
429 */
431 */
430 function plotselected(ranges,cur_data) {
432 function plotselected(ranges,cur_data) {
431 //updates the data for new plot
433 //updates the data for new plot
432 data = getDataAccordingToRanges(ranges);
434 data = getDataAccordingToRanges(ranges);
433 generateCheckboxes(data);
435 generateCheckboxes(data);
434
436
435 var new_options = YAHOO.lang.merge(plot_options, {
437 var new_options = YAHOO.lang.merge(plot_options, {
436 xaxis: {
438 xaxis: {
437 min: ranges.xaxis.from,
439 min: ranges.xaxis.from,
438 max: ranges.xaxis.to,
440 max: ranges.xaxis.to,
439 mode:"time",
441 mode:"time",
440 timeformat: "%d/%m",
442 timeformat: "%d/%m",
441 }
443 }
442 });
444 });
443 // do the zooming
445 // do the zooming
444 plot = YAHOO.widget.Flot(plotContainer, data, new_options);
446 plot = YAHOO.widget.Flot(plotContainer, data, new_options);
445
447
446 plot.subscribe("plotselected", plotselected);
448 plot.subscribe("plotselected", plotselected);
447
449
448 //resubscribe plothover
450 //resubscribe plothover
449 plot.subscribe("plothover", plothover);
451 plot.subscribe("plothover", plothover);
450
452
451 // don't fire event on the overview to prevent eternal loop
453 // don't fire event on the overview to prevent eternal loop
452 overview.setSelection(ranges, true);
454 overview.setSelection(ranges, true);
453
455
454 //resubscribe choiced
456 //resubscribe choiced
455 YAHOO.util.Event.on(choiceContainer.getElementsByTagName("input"), "click", plotchoiced, [data, ranges]);
457 YAHOO.util.Event.on(choiceContainer.getElementsByTagName("input"), "click", plotchoiced, [data, ranges]);
456 }
458 }
457
459
458 var previousPoint = null;
460 var previousPoint = null;
459
461
460 function plothover(o) {
462 function plothover(o) {
461 var pos = o.pos;
463 var pos = o.pos;
462 var item = o.item;
464 var item = o.item;
463
465
464 //YAHOO.util.Dom.get("x").innerHTML = pos.x.toFixed(2);
466 //YAHOO.util.Dom.get("x").innerHTML = pos.x.toFixed(2);
465 //YAHOO.util.Dom.get("y").innerHTML = pos.y.toFixed(2);
467 //YAHOO.util.Dom.get("y").innerHTML = pos.y.toFixed(2);
466 if (item) {
468 if (item) {
467 if (previousPoint != item.datapoint) {
469 if (previousPoint != item.datapoint) {
468 previousPoint = item.datapoint;
470 previousPoint = item.datapoint;
469
471
470 var tooltip = YAHOO.util.Dom.get("tooltip");
472 var tooltip = YAHOO.util.Dom.get("tooltip");
471 if(tooltip) {
473 if(tooltip) {
472 tooltip.parentNode.removeChild(tooltip);
474 tooltip.parentNode.removeChild(tooltip);
473 }
475 }
474 var x = item.datapoint.x.toFixed(2);
476 var x = item.datapoint.x.toFixed(2);
475 var y = item.datapoint.y.toFixed(2);
477 var y = item.datapoint.y.toFixed(2);
476
478
477 if (!item.series.label){
479 if (!item.series.label){
478 item.series.label = 'commits';
480 item.series.label = 'commits';
479 }
481 }
480 var d = new Date(x*1000);
482 var d = new Date(x*1000);
481 var fd = d.toDateString()
483 var fd = d.toDateString()
482 var nr_commits = parseInt(y);
484 var nr_commits = parseInt(y);
483
485
484 var cur_data = dataset[item.series.label].data[item.dataIndex];
486 var cur_data = dataset[item.series.label].data[item.dataIndex];
485 var added = cur_data.added;
487 var added = cur_data.added;
486 var changed = cur_data.changed;
488 var changed = cur_data.changed;
487 var removed = cur_data.removed;
489 var removed = cur_data.removed;
488
490
489 var nr_commits_suffix = " ${_('commits')} ";
491 var nr_commits_suffix = " ${_('commits')} ";
490 var added_suffix = " ${_('files added')} ";
492 var added_suffix = " ${_('files added')} ";
491 var changed_suffix = " ${_('files changed')} ";
493 var changed_suffix = " ${_('files changed')} ";
492 var removed_suffix = " ${_('files removed')} ";
494 var removed_suffix = " ${_('files removed')} ";
493
495
494
496
495 if(nr_commits == 1){nr_commits_suffix = " ${_('commit')} ";}
497 if(nr_commits == 1){nr_commits_suffix = " ${_('commit')} ";}
496 if(added==1){added_suffix=" ${_('file added')} ";}
498 if(added==1){added_suffix=" ${_('file added')} ";}
497 if(changed==1){changed_suffix=" ${_('file changed')} ";}
499 if(changed==1){changed_suffix=" ${_('file changed')} ";}
498 if(removed==1){removed_suffix=" ${_('file removed')} ";}
500 if(removed==1){removed_suffix=" ${_('file removed')} ";}
499
501
500 showTooltip(item.pageX, item.pageY, item.series.label + " on " + fd
502 showTooltip(item.pageX, item.pageY, item.series.label + " on " + fd
501 +'<br/>'+
503 +'<br/>'+
502 nr_commits + nr_commits_suffix+'<br/>'+
504 nr_commits + nr_commits_suffix+'<br/>'+
503 added + added_suffix +'<br/>'+
505 added + added_suffix +'<br/>'+
504 changed + changed_suffix + '<br/>'+
506 changed + changed_suffix + '<br/>'+
505 removed + removed_suffix + '<br/>');
507 removed + removed_suffix + '<br/>');
506 }
508 }
507 }
509 }
508 else {
510 else {
509 var tooltip = YAHOO.util.Dom.get("tooltip");
511 var tooltip = YAHOO.util.Dom.get("tooltip");
510
512
511 if(tooltip) {
513 if(tooltip) {
512 tooltip.parentNode.removeChild(tooltip);
514 tooltip.parentNode.removeChild(tooltip);
513 }
515 }
514 previousPoint = null;
516 previousPoint = null;
515 }
517 }
516 }
518 }
517
519
518 /**
520 /**
519 * MAIN EXECUTION
521 * MAIN EXECUTION
520 */
522 */
521
523
522 var data = getDataAccordingToRanges(initial_ranges);
524 var data = getDataAccordingToRanges(initial_ranges);
523 generateCheckboxes(data);
525 generateCheckboxes(data);
524
526
525 //main plot
527 //main plot
526 var plot = YAHOO.widget.Flot(plotContainer,data,plot_options);
528 var plot = YAHOO.widget.Flot(plotContainer,data,plot_options);
527
529
528 //overview
530 //overview
529 var overview = YAHOO.widget.Flot(overviewContainer, overview_dataset, overview_options);
531 var overview = YAHOO.widget.Flot(overviewContainer, overview_dataset, overview_options);
530
532
531 //show initial selection on overview
533 //show initial selection on overview
532 overview.setSelection(initial_ranges);
534 overview.setSelection(initial_ranges);
533
535
534 plot.subscribe("plotselected", plotselected);
536 plot.subscribe("plotselected", plotselected);
535
537
536 overview.subscribe("plotselected", function (ranges) {
538 overview.subscribe("plotselected", function (ranges) {
537 plot.setSelection(ranges);
539 plot.setSelection(ranges);
538 });
540 });
539
541
540 plot.subscribe("plothover", plothover);
542 plot.subscribe("plothover", plothover);
541
543
542 YAHOO.util.Event.on(choiceContainer.getElementsByTagName("input"), "click", plotchoiced, [data, initial_ranges]);
544 YAHOO.util.Event.on(choiceContainer.getElementsByTagName("input"), "click", plotchoiced, [data, initial_ranges]);
543 }
545 }
544 SummaryPlot(${c.ts_min},${c.ts_max},${c.commit_data|n},${c.overview_data|n});
546 SummaryPlot(${c.ts_min},${c.ts_max},${c.commit_data|n},${c.overview_data|n});
545 </script>
547 </script>
546
548
547 </div>
549 </div>
548 </div>
550 </div>
549
551
550 <div class="box">
552 <div class="box">
551 <div class="title">
553 <div class="title">
552 <div class="breadcrumbs">${h.link_to(_('Last ten changes'),h.url('changelog_home',repo_name=c.repo_name))}</div>
554 <div class="breadcrumbs">${h.link_to(_('Last ten changes'),h.url('changelog_home',repo_name=c.repo_name))}</div>
553 </div>
555 </div>
554 <div class="table">
556 <div class="table">
555 <%include file='../shortlog/shortlog_data.html'/>
557 <%include file='../shortlog/shortlog_data.html'/>
556 %if c.repo_changesets:
558 %if c.repo_changesets:
557 ${h.link_to(_('show more'),h.url('changelog_home',repo_name=c.repo_name))}
559 ${h.link_to(_('show more'),h.url('changelog_home',repo_name=c.repo_name))}
558 %endif
560 %endif
559 </div>
561 </div>
560 </div>
562 </div>
561 <div class="box">
563 <div class="box">
562 <div class="title">
564 <div class="title">
563 <div class="breadcrumbs">${h.link_to(_('Last ten tags'),h.url('tags_home',repo_name=c.repo_name))}</div>
565 <div class="breadcrumbs">${h.link_to(_('Last ten tags'),h.url('tags_home',repo_name=c.repo_name))}</div>
564 </div>
566 </div>
565 <div class="table">
567 <div class="table">
566 <%include file='../tags/tags_data.html'/>
568 <%include file='../tags/tags_data.html'/>
567 %if c.repo_changesets:
569 %if c.repo_changesets:
568 ${h.link_to(_('show more'),h.url('tags_home',repo_name=c.repo_name))}
570 ${h.link_to(_('show more'),h.url('tags_home',repo_name=c.repo_name))}
569 %endif
571 %endif
570 </div>
572 </div>
571 </div>
573 </div>
572 <div class="box">
574 <div class="box">
573 <div class="title">
575 <div class="title">
574 <div class="breadcrumbs">${h.link_to(_('Last ten branches'),h.url('branches_home',repo_name=c.repo_name))}</div>
576 <div class="breadcrumbs">${h.link_to(_('Last ten branches'),h.url('branches_home',repo_name=c.repo_name))}</div>
575 </div>
577 </div>
576 <div class="table">
578 <div class="table">
577 <%include file='../branches/branches_data.html'/>
579 <%include file='../branches/branches_data.html'/>
578 %if c.repo_changesets:
580 %if c.repo_changesets:
579 ${h.link_to(_('show more'),h.url('branches_home',repo_name=c.repo_name))}
581 ${h.link_to(_('show more'),h.url('branches_home',repo_name=c.repo_name))}
580 %endif
582 %endif
581 </div>
583 </div>
582 </div>
584 </div>
583
585
584 </%def> No newline at end of file
586 </%def>
General Comments 0
You need to be logged in to leave comments. Login now