Show More
@@ -1,1393 +1,1392 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 | 3 | # Copyright (C) 2011-2019 RhodeCode GmbH |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
7 | 7 | # (only), as published by the Free Software Foundation. |
|
8 | 8 | # |
|
9 | 9 | # This program is distributed in the hope that it will be useful, |
|
10 | 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 | 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
12 | 12 | # GNU General Public License for more details. |
|
13 | 13 | # |
|
14 | 14 | # You should have received a copy of the GNU Affero General Public License |
|
15 | 15 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
16 | 16 | # |
|
17 | 17 | # This program is dual-licensed. If you wish to learn more about the |
|
18 | 18 | # RhodeCode Enterprise Edition, including its added features, Support services, |
|
19 | 19 | # and proprietary license terms, please see https://rhodecode.com/licenses/ |
|
20 | 20 | |
|
21 | 21 | import itertools |
|
22 | 22 | import logging |
|
23 | 23 | import os |
|
24 | 24 | import shutil |
|
25 | 25 | import tempfile |
|
26 | 26 | import collections |
|
27 | 27 | import urllib |
|
28 | 28 | |
|
29 | 29 | from pyramid.httpexceptions import HTTPNotFound, HTTPBadRequest, HTTPFound |
|
30 | 30 | from pyramid.view import view_config |
|
31 | 31 | from pyramid.renderers import render |
|
32 | 32 | from pyramid.response import Response |
|
33 | 33 | |
|
34 | 34 | import rhodecode |
|
35 | 35 | from rhodecode.apps._base import RepoAppView |
|
36 | 36 | |
|
37 | 37 | |
|
38 | 38 | from rhodecode.lib import diffs, helpers as h, rc_cache |
|
39 | 39 | from rhodecode.lib import audit_logger |
|
40 | 40 | from rhodecode.lib.view_utils import parse_path_ref |
|
41 | 41 | from rhodecode.lib.exceptions import NonRelativePathError |
|
42 | 42 | from rhodecode.lib.codeblocks import ( |
|
43 | 43 | filenode_as_lines_tokens, filenode_as_annotated_lines_tokens) |
|
44 | 44 | from rhodecode.lib.utils2 import ( |
|
45 | 45 | convert_line_endings, detect_mode, safe_str, str2bool, safe_int) |
|
46 | 46 | from rhodecode.lib.auth import ( |
|
47 | 47 | LoginRequired, HasRepoPermissionAnyDecorator, CSRFRequired) |
|
48 | 48 | from rhodecode.lib.vcs import path as vcspath |
|
49 | 49 | from rhodecode.lib.vcs.backends.base import EmptyCommit |
|
50 | 50 | from rhodecode.lib.vcs.conf import settings |
|
51 | 51 | from rhodecode.lib.vcs.nodes import FileNode |
|
52 | 52 | from rhodecode.lib.vcs.exceptions import ( |
|
53 | 53 | RepositoryError, CommitDoesNotExistError, EmptyRepositoryError, |
|
54 | 54 | ImproperArchiveTypeError, VCSError, NodeAlreadyExistsError, |
|
55 | 55 | NodeDoesNotExistError, CommitError, NodeError) |
|
56 | 56 | |
|
57 | 57 | from rhodecode.model.scm import ScmModel |
|
58 | 58 | from rhodecode.model.db import Repository |
|
59 | 59 | |
|
60 | 60 | log = logging.getLogger(__name__) |
|
61 | 61 | |
|
62 | 62 | |
|
63 | 63 | class RepoFilesView(RepoAppView): |
|
64 | 64 | |
|
65 | 65 | @staticmethod |
|
66 | 66 | def adjust_file_path_for_svn(f_path, repo): |
|
67 | 67 | """ |
|
68 | 68 | Computes the relative path of `f_path`. |
|
69 | 69 | |
|
70 | 70 | This is mainly based on prefix matching of the recognized tags and |
|
71 | 71 | branches in the underlying repository. |
|
72 | 72 | """ |
|
73 | 73 | tags_and_branches = itertools.chain( |
|
74 | 74 | repo.branches.iterkeys(), |
|
75 | 75 | repo.tags.iterkeys()) |
|
76 | 76 | tags_and_branches = sorted(tags_and_branches, key=len, reverse=True) |
|
77 | 77 | |
|
78 | 78 | for name in tags_and_branches: |
|
79 | 79 | if f_path.startswith('{}/'.format(name)): |
|
80 | 80 | f_path = vcspath.relpath(f_path, name) |
|
81 | 81 | break |
|
82 | 82 | return f_path |
|
83 | 83 | |
|
84 | 84 | def load_default_context(self): |
|
85 | 85 | c = self._get_local_tmpl_context(include_app_defaults=True) |
|
86 | 86 | c.rhodecode_repo = self.rhodecode_vcs_repo |
|
87 | 87 | c.enable_downloads = self.db_repo.enable_downloads |
|
88 | 88 | return c |
|
89 | 89 | |
|
90 | 90 | def _ensure_not_locked(self): |
|
91 | 91 | _ = self.request.translate |
|
92 | 92 | |
|
93 | 93 | repo = self.db_repo |
|
94 | 94 | if repo.enable_locking and repo.locked[0]: |
|
95 | 95 | h.flash(_('This repository has been locked by %s on %s') |
|
96 | 96 | % (h.person_by_id(repo.locked[0]), |
|
97 | 97 | h.format_date(h.time_to_datetime(repo.locked[1]))), |
|
98 | 98 | 'warning') |
|
99 | 99 | files_url = h.route_path( |
|
100 | 100 | 'repo_files:default_path', |
|
101 | 101 | repo_name=self.db_repo_name, commit_id='tip') |
|
102 | 102 | raise HTTPFound(files_url) |
|
103 | 103 | |
|
104 | 104 | def check_branch_permission(self, branch_name): |
|
105 | 105 | _ = self.request.translate |
|
106 | 106 | |
|
107 | 107 | rule, branch_perm = self._rhodecode_user.get_rule_and_branch_permission( |
|
108 | 108 | self.db_repo_name, branch_name) |
|
109 | 109 | if branch_perm and branch_perm not in ['branch.push', 'branch.push_force']: |
|
110 | 110 | h.flash( |
|
111 | 111 | _('Branch `{}` changes forbidden by rule {}.').format(branch_name, rule), |
|
112 | 112 | 'warning') |
|
113 | 113 | files_url = h.route_path( |
|
114 | 114 | 'repo_files:default_path', |
|
115 | 115 | repo_name=self.db_repo_name, commit_id='tip') |
|
116 | 116 | raise HTTPFound(files_url) |
|
117 | 117 | |
|
118 | 118 | def _get_commit_and_path(self): |
|
119 | 119 | default_commit_id = self.db_repo.landing_rev[1] |
|
120 | 120 | default_f_path = '/' |
|
121 | 121 | |
|
122 | 122 | commit_id = self.request.matchdict.get( |
|
123 | 123 | 'commit_id', default_commit_id) |
|
124 | 124 | f_path = self._get_f_path(self.request.matchdict, default_f_path) |
|
125 | 125 | return commit_id, f_path |
|
126 | 126 | |
|
127 | 127 | def _get_default_encoding(self, c): |
|
128 | 128 | enc_list = getattr(c, 'default_encodings', []) |
|
129 | 129 | return enc_list[0] if enc_list else 'UTF-8' |
|
130 | 130 | |
|
131 | 131 | def _get_commit_or_redirect(self, commit_id, redirect_after=True): |
|
132 | 132 | """ |
|
133 | 133 | This is a safe way to get commit. If an error occurs it redirects to |
|
134 | 134 | tip with proper message |
|
135 | 135 | |
|
136 | 136 | :param commit_id: id of commit to fetch |
|
137 | 137 | :param redirect_after: toggle redirection |
|
138 | 138 | """ |
|
139 | 139 | _ = self.request.translate |
|
140 | 140 | |
|
141 | 141 | try: |
|
142 | 142 | return self.rhodecode_vcs_repo.get_commit(commit_id) |
|
143 | 143 | except EmptyRepositoryError: |
|
144 | 144 | if not redirect_after: |
|
145 | 145 | return None |
|
146 | 146 | |
|
147 | 147 | _url = h.route_path( |
|
148 | 148 | 'repo_files_add_file', |
|
149 | 149 | repo_name=self.db_repo_name, commit_id=0, f_path='', |
|
150 | 150 | _anchor='edit') |
|
151 | 151 | |
|
152 | 152 | if h.HasRepoPermissionAny( |
|
153 | 153 | 'repository.write', 'repository.admin')(self.db_repo_name): |
|
154 | 154 | add_new = h.link_to( |
|
155 | 155 | _('Click here to add a new file.'), _url, class_="alert-link") |
|
156 | 156 | else: |
|
157 | 157 | add_new = "" |
|
158 | 158 | |
|
159 | 159 | h.flash(h.literal( |
|
160 | 160 | _('There are no files yet. %s') % add_new), category='warning') |
|
161 | 161 | raise HTTPFound( |
|
162 | 162 | h.route_path('repo_summary', repo_name=self.db_repo_name)) |
|
163 | 163 | |
|
164 | 164 | except (CommitDoesNotExistError, LookupError): |
|
165 | 165 | msg = _('No such commit exists for this repository') |
|
166 | 166 | h.flash(msg, category='error') |
|
167 | 167 | raise HTTPNotFound() |
|
168 | 168 | except RepositoryError as e: |
|
169 | 169 | h.flash(safe_str(h.escape(e)), category='error') |
|
170 | 170 | raise HTTPNotFound() |
|
171 | 171 | |
|
172 | 172 | def _get_filenode_or_redirect(self, commit_obj, path): |
|
173 | 173 | """ |
|
174 | 174 | Returns file_node, if error occurs or given path is directory, |
|
175 | 175 | it'll redirect to top level path |
|
176 | 176 | """ |
|
177 | 177 | _ = self.request.translate |
|
178 | 178 | |
|
179 | 179 | try: |
|
180 | 180 | file_node = commit_obj.get_node(path) |
|
181 | 181 | if file_node.is_dir(): |
|
182 | 182 | raise RepositoryError('The given path is a directory') |
|
183 | 183 | except CommitDoesNotExistError: |
|
184 | 184 | log.exception('No such commit exists for this repository') |
|
185 | 185 | h.flash(_('No such commit exists for this repository'), category='error') |
|
186 | 186 | raise HTTPNotFound() |
|
187 | 187 | except RepositoryError as e: |
|
188 | 188 | log.warning('Repository error while fetching ' |
|
189 | 189 | 'filenode `%s`. Err:%s', path, e) |
|
190 | 190 | h.flash(safe_str(h.escape(e)), category='error') |
|
191 | 191 | raise HTTPNotFound() |
|
192 | 192 | |
|
193 | 193 | return file_node |
|
194 | 194 | |
|
195 | 195 | def _is_valid_head(self, commit_id, repo): |
|
196 | 196 | branch_name = sha_commit_id = '' |
|
197 | 197 | is_head = False |
|
198 | 198 | |
|
199 | 199 | if h.is_svn(repo) and not repo.is_empty(): |
|
200 | 200 | # Note: Subversion only has one head. |
|
201 | 201 | if commit_id == repo.get_commit(commit_idx=-1).raw_id: |
|
202 | 202 | is_head = True |
|
203 | 203 | return branch_name, sha_commit_id, is_head |
|
204 | 204 | |
|
205 | 205 | for _branch_name, branch_commit_id in repo.branches.items(): |
|
206 | 206 | # simple case we pass in branch name, it's a HEAD |
|
207 | 207 | if commit_id == _branch_name: |
|
208 | 208 | is_head = True |
|
209 | 209 | branch_name = _branch_name |
|
210 | 210 | sha_commit_id = branch_commit_id |
|
211 | 211 | break |
|
212 | 212 | # case when we pass in full sha commit_id, which is a head |
|
213 | 213 | elif commit_id == branch_commit_id: |
|
214 | 214 | is_head = True |
|
215 | 215 | branch_name = _branch_name |
|
216 | 216 | sha_commit_id = branch_commit_id |
|
217 | 217 | break |
|
218 | 218 | |
|
219 | 219 | # checked branches, means we only need to try to get the branch/commit_sha |
|
220 | 220 | if not repo.is_empty: |
|
221 | 221 | commit = repo.get_commit(commit_id=commit_id) |
|
222 | 222 | if commit: |
|
223 | 223 | branch_name = commit.branch |
|
224 | 224 | sha_commit_id = commit.raw_id |
|
225 | 225 | |
|
226 | 226 | return branch_name, sha_commit_id, is_head |
|
227 | 227 | |
|
228 | 228 | def _get_tree_at_commit(self, c, commit_id, f_path, full_load=False): |
|
229 | 229 | |
|
230 | 230 | repo_id = self.db_repo.repo_id |
|
231 | 231 | force_recache = self.get_recache_flag() |
|
232 | 232 | |
|
233 | 233 | cache_seconds = safe_int( |
|
234 | 234 | rhodecode.CONFIG.get('rc_cache.cache_repo.expiration_time')) |
|
235 | 235 | cache_on = not force_recache and cache_seconds > 0 |
|
236 | 236 | log.debug( |
|
237 | 237 | 'Computing FILE TREE for repo_id %s commit_id `%s` and path `%s`' |
|
238 | 238 | 'with caching: %s[TTL: %ss]' % ( |
|
239 | 239 | repo_id, commit_id, f_path, cache_on, cache_seconds or 0)) |
|
240 | 240 | |
|
241 | 241 | cache_namespace_uid = 'cache_repo.{}'.format(repo_id) |
|
242 | 242 | region = rc_cache.get_or_create_region('cache_repo', cache_namespace_uid) |
|
243 | 243 | |
|
244 | 244 | @region.conditional_cache_on_arguments(namespace=cache_namespace_uid, |
|
245 | 245 | condition=cache_on) |
|
246 | 246 | def compute_file_tree(repo_id, commit_id, f_path, full_load): |
|
247 | 247 | log.debug('Generating cached file tree for repo_id: %s, %s, %s', |
|
248 | 248 | repo_id, commit_id, f_path) |
|
249 | 249 | |
|
250 | 250 | c.full_load = full_load |
|
251 | 251 | return render( |
|
252 | 252 | 'rhodecode:templates/files/files_browser_tree.mako', |
|
253 | 253 | self._get_template_context(c), self.request) |
|
254 | 254 | |
|
255 | 255 | return compute_file_tree(self.db_repo.repo_id, commit_id, f_path, full_load) |
|
256 | 256 | |
|
257 | 257 | def _get_archive_spec(self, fname): |
|
258 | 258 | log.debug('Detecting archive spec for: `%s`', fname) |
|
259 | 259 | |
|
260 | 260 | fileformat = None |
|
261 | 261 | ext = None |
|
262 | 262 | content_type = None |
|
263 | 263 | for a_type, ext_data in settings.ARCHIVE_SPECS.items(): |
|
264 | 264 | content_type, extension = ext_data |
|
265 | 265 | |
|
266 | 266 | if fname.endswith(extension): |
|
267 | 267 | fileformat = a_type |
|
268 | 268 | log.debug('archive is of type: %s', fileformat) |
|
269 | 269 | ext = extension |
|
270 | 270 | break |
|
271 | 271 | |
|
272 | 272 | if not fileformat: |
|
273 | 273 | raise ValueError() |
|
274 | 274 | |
|
275 | 275 | # left over part of whole fname is the commit |
|
276 | 276 | commit_id = fname[:-len(ext)] |
|
277 | 277 | |
|
278 | 278 | return commit_id, ext, fileformat, content_type |
|
279 | 279 | |
|
280 | 280 | @LoginRequired() |
|
281 | 281 | @HasRepoPermissionAnyDecorator( |
|
282 | 282 | 'repository.read', 'repository.write', 'repository.admin') |
|
283 | 283 | @view_config( |
|
284 | 284 | route_name='repo_archivefile', request_method='GET', |
|
285 | 285 | renderer=None) |
|
286 | 286 | def repo_archivefile(self): |
|
287 | 287 | # archive cache config |
|
288 | 288 | from rhodecode import CONFIG |
|
289 | 289 | _ = self.request.translate |
|
290 | 290 | self.load_default_context() |
|
291 | 291 | |
|
292 | 292 | fname = self.request.matchdict['fname'] |
|
293 | 293 | subrepos = self.request.GET.get('subrepos') == 'true' |
|
294 | 294 | |
|
295 | 295 | if not self.db_repo.enable_downloads: |
|
296 | 296 | return Response(_('Downloads disabled')) |
|
297 | 297 | |
|
298 | 298 | try: |
|
299 | 299 | commit_id, ext, fileformat, content_type = \ |
|
300 | 300 | self._get_archive_spec(fname) |
|
301 | 301 | except ValueError: |
|
302 | 302 | return Response(_('Unknown archive type for: `{}`').format( |
|
303 | 303 | h.escape(fname))) |
|
304 | 304 | |
|
305 | 305 | try: |
|
306 | 306 | commit = self.rhodecode_vcs_repo.get_commit(commit_id) |
|
307 | 307 | except CommitDoesNotExistError: |
|
308 | 308 | return Response(_('Unknown commit_id {}').format( |
|
309 | 309 | h.escape(commit_id))) |
|
310 | 310 | except EmptyRepositoryError: |
|
311 | 311 | return Response(_('Empty repository')) |
|
312 | 312 | |
|
313 | 313 | archive_name = '%s-%s%s%s' % ( |
|
314 | 314 | safe_str(self.db_repo_name.replace('/', '_')), |
|
315 | 315 | '-sub' if subrepos else '', |
|
316 | 316 | safe_str(commit.short_id), ext) |
|
317 | 317 | |
|
318 | 318 | use_cached_archive = False |
|
319 | 319 | archive_cache_enabled = CONFIG.get( |
|
320 | 320 | 'archive_cache_dir') and not self.request.GET.get('no_cache') |
|
321 | 321 | cached_archive_path = None |
|
322 | 322 | |
|
323 | 323 | if archive_cache_enabled: |
|
324 | 324 | # check if we it's ok to write |
|
325 | 325 | if not os.path.isdir(CONFIG['archive_cache_dir']): |
|
326 | 326 | os.makedirs(CONFIG['archive_cache_dir']) |
|
327 | 327 | cached_archive_path = os.path.join( |
|
328 | 328 | CONFIG['archive_cache_dir'], archive_name) |
|
329 | 329 | if os.path.isfile(cached_archive_path): |
|
330 | 330 | log.debug('Found cached archive in %s', cached_archive_path) |
|
331 | 331 | fd, archive = None, cached_archive_path |
|
332 | 332 | use_cached_archive = True |
|
333 | 333 | else: |
|
334 | 334 | log.debug('Archive %s is not yet cached', archive_name) |
|
335 | 335 | |
|
336 | 336 | if not use_cached_archive: |
|
337 | 337 | # generate new archive |
|
338 | 338 | fd, archive = tempfile.mkstemp() |
|
339 | 339 | log.debug('Creating new temp archive in %s', archive) |
|
340 | 340 | try: |
|
341 | 341 | commit.archive_repo(archive, kind=fileformat, subrepos=subrepos) |
|
342 | 342 | except ImproperArchiveTypeError: |
|
343 | 343 | return _('Unknown archive type') |
|
344 | 344 | if archive_cache_enabled: |
|
345 | 345 | # if we generated the archive and we have cache enabled |
|
346 | 346 | # let's use this for future |
|
347 | 347 | log.debug('Storing new archive in %s', cached_archive_path) |
|
348 | 348 | shutil.move(archive, cached_archive_path) |
|
349 | 349 | archive = cached_archive_path |
|
350 | 350 | |
|
351 | 351 | # store download action |
|
352 | 352 | audit_logger.store_web( |
|
353 | 353 | 'repo.archive.download', action_data={ |
|
354 | 354 | 'user_agent': self.request.user_agent, |
|
355 | 355 | 'archive_name': archive_name, |
|
356 | 356 | 'archive_spec': fname, |
|
357 | 357 | 'archive_cached': use_cached_archive}, |
|
358 | 358 | user=self._rhodecode_user, |
|
359 | 359 | repo=self.db_repo, |
|
360 | 360 | commit=True |
|
361 | 361 | ) |
|
362 | 362 | |
|
363 | 363 | def get_chunked_archive(archive_path): |
|
364 | 364 | with open(archive_path, 'rb') as stream: |
|
365 | 365 | while True: |
|
366 | 366 | data = stream.read(16 * 1024) |
|
367 | 367 | if not data: |
|
368 | 368 | if fd: # fd means we used temporary file |
|
369 | 369 | os.close(fd) |
|
370 | 370 | if not archive_cache_enabled: |
|
371 | 371 | log.debug('Destroying temp archive %s', archive_path) |
|
372 | 372 | os.remove(archive_path) |
|
373 | 373 | break |
|
374 | 374 | yield data |
|
375 | 375 | |
|
376 | 376 | response = Response(app_iter=get_chunked_archive(archive)) |
|
377 | 377 | response.content_disposition = str( |
|
378 | 378 | 'attachment; filename=%s' % archive_name) |
|
379 | 379 | response.content_type = str(content_type) |
|
380 | 380 | |
|
381 | 381 | return response |
|
382 | 382 | |
|
383 | 383 | def _get_file_node(self, commit_id, f_path): |
|
384 | 384 | if commit_id not in ['', None, 'None', '0' * 12, '0' * 40]: |
|
385 | 385 | commit = self.rhodecode_vcs_repo.get_commit(commit_id=commit_id) |
|
386 | 386 | try: |
|
387 | 387 | node = commit.get_node(f_path) |
|
388 | 388 | if node.is_dir(): |
|
389 | 389 | raise NodeError('%s path is a %s not a file' |
|
390 | 390 | % (node, type(node))) |
|
391 | 391 | except NodeDoesNotExistError: |
|
392 | 392 | commit = EmptyCommit( |
|
393 | 393 | commit_id=commit_id, |
|
394 | 394 | idx=commit.idx, |
|
395 | 395 | repo=commit.repository, |
|
396 | 396 | alias=commit.repository.alias, |
|
397 | 397 | message=commit.message, |
|
398 | 398 | author=commit.author, |
|
399 | 399 | date=commit.date) |
|
400 | 400 | node = FileNode(f_path, '', commit=commit) |
|
401 | 401 | else: |
|
402 | 402 | commit = EmptyCommit( |
|
403 | 403 | repo=self.rhodecode_vcs_repo, |
|
404 | 404 | alias=self.rhodecode_vcs_repo.alias) |
|
405 | 405 | node = FileNode(f_path, '', commit=commit) |
|
406 | 406 | return node |
|
407 | 407 | |
|
408 | 408 | @LoginRequired() |
|
409 | 409 | @HasRepoPermissionAnyDecorator( |
|
410 | 410 | 'repository.read', 'repository.write', 'repository.admin') |
|
411 | 411 | @view_config( |
|
412 | 412 | route_name='repo_files_diff', request_method='GET', |
|
413 | 413 | renderer=None) |
|
414 | 414 | def repo_files_diff(self): |
|
415 | 415 | c = self.load_default_context() |
|
416 | 416 | f_path = self._get_f_path(self.request.matchdict) |
|
417 | 417 | diff1 = self.request.GET.get('diff1', '') |
|
418 | 418 | diff2 = self.request.GET.get('diff2', '') |
|
419 | 419 | |
|
420 | 420 | path1, diff1 = parse_path_ref(diff1, default_path=f_path) |
|
421 | 421 | |
|
422 | 422 | ignore_whitespace = str2bool(self.request.GET.get('ignorews')) |
|
423 | 423 | line_context = self.request.GET.get('context', 3) |
|
424 | 424 | |
|
425 | 425 | if not any((diff1, diff2)): |
|
426 | 426 | h.flash( |
|
427 | 427 | 'Need query parameter "diff1" or "diff2" to generate a diff.', |
|
428 | 428 | category='error') |
|
429 | 429 | raise HTTPBadRequest() |
|
430 | 430 | |
|
431 | 431 | c.action = self.request.GET.get('diff') |
|
432 | 432 | if c.action not in ['download', 'raw']: |
|
433 | 433 | compare_url = h.route_path( |
|
434 | 434 | 'repo_compare', |
|
435 | 435 | repo_name=self.db_repo_name, |
|
436 | 436 | source_ref_type='rev', |
|
437 | 437 | source_ref=diff1, |
|
438 | 438 | target_repo=self.db_repo_name, |
|
439 | 439 | target_ref_type='rev', |
|
440 | 440 | target_ref=diff2, |
|
441 | 441 | _query=dict(f_path=f_path)) |
|
442 | 442 | # redirect to new view if we render diff |
|
443 | 443 | raise HTTPFound(compare_url) |
|
444 | 444 | |
|
445 | 445 | try: |
|
446 | 446 | node1 = self._get_file_node(diff1, path1) |
|
447 | 447 | node2 = self._get_file_node(diff2, f_path) |
|
448 | 448 | except (RepositoryError, NodeError): |
|
449 | 449 | log.exception("Exception while trying to get node from repository") |
|
450 | 450 | raise HTTPFound( |
|
451 | 451 | h.route_path('repo_files', repo_name=self.db_repo_name, |
|
452 | 452 | commit_id='tip', f_path=f_path)) |
|
453 | 453 | |
|
454 | 454 | if all(isinstance(node.commit, EmptyCommit) |
|
455 | 455 | for node in (node1, node2)): |
|
456 | 456 | raise HTTPNotFound() |
|
457 | 457 | |
|
458 | 458 | c.commit_1 = node1.commit |
|
459 | 459 | c.commit_2 = node2.commit |
|
460 | 460 | |
|
461 | 461 | if c.action == 'download': |
|
462 | 462 | _diff = diffs.get_gitdiff(node1, node2, |
|
463 | 463 | ignore_whitespace=ignore_whitespace, |
|
464 | 464 | context=line_context) |
|
465 | 465 | diff = diffs.DiffProcessor(_diff, format='gitdiff') |
|
466 | 466 | |
|
467 | 467 | response = Response(self.path_filter.get_raw_patch(diff)) |
|
468 | 468 | response.content_type = 'text/plain' |
|
469 | 469 | response.content_disposition = ( |
|
470 | 470 | 'attachment; filename=%s_%s_vs_%s.diff' % (f_path, diff1, diff2) |
|
471 | 471 | ) |
|
472 | 472 | charset = self._get_default_encoding(c) |
|
473 | 473 | if charset: |
|
474 | 474 | response.charset = charset |
|
475 | 475 | return response |
|
476 | 476 | |
|
477 | 477 | elif c.action == 'raw': |
|
478 | 478 | _diff = diffs.get_gitdiff(node1, node2, |
|
479 | 479 | ignore_whitespace=ignore_whitespace, |
|
480 | 480 | context=line_context) |
|
481 | 481 | diff = diffs.DiffProcessor(_diff, format='gitdiff') |
|
482 | 482 | |
|
483 | 483 | response = Response(self.path_filter.get_raw_patch(diff)) |
|
484 | 484 | response.content_type = 'text/plain' |
|
485 | 485 | charset = self._get_default_encoding(c) |
|
486 | 486 | if charset: |
|
487 | 487 | response.charset = charset |
|
488 | 488 | return response |
|
489 | 489 | |
|
490 | 490 | # in case we ever end up here |
|
491 | 491 | raise HTTPNotFound() |
|
492 | 492 | |
|
493 | 493 | @LoginRequired() |
|
494 | 494 | @HasRepoPermissionAnyDecorator( |
|
495 | 495 | 'repository.read', 'repository.write', 'repository.admin') |
|
496 | 496 | @view_config( |
|
497 | 497 | route_name='repo_files_diff_2way_redirect', request_method='GET', |
|
498 | 498 | renderer=None) |
|
499 | 499 | def repo_files_diff_2way_redirect(self): |
|
500 | 500 | """ |
|
501 | 501 | Kept only to make OLD links work |
|
502 | 502 | """ |
|
503 | 503 | f_path = self._get_f_path_unchecked(self.request.matchdict) |
|
504 | 504 | diff1 = self.request.GET.get('diff1', '') |
|
505 | 505 | diff2 = self.request.GET.get('diff2', '') |
|
506 | 506 | |
|
507 | 507 | if not any((diff1, diff2)): |
|
508 | 508 | h.flash( |
|
509 | 509 | 'Need query parameter "diff1" or "diff2" to generate a diff.', |
|
510 | 510 | category='error') |
|
511 | 511 | raise HTTPBadRequest() |
|
512 | 512 | |
|
513 | 513 | compare_url = h.route_path( |
|
514 | 514 | 'repo_compare', |
|
515 | 515 | repo_name=self.db_repo_name, |
|
516 | 516 | source_ref_type='rev', |
|
517 | 517 | source_ref=diff1, |
|
518 | 518 | target_ref_type='rev', |
|
519 | 519 | target_ref=diff2, |
|
520 | 520 | _query=dict(f_path=f_path, diffmode='sideside', |
|
521 | 521 | target_repo=self.db_repo_name,)) |
|
522 | 522 | raise HTTPFound(compare_url) |
|
523 | 523 | |
|
524 | 524 | @LoginRequired() |
|
525 | 525 | @HasRepoPermissionAnyDecorator( |
|
526 | 526 | 'repository.read', 'repository.write', 'repository.admin') |
|
527 | 527 | @view_config( |
|
528 | 528 | route_name='repo_files', request_method='GET', |
|
529 | 529 | renderer=None) |
|
530 | 530 | @view_config( |
|
531 | 531 | route_name='repo_files:default_path', request_method='GET', |
|
532 | 532 | renderer=None) |
|
533 | 533 | @view_config( |
|
534 | 534 | route_name='repo_files:default_commit', request_method='GET', |
|
535 | 535 | renderer=None) |
|
536 | 536 | @view_config( |
|
537 | 537 | route_name='repo_files:rendered', request_method='GET', |
|
538 | 538 | renderer=None) |
|
539 | 539 | @view_config( |
|
540 | 540 | route_name='repo_files:annotated', request_method='GET', |
|
541 | 541 | renderer=None) |
|
542 | 542 | def repo_files(self): |
|
543 | 543 | c = self.load_default_context() |
|
544 | 544 | |
|
545 | 545 | view_name = getattr(self.request.matched_route, 'name', None) |
|
546 | 546 | |
|
547 | 547 | c.annotate = view_name == 'repo_files:annotated' |
|
548 | 548 | # default is false, but .rst/.md files later are auto rendered, we can |
|
549 | 549 | # overwrite auto rendering by setting this GET flag |
|
550 | 550 | c.renderer = view_name == 'repo_files:rendered' or \ |
|
551 | 551 | not self.request.GET.get('no-render', False) |
|
552 | 552 | |
|
553 | 553 | # redirect to given commit_id from form if given |
|
554 | 554 | get_commit_id = self.request.GET.get('at_rev', None) |
|
555 | 555 | if get_commit_id: |
|
556 | 556 | self._get_commit_or_redirect(get_commit_id) |
|
557 | 557 | |
|
558 | 558 | commit_id, f_path = self._get_commit_and_path() |
|
559 | 559 | c.commit = self._get_commit_or_redirect(commit_id) |
|
560 | 560 | c.branch = self.request.GET.get('branch', None) |
|
561 | 561 | c.f_path = f_path |
|
562 | 562 | |
|
563 | 563 | # prev link |
|
564 | 564 | try: |
|
565 | 565 | prev_commit = c.commit.prev(c.branch) |
|
566 | 566 | c.prev_commit = prev_commit |
|
567 | 567 | c.url_prev = h.route_path( |
|
568 | 568 | 'repo_files', repo_name=self.db_repo_name, |
|
569 | 569 | commit_id=prev_commit.raw_id, f_path=f_path) |
|
570 | 570 | if c.branch: |
|
571 | 571 | c.url_prev += '?branch=%s' % c.branch |
|
572 | 572 | except (CommitDoesNotExistError, VCSError): |
|
573 | 573 | c.url_prev = '#' |
|
574 | 574 | c.prev_commit = EmptyCommit() |
|
575 | 575 | |
|
576 | 576 | # next link |
|
577 | 577 | try: |
|
578 | 578 | next_commit = c.commit.next(c.branch) |
|
579 | 579 | c.next_commit = next_commit |
|
580 | 580 | c.url_next = h.route_path( |
|
581 | 581 | 'repo_files', repo_name=self.db_repo_name, |
|
582 | 582 | commit_id=next_commit.raw_id, f_path=f_path) |
|
583 | 583 | if c.branch: |
|
584 | 584 | c.url_next += '?branch=%s' % c.branch |
|
585 | 585 | except (CommitDoesNotExistError, VCSError): |
|
586 | 586 | c.url_next = '#' |
|
587 | 587 | c.next_commit = EmptyCommit() |
|
588 | 588 | |
|
589 | 589 | # files or dirs |
|
590 | 590 | try: |
|
591 | 591 | c.file = c.commit.get_node(f_path) |
|
592 | 592 | c.file_author = True |
|
593 | 593 | c.file_tree = '' |
|
594 | 594 | |
|
595 | 595 | # load file content |
|
596 | 596 | if c.file.is_file(): |
|
597 | 597 | c.lf_node = c.file.get_largefile_node() |
|
598 | 598 | |
|
599 | 599 | c.file_source_page = 'true' |
|
600 | 600 | c.file_last_commit = c.file.last_commit |
|
601 | 601 | if c.file.size < c.visual.cut_off_limit_diff: |
|
602 | 602 | if c.annotate: # annotation has precedence over renderer |
|
603 | 603 | c.annotated_lines = filenode_as_annotated_lines_tokens( |
|
604 | 604 | c.file |
|
605 | 605 | ) |
|
606 | 606 | else: |
|
607 | 607 | c.renderer = ( |
|
608 | 608 | c.renderer and h.renderer_from_filename(c.file.path) |
|
609 | 609 | ) |
|
610 | 610 | if not c.renderer: |
|
611 | 611 | c.lines = filenode_as_lines_tokens(c.file) |
|
612 | 612 | |
|
613 | 613 | _branch_name, _sha_commit_id, is_head = self._is_valid_head( |
|
614 | 614 | commit_id, self.rhodecode_vcs_repo) |
|
615 | 615 | c.on_branch_head = is_head |
|
616 | 616 | |
|
617 | 617 | branch = c.commit.branch if ( |
|
618 | 618 | c.commit.branch and '/' not in c.commit.branch) else None |
|
619 | 619 | c.branch_or_raw_id = branch or c.commit.raw_id |
|
620 | 620 | c.branch_name = c.commit.branch or h.short_id(c.commit.raw_id) |
|
621 | 621 | |
|
622 | 622 | author = c.file_last_commit.author |
|
623 | 623 | c.authors = [[ |
|
624 | 624 | h.email(author), |
|
625 | 625 | h.person(author, 'username_or_name_or_email'), |
|
626 | 626 | 1 |
|
627 | 627 | ]] |
|
628 | 628 | |
|
629 | 629 | else: # load tree content at path |
|
630 | 630 | c.file_source_page = 'false' |
|
631 | 631 | c.authors = [] |
|
632 | 632 | # this loads a simple tree without metadata to speed things up |
|
633 | 633 | # later via ajax we call repo_nodetree_full and fetch whole |
|
634 | 634 | c.file_tree = self._get_tree_at_commit(c, c.commit.raw_id, f_path) |
|
635 | 635 | |
|
636 | 636 | except RepositoryError as e: |
|
637 | 637 | h.flash(safe_str(h.escape(e)), category='error') |
|
638 | 638 | raise HTTPNotFound() |
|
639 | 639 | |
|
640 | 640 | if self.request.environ.get('HTTP_X_PJAX'): |
|
641 | 641 | html = render('rhodecode:templates/files/files_pjax.mako', |
|
642 | 642 | self._get_template_context(c), self.request) |
|
643 | 643 | else: |
|
644 | 644 | html = render('rhodecode:templates/files/files.mako', |
|
645 | 645 | self._get_template_context(c), self.request) |
|
646 | 646 | return Response(html) |
|
647 | 647 | |
|
648 | 648 | @HasRepoPermissionAnyDecorator( |
|
649 | 649 | 'repository.read', 'repository.write', 'repository.admin') |
|
650 | 650 | @view_config( |
|
651 | 651 | route_name='repo_files:annotated_previous', request_method='GET', |
|
652 | 652 | renderer=None) |
|
653 | 653 | def repo_files_annotated_previous(self): |
|
654 | 654 | self.load_default_context() |
|
655 | 655 | |
|
656 | 656 | commit_id, f_path = self._get_commit_and_path() |
|
657 | 657 | commit = self._get_commit_or_redirect(commit_id) |
|
658 | 658 | prev_commit_id = commit.raw_id |
|
659 | 659 | line_anchor = self.request.GET.get('line_anchor') |
|
660 | 660 | is_file = False |
|
661 | 661 | try: |
|
662 | 662 | _file = commit.get_node(f_path) |
|
663 | 663 | is_file = _file.is_file() |
|
664 | 664 | except (NodeDoesNotExistError, CommitDoesNotExistError, VCSError): |
|
665 | 665 | pass |
|
666 | 666 | |
|
667 | 667 | if is_file: |
|
668 | 668 | history = commit.get_path_history(f_path) |
|
669 | 669 | prev_commit_id = history[1].raw_id \ |
|
670 | 670 | if len(history) > 1 else prev_commit_id |
|
671 | 671 | prev_url = h.route_path( |
|
672 | 672 | 'repo_files:annotated', repo_name=self.db_repo_name, |
|
673 | 673 | commit_id=prev_commit_id, f_path=f_path, |
|
674 | 674 | _anchor='L{}'.format(line_anchor)) |
|
675 | 675 | |
|
676 | 676 | raise HTTPFound(prev_url) |
|
677 | 677 | |
|
678 | 678 | @LoginRequired() |
|
679 | 679 | @HasRepoPermissionAnyDecorator( |
|
680 | 680 | 'repository.read', 'repository.write', 'repository.admin') |
|
681 | 681 | @view_config( |
|
682 | 682 | route_name='repo_nodetree_full', request_method='GET', |
|
683 | 683 | renderer=None, xhr=True) |
|
684 | 684 | @view_config( |
|
685 | 685 | route_name='repo_nodetree_full:default_path', request_method='GET', |
|
686 | 686 | renderer=None, xhr=True) |
|
687 | 687 | def repo_nodetree_full(self): |
|
688 | 688 | """ |
|
689 | 689 | Returns rendered html of file tree that contains commit date, |
|
690 | 690 | author, commit_id for the specified combination of |
|
691 | 691 | repo, commit_id and file path |
|
692 | 692 | """ |
|
693 | 693 | c = self.load_default_context() |
|
694 | 694 | |
|
695 | 695 | commit_id, f_path = self._get_commit_and_path() |
|
696 | 696 | commit = self._get_commit_or_redirect(commit_id) |
|
697 | 697 | try: |
|
698 | 698 | dir_node = commit.get_node(f_path) |
|
699 | 699 | except RepositoryError as e: |
|
700 | 700 | return Response('error: {}'.format(h.escape(safe_str(e)))) |
|
701 | 701 | |
|
702 | 702 | if dir_node.is_file(): |
|
703 | 703 | return Response('') |
|
704 | 704 | |
|
705 | 705 | c.file = dir_node |
|
706 | 706 | c.commit = commit |
|
707 | 707 | |
|
708 | 708 | html = self._get_tree_at_commit( |
|
709 | 709 | c, commit.raw_id, dir_node.path, full_load=True) |
|
710 | 710 | |
|
711 | 711 | return Response(html) |
|
712 | 712 | |
|
713 | 713 | def _get_attachement_headers(self, f_path): |
|
714 | 714 | f_name = safe_str(f_path.split(Repository.NAME_SEP)[-1]) |
|
715 | 715 | safe_path = f_name.replace('"', '\\"') |
|
716 | 716 | encoded_path = urllib.quote(f_name) |
|
717 | 717 | |
|
718 | 718 | return "attachment; " \ |
|
719 | 719 | "filename=\"{}\"; " \ |
|
720 | 720 | "filename*=UTF-8\'\'{}".format(safe_path, encoded_path) |
|
721 | 721 | |
|
722 | 722 | @LoginRequired() |
|
723 | 723 | @HasRepoPermissionAnyDecorator( |
|
724 | 724 | 'repository.read', 'repository.write', 'repository.admin') |
|
725 | 725 | @view_config( |
|
726 | 726 | route_name='repo_file_raw', request_method='GET', |
|
727 | 727 | renderer=None) |
|
728 | 728 | def repo_file_raw(self): |
|
729 | 729 | """ |
|
730 | 730 | Action for show as raw, some mimetypes are "rendered", |
|
731 | 731 | those include images, icons. |
|
732 | 732 | """ |
|
733 | 733 | c = self.load_default_context() |
|
734 | 734 | |
|
735 | 735 | commit_id, f_path = self._get_commit_and_path() |
|
736 | 736 | commit = self._get_commit_or_redirect(commit_id) |
|
737 | 737 | file_node = self._get_filenode_or_redirect(commit, f_path) |
|
738 | 738 | |
|
739 | 739 | raw_mimetype_mapping = { |
|
740 | 740 | # map original mimetype to a mimetype used for "show as raw" |
|
741 | 741 | # you can also provide a content-disposition to override the |
|
742 | 742 | # default "attachment" disposition. |
|
743 | 743 | # orig_type: (new_type, new_dispo) |
|
744 | 744 | |
|
745 | 745 | # show images inline: |
|
746 | 746 | # Do not re-add SVG: it is unsafe and permits XSS attacks. One can |
|
747 | 747 | # for example render an SVG with javascript inside or even render |
|
748 | 748 | # HTML. |
|
749 | 749 | 'image/x-icon': ('image/x-icon', 'inline'), |
|
750 | 750 | 'image/png': ('image/png', 'inline'), |
|
751 | 751 | 'image/gif': ('image/gif', 'inline'), |
|
752 | 752 | 'image/jpeg': ('image/jpeg', 'inline'), |
|
753 | 753 | 'application/pdf': ('application/pdf', 'inline'), |
|
754 | 754 | } |
|
755 | 755 | |
|
756 | 756 | mimetype = file_node.mimetype |
|
757 | 757 | try: |
|
758 | 758 | mimetype, disposition = raw_mimetype_mapping[mimetype] |
|
759 | 759 | except KeyError: |
|
760 | 760 | # we don't know anything special about this, handle it safely |
|
761 | 761 | if file_node.is_binary: |
|
762 | 762 | # do same as download raw for binary files |
|
763 | 763 | mimetype, disposition = 'application/octet-stream', 'attachment' |
|
764 | 764 | else: |
|
765 | 765 | # do not just use the original mimetype, but force text/plain, |
|
766 | 766 | # otherwise it would serve text/html and that might be unsafe. |
|
767 | 767 | # Note: underlying vcs library fakes text/plain mimetype if the |
|
768 | 768 | # mimetype can not be determined and it thinks it is not |
|
769 | 769 | # binary.This might lead to erroneous text display in some |
|
770 | 770 | # cases, but helps in other cases, like with text files |
|
771 | 771 | # without extension. |
|
772 | 772 | mimetype, disposition = 'text/plain', 'inline' |
|
773 | 773 | |
|
774 | 774 | if disposition == 'attachment': |
|
775 | 775 | disposition = self._get_attachement_headers(f_path) |
|
776 | 776 | |
|
777 | 777 | def stream_node(): |
|
778 | 778 | yield file_node.raw_bytes |
|
779 | 779 | |
|
780 | 780 | response = Response(app_iter=stream_node()) |
|
781 | 781 | response.content_disposition = disposition |
|
782 | 782 | response.content_type = mimetype |
|
783 | 783 | |
|
784 | 784 | charset = self._get_default_encoding(c) |
|
785 | 785 | if charset: |
|
786 | 786 | response.charset = charset |
|
787 | 787 | |
|
788 | 788 | return response |
|
789 | 789 | |
|
790 | 790 | @LoginRequired() |
|
791 | 791 | @HasRepoPermissionAnyDecorator( |
|
792 | 792 | 'repository.read', 'repository.write', 'repository.admin') |
|
793 | 793 | @view_config( |
|
794 | 794 | route_name='repo_file_download', request_method='GET', |
|
795 | 795 | renderer=None) |
|
796 | 796 | @view_config( |
|
797 | 797 | route_name='repo_file_download:legacy', request_method='GET', |
|
798 | 798 | renderer=None) |
|
799 | 799 | def repo_file_download(self): |
|
800 | 800 | c = self.load_default_context() |
|
801 | 801 | |
|
802 | 802 | commit_id, f_path = self._get_commit_and_path() |
|
803 | 803 | commit = self._get_commit_or_redirect(commit_id) |
|
804 | 804 | file_node = self._get_filenode_or_redirect(commit, f_path) |
|
805 | 805 | |
|
806 | 806 | if self.request.GET.get('lf'): |
|
807 | 807 | # only if lf get flag is passed, we download this file |
|
808 | 808 | # as LFS/Largefile |
|
809 | 809 | lf_node = file_node.get_largefile_node() |
|
810 | 810 | if lf_node: |
|
811 | 811 | # overwrite our pointer with the REAL large-file |
|
812 | 812 | file_node = lf_node |
|
813 | 813 | |
|
814 | 814 | disposition = self._get_attachement_headers(f_path) |
|
815 | 815 | |
|
816 | 816 | def stream_node(): |
|
817 | 817 | yield file_node.raw_bytes |
|
818 | 818 | |
|
819 | 819 | response = Response(app_iter=stream_node()) |
|
820 | 820 | response.content_disposition = disposition |
|
821 | 821 | response.content_type = file_node.mimetype |
|
822 | 822 | |
|
823 | 823 | charset = self._get_default_encoding(c) |
|
824 | 824 | if charset: |
|
825 | 825 | response.charset = charset |
|
826 | 826 | |
|
827 | 827 | return response |
|
828 | 828 | |
|
829 | 829 | def _get_nodelist_at_commit(self, repo_name, repo_id, commit_id, f_path): |
|
830 | 830 | |
|
831 | 831 | cache_seconds = safe_int( |
|
832 | 832 | rhodecode.CONFIG.get('rc_cache.cache_repo.expiration_time')) |
|
833 | 833 | cache_on = cache_seconds > 0 |
|
834 | 834 | log.debug( |
|
835 | 835 | 'Computing FILE SEARCH for repo_id %s commit_id `%s` and path `%s`' |
|
836 | 836 | 'with caching: %s[TTL: %ss]' % ( |
|
837 | 837 | repo_id, commit_id, f_path, cache_on, cache_seconds or 0)) |
|
838 | 838 | |
|
839 | 839 | cache_namespace_uid = 'cache_repo.{}'.format(repo_id) |
|
840 | 840 | region = rc_cache.get_or_create_region('cache_repo', cache_namespace_uid) |
|
841 | 841 | |
|
842 | 842 | @region.conditional_cache_on_arguments(namespace=cache_namespace_uid, |
|
843 | 843 | condition=cache_on) |
|
844 | 844 | def compute_file_search(repo_id, commit_id, f_path): |
|
845 | 845 | log.debug('Generating cached nodelist for repo_id:%s, %s, %s', |
|
846 | 846 | repo_id, commit_id, f_path) |
|
847 | 847 | try: |
|
848 | 848 | _d, _f = ScmModel().get_nodes( |
|
849 | 849 | repo_name, commit_id, f_path, flat=False) |
|
850 | 850 | except (RepositoryError, CommitDoesNotExistError, Exception) as e: |
|
851 | 851 | log.exception(safe_str(e)) |
|
852 | 852 | h.flash(safe_str(h.escape(e)), category='error') |
|
853 | 853 | raise HTTPFound(h.route_path( |
|
854 | 854 | 'repo_files', repo_name=self.db_repo_name, |
|
855 | 855 | commit_id='tip', f_path='/')) |
|
856 | 856 | return _d + _f |
|
857 | 857 | |
|
858 | 858 | return compute_file_search(self.db_repo.repo_id, commit_id, f_path) |
|
859 | 859 | |
|
860 | 860 | @LoginRequired() |
|
861 | 861 | @HasRepoPermissionAnyDecorator( |
|
862 | 862 | 'repository.read', 'repository.write', 'repository.admin') |
|
863 | 863 | @view_config( |
|
864 | 864 | route_name='repo_files_nodelist', request_method='GET', |
|
865 | 865 | renderer='json_ext', xhr=True) |
|
866 | 866 | def repo_nodelist(self): |
|
867 | 867 | self.load_default_context() |
|
868 | 868 | |
|
869 | 869 | commit_id, f_path = self._get_commit_and_path() |
|
870 | 870 | commit = self._get_commit_or_redirect(commit_id) |
|
871 | 871 | |
|
872 | 872 | metadata = self._get_nodelist_at_commit( |
|
873 | 873 | self.db_repo_name, self.db_repo.repo_id, commit.raw_id, f_path) |
|
874 | 874 | return {'nodes': metadata} |
|
875 | 875 | |
|
876 | def _create_references( | |
|
877 | self, branches_or_tags, symbolic_reference, f_path): | |
|
876 | def _create_references(self, branches_or_tags, symbolic_reference, f_path, ref_type): | |
|
878 | 877 | items = [] |
|
879 | 878 | for name, commit_id in branches_or_tags.items(): |
|
880 | sym_ref = symbolic_reference(commit_id, name, f_path) | |
|
881 | items.append((sym_ref, name)) | |
|
879 | sym_ref = symbolic_reference(commit_id, name, f_path, ref_type) | |
|
880 | items.append((sym_ref, name, ref_type)) | |
|
882 | 881 | return items |
|
883 | 882 | |
|
884 | def _symbolic_reference(self, commit_id, name, f_path): | |
|
883 | def _symbolic_reference(self, commit_id, name, f_path, ref_type): | |
|
885 | 884 | return commit_id |
|
886 | 885 | |
|
887 | def _symbolic_reference_svn(self, commit_id, name, f_path): | |
|
886 | def _symbolic_reference_svn(self, commit_id, name, f_path, ref_type): | |
|
888 | 887 | new_f_path = vcspath.join(name, f_path) |
|
889 | 888 | return u'%s@%s' % (new_f_path, commit_id) |
|
890 | 889 | |
|
891 | 890 | def _get_node_history(self, commit_obj, f_path, commits=None): |
|
892 | 891 | """ |
|
893 | 892 | get commit history for given node |
|
894 | 893 | |
|
895 | 894 | :param commit_obj: commit to calculate history |
|
896 | 895 | :param f_path: path for node to calculate history for |
|
897 | 896 | :param commits: if passed don't calculate history and take |
|
898 | 897 | commits defined in this list |
|
899 | 898 | """ |
|
900 | 899 | _ = self.request.translate |
|
901 | 900 | |
|
902 | 901 | # calculate history based on tip |
|
903 | 902 | tip = self.rhodecode_vcs_repo.get_commit() |
|
904 | 903 | if commits is None: |
|
905 | 904 | pre_load = ["author", "branch"] |
|
906 | 905 | try: |
|
907 | 906 | commits = tip.get_path_history(f_path, pre_load=pre_load) |
|
908 | 907 | except (NodeDoesNotExistError, CommitError): |
|
909 | 908 | # this node is not present at tip! |
|
910 | 909 | commits = commit_obj.get_path_history(f_path, pre_load=pre_load) |
|
911 | 910 | |
|
912 | 911 | history = [] |
|
913 | 912 | commits_group = ([], _("Changesets")) |
|
914 | 913 | for commit in commits: |
|
915 | 914 | branch = ' (%s)' % commit.branch if commit.branch else '' |
|
916 | 915 | n_desc = 'r%s:%s%s' % (commit.idx, commit.short_id, branch) |
|
917 | commits_group[0].append((commit.raw_id, n_desc,)) | |
|
916 | commits_group[0].append((commit.raw_id, n_desc, 'sha')) | |
|
918 | 917 | history.append(commits_group) |
|
919 | 918 | |
|
920 | 919 | symbolic_reference = self._symbolic_reference |
|
921 | 920 | |
|
922 | 921 | if self.rhodecode_vcs_repo.alias == 'svn': |
|
923 | 922 | adjusted_f_path = RepoFilesView.adjust_file_path_for_svn( |
|
924 | 923 | f_path, self.rhodecode_vcs_repo) |
|
925 | 924 | if adjusted_f_path != f_path: |
|
926 | 925 | log.debug( |
|
927 | 926 | 'Recognized svn tag or branch in file "%s", using svn ' |
|
928 | 927 | 'specific symbolic references', f_path) |
|
929 | 928 | f_path = adjusted_f_path |
|
930 | 929 | symbolic_reference = self._symbolic_reference_svn |
|
931 | 930 | |
|
932 | 931 | branches = self._create_references( |
|
933 | self.rhodecode_vcs_repo.branches, symbolic_reference, f_path) | |
|
932 | self.rhodecode_vcs_repo.branches, symbolic_reference, f_path, 'branch') | |
|
934 | 933 | branches_group = (branches, _("Branches")) |
|
935 | 934 | |
|
936 | 935 | tags = self._create_references( |
|
937 | self.rhodecode_vcs_repo.tags, symbolic_reference, f_path) | |
|
936 | self.rhodecode_vcs_repo.tags, symbolic_reference, f_path, 'tag') | |
|
938 | 937 | tags_group = (tags, _("Tags")) |
|
939 | 938 | |
|
940 | 939 | history.append(branches_group) |
|
941 | 940 | history.append(tags_group) |
|
942 | 941 | |
|
943 | 942 | return history, commits |
|
944 | 943 | |
|
945 | 944 | @LoginRequired() |
|
946 | 945 | @HasRepoPermissionAnyDecorator( |
|
947 | 946 | 'repository.read', 'repository.write', 'repository.admin') |
|
948 | 947 | @view_config( |
|
949 | 948 | route_name='repo_file_history', request_method='GET', |
|
950 | 949 | renderer='json_ext') |
|
951 | 950 | def repo_file_history(self): |
|
952 | 951 | self.load_default_context() |
|
953 | 952 | |
|
954 | 953 | commit_id, f_path = self._get_commit_and_path() |
|
955 | 954 | commit = self._get_commit_or_redirect(commit_id) |
|
956 | 955 | file_node = self._get_filenode_or_redirect(commit, f_path) |
|
957 | 956 | |
|
958 | 957 | if file_node.is_file(): |
|
959 | 958 | file_history, _hist = self._get_node_history(commit, f_path) |
|
960 | 959 | |
|
961 | 960 | res = [] |
|
962 | 961 | for obj in file_history: |
|
963 | 962 | res.append({ |
|
964 | 963 | 'text': obj[1], |
|
965 | 'children': [{'id': o[0], 'text': o[1]} for o in obj[0]] | |
|
964 | 'children': [{'id': o[0], 'text': o[1], 'type': o[2]} for o in obj[0]] | |
|
966 | 965 | }) |
|
967 | 966 | |
|
968 | 967 | data = { |
|
969 | 968 | 'more': False, |
|
970 | 969 | 'results': res |
|
971 | 970 | } |
|
972 | 971 | return data |
|
973 | 972 | |
|
974 | 973 | log.warning('Cannot fetch history for directory') |
|
975 | 974 | raise HTTPBadRequest() |
|
976 | 975 | |
|
977 | 976 | @LoginRequired() |
|
978 | 977 | @HasRepoPermissionAnyDecorator( |
|
979 | 978 | 'repository.read', 'repository.write', 'repository.admin') |
|
980 | 979 | @view_config( |
|
981 | 980 | route_name='repo_file_authors', request_method='GET', |
|
982 | 981 | renderer='rhodecode:templates/files/file_authors_box.mako') |
|
983 | 982 | def repo_file_authors(self): |
|
984 | 983 | c = self.load_default_context() |
|
985 | 984 | |
|
986 | 985 | commit_id, f_path = self._get_commit_and_path() |
|
987 | 986 | commit = self._get_commit_or_redirect(commit_id) |
|
988 | 987 | file_node = self._get_filenode_or_redirect(commit, f_path) |
|
989 | 988 | |
|
990 | 989 | if not file_node.is_file(): |
|
991 | 990 | raise HTTPBadRequest() |
|
992 | 991 | |
|
993 | 992 | c.file_last_commit = file_node.last_commit |
|
994 | 993 | if self.request.GET.get('annotate') == '1': |
|
995 | 994 | # use _hist from annotation if annotation mode is on |
|
996 | 995 | commit_ids = set(x[1] for x in file_node.annotate) |
|
997 | 996 | _hist = ( |
|
998 | 997 | self.rhodecode_vcs_repo.get_commit(commit_id) |
|
999 | 998 | for commit_id in commit_ids) |
|
1000 | 999 | else: |
|
1001 | 1000 | _f_history, _hist = self._get_node_history(commit, f_path) |
|
1002 | 1001 | c.file_author = False |
|
1003 | 1002 | |
|
1004 | 1003 | unique = collections.OrderedDict() |
|
1005 | 1004 | for commit in _hist: |
|
1006 | 1005 | author = commit.author |
|
1007 | 1006 | if author not in unique: |
|
1008 | 1007 | unique[commit.author] = [ |
|
1009 | 1008 | h.email(author), |
|
1010 | 1009 | h.person(author, 'username_or_name_or_email'), |
|
1011 | 1010 | 1 # counter |
|
1012 | 1011 | ] |
|
1013 | 1012 | |
|
1014 | 1013 | else: |
|
1015 | 1014 | # increase counter |
|
1016 | 1015 | unique[commit.author][2] += 1 |
|
1017 | 1016 | |
|
1018 | 1017 | c.authors = [val for val in unique.values()] |
|
1019 | 1018 | |
|
1020 | 1019 | return self._get_template_context(c) |
|
1021 | 1020 | |
|
1022 | 1021 | @LoginRequired() |
|
1023 | 1022 | @HasRepoPermissionAnyDecorator('repository.write', 'repository.admin') |
|
1024 | 1023 | @view_config( |
|
1025 | 1024 | route_name='repo_files_remove_file', request_method='GET', |
|
1026 | 1025 | renderer='rhodecode:templates/files/files_delete.mako') |
|
1027 | 1026 | def repo_files_remove_file(self): |
|
1028 | 1027 | _ = self.request.translate |
|
1029 | 1028 | c = self.load_default_context() |
|
1030 | 1029 | commit_id, f_path = self._get_commit_and_path() |
|
1031 | 1030 | |
|
1032 | 1031 | self._ensure_not_locked() |
|
1033 | 1032 | _branch_name, _sha_commit_id, is_head = \ |
|
1034 | 1033 | self._is_valid_head(commit_id, self.rhodecode_vcs_repo) |
|
1035 | 1034 | |
|
1036 | 1035 | if not is_head: |
|
1037 | 1036 | h.flash(_('You can only delete files with commit ' |
|
1038 | 1037 | 'being a valid branch head.'), category='warning') |
|
1039 | 1038 | raise HTTPFound( |
|
1040 | 1039 | h.route_path('repo_files', |
|
1041 | 1040 | repo_name=self.db_repo_name, commit_id='tip', |
|
1042 | 1041 | f_path=f_path)) |
|
1043 | 1042 | |
|
1044 | 1043 | self.check_branch_permission(_branch_name) |
|
1045 | 1044 | c.commit = self._get_commit_or_redirect(commit_id) |
|
1046 | 1045 | c.file = self._get_filenode_or_redirect(c.commit, f_path) |
|
1047 | 1046 | |
|
1048 | 1047 | c.default_message = _( |
|
1049 | 1048 | 'Deleted file {} via RhodeCode Enterprise').format(f_path) |
|
1050 | 1049 | c.f_path = f_path |
|
1051 | 1050 | |
|
1052 | 1051 | return self._get_template_context(c) |
|
1053 | 1052 | |
|
1054 | 1053 | @LoginRequired() |
|
1055 | 1054 | @HasRepoPermissionAnyDecorator('repository.write', 'repository.admin') |
|
1056 | 1055 | @CSRFRequired() |
|
1057 | 1056 | @view_config( |
|
1058 | 1057 | route_name='repo_files_delete_file', request_method='POST', |
|
1059 | 1058 | renderer=None) |
|
1060 | 1059 | def repo_files_delete_file(self): |
|
1061 | 1060 | _ = self.request.translate |
|
1062 | 1061 | |
|
1063 | 1062 | c = self.load_default_context() |
|
1064 | 1063 | commit_id, f_path = self._get_commit_and_path() |
|
1065 | 1064 | |
|
1066 | 1065 | self._ensure_not_locked() |
|
1067 | 1066 | _branch_name, _sha_commit_id, is_head = \ |
|
1068 | 1067 | self._is_valid_head(commit_id, self.rhodecode_vcs_repo) |
|
1069 | 1068 | |
|
1070 | 1069 | if not is_head: |
|
1071 | 1070 | h.flash(_('You can only delete files with commit ' |
|
1072 | 1071 | 'being a valid branch head.'), category='warning') |
|
1073 | 1072 | raise HTTPFound( |
|
1074 | 1073 | h.route_path('repo_files', |
|
1075 | 1074 | repo_name=self.db_repo_name, commit_id='tip', |
|
1076 | 1075 | f_path=f_path)) |
|
1077 | 1076 | self.check_branch_permission(_branch_name) |
|
1078 | 1077 | |
|
1079 | 1078 | c.commit = self._get_commit_or_redirect(commit_id) |
|
1080 | 1079 | c.file = self._get_filenode_or_redirect(c.commit, f_path) |
|
1081 | 1080 | |
|
1082 | 1081 | c.default_message = _( |
|
1083 | 1082 | 'Deleted file {} via RhodeCode Enterprise').format(f_path) |
|
1084 | 1083 | c.f_path = f_path |
|
1085 | 1084 | node_path = f_path |
|
1086 | 1085 | author = self._rhodecode_db_user.full_contact |
|
1087 | 1086 | message = self.request.POST.get('message') or c.default_message |
|
1088 | 1087 | try: |
|
1089 | 1088 | nodes = { |
|
1090 | 1089 | node_path: { |
|
1091 | 1090 | 'content': '' |
|
1092 | 1091 | } |
|
1093 | 1092 | } |
|
1094 | 1093 | ScmModel().delete_nodes( |
|
1095 | 1094 | user=self._rhodecode_db_user.user_id, repo=self.db_repo, |
|
1096 | 1095 | message=message, |
|
1097 | 1096 | nodes=nodes, |
|
1098 | 1097 | parent_commit=c.commit, |
|
1099 | 1098 | author=author, |
|
1100 | 1099 | ) |
|
1101 | 1100 | |
|
1102 | 1101 | h.flash( |
|
1103 | 1102 | _('Successfully deleted file `{}`').format( |
|
1104 | 1103 | h.escape(f_path)), category='success') |
|
1105 | 1104 | except Exception: |
|
1106 | 1105 | log.exception('Error during commit operation') |
|
1107 | 1106 | h.flash(_('Error occurred during commit'), category='error') |
|
1108 | 1107 | raise HTTPFound( |
|
1109 | 1108 | h.route_path('repo_commit', repo_name=self.db_repo_name, |
|
1110 | 1109 | commit_id='tip')) |
|
1111 | 1110 | |
|
1112 | 1111 | @LoginRequired() |
|
1113 | 1112 | @HasRepoPermissionAnyDecorator('repository.write', 'repository.admin') |
|
1114 | 1113 | @view_config( |
|
1115 | 1114 | route_name='repo_files_edit_file', request_method='GET', |
|
1116 | 1115 | renderer='rhodecode:templates/files/files_edit.mako') |
|
1117 | 1116 | def repo_files_edit_file(self): |
|
1118 | 1117 | _ = self.request.translate |
|
1119 | 1118 | c = self.load_default_context() |
|
1120 | 1119 | commit_id, f_path = self._get_commit_and_path() |
|
1121 | 1120 | |
|
1122 | 1121 | self._ensure_not_locked() |
|
1123 | 1122 | _branch_name, _sha_commit_id, is_head = \ |
|
1124 | 1123 | self._is_valid_head(commit_id, self.rhodecode_vcs_repo) |
|
1125 | 1124 | |
|
1126 | 1125 | if not is_head: |
|
1127 | 1126 | h.flash(_('You can only edit files with commit ' |
|
1128 | 1127 | 'being a valid branch head.'), category='warning') |
|
1129 | 1128 | raise HTTPFound( |
|
1130 | 1129 | h.route_path('repo_files', |
|
1131 | 1130 | repo_name=self.db_repo_name, commit_id='tip', |
|
1132 | 1131 | f_path=f_path)) |
|
1133 | 1132 | self.check_branch_permission(_branch_name) |
|
1134 | 1133 | |
|
1135 | 1134 | c.commit = self._get_commit_or_redirect(commit_id) |
|
1136 | 1135 | c.file = self._get_filenode_or_redirect(c.commit, f_path) |
|
1137 | 1136 | |
|
1138 | 1137 | if c.file.is_binary: |
|
1139 | 1138 | files_url = h.route_path( |
|
1140 | 1139 | 'repo_files', |
|
1141 | 1140 | repo_name=self.db_repo_name, |
|
1142 | 1141 | commit_id=c.commit.raw_id, f_path=f_path) |
|
1143 | 1142 | raise HTTPFound(files_url) |
|
1144 | 1143 | |
|
1145 | 1144 | c.default_message = _( |
|
1146 | 1145 | 'Edited file {} via RhodeCode Enterprise').format(f_path) |
|
1147 | 1146 | c.f_path = f_path |
|
1148 | 1147 | |
|
1149 | 1148 | return self._get_template_context(c) |
|
1150 | 1149 | |
|
1151 | 1150 | @LoginRequired() |
|
1152 | 1151 | @HasRepoPermissionAnyDecorator('repository.write', 'repository.admin') |
|
1153 | 1152 | @CSRFRequired() |
|
1154 | 1153 | @view_config( |
|
1155 | 1154 | route_name='repo_files_update_file', request_method='POST', |
|
1156 | 1155 | renderer=None) |
|
1157 | 1156 | def repo_files_update_file(self): |
|
1158 | 1157 | _ = self.request.translate |
|
1159 | 1158 | c = self.load_default_context() |
|
1160 | 1159 | commit_id, f_path = self._get_commit_and_path() |
|
1161 | 1160 | |
|
1162 | 1161 | self._ensure_not_locked() |
|
1163 | 1162 | _branch_name, _sha_commit_id, is_head = \ |
|
1164 | 1163 | self._is_valid_head(commit_id, self.rhodecode_vcs_repo) |
|
1165 | 1164 | |
|
1166 | 1165 | if not is_head: |
|
1167 | 1166 | h.flash(_('You can only edit files with commit ' |
|
1168 | 1167 | 'being a valid branch head.'), category='warning') |
|
1169 | 1168 | raise HTTPFound( |
|
1170 | 1169 | h.route_path('repo_files', |
|
1171 | 1170 | repo_name=self.db_repo_name, commit_id='tip', |
|
1172 | 1171 | f_path=f_path)) |
|
1173 | 1172 | |
|
1174 | 1173 | self.check_branch_permission(_branch_name) |
|
1175 | 1174 | |
|
1176 | 1175 | c.commit = self._get_commit_or_redirect(commit_id) |
|
1177 | 1176 | c.file = self._get_filenode_or_redirect(c.commit, f_path) |
|
1178 | 1177 | |
|
1179 | 1178 | if c.file.is_binary: |
|
1180 | 1179 | raise HTTPFound( |
|
1181 | 1180 | h.route_path('repo_files', |
|
1182 | 1181 | repo_name=self.db_repo_name, |
|
1183 | 1182 | commit_id=c.commit.raw_id, |
|
1184 | 1183 | f_path=f_path)) |
|
1185 | 1184 | |
|
1186 | 1185 | c.default_message = _( |
|
1187 | 1186 | 'Edited file {} via RhodeCode Enterprise').format(f_path) |
|
1188 | 1187 | c.f_path = f_path |
|
1189 | 1188 | old_content = c.file.content |
|
1190 | 1189 | sl = old_content.splitlines(1) |
|
1191 | 1190 | first_line = sl[0] if sl else '' |
|
1192 | 1191 | |
|
1193 | 1192 | r_post = self.request.POST |
|
1194 | 1193 | # line endings: 0 - Unix, 1 - Mac, 2 - DOS |
|
1195 | 1194 | line_ending_mode = detect_mode(first_line, 0) |
|
1196 | 1195 | content = convert_line_endings(r_post.get('content', ''), line_ending_mode) |
|
1197 | 1196 | |
|
1198 | 1197 | message = r_post.get('message') or c.default_message |
|
1199 | 1198 | org_f_path = c.file.unicode_path |
|
1200 | 1199 | filename = r_post['filename'] |
|
1201 | 1200 | org_filename = c.file.name |
|
1202 | 1201 | |
|
1203 | 1202 | if content == old_content and filename == org_filename: |
|
1204 | 1203 | h.flash(_('No changes'), category='warning') |
|
1205 | 1204 | raise HTTPFound( |
|
1206 | 1205 | h.route_path('repo_commit', repo_name=self.db_repo_name, |
|
1207 | 1206 | commit_id='tip')) |
|
1208 | 1207 | try: |
|
1209 | 1208 | mapping = { |
|
1210 | 1209 | org_f_path: { |
|
1211 | 1210 | 'org_filename': org_f_path, |
|
1212 | 1211 | 'filename': os.path.join(c.file.dir_path, filename), |
|
1213 | 1212 | 'content': content, |
|
1214 | 1213 | 'lexer': '', |
|
1215 | 1214 | 'op': 'mod', |
|
1216 | 1215 | 'mode': c.file.mode |
|
1217 | 1216 | } |
|
1218 | 1217 | } |
|
1219 | 1218 | |
|
1220 | 1219 | ScmModel().update_nodes( |
|
1221 | 1220 | user=self._rhodecode_db_user.user_id, |
|
1222 | 1221 | repo=self.db_repo, |
|
1223 | 1222 | message=message, |
|
1224 | 1223 | nodes=mapping, |
|
1225 | 1224 | parent_commit=c.commit, |
|
1226 | 1225 | ) |
|
1227 | 1226 | |
|
1228 | 1227 | h.flash( |
|
1229 | 1228 | _('Successfully committed changes to file `{}`').format( |
|
1230 | 1229 | h.escape(f_path)), category='success') |
|
1231 | 1230 | except Exception: |
|
1232 | 1231 | log.exception('Error occurred during commit') |
|
1233 | 1232 | h.flash(_('Error occurred during commit'), category='error') |
|
1234 | 1233 | raise HTTPFound( |
|
1235 | 1234 | h.route_path('repo_commit', repo_name=self.db_repo_name, |
|
1236 | 1235 | commit_id='tip')) |
|
1237 | 1236 | |
|
1238 | 1237 | @LoginRequired() |
|
1239 | 1238 | @HasRepoPermissionAnyDecorator('repository.write', 'repository.admin') |
|
1240 | 1239 | @view_config( |
|
1241 | 1240 | route_name='repo_files_add_file', request_method='GET', |
|
1242 | 1241 | renderer='rhodecode:templates/files/files_add.mako') |
|
1243 | 1242 | def repo_files_add_file(self): |
|
1244 | 1243 | _ = self.request.translate |
|
1245 | 1244 | c = self.load_default_context() |
|
1246 | 1245 | commit_id, f_path = self._get_commit_and_path() |
|
1247 | 1246 | |
|
1248 | 1247 | self._ensure_not_locked() |
|
1249 | 1248 | |
|
1250 | 1249 | c.commit = self._get_commit_or_redirect(commit_id, redirect_after=False) |
|
1251 | 1250 | if c.commit is None: |
|
1252 | 1251 | c.commit = EmptyCommit(alias=self.rhodecode_vcs_repo.alias) |
|
1253 | 1252 | c.default_message = (_('Added file via RhodeCode Enterprise')) |
|
1254 | 1253 | c.f_path = f_path.lstrip('/') # ensure not relative path |
|
1255 | 1254 | |
|
1256 | 1255 | if self.rhodecode_vcs_repo.is_empty: |
|
1257 | 1256 | # for empty repository we cannot check for current branch, we rely on |
|
1258 | 1257 | # c.commit.branch instead |
|
1259 | 1258 | _branch_name = c.commit.branch |
|
1260 | 1259 | is_head = True |
|
1261 | 1260 | else: |
|
1262 | 1261 | _branch_name, _sha_commit_id, is_head = \ |
|
1263 | 1262 | self._is_valid_head(commit_id, self.rhodecode_vcs_repo) |
|
1264 | 1263 | |
|
1265 | 1264 | if not is_head: |
|
1266 | 1265 | h.flash(_('You can only add files with commit ' |
|
1267 | 1266 | 'being a valid branch head.'), category='warning') |
|
1268 | 1267 | raise HTTPFound( |
|
1269 | 1268 | h.route_path('repo_files', |
|
1270 | 1269 | repo_name=self.db_repo_name, commit_id='tip', |
|
1271 | 1270 | f_path=f_path)) |
|
1272 | 1271 | |
|
1273 | 1272 | self.check_branch_permission(_branch_name) |
|
1274 | 1273 | |
|
1275 | 1274 | return self._get_template_context(c) |
|
1276 | 1275 | |
|
1277 | 1276 | @LoginRequired() |
|
1278 | 1277 | @HasRepoPermissionAnyDecorator('repository.write', 'repository.admin') |
|
1279 | 1278 | @CSRFRequired() |
|
1280 | 1279 | @view_config( |
|
1281 | 1280 | route_name='repo_files_create_file', request_method='POST', |
|
1282 | 1281 | renderer=None) |
|
1283 | 1282 | def repo_files_create_file(self): |
|
1284 | 1283 | _ = self.request.translate |
|
1285 | 1284 | c = self.load_default_context() |
|
1286 | 1285 | commit_id, f_path = self._get_commit_and_path() |
|
1287 | 1286 | |
|
1288 | 1287 | self._ensure_not_locked() |
|
1289 | 1288 | |
|
1290 | 1289 | r_post = self.request.POST |
|
1291 | 1290 | |
|
1292 | 1291 | c.commit = self._get_commit_or_redirect( |
|
1293 | 1292 | commit_id, redirect_after=False) |
|
1294 | 1293 | if c.commit is None: |
|
1295 | 1294 | c.commit = EmptyCommit(alias=self.rhodecode_vcs_repo.alias) |
|
1296 | 1295 | |
|
1297 | 1296 | if self.rhodecode_vcs_repo.is_empty: |
|
1298 | 1297 | # for empty repository we cannot check for current branch, we rely on |
|
1299 | 1298 | # c.commit.branch instead |
|
1300 | 1299 | _branch_name = c.commit.branch |
|
1301 | 1300 | is_head = True |
|
1302 | 1301 | else: |
|
1303 | 1302 | _branch_name, _sha_commit_id, is_head = \ |
|
1304 | 1303 | self._is_valid_head(commit_id, self.rhodecode_vcs_repo) |
|
1305 | 1304 | |
|
1306 | 1305 | if not is_head: |
|
1307 | 1306 | h.flash(_('You can only add files with commit ' |
|
1308 | 1307 | 'being a valid branch head.'), category='warning') |
|
1309 | 1308 | raise HTTPFound( |
|
1310 | 1309 | h.route_path('repo_files', |
|
1311 | 1310 | repo_name=self.db_repo_name, commit_id='tip', |
|
1312 | 1311 | f_path=f_path)) |
|
1313 | 1312 | |
|
1314 | 1313 | self.check_branch_permission(_branch_name) |
|
1315 | 1314 | |
|
1316 | 1315 | c.default_message = (_('Added file via RhodeCode Enterprise')) |
|
1317 | 1316 | c.f_path = f_path |
|
1318 | 1317 | unix_mode = 0 |
|
1319 | 1318 | content = convert_line_endings(r_post.get('content', ''), unix_mode) |
|
1320 | 1319 | |
|
1321 | 1320 | message = r_post.get('message') or c.default_message |
|
1322 | 1321 | filename = r_post.get('filename') |
|
1323 | 1322 | location = r_post.get('location', '') # dir location |
|
1324 | 1323 | file_obj = r_post.get('upload_file', None) |
|
1325 | 1324 | |
|
1326 | 1325 | if file_obj is not None and hasattr(file_obj, 'filename'): |
|
1327 | 1326 | filename = r_post.get('filename_upload') |
|
1328 | 1327 | content = file_obj.file |
|
1329 | 1328 | |
|
1330 | 1329 | if hasattr(content, 'file'): |
|
1331 | 1330 | # non posix systems store real file under file attr |
|
1332 | 1331 | content = content.file |
|
1333 | 1332 | |
|
1334 | 1333 | if self.rhodecode_vcs_repo.is_empty: |
|
1335 | 1334 | default_redirect_url = h.route_path( |
|
1336 | 1335 | 'repo_summary', repo_name=self.db_repo_name) |
|
1337 | 1336 | else: |
|
1338 | 1337 | default_redirect_url = h.route_path( |
|
1339 | 1338 | 'repo_commit', repo_name=self.db_repo_name, commit_id='tip') |
|
1340 | 1339 | |
|
1341 | 1340 | # If there's no commit, redirect to repo summary |
|
1342 | 1341 | if type(c.commit) is EmptyCommit: |
|
1343 | 1342 | redirect_url = h.route_path( |
|
1344 | 1343 | 'repo_summary', repo_name=self.db_repo_name) |
|
1345 | 1344 | else: |
|
1346 | 1345 | redirect_url = default_redirect_url |
|
1347 | 1346 | |
|
1348 | 1347 | if not filename: |
|
1349 | 1348 | h.flash(_('No filename'), category='warning') |
|
1350 | 1349 | raise HTTPFound(redirect_url) |
|
1351 | 1350 | |
|
1352 | 1351 | # extract the location from filename, |
|
1353 | 1352 | # allows using foo/bar.txt syntax to create subdirectories |
|
1354 | 1353 | subdir_loc = filename.rsplit('/', 1) |
|
1355 | 1354 | if len(subdir_loc) == 2: |
|
1356 | 1355 | location = os.path.join(location, subdir_loc[0]) |
|
1357 | 1356 | |
|
1358 | 1357 | # strip all crap out of file, just leave the basename |
|
1359 | 1358 | filename = os.path.basename(filename) |
|
1360 | 1359 | node_path = os.path.join(location, filename) |
|
1361 | 1360 | author = self._rhodecode_db_user.full_contact |
|
1362 | 1361 | |
|
1363 | 1362 | try: |
|
1364 | 1363 | nodes = { |
|
1365 | 1364 | node_path: { |
|
1366 | 1365 | 'content': content |
|
1367 | 1366 | } |
|
1368 | 1367 | } |
|
1369 | 1368 | ScmModel().create_nodes( |
|
1370 | 1369 | user=self._rhodecode_db_user.user_id, |
|
1371 | 1370 | repo=self.db_repo, |
|
1372 | 1371 | message=message, |
|
1373 | 1372 | nodes=nodes, |
|
1374 | 1373 | parent_commit=c.commit, |
|
1375 | 1374 | author=author, |
|
1376 | 1375 | ) |
|
1377 | 1376 | |
|
1378 | 1377 | h.flash( |
|
1379 | 1378 | _('Successfully committed new file `{}`').format( |
|
1380 | 1379 | h.escape(node_path)), category='success') |
|
1381 | 1380 | except NonRelativePathError: |
|
1382 | 1381 | log.exception('Non Relative path found') |
|
1383 | 1382 | h.flash(_( |
|
1384 | 1383 | 'The location specified must be a relative path and must not ' |
|
1385 | 1384 | 'contain .. in the path'), category='warning') |
|
1386 | 1385 | raise HTTPFound(default_redirect_url) |
|
1387 | 1386 | except (NodeError, NodeAlreadyExistsError) as e: |
|
1388 | 1387 | h.flash(_(h.escape(e)), category='error') |
|
1389 | 1388 | except Exception: |
|
1390 | 1389 | log.exception('Error occurred during commit') |
|
1391 | 1390 | h.flash(_('Error occurred during commit'), category='error') |
|
1392 | 1391 | |
|
1393 | 1392 | raise HTTPFound(default_redirect_url) |
@@ -1,2050 +1,2057 b'' | |||
|
1 | 1 | # -*- coding: utf-8 -*- |
|
2 | 2 | |
|
3 | 3 | # Copyright (C) 2010-2019 RhodeCode GmbH |
|
4 | 4 | # |
|
5 | 5 | # This program is free software: you can redistribute it and/or modify |
|
6 | 6 | # it under the terms of the GNU Affero General Public License, version 3 |
|
7 | 7 | # (only), as published by the Free Software Foundation. |
|
8 | 8 | # |
|
9 | 9 | # This program is distributed in the hope that it will be useful, |
|
10 | 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 | 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
12 | 12 | # GNU General Public License for more details. |
|
13 | 13 | # |
|
14 | 14 | # You should have received a copy of the GNU Affero General Public License |
|
15 | 15 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
16 | 16 | # |
|
17 | 17 | # This program is dual-licensed. If you wish to learn more about the |
|
18 | 18 | # RhodeCode Enterprise Edition, including its added features, Support services, |
|
19 | 19 | # and proprietary license terms, please see https://rhodecode.com/licenses/ |
|
20 | 20 | |
|
21 | 21 | """ |
|
22 | 22 | Helper functions |
|
23 | 23 | |
|
24 | 24 | Consists of functions to typically be used within templates, but also |
|
25 | 25 | available to Controllers. This module is available to both as 'h'. |
|
26 | 26 | """ |
|
27 | 27 | |
|
28 | 28 | import os |
|
29 | 29 | import random |
|
30 | 30 | import hashlib |
|
31 | 31 | import StringIO |
|
32 | 32 | import textwrap |
|
33 | 33 | import urllib |
|
34 | 34 | import math |
|
35 | 35 | import logging |
|
36 | 36 | import re |
|
37 | 37 | import time |
|
38 | 38 | import string |
|
39 | 39 | import hashlib |
|
40 | 40 | from collections import OrderedDict |
|
41 | 41 | |
|
42 | 42 | import pygments |
|
43 | 43 | import itertools |
|
44 | 44 | import fnmatch |
|
45 | 45 | import bleach |
|
46 | 46 | |
|
47 | 47 | from pyramid import compat |
|
48 | 48 | from datetime import datetime |
|
49 | 49 | from functools import partial |
|
50 | 50 | from pygments.formatters.html import HtmlFormatter |
|
51 | 51 | from pygments.lexers import ( |
|
52 | 52 | get_lexer_by_name, get_lexer_for_filename, get_lexer_for_mimetype) |
|
53 | 53 | |
|
54 | 54 | from pyramid.threadlocal import get_current_request |
|
55 | 55 | |
|
56 | 56 | from webhelpers.html import literal, HTML, escape |
|
57 | 57 | from webhelpers.html.tools import * |
|
58 | 58 | from webhelpers.html.builder import make_tag |
|
59 | 59 | from webhelpers.html.tags import auto_discovery_link, checkbox, css_classes, \ |
|
60 | 60 | end_form, file, form as wh_form, hidden, image, javascript_link, link_to, \ |
|
61 | 61 | link_to_if, link_to_unless, ol, required_legend, select, stylesheet_link, \ |
|
62 | 62 | submit, text, password, textarea, title, ul, xml_declaration, radio |
|
63 | 63 | from webhelpers.html.tools import auto_link, button_to, highlight, \ |
|
64 | 64 | js_obfuscate, mail_to, strip_links, strip_tags, tag_re |
|
65 | 65 | from webhelpers.text import chop_at, collapse, convert_accented_entities, \ |
|
66 | 66 | convert_misc_entities, lchop, plural, rchop, remove_formatting, \ |
|
67 | 67 | replace_whitespace, urlify, truncate, wrap_paragraphs |
|
68 | 68 | from webhelpers.date import time_ago_in_words |
|
69 | 69 | from webhelpers.paginate import Page as _Page |
|
70 | 70 | from webhelpers.html.tags import _set_input_attrs, _set_id_attr, \ |
|
71 | 71 | convert_boolean_attrs, NotGiven, _make_safe_id_component |
|
72 | 72 | from webhelpers2.number import format_byte_size |
|
73 | 73 | |
|
74 | 74 | from rhodecode.lib.action_parser import action_parser |
|
75 | 75 | from rhodecode.lib.ext_json import json |
|
76 | 76 | from rhodecode.lib.utils import repo_name_slug, get_custom_lexer |
|
77 | 77 | from rhodecode.lib.utils2 import str2bool, safe_unicode, safe_str, \ |
|
78 | 78 | get_commit_safe, datetime_to_time, time_to_datetime, time_to_utcdatetime, \ |
|
79 | 79 | AttributeDict, safe_int, md5, md5_safe |
|
80 | 80 | from rhodecode.lib.markup_renderer import MarkupRenderer, relative_links |
|
81 | 81 | from rhodecode.lib.vcs.exceptions import CommitDoesNotExistError |
|
82 | 82 | from rhodecode.lib.vcs.backends.base import BaseChangeset, EmptyCommit |
|
83 | 83 | from rhodecode.lib.index.search_utils import get_matching_line_offsets |
|
84 | 84 | from rhodecode.config.conf import DATE_FORMAT, DATETIME_FORMAT |
|
85 | 85 | from rhodecode.model.changeset_status import ChangesetStatusModel |
|
86 | 86 | from rhodecode.model.db import Permission, User, Repository |
|
87 | 87 | from rhodecode.model.repo_group import RepoGroupModel |
|
88 | 88 | from rhodecode.model.settings import IssueTrackerSettingsModel |
|
89 | 89 | |
|
90 | 90 | |
|
91 | 91 | log = logging.getLogger(__name__) |
|
92 | 92 | |
|
93 | 93 | |
|
94 | 94 | DEFAULT_USER = User.DEFAULT_USER |
|
95 | 95 | DEFAULT_USER_EMAIL = User.DEFAULT_USER_EMAIL |
|
96 | 96 | |
|
97 | 97 | |
|
98 | 98 | def asset(path, ver=None, **kwargs): |
|
99 | 99 | """ |
|
100 | 100 | Helper to generate a static asset file path for rhodecode assets |
|
101 | 101 | |
|
102 | 102 | eg. h.asset('images/image.png', ver='3923') |
|
103 | 103 | |
|
104 | 104 | :param path: path of asset |
|
105 | 105 | :param ver: optional version query param to append as ?ver= |
|
106 | 106 | """ |
|
107 | 107 | request = get_current_request() |
|
108 | 108 | query = {} |
|
109 | 109 | query.update(kwargs) |
|
110 | 110 | if ver: |
|
111 | 111 | query = {'ver': ver} |
|
112 | 112 | return request.static_path( |
|
113 | 113 | 'rhodecode:public/{}'.format(path), _query=query) |
|
114 | 114 | |
|
115 | 115 | |
|
116 | 116 | default_html_escape_table = { |
|
117 | 117 | ord('&'): u'&', |
|
118 | 118 | ord('<'): u'<', |
|
119 | 119 | ord('>'): u'>', |
|
120 | 120 | ord('"'): u'"', |
|
121 | 121 | ord("'"): u''', |
|
122 | 122 | } |
|
123 | 123 | |
|
124 | 124 | |
|
125 | 125 | def html_escape(text, html_escape_table=default_html_escape_table): |
|
126 | 126 | """Produce entities within text.""" |
|
127 | 127 | return text.translate(html_escape_table) |
|
128 | 128 | |
|
129 | 129 | |
|
130 | 130 | def chop_at_smart(s, sub, inclusive=False, suffix_if_chopped=None): |
|
131 | 131 | """ |
|
132 | 132 | Truncate string ``s`` at the first occurrence of ``sub``. |
|
133 | 133 | |
|
134 | 134 | If ``inclusive`` is true, truncate just after ``sub`` rather than at it. |
|
135 | 135 | """ |
|
136 | 136 | suffix_if_chopped = suffix_if_chopped or '' |
|
137 | 137 | pos = s.find(sub) |
|
138 | 138 | if pos == -1: |
|
139 | 139 | return s |
|
140 | 140 | |
|
141 | 141 | if inclusive: |
|
142 | 142 | pos += len(sub) |
|
143 | 143 | |
|
144 | 144 | chopped = s[:pos] |
|
145 | 145 | left = s[pos:].strip() |
|
146 | 146 | |
|
147 | 147 | if left and suffix_if_chopped: |
|
148 | 148 | chopped += suffix_if_chopped |
|
149 | 149 | |
|
150 | 150 | return chopped |
|
151 | 151 | |
|
152 | 152 | |
|
153 | 153 | def shorter(text, size=20): |
|
154 | 154 | postfix = '...' |
|
155 | 155 | if len(text) > size: |
|
156 | 156 | return text[:size - len(postfix)] + postfix |
|
157 | 157 | return text |
|
158 | 158 | |
|
159 | 159 | |
|
160 | 160 | def _reset(name, value=None, id=NotGiven, type="reset", **attrs): |
|
161 | 161 | """ |
|
162 | 162 | Reset button |
|
163 | 163 | """ |
|
164 | 164 | _set_input_attrs(attrs, type, name, value) |
|
165 | 165 | _set_id_attr(attrs, id, name) |
|
166 | 166 | convert_boolean_attrs(attrs, ["disabled"]) |
|
167 | 167 | return HTML.input(**attrs) |
|
168 | 168 | |
|
169 | 169 | reset = _reset |
|
170 | 170 | safeid = _make_safe_id_component |
|
171 | 171 | |
|
172 | 172 | |
|
173 | 173 | def branding(name, length=40): |
|
174 | 174 | return truncate(name, length, indicator="") |
|
175 | 175 | |
|
176 | 176 | |
|
177 | 177 | def FID(raw_id, path): |
|
178 | 178 | """ |
|
179 | 179 | Creates a unique ID for filenode based on it's hash of path and commit |
|
180 | 180 | it's safe to use in urls |
|
181 | 181 | |
|
182 | 182 | :param raw_id: |
|
183 | 183 | :param path: |
|
184 | 184 | """ |
|
185 | 185 | |
|
186 | 186 | return 'c-%s-%s' % (short_id(raw_id), md5_safe(path)[:12]) |
|
187 | 187 | |
|
188 | 188 | |
|
189 | 189 | class _GetError(object): |
|
190 | 190 | """Get error from form_errors, and represent it as span wrapped error |
|
191 | 191 | message |
|
192 | 192 | |
|
193 | 193 | :param field_name: field to fetch errors for |
|
194 | 194 | :param form_errors: form errors dict |
|
195 | 195 | """ |
|
196 | 196 | |
|
197 | 197 | def __call__(self, field_name, form_errors): |
|
198 | 198 | tmpl = """<span class="error_msg">%s</span>""" |
|
199 | 199 | if form_errors and field_name in form_errors: |
|
200 | 200 | return literal(tmpl % form_errors.get(field_name)) |
|
201 | 201 | |
|
202 | ||
|
202 | 203 | get_error = _GetError() |
|
203 | 204 | |
|
204 | 205 | |
|
205 | 206 | class _ToolTip(object): |
|
206 | 207 | |
|
207 | 208 | def __call__(self, tooltip_title, trim_at=50): |
|
208 | 209 | """ |
|
209 | 210 | Special function just to wrap our text into nice formatted |
|
210 | 211 | autowrapped text |
|
211 | 212 | |
|
212 | 213 | :param tooltip_title: |
|
213 | 214 | """ |
|
214 | 215 | tooltip_title = escape(tooltip_title) |
|
215 | 216 | tooltip_title = tooltip_title.replace('<', '<').replace('>', '>') |
|
216 | 217 | return tooltip_title |
|
217 | 218 | |
|
219 | ||
|
218 | 220 | tooltip = _ToolTip() |
|
219 | 221 | |
|
220 | 222 | |
|
221 | def files_breadcrumbs(repo_name, commit_id, file_path, at_ref=None): | |
|
223 | def files_breadcrumbs(repo_name, commit_id, file_path, at_ref=None, limit_items=False): | |
|
222 | 224 | if isinstance(file_path, str): |
|
223 | 225 | file_path = safe_unicode(file_path) |
|
226 | ||
|
224 | 227 | route_qry = {'at': at_ref} if at_ref else None |
|
225 | 228 | |
|
226 | # TODO: johbo: Is this always a url like path, or is this operating | |
|
227 | # system dependent? | |
|
228 | path_segments = file_path.split('/') | |
|
229 | ||
|
230 | repo_name_html = escape(repo_name) | |
|
231 | if len(path_segments) == 1 and path_segments[0] == '': | |
|
232 | url_segments = [repo_name_html] | |
|
233 | else: | |
|
229 | # first segment is a `..` link to repo files | |
|
230 | root_name = literal(u'<i class="icon-home"></i>') | |
|
234 | 231 |
|
|
235 | 232 |
|
|
236 |
|
|
|
233 | root_name, | |
|
237 | 234 |
|
|
238 | 235 |
|
|
239 | 236 |
|
|
240 | 237 |
|
|
241 | 238 |
|
|
242 | 239 |
|
|
243 | 240 |
|
|
244 | 241 | |
|
242 | path_segments = file_path.split('/') | |
|
245 | 243 | last_cnt = len(path_segments) - 1 |
|
246 | 244 | for cnt, segment in enumerate(path_segments): |
|
247 | 245 | if not segment: |
|
248 | 246 | continue |
|
249 | 247 | segment_html = escape(segment) |
|
250 | 248 | |
|
251 | 249 | if cnt != last_cnt: |
|
252 | 250 | url_segments.append( |
|
253 | 251 | link_to( |
|
254 | 252 | segment_html, |
|
255 | 253 | route_path( |
|
256 | 254 | 'repo_files', |
|
257 | 255 | repo_name=repo_name, |
|
258 | 256 | commit_id=commit_id, |
|
259 | 257 | f_path='/'.join(path_segments[:cnt + 1]), |
|
260 | 258 | _query=route_qry), |
|
261 | 259 | )) |
|
262 | 260 | else: |
|
263 | 261 | url_segments.append(segment_html) |
|
264 | 262 | |
|
265 | return literal('/'.join(url_segments)) | |
|
263 | limited_url_segments = url_segments[:1] + ['...'] + url_segments[-5:] | |
|
264 | if limit_items and len(limited_url_segments) < len(url_segments): | |
|
265 | url_segments = limited_url_segments | |
|
266 | ||
|
267 | full_path = file_path | |
|
268 | icon = '<i class="file-breadcrumb-copy tooltip icon-clipboard clipboard-action" data-clipboard-text="{}" title="Copy the full path"></i>'.format(full_path) | |
|
269 | if file_path == '': | |
|
270 | return root_name | |
|
271 | else: | |
|
272 | return literal(' / '.join(url_segments) + icon) | |
|
266 | 273 | |
|
267 | 274 | |
|
268 | 275 | def code_highlight(code, lexer, formatter, use_hl_filter=False): |
|
269 | 276 | """ |
|
270 | 277 | Lex ``code`` with ``lexer`` and format it with the formatter ``formatter``. |
|
271 | 278 | |
|
272 | 279 | If ``outfile`` is given and a valid file object (an object |
|
273 | 280 | with a ``write`` method), the result will be written to it, otherwise |
|
274 | 281 | it is returned as a string. |
|
275 | 282 | """ |
|
276 | 283 | if use_hl_filter: |
|
277 | 284 | # add HL filter |
|
278 | 285 | from rhodecode.lib.index import search_utils |
|
279 | 286 | lexer.add_filter(search_utils.ElasticSearchHLFilter()) |
|
280 | 287 | return pygments.format(pygments.lex(code, lexer), formatter) |
|
281 | 288 | |
|
282 | 289 | |
|
283 | 290 | class CodeHtmlFormatter(HtmlFormatter): |
|
284 | 291 | """ |
|
285 | 292 | My code Html Formatter for source codes |
|
286 | 293 | """ |
|
287 | 294 | |
|
288 | 295 | def wrap(self, source, outfile): |
|
289 | 296 | return self._wrap_div(self._wrap_pre(self._wrap_code(source))) |
|
290 | 297 | |
|
291 | 298 | def _wrap_code(self, source): |
|
292 | 299 | for cnt, it in enumerate(source): |
|
293 | 300 | i, t = it |
|
294 | 301 | t = '<div id="L%s">%s</div>' % (cnt + 1, t) |
|
295 | 302 | yield i, t |
|
296 | 303 | |
|
297 | 304 | def _wrap_tablelinenos(self, inner): |
|
298 | 305 | dummyoutfile = StringIO.StringIO() |
|
299 | 306 | lncount = 0 |
|
300 | 307 | for t, line in inner: |
|
301 | 308 | if t: |
|
302 | 309 | lncount += 1 |
|
303 | 310 | dummyoutfile.write(line) |
|
304 | 311 | |
|
305 | 312 | fl = self.linenostart |
|
306 | 313 | mw = len(str(lncount + fl - 1)) |
|
307 | 314 | sp = self.linenospecial |
|
308 | 315 | st = self.linenostep |
|
309 | 316 | la = self.lineanchors |
|
310 | 317 | aln = self.anchorlinenos |
|
311 | 318 | nocls = self.noclasses |
|
312 | 319 | if sp: |
|
313 | 320 | lines = [] |
|
314 | 321 | |
|
315 | 322 | for i in range(fl, fl + lncount): |
|
316 | 323 | if i % st == 0: |
|
317 | 324 | if i % sp == 0: |
|
318 | 325 | if aln: |
|
319 | 326 | lines.append('<a href="#%s%d" class="special">%*d</a>' % |
|
320 | 327 | (la, i, mw, i)) |
|
321 | 328 | else: |
|
322 | 329 | lines.append('<span class="special">%*d</span>' % (mw, i)) |
|
323 | 330 | else: |
|
324 | 331 | if aln: |
|
325 | 332 | lines.append('<a href="#%s%d">%*d</a>' % (la, i, mw, i)) |
|
326 | 333 | else: |
|
327 | 334 | lines.append('%*d' % (mw, i)) |
|
328 | 335 | else: |
|
329 | 336 | lines.append('') |
|
330 | 337 | ls = '\n'.join(lines) |
|
331 | 338 | else: |
|
332 | 339 | lines = [] |
|
333 | 340 | for i in range(fl, fl + lncount): |
|
334 | 341 | if i % st == 0: |
|
335 | 342 | if aln: |
|
336 | 343 | lines.append('<a href="#%s%d">%*d</a>' % (la, i, mw, i)) |
|
337 | 344 | else: |
|
338 | 345 | lines.append('%*d' % (mw, i)) |
|
339 | 346 | else: |
|
340 | 347 | lines.append('') |
|
341 | 348 | ls = '\n'.join(lines) |
|
342 | 349 | |
|
343 | 350 | # in case you wonder about the seemingly redundant <div> here: since the |
|
344 | 351 | # content in the other cell also is wrapped in a div, some browsers in |
|
345 | 352 | # some configurations seem to mess up the formatting... |
|
346 | 353 | if nocls: |
|
347 | 354 | yield 0, ('<table class="%stable">' % self.cssclass + |
|
348 | 355 | '<tr><td><div class="linenodiv" ' |
|
349 | 356 | 'style="background-color: #f0f0f0; padding-right: 10px">' |
|
350 | 357 | '<pre style="line-height: 125%">' + |
|
351 | 358 | ls + '</pre></div></td><td id="hlcode" class="code">') |
|
352 | 359 | else: |
|
353 | 360 | yield 0, ('<table class="%stable">' % self.cssclass + |
|
354 | 361 | '<tr><td class="linenos"><div class="linenodiv"><pre>' + |
|
355 | 362 | ls + '</pre></div></td><td id="hlcode" class="code">') |
|
356 | 363 | yield 0, dummyoutfile.getvalue() |
|
357 | 364 | yield 0, '</td></tr></table>' |
|
358 | 365 | |
|
359 | 366 | |
|
360 | 367 | class SearchContentCodeHtmlFormatter(CodeHtmlFormatter): |
|
361 | 368 | def __init__(self, **kw): |
|
362 | 369 | # only show these line numbers if set |
|
363 | 370 | self.only_lines = kw.pop('only_line_numbers', []) |
|
364 | 371 | self.query_terms = kw.pop('query_terms', []) |
|
365 | 372 | self.max_lines = kw.pop('max_lines', 5) |
|
366 | 373 | self.line_context = kw.pop('line_context', 3) |
|
367 | 374 | self.url = kw.pop('url', None) |
|
368 | 375 | |
|
369 | 376 | super(CodeHtmlFormatter, self).__init__(**kw) |
|
370 | 377 | |
|
371 | 378 | def _wrap_code(self, source): |
|
372 | 379 | for cnt, it in enumerate(source): |
|
373 | 380 | i, t = it |
|
374 | 381 | t = '<pre>%s</pre>' % t |
|
375 | 382 | yield i, t |
|
376 | 383 | |
|
377 | 384 | def _wrap_tablelinenos(self, inner): |
|
378 | 385 | yield 0, '<table class="code-highlight %stable">' % self.cssclass |
|
379 | 386 | |
|
380 | 387 | last_shown_line_number = 0 |
|
381 | 388 | current_line_number = 1 |
|
382 | 389 | |
|
383 | 390 | for t, line in inner: |
|
384 | 391 | if not t: |
|
385 | 392 | yield t, line |
|
386 | 393 | continue |
|
387 | 394 | |
|
388 | 395 | if current_line_number in self.only_lines: |
|
389 | 396 | if last_shown_line_number + 1 != current_line_number: |
|
390 | 397 | yield 0, '<tr>' |
|
391 | 398 | yield 0, '<td class="line">...</td>' |
|
392 | 399 | yield 0, '<td id="hlcode" class="code"></td>' |
|
393 | 400 | yield 0, '</tr>' |
|
394 | 401 | |
|
395 | 402 | yield 0, '<tr>' |
|
396 | 403 | if self.url: |
|
397 | 404 | yield 0, '<td class="line"><a href="%s#L%i">%i</a></td>' % ( |
|
398 | 405 | self.url, current_line_number, current_line_number) |
|
399 | 406 | else: |
|
400 | 407 | yield 0, '<td class="line"><a href="">%i</a></td>' % ( |
|
401 | 408 | current_line_number) |
|
402 | 409 | yield 0, '<td id="hlcode" class="code">' + line + '</td>' |
|
403 | 410 | yield 0, '</tr>' |
|
404 | 411 | |
|
405 | 412 | last_shown_line_number = current_line_number |
|
406 | 413 | |
|
407 | 414 | current_line_number += 1 |
|
408 | 415 | |
|
409 | 416 | yield 0, '</table>' |
|
410 | 417 | |
|
411 | 418 | |
|
412 | 419 | def hsv_to_rgb(h, s, v): |
|
413 | 420 | """ Convert hsv color values to rgb """ |
|
414 | 421 | |
|
415 | 422 | if s == 0.0: |
|
416 | 423 | return v, v, v |
|
417 | 424 | i = int(h * 6.0) # XXX assume int() truncates! |
|
418 | 425 | f = (h * 6.0) - i |
|
419 | 426 | p = v * (1.0 - s) |
|
420 | 427 | q = v * (1.0 - s * f) |
|
421 | 428 | t = v * (1.0 - s * (1.0 - f)) |
|
422 | 429 | i = i % 6 |
|
423 | 430 | if i == 0: |
|
424 | 431 | return v, t, p |
|
425 | 432 | if i == 1: |
|
426 | 433 | return q, v, p |
|
427 | 434 | if i == 2: |
|
428 | 435 | return p, v, t |
|
429 | 436 | if i == 3: |
|
430 | 437 | return p, q, v |
|
431 | 438 | if i == 4: |
|
432 | 439 | return t, p, v |
|
433 | 440 | if i == 5: |
|
434 | 441 | return v, p, q |
|
435 | 442 | |
|
436 | 443 | |
|
437 | 444 | def unique_color_generator(n=10000, saturation=0.10, lightness=0.95): |
|
438 | 445 | """ |
|
439 | 446 | Generator for getting n of evenly distributed colors using |
|
440 | 447 | hsv color and golden ratio. It always return same order of colors |
|
441 | 448 | |
|
442 | 449 | :param n: number of colors to generate |
|
443 | 450 | :param saturation: saturation of returned colors |
|
444 | 451 | :param lightness: lightness of returned colors |
|
445 | 452 | :returns: RGB tuple |
|
446 | 453 | """ |
|
447 | 454 | |
|
448 | 455 | golden_ratio = 0.618033988749895 |
|
449 | 456 | h = 0.22717784590367374 |
|
450 | 457 | |
|
451 | 458 | for _ in xrange(n): |
|
452 | 459 | h += golden_ratio |
|
453 | 460 | h %= 1 |
|
454 | 461 | HSV_tuple = [h, saturation, lightness] |
|
455 | 462 | RGB_tuple = hsv_to_rgb(*HSV_tuple) |
|
456 | 463 | yield map(lambda x: str(int(x * 256)), RGB_tuple) |
|
457 | 464 | |
|
458 | 465 | |
|
459 | 466 | def color_hasher(n=10000, saturation=0.10, lightness=0.95): |
|
460 | 467 | """ |
|
461 | 468 | Returns a function which when called with an argument returns a unique |
|
462 | 469 | color for that argument, eg. |
|
463 | 470 | |
|
464 | 471 | :param n: number of colors to generate |
|
465 | 472 | :param saturation: saturation of returned colors |
|
466 | 473 | :param lightness: lightness of returned colors |
|
467 | 474 | :returns: css RGB string |
|
468 | 475 | |
|
469 | 476 | >>> color_hash = color_hasher() |
|
470 | 477 | >>> color_hash('hello') |
|
471 | 478 | 'rgb(34, 12, 59)' |
|
472 | 479 | >>> color_hash('hello') |
|
473 | 480 | 'rgb(34, 12, 59)' |
|
474 | 481 | >>> color_hash('other') |
|
475 | 482 | 'rgb(90, 224, 159)' |
|
476 | 483 | """ |
|
477 | 484 | |
|
478 | 485 | color_dict = {} |
|
479 | 486 | cgenerator = unique_color_generator( |
|
480 | 487 | saturation=saturation, lightness=lightness) |
|
481 | 488 | |
|
482 | 489 | def get_color_string(thing): |
|
483 | 490 | if thing in color_dict: |
|
484 | 491 | col = color_dict[thing] |
|
485 | 492 | else: |
|
486 | 493 | col = color_dict[thing] = cgenerator.next() |
|
487 | 494 | return "rgb(%s)" % (', '.join(col)) |
|
488 | 495 | |
|
489 | 496 | return get_color_string |
|
490 | 497 | |
|
491 | 498 | |
|
492 | 499 | def get_lexer_safe(mimetype=None, filepath=None): |
|
493 | 500 | """ |
|
494 | 501 | Tries to return a relevant pygments lexer using mimetype/filepath name, |
|
495 | 502 | defaulting to plain text if none could be found |
|
496 | 503 | """ |
|
497 | 504 | lexer = None |
|
498 | 505 | try: |
|
499 | 506 | if mimetype: |
|
500 | 507 | lexer = get_lexer_for_mimetype(mimetype) |
|
501 | 508 | if not lexer: |
|
502 | 509 | lexer = get_lexer_for_filename(filepath) |
|
503 | 510 | except pygments.util.ClassNotFound: |
|
504 | 511 | pass |
|
505 | 512 | |
|
506 | 513 | if not lexer: |
|
507 | 514 | lexer = get_lexer_by_name('text') |
|
508 | 515 | |
|
509 | 516 | return lexer |
|
510 | 517 | |
|
511 | 518 | |
|
512 | 519 | def get_lexer_for_filenode(filenode): |
|
513 | 520 | lexer = get_custom_lexer(filenode.extension) or filenode.lexer |
|
514 | 521 | return lexer |
|
515 | 522 | |
|
516 | 523 | |
|
517 | 524 | def pygmentize(filenode, **kwargs): |
|
518 | 525 | """ |
|
519 | 526 | pygmentize function using pygments |
|
520 | 527 | |
|
521 | 528 | :param filenode: |
|
522 | 529 | """ |
|
523 | 530 | lexer = get_lexer_for_filenode(filenode) |
|
524 | 531 | return literal(code_highlight(filenode.content, lexer, |
|
525 | 532 | CodeHtmlFormatter(**kwargs))) |
|
526 | 533 | |
|
527 | 534 | |
|
528 | 535 | def is_following_repo(repo_name, user_id): |
|
529 | 536 | from rhodecode.model.scm import ScmModel |
|
530 | 537 | return ScmModel().is_following_repo(repo_name, user_id) |
|
531 | 538 | |
|
532 | 539 | |
|
533 | 540 | class _Message(object): |
|
534 | 541 | """A message returned by ``Flash.pop_messages()``. |
|
535 | 542 | |
|
536 | 543 | Converting the message to a string returns the message text. Instances |
|
537 | 544 | also have the following attributes: |
|
538 | 545 | |
|
539 | 546 | * ``message``: the message text. |
|
540 | 547 | * ``category``: the category specified when the message was created. |
|
541 | 548 | """ |
|
542 | 549 | |
|
543 | 550 | def __init__(self, category, message): |
|
544 | 551 | self.category = category |
|
545 | 552 | self.message = message |
|
546 | 553 | |
|
547 | 554 | def __str__(self): |
|
548 | 555 | return self.message |
|
549 | 556 | |
|
550 | 557 | __unicode__ = __str__ |
|
551 | 558 | |
|
552 | 559 | def __html__(self): |
|
553 | 560 | return escape(safe_unicode(self.message)) |
|
554 | 561 | |
|
555 | 562 | |
|
556 | 563 | class Flash(object): |
|
557 | 564 | # List of allowed categories. If None, allow any category. |
|
558 | 565 | categories = ["warning", "notice", "error", "success"] |
|
559 | 566 | |
|
560 | 567 | # Default category if none is specified. |
|
561 | 568 | default_category = "notice" |
|
562 | 569 | |
|
563 | 570 | def __init__(self, session_key="flash", categories=None, |
|
564 | 571 | default_category=None): |
|
565 | 572 | """ |
|
566 | 573 | Instantiate a ``Flash`` object. |
|
567 | 574 | |
|
568 | 575 | ``session_key`` is the key to save the messages under in the user's |
|
569 | 576 | session. |
|
570 | 577 | |
|
571 | 578 | ``categories`` is an optional list which overrides the default list |
|
572 | 579 | of categories. |
|
573 | 580 | |
|
574 | 581 | ``default_category`` overrides the default category used for messages |
|
575 | 582 | when none is specified. |
|
576 | 583 | """ |
|
577 | 584 | self.session_key = session_key |
|
578 | 585 | if categories is not None: |
|
579 | 586 | self.categories = categories |
|
580 | 587 | if default_category is not None: |
|
581 | 588 | self.default_category = default_category |
|
582 | 589 | if self.categories and self.default_category not in self.categories: |
|
583 | 590 | raise ValueError( |
|
584 | 591 | "unrecognized default category %r" % (self.default_category,)) |
|
585 | 592 | |
|
586 | 593 | def pop_messages(self, session=None, request=None): |
|
587 | 594 | """ |
|
588 | 595 | Return all accumulated messages and delete them from the session. |
|
589 | 596 | |
|
590 | 597 | The return value is a list of ``Message`` objects. |
|
591 | 598 | """ |
|
592 | 599 | messages = [] |
|
593 | 600 | |
|
594 | 601 | if not session: |
|
595 | 602 | if not request: |
|
596 | 603 | request = get_current_request() |
|
597 | 604 | session = request.session |
|
598 | 605 | |
|
599 | 606 | # Pop the 'old' pylons flash messages. They are tuples of the form |
|
600 | 607 | # (category, message) |
|
601 | 608 | for cat, msg in session.pop(self.session_key, []): |
|
602 | 609 | messages.append(_Message(cat, msg)) |
|
603 | 610 | |
|
604 | 611 | # Pop the 'new' pyramid flash messages for each category as list |
|
605 | 612 | # of strings. |
|
606 | 613 | for cat in self.categories: |
|
607 | 614 | for msg in session.pop_flash(queue=cat): |
|
608 | 615 | messages.append(_Message(cat, msg)) |
|
609 | 616 | # Map messages from the default queue to the 'notice' category. |
|
610 | 617 | for msg in session.pop_flash(): |
|
611 | 618 | messages.append(_Message('notice', msg)) |
|
612 | 619 | |
|
613 | 620 | session.save() |
|
614 | 621 | return messages |
|
615 | 622 | |
|
616 | 623 | def json_alerts(self, session=None, request=None): |
|
617 | 624 | payloads = [] |
|
618 | 625 | messages = flash.pop_messages(session=session, request=request) |
|
619 | 626 | if messages: |
|
620 | 627 | for message in messages: |
|
621 | 628 | subdata = {} |
|
622 | 629 | if hasattr(message.message, 'rsplit'): |
|
623 | 630 | flash_data = message.message.rsplit('|DELIM|', 1) |
|
624 | 631 | org_message = flash_data[0] |
|
625 | 632 | if len(flash_data) > 1: |
|
626 | 633 | subdata = json.loads(flash_data[1]) |
|
627 | 634 | else: |
|
628 | 635 | org_message = message.message |
|
629 | 636 | payloads.append({ |
|
630 | 637 | 'message': { |
|
631 | 638 | 'message': u'{}'.format(org_message), |
|
632 | 639 | 'level': message.category, |
|
633 | 640 | 'force': True, |
|
634 | 641 | 'subdata': subdata |
|
635 | 642 | } |
|
636 | 643 | }) |
|
637 | 644 | return json.dumps(payloads) |
|
638 | 645 | |
|
639 | 646 | def __call__(self, message, category=None, ignore_duplicate=False, |
|
640 | 647 | session=None, request=None): |
|
641 | 648 | |
|
642 | 649 | if not session: |
|
643 | 650 | if not request: |
|
644 | 651 | request = get_current_request() |
|
645 | 652 | session = request.session |
|
646 | 653 | |
|
647 | 654 | session.flash( |
|
648 | 655 | message, queue=category, allow_duplicate=not ignore_duplicate) |
|
649 | 656 | |
|
650 | 657 | |
|
651 | 658 | flash = Flash() |
|
652 | 659 | |
|
653 | 660 | #============================================================================== |
|
654 | 661 | # SCM FILTERS available via h. |
|
655 | 662 | #============================================================================== |
|
656 | 663 | from rhodecode.lib.vcs.utils import author_name, author_email |
|
657 | 664 | from rhodecode.lib.utils2 import credentials_filter, age, age_from_seconds |
|
658 | 665 | from rhodecode.model.db import User, ChangesetStatus |
|
659 | 666 | |
|
660 | 667 | capitalize = lambda x: x.capitalize() |
|
661 | 668 | email = author_email |
|
662 | 669 | short_id = lambda x: x[:12] |
|
663 | 670 | hide_credentials = lambda x: ''.join(credentials_filter(x)) |
|
664 | 671 | |
|
665 | 672 | |
|
666 | 673 | import pytz |
|
667 | 674 | import tzlocal |
|
668 | 675 | local_timezone = tzlocal.get_localzone() |
|
669 | 676 | |
|
670 | 677 | |
|
671 | 678 | def age_component(datetime_iso, value=None, time_is_local=False): |
|
672 | 679 | title = value or format_date(datetime_iso) |
|
673 | 680 | tzinfo = '+00:00' |
|
674 | 681 | |
|
675 | 682 | # detect if we have a timezone info, otherwise, add it |
|
676 | 683 | if time_is_local and isinstance(datetime_iso, datetime) and not datetime_iso.tzinfo: |
|
677 | 684 | force_timezone = os.environ.get('RC_TIMEZONE', '') |
|
678 | 685 | if force_timezone: |
|
679 | 686 | force_timezone = pytz.timezone(force_timezone) |
|
680 | 687 | timezone = force_timezone or local_timezone |
|
681 | 688 | offset = timezone.localize(datetime_iso).strftime('%z') |
|
682 | 689 | tzinfo = '{}:{}'.format(offset[:-2], offset[-2:]) |
|
683 | 690 | |
|
684 | 691 | return literal( |
|
685 | 692 | '<time class="timeago tooltip" ' |
|
686 | 693 | 'title="{1}{2}" datetime="{0}{2}">{1}</time>'.format( |
|
687 | 694 | datetime_iso, title, tzinfo)) |
|
688 | 695 | |
|
689 | 696 | |
|
690 | 697 | def _shorten_commit_id(commit_id, commit_len=None): |
|
691 | 698 | if commit_len is None: |
|
692 | 699 | request = get_current_request() |
|
693 | 700 | commit_len = request.call_context.visual.show_sha_length |
|
694 | 701 | return commit_id[:commit_len] |
|
695 | 702 | |
|
696 | 703 | |
|
697 | 704 | def show_id(commit, show_idx=None, commit_len=None): |
|
698 | 705 | """ |
|
699 | 706 | Configurable function that shows ID |
|
700 | 707 | by default it's r123:fffeeefffeee |
|
701 | 708 | |
|
702 | 709 | :param commit: commit instance |
|
703 | 710 | """ |
|
704 | 711 | if show_idx is None: |
|
705 | 712 | request = get_current_request() |
|
706 | 713 | show_idx = request.call_context.visual.show_revision_number |
|
707 | 714 | |
|
708 | 715 | raw_id = _shorten_commit_id(commit.raw_id, commit_len=commit_len) |
|
709 | 716 | if show_idx: |
|
710 | 717 | return 'r%s:%s' % (commit.idx, raw_id) |
|
711 | 718 | else: |
|
712 | 719 | return '%s' % (raw_id, ) |
|
713 | 720 | |
|
714 | 721 | |
|
715 | 722 | def format_date(date): |
|
716 | 723 | """ |
|
717 | 724 | use a standardized formatting for dates used in RhodeCode |
|
718 | 725 | |
|
719 | 726 | :param date: date/datetime object |
|
720 | 727 | :return: formatted date |
|
721 | 728 | """ |
|
722 | 729 | |
|
723 | 730 | if date: |
|
724 | 731 | _fmt = "%a, %d %b %Y %H:%M:%S" |
|
725 | 732 | return safe_unicode(date.strftime(_fmt)) |
|
726 | 733 | |
|
727 | 734 | return u"" |
|
728 | 735 | |
|
729 | 736 | |
|
730 | 737 | class _RepoChecker(object): |
|
731 | 738 | |
|
732 | 739 | def __init__(self, backend_alias): |
|
733 | 740 | self._backend_alias = backend_alias |
|
734 | 741 | |
|
735 | 742 | def __call__(self, repository): |
|
736 | 743 | if hasattr(repository, 'alias'): |
|
737 | 744 | _type = repository.alias |
|
738 | 745 | elif hasattr(repository, 'repo_type'): |
|
739 | 746 | _type = repository.repo_type |
|
740 | 747 | else: |
|
741 | 748 | _type = repository |
|
742 | 749 | return _type == self._backend_alias |
|
743 | 750 | |
|
744 | 751 | |
|
745 | 752 | is_git = _RepoChecker('git') |
|
746 | 753 | is_hg = _RepoChecker('hg') |
|
747 | 754 | is_svn = _RepoChecker('svn') |
|
748 | 755 | |
|
749 | 756 | |
|
750 | 757 | def get_repo_type_by_name(repo_name): |
|
751 | 758 | repo = Repository.get_by_repo_name(repo_name) |
|
752 | 759 | if repo: |
|
753 | 760 | return repo.repo_type |
|
754 | 761 | |
|
755 | 762 | |
|
756 | 763 | def is_svn_without_proxy(repository): |
|
757 | 764 | if is_svn(repository): |
|
758 | 765 | from rhodecode.model.settings import VcsSettingsModel |
|
759 | 766 | conf = VcsSettingsModel().get_ui_settings_as_config_obj() |
|
760 | 767 | return not str2bool(conf.get('vcs_svn_proxy', 'http_requests_enabled')) |
|
761 | 768 | return False |
|
762 | 769 | |
|
763 | 770 | |
|
764 | 771 | def discover_user(author): |
|
765 | 772 | """ |
|
766 | 773 | Tries to discover RhodeCode User based on the autho string. Author string |
|
767 | 774 | is typically `FirstName LastName <email@address.com>` |
|
768 | 775 | """ |
|
769 | 776 | |
|
770 | 777 | # if author is already an instance use it for extraction |
|
771 | 778 | if isinstance(author, User): |
|
772 | 779 | return author |
|
773 | 780 | |
|
774 | 781 | # Valid email in the attribute passed, see if they're in the system |
|
775 | 782 | _email = author_email(author) |
|
776 | 783 | if _email != '': |
|
777 | 784 | user = User.get_by_email(_email, case_insensitive=True, cache=True) |
|
778 | 785 | if user is not None: |
|
779 | 786 | return user |
|
780 | 787 | |
|
781 | 788 | # Maybe it's a username, we try to extract it and fetch by username ? |
|
782 | 789 | _author = author_name(author) |
|
783 | 790 | user = User.get_by_username(_author, case_insensitive=True, cache=True) |
|
784 | 791 | if user is not None: |
|
785 | 792 | return user |
|
786 | 793 | |
|
787 | 794 | return None |
|
788 | 795 | |
|
789 | 796 | |
|
790 | 797 | def email_or_none(author): |
|
791 | 798 | # extract email from the commit string |
|
792 | 799 | _email = author_email(author) |
|
793 | 800 | |
|
794 | 801 | # If we have an email, use it, otherwise |
|
795 | 802 | # see if it contains a username we can get an email from |
|
796 | 803 | if _email != '': |
|
797 | 804 | return _email |
|
798 | 805 | else: |
|
799 | 806 | user = User.get_by_username( |
|
800 | 807 | author_name(author), case_insensitive=True, cache=True) |
|
801 | 808 | |
|
802 | 809 | if user is not None: |
|
803 | 810 | return user.email |
|
804 | 811 | |
|
805 | 812 | # No valid email, not a valid user in the system, none! |
|
806 | 813 | return None |
|
807 | 814 | |
|
808 | 815 | |
|
809 | 816 | def link_to_user(author, length=0, **kwargs): |
|
810 | 817 | user = discover_user(author) |
|
811 | 818 | # user can be None, but if we have it already it means we can re-use it |
|
812 | 819 | # in the person() function, so we save 1 intensive-query |
|
813 | 820 | if user: |
|
814 | 821 | author = user |
|
815 | 822 | |
|
816 | 823 | display_person = person(author, 'username_or_name_or_email') |
|
817 | 824 | if length: |
|
818 | 825 | display_person = shorter(display_person, length) |
|
819 | 826 | |
|
820 | 827 | if user: |
|
821 | 828 | return link_to( |
|
822 | 829 | escape(display_person), |
|
823 | 830 | route_path('user_profile', username=user.username), |
|
824 | 831 | **kwargs) |
|
825 | 832 | else: |
|
826 | 833 | return escape(display_person) |
|
827 | 834 | |
|
828 | 835 | |
|
829 | 836 | def link_to_group(users_group_name, **kwargs): |
|
830 | 837 | return link_to( |
|
831 | 838 | escape(users_group_name), |
|
832 | 839 | route_path('user_group_profile', user_group_name=users_group_name), |
|
833 | 840 | **kwargs) |
|
834 | 841 | |
|
835 | 842 | |
|
836 | 843 | def person(author, show_attr="username_and_name"): |
|
837 | 844 | user = discover_user(author) |
|
838 | 845 | if user: |
|
839 | 846 | return getattr(user, show_attr) |
|
840 | 847 | else: |
|
841 | 848 | _author = author_name(author) |
|
842 | 849 | _email = email(author) |
|
843 | 850 | return _author or _email |
|
844 | 851 | |
|
845 | 852 | |
|
846 | 853 | def author_string(email): |
|
847 | 854 | if email: |
|
848 | 855 | user = User.get_by_email(email, case_insensitive=True, cache=True) |
|
849 | 856 | if user: |
|
850 | 857 | if user.first_name or user.last_name: |
|
851 | 858 | return '%s %s <%s>' % ( |
|
852 | 859 | user.first_name, user.last_name, email) |
|
853 | 860 | else: |
|
854 | 861 | return email |
|
855 | 862 | else: |
|
856 | 863 | return email |
|
857 | 864 | else: |
|
858 | 865 | return None |
|
859 | 866 | |
|
860 | 867 | |
|
861 | 868 | def person_by_id(id_, show_attr="username_and_name"): |
|
862 | 869 | # attr to return from fetched user |
|
863 | 870 | person_getter = lambda usr: getattr(usr, show_attr) |
|
864 | 871 | |
|
865 | 872 | #maybe it's an ID ? |
|
866 | 873 | if str(id_).isdigit() or isinstance(id_, int): |
|
867 | 874 | id_ = int(id_) |
|
868 | 875 | user = User.get(id_) |
|
869 | 876 | if user is not None: |
|
870 | 877 | return person_getter(user) |
|
871 | 878 | return id_ |
|
872 | 879 | |
|
873 | 880 | |
|
874 | 881 | def gravatar_with_user(request, author, show_disabled=False): |
|
875 | 882 | _render = request.get_partial_renderer( |
|
876 | 883 | 'rhodecode:templates/base/base.mako') |
|
877 | 884 | return _render('gravatar_with_user', author, show_disabled=show_disabled) |
|
878 | 885 | |
|
879 | 886 | |
|
880 | 887 | tags_paterns = OrderedDict(( |
|
881 | 888 | ('lang', (re.compile(r'\[(lang|language)\ \=\>\ *([a-zA-Z\-\/\#\+\.]*)\]'), |
|
882 | 889 | '<div class="metatag" tag="lang">\\2</div>')), |
|
883 | 890 | |
|
884 | 891 | ('see', (re.compile(r'\[see\ \=\>\ *([a-zA-Z0-9\/\=\?\&\ \:\/\.\-]*)\]'), |
|
885 | 892 | '<div class="metatag" tag="see">see: \\1 </div>')), |
|
886 | 893 | |
|
887 | 894 | ('url', (re.compile(r'\[url\ \=\>\ \[([a-zA-Z0-9\ \.\-\_]+)\]\((http://|https://|/)(.*?)\)\]'), |
|
888 | 895 | '<div class="metatag" tag="url"> <a href="\\2\\3">\\1</a> </div>')), |
|
889 | 896 | |
|
890 | 897 | ('license', (re.compile(r'\[license\ \=\>\ *([a-zA-Z0-9\/\=\?\&\ \:\/\.\-]*)\]'), |
|
891 | 898 | '<div class="metatag" tag="license"><a href="http:\/\/www.opensource.org/licenses/\\1">\\1</a></div>')), |
|
892 | 899 | |
|
893 | 900 | ('ref', (re.compile(r'\[(requires|recommends|conflicts|base)\ \=\>\ *([a-zA-Z0-9\-\/]*)\]'), |
|
894 | 901 | '<div class="metatag" tag="ref \\1">\\1: <a href="/\\2">\\2</a></div>')), |
|
895 | 902 | |
|
896 | 903 | ('state', (re.compile(r'\[(stable|featured|stale|dead|dev|deprecated)\]'), |
|
897 | 904 | '<div class="metatag" tag="state \\1">\\1</div>')), |
|
898 | 905 | |
|
899 | 906 | # label in grey |
|
900 | 907 | ('label', (re.compile(r'\[([a-z]+)\]'), |
|
901 | 908 | '<div class="metatag" tag="label">\\1</div>')), |
|
902 | 909 | |
|
903 | 910 | # generic catch all in grey |
|
904 | 911 | ('generic', (re.compile(r'\[([a-zA-Z0-9\.\-\_]+)\]'), |
|
905 | 912 | '<div class="metatag" tag="generic">\\1</div>')), |
|
906 | 913 | )) |
|
907 | 914 | |
|
908 | 915 | |
|
909 | 916 | def extract_metatags(value): |
|
910 | 917 | """ |
|
911 | 918 | Extract supported meta-tags from given text value |
|
912 | 919 | """ |
|
913 | 920 | tags = [] |
|
914 | 921 | if not value: |
|
915 | 922 | return tags, '' |
|
916 | 923 | |
|
917 | 924 | for key, val in tags_paterns.items(): |
|
918 | 925 | pat, replace_html = val |
|
919 | 926 | tags.extend([(key, x.group()) for x in pat.finditer(value)]) |
|
920 | 927 | value = pat.sub('', value) |
|
921 | 928 | |
|
922 | 929 | return tags, value |
|
923 | 930 | |
|
924 | 931 | |
|
925 | 932 | def style_metatag(tag_type, value): |
|
926 | 933 | """ |
|
927 | 934 | converts tags from value into html equivalent |
|
928 | 935 | """ |
|
929 | 936 | if not value: |
|
930 | 937 | return '' |
|
931 | 938 | |
|
932 | 939 | html_value = value |
|
933 | 940 | tag_data = tags_paterns.get(tag_type) |
|
934 | 941 | if tag_data: |
|
935 | 942 | pat, replace_html = tag_data |
|
936 | 943 | # convert to plain `unicode` instead of a markup tag to be used in |
|
937 | 944 | # regex expressions. safe_unicode doesn't work here |
|
938 | 945 | html_value = pat.sub(replace_html, unicode(value)) |
|
939 | 946 | |
|
940 | 947 | return html_value |
|
941 | 948 | |
|
942 | 949 | |
|
943 | 950 | def bool2icon(value, show_at_false=True): |
|
944 | 951 | """ |
|
945 | 952 | Returns boolean value of a given value, represented as html element with |
|
946 | 953 | classes that will represent icons |
|
947 | 954 | |
|
948 | 955 | :param value: given value to convert to html node |
|
949 | 956 | """ |
|
950 | 957 | |
|
951 | 958 | if value: # does bool conversion |
|
952 | 959 | return HTML.tag('i', class_="icon-true") |
|
953 | 960 | else: # not true as bool |
|
954 | 961 | if show_at_false: |
|
955 | 962 | return HTML.tag('i', class_="icon-false") |
|
956 | 963 | return HTML.tag('i') |
|
957 | 964 | |
|
958 | 965 | #============================================================================== |
|
959 | 966 | # PERMS |
|
960 | 967 | #============================================================================== |
|
961 | 968 | from rhodecode.lib.auth import HasPermissionAny, HasPermissionAll, \ |
|
962 | 969 | HasRepoPermissionAny, HasRepoPermissionAll, HasRepoGroupPermissionAll, \ |
|
963 | 970 | HasRepoGroupPermissionAny, HasRepoPermissionAnyApi, get_csrf_token, \ |
|
964 | 971 | csrf_token_key |
|
965 | 972 | |
|
966 | 973 | |
|
967 | 974 | #============================================================================== |
|
968 | 975 | # GRAVATAR URL |
|
969 | 976 | #============================================================================== |
|
970 | 977 | class InitialsGravatar(object): |
|
971 | 978 | def __init__(self, email_address, first_name, last_name, size=30, |
|
972 | 979 | background=None, text_color='#fff'): |
|
973 | 980 | self.size = size |
|
974 | 981 | self.first_name = first_name |
|
975 | 982 | self.last_name = last_name |
|
976 | 983 | self.email_address = email_address |
|
977 | 984 | self.background = background or self.str2color(email_address) |
|
978 | 985 | self.text_color = text_color |
|
979 | 986 | |
|
980 | 987 | def get_color_bank(self): |
|
981 | 988 | """ |
|
982 | 989 | returns a predefined list of colors that gravatars can use. |
|
983 | 990 | Those are randomized distinct colors that guarantee readability and |
|
984 | 991 | uniqueness. |
|
985 | 992 | |
|
986 | 993 | generated with: http://phrogz.net/css/distinct-colors.html |
|
987 | 994 | """ |
|
988 | 995 | return [ |
|
989 | 996 | '#bf3030', '#a67f53', '#00ff00', '#5989b3', '#392040', '#d90000', |
|
990 | 997 | '#402910', '#204020', '#79baf2', '#a700b3', '#bf6060', '#7f5320', |
|
991 | 998 | '#008000', '#003059', '#ee00ff', '#ff0000', '#8c4b00', '#007300', |
|
992 | 999 | '#005fb3', '#de73e6', '#ff4040', '#ffaa00', '#3df255', '#203140', |
|
993 | 1000 | '#47004d', '#591616', '#664400', '#59b365', '#0d2133', '#83008c', |
|
994 | 1001 | '#592d2d', '#bf9f60', '#73e682', '#1d3f73', '#73006b', '#402020', |
|
995 | 1002 | '#b2862d', '#397341', '#597db3', '#e600d6', '#a60000', '#736039', |
|
996 | 1003 | '#00b318', '#79aaf2', '#330d30', '#ff8080', '#403010', '#16591f', |
|
997 | 1004 | '#002459', '#8c4688', '#e50000', '#ffbf40', '#00732e', '#102340', |
|
998 | 1005 | '#bf60ac', '#8c4646', '#cc8800', '#00a642', '#1d3473', '#b32d98', |
|
999 | 1006 | '#660e00', '#ffd580', '#80ffb2', '#7391e6', '#733967', '#d97b6c', |
|
1000 | 1007 | '#8c5e00', '#59b389', '#3967e6', '#590047', '#73281d', '#665200', |
|
1001 | 1008 | '#00e67a', '#2d50b3', '#8c2377', '#734139', '#b2982d', '#16593a', |
|
1002 | 1009 | '#001859', '#ff00aa', '#a65e53', '#ffcc00', '#0d3321', '#2d3959', |
|
1003 | 1010 | '#731d56', '#401610', '#4c3d00', '#468c6c', '#002ca6', '#d936a3', |
|
1004 | 1011 | '#d94c36', '#403920', '#36d9a3', '#0d1733', '#592d4a', '#993626', |
|
1005 | 1012 | '#cca300', '#00734d', '#46598c', '#8c005e', '#7f1100', '#8c7000', |
|
1006 | 1013 | '#00a66f', '#7382e6', '#b32d74', '#d9896c', '#ffe680', '#1d7362', |
|
1007 | 1014 | '#364cd9', '#73003d', '#d93a00', '#998a4d', '#59b3a1', '#5965b3', |
|
1008 | 1015 | '#e5007a', '#73341d', '#665f00', '#00b38f', '#0018b3', '#59163a', |
|
1009 | 1016 | '#b2502d', '#bfb960', '#00ffcc', '#23318c', '#a6537f', '#734939', |
|
1010 | 1017 | '#b2a700', '#104036', '#3d3df2', '#402031', '#e56739', '#736f39', |
|
1011 | 1018 | '#79f2ea', '#000059', '#401029', '#4c1400', '#ffee00', '#005953', |
|
1012 | 1019 | '#101040', '#990052', '#402820', '#403d10', '#00ffee', '#0000d9', |
|
1013 | 1020 | '#ff80c4', '#a66953', '#eeff00', '#00ccbe', '#8080ff', '#e673a1', |
|
1014 | 1021 | '#a62c00', '#474d00', '#1a3331', '#46468c', '#733950', '#662900', |
|
1015 | 1022 | '#858c23', '#238c85', '#0f0073', '#b20047', '#d9986c', '#becc00', |
|
1016 | 1023 | '#396f73', '#281d73', '#ff0066', '#ff6600', '#dee673', '#59adb3', |
|
1017 | 1024 | '#6559b3', '#590024', '#b2622d', '#98b32d', '#36ced9', '#332d59', |
|
1018 | 1025 | '#40001a', '#733f1d', '#526600', '#005359', '#242040', '#bf6079', |
|
1019 | 1026 | '#735039', '#cef23d', '#007780', '#5630bf', '#66001b', '#b24700', |
|
1020 | 1027 | '#acbf60', '#1d6273', '#25008c', '#731d34', '#a67453', '#50592d', |
|
1021 | 1028 | '#00ccff', '#6600ff', '#ff0044', '#4c1f00', '#8a994d', '#79daf2', |
|
1022 | 1029 | '#a173e6', '#d93662', '#402310', '#aaff00', '#2d98b3', '#8c40ff', |
|
1023 | 1030 | '#592d39', '#ff8c40', '#354020', '#103640', '#1a0040', '#331a20', |
|
1024 | 1031 | '#331400', '#334d00', '#1d5673', '#583973', '#7f0022', '#4c3626', |
|
1025 | 1032 | '#88cc00', '#36a3d9', '#3d0073', '#d9364c', '#33241a', '#698c23', |
|
1026 | 1033 | '#5995b3', '#300059', '#e57382', '#7f3300', '#366600', '#00aaff', |
|
1027 | 1034 | '#3a1659', '#733941', '#663600', '#74b32d', '#003c59', '#7f53a6', |
|
1028 | 1035 | '#73000f', '#ff8800', '#baf279', '#79caf2', '#291040', '#a6293a', |
|
1029 | 1036 | '#b2742d', '#587339', '#0077b3', '#632699', '#400009', '#d9a66c', |
|
1030 | 1037 | '#294010', '#2d4a59', '#aa00ff', '#4c131b', '#b25f00', '#5ce600', |
|
1031 | 1038 | '#267399', '#a336d9', '#990014', '#664e33', '#86bf60', '#0088ff', |
|
1032 | 1039 | '#7700b3', '#593a16', '#073300', '#1d4b73', '#ac60bf', '#e59539', |
|
1033 | 1040 | '#4f8c46', '#368dd9', '#5c0073' |
|
1034 | 1041 | ] |
|
1035 | 1042 | |
|
1036 | 1043 | def rgb_to_hex_color(self, rgb_tuple): |
|
1037 | 1044 | """ |
|
1038 | 1045 | Converts an rgb_tuple passed to an hex color. |
|
1039 | 1046 | |
|
1040 | 1047 | :param rgb_tuple: tuple with 3 ints represents rgb color space |
|
1041 | 1048 | """ |
|
1042 | 1049 | return '#' + ("".join(map(chr, rgb_tuple)).encode('hex')) |
|
1043 | 1050 | |
|
1044 | 1051 | def email_to_int_list(self, email_str): |
|
1045 | 1052 | """ |
|
1046 | 1053 | Get every byte of the hex digest value of email and turn it to integer. |
|
1047 | 1054 | It's going to be always between 0-255 |
|
1048 | 1055 | """ |
|
1049 | 1056 | digest = md5_safe(email_str.lower()) |
|
1050 | 1057 | return [int(digest[i * 2:i * 2 + 2], 16) for i in range(16)] |
|
1051 | 1058 | |
|
1052 | 1059 | def pick_color_bank_index(self, email_str, color_bank): |
|
1053 | 1060 | return self.email_to_int_list(email_str)[0] % len(color_bank) |
|
1054 | 1061 | |
|
1055 | 1062 | def str2color(self, email_str): |
|
1056 | 1063 | """ |
|
1057 | 1064 | Tries to map in a stable algorithm an email to color |
|
1058 | 1065 | |
|
1059 | 1066 | :param email_str: |
|
1060 | 1067 | """ |
|
1061 | 1068 | color_bank = self.get_color_bank() |
|
1062 | 1069 | # pick position (module it's length so we always find it in the |
|
1063 | 1070 | # bank even if it's smaller than 256 values |
|
1064 | 1071 | pos = self.pick_color_bank_index(email_str, color_bank) |
|
1065 | 1072 | return color_bank[pos] |
|
1066 | 1073 | |
|
1067 | 1074 | def normalize_email(self, email_address): |
|
1068 | 1075 | import unicodedata |
|
1069 | 1076 | # default host used to fill in the fake/missing email |
|
1070 | 1077 | default_host = u'localhost' |
|
1071 | 1078 | |
|
1072 | 1079 | if not email_address: |
|
1073 | 1080 | email_address = u'%s@%s' % (User.DEFAULT_USER, default_host) |
|
1074 | 1081 | |
|
1075 | 1082 | email_address = safe_unicode(email_address) |
|
1076 | 1083 | |
|
1077 | 1084 | if u'@' not in email_address: |
|
1078 | 1085 | email_address = u'%s@%s' % (email_address, default_host) |
|
1079 | 1086 | |
|
1080 | 1087 | if email_address.endswith(u'@'): |
|
1081 | 1088 | email_address = u'%s%s' % (email_address, default_host) |
|
1082 | 1089 | |
|
1083 | 1090 | email_address = unicodedata.normalize('NFKD', email_address)\ |
|
1084 | 1091 | .encode('ascii', 'ignore') |
|
1085 | 1092 | return email_address |
|
1086 | 1093 | |
|
1087 | 1094 | def get_initials(self): |
|
1088 | 1095 | """ |
|
1089 | 1096 | Returns 2 letter initials calculated based on the input. |
|
1090 | 1097 | The algorithm picks first given email address, and takes first letter |
|
1091 | 1098 | of part before @, and then the first letter of server name. In case |
|
1092 | 1099 | the part before @ is in a format of `somestring.somestring2` it replaces |
|
1093 | 1100 | the server letter with first letter of somestring2 |
|
1094 | 1101 | |
|
1095 | 1102 | In case function was initialized with both first and lastname, this |
|
1096 | 1103 | overrides the extraction from email by first letter of the first and |
|
1097 | 1104 | last name. We add special logic to that functionality, In case Full name |
|
1098 | 1105 | is compound, like Guido Von Rossum, we use last part of the last name |
|
1099 | 1106 | (Von Rossum) picking `R`. |
|
1100 | 1107 | |
|
1101 | 1108 | Function also normalizes the non-ascii characters to they ascii |
|
1102 | 1109 | representation, eg Ą => A |
|
1103 | 1110 | """ |
|
1104 | 1111 | import unicodedata |
|
1105 | 1112 | # replace non-ascii to ascii |
|
1106 | 1113 | first_name = unicodedata.normalize( |
|
1107 | 1114 | 'NFKD', safe_unicode(self.first_name)).encode('ascii', 'ignore') |
|
1108 | 1115 | last_name = unicodedata.normalize( |
|
1109 | 1116 | 'NFKD', safe_unicode(self.last_name)).encode('ascii', 'ignore') |
|
1110 | 1117 | |
|
1111 | 1118 | # do NFKD encoding, and also make sure email has proper format |
|
1112 | 1119 | email_address = self.normalize_email(self.email_address) |
|
1113 | 1120 | |
|
1114 | 1121 | # first push the email initials |
|
1115 | 1122 | prefix, server = email_address.split('@', 1) |
|
1116 | 1123 | |
|
1117 | 1124 | # check if prefix is maybe a 'first_name.last_name' syntax |
|
1118 | 1125 | _dot_split = prefix.rsplit('.', 1) |
|
1119 | 1126 | if len(_dot_split) == 2 and _dot_split[1]: |
|
1120 | 1127 | initials = [_dot_split[0][0], _dot_split[1][0]] |
|
1121 | 1128 | else: |
|
1122 | 1129 | initials = [prefix[0], server[0]] |
|
1123 | 1130 | |
|
1124 | 1131 | # then try to replace either first_name or last_name |
|
1125 | 1132 | fn_letter = (first_name or " ")[0].strip() |
|
1126 | 1133 | ln_letter = (last_name.split(' ', 1)[-1] or " ")[0].strip() |
|
1127 | 1134 | |
|
1128 | 1135 | if fn_letter: |
|
1129 | 1136 | initials[0] = fn_letter |
|
1130 | 1137 | |
|
1131 | 1138 | if ln_letter: |
|
1132 | 1139 | initials[1] = ln_letter |
|
1133 | 1140 | |
|
1134 | 1141 | return ''.join(initials).upper() |
|
1135 | 1142 | |
|
1136 | 1143 | def get_img_data_by_type(self, font_family, img_type): |
|
1137 | 1144 | default_user = """ |
|
1138 | 1145 | <svg xmlns="http://www.w3.org/2000/svg" |
|
1139 | 1146 | version="1.1" x="0px" y="0px" width="{size}" height="{size}" |
|
1140 | 1147 | viewBox="-15 -10 439.165 429.164" |
|
1141 | 1148 | |
|
1142 | 1149 | xml:space="preserve" |
|
1143 | 1150 | style="background:{background};" > |
|
1144 | 1151 | |
|
1145 | 1152 | <path d="M204.583,216.671c50.664,0,91.74-48.075, |
|
1146 | 1153 | 91.74-107.378c0-82.237-41.074-107.377-91.74-107.377 |
|
1147 | 1154 | c-50.668,0-91.74,25.14-91.74,107.377C112.844, |
|
1148 | 1155 | 168.596,153.916,216.671, |
|
1149 | 1156 | 204.583,216.671z" fill="{text_color}"/> |
|
1150 | 1157 | <path d="M407.164,374.717L360.88, |
|
1151 | 1158 | 270.454c-2.117-4.771-5.836-8.728-10.465-11.138l-71.83-37.392 |
|
1152 | 1159 | c-1.584-0.823-3.502-0.663-4.926,0.415c-20.316, |
|
1153 | 1160 | 15.366-44.203,23.488-69.076,23.488c-24.877, |
|
1154 | 1161 | 0-48.762-8.122-69.078-23.488 |
|
1155 | 1162 | c-1.428-1.078-3.346-1.238-4.93-0.415L58.75, |
|
1156 | 1163 | 259.316c-4.631,2.41-8.346,6.365-10.465,11.138L2.001,374.717 |
|
1157 | 1164 | c-3.191,7.188-2.537,15.412,1.75,22.005c4.285, |
|
1158 | 1165 | 6.592,11.537,10.526,19.4,10.526h362.861c7.863,0,15.117-3.936, |
|
1159 | 1166 | 19.402-10.527 C409.699,390.129, |
|
1160 | 1167 | 410.355,381.902,407.164,374.717z" fill="{text_color}"/> |
|
1161 | 1168 | </svg>""".format( |
|
1162 | 1169 | size=self.size, |
|
1163 | 1170 | background='#979797', # @grey4 |
|
1164 | 1171 | text_color=self.text_color, |
|
1165 | 1172 | font_family=font_family) |
|
1166 | 1173 | |
|
1167 | 1174 | return { |
|
1168 | 1175 | "default_user": default_user |
|
1169 | 1176 | }[img_type] |
|
1170 | 1177 | |
|
1171 | 1178 | def get_img_data(self, svg_type=None): |
|
1172 | 1179 | """ |
|
1173 | 1180 | generates the svg metadata for image |
|
1174 | 1181 | """ |
|
1175 | 1182 | fonts = [ |
|
1176 | 1183 | '-apple-system', |
|
1177 | 1184 | 'BlinkMacSystemFont', |
|
1178 | 1185 | 'Segoe UI', |
|
1179 | 1186 | 'Roboto', |
|
1180 | 1187 | 'Oxygen-Sans', |
|
1181 | 1188 | 'Ubuntu', |
|
1182 | 1189 | 'Cantarell', |
|
1183 | 1190 | 'Helvetica Neue', |
|
1184 | 1191 | 'sans-serif' |
|
1185 | 1192 | ] |
|
1186 | 1193 | font_family = ','.join(fonts) |
|
1187 | 1194 | if svg_type: |
|
1188 | 1195 | return self.get_img_data_by_type(font_family, svg_type) |
|
1189 | 1196 | |
|
1190 | 1197 | initials = self.get_initials() |
|
1191 | 1198 | img_data = """ |
|
1192 | 1199 | <svg xmlns="http://www.w3.org/2000/svg" pointer-events="none" |
|
1193 | 1200 | width="{size}" height="{size}" |
|
1194 | 1201 | style="width: 100%; height: 100%; background-color: {background}" |
|
1195 | 1202 | viewBox="0 0 {size} {size}"> |
|
1196 | 1203 | <text text-anchor="middle" y="50%" x="50%" dy="0.35em" |
|
1197 | 1204 | pointer-events="auto" fill="{text_color}" |
|
1198 | 1205 | font-family="{font_family}" |
|
1199 | 1206 | style="font-weight: 400; font-size: {f_size}px;">{text} |
|
1200 | 1207 | </text> |
|
1201 | 1208 | </svg>""".format( |
|
1202 | 1209 | size=self.size, |
|
1203 | 1210 | f_size=self.size/2.05, # scale the text inside the box nicely |
|
1204 | 1211 | background=self.background, |
|
1205 | 1212 | text_color=self.text_color, |
|
1206 | 1213 | text=initials.upper(), |
|
1207 | 1214 | font_family=font_family) |
|
1208 | 1215 | |
|
1209 | 1216 | return img_data |
|
1210 | 1217 | |
|
1211 | 1218 | def generate_svg(self, svg_type=None): |
|
1212 | 1219 | img_data = self.get_img_data(svg_type) |
|
1213 | 1220 | return "data:image/svg+xml;base64,%s" % img_data.encode('base64') |
|
1214 | 1221 | |
|
1215 | 1222 | |
|
1216 | 1223 | def initials_gravatar(email_address, first_name, last_name, size=30): |
|
1217 | 1224 | svg_type = None |
|
1218 | 1225 | if email_address == User.DEFAULT_USER_EMAIL: |
|
1219 | 1226 | svg_type = 'default_user' |
|
1220 | 1227 | klass = InitialsGravatar(email_address, first_name, last_name, size) |
|
1221 | 1228 | return klass.generate_svg(svg_type=svg_type) |
|
1222 | 1229 | |
|
1223 | 1230 | |
|
1224 | 1231 | def gravatar_url(email_address, size=30, request=None): |
|
1225 | 1232 | request = get_current_request() |
|
1226 | 1233 | _use_gravatar = request.call_context.visual.use_gravatar |
|
1227 | 1234 | _gravatar_url = request.call_context.visual.gravatar_url |
|
1228 | 1235 | |
|
1229 | 1236 | _gravatar_url = _gravatar_url or User.DEFAULT_GRAVATAR_URL |
|
1230 | 1237 | |
|
1231 | 1238 | email_address = email_address or User.DEFAULT_USER_EMAIL |
|
1232 | 1239 | if isinstance(email_address, unicode): |
|
1233 | 1240 | # hashlib crashes on unicode items |
|
1234 | 1241 | email_address = safe_str(email_address) |
|
1235 | 1242 | |
|
1236 | 1243 | # empty email or default user |
|
1237 | 1244 | if not email_address or email_address == User.DEFAULT_USER_EMAIL: |
|
1238 | 1245 | return initials_gravatar(User.DEFAULT_USER_EMAIL, '', '', size=size) |
|
1239 | 1246 | |
|
1240 | 1247 | if _use_gravatar: |
|
1241 | 1248 | # TODO: Disuse pyramid thread locals. Think about another solution to |
|
1242 | 1249 | # get the host and schema here. |
|
1243 | 1250 | request = get_current_request() |
|
1244 | 1251 | tmpl = safe_str(_gravatar_url) |
|
1245 | 1252 | tmpl = tmpl.replace('{email}', email_address)\ |
|
1246 | 1253 | .replace('{md5email}', md5_safe(email_address.lower())) \ |
|
1247 | 1254 | .replace('{netloc}', request.host)\ |
|
1248 | 1255 | .replace('{scheme}', request.scheme)\ |
|
1249 | 1256 | .replace('{size}', safe_str(size)) |
|
1250 | 1257 | return tmpl |
|
1251 | 1258 | else: |
|
1252 | 1259 | return initials_gravatar(email_address, '', '', size=size) |
|
1253 | 1260 | |
|
1254 | 1261 | |
|
1255 | 1262 | class Page(_Page): |
|
1256 | 1263 | """ |
|
1257 | 1264 | Custom pager to match rendering style with paginator |
|
1258 | 1265 | """ |
|
1259 | 1266 | |
|
1260 | 1267 | def _get_pos(self, cur_page, max_page, items): |
|
1261 | 1268 | edge = (items / 2) + 1 |
|
1262 | 1269 | if (cur_page <= edge): |
|
1263 | 1270 | radius = max(items / 2, items - cur_page) |
|
1264 | 1271 | elif (max_page - cur_page) < edge: |
|
1265 | 1272 | radius = (items - 1) - (max_page - cur_page) |
|
1266 | 1273 | else: |
|
1267 | 1274 | radius = items / 2 |
|
1268 | 1275 | |
|
1269 | 1276 | left = max(1, (cur_page - (radius))) |
|
1270 | 1277 | right = min(max_page, cur_page + (radius)) |
|
1271 | 1278 | return left, cur_page, right |
|
1272 | 1279 | |
|
1273 | 1280 | def _range(self, regexp_match): |
|
1274 | 1281 | """ |
|
1275 | 1282 | Return range of linked pages (e.g. '1 2 [3] 4 5 6 7 8'). |
|
1276 | 1283 | |
|
1277 | 1284 | Arguments: |
|
1278 | 1285 | |
|
1279 | 1286 | regexp_match |
|
1280 | 1287 | A "re" (regular expressions) match object containing the |
|
1281 | 1288 | radius of linked pages around the current page in |
|
1282 | 1289 | regexp_match.group(1) as a string |
|
1283 | 1290 | |
|
1284 | 1291 | This function is supposed to be called as a callable in |
|
1285 | 1292 | re.sub. |
|
1286 | 1293 | |
|
1287 | 1294 | """ |
|
1288 | 1295 | radius = int(regexp_match.group(1)) |
|
1289 | 1296 | |
|
1290 | 1297 | # Compute the first and last page number within the radius |
|
1291 | 1298 | # e.g. '1 .. 5 6 [7] 8 9 .. 12' |
|
1292 | 1299 | # -> leftmost_page = 5 |
|
1293 | 1300 | # -> rightmost_page = 9 |
|
1294 | 1301 | leftmost_page, _cur, rightmost_page = self._get_pos(self.page, |
|
1295 | 1302 | self.last_page, |
|
1296 | 1303 | (radius * 2) + 1) |
|
1297 | 1304 | nav_items = [] |
|
1298 | 1305 | |
|
1299 | 1306 | # Create a link to the first page (unless we are on the first page |
|
1300 | 1307 | # or there would be no need to insert '..' spacers) |
|
1301 | 1308 | if self.page != self.first_page and self.first_page < leftmost_page: |
|
1302 | 1309 | nav_items.append(self._pagerlink(self.first_page, self.first_page)) |
|
1303 | 1310 | |
|
1304 | 1311 | # Insert dots if there are pages between the first page |
|
1305 | 1312 | # and the currently displayed page range |
|
1306 | 1313 | if leftmost_page - self.first_page > 1: |
|
1307 | 1314 | # Wrap in a SPAN tag if nolink_attr is set |
|
1308 | 1315 | text = '..' |
|
1309 | 1316 | if self.dotdot_attr: |
|
1310 | 1317 | text = HTML.span(c=text, **self.dotdot_attr) |
|
1311 | 1318 | nav_items.append(text) |
|
1312 | 1319 | |
|
1313 | 1320 | for thispage in xrange(leftmost_page, rightmost_page + 1): |
|
1314 | 1321 | # Hilight the current page number and do not use a link |
|
1315 | 1322 | if thispage == self.page: |
|
1316 | 1323 | text = '%s' % (thispage,) |
|
1317 | 1324 | # Wrap in a SPAN tag if nolink_attr is set |
|
1318 | 1325 | if self.curpage_attr: |
|
1319 | 1326 | text = HTML.span(c=text, **self.curpage_attr) |
|
1320 | 1327 | nav_items.append(text) |
|
1321 | 1328 | # Otherwise create just a link to that page |
|
1322 | 1329 | else: |
|
1323 | 1330 | text = '%s' % (thispage,) |
|
1324 | 1331 | nav_items.append(self._pagerlink(thispage, text)) |
|
1325 | 1332 | |
|
1326 | 1333 | # Insert dots if there are pages between the displayed |
|
1327 | 1334 | # page numbers and the end of the page range |
|
1328 | 1335 | if self.last_page - rightmost_page > 1: |
|
1329 | 1336 | text = '..' |
|
1330 | 1337 | # Wrap in a SPAN tag if nolink_attr is set |
|
1331 | 1338 | if self.dotdot_attr: |
|
1332 | 1339 | text = HTML.span(c=text, **self.dotdot_attr) |
|
1333 | 1340 | nav_items.append(text) |
|
1334 | 1341 | |
|
1335 | 1342 | # Create a link to the very last page (unless we are on the last |
|
1336 | 1343 | # page or there would be no need to insert '..' spacers) |
|
1337 | 1344 | if self.page != self.last_page and rightmost_page < self.last_page: |
|
1338 | 1345 | nav_items.append(self._pagerlink(self.last_page, self.last_page)) |
|
1339 | 1346 | |
|
1340 | 1347 | ## prerender links |
|
1341 | 1348 | #_page_link = url.current() |
|
1342 | 1349 | #nav_items.append(literal('<link rel="prerender" href="%s?page=%s">' % (_page_link, str(int(self.page)+1)))) |
|
1343 | 1350 | #nav_items.append(literal('<link rel="prefetch" href="%s?page=%s">' % (_page_link, str(int(self.page)+1)))) |
|
1344 | 1351 | return self.separator.join(nav_items) |
|
1345 | 1352 | |
|
1346 | 1353 | def pager(self, format='~2~', page_param='page', partial_param='partial', |
|
1347 | 1354 | show_if_single_page=False, separator=' ', onclick=None, |
|
1348 | 1355 | symbol_first='<<', symbol_last='>>', |
|
1349 | 1356 | symbol_previous='<', symbol_next='>', |
|
1350 | 1357 | link_attr={'class': 'pager_link', 'rel': 'prerender'}, |
|
1351 | 1358 | curpage_attr={'class': 'pager_curpage'}, |
|
1352 | 1359 | dotdot_attr={'class': 'pager_dotdot'}, **kwargs): |
|
1353 | 1360 | |
|
1354 | 1361 | self.curpage_attr = curpage_attr |
|
1355 | 1362 | self.separator = separator |
|
1356 | 1363 | self.pager_kwargs = kwargs |
|
1357 | 1364 | self.page_param = page_param |
|
1358 | 1365 | self.partial_param = partial_param |
|
1359 | 1366 | self.onclick = onclick |
|
1360 | 1367 | self.link_attr = link_attr |
|
1361 | 1368 | self.dotdot_attr = dotdot_attr |
|
1362 | 1369 | |
|
1363 | 1370 | # Don't show navigator if there is no more than one page |
|
1364 | 1371 | if self.page_count == 0 or (self.page_count == 1 and not show_if_single_page): |
|
1365 | 1372 | return '' |
|
1366 | 1373 | |
|
1367 | 1374 | from string import Template |
|
1368 | 1375 | # Replace ~...~ in token format by range of pages |
|
1369 | 1376 | result = re.sub(r'~(\d+)~', self._range, format) |
|
1370 | 1377 | |
|
1371 | 1378 | # Interpolate '%' variables |
|
1372 | 1379 | result = Template(result).safe_substitute({ |
|
1373 | 1380 | 'first_page': self.first_page, |
|
1374 | 1381 | 'last_page': self.last_page, |
|
1375 | 1382 | 'page': self.page, |
|
1376 | 1383 | 'page_count': self.page_count, |
|
1377 | 1384 | 'items_per_page': self.items_per_page, |
|
1378 | 1385 | 'first_item': self.first_item, |
|
1379 | 1386 | 'last_item': self.last_item, |
|
1380 | 1387 | 'item_count': self.item_count, |
|
1381 | 1388 | 'link_first': self.page > self.first_page and \ |
|
1382 | 1389 | self._pagerlink(self.first_page, symbol_first) or '', |
|
1383 | 1390 | 'link_last': self.page < self.last_page and \ |
|
1384 | 1391 | self._pagerlink(self.last_page, symbol_last) or '', |
|
1385 | 1392 | 'link_previous': self.previous_page and \ |
|
1386 | 1393 | self._pagerlink(self.previous_page, symbol_previous) \ |
|
1387 | 1394 | or HTML.span(symbol_previous, class_="pg-previous disabled"), |
|
1388 | 1395 | 'link_next': self.next_page and \ |
|
1389 | 1396 | self._pagerlink(self.next_page, symbol_next) \ |
|
1390 | 1397 | or HTML.span(symbol_next, class_="pg-next disabled") |
|
1391 | 1398 | }) |
|
1392 | 1399 | |
|
1393 | 1400 | return literal(result) |
|
1394 | 1401 | |
|
1395 | 1402 | |
|
1396 | 1403 | #============================================================================== |
|
1397 | 1404 | # REPO PAGER, PAGER FOR REPOSITORY |
|
1398 | 1405 | #============================================================================== |
|
1399 | 1406 | class RepoPage(Page): |
|
1400 | 1407 | |
|
1401 | 1408 | def __init__(self, collection, page=1, items_per_page=20, |
|
1402 | 1409 | item_count=None, url=None, **kwargs): |
|
1403 | 1410 | |
|
1404 | 1411 | """Create a "RepoPage" instance. special pager for paging |
|
1405 | 1412 | repository |
|
1406 | 1413 | """ |
|
1407 | 1414 | self._url_generator = url |
|
1408 | 1415 | |
|
1409 | 1416 | # Safe the kwargs class-wide so they can be used in the pager() method |
|
1410 | 1417 | self.kwargs = kwargs |
|
1411 | 1418 | |
|
1412 | 1419 | # Save a reference to the collection |
|
1413 | 1420 | self.original_collection = collection |
|
1414 | 1421 | |
|
1415 | 1422 | self.collection = collection |
|
1416 | 1423 | |
|
1417 | 1424 | # The self.page is the number of the current page. |
|
1418 | 1425 | # The first page has the number 1! |
|
1419 | 1426 | try: |
|
1420 | 1427 | self.page = int(page) # make it int() if we get it as a string |
|
1421 | 1428 | except (ValueError, TypeError): |
|
1422 | 1429 | self.page = 1 |
|
1423 | 1430 | |
|
1424 | 1431 | self.items_per_page = items_per_page |
|
1425 | 1432 | |
|
1426 | 1433 | # Unless the user tells us how many items the collections has |
|
1427 | 1434 | # we calculate that ourselves. |
|
1428 | 1435 | if item_count is not None: |
|
1429 | 1436 | self.item_count = item_count |
|
1430 | 1437 | else: |
|
1431 | 1438 | self.item_count = len(self.collection) |
|
1432 | 1439 | |
|
1433 | 1440 | # Compute the number of the first and last available page |
|
1434 | 1441 | if self.item_count > 0: |
|
1435 | 1442 | self.first_page = 1 |
|
1436 | 1443 | self.page_count = int(math.ceil(float(self.item_count) / |
|
1437 | 1444 | self.items_per_page)) |
|
1438 | 1445 | self.last_page = self.first_page + self.page_count - 1 |
|
1439 | 1446 | |
|
1440 | 1447 | # Make sure that the requested page number is the range of |
|
1441 | 1448 | # valid pages |
|
1442 | 1449 | if self.page > self.last_page: |
|
1443 | 1450 | self.page = self.last_page |
|
1444 | 1451 | elif self.page < self.first_page: |
|
1445 | 1452 | self.page = self.first_page |
|
1446 | 1453 | |
|
1447 | 1454 | # Note: the number of items on this page can be less than |
|
1448 | 1455 | # items_per_page if the last page is not full |
|
1449 | 1456 | self.first_item = max(0, (self.item_count) - (self.page * |
|
1450 | 1457 | items_per_page)) |
|
1451 | 1458 | self.last_item = ((self.item_count - 1) - items_per_page * |
|
1452 | 1459 | (self.page - 1)) |
|
1453 | 1460 | |
|
1454 | 1461 | self.items = list(self.collection[self.first_item:self.last_item + 1]) |
|
1455 | 1462 | |
|
1456 | 1463 | # Links to previous and next page |
|
1457 | 1464 | if self.page > self.first_page: |
|
1458 | 1465 | self.previous_page = self.page - 1 |
|
1459 | 1466 | else: |
|
1460 | 1467 | self.previous_page = None |
|
1461 | 1468 | |
|
1462 | 1469 | if self.page < self.last_page: |
|
1463 | 1470 | self.next_page = self.page + 1 |
|
1464 | 1471 | else: |
|
1465 | 1472 | self.next_page = None |
|
1466 | 1473 | |
|
1467 | 1474 | # No items available |
|
1468 | 1475 | else: |
|
1469 | 1476 | self.first_page = None |
|
1470 | 1477 | self.page_count = 0 |
|
1471 | 1478 | self.last_page = None |
|
1472 | 1479 | self.first_item = None |
|
1473 | 1480 | self.last_item = None |
|
1474 | 1481 | self.previous_page = None |
|
1475 | 1482 | self.next_page = None |
|
1476 | 1483 | self.items = [] |
|
1477 | 1484 | |
|
1478 | 1485 | # This is a subclass of the 'list' type. Initialise the list now. |
|
1479 | 1486 | list.__init__(self, reversed(self.items)) |
|
1480 | 1487 | |
|
1481 | 1488 | |
|
1482 | 1489 | def breadcrumb_repo_link(repo): |
|
1483 | 1490 | """ |
|
1484 | 1491 | Makes a breadcrumbs path link to repo |
|
1485 | 1492 | |
|
1486 | 1493 | ex:: |
|
1487 | 1494 | group >> subgroup >> repo |
|
1488 | 1495 | |
|
1489 | 1496 | :param repo: a Repository instance |
|
1490 | 1497 | """ |
|
1491 | 1498 | |
|
1492 | 1499 | path = [ |
|
1493 | 1500 | link_to(group.name, route_path('repo_group_home', repo_group_name=group.group_name), |
|
1494 | 1501 | title='last change:{}'.format(format_date(group.last_commit_change))) |
|
1495 | 1502 | for group in repo.groups_with_parents |
|
1496 | 1503 | ] + [ |
|
1497 | 1504 | link_to(repo.just_name, route_path('repo_summary', repo_name=repo.repo_name), |
|
1498 | 1505 | title='last change:{}'.format(format_date(repo.last_commit_change))) |
|
1499 | 1506 | ] |
|
1500 | 1507 | |
|
1501 | 1508 | return literal(' » '.join(path)) |
|
1502 | 1509 | |
|
1503 | 1510 | |
|
1504 | 1511 | def breadcrumb_repo_group_link(repo_group): |
|
1505 | 1512 | """ |
|
1506 | 1513 | Makes a breadcrumbs path link to repo |
|
1507 | 1514 | |
|
1508 | 1515 | ex:: |
|
1509 | 1516 | group >> subgroup |
|
1510 | 1517 | |
|
1511 | 1518 | :param repo_group: a Repository Group instance |
|
1512 | 1519 | """ |
|
1513 | 1520 | |
|
1514 | 1521 | path = [ |
|
1515 | 1522 | link_to(group.name, |
|
1516 | 1523 | route_path('repo_group_home', repo_group_name=group.group_name), |
|
1517 | 1524 | title='last change:{}'.format(format_date(group.last_commit_change))) |
|
1518 | 1525 | for group in repo_group.parents |
|
1519 | 1526 | ] + [ |
|
1520 | 1527 | link_to(repo_group.name, |
|
1521 | 1528 | route_path('repo_group_home', repo_group_name=repo_group.group_name), |
|
1522 | 1529 | title='last change:{}'.format(format_date(repo_group.last_commit_change))) |
|
1523 | 1530 | ] |
|
1524 | 1531 | |
|
1525 | 1532 | return literal(' » '.join(path)) |
|
1526 | 1533 | |
|
1527 | 1534 | |
|
1528 | 1535 | def format_byte_size_binary(file_size): |
|
1529 | 1536 | """ |
|
1530 | 1537 | Formats file/folder sizes to standard. |
|
1531 | 1538 | """ |
|
1532 | 1539 | if file_size is None: |
|
1533 | 1540 | file_size = 0 |
|
1534 | 1541 | |
|
1535 | 1542 | formatted_size = format_byte_size(file_size, binary=True) |
|
1536 | 1543 | return formatted_size |
|
1537 | 1544 | |
|
1538 | 1545 | |
|
1539 | 1546 | def urlify_text(text_, safe=True): |
|
1540 | 1547 | """ |
|
1541 | 1548 | Extrac urls from text and make html links out of them |
|
1542 | 1549 | |
|
1543 | 1550 | :param text_: |
|
1544 | 1551 | """ |
|
1545 | 1552 | |
|
1546 | 1553 | url_pat = re.compile(r'''(http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@#.&+]''' |
|
1547 | 1554 | '''|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+)''') |
|
1548 | 1555 | |
|
1549 | 1556 | def url_func(match_obj): |
|
1550 | 1557 | url_full = match_obj.groups()[0] |
|
1551 | 1558 | return '<a href="%(url)s">%(url)s</a>' % ({'url': url_full}) |
|
1552 | 1559 | _newtext = url_pat.sub(url_func, text_) |
|
1553 | 1560 | if safe: |
|
1554 | 1561 | return literal(_newtext) |
|
1555 | 1562 | return _newtext |
|
1556 | 1563 | |
|
1557 | 1564 | |
|
1558 | 1565 | def urlify_commits(text_, repository): |
|
1559 | 1566 | """ |
|
1560 | 1567 | Extract commit ids from text and make link from them |
|
1561 | 1568 | |
|
1562 | 1569 | :param text_: |
|
1563 | 1570 | :param repository: repo name to build the URL with |
|
1564 | 1571 | """ |
|
1565 | 1572 | |
|
1566 | 1573 | URL_PAT = re.compile(r'(^|\s)([0-9a-fA-F]{12,40})($|\s)') |
|
1567 | 1574 | |
|
1568 | 1575 | def url_func(match_obj): |
|
1569 | 1576 | commit_id = match_obj.groups()[1] |
|
1570 | 1577 | pref = match_obj.groups()[0] |
|
1571 | 1578 | suf = match_obj.groups()[2] |
|
1572 | 1579 | |
|
1573 | 1580 | tmpl = ( |
|
1574 | 1581 | '%(pref)s<a class="%(cls)s" href="%(url)s">' |
|
1575 | 1582 | '%(commit_id)s</a>%(suf)s' |
|
1576 | 1583 | ) |
|
1577 | 1584 | return tmpl % { |
|
1578 | 1585 | 'pref': pref, |
|
1579 | 1586 | 'cls': 'revision-link', |
|
1580 | 1587 | 'url': route_url('repo_commit', repo_name=repository, commit_id=commit_id), |
|
1581 | 1588 | 'commit_id': commit_id, |
|
1582 | 1589 | 'suf': suf |
|
1583 | 1590 | } |
|
1584 | 1591 | |
|
1585 | 1592 | newtext = URL_PAT.sub(url_func, text_) |
|
1586 | 1593 | |
|
1587 | 1594 | return newtext |
|
1588 | 1595 | |
|
1589 | 1596 | |
|
1590 | 1597 | def _process_url_func(match_obj, repo_name, uid, entry, |
|
1591 | 1598 | return_raw_data=False, link_format='html'): |
|
1592 | 1599 | pref = '' |
|
1593 | 1600 | if match_obj.group().startswith(' '): |
|
1594 | 1601 | pref = ' ' |
|
1595 | 1602 | |
|
1596 | 1603 | issue_id = ''.join(match_obj.groups()) |
|
1597 | 1604 | |
|
1598 | 1605 | if link_format == 'html': |
|
1599 | 1606 | tmpl = ( |
|
1600 | 1607 | '%(pref)s<a class="%(cls)s" href="%(url)s">' |
|
1601 | 1608 | '%(issue-prefix)s%(id-repr)s' |
|
1602 | 1609 | '</a>') |
|
1603 | 1610 | elif link_format == 'rst': |
|
1604 | 1611 | tmpl = '`%(issue-prefix)s%(id-repr)s <%(url)s>`_' |
|
1605 | 1612 | elif link_format == 'markdown': |
|
1606 | 1613 | tmpl = '[%(issue-prefix)s%(id-repr)s](%(url)s)' |
|
1607 | 1614 | else: |
|
1608 | 1615 | raise ValueError('Bad link_format:{}'.format(link_format)) |
|
1609 | 1616 | |
|
1610 | 1617 | (repo_name_cleaned, |
|
1611 | 1618 | parent_group_name) = RepoGroupModel()._get_group_name_and_parent(repo_name) |
|
1612 | 1619 | |
|
1613 | 1620 | # variables replacement |
|
1614 | 1621 | named_vars = { |
|
1615 | 1622 | 'id': issue_id, |
|
1616 | 1623 | 'repo': repo_name, |
|
1617 | 1624 | 'repo_name': repo_name_cleaned, |
|
1618 | 1625 | 'group_name': parent_group_name |
|
1619 | 1626 | } |
|
1620 | 1627 | # named regex variables |
|
1621 | 1628 | named_vars.update(match_obj.groupdict()) |
|
1622 | 1629 | _url = string.Template(entry['url']).safe_substitute(**named_vars) |
|
1623 | 1630 | |
|
1624 | 1631 | def quote_cleaner(input_str): |
|
1625 | 1632 | """Remove quotes as it's HTML""" |
|
1626 | 1633 | return input_str.replace('"', '') |
|
1627 | 1634 | |
|
1628 | 1635 | data = { |
|
1629 | 1636 | 'pref': pref, |
|
1630 | 1637 | 'cls': quote_cleaner('issue-tracker-link'), |
|
1631 | 1638 | 'url': quote_cleaner(_url), |
|
1632 | 1639 | 'id-repr': issue_id, |
|
1633 | 1640 | 'issue-prefix': entry['pref'], |
|
1634 | 1641 | 'serv': entry['url'], |
|
1635 | 1642 | } |
|
1636 | 1643 | if return_raw_data: |
|
1637 | 1644 | return { |
|
1638 | 1645 | 'id': issue_id, |
|
1639 | 1646 | 'url': _url |
|
1640 | 1647 | } |
|
1641 | 1648 | return tmpl % data |
|
1642 | 1649 | |
|
1643 | 1650 | |
|
1644 | 1651 | def get_active_pattern_entries(repo_name): |
|
1645 | 1652 | repo = None |
|
1646 | 1653 | if repo_name: |
|
1647 | 1654 | # Retrieving repo_name to avoid invalid repo_name to explode on |
|
1648 | 1655 | # IssueTrackerSettingsModel but still passing invalid name further down |
|
1649 | 1656 | repo = Repository.get_by_repo_name(repo_name, cache=True) |
|
1650 | 1657 | |
|
1651 | 1658 | settings_model = IssueTrackerSettingsModel(repo=repo) |
|
1652 | 1659 | active_entries = settings_model.get_settings(cache=True) |
|
1653 | 1660 | return active_entries |
|
1654 | 1661 | |
|
1655 | 1662 | |
|
1656 | 1663 | def process_patterns(text_string, repo_name, link_format='html', active_entries=None): |
|
1657 | 1664 | |
|
1658 | 1665 | allowed_formats = ['html', 'rst', 'markdown'] |
|
1659 | 1666 | if link_format not in allowed_formats: |
|
1660 | 1667 | raise ValueError('Link format can be only one of:{} got {}'.format( |
|
1661 | 1668 | allowed_formats, link_format)) |
|
1662 | 1669 | |
|
1663 | 1670 | active_entries = active_entries or get_active_pattern_entries(repo_name) |
|
1664 | 1671 | issues_data = [] |
|
1665 | 1672 | newtext = text_string |
|
1666 | 1673 | |
|
1667 | 1674 | for uid, entry in active_entries.items(): |
|
1668 | 1675 | log.debug('found issue tracker entry with uid %s', uid) |
|
1669 | 1676 | |
|
1670 | 1677 | if not (entry['pat'] and entry['url']): |
|
1671 | 1678 | log.debug('skipping due to missing data') |
|
1672 | 1679 | continue |
|
1673 | 1680 | |
|
1674 | 1681 | log.debug('issue tracker entry: uid: `%s` PAT:%s URL:%s PREFIX:%s', |
|
1675 | 1682 | uid, entry['pat'], entry['url'], entry['pref']) |
|
1676 | 1683 | |
|
1677 | 1684 | try: |
|
1678 | 1685 | pattern = re.compile(r'%s' % entry['pat']) |
|
1679 | 1686 | except re.error: |
|
1680 | 1687 | log.exception( |
|
1681 | 1688 | 'issue tracker pattern: `%s` failed to compile', |
|
1682 | 1689 | entry['pat']) |
|
1683 | 1690 | continue |
|
1684 | 1691 | |
|
1685 | 1692 | data_func = partial( |
|
1686 | 1693 | _process_url_func, repo_name=repo_name, entry=entry, uid=uid, |
|
1687 | 1694 | return_raw_data=True) |
|
1688 | 1695 | |
|
1689 | 1696 | for match_obj in pattern.finditer(text_string): |
|
1690 | 1697 | issues_data.append(data_func(match_obj)) |
|
1691 | 1698 | |
|
1692 | 1699 | url_func = partial( |
|
1693 | 1700 | _process_url_func, repo_name=repo_name, entry=entry, uid=uid, |
|
1694 | 1701 | link_format=link_format) |
|
1695 | 1702 | |
|
1696 | 1703 | newtext = pattern.sub(url_func, newtext) |
|
1697 | 1704 | log.debug('processed prefix:uid `%s`', uid) |
|
1698 | 1705 | |
|
1699 | 1706 | return newtext, issues_data |
|
1700 | 1707 | |
|
1701 | 1708 | |
|
1702 | 1709 | def urlify_commit_message(commit_text, repository=None, active_pattern_entries=None): |
|
1703 | 1710 | """ |
|
1704 | 1711 | Parses given text message and makes proper links. |
|
1705 | 1712 | issues are linked to given issue-server, and rest is a commit link |
|
1706 | 1713 | |
|
1707 | 1714 | :param commit_text: |
|
1708 | 1715 | :param repository: |
|
1709 | 1716 | """ |
|
1710 | 1717 | def escaper(string): |
|
1711 | 1718 | return string.replace('<', '<').replace('>', '>') |
|
1712 | 1719 | |
|
1713 | 1720 | newtext = escaper(commit_text) |
|
1714 | 1721 | |
|
1715 | 1722 | # extract http/https links and make them real urls |
|
1716 | 1723 | newtext = urlify_text(newtext, safe=False) |
|
1717 | 1724 | |
|
1718 | 1725 | # urlify commits - extract commit ids and make link out of them, if we have |
|
1719 | 1726 | # the scope of repository present. |
|
1720 | 1727 | if repository: |
|
1721 | 1728 | newtext = urlify_commits(newtext, repository) |
|
1722 | 1729 | |
|
1723 | 1730 | # process issue tracker patterns |
|
1724 | 1731 | newtext, issues = process_patterns(newtext, repository or '', |
|
1725 | 1732 | active_entries=active_pattern_entries) |
|
1726 | 1733 | |
|
1727 | 1734 | return literal(newtext) |
|
1728 | 1735 | |
|
1729 | 1736 | |
|
1730 | 1737 | def render_binary(repo_name, file_obj): |
|
1731 | 1738 | """ |
|
1732 | 1739 | Choose how to render a binary file |
|
1733 | 1740 | """ |
|
1734 | 1741 | |
|
1735 | 1742 | filename = file_obj.name |
|
1736 | 1743 | |
|
1737 | 1744 | # images |
|
1738 | 1745 | for ext in ['*.png', '*.jpg', '*.ico', '*.gif']: |
|
1739 | 1746 | if fnmatch.fnmatch(filename, pat=ext): |
|
1740 | 1747 | alt = escape(filename) |
|
1741 | 1748 | src = route_path( |
|
1742 | 1749 | 'repo_file_raw', repo_name=repo_name, |
|
1743 | 1750 | commit_id=file_obj.commit.raw_id, |
|
1744 | 1751 | f_path=file_obj.path) |
|
1745 | 1752 | return literal( |
|
1746 | 1753 | '<img class="rendered-binary" alt="{}" src="{}">'.format(alt, src)) |
|
1747 | 1754 | |
|
1748 | 1755 | |
|
1749 | 1756 | def renderer_from_filename(filename, exclude=None): |
|
1750 | 1757 | """ |
|
1751 | 1758 | choose a renderer based on filename, this works only for text based files |
|
1752 | 1759 | """ |
|
1753 | 1760 | |
|
1754 | 1761 | # ipython |
|
1755 | 1762 | for ext in ['*.ipynb']: |
|
1756 | 1763 | if fnmatch.fnmatch(filename, pat=ext): |
|
1757 | 1764 | return 'jupyter' |
|
1758 | 1765 | |
|
1759 | 1766 | is_markup = MarkupRenderer.renderer_from_filename(filename, exclude=exclude) |
|
1760 | 1767 | if is_markup: |
|
1761 | 1768 | return is_markup |
|
1762 | 1769 | return None |
|
1763 | 1770 | |
|
1764 | 1771 | |
|
1765 | 1772 | def render(source, renderer='rst', mentions=False, relative_urls=None, |
|
1766 | 1773 | repo_name=None): |
|
1767 | 1774 | |
|
1768 | 1775 | def maybe_convert_relative_links(html_source): |
|
1769 | 1776 | if relative_urls: |
|
1770 | 1777 | return relative_links(html_source, relative_urls) |
|
1771 | 1778 | return html_source |
|
1772 | 1779 | |
|
1773 | 1780 | if renderer == 'plain': |
|
1774 | 1781 | return literal( |
|
1775 | 1782 | MarkupRenderer.plain(source, leading_newline=False)) |
|
1776 | 1783 | |
|
1777 | 1784 | elif renderer == 'rst': |
|
1778 | 1785 | if repo_name: |
|
1779 | 1786 | # process patterns on comments if we pass in repo name |
|
1780 | 1787 | source, issues = process_patterns( |
|
1781 | 1788 | source, repo_name, link_format='rst') |
|
1782 | 1789 | |
|
1783 | 1790 | return literal( |
|
1784 | 1791 | '<div class="rst-block">%s</div>' % |
|
1785 | 1792 | maybe_convert_relative_links( |
|
1786 | 1793 | MarkupRenderer.rst(source, mentions=mentions))) |
|
1787 | 1794 | |
|
1788 | 1795 | elif renderer == 'markdown': |
|
1789 | 1796 | if repo_name: |
|
1790 | 1797 | # process patterns on comments if we pass in repo name |
|
1791 | 1798 | source, issues = process_patterns( |
|
1792 | 1799 | source, repo_name, link_format='markdown') |
|
1793 | 1800 | |
|
1794 | 1801 | return literal( |
|
1795 | 1802 | '<div class="markdown-block">%s</div>' % |
|
1796 | 1803 | maybe_convert_relative_links( |
|
1797 | 1804 | MarkupRenderer.markdown(source, flavored=True, |
|
1798 | 1805 | mentions=mentions))) |
|
1799 | 1806 | |
|
1800 | 1807 | elif renderer == 'jupyter': |
|
1801 | 1808 | return literal( |
|
1802 | 1809 | '<div class="ipynb">%s</div>' % |
|
1803 | 1810 | maybe_convert_relative_links( |
|
1804 | 1811 | MarkupRenderer.jupyter(source))) |
|
1805 | 1812 | |
|
1806 | 1813 | # None means just show the file-source |
|
1807 | 1814 | return None |
|
1808 | 1815 | |
|
1809 | 1816 | |
|
1810 | 1817 | def commit_status(repo, commit_id): |
|
1811 | 1818 | return ChangesetStatusModel().get_status(repo, commit_id) |
|
1812 | 1819 | |
|
1813 | 1820 | |
|
1814 | 1821 | def commit_status_lbl(commit_status): |
|
1815 | 1822 | return dict(ChangesetStatus.STATUSES).get(commit_status) |
|
1816 | 1823 | |
|
1817 | 1824 | |
|
1818 | 1825 | def commit_time(repo_name, commit_id): |
|
1819 | 1826 | repo = Repository.get_by_repo_name(repo_name) |
|
1820 | 1827 | commit = repo.get_commit(commit_id=commit_id) |
|
1821 | 1828 | return commit.date |
|
1822 | 1829 | |
|
1823 | 1830 | |
|
1824 | 1831 | def get_permission_name(key): |
|
1825 | 1832 | return dict(Permission.PERMS).get(key) |
|
1826 | 1833 | |
|
1827 | 1834 | |
|
1828 | 1835 | def journal_filter_help(request): |
|
1829 | 1836 | _ = request.translate |
|
1830 | 1837 | from rhodecode.lib.audit_logger import ACTIONS |
|
1831 | 1838 | actions = '\n'.join(textwrap.wrap(', '.join(sorted(ACTIONS.keys())), 80)) |
|
1832 | 1839 | |
|
1833 | 1840 | return _( |
|
1834 | 1841 | 'Example filter terms:\n' + |
|
1835 | 1842 | ' repository:vcs\n' + |
|
1836 | 1843 | ' username:marcin\n' + |
|
1837 | 1844 | ' username:(NOT marcin)\n' + |
|
1838 | 1845 | ' action:*push*\n' + |
|
1839 | 1846 | ' ip:127.0.0.1\n' + |
|
1840 | 1847 | ' date:20120101\n' + |
|
1841 | 1848 | ' date:[20120101100000 TO 20120102]\n' + |
|
1842 | 1849 | '\n' + |
|
1843 | 1850 | 'Actions: {actions}\n' + |
|
1844 | 1851 | '\n' + |
|
1845 | 1852 | 'Generate wildcards using \'*\' character:\n' + |
|
1846 | 1853 | ' "repository:vcs*" - search everything starting with \'vcs\'\n' + |
|
1847 | 1854 | ' "repository:*vcs*" - search for repository containing \'vcs\'\n' + |
|
1848 | 1855 | '\n' + |
|
1849 | 1856 | 'Optional AND / OR operators in queries\n' + |
|
1850 | 1857 | ' "repository:vcs OR repository:test"\n' + |
|
1851 | 1858 | ' "username:test AND repository:test*"\n' |
|
1852 | 1859 | ).format(actions=actions) |
|
1853 | 1860 | |
|
1854 | 1861 | |
|
1855 | 1862 | def not_mapped_error(repo_name): |
|
1856 | 1863 | from rhodecode.translation import _ |
|
1857 | 1864 | flash(_('%s repository is not mapped to db perhaps' |
|
1858 | 1865 | ' it was created or renamed from the filesystem' |
|
1859 | 1866 | ' please run the application again' |
|
1860 | 1867 | ' in order to rescan repositories') % repo_name, category='error') |
|
1861 | 1868 | |
|
1862 | 1869 | |
|
1863 | 1870 | def ip_range(ip_addr): |
|
1864 | 1871 | from rhodecode.model.db import UserIpMap |
|
1865 | 1872 | s, e = UserIpMap._get_ip_range(ip_addr) |
|
1866 | 1873 | return '%s - %s' % (s, e) |
|
1867 | 1874 | |
|
1868 | 1875 | |
|
1869 | 1876 | def form(url, method='post', needs_csrf_token=True, **attrs): |
|
1870 | 1877 | """Wrapper around webhelpers.tags.form to prevent CSRF attacks.""" |
|
1871 | 1878 | if method.lower() != 'get' and needs_csrf_token: |
|
1872 | 1879 | raise Exception( |
|
1873 | 1880 | 'Forms to POST/PUT/DELETE endpoints should have (in general) a ' + |
|
1874 | 1881 | 'CSRF token. If the endpoint does not require such token you can ' + |
|
1875 | 1882 | 'explicitly set the parameter needs_csrf_token to false.') |
|
1876 | 1883 | |
|
1877 | 1884 | return wh_form(url, method=method, **attrs) |
|
1878 | 1885 | |
|
1879 | 1886 | |
|
1880 | 1887 | def secure_form(form_url, method="POST", multipart=False, **attrs): |
|
1881 | 1888 | """Start a form tag that points the action to an url. This |
|
1882 | 1889 | form tag will also include the hidden field containing |
|
1883 | 1890 | the auth token. |
|
1884 | 1891 | |
|
1885 | 1892 | The url options should be given either as a string, or as a |
|
1886 | 1893 | ``url()`` function. The method for the form defaults to POST. |
|
1887 | 1894 | |
|
1888 | 1895 | Options: |
|
1889 | 1896 | |
|
1890 | 1897 | ``multipart`` |
|
1891 | 1898 | If set to True, the enctype is set to "multipart/form-data". |
|
1892 | 1899 | ``method`` |
|
1893 | 1900 | The method to use when submitting the form, usually either |
|
1894 | 1901 | "GET" or "POST". If "PUT", "DELETE", or another verb is used, a |
|
1895 | 1902 | hidden input with name _method is added to simulate the verb |
|
1896 | 1903 | over POST. |
|
1897 | 1904 | |
|
1898 | 1905 | """ |
|
1899 | 1906 | from webhelpers.pylonslib.secure_form import insecure_form |
|
1900 | 1907 | |
|
1901 | 1908 | if 'request' in attrs: |
|
1902 | 1909 | session = attrs['request'].session |
|
1903 | 1910 | del attrs['request'] |
|
1904 | 1911 | else: |
|
1905 | 1912 | raise ValueError( |
|
1906 | 1913 | 'Calling this form requires request= to be passed as argument') |
|
1907 | 1914 | |
|
1908 | 1915 | form = insecure_form(form_url, method, multipart, **attrs) |
|
1909 | 1916 | token = literal( |
|
1910 | 1917 | '<input type="hidden" id="{}" name="{}" value="{}">'.format( |
|
1911 | 1918 | csrf_token_key, csrf_token_key, get_csrf_token(session))) |
|
1912 | 1919 | |
|
1913 | 1920 | return literal("%s\n%s" % (form, token)) |
|
1914 | 1921 | |
|
1915 | 1922 | |
|
1916 | 1923 | def dropdownmenu(name, selected, options, enable_filter=False, **attrs): |
|
1917 | 1924 | select_html = select(name, selected, options, **attrs) |
|
1918 | 1925 | select2 = """ |
|
1919 | 1926 | <script> |
|
1920 | 1927 | $(document).ready(function() { |
|
1921 | 1928 | $('#%s').select2({ |
|
1922 | 1929 | containerCssClass: 'drop-menu', |
|
1923 | 1930 | dropdownCssClass: 'drop-menu-dropdown', |
|
1924 | 1931 | dropdownAutoWidth: true%s |
|
1925 | 1932 | }); |
|
1926 | 1933 | }); |
|
1927 | 1934 | </script> |
|
1928 | 1935 | """ |
|
1929 | 1936 | filter_option = """, |
|
1930 | 1937 | minimumResultsForSearch: -1 |
|
1931 | 1938 | """ |
|
1932 | 1939 | input_id = attrs.get('id') or name |
|
1933 | 1940 | filter_enabled = "" if enable_filter else filter_option |
|
1934 | 1941 | select_script = literal(select2 % (input_id, filter_enabled)) |
|
1935 | 1942 | |
|
1936 | 1943 | return literal(select_html+select_script) |
|
1937 | 1944 | |
|
1938 | 1945 | |
|
1939 | 1946 | def get_visual_attr(tmpl_context_var, attr_name): |
|
1940 | 1947 | """ |
|
1941 | 1948 | A safe way to get a variable from visual variable of template context |
|
1942 | 1949 | |
|
1943 | 1950 | :param tmpl_context_var: instance of tmpl_context, usually present as `c` |
|
1944 | 1951 | :param attr_name: name of the attribute we fetch from the c.visual |
|
1945 | 1952 | """ |
|
1946 | 1953 | visual = getattr(tmpl_context_var, 'visual', None) |
|
1947 | 1954 | if not visual: |
|
1948 | 1955 | return |
|
1949 | 1956 | else: |
|
1950 | 1957 | return getattr(visual, attr_name, None) |
|
1951 | 1958 | |
|
1952 | 1959 | |
|
1953 | 1960 | def get_last_path_part(file_node): |
|
1954 | 1961 | if not file_node.path: |
|
1955 | 1962 | return u'/' |
|
1956 | 1963 | |
|
1957 | 1964 | path = safe_unicode(file_node.path.split('/')[-1]) |
|
1958 | 1965 | return u'../' + path |
|
1959 | 1966 | |
|
1960 | 1967 | |
|
1961 | 1968 | def route_url(*args, **kwargs): |
|
1962 | 1969 | """ |
|
1963 | 1970 | Wrapper around pyramids `route_url` (fully qualified url) function. |
|
1964 | 1971 | """ |
|
1965 | 1972 | req = get_current_request() |
|
1966 | 1973 | return req.route_url(*args, **kwargs) |
|
1967 | 1974 | |
|
1968 | 1975 | |
|
1969 | 1976 | def route_path(*args, **kwargs): |
|
1970 | 1977 | """ |
|
1971 | 1978 | Wrapper around pyramids `route_path` function. |
|
1972 | 1979 | """ |
|
1973 | 1980 | req = get_current_request() |
|
1974 | 1981 | return req.route_path(*args, **kwargs) |
|
1975 | 1982 | |
|
1976 | 1983 | |
|
1977 | 1984 | def route_path_or_none(*args, **kwargs): |
|
1978 | 1985 | try: |
|
1979 | 1986 | return route_path(*args, **kwargs) |
|
1980 | 1987 | except KeyError: |
|
1981 | 1988 | return None |
|
1982 | 1989 | |
|
1983 | 1990 | |
|
1984 | 1991 | def current_route_path(request, **kw): |
|
1985 | 1992 | new_args = request.GET.mixed() |
|
1986 | 1993 | new_args.update(kw) |
|
1987 | 1994 | return request.current_route_path(_query=new_args) |
|
1988 | 1995 | |
|
1989 | 1996 | |
|
1990 | 1997 | def api_call_example(method, args): |
|
1991 | 1998 | """ |
|
1992 | 1999 | Generates an API call example via CURL |
|
1993 | 2000 | """ |
|
1994 | 2001 | args_json = json.dumps(OrderedDict([ |
|
1995 | 2002 | ('id', 1), |
|
1996 | 2003 | ('auth_token', 'SECRET'), |
|
1997 | 2004 | ('method', method), |
|
1998 | 2005 | ('args', args) |
|
1999 | 2006 | ])) |
|
2000 | 2007 | return literal( |
|
2001 | 2008 | "curl {api_url} -X POST -H 'content-type:text/plain' --data-binary '{data}'" |
|
2002 | 2009 | "<br/><br/>SECRET can be found in <a href=\"{token_url}\">auth-tokens</a> page, " |
|
2003 | 2010 | "and needs to be of `api calls` role." |
|
2004 | 2011 | .format( |
|
2005 | 2012 | api_url=route_url('apiv2'), |
|
2006 | 2013 | token_url=route_url('my_account_auth_tokens'), |
|
2007 | 2014 | data=args_json)) |
|
2008 | 2015 | |
|
2009 | 2016 | |
|
2010 | 2017 | def notification_description(notification, request): |
|
2011 | 2018 | """ |
|
2012 | 2019 | Generate notification human readable description based on notification type |
|
2013 | 2020 | """ |
|
2014 | 2021 | from rhodecode.model.notification import NotificationModel |
|
2015 | 2022 | return NotificationModel().make_description( |
|
2016 | 2023 | notification, translate=request.translate) |
|
2017 | 2024 | |
|
2018 | 2025 | |
|
2019 | 2026 | def go_import_header(request, db_repo=None): |
|
2020 | 2027 | """ |
|
2021 | 2028 | Creates a header for go-import functionality in Go Lang |
|
2022 | 2029 | """ |
|
2023 | 2030 | |
|
2024 | 2031 | if not db_repo: |
|
2025 | 2032 | return |
|
2026 | 2033 | if 'go-get' not in request.GET: |
|
2027 | 2034 | return |
|
2028 | 2035 | |
|
2029 | 2036 | clone_url = db_repo.clone_url() |
|
2030 | 2037 | prefix = re.split(r'^https?:\/\/', clone_url)[-1] |
|
2031 | 2038 | # we have a repo and go-get flag, |
|
2032 | 2039 | return literal('<meta name="go-import" content="{} {} {}">'.format( |
|
2033 | 2040 | prefix, db_repo.repo_type, clone_url)) |
|
2034 | 2041 | |
|
2035 | 2042 | |
|
2036 | 2043 | def reviewer_as_json(*args, **kwargs): |
|
2037 | 2044 | from rhodecode.apps.repository.utils import reviewer_as_json as _reviewer_as_json |
|
2038 | 2045 | return _reviewer_as_json(*args, **kwargs) |
|
2039 | 2046 | |
|
2040 | 2047 | |
|
2041 | 2048 | def get_repo_view_type(request): |
|
2042 | 2049 | route_name = request.matched_route.name |
|
2043 | 2050 | route_to_view_type = { |
|
2044 | 2051 | 'repo_changelog': 'changelog', |
|
2045 | 2052 | 'repo_files': 'files', |
|
2046 | 2053 | 'repo_summary': 'summary', |
|
2047 | 2054 | 'repo_commit': 'commit' |
|
2048 | 2055 | } |
|
2049 | 2056 | |
|
2050 | 2057 | return route_to_view_type.get(route_name) |
@@ -1,2583 +1,2584 b'' | |||
|
1 | 1 | //Primary CSS |
|
2 | 2 | |
|
3 | 3 | //--- IMPORTS ------------------// |
|
4 | 4 | |
|
5 | 5 | @import 'helpers'; |
|
6 | 6 | @import 'mixins'; |
|
7 | 7 | @import 'rcicons'; |
|
8 | 8 | @import 'variables'; |
|
9 | 9 | @import 'bootstrap-variables'; |
|
10 | 10 | @import 'form-bootstrap'; |
|
11 | 11 | @import 'codemirror'; |
|
12 | 12 | @import 'legacy_code_styles'; |
|
13 | 13 | @import 'readme-box'; |
|
14 | 14 | @import 'progress-bar'; |
|
15 | 15 | |
|
16 | 16 | @import 'type'; |
|
17 | 17 | @import 'alerts'; |
|
18 | 18 | @import 'buttons'; |
|
19 | 19 | @import 'tags'; |
|
20 | 20 | @import 'code-block'; |
|
21 | 21 | @import 'examples'; |
|
22 | 22 | @import 'login'; |
|
23 | 23 | @import 'main-content'; |
|
24 | 24 | @import 'select2'; |
|
25 | 25 | @import 'comments'; |
|
26 | 26 | @import 'panels-bootstrap'; |
|
27 | 27 | @import 'panels'; |
|
28 | 28 | @import 'deform'; |
|
29 | 29 | |
|
30 | 30 | //--- BASE ------------------// |
|
31 | 31 | .noscript-error { |
|
32 | 32 | top: 0; |
|
33 | 33 | left: 0; |
|
34 | 34 | width: 100%; |
|
35 | 35 | z-index: 101; |
|
36 | 36 | text-align: center; |
|
37 | 37 | font-size: 120%; |
|
38 | 38 | color: white; |
|
39 | 39 | background-color: @alert2; |
|
40 | 40 | padding: 5px 0 5px 0; |
|
41 | 41 | font-weight: @text-semibold-weight; |
|
42 | 42 | font-family: @text-semibold; |
|
43 | 43 | } |
|
44 | 44 | |
|
45 | 45 | html { |
|
46 | 46 | display: table; |
|
47 | 47 | height: 100%; |
|
48 | 48 | width: 100%; |
|
49 | 49 | } |
|
50 | 50 | |
|
51 | 51 | body { |
|
52 | 52 | display: table-cell; |
|
53 | 53 | width: 100%; |
|
54 | 54 | } |
|
55 | 55 | |
|
56 | 56 | //--- LAYOUT ------------------// |
|
57 | 57 | |
|
58 | 58 | .hidden{ |
|
59 | 59 | display: none !important; |
|
60 | 60 | } |
|
61 | 61 | |
|
62 | 62 | .box{ |
|
63 | 63 | float: left; |
|
64 | 64 | width: 100%; |
|
65 | 65 | } |
|
66 | 66 | |
|
67 | 67 | .browser-header { |
|
68 | 68 | clear: both; |
|
69 | 69 | } |
|
70 | 70 | .main { |
|
71 | 71 | clear: both; |
|
72 | 72 | padding:0 0 @pagepadding; |
|
73 | 73 | height: auto; |
|
74 | 74 | |
|
75 | 75 | &:after { //clearfix |
|
76 | 76 | content:""; |
|
77 | 77 | clear:both; |
|
78 | 78 | width:100%; |
|
79 | 79 | display:block; |
|
80 | 80 | } |
|
81 | 81 | } |
|
82 | 82 | |
|
83 | 83 | .action-link{ |
|
84 | 84 | margin-left: @padding; |
|
85 | 85 | padding-left: @padding; |
|
86 | 86 | border-left: @border-thickness solid @border-default-color; |
|
87 | 87 | } |
|
88 | 88 | |
|
89 | 89 | input + .action-link, .action-link.first{ |
|
90 | 90 | border-left: none; |
|
91 | 91 | } |
|
92 | 92 | |
|
93 | 93 | .action-link.last{ |
|
94 | 94 | margin-right: @padding; |
|
95 | 95 | padding-right: @padding; |
|
96 | 96 | } |
|
97 | 97 | |
|
98 | 98 | .action-link.active, |
|
99 | 99 | .action-link.active a{ |
|
100 | 100 | color: @grey4; |
|
101 | 101 | } |
|
102 | 102 | |
|
103 | 103 | .action-link.disabled { |
|
104 | 104 | color: @grey4; |
|
105 | 105 | cursor: inherit; |
|
106 | 106 | } |
|
107 | 107 | |
|
108 | 108 | .clipboard-action { |
|
109 | 109 | cursor: pointer; |
|
110 | 110 | } |
|
111 | 111 | |
|
112 | 112 | ul.simple-list{ |
|
113 | 113 | list-style: none; |
|
114 | 114 | margin: 0; |
|
115 | 115 | padding: 0; |
|
116 | 116 | } |
|
117 | 117 | |
|
118 | 118 | .main-content { |
|
119 | 119 | padding-bottom: @pagepadding; |
|
120 | 120 | } |
|
121 | 121 | |
|
122 | 122 | .wide-mode-wrapper { |
|
123 | 123 | max-width:4000px !important; |
|
124 | 124 | } |
|
125 | 125 | |
|
126 | 126 | .wrapper { |
|
127 | 127 | position: relative; |
|
128 | 128 | max-width: @wrapper-maxwidth; |
|
129 | 129 | margin: 0 auto; |
|
130 | 130 | } |
|
131 | 131 | |
|
132 | 132 | #content { |
|
133 | 133 | clear: both; |
|
134 | 134 | padding: 0 @contentpadding; |
|
135 | 135 | } |
|
136 | 136 | |
|
137 | 137 | .advanced-settings-fields{ |
|
138 | 138 | input{ |
|
139 | 139 | margin-left: @textmargin; |
|
140 | 140 | margin-right: @padding/2; |
|
141 | 141 | } |
|
142 | 142 | } |
|
143 | 143 | |
|
144 | 144 | .cs_files_title { |
|
145 | 145 | margin: @pagepadding 0 0; |
|
146 | 146 | } |
|
147 | 147 | |
|
148 | 148 | input.inline[type="file"] { |
|
149 | 149 | display: inline; |
|
150 | 150 | } |
|
151 | 151 | |
|
152 | 152 | .error_page { |
|
153 | 153 | margin: 10% auto; |
|
154 | 154 | |
|
155 | 155 | h1 { |
|
156 | 156 | color: @grey2; |
|
157 | 157 | } |
|
158 | 158 | |
|
159 | 159 | .alert { |
|
160 | 160 | margin: @padding 0; |
|
161 | 161 | } |
|
162 | 162 | |
|
163 | 163 | .error-branding { |
|
164 | 164 | color: @grey4; |
|
165 | 165 | font-weight: @text-semibold-weight; |
|
166 | 166 | font-family: @text-semibold; |
|
167 | 167 | } |
|
168 | 168 | |
|
169 | 169 | .error_message { |
|
170 | 170 | font-family: @text-regular; |
|
171 | 171 | } |
|
172 | 172 | |
|
173 | 173 | .sidebar { |
|
174 | 174 | min-height: 275px; |
|
175 | 175 | margin: 0; |
|
176 | 176 | padding: 0 0 @sidebarpadding @sidebarpadding; |
|
177 | 177 | border: none; |
|
178 | 178 | } |
|
179 | 179 | |
|
180 | 180 | .main-content { |
|
181 | 181 | position: relative; |
|
182 | 182 | margin: 0 @sidebarpadding @sidebarpadding; |
|
183 | 183 | padding: 0 0 0 @sidebarpadding; |
|
184 | 184 | border-left: @border-thickness solid @grey5; |
|
185 | 185 | |
|
186 | 186 | @media (max-width:767px) { |
|
187 | 187 | clear: both; |
|
188 | 188 | width: 100%; |
|
189 | 189 | margin: 0; |
|
190 | 190 | border: none; |
|
191 | 191 | } |
|
192 | 192 | } |
|
193 | 193 | |
|
194 | 194 | .inner-column { |
|
195 | 195 | float: left; |
|
196 | 196 | width: 29.75%; |
|
197 | 197 | min-height: 150px; |
|
198 | 198 | margin: @sidebarpadding 2% 0 0; |
|
199 | 199 | padding: 0 2% 0 0; |
|
200 | 200 | border-right: @border-thickness solid @grey5; |
|
201 | 201 | |
|
202 | 202 | @media (max-width:767px) { |
|
203 | 203 | clear: both; |
|
204 | 204 | width: 100%; |
|
205 | 205 | border: none; |
|
206 | 206 | } |
|
207 | 207 | |
|
208 | 208 | ul { |
|
209 | 209 | padding-left: 1.25em; |
|
210 | 210 | } |
|
211 | 211 | |
|
212 | 212 | &:last-child { |
|
213 | 213 | margin: @sidebarpadding 0 0; |
|
214 | 214 | border: none; |
|
215 | 215 | } |
|
216 | 216 | |
|
217 | 217 | h4 { |
|
218 | 218 | margin: 0 0 @padding; |
|
219 | 219 | font-weight: @text-semibold-weight; |
|
220 | 220 | font-family: @text-semibold; |
|
221 | 221 | } |
|
222 | 222 | } |
|
223 | 223 | } |
|
224 | 224 | .error-page-logo { |
|
225 | 225 | width: 130px; |
|
226 | 226 | height: 160px; |
|
227 | 227 | } |
|
228 | 228 | |
|
229 | 229 | // HEADER |
|
230 | 230 | .header { |
|
231 | 231 | |
|
232 | 232 | // TODO: johbo: Fix login pages, so that they work without a min-height |
|
233 | 233 | // for the header and then remove the min-height. I chose a smaller value |
|
234 | 234 | // intentionally here to avoid rendering issues in the main navigation. |
|
235 | 235 | min-height: 49px; |
|
236 | 236 | |
|
237 | 237 | position: relative; |
|
238 | 238 | vertical-align: bottom; |
|
239 | 239 | padding: 0 @header-padding; |
|
240 | 240 | background-color: @grey1; |
|
241 | 241 | color: @grey5; |
|
242 | 242 | |
|
243 | 243 | .title { |
|
244 | 244 | overflow: visible; |
|
245 | 245 | } |
|
246 | 246 | |
|
247 | 247 | &:before, |
|
248 | 248 | &:after { |
|
249 | 249 | content: ""; |
|
250 | 250 | clear: both; |
|
251 | 251 | width: 100%; |
|
252 | 252 | } |
|
253 | 253 | |
|
254 | 254 | // TODO: johbo: Avoids breaking "Repositories" chooser |
|
255 | 255 | .select2-container .select2-choice .select2-arrow { |
|
256 | 256 | display: none; |
|
257 | 257 | } |
|
258 | 258 | } |
|
259 | 259 | |
|
260 | 260 | #header-inner { |
|
261 | 261 | &.title { |
|
262 | 262 | margin: 0; |
|
263 | 263 | } |
|
264 | 264 | &:before, |
|
265 | 265 | &:after { |
|
266 | 266 | content: ""; |
|
267 | 267 | clear: both; |
|
268 | 268 | } |
|
269 | 269 | } |
|
270 | 270 | |
|
271 | 271 | // Gists |
|
272 | 272 | #files_data { |
|
273 | 273 | clear: both; //for firefox |
|
274 | 274 | } |
|
275 | 275 | #gistid { |
|
276 | 276 | margin-right: @padding; |
|
277 | 277 | } |
|
278 | 278 | |
|
279 | 279 | // Global Settings Editor |
|
280 | 280 | .textarea.editor { |
|
281 | 281 | float: left; |
|
282 | 282 | position: relative; |
|
283 | 283 | max-width: @texteditor-width; |
|
284 | 284 | |
|
285 | 285 | select { |
|
286 | 286 | position: absolute; |
|
287 | 287 | top:10px; |
|
288 | 288 | right:0; |
|
289 | 289 | } |
|
290 | 290 | |
|
291 | 291 | .CodeMirror { |
|
292 | 292 | margin: 0; |
|
293 | 293 | } |
|
294 | 294 | |
|
295 | 295 | .help-block { |
|
296 | 296 | margin: 0 0 @padding; |
|
297 | 297 | padding:.5em; |
|
298 | 298 | background-color: @grey6; |
|
299 | 299 | &.pre-formatting { |
|
300 | 300 | white-space: pre; |
|
301 | 301 | } |
|
302 | 302 | } |
|
303 | 303 | } |
|
304 | 304 | |
|
305 | 305 | ul.auth_plugins { |
|
306 | 306 | margin: @padding 0 @padding @legend-width; |
|
307 | 307 | padding: 0; |
|
308 | 308 | |
|
309 | 309 | li { |
|
310 | 310 | margin-bottom: @padding; |
|
311 | 311 | line-height: 1em; |
|
312 | 312 | list-style-type: none; |
|
313 | 313 | |
|
314 | 314 | .auth_buttons .btn { |
|
315 | 315 | margin-right: @padding; |
|
316 | 316 | } |
|
317 | 317 | |
|
318 | 318 | } |
|
319 | 319 | } |
|
320 | 320 | |
|
321 | 321 | |
|
322 | 322 | // My Account PR list |
|
323 | 323 | |
|
324 | 324 | #show_closed { |
|
325 | 325 | margin: 0 1em 0 0; |
|
326 | 326 | } |
|
327 | 327 | |
|
328 | 328 | .pullrequestlist { |
|
329 | 329 | .closed { |
|
330 | 330 | background-color: @grey6; |
|
331 | 331 | } |
|
332 | 332 | .td-status { |
|
333 | 333 | padding-left: .5em; |
|
334 | 334 | } |
|
335 | 335 | .log-container .truncate { |
|
336 | 336 | height: 2.75em; |
|
337 | 337 | white-space: pre-line; |
|
338 | 338 | } |
|
339 | 339 | table.rctable .user { |
|
340 | 340 | padding-left: 0; |
|
341 | 341 | } |
|
342 | 342 | table.rctable { |
|
343 | 343 | td.td-description, |
|
344 | 344 | .rc-user { |
|
345 | 345 | min-width: auto; |
|
346 | 346 | } |
|
347 | 347 | } |
|
348 | 348 | } |
|
349 | 349 | |
|
350 | 350 | // Pull Requests |
|
351 | 351 | |
|
352 | 352 | .pullrequests_section_head { |
|
353 | 353 | display: block; |
|
354 | 354 | clear: both; |
|
355 | 355 | margin: @padding 0; |
|
356 | 356 | font-weight: @text-bold-weight; |
|
357 | 357 | font-family: @text-bold; |
|
358 | 358 | } |
|
359 | 359 | |
|
360 | 360 | .pr-origininfo, .pr-targetinfo { |
|
361 | 361 | position: relative; |
|
362 | 362 | |
|
363 | 363 | .tag { |
|
364 | 364 | display: inline-block; |
|
365 | 365 | margin: 0 1em .5em 0; |
|
366 | 366 | } |
|
367 | 367 | |
|
368 | 368 | .clone-url { |
|
369 | 369 | display: inline-block; |
|
370 | 370 | margin: 0 0 .5em 0; |
|
371 | 371 | padding: 0; |
|
372 | 372 | line-height: 1.2em; |
|
373 | 373 | } |
|
374 | 374 | } |
|
375 | 375 | |
|
376 | 376 | .pr-mergeinfo { |
|
377 | 377 | min-width: 95% !important; |
|
378 | 378 | padding: 0 !important; |
|
379 | 379 | border: 0; |
|
380 | 380 | } |
|
381 | 381 | .pr-mergeinfo-copy { |
|
382 | 382 | padding: 0 0; |
|
383 | 383 | } |
|
384 | 384 | |
|
385 | 385 | .pr-pullinfo { |
|
386 | 386 | min-width: 95% !important; |
|
387 | 387 | padding: 0 !important; |
|
388 | 388 | border: 0; |
|
389 | 389 | } |
|
390 | 390 | .pr-pullinfo-copy { |
|
391 | 391 | padding: 0 0; |
|
392 | 392 | } |
|
393 | 393 | |
|
394 | 394 | |
|
395 | 395 | #pr-title-input { |
|
396 | 396 | width: 72%; |
|
397 | 397 | font-size: 1em; |
|
398 | 398 | margin: 0; |
|
399 | 399 | padding: 0 0 0 @padding/4; |
|
400 | 400 | line-height: 1.7em; |
|
401 | 401 | color: @text-color; |
|
402 | 402 | letter-spacing: .02em; |
|
403 | 403 | font-weight: @text-bold-weight; |
|
404 | 404 | font-family: @text-bold; |
|
405 | 405 | } |
|
406 | 406 | |
|
407 | 407 | #pullrequest_title { |
|
408 | 408 | width: 100%; |
|
409 | 409 | box-sizing: border-box; |
|
410 | 410 | } |
|
411 | 411 | |
|
412 | 412 | #pr_open_message { |
|
413 | 413 | border: @border-thickness solid #fff; |
|
414 | 414 | border-radius: @border-radius; |
|
415 | 415 | padding: @padding-large-vertical @padding-large-vertical @padding-large-vertical 0; |
|
416 | 416 | text-align: left; |
|
417 | 417 | overflow: hidden; |
|
418 | 418 | } |
|
419 | 419 | |
|
420 | 420 | .pr-submit-button { |
|
421 | 421 | float: right; |
|
422 | 422 | margin: 0 0 0 5px; |
|
423 | 423 | } |
|
424 | 424 | |
|
425 | 425 | .pr-spacing-container { |
|
426 | 426 | padding: 20px; |
|
427 | 427 | clear: both |
|
428 | 428 | } |
|
429 | 429 | |
|
430 | 430 | #pr-description-input { |
|
431 | 431 | margin-bottom: 0; |
|
432 | 432 | } |
|
433 | 433 | |
|
434 | 434 | .pr-description-label { |
|
435 | 435 | vertical-align: top; |
|
436 | 436 | } |
|
437 | 437 | |
|
438 | 438 | .perms_section_head { |
|
439 | 439 | min-width: 625px; |
|
440 | 440 | |
|
441 | 441 | h2 { |
|
442 | 442 | margin-bottom: 0; |
|
443 | 443 | } |
|
444 | 444 | |
|
445 | 445 | .label-checkbox { |
|
446 | 446 | float: left; |
|
447 | 447 | } |
|
448 | 448 | |
|
449 | 449 | &.field { |
|
450 | 450 | margin: @space 0 @padding; |
|
451 | 451 | } |
|
452 | 452 | |
|
453 | 453 | &:first-child.field { |
|
454 | 454 | margin-top: 0; |
|
455 | 455 | |
|
456 | 456 | .label { |
|
457 | 457 | margin-top: 0; |
|
458 | 458 | padding-top: 0; |
|
459 | 459 | } |
|
460 | 460 | |
|
461 | 461 | .radios { |
|
462 | 462 | padding-top: 0; |
|
463 | 463 | } |
|
464 | 464 | } |
|
465 | 465 | |
|
466 | 466 | .radios { |
|
467 | 467 | position: relative; |
|
468 | 468 | width: 505px; |
|
469 | 469 | } |
|
470 | 470 | } |
|
471 | 471 | |
|
472 | 472 | //--- MODULES ------------------// |
|
473 | 473 | |
|
474 | 474 | |
|
475 | 475 | // Server Announcement |
|
476 | 476 | #server-announcement { |
|
477 | 477 | width: 95%; |
|
478 | 478 | margin: @padding auto; |
|
479 | 479 | padding: @padding; |
|
480 | 480 | border-width: 2px; |
|
481 | 481 | border-style: solid; |
|
482 | 482 | .border-radius(2px); |
|
483 | 483 | font-weight: @text-bold-weight; |
|
484 | 484 | font-family: @text-bold; |
|
485 | 485 | |
|
486 | 486 | &.info { border-color: @alert4; background-color: @alert4-inner; } |
|
487 | 487 | &.warning { border-color: @alert3; background-color: @alert3-inner; } |
|
488 | 488 | &.error { border-color: @alert2; background-color: @alert2-inner; } |
|
489 | 489 | &.success { border-color: @alert1; background-color: @alert1-inner; } |
|
490 | 490 | &.neutral { border-color: @grey3; background-color: @grey6; } |
|
491 | 491 | } |
|
492 | 492 | |
|
493 | 493 | // Fixed Sidebar Column |
|
494 | 494 | .sidebar-col-wrapper { |
|
495 | 495 | padding-left: @sidebar-all-width; |
|
496 | 496 | |
|
497 | 497 | .sidebar { |
|
498 | 498 | width: @sidebar-width; |
|
499 | 499 | margin-left: -@sidebar-all-width; |
|
500 | 500 | } |
|
501 | 501 | } |
|
502 | 502 | |
|
503 | 503 | .sidebar-col-wrapper.scw-small { |
|
504 | 504 | padding-left: @sidebar-small-all-width; |
|
505 | 505 | |
|
506 | 506 | .sidebar { |
|
507 | 507 | width: @sidebar-small-width; |
|
508 | 508 | margin-left: -@sidebar-small-all-width; |
|
509 | 509 | } |
|
510 | 510 | } |
|
511 | 511 | |
|
512 | 512 | |
|
513 | 513 | // FOOTER |
|
514 | 514 | #footer { |
|
515 | 515 | padding: 0; |
|
516 | 516 | text-align: center; |
|
517 | 517 | vertical-align: middle; |
|
518 | 518 | color: @grey2; |
|
519 | 519 | font-size: 11px; |
|
520 | 520 | |
|
521 | 521 | p { |
|
522 | 522 | margin: 0; |
|
523 | 523 | padding: 1em; |
|
524 | 524 | line-height: 1em; |
|
525 | 525 | } |
|
526 | 526 | |
|
527 | 527 | .server-instance { //server instance |
|
528 | 528 | display: none; |
|
529 | 529 | } |
|
530 | 530 | |
|
531 | 531 | .title { |
|
532 | 532 | float: none; |
|
533 | 533 | margin: 0 auto; |
|
534 | 534 | } |
|
535 | 535 | } |
|
536 | 536 | |
|
537 | 537 | button.close { |
|
538 | 538 | padding: 0; |
|
539 | 539 | cursor: pointer; |
|
540 | 540 | background: transparent; |
|
541 | 541 | border: 0; |
|
542 | 542 | .box-shadow(none); |
|
543 | 543 | -webkit-appearance: none; |
|
544 | 544 | } |
|
545 | 545 | |
|
546 | 546 | .close { |
|
547 | 547 | float: right; |
|
548 | 548 | font-size: 21px; |
|
549 | 549 | font-family: @text-bootstrap; |
|
550 | 550 | line-height: 1em; |
|
551 | 551 | font-weight: bold; |
|
552 | 552 | color: @grey2; |
|
553 | 553 | |
|
554 | 554 | &:hover, |
|
555 | 555 | &:focus { |
|
556 | 556 | color: @grey1; |
|
557 | 557 | text-decoration: none; |
|
558 | 558 | cursor: pointer; |
|
559 | 559 | } |
|
560 | 560 | } |
|
561 | 561 | |
|
562 | 562 | // GRID |
|
563 | 563 | .sorting, |
|
564 | 564 | .sorting_desc, |
|
565 | 565 | .sorting_asc { |
|
566 | 566 | cursor: pointer; |
|
567 | 567 | } |
|
568 | 568 | .sorting_desc:after { |
|
569 | 569 | content: "\00A0\25B2"; |
|
570 | 570 | font-size: .75em; |
|
571 | 571 | } |
|
572 | 572 | .sorting_asc:after { |
|
573 | 573 | content: "\00A0\25BC"; |
|
574 | 574 | font-size: .68em; |
|
575 | 575 | } |
|
576 | 576 | |
|
577 | 577 | |
|
578 | 578 | .user_auth_tokens { |
|
579 | 579 | |
|
580 | 580 | &.truncate { |
|
581 | 581 | white-space: nowrap; |
|
582 | 582 | overflow: hidden; |
|
583 | 583 | text-overflow: ellipsis; |
|
584 | 584 | } |
|
585 | 585 | |
|
586 | 586 | .fields .field .input { |
|
587 | 587 | margin: 0; |
|
588 | 588 | } |
|
589 | 589 | |
|
590 | 590 | input#description { |
|
591 | 591 | width: 100px; |
|
592 | 592 | margin: 0; |
|
593 | 593 | } |
|
594 | 594 | |
|
595 | 595 | .drop-menu { |
|
596 | 596 | // TODO: johbo: Remove this, should work out of the box when |
|
597 | 597 | // having multiple inputs inline |
|
598 | 598 | margin: 0 0 0 5px; |
|
599 | 599 | } |
|
600 | 600 | } |
|
601 | 601 | #user_list_table { |
|
602 | 602 | .closed { |
|
603 | 603 | background-color: @grey6; |
|
604 | 604 | } |
|
605 | 605 | } |
|
606 | 606 | |
|
607 | 607 | |
|
608 | 608 | input, textarea { |
|
609 | 609 | &.disabled { |
|
610 | 610 | opacity: .5; |
|
611 | 611 | } |
|
612 | 612 | |
|
613 | 613 | &:hover { |
|
614 | 614 | border-color: @grey3; |
|
615 | 615 | box-shadow: @button-shadow; |
|
616 | 616 | } |
|
617 | 617 | |
|
618 | 618 | &:focus { |
|
619 | 619 | border-color: @rcblue; |
|
620 | 620 | box-shadow: @button-shadow; |
|
621 | 621 | } |
|
622 | 622 | } |
|
623 | 623 | |
|
624 | 624 | // remove extra padding in firefox |
|
625 | 625 | input::-moz-focus-inner { border:0; padding:0 } |
|
626 | 626 | |
|
627 | 627 | .adjacent input { |
|
628 | 628 | margin-bottom: @padding; |
|
629 | 629 | } |
|
630 | 630 | |
|
631 | 631 | .permissions_boxes { |
|
632 | 632 | display: block; |
|
633 | 633 | } |
|
634 | 634 | |
|
635 | 635 | //FORMS |
|
636 | 636 | |
|
637 | 637 | .medium-inline, |
|
638 | 638 | input#description.medium-inline { |
|
639 | 639 | display: inline; |
|
640 | 640 | width: @medium-inline-input-width; |
|
641 | 641 | min-width: 100px; |
|
642 | 642 | } |
|
643 | 643 | |
|
644 | 644 | select { |
|
645 | 645 | //reset |
|
646 | 646 | -webkit-appearance: none; |
|
647 | 647 | -moz-appearance: none; |
|
648 | 648 | |
|
649 | 649 | display: inline-block; |
|
650 | 650 | height: 28px; |
|
651 | 651 | width: auto; |
|
652 | 652 | margin: 0 @padding @padding 0; |
|
653 | 653 | padding: 0 18px 0 8px; |
|
654 | 654 | line-height:1em; |
|
655 | 655 | font-size: @basefontsize; |
|
656 | 656 | border: @border-thickness solid @grey5; |
|
657 | 657 | border-radius: @border-radius; |
|
658 | 658 | background:white url("../images/dt-arrow-dn.png") no-repeat 100% 50%; |
|
659 | 659 | color: @grey4; |
|
660 | 660 | box-shadow: @button-shadow; |
|
661 | 661 | |
|
662 | 662 | &:after { |
|
663 | 663 | content: "\00A0\25BE"; |
|
664 | 664 | } |
|
665 | 665 | |
|
666 | 666 | &:focus, &:hover { |
|
667 | 667 | outline: none; |
|
668 | 668 | border-color: @grey4; |
|
669 | 669 | color: @rcdarkblue; |
|
670 | 670 | } |
|
671 | 671 | } |
|
672 | 672 | |
|
673 | 673 | option { |
|
674 | 674 | &:focus { |
|
675 | 675 | outline: none; |
|
676 | 676 | } |
|
677 | 677 | } |
|
678 | 678 | |
|
679 | 679 | input, |
|
680 | 680 | textarea { |
|
681 | 681 | padding: @input-padding; |
|
682 | 682 | border: @input-border-thickness solid @border-highlight-color; |
|
683 | 683 | .border-radius (@border-radius); |
|
684 | 684 | font-family: @text-light; |
|
685 | 685 | font-size: @basefontsize; |
|
686 | 686 | |
|
687 | 687 | &.input-sm { |
|
688 | 688 | padding: 5px; |
|
689 | 689 | } |
|
690 | 690 | |
|
691 | 691 | &#description { |
|
692 | 692 | min-width: @input-description-minwidth; |
|
693 | 693 | min-height: 1em; |
|
694 | 694 | padding: 10px; |
|
695 | 695 | } |
|
696 | 696 | } |
|
697 | 697 | |
|
698 | 698 | .field-sm { |
|
699 | 699 | input, |
|
700 | 700 | textarea { |
|
701 | 701 | padding: 5px; |
|
702 | 702 | } |
|
703 | 703 | } |
|
704 | 704 | |
|
705 | 705 | textarea { |
|
706 | 706 | display: block; |
|
707 | 707 | clear: both; |
|
708 | 708 | width: 100%; |
|
709 | 709 | min-height: 100px; |
|
710 | 710 | margin-bottom: @padding; |
|
711 | 711 | .box-sizing(border-box); |
|
712 | 712 | overflow: auto; |
|
713 | 713 | } |
|
714 | 714 | |
|
715 | 715 | label { |
|
716 | 716 | font-family: @text-light; |
|
717 | 717 | } |
|
718 | 718 | |
|
719 | 719 | // GRAVATARS |
|
720 | 720 | // centers gravatar on username to the right |
|
721 | 721 | |
|
722 | 722 | .gravatar { |
|
723 | 723 | display: inline; |
|
724 | 724 | min-width: 16px; |
|
725 | 725 | min-height: 16px; |
|
726 | 726 | margin: -5px 0; |
|
727 | 727 | padding: 0; |
|
728 | 728 | line-height: 1em; |
|
729 | 729 | box-sizing: content-box; |
|
730 | 730 | border-radius: 50%; |
|
731 | 731 | |
|
732 | 732 | &.gravatar-large { |
|
733 | 733 | margin: -0.5em .25em -0.5em 0; |
|
734 | 734 | } |
|
735 | 735 | |
|
736 | 736 | & + .user { |
|
737 | 737 | display: inline; |
|
738 | 738 | margin: 0; |
|
739 | 739 | padding: 0 0 0 .17em; |
|
740 | 740 | line-height: 1em; |
|
741 | 741 | } |
|
742 | 742 | } |
|
743 | 743 | |
|
744 | 744 | .user-inline-data { |
|
745 | 745 | display: inline-block; |
|
746 | 746 | float: left; |
|
747 | 747 | padding-left: .5em; |
|
748 | 748 | line-height: 1.3em; |
|
749 | 749 | } |
|
750 | 750 | |
|
751 | 751 | .rc-user { // gravatar + user wrapper |
|
752 | 752 | float: left; |
|
753 | 753 | position: relative; |
|
754 | 754 | min-width: 100px; |
|
755 | 755 | max-width: 200px; |
|
756 | 756 | min-height: (@gravatar-size + @border-thickness * 2); // account for border |
|
757 | 757 | display: block; |
|
758 | 758 | padding: 0 0 0 (@gravatar-size + @basefontsize/2 + @border-thickness * 2); |
|
759 | 759 | |
|
760 | 760 | |
|
761 | 761 | .gravatar { |
|
762 | 762 | display: block; |
|
763 | 763 | position: absolute; |
|
764 | 764 | top: 0; |
|
765 | 765 | left: 0; |
|
766 | 766 | min-width: @gravatar-size; |
|
767 | 767 | min-height: @gravatar-size; |
|
768 | 768 | margin: 0; |
|
769 | 769 | } |
|
770 | 770 | |
|
771 | 771 | .user { |
|
772 | 772 | display: block; |
|
773 | 773 | max-width: 175px; |
|
774 | 774 | padding-top: 2px; |
|
775 | 775 | overflow: hidden; |
|
776 | 776 | text-overflow: ellipsis; |
|
777 | 777 | } |
|
778 | 778 | } |
|
779 | 779 | |
|
780 | 780 | .gist-gravatar, |
|
781 | 781 | .journal_container { |
|
782 | 782 | .gravatar-large { |
|
783 | 783 | margin: 0 .5em -10px 0; |
|
784 | 784 | } |
|
785 | 785 | } |
|
786 | 786 | |
|
787 | 787 | |
|
788 | 788 | // ADMIN SETTINGS |
|
789 | 789 | |
|
790 | 790 | // Tag Patterns |
|
791 | 791 | .tag_patterns { |
|
792 | 792 | .tag_input { |
|
793 | 793 | margin-bottom: @padding; |
|
794 | 794 | } |
|
795 | 795 | } |
|
796 | 796 | |
|
797 | 797 | .locked_input { |
|
798 | 798 | position: relative; |
|
799 | 799 | |
|
800 | 800 | input { |
|
801 | 801 | display: inline; |
|
802 | 802 | margin: 3px 5px 0px 0px; |
|
803 | 803 | } |
|
804 | 804 | |
|
805 | 805 | br { |
|
806 | 806 | display: none; |
|
807 | 807 | } |
|
808 | 808 | |
|
809 | 809 | .error-message { |
|
810 | 810 | float: left; |
|
811 | 811 | width: 100%; |
|
812 | 812 | } |
|
813 | 813 | |
|
814 | 814 | .lock_input_button { |
|
815 | 815 | display: inline; |
|
816 | 816 | } |
|
817 | 817 | |
|
818 | 818 | .help-block { |
|
819 | 819 | clear: both; |
|
820 | 820 | } |
|
821 | 821 | } |
|
822 | 822 | |
|
823 | 823 | // Notifications |
|
824 | 824 | |
|
825 | 825 | .notifications_buttons { |
|
826 | 826 | margin: 0 0 @space 0; |
|
827 | 827 | padding: 0; |
|
828 | 828 | |
|
829 | 829 | .btn { |
|
830 | 830 | display: inline-block; |
|
831 | 831 | } |
|
832 | 832 | } |
|
833 | 833 | |
|
834 | 834 | .notification-list { |
|
835 | 835 | |
|
836 | 836 | div { |
|
837 | 837 | display: inline-block; |
|
838 | 838 | vertical-align: middle; |
|
839 | 839 | } |
|
840 | 840 | |
|
841 | 841 | .container { |
|
842 | 842 | display: block; |
|
843 | 843 | margin: 0 0 @padding 0; |
|
844 | 844 | } |
|
845 | 845 | |
|
846 | 846 | .delete-notifications { |
|
847 | 847 | margin-left: @padding; |
|
848 | 848 | text-align: right; |
|
849 | 849 | cursor: pointer; |
|
850 | 850 | } |
|
851 | 851 | |
|
852 | 852 | .read-notifications { |
|
853 | 853 | margin-left: @padding/2; |
|
854 | 854 | text-align: right; |
|
855 | 855 | width: 35px; |
|
856 | 856 | cursor: pointer; |
|
857 | 857 | } |
|
858 | 858 | |
|
859 | 859 | .icon-minus-sign { |
|
860 | 860 | color: @alert2; |
|
861 | 861 | } |
|
862 | 862 | |
|
863 | 863 | .icon-ok-sign { |
|
864 | 864 | color: @alert1; |
|
865 | 865 | } |
|
866 | 866 | } |
|
867 | 867 | |
|
868 | 868 | .user_settings { |
|
869 | 869 | float: left; |
|
870 | 870 | clear: both; |
|
871 | 871 | display: block; |
|
872 | 872 | width: 100%; |
|
873 | 873 | |
|
874 | 874 | .gravatar_box { |
|
875 | 875 | margin-bottom: @padding; |
|
876 | 876 | |
|
877 | 877 | &:after { |
|
878 | 878 | content: " "; |
|
879 | 879 | clear: both; |
|
880 | 880 | width: 100%; |
|
881 | 881 | } |
|
882 | 882 | } |
|
883 | 883 | |
|
884 | 884 | .fields .field { |
|
885 | 885 | clear: both; |
|
886 | 886 | } |
|
887 | 887 | } |
|
888 | 888 | |
|
889 | 889 | .advanced_settings { |
|
890 | 890 | margin-bottom: @space; |
|
891 | 891 | |
|
892 | 892 | .help-block { |
|
893 | 893 | margin-left: 0; |
|
894 | 894 | } |
|
895 | 895 | |
|
896 | 896 | button + .help-block { |
|
897 | 897 | margin-top: @padding; |
|
898 | 898 | } |
|
899 | 899 | } |
|
900 | 900 | |
|
901 | 901 | // admin settings radio buttons and labels |
|
902 | 902 | .label-2 { |
|
903 | 903 | float: left; |
|
904 | 904 | width: @label2-width; |
|
905 | 905 | |
|
906 | 906 | label { |
|
907 | 907 | color: @grey1; |
|
908 | 908 | } |
|
909 | 909 | } |
|
910 | 910 | .checkboxes { |
|
911 | 911 | float: left; |
|
912 | 912 | width: @checkboxes-width; |
|
913 | 913 | margin-bottom: @padding; |
|
914 | 914 | |
|
915 | 915 | .checkbox { |
|
916 | 916 | width: 100%; |
|
917 | 917 | |
|
918 | 918 | label { |
|
919 | 919 | margin: 0; |
|
920 | 920 | padding: 0; |
|
921 | 921 | } |
|
922 | 922 | } |
|
923 | 923 | |
|
924 | 924 | .checkbox + .checkbox { |
|
925 | 925 | display: inline-block; |
|
926 | 926 | } |
|
927 | 927 | |
|
928 | 928 | label { |
|
929 | 929 | margin-right: 1em; |
|
930 | 930 | } |
|
931 | 931 | } |
|
932 | 932 | |
|
933 | 933 | // CHANGELOG |
|
934 | 934 | .container_header { |
|
935 | 935 | float: left; |
|
936 | 936 | display: block; |
|
937 | 937 | width: 100%; |
|
938 | 938 | margin: @padding 0 @padding; |
|
939 | 939 | |
|
940 | 940 | #filter_changelog { |
|
941 | 941 | float: left; |
|
942 | 942 | margin-right: @padding; |
|
943 | 943 | } |
|
944 | 944 | |
|
945 | 945 | .breadcrumbs_light { |
|
946 | 946 | display: inline-block; |
|
947 | 947 | } |
|
948 | 948 | } |
|
949 | 949 | |
|
950 | 950 | .info_box { |
|
951 | 951 | float: right; |
|
952 | 952 | } |
|
953 | 953 | |
|
954 | 954 | |
|
955 | 955 | #graph_nodes { |
|
956 | 956 | padding-top: 43px; |
|
957 | 957 | } |
|
958 | 958 | |
|
959 | 959 | #graph_content{ |
|
960 | 960 | |
|
961 | 961 | // adjust for table headers so that graph renders properly |
|
962 | 962 | // #graph_nodes padding - table cell padding |
|
963 | 963 | padding-top: (@space - (@basefontsize * 2.4)); |
|
964 | 964 | |
|
965 | 965 | &.graph_full_width { |
|
966 | 966 | width: 100%; |
|
967 | 967 | max-width: 100%; |
|
968 | 968 | } |
|
969 | 969 | } |
|
970 | 970 | |
|
971 | 971 | #graph { |
|
972 | 972 | .flag_status { |
|
973 | 973 | margin: 0; |
|
974 | 974 | } |
|
975 | 975 | |
|
976 | 976 | .pagination-left { |
|
977 | 977 | float: left; |
|
978 | 978 | clear: both; |
|
979 | 979 | } |
|
980 | 980 | |
|
981 | 981 | .log-container { |
|
982 | 982 | max-width: 345px; |
|
983 | 983 | |
|
984 | 984 | .message{ |
|
985 | 985 | max-width: 340px; |
|
986 | 986 | } |
|
987 | 987 | } |
|
988 | 988 | |
|
989 | 989 | .graph-col-wrapper { |
|
990 | 990 | padding-left: 110px; |
|
991 | 991 | |
|
992 | 992 | #graph_nodes { |
|
993 | 993 | width: 100px; |
|
994 | 994 | margin-left: -110px; |
|
995 | 995 | float: left; |
|
996 | 996 | clear: left; |
|
997 | 997 | } |
|
998 | 998 | } |
|
999 | 999 | |
|
1000 | 1000 | .load-more-commits { |
|
1001 | 1001 | text-align: center; |
|
1002 | 1002 | } |
|
1003 | 1003 | .load-more-commits:hover { |
|
1004 | 1004 | background-color: @grey7; |
|
1005 | 1005 | } |
|
1006 | 1006 | .load-more-commits { |
|
1007 | 1007 | a { |
|
1008 | 1008 | display: block; |
|
1009 | 1009 | } |
|
1010 | 1010 | } |
|
1011 | 1011 | } |
|
1012 | 1012 | |
|
1013 | 1013 | #filter_changelog { |
|
1014 | 1014 | float: left; |
|
1015 | 1015 | } |
|
1016 | 1016 | |
|
1017 | 1017 | |
|
1018 | 1018 | //--- THEME ------------------// |
|
1019 | 1019 | |
|
1020 | 1020 | #logo { |
|
1021 | 1021 | float: left; |
|
1022 | 1022 | margin: 9px 0 0 0; |
|
1023 | 1023 | |
|
1024 | 1024 | .header { |
|
1025 | 1025 | background-color: transparent; |
|
1026 | 1026 | } |
|
1027 | 1027 | |
|
1028 | 1028 | a { |
|
1029 | 1029 | display: inline-block; |
|
1030 | 1030 | } |
|
1031 | 1031 | |
|
1032 | 1032 | img { |
|
1033 | 1033 | height:30px; |
|
1034 | 1034 | } |
|
1035 | 1035 | } |
|
1036 | 1036 | |
|
1037 | 1037 | .logo-wrapper { |
|
1038 | 1038 | float:left; |
|
1039 | 1039 | } |
|
1040 | 1040 | |
|
1041 | 1041 | .branding { |
|
1042 | 1042 | float: left; |
|
1043 | 1043 | padding: 9px 2px; |
|
1044 | 1044 | line-height: 1em; |
|
1045 | 1045 | font-size: @navigation-fontsize; |
|
1046 | 1046 | |
|
1047 | 1047 | a { |
|
1048 | 1048 | color: @grey5 |
|
1049 | 1049 | } |
|
1050 | 1050 | } |
|
1051 | 1051 | |
|
1052 | 1052 | img { |
|
1053 | 1053 | border: none; |
|
1054 | 1054 | outline: none; |
|
1055 | 1055 | } |
|
1056 | 1056 | user-profile-header |
|
1057 | 1057 | label { |
|
1058 | 1058 | |
|
1059 | 1059 | input[type="checkbox"] { |
|
1060 | 1060 | margin-right: 1em; |
|
1061 | 1061 | } |
|
1062 | 1062 | input[type="radio"] { |
|
1063 | 1063 | margin-right: 1em; |
|
1064 | 1064 | } |
|
1065 | 1065 | } |
|
1066 | 1066 | |
|
1067 | 1067 | .flag_status { |
|
1068 | 1068 | margin: 2px; |
|
1069 | 1069 | &.under_review { |
|
1070 | 1070 | .circle(5px, @alert3); |
|
1071 | 1071 | } |
|
1072 | 1072 | &.approved { |
|
1073 | 1073 | .circle(5px, @alert1); |
|
1074 | 1074 | } |
|
1075 | 1075 | &.rejected, |
|
1076 | 1076 | &.forced_closed{ |
|
1077 | 1077 | .circle(5px, @alert2); |
|
1078 | 1078 | } |
|
1079 | 1079 | &.not_reviewed { |
|
1080 | 1080 | .circle(5px, @grey5); |
|
1081 | 1081 | } |
|
1082 | 1082 | } |
|
1083 | 1083 | |
|
1084 | 1084 | .flag_status_comment_box { |
|
1085 | 1085 | margin: 5px 6px 0px 2px; |
|
1086 | 1086 | } |
|
1087 | 1087 | .test_pattern_preview { |
|
1088 | 1088 | margin: @space 0; |
|
1089 | 1089 | |
|
1090 | 1090 | p { |
|
1091 | 1091 | margin-bottom: 0; |
|
1092 | 1092 | border-bottom: @border-thickness solid @border-default-color; |
|
1093 | 1093 | color: @grey3; |
|
1094 | 1094 | } |
|
1095 | 1095 | |
|
1096 | 1096 | .btn { |
|
1097 | 1097 | margin-bottom: @padding; |
|
1098 | 1098 | } |
|
1099 | 1099 | } |
|
1100 | 1100 | #test_pattern_result { |
|
1101 | 1101 | display: none; |
|
1102 | 1102 | &:extend(pre); |
|
1103 | 1103 | padding: .9em; |
|
1104 | 1104 | color: @grey3; |
|
1105 | 1105 | background-color: @grey7; |
|
1106 | 1106 | border-right: @border-thickness solid @border-default-color; |
|
1107 | 1107 | border-bottom: @border-thickness solid @border-default-color; |
|
1108 | 1108 | border-left: @border-thickness solid @border-default-color; |
|
1109 | 1109 | } |
|
1110 | 1110 | |
|
1111 | 1111 | #repo_vcs_settings { |
|
1112 | 1112 | #inherit_overlay_vcs_default { |
|
1113 | 1113 | display: none; |
|
1114 | 1114 | } |
|
1115 | 1115 | #inherit_overlay_vcs_custom { |
|
1116 | 1116 | display: custom; |
|
1117 | 1117 | } |
|
1118 | 1118 | &.inherited { |
|
1119 | 1119 | #inherit_overlay_vcs_default { |
|
1120 | 1120 | display: block; |
|
1121 | 1121 | } |
|
1122 | 1122 | #inherit_overlay_vcs_custom { |
|
1123 | 1123 | display: none; |
|
1124 | 1124 | } |
|
1125 | 1125 | } |
|
1126 | 1126 | } |
|
1127 | 1127 | |
|
1128 | 1128 | .issue-tracker-link { |
|
1129 | 1129 | color: @rcblue; |
|
1130 | 1130 | } |
|
1131 | 1131 | |
|
1132 | 1132 | // Issue Tracker Table Show/Hide |
|
1133 | 1133 | #repo_issue_tracker { |
|
1134 | 1134 | #inherit_overlay { |
|
1135 | 1135 | display: none; |
|
1136 | 1136 | } |
|
1137 | 1137 | #custom_overlay { |
|
1138 | 1138 | display: custom; |
|
1139 | 1139 | } |
|
1140 | 1140 | &.inherited { |
|
1141 | 1141 | #inherit_overlay { |
|
1142 | 1142 | display: block; |
|
1143 | 1143 | } |
|
1144 | 1144 | #custom_overlay { |
|
1145 | 1145 | display: none; |
|
1146 | 1146 | } |
|
1147 | 1147 | } |
|
1148 | 1148 | } |
|
1149 | 1149 | table.issuetracker { |
|
1150 | 1150 | &.readonly { |
|
1151 | 1151 | tr, td { |
|
1152 | 1152 | color: @grey3; |
|
1153 | 1153 | } |
|
1154 | 1154 | } |
|
1155 | 1155 | .edit { |
|
1156 | 1156 | display: none; |
|
1157 | 1157 | } |
|
1158 | 1158 | .editopen { |
|
1159 | 1159 | .edit { |
|
1160 | 1160 | display: inline; |
|
1161 | 1161 | } |
|
1162 | 1162 | .entry { |
|
1163 | 1163 | display: none; |
|
1164 | 1164 | } |
|
1165 | 1165 | } |
|
1166 | 1166 | tr td.td-action { |
|
1167 | 1167 | min-width: 117px; |
|
1168 | 1168 | } |
|
1169 | 1169 | td input { |
|
1170 | 1170 | max-width: none; |
|
1171 | 1171 | min-width: 30px; |
|
1172 | 1172 | width: 80%; |
|
1173 | 1173 | } |
|
1174 | 1174 | .issuetracker_pref input { |
|
1175 | 1175 | width: 40%; |
|
1176 | 1176 | } |
|
1177 | 1177 | input.edit_issuetracker_update { |
|
1178 | 1178 | margin-right: 0; |
|
1179 | 1179 | width: auto; |
|
1180 | 1180 | } |
|
1181 | 1181 | } |
|
1182 | 1182 | |
|
1183 | 1183 | table.integrations { |
|
1184 | 1184 | .td-icon { |
|
1185 | 1185 | width: 20px; |
|
1186 | 1186 | .integration-icon { |
|
1187 | 1187 | height: 20px; |
|
1188 | 1188 | width: 20px; |
|
1189 | 1189 | } |
|
1190 | 1190 | } |
|
1191 | 1191 | } |
|
1192 | 1192 | |
|
1193 | 1193 | .integrations { |
|
1194 | 1194 | a.integration-box { |
|
1195 | 1195 | color: @text-color; |
|
1196 | 1196 | &:hover { |
|
1197 | 1197 | .panel { |
|
1198 | 1198 | background: #fbfbfb; |
|
1199 | 1199 | } |
|
1200 | 1200 | } |
|
1201 | 1201 | .integration-icon { |
|
1202 | 1202 | width: 30px; |
|
1203 | 1203 | height: 30px; |
|
1204 | 1204 | margin-right: 20px; |
|
1205 | 1205 | float: left; |
|
1206 | 1206 | } |
|
1207 | 1207 | |
|
1208 | 1208 | .panel-body { |
|
1209 | 1209 | padding: 10px; |
|
1210 | 1210 | } |
|
1211 | 1211 | .panel { |
|
1212 | 1212 | margin-bottom: 10px; |
|
1213 | 1213 | } |
|
1214 | 1214 | h2 { |
|
1215 | 1215 | display: inline-block; |
|
1216 | 1216 | margin: 0; |
|
1217 | 1217 | min-width: 140px; |
|
1218 | 1218 | } |
|
1219 | 1219 | } |
|
1220 | 1220 | a.integration-box.dummy-integration { |
|
1221 | 1221 | color: @grey4 |
|
1222 | 1222 | } |
|
1223 | 1223 | } |
|
1224 | 1224 | |
|
1225 | 1225 | //Permissions Settings |
|
1226 | 1226 | #add_perm { |
|
1227 | 1227 | margin: 0 0 @padding; |
|
1228 | 1228 | cursor: pointer; |
|
1229 | 1229 | } |
|
1230 | 1230 | |
|
1231 | 1231 | .perm_ac { |
|
1232 | 1232 | input { |
|
1233 | 1233 | width: 95%; |
|
1234 | 1234 | } |
|
1235 | 1235 | } |
|
1236 | 1236 | |
|
1237 | 1237 | .autocomplete-suggestions { |
|
1238 | 1238 | width: auto !important; // overrides autocomplete.js |
|
1239 | 1239 | min-width: 278px; |
|
1240 | 1240 | margin: 0; |
|
1241 | 1241 | border: @border-thickness solid @grey5; |
|
1242 | 1242 | border-radius: @border-radius; |
|
1243 | 1243 | color: @grey2; |
|
1244 | 1244 | background-color: white; |
|
1245 | 1245 | } |
|
1246 | 1246 | |
|
1247 | 1247 | .autocomplete-selected { |
|
1248 | 1248 | background: #F0F0F0; |
|
1249 | 1249 | } |
|
1250 | 1250 | |
|
1251 | 1251 | .ac-container-wrap { |
|
1252 | 1252 | margin: 0; |
|
1253 | 1253 | padding: 8px; |
|
1254 | 1254 | border-bottom: @border-thickness solid @grey5; |
|
1255 | 1255 | list-style-type: none; |
|
1256 | 1256 | cursor: pointer; |
|
1257 | 1257 | |
|
1258 | 1258 | &:hover { |
|
1259 | 1259 | background-color: @grey7; |
|
1260 | 1260 | } |
|
1261 | 1261 | |
|
1262 | 1262 | img { |
|
1263 | 1263 | height: @gravatar-size; |
|
1264 | 1264 | width: @gravatar-size; |
|
1265 | 1265 | margin-right: 1em; |
|
1266 | 1266 | } |
|
1267 | 1267 | |
|
1268 | 1268 | strong { |
|
1269 | 1269 | font-weight: normal; |
|
1270 | 1270 | } |
|
1271 | 1271 | } |
|
1272 | 1272 | |
|
1273 | 1273 | // Settings Dropdown |
|
1274 | 1274 | .user-menu .container { |
|
1275 | 1275 | padding: 0 4px; |
|
1276 | 1276 | margin: 0; |
|
1277 | 1277 | } |
|
1278 | 1278 | |
|
1279 | 1279 | .user-menu .gravatar { |
|
1280 | 1280 | cursor: pointer; |
|
1281 | 1281 | } |
|
1282 | 1282 | |
|
1283 | 1283 | .codeblock { |
|
1284 | 1284 | margin-bottom: @padding; |
|
1285 | 1285 | clear: both; |
|
1286 | 1286 | |
|
1287 | 1287 | .stats { |
|
1288 | 1288 | overflow: hidden; |
|
1289 | 1289 | } |
|
1290 | 1290 | |
|
1291 | 1291 | .message{ |
|
1292 | 1292 | textarea{ |
|
1293 | 1293 | margin: 0; |
|
1294 | 1294 | } |
|
1295 | 1295 | } |
|
1296 | 1296 | |
|
1297 | 1297 | .code-header { |
|
1298 | 1298 | .stats { |
|
1299 | 1299 | line-height: 2em; |
|
1300 | 1300 | |
|
1301 | 1301 | .revision_id { |
|
1302 | 1302 | margin-left: 0; |
|
1303 | 1303 | } |
|
1304 | 1304 | .buttons { |
|
1305 | 1305 | padding-right: 0; |
|
1306 | 1306 | } |
|
1307 | 1307 | } |
|
1308 | 1308 | |
|
1309 | 1309 | .item{ |
|
1310 | 1310 | margin-right: 0.5em; |
|
1311 | 1311 | } |
|
1312 | 1312 | } |
|
1313 | 1313 | |
|
1314 | 1314 | #editor_container{ |
|
1315 | 1315 | position: relative; |
|
1316 | 1316 | margin: @padding; |
|
1317 | 1317 | } |
|
1318 | 1318 | } |
|
1319 | 1319 | |
|
1320 | 1320 | #file_history_container { |
|
1321 | 1321 | display: none; |
|
1322 | 1322 | } |
|
1323 | 1323 | |
|
1324 | 1324 | .file-history-inner { |
|
1325 | 1325 | margin-bottom: 10px; |
|
1326 | 1326 | } |
|
1327 | 1327 | |
|
1328 | 1328 | // Pull Requests |
|
1329 | 1329 | .summary-details { |
|
1330 | 1330 | width: 72%; |
|
1331 | 1331 | } |
|
1332 | 1332 | .pr-summary { |
|
1333 | 1333 | border-bottom: @border-thickness solid @grey5; |
|
1334 | 1334 | margin-bottom: @space; |
|
1335 | 1335 | } |
|
1336 | 1336 | .reviewers-title { |
|
1337 | 1337 | width: 25%; |
|
1338 | 1338 | min-width: 200px; |
|
1339 | 1339 | } |
|
1340 | 1340 | .reviewers { |
|
1341 | 1341 | width: 25%; |
|
1342 | 1342 | min-width: 200px; |
|
1343 | 1343 | } |
|
1344 | 1344 | .reviewers ul li { |
|
1345 | 1345 | position: relative; |
|
1346 | 1346 | width: 100%; |
|
1347 | 1347 | padding-bottom: 8px; |
|
1348 | 1348 | list-style-type: none; |
|
1349 | 1349 | } |
|
1350 | 1350 | |
|
1351 | 1351 | .reviewer_entry { |
|
1352 | 1352 | min-height: 55px; |
|
1353 | 1353 | } |
|
1354 | 1354 | |
|
1355 | 1355 | .reviewers_member { |
|
1356 | 1356 | width: 100%; |
|
1357 | 1357 | overflow: auto; |
|
1358 | 1358 | } |
|
1359 | 1359 | .reviewer_reason { |
|
1360 | 1360 | padding-left: 20px; |
|
1361 | 1361 | line-height: 1.5em; |
|
1362 | 1362 | } |
|
1363 | 1363 | .reviewer_status { |
|
1364 | 1364 | display: inline-block; |
|
1365 | 1365 | vertical-align: top; |
|
1366 | 1366 | width: 25px; |
|
1367 | 1367 | min-width: 25px; |
|
1368 | 1368 | height: 1.2em; |
|
1369 | 1369 | margin-top: 3px; |
|
1370 | 1370 | line-height: 1em; |
|
1371 | 1371 | } |
|
1372 | 1372 | |
|
1373 | 1373 | .reviewer_name { |
|
1374 | 1374 | display: inline-block; |
|
1375 | 1375 | max-width: 83%; |
|
1376 | 1376 | padding-right: 20px; |
|
1377 | 1377 | vertical-align: middle; |
|
1378 | 1378 | line-height: 1; |
|
1379 | 1379 | |
|
1380 | 1380 | .rc-user { |
|
1381 | 1381 | min-width: 0; |
|
1382 | 1382 | margin: -2px 1em 0 0; |
|
1383 | 1383 | } |
|
1384 | 1384 | |
|
1385 | 1385 | .reviewer { |
|
1386 | 1386 | float: left; |
|
1387 | 1387 | } |
|
1388 | 1388 | } |
|
1389 | 1389 | |
|
1390 | 1390 | .reviewer_member_mandatory { |
|
1391 | 1391 | position: absolute; |
|
1392 | 1392 | left: 15px; |
|
1393 | 1393 | top: 8px; |
|
1394 | 1394 | width: 16px; |
|
1395 | 1395 | font-size: 11px; |
|
1396 | 1396 | margin: 0; |
|
1397 | 1397 | padding: 0; |
|
1398 | 1398 | color: black; |
|
1399 | 1399 | } |
|
1400 | 1400 | |
|
1401 | 1401 | .reviewer_member_mandatory_remove, |
|
1402 | 1402 | .reviewer_member_remove { |
|
1403 | 1403 | position: absolute; |
|
1404 | 1404 | right: 0; |
|
1405 | 1405 | top: 0; |
|
1406 | 1406 | width: 16px; |
|
1407 | 1407 | margin-bottom: 10px; |
|
1408 | 1408 | padding: 0; |
|
1409 | 1409 | color: black; |
|
1410 | 1410 | } |
|
1411 | 1411 | |
|
1412 | 1412 | .reviewer_member_mandatory_remove { |
|
1413 | 1413 | color: @grey4; |
|
1414 | 1414 | } |
|
1415 | 1415 | |
|
1416 | 1416 | .reviewer_member_status { |
|
1417 | 1417 | margin-top: 5px; |
|
1418 | 1418 | } |
|
1419 | 1419 | .pr-summary #summary{ |
|
1420 | 1420 | width: 100%; |
|
1421 | 1421 | } |
|
1422 | 1422 | .pr-summary .action_button:hover { |
|
1423 | 1423 | border: 0; |
|
1424 | 1424 | cursor: pointer; |
|
1425 | 1425 | } |
|
1426 | 1426 | .pr-details-title { |
|
1427 | 1427 | padding-bottom: 8px; |
|
1428 | 1428 | border-bottom: @border-thickness solid @grey5; |
|
1429 | 1429 | |
|
1430 | 1430 | .action_button.disabled { |
|
1431 | 1431 | color: @grey4; |
|
1432 | 1432 | cursor: inherit; |
|
1433 | 1433 | } |
|
1434 | 1434 | .action_button { |
|
1435 | 1435 | color: @rcblue; |
|
1436 | 1436 | } |
|
1437 | 1437 | } |
|
1438 | 1438 | .pr-details-content { |
|
1439 | 1439 | margin-top: @textmargin; |
|
1440 | 1440 | margin-bottom: @textmargin; |
|
1441 | 1441 | } |
|
1442 | 1442 | |
|
1443 | 1443 | .pr-reviewer-rules { |
|
1444 | 1444 | padding: 10px 0px 20px 0px; |
|
1445 | 1445 | } |
|
1446 | 1446 | |
|
1447 | 1447 | .group_members { |
|
1448 | 1448 | margin-top: 0; |
|
1449 | 1449 | padding: 0; |
|
1450 | 1450 | list-style: outside none none; |
|
1451 | 1451 | |
|
1452 | 1452 | img { |
|
1453 | 1453 | height: @gravatar-size; |
|
1454 | 1454 | width: @gravatar-size; |
|
1455 | 1455 | margin-right: .5em; |
|
1456 | 1456 | margin-left: 3px; |
|
1457 | 1457 | } |
|
1458 | 1458 | |
|
1459 | 1459 | .to-delete { |
|
1460 | 1460 | .user { |
|
1461 | 1461 | text-decoration: line-through; |
|
1462 | 1462 | } |
|
1463 | 1463 | } |
|
1464 | 1464 | } |
|
1465 | 1465 | |
|
1466 | 1466 | .compare_view_commits_title { |
|
1467 | 1467 | .disabled { |
|
1468 | 1468 | cursor: inherit; |
|
1469 | 1469 | &:hover{ |
|
1470 | 1470 | background-color: inherit; |
|
1471 | 1471 | color: inherit; |
|
1472 | 1472 | } |
|
1473 | 1473 | } |
|
1474 | 1474 | } |
|
1475 | 1475 | |
|
1476 | 1476 | .subtitle-compare { |
|
1477 | 1477 | margin: -15px 0px 0px 0px; |
|
1478 | 1478 | } |
|
1479 | 1479 | |
|
1480 | 1480 | .comments-summary-td { |
|
1481 | 1481 | border-top: 1px dashed @grey5; |
|
1482 | 1482 | } |
|
1483 | 1483 | |
|
1484 | 1484 | // new entry in group_members |
|
1485 | 1485 | .td-author-new-entry { |
|
1486 | 1486 | background-color: rgba(red(@alert1), green(@alert1), blue(@alert1), 0.3); |
|
1487 | 1487 | } |
|
1488 | 1488 | |
|
1489 | 1489 | .usergroup_member_remove { |
|
1490 | 1490 | width: 16px; |
|
1491 | 1491 | margin-bottom: 10px; |
|
1492 | 1492 | padding: 0; |
|
1493 | 1493 | color: black !important; |
|
1494 | 1494 | cursor: pointer; |
|
1495 | 1495 | } |
|
1496 | 1496 | |
|
1497 | 1497 | .reviewer_ac .ac-input { |
|
1498 | 1498 | width: 92%; |
|
1499 | 1499 | margin-bottom: 1em; |
|
1500 | 1500 | } |
|
1501 | 1501 | |
|
1502 | 1502 | .compare_view_commits tr{ |
|
1503 | 1503 | height: 20px; |
|
1504 | 1504 | } |
|
1505 | 1505 | .compare_view_commits td { |
|
1506 | 1506 | vertical-align: top; |
|
1507 | 1507 | padding-top: 10px; |
|
1508 | 1508 | } |
|
1509 | 1509 | .compare_view_commits .author { |
|
1510 | 1510 | margin-left: 5px; |
|
1511 | 1511 | } |
|
1512 | 1512 | |
|
1513 | 1513 | .compare_view_commits { |
|
1514 | 1514 | .color-a { |
|
1515 | 1515 | color: @alert1; |
|
1516 | 1516 | } |
|
1517 | 1517 | |
|
1518 | 1518 | .color-c { |
|
1519 | 1519 | color: @color3; |
|
1520 | 1520 | } |
|
1521 | 1521 | |
|
1522 | 1522 | .color-r { |
|
1523 | 1523 | color: @color5; |
|
1524 | 1524 | } |
|
1525 | 1525 | |
|
1526 | 1526 | .color-a-bg { |
|
1527 | 1527 | background-color: @alert1; |
|
1528 | 1528 | } |
|
1529 | 1529 | |
|
1530 | 1530 | .color-c-bg { |
|
1531 | 1531 | background-color: @alert3; |
|
1532 | 1532 | } |
|
1533 | 1533 | |
|
1534 | 1534 | .color-r-bg { |
|
1535 | 1535 | background-color: @alert2; |
|
1536 | 1536 | } |
|
1537 | 1537 | |
|
1538 | 1538 | .color-a-border { |
|
1539 | 1539 | border: 1px solid @alert1; |
|
1540 | 1540 | } |
|
1541 | 1541 | |
|
1542 | 1542 | .color-c-border { |
|
1543 | 1543 | border: 1px solid @alert3; |
|
1544 | 1544 | } |
|
1545 | 1545 | |
|
1546 | 1546 | .color-r-border { |
|
1547 | 1547 | border: 1px solid @alert2; |
|
1548 | 1548 | } |
|
1549 | 1549 | |
|
1550 | 1550 | .commit-change-indicator { |
|
1551 | 1551 | width: 15px; |
|
1552 | 1552 | height: 15px; |
|
1553 | 1553 | position: relative; |
|
1554 | 1554 | left: 15px; |
|
1555 | 1555 | } |
|
1556 | 1556 | |
|
1557 | 1557 | .commit-change-content { |
|
1558 | 1558 | text-align: center; |
|
1559 | 1559 | vertical-align: middle; |
|
1560 | 1560 | line-height: 15px; |
|
1561 | 1561 | } |
|
1562 | 1562 | } |
|
1563 | 1563 | |
|
1564 | 1564 | .compare_view_filepath { |
|
1565 | 1565 | color: @grey1; |
|
1566 | 1566 | } |
|
1567 | 1567 | |
|
1568 | 1568 | .show_more { |
|
1569 | 1569 | display: inline-block; |
|
1570 | 1570 | width: 0; |
|
1571 | 1571 | height: 0; |
|
1572 | 1572 | vertical-align: middle; |
|
1573 | 1573 | content: ""; |
|
1574 | 1574 | border: 4px solid; |
|
1575 | 1575 | border-right-color: transparent; |
|
1576 | 1576 | border-bottom-color: transparent; |
|
1577 | 1577 | border-left-color: transparent; |
|
1578 | 1578 | font-size: 0; |
|
1579 | 1579 | } |
|
1580 | 1580 | |
|
1581 | 1581 | .journal_more .show_more { |
|
1582 | 1582 | display: inline; |
|
1583 | 1583 | |
|
1584 | 1584 | &:after { |
|
1585 | 1585 | content: none; |
|
1586 | 1586 | } |
|
1587 | 1587 | } |
|
1588 | 1588 | |
|
1589 | 1589 | .compare_view_commits .collapse_commit:after { |
|
1590 | 1590 | cursor: pointer; |
|
1591 | 1591 | content: "\00A0\25B4"; |
|
1592 | 1592 | margin-left: -3px; |
|
1593 | 1593 | font-size: 17px; |
|
1594 | 1594 | color: @grey4; |
|
1595 | 1595 | } |
|
1596 | 1596 | |
|
1597 | 1597 | .diff_links { |
|
1598 | 1598 | margin-left: 8px; |
|
1599 | 1599 | } |
|
1600 | 1600 | |
|
1601 | 1601 | div.ancestor { |
|
1602 | 1602 | margin: -30px 0px; |
|
1603 | 1603 | } |
|
1604 | 1604 | |
|
1605 | 1605 | .cs_icon_td input[type="checkbox"] { |
|
1606 | 1606 | display: none; |
|
1607 | 1607 | } |
|
1608 | 1608 | |
|
1609 | 1609 | .cs_icon_td .expand_file_icon:after { |
|
1610 | 1610 | cursor: pointer; |
|
1611 | 1611 | content: "\00A0\25B6"; |
|
1612 | 1612 | font-size: 12px; |
|
1613 | 1613 | color: @grey4; |
|
1614 | 1614 | } |
|
1615 | 1615 | |
|
1616 | 1616 | .cs_icon_td .collapse_file_icon:after { |
|
1617 | 1617 | cursor: pointer; |
|
1618 | 1618 | content: "\00A0\25BC"; |
|
1619 | 1619 | font-size: 12px; |
|
1620 | 1620 | color: @grey4; |
|
1621 | 1621 | } |
|
1622 | 1622 | |
|
1623 | 1623 | /*new binary |
|
1624 | 1624 | NEW_FILENODE = 1 |
|
1625 | 1625 | DEL_FILENODE = 2 |
|
1626 | 1626 | MOD_FILENODE = 3 |
|
1627 | 1627 | RENAMED_FILENODE = 4 |
|
1628 | 1628 | COPIED_FILENODE = 5 |
|
1629 | 1629 | CHMOD_FILENODE = 6 |
|
1630 | 1630 | BIN_FILENODE = 7 |
|
1631 | 1631 | */ |
|
1632 | 1632 | .cs_files_expand { |
|
1633 | 1633 | font-size: @basefontsize + 5px; |
|
1634 | 1634 | line-height: 1.8em; |
|
1635 | 1635 | float: right; |
|
1636 | 1636 | } |
|
1637 | 1637 | |
|
1638 | 1638 | .cs_files_expand span{ |
|
1639 | 1639 | color: @rcblue; |
|
1640 | 1640 | cursor: pointer; |
|
1641 | 1641 | } |
|
1642 | 1642 | .cs_files { |
|
1643 | 1643 | clear: both; |
|
1644 | 1644 | padding-bottom: @padding; |
|
1645 | 1645 | |
|
1646 | 1646 | .cur_cs { |
|
1647 | 1647 | margin: 10px 2px; |
|
1648 | 1648 | font-weight: bold; |
|
1649 | 1649 | } |
|
1650 | 1650 | |
|
1651 | 1651 | .node { |
|
1652 | 1652 | float: left; |
|
1653 | 1653 | } |
|
1654 | 1654 | |
|
1655 | 1655 | .changes { |
|
1656 | 1656 | float: right; |
|
1657 | 1657 | color: white; |
|
1658 | 1658 | font-size: @basefontsize - 4px; |
|
1659 | 1659 | margin-top: 4px; |
|
1660 | 1660 | opacity: 0.6; |
|
1661 | 1661 | filter: Alpha(opacity=60); /* IE8 and earlier */ |
|
1662 | 1662 | |
|
1663 | 1663 | .added { |
|
1664 | 1664 | background-color: @alert1; |
|
1665 | 1665 | float: left; |
|
1666 | 1666 | text-align: center; |
|
1667 | 1667 | } |
|
1668 | 1668 | |
|
1669 | 1669 | .deleted { |
|
1670 | 1670 | background-color: @alert2; |
|
1671 | 1671 | float: left; |
|
1672 | 1672 | text-align: center; |
|
1673 | 1673 | } |
|
1674 | 1674 | |
|
1675 | 1675 | .bin { |
|
1676 | 1676 | background-color: @alert1; |
|
1677 | 1677 | text-align: center; |
|
1678 | 1678 | } |
|
1679 | 1679 | |
|
1680 | 1680 | /*new binary*/ |
|
1681 | 1681 | .bin.bin1 { |
|
1682 | 1682 | background-color: @alert1; |
|
1683 | 1683 | text-align: center; |
|
1684 | 1684 | } |
|
1685 | 1685 | |
|
1686 | 1686 | /*deleted binary*/ |
|
1687 | 1687 | .bin.bin2 { |
|
1688 | 1688 | background-color: @alert2; |
|
1689 | 1689 | text-align: center; |
|
1690 | 1690 | } |
|
1691 | 1691 | |
|
1692 | 1692 | /*mod binary*/ |
|
1693 | 1693 | .bin.bin3 { |
|
1694 | 1694 | background-color: @grey2; |
|
1695 | 1695 | text-align: center; |
|
1696 | 1696 | } |
|
1697 | 1697 | |
|
1698 | 1698 | /*rename file*/ |
|
1699 | 1699 | .bin.bin4 { |
|
1700 | 1700 | background-color: @alert4; |
|
1701 | 1701 | text-align: center; |
|
1702 | 1702 | } |
|
1703 | 1703 | |
|
1704 | 1704 | /*copied file*/ |
|
1705 | 1705 | .bin.bin5 { |
|
1706 | 1706 | background-color: @alert4; |
|
1707 | 1707 | text-align: center; |
|
1708 | 1708 | } |
|
1709 | 1709 | |
|
1710 | 1710 | /*chmod file*/ |
|
1711 | 1711 | .bin.bin6 { |
|
1712 | 1712 | background-color: @grey2; |
|
1713 | 1713 | text-align: center; |
|
1714 | 1714 | } |
|
1715 | 1715 | } |
|
1716 | 1716 | } |
|
1717 | 1717 | |
|
1718 | 1718 | .cs_files .cs_added, .cs_files .cs_A, |
|
1719 | 1719 | .cs_files .cs_added, .cs_files .cs_M, |
|
1720 | 1720 | .cs_files .cs_added, .cs_files .cs_D { |
|
1721 | 1721 | height: 16px; |
|
1722 | 1722 | padding-right: 10px; |
|
1723 | 1723 | margin-top: 7px; |
|
1724 | 1724 | text-align: left; |
|
1725 | 1725 | } |
|
1726 | 1726 | |
|
1727 | 1727 | .cs_icon_td { |
|
1728 | 1728 | min-width: 16px; |
|
1729 | 1729 | width: 16px; |
|
1730 | 1730 | } |
|
1731 | 1731 | |
|
1732 | 1732 | .pull-request-merge { |
|
1733 | 1733 | border: 1px solid @grey5; |
|
1734 | 1734 | padding: 10px 0px 20px; |
|
1735 | 1735 | margin-top: 10px; |
|
1736 | 1736 | margin-bottom: 20px; |
|
1737 | 1737 | } |
|
1738 | 1738 | |
|
1739 | 1739 | .pull-request-merge ul { |
|
1740 | 1740 | padding: 0px 0px; |
|
1741 | 1741 | } |
|
1742 | 1742 | |
|
1743 | 1743 | .pull-request-merge li { |
|
1744 | 1744 | list-style-type: none; |
|
1745 | 1745 | } |
|
1746 | 1746 | |
|
1747 | 1747 | .pull-request-merge .pull-request-wrap { |
|
1748 | 1748 | height: auto; |
|
1749 | 1749 | padding: 0px 0px; |
|
1750 | 1750 | text-align: right; |
|
1751 | 1751 | } |
|
1752 | 1752 | |
|
1753 | 1753 | .pull-request-merge span { |
|
1754 | 1754 | margin-right: 5px; |
|
1755 | 1755 | } |
|
1756 | 1756 | |
|
1757 | 1757 | .pull-request-merge-actions { |
|
1758 | 1758 | min-height: 30px; |
|
1759 | 1759 | padding: 0px 0px; |
|
1760 | 1760 | } |
|
1761 | 1761 | |
|
1762 | 1762 | .pull-request-merge-info { |
|
1763 | 1763 | padding: 0px 5px 5px 0px; |
|
1764 | 1764 | } |
|
1765 | 1765 | |
|
1766 | 1766 | .merge-status { |
|
1767 | 1767 | margin-right: 5px; |
|
1768 | 1768 | } |
|
1769 | 1769 | |
|
1770 | 1770 | .merge-message { |
|
1771 | 1771 | font-size: 1.2em |
|
1772 | 1772 | } |
|
1773 | 1773 | |
|
1774 | 1774 | .merge-message.success i, |
|
1775 | 1775 | .merge-icon.success i { |
|
1776 | 1776 | color:@alert1; |
|
1777 | 1777 | } |
|
1778 | 1778 | |
|
1779 | 1779 | .merge-message.warning i, |
|
1780 | 1780 | .merge-icon.warning i { |
|
1781 | 1781 | color: @alert3; |
|
1782 | 1782 | } |
|
1783 | 1783 | |
|
1784 | 1784 | .merge-message.error i, |
|
1785 | 1785 | .merge-icon.error i { |
|
1786 | 1786 | color:@alert2; |
|
1787 | 1787 | } |
|
1788 | 1788 | |
|
1789 | 1789 | .pr-versions { |
|
1790 | 1790 | font-size: 1.1em; |
|
1791 | 1791 | |
|
1792 | 1792 | table { |
|
1793 | 1793 | padding: 0px 5px; |
|
1794 | 1794 | } |
|
1795 | 1795 | |
|
1796 | 1796 | td { |
|
1797 | 1797 | line-height: 15px; |
|
1798 | 1798 | } |
|
1799 | 1799 | |
|
1800 | 1800 | .flag_status { |
|
1801 | 1801 | margin: 0; |
|
1802 | 1802 | } |
|
1803 | 1803 | |
|
1804 | 1804 | .compare-radio-button { |
|
1805 | 1805 | position: relative; |
|
1806 | 1806 | top: -3px; |
|
1807 | 1807 | } |
|
1808 | 1808 | } |
|
1809 | 1809 | |
|
1810 | 1810 | |
|
1811 | 1811 | #close_pull_request { |
|
1812 | 1812 | margin-right: 0px; |
|
1813 | 1813 | } |
|
1814 | 1814 | |
|
1815 | 1815 | .empty_data { |
|
1816 | 1816 | color: @grey4; |
|
1817 | 1817 | } |
|
1818 | 1818 | |
|
1819 | 1819 | #changeset_compare_view_content { |
|
1820 | 1820 | clear: both; |
|
1821 | 1821 | width: 100%; |
|
1822 | 1822 | box-sizing: border-box; |
|
1823 | 1823 | .border-radius(@border-radius); |
|
1824 | 1824 | |
|
1825 | 1825 | .help-block { |
|
1826 | 1826 | margin: @padding 0; |
|
1827 | 1827 | color: @text-color; |
|
1828 | 1828 | &.pre-formatting { |
|
1829 | 1829 | white-space: pre; |
|
1830 | 1830 | } |
|
1831 | 1831 | } |
|
1832 | 1832 | |
|
1833 | 1833 | .empty_data { |
|
1834 | 1834 | margin: @padding 0; |
|
1835 | 1835 | } |
|
1836 | 1836 | |
|
1837 | 1837 | .alert { |
|
1838 | 1838 | margin-bottom: @space; |
|
1839 | 1839 | } |
|
1840 | 1840 | } |
|
1841 | 1841 | |
|
1842 | 1842 | .table_disp { |
|
1843 | 1843 | .status { |
|
1844 | 1844 | width: auto; |
|
1845 | 1845 | |
|
1846 | 1846 | .flag_status { |
|
1847 | 1847 | float: left; |
|
1848 | 1848 | } |
|
1849 | 1849 | } |
|
1850 | 1850 | } |
|
1851 | 1851 | |
|
1852 | 1852 | |
|
1853 | 1853 | .creation_in_progress { |
|
1854 | 1854 | color: @grey4 |
|
1855 | 1855 | } |
|
1856 | 1856 | |
|
1857 | 1857 | .status_box_menu { |
|
1858 | 1858 | margin: 0; |
|
1859 | 1859 | } |
|
1860 | 1860 | |
|
1861 | 1861 | .notification-table{ |
|
1862 | 1862 | margin-bottom: @space; |
|
1863 | 1863 | display: table; |
|
1864 | 1864 | width: 100%; |
|
1865 | 1865 | |
|
1866 | 1866 | .container{ |
|
1867 | 1867 | display: table-row; |
|
1868 | 1868 | |
|
1869 | 1869 | .notification-header{ |
|
1870 | 1870 | border-bottom: @border-thickness solid @border-default-color; |
|
1871 | 1871 | } |
|
1872 | 1872 | |
|
1873 | 1873 | .notification-subject{ |
|
1874 | 1874 | display: table-cell; |
|
1875 | 1875 | } |
|
1876 | 1876 | } |
|
1877 | 1877 | } |
|
1878 | 1878 | |
|
1879 | 1879 | // Notifications |
|
1880 | 1880 | .notification-header{ |
|
1881 | 1881 | display: table; |
|
1882 | 1882 | width: 100%; |
|
1883 | 1883 | padding: floor(@basefontsize/2) 0; |
|
1884 | 1884 | line-height: 1em; |
|
1885 | 1885 | |
|
1886 | 1886 | .desc, .delete-notifications, .read-notifications{ |
|
1887 | 1887 | display: table-cell; |
|
1888 | 1888 | text-align: left; |
|
1889 | 1889 | } |
|
1890 | 1890 | |
|
1891 | 1891 | .desc{ |
|
1892 | 1892 | width: 1163px; |
|
1893 | 1893 | } |
|
1894 | 1894 | |
|
1895 | 1895 | .delete-notifications, .read-notifications{ |
|
1896 | 1896 | width: 35px; |
|
1897 | 1897 | min-width: 35px; //fixes when only one button is displayed |
|
1898 | 1898 | } |
|
1899 | 1899 | } |
|
1900 | 1900 | |
|
1901 | 1901 | .notification-body { |
|
1902 | 1902 | .markdown-block, |
|
1903 | 1903 | .rst-block { |
|
1904 | 1904 | padding: @padding 0; |
|
1905 | 1905 | } |
|
1906 | 1906 | |
|
1907 | 1907 | .notification-subject { |
|
1908 | 1908 | padding: @textmargin 0; |
|
1909 | 1909 | border-bottom: @border-thickness solid @border-default-color; |
|
1910 | 1910 | } |
|
1911 | 1911 | } |
|
1912 | 1912 | |
|
1913 | 1913 | |
|
1914 | 1914 | .notifications_buttons{ |
|
1915 | 1915 | float: right; |
|
1916 | 1916 | } |
|
1917 | 1917 | |
|
1918 | 1918 | #notification-status{ |
|
1919 | 1919 | display: inline; |
|
1920 | 1920 | } |
|
1921 | 1921 | |
|
1922 | 1922 | // Repositories |
|
1923 | 1923 | |
|
1924 | 1924 | #summary.fields{ |
|
1925 | 1925 | display: table; |
|
1926 | 1926 | |
|
1927 | 1927 | .field{ |
|
1928 | 1928 | display: table-row; |
|
1929 | 1929 | |
|
1930 | 1930 | .label-summary{ |
|
1931 | 1931 | display: table-cell; |
|
1932 | 1932 | min-width: @label-summary-minwidth; |
|
1933 | 1933 | padding-top: @padding/2; |
|
1934 | 1934 | padding-bottom: @padding/2; |
|
1935 | 1935 | padding-right: @padding/2; |
|
1936 | 1936 | } |
|
1937 | 1937 | |
|
1938 | 1938 | .input{ |
|
1939 | 1939 | display: table-cell; |
|
1940 | 1940 | padding: @padding/2; |
|
1941 | 1941 | |
|
1942 | 1942 | input{ |
|
1943 | 1943 | min-width: 29em; |
|
1944 | 1944 | padding: @padding/4; |
|
1945 | 1945 | } |
|
1946 | 1946 | } |
|
1947 | 1947 | .statistics, .downloads{ |
|
1948 | 1948 | .disabled{ |
|
1949 | 1949 | color: @grey4; |
|
1950 | 1950 | } |
|
1951 | 1951 | } |
|
1952 | 1952 | } |
|
1953 | 1953 | } |
|
1954 | 1954 | |
|
1955 | 1955 | #summary{ |
|
1956 | 1956 | width: 70%; |
|
1957 | 1957 | } |
|
1958 | 1958 | |
|
1959 | 1959 | |
|
1960 | 1960 | // Journal |
|
1961 | 1961 | .journal.title { |
|
1962 | 1962 | h5 { |
|
1963 | 1963 | float: left; |
|
1964 | 1964 | margin: 0; |
|
1965 | 1965 | width: 70%; |
|
1966 | 1966 | } |
|
1967 | 1967 | |
|
1968 | 1968 | ul { |
|
1969 | 1969 | float: right; |
|
1970 | 1970 | display: inline-block; |
|
1971 | 1971 | margin: 0; |
|
1972 | 1972 | width: 30%; |
|
1973 | 1973 | text-align: right; |
|
1974 | 1974 | |
|
1975 | 1975 | li { |
|
1976 | 1976 | display: inline; |
|
1977 | 1977 | font-size: @journal-fontsize; |
|
1978 | 1978 | line-height: 1em; |
|
1979 | 1979 | |
|
1980 | 1980 | list-style-type: none; |
|
1981 | 1981 | } |
|
1982 | 1982 | } |
|
1983 | 1983 | } |
|
1984 | 1984 | |
|
1985 | 1985 | .filterexample { |
|
1986 | 1986 | position: absolute; |
|
1987 | 1987 | top: 95px; |
|
1988 | 1988 | left: @contentpadding; |
|
1989 | 1989 | color: @rcblue; |
|
1990 | 1990 | font-size: 11px; |
|
1991 | 1991 | font-family: @text-regular; |
|
1992 | 1992 | cursor: help; |
|
1993 | 1993 | |
|
1994 | 1994 | &:hover { |
|
1995 | 1995 | color: @rcdarkblue; |
|
1996 | 1996 | } |
|
1997 | 1997 | |
|
1998 | 1998 | @media (max-width:768px) { |
|
1999 | 1999 | position: relative; |
|
2000 | 2000 | top: auto; |
|
2001 | 2001 | left: auto; |
|
2002 | 2002 | display: block; |
|
2003 | 2003 | } |
|
2004 | 2004 | } |
|
2005 | 2005 | |
|
2006 | 2006 | |
|
2007 | 2007 | #journal{ |
|
2008 | 2008 | margin-bottom: @space; |
|
2009 | 2009 | |
|
2010 | 2010 | .journal_day{ |
|
2011 | 2011 | margin-bottom: @textmargin/2; |
|
2012 | 2012 | padding-bottom: @textmargin/2; |
|
2013 | 2013 | font-size: @journal-fontsize; |
|
2014 | 2014 | border-bottom: @border-thickness solid @border-default-color; |
|
2015 | 2015 | } |
|
2016 | 2016 | |
|
2017 | 2017 | .journal_container{ |
|
2018 | 2018 | margin-bottom: @space; |
|
2019 | 2019 | |
|
2020 | 2020 | .journal_user{ |
|
2021 | 2021 | display: inline-block; |
|
2022 | 2022 | } |
|
2023 | 2023 | .journal_action_container{ |
|
2024 | 2024 | display: block; |
|
2025 | 2025 | margin-top: @textmargin; |
|
2026 | 2026 | |
|
2027 | 2027 | div{ |
|
2028 | 2028 | display: inline; |
|
2029 | 2029 | } |
|
2030 | 2030 | |
|
2031 | 2031 | div.journal_action_params{ |
|
2032 | 2032 | display: block; |
|
2033 | 2033 | } |
|
2034 | 2034 | |
|
2035 | 2035 | div.journal_repo:after{ |
|
2036 | 2036 | content: "\A"; |
|
2037 | 2037 | white-space: pre; |
|
2038 | 2038 | } |
|
2039 | 2039 | |
|
2040 | 2040 | div.date{ |
|
2041 | 2041 | display: block; |
|
2042 | 2042 | margin-bottom: @textmargin; |
|
2043 | 2043 | } |
|
2044 | 2044 | } |
|
2045 | 2045 | } |
|
2046 | 2046 | } |
|
2047 | 2047 | |
|
2048 | 2048 | // Files |
|
2049 | 2049 | .edit-file-title { |
|
2050 | 2050 | border-bottom: @border-thickness solid @border-default-color; |
|
2051 | 2051 | |
|
2052 | 2052 | .breadcrumbs { |
|
2053 | 2053 | margin-bottom: 0; |
|
2054 | 2054 | } |
|
2055 | 2055 | } |
|
2056 | 2056 | |
|
2057 | 2057 | .edit-file-fieldset { |
|
2058 | 2058 | margin-top: @sidebarpadding; |
|
2059 | 2059 | |
|
2060 | 2060 | .fieldset { |
|
2061 | 2061 | .left-label { |
|
2062 | 2062 | width: 13%; |
|
2063 | 2063 | } |
|
2064 | 2064 | .right-content { |
|
2065 | 2065 | width: 87%; |
|
2066 | 2066 | max-width: 100%; |
|
2067 | 2067 | } |
|
2068 | 2068 | .filename-label { |
|
2069 | 2069 | margin-top: 13px; |
|
2070 | 2070 | } |
|
2071 | 2071 | .commit-message-label { |
|
2072 | 2072 | margin-top: 4px; |
|
2073 | 2073 | } |
|
2074 | 2074 | .file-upload-input { |
|
2075 | 2075 | input { |
|
2076 | 2076 | display: none; |
|
2077 | 2077 | } |
|
2078 | 2078 | margin-top: 10px; |
|
2079 | 2079 | } |
|
2080 | 2080 | .file-upload-label { |
|
2081 | 2081 | margin-top: 10px; |
|
2082 | 2082 | } |
|
2083 | 2083 | p { |
|
2084 | 2084 | margin-top: 5px; |
|
2085 | 2085 | } |
|
2086 | 2086 | |
|
2087 | 2087 | } |
|
2088 | 2088 | .custom-path-link { |
|
2089 | 2089 | margin-left: 5px; |
|
2090 | 2090 | } |
|
2091 | 2091 | #commit { |
|
2092 | 2092 | resize: vertical; |
|
2093 | 2093 | } |
|
2094 | 2094 | } |
|
2095 | 2095 | |
|
2096 | 2096 | .delete-file-preview { |
|
2097 | 2097 | max-height: 250px; |
|
2098 | 2098 | } |
|
2099 | 2099 | |
|
2100 | 2100 | .new-file, |
|
2101 | 2101 | #filter_activate, |
|
2102 | 2102 | #filter_deactivate { |
|
2103 | 2103 | float: right; |
|
2104 | 2104 | margin: 0 0 0 10px; |
|
2105 | 2105 | } |
|
2106 | 2106 | |
|
2107 | 2107 | h3.files_location{ |
|
2108 | 2108 | line-height: 2.4em; |
|
2109 | 2109 | } |
|
2110 | 2110 | |
|
2111 | 2111 | .browser-nav { |
|
2112 | 2112 | width: 100%; |
|
2113 | 2113 | display: table; |
|
2114 | 2114 | margin-bottom: 20px; |
|
2115 | 2115 | |
|
2116 | 2116 | .info_box { |
|
2117 | 2117 | float: left; |
|
2118 | 2118 | display: inline-table; |
|
2119 | 2119 | height: 2.5em; |
|
2120 | 2120 | |
|
2121 | 2121 | .browser-cur-rev, .info_box_elem { |
|
2122 | 2122 | display: table-cell; |
|
2123 | 2123 | vertical-align: middle; |
|
2124 | 2124 | } |
|
2125 | 2125 | |
|
2126 | 2126 | .drop-menu { |
|
2127 | 2127 | margin: 0 10px; |
|
2128 | 2128 | } |
|
2129 | 2129 | |
|
2130 | 2130 | .info_box_elem { |
|
2131 | 2131 | border-top: @border-thickness solid @grey5; |
|
2132 | 2132 | border-bottom: @border-thickness solid @grey5; |
|
2133 | 2133 | box-shadow: @button-shadow; |
|
2134 | 2134 | |
|
2135 | 2135 | #at_rev, a { |
|
2136 | 2136 | padding: 0.6em 0.4em; |
|
2137 | 2137 | margin: 0; |
|
2138 | 2138 | .box-shadow(none); |
|
2139 | 2139 | border: 0; |
|
2140 | 2140 | height: 12px; |
|
2141 | 2141 | color: @grey2; |
|
2142 | 2142 | } |
|
2143 | 2143 | |
|
2144 | 2144 | input#at_rev { |
|
2145 | 2145 | max-width: 50px; |
|
2146 | 2146 | text-align: center; |
|
2147 | 2147 | } |
|
2148 | 2148 | |
|
2149 | 2149 | &.previous { |
|
2150 | 2150 | border: @border-thickness solid @grey5; |
|
2151 | 2151 | border-top-left-radius: @border-radius; |
|
2152 | 2152 | border-bottom-left-radius: @border-radius; |
|
2153 | 2153 | |
|
2154 | 2154 | &:hover { |
|
2155 | 2155 | border-color: @grey4; |
|
2156 | 2156 | } |
|
2157 | 2157 | |
|
2158 | 2158 | .disabled { |
|
2159 | 2159 | color: @grey5; |
|
2160 | 2160 | cursor: not-allowed; |
|
2161 | 2161 | opacity: 0.5; |
|
2162 | 2162 | } |
|
2163 | 2163 | } |
|
2164 | 2164 | |
|
2165 | 2165 | &.next { |
|
2166 | 2166 | border: @border-thickness solid @grey5; |
|
2167 | 2167 | border-top-right-radius: @border-radius; |
|
2168 | 2168 | border-bottom-right-radius: @border-radius; |
|
2169 | 2169 | |
|
2170 | 2170 | &:hover { |
|
2171 | 2171 | border-color: @grey4; |
|
2172 | 2172 | } |
|
2173 | 2173 | |
|
2174 | 2174 | .disabled { |
|
2175 | 2175 | color: @grey5; |
|
2176 | 2176 | cursor: not-allowed; |
|
2177 | 2177 | opacity: 0.5; |
|
2178 | 2178 | } |
|
2179 | 2179 | } |
|
2180 | 2180 | } |
|
2181 | 2181 | |
|
2182 | 2182 | .browser-cur-rev { |
|
2183 | 2183 | |
|
2184 | 2184 | span{ |
|
2185 | 2185 | margin: 0; |
|
2186 | 2186 | color: @rcblue; |
|
2187 | 2187 | height: 12px; |
|
2188 | 2188 | display: inline-block; |
|
2189 | 2189 | padding: 0.7em 1em ; |
|
2190 | 2190 | border: @border-thickness solid @rcblue; |
|
2191 | 2191 | margin-right: @padding; |
|
2192 | 2192 | } |
|
2193 | 2193 | } |
|
2194 | 2194 | |
|
2195 | } | |
|
2196 | ||
|
2195 | 2197 |
|
|
2196 | 2198 |
|
|
2197 | 2199 |
|
|
2198 | 2200 |
|
|
2199 | } | |
|
2200 | 2201 | |
|
2201 | 2202 | .search_activate { |
|
2202 | 2203 | display: table-cell; |
|
2203 | 2204 | vertical-align: middle; |
|
2204 | 2205 | |
|
2205 | 2206 | input, label{ |
|
2206 | 2207 | margin: 0; |
|
2207 | 2208 | padding: 0; |
|
2208 | 2209 | } |
|
2209 | 2210 | |
|
2210 | 2211 | input{ |
|
2211 | 2212 | margin-left: @textmargin; |
|
2212 | 2213 | } |
|
2213 | 2214 | |
|
2214 | 2215 | } |
|
2215 | 2216 | } |
|
2216 | 2217 | |
|
2217 | 2218 | .browser-cur-rev{ |
|
2218 | 2219 | margin-bottom: @textmargin; |
|
2219 | 2220 | } |
|
2220 | 2221 | |
|
2221 | 2222 | #node_filter_box_loading{ |
|
2222 | 2223 | .info_text; |
|
2223 | 2224 | } |
|
2224 | 2225 | |
|
2225 | 2226 | .browser-search { |
|
2226 | 2227 | margin: -25px 0px 5px 0px; |
|
2227 | 2228 | } |
|
2228 | 2229 | |
|
2229 | 2230 | .files-quick-filter { |
|
2230 | 2231 | float: right; |
|
2231 | 2232 | width: 180px; |
|
2232 | 2233 | position: relative; |
|
2233 | 2234 | } |
|
2234 | 2235 | |
|
2235 | 2236 | .files-filter-box { |
|
2236 | 2237 | display: flex; |
|
2237 | 2238 | padding: 0px; |
|
2238 | 2239 | border-radius: 3px; |
|
2239 | 2240 | margin-bottom: 0; |
|
2240 | 2241 | |
|
2241 | 2242 | a { |
|
2242 | 2243 | border: none !important; |
|
2243 | 2244 | } |
|
2244 | 2245 | |
|
2245 | 2246 | li { |
|
2246 | 2247 | list-style-type: none |
|
2247 | 2248 | } |
|
2248 | 2249 | } |
|
2249 | 2250 | |
|
2250 | 2251 | .files-filter-box-path { |
|
2251 | 2252 | line-height: 33px; |
|
2252 | 2253 | padding: 0; |
|
2253 | 2254 | width: 20px; |
|
2254 | 2255 | position: absolute; |
|
2255 | 2256 | z-index: 11; |
|
2256 | 2257 | left: 5px; |
|
2257 | 2258 | } |
|
2258 | 2259 | |
|
2259 | 2260 | .files-filter-box-input { |
|
2260 | 2261 | margin-right: 0; |
|
2261 | 2262 | |
|
2262 | 2263 | input { |
|
2263 | 2264 | border: 1px solid @white; |
|
2264 | 2265 | padding-left: 25px; |
|
2265 | 2266 | width: 145px; |
|
2266 | 2267 | |
|
2267 | 2268 | &:hover { |
|
2268 | 2269 | border-color: @grey6; |
|
2269 | 2270 | } |
|
2270 | 2271 | |
|
2271 | 2272 | &:focus { |
|
2272 | 2273 | border-color: @grey5; |
|
2273 | 2274 | } |
|
2274 | 2275 | } |
|
2275 | 2276 | } |
|
2276 | 2277 | |
|
2277 | 2278 | .browser-result{ |
|
2278 | 2279 | td a{ |
|
2279 | 2280 | margin-left: 0.5em; |
|
2280 | 2281 | display: inline-block; |
|
2281 | 2282 | |
|
2282 | 2283 | em { |
|
2283 | 2284 | font-weight: @text-bold-weight; |
|
2284 | 2285 | font-family: @text-bold; |
|
2285 | 2286 | } |
|
2286 | 2287 | } |
|
2287 | 2288 | } |
|
2288 | 2289 | |
|
2289 | 2290 | .browser-highlight{ |
|
2290 | 2291 | background-color: @grey5-alpha; |
|
2291 | 2292 | } |
|
2292 | 2293 | |
|
2293 | 2294 | |
|
2294 | 2295 | // Search |
|
2295 | 2296 | |
|
2296 | 2297 | .search-form{ |
|
2297 | 2298 | #q { |
|
2298 | 2299 | width: @search-form-width; |
|
2299 | 2300 | } |
|
2300 | 2301 | .fields{ |
|
2301 | 2302 | margin: 0 0 @space; |
|
2302 | 2303 | } |
|
2303 | 2304 | |
|
2304 | 2305 | label{ |
|
2305 | 2306 | display: inline-block; |
|
2306 | 2307 | margin-right: @textmargin; |
|
2307 | 2308 | padding-top: 0.25em; |
|
2308 | 2309 | } |
|
2309 | 2310 | |
|
2310 | 2311 | |
|
2311 | 2312 | .results{ |
|
2312 | 2313 | clear: both; |
|
2313 | 2314 | margin: 0 0 @padding; |
|
2314 | 2315 | } |
|
2315 | 2316 | |
|
2316 | 2317 | .search-tags { |
|
2317 | 2318 | padding: 5px 0; |
|
2318 | 2319 | } |
|
2319 | 2320 | } |
|
2320 | 2321 | |
|
2321 | 2322 | div.search-feedback-items { |
|
2322 | 2323 | display: inline-block; |
|
2323 | 2324 | } |
|
2324 | 2325 | |
|
2325 | 2326 | div.search-code-body { |
|
2326 | 2327 | background-color: #ffffff; padding: 5px 0 5px 10px; |
|
2327 | 2328 | pre { |
|
2328 | 2329 | .match { background-color: #faffa6;} |
|
2329 | 2330 | .break { display: block; width: 100%; background-color: #DDE7EF; color: #747474; } |
|
2330 | 2331 | } |
|
2331 | 2332 | } |
|
2332 | 2333 | |
|
2333 | 2334 | .expand_commit.search { |
|
2334 | 2335 | .show_more.open { |
|
2335 | 2336 | height: auto; |
|
2336 | 2337 | max-height: none; |
|
2337 | 2338 | } |
|
2338 | 2339 | } |
|
2339 | 2340 | |
|
2340 | 2341 | .search-results { |
|
2341 | 2342 | |
|
2342 | 2343 | h2 { |
|
2343 | 2344 | margin-bottom: 0; |
|
2344 | 2345 | } |
|
2345 | 2346 | .codeblock { |
|
2346 | 2347 | border: none; |
|
2347 | 2348 | background: transparent; |
|
2348 | 2349 | } |
|
2349 | 2350 | |
|
2350 | 2351 | .codeblock-header { |
|
2351 | 2352 | border: none; |
|
2352 | 2353 | background: transparent; |
|
2353 | 2354 | } |
|
2354 | 2355 | |
|
2355 | 2356 | .code-body { |
|
2356 | 2357 | border: @border-thickness solid @border-default-color; |
|
2357 | 2358 | .border-radius(@border-radius); |
|
2358 | 2359 | } |
|
2359 | 2360 | |
|
2360 | 2361 | .td-commit { |
|
2361 | 2362 | &:extend(pre); |
|
2362 | 2363 | border-bottom: @border-thickness solid @border-default-color; |
|
2363 | 2364 | } |
|
2364 | 2365 | |
|
2365 | 2366 | .message { |
|
2366 | 2367 | height: auto; |
|
2367 | 2368 | max-width: 350px; |
|
2368 | 2369 | white-space: normal; |
|
2369 | 2370 | text-overflow: initial; |
|
2370 | 2371 | overflow: visible; |
|
2371 | 2372 | |
|
2372 | 2373 | .match { background-color: #faffa6;} |
|
2373 | 2374 | .break { background-color: #DDE7EF; width: 100%; color: #747474; display: block; } |
|
2374 | 2375 | } |
|
2375 | 2376 | |
|
2376 | 2377 | } |
|
2377 | 2378 | |
|
2378 | 2379 | table.rctable td.td-search-results div { |
|
2379 | 2380 | max-width: 100%; |
|
2380 | 2381 | } |
|
2381 | 2382 | |
|
2382 | 2383 | #tip-box, .tip-box{ |
|
2383 | 2384 | padding: @menupadding/2; |
|
2384 | 2385 | display: block; |
|
2385 | 2386 | border: @border-thickness solid @border-highlight-color; |
|
2386 | 2387 | .border-radius(@border-radius); |
|
2387 | 2388 | background-color: white; |
|
2388 | 2389 | z-index: 99; |
|
2389 | 2390 | white-space: pre-wrap; |
|
2390 | 2391 | } |
|
2391 | 2392 | |
|
2392 | 2393 | #linktt { |
|
2393 | 2394 | width: 79px; |
|
2394 | 2395 | } |
|
2395 | 2396 | |
|
2396 | 2397 | #help_kb .modal-content{ |
|
2397 | 2398 | max-width: 750px; |
|
2398 | 2399 | margin: 10% auto; |
|
2399 | 2400 | |
|
2400 | 2401 | table{ |
|
2401 | 2402 | td,th{ |
|
2402 | 2403 | border-bottom: none; |
|
2403 | 2404 | line-height: 2.5em; |
|
2404 | 2405 | } |
|
2405 | 2406 | th{ |
|
2406 | 2407 | padding-bottom: @textmargin/2; |
|
2407 | 2408 | } |
|
2408 | 2409 | td.keys{ |
|
2409 | 2410 | text-align: center; |
|
2410 | 2411 | } |
|
2411 | 2412 | } |
|
2412 | 2413 | |
|
2413 | 2414 | .block-left{ |
|
2414 | 2415 | width: 45%; |
|
2415 | 2416 | margin-right: 5%; |
|
2416 | 2417 | } |
|
2417 | 2418 | .modal-footer{ |
|
2418 | 2419 | clear: both; |
|
2419 | 2420 | } |
|
2420 | 2421 | .key.tag{ |
|
2421 | 2422 | padding: 0.5em; |
|
2422 | 2423 | background-color: @rcblue; |
|
2423 | 2424 | color: white; |
|
2424 | 2425 | border-color: @rcblue; |
|
2425 | 2426 | .box-shadow(none); |
|
2426 | 2427 | } |
|
2427 | 2428 | } |
|
2428 | 2429 | |
|
2429 | 2430 | |
|
2430 | 2431 | |
|
2431 | 2432 | //--- IMPORTS FOR REFACTORED STYLES ------------------// |
|
2432 | 2433 | |
|
2433 | 2434 | @import 'statistics-graph'; |
|
2434 | 2435 | @import 'tables'; |
|
2435 | 2436 | @import 'forms'; |
|
2436 | 2437 | @import 'diff'; |
|
2437 | 2438 | @import 'summary'; |
|
2438 | 2439 | @import 'navigation'; |
|
2439 | 2440 | |
|
2440 | 2441 | //--- SHOW/HIDE SECTIONS --// |
|
2441 | 2442 | |
|
2442 | 2443 | .btn-collapse { |
|
2443 | 2444 | float: right; |
|
2444 | 2445 | text-align: right; |
|
2445 | 2446 | font-family: @text-light; |
|
2446 | 2447 | font-size: @basefontsize; |
|
2447 | 2448 | cursor: pointer; |
|
2448 | 2449 | border: none; |
|
2449 | 2450 | color: @rcblue; |
|
2450 | 2451 | } |
|
2451 | 2452 | |
|
2452 | 2453 | table.rctable, |
|
2453 | 2454 | table.dataTable { |
|
2454 | 2455 | .btn-collapse { |
|
2455 | 2456 | float: right; |
|
2456 | 2457 | text-align: right; |
|
2457 | 2458 | } |
|
2458 | 2459 | } |
|
2459 | 2460 | |
|
2460 | 2461 | table.rctable { |
|
2461 | 2462 | &.permissions { |
|
2462 | 2463 | |
|
2463 | 2464 | th.td-owner { |
|
2464 | 2465 | padding: 0; |
|
2465 | 2466 | } |
|
2466 | 2467 | |
|
2467 | 2468 | th { |
|
2468 | 2469 | font-weight: normal; |
|
2469 | 2470 | padding: 0 5px; |
|
2470 | 2471 | } |
|
2471 | 2472 | |
|
2472 | 2473 | } |
|
2473 | 2474 | } |
|
2474 | 2475 | |
|
2475 | 2476 | |
|
2476 | 2477 | // TODO: johbo: Fix for IE10, this avoids that we see a border |
|
2477 | 2478 | // and padding around checkboxes and radio boxes. Move to the right place, |
|
2478 | 2479 | // or better: Remove this once we did the form refactoring. |
|
2479 | 2480 | input[type=checkbox], |
|
2480 | 2481 | input[type=radio] { |
|
2481 | 2482 | padding: 0; |
|
2482 | 2483 | border: none; |
|
2483 | 2484 | } |
|
2484 | 2485 | |
|
2485 | 2486 | .toggle-ajax-spinner{ |
|
2486 | 2487 | height: 16px; |
|
2487 | 2488 | width: 16px; |
|
2488 | 2489 | } |
|
2489 | 2490 | |
|
2490 | 2491 | |
|
2491 | 2492 | .markup-form .clearfix { |
|
2492 | 2493 | .border-radius(@border-radius); |
|
2493 | 2494 | margin: 0px; |
|
2494 | 2495 | } |
|
2495 | 2496 | |
|
2496 | 2497 | .markup-form-area { |
|
2497 | 2498 | padding: 8px 12px; |
|
2498 | 2499 | border: 1px solid @grey4; |
|
2499 | 2500 | .border-radius(@border-radius); |
|
2500 | 2501 | } |
|
2501 | 2502 | |
|
2502 | 2503 | .markup-form-area-header .nav-links { |
|
2503 | 2504 | display: flex; |
|
2504 | 2505 | flex-flow: row wrap; |
|
2505 | 2506 | -webkit-flex-flow: row wrap; |
|
2506 | 2507 | width: 100%; |
|
2507 | 2508 | } |
|
2508 | 2509 | |
|
2509 | 2510 | .markup-form-area-footer { |
|
2510 | 2511 | display: flex; |
|
2511 | 2512 | } |
|
2512 | 2513 | |
|
2513 | 2514 | .markup-form-area-footer .toolbar { |
|
2514 | 2515 | |
|
2515 | 2516 | } |
|
2516 | 2517 | |
|
2517 | 2518 | // markup Form |
|
2518 | 2519 | div.markup-form { |
|
2519 | 2520 | margin-top: 20px; |
|
2520 | 2521 | } |
|
2521 | 2522 | |
|
2522 | 2523 | .markup-form strong { |
|
2523 | 2524 | display: block; |
|
2524 | 2525 | margin-bottom: 15px; |
|
2525 | 2526 | } |
|
2526 | 2527 | |
|
2527 | 2528 | .markup-form textarea { |
|
2528 | 2529 | width: 100%; |
|
2529 | 2530 | height: 100px; |
|
2530 | 2531 | font-family: @text-monospace; |
|
2531 | 2532 | } |
|
2532 | 2533 | |
|
2533 | 2534 | form.markup-form { |
|
2534 | 2535 | margin-top: 10px; |
|
2535 | 2536 | margin-left: 10px; |
|
2536 | 2537 | } |
|
2537 | 2538 | |
|
2538 | 2539 | .markup-form .comment-block-ta, |
|
2539 | 2540 | .markup-form .preview-box { |
|
2540 | 2541 | .border-radius(@border-radius); |
|
2541 | 2542 | .box-sizing(border-box); |
|
2542 | 2543 | background-color: white; |
|
2543 | 2544 | } |
|
2544 | 2545 | |
|
2545 | 2546 | .markup-form .preview-box.unloaded { |
|
2546 | 2547 | height: 50px; |
|
2547 | 2548 | text-align: center; |
|
2548 | 2549 | padding: 20px; |
|
2549 | 2550 | background-color: white; |
|
2550 | 2551 | } |
|
2551 | 2552 | |
|
2552 | 2553 | .dropzone { |
|
2553 | 2554 | border: 2px dashed @rcdarkblue; |
|
2554 | 2555 | border-radius: 5px; |
|
2555 | 2556 | background: white; |
|
2556 | 2557 | min-height: 200px; |
|
2557 | 2558 | padding: 54px; |
|
2558 | 2559 | } |
|
2559 | 2560 | .dropzone .dz-message { |
|
2560 | 2561 | font-weight: 700; |
|
2561 | 2562 | } |
|
2562 | 2563 | |
|
2563 | 2564 | .dropzone .dz-message { |
|
2564 | 2565 | text-align: center; |
|
2565 | 2566 | margin: 2em 0; |
|
2566 | 2567 | } |
|
2567 | 2568 | |
|
2568 | 2569 | .dz-preview { |
|
2569 | 2570 | margin: 10px -40px !important; |
|
2570 | 2571 | position: relative; |
|
2571 | 2572 | vertical-align: top; |
|
2572 | 2573 | border: 1px solid @grey4; |
|
2573 | 2574 | border-radius: 5px; |
|
2574 | 2575 | padding: 10px; |
|
2575 | 2576 | } |
|
2576 | 2577 | |
|
2577 | 2578 | .dz-filename { |
|
2578 | 2579 | font-weight: 700; |
|
2579 | 2580 | } |
|
2580 | 2581 | |
|
2581 | 2582 | .dz-error-message { |
|
2582 | 2583 | color: @alert2; |
|
2583 | 2584 | } No newline at end of file |
@@ -1,273 +1,274 b'' | |||
|
1 | 1 | @font-face { |
|
2 | 2 | font-family: 'rcicons'; |
|
3 | 3 | |
|
4 |
src: url('../fonts/RCIcons/rcicons.eot? |
|
|
5 |
src: url('../fonts/RCIcons/rcicons.eot? |
|
|
6 |
url('../fonts/RCIcons/rcicons.woff2? |
|
|
7 |
url('../fonts/RCIcons/rcicons.woff? |
|
|
8 |
url('../fonts/RCIcons |
|
|
9 |
url('../fonts/RCIcons/rcicons.svg? |
|
|
4 | src: url('../fonts/RCIcons/rcicons.eot?9641970'); | |
|
5 | src: url('../fonts/RCIcons/rcicons.eot?9641970#iefix') format('embedded-opentype'), | |
|
6 | url('../fonts/RCIcons/rcicons.woff2?9641970') format('woff2'), | |
|
7 | url('../fonts/RCIcons/rcicons.woff?9641970') format('woff'), | |
|
8 | url('../fonts/RCIcons/rcicons.ttf?9641970') format('truetype'), | |
|
9 | url('../fonts/RCIcons/rcicons.svg?9641970#rcicons') format('svg'); | |
|
10 | 10 | |
|
11 | 11 | font-weight: normal; |
|
12 | 12 | font-style: normal; |
|
13 | 13 | } |
|
14 | 14 | /* Chrome hack: SVG is rendered more smooth in Windozze. 100% magic, uncomment if you need it. */ |
|
15 | 15 | /* Note, that will break hinting! In other OS-es font will be not as sharp as it could be */ |
|
16 | 16 | /* |
|
17 | 17 | @media screen and (-webkit-min-device-pixel-ratio:0) { |
|
18 | 18 | @font-face { |
|
19 | 19 | font-family: 'rcicons'; |
|
20 | 20 | src: url('../fonts/RCIcons/rcicons.svg?74666722#rcicons') format('svg'); |
|
21 | 21 | } |
|
22 | 22 | } |
|
23 | 23 | */ |
|
24 | 24 | |
|
25 | 25 | [class^="icon-"]:before, [class*=" icon-"]:before { |
|
26 | 26 | font-family: "rcicons"; |
|
27 | 27 | font-style: normal; |
|
28 | 28 | font-weight: normal; |
|
29 | 29 | speak: none; |
|
30 | 30 | |
|
31 | 31 | display: inline-block; |
|
32 | 32 | text-decoration: inherit; |
|
33 | 33 | width: 1em; |
|
34 | 34 | margin-right: .2em; |
|
35 | 35 | text-align: center; |
|
36 | 36 | /* opacity: .8; */ |
|
37 | 37 | |
|
38 | 38 | /* For safety - reset parent styles, that can break glyph codes*/ |
|
39 | 39 | font-variant: normal; |
|
40 | 40 | text-transform: none; |
|
41 | 41 | |
|
42 | 42 | /* fix buttons height, for twitter bootstrap */ |
|
43 | 43 | line-height: 1em; |
|
44 | 44 | |
|
45 | 45 | /* Animation center compensation - margins should be symmetric */ |
|
46 | 46 | /* remove if not needed */ |
|
47 | 47 | margin-left: .2em; |
|
48 | 48 | |
|
49 | 49 | /* you can be more comfortable with increased icons size */ |
|
50 | 50 | /* font-size: 120%; */ |
|
51 | 51 | |
|
52 | 52 | /* Font smoothing. That was taken from TWBS */ |
|
53 | 53 | -webkit-font-smoothing: antialiased; |
|
54 | 54 | -moz-osx-font-smoothing: grayscale; |
|
55 | 55 | |
|
56 | 56 | /* Uncomment for 3D effect */ |
|
57 | 57 | /* text-shadow: 1px 1px 1px rgba(127, 127, 127, 0.3); */ |
|
58 | 58 | } |
|
59 | 59 | |
|
60 | 60 | .animate-spin { |
|
61 | 61 | -moz-animation: spin 2s infinite linear; |
|
62 | 62 | -o-animation: spin 2s infinite linear; |
|
63 | 63 | -webkit-animation: spin 2s infinite linear; |
|
64 | 64 | animation: spin 2s infinite linear; |
|
65 | 65 | display: inline-block; |
|
66 | 66 | } |
|
67 | 67 | @-moz-keyframes spin { |
|
68 | 68 | 0% { |
|
69 | 69 | -moz-transform: rotate(0deg); |
|
70 | 70 | -o-transform: rotate(0deg); |
|
71 | 71 | -webkit-transform: rotate(0deg); |
|
72 | 72 | transform: rotate(0deg); |
|
73 | 73 | } |
|
74 | 74 | |
|
75 | 75 | 100% { |
|
76 | 76 | -moz-transform: rotate(359deg); |
|
77 | 77 | -o-transform: rotate(359deg); |
|
78 | 78 | -webkit-transform: rotate(359deg); |
|
79 | 79 | transform: rotate(359deg); |
|
80 | 80 | } |
|
81 | 81 | } |
|
82 | 82 | @-webkit-keyframes spin { |
|
83 | 83 | 0% { |
|
84 | 84 | -moz-transform: rotate(0deg); |
|
85 | 85 | -o-transform: rotate(0deg); |
|
86 | 86 | -webkit-transform: rotate(0deg); |
|
87 | 87 | transform: rotate(0deg); |
|
88 | 88 | } |
|
89 | 89 | |
|
90 | 90 | 100% { |
|
91 | 91 | -moz-transform: rotate(359deg); |
|
92 | 92 | -o-transform: rotate(359deg); |
|
93 | 93 | -webkit-transform: rotate(359deg); |
|
94 | 94 | transform: rotate(359deg); |
|
95 | 95 | } |
|
96 | 96 | } |
|
97 | 97 | @-o-keyframes spin { |
|
98 | 98 | 0% { |
|
99 | 99 | -moz-transform: rotate(0deg); |
|
100 | 100 | -o-transform: rotate(0deg); |
|
101 | 101 | -webkit-transform: rotate(0deg); |
|
102 | 102 | transform: rotate(0deg); |
|
103 | 103 | } |
|
104 | 104 | |
|
105 | 105 | 100% { |
|
106 | 106 | -moz-transform: rotate(359deg); |
|
107 | 107 | -o-transform: rotate(359deg); |
|
108 | 108 | -webkit-transform: rotate(359deg); |
|
109 | 109 | transform: rotate(359deg); |
|
110 | 110 | } |
|
111 | 111 | } |
|
112 | 112 | @-ms-keyframes spin { |
|
113 | 113 | 0% { |
|
114 | 114 | -moz-transform: rotate(0deg); |
|
115 | 115 | -o-transform: rotate(0deg); |
|
116 | 116 | -webkit-transform: rotate(0deg); |
|
117 | 117 | transform: rotate(0deg); |
|
118 | 118 | } |
|
119 | 119 | |
|
120 | 120 | 100% { |
|
121 | 121 | -moz-transform: rotate(359deg); |
|
122 | 122 | -o-transform: rotate(359deg); |
|
123 | 123 | -webkit-transform: rotate(359deg); |
|
124 | 124 | transform: rotate(359deg); |
|
125 | 125 | } |
|
126 | 126 | } |
|
127 | 127 | @keyframes spin { |
|
128 | 128 | 0% { |
|
129 | 129 | -moz-transform: rotate(0deg); |
|
130 | 130 | -o-transform: rotate(0deg); |
|
131 | 131 | -webkit-transform: rotate(0deg); |
|
132 | 132 | transform: rotate(0deg); |
|
133 | 133 | } |
|
134 | 134 | |
|
135 | 135 | 100% { |
|
136 | 136 | -moz-transform: rotate(359deg); |
|
137 | 137 | -o-transform: rotate(359deg); |
|
138 | 138 | -webkit-transform: rotate(359deg); |
|
139 | 139 | transform: rotate(359deg); |
|
140 | 140 | } |
|
141 | 141 | } |
|
142 | 142 | |
|
143 | 143 | |
|
144 | 144 | |
|
145 | 145 | .icon-no-margin::before { |
|
146 | 146 | margin: 0; |
|
147 | 147 | |
|
148 | 148 | } |
|
149 | 149 | // -- ICON CLASSES -- // |
|
150 | 150 | // sorter = lambda s: '\n'.join(sorted(s.splitlines())) |
|
151 | 151 | |
|
152 | 152 | .icon-delete:before { content: '\e800'; } /* '' */ |
|
153 | 153 | .icon-ok:before { content: '\e801'; } /* '' */ |
|
154 | 154 | .icon-comment:before { content: '\e802'; } /* '' */ |
|
155 | 155 | .icon-bookmark:before { content: '\e803'; } /* '' */ |
|
156 | 156 | .icon-branch:before { content: '\e804'; } /* '' */ |
|
157 | 157 | .icon-tag:before { content: '\e805'; } /* '' */ |
|
158 | 158 | .icon-lock:before { content: '\e806'; } /* '' */ |
|
159 | 159 | .icon-unlock:before { content: '\e807'; } /* '' */ |
|
160 | 160 | .icon-feed:before { content: '\e808'; } /* '' */ |
|
161 | 161 | .icon-left:before { content: '\e809'; } /* '' */ |
|
162 | 162 | .icon-right:before { content: '\e80a'; } /* '' */ |
|
163 | 163 | .icon-down:before { content: '\e80b'; } /* '' */ |
|
164 | 164 | .icon-folder:before { content: '\e80c'; } /* '' */ |
|
165 | 165 | .icon-folder-open:before { content: '\e80d'; } /* '' */ |
|
166 | 166 | .icon-folder-empty:before { content: '\f114'; } /* '' */ |
|
167 | 167 | .icon-folder-open-empty:before { content: '\f115'; } /* '' */ |
|
168 | 168 | .icon-trash-empty:before { content: '\e80e'; } /* '' */ |
|
169 | 169 | .icon-group:before { content: '\e80f'; } /* '' */ |
|
170 | 170 | .icon-remove:before { content: '\e810'; } /* '' */ |
|
171 | 171 | .icon-fork:before { content: '\e811'; } /* '' */ |
|
172 | 172 | .icon-more:before { content: '\e812'; } /* '' */ |
|
173 | 173 | .icon-search:before { content: '\e813'; } /* '' */ |
|
174 | 174 | .icon-scissors:before { content: '\e814'; } /* '' */ |
|
175 | 175 | .icon-download:before { content: '\e815'; } /* '' */ |
|
176 | 176 | .icon-doc:before { content: '\e816'; } /* '' */ |
|
177 | 177 | .icon-cog:before { content: '\e817'; } /* '' */ |
|
178 | 178 | .icon-cog-alt:before { content: '\e818'; } /* '' */ |
|
179 | 179 | .icon-eye:before { content: '\e819'; } /* '' */ |
|
180 | 180 | .icon-eye-off:before { content: '\e81a'; } /* '' */ |
|
181 | 181 | .icon-cancel-circled2:before { content: '\e81b'; } /* '' */ |
|
182 | 182 | .icon-cancel-circled:before { content: '\e81c'; } /* '' */ |
|
183 | 183 | .icon-plus:before { content: '\e81d'; } /* '' */ |
|
184 | 184 | .icon-plus-circled:before { content: '\e81e'; } /* '' */ |
|
185 | 185 | .icon-minus-circled:before { content: '\e81f'; } /* '' */ |
|
186 | 186 | .icon-minus:before { content: '\e820'; } /* '' */ |
|
187 | 187 | .icon-info-circled:before { content: '\e821'; } /* '' */ |
|
188 | 188 | .icon-upload:before { content: '\e822'; } /* '' */ |
|
189 | .icon-home:before { content: '\e823'; } /* '' */ | |
|
189 | 190 | .icon-git:before { content: '\e82a'; } /* '' */ |
|
190 | 191 | .icon-hg:before { content: '\e82d'; } /* '' */ |
|
191 | 192 | .icon-svn:before { content: '\e82e'; } /* '' */ |
|
192 | 193 | .icon-comment-add:before { content: '\e82f'; } /* '' */ |
|
193 | 194 | .icon-comment-toggle:before { content: '\e830'; } /* '' */ |
|
194 | 195 | .icon-rhodecode:before { content: '\e831'; } /* '' */ |
|
195 | 196 | .icon-up:before { content: '\e832'; } /* '' */ |
|
196 | 197 | .icon-merge:before { content: '\e833'; } /* '' */ |
|
197 | 198 | .icon-docs:before { content: '\f0c5'; } /* '' */ |
|
198 | 199 | .icon-menu:before { content: '\f0c9'; } /* '' */ |
|
199 | 200 | .icon-paste:before { content: '\f0ea'; } /* '' */ |
|
200 | 201 | .icon-doc-text:before { content: '\f0f6'; } /* '' */ |
|
201 | 202 | .icon-plus-squared:before { content: '\f0fe'; } /* '' */ |
|
202 | 203 | .icon-minus-squared:before { content: '\f146'; } /* '' */ |
|
203 | 204 | .icon-minus-squared-alt:before { content: '\f147'; } /* '' */ |
|
204 | 205 | .icon-doc-inv:before { content: '\f15b'; } /* '' */ |
|
205 | 206 | .icon-doc-text-inv:before { content: '\f15c'; } /* '' */ |
|
206 | 207 | .icon-plus-squared-alt:before { content: '\f196'; } /* '' */ |
|
207 | 208 | .icon-file-code:before { content: '\f1c9'; } /* '' */ |
|
208 | 209 | .icon-sliders:before { content: '\f1de'; } /* '' */ |
|
209 | 210 | .icon-trash:before { content: '\f1f8'; } /* '' */ |
|
210 | 211 | .icon-spin-alt:before { content: '\e834'; } /* '' */ |
|
211 | 212 | .icon-spin:before { content: '\e838'; } /* '' */ |
|
212 | 213 | |
|
213 | 214 | |
|
214 | 215 | // MERGED ICONS BASED ON CURRENT ONES |
|
215 | 216 | .icon-repo-group:before { &:extend(.icon-folder-open:before); } |
|
216 | 217 | .icon-repo-private:before { &:extend(.icon-lock:before); } |
|
217 | 218 | .icon-repo-lock:before { &:extend(.icon-lock:before); } |
|
218 | 219 | .icon-unlock-alt:before { &:extend(.icon-unlock:before); } |
|
219 | 220 | .icon-repo-unlock:before { &:extend(.icon-unlock:before); } |
|
220 | 221 | .icon-repo-public:before { &:extend(.icon-unlock:before); } |
|
221 | 222 | .icon-rss-sign:before { &:extend(.icon-feed:before); } |
|
222 | 223 | .icon-code-fork:before { &:extend(.icon-fork:before); } |
|
223 | 224 | .icon-arrow_up:before { &:extend(.icon-up:before); } |
|
224 | 225 | .icon-file:before { &:extend(.icon-file-code:before); } |
|
225 | 226 | .icon-file-text:before { &:extend(.icon-file-code:before); } |
|
226 | 227 | .icon-directory:before { &:extend(.icon-folder:before); } |
|
227 | 228 | .icon-more-linked:before { &:extend(.icon-more:before); } |
|
228 | 229 | .icon-clipboard:before { &:extend(.icon-docs:before); } |
|
229 | 230 | .icon-copy:before { &:extend(.icon-docs:before); } |
|
230 | 231 | .icon-true:before { &:extend(.icon-ok:before); } |
|
231 | 232 | .icon-false:before { &:extend(.icon-delete:before); } |
|
232 | 233 | .icon-expand-linked:before { &:extend(.icon-down:before); } |
|
233 | 234 | .icon-pr-merge-fail:before { &:extend(.icon-delete:before); } |
|
234 | 235 | |
|
235 | 236 | // TRANSFORM |
|
236 | 237 | |
|
237 | 238 | .icon-merge:before {transform: rotate(180deg);} |
|
238 | 239 | |
|
239 | 240 | // -- END ICON CLASSES -- // |
|
240 | 241 | |
|
241 | 242 | |
|
242 | 243 | //--- ICONS STYLING ------------------// |
|
243 | 244 | |
|
244 | 245 | .icon-git { color: @color4 !important; } |
|
245 | 246 | .icon-hg { color: @color8 !important; } |
|
246 | 247 | .icon-svn { color: @color1 !important; } |
|
247 | 248 | .icon-git-inv { color: @color4 !important; } |
|
248 | 249 | .icon-hg-inv { color: @color8 !important; } |
|
249 | 250 | .icon-svn-inv { color: @color1 !important; } |
|
250 | 251 | .icon-repo-lock { color: #FF0000; } |
|
251 | 252 | .icon-repo-unlock { color: #FF0000; } |
|
252 | 253 | .icon-false { color: @grey5 } |
|
253 | 254 | .icon-expand-linked { cursor: pointer; color: @grey3; font-size: 14px } |
|
254 | 255 | .icon-more-linked { cursor: pointer; color: @grey3 } |
|
255 | 256 | |
|
256 | 257 | .repo-switcher-dropdown .select2-result-label { |
|
257 | 258 | .icon-git:before { |
|
258 | 259 | &:extend(.icon-git-transparent:before); |
|
259 | 260 | } |
|
260 | 261 | .icon-hg:before { |
|
261 | 262 | &:extend(.icon-hg-transparent:before); |
|
262 | 263 | color: @alert4; |
|
263 | 264 | } |
|
264 | 265 | .icon-svn:before { |
|
265 | 266 | &:extend(.icon-svn-transparent:before); |
|
266 | 267 | } |
|
267 | 268 | } |
|
268 | 269 | |
|
269 | 270 | .icon-user-group:before { |
|
270 | 271 | &:extend(.icon-group:before); |
|
271 | 272 | margin: 0; |
|
272 | 273 | font-size: 16px; |
|
273 | 274 | } |
@@ -1,478 +1,476 b'' | |||
|
1 | 1 | // summary.less |
|
2 | 2 | // For use in RhodeCode applications; |
|
3 | 3 | // Used for headers and file detail summary screens. |
|
4 | 4 | |
|
5 | 5 | .summary { |
|
6 | 6 | clear: both; |
|
7 | 7 | float: none; |
|
8 | 8 | position: relative; |
|
9 | 9 | width: 100%; |
|
10 | 10 | margin: 0; |
|
11 | 11 | padding: 0; |
|
12 | 12 | background: #FCFCFC; |
|
13 | 13 | border: 1px solid #EAEAEA; |
|
14 | 14 | border-radius: @border-radius; |
|
15 | 15 | margin-bottom: 20px; |
|
16 | 16 | |
|
17 | 17 | .summary-detail-header { |
|
18 | 18 | display: block; |
|
19 | 19 | width: 100%; |
|
20 | 20 | margin-bottom: 10px; |
|
21 | 21 | padding: 0 0 .5em 0; |
|
22 | 22 | border-bottom: @border-thickness solid @border-default-color; |
|
23 | 23 | |
|
24 | 24 | .breadcrumbs { |
|
25 | 25 | display: inline; |
|
26 | 26 | margin: 0; |
|
27 | 27 | padding: 0; |
|
28 | 28 | } |
|
29 | 29 | |
|
30 | 30 | h4 { |
|
31 | 31 | margin: 0 1em 0 0; |
|
32 | 32 | padding: 10px 0 5px 20px; |
|
33 | 33 | line-height: 1.2em; |
|
34 | 34 | font-size: @basefontsize; |
|
35 | 35 | } |
|
36 | 36 | |
|
37 | 37 | .action_link { |
|
38 | 38 | float: right; |
|
39 | 39 | } |
|
40 | 40 | |
|
41 | 41 | .new-file { |
|
42 | 42 | float: right; |
|
43 | 43 | margin-top: -1.5em; |
|
44 | 44 | } |
|
45 | 45 | } |
|
46 | 46 | |
|
47 | 47 | .summary-detail { |
|
48 | 48 | float: none; |
|
49 | 49 | position: relative; |
|
50 | 50 | width: 100%; |
|
51 | 51 | margin: 0; |
|
52 | 52 | padding: 0 0 20px 0; |
|
53 | 53 | |
|
54 | 54 | .file_diff_buttons { |
|
55 | 55 | margin-top: @space; |
|
56 | 56 | } |
|
57 | 57 | |
|
58 | 58 | // commit message |
|
59 | 59 | .commit { |
|
60 | 60 | white-space: pre-wrap; |
|
61 | 61 | } |
|
62 | 62 | |
|
63 | 63 | .left-clone { |
|
64 | 64 | float: left; |
|
65 | 65 | height: 30px; |
|
66 | 66 | margin: 0; |
|
67 | 67 | padding: 0; |
|
68 | 68 | width: 130px; |
|
69 | 69 | font-weight: @text-semibold-weight; |
|
70 | 70 | font-family: @text-semibold; |
|
71 | 71 | } |
|
72 | 72 | .left-clone select { |
|
73 | 73 | width: 130px; |
|
74 | 74 | margin-right: 0; |
|
75 | 75 | background-color: @grey7; |
|
76 | 76 | border-color: @grey4; |
|
77 | 77 | color: #5C5C5C; |
|
78 | 78 | border-top-right-radius: 0; |
|
79 | 79 | border-bottom-right-radius: 0; |
|
80 | 80 | } |
|
81 | 81 | |
|
82 | 82 | .right-clone { |
|
83 | 83 | float: left; |
|
84 | 84 | width: ~"calc(100% - 170px)"; |
|
85 | 85 | |
|
86 | 86 | .clipboard-action { |
|
87 | 87 | margin-left: -30px; |
|
88 | 88 | } |
|
89 | 89 | } |
|
90 | 90 | |
|
91 | 91 | .clone_url_input { |
|
92 | 92 | width: ~"calc(100% - 90px)"; |
|
93 | 93 | padding: 6px 30px 6px 10px; |
|
94 | 94 | height: 14px; |
|
95 | 95 | box-shadow: 0 1px 1px 0 rgba(0,0,0,0.07); |
|
96 | 96 | border-top-left-radius: 0; |
|
97 | 97 | border-bottom-left-radius: 0; |
|
98 | 98 | margin-left: -1px; |
|
99 | 99 | } |
|
100 | 100 | |
|
101 | 101 | &.directory { |
|
102 | 102 | margin-bottom: 0; |
|
103 | 103 | } |
|
104 | 104 | |
|
105 | 105 | .desc { |
|
106 | 106 | white-space: pre-wrap; |
|
107 | 107 | } |
|
108 | 108 | .disabled { |
|
109 | 109 | opacity: .5; |
|
110 | 110 | cursor: inherit; |
|
111 | 111 | } |
|
112 | 112 | .help-block { |
|
113 | 113 | color: inherit; |
|
114 | 114 | margin: 0; |
|
115 | 115 | } |
|
116 | 116 | } |
|
117 | 117 | |
|
118 | 118 | .sidebar-right { |
|
119 | 119 | float: left; |
|
120 | 120 | width: 24%; |
|
121 | 121 | margin: 0; |
|
122 | 122 | padding: 0; |
|
123 | 123 | |
|
124 | 124 | ul { |
|
125 | 125 | margin-left: 0; |
|
126 | 126 | padding-left: 0; |
|
127 | 127 | |
|
128 | 128 | li { |
|
129 | 129 | list-style-type: none; |
|
130 | 130 | } |
|
131 | 131 | } |
|
132 | 132 | } |
|
133 | 133 | |
|
134 | 134 | #clone_by_name, #clone_by_id{ |
|
135 | 135 | display: inline-block; |
|
136 | 136 | margin-left: 0px; |
|
137 | 137 | } |
|
138 | 138 | |
|
139 | 139 | .codeblock { |
|
140 | 140 | border: none; |
|
141 | 141 | background-color: transparent; |
|
142 | 142 | } |
|
143 | 143 | |
|
144 | 144 | .code-body { |
|
145 | 145 | border: @border-thickness solid @border-default-color; |
|
146 | 146 | .border-radius(@border-radius); |
|
147 | 147 | } |
|
148 | 148 | |
|
149 | 149 | .btn-collapse { |
|
150 | 150 | clear: both; |
|
151 | 151 | float: none; |
|
152 | 152 | background: #F7F7F7; |
|
153 | 153 | text-align: center; |
|
154 | 154 | color: #949494; |
|
155 | 155 | font-size: 11px; |
|
156 | 156 | |
|
157 | 157 | &:hover { |
|
158 | 158 | background: #f1f1f1; |
|
159 | 159 | color: #2B2B2D; |
|
160 | 160 | } |
|
161 | 161 | } |
|
162 | 162 | } |
|
163 | 163 | |
|
164 | 164 | // this is used outside of just the summary |
|
165 | 165 | .fieldset, // similar to form fieldset |
|
166 | 166 | .summary .sidebar-right-content { // these have to match |
|
167 | 167 | clear: both; |
|
168 | 168 | float: none; |
|
169 | 169 | position: relative; |
|
170 | 170 | display:block; |
|
171 | 171 | width: 100%; |
|
172 | 172 | min-height: 1em; |
|
173 | 173 | margin-bottom: 10px; |
|
174 | 174 | padding: 0; |
|
175 | 175 | line-height: 1.2em; |
|
176 | 176 | |
|
177 | 177 | &:after { // clearfix |
|
178 | 178 | content: ""; |
|
179 | 179 | clear: both; |
|
180 | 180 | width: 100%; |
|
181 | 181 | height: 1em; |
|
182 | 182 | } |
|
183 | 183 | } |
|
184 | 184 | |
|
185 | 185 | .summary .sidebar-right-content { |
|
186 | 186 | margin-bottom: 0; |
|
187 | 187 | |
|
188 | 188 | .rc-user { |
|
189 | 189 | min-width: 0; |
|
190 | 190 | } |
|
191 | 191 | |
|
192 | 192 | li { |
|
193 | 193 | list-style: none; |
|
194 | 194 | line-height: normal; |
|
195 | 195 | } |
|
196 | 196 | } |
|
197 | 197 | |
|
198 | 198 | .summary { |
|
199 | 199 | .fieldset { |
|
200 | 200 | margin-bottom: 0; |
|
201 | 201 | } |
|
202 | 202 | } |
|
203 | 203 | |
|
204 | 204 | .fieldset { |
|
205 | 205 | |
|
206 | 206 | .left-label { // similar to form legend |
|
207 | 207 | display: block; |
|
208 | 208 | margin: 0; |
|
209 | 209 | padding: 0; |
|
210 | 210 | font-weight: @text-semibold-weight; |
|
211 | 211 | font-family: @text-semibold; |
|
212 | 212 | } |
|
213 | 213 | |
|
214 | 214 | .left-label-summary { |
|
215 | 215 | padding-left: 20px; |
|
216 | 216 | margin-bottom: 5px; |
|
217 | 217 | |
|
218 | 218 | p { |
|
219 | 219 | margin-bottom: 5px; |
|
220 | 220 | color: @grey1; |
|
221 | 221 | float: left; |
|
222 | 222 | width: 130px; |
|
223 | 223 | |
|
224 | 224 | &.spacing { |
|
225 | 225 | margin-top: 10px; |
|
226 | 226 | } |
|
227 | 227 | } |
|
228 | 228 | |
|
229 | 229 | .right-label-summary { |
|
230 | 230 | float: left; |
|
231 | 231 | margin-top: 7px; |
|
232 | 232 | width: ~"calc(100% - 160px)"; |
|
233 | 233 | } |
|
234 | 234 | } |
|
235 | 235 | |
|
236 | 236 | .left-label-summary-files { |
|
237 | 237 | padding-left: 45px; |
|
238 | 238 | margin-top: 5px; |
|
239 | 239 | |
|
240 | 240 | p { |
|
241 | 241 | margin-bottom: 5px; |
|
242 | 242 | color: @grey1; |
|
243 | 243 | float: left; |
|
244 | 244 | width: 130px; |
|
245 | 245 | |
|
246 | 246 | &.spacing { |
|
247 | 247 | margin-top: 10px; |
|
248 | 248 | } |
|
249 | 249 | } |
|
250 | 250 | |
|
251 | 251 | .right-label-summary { |
|
252 | 252 | float: left; |
|
253 | 253 | margin-top: 7px; |
|
254 | 254 | } |
|
255 | 255 | } |
|
256 | 256 | |
|
257 | 257 | .left-content { |
|
258 | 258 | width: ~"calc(60% - 20px)"; |
|
259 | 259 | float: left; |
|
260 | 260 | margin: 15px 0 15px 20px; |
|
261 | 261 | |
|
262 | 262 | .rc-user { |
|
263 | 263 | min-width: auto; |
|
264 | 264 | max-width: none; |
|
265 | 265 | min-height: auto; |
|
266 | 266 | padding-right: 5px; |
|
267 | 267 | } |
|
268 | 268 | |
|
269 | 269 | .left-content-avatar { |
|
270 | 270 | width: 45px; |
|
271 | 271 | float: left; |
|
272 | 272 | margin-top: 8px; |
|
273 | 273 | } |
|
274 | 274 | |
|
275 | 275 | .left-content-message { |
|
276 | 276 | float: left; |
|
277 | 277 | width: ~"calc(100% - 45px)"; |
|
278 | 278 | } |
|
279 | 279 | } |
|
280 | 280 | |
|
281 | 281 | .right-content { // similar to form fields |
|
282 | 282 | float: left; |
|
283 | 283 | display: block; |
|
284 | 284 | width: ~"calc(40% - 20px)"; |
|
285 | 285 | text-align: right; |
|
286 | 286 | margin: 15px 20px 15px 0; |
|
287 | 287 | |
|
288 | 288 | .truncate-wrap, |
|
289 | 289 | .truncate { |
|
290 | 290 | max-width: 100%; |
|
291 | 291 | width: 100%; |
|
292 | 292 | } |
|
293 | 293 | |
|
294 | 294 | .commit-long { |
|
295 | 295 | overflow-x: auto; |
|
296 | 296 | } |
|
297 | 297 | |
|
298 | 298 | .commit-info { |
|
299 | 299 | margin-top: 7px; |
|
300 | 300 | } |
|
301 | 301 | |
|
302 | 302 | .tag, .tagtag, .branchtag, .booktag, .metatag, .perm_tag { |
|
303 | 303 | background:transparent; |
|
304 | 304 | border: none; |
|
305 | 305 | box-shadow: none; |
|
306 | 306 | margin-left: 10px; |
|
307 | 307 | font-size: 13px; |
|
308 | 308 | } |
|
309 | 309 | |
|
310 | 310 | .tag span, .tag i { |
|
311 | 311 | color: @grey1; |
|
312 | 312 | } |
|
313 | 313 | } |
|
314 | 314 | .commit { |
|
315 | 315 | color: @grey1; |
|
316 | 316 | margin-bottom: 5px; |
|
317 | 317 | white-space: pre; |
|
318 | 318 | } |
|
319 | 319 | .commit.truncate-wrap { |
|
320 | 320 | overflow:hidden; |
|
321 | 321 | text-overflow: ellipsis; |
|
322 | 322 | } |
|
323 | 323 | .commit-author { |
|
324 | 324 | color: @grey1; |
|
325 | 325 | } |
|
326 | 326 | .commit-date { |
|
327 | 327 | color: @grey4; |
|
328 | 328 | } |
|
329 | 329 | } |
|
330 | 330 | |
|
331 | 331 | // expand commit message |
|
332 | 332 | #message_expand { |
|
333 | 333 | clear: both; |
|
334 | 334 | display: block; |
|
335 | 335 | color: @rcblue; |
|
336 | 336 | cursor: pointer; |
|
337 | 337 | } |
|
338 | 338 | |
|
339 | 339 | #trimmed_message_box { |
|
340 | 340 | max-height: floor(2 * @basefontsize * 1.2); // 2 lines * line-height |
|
341 | 341 | overflow: hidden; |
|
342 | 342 | } |
|
343 | 343 | |
|
344 | 344 | // show/hide comments button |
|
345 | 345 | .show-inline-comments { |
|
346 | 346 | display: inline; |
|
347 | 347 | cursor: pointer; |
|
348 | 348 | |
|
349 | 349 | .comments-show { display: inline; } |
|
350 | 350 | .comments-hide { display: none; } |
|
351 | 351 | |
|
352 | 352 | &.comments-visible { |
|
353 | 353 | .comments-show { display: none; } |
|
354 | 354 | .comments-hide { display: inline; } |
|
355 | 355 | } |
|
356 | 356 | } |
|
357 | 357 | |
|
358 | 358 | // Quick Start section |
|
359 | 359 | |
|
360 | 360 | .empty-repo { |
|
361 | 361 | border: 1px solid #EAEAEA; |
|
362 | 362 | border-bottom: 0; |
|
363 | 363 | border-radius: @border-radius; |
|
364 | 364 | padding: 0 20px; |
|
365 | 365 | } |
|
366 | 366 | |
|
367 | 367 | .empty-repo h3, .quick_start p { |
|
368 | 368 | margin-bottom: 10px; |
|
369 | 369 | } |
|
370 | 370 | |
|
371 | 371 | .quick_start pre { |
|
372 | 372 | background: #FCFEFF; |
|
373 | 373 | border: 1px solid #CBDBEB; |
|
374 | 374 | box-shadow: @button-shadow; |
|
375 | 375 | padding: 10px 15px; |
|
376 | 376 | border-radius: 4px; |
|
377 | 377 | color: @grey2; |
|
378 | 378 | } |
|
379 | 379 | |
|
380 | 380 | .clear-fix { |
|
381 | 381 | clear: both; |
|
382 | 382 | } |
|
383 | 383 | |
|
384 | 384 | .quick_start { |
|
385 | 385 | display: block; |
|
386 | 386 | position: relative; |
|
387 | 387 | border: 1px solid #EAEAEA; |
|
388 | 388 | border-top: 0; |
|
389 | 389 | border-radius: @border-radius; |
|
390 | 390 | padding: 0 20px; |
|
391 | 391 | |
|
392 | 392 | // adds some space to make copy and paste easier |
|
393 | 393 | .left-label, |
|
394 | 394 | .right-content { |
|
395 | 395 | line-height: 1.6em; |
|
396 | 396 | } |
|
397 | 397 | } |
|
398 | 398 | |
|
399 | 399 | |
|
400 | 400 | .submodule { |
|
401 | 401 | .summary-detail { |
|
402 | 402 | width: 100%; |
|
403 | 403 | |
|
404 | 404 | .btn-collapse { |
|
405 | 405 | display: none; |
|
406 | 406 | } |
|
407 | 407 | } |
|
408 | 408 | } |
|
409 | 409 | |
|
410 | 410 | .codeblock-header { |
|
411 | 411 | float: left; |
|
412 | 412 | display: block; |
|
413 | 413 | width: 100%; |
|
414 | 414 | margin: 0; |
|
415 | 415 | |
|
416 | 416 | .stats { |
|
417 | 417 | float: left; |
|
418 | 418 | padding: 10px; |
|
419 | 419 | } |
|
420 | 420 | .stats-filename { |
|
421 | 421 | font-size: 120%; |
|
422 | 422 | } |
|
423 | 423 | .stats-first-item { |
|
424 | 424 | padding: 0px 0px 0px 3px; |
|
425 | 425 | } |
|
426 | 426 | |
|
427 | 427 | .stats-info { |
|
428 | margin-top: 5px; | |
|
429 | 428 | color: @grey4; |
|
430 | 429 | } |
|
431 | 430 | |
|
432 | 431 | .buttons { |
|
433 | 432 | float: right; |
|
434 | 433 | text-align: right; |
|
435 | 434 | color: @grey4; |
|
436 | 435 | padding: 10px; |
|
437 | margin-top: 15px; | |
|
438 | 436 | } |
|
439 | 437 | |
|
440 | 438 | .file-container { |
|
441 | 439 | display: inline-block; |
|
442 | 440 | width: 100%; |
|
443 | 441 | } |
|
444 | 442 | |
|
445 | 443 | } |
|
446 | 444 | |
|
447 | 445 | #summary-menu-stats { |
|
448 | 446 | |
|
449 | 447 | .stats-bullet { |
|
450 | 448 | color: @grey3; |
|
451 | 449 | min-width: 3em; |
|
452 | 450 | } |
|
453 | 451 | |
|
454 | 452 | .repo-size { |
|
455 | 453 | margin-bottom: .5em; |
|
456 | 454 | } |
|
457 | 455 | |
|
458 | 456 | } |
|
459 | 457 | |
|
460 | 458 | .rctable.repo_summary { |
|
461 | 459 | border: 1px solid #eaeaea; |
|
462 | 460 | border-radius: 2px; |
|
463 | 461 | border-collapse: inherit; |
|
464 | 462 | border-bottom: 0; |
|
465 | 463 | |
|
466 | 464 | th { |
|
467 | 465 | background: @grey7; |
|
468 | 466 | border-bottom: 0; |
|
469 | 467 | } |
|
470 | 468 | |
|
471 | 469 | td { |
|
472 | 470 | border-color: #eaeaea; |
|
473 | 471 | } |
|
474 | 472 | |
|
475 | 473 | td.td-status { |
|
476 | 474 | padding: 0 0 0 10px; |
|
477 | 475 | } |
|
478 | 476 | } |
@@ -1,597 +1,603 b'' | |||
|
1 | 1 | { |
|
2 | 2 | "name": "rcicons", |
|
3 | 3 | "css_prefix_text": "icon-", |
|
4 | 4 | "css_use_suffix": false, |
|
5 | 5 | "hinting": true, |
|
6 | 6 | "units_per_em": 1000, |
|
7 | 7 | "ascent": 850, |
|
8 | 8 | "copyright": "RhodeCode GmbH", |
|
9 | 9 | "glyphs": [ |
|
10 | 10 | { |
|
11 | 11 | "uid": "a5f9b6d4d795603e6e29a5b8007cc139", |
|
12 | 12 | "css": "bookmark", |
|
13 | 13 | "code": 59395, |
|
14 | 14 | "src": "custom_icons", |
|
15 | 15 | "selected": true, |
|
16 | 16 | "svg": { |
|
17 | 17 | "path": "M780 990L520 700C510 690 495 690 485 700L225 995C205 1015 180 1000 180 965V35C175 15 190 0 205 0H795C810 0 825 15 825 35V960C825 995 795 1010 780 990Z", |
|
18 | 18 | "width": 1000 |
|
19 | 19 | }, |
|
20 | 20 | "search": [ |
|
21 | 21 | "bookmark" |
|
22 | 22 | ] |
|
23 | 23 | }, |
|
24 | 24 | { |
|
25 | 25 | "uid": "fbc028d3a6a0df72f8f508ff5dfbab72", |
|
26 | 26 | "css": "tag", |
|
27 | 27 | "code": 59397, |
|
28 | 28 | "src": "custom_icons", |
|
29 | 29 | "selected": true, |
|
30 | 30 | "svg": { |
|
31 | 31 | "path": "M459.8 62.5L93.8 53.6C75.9 53.6 62.5 67 62.5 84.8L75.9 450.9C75.9 459.8 80.4 464.3 84.8 473.2L549.1 937.5C562.5 950.9 580.4 950.9 593.8 937.5L946.4 584.8C959.8 571.4 959.8 553.6 946.4 540.2L477.7 71.4C473.2 67 464.3 62.5 459.8 62.5ZM357.1 285.7C357.1 321.4 325.9 352.7 290.2 352.7 254.5 352.7 223.2 321.4 223.2 285.7 223.2 250 254.5 218.8 290.2 218.8S357.1 245.5 357.1 285.7Z", |
|
32 | 32 | "width": 1000 |
|
33 | 33 | }, |
|
34 | 34 | "search": [ |
|
35 | 35 | "tag" |
|
36 | 36 | ] |
|
37 | 37 | }, |
|
38 | 38 | { |
|
39 | 39 | "uid": "1c67c02366438b324c184ff9e356dca1", |
|
40 | 40 | "css": "branch", |
|
41 | 41 | "code": 59396, |
|
42 | 42 | "src": "custom_icons", |
|
43 | 43 | "selected": true, |
|
44 | 44 | "svg": { |
|
45 | 45 | "path": "M875 250C875 174.1 817 116.1 741.1 116.1S607.1 174.1 607.1 250C607.1 299.1 633.9 339.3 669.6 361.6 651.8 504.5 531.3 544.6 459.8 558V245.5C504.5 223.2 531.3 183 531.3 133.9 531.3 58 473.2 0 397.3 0S263.4 58 263.4 133.9C263.4 183 290.2 227.7 330.4 250V750C290.2 772.3 263.4 817 263.4 866.1 263.4 942 321.4 1000 397.3 1000S531.3 942 531.3 866.1C531.3 817 504.5 772.3 464.3 750V692C526.8 683 629.5 660.7 709.8 580.4 767.9 522.3 799.1 450.9 808 366.1 848.2 343.8 875 299.1 875 250ZM397.3 89.3C424.1 89.3 442 107.1 442 133.9S424.1 178.6 397.3 178.6 352.7 160.7 352.7 133.9 370.5 89.3 397.3 89.3ZM397.3 910.7C370.5 910.7 352.7 892.9 352.7 866.1S370.5 821.4 397.3 821.4 442 839.3 442 866.1 419.6 910.7 397.3 910.7ZM741.1 205.4C767.9 205.4 785.7 223.2 785.7 250S767.9 294.6 741.1 294.6 696.4 276.8 696.4 250 718.8 205.4 741.1 205.4Z", |
|
46 | 46 | "width": 1000 |
|
47 | 47 | }, |
|
48 | 48 | "search": [ |
|
49 | 49 | "branch" |
|
50 | 50 | ] |
|
51 | 51 | }, |
|
52 | 52 | { |
|
53 | 53 | "uid": "b75f7b47706aebd803ef370082e8e334", |
|
54 | 54 | "css": "group", |
|
55 | 55 | "code": 59407, |
|
56 | 56 | "src": "custom_icons", |
|
57 | 57 | "selected": true, |
|
58 | 58 | "svg": { |
|
59 | 59 | "path": "M961.5 630.8V646.2C961.5 650 957.7 657.7 950 657.7H788.5 784.6C769.2 638.5 746.2 619.2 707.7 615.4 673.1 607.7 653.8 600 638.5 592.3 646.2 584.6 657.7 580.8 669.2 576.9 715.4 569.2 726.9 553.8 734.6 542.3 742.3 530.8 742.3 519.2 734.6 503.8 726.9 488.5 703.8 461.5 703.8 423.1 703.8 384.6 703.8 319.2 776.9 319.2H784.6 792.3C865.4 323.1 869.2 384.6 865.4 423.1 865.4 461.5 842.3 492.3 834.6 503.8 826.9 519.2 826.9 530.8 834.6 542.3 842.3 553.8 857.7 569.2 900 576.9 953.8 580.8 961.5 623.1 961.5 630.8 961.5 630.8 961.5 630.8 961.5 630.8ZM253.8 646.2C269.2 630.8 292.3 615.4 323.1 611.5 361.5 603.8 384.6 596.2 396.2 584.6 388.5 576.9 376.9 569.2 361.5 565.4 315.4 557.7 303.8 542.3 296.2 530.8 288.5 519.2 288.5 507.7 296.2 492.3 303.8 476.9 326.9 450 326.9 411.5 326.9 373.1 326.9 307.7 253.8 307.7H246.2 234.6C161.5 311.5 157.7 373.1 161.5 411.5 161.5 450 184.6 480.8 192.3 492.3 200 507.7 200 519.2 192.3 530.8 184.6 542.3 169.2 557.7 126.9 565.4 80.8 573.1 73.1 615.4 73.1 619.2 73.1 619.2 73.1 619.2 73.1 619.2V634.6C73.1 638.5 76.9 646.2 84.6 646.2H246.2 253.8ZM707.7 634.6C634.6 623.1 611.5 600 600 580.8 588.5 561.5 588.5 542.3 600 519.2 611.5 496.2 650 450 653.8 388.5 657.7 326.9 653.8 223.1 534.6 219.2H519.2 503.8C384.6 223.1 380.8 323.1 384.6 384.6 388.5 446.2 423.1 492.3 438.5 515.4 450 538.5 450 557.7 438.5 576.9 426.9 596.2 403.8 619.2 330.8 630.8 257.7 642.3 246.2 711.5 246.2 719.2 246.2 719.2 246.2 719.2 246.2 719.2V742.3C246.2 750 253.8 757.7 261.5 757.7H519.2 776.9C784.6 757.7 792.3 750 792.3 742.3V719.2C792.3 719.2 792.3 719.2 792.3 719.2 788.5 715.4 780.8 646.2 707.7 634.6Z", |
|
60 | 60 | "width": 1000 |
|
61 | 61 | }, |
|
62 | 62 | "search": [ |
|
63 | 63 | "group" |
|
64 | 64 | ] |
|
65 | 65 | }, |
|
66 | 66 | { |
|
67 | 67 | "uid": "7ae0ef039bb0217d9581e44b09448905", |
|
68 | 68 | "css": "fork", |
|
69 | 69 | "code": 59409, |
|
70 | 70 | "src": "custom_icons", |
|
71 | 71 | "selected": true, |
|
72 | 72 | "svg": { |
|
73 | 73 | "path": "M792.3 196.2C792.3 138.5 746.2 96.2 692.3 96.2 634.6 96.2 592.3 142.3 592.3 196.2 592.3 230.8 611.5 261.5 638.5 280.8 626.9 365.4 569.2 403.8 511.5 423.1 453.8 407.7 396.2 369.2 384.6 280.8 411.5 261.5 430.8 230.8 430.8 196.2 430.8 138.5 384.6 96.2 330.8 96.2S223.1 138.5 223.1 196.2C223.1 234.6 246.2 269.2 276.9 284.6 288.5 392.3 353.8 473.1 457.7 511.5V673.1C426.9 692.3 407.7 723.1 407.7 761.5 407.7 819.2 453.8 861.5 507.7 861.5S607.7 815.4 607.7 761.5C607.7 723.1 588.5 692.3 557.7 673.1V511.5C661.5 473.1 726.9 392.3 738.5 284.6 769.2 265.4 792.3 234.6 792.3 196.2ZM326.9 161.5C346.2 161.5 361.5 176.9 361.5 196.2S346.2 226.9 326.9 226.9 292.3 215.4 292.3 196.2 307.7 161.5 326.9 161.5ZM507.7 796.2C488.5 796.2 473.1 780.8 473.1 761.5S488.5 726.9 507.7 726.9C526.9 726.9 542.3 742.3 542.3 761.5S526.9 796.2 507.7 796.2ZM692.3 161.5C711.5 161.5 726.9 176.9 726.9 196.2S711.5 226.9 692.3 226.9 657.7 211.5 657.7 192.3 673.1 161.5 692.3 161.5Z", |
|
74 | 74 | "width": 1000 |
|
75 | 75 | }, |
|
76 | 76 | "search": [ |
|
77 | 77 | "fork" |
|
78 | 78 | ] |
|
79 | 79 | }, |
|
80 | 80 | { |
|
81 | 81 | "uid": "65e66c3e7d74e2c345fb78fadd400d3f", |
|
82 | 82 | "css": "rhodecode", |
|
83 | 83 | "code": 59441, |
|
84 | 84 | "src": "custom_icons", |
|
85 | 85 | "selected": true, |
|
86 | 86 | "svg": { |
|
87 | 87 | "path": "M174.6 216.8C173.4 220.9 172.2 225 171 229.1 168.1 239.1 165.2 249.1 162.3 259.1 158.7 271.6 155 284.2 151.4 296.7 148 308.4 144.6 320.1 141.2 331.8 139 339.3 136.8 346.8 134.7 354.3 134.4 355.4 134.1 356.5 133.7 357.6 133.7 357.7 133.9 358.2 134 358.3 134.3 359 134.5 359.7 134.8 360.5 137.2 367.3 139.7 374.1 142.1 381 146 392 149.9 403 153.9 414.1 158.3 426.5 162.8 439 167.2 451.4 171.1 462.5 175.1 473.6 179 484.7 181.5 491.7 184 498.6 186.4 505.6 186.8 506.7 187.2 507.7 187.5 508.8 187.8 509.6 188.6 510.4 189 511.1 192.8 516.9 196.5 522.6 200.3 528.4 206.5 537.9 212.7 547.4 219 556.9 226.2 567.9 233.4 578.9 240.6 590 247.3 600.3 254.1 610.6 260.8 620.9 265.6 628.2 270.4 635.6 275.2 642.9 276.4 644.8 277.6 646.6 278.9 648.5 279.2 649 279.5 649.5 279.8 649.8 282.7 652.6 285.5 655.4 288.4 658.2 294.6 664.3 300.9 670.5 307.1 676.6 315.5 684.9 323.9 693.2 332.4 701.4 341.8 710.6 351.2 719.9 360.6 729.1 369.8 738.1 378.9 747.1 388.1 756.1 395.8 763.7 403.6 771.3 411.3 778.9 416.4 783.9 421.5 788.9 426.6 793.9 428.2 795.5 429.8 797.3 431.6 798.6 438.9 803.9 446.1 809.2 453.4 814.5 463.7 822 473.9 829.5 484.2 837 487.6 839.5 491.1 842 494.5 844.5 495.3 845.1 496.1 845.7 496.9 846.3 497.2 846.5 497.2 846.6 497.6 846.4 504.7 842.7 511.8 839.1 518.9 835.4 530.3 829.5 541.7 823.6 553.1 817.7 559.2 814.5 565.4 811.4 571.5 808.2 571.9 808 572.3 807.1 572.6 806.8 573.7 805.4 574.8 804 576 802.5 580.2 797.2 584.3 791.9 588.5 786.7 594.7 778.9 600.8 771.1 607 763.3 614.5 753.8 622 744.3 629.5 734.8 637.7 724.5 645.8 714.1 654 703.8 662.1 693.5 670.3 683.2 678.4 672.9 685.9 663.5 693.3 654 700.8 644.6 706.9 636.9 713 629.2 719.1 621.5 723.2 616.4 727.2 611.2 731.3 606.1 732.7 604.4 734 602.6 735.4 600.9 735.2 600.8 734.8 600.8 734.6 600.7 733.8 600.5 733 600.4 732.2 600.2 729.1 599.6 726 598.9 722.9 598.2 718 597.1 713 596 708.1 594.8 701.5 593.2 694.9 591.5 688.3 589.7 680.2 587.5 672.2 585.2 664.1 582.9 654.7 580.1 645.4 577.2 636.1 574.1 625.6 570.6 615.2 567 604.8 563.3 593.4 559.1 582 554.8 570.8 550.2 558.6 545.3 546.6 540.1 534.6 534.8 521.9 529.1 509.3 523.1 496.8 516.8 483.7 510.2 470.7 503.4 457.9 496.2 444.6 488.7 431.4 480.9 418.5 472.8 405.1 464.4 392 455.6 379.1 446.4 365.9 437 352.9 427.1 340.3 416.9 327.4 406.4 314.8 395.5 302.7 384.2 290.3 372.6 278.3 360.6 266.8 348.1 255.1 335.3 243.8 322.1 233.2 308.4 222.3 294.4 212 279.9 202.4 265 192.5 249.7 183.4 233.9 175 217.8 175 217.4 174.8 217.1 174.6 216.8ZM172.1 214.2C170.7 218.7 169.3 223.3 167.8 227.8 164.5 238.5 161.1 249.2 157.8 259.9 153.9 272.4 150 285 146.1 297.5 143 307.5 139.9 317.4 136.7 327.4 135.9 330.1 135 332.7 134.2 335.4 134 336.1 133.6 336.7 133.8 337.4 135.4 342.2 137 347.1 138.6 351.9 141.9 361.9 145.2 371.8 148.6 381.8 152.7 394.1 156.8 406.5 160.9 418.8 164.9 430.8 168.9 442.8 172.9 454.8 175.9 463.7 178.8 472.6 181.8 481.4 182.6 483.8 183.4 486.2 184.2 488.7 184.4 489.4 184.6 490.1 184.9 490.8 187.2 495 189.5 499.2 191.8 503.4 196.8 512.6 201.9 521.8 206.9 531 213.2 542.4 219.4 553.9 225.7 565.3 231.7 576.2 237.6 587.1 243.6 598 247.8 605.6 251.9 613.2 256.1 620.8 257.3 623 258.2 625.4 259.9 627.2 264.1 631.7 268.3 636.2 272.5 640.7 280.2 648.9 287.9 657.2 295.5 665.4 304.5 675 313.5 684.7 322.4 694.3 330.5 703 338.6 711.7 346.7 720.4 351.8 725.8 356.8 731.3 361.9 736.7 363.5 738.4 365 740 366.6 741.6 372.3 747.3 378 753 383.7 758.7 392.5 767.5 401.2 776.2 410 785 419.1 794.1 428.3 803.3 437.4 812.4 444.2 819.2 451.1 826.1 457.9 832.9 459.6 834.6 461.3 836.3 463 838 463.3 838.3 463.6 838.6 463.8 838.8 463.9 838.9 465.1 838.7 465.3 838.6 475.9 837.2 486.5 835.8 497 834.5 505.6 833.4 514.1 832.3 522.7 831.2 523 831.2 523.7 830.1 523.9 829.9 525.1 828.6 526.3 827.2 527.6 825.9 532.1 820.9 536.7 815.9 541.2 810.9 547.9 803.5 554.6 796.1 561.4 788.7 569.6 779.7 577.7 770.7 585.9 761.8 594.8 752 603.6 742.3 612.5 732.5 621.3 722.8 630.1 713.1 639 703.4 647 694.5 655.1 685.7 663.1 676.8 669.6 669.6 676.2 662.4 682.7 655.2 687 650.5 691.3 645.8 695.6 641 696.6 639.9 697.7 638.7 698.7 637.6 698.9 637.4 699.6 636.9 699.6 636.6 699.6 636.5 696.6 635.7 696.5 635.7 693.5 634.8 690.4 633.9 687.4 633 682.6 631.5 677.8 630 673 628.4 666.6 626.3 660.1 624.1 653.8 621.8 645.9 619 638.1 616.1 630.3 613.1 621.2 609.6 612.1 606 603.1 602.2 592.9 598 582.8 593.6 572.8 589 561.8 584 550.8 578.8 540 573.4 528.3 567.6 516.7 561.6 505.2 555.3 493 548.7 480.9 541.8 469 534.6 456.5 527.1 444.1 519.3 431.9 511.2 419.2 502.8 406.7 494 394.5 484.9 381.8 475.5 369.5 465.8 357.4 455.7 345 445.3 332.8 434.6 321.1 423.4 309.1 412 297.4 400.2 286.2 388 274.7 375.5 263.7 362.6 253.2 349.3 242.5 335.7 232.3 321.7 222.8 307.2 213 292.4 203.9 277.2 195.5 261.7 186.8 246.5 179 230.5 172.1 214.2ZM169.5 204C168.8 207.8 168.1 211.6 167.3 215.4 165.5 224.9 163.7 234.5 161.9 244 159.5 256.5 157.1 269 154.7 281.5 152.3 294.2 149.8 307 147.4 319.7 145.5 329.9 143.5 340.1 141.6 350.3 140.7 355.2 139.7 360.1 138.8 365 138.7 365.7 139.1 366.4 139.3 367 140.2 369.6 141.1 372.2 142 374.8 145.4 384.5 148.7 394.3 152.1 404 156.4 416.4 160.7 428.7 165 441.1 168.8 452.1 172.6 463 176.4 474 178.3 479.5 180.2 485 182.1 490.5 182.3 491.2 182.7 491.8 183 492.4 184.2 494.8 185.4 497.1 186.5 499.5 190.9 508.4 195.4 517.2 199.8 526.1 205.6 537.7 211.4 549.3 217.2 560.9 222.7 571.9 228.2 583 233.8 594 237.4 601.2 241 608.3 244.6 615.5 245.2 616.6 245.7 617.7 246.3 618.8 246.7 619.6 247.6 620.4 248.2 621.1 252.8 626.6 257.4 632.1 262 637.7 269.5 646.7 276.9 655.6 284.4 664.6 292.8 674.7 301.3 684.9 309.7 695 317.2 704 324.8 713.1 332.3 722.1 337 727.8 341.8 733.5 346.5 739.1 347.2 740 347.9 740.8 348.7 741.7 348.9 741.9 349.2 742 349.4 742.2 350.2 742.7 350.9 743.2 351.7 743.7 358.7 748.5 365.8 753.3 372.8 758.1 383.3 765.3 393.9 772.5 404.4 779.7 414.6 786.6 424.7 793.6 434.9 800.5 440.8 804.5 446.7 808.6 452.7 812.6 456.3 815.1 459.5 818.1 462.9 820.8 472.5 828.7 482.1 836.7 491.7 844.6 498.5 850.2 505.4 855.9 512.2 861.5 512.8 862 512.7 861.9 513.3 861.3 514.2 860.3 515.2 859.2 516.1 858.2 520 853.9 524 849.6 527.9 845.3 534 838.6 540.2 831.9 546.3 825.2 554 816.8 561.7 808.3 569.4 799.9 578.1 790.4 586.7 781 595.4 771.5 604.4 761.7 613.3 751.9 622.3 742.1 630.9 732.6 639.6 723.2 648.2 713.7 655.9 705.3 663.6 696.9 671.3 688.5 677.4 681.8 683.5 675.1 689.6 668.4 693.5 664.1 697.4 659.9 701.3 655.6 702.4 654.4 703.5 653.2 704.6 652 704.6 652 704.6 652 704.6 652 704.6 652 704.6 652 704.6 652 704.6 652.1 701.6 651.3 701.5 651.3 698.5 650.5 695.5 649.5 692.6 648.6 687.9 647.1 683.1 645.5 678.4 643.8 672.1 641.6 665.8 639.2 659.5 636.9 651.8 634 644.1 630.9 636.4 627.8 627.5 624.1 618.6 620.3 609.7 616.4 599.7 612 589.8 607.4 580 602.7 569.2 597.5 558.4 592.1 547.7 586.6 536.2 580.6 524.8 574.4 513.4 568 501.4 561.2 489.5 554.2 477.7 546.9 465.3 539.3 453.1 531.4 441.1 523.3 428.6 514.8 416.3 506.1 404.2 497 391.7 487.7 379.5 478 367.5 468 355.2 457.8 343.2 447.2 331.5 436.3 319.6 425.2 308 413.6 296.8 401.7 285.4 389.6 274.5 377.1 264 364.3 253.3 351.2 243.2 337.8 233.6 323.9 223.8 309.8 214.6 295.4 206.1 280.5 197.4 265.4 189.4 249.9 182.1 234 177.7 224.2 173.5 214.2 169.5 204ZM866 183.5C863.9 179.4 861.1 176.2 857.1 174 851.9 171.1 846.2 168.9 840.7 166.5 829.5 161.7 818.2 157.4 806.7 153.4 783.6 145.4 760 138.9 736.3 132.9 711.7 126.7 687.1 120.9 662.3 115.7 637.1 110.4 611.7 105.6 586.3 101.4 561.2 97.2 536 93.1 510.5 91.1 497.8 90.1 485 89.9 472.4 91.3 465.9 92 459.4 93.2 453 94.2 446.6 95.2 440.1 96.2 433.7 97.3 408.2 101.5 382.8 106 357.4 111 332.2 115.9 307.1 121.2 282.1 126.9 257.2 132.5 232.6 139.2 208.4 147.3 196.3 151.4 184.2 155.8 172.3 160.5 166.4 162.8 160.5 165.2 154.6 167.7 151.7 168.9 148.8 170.2 145.8 171.4 143.2 172.5 140.6 173.5 138.1 174.7 134 176.7 130.6 179.7 128.3 183.6 127 185.8 126.2 188.2 125.3 190.6 124.2 193.6 123.1 196.6 122.1 199.6 118.1 211.5 114.9 223.7 112.5 236 107.7 260.4 106 285.4 106.8 310.2 107.2 322.7 108.2 335.3 109.7 347.7 111.2 360.2 112.7 372.8 115.1 385.2 119.8 410.4 126.7 435.1 134.8 459.3 138.9 471.4 143.3 483.5 147.9 495.4 152.2 506.5 157.5 517.3 162.7 528 173 549.2 184.4 569.8 196.6 589.9 208.8 609.9 221.9 629.3 235.7 648.1 249.5 666.8 264.1 685 279.3 702.6 295.3 721.1 311.7 739.2 328.6 756.9 345.6 774.8 363 792.2 381 809 398.9 825.9 417.4 842.2 436.4 857.8 445.6 865.4 454.9 872.8 464.2 880.2 473.6 887.7 483.1 895.1 492 903.2 494.3 905.2 496.5 907.3 498.7 909.5 498.9 909.7 499.7 910.8 500 910.8 500.2 910.8 500.5 910.8 500.7 910.8 501.2 910.8 502 911 502.5 910.8 507.3 907.1 512 903.3 516.8 899.6 526.2 892.1 535.6 884.6 544.9 876.9 563.3 861.7 581.4 846.2 599.2 830.3 616.9 814.5 634.1 798.2 651 781.5 667.9 764.7 684.4 747.5 700.3 729.7 716.3 711.8 731.8 693.4 746.5 674.4 761 655.7 774.8 636.5 787.8 616.8 800.7 597.2 812.8 577 823.8 556.2 835 535.1 845.2 513.5 854.3 491.4 863.4 469.1 871.2 446.3 877.3 423 883.4 399.9 887.8 376.4 890.3 352.7 892.9 328.6 893.4 304.3 892 280 891.8 276.9 891 273.8 890.3 270.7 889.7 267.7 889 264.6 888.4 261.6 887.2 255.7 886 249.9 884.7 244 882.3 233 879.7 222 876.5 211.1 873.4 201.8 870.1 192.5 866 183.5 863.5 178.4 878.8 211.7 866 183.5ZM814.8 393.5C808.1 418.2 799.5 442.5 789.4 466 780 487.9 770 509.6 758.5 530.5 747.4 550.7 735.1 570.3 722 589.3 708.8 608.4 694.7 626.8 680 644.8 664.8 663.4 649 681.5 632.7 699.1 615.9 717.3 598.5 734.9 580.5 752 562.5 769.1 544.1 785.7 525.1 801.6 515.7 809.5 506.1 817.3 496.5 824.9 496.1 825.2 495.2 826.3 494.7 826.3 494 826.3 493.3 826.3 492.6 826.3 492 826.3 491.4 825.5 491 825.1 490.5 824.6 490 824.1 489.5 823.6 488.4 822.6 487.2 821.5 486.1 820.5 481.6 816.6 476.9 813.1 472.2 809.4 469.9 807.6 467.6 805.7 465.3 803.8 463.1 801.9 461 799.8 458.8 797.8 454.2 793.7 449.7 789.6 445.2 785.5 435.9 777 426.6 768.5 417.5 759.8 408.4 751.1 399.5 742.3 390.9 733.2 386.7 728.8 382.7 724.3 378.4 720 374.2 715.8 370 711.5 365.8 707.2 349.1 690 332.9 672.5 317.4 654.3 301.8 636 286.9 617 273.1 597.3 259.2 577.5 246.4 556.9 234.5 535.8 222.8 515 212.1 493.7 202.6 471.8 193.1 449.9 184.8 427.4 177.9 404.6 176.1 398.6 174.4 392.6 173.1 386.5 171.7 380.1 170.6 373.6 169.6 367.1 167.6 354.2 166.3 341.2 165.5 328.2 164.7 315.3 164.3 302.3 164.5 289.3 164.7 276.7 165.9 264.2 167.5 251.7 167.9 248.5 168.3 245.4 168.7 242.2 168.9 240.6 169.1 239.1 169.3 237.5 169.5 235.9 169.6 234.3 169.8 232.7 170.1 230.3 171.1 228.1 171.7 225.7 172 224.5 172.2 223.2 172.2 221.9 172.2 220.8 172.8 220.1 173.6 219.5 174.6 218.8 175.6 218.3 176.5 217.5 177.1 217 177.6 216.6 178.4 216.3 179.2 216 180.1 215.7 180.9 215.3 183.9 214.2 186.8 213 189.8 211.9 195.7 209.7 201.6 207.5 207.6 205.3 231.3 196.7 255.3 189 279.7 182.4 292 179.1 304.3 176.1 316.7 173.5 322.9 172.2 329.1 170.6 335.4 169.3 341.7 167.9 348 166.6 354.3 165.4 379.8 160.4 405.4 156.3 431.1 152.5 444 150.6 457 148.8 470 147 473.2 146.6 476.5 146.1 479.7 145.7 481.3 145.5 482.8 145.3 484.4 145.1 485.7 144.9 487.1 145 488.4 145.1 493.9 145.1 499.5 145.3 504.9 146.3 506.2 146.5 507.4 146.8 508.6 147.1 510.1 147.5 511.5 147.8 513 148 516.1 148.4 519.2 148.9 522.3 149.3 528.6 150.2 534.8 151.1 541.1 152 553.7 153.8 566.4 155.7 579 157.7 604.4 161.7 629.7 166 654.8 171.4 680 176.8 705 183.2 729.7 190.3 742.1 193.9 754.4 197.7 766.6 201.7 772.7 203.7 778.7 205.8 784.7 207.9 787.7 209 790.7 210 793.7 211.1 795.1 211.6 796.6 212.1 798 212.7 798.7 213 799.4 213.2 800.1 213.5 800.8 213.8 801.9 214 802.4 214.5 803.6 215.7 805.3 216.5 806.3 217.9 806.8 218.7 807.1 219.5 807.2 220.5 807.3 221.2 807.2 221.8 807.4 222.5 807.7 223.4 807.9 224.3 808.1 225.2 809.8 231.5 811.2 237.9 812.3 244.4 813.4 250.8 814.1 257.2 814.5 263.6 814.7 266.8 814.8 270 814.9 273.2 814.9 274 814.9 274.7 814.9 275.5 814.9 276.3 815.2 277.1 815.3 277.8 815.7 279.5 816 281.1 816.4 282.8 821.3 306.5 822.7 330.7 820.7 354.8 819.6 367.7 817.6 380.7 814.8 393.5 807.1 421.7 822.5 357.6 814.8 393.5ZM617.6 393.5C616.1 389 614.6 384.5 613.1 379.9 612.9 379.3 612.7 378.7 612.5 378.1 612.4 377.7 612.5 377.1 612.4 376.7 612.3 376.1 612.2 375.5 612.1 374.9 611.8 373.8 611.4 372.8 610.8 371.9 609.7 370.1 608.1 368.5 606.5 367 604.7 365.2 602.4 362.7 599.6 362.7 601.6 360.7 604.3 360 606.5 358.3 607.6 357.4 608.5 356.5 609.7 355.7 610.5 355.2 611.6 354.7 612.1 353.8 612.3 353.4 612.4 352.9 612.4 352.5 612.9 352 613.3 351.5 613.7 350.9 614.4 349.8 614.7 348.6 614.9 347.3 615.1 345.1 615 342.9 615 340.7 615 338.4 615 336.1 615 333.8 615 331.4 615 329 614.4 326.6 613.1 321.5 610 316.8 606.4 313.1 604.7 311.4 603 309.9 601 308.6 598.3 306.9 595.5 305.5 592.7 304.1 589.9 302.7 586.9 301.8 583.8 301.4 581.4 301.1 579 301.1 576.6 301.1 573.9 301.1 571.2 301.1 568.5 301.1 556.2 301.1 543.8 301.1 531.5 301.1 526.9 301.1 522.3 301.1 517.7 301.1 516.9 301.1 516.1 301.1 515.2 301.1 515.1 301.1 515.2 305.3 515.2 305.6 515.2 308.8 515.2 311.9 515.2 315.1 515.2 316.2 515.2 317.3 515.2 318.4 515.2 318.9 515 319.1 515.5 319.1 516.7 319.1 528 319 528 319.2 528 327.2 528 335.2 528 343.2 528 355.8 528 368.3 528 380.9 528 384.6 528 388.3 528 392 528 392.2 528.1 393.4 527.9 393.4 525.4 393.4 522.8 393.4 520.3 393.4 518.9 393.4 517.6 393.4 516.2 393.4 515.9 393.4 515.2 393.2 515.2 393.6 515.2 395.7 515.2 397.8 515.2 400 515.2 401 515.2 414 515.2 414 524.7 414 534.3 414 543.8 414 549.3 414 554.8 414 560.2 414 561.4 414 562.5 414 563.7 414 564 414 563.8 411.1 563.8 410.7 563.8 405.1 563.8 399.6 563.8 394 563.8 393.4 563.9 393.5 563.3 393.5 562 393.5 560.7 393.5 559.3 393.5 557.8 393.5 556.3 393.5 554.8 393.5 554.6 393.5 553.5 393.7 553.5 393.4 553.5 388.4 553.5 383.4 553.5 378.4 553.5 375.6 553.5 372.9 553.5 370.1 553.5 369.4 553.5 368.8 553.5 368.1 553.5 367.7 554.2 367.9 554.5 367.9 557.4 367.9 560.2 367.9 563.1 367.9 565 367.9 566.9 367.9 568.8 367.9 570.1 367.9 571.6 367.7 572.8 368.1 573.9 368.4 574.8 369 575.7 369.7 576.8 370.6 578.3 371.8 578.9 373.1 579.2 373.8 579.2 374.5 579.2 375.3 579.2 376.6 579.6 377.7 580.2 378.9 580.7 380 581.3 381 581.6 382.2 581.7 382.6 581.7 383 581.8 383.4 581.9 384 582 384.6 582.1 385.1 583.1 390.9 584.2 396.6 585.2 402.4 585.6 404.9 586.1 407.3 586.5 409.8 586.6 410.3 586.7 410.8 586.8 411.3 586.8 411.4 587.2 411.4 587.4 411.4 597.8 411.4 608.3 411.4 618.7 411.4 619.2 411.4 619.6 411.4 620.1 411.4 620.2 411.4 620.2 410.7 620.2 410.6 620.2 408.2 620.2 405.7 620.2 403.3 620.2 398.3 620.2 393.3 620.2 388.4 620.2 388.4 620.2 388.4 620.2 388.4 619.3 390.1 618.5 391.8 617.6 393.5ZM592 339.7C592 342 589.2 342.8 587.7 344.1 587.4 344.3 587.1 344.6 586.9 344.8 586.7 344.8 586.4 344.8 586.2 344.9 585.8 345 585.4 345.2 585.1 345.4 584.4 345.9 583.9 346.6 583.2 347 582.1 347.5 580.7 347.3 579.6 347.3 577.9 347.3 576.3 347.3 574.6 347.3 573.9 347.3 573.2 347.3 572.5 347.3 569.5 347.3 566.4 347.3 563.4 347.3 563 347.3 558.8 347.4 558.8 347.2 558.8 337.9 558.8 328.5 558.8 319.2 558.8 319.1 571.7 319.2 573 319.2 577 319.2 581 319.1 584.9 320.1 586.4 320.5 587.8 321 589.2 321.6 590.1 322.1 591 323.2 591.6 324 593.1 325.7 594.1 327.8 594.5 330 594.6 330.7 594.6 331.3 594.6 332 594.3 332.6 594 333.2 593.7 333.9 593.3 334.7 592.9 335.5 592.6 336.3 592.1 337.4 592 338.5 592 339.7ZM722.6 393.5C722.6 384.2 722.6 374.9 722.6 365.6 722.6 357.1 720.9 348 714.6 341.9 707.5 335.1 696.4 333.9 687 334.7 685.1 334.9 683.2 335.3 681.4 336.1 680.4 336.5 679.5 336.9 678.6 337.6 678 338.1 677.3 338.5 676.7 338.8 673.6 340.4 670.5 341.6 668.8 344.9 668.8 335.9 668.8 326.8 668.8 317.8 668.8 311.9 668.8 306 668.8 300.1 668.8 298.4 668.8 296.6 668.8 294.9 668.8 294.4 669.1 293.7 668.5 293.7 657.9 293.7 647.3 293.7 636.7 293.7 635.5 293.7 634.2 293.7 633 293.7 633 293.7 633 297.8 633 298.1 633 303.4 633 308.7 633 314 633 314.3 633.8 314.2 634 314.2 635.4 314.2 636.7 314.2 638.1 314.2 640.6 314.2 643.2 314.2 645.7 314.2 645.9 314.2 645.8 319.4 645.8 319.8 645.8 331.2 645.8 342.6 645.8 353.9 645.8 364.9 645.8 375.8 645.8 386.8 645.8 388 645.8 389.2 645.8 390.3 645.8 391.2 645.7 391 644.6 391 641.6 391 638.7 391 635.7 391 634.8 391 633.9 391 633 391 632.9 391 632.9 391.9 632.9 392 632.9 397.7 632.9 403.4 632.9 409 632.9 409.8 632.9 410.5 632.9 411.3 632.9 411.5 633 411.5 633.2 411.5 634.5 411.5 635.9 411.5 637.2 411.5 649.1 411.5 661 411.5 672.9 411.5 673.4 411.5 681.5 411.5 681.5 411.5 681.5 406.5 681.5 401.5 681.5 396.5 681.5 394.7 681.5 392.9 681.5 391.1 681.5 391.1 675.6 391.1 675.2 391.1 674.8 391.1 668.7 391.1 668.7 391.1 668.7 389.8 668.7 388.5 668.7 387.3 668.7 381.2 668.7 375 668.7 368.9 668.7 366.5 668.7 364.2 668.7 361.8 668.7 361.3 668.7 360.9 668.7 360.4 668.7 360 670.3 358.8 670.6 358.5 671.7 357.5 672.8 356.5 674.2 355.8 674.7 355.5 675.3 355.3 675.8 355.3 676.5 355.2 676.8 354.8 677.4 354.3 678.5 353.5 679.7 353 681 352.8 683.6 352.4 685.8 352.7 687.9 354.2 689.1 355.1 690.1 356.1 691.2 357.2 692 358 692.7 358.8 693.3 359.8 694.2 361.6 694.3 363.7 694.3 365.7 694.4 369.3 694.3 372.9 694.3 376.6 694.3 387.8 694.3 399 694.3 410.3 694.3 410.9 694 411.6 694.7 411.6 696.4 411.6 698.1 411.6 699.8 411.6 706 411.6 712.3 411.6 718.5 411.6 722.4 411.6 726.3 411.6 730.2 411.6 730.2 411.6 730.2 398.5 730.2 397.5 730.2 395.4 730.2 393.3 730.2 391.2 727.8 391.8 725.2 392.6 722.6 393.5ZM730.3 270.6C727.9 270.6 725.4 270.6 723 270.6 722 270.6 721.1 270.6 720.1 270.6 720 270.6 719.6 271.3 719.6 271.4 716.5 276 713.4 280.6 710.4 285.3 708.9 287.5 707.4 289.7 706 292 705.6 292.5 705.3 293.1 704.9 293.6 704.6 294.1 704.8 294.9 704.8 295.4 704.8 295.6 704.8 298.8 704.8 298.8 705.4 298.8 706 298.8 706.5 298.8 709.5 298.8 712.4 298.8 715.4 298.8 717.8 298.8 720.1 298.8 722.5 298.8 723 298.8 722.7 299.6 722.7 299.9 722.7 301.4 722.7 302.9 722.7 304.4 722.7 305.8 722.7 307.1 722.7 308.5 722.7 309.3 723 309.1 723.8 309.1 725.3 309.1 726.9 309.1 728.4 309.1 728.7 309.1 730.3 309.3 730.3 308.9 730.3 306.2 730.3 303.4 730.3 300.7 730.3 300.4 730.1 298.8 730.5 298.8 731.9 298.8 733.3 298.8 734.6 298.8 734.7 298.8 735.4 298.8 735.4 298.8 735.4 298.2 735.4 297.7 735.4 297.1 735.4 296.9 735.4 293.7 735.4 293.7 734.1 293.7 732.9 293.7 731.6 293.7 731.1 293.7 730.3 294 730.3 293.4 730.3 285.7 730.3 278.1 730.3 270.6ZM722.6 285.9C722.6 287.2 722.6 288.5 722.6 289.7 722.6 290.6 722.6 291.4 722.6 292.3 722.6 292.5 722.7 293.4 722.6 293.6 722.5 293.7 721.6 293.6 721.5 293.6 720.6 293.6 719.7 293.6 718.8 293.6 717.5 293.6 716.2 293.6 715 293.6 716.3 291.6 717.7 289.6 719 287.6 719.6 286.7 720.2 285.9 720.8 285.1 722.4 283.1 722.6 280.7 722.6 278.2 722.6 280.8 722.6 283.4 722.6 285.9ZM763.6 288.5C760.9 285.8 756.2 285.9 752.6 285.9 752 285.9 751.4 285.9 750.8 285.9 750.8 285.9 750.8 284.8 750.8 284.7 750.8 283.4 750.8 282.1 750.8 280.8 750.8 280.7 763.9 280.8 765.2 280.8 765.7 280.8 766.2 281 766.2 280.5 766.2 279.1 766.2 277.7 766.2 276.4 766.2 275.3 766.2 274.2 766.2 273.2 766.2 273.2 764.9 273.2 764.9 273.2 759.2 273.2 753.5 273.2 747.8 273.2 747.2 273.2 746.5 273.2 745.9 273.2 745.7 273.2 745.7 273.6 745.7 273.8 745.4 276 745.1 278.2 744.9 280.4 744.3 284.8 743.8 289.3 743.2 293.7 747 293.7 751.5 293.1 755.1 294.8 757.9 296.2 759 299.4 758.5 302.4 758 305.8 754.4 306.5 751.5 306.5 749.6 306.5 743.2 307 743.2 303.9 742.3 306.5 741.5 309 740.6 311.6 742.3 311.6 744 312.6 745.6 313.2 748 314.1 750.5 314.3 753 314.1 756.9 313.8 761 312.5 763.6 309.4 766.3 306.1 766.2 301.9 766.2 297.8 766.2 295.6 766.2 293.3 765.7 291.1 765.5 290.1 765 288.6 763.7 288.5 763.7 288.5 763.6 288.5 763.6 288.5 761 285.9 766.2 288.5 763.6 288.5Z", |
|
88 | 88 | "width": 1000 |
|
89 | 89 | }, |
|
90 | 90 | "search": [ |
|
91 | 91 | "rhodecode" |
|
92 | 92 | ] |
|
93 | 93 | }, |
|
94 | 94 | { |
|
95 | 95 | "uid": "e5ad8728e6d6290aff4b6ffcfcaa9167", |
|
96 | 96 | "css": "up", |
|
97 | 97 | "code": 59442, |
|
98 | 98 | "src": "custom_icons", |
|
99 | 99 | "selected": true, |
|
100 | 100 | "svg": { |
|
101 | 101 | "path": "M686.5 595.8L513.6 379.1C506.3 369.9 492.4 369.9 485.1 379.1L312.2 595.8C302.7 607.8 311.2 625.4 326.5 625.4H672.2C687.5 625.4 696 607.8 686.5 595.8Z", |
|
102 | 102 | "width": 1000 |
|
103 | 103 | }, |
|
104 | 104 | "search": [ |
|
105 | 105 | "up" |
|
106 | 106 | ] |
|
107 | 107 | }, |
|
108 | 108 | { |
|
109 | 109 | "uid": "6e459e39444c93a2c017f258186765d6", |
|
110 | 110 | "css": "unlock", |
|
111 | 111 | "code": 59399, |
|
112 | 112 | "src": "custom_icons", |
|
113 | 113 | "selected": true, |
|
114 | 114 | "svg": { |
|
115 | 115 | "path": "M780.8 434.6H396.2V342.3C396.2 284.6 438.5 238.5 492.3 226.9 492.3 226.9 492.3 226.9 496.2 226.9 503.8 226.9 507.7 226.9 515.4 226.9 515.4 226.9 519.2 226.9 519.2 226.9 519.2 226.9 519.2 226.9 523.1 226.9 530.8 226.9 538.5 226.9 546.2 230.8 546.2 230.8 546.2 230.8 546.2 230.8 553.8 230.8 557.7 234.6 565.4 238.5 565.4 238.5 569.2 238.5 569.2 242.3 573.1 246.2 580.8 246.2 584.6 250 584.6 250 584.6 250 584.6 250 588.5 253.8 596.2 257.7 600 261.5 600 261.5 603.8 265.4 603.8 265.4 607.7 269.2 611.5 273.1 615.4 276.9 615.4 276.9 615.4 276.9 619.2 280.8 623.1 284.6 626.9 292.3 630.8 300 630.8 300 630.8 303.8 630.8 303.8 634.6 307.7 634.6 315.4 634.6 319.2 634.6 319.2 634.6 323.1 634.6 323.1 634.6 323.1 634.6 323.1 634.6 326.9 638.5 338.5 646.2 346.2 657.7 346.2H715.4C730.8 346.2 742.3 334.6 738.5 319.2 738.5 319.2 738.5 319.2 738.5 319.2 738.5 319.2 738.5 315.4 738.5 315.4 738.5 307.7 734.6 303.8 734.6 296.2 734.6 292.3 734.6 292.3 730.8 288.5 730.8 273.1 730.8 269.2 726.9 261.5 726.9 261.5 726.9 257.7 723.1 257.7 719.2 250 715.4 242.3 711.5 234.6 711.5 234.6 707.7 230.8 707.7 230.8 703.8 223.1 700 219.2 696.2 215.4 696.2 211.5 692.3 211.5 692.3 207.7 688.5 203.8 684.6 196.2 680.8 192.3 680.8 192.3 676.9 188.5 676.9 188.5 669.2 180.8 665.4 176.9 657.7 169.2 657.7 169.2 653.8 169.2 653.8 165.4 650 161.5 642.3 157.7 634.6 153.8 630.8 153.8 630.8 150 626.9 150 623.1 146.2 615.4 142.3 611.5 142.3 607.7 142.3 607.7 138.5 603.8 138.5 596.2 134.6 588.5 130.8 580.8 130.8 580.8 130.8 580.8 130.8 580.8 130.8 573.1 126.9 565.4 126.9 553.8 123.1 550 123.1 550 123.1 546.2 123.1 538.5 123.1 534.6 123.1 526.9 119.2 523.1 119.2 519.2 119.2 519.2 119.2 511.5 119.2 503.8 119.2 496.2 119.2 496.2 119.2 492.3 119.2 492.3 119.2 484.6 119.2 476.9 123.1 465.4 123.1 461.5 123.1 453.8 126.9 450 126.9 450 126.9 446.2 126.9 446.2 126.9 353.8 153.8 288.5 242.3 288.5 342.3V434.6H246.2C230.8 434.6 223.1 446.2 223.1 457.7V857.7C223.1 873.1 234.6 880.8 246.2 880.8H780.8C796.2 880.8 803.8 869.2 803.8 857.7V457.7C807.7 446.2 796.2 434.6 780.8 434.6Z", |
|
116 | 116 | "width": 1000 |
|
117 | 117 | }, |
|
118 | 118 | "search": [ |
|
119 | 119 | "unlock" |
|
120 | 120 | ] |
|
121 | 121 | }, |
|
122 | 122 | { |
|
123 | 123 | "uid": "b077586592b9b69166b981325446c836", |
|
124 | 124 | "css": "delete", |
|
125 | 125 | "code": 59392, |
|
126 | 126 | "src": "custom_icons", |
|
127 | 127 | "selected": true, |
|
128 | 128 | "svg": { |
|
129 | 129 | "path": "M515.4 92.3C303.8 92.3 130.8 265.4 130.8 476.9 130.8 688.5 303.8 861.5 515.4 861.5S900 688.5 900 476.9C900 265.4 726.9 92.3 515.4 92.3ZM742.3 507.7C742.3 523.1 730.8 534.6 711.5 534.6H315.4C300 534.6 284.6 523.1 284.6 507.7V446.2C284.6 430.8 296.2 419.2 315.4 419.2H711.5C726.9 419.2 742.3 430.8 742.3 446.2V507.7Z", |
|
130 | 130 | "width": 1000 |
|
131 | 131 | }, |
|
132 | 132 | "search": [ |
|
133 | 133 | "delete" |
|
134 | 134 | ] |
|
135 | 135 | }, |
|
136 | 136 | { |
|
137 | 137 | "uid": "dca63ad885c0d6f1780a8d1d55bc2380", |
|
138 | 138 | "css": "ok", |
|
139 | 139 | "code": 59393, |
|
140 | 140 | "src": "custom_icons", |
|
141 | 141 | "selected": true, |
|
142 | 142 | "svg": { |
|
143 | 143 | "path": "M515.4 115.4C303.8 115.4 130.8 288.5 130.8 500 130.8 711.5 303.8 884.6 515.4 884.6S900 711.5 900 500C900 288.5 726.9 115.4 515.4 115.4ZM753.8 411.5L450 715.4C438.5 726.9 423.1 726.9 411.5 715.4L273.1 576.9C261.5 565.4 261.5 550 273.1 538.5L315.4 496.2C326.9 484.6 342.3 484.6 353.8 496.2L411.5 553.8C423.1 565.4 438.5 565.4 450 553.8L669.2 334.6C680.8 323.1 696.2 323.1 707.7 334.6L750 376.9C765.4 384.6 765.4 400 753.8 411.5Z", |
|
144 | 144 | "width": 1000 |
|
145 | 145 | }, |
|
146 | 146 | "search": [ |
|
147 | 147 | "ok" |
|
148 | 148 | ] |
|
149 | 149 | }, |
|
150 | 150 | { |
|
151 | 151 | "uid": "c158b3a004c055c6ad1471cd98932268", |
|
152 | 152 | "css": "down", |
|
153 | 153 | "code": 59403, |
|
154 | 154 | "src": "custom_icons", |
|
155 | 155 | "selected": true, |
|
156 | 156 | "svg": { |
|
157 | 157 | "path": "M703.8 396.2L530.8 615.4C523.1 623.1 507.7 623.1 503.8 615.4L330.8 396.2C323.1 384.6 330.8 365.4 346.2 365.4H692.3C703.8 365.4 711.5 384.6 703.8 396.2Z", |
|
158 | 158 | "width": 1000 |
|
159 | 159 | }, |
|
160 | 160 | "search": [ |
|
161 | 161 | "arrow_down" |
|
162 | 162 | ] |
|
163 | 163 | }, |
|
164 | 164 | { |
|
165 | 165 | "uid": "02f59f392ad28056845cfc04cb121f13", |
|
166 | 166 | "css": "comment", |
|
167 | 167 | "code": 59394, |
|
168 | 168 | "src": "custom_icons", |
|
169 | 169 | "selected": true, |
|
170 | 170 | "svg": { |
|
171 | 171 | "path": "M130.8 784.6V280.8C130.8 207.7 188.5 150 261.5 150H769.2C842.3 150 900 207.7 900 280.8V569.2C900 642.3 842.3 700 769.2 700H273.1C269.2 700 261.5 703.8 257.7 707.7L165.4 800C153.8 815.4 130.8 803.8 130.8 784.6ZM261.5 211.5C223.1 211.5 188.5 242.3 188.5 284.6V696.2L234.6 650C238.5 646.2 242.3 642.3 250 642.3H769.2C807.7 642.3 842.3 611.5 842.3 569.2V280.8C842.3 242.3 811.5 207.7 769.2 207.7H261.5Z", |
|
172 | 172 | "width": 1000 |
|
173 | 173 | }, |
|
174 | 174 | "search": [ |
|
175 | 175 | "comment" |
|
176 | 176 | ] |
|
177 | 177 | }, |
|
178 | 178 | { |
|
179 | 179 | "uid": "9a44b838872ca62b8aba7bbbbf67cc59", |
|
180 | 180 | "css": "feed", |
|
181 | 181 | "code": 59400, |
|
182 | 182 | "src": "custom_icons", |
|
183 | 183 | "selected": true, |
|
184 | 184 | "svg": { |
|
185 | 185 | "path": "M842.3 111.5H188.5C153.8 111.5 130.8 138.5 130.8 169.2V826.9C130.8 857.7 157.7 884.6 188.5 884.6H846.2C876.9 884.6 903.8 857.7 903.8 826.9V169.2C900 138.5 873.1 111.5 842.3 111.5ZM307.7 776.9C269.2 776.9 234.6 746.2 234.6 703.8S265.4 630.8 307.7 630.8C346.2 630.8 380.8 661.5 380.8 703.8S346.2 776.9 307.7 776.9ZM553.8 788.5C519.2 788.5 496.2 761.5 496.2 730.8 496.2 619.2 407.7 530.8 296.2 530.8 265.4 530.8 230.8 503.8 230.8 473.1 230.8 438.5 253.8 411.5 284.6 411.5L296.2 411.5C473.1 411.5 615.4 553.8 615.4 730.8 611.5 761.5 584.6 788.5 553.8 788.5ZM750 788.5C715.4 788.5 692.3 761.5 692.3 730.8 692.3 511.5 511.5 330.8 292.3 330.8 261.5 330.8 226.9 303.8 226.9 269.2 226.9 234.6 250 207.7 280.8 207.7L292.3 207.7C576.9 207.7 811.5 438.5 811.5 726.9 811.5 761.5 784.6 788.5 750 788.5Z", |
|
186 | 186 | "width": 1000 |
|
187 | 187 | }, |
|
188 | 188 | "search": [ |
|
189 | 189 | "feed" |
|
190 | 190 | ] |
|
191 | 191 | }, |
|
192 | 192 | { |
|
193 | 193 | "uid": "e0118d6f20b76d77317977ae8dc849d7", |
|
194 | 194 | "css": "left", |
|
195 | 195 | "code": 59401, |
|
196 | 196 | "src": "custom_icons", |
|
197 | 197 | "selected": true, |
|
198 | 198 | "svg": { |
|
199 | 199 | "path": "M692.3 76.9L761.5 146.2C773.1 157.7 773.1 173.1 761.5 184.6L473.1 473.1C461.5 484.6 461.5 500 473.1 511.5L769.2 807.7C780.8 819.2 780.8 834.6 769.2 846.2L700 915.4C688.5 926.9 673.1 926.9 661.5 915.4L257.7 511.5C246.2 500 246.2 484.6 257.7 473.1L653.8 76.9C665.4 65.4 680.8 65.4 692.3 76.9Z", |
|
200 | 200 | "width": 1000 |
|
201 | 201 | }, |
|
202 | 202 | "search": [ |
|
203 | 203 | "left" |
|
204 | 204 | ] |
|
205 | 205 | }, |
|
206 | 206 | { |
|
207 | 207 | "uid": "3cea97f90c8f2b0a90833855434f58de", |
|
208 | 208 | "css": "right", |
|
209 | 209 | "code": 59402, |
|
210 | 210 | "src": "custom_icons", |
|
211 | 211 | "selected": true, |
|
212 | 212 | "svg": { |
|
213 | 213 | "path": "M338.5 915.4L265.4 846.2C253.8 834.6 253.8 819.2 265.4 807.7L553.8 519.2C565.4 507.7 565.4 492.3 553.8 480.8L257.7 184.6C246.2 173.1 246.2 157.7 257.7 146.2L326.9 76.9C338.5 65.4 353.8 65.4 365.4 76.9L769.2 480.8C780.8 492.3 780.8 507.7 769.2 519.2L376.9 915.4C365.4 926.9 346.2 926.9 338.5 915.4Z", |
|
214 | 214 | "width": 1000 |
|
215 | 215 | }, |
|
216 | 216 | "search": [ |
|
217 | 217 | "right" |
|
218 | 218 | ] |
|
219 | 219 | }, |
|
220 | 220 | { |
|
221 | 221 | "uid": "820a44cb2e7fc1d0e28b1d2a8cd44cb9", |
|
222 | 222 | "css": "git", |
|
223 | 223 | "code": 59434, |
|
224 | 224 | "src": "custom_icons", |
|
225 | 225 | "selected": true, |
|
226 | 226 | "svg": { |
|
227 | 227 | "path": "M928.8 6.3H71.3C35 6.3 6.3 36.3 6.3 71.3V927.5C6.3 963.8 36.3 992.5 71.3 992.5H927.5C963.8 992.5 992.5 962.5 992.5 927.5V71.3C993.8 36.3 963.7 6.3 928.8 6.3ZM200 555C203.8 566.3 208.8 575 213.8 582.5 220 590 227.5 596.3 236.3 600 245 603.8 255 606.3 265 606.3 273.8 606.3 281.3 605 288.8 603.8 296.3 602.5 302.5 600 308.8 597.5L315 546.3H287.5C283.8 546.3 280 545 277.5 542.5 276.3 541.3 275 537.5 275 535L280 496.2H385L368.7 627.5C361.2 633.8 352.5 638.7 343.7 642.5 335 646.3 326.3 650 316.2 652.5 306.2 655 297.5 657.5 286.3 658.8 276.3 660 265 661.3 252.5 661.3 232.5 661.3 215 657.5 198.7 650 182.5 642.5 168.7 632.5 157.5 620 146.2 607.5 137.5 592.5 131.2 575 125 557.5 121.2 538.8 121.2 518.8 121.2 501.3 123.7 485 127.5 468.8 131.2 452.5 137.5 438.8 145 425 152.5 411.3 161.2 400 171.2 388.8 181.2 377.5 192.5 368.8 205 361.3 217.5 353.8 231.3 347.5 246.3 343.8 261.3 340 276.3 337.5 292.5 337.5 306.3 337.5 317.5 338.8 328.7 341.3 340 343.8 350 347.5 357.5 351.3 366.2 355 373.8 360 380 365 386.3 370 392.5 376.3 397.5 381.3L377.5 412.5C373.8 417.5 368.8 420 363.8 421.3 358.8 422.5 353.7 421.3 347.5 417.5 342.5 413.8 337.5 411.3 333.7 408.8 328.7 406.3 325 403.8 320 402.5 315 401.3 310 400 305 398.8 300 397.5 293.7 397.5 287.5 397.5 273.7 397.5 261.2 400 250 406.3 238.7 412.5 228.7 420 221.2 431.3 212.5 441.2 206.2 455 202.5 468.8 197.5 483.8 196.2 500 196.2 517.5 195 531.3 197.5 543.8 200 555ZM536.3 657.5H465L503.7 342.5H575L536.3 657.5ZM878.8 398.8H798.8L766.3 657.5H696.3L727.5 398.7H647.5L655 342.5H886.3L878.8 398.8Z", |
|
228 | 228 | "width": 1000 |
|
229 | 229 | }, |
|
230 | 230 | "search": [ |
|
231 | 231 | "git" |
|
232 | 232 | ] |
|
233 | 233 | }, |
|
234 | 234 | { |
|
235 | 235 | "uid": "ea152b092f5ad7d610de2c388553e188", |
|
236 | 236 | "css": "hg", |
|
237 | 237 | "code": 59437, |
|
238 | 238 | "src": "custom_icons", |
|
239 | 239 | "selected": true, |
|
240 | 240 | "svg": { |
|
241 | 241 | "path": "M926.6 9.2H73.9C37.9 9.2 8.7 38.5 8.7 74.4V927.1C8.7 963.1 38 992.3 73.9 992.3H926.6C962.6 992.3 991.8 963 991.8 927.1V74.4C991.8 38.4 962.6 9.2 926.6 9.2ZM444 657.4H373.5L389.8 524.1H276.7L260.4 657.4H189.9L228.6 344.2H299.1L282.8 476.4H395.9L412.2 344.2H482.7L444 657.4ZM621 555.8C624.3 566.8 629.1 576 635.3 583.5 641.5 591 648.8 596.8 657.5 600.8 666.1 604.8 675.6 606.8 686.1 606.8 694.7 606.8 702.4 606 709.3 604.5 716.2 603 722.8 600.8 729.1 598.1L735.1 546.9H708.4C704.1 546.9 700.8 545.8 698.6 543.6 696.4 541.4 695.5 538.5 695.9 534.9L700.6 496.2H805.1L788.8 627.1C780.8 633 772.5 638.1 763.9 642.3 755.3 646.6 746.3 650 736.9 652.7 727.5 655.5 717.6 657.5 707.2 658.7 696.8 660 685.7 660.6 674 660.6 654.6 660.6 637 657 621 650 605 642.9 591.3 633.1 579.9 620.7 568.5 608.2 559.7 593.5 553.5 576.4 547.2 559.3 544.1 540.9 544.1 520.9 544.1 503.6 546.1 487.1 550 471.3 554 455.6 559.6 441.1 566.9 427.8 574.2 414.5 583 402.4 593.2 391.7 603.4 381 614.9 371.8 627.4 364.2 639.9 356.6 653.5 350.7 667.9 346.6 682.4 342.6 697.6 340.5 713.5 340.5 726.8 340.5 738.9 341.7 749.7 344.2 760.5 346.6 770.2 349.9 778.8 353.9 787.4 358 795.1 362.8 801.8 368.1 808.6 373.5 814.5 379 819.7 384.8L797 413.2C793.3 418.2 788.8 421.3 783.7 422.3 778.6 423.4 773.2 422.2 767.8 418.8 762.8 415.4 758.1 412.4 753.6 409.9 749.2 407.4 744.7 405.3 740.1 403.7 735.5 402 730.7 400.8 725.6 400 720.5 399.2 714.8 398.8 708.5 398.8 694.9 398.8 682.4 401.7 671.1 407.5 659.8 413.3 650 421.5 641.9 432 633.7 442.5 627.4 455.2 622.9 469.9 618.4 484.7 616.1 501 616.1 518.7 615.9 532.5 617.6 544.8 621 555.8Z", |
|
242 | 242 | "width": 1000 |
|
243 | 243 | }, |
|
244 | 244 | "search": [ |
|
245 | 245 | "hg" |
|
246 | 246 | ] |
|
247 | 247 | }, |
|
248 | 248 | { |
|
249 | 249 | "uid": "4a842c0afb4c35dacd21da71f9fed3f1", |
|
250 | 250 | "css": "comment-add", |
|
251 | 251 | "code": 59439, |
|
252 | 252 | "src": "custom_icons", |
|
253 | 253 | "selected": true, |
|
254 | 254 | "svg": { |
|
255 | 255 | "path": "M952.4 591.9V274.9C952.4 268.4 952.3 261.9 951.8 255.4 950.7 242.9 948.2 230.6 944.1 218.8 936.5 196.6 923.8 176.2 907.3 159.6 890.8 143.1 870.6 130.4 848.5 122.7 836.6 118.6 824.2 115.9 811.6 114.8 805.3 114.2 798.9 114.2 792.6 114.2H216.9C204 114.2 191.3 114.1 178.5 116 166.3 117.9 154.4 121.2 143 125.9 121.4 134.8 101.9 148.7 86.4 166.2 70.8 183.8 59.3 205 53.1 227.7 49.7 240.1 47.9 252.8 47.6 265.6 47.3 278.7 47.6 291.8 47.6 304.9V861.8C47.6 870.7 52.5 878.6 60.5 882.5 67.3 885.9 75.6 886.2 82.4 882.7 84.8 881.5 86.9 879.7 88.8 877.8 91.1 875.5 93.4 873.2 95.6 871 100.3 866.3 105 861.6 109.7 856.9L137.9 828.6C147.3 819.2 156.6 809.9 166 800.5 175.2 791.3 184.6 782.1 193.7 772.7 197.7 768.5 201.9 764.4 207.6 762.7 210.4 761.9 213.2 761.8 216 761.8H782.7C795.5 761.8 808.3 762 821 760.1 844.8 756.5 867.7 747.3 887.3 733.3 906.2 719.9 922.1 702.1 933.2 681.8 945.1 660.2 951.5 636 952.2 611.4 952.5 604.9 952.4 598.4 952.4 591.9ZM883.4 285.1V602.5C883.4 608.8 883.4 615.1 882.5 621.4 881.7 627.5 880.2 633.6 878.1 639.4 874.4 649.4 868.8 658.7 861.7 666.7 846.6 683.6 825.1 693.8 802.5 695.1 796.3 695.4 790 695.2 783.8 695.2H207.8C201.2 695.2 194.7 695.2 188.1 695.2 185 695.2 181.8 695.2 178.8 696.1 176.2 696.9 173.9 698.2 171.8 699.9 169.6 701.7 167.6 703.7 165.6 705.7 163.3 708 161 710.3 158.7 712.6 154 717.3 149.4 721.9 144.7 726.6 135.3 736 126 745.3 116.6 754.7V270C116.6 257.8 118.8 245.7 123.7 234.6 128 224.9 134 215.9 141.5 208.4 157.5 192.4 179.6 183.3 202.2 183.3H791.5C797.6 183.3 803.7 183.3 809.7 184.2 832 187.4 852.4 199.4 866 217.4 872.8 226.4 877.7 236.7 880.5 247.6 882 253.5 882.9 259.6 883.1 265.8 883.6 272.2 883.4 278.7 883.4 285.1ZM668.8 402H538.2C534.4 402 526.7 394.3 526.7 390.5V263.7C526.7 256 519 248.3 515.2 248.3H465.3C457.6 248.3 449.9 256 449.9 259.8V390.4C449.9 394.2 442.2 401.9 438.4 401.9H311.7C304 401.9 296.3 409.6 296.3 413.4V463.3C296.3 471 304 478.7 307.8 478.7H434.5C442.2 478.7 449.9 486.4 449.9 490.2V617C449.9 624.7 457.6 632.4 461.4 632.4H511.3C519 632.4 526.7 624.7 526.7 620.9V494.1C526.7 486.4 534.4 478.7 538.2 478.7H665C672.7 478.7 680.4 471 680.4 467.2V417.3C680.3 409.6 672.6 402 668.8 402Z", |
|
256 | 256 | "width": 1000 |
|
257 | 257 | }, |
|
258 | 258 | "search": [ |
|
259 | 259 | "comment-add" |
|
260 | 260 | ] |
|
261 | 261 | }, |
|
262 | 262 | { |
|
263 | 263 | "uid": "2427f6b8d4379b9a0b41cf31780807cf", |
|
264 | 264 | "css": "comment-toggle", |
|
265 | 265 | "code": 59440, |
|
266 | 266 | "src": "custom_icons", |
|
267 | 267 | "selected": true, |
|
268 | 268 | "svg": { |
|
269 | 269 | "path": "M797.6 114.2H202.4C116.6 114.2 47.6 183.3 47.6 269V861.9C47.6 881.4 69.5 891.1 84.1 881.8 86.4 880.7 88.6 879.1 90.6 877.1L199.8 768C202.1 765.7 204.7 764 207.7 762.8 209.7 762.2 211.9 761.9 214.3 761.9H797.6C883.4 761.9 952.4 692.8 952.4 607.1V269C952.4 183.2 883.3 114.2 797.6 114.2ZM118.3 752.6V269.5C118.3 222.5 156.4 184.3 203.5 184.3H680.1C593.7 267.9 175.5 695.4 171.4 699.5L118.3 752.6Z", |
|
270 | 270 | "width": 1000 |
|
271 | 271 | }, |
|
272 | 272 | "search": [ |
|
273 | 273 | "comment-toggle" |
|
274 | 274 | ] |
|
275 | 275 | }, |
|
276 | 276 | { |
|
277 | 277 | "uid": "6533bdc16ab201eb3f3b27ce989cab33", |
|
278 | 278 | "css": "folder-open-empty", |
|
279 | 279 | "code": 61717, |
|
280 | 280 | "src": "fontawesome" |
|
281 | 281 | }, |
|
282 | 282 | { |
|
283 | 283 | "uid": "d64b34fac1d9923b7d29d1550b628ecd", |
|
284 | 284 | "css": "lock", |
|
285 | 285 | "code": 59398, |
|
286 | 286 | "src": "custom_icons", |
|
287 | 287 | "selected": true, |
|
288 | 288 | "svg": { |
|
289 | 289 | "path": "M812.5 424.1H758.9V317C758.9 308 758.9 303.6 758.9 299.1 758.9 294.6 758.9 290.2 758.9 285.7 758.9 281.3 758.9 281.3 758.9 276.8 758.9 267.9 758.9 263.4 754.5 254.5 754.5 250 754.5 250 750 245.5 750 236.6 745.5 232.1 741.1 223.2 741.1 223.2 741.1 218.8 736.6 218.8 732.1 209.8 727.7 200.9 723.2 192 723.2 192 718.8 187.5 718.8 187.5 723.2 178.6 718.8 169.6 714.3 165.2 714.3 160.7 709.8 160.7 709.8 156.3 705.4 151.8 700.9 142.9 696.4 138.4 696.4 138.4 692 133.9 692 133.9 683 125 678.6 120.5 669.6 111.6 669.6 111.6 665.2 111.6 665.2 107.1 660.7 102.7 651.8 98.2 642.9 93.8 638.4 93.8 638.4 89.3 633.9 89.3 629.5 84.8 620.5 80.4 616.1 80.4 611.6 80.4 611.6 75.9 607.1 75.9 598.2 71.4 589.3 67 580.4 67 580.4 67 580.4 67 580.4 67 571.4 62.5 562.5 62.5 549.1 58 544.6 58 544.6 58 540.2 58 535.7 58 535.7 58 531.3 58 531.3 58 526.8 58 526.8 58 526.8 58 522.3 58 522.3 58 522.3 58 522.3 58 522.3 58 522.3 58 522.3 58 522.3 58 517.9 58 513.4 58 513.4 58 513.4 58 508.9 58 508.9 58 504.5 58 504.5 58 500 58 500 58 500 58 500 58 495.5 58 491.1 58 491.1 58 491.1 58 491.1 58 491.1 58 491.1 58 491.1 58 491.1 58 491.1 58 486.6 58 486.6 58 486.6 58 482.1 58 482.1 58 477.7 58 477.7 58 473.2 58 468.8 58 468.8 58 464.3 58 455.4 58 442 62.5 433 67 433 67 433 67 433 67 410.7 67 397.3 71.4 388.4 75.9 383.9 75.9 383.9 80.4 379.5 80.4 375 84.8 370.5 84.8 361.6 89.3 361.6 93.8 357.1 93.8 357.1 93.8 348.2 98.2 339.3 102.7 334.8 111.6 334.8 111.6 330.4 111.6 330.4 116.1 321.4 120.5 317 125 308 133.9 308 133.9 303.6 138.4 303.6 138.4 299.1 142.9 294.6 151.8 290.2 156.3 290.2 160.7 285.7 160.7 285.7 165.2 276.8 169.6 272.3 178.6 272.3 183 267.9 183 267.9 187.5 267.9 187.5 263.4 196.4 258.9 205.4 254.5 214.3 254.5 214.3 254.5 218.8 250 218.8 250 232.1 245.5 236.6 245.5 245.5 245.5 250 245.5 250 241.1 254.5 241.1 263.4 236.6 267.9 236.6 276.8 236.6 281.3 236.6 281.3 236.6 285.7 236.6 290.2 236.6 294.6 236.6 299.1 236.6 303.6 236.6 312.5 236.6 317V424.1H187.5C169.6 424.1 160.7 437.5 160.7 450.9V915.2C160.7 933 174.1 942 187.5 942H808C825.9 942 834.8 928.6 834.8 915.2V450.9C839.3 433 825.9 424.1 812.5 424.1ZM361.6 317C361.6 250 410.7 196.4 473.2 183 473.2 183 473.2 183 477.7 183 486.6 183 491.1 183 500 183 500 183 504.5 183 504.5 183 504.5 183 504.5 183 504.5 183 513.4 183 517.9 183 526.8 183 526.8 183 526.8 183 531.3 183 593.8 196.4 642.9 250 642.9 317V424.1H361.6V317Z", |
|
290 | 290 | "width": 1000 |
|
291 | 291 | }, |
|
292 | 292 | "search": [ |
|
293 | 293 | "lock" |
|
294 | 294 | ] |
|
295 | 295 | }, |
|
296 | 296 | { |
|
297 | 297 | "uid": "d95fde5e3bfeb3302efc47c90538a1c5", |
|
298 | 298 | "css": "more", |
|
299 | 299 | "code": 59410, |
|
300 | 300 | "src": "custom_icons", |
|
301 | 301 | "selected": true, |
|
302 | 302 | "svg": { |
|
303 | 303 | "path": "M546.2 415.4H446.2C430.8 415.4 419.2 426.9 419.2 442.3V542.3C419.2 557.7 430.8 569.2 446.2 569.2H546.2C561.5 569.2 573.1 557.7 573.1 542.3V442.3C573.1 426.9 561.5 415.4 546.2 415.4ZM546.2 107.7H446.2C430.8 107.7 419.2 119.2 419.2 134.6V234.6C419.2 250 430.8 261.5 446.2 261.5H546.2C561.5 261.5 573.1 250 573.1 234.6V134.6C573.1 119.2 561.5 107.7 546.2 107.7ZM546.2 723.1H446.2C430.8 723.1 419.2 734.6 419.2 750V850C419.2 865.4 430.8 876.9 446.2 876.9H546.2C561.5 876.9 573.1 865.4 573.1 850V750C573.1 734.6 561.5 723.1 546.2 723.1Z", |
|
304 | 304 | "width": 1000 |
|
305 | 305 | }, |
|
306 | 306 | "search": [ |
|
307 | 307 | "more" |
|
308 | 308 | ] |
|
309 | 309 | }, |
|
310 | 310 | { |
|
311 | 311 | "uid": "34e7772638ae3ca1bfb0a4eca2c39221", |
|
312 | 312 | "css": "merge", |
|
313 | 313 | "code": 59443, |
|
314 | 314 | "src": "custom_icons", |
|
315 | 315 | "selected": true, |
|
316 | 316 | "svg": { |
|
317 | 317 | "path": "M199.8 740.5C199.8 812.2 258.1 870.5 329.8 870.5S459.8 812.2 459.8 740.5C459.8 694.6 435.8 654.5 399.8 631.3 418.4 491.7 533.4 451.9 602.4 440.6V742.4C563.7 765 537.4 806.4 537.4 854.4 537.4 926.1 595.7 984.4 667.4 984.4S797.4 926.1 797.4 854.4C797.4 806.5 771.1 765 732.4 742.4V254.9C771.1 232.3 797.4 190.9 797.4 142.9 797.4 71.2 739.1 12.9 667.4 12.9S537.4 71.2 537.4 142.9C537.4 190.8 563.7 232.3 602.4 254.9V309.9C542.2 317.8 440.4 342.3 364.2 417.8 309.5 472.1 277.9 542.1 269.6 625.9 228.4 647.7 199.8 690.6 199.8 740.5ZM667.6 897.8C643.7 897.8 624.3 878.3 624.3 854.5S643.8 811.2 667.6 811.2C691.5 811.2 710.9 830.7 710.9 854.5S691.5 897.8 667.6 897.8ZM667.6 99.6C691.5 99.6 710.9 119 710.9 142.9S691.4 186.2 667.6 186.2C643.7 186.2 624.3 166.8 624.3 142.9S643.7 99.6 667.6 99.6ZM329.9 783.9C306 783.9 286.6 764.4 286.6 740.6S306.1 697.3 329.9 697.3C353.8 697.3 373.2 716.7 373.2 740.6S353.8 783.9 329.9 783.9Z", |
|
318 | 318 | "width": 1000 |
|
319 | 319 | }, |
|
320 | 320 | "search": [ |
|
321 | 321 | "merge" |
|
322 | 322 | ] |
|
323 | 323 | }, |
|
324 | 324 | { |
|
325 | 325 | "uid": "c95735c17a10af81448c7fed98a04546", |
|
326 | 326 | "css": "folder-open", |
|
327 | 327 | "code": 59405, |
|
328 | 328 | "src": "fontawesome" |
|
329 | 329 | }, |
|
330 | 330 | { |
|
331 | 331 | "uid": "865ac833a8efcfc24a6f573705ce56b1", |
|
332 | 332 | "css": "svn", |
|
333 | 333 | "code": 59438, |
|
334 | 334 | "src": "custom_icons", |
|
335 | 335 | "selected": true, |
|
336 | 336 | "svg": { |
|
337 | 337 | "path": "M933.4 9.2H80.7C44.7 9.2 15.5 38.5 15.5 74.4V927.1C15.5 963.1 44.8 992.3 80.7 992.3H933.4C969.4 992.3 998.6 963 998.6 927.1V74.4C998.7 38.4 969.4 9.2 933.4 9.2ZM167.9 447.1C171.1 451 175.4 454.4 180.8 457.3 186.2 460.2 192.2 463 199 465.4 205.7 467.8 212.7 470.5 219.8 473.3 226.9 476.2 233.9 479.5 240.7 483.2 247.5 486.9 253.6 491.6 259 497.2 264.4 502.8 268.7 509.6 271.9 517.4 275.1 525.3 276.8 534.8 276.8 545.8 276.8 561.6 274.1 576.4 268.6 590.3 263.1 604.3 255.3 616.4 245.1 626.8 234.9 637.2 222.5 645.4 208 651.5 193.4 657.6 177 660.7 158.8 660.7 149.7 660.7 140.7 659.7 131.5 657.7S113.6 652.8 105.2 649.2C96.8 645.5 89 641.2 81.8 636.2 74.6 631.2 68.5 625.6 63.5 619.5L88.5 586.7C90.5 584.3 93 582.3 95.9 580.7 98.8 579.1 101.8 578.3 104.8 578.3 108.8 578.3 112.7 579.7 116.5 582.5 120.3 585.3 124.5 588.4 129.1 591.8 133.7 595.2 139 598.2 145.1 601.1 151.2 603.9 158.7 605.3 167.6 605.3 180.7 605.3 190.7 601.7 197.8 594.7 204.9 587.6 208.4 577.1 208.4 563.2 208.4 556.8 206.8 551.4 203.5 547.3 200.3 543.1 196 539.7 190.8 536.8 185.6 533.9 179.6 531.4 172.8 529.1 166 526.9 159.2 524.5 152.1 521.9 145.1 519.3 138.2 516.2 131.4 512.8 124.6 509.3 118.6 504.7 113.4 499 108.2 493.3 103.9 486.4 100.7 478.2 97.5 469.9 95.9 459.8 95.9 447.7 95.9 433.8 98.5 420.4 103.7 407.6 108.9 394.8 116.4 383.4 126.2 373.5 136 363.6 147.8 355.7 161.7 349.8 175.6 343.9 191.3 341 208.6 341 217.5 341 226.1 341.9 234.5 343.8S250.8 348.2 258.1 351.6C265.4 354.9 272.1 358.8 278.1 363.3 284.1 367.8 289.2 372.8 293.4 378.1L272.3 407C269.7 410.3 267.2 412.8 264.8 414.4 262.4 416 259.4 416.8 256 416.8 252.7 416.8 249.4 415.8 246.1 413.6 242.8 411.4 239.1 409.1 235 406.5 230.9 403.9 226.2 401.6 220.9 399.4 215.6 397.2 209.3 396.2 202.2 396.2 195.6 396.2 189.8 397.1 184.9 399 179.9 400.9 175.8 403.4 172.5 406.8 169.2 410.1 166.7 414 165.1 418.4 163.5 422.9 162.6 427.8 162.6 433 163.1 438.4 164.7 443.2 167.9 447.1ZM480 657.4H416.3L339.2 343.7H395.6C401.6 343.7 406.4 345.1 410 348 413.6 350.8 415.8 354.5 416.7 359L449.4 531.8C451.3 538.7 453 546.3 454.6 554.8 456.2 563.2 457.5 571.9 458.7 581 461.7 572 464.9 563.2 468.4 554.8 471.8 546.4 475.4 538.8 479.2 531.8L552.3 359C553.2 357.1 554.4 355.2 556.1 353.4 557.7 351.5 559.6 349.8 561.8 348.4 564 347 566.4 345.8 569 345 571.6 344.2 574.4 343.7 577.3 343.7H634.1L480 657.4ZM902.6 657.4H866C860.5 657.4 856.1 656.5 852.8 654.7 849.4 652.9 846.2 649.9 843.2 645.8L733.6 452.2C733.3 456.2 733 460.1 732.7 463.8 732.3 467.6 732 471.1 731.7 474.4L710.2 657.4H648.2L686.9 343.7H723.9C726.9 343.7 729.5 343.8 731.6 344 733.7 344.2 735.5 344.7 737.1 345.5 738.7 346.3 740.1 347.4 741.4 348.8S744.1 352.1 745.5 354.4L855.5 548.1C855.8 543.1 856.2 538.3 856.7 533.7 857.2 529.2 857.8 524.8 858.3 520.8L879.4 343.6H941.4L902.6 657.4Z", |
|
338 | 338 | "width": 1000 |
|
339 | 339 | }, |
|
340 | 340 | "search": [ |
|
341 | 341 | "svn" |
|
342 | 342 | ] |
|
343 | 343 | }, |
|
344 | 344 | { |
|
345 | 345 | "uid": "bbfb51903f40597f0b70fd75bc7b5cac", |
|
346 | 346 | "css": "trash", |
|
347 | 347 | "code": 61944, |
|
348 | 348 | "src": "fontawesome" |
|
349 | 349 | }, |
|
350 | 350 | { |
|
351 | 351 | "uid": "f48ae54adfb27d8ada53d0fd9e34ee10", |
|
352 | 352 | "css": "trash-empty", |
|
353 | 353 | "code": 59406, |
|
354 | 354 | "src": "fontawesome" |
|
355 | 355 | }, |
|
356 | 356 | { |
|
357 | 357 | "uid": "f8aa663c489bcbd6e68ec8147dca841e", |
|
358 | 358 | "css": "folder", |
|
359 | 359 | "code": 59404, |
|
360 | 360 | "src": "fontawesome" |
|
361 | 361 | }, |
|
362 | 362 | { |
|
363 | 363 | "uid": "c8585e1e5b0467f28b70bce765d5840c", |
|
364 | 364 | "css": "docs", |
|
365 | 365 | "code": 61637, |
|
366 | 366 | "src": "fontawesome" |
|
367 | 367 | }, |
|
368 | 368 | { |
|
369 | 369 | "uid": "1b5a5d7b7e3c71437f5a26befdd045ed", |
|
370 | 370 | "css": "doc", |
|
371 | 371 | "code": 59414, |
|
372 | 372 | "src": "fontawesome" |
|
373 | 373 | }, |
|
374 | 374 | { |
|
375 | 375 | "uid": "5408be43f7c42bccee419c6be53fdef5", |
|
376 | 376 | "css": "doc-text", |
|
377 | 377 | "code": 61686, |
|
378 | 378 | "src": "fontawesome" |
|
379 | 379 | }, |
|
380 | 380 | { |
|
381 | 381 | "uid": "b091a8bd0fdade174951f17d936f51e4", |
|
382 | 382 | "css": "folder-empty", |
|
383 | 383 | "code": 61716, |
|
384 | 384 | "src": "fontawesome" |
|
385 | 385 | }, |
|
386 | 386 | { |
|
387 | 387 | "uid": "c08a1cde48d96cba21d8c05fa7d7feb1", |
|
388 | 388 | "css": "doc-text-inv", |
|
389 | 389 | "code": 61788, |
|
390 | 390 | "src": "fontawesome" |
|
391 | 391 | }, |
|
392 | 392 | { |
|
393 | 393 | "uid": "178053298e3e5b03551d754d4b9acd8b", |
|
394 | 394 | "css": "doc-inv", |
|
395 | 395 | "code": 61787, |
|
396 | 396 | "src": "fontawesome" |
|
397 | 397 | }, |
|
398 | 398 | { |
|
399 | 399 | "uid": "e99461abfef3923546da8d745372c995", |
|
400 | 400 | "css": "cog", |
|
401 | 401 | "code": 59415, |
|
402 | 402 | "src": "fontawesome" |
|
403 | 403 | }, |
|
404 | 404 | { |
|
405 | 405 | "uid": "98687378abd1faf8f6af97c254eb6cd6", |
|
406 | 406 | "css": "cog-alt", |
|
407 | 407 | "code": 59416, |
|
408 | 408 | "src": "fontawesome" |
|
409 | 409 | }, |
|
410 | 410 | { |
|
411 | 411 | "uid": "21b42d3c3e6be44c3cc3d73042faa216", |
|
412 | 412 | "css": "sliders", |
|
413 | 413 | "code": 61918, |
|
414 | 414 | "src": "fontawesome" |
|
415 | 415 | }, |
|
416 | 416 | { |
|
417 | 417 | "uid": "559647a6f430b3aeadbecd67194451dd", |
|
418 | 418 | "css": "menu", |
|
419 | 419 | "code": 61641, |
|
420 | 420 | "src": "fontawesome" |
|
421 | 421 | }, |
|
422 | 422 | { |
|
423 | 423 | "uid": "c5fd349cbd3d23e4ade333789c29c729", |
|
424 | 424 | "css": "eye", |
|
425 | 425 | "code": 59417, |
|
426 | 426 | "src": "fontawesome" |
|
427 | 427 | }, |
|
428 | 428 | { |
|
429 | 429 | "uid": "7fd683b2c518ceb9e5fa6757f2276faa", |
|
430 | 430 | "css": "eye-off", |
|
431 | 431 | "code": 59418, |
|
432 | 432 | "src": "fontawesome" |
|
433 | 433 | }, |
|
434 | 434 | { |
|
435 | 435 | "uid": "2e2dba0307a502a8507c1729084c7ab5", |
|
436 | 436 | "css": "cancel-circled2", |
|
437 | 437 | "code": 59419, |
|
438 | 438 | "src": "fontawesome" |
|
439 | 439 | }, |
|
440 | 440 | { |
|
441 | 441 | "uid": "0f4cae16f34ae243a6144c18a003f2d8", |
|
442 | 442 | "css": "cancel-circled", |
|
443 | 443 | "code": 59420, |
|
444 | 444 | "src": "fontawesome" |
|
445 | 445 | }, |
|
446 | 446 | { |
|
447 | 447 | "uid": "26613a2e6bc41593c54bead46f8c8ee3", |
|
448 | 448 | "css": "file-code", |
|
449 | 449 | "code": 61897, |
|
450 | 450 | "src": "fontawesome" |
|
451 | 451 | }, |
|
452 | 452 | { |
|
453 | 453 | "uid": "5211af474d3a9848f67f945e2ccaf143", |
|
454 | 454 | "css": "remove", |
|
455 | 455 | "code": 59408, |
|
456 | 456 | "src": "fontawesome" |
|
457 | 457 | }, |
|
458 | 458 | { |
|
459 | 459 | "uid": "44e04715aecbca7f266a17d5a7863c68", |
|
460 | 460 | "css": "plus", |
|
461 | 461 | "code": 59421, |
|
462 | 462 | "src": "fontawesome" |
|
463 | 463 | }, |
|
464 | 464 | { |
|
465 | 465 | "uid": "4ba33d2607902cf690dd45df09774cb0", |
|
466 | 466 | "css": "plus-circled", |
|
467 | 467 | "code": 59422, |
|
468 | 468 | "src": "fontawesome" |
|
469 | 469 | }, |
|
470 | 470 | { |
|
471 | 471 | "uid": "1a5cfa186647e8c929c2b17b9fc4dac1", |
|
472 | 472 | "css": "plus-squared", |
|
473 | 473 | "code": 61694, |
|
474 | 474 | "src": "fontawesome" |
|
475 | 475 | }, |
|
476 | 476 | { |
|
477 | 477 | "uid": "2d3be3e856fc1e4ac067590d2ded1b07", |
|
478 | 478 | "css": "plus-squared-alt", |
|
479 | 479 | "code": 61846, |
|
480 | 480 | "src": "fontawesome" |
|
481 | 481 | }, |
|
482 | 482 | { |
|
483 | 483 | "uid": "eeadb020bb75d089b25d8424aabe19e0", |
|
484 | 484 | "css": "minus-circled", |
|
485 | 485 | "code": 59423, |
|
486 | 486 | "src": "fontawesome" |
|
487 | 487 | }, |
|
488 | 488 | { |
|
489 | 489 | "uid": "f755a58fb985eeb70bd47d9b31892a34", |
|
490 | 490 | "css": "minus-squared", |
|
491 | 491 | "code": 61766, |
|
492 | 492 | "src": "fontawesome" |
|
493 | 493 | }, |
|
494 | 494 | { |
|
495 | 495 | "uid": "18ef25350258541e8e54148ed79845c0", |
|
496 | 496 | "css": "minus-squared-alt", |
|
497 | 497 | "code": 61767, |
|
498 | 498 | "src": "fontawesome" |
|
499 | 499 | }, |
|
500 | 500 | { |
|
501 | 501 | "uid": "861ab06e455e2de3232ebef67d60d708", |
|
502 | 502 | "css": "minus", |
|
503 | 503 | "code": 59424, |
|
504 | 504 | "src": "fontawesome" |
|
505 | 505 | }, |
|
506 | 506 | { |
|
507 | 507 | "uid": "e82cedfa1d5f15b00c5a81c9bd731ea2", |
|
508 | 508 | "css": "info-circled", |
|
509 | 509 | "code": 59425, |
|
510 | 510 | "src": "fontawesome" |
|
511 | 511 | }, |
|
512 | 512 | { |
|
513 | 513 | "uid": "9dd9e835aebe1060ba7190ad2b2ed951", |
|
514 | 514 | "css": "search", |
|
515 | 515 | "code": 59411, |
|
516 | 516 | "src": "fontawesome" |
|
517 | 517 | }, |
|
518 | 518 | { |
|
519 | 519 | "uid": "b429436ec5a518c78479d44ef18dbd60", |
|
520 | 520 | "css": "paste", |
|
521 | 521 | "code": 61674, |
|
522 | 522 | "src": "fontawesome" |
|
523 | 523 | }, |
|
524 | 524 | { |
|
525 | 525 | "uid": "8772331a9fec983cdb5d72902a6f9e0e", |
|
526 | 526 | "css": "scissors", |
|
527 | 527 | "code": 59412, |
|
528 | 528 | "src": "fontawesome" |
|
529 | 529 | }, |
|
530 | 530 | { |
|
531 | 531 | "uid": "9a76bc135eac17d2c8b8ad4a5774fc87", |
|
532 | 532 | "css": "download", |
|
533 | 533 | "code": 59413, |
|
534 | 534 | "src": "fontawesome" |
|
535 | 535 | }, |
|
536 | 536 | { |
|
537 | 537 | "uid": "eeec3208c90b7b48e804919d0d2d4a41", |
|
538 | 538 | "css": "upload", |
|
539 | 539 | "code": 59426, |
|
540 | 540 | "src": "fontawesome" |
|
541 | 541 | }, |
|
542 | 542 | { |
|
543 | 543 | "uid": "5d2d07f112b8de19f2c0dbfec3e42c05", |
|
544 | 544 | "css": "spin", |
|
545 | 545 | "code": 59448, |
|
546 | 546 | "src": "fontelico" |
|
547 | 547 | }, |
|
548 | 548 | { |
|
549 | 549 | "uid": "9bd60140934a1eb9236fd7a8ab1ff6ba", |
|
550 | 550 | "css": "spin-alt", |
|
551 | 551 | "code": 59444, |
|
552 | 552 | "src": "fontelico" |
|
553 | 553 | }, |
|
554 | 554 | { |
|
555 | "uid": "513ac180ff85bd275f2b736720cbbf5e", | |
|
556 | "css": "home", | |
|
557 | "code": 59427, | |
|
558 | "src": "entypo" | |
|
559 | }, | |
|
560 | { | |
|
555 | 561 | "uid": "c43db6645e7515889fc2193294f50767", |
|
556 | 562 | "css": "plus", |
|
557 | 563 | "code": 59411, |
|
558 | 564 | "src": "custom_icons", |
|
559 | 565 | "selected": false, |
|
560 | 566 | "svg": { |
|
561 | 567 | "path": "M873.1 446.2H619.2C603.8 446.2 592.3 434.6 592.3 419.2V165.4C592.3 150 580.8 138.5 565.4 138.5H465.4C450 138.5 438.5 150 438.5 165.4V419.2C438.5 434.6 426.9 446.2 411.5 446.2H157.7C142.3 446.2 130.8 457.7 130.8 473.1V573.1C130.8 588.5 142.3 600 157.7 600H411.5C426.9 600 438.5 611.5 438.5 626.9V880.8C438.5 896.2 450 907.7 465.4 907.7H565.4C580.8 907.7 592.3 896.2 592.3 880.8V626.9C592.3 611.5 603.8 600 619.2 600H873.1C888.5 600 900 588.5 900 573.1V473.1C900 457.7 888.5 446.2 873.1 446.2Z", |
|
562 | 568 | "width": 1000 |
|
563 | 569 | }, |
|
564 | 570 | "search": [ |
|
565 | 571 | "plus" |
|
566 | 572 | ] |
|
567 | 573 | }, |
|
568 | 574 | { |
|
569 | 575 | "uid": "7d7f338d90203f20c0d8d5c26091cc69", |
|
570 | 576 | "css": "minus", |
|
571 | 577 | "code": 59412, |
|
572 | 578 | "src": "custom_icons", |
|
573 | 579 | "selected": false, |
|
574 | 580 | "svg": { |
|
575 | 581 | "path": "M980 560H20C10 560 0 550 0 540V380C0 370 10 360 20 360H985C995 360 1005 370 1005 380V545C1000 550 990 560 980 560Z", |
|
576 | 582 | "width": 1000 |
|
577 | 583 | }, |
|
578 | 584 | "search": [ |
|
579 | 585 | "minus" |
|
580 | 586 | ] |
|
581 | 587 | }, |
|
582 | 588 | { |
|
583 | 589 | "uid": "4ccc61480001600f2e7e3c7dd0546c6e", |
|
584 | 590 | "css": "remove", |
|
585 | 591 | "code": 59413, |
|
586 | 592 | "src": "custom_icons", |
|
587 | 593 | "selected": false, |
|
588 | 594 | "svg": { |
|
589 | 595 | "path": "M975 140L860 25C845 10 825 10 810 25L525 310C510 325 490 325 475 310L190 25C175 10 155 10 140 25L25 140C10 155 10 175 25 190L310 475C325 490 325 510 310 525L25 810C10 825 10 845 25 860L140 975C155 990 175 990 190 975L475 690C490 675 510 675 525 690L810 975C825 990 845 990 860 975L975 860C990 845 990 825 975 810L690 525C675 510 675 490 690 475L975 190C990 180 990 155 975 140Z", |
|
590 | 596 | "width": 1000 |
|
591 | 597 | }, |
|
592 | 598 | "search": [ |
|
593 | 599 | "remove" |
|
594 | 600 | ] |
|
595 | 601 | } |
|
596 | 602 | ] |
|
597 | 603 | } No newline at end of file |
|
1 | NO CONTENT: modified file, binary diff hidden |
@@ -1,130 +1,132 b'' | |||
|
1 | 1 | <?xml version="1.0" standalone="no"?> |
|
2 | 2 | <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"> |
|
3 | 3 | <svg xmlns="http://www.w3.org/2000/svg"> |
|
4 | 4 | <metadata>Copyright (C) 2019 by original authors @ fontello.com</metadata> |
|
5 | 5 | <defs> |
|
6 | 6 | <font id="rcicons" horiz-adv-x="1000" > |
|
7 | 7 | <font-face font-family="rcicons" font-weight="400" font-stretch="normal" units-per-em="1000" ascent="850" descent="-150" /> |
|
8 | 8 | <missing-glyph horiz-adv-x="1000" /> |
|
9 | 9 | <glyph glyph-name="delete" unicode="" d="M515 758c-211 0-384-173-384-385 0-211 173-385 384-385s385 174 385 385c0 212-173 385-385 385z m227-416c0-15-11-27-30-27h-397c-15 0-30 12-30 27v62c0 15 11 27 30 27h397c15 0 30-12 30-27v-62z" horiz-adv-x="1000" /> |
|
10 | 10 | |
|
11 | 11 | <glyph glyph-name="ok" unicode="" d="M515 735c-211 0-384-173-384-385 0-211 173-385 384-385s385 174 385 385c0 212-173 385-385 385z m239-296l-304-304c-11-12-27-12-38 0l-139 138c-11 12-11 27 0 39l42 42c12 11 27 11 39 0l58-58c11-11 27-11 38 0l219 219c12 12 27 12 39 0l42-42c15-8 15-23 4-34z" horiz-adv-x="1000" /> |
|
12 | 12 | |
|
13 | 13 | <glyph glyph-name="comment" unicode="" d="M131 65v504c0 73 58 131 131 131h507c73 0 131-58 131-131v-288c0-73-58-131-131-131h-496c-4 0-11-4-15-8l-93-92c-11-15-34-4-34 15z m131 574c-39 0-73-31-73-74v-411l46 46c4 4 7 8 15 8h519c39 0 73 31 73 73v288c0 39-30 73-73 73h-507z" horiz-adv-x="1000" /> |
|
14 | 14 | |
|
15 | 15 | <glyph glyph-name="bookmark" unicode="" d="M780-140l-260 290c-10 10-25 10-35 0l-260-295c-20-20-45-5-45 30v930c-5 20 10 35 25 35h590c15 0 30-15 30-35v-925c0-35-30-50-45-30z" horiz-adv-x="1000" /> |
|
16 | 16 | |
|
17 | 17 | <glyph glyph-name="branch" unicode="" d="M875 600c0 76-58 134-134 134s-134-58-134-134c0-49 27-89 63-112-18-142-139-183-210-196v313c45 22 71 62 71 111 0 76-58 134-134 134s-134-58-134-134c0-49 27-94 67-116v-500c-40-22-67-67-67-116 0-76 58-134 134-134s134 58 134 134c0 49-26 94-67 116v58c63 9 166 31 246 112 58 58 89 129 98 214 40 22 67 67 67 116z m-478 161c27 0 45-18 45-45s-18-45-45-45-44 18-44 45 18 45 44 45z m0-822c-26 0-44 18-44 45s18 45 44 45 45-18 45-45-22-45-45-45z m344 706c27 0 45-18 45-45s-18-45-45-45-45 18-45 45 23 45 45 45z" horiz-adv-x="1000" /> |
|
18 | 18 | |
|
19 | 19 | <glyph glyph-name="tag" unicode="" d="M460 788l-366 8c-18 0-31-13-31-31l13-366c0-9 4-13 9-22l464-465c14-13 31-13 45 0l352 353c14 14 14 31 0 45l-468 469c-5 4-14 9-18 9z m-103-224c0-35-31-67-67-67-35 0-67 32-67 67 0 36 32 67 67 67s67-26 67-67z" horiz-adv-x="1000" /> |
|
20 | 20 | |
|
21 | 21 | <glyph glyph-name="lock" unicode="" d="M813 426h-54v107c0 9 0 13 0 18 0 4 0 9 0 13 0 5 0 5 0 9 0 9 0 14-4 23 0 4 0 4-5 9 0 8-4 13-9 22 0 0 0 4-4 4-5 9-9 18-14 27 0 0-4 5-4 5 4 8 0 17-5 22 0 4-4 4-4 9-5 4-9 13-14 18 0 0-4 4-4 4-9 9-13 14-22 22 0 0-5 0-5 5-4 4-13 9-22 13-5 0-5 5-9 5-4 4-13 9-18 9-4 0-4 4-9 4-9 5-18 9-27 9 0 0 0 0 0 0-9 5-17 5-31 9-4 0-4 0-9 0-4 0-4 0-9 0 0 0-4 0-4 0 0 0-5 0-5 0 0 0 0 0 0 0 0 0 0 0 0 0-4 0-9 0-9 0 0 0-4 0-4 0-4 0-4 0-9 0 0 0 0 0 0 0-4 0-9 0-9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0-4 0-4 0 0 0-5 0-5 0-4 0-4 0-9 0-4 0-4 0-9 0-9 0-22-4-31-9 0 0 0 0 0 0-22 0-36-4-45-9-4 0-4-4-8-4-5-5-9-5-18-9 0-5-5-5-5-5-9-4-18-9-22-18 0 0-5 0-5-4-9-4-13-9-22-18 0 0-4-4-4-4-5-5-9-14-14-18 0-5-4-5-4-9-9-5-14-14-14-18-4 0-4-4-4-4-5-9-9-18-13-27 0 0 0-5-5-5 0-13-4-18-4-26 0-5 0-5-5-9 0-9-4-14-4-23 0-4 0-4 0-9 0-4 0-9 0-13 0-5 0-13 0-18v-107h-49c-18 0-27-13-27-27v-464c0-18 13-27 27-27h620c18 0 27 13 27 27v464c4 18-9 27-22 27z m-451 107c0 67 49 121 111 134 0 0 0 0 5 0 9 0 13 0 22 0 0 0 5 0 5 0 0 0 0 0 0 0 8 0 13 0 22 0 0 0 0 0 4 0 63-13 112-67 112-134v-107h-281v107z" horiz-adv-x="1000" /> |
|
22 | 22 | |
|
23 | 23 | <glyph glyph-name="unlock" unicode="" d="M781 415h-385v93c0 57 43 104 96 115 0 0 0 0 4 0 8 0 12 0 19 0 0 0 4 0 4 0 0 0 0 0 4 0 8 0 16 0 23-4 0 0 0 0 0 0 8 0 12-4 19-7 0 0 4 0 4-4 4-4 12-4 16-8 0 0 0 0 0 0 4-4 11-8 15-11 0 0 4-4 4-4 4-4 8-8 11-12 0 0 0 0 4-4 4-4 8-11 12-19 0 0 0-4 0-4 4-4 4-11 4-15 0 0 0-4 0-4 0 0 0 0 0-4 4-11 11-19 23-19h57c16 0 27 11 24 27 0 0 0 0 0 0 0 0 0 4 0 4 0 7-4 11-4 19 0 4 0 4-4 8 0 15 0 19-4 27 0 0 0 3-4 3-4 8-8 16-11 23 0 0-4 4-4 4-4 8-8 12-12 16 0 4-4 4-4 7-3 4-7 12-11 16 0 0-4 4-4 4-8 7-12 11-19 19 0 0-4 0-4 4-4 4-12 7-19 11-4 0-4 4-8 4-4 4-12 8-15 8-4 0-4 4-8 4-8 3-15 7-23 7 0 0 0 0 0 0-8 4-16 4-27 8-4 0-4 0-8 0-7 0-11 0-19 4-4 0-8 0-8 0-7 0-15 0-23 0 0 0-4 0-4 0-7 0-15-4-27-4-3 0-11-4-15-4 0 0-4 0-4 0-92-27-157-115-157-215v-93h-43c-15 0-23-11-23-23v-400c0-15 12-23 23-23h535c15 0 23 12 23 23v400c4 12-8 23-23 23z" horiz-adv-x="1000" /> |
|
24 | 24 | |
|
25 | 25 | <glyph glyph-name="feed" unicode="" d="M842 739h-653c-35 0-58-27-58-58v-658c0-31 27-58 58-58h657c31 0 58 27 58 58v658c-4 31-31 58-62 58z m-534-666c-39 0-73 31-73 73s30 73 73 73c38 0 73-30 73-73s-35-73-73-73z m246-11c-35 0-58 27-58 57 0 112-88 200-200 200-31 0-65 27-65 58 0 35 23 62 54 62l11 0c177 0 319-143 319-320-3-30-30-57-61-57z m196 0c-35 0-58 27-58 57 0 220-180 400-400 400-30 0-65 27-65 62 0 34 23 61 54 61l11 0c285 0 520-230 520-519 0-34-27-61-62-61z" horiz-adv-x="1000" /> |
|
26 | 26 | |
|
27 | 27 | <glyph glyph-name="left" unicode="" d="M692 773l70-69c11-12 11-27 0-39l-289-288c-11-12-11-27 0-38l296-297c12-11 12-27 0-38l-69-69c-11-12-27-12-38 0l-404 404c-12 11-12 26 0 38l396 396c11 12 27 12 38 0z" horiz-adv-x="1000" /> |
|
28 | 28 | |
|
29 | 29 | <glyph glyph-name="right" unicode="" d="M339-65l-74 69c-11 11-11 27 0 38l289 289c11 11 11 27 0 38l-296 296c-12 12-12 27 0 39l69 69c12 12 27 12 38 0l404-404c12-11 12-27 0-38l-392-396c-12-12-31-12-38 0z" horiz-adv-x="1000" /> |
|
30 | 30 | |
|
31 | 31 | <glyph glyph-name="down" unicode="" d="M704 454l-173-219c-8-8-23-8-27 0l-173 219c-8 11 0 31 15 31h346c12 0 20-20 12-31z" horiz-adv-x="1000" /> |
|
32 | 32 | |
|
33 | 33 | <glyph glyph-name="folder" unicode="" d="M929 511v-393q0-51-37-88t-88-37h-679q-51 0-88 37t-37 88v536q0 51 37 88t88 37h179q51 0 88-37t37-88v-18h375q51 0 88-37t37-88z" horiz-adv-x="928.6" /> |
|
34 | 34 | |
|
35 | 35 | <glyph glyph-name="folder-open" unicode="" d="M1049 319q0-17-18-37l-187-221q-24-28-67-48t-81-20h-607q-19 0-33 7t-15 24q0 17 17 37l188 221q24 28 67 48t80 20h607q19 0 34-7t15-24z m-192 192v-90h-464q-53 0-110-26t-92-67l-188-221-2-3q0 2-1 7t0 7v536q0 51 37 88t88 37h179q51 0 88-37t37-88v-18h303q52 0 88-37t37-88z" horiz-adv-x="1071.4" /> |
|
36 | 36 | |
|
37 | 37 | <glyph glyph-name="trash-empty" unicode="" d="M286 439v-321q0-8-5-13t-13-5h-36q-8 0-13 5t-5 13v321q0 8 5 13t13 5h36q8 0 13-5t5-13z m143 0v-321q0-8-5-13t-13-5h-36q-8 0-13 5t-5 13v321q0 8 5 13t13 5h36q8 0 13-5t5-13z m142 0v-321q0-8-5-13t-12-5h-36q-8 0-13 5t-5 13v321q0 8 5 13t13 5h36q7 0 12-5t5-13z m72-404v529h-500v-529q0-12 4-22t8-15 6-5h464q2 0 6 5t8 15 4 22z m-375 601h250l-27 65q-4 5-9 6h-177q-6-1-10-6z m518-18v-36q0-8-5-13t-13-5h-54v-529q0-46-26-80t-63-34h-464q-37 0-63 33t-27 79v531h-53q-8 0-13 5t-5 13v36q0 8 5 13t13 5h172l39 93q9 21 31 35t44 15h178q23 0 44-15t30-35l39-93h173q8 0 13-5t5-13z" horiz-adv-x="785.7" /> |
|
38 | 38 | |
|
39 | 39 | <glyph glyph-name="group" unicode="" d="M962 219v-15c0-4-4-12-12-12h-161-4c-16 20-39 39-77 43-35 7-54 15-69 23 7 7 19 11 30 15 46 8 58 23 66 35 7 11 7 23 0 38-8 16-31 43-31 81 0 38 0 104 73 104h8 7c73-4 77-66 73-104 0-38-23-69-30-81-8-15-8-27 0-38 7-12 23-27 65-35 54-4 62-46 62-54 0 0 0 0 0 0z m-708-15c15 15 38 31 69 35 39 7 62 15 73 26-7 8-19 16-34 20-47 7-58 23-66 34-7 12-7 23 0 39 8 15 31 42 31 81 0 38 0 103-73 103h-8-11c-73-3-77-65-73-103 0-39 23-70 30-81 8-16 8-27 0-39-7-11-23-27-65-34-46-8-54-50-54-54 0 0 0 0 0 0v-16c0-3 4-11 12-11h161 8z m454 11c-73 12-96 35-108 54-11 20-11 39 0 62 12 23 50 69 54 131 4 61 0 165-119 169h-16-15c-119-4-123-104-119-166 4-61 38-107 54-130 11-23 11-43 0-62-12-19-35-42-108-54-73-11-85-80-85-88 0 0 0 0 0 0v-23c0-8 8-16 16-16h257 258c8 0 15 8 15 16v23c0 0 0 0 0 0-3 4-11 73-84 84z" horiz-adv-x="1000" /> |
|
40 | 40 | |
|
41 | 41 | <glyph glyph-name="remove" unicode="" d="M724 112q0-22-15-38l-76-76q-16-15-38-15t-38 15l-164 165-164-165q-16-15-38-15t-38 15l-76 76q-16 16-16 38t16 38l164 164-164 164q-16 16-16 38t16 38l76 76q16 16 38 16t38-16l164-164 164 164q16 16 38 16t38-16l76-76q15-15 15-38t-15-38l-164-164 164-164q15-15 15-38z" horiz-adv-x="785.7" /> |
|
42 | 42 | |
|
43 | 43 | <glyph glyph-name="fork" unicode="" d="M792 654c0 58-46 100-100 100-57 0-100-46-100-100 0-35 20-65 47-85-12-84-70-123-127-142-58 15-116 54-127 142 27 20 46 50 46 85 0 58-46 100-100 100s-108-42-108-100c0-39 23-73 54-89 12-107 77-188 181-226v-162c-31-19-50-50-50-88 0-58 46-101 100-101s100 47 100 101c0 38-19 69-50 88v162c104 38 169 119 181 226 30 20 53 50 53 89z m-465 35c19 0 35-16 35-35s-16-31-35-31-35 12-35 31 16 35 35 35z m181-635c-19 0-35 15-35 35s16 34 35 34c19 0 34-15 34-34s-15-35-34-35z m184 635c20 0 35-16 35-35s-15-31-35-31-34 16-34 35 15 31 34 31z" horiz-adv-x="1000" /> |
|
44 | 44 | |
|
45 | 45 | <glyph glyph-name="more" unicode="" d="M546 435h-100c-15 0-27-12-27-27v-100c0-16 12-27 27-27h100c16 0 27 11 27 27v100c0 15-11 27-27 27z m0 307h-100c-15 0-27-11-27-27v-100c0-15 12-26 27-26h100c16 0 27 11 27 26v100c0 16-11 27-27 27z m0-615h-100c-15 0-27-12-27-27v-100c0-15 12-27 27-27h100c16 0 27 12 27 27v100c0 15-11 27-27 27z" horiz-adv-x="1000" /> |
|
46 | 46 | |
|
47 | 47 | <glyph glyph-name="search" unicode="" d="M643 386q0 103-73 176t-177 74-177-74-73-176 73-177 177-73 177 73 73 177z m286-465q0-29-22-50t-50-21q-30 0-50 21l-191 191q-100-69-223-69-80 0-153 31t-125 84-84 125-31 153 31 152 84 126 125 84 153 31 153-31 125-84 84-126 31-152q0-123-69-223l191-191q21-21 21-51z" horiz-adv-x="928.6" /> |
|
48 | 48 | |
|
49 | 49 | <glyph glyph-name="scissors" unicode="" d="M536 350q14 0 25-11t10-25-10-25-25-10-25 10-11 25 11 25 25 11z m167-36l283-222q16-11 14-31-3-20-19-28l-72-36q-7-4-16-4-10 0-17 4l-385 216-62-36q-4-3-7-3 8-28 6-54-4-43-31-83t-74-69q-74-47-154-47-76 0-124 44-51 47-44 116 4 42 31 82t73 69q74 47 155 47 46 0 84-18 5 8 13 13l68 40-68 41q-8 5-13 12-38-17-84-17-81 0-155 47-46 30-73 69t-31 82q-3 33 8 63t36 52q47 44 124 44 80 0 154-47 46-29 74-68t31-83q2-27-6-54 3-1 7-3l62-37 385 216q7 5 17 5 9 0 16-4l72-36q16-9 19-28 2-20-14-32z m-380 145q26 24 12 61t-59 65q-52 33-107 33-42 0-63-20-26-24-12-60t59-66q51-33 107-33 41 0 63 20z m-47-415q45 28 59 65t-12 60q-22 20-63 20-56 0-107-33-45-28-59-65t12-60q21-20 63-20 55 0 107 33z m99 342l54-33v7q0 20 18 31l8 4-44 26-15-14q-1-2-5-6t-7-7q-1-1-2-2t-2-1z m125-125l54-18 410 321-71 36-429-240v-64l-89-53 5-5q1-1 4-3 2-2 6-7t6-6l15-15z m393-232l71 35-290 228-99-77q-1-2-7-4z" horiz-adv-x="1000" /> |
|
50 | 50 | |
|
51 | 51 | <glyph glyph-name="download" unicode="" d="M714 100q0 15-10 25t-25 11-25-11-11-25 11-25 25-11 25 11 10 25z m143 0q0 15-10 25t-26 11-25-11-10-25 10-25 25-11 26 11 10 25z m72 125v-179q0-22-16-37t-38-16h-821q-23 0-38 16t-16 37v179q0 22 16 38t38 16h259l75-76q33-32 76-32t76 32l76 76h259q22 0 38-16t16-38z m-182 318q10-23-8-39l-250-250q-10-11-25-11t-25 11l-250 250q-17 16-8 39 10 21 33 21h143v250q0 15 11 25t25 11h143q14 0 25-11t10-25v-250h143q24 0 33-21z" horiz-adv-x="928.6" /> |
|
52 | 52 | |
|
53 | 53 | <glyph glyph-name="doc" unicode="" d="M819 638q16-16 27-42t11-50v-642q0-23-15-38t-38-16h-750q-23 0-38 16t-16 38v892q0 23 16 38t38 16h500q22 0 49-11t42-27z m-248 136v-210h210q-5 17-12 23l-175 175q-6 7-23 12z m215-853v572h-232q-23 0-38 16t-16 37v233h-429v-858h715z" horiz-adv-x="857.1" /> |
|
54 | 54 | |
|
55 | 55 | <glyph glyph-name="cog" unicode="" d="M571 350q0 59-41 101t-101 42-101-42-42-101 42-101 101-42 101 42 41 101z m286 61v-124q0-7-4-13t-11-7l-104-16q-10-30-21-51 19-27 59-77 6-6 6-13t-5-13q-15-21-55-61t-53-39q-7 0-14 5l-77 60q-25-13-51-21-9-76-16-104-4-16-20-16h-124q-8 0-14 5t-6 12l-16 103q-27 9-50 21l-79-60q-6-5-14-5-8 0-14 6-70 64-92 94-4 5-4 13 0 6 5 12 8 12 28 37t30 40q-15 28-23 55l-102 15q-7 1-11 7t-5 13v124q0 7 5 13t10 7l104 16q8 25 22 51-23 32-60 77-6 7-6 14 0 5 5 12 15 20 55 60t53 40q7 0 15-5l77-60q24 13 50 21 9 76 17 104 3 16 20 16h124q7 0 13-5t7-12l15-103q28-9 51-20l79 59q5 5 13 5 7 0 14-5 72-67 92-95 4-5 4-12 0-7-4-13-9-12-29-37t-30-40q15-28 23-54l102-16q7-1 12-7t4-13z" horiz-adv-x="857.1" /> |
|
56 | 56 | |
|
57 | 57 | <glyph glyph-name="cog-alt" unicode="" d="M500 350q0 59-42 101t-101 42-101-42-42-101 42-101 101-42 101 42 42 101z m429-286q0 29-22 51t-50 21-50-21-21-51q0-29 21-50t50-21 51 21 21 50z m0 572q0 29-22 50t-50 21-50-21-21-50q0-30 21-51t50-21 51 21 21 51z m-215-235v-103q0-6-4-11t-8-6l-87-14q-6-19-18-42 19-27 50-64 4-6 4-11 0-7-4-11-12-17-46-50t-43-33q-7 0-12 4l-64 50q-21-11-43-17-6-60-13-87-4-13-17-13h-104q-6 0-11 4t-5 10l-13 85q-19 6-42 18l-66-50q-4-4-11-4-6 0-12 4-80 75-80 90 0 5 4 10 5 8 23 30t26 34q-13 24-20 46l-85 13q-5 1-9 5t-4 11v104q0 5 4 10t9 6l86 14q7 19 18 42-19 27-50 64-4 6-4 11 0 7 4 12 12 16 46 49t44 33q6 0 12-4l64-50q19 10 43 18 6 60 13 86 3 13 16 13h104q6 0 11-4t6-10l13-85q19-6 42-17l65 49q5 4 12 4 6 0 11-4 81-75 81-90 0-4-4-10-7-9-24-30t-25-34q13-27 19-46l85-12q6-2 9-6t4-11z m357-298v-78q0-9-83-17-6-15-16-29 28-63 28-77 0-2-2-4-68-40-69-40-5 0-26 27t-29 37q-11-1-17-1t-17 1q-7-11-29-37t-25-27q-1 0-69 40-3 2-3 4 0 14 29 77-10 14-17 29-83 8-83 17v78q0 9 83 18 7 16 17 29-29 63-29 77 0 2 3 4 2 1 19 11t33 19 17 9q4 0 25-26t29-38q12 1 17 1t17-1q28 40 51 63l4 1q2 0 69-39 2-2 2-4 0-14-28-77 9-13 16-29 83-9 83-18z m0 572v-78q0-9-83-18-6-15-16-29 28-63 28-77 0-2-2-4-68-39-69-39-5 0-26 26t-29 38q-11-1-17-1t-17 1q-7-12-29-38t-25-26q-1 0-69 39-3 2-3 4 0 14 29 77-10 14-17 29-83 9-83 18v78q0 9 83 17 7 16 17 29-29 63-29 77 0 2 3 4 2 1 19 11t33 19 17 9q4 0 25-26t29-37q12 1 17 1t17-1q28 39 51 62l4 1q2 0 69-39 2-2 2-4 0-14-28-77 9-13 16-29 83-8 83-17z" horiz-adv-x="1071.4" /> |
|
58 | 58 | |
|
59 | 59 | <glyph glyph-name="eye" unicode="" d="M929 314q-85 132-213 197 34-58 34-125 0-103-73-177t-177-73-177 73-73 177q0 67 34 125-128-65-213-197 75-114 187-182t242-68 243 68 186 182z m-402 215q0 11-8 19t-19 7q-70 0-120-50t-50-119q0-11 8-19t19-8 19 8 8 19q0 48 34 82t82 34q11 0 19 8t8 19z m473-215q0-19-11-38-78-129-210-206t-279-77-279 77-210 206q-11 19-11 38t11 39q78 128 210 205t279 78 279-78 210-205q11-20 11-39z" horiz-adv-x="1000" /> |
|
60 | 60 | |
|
61 | 61 | <glyph glyph-name="eye-off" unicode="" d="M310 105l43 79q-48 35-76 88t-27 114q0 67 34 125-128-65-213-197 94-144 239-209z m217 424q0 11-8 19t-19 7q-70 0-120-50t-50-119q0-11 8-19t19-8 19 8 8 19q0 48 34 82t82 34q11 0 19 8t8 19z m202 106q0-4 0-5-59-105-176-316t-176-316l-28-50q-5-9-15-9-7 0-75 39-9 6-9 16 0 7 25 49-80 36-147 96t-117 137q-11 17-11 38t11 39q86 131 212 207t277 76q50 0 100-10l31 54q5 9 15 9 3 0 10-3t18-9 18-10 18-10 10-7q9-5 9-15z m21-249q0-78-44-142t-117-91l157 280q4-25 4-47z m250-72q0-19-11-38-22-36-61-81-84-96-194-149t-234-53l41 74q119 10 219 76t169 171q-65 100-158 164l35 63q53-36 102-85t81-103q11-19 11-39z" horiz-adv-x="1000" /> |
|
62 | 62 | |
|
63 | 63 | <glyph glyph-name="cancel-circled2" unicode="" d="M612 248l-81-82q-6-5-13-5t-13 5l-76 77-77-77q-5-5-13-5t-12 5l-82 82q-6 6-6 13t6 13l76 76-76 77q-6 5-6 12t6 13l82 82q5 5 12 5t13-5l77-77 76 77q6 5 13 5t13-5l81-82q6-5 6-13t-6-12l-76-77 76-76q6-6 6-13t-6-13z m120 102q0 83-41 152t-110 111-152 41-153-41-110-111-41-152 41-152 110-111 153-41 152 41 110 111 41 152z m125 0q0-117-57-215t-156-156-215-58-216 58-155 156-58 215 58 215 155 156 216 58 215-58 156-156 57-215z" horiz-adv-x="857.1" /> |
|
64 | 64 | |
|
65 | 65 | <glyph glyph-name="cancel-circled" unicode="" d="M641 224q0 14-10 25l-101 101 101 101q10 11 10 25 0 15-10 26l-51 50q-10 11-25 11-15 0-25-11l-101-101-101 101q-11 11-25 11-16 0-26-11l-50-50q-11-11-11-26 0-14 11-25l101-101-101-101q-11-11-11-25 0-15 11-26l50-50q10-11 26-11 14 0 25 11l101 101 101-101q10-11 25-11 15 0 25 11l51 50q10 11 10 26z m216 126q0-117-57-215t-156-156-215-58-216 58-155 156-58 215 58 215 155 156 216 58 215-58 156-156 57-215z" horiz-adv-x="857.1" /> |
|
66 | 66 | |
|
67 | 67 | <glyph glyph-name="plus" unicode="" d="M786 439v-107q0-22-16-38t-38-15h-232v-233q0-22-16-37t-38-16h-107q-22 0-38 16t-15 37v233h-232q-23 0-38 15t-16 38v107q0 23 16 38t38 16h232v232q0 22 15 38t38 16h107q23 0 38-16t16-38v-232h232q23 0 38-16t16-38z" horiz-adv-x="785.7" /> |
|
68 | 68 | |
|
69 | 69 | <glyph glyph-name="plus-circled" unicode="" d="M679 314v72q0 14-11 25t-25 10h-143v143q0 15-11 25t-25 11h-71q-15 0-25-11t-11-25v-143h-143q-14 0-25-10t-10-25v-72q0-14 10-25t25-10h143v-143q0-15 11-25t25-11h71q15 0 25 11t11 25v143h143q14 0 25 10t11 25z m178 36q0-117-57-215t-156-156-215-58-216 58-155 156-58 215 58 215 155 156 216 58 215-58 156-156 57-215z" horiz-adv-x="857.1" /> |
|
70 | 70 | |
|
71 | 71 | <glyph glyph-name="minus-circled" unicode="" d="M679 314v72q0 14-11 25t-25 10h-429q-14 0-25-10t-10-25v-72q0-14 10-25t25-10h429q14 0 25 10t11 25z m178 36q0-117-57-215t-156-156-215-58-216 58-155 156-58 215 58 215 155 156 216 58 215-58 156-156 57-215z" horiz-adv-x="857.1" /> |
|
72 | 72 | |
|
73 | 73 | <glyph glyph-name="minus" unicode="" d="M786 439v-107q0-22-16-38t-38-15h-678q-23 0-38 15t-16 38v107q0 23 16 38t38 16h678q23 0 38-16t16-38z" horiz-adv-x="785.7" /> |
|
74 | 74 | |
|
75 | 75 | <glyph glyph-name="info-circled" unicode="" d="M571 82v89q0 8-5 13t-12 5h-54v286q0 8-5 13t-13 5h-178q-8 0-13-5t-5-13v-89q0-8 5-13t13-5h53v-179h-53q-8 0-13-5t-5-13v-89q0-8 5-13t13-5h250q7 0 12 5t5 13z m-71 500v89q0 8-5 13t-13 5h-107q-8 0-13-5t-5-13v-89q0-8 5-13t13-5h107q8 0 13 5t5 13z m357-232q0-117-57-215t-156-156-215-58-216 58-155 156-58 215 58 215 155 156 216 58 215-58 156-156 57-215z" horiz-adv-x="857.1" /> |
|
76 | 76 | |
|
77 | 77 | <glyph glyph-name="upload" unicode="" d="M714 29q0 14-10 25t-25 10-25-10-11-25 11-25 25-11 25 11 10 25z m143 0q0 14-10 25t-26 10-25-10-10-25 10-25 25-11 26 11 10 25z m72 125v-179q0-22-16-38t-38-16h-821q-23 0-38 16t-16 38v179q0 22 16 38t38 15h238q12-31 39-51t62-20h143q34 0 61 20t40 51h238q22 0 38-15t16-38z m-182 361q-9-22-33-22h-143v-250q0-15-10-25t-25-11h-143q-15 0-25 11t-11 25v250h-143q-23 0-33 22-9 22 8 39l250 250q10 10 25 10t25-10l250-250q18-17 8-39z" horiz-adv-x="928.6" /> |
|
78 | 78 | |
|
79 | <glyph glyph-name="home" unicode="" d="M888 336q16-16 11-27t-27-11l-84 0 0-310q0-14-1-21t-8-13-23-6l-204 0 0 310-204 0 0-310-194 0q-28 0-35 10t-7 30l0 310-84 0q-22 0-27 11t11 27l400 402q16 16 38 16t38-16z" horiz-adv-x="900" /> | |
|
80 | ||
|
79 | 81 | <glyph glyph-name="git" unicode="" d="M929 844h-858c-36 0-65-30-65-65v-857c0-36 30-65 65-65h857c36 0 65 30 65 65v857c1 35-29 65-64 65z m-729-549c4-11 9-20 14-27 6-8 14-14 22-18 9-4 19-6 29-6 9 0 16 1 24 2 7 2 14 4 20 7l6 51h-27c-4 0-8 1-10 4-2 1-3 5-3 7l5 39h105l-16-131c-8-7-16-12-25-15-9-4-18-8-28-10-10-3-18-5-30-7-10-1-21-2-33-2-20 0-38 4-54 11-16 8-30 18-41 30-12 13-20 28-27 45-6 18-10 36-10 56 0 18 3 34 7 50 3 17 10 30 17 44 8 14 16 25 26 36 10 12 22 20 34 28 13 7 26 14 41 17 15 4 30 7 47 7 13 0 25-2 36-4 11-3 21-6 29-10 8-4 16-9 22-14 6-5 13-11 18-16l-20-31c-4-5-9-8-14-9-5-1-10 0-16 4-5 3-10 6-14 8-5 3-9 5-14 7-5 1-10 2-15 3-5 2-11 2-17 2-14 0-27-3-38-9-11-6-21-14-29-25-8-10-15-24-18-38-5-15-7-31-7-48-1-14 2-27 4-38z m336-102h-71l39 315h71l-39-315z m343 258h-80l-33-258h-70l32 258h-80l7 57h231l-7-57z" horiz-adv-x="1000" /> |
|
80 | 82 | |
|
81 | 83 | <glyph glyph-name="hg" unicode="" d="M927 841h-853c-36 0-65-29-65-65v-853c0-36 29-65 65-65h853c36 0 65 29 65 65v853c0 36-29 65-65 65z m-483-648h-70l16 133h-113l-17-133h-70l39 313h70l-16-132h113l16 132h71l-39-313z m177 101c3-11 8-20 14-27 7-8 14-14 23-18 8-4 18-6 28-6 9 0 16 1 23 3 7 1 14 3 20 6l6 51h-27c-4 0-7 1-9 3-3 3-3 6-3 9l5 39h104l-16-131c-8-6-16-11-25-15-9-5-18-8-27-11-9-2-19-4-30-6-10-1-21-2-33-2-19 0-37 4-53 11-16 7-30 17-41 29-11 13-20 28-26 45-7 17-10 35-10 55 0 17 2 34 6 50 4 15 10 30 17 43 7 14 16 26 26 36 10 11 22 20 34 28 13 7 27 13 41 17 14 4 30 7 46 7 13 0 25-2 36-4 11-3 20-6 29-10 8-4 16-9 23-14 7-5 13-11 18-17l-23-28c-4-5-8-8-13-9-5-1-11 0-16 3-5 4-10 7-14 9-5 3-9 5-14 6-4 2-9 3-14 4-5 1-11 1-17 1-14 0-27-3-38-8-11-6-21-14-29-25-8-10-15-23-19-38-5-15-7-31-7-49 0-13 2-26 5-37z" horiz-adv-x="1000" /> |
|
82 | 84 | |
|
83 | 85 | <glyph glyph-name="svn" unicode="" d="M933 841h-852c-36 0-65-29-65-65v-853c0-36 29-65 65-65h852c36 0 66 29 66 65v853c0 36-30 65-66 65z m-765-438c3-4 7-7 13-10 5-3 11-6 18-8 7-3 14-5 21-8 7-3 14-6 21-10 7-4 13-9 18-14 5-6 10-13 13-20 3-8 5-18 5-29 0-16-3-30-8-44-6-14-14-26-24-37-10-10-22-18-37-24-15-7-31-10-49-10-9 0-18 1-27 3s-18 5-27 9c-8 4-16 8-23 13-7 5-13 10-18 17l25 32c2 3 4 5 7 6 3 2 6 3 9 3 4 0 8-2 12-4 3-3 8-6 12-10 5-3 10-6 16-9 6-3 14-4 23-4 13 0 23 3 30 10 7 7 10 18 10 32 0 6-1 12-4 16-4 4-8 7-13 10-5 3-11 6-18 8-7 2-14 5-21 7-7 3-14 6-21 9-6 4-12 8-18 14-5 6-9 13-12 21-3 8-5 18-5 30 0 14 3 28 8 40 5 13 12 25 22 35 10 9 22 17 36 23 14 6 29 9 47 9 9 0 17-1 26-3s16-4 23-8c7-3 14-7 20-11 6-5 11-10 15-15l-21-29c-2-3-5-6-7-7-3-2-6-3-9-3-3 0-7 1-10 3-3 3-7 5-11 8-4 2-9 4-14 7-5 2-12 3-19 3-6 0-12-1-17-3-5-2-9-4-12-8-4-3-6-7-8-11-1-5-2-10-2-15 0-5 2-10 5-14z m312-210h-64l-77 313h57c6 0 10-1 14-4 4-3 6-6 7-11l32-173c2-7 4-14 6-23 1-8 3-17 4-26 3 9 6 18 9 26 4 9 7 16 11 23l73 173c1 2 2 4 4 6 2 2 4 3 6 5 2 1 4 2 7 3 3 1 5 1 8 1h57l-154-313z m423 0h-37c-5 0-10 1-13 2-4 2-7 5-10 9l-109 194c-1-4-1-8-1-12-1-4-1-7-1-10l-22-183h-62l39 313h37c3 0 6 0 8 0 2 0 4-1 5-1 2-1 3-2 4-4s3-3 5-5l110-194c0 5 0 10 1 14 0 5 1 9 1 13l21 177h62l-38-313z" horiz-adv-x="1000" /> |
|
84 | 86 | |
|
85 | 87 | <glyph glyph-name="comment-add" unicode="" d="M952 258v317c0 7 0 13 0 20-1 12-4 24-8 36-7 22-20 43-37 59-16 17-36 30-58 37-12 4-25 7-37 8-7 1-13 1-19 1h-576c-13 0-26 0-38-2-13-2-25-5-36-10-22-9-41-23-57-40-15-18-27-39-33-62-3-12-5-25-5-38-1-13 0-26 0-39v-557c0-9 5-17 13-21 6-3 15-3 21 0 3 1 5 3 7 5 2 2 4 5 7 7 4 5 9 9 14 14l28 28c9 10 19 19 28 29 9 9 19 18 28 27 4 5 8 9 14 10 2 1 5 1 8 1h567c13 0 25 0 38 2 24 4 47 13 66 27 19 13 35 31 46 51 12 22 19 46 19 71 1 6 0 13 0 19z m-69 307v-317c0-7 0-13 0-19-1-6-3-13-5-18-4-10-9-20-16-28-15-17-37-27-59-28-7 0-13 0-19 0h-576c-7 0-13 0-20 0-3 0-6 0-9-1-3-1-5-2-7-4-2-2-4-4-6-6-3-2-5-4-7-7-5-4-10-9-14-14-10-9-19-18-28-28v485c0 12 2 24 7 35 4 10 10 19 18 27 16 16 38 25 60 25h590c6 0 12 0 18-1 22-3 42-15 56-33 7-9 12-20 15-31 1-5 2-12 2-18 1-6 0-13 0-19z m-214-117h-131c-4 0-11 8-11 12v126c0 8-8 16-12 16h-50c-7 0-15-8-15-12v-130c0-4-8-12-12-12h-126c-8 0-16-8-16-11v-50c0-8 8-16 12-16h127c7 0 15-7 15-11v-127c0-8 8-15 11-15h50c8 0 16 7 16 11v127c0 8 7 15 11 15h127c8 0 15 8 15 12v50c0 7-7 15-11 15z" horiz-adv-x="1000" /> |
|
86 | 88 | |
|
87 | 89 | <glyph glyph-name="comment-toggle" unicode="" d="M798 736h-596c-85 0-154-69-154-155v-593c0-19 22-29 36-20 2 1 5 3 7 5l109 109c2 2 5 4 8 5 2 1 4 1 6 1h584c85 0 154 69 154 155v338c0 86-69 155-154 155z m-680-639v484c0 47 38 85 86 85h476c-86-84-504-511-509-515l-53-54z" horiz-adv-x="1000" /> |
|
88 | 90 | |
|
89 | 91 | <glyph glyph-name="rhodecode" unicode="" d="M175 633c-2-4-3-8-4-12-3-10-6-20-9-30-3-13-7-25-11-38-3-11-6-23-10-35-2-7-4-15-6-22-1-1-1-2-1-4 0 0 0 0 0 0 0-1 1-2 1-2 2-7 5-14 7-21 4-11 8-22 12-33 4-12 9-25 13-37 4-11 8-23 12-34 3-7 5-14 7-21 1-1 1-2 2-3 0-1 1-1 1-2 4-6 8-12 11-17 7-10 13-19 19-29 7-11 14-22 22-33 6-10 13-21 20-31 5-7 9-15 14-22 1-2 3-4 4-5 0-1 1-1 1-2 3-3 6-5 8-8 7-6 13-12 19-19 9-8 17-16 25-24 10-10 19-19 29-28 9-9 18-18 27-27 8-8 16-15 23-23 5-5 11-10 16-15 1-1 3-3 5-5 7-5 14-10 21-15 11-8 21-15 31-23 4-2 7-5 11-7 0-1 1-2 2-2 0 0 0-1 1 0 7 3 14 7 21 11 11 6 23 11 34 17 6 4 12 7 19 10 0 0 0 1 1 1 1 2 2 3 3 5 4 5 8 10 13 15 6 8 12 16 18 24 8 9 15 19 23 28 8 11 16 21 24 31 8 11 16 21 24 31 8 10 15 19 23 28 6 8 12 16 18 24 4 5 8 10 12 15 2 2 3 3 4 5 0 0 0 0 0 0-1 1-2 1-3 1-3 0-6 1-9 2-5 1-10 2-15 3-6 2-13 4-20 5-8 3-16 5-24 7-9 3-19 6-28 9-10 3-21 7-31 11-12 4-23 8-34 13-12 5-24 10-36 15-13 6-26 12-38 18-13 7-26 14-39 21-13 7-27 15-39 23-14 9-27 17-40 27-13 9-26 19-39 29-13 11-25 22-37 33-13 11-25 23-36 36-12 13-23 26-34 40-11 14-21 28-31 43-9 15-19 31-27 47 0 1 0 1 0 1z m-3 3c-1-5-3-9-4-14-3-10-7-21-10-32-4-12-8-25-12-37-3-10-6-20-9-30-1-3-2-6-3-8 0-1 0-2 0-2 1-5 3-10 5-15 3-10 6-20 10-30 4-12 8-24 12-37 4-12 8-24 12-36 3-9 6-18 9-26 1-3 1-5 2-8 0 0 1-1 1-2 2-4 5-8 7-12 5-10 10-19 15-28 6-11 12-23 19-34 6-11 12-22 18-33 4-8 8-15 12-23 1-2 2-4 4-6 4-5 8-9 13-14 7-8 15-16 23-24 9-10 18-20 26-29 9-9 17-18 25-26 5-6 10-11 15-17 2-1 3-3 5-5 5-5 11-11 17-17 9-8 17-17 26-26 9-9 18-18 27-27 7-7 14-14 21-21 2-2 3-3 5-5 0 0 1-1 1-1 0 0 1 0 1 0 11 2 22 3 32 5 9 1 17 2 26 3 0 0 1 1 1 1 1 1 2 3 4 4 4 5 9 10 13 15 7 8 14 15 20 22 9 9 17 18 25 27 9 10 18 20 27 30 8 9 17 19 26 29 8 9 16 17 24 26 7 7 13 15 20 22 4 5 8 9 13 14 1 1 2 2 3 3 0 1 1 1 1 1 0 1-3 1-3 1-3 1-7 2-10 3-4 2-9 3-14 5-6 2-13 4-19 6-8 3-16 6-24 9-9 3-18 7-27 11-10 4-20 8-30 13-11 5-22 10-33 16-12 5-23 11-35 18-12 6-24 13-36 20-12 8-25 16-37 24-13 8-25 17-37 26-13 10-25 19-38 29-12 11-24 21-36 33-12 11-24 23-35 35-11 13-22 25-33 39-10 13-21 27-30 42-10 15-19 30-27 45-9 16-17 32-24 48z m-2 10c-1-4-2-8-3-11-1-10-3-19-5-29-2-12-5-25-7-37-3-13-5-26-8-39-1-10-3-20-5-30-1-5-2-10-3-15 0-1 0-1 0-2 1-3 2-5 3-8 3-9 7-19 10-29 4-12 9-25 13-37 4-11 8-22 11-33 2-5 4-11 6-16 0-1 1-2 1-2 1-3 2-5 4-7 4-9 8-18 13-27 6-12 11-23 17-35 6-11 11-22 17-33 3-7 7-14 11-21 0-2 1-3 1-4 1-1 2-1 2-2 5-6 9-11 14-17 8-9 15-18 22-27 9-10 17-20 26-30 7-9 15-18 22-27 5-6 10-11 15-17 0-1 1-2 2-3 0 0 0 0 0 0 1-1 2-1 3-2 7-4 14-9 21-14 10-7 21-14 31-22 11-7 21-14 31-20 6-4 12-9 18-13 3-2 7-5 10-8 10-8 19-16 29-24 7-5 13-11 20-17 1 0 1 0 1 1 1 1 2 2 3 3 4 4 8 8 12 13 6 6 12 13 18 20 8 8 16 17 23 25 9 10 18 19 26 29 9 9 18 19 27 29 9 9 18 19 26 28 8 9 16 17 23 26 6 6 13 13 19 20 4 4 7 8 11 12 1 2 3 3 4 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0-3 1-3 1-3 1-6 2-9 2-5 2-10 4-15 5-6 2-12 5-18 7-8 3-16 6-24 9-8 4-17 8-26 12-10 4-20 9-30 13-11 6-22 11-32 16-12 6-23 13-35 19-12 7-23 14-35 21-13 8-25 16-37 24-12 8-25 17-37 26-12 9-24 19-36 29-13 10-25 21-36 32-12 11-24 22-35 34-12 12-22 25-33 38-11 13-21 26-30 40-10 14-19 29-28 44-9 15-17 30-24 46-4 10-8 20-12 30z m696 21c-2 4-5 7-9 9-5 3-11 5-16 8-11 4-23 9-34 13-23 8-47 14-71 20-24 6-49 12-74 17-25 6-50 10-76 15-25 4-50 8-75 10-13 1-26 1-39 0-6-1-13-2-19-3-6-1-13-2-19-3-26-4-51-9-77-14-25-5-50-10-75-16-25-5-49-12-74-20-12-4-24-9-36-13-6-3-11-5-17-8-3-1-6-2-9-3-3-1-5-2-8-4-4-2-7-5-10-9-1-2-2-4-3-7-1-3-2-6-3-9-4-11-7-24-9-36-5-24-7-49-6-74 0-13 1-25 3-38 1-12 3-25 5-37 5-25 12-50 20-74 4-12 8-24 13-36 4-11 10-22 15-33 10-21 21-42 34-62 12-20 25-39 39-58 14-19 28-37 43-55 16-18 33-36 50-54 17-18 34-35 52-52 18-17 36-33 55-49 10-7 19-15 28-22 10-8 19-15 28-23 2-2 5-4 7-7 0 0 1-1 1-1 0 0 1 0 1 0 0 0 1 0 2 0 4 4 9 8 14 11 9 8 19 15 28 23 18 15 36 31 54 47 18 16 35 32 52 49 17 16 33 34 49 51 16 18 32 37 47 56 14 18 28 38 41 57 13 20 25 40 36 61 11 21 21 43 30 65 9 22 17 45 23 68 6 23 11 47 13 70 3 24 3 49 2 73 0 3-1 6-2 9 0 3-1 6-2 9-1 6-2 12-3 18-3 11-5 22-8 33-4 9-7 19-11 28-2 5 13-29 0 0z m-51-210c-7-25-15-49-26-73-9-22-19-44-30-64-12-21-24-40-37-59-13-19-27-38-42-56-15-18-31-36-47-54-17-18-34-36-52-53-18-17-37-34-56-50-9-7-19-15-28-23-1 0-2-1-2-1-1 0-2 0-2 0-1 0-2 1-2 1 0 0-1 1-1 1-2 1-3 3-4 4-4 3-9 7-14 11-2 1-4 3-7 5-2 2-4 4-6 6-5 4-9 8-14 13-9 8-18 17-27 25-10 9-18 18-27 27-4 4-8 9-13 13-4 4-8 9-12 13-17 17-33 35-49 53-15 18-30 37-44 57-14 20-27 40-38 61-12 21-23 42-32 64-10 22-18 45-25 67-2 6-4 12-5 19-1 6-2 12-3 19-2 13-4 26-4 39-1 13-2 26-1 39 0 12 1 25 3 37 0 4 0 7 1 10 0 1 0 3 0 5 1 1 1 3 1 4 0 3 1 5 2 7 0 2 0 3 0 4 0 1 1 2 2 3 1 0 2 1 3 2 0 0 1 0 1 1 1 0 2 0 3 1 3 1 6 2 9 3 6 2 12 5 18 7 23 8 47 16 72 23 12 3 24 6 37 9 6 1 12 2 18 4 7 1 13 2 19 4 26 5 51 9 77 13 13 1 26 3 39 5 3 0 7 1 10 1 1 1 3 1 4 1 2 0 3 0 4 0 6 0 12 0 17-1 1 0 2-1 4-1 1 0 3-1 4-1 3 0 6-1 9-1 7-1 13-2 19-3 13-2 25-4 38-6 25-4 51-8 76-13 25-6 50-12 75-19 12-4 24-8 37-12 6-2 12-4 18-6 3-1 6-2 9-3 1-1 3-1 4-2 1 0 1 0 2 0 1-1 2-1 2-1 2-2 3-2 4-4 1-1 1-1 1-2 0-1 0-2 0-2 1-1 1-2 1-3 2-6 3-13 4-19 1-7 2-13 3-20 0-3 0-6 0-9 0-1 0-2 0-2 0-1 0-2 0-3 1-1 1-3 1-5 5-23 7-48 5-72-1-13-3-26-6-38-8-29 8 35 0 0z m-197 0c-2 4-3 9-5 13 0 1 0 1 0 2-1 0 0 1-1 1 0 1 0 2 0 2 0 1-1 2-1 3-1 2-3 4-4 5-2 2-5 4-7 4 2 2 4 3 7 5 1 1 2 2 3 2 1 1 2 1 2 2 0 1 0 1 0 2 1 0 1 1 2 1 0 1 1 2 1 4 0 2 0 4 0 6 0 3 0 5 0 7 0 3 0 5-1 7-1 6-4 10-8 14-1 2-3 3-5 4-3 2-5 4-8 5-3 1-6 2-9 3-3 0-5 0-7 0-3 0-6 0-8 0-13 0-25 0-37 0-5 0-10 0-14 0-1 0-2 0-3 0 0 0 0-4 0-5 0-3 0-6 0-9 0-1 0-2 0-3 0-1 0-1 1-1 1 0 12 0 12 0 0-8 0-16 0-24 0-13 0-25 0-38 0-4 0-7 0-11 0 0 0-1 0-1-3 0-5 0-8 0-1 0-2 0-4 0 0 0-1 0-1-1 0-2 0-4 0-6 0-1 0-14 0-14 10 0 19 0 29 0 5 0 11 0 16 0 1 0 3 0 4 0 0 0 0 3 0 3 0 6 0 11 0 17 0 1 0 1-1 1-1 0-2 0-4 0-1 0-3 0-4 0 0 0-1-1-1 0 0 5 0 10 0 15 0 2 0 5 0 8 0 1 0 1 0 2 0 0 0 0 1 0 2 0 5 0 8 0 2 0 4 0 6 0 1 0 3 0 4 0 1 0 2-1 3-2 1-1 2-2 3-3 0-1 0-1 0-2 0-2 1-3 1-4 1-1 1-2 2-3 0-1 0-1 0-1 0-1 0-2 0-2 1-6 2-12 3-17 1-3 1-5 2-8 0 0 0-1 0-1 0 0 0 0 0 0 11 0 21 0 32 0 0 0 1 0 1 0 0 0 0 0 0 0 0 3 0 5 0 8 0 5 0 10 0 15 0 0 0 0 0 0-1-2-1-4-2-5z m-26 53c0-2-3-3-4-4-1 0-1-1-1-1 0 0-1 0-1 0 0 0-1 0-1 0-1-1-1-2-2-2-1 0-2 0-3 0-2 0-4 0-5 0-1 0-2 0-2 0-3 0-7 0-10 0 0 0-4 0-4 0 0 9 0 19 0 28 0 0 13 0 14 0 4 0 8 0 12-1 1 0 3-1 4-2 1 0 2-1 3-2 1-2 2-4 3-6 0-1 0-1 0-2-1-1-1-1-1-2-1-1-1-1-1-2-1-1-1-2-1-4z m131-53c0 9 0 18 0 27 0 9-2 18-8 24-7 7-19 8-28 7-2 0-4 0-6-1-1 0-1-1-2-2-1 0-2 0-2-1-3-1-6-3-8-6 0 9 0 18 0 27 0 6 0 12 0 18 0 2 0 3 0 5 0 1 0 1 0 1-11 0-22 0-32 0-1 0-3 0-4 0 0 0 0-4 0-4 0-5 0-11 0-16 0 0 1 0 1 0 1 0 3 0 4 0 3 0 5 0 8 0 0 0 0-5 0-6 0-11 0-23 0-34 0-11 0-22 0-33 0-1 0-2 0-3 0-1 0-1-1-1-3 0-6 0-9 0-1 0-2 0-3 0 0 0 0-1 0-1 0-6 0-11 0-17 0-1 0-1 0-2 0 0 0 0 0 0 2 0 3 0 4 0 12 0 24 0 36 0 0 0 9 0 9 0 0 5 0 10 0 15 0 1 0 3 0 5 0 0-6 0-7 0 0 0-6 0-6 0 0 1 0 3 0 4 0 6 0 12 0 18 0 3 0 5 0 7 0 1 0 1 0 2 0 0 1 1 2 2 1 1 2 2 3 2 1 1 1 1 2 1 1 0 1 0 1 1 2 1 3 1 4 1 3 1 5 0 7-1 1-1 2-2 3-3 1-1 2-2 2-3 1-2 1-4 1-6 0-3 0-7 0-11 0-11 0-22 0-33 0-1 0-2 1-2 1 0 3 0 5 0 6 0 12 0 19 0 3 0 7 0 11 0 0 0 0 14 0 15 0 2 0 4 0 6-2-1-5-2-7-2z m7 122c-2 0-5 0-7 0-1 0-2 0-3 0 0 0 0 0 0 0-3-5-7-10-10-14-1-2-3-5-4-7 0 0-1-1-1-2 0 0 0-1 0-1 0-1 0-4 0-4 0 0 1 0 2 0 3 0 5 0 8 0 3 0 5 0 8 0 0 0 0-1 0-1 0-1 0-3 0-4 0-2 0-3 0-4 0-1 0-1 1-1 1 0 3 0 4 0 1 0 2 0 2 0 0 3 0 6 0 8 0 1 0 2 1 2 1 0 2 0 4 0 0 0 0 0 0 0 0 1 0 1 0 2 0 0 0 3 0 3-1 0-2 0-3 0-1 0-2 0-2 1 0 7 0 15 0 22z m-7-15c0-1 0-2 0-4 0-1 0-1 0-2 0 0 0-1 0-2 0 0-1 0-1 0-1 0-2 0-3 0-1 0-3 0-4 0 1 2 3 4 4 6 1 1 1 2 2 3 1 2 2 4 2 7 0-3 0-5 0-8z m41-2c-3 2-8 2-11 2-1 0-2 0-2 0 0 0 0 1 0 1 0 2 0 3 0 4 0 0 13 0 14 0 1 0 1 0 1 1 0 1 0 2 0 4 0 1 0 2 0 3 0 0-1 0-1 0-6 0-11 0-17 0-1 0-1 0-2 0 0 0 0-1 0-1-1-2-1-4-1-6-1-5-1-9-2-14 4 0 9 1 12-1 3-1 4-4 4-7-1-4-5-4-7-4-2 0-9-1-9 2-1-2-1-5-2-8 1 0 3-1 5-1 2-1 5-1 7-1 4 0 8 2 11 5 2 3 2 7 2 11 0 2 0 5 0 7 0 1-1 2-2 3 0 0 0 0 0 0-3 2 2 0 0 0z" horiz-adv-x="1000" /> |
|
90 | 92 | |
|
91 | 93 | <glyph glyph-name="up" unicode="" d="M687 254l-173 217c-8 9-22 9-29 0l-173-217c-9-12-1-29 15-29h345c16 0 24 17 15 29z" horiz-adv-x="1000" /> |
|
92 | 94 | |
|
93 | 95 | <glyph glyph-name="merge" unicode="" d="M200 110c0-72 58-131 130-131s130 59 130 131c0 45-24 86-60 109 18 139 133 179 202 190v-301c-38-23-65-64-65-112 0-72 59-130 130-130s130 58 130 130c0 48-26 89-65 112v487c39 23 65 64 65 112 0 72-58 130-130 130s-130-58-130-130c0-48 27-89 65-112v-55c-60-8-162-32-238-108-54-54-86-124-94-208-42-22-70-65-70-114z m468-158c-24 0-44 20-44 43s20 44 44 44c24 0 43-20 43-44s-19-43-43-43z m0 798c24 0 43-19 43-43s-20-43-43-43c-24 0-44 19-44 43s20 43 44 43z m-338-684c-24 0-43 20-43 43s19 44 43 44c24 0 43-20 43-44s-19-43-43-43z" horiz-adv-x="1000" /> |
|
94 | 96 | |
|
95 | 97 | <glyph glyph-name="spin-alt" unicode="" d="M498 850c-114 0-228-39-320-116l0 0c173 140 428 130 588-31 134-134 164-332 89-495-10-29-5-50 12-68 21-20 61-23 84 0 3 3 12 15 15 24 71 180 33 393-112 539-99 98-228 147-356 147z m-409-274c-14 0-29-5-39-16-3-3-13-15-15-24-71-180-34-393 112-539 185-185 479-195 676-31l0 0c-173-140-428-130-589 31-134 134-163 333-89 495 11 29 6 50-12 68-11 11-27 17-44 16z" horiz-adv-x="1001" /> |
|
96 | 98 | |
|
97 | 99 | <glyph glyph-name="spin" unicode="" d="M462 850c-6 0-11-5-11-11l0-183 0 0c0-6 5-11 11-11l69 0c1 0 1 0 1 0 7 0 12 5 12 11l0 183 0 0c0 6-5 11-12 11l-69 0c0 0 0 0-1 0z m250-47c-4 1-8-2-10-5l-91-158 0 0c-4-6-2-13 4-16l60-34c0-1 0-1 0-1 6-3 13-1 16 4l91 158c3 6 2 13-4 16l-61 35c-1 1-3 1-5 1z m-428-2c-2 0-4-1-6-2l-61-35c-5-3-7-10-4-16l91-157c0 0 0 0 0 0 3-6 10-8 16-5l61 35c5 4 7 11 4 16l-91 157c0 1 0 1 0 1-2 4-6 6-10 6z m620-163c-2 0-4 0-6-1l-157-91c0 0 0 0 0 0-6-3-8-10-5-16l35-61c4-5 11-7 16-4l157 91c1 0 1 0 1 0 6 3 7 11 4 16l-35 61c-2 4-6 6-10 5z m-810-4c-5 0-9-2-11-6l-35-61c-3-5-1-12 4-15l158-91 0 0c6-4 13-2 16 4l35 60c0 0 0 0 0 0 3 6 1 13-4 16l-158 91c-2 1-4 2-5 2z m712-235l0 0c-6 0-11-5-11-11l0-69c0-1 0-1 0-1 0-7 5-12 11-12l183 0 0 0c6 0 11 5 11 12l0 69c0 0 0 0 0 1 0 6-5 11-11 11l-183 0z m-794-5l0 0c-7 0-12-5-12-12l0-69c0 0 0 0 0-1 0-6 5-11 12-11l182 0 0 0c6 0 11 5 11 11l0 69c0 1 0 1 0 1 0 7-5 12-11 12l-182 0z m772-153c-4 0-8-2-10-6l-34-60c-1 0-1 0-1 0-3-6-1-13 4-16l158-91c6-3 13-1 16 4l35 61c3 5 1 12-4 15l-158 92 0 0c-2 1-4 1-6 1z m-566-5c-1 0-3 0-5-1l-157-91c0 0-1 0-1 0-5-3-7-10-4-16l35-61c3-5 10-7 16-4l157 91c0 0 0 0 0 0 6 3 8 10 5 16l-35 61c-3 3-7 6-11 5z m468-121c-2 0-4 0-6-1l-61-35c-5-4-7-11-4-16l91-157c0-1 0-1 0-1 3-6 11-7 16-4l61 35c5 3 7 10 4 16l-91 157c0 0 0 0 0 0-2 4-6 6-10 6z m-367-2c-4 0-8-2-10-6l-91-158c-3-6-1-13 4-16l61-35c5-3 12-1 15 4l92 158 0 0c3 6 1 13-5 16l-60 35c0 0 0 0 0 0-2 1-4 1-6 2z m149-58c-7 0-12-5-12-11l0-183 0 0c0-6 5-11 12-11l69 0c0 0 0 0 1 0 6 0 11 5 11 11l0 183 0 0c0 6-5 11-11 11l-69 0c-1 0-1 0-1 0z" horiz-adv-x="1000" /> |
|
98 | 100 | |
|
99 | 101 | <glyph glyph-name="docs" unicode="" d="M946 636q23 0 38-16t16-38v-678q0-23-16-38t-38-16h-535q-23 0-38 16t-16 38v160h-303q-23 0-38 16t-16 38v375q0 22 11 49t27 42l228 228q15 16 42 27t49 11h232q23 0 38-16t16-38v-183q38 23 71 23h232z m-303-119l-167-167h167v167z m-357 214l-167-167h167v167z m109-361l176 176v233h-214v-233q0-22-15-37t-38-16h-233v-357h286v143q0 22 11 49t27 42z m534-449v643h-215v-232q0-22-15-38t-38-15h-232v-358h500z" horiz-adv-x="1000" /> |
|
100 | 102 | |
|
101 | 103 | <glyph glyph-name="menu" unicode="" d="M857 100v-71q0-15-10-25t-26-11h-785q-15 0-25 11t-11 25v71q0 15 11 25t25 11h785q15 0 26-11t10-25z m0 286v-72q0-14-10-25t-26-10h-785q-15 0-25 10t-11 25v72q0 14 11 25t25 10h785q15 0 26-10t10-25z m0 285v-71q0-14-10-25t-26-11h-785q-15 0-25 11t-11 25v71q0 15 11 26t25 10h785q15 0 26-10t10-26z" horiz-adv-x="857.1" /> |
|
102 | 104 | |
|
103 | 105 | <glyph glyph-name="paste" unicode="" d="M429-79h500v358h-233q-22 0-37 15t-16 38v232h-214v-643z m142 804v36q0 7-5 12t-12 6h-393q-7 0-13-6t-5-12v-36q0-7 5-13t13-5h393q7 0 12 5t5 13z m143-375h167l-167 167v-167z m286-71v-375q0-23-16-38t-38-16h-535q-23 0-38 16t-16 38v89h-303q-23 0-38 16t-16 37v750q0 23 16 38t38 16h607q22 0 38-16t15-38v-183q12-7 20-15l228-228q16-15 27-42t11-49z" horiz-adv-x="1000" /> |
|
104 | 106 | |
|
105 | 107 | <glyph glyph-name="doc-text" unicode="" d="M819 638q16-16 27-42t11-50v-642q0-23-15-38t-38-16h-750q-23 0-38 16t-16 38v892q0 23 16 38t38 16h500q22 0 49-11t42-27z m-248 136v-210h210q-5 17-12 23l-175 175q-6 7-23 12z m215-853v572h-232q-23 0-38 16t-16 37v233h-429v-858h715z m-572 483q0 7 5 12t13 5h393q8 0 13-5t5-12v-36q0-8-5-13t-13-5h-393q-8 0-13 5t-5 13v36z m411-125q8 0 13-5t5-13v-36q0-8-5-13t-13-5h-393q-8 0-13 5t-5 13v36q0 8 5 13t13 5h393z m0-143q8 0 13-5t5-13v-36q0-8-5-13t-13-5h-393q-8 0-13 5t-5 13v36q0 8 5 13t13 5h393z" horiz-adv-x="857.1" /> |
|
106 | 108 | |
|
107 | 109 | <glyph glyph-name="plus-squared" unicode="" d="M714 314v72q0 14-10 25t-25 10h-179v179q0 15-11 25t-25 11h-71q-15 0-25-11t-11-25v-179h-178q-15 0-25-10t-11-25v-72q0-14 11-25t25-10h178v-179q0-14 11-25t25-11h71q15 0 25 11t11 25v179h179q14 0 25 10t10 25z m143 304v-536q0-66-47-113t-114-48h-535q-67 0-114 48t-47 113v536q0 66 47 113t114 48h535q67 0 114-48t47-113z" horiz-adv-x="857.1" /> |
|
108 | 110 | |
|
109 | 111 | <glyph glyph-name="folder-empty" unicode="" d="M857 118v393q0 22-15 38t-38 15h-393q-23 0-38 16t-16 38v36q0 22-15 38t-38 15h-179q-22 0-38-15t-16-38v-536q0-22 16-38t38-16h679q22 0 38 16t15 38z m72 393v-393q0-51-37-88t-88-37h-679q-51 0-88 37t-37 88v536q0 51 37 88t88 37h179q51 0 88-37t37-88v-18h375q51 0 88-37t37-88z" horiz-adv-x="928.6" /> |
|
110 | 112 | |
|
111 | 113 | <glyph glyph-name="folder-open-empty" unicode="" d="M994 331q0 19-30 19h-607q-22 0-48-12t-39-29l-164-203q-11-13-11-22 0-20 30-20h607q23 0 48 13t40 29l164 203q10 12 10 22z m-637 90h429v90q0 22-16 38t-38 15h-321q-23 0-38 16t-16 38v36q0 22-15 38t-38 15h-179q-22 0-38-15t-16-38v-476l143 175q25 30 65 49t78 19z m708-90q0-35-25-67l-165-203q-24-30-65-49t-78-19h-607q-51 0-88 37t-37 88v536q0 51 37 88t88 37h179q51 0 88-37t37-88v-18h303q52 0 88-37t37-88v-90h107q30 0 56-13t37-40q8-17 8-37z" horiz-adv-x="1071.4" /> |
|
112 | 114 | |
|
113 | 115 | <glyph glyph-name="minus-squared" unicode="" d="M714 314v72q0 14-10 25t-25 10h-500q-15 0-25-10t-11-25v-72q0-14 11-25t25-10h500q14 0 25 10t10 25z m143 304v-536q0-66-47-113t-114-48h-535q-67 0-114 48t-47 113v536q0 66 47 113t114 48h535q67 0 114-48t47-113z" horiz-adv-x="857.1" /> |
|
114 | 116 | |
|
115 | 117 | <glyph glyph-name="minus-squared-alt" unicode="" d="M643 404v-36q0-8-5-13t-13-5h-464q-8 0-13 5t-5 13v36q0 7 5 12t13 5h464q8 0 13-5t5-12z m71-250v464q0 37-26 63t-63 26h-464q-37 0-63-26t-27-63v-464q0-37 27-63t63-27h464q37 0 63 27t26 63z m72 464v-464q0-67-47-114t-114-47h-464q-67 0-114 47t-47 114v464q0 66 47 113t114 48h464q66 0 114-48t47-113z" horiz-adv-x="785.7" /> |
|
116 | 118 | |
|
117 | 119 | <glyph glyph-name="doc-inv" unicode="" d="M571 564v264q13-8 21-16l227-228q8-7 16-20h-264z m-71-18q0-22 16-37t38-16h303v-589q0-23-15-38t-38-16h-750q-23 0-38 16t-16 38v892q0 23 16 38t38 16h446v-304z" horiz-adv-x="857.1" /> |
|
118 | 120 | |
|
119 | 121 | <glyph glyph-name="doc-text-inv" unicode="" d="M819 584q8-7 16-20h-264v264q13-8 21-16z m-265-91h303v-589q0-23-15-38t-38-16h-750q-23 0-38 16t-16 38v892q0 23 16 38t38 16h446v-304q0-22 16-37t38-16z m89-411v36q0 8-5 13t-13 5h-393q-8 0-13-5t-5-13v-36q0-8 5-13t13-5h393q8 0 13 5t5 13z m0 143v36q0 8-5 13t-13 5h-393q-8 0-13-5t-5-13v-36q0-8 5-13t13-5h393q8 0 13 5t5 13z m0 143v36q0 7-5 12t-13 5h-393q-8 0-13-5t-5-12v-36q0-8 5-13t13-5h393q8 0 13 5t5 13z" horiz-adv-x="857.1" /> |
|
120 | 122 | |
|
121 | 123 | <glyph glyph-name="plus-squared-alt" unicode="" d="M643 404v-36q0-8-5-13t-13-5h-196v-196q0-8-5-13t-13-5h-36q-8 0-13 5t-5 13v196h-196q-8 0-13 5t-5 13v36q0 7 5 12t13 5h196v197q0 8 5 13t13 5h36q8 0 13-5t5-13v-197h196q8 0 13-5t5-12z m71-250v464q0 37-26 63t-63 26h-464q-37 0-63-26t-27-63v-464q0-37 27-63t63-27h464q37 0 63 27t26 63z m72 464v-464q0-67-47-114t-114-47h-464q-67 0-114 47t-47 114v464q0 66 47 113t114 48h464q66 0 114-48t47-113z" horiz-adv-x="785.7" /> |
|
122 | 124 | |
|
123 | 125 | <glyph glyph-name="file-code" unicode="" d="M819 638q16-16 27-42t11-50v-642q0-23-15-38t-38-16h-750q-23 0-38 16t-16 38v892q0 23 16 38t38 16h500q22 0 49-11t42-27z m-248 136v-210h210q-5 17-12 23l-175 175q-6 7-23 12z m215-853v572h-232q-23 0-38 16t-16 37v233h-429v-858h715z m-518 500q4 7 12 7t13-3l28-21q7-5 7-12t-3-13l-102-136 102-136q4-6 3-13t-7-12l-28-21q-6-4-13-4t-12 7l-126 168q-8 11 0 22z m447-167q8-11 0-22l-126-168q-4-6-11-7t-14 4l-28 21q-6 5-7 12t3 13l102 136-102 136q-4 6-3 13t7 12l28 21q6 4 14 3t11-7z m-346-258q-7 1-11 8t-3 13l77 464q1 7 7 11t14 3l35-5q7-2 11-8t3-13l-77-464q-1-7-7-11t-13-3z" horiz-adv-x="857.1" /> |
|
124 | 126 | |
|
125 | 127 | <glyph glyph-name="sliders" unicode="" d="M196 64v-71h-196v71h196z m197 72q14 0 25-11t11-25v-143q0-14-11-25t-25-11h-143q-14 0-25 11t-11 25v143q0 15 11 25t25 11h143z m89 214v-71h-482v71h482z m-357 286v-72h-125v72h125z m732-572v-71h-411v71h411z m-536 643q15 0 26-10t10-26v-142q0-15-10-25t-26-11h-142q-15 0-25 11t-11 25v142q0 15 11 26t25 10h142z m358-286q14 0 25-10t10-25v-143q0-15-10-25t-25-11h-143q-15 0-25 11t-11 25v143q0 14 11 25t25 10h143z m178-71v-71h-125v71h125z m0 286v-72h-482v72h482z" horiz-adv-x="857.1" /> |
|
126 | 128 | |
|
127 | 129 | <glyph glyph-name="trash" unicode="" d="M286 82v393q0 8-5 13t-13 5h-36q-8 0-13-5t-5-13v-393q0-8 5-13t13-5h36q8 0 13 5t5 13z m143 0v393q0 8-5 13t-13 5h-36q-8 0-13-5t-5-13v-393q0-8 5-13t13-5h36q8 0 13 5t5 13z m142 0v393q0 8-5 13t-12 5h-36q-8 0-13-5t-5-13v-393q0-8 5-13t13-5h36q7 0 12 5t5 13z m-303 554h250l-27 65q-4 5-9 6h-177q-6-1-10-6z m518-18v-36q0-8-5-13t-13-5h-54v-529q0-46-26-80t-63-34h-464q-37 0-63 33t-27 79v531h-53q-8 0-13 5t-5 13v36q0 8 5 13t13 5h172l39 93q9 21 31 35t44 15h178q23 0 44-15t30-35l39-93h173q8 0 13-5t5-13z" horiz-adv-x="785.7" /> |
|
128 | 130 | </font> |
|
129 | 131 | </defs> |
|
130 | 132 | </svg> No newline at end of file |
|
1 | NO CONTENT: modified file, binary diff hidden |
|
1 | NO CONTENT: modified file, binary diff hidden |
|
1 | NO CONTENT: modified file, binary diff hidden |
@@ -1,82 +1,75 b'' | |||
|
1 | 1 | /* COMMON */ |
|
2 | 2 | var select2RefFilterResults = function(queryTerm, data) { |
|
3 | 3 | var filteredData = {results: []}; |
|
4 | 4 | //filter results |
|
5 | 5 | $.each(data.results, function() { |
|
6 | 6 | var section = this.text; |
|
7 | 7 | var children = []; |
|
8 | 8 | $.each(this.children, function() { |
|
9 | 9 | if (queryTerm.length === 0 || this.text.toUpperCase().indexOf(queryTerm.toUpperCase()) >= 0) { |
|
10 | 10 | children.push(this); |
|
11 | 11 | } |
|
12 | 12 | }); |
|
13 | 13 | |
|
14 | 14 | if (children.length > 0) { |
|
15 | 15 | filteredData.results.push({ |
|
16 | 16 | 'text': section, |
|
17 | 17 | 'children': children |
|
18 | 18 | }); |
|
19 | 19 | } |
|
20 | 20 | }); |
|
21 | 21 | |
|
22 | 22 | return filteredData |
|
23 | 23 | }; |
|
24 | 24 | |
|
25 | 25 | |
|
26 | 26 | var select2RefBaseSwitcher = function(targetElement, loadUrl, initialData){ |
|
27 | 27 | var formatResult = function(result, container, query) { |
|
28 | 28 | return formatSelect2SelectionRefs(result); |
|
29 | 29 | }; |
|
30 | 30 | |
|
31 | 31 | var formatSelection = function(data, container) { |
|
32 | 32 | return formatSelect2SelectionRefs(data); |
|
33 | 33 | }; |
|
34 | 34 | |
|
35 | 35 | $(targetElement).select2({ |
|
36 | 36 | cachedDataSource: {}, |
|
37 | 37 | dropdownAutoWidth: true, |
|
38 | 38 | width: "resolve", |
|
39 | 39 | containerCssClass: "drop-menu", |
|
40 | 40 | dropdownCssClass: "drop-menu-dropdown", |
|
41 | 41 | query: function(query) { |
|
42 | 42 | var self = this; |
|
43 | 43 | var cacheKey = '__ALLREFS__'; |
|
44 | 44 | var cachedData = self.cachedDataSource[cacheKey]; |
|
45 | 45 | if (cachedData) { |
|
46 | 46 | var data = select2RefFilterResults(query.term, cachedData); |
|
47 | 47 | query.callback({results: data.results}); |
|
48 | 48 | } else { |
|
49 | 49 | $.ajax({ |
|
50 | 50 | url: loadUrl, |
|
51 | 51 | data: {}, |
|
52 | 52 | dataType: 'json', |
|
53 | 53 | type: 'GET', |
|
54 | 54 | success: function(data) { |
|
55 | 55 | self.cachedDataSource[cacheKey] = data; |
|
56 | 56 | query.callback({results: data.results}); |
|
57 | 57 | } |
|
58 | 58 | }); |
|
59 | 59 | } |
|
60 | 60 | }, |
|
61 | 61 | initSelection: function(element, callback) { |
|
62 | 62 | callback(initialData); |
|
63 | 63 | }, |
|
64 | 64 | formatResult: formatResult, |
|
65 | 65 | formatSelection: formatSelection |
|
66 | 66 | }); |
|
67 | 67 | |
|
68 | 68 | }; |
|
69 | 69 | |
|
70 | 70 | /* WIDGETS */ |
|
71 | 71 | var select2RefSwitcher = function(targetElement, initialData) { |
|
72 | 72 | var loadUrl = pyroutes.url('repo_refs_data', |
|
73 | 73 | {'repo_name': templateContext.repo_name}); |
|
74 | 74 | select2RefBaseSwitcher(targetElement, loadUrl, initialData); |
|
75 | 75 | }; |
|
76 | ||
|
77 | var select2FileHistorySwitcher = function(targetElement, initialData, state) { | |
|
78 | var loadUrl = pyroutes.url('repo_file_history', | |
|
79 | {'repo_name': templateContext.repo_name, 'commit_id': state.rev, | |
|
80 | 'f_path': state.f_path}); | |
|
81 | select2RefBaseSwitcher(targetElement, loadUrl, initialData); | |
|
82 | }; |
@@ -1,39 +1,51 b'' | |||
|
1 | 1 | <%namespace name="base" file="/base/base.mako"/> |
|
2 | 2 | <div class="table"> |
|
3 | 3 | |
|
4 | 4 | <table class="table rctable file_history"> |
|
5 | 5 | %for cnt,cs in enumerate(c.pagination): |
|
6 | <tr id="chg_${cnt+1}" class="${'tablerow%s' % (cnt%2)}"> | |
|
6 | <tr id="chg_${cnt+1}" class="${('tablerow%s' % (cnt%2))}"> | |
|
7 | 7 | <td class="td-user"> |
|
8 | 8 | ${base.gravatar_with_user(cs.author, 16)} |
|
9 | 9 | </td> |
|
10 | 10 | <td class="td-time"> |
|
11 | 11 | <div class="date"> |
|
12 | 12 | ${h.age_component(cs.date)} |
|
13 | 13 | </div> |
|
14 | 14 | </td> |
|
15 | 15 | <td class="td-message"> |
|
16 | 16 | <div class="log-container"> |
|
17 | 17 | <div class="message_history" title="${h.tooltip(cs.message)}"> |
|
18 | 18 | <a href="${h.route_path('repo_commit',repo_name=c.repo_name,commit_id=cs.raw_id)}"> |
|
19 | 19 | ${h.shorter(cs.message, 75)} |
|
20 | 20 | </a> |
|
21 | 21 | </div> |
|
22 | 22 | </div> |
|
23 | 23 | </td> |
|
24 | 24 | <td class="td-hash"> |
|
25 | 25 | <code> |
|
26 | 26 | <a href="${h.route_path('repo_commit',repo_name=c.repo_name,commit_id=cs.raw_id)}"> |
|
27 | 27 | <span>${h.show_id(cs)}</span> |
|
28 | 28 | </a> |
|
29 | 29 | </code> |
|
30 | 30 | </td> |
|
31 | 31 | <td class="td-actions"> |
|
32 | 32 | <a href="${h.route_path('repo_files',repo_name=c.repo_name,commit_id=cs.raw_id,f_path=c.changelog_for_path)}"> |
|
33 | 33 | ${_('Show File')} |
|
34 | 34 | </a> |
|
35 | 35 | </td> |
|
36 | <td class="td-actions"> | |
|
37 | <a href="${h.route_path('repo_compare',repo_name=c.repo_name, source_ref_type="rev", source_ref=cs.raw_id,target_ref_type="rev", target_ref=c.commit_id,_query=dict(merge='1',f_path=c.changelog_for_path))}"> | |
|
38 | ${_('Diff File')} | |
|
39 | </a> | |
|
40 | </td> | |
|
36 | 41 | </tr> |
|
37 | 42 | %endfor |
|
43 | <tr> | |
|
44 | <td colspan="6"> | |
|
45 | <a id="file_history_overview_full" href="${h.route_path('repo_changelog_file',repo_name=c.repo_name, commit_id=c.commit_id, f_path=c.f_path)}"> | |
|
46 | ${_('Show Full History')} | |
|
47 | </a> | |
|
48 | </td> | |
|
49 | </tr> | |
|
38 | 50 | </table> |
|
39 | 51 | </div> |
@@ -1,40 +1,35 b'' | |||
|
1 | 1 | <%namespace name="base" file="/base/base.mako"/> |
|
2 | 2 | |
|
3 | 3 | % if c.authors: |
|
4 | 4 | |
|
5 | 5 | <table class="sidebar-right-content"> |
|
6 | 6 | % for email, user, commits in sorted(c.authors, key=lambda e: c.file_last_commit.author_email!=e[0]): |
|
7 | 7 | <tr class="file_author tooltip" title="${h.tooltip(h.author_string(email))}"> |
|
8 | 8 | |
|
9 | 9 | <td> |
|
10 | 10 | <span class="user commit-author">${h.link_to_user(user)}</span> |
|
11 | 11 | % if c.file_author: |
|
12 | 12 | <span class="commit-date">- ${h.age_component(c.file_last_commit.date)}</span> |
|
13 | <a href="#ShowAuthors" id="show_authors" class="action_link"> - ${_('Load All Authors')}</a> | |
|
13 | 14 | % elif c.file_last_commit.author_email==email: |
|
14 | 15 | <span> (${_('last author')})</span> |
|
15 | 16 | % endif |
|
16 | 17 | </td> |
|
17 | 18 | |
|
18 | 19 | <td> |
|
19 | 20 | % if not c.file_author: |
|
20 | 21 | <code> |
|
21 | 22 | % if commits == 1: |
|
22 | 23 | ${commits} ${_('Commit')} |
|
23 | 24 | % else: |
|
24 | 25 | ${commits} ${_('Commits')} |
|
25 | 26 | % endif |
|
26 | 27 | </code> |
|
27 | 28 | % endif |
|
28 | 29 | </td> |
|
29 | 30 | </tr> |
|
30 | <tr> | |
|
31 | <td colspan="2"> | |
|
32 | % if c.file_author: | |
|
33 | <a href="#ShowAuthors" id="show_authors" class="action_link">${_('Show Authors')}</a> | |
|
34 | % endif | |
|
35 | </td> | |
|
36 | </tr> | |
|
31 | ||
|
37 | 32 |
|
|
38 | 33 | </table> |
|
39 | 34 | % endif |
|
40 | 35 |
@@ -1,393 +1,463 b'' | |||
|
1 | 1 | <%inherit file="/base/base.mako"/> |
|
2 | 2 | |
|
3 | 3 | <%def name="title(*args)"> |
|
4 | 4 | ${_('{} Files').format(c.repo_name)} |
|
5 | 5 | %if hasattr(c,'file'): |
|
6 | 6 | · ${(h.safe_unicode(c.file.path) or '\\')} |
|
7 | 7 | %endif |
|
8 | 8 | |
|
9 | 9 | %if c.rhodecode_name: |
|
10 | 10 | · ${h.branding(c.rhodecode_name)} |
|
11 | 11 | %endif |
|
12 | 12 | </%def> |
|
13 | 13 | |
|
14 | 14 | <%def name="breadcrumbs_links()"> |
|
15 | 15 | ${_('Files')} |
|
16 | 16 | %if c.file: |
|
17 | 17 | @ ${h.show_id(c.commit)} |
|
18 | 18 | %endif |
|
19 | 19 | </%def> |
|
20 | 20 | |
|
21 | 21 | <%def name="menu_bar_nav()"> |
|
22 | 22 | ${self.menu_items(active='repositories')} |
|
23 | 23 | </%def> |
|
24 | 24 | |
|
25 | 25 | <%def name="menu_bar_subnav()"> |
|
26 | 26 | ${self.repo_menu(active='files')} |
|
27 | 27 | </%def> |
|
28 | 28 | |
|
29 | 29 | <%def name="main()"> |
|
30 | 30 | <div> |
|
31 | 31 | <div id="files_data"> |
|
32 | 32 | <%include file='files_pjax.mako'/> |
|
33 | 33 | </div> |
|
34 | 34 | </div> |
|
35 | 35 | <script> |
|
36 | 36 | |
|
37 | 37 | var metadataRequest = null; |
|
38 | 38 | var fileSourcePage = ${c.file_source_page}; |
|
39 | 39 | var atRef = '${request.GET.get('at', '')}'; |
|
40 | 40 | |
|
41 | 41 | var getState = function(context) { |
|
42 | 42 | var url = $(location).attr('href'); |
|
43 | 43 | var _base_url = '${h.route_path("repo_files",repo_name=c.repo_name,commit_id='',f_path='')}'; |
|
44 | 44 | var _annotate_url = '${h.route_path("repo_files:annotated",repo_name=c.repo_name,commit_id='',f_path='')}'; |
|
45 | 45 | _base_url = _base_url.replace('//', '/'); |
|
46 | 46 | _annotate_url = _annotate_url.replace('//', '/'); |
|
47 | 47 | |
|
48 | 48 | //extract f_path from url. |
|
49 | 49 | var parts = url.split(_base_url); |
|
50 | 50 | if (parts.length != 2) { |
|
51 | 51 | parts = url.split(_annotate_url); |
|
52 | 52 | if (parts.length != 2) { |
|
53 | 53 | var rev = "tip"; |
|
54 | 54 | var f_path = ""; |
|
55 | 55 | } else { |
|
56 | 56 | var parts2 = parts[1].split('/'); |
|
57 | 57 | var rev = parts2.shift(); // pop the first element which is the revision |
|
58 | 58 | var f_path = parts2.join('/'); |
|
59 | 59 | } |
|
60 | 60 | |
|
61 | 61 | } else { |
|
62 | 62 | var parts2 = parts[1].split('/'); |
|
63 | 63 | var rev = parts2.shift(); // pop the first element which is the revision |
|
64 | 64 | var f_path = parts2.join('/'); |
|
65 | 65 | } |
|
66 | 66 | |
|
67 | 67 | var url_params = { |
|
68 | 68 | repo_name: templateContext.repo_name, |
|
69 | 69 | commit_id: rev, |
|
70 | 70 | f_path:'__FPATH__' |
|
71 | 71 | }; |
|
72 | 72 | if (atRef !== '') { |
|
73 | 73 | url_params['at'] = atRef |
|
74 | 74 | } |
|
75 | 75 | |
|
76 | 76 | var _url_base = pyroutes.url('repo_files', url_params); |
|
77 | 77 | var _node_list_url = pyroutes.url('repo_files_nodelist', |
|
78 | 78 | {repo_name: templateContext.repo_name, |
|
79 | 79 | commit_id: rev, f_path: f_path}); |
|
80 | 80 | |
|
81 | 81 | return { |
|
82 | 82 | url: url, |
|
83 | 83 | f_path: f_path, |
|
84 | 84 | rev: rev, |
|
85 | 85 | commit_id: "${c.commit.raw_id}", |
|
86 | 86 | node_list_url: _node_list_url, |
|
87 | 87 | url_base: _url_base |
|
88 | 88 | }; |
|
89 | 89 | }; |
|
90 | 90 | |
|
91 | 91 | var getFilesMetadata = function() { |
|
92 | 92 | if (metadataRequest && metadataRequest.readyState != 4) { |
|
93 | 93 | metadataRequest.abort(); |
|
94 | 94 | } |
|
95 | 95 | if (fileSourcePage) { |
|
96 | 96 | return false; |
|
97 | 97 | } |
|
98 | 98 | |
|
99 | 99 | if ($('#file-tree-wrapper').hasClass('full-load')) { |
|
100 | 100 | // in case our HTML wrapper has full-load class we don't |
|
101 | 101 | // trigger the async load of metadata |
|
102 | 102 | return false; |
|
103 | 103 | } |
|
104 | 104 | |
|
105 | 105 | var state = getState('metadata'); |
|
106 | 106 | var url_data = { |
|
107 | 107 | 'repo_name': templateContext.repo_name, |
|
108 | 108 | 'commit_id': state.commit_id, |
|
109 | 109 | 'f_path': state.f_path |
|
110 | 110 | }; |
|
111 | 111 | |
|
112 | 112 | var url = pyroutes.url('repo_nodetree_full', url_data); |
|
113 | 113 | |
|
114 | 114 | metadataRequest = $.ajax({url: url}); |
|
115 | 115 | |
|
116 | 116 | metadataRequest.done(function(data) { |
|
117 | 117 | $('#file-tree').html(data); |
|
118 | 118 | timeagoActivate(); |
|
119 | 119 | }); |
|
120 | 120 | metadataRequest.fail(function (data, textStatus, errorThrown) { |
|
121 | console.log(data); | |
|
122 | 121 | if (data.status != 0) { |
|
123 | 122 | alert("Error while fetching metadata.\nError code {0} ({1}).Please consider reloading the page".format(data.status,data.statusText)); |
|
124 | 123 | } |
|
125 | 124 | }); |
|
126 | 125 | }; |
|
127 | 126 | |
|
128 |
var |
|
|
129 | timeagoActivate(); | |
|
130 | ||
|
131 | if ($('#trimmed_message_box').height() < 50) { | |
|
132 | $('#message_expand').hide(); | |
|
133 | } | |
|
134 | ||
|
135 | $('#message_expand').on('click', function(e) { | |
|
136 | $('#trimmed_message_box').css('max-height', 'none'); | |
|
137 | $(this).hide(); | |
|
138 | }); | |
|
139 | ||
|
127 | var initFileJS = function () { | |
|
140 | 128 | var state = getState('callbacks'); |
|
141 | 129 | |
|
142 | // VIEW FOR FILE SOURCE | |
|
143 | if (fileSourcePage) { | |
|
144 | // variants for with source code, not tree view | |
|
145 | ||
|
146 | 130 |
|
|
147 | 131 |
|
|
148 | 132 | |
|
149 |
|
|
|
133 | // file history select2 used for history of file, and switch to | |
|
150 | 134 |
|
|
135 | at_ref: atRef, | |
|
151 | 136 |
|
|
152 |
|
|
|
137 | text: '${c.commit.raw_id}', | |
|
153 | 138 |
|
|
154 |
|
|
|
155 | files_url: null | |
|
139 | raw_id: '${c.commit.raw_id}', | |
|
140 | idx: ${c.commit.idx}, | |
|
141 | files_url: null, | |
|
156 | 142 |
|
|
157 | 143 | |
|
158 | select2FileHistorySwitcher('#diff1', initialCommitData, state); | |
|
144 | // check if we have ref info. | |
|
145 | var selectedRef = fileTreeRefs[atRef]; | |
|
146 | if (selectedRef !== undefined) { | |
|
147 | $.extend(initialCommitData, selectedRef) | |
|
148 | } | |
|
149 | ||
|
150 | var loadUrl = pyroutes.url('repo_file_history', {'repo_name': templateContext.repo_name, 'commit_id': state.rev,'f_path': state.f_path}); | |
|
151 | var cacheKey = '__SINGLE_FILE_REFS__'; | |
|
152 | var cachedDataSource = {}; | |
|
159 | 153 | |
|
160 | // show at, diff to actions handlers | |
|
161 | $('#diff1').on('change', function(e) { | |
|
162 | $('#diff_to_commit').removeClass('disabled').removeAttr("disabled"); | |
|
163 | $('#diff_to_commit').val(_gettext('Diff to Commit ') + e.val.truncateAfter(8, '...')); | |
|
154 | var loadRefsData = function (query) { | |
|
155 | $.ajax({ | |
|
156 | url: loadUrl, | |
|
157 | data: {}, | |
|
158 | dataType: 'json', | |
|
159 | type: 'GET', | |
|
160 | success: function (data) { | |
|
161 | cachedDataSource[cacheKey] = data; | |
|
162 | query.callback({results: data.results}); | |
|
163 | } | |
|
164 | }); | |
|
165 | }; | |
|
164 | 166 | |
|
165 | $('#show_at_commit').removeClass('disabled').removeAttr("disabled"); | |
|
166 | $('#show_at_commit').val(_gettext('Show at Commit ') + e.val.truncateAfter(8, '...')); | |
|
167 | var feedRefsData = function (query, cachedData) { | |
|
168 | var data = {results: []}; | |
|
169 | //filter results | |
|
170 | $.each(cachedData.results, function () { | |
|
171 | var section = this.text; | |
|
172 | var children = []; | |
|
173 | $.each(this.children, function () { | |
|
174 | if (query.term.length === 0 || this.text.toUpperCase().indexOf(query.term.toUpperCase()) >= 0) { | |
|
175 | children.push(this) | |
|
176 | } | |
|
177 | }); | |
|
178 | data.results.push({ | |
|
179 | 'text': section, | |
|
180 | 'children': children | |
|
181 | }) | |
|
167 | 182 | }); |
|
168 | 183 | |
|
169 | $('#diff_to_commit').on('click', function(e) { | |
|
170 | var diff1 = $('#diff1').val(); | |
|
171 | var diff2 = $('#diff2').val(); | |
|
184 | query.callback(data); | |
|
185 | }; | |
|
186 | ||
|
187 | var select2FileHistorySwitcher = function (targetElement, loadUrl, initialData) { | |
|
188 | var formatResult = function (result, container, query) { | |
|
189 | return formatSelect2SelectionRefs(result); | |
|
190 | }; | |
|
191 | ||
|
192 | var formatSelection = function (data, container) { | |
|
193 | var commit_ref = data; | |
|
172 | 194 | |
|
173 |
var |
|
|
174 | repo_name: templateContext.repo_name, | |
|
175 | source_ref: diff1, | |
|
176 |
|
|
|
177 | target_ref: diff2, | |
|
178 | target_ref_type: 'rev', | |
|
179 | merge: 1, | |
|
180 | f_path: state.f_path | |
|
195 | var tmpl = ''; | |
|
196 | if (commit_ref.type === 'sha') { | |
|
197 | tmpl = (commit_ref.raw_id || "").substr(0,8); | |
|
198 | } else if (commit_ref.type === 'branch') { | |
|
199 | tmpl = tmpl.concat('<i class="icon-branch"></i> '); | |
|
200 | tmpl = tmpl.concat(escapeHtml(commit_ref.text)); | |
|
201 | } else if (commit_ref.type === 'tag') { | |
|
202 | tmpl = tmpl.concat('<i class="icon-tag"></i> '); | |
|
203 | tmpl = tmpl.concat(escapeHtml(commit_ref.text)); | |
|
204 | } else if (commit_ref.type === 'book') { | |
|
205 | tmpl = tmpl.concat('<i class="icon-bookmark"></i> '); | |
|
206 | tmpl = tmpl.concat(escapeHtml(commit_ref.text)); | |
|
207 | } | |
|
208 | var idx = commit_ref.idx || 0; | |
|
209 | tmpl = tmpl.concat('<span class="select-index-number">r{0}</span>'.format(idx)); | |
|
210 | return tmpl | |
|
181 | 211 |
|
|
182 | window.location = pyroutes.url('repo_compare', url_data); | |
|
212 | ||
|
213 | $(targetElement).select2({ | |
|
214 | dropdownAutoWidth: true, | |
|
215 | width: "resolve", | |
|
216 | containerCssClass: "drop-menu", | |
|
217 | dropdownCssClass: "drop-menu-dropdown", | |
|
218 | query: function(query) { | |
|
219 | var cachedData = cachedDataSource[cacheKey]; | |
|
220 | if (cachedData) { | |
|
221 | feedRefsData(query, cachedData) | |
|
222 | } else { | |
|
223 | loadRefsData(query) | |
|
224 | } | |
|
225 | }, | |
|
226 | initSelection: function(element, callback) { | |
|
227 | callback(initialData); | |
|
228 | }, | |
|
229 | formatResult: formatResult, | |
|
230 | formatSelection: formatSelection | |
|
183 | 231 |
|
|
184 | 232 | |
|
185 | $('#show_at_commit').on('click', function(e) { | |
|
186 | var diff1 = $('#diff1').val(); | |
|
233 | }; | |
|
234 | ||
|
235 | select2FileHistorySwitcher('#file_refs_filter', loadUrl, initialCommitData); | |
|
187 | 236 | |
|
188 | var annotate = $('#annotate').val(); | |
|
189 | if (annotate === "True") { | |
|
237 | $('#file_refs_filter').on('change', function(e) { | |
|
238 | var data = $('#file_refs_filter').select2('data'); | |
|
239 | var commit_id = data.id; | |
|
240 | ||
|
241 | if ("${c.annotate}" === "True") { | |
|
190 | 242 |
|
|
191 | 243 |
|
|
192 |
|
|
|
244 | 'commit_id': commit_id, 'f_path': state.f_path}); | |
|
193 | 245 |
|
|
194 | 246 |
|
|
195 | 247 |
|
|
196 |
|
|
|
248 | 'commit_id': commit_id, 'f_path': state.f_path}); | |
|
197 | 249 |
|
|
198 | 250 |
|
|
199 | 251 | |
|
200 | 252 |
|
|
201 | 253 | |
|
202 | 254 |
|
|
203 | 255 |
|
|
204 | 256 |
|
|
205 | 257 |
|
|
206 | 258 |
|
|
207 | 259 |
|
|
208 | 260 | |
|
209 | 261 |
|
|
210 | 262 |
|
|
211 | 263 |
|
|
212 | 264 |
|
|
213 | 265 |
|
|
214 | 266 |
|
|
215 | 267 |
|
|
216 | 268 |
|
|
217 | 269 |
|
|
218 | 270 |
|
|
219 | 271 |
|
|
220 | 272 | |
|
221 | 273 |
|
|
222 | 274 |
|
|
223 | 275 |
|
|
224 | 276 |
|
|
225 | 277 |
|
|
226 | 278 |
|
|
227 | 279 |
|
|
228 | 280 |
|
|
229 | 281 |
|
|
230 | 282 |
|
|
231 | 283 |
|
|
232 | 284 |
|
|
233 | 285 | |
|
234 | 286 |
|
|
235 | 287 |
|
|
236 | 288 |
|
|
237 | 289 |
|
|
238 | 290 |
|
|
239 |
|
|
|
291 | }); | |
|
240 | 292 |
|
|
241 | 293 | |
|
242 | } | |
|
243 | // VIEW FOR FILE TREE BROWSER | |
|
244 | else { | |
|
294 | ||
|
295 | }; | |
|
296 | ||
|
297 | var initTreeJS = function () { | |
|
298 | var state = getState('callbacks'); | |
|
245 | 299 |
|
|
246 | 300 | |
|
247 | 301 |
|
|
248 | 302 |
|
|
249 | 303 | |
|
250 | 304 |
|
|
251 | 305 |
|
|
252 | 306 |
|
|
253 | 307 |
|
|
254 | 308 |
|
|
255 | 309 |
|
|
256 | 310 |
|
|
257 | 311 |
|
|
258 | 312 |
|
|
259 | 313 |
|
|
260 | 314 | |
|
261 | 315 |
|
|
262 | 316 |
|
|
263 | 317 |
|
|
264 | 318 |
|
|
265 | 319 |
|
|
266 | 320 | |
|
267 | 321 |
|
|
268 | 322 |
|
|
269 | 323 |
|
|
270 | 324 | |
|
271 | 325 |
|
|
272 | 326 |
|
|
273 | 327 |
|
|
274 | 328 |
|
|
275 | 329 |
|
|
276 | 330 |
|
|
277 | 331 |
|
|
278 | 332 |
|
|
279 | 333 |
|
|
280 | 334 |
|
|
281 | 335 |
|
|
282 | 336 |
|
|
283 | 337 | |
|
284 | 338 |
|
|
285 | 339 |
|
|
286 | 340 |
|
|
287 | 341 |
|
|
288 | 342 |
|
|
289 | 343 |
|
|
290 | 344 |
|
|
291 | 345 |
|
|
292 | 346 |
|
|
293 | 347 |
|
|
294 | 348 |
|
|
295 | 349 |
|
|
296 | 350 |
|
|
297 | 351 |
|
|
298 | 352 |
|
|
299 | 353 |
|
|
300 | 354 | |
|
301 | 355 |
|
|
302 | 356 |
|
|
303 | 357 |
|
|
304 | 358 |
|
|
305 | 359 |
|
|
306 | 360 | |
|
307 | 361 |
|
|
308 | 362 |
|
|
309 | 363 |
|
|
310 | 364 |
|
|
311 | 365 |
|
|
312 | 366 |
|
|
313 | 367 |
|
|
314 | 368 |
|
|
315 | 369 |
|
|
316 | 370 |
|
|
317 | 371 |
|
|
318 | 372 |
|
|
319 | 373 |
|
|
320 | 374 |
|
|
321 | 375 |
|
|
322 | 376 | |
|
323 | 377 |
|
|
324 | 378 |
|
|
325 | 379 |
|
|
326 | 380 |
|
|
327 | 381 | |
|
328 | 382 |
|
|
329 | 383 |
|
|
330 | 384 | |
|
331 | 385 |
|
|
332 | 386 |
|
|
333 |
|
|
|
387 | tmpl = (commit_ref.raw_id || "").substr(0,8); | |
|
334 | 388 |
|
|
335 | 389 |
|
|
336 | 390 |
|
|
337 | 391 |
|
|
338 | 392 |
|
|
339 | 393 |
|
|
340 | 394 |
|
|
341 | 395 |
|
|
342 | 396 |
|
|
343 | 397 |
|
|
344 | 398 | |
|
345 | tmpl = tmpl.concat('<span class="select-index-number">r{0}</span>'.format(commit_ref.idx)); | |
|
399 | var idx = commit_ref.idx || 0; | |
|
400 | tmpl = tmpl.concat('<span class="select-index-number">r{0}</span>'.format(idx)); | |
|
346 | 401 |
|
|
347 | 402 |
|
|
348 | 403 | |
|
349 | 404 |
|
|
350 | 405 |
|
|
351 | 406 |
|
|
352 | 407 |
|
|
353 | 408 |
|
|
354 | 409 |
|
|
355 | 410 | |
|
356 | 411 |
|
|
357 | 412 |
|
|
358 | 413 |
|
|
359 | 414 |
|
|
360 | 415 |
|
|
361 | 416 |
|
|
362 | 417 |
|
|
363 | 418 |
|
|
364 | 419 |
|
|
365 | 420 |
|
|
366 | 421 |
|
|
367 | 422 |
|
|
368 | 423 |
|
|
369 | 424 | |
|
370 | 425 |
|
|
371 | 426 | |
|
372 | 427 |
|
|
373 | 428 | |
|
374 | 429 |
|
|
375 | 430 |
|
|
376 | 431 |
|
|
377 | 432 |
|
|
378 | 433 | |
|
379 | } | |
|
380 | 434 | }; |
|
381 | 435 | |
|
382 | 436 | $(document).ready(function() { |
|
383 |
|
|
|
437 | timeagoActivate(); | |
|
438 | ||
|
439 | if ($('#trimmed_message_box').height() < 50) { | |
|
440 | $('#message_expand').hide(); | |
|
441 | } | |
|
442 | ||
|
443 | $('#message_expand').on('click', function(e) { | |
|
444 | $('#trimmed_message_box').css('max-height', 'none'); | |
|
445 | $(this).hide(); | |
|
446 | }); | |
|
447 | ||
|
448 | if (fileSourcePage) { | |
|
449 | initFileJS() | |
|
450 | } else { | |
|
451 | initTreeJS() | |
|
452 | } | |
|
453 | ||
|
384 | 454 | var search_GET = "${request.GET.get('search','')}"; |
|
385 | 455 | if (search_GET === "1") { |
|
386 | 456 | NodeFilter.initFilter(); |
|
387 | 457 | NodeFilter.focus(); |
|
388 | 458 | } |
|
389 | 459 | }); |
|
390 | 460 | |
|
391 | 461 | </script> |
|
392 | 462 | |
|
393 | 463 | </%def> No newline at end of file |
@@ -1,53 +1,64 b'' | |||
|
1 | 1 | |
|
2 | 2 | <div id="codeblock" class="browserblock"> |
|
3 | 3 | <div class="browser-header"> |
|
4 | 4 | <div class="browser-nav"> |
|
5 | 5 | |
|
6 | 6 | <div class="info_box"> |
|
7 | 7 | |
|
8 | 8 | <div class="info_box_elem previous"> |
|
9 | 9 | <a id="prev_commit_link" data-commit-id="${c.prev_commit.raw_id}" class=" ${('disabled' if c.url_prev == '#' else '')}" href="${c.url_prev}" title="${_('Previous commit')}"><i class="icon-left"></i></a> |
|
10 | 10 | </div> |
|
11 | 11 | |
|
12 | 12 | ${h.hidden('refs_filter')} |
|
13 | 13 | |
|
14 | 14 | <div class="info_box_elem next"> |
|
15 | 15 | <a id="next_commit_link" data-commit-id="${c.next_commit.raw_id}" class=" ${('disabled' if c.url_next == '#' else '')}" href="${c.url_next}" title="${_('Next commit')}"><i class="icon-right"></i></a> |
|
16 | 16 | </div> |
|
17 | 17 | </div> |
|
18 | 18 | |
|
19 | 19 | % if h.HasRepoPermissionAny('repository.write','repository.admin')(c.repo_name): |
|
20 | <div title="${_('Add New File')}" class="btn btn-primary new-file"> | |
|
21 | <a href="${h.route_path('repo_files_add_file',repo_name=c.repo_name,commit_id=c.commit.raw_id,f_path=c.f_path, _anchor='edit')}"> | |
|
22 |
${_(' |
|
|
20 | <div> | |
|
21 | <a class="btn btn-primary new-file" href="${h.route_path('repo_files_add_file',repo_name=c.repo_name,commit_id=c.commit.raw_id,f_path=c.f_path, _anchor='edit')}"> | |
|
22 | ${_('Upload File')} | |
|
23 | </a> | |
|
24 | <a class="btn btn-primary new-file" href="${h.route_path('repo_files_add_file',repo_name=c.repo_name,commit_id=c.commit.raw_id,f_path=c.f_path, _anchor='edit')}"> | |
|
25 | ${_('Add File')} | |
|
26 | </a> | |
|
23 | 27 | </div> |
|
24 | 28 | % endif |
|
25 | 29 | |
|
26 | 30 | % if c.enable_downloads: |
|
27 | 31 | <% at_path = '{}'.format(request.GET.get('at') or c.commit.raw_id[:6]) %> |
|
28 | 32 | <div class="btn btn-default new-file"> |
|
33 | % if c.f_path == '/': | |
|
29 | 34 | <a href="${h.route_path('repo_archivefile',repo_name=c.repo_name, fname='{}.zip'.format(c.commit.raw_id))}"> |
|
30 |
${_('Download ZIP |
|
|
35 | ${_('Download full tree ZIP')} | |
|
31 | 36 | </a> |
|
37 | % else: | |
|
38 | <a href="${h.route_path('repo_archivefile',repo_name=c.repo_name, fname='{}.zip'.format(c.commit.raw_id))}"> | |
|
39 | ${_('Download this tree ZIP')} | |
|
40 | </a> | |
|
41 | % endif | |
|
32 | 42 | </div> |
|
33 | 43 | % endif |
|
34 | 44 | |
|
35 | 45 | <div class="files-quick-filter"> |
|
36 | 46 | <ul class="files-filter-box"> |
|
37 | 47 | <li class="files-filter-box-path"> |
|
38 | 48 | <i class="icon-search"></i> |
|
39 | 49 | </li> |
|
40 | 50 | <li class="files-filter-box-input"> |
|
41 | 51 | <input onkeydown="NodeFilter.initFilter(event)" class="init" type="text" placeholder="Quick filter" name="filter" size="25" id="node_filter" autocomplete="off"> |
|
42 | 52 | </li> |
|
43 | 53 | </ul> |
|
44 | 54 | </div> |
|
45 | 55 | </div> |
|
46 | 56 | |
|
47 | 57 | </div> |
|
58 | ||
|
48 | 59 | ## file tree is computed from caches, and filled in |
|
49 | 60 | <div id="file-tree"> |
|
50 | 61 | ${c.file_tree |n} |
|
51 | 62 | </div> |
|
52 | 63 | |
|
53 | 64 | </div> |
@@ -1,89 +1,83 b'' | |||
|
1 | 1 | <% |
|
2 | 2 | if request.GET.get('at'): |
|
3 | 3 | query={'at': request.GET.get('at')} |
|
4 | 4 | else: |
|
5 | 5 | query=None |
|
6 | 6 | %> |
|
7 | 7 | <div id="file-tree-wrapper" class="browser-body ${('full-load' if c.full_load else '')}"> |
|
8 | 8 | <table class="code-browser rctable repo_summary"> |
|
9 | 9 | <thead> |
|
10 | 10 | <tr> |
|
11 | 11 | <th>${_('Name')}</th> |
|
12 | 12 | <th>${_('Size')}</th> |
|
13 | 13 | <th>${_('Modified')}</th> |
|
14 | 14 | <th>${_('Last Commit')}</th> |
|
15 | 15 | <th>${_('Author')}</th> |
|
16 | 16 | </tr> |
|
17 | 17 | </thead> |
|
18 | 18 | |
|
19 | 19 | <tbody id="tbody"> |
|
20 | %if c.file.parent: | |
|
21 |
<t |
|
|
22 | <td class="td-componentname"> | |
|
23 | <a href="${h.route_path('repo_files',repo_name=c.repo_name,commit_id=c.commit.raw_id,f_path=c.file.parent.path, _query=query)}"> | |
|
24 | <i class="icon-directory"></i>.. | |
|
25 | </a> | |
|
20 | <tr> | |
|
21 | <td colspan="5"> | |
|
22 | ||
|
23 | ${h.files_breadcrumbs(c.repo_name,c.commit.raw_id,c.file.path, request.GET.get('at'), limit_items=True)} | |
|
24 | ||
|
26 | 25 | </td> |
|
27 | <td></td> | |
|
28 | <td></td> | |
|
29 | <td></td> | |
|
30 | <td></td> | |
|
31 | 26 |
|
|
32 | %endif | |
|
33 | 27 | %for cnt,node in enumerate(c.file): |
|
34 | 28 | <tr class="parity${cnt%2}"> |
|
35 | 29 | <td class="td-componentname"> |
|
36 | 30 | % if node.is_submodule(): |
|
37 | 31 | <span class="submodule-dir"> |
|
38 | 32 | % if node.url.startswith('http://') or node.url.startswith('https://'): |
|
39 | 33 | <a href="${node.url}"> |
|
40 | 34 | <i class="icon-directory browser-dir"></i>${node.name} |
|
41 | 35 | </a> |
|
42 | 36 | % else: |
|
43 | 37 | <i class="icon-directory browser-dir"></i>${node.name} |
|
44 | 38 | % endif |
|
45 | 39 | </span> |
|
46 | 40 | % else: |
|
47 | 41 | |
|
48 | 42 | <a href="${h.route_path('repo_files',repo_name=c.repo_name,commit_id=c.commit.raw_id,f_path=h.safe_unicode(node.path), _query=query)}"> |
|
49 | 43 | <i class="${('icon-file-text browser-file' if node.is_file() else 'icon-directory browser-dir')}"></i>${node.name} |
|
50 | 44 | </a> |
|
51 | 45 | % endif |
|
52 | 46 | </td> |
|
53 | 47 | %if node.is_file(): |
|
54 | 48 | <td class="td-size" data-attr-name="size"> |
|
55 | 49 | % if c.full_load: |
|
56 | 50 | <span data-size="${node.size}">${h.format_byte_size_binary(node.size)}</span> |
|
57 | 51 | % else: |
|
58 | 52 | ${_('Loading ...')} |
|
59 | 53 | % endif |
|
60 | 54 | </td> |
|
61 | 55 | <td class="td-time" data-attr-name="modified_at"> |
|
62 | 56 | % if c.full_load: |
|
63 | 57 | <span data-date="${node.last_commit.date}">${h.age_component(node.last_commit.date)}</span> |
|
64 | 58 | % endif |
|
65 | 59 | </td> |
|
66 | 60 | <td class="td-hash" data-attr-name="commit_id"> |
|
67 | 61 | % if c.full_load: |
|
68 | 62 | <div class="tooltip" title="${h.tooltip(node.last_commit.message)}"> |
|
69 | 63 | <pre data-commit-id="${node.last_commit.raw_id}">r${node.last_commit.idx}:${node.last_commit.short_id}</pre> |
|
70 | 64 | </div> |
|
71 | 65 | % endif |
|
72 | 66 | </td> |
|
73 | 67 | <td class="td-user" data-attr-name="author"> |
|
74 | 68 | % if c.full_load: |
|
75 | 69 | <span data-author="${node.last_commit.author}" title="${h.tooltip(node.last_commit.author)}">${h.gravatar_with_user(request, node.last_commit.author)|n}</span> |
|
76 | 70 | % endif |
|
77 | 71 | </td> |
|
78 | 72 | %else: |
|
79 | 73 | <td></td> |
|
80 | 74 | <td></td> |
|
81 | 75 | <td></td> |
|
82 | 76 | <td></td> |
|
83 | 77 | %endif |
|
84 | 78 | </tr> |
|
85 | 79 | %endfor |
|
86 | 80 | </tbody> |
|
87 | 81 | <tbody id="tbody_filtered"></tbody> |
|
88 | 82 | </table> |
|
89 | 83 | </div> |
@@ -1,41 +1,34 b'' | |||
|
1 | 1 | <%def name="title(*args)"> |
|
2 | 2 | ${_('{} Files').format(c.repo_name)} |
|
3 | 3 | %if hasattr(c,'file'): |
|
4 | 4 | · ${(h.safe_unicode(c.file.path) or '\\')} |
|
5 | 5 | %endif |
|
6 | 6 | |
|
7 | 7 | %if c.rhodecode_name: |
|
8 | 8 | · ${h.branding(c.rhodecode_name)} |
|
9 | 9 | %endif |
|
10 | 10 | </%def> |
|
11 | 11 | |
|
12 | 12 | <div> |
|
13 | 13 | |
|
14 | 14 | <div class="summary-detail"> |
|
15 | 15 | <div class="summary-detail-header"> |
|
16 | <div class="breadcrumbs files_location"> | |
|
17 | <h4> | |
|
18 | ${h.files_breadcrumbs(c.repo_name,c.commit.raw_id,c.file.path, request.GET.get('at'))} | |
|
19 | %if c.annotate: | |
|
20 | - ${_('annotation')} | |
|
21 | %endif | |
|
22 | </h4> | |
|
23 | </div> | |
|
16 | ||
|
24 | 17 | </div><!--end summary-detail-header--> |
|
25 | 18 | |
|
26 | 19 | % if c.file.is_submodule(): |
|
27 | 20 | <span class="submodule-dir">Submodule ${h.escape(c.file.name)}</span> |
|
28 | 21 | % elif c.file.is_dir(): |
|
29 | 22 | <%include file='files_tree_header.mako'/> |
|
30 | 23 | % else: |
|
31 | 24 | <%include file='files_source_header.mako'/> |
|
32 | 25 | % endif |
|
33 | 26 | |
|
34 | 27 | </div> <!--end summary-detail--> |
|
35 | 28 | % if c.file.is_dir(): |
|
36 | 29 | <%include file='files_browser.mako'/> |
|
37 | 30 | % else: |
|
38 | 31 | <%include file='files_source.mako'/> |
|
39 | 32 | % endif |
|
40 | 33 | |
|
41 | 34 | </div> |
@@ -1,131 +1,148 b'' | |||
|
1 | 1 | <%namespace name="sourceblock" file="/codeblocks/source.mako"/> |
|
2 | 2 | |
|
3 |
<div id="codeblock" class=" |
|
|
4 |
<div class=" |
|
|
3 | <div id="codeblock" class="browserblock"> | |
|
4 | <div class="browser-header"> | |
|
5 | <div class="browser-nav"> | |
|
6 | <div class="pull-left"> | |
|
7 | ## loads the history for a file | |
|
8 | ${h.hidden('file_refs_filter')} | |
|
9 | </div> | |
|
10 | ||
|
11 | <div class="pull-right"> | |
|
12 | ||
|
13 | ## Download | |
|
14 | % if c.lf_node: | |
|
15 | <a class="btn btn-default" href="${h.route_path('repo_file_download',repo_name=c.repo_name,commit_id=c.commit.raw_id,f_path=c.f_path, _query=dict(lf=1))}"> | |
|
16 | ${_('Download largefile')} | |
|
17 | </a> | |
|
18 | % else: | |
|
19 | <a class="btn btn-default" href="${h.route_path('repo_file_download',repo_name=c.repo_name,commit_id=c.commit.raw_id,f_path=c.f_path)}"> | |
|
20 | ${_('Download file')} | |
|
21 | </a> | |
|
22 | % endif | |
|
23 | ||
|
24 | %if h.HasRepoPermissionAny('repository.write','repository.admin')(c.repo_name): | |
|
25 | ## on branch head, can edit files | |
|
26 | %if c.on_branch_head and c.branch_or_raw_id and not c.file.is_binary: | |
|
27 | ## binary files are delete only | |
|
28 | % if c.file.is_binary: | |
|
29 | ${h.link_to(_('Edit'), '#Edit', class_="btn btn-default disabled tooltip", title=_('Editing binary files not allowed'))} | |
|
30 | ${h.link_to(_('Delete'), h.route_path('repo_files_remove_file',repo_name=c.repo_name,commit_id=c.branch_or_raw_id,f_path=c.f_path, _anchor='edit'),class_="btn btn-danger")} | |
|
31 | % else: | |
|
32 | <a class="btn btn-default" href="${h.route_path('repo_files_edit_file',repo_name=c.repo_name,commit_id=c.branch_or_raw_id,f_path=c.f_path, _anchor='edit')}"> | |
|
33 | ${_('Edit on branch: ')}<code>${c.branch_name}</code> | |
|
34 | </a> | |
|
35 | ||
|
36 | <a class="btn btn-danger" href="${h.route_path('repo_files_remove_file',repo_name=c.repo_name,commit_id=c.branch_or_raw_id,f_path=c.f_path, _anchor='edit')}"> | |
|
37 | ${_('Delete')} | |
|
38 | </a> | |
|
39 | % endif | |
|
40 | ## not on head, forbid all | |
|
41 | % else: | |
|
42 | ${h.link_to(_('Edit'), '#Edit', class_="btn btn-default disabled tooltip", title=_('Editing files allowed only when on branch head commit'))} | |
|
43 | ${h.link_to(_('Delete'), '#Delete', class_="btn btn-default btn-danger disabled tooltip", title=_('Deleting files allowed only when on branch head commit'))} | |
|
44 | % endif | |
|
45 | %endif | |
|
46 | ||
|
47 | </div> | |
|
48 | </div> | |
|
49 | <div id="file_history_container"></div> | |
|
50 | ||
|
51 | </div> | |
|
52 | </div> | |
|
53 | ||
|
54 | <div class="codeblock codeblock-header"> | |
|
55 | <div> | |
|
56 | ${h.files_breadcrumbs(c.repo_name,c.commit.raw_id,c.file.path, request.GET.get('at'))} | |
|
57 | </div> | |
|
5 | 58 | <div class="stats"> |
|
6 | <span class="stats-filename"> | |
|
7 | <strong> | |
|
8 | <i class="icon-file-text"></i> | |
|
9 | ${c.file.unicode_path_safe} | |
|
10 | </strong> | |
|
11 | </span> | |
|
12 | <span class="item last"><i class="tooltip icon-clipboard clipboard-action" data-clipboard-text="${c.f_path}" title="${_('Copy the full path')}"></i></span> | |
|
13 | <br/> | |
|
14 | 59 | |
|
15 | 60 | % if c.lf_node: |
|
16 | 61 | <span title="${_('This file is a pointer to large binary file')}"> | ${_('LargeFile')} ${h.format_byte_size_binary(c.lf_node.size)} </span> |
|
17 | 62 | % endif |
|
18 | 63 | |
|
19 | 64 | <div class="stats-info"> |
|
20 | 65 | <span class="stats-first-item">${c.file.lines()[0]} ${_ungettext('line', 'lines', c.file.lines()[0])}</span> |
|
21 | 66 | <span> | ${h.format_byte_size_binary(c.file.size)}</span> |
|
22 | 67 | <span> | ${c.file.mimetype} </span> |
|
23 | 68 | <span> | ${h.get_lexer_for_filenode(c.file).__class__.__name__}</span> |
|
24 | 69 | </div> |
|
70 | ||
|
25 | 71 | </div> |
|
26 |
<div class=" |
|
|
27 | <a id="file_history_overview" href="#"> | |
|
72 | <div class="pull-right"> | |
|
73 | <a id="file_history_overview" href="#loadHistory"> | |
|
28 | 74 | ${_('History')} |
|
29 | 75 | </a> |
|
30 | <a id="file_history_overview_full" style="display: none" href="${h.route_path('repo_changelog_file',repo_name=c.repo_name, commit_id=c.commit.raw_id, f_path=c.f_path)}"> | |
|
31 | ${_('Show Full History')} | |
|
32 | </a> | | |
|
76 | | | |
|
33 | 77 | %if c.annotate: |
|
34 | 78 | ${h.link_to(_('Source'), h.route_path('repo_files', repo_name=c.repo_name,commit_id=c.commit.raw_id,f_path=c.f_path))} |
|
35 | 79 | %else: |
|
36 | 80 | ${h.link_to(_('Annotation'), h.route_path('repo_files:annotated',repo_name=c.repo_name,commit_id=c.commit.raw_id,f_path=c.f_path))} |
|
37 | 81 | %endif |
|
38 | 82 | | ${h.link_to(_('Raw'), h.route_path('repo_file_raw',repo_name=c.repo_name,commit_id=c.commit.raw_id,f_path=c.f_path))} |
|
39 | | | |
|
40 | % if c.lf_node: | |
|
41 | <a href="${h.route_path('repo_file_download',repo_name=c.repo_name,commit_id=c.commit.raw_id,f_path=c.f_path, _query=dict(lf=1))}"> | |
|
42 | ${_('Download largefile')} | |
|
43 | </a> | |
|
44 | % else: | |
|
45 | <a href="${h.route_path('repo_file_download',repo_name=c.repo_name,commit_id=c.commit.raw_id,f_path=c.f_path)}"> | |
|
46 | ${_('Download')} | |
|
47 | </a> | |
|
48 | % endif | |
|
49 | 83 |
|
|
50 | %if h.HasRepoPermissionAny('repository.write','repository.admin')(c.repo_name): | |
|
51 | | | |
|
52 | %if c.on_branch_head and c.branch_or_raw_id and not c.file.is_binary: | |
|
53 | <a href="${h.route_path('repo_files_edit_file',repo_name=c.repo_name,commit_id=c.branch_or_raw_id,f_path=c.f_path, _anchor='edit')}"> | |
|
54 | ${_('Edit on Branch:{}').format(c.branch_name)} | |
|
55 | </a> | |
|
56 | | <a class="btn-danger btn-link" href="${h.route_path('repo_files_remove_file',repo_name=c.repo_name,commit_id=c.branch_or_raw_id,f_path=c.f_path, _anchor='edit')}">${_('Delete')} | |
|
57 | </a> | |
|
58 | %elif c.on_branch_head and c.branch_or_raw_id and c.file.is_binary: | |
|
59 | ${h.link_to(_('Edit'), '#', class_="btn btn-link disabled tooltip", title=_('Editing binary files not allowed'))} | |
|
60 | | ${h.link_to(_('Delete'), h.route_path('repo_files_remove_file',repo_name=c.repo_name,commit_id=c.branch_or_raw_id,f_path=c.f_path, _anchor='edit'),class_="btn-danger btn-link")} | |
|
61 | %else: | |
|
62 | ${h.link_to(_('Edit'), '#', class_="btn btn-link disabled tooltip", title=_('Editing files allowed only when on branch head commit'))} | |
|
63 | | ${h.link_to(_('Delete'), '#', class_="btn btn-danger btn-link disabled tooltip", title=_('Deleting files allowed only when on branch head commit'))} | |
|
64 | %endif | |
|
65 | %endif | |
|
66 | 84 | </div> |
|
67 | </div> | |
|
68 | <div id="file_history_container"></div> | |
|
85 | ||
|
69 | 86 | <div class="code-body"> |
|
70 | 87 | %if c.file.is_binary: |
|
71 | 88 | <% rendered_binary = h.render_binary(c.repo_name, c.file)%> |
|
72 | 89 | % if rendered_binary: |
|
73 | 90 | ${rendered_binary} |
|
74 | 91 | % else: |
|
75 | 92 | <div> |
|
76 | 93 | ${_('Binary file (%s)') % c.file.mimetype} |
|
77 | 94 | </div> |
|
78 | 95 | % endif |
|
79 | 96 | %else: |
|
80 | 97 | % if c.file.size < c.visual.cut_off_limit_file: |
|
81 | 98 | %if c.renderer and not c.annotate: |
|
82 | 99 | ## pick relative url based on renderer |
|
83 | 100 | <% |
|
84 | 101 | relative_urls = { |
|
85 | 102 | 'raw': h.route_path('repo_file_raw',repo_name=c.repo_name,commit_id=c.commit.raw_id,f_path=c.f_path), |
|
86 | 103 | 'standard': h.route_path('repo_files',repo_name=c.repo_name,commit_id=c.commit.raw_id,f_path=c.f_path), |
|
87 | 104 | } |
|
88 | 105 | %> |
|
89 | 106 | ${h.render(c.file.content, renderer=c.renderer, relative_urls=relative_urls)} |
|
90 | 107 | %else: |
|
91 | 108 | <table class="cb codehilite"> |
|
92 | 109 | %if c.annotate: |
|
93 | 110 | <% color_hasher = h.color_hasher() %> |
|
94 | 111 | %for annotation, lines in c.annotated_lines: |
|
95 | 112 | ${sourceblock.render_annotation_lines(annotation, lines, color_hasher)} |
|
96 | 113 | %endfor |
|
97 | 114 | %else: |
|
98 | 115 | %for line_num, tokens in enumerate(c.lines, 1): |
|
99 | 116 | ${sourceblock.render_line(line_num, tokens)} |
|
100 | 117 | %endfor |
|
101 | 118 | %endif |
|
102 | 119 | </table> |
|
103 | 120 | %endif |
|
104 | 121 | %else: |
|
105 | 122 | ${_('File size {} is bigger then allowed limit {}. ').format(h.format_byte_size_binary(c.file.size), h.format_byte_size_binary(c.visual.cut_off_limit_file))} ${h.link_to(_('Show as raw'), |
|
106 | 123 | h.route_path('repo_file_raw',repo_name=c.repo_name,commit_id=c.commit.raw_id,f_path=c.f_path))} |
|
107 | 124 | %endif |
|
108 | 125 | %endif |
|
109 | 126 | </div> |
|
110 | 127 | </div> |
|
111 | 128 | |
|
112 | 129 | <script type="text/javascript"> |
|
113 | 130 | % if request.GET.get('mark'): |
|
114 | 131 | |
|
115 | 132 | $(function(){ |
|
116 | 133 | $(".codehilite").mark( |
|
117 | 134 | "${request.GET.get('mark')}", |
|
118 | 135 | { |
|
119 | 136 | "className": 'match', |
|
120 | 137 | "accuracy": "complementary", |
|
121 | 138 | "ignorePunctuation": ":._(){}[]!'+=".split(""), |
|
122 | 139 | "each": function(el) { |
|
123 | 140 | // and also highlight lines ! |
|
124 | 141 | $($(el).closest('tr')).find('td.cb-lineno').addClass('cb-line-selected'); |
|
125 | 142 | } |
|
126 | 143 | } |
|
127 | 144 | ); |
|
128 | 145 | |
|
129 | 146 | }); |
|
130 | 147 | % endif |
|
131 | 148 | </script> |
@@ -1,84 +1,61 b'' | |||
|
1 | 1 | <%namespace name="base" file="/base/base.mako"/> |
|
2 | 2 | <%namespace name="file_base" file="/files/base.mako"/> |
|
3 | 3 | |
|
4 | 4 | <div class="summary"> |
|
5 | 5 | <div class="fieldset"> |
|
6 | 6 | <div class="left-content"> |
|
7 | 7 | |
|
8 | 8 | <div class="left-content-avatar"> |
|
9 | 9 | ${base.gravatar(c.file_last_commit.author_email, 30)} |
|
10 | 10 | </div> |
|
11 | 11 | |
|
12 | 12 | <div class="left-content-message"> |
|
13 | 13 | <div class="fieldset collapsable-content no-hide" data-toggle="summary-details"> |
|
14 | 14 | <div class="commit truncate-wrap">${h.urlify_commit_message(h.chop_at_smart(c.commit.message, '\n', suffix_if_chopped='...'), c.repo_name)}</div> |
|
15 | 15 | </div> |
|
16 | 16 | |
|
17 | 17 | <div class="fieldset collapsable-content" data-toggle="summary-details"> |
|
18 | 18 | <div class="commit">${h.urlify_commit_message(c.commit.message,c.repo_name)}</div> |
|
19 | 19 | </div> |
|
20 | 20 | |
|
21 | 21 | <div class="fieldset" data-toggle="summary-details"> |
|
22 | 22 | <div class="" id="file_authors"> |
|
23 | 23 | ## loads single author, or ALL |
|
24 | 24 | <%include file='file_authors_box.mako'/> |
|
25 | 25 | </div> |
|
26 | 26 | </div> |
|
27 | 27 | </div> |
|
28 | 28 | |
|
29 | 29 | <div class="fieldset collapsable-content" data-toggle="summary-details"> |
|
30 | 30 | <div class="left-label-summary-files"> |
|
31 | 31 | <p>${_('File last commit')}</p> |
|
32 | 32 | <div class="right-label-summary"> |
|
33 | 33 | <code><a href="${h.route_path('repo_commit',repo_name=c.repo_name,commit_id=c.file_last_commit.raw_id)}">${h.show_id(c.file_last_commit)}</a></code> |
|
34 | 34 | |
|
35 | 35 | ${file_base.refs(c.file_last_commit)} |
|
36 | 36 | </div> |
|
37 | 37 | </div> |
|
38 | 38 | </div> |
|
39 | ||
|
40 | ||
|
41 | <div class="fieldset collapsable-content" data-toggle="summary-details"> | |
|
42 | <div class="left-label-summary-files"> | |
|
43 | <p class="spacing">${_('Show/Diff file')}</p> | |
|
44 | <div class="right-label-summary"> | |
|
45 | ${h.hidden('diff1')} | |
|
46 | ${h.hidden('diff2',c.commit.raw_id)} | |
|
47 | ${h.hidden('annotate', c.annotate)} | |
|
48 | </div> | |
|
49 | </div> | |
|
50 | </div> | |
|
51 | ||
|
52 | ||
|
53 | <div class="fieldset collapsable-content" data-toggle="summary-details"> | |
|
54 | <div class="left-label-summary-files"> | |
|
55 | <p>${_('Action')}</p> | |
|
56 | <div class="right-label-summary"> | |
|
57 | ${h.submit('diff_to_commit',_('Diff to Commit'),class_="btn disabled",disabled="true")} | |
|
58 | ${h.submit('show_at_commit',_('Show at Commit'),class_="btn disabled",disabled="true")} | |
|
59 | </div> | |
|
60 | </div> | |
|
61 | </div> | |
|
62 | 39 | </div> |
|
63 | 40 | |
|
64 | 41 | <div class="right-content"> |
|
65 | 42 | <div data-toggle="summary-details"> |
|
66 | 43 | <div class="tags commit-info tags-main"> |
|
67 | 44 | <code><a href="${h.route_path('repo_commit',repo_name=c.repo_name,commit_id=c.commit.raw_id)}">${h.show_id(c.commit)}</a></code> |
|
68 | 45 | ${file_base.refs(c.commit)} |
|
69 | 46 | </div> |
|
70 | 47 | </div> |
|
71 | 48 | </div> |
|
72 | 49 | |
|
73 | 50 | <div class="clear-fix"></div> |
|
74 | 51 | |
|
75 | 52 | <div class="btn-collapse" data-toggle="summary-details"> |
|
76 | 53 | ${_('Show More')} |
|
77 | 54 | </div> |
|
78 | 55 | |
|
79 | 56 | </div> |
|
80 | 57 | </div> |
|
81 | 58 | |
|
82 | 59 | <script> |
|
83 | 60 | collapsableContent(); |
|
84 | 61 | </script> |
General Comments 0
You need to be logged in to leave comments.
Login now