Compare commits
144 Commits
2.670
...
dev/fix-po
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
925af91ce8 | ||
|
|
e3e6a9b44f | ||
|
|
29cf93863d | ||
|
|
b502deaddf | ||
|
|
0d4c4b7582 | ||
|
|
a272f94d93 | ||
|
|
9026459a53 | ||
|
|
24cd92a061 | ||
|
|
8417d5c279 | ||
|
|
dda9b972b9 | ||
|
|
cce4d69a09 | ||
|
|
6a9e0afa7b | ||
|
|
658f930d69 | ||
|
|
1c7781299d | ||
|
|
6c674def60 | ||
|
|
692cb6ea70 | ||
|
|
200444d8d6 | ||
|
|
01e454414b | ||
|
|
b5ce991eb3 | ||
|
|
045c7abfdf | ||
|
|
5e4b937410 | ||
|
|
3d22baaeea | ||
|
|
502a54b6df | ||
|
|
6fec16bbd2 | ||
|
|
65de483f37 | ||
|
|
222a2fd31b | ||
|
|
2d014758a2 | ||
|
|
01ce0a70d1 | ||
|
|
166cfefa28 | ||
|
|
3d0a9aeea8 | ||
|
|
616547c26f | ||
|
|
24db25a6c5 | ||
|
|
072bf2bda3 | ||
|
|
8bc89757a7 | ||
|
|
02d2ce697f | ||
|
|
bc9d7e67a8 | ||
|
|
7b6c3b3857 | ||
|
|
ba0d06743d | ||
|
|
759359db48 | ||
|
|
31680372d2 | ||
|
|
c23b6b5b48 | ||
|
|
0f71dac9cf | ||
|
|
6b78f7d8b5 | ||
|
|
c57711a3b5 | ||
|
|
6c008506d9 | ||
|
|
32d20fe18c | ||
|
|
2259de1962 | ||
|
|
6873c65c42 | ||
|
|
f2b94348dc | ||
|
|
6fecd282b8 | ||
|
|
1e1f9982d7 | ||
|
|
19e86a9657 | ||
|
|
42850e5795 | ||
|
|
e99841ebc6 | ||
|
|
c8e06cb06c | ||
|
|
2f8e484829 | ||
|
|
17ba87cbc6 | ||
|
|
22c31d206f | ||
|
|
f7f2fcbdb8 | ||
|
|
1a88fcdb74 | ||
|
|
34040bd0df | ||
|
|
89ab870924 | ||
|
|
bc87da9048 | ||
|
|
f9cac4c4a4 | ||
|
|
c51f0ed465 | ||
|
|
63a07308ab | ||
|
|
51cf5c0798 | ||
|
|
270ef90703 | ||
|
|
2bf3f4834c | ||
|
|
82e7e343f5 | ||
|
|
dea3af005f | ||
|
|
b4c79b1348 | ||
|
|
8f9663fd9c | ||
|
|
3bb7eeb144 | ||
|
|
51b5e9c15a | ||
|
|
5e90e1438a | ||
|
|
9f9a54ed51 | ||
|
|
0befd2663c | ||
|
|
f759798e7f | ||
|
|
cfe8d72d85 | ||
|
|
1fed13ba32 | ||
|
|
39786bae17 | ||
|
|
593fb94f11 | ||
|
|
37296f5b22 | ||
|
|
51e3dccb1d | ||
|
|
f354238c24 | ||
|
|
223b0f331f | ||
|
|
851883c41d | ||
|
|
95b74cc45f | ||
|
|
e327940bd6 | ||
|
|
18d5344043 | ||
|
|
fd7760d2e1 | ||
|
|
8b9cb8c603 | ||
|
|
77ffa83f8f | ||
|
|
32fb7f2462 | ||
|
|
afd6fad51e | ||
|
|
0be0ba411a | ||
|
|
11be3726f7 | ||
|
|
1726be59e6 | ||
|
|
61d3618cc5 | ||
|
|
84ea802947 | ||
|
|
2dea2f8090 | ||
|
|
22c580aea1 | ||
|
|
8f880ab366 | ||
|
|
f8f35b26c6 | ||
|
|
875c973658 | ||
|
|
8742ccd312 | ||
|
|
94436938d0 | ||
|
|
cec6e6074d | ||
|
|
aeee5edd15 | ||
|
|
359eb13f0e | ||
|
|
316f1330de | ||
|
|
ff83f05768 | ||
|
|
97ba9cbd46 | ||
|
|
ee5009a47f | ||
|
|
1bfd92c21c | ||
|
|
97ed7cef25 | ||
|
|
ea691b895e | ||
|
|
98641c73bd | ||
|
|
c8a6a0f69a | ||
|
|
e90b946de6 | ||
|
|
8a09ca5342 | ||
|
|
abf05faa20 | ||
|
|
47d2411e2b | ||
|
|
f98a6a31dc | ||
|
|
6b7832acd0 | ||
|
|
e70bf0ffaa | ||
|
|
9458057978 | ||
|
|
bbdd520807 | ||
|
|
c85e0b8c50 | ||
|
|
d78dcb7625 | ||
|
|
8f79fbd0fd | ||
|
|
8c56e266d1 | ||
|
|
a68dacad64 | ||
|
|
cc0f8134da | ||
|
|
0055cccfef | ||
|
|
f9b818c0b0 | ||
|
|
678c50ed3c | ||
|
|
da34454d9b | ||
|
|
5a806c48c1 | ||
|
|
9faa2b4323 | ||
|
|
66f5f22320 | ||
|
|
623a5f0fa0 | ||
|
|
6dfaa54616 |
29
CHANGELOG.md
@@ -1,4 +1,26 @@
|
||||
## Changelog
|
||||
#### 2.680 (October, 2026)
|
||||
* Add color schemes to the Terminal module
|
||||
* Add per-user Terminal preferences for color scheme, font size, screen reader mode and terminal dimensions
|
||||
* Add protection against infinite loops resolving recursive symlinks (thanks to Carl Zuzart, Zedden I.T.)
|
||||
* Add a Cloudmin virtualization host profile to the nftables module
|
||||
* Add drop-down menu, dialog, breadcrumb and page link widgets to the UI library, built on native `details` and `dialog` elements
|
||||
* Add confirmation dialogs for buttons and links carrying `data-ui-confirm`, replacing the browser's own prompt
|
||||
* Update File Manager to use the new UI widgets in the standard theme, dropping legacy templates
|
||||
* Fix standard theme sortable tables dropping controls from table headings, such as the select-all checkbox in File Manager
|
||||
* Fix two-factor authentication validation to use the Webmin configuration and data directories passed by the caller
|
||||
* Fix HTML escaping of module, script and session fields on the Webmin Actions Log details page
|
||||
* Fix mailbox attachment option injection
|
||||
* Fix path traversal and command injection in parameterized Custom Commands file editors
|
||||
* Fix MySQL/MariaDB manual editor ACL bypass
|
||||
* Fix the logged in users list in Users and Groups module showing nobody when `who` prints ISO dates under a non-C locale or `sshd pts/N` lines from the logind backend [forum.virtualmin.com/t/138162](https://forum.virtualmin.com/t/138162)
|
||||
* Fix mail date parsing of ISO dates like `2026-10-15 02:33` returning the wrong minutes
|
||||
* Add optional address-family selection to HTTP downloads and socket connections, preserved across redirects [#1300](https://github.com/virtualmin/virtualmin-gpl/issues/1300)
|
||||
* Update the Authentic theme to the latest version with various improvements:
|
||||
- Add support for Terminal module color preferences
|
||||
- Add support for the new Cloudmin navigation, graphical console and live virtual machine controls
|
||||
- Fix spacing and borders in widgets, tables and tab panes
|
||||
|
||||
#### 2.670 (September 20, 2026)
|
||||
* Add new Hardware Information module for inspecting system, firmware, security, PCI, USB, storage, network, processor, sensor, driver, and kernel module details
|
||||
* Add options to send Webmin and Usermin errors to the systemd journal [forum.virtualmin.com/t/136562](https://forum.virtualmin.com/t/miniserv-webserver-log-growing-too-big-should-be-rotated/136562)
|
||||
@@ -20,6 +42,13 @@
|
||||
* Fix ACL operations bypassing configured allowed paths in File Manager
|
||||
* Fix arbitrary file reads in Software Packages module
|
||||
* Fix TLS client certificate verification
|
||||
* Fix Apache Webserver module to enforce the allowed directory ACL when manually editing `.htaccess` files
|
||||
* Fix Custom Commands module to properly quote parameter values passed to commands and to reject parameters with multiple values
|
||||
* Fix DNSSEC NSEC3 zone signing in BIND DNS Server module to use zero additional hash iterations, as recommended by RFC 9276
|
||||
* Fix System Logs module to create a new log file only after the log entry passes validation
|
||||
* Fix file chooser to lift the root directory restriction only when the chroot is at or under the allowed root
|
||||
* Fix password changes from the login page using a configured password change command to fail unless the command prompts for the old password
|
||||
* Fix File Manager search results to only include files under the allowed directories
|
||||
* Update Backup Configuration module's destination selector to use the new select-based UI
|
||||
* Update the Authentic theme to the latest version with various improvements:
|
||||
- Add support for HTML signatures in Usermin
|
||||
|
||||
@@ -447,7 +447,11 @@ if ($miniserv{'userdb'} && !$miniserv{'userdb_addto'}) {
|
||||
$user->{'proto'} = $proto;
|
||||
}
|
||||
else {
|
||||
# Adding to local files
|
||||
# Add a single-line record to the local user file
|
||||
foreach my $value (values %$user) {
|
||||
$value =~ s/[\r\n].*//s
|
||||
if (defined($value) && !ref($value));
|
||||
}
|
||||
&lock_file($ENV{'MINISERV_CONFIG'});
|
||||
if ($user->{'theme'}) {
|
||||
$miniserv{"preroot_".$user->{'name'}} =
|
||||
@@ -628,7 +632,11 @@ if ($user->{'proto'}) {
|
||||
&disconnect_userdb($miniserv{'userdb'}, $dbh);
|
||||
}
|
||||
else {
|
||||
# In local files
|
||||
# Update the single-line record in the local user file
|
||||
foreach my $value (values %$user) {
|
||||
$value =~ s/[\r\n].*//s
|
||||
if (defined($value) && !ref($value));
|
||||
}
|
||||
&lock_file($ENV{'MINISERV_CONFIG'});
|
||||
delete($miniserv{"preroot_".$username});
|
||||
if ($user->{'theme'}) {
|
||||
@@ -1466,7 +1474,9 @@ return if (&is_readonly_mode());
|
||||
my $sid = &generate_random_session_id();
|
||||
return if (!$sid);
|
||||
my $t = time();
|
||||
$sessiondb{$sid} = "$username $t 127.0.0.1".($lifetime ? " ".$lifetime : "");
|
||||
# miniserv only looks up sessions by their hashed key
|
||||
$sessiondb{&hash_session_id($sid)} =
|
||||
"$username $t 127.0.0.1".($lifetime ? " ".$lifetime : "");
|
||||
dbmclose(%sessiondb);
|
||||
return $sid;
|
||||
}
|
||||
|
||||
@@ -108,7 +108,11 @@ foreach my $u (@users) {
|
||||
$msg = "<i>".&text('convert_exists', $u->{'user'})."</i>";
|
||||
$exists++;
|
||||
}
|
||||
elsif ($u->{'user'} !~ /^[A-z0-9\-\_\.]+$/) {
|
||||
elsif ($u->{'user'} !~ /^[A-z0-9\-\_\.]+$/ ||
|
||||
(!$access{'acl'} &&
|
||||
$u->{'user'} =~ /^(root|admin|sysadm)$/)) {
|
||||
# Reject invalid names and privileged RPC names that this
|
||||
# administrator is not allowed to create.
|
||||
$msg = "<i>".&text('convert_invalid', $u->{'user'})."</i>";
|
||||
$invalid++;
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ else {
|
||||
|
||||
my %minfo = $in{'mod'} ? &get_module_info($in{'mod'})
|
||||
: ( 'desc' => $text{'index_global'} );
|
||||
%minfo || &error($text{'acl_emod2'});
|
||||
my $below = &text($in{'group'} ? 'acl_title3' : 'acl_title2',
|
||||
"<tt>".&html_escape($who)."</tt>",
|
||||
"<tt>$minfo{'desc'}</tt>");
|
||||
|
||||
@@ -129,6 +129,7 @@ save_emd5=The Same as Unix password option cannot be used on systems with MD5 en
|
||||
save_eunix=The Unix user '$1' does not exist
|
||||
save_emod=You cannot grant access to module '$1'
|
||||
save_ecreate=You are not allowed to create users
|
||||
save_ecreateroot=You are not allowed to create RPC root users
|
||||
save_euser=You are not allowed to edit this user
|
||||
save_ecolon=Passwords cannot contain the : character
|
||||
save_epass=Password is not valid : $1
|
||||
@@ -201,6 +202,7 @@ acl_chcert=Can change SSL certificate name?
|
||||
acl_euser=You are not allowed to edit the ACL for this user
|
||||
acl_egroup=You are not allowed to edit group ACLs
|
||||
acl_emod=You are not allowed to edit the ACL for this module
|
||||
acl_emod2=Module does not exist
|
||||
acl_others=Can see inaccessible modules?
|
||||
acl_cert=Can request certificate?
|
||||
acl_err=Failed to save access control
|
||||
|
||||
@@ -7,7 +7,7 @@ no warnings 'redefine';
|
||||
no warnings 'uninitialized';
|
||||
require './acl-lib.pl'; ## no critic
|
||||
our (%in, %text, %config, %access);
|
||||
$access{'pass'} || &error($text{'sql_ecannot'});
|
||||
$access{'sql'} || &error($text{'sql_ecannot'});
|
||||
&ReadParse();
|
||||
&error_setup($text{'makedn_err'});
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ no warnings 'redefine';
|
||||
no warnings 'uninitialized';
|
||||
require './acl-lib.pl'; ## no critic
|
||||
our (%in, %text, %config, %access);
|
||||
$access{'pass'} || &error($text{'sql_ecannot'});
|
||||
$access{'sql'} || &error($text{'sql_ecannot'});
|
||||
&ReadParse();
|
||||
&error_setup($text{'make_err'});
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ require './acl-lib.pl'; ## no critic
|
||||
our (%in, %text, %config, %access, $base_remote_user, %gconfig,
|
||||
$config_directory);
|
||||
&ReadParse();
|
||||
$access{'acl'} || &error($text{'acl_emod'});
|
||||
|
||||
my $who;
|
||||
if ($in{'_acl_group'}) {
|
||||
@@ -30,6 +31,7 @@ my $aclfile = $in{'_acl_group'} ? "$config_directory/$in{'_acl_mod'}/$who.gacl"
|
||||
: "$config_directory/$in{'_acl_mod'}/$who.acl";
|
||||
my %minfo = $in{'_acl_mod'} ? &get_module_info($in{'_acl_mod'})
|
||||
: ( 'desc' => $text{'index_global'} );
|
||||
%minfo || &error($text{'acl_emod2'});
|
||||
if ($in{'reset'}) {
|
||||
# Just remove the .acl file
|
||||
&lock_file($aclfile);
|
||||
|
||||
@@ -9,6 +9,7 @@ no warnings 'uninitialized';
|
||||
require './acl-lib.pl'; ## no critic
|
||||
our (%in, %text, %config, %access, $config_directory);
|
||||
&ReadParse();
|
||||
$access{'groups'} || &error($text{'gedit_ecannot'});
|
||||
|
||||
# Check for special button clicks, and redirect
|
||||
if ($in{'but_clone'}) {
|
||||
|
||||
@@ -7,7 +7,7 @@ no warnings 'redefine';
|
||||
no warnings 'uninitialized';
|
||||
require './acl-lib.pl'; ## no critic
|
||||
our (%in, %text, %config, %access);
|
||||
$access{'pass'} || &error($text{'sql_ecannot'});
|
||||
$access{'sql'} || &error($text{'sql_ecannot'});
|
||||
&ReadParse();
|
||||
&error_setup($text{'sql_err'});
|
||||
my %miniserv;
|
||||
|
||||
@@ -56,8 +56,16 @@ else {
|
||||
}
|
||||
&error_setup($text{'save_err'});
|
||||
|
||||
if ((!$in{'old'} ||
|
||||
$in{'name'} ne $in{'old'}) &&
|
||||
$in{'name'} =~ /^(root|admin|sysadm)$/) {
|
||||
# User has one of the privileged names, make sure this user can
|
||||
# edit ACLs to prevent creation of RPC-root users
|
||||
$access{'acl'} || &error($text{'save_ecreateroot'});
|
||||
}
|
||||
|
||||
# Validate username, and check for a clash
|
||||
$in{'name'} =~ /^[A-z0-9\-\_\.\@]+$/ && $in{'name'} !~ /^\@/ ||
|
||||
$in{'name'} =~ /^[A-Za-z0-9\-\_\.\@]+$/ && $in{'name'} !~ /^\@/ ||
|
||||
&error(&text('save_ename', &html_escape($in{'name'})));
|
||||
$in{'name'} eq 'webmin' && &error($text{'save_enamewebmin'});
|
||||
if (!$in{'old'} || $in{'old'} ne $in{'name'}) {
|
||||
|
||||
@@ -7,7 +7,7 @@ no warnings 'redefine';
|
||||
no warnings 'uninitialized';
|
||||
require './acl-lib.pl'; ## no critic
|
||||
our (%in, %text, %config, %access);
|
||||
$access{'pass'} || &error($text{'sql_ecannot'});
|
||||
$access{'sql'} || &error($text{'sql_ecannot'});
|
||||
|
||||
&ui_print_unbuffered_header(undef, $text{'schema_title'}, "");
|
||||
|
||||
|
||||
@@ -1265,6 +1265,31 @@ subtest 'CGI harness smoke' => sub {
|
||||
'error path emits an HTML error page');
|
||||
};
|
||||
|
||||
# All SQL and LDAP user database helpers must use the dedicated SQL access
|
||||
# flag. Password-editing access alone must not allow direct CGI requests.
|
||||
subtest 'user database CGI permission gates' => sub {
|
||||
foreach my $cgi ('schema.cgi', 'maketables.cgi', 'makedn.cgi') {
|
||||
_reset_fixture();
|
||||
_seed_user_acl('admin', { pass => 1, sql => 0 });
|
||||
my $r = run_cgi($cgi, {});
|
||||
ok(!$r->{location}, "$cgi does not redirect without SQL access");
|
||||
like($r->{out},
|
||||
qr/not allowed to configure the user and group database/i,
|
||||
"$cgi rejects password-only administrators");
|
||||
}
|
||||
|
||||
# The read-only schema endpoint provides a safe positive permission test.
|
||||
_reset_fixture();
|
||||
_seed_user_acl('admin', { pass => 0, sql => 1 });
|
||||
my $r = run_cgi('schema.cgi', {});
|
||||
is($r->{status}, 0, 'schema.cgi renders with SQL access');
|
||||
unlike($r->{out},
|
||||
qr/not allowed to configure the user and group database/i,
|
||||
'schema.cgi accepts SQL-only administrators');
|
||||
like($r->{out}, qr/attributetype/i,
|
||||
'schema.cgi displays the LDAP schema');
|
||||
};
|
||||
|
||||
# delete_user.cgi — four distinct gates. NOTE: <rootdir>/acl/defaultacl has
|
||||
# every flag set to 1, and get_module_acl merges it under the per-user ACL.
|
||||
# So each denial test must EXPLICITLY set the relevant key to 0; relying on
|
||||
@@ -1449,6 +1474,40 @@ subtest 'save_user.cgi create privilege' => sub {
|
||||
delete_user('admin');
|
||||
};
|
||||
|
||||
# Unix conversion must not bypass the privileged-name guard in save_user.cgi.
|
||||
# An ACL-capable administrator can still deliberately convert such a user.
|
||||
subtest 'convert.cgi privileged username gate' => sub {
|
||||
_reset_fixture();
|
||||
_seed_user_acl('operator', {
|
||||
sync => 1, create => 1, acl => 0, gassign => '*',
|
||||
});
|
||||
create_group({ name => 'converted', members => [], modules => ['acl'] });
|
||||
|
||||
my $r = run_cgi('convert.cgi', {
|
||||
conv => 1, users => 'root', wgroup => 'converted', sync => 1,
|
||||
}, user => 'operator');
|
||||
_clear_caches();
|
||||
is($r->{status}, 0, 'conversion completes without ACL access');
|
||||
ok(!get_user('root'),
|
||||
'conversion skips a privileged RPC username without ACL access');
|
||||
like($r->{out}, qr/root.*not a valid Webmin username/i,
|
||||
'conversion reports the privileged username as invalid');
|
||||
|
||||
_reset_fixture();
|
||||
_seed_user_acl('operator', {
|
||||
sync => 1, create => 1, acl => 1, gassign => '*',
|
||||
});
|
||||
create_group({ name => 'converted', members => [], modules => ['acl'] });
|
||||
|
||||
$r = run_cgi('convert.cgi', {
|
||||
conv => 1, users => 'root', wgroup => 'converted', sync => 1,
|
||||
}, user => 'operator');
|
||||
_clear_caches();
|
||||
is($r->{status}, 0, 'conversion completes with ACL access');
|
||||
ok(get_user('root'),
|
||||
'ACL-capable administrator can convert a privileged username');
|
||||
};
|
||||
|
||||
subtest 'save_user.cgi gassign whitelist' => sub {
|
||||
# gassign='admins' allows assigning only to group "admins"; trying to
|
||||
# assign to a different group should fail.
|
||||
|
||||
@@ -7,8 +7,8 @@ no warnings 'once';
|
||||
our $module_name;
|
||||
$main::no_acl_check = 1;
|
||||
$main::no_referers_check = 1;
|
||||
$ENV{'WEBMIN_CONFIG'} = "/etc/webmin";
|
||||
$ENV{'WEBMIN_VAR'} = "/var/webmin";
|
||||
$ENV{'WEBMIN_CONFIG'} ||= "/etc/webmin";
|
||||
$ENV{'WEBMIN_VAR'} ||= "/var/webmin";
|
||||
if ($0 =~ /^(.*\/)[^\/]+$/) {
|
||||
chdir($1);
|
||||
}
|
||||
|
||||
@@ -1991,30 +1991,57 @@ return @rv;
|
||||
# or undef.
|
||||
sub test_config
|
||||
{
|
||||
if ($httpd_modules{'core'} >= 1.301) {
|
||||
# Test the configuration with the available command
|
||||
local $cmd;
|
||||
if ($config{'test_apachectl'} &&
|
||||
return undef if ($httpd_modules{'core'} < 1.301);
|
||||
my $okre = qr/(syntax|Checking).*\s+ok/i;
|
||||
|
||||
# Build the httpd command from the configured paths
|
||||
my $httpd = &find_httpd();
|
||||
my $httpdcmd = "\"$httpd\" -d \"$config{'httpd_dir'}\"";
|
||||
if ($config{'httpd_conf'}) {
|
||||
$httpdcmd .= " -f \"$config{'httpd_conf'}\"";
|
||||
}
|
||||
foreach my $d (&get_httpd_defines()) {
|
||||
$httpdcmd .= " -D$d";
|
||||
}
|
||||
|
||||
# Pick the standard test command
|
||||
my ($cmd, $apachectl);
|
||||
if ($config{'test_apachectl'} &&
|
||||
-x &translate_filename($config{'apachectl_path'})) {
|
||||
# Test with apachectl
|
||||
$cmd = "\"$config{'apachectl_path'}\" configtest";
|
||||
# Test with apachectl, which may set up environment the config needs
|
||||
$apachectl = "\"$config{'apachectl_path'}\"";
|
||||
$cmd = "$apachectl configtest";
|
||||
}
|
||||
else {
|
||||
else {
|
||||
# Test with httpd
|
||||
local $httpd = &find_httpd();
|
||||
$cmd = "\"$httpd\" -d \"$config{'httpd_dir'}\" -t";
|
||||
if ($config{'httpd_conf'}) {
|
||||
$cmd .= " -f \"$config{'httpd_conf'}\"";
|
||||
$cmd = "$httpdcmd -t";
|
||||
}
|
||||
foreach $d (&get_httpd_defines()) {
|
||||
$cmd .= " -D$d";
|
||||
|
||||
# Without a global ServerName, Apache looks up the system hostname in DNS
|
||||
# while loading the config, which stalls the test when DNS is slow. So first
|
||||
# try the test with a placeholder ServerName. Apache applies -C directives
|
||||
# before reading the config files, so a ServerName that this check misses,
|
||||
# such as one inside an IfModule section, still takes effect.
|
||||
my $conf = &get_config();
|
||||
if ($conf && !&find_directive("ServerName", $conf)) {
|
||||
my $noname = "-C \"ServerName localhost\"";
|
||||
my $out = &backquote_command(
|
||||
($apachectl ? "$apachectl $noname -t" : "$httpdcmd $noname -t").
|
||||
" 2>&1");
|
||||
if ($apachectl && $httpd && $out =~ /no\s+longer\s+supported/i) {
|
||||
# Red Hat's apachectl refuses extra arguments, and its
|
||||
# configtest just runs httpd -t, so test with httpd instead
|
||||
$out = &backquote_command("$httpdcmd $noname -t 2>&1");
|
||||
}
|
||||
return undef if ($out =~ $okre);
|
||||
}
|
||||
local $out = &backquote_command("$cmd 2>&1");
|
||||
if ($out && $out !~ /(syntax|Checking).*\s+ok/i) {
|
||||
|
||||
# Run the standard test. This also runs when the quick test failed, in case
|
||||
# the extra arguments, rather than the config, caused the failure.
|
||||
my $out = &backquote_command("$cmd 2>&1");
|
||||
if ($out && $out !~ $okre) {
|
||||
return $out;
|
||||
}
|
||||
}
|
||||
return undef;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
show_list=0
|
||||
httpd_path=c:/program files/apache group/apache2/bin/Apache.exe
|
||||
httpd_conf=
|
||||
httpd_dir=c:/program files/apache group/apache2
|
||||
mime_types=
|
||||
srm_conf=
|
||||
access_conf=
|
||||
show_order=0
|
||||
max_servers=100
|
||||
test_config=0
|
||||
test_manual=0
|
||||
test_always=0
|
||||
test_apachectl=0
|
||||
start_cmd=net start apache2
|
||||
stop_cmd=net stop apache2
|
||||
#apply_cmd="c:/program files/apache group/apache2/bin/Apache.exe" -k restart
|
||||
auto_mods=1
|
||||
show_names=0
|
||||
allow_virtualmin=0
|
||||
format_config=1
|
||||
256
apache/t/test-config.t
Normal file
@@ -0,0 +1,256 @@
|
||||
#!/usr/bin/perl
|
||||
# Tests for test_config, which must check the Apache config without waiting
|
||||
# on a DNS lookup of the system hostname.
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use Test::More;
|
||||
use File::Basename qw(dirname);
|
||||
use File::Path qw(make_path);
|
||||
use File::Spec;
|
||||
use File::Temp qw(tempdir);
|
||||
use Cwd qw(abs_path);
|
||||
|
||||
my $root = abs_path(File::Spec->catdir(dirname(__FILE__), '..', '..'));
|
||||
my $tmp = abs_path(tempdir(CLEANUP => 1));
|
||||
my $webmin_config = File::Spec->catdir($tmp, 'webmin-config');
|
||||
my $webmin_var = File::Spec->catdir($tmp, 'webmin-var');
|
||||
my $bin = File::Spec->catdir($tmp, 'bin');
|
||||
my $log = File::Spec->catfile($tmp, 'commands.log');
|
||||
|
||||
# Paths with spaces check that the configured paths are used and quoted
|
||||
my $apache_root = File::Spec->catdir($tmp, 'apache root');
|
||||
my $apache_conf = File::Spec->catfile($apache_root, 'main config.conf');
|
||||
|
||||
make_path($webmin_config, $webmin_var, "$webmin_config/apache",
|
||||
"$webmin_var/apache", $apache_root, $bin);
|
||||
|
||||
# write_text(file, text, [mode])
|
||||
# Writes a file, optionally setting its permissions
|
||||
sub write_text
|
||||
{
|
||||
my ($file, $text, $mode) = @_;
|
||||
open(my $fh, '>', $file) || die "Failed to write $file: $!";
|
||||
print $fh $text;
|
||||
close($fh) || die "Failed to close $file: $!";
|
||||
chmod($mode, $file) || die "Failed to chmod $file: $!" if (defined($mode));
|
||||
}
|
||||
|
||||
# Shell snippet that logs the program name and its arguments, one per field
|
||||
my $log_args = <<'EOF';
|
||||
{ printf '%s' "$FAKE_NAME"; for a in "$@"; do printf '|%s' "$a"; done;
|
||||
printf '\n'; } >> "$FAKE_APACHE_LOG"
|
||||
EOF
|
||||
|
||||
# Fake httpd, which passes or fails the test based on the environment
|
||||
my $httpd = File::Spec->catfile($bin, 'httpd');
|
||||
write_text($httpd, "#!/bin/sh\nFAKE_NAME=httpd\n".$log_args.<<'EOF', 0755);
|
||||
if [ "$FAKE_APACHE_RESULT" = "error" ]; then
|
||||
echo "AH00526: Syntax error on line 2 of test.conf:"
|
||||
echo "Invalid command 'Bogus', perhaps misspelled"
|
||||
exit 1
|
||||
fi
|
||||
echo "Syntax OK"
|
||||
EOF
|
||||
|
||||
# Debian-style apache2ctl, which passes extra arguments to httpd
|
||||
my $debian_ctl = File::Spec->catfile($bin, 'debian-ctl');
|
||||
write_text($debian_ctl,
|
||||
"#!/bin/sh\nFAKE_NAME=apachectl\n".$log_args.<<"EOF", 0755);
|
||||
case "\$*" in
|
||||
configtest) exec "$httpd" -t ;;
|
||||
*) exec "$httpd" "\$@" ;;
|
||||
esac
|
||||
EOF
|
||||
|
||||
# Red Hat-style apachectl, which refuses extra arguments
|
||||
my $redhat_ctl = File::Spec->catfile($bin, 'redhat-ctl');
|
||||
write_text($redhat_ctl,
|
||||
"#!/bin/sh\nFAKE_NAME=apachectl\n".$log_args.<<"EOF", 0755);
|
||||
if [ "x\$2" != "x" ]; then
|
||||
echo "Passing arguments to httpd using apachectl is no longer supported."
|
||||
exit 1
|
||||
fi
|
||||
case "\$1" in
|
||||
configtest|-t) exec "$httpd" -t ;;
|
||||
esac
|
||||
exit 2
|
||||
EOF
|
||||
|
||||
# Wrapper that only understands configtest
|
||||
my $strict_ctl = File::Spec->catfile($bin, 'strict-ctl');
|
||||
write_text($strict_ctl,
|
||||
"#!/bin/sh\nFAKE_NAME=apachectl\n".$log_args.<<"EOF", 0755);
|
||||
case "\$1" in
|
||||
configtest) exec "$httpd" -t ;;
|
||||
esac
|
||||
echo "usage: apachectl configtest"
|
||||
exit 2
|
||||
EOF
|
||||
|
||||
write_text(File::Spec->catfile($webmin_config, 'config'),
|
||||
"os_type=debian-linux\n".
|
||||
"os_version=12\n".
|
||||
"real_os_type=Debian Linux\n".
|
||||
"real_os_version=12\n");
|
||||
write_text(File::Spec->catfile($webmin_config, 'miniserv.conf'),
|
||||
"root=$root\n");
|
||||
write_text(File::Spec->catfile($webmin_config, 'apache', 'config'),
|
||||
"httpd_dir=$apache_root\n".
|
||||
"httpd_path=$httpd\n".
|
||||
"httpd_conf=$apache_conf\n".
|
||||
"apachectl_path=$debian_ctl\n".
|
||||
"httpd_version=2.4.57\n".
|
||||
"test_apachectl=0\n".
|
||||
"test_config=1\n");
|
||||
|
||||
$ENV{'WEBMIN_CONFIG'} = $webmin_config;
|
||||
$ENV{'WEBMIN_VAR'} = $webmin_var;
|
||||
$ENV{'FOREIGN_MODULE_NAME'} = 'apache';
|
||||
$ENV{'FOREIGN_ROOT_DIRECTORY'} = $root;
|
||||
$ENV{'REMOTE_USER'} = 'root';
|
||||
$ENV{'FAKE_APACHE_LOG'} = $log;
|
||||
$ENV{'FAKE_APACHE_RESULT'} = 'ok';
|
||||
|
||||
unshift(@INC, $root);
|
||||
require File::Spec->catfile($root, 'apache', 'apache-lib.pl');
|
||||
|
||||
{
|
||||
no warnings 'once';
|
||||
$main::httpd_modules{'core'} = 2.4;
|
||||
}
|
||||
|
||||
# set_apache_conf(text)
|
||||
# Writes the main Apache config file and clears the cached copy
|
||||
sub set_apache_conf
|
||||
{
|
||||
my ($text) = @_;
|
||||
write_text($apache_conf, $text);
|
||||
main::flush_config_cache();
|
||||
}
|
||||
|
||||
# A ServerName inside a virtual host is not global, so Apache still looks up
|
||||
# the system hostname
|
||||
my $no_global_name = "Listen 80\n".
|
||||
"<VirtualHost *:80>\n".
|
||||
" ServerName vhost.example\n".
|
||||
"</VirtualHost>\n";
|
||||
set_apache_conf($no_global_name);
|
||||
|
||||
# Expected log lines for the fake commands
|
||||
my $noname = 'ServerName localhost';
|
||||
my $direct_fast = join('|', 'httpd', '-d', $apache_root, '-f', $apache_conf,
|
||||
'-C', $noname, '-t');
|
||||
my $direct_std = join('|', 'httpd', '-d', $apache_root, '-f', $apache_conf,
|
||||
'-t');
|
||||
my $ctl_fast = join('|', 'apachectl', '-C', $noname, '-t');
|
||||
my $ctl_std = 'apachectl|configtest';
|
||||
my $httpd_fast = join('|', 'httpd', '-C', $noname, '-t');
|
||||
my $httpd_std = 'httpd|-t';
|
||||
|
||||
# run_test(test-apachectl, [apachectl-path], result)
|
||||
# Runs test_config with the given settings, and returns its result and the
|
||||
# commands it ran
|
||||
sub run_test
|
||||
{
|
||||
my ($use_ctl, $ctl, $result) = @_;
|
||||
no warnings 'once';
|
||||
$main::config{'test_apachectl'} = $use_ctl;
|
||||
$main::config{'apachectl_path'} = $ctl if ($ctl);
|
||||
$ENV{'FAKE_APACHE_RESULT'} = $result;
|
||||
unlink($log);
|
||||
my $err = main::test_config();
|
||||
my @cmds;
|
||||
if (open(my $fh, '<', $log)) {
|
||||
chomp(@cmds = <$fh>);
|
||||
close($fh);
|
||||
}
|
||||
return ($err, \@cmds);
|
||||
}
|
||||
|
||||
subtest 'httpd test skips the hostname lookup' => sub {
|
||||
my ($err, $cmds) = run_test(0, undef, 'ok');
|
||||
is($err, undef, 'valid config passes');
|
||||
is_deeply($cmds, [ $direct_fast ],
|
||||
'httpd runs once with configured paths and ServerName');
|
||||
};
|
||||
|
||||
subtest 'httpd test reports config errors' => sub {
|
||||
my ($err, $cmds) = run_test(0, undef, 'error');
|
||||
like($err, qr/Syntax error on line 2/, 'error output is returned');
|
||||
is_deeply($cmds, [ $direct_fast, $direct_std ],
|
||||
'failure is confirmed with the standard test');
|
||||
};
|
||||
|
||||
subtest 'Debian apachectl passes ServerName to httpd' => sub {
|
||||
my ($err, $cmds) = run_test(1, $debian_ctl, 'ok');
|
||||
is($err, undef, 'valid config passes');
|
||||
is_deeply($cmds, [ $ctl_fast, $httpd_fast ],
|
||||
'apachectl runs httpd with the placeholder ServerName');
|
||||
};
|
||||
|
||||
subtest 'Debian apachectl reports config errors' => sub {
|
||||
my ($err, $cmds) = run_test(1, $debian_ctl, 'error');
|
||||
like($err, qr/Syntax error on line 2/, 'error output is returned');
|
||||
is_deeply($cmds, [ $ctl_fast, $httpd_fast, $ctl_std, $httpd_std ],
|
||||
'failure is confirmed with apachectl configtest');
|
||||
};
|
||||
|
||||
subtest 'Red Hat apachectl falls back to httpd' => sub {
|
||||
my ($err, $cmds) = run_test(1, $redhat_ctl, 'ok');
|
||||
is($err, undef, 'valid config passes');
|
||||
is_deeply($cmds, [ $ctl_fast, $direct_fast ],
|
||||
'httpd is run directly when apachectl refuses arguments');
|
||||
};
|
||||
|
||||
subtest 'Red Hat apachectl reports config errors' => sub {
|
||||
my ($err, $cmds) = run_test(1, $redhat_ctl, 'error');
|
||||
like($err, qr/Syntax error on line 2/, 'error output is returned');
|
||||
unlike($err, qr/no longer supported/,
|
||||
'apachectl refusal is not reported as a config error');
|
||||
is_deeply($cmds, [ $ctl_fast, $direct_fast, $ctl_std, $httpd_std ],
|
||||
'failure is confirmed with apachectl configtest');
|
||||
};
|
||||
|
||||
subtest 'unknown apachectl falls back to configtest' => sub {
|
||||
my ($err, $cmds) = run_test(1, $strict_ctl, 'ok');
|
||||
is($err, undef, 'valid config passes');
|
||||
is_deeply($cmds, [ $ctl_fast, $ctl_std, $httpd_std ],
|
||||
'standard test runs when apachectl rejects the arguments');
|
||||
};
|
||||
|
||||
subtest 'global ServerName uses only the standard test' => sub {
|
||||
set_apache_conf("ServerName www.example.com\n".$no_global_name);
|
||||
my ($err, $cmds) = run_test(0, undef, 'ok');
|
||||
is($err, undef, 'valid config passes');
|
||||
is_deeply($cmds, [ $direct_std ], 'httpd runs without a placeholder');
|
||||
|
||||
($err, $cmds) = run_test(1, $redhat_ctl, 'error');
|
||||
like($err, qr/Syntax error on line 2/, 'error output is returned');
|
||||
is_deeply($cmds, [ $ctl_std, $httpd_std ],
|
||||
'apachectl configtest runs as before');
|
||||
set_apache_conf($no_global_name);
|
||||
};
|
||||
|
||||
subtest 'global ServerName in an included file is found' => sub {
|
||||
# Webmin expands includes with glob(), which splits paths on spaces
|
||||
my $inc = File::Spec->catfile($tmp, 'servername.conf');
|
||||
write_text($inc, "ServerName www.example.com\n");
|
||||
set_apache_conf("Include $inc\n".$no_global_name);
|
||||
my ($err, $cmds) = run_test(1, $debian_ctl, 'ok');
|
||||
is($err, undef, 'valid config passes');
|
||||
is_deeply($cmds, [ $ctl_std, $httpd_std ],
|
||||
'apachectl configtest runs as before');
|
||||
unlink($inc);
|
||||
set_apache_conf($no_global_name);
|
||||
};
|
||||
|
||||
subtest 'old Apache versions are not tested' => sub {
|
||||
no warnings 'once';
|
||||
local $main::httpd_modules{'core'} = 1.3;
|
||||
my ($err, $cmds) = run_test(0, undef, 'error');
|
||||
is($err, undef, 'no error is reported');
|
||||
is_deeply($cmds, [ ], 'no test command runs');
|
||||
};
|
||||
|
||||
done_testing();
|
||||
@@ -1,12 +0,0 @@
|
||||
driver=Pg
|
||||
user=bacula
|
||||
pass=opencountry
|
||||
db=bacula
|
||||
bacula_dir=c:/bacula/bin
|
||||
bextract=bextract
|
||||
bls=bls
|
||||
btape=btape
|
||||
wait=1
|
||||
apply=1
|
||||
showdirs=0
|
||||
init_start=0
|
||||
@@ -1,61 +0,0 @@
|
||||
soa_style=1
|
||||
named_path=c:/windows/system32/dns/bin/named.exe
|
||||
named_conf=c:/windows/system32/dns/etc/named.conf
|
||||
show_list=1
|
||||
records_order=0
|
||||
max_zones=50
|
||||
rev_def=0
|
||||
support_aaaa=1
|
||||
allow_comments=0
|
||||
allow_wild=1
|
||||
allow_long=0
|
||||
master_ttl=1
|
||||
whois_cmd=c:/windows/system32/dns/bin/whois.exe
|
||||
short_names=0
|
||||
updserial_def=0
|
||||
updserial_on=1
|
||||
updserial_man=1
|
||||
ndc_cmd=c:/windows/system32/dns/bin/ndc.exe
|
||||
forwardzonefilename_format=ZONE.hosts
|
||||
reversezonefilename_format=ZONE.rev
|
||||
rev_must=0
|
||||
ipv6_mode=1
|
||||
allow_underscore=0
|
||||
by_view=0
|
||||
confirm_zone=1
|
||||
confirm_rec=0
|
||||
no_chroot=0
|
||||
relative_paths=0
|
||||
rndc_cmd=c:/windows/system32/dns/bin/rndc.exe
|
||||
no_pid_chroot=0
|
||||
soa_start=0
|
||||
rndc_conf=c:/windows/system32/dns/etc/rndc.conf
|
||||
rndcconf_cmd=c:/windows/system32/dns/bin/rndc-confgen.exe
|
||||
largezones=0
|
||||
auto_chroot=
|
||||
pid_file=c:/windows/system32/dns/etc/named.pid
|
||||
default_prins=
|
||||
restart_cmd=sc restart named
|
||||
file_perms=
|
||||
extra_reverse=
|
||||
default_master=
|
||||
master_dir=
|
||||
chroot=
|
||||
file_owner=
|
||||
named_group=
|
||||
this_ip=
|
||||
stop_cmd=sc stop named
|
||||
named_user=
|
||||
free_nets=
|
||||
start_cmd=sc start named
|
||||
zones_file=
|
||||
extra_forward=
|
||||
slave_dir=
|
||||
keygen=dnssec-keygen
|
||||
signzone=dnssec-signzone
|
||||
checkconf=named-checkconf
|
||||
other_slaves=1
|
||||
force_random=0
|
||||
spf_record=0
|
||||
dnssec_info=1
|
||||
allow_alias=0
|
||||
@@ -48,6 +48,10 @@ print &ui_table_row($text{'acl_move'},
|
||||
&ui_radio("move", $_[0]->{'move'},
|
||||
[ [ 1, $text{'yes'} ], [ 0, $text{'no'} ] ]));
|
||||
|
||||
print &ui_table_row($text{'acl_env'},
|
||||
&ui_radio("env", $_[0]->{'env'},
|
||||
[ [ 1, $text{'yes'} ], [ 0, $text{'no'} ] ]));
|
||||
|
||||
print &ui_table_row($text{'acl_kill'},
|
||||
&ui_radio("kill", $_[0]->{'kill'},
|
||||
[ [ 1, $text{'yes'} ], [ 0, $text{'no'} ] ]));
|
||||
@@ -79,6 +83,7 @@ $_[0]->{'command'} = $in{'command'};
|
||||
$_[0]->{'create'} = $in{'create'};
|
||||
$_[0]->{'delete'} = $in{'delete'};
|
||||
$_[0]->{'move'} = $in{'move'};
|
||||
$_[0]->{'env'} = $in{'env'};
|
||||
$_[0]->{'kill'} = $in{'kill'};
|
||||
$_[0]->{'hourly'} = $in{'hourly'};
|
||||
$_[0]->{'stop'} = $in{'stop'};
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
cron_input=0
|
||||
vixie_cron=0
|
||||
cron_deny_all=2
|
||||
max_len=80
|
||||
show_run=0
|
||||
show_time=0
|
||||
match_mode=0
|
||||
match_user=1
|
||||
kill_subs=0
|
||||
single_file=c:/cronw/crontab.txt
|
||||
show_comment=0
|
||||
hourly_only=0
|
||||
max_jobs=400
|
||||
show_next=0
|
||||
@@ -1079,6 +1079,8 @@ if ($in{'special_def'}) {
|
||||
foreach $arr (@pers) {
|
||||
delete($job->{$arr});
|
||||
}
|
||||
# Special times are single words like daily or reboot
|
||||
$in{'special'} =~ /^[a-z]+$/i || &error($text{'save_especial'});
|
||||
$job->{'special'} = $in{'special'};
|
||||
}
|
||||
else {
|
||||
@@ -1092,6 +1094,11 @@ else {
|
||||
# Need to work out and simplify ranges selected
|
||||
local (@range, @newrange, $i);
|
||||
@range = split(/\0/, $in{$arr});
|
||||
# Selected times are plain numbers
|
||||
foreach my $v (@range) {
|
||||
$v =~ /^\d+$/ || &error(&text('save_etime',
|
||||
$text{"edit_$arr"}));
|
||||
}
|
||||
@range = sort { $a <=> $b } @range;
|
||||
local $start = -1;
|
||||
for($i=0; $i<@range; $i++) {
|
||||
@@ -1168,6 +1175,11 @@ if ($in->{'range_def'}) {
|
||||
else {
|
||||
# Validate and store range
|
||||
foreach my $r ("start", "end") {
|
||||
# Dates go into the job's command, so only allow numbers
|
||||
foreach my $f ("day", "month", "year") {
|
||||
$in->{'range_'.$r.'_'.$f} =~ /^\d+$/ ||
|
||||
&error($text{'range_e'.$r});
|
||||
}
|
||||
eval { timelocal(0, 0, 0, $in->{'range_'.$r.'_day'},
|
||||
$in->{'range_'.$r.'_month'}-1,
|
||||
$in->{'range_'.$r.'_year'}-1900) };
|
||||
@@ -1308,6 +1320,43 @@ elsif ($config{cron_deny_all} == 1) {
|
||||
return !$err;
|
||||
}
|
||||
|
||||
=head2 get_cron_move_target(\@jobs, index, direction)
|
||||
|
||||
Returns the Cron entry that the indexed entry would be swapped with for an up,
|
||||
down, top or bottom move.
|
||||
|
||||
=cut
|
||||
sub get_cron_move_target
|
||||
{
|
||||
my ($jobs, $idx, $direction) = @_;
|
||||
my $job = $jobs->[$idx];
|
||||
return if (!$job);
|
||||
|
||||
if ($direction eq "up") {
|
||||
return $idx > 0 ? $jobs->[$idx-1] : undef;
|
||||
}
|
||||
elsif ($direction eq "down") {
|
||||
return $idx < $#$jobs ? $jobs->[$idx+1] : undef;
|
||||
}
|
||||
elsif ($direction eq "top") {
|
||||
my $swap;
|
||||
for(my $i=$idx-1;
|
||||
$i >= 0 && $jobs->[$i]->{'file'} eq $job->{'file'}; $i--) {
|
||||
$swap = $jobs->[$i];
|
||||
}
|
||||
return $swap;
|
||||
}
|
||||
elsif ($direction eq "bottom") {
|
||||
my $swap;
|
||||
for(my $i=$idx+1;
|
||||
$i < @$jobs && $jobs->[$i]->{'file'} eq $job->{'file'}; $i++) {
|
||||
$swap = $jobs->[$i];
|
||||
}
|
||||
return $swap;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
=head2 swap_cron_jobs(&job1, &job2)
|
||||
|
||||
Swaps two Cron jobs, which must be in the same file, identified by their
|
||||
|
||||
@@ -6,6 +6,7 @@ command=1
|
||||
create=1
|
||||
delete=1
|
||||
move=1
|
||||
env=1
|
||||
kill=1
|
||||
hourly=2
|
||||
stop=1
|
||||
|
||||
@@ -6,9 +6,10 @@ require './cron-lib.pl';
|
||||
&ReadParse();
|
||||
@jobs = &list_cron_jobs();
|
||||
$job = $jobs[$in{'idx'}];
|
||||
&lock_file($job->{'file'});
|
||||
$job && !$job->{'name'} || &error($text{'edit_egone'});
|
||||
$access{'delete'} && &can_edit_user(\%access, $job->{'user'}) ||
|
||||
&error($text{'edit_ecannot'});
|
||||
&lock_file($job->{'file'});
|
||||
&delete_cron_job($job);
|
||||
&unlock_file($job->{'file'});
|
||||
&webmin_log("delete", "cron", $job->{'user'}, $job);
|
||||
|
||||
@@ -4,11 +4,13 @@
|
||||
|
||||
require './cron-lib.pl';
|
||||
&ReadParse();
|
||||
$access{'env'} || &error($text{'env_ecannot'});
|
||||
@jobs = &list_cron_jobs();
|
||||
$job = $jobs[$in{'idx'}];
|
||||
&lock_file($job->{'file'});
|
||||
&can_edit_user(\%access, $job->{'user'}) ||
|
||||
$job && $job->{'name'} || &error($text{'env_egone'});
|
||||
$access{'delete'} && &can_edit_user(\%access, $job->{'user'}) ||
|
||||
&error($text{'edit_ecannot'});
|
||||
&lock_file($job->{'file'});
|
||||
&delete_cron_job($job);
|
||||
&unlock_file($job->{'file'});
|
||||
&webmin_log("delete", "env", $job->{'user'}, $job);
|
||||
|
||||
@@ -9,13 +9,20 @@ require './cron-lib.pl';
|
||||
@d || &error($text{'delete_enone'});
|
||||
|
||||
if ($in{'delete'}) {
|
||||
# Delete selected jobs
|
||||
# Validate all selected jobs before changing any of them
|
||||
@selected = ( );
|
||||
foreach $d (sort { $b <=> $a } @d) {
|
||||
($job) = grep { $_->{'index'} eq $d } @jobs;
|
||||
$job || next;
|
||||
&lock_file($job->{'file'});
|
||||
!$job->{'name'} || $access{'env'} ||
|
||||
&error($text{'env_ecannot'});
|
||||
$access{'delete'} && &can_edit_user(\%access, $job->{'user'}) ||
|
||||
&error($text{'edit_ecannot'});
|
||||
push(@selected, $job);
|
||||
}
|
||||
# Delete selected jobs
|
||||
foreach $job (@selected) {
|
||||
&lock_file($job->{'file'});
|
||||
&delete_cron_job($job);
|
||||
@jobs = grep { $_ ne $job } @jobs;
|
||||
}
|
||||
@@ -23,13 +30,20 @@ if ($in{'delete'}) {
|
||||
&webmin_log("delete", "crons", scalar(@d));
|
||||
}
|
||||
elsif ($in{'disable'} || $in{'enable'}) {
|
||||
# Disable selected
|
||||
# Validate all selected jobs before changing any of them
|
||||
@selected = ( );
|
||||
foreach $d (@d) {
|
||||
($job) = grep { $_->{'index'} eq $d } @jobs;
|
||||
$job || next;
|
||||
&lock_file($job->{'file'});
|
||||
!$job->{'name'} || $access{'env'} ||
|
||||
&error($text{'env_ecannot'});
|
||||
&can_edit_user(\%access, $job->{'user'}) ||
|
||||
&error($text{'edit_ecannot'});
|
||||
push(@selected, $job);
|
||||
}
|
||||
# Enable or disable selected jobs
|
||||
foreach $job (@selected) {
|
||||
&lock_file($job->{'file'});
|
||||
$job->{'active'} = $in{'disable'} ? 0 : 1;
|
||||
&change_cron_job($job);
|
||||
@jobs = grep { $_ ne $job } @jobs;
|
||||
|
||||
@@ -8,7 +8,7 @@ require './cron-lib.pl';
|
||||
|
||||
if (!$in{'new'}) {
|
||||
$job = $jobs[$in{'idx'}];
|
||||
$job || &error($text{'edit_egone'});
|
||||
$job && !$job->{'name'} || &error($text{'edit_egone'});
|
||||
&can_edit_user(\%access, $job->{'user'}) ||
|
||||
&error($text{'edit_ecannot'});
|
||||
&ui_print_header(undef, $text{'edit_title'}, "");
|
||||
@@ -18,7 +18,7 @@ else {
|
||||
if (defined($in{'clone'})) {
|
||||
# Default to clone source
|
||||
$clone = $jobs[$in{'clone'}];
|
||||
$clone || &error($text{'edit_egone'});
|
||||
$clone && !$clone->{'name'} || &error($text{'edit_egone'});
|
||||
&can_edit_user(\%access, $clone->{'user'}) ||
|
||||
&error($text{'edit_ecannot'});
|
||||
$job = { %$clone };
|
||||
|
||||
@@ -4,15 +4,18 @@
|
||||
|
||||
require './cron-lib.pl';
|
||||
&ReadParse();
|
||||
$access{'env'} || &error($text{'env_ecannot'});
|
||||
|
||||
if (!$in{'new'}) {
|
||||
@jobs = &list_cron_jobs();
|
||||
$env = $jobs[$in{'idx'}];
|
||||
$env && $env->{'name'} || &error($text{'env_egone'});
|
||||
&can_edit_user(\%access, $env->{'user'}) ||
|
||||
&error($text{'edit_ecannot'});
|
||||
&ui_print_header(undef, $text{'env_title1'}, "");
|
||||
}
|
||||
else {
|
||||
$access{'create'} || &error($text{'save_ecannot2'});
|
||||
&ui_print_header(undef, $text{'env_title2'}, "");
|
||||
$env = { 'active' => 1 };
|
||||
}
|
||||
@@ -68,8 +71,9 @@ if ($in{'new'}) {
|
||||
print &ui_form_end([ [ undef, $text{'create'} ] ]);
|
||||
}
|
||||
else {
|
||||
print &ui_form_end([ [ undef, $text{'save'} ],
|
||||
[ "delete", $text{'delete'} ] ]);
|
||||
my @buttons = ( [ undef, $text{'save'} ] );
|
||||
push(@buttons, [ "delete", $text{'delete'} ]) if ($access{'delete'});
|
||||
print &ui_form_end(\@buttons);
|
||||
}
|
||||
|
||||
&ui_print_footer("", $text{'index_return'});
|
||||
|
||||
@@ -7,6 +7,7 @@ require './cron-lib.pl';
|
||||
|
||||
@jobs = &list_cron_jobs();
|
||||
$job = $jobs[$in{'idx'}];
|
||||
$job && !$job->{'name'} || &error($text{'edit_egone'});
|
||||
&can_edit_user(\%access, $job->{'user'}) || &error($text{'exec_ecannot'});
|
||||
&foreign_require("proc", "proc-lib.pl");
|
||||
|
||||
|
||||
@@ -52,7 +52,8 @@ if ($access{'create'}) {
|
||||
$text{'index_create'}) );
|
||||
push(@crlinks, &ui_link("edit_env.cgi?new=1&search=".
|
||||
&urlize($in{'search'}),
|
||||
$text{'index_ecreate'}) ) if ($env_support);
|
||||
$text{'index_ecreate'}) )
|
||||
if ($env_support && $access{'env'});
|
||||
}
|
||||
if ($config{cron_allow_file} && $config{cron_deny_file} && $access{'allow'}) {
|
||||
push(@crlinks, &ui_link("edit_allow.cgi", $text{'index_allow'}) );
|
||||
@@ -106,9 +107,11 @@ foreach $u (@ulist) {
|
||||
if ($job->{'name'}) {
|
||||
# An environment variable - show the name only
|
||||
$cmdidx = scalar(@cols);
|
||||
push(@cols, &ui_link("edit_env.cgi?idx=".$idx,
|
||||
"<i>$text{'index_env'}</i> ".
|
||||
"<tt>@{[&html_escape($job->{'name'})]} = @{[&html_escape($job->{'value'})]}</tt>") );
|
||||
local $envdesc = "<i>$text{'index_env'}</i> ".
|
||||
"<tt>@{[&html_escape($job->{'name'})]} = @{[&html_escape($job->{'value'})]}</tt>";
|
||||
push(@cols, $access{'env'} ?
|
||||
&ui_link("edit_env.cgi?idx=".$idx, $envdesc) :
|
||||
$envdesc);
|
||||
$donelink = 1;
|
||||
}
|
||||
elsif (@exp && $access{'command'}) {
|
||||
@@ -219,6 +222,7 @@ foreach $u (@ulist) {
|
||||
push(@cols, $job->{'command'}.' '.$job->{'name'}.' '.
|
||||
$job->{'comment'});
|
||||
push(@rows, \@cols);
|
||||
$noenv{$idx}++ if ($job->{'name'} && !$access{'env'});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -264,8 +268,10 @@ elsif (@rows) {
|
||||
$access{'move'} ? ( $text{'index_move'} ) : ( ),
|
||||
], 100, 0, \@tds);
|
||||
foreach my $r (@rows) {
|
||||
# Variables cannot be selected without permission to edit them
|
||||
print &ui_checked_columns_row([ @$r[1..(@$r-2)] ],
|
||||
\@tds, "d", $r->[0]);
|
||||
\@tds, "d", $r->[0], 0,
|
||||
$noenv{$r->[0]});
|
||||
}
|
||||
print &ui_columns_end();
|
||||
print &ui_links_row(\@links);
|
||||
|
||||
@@ -7,6 +7,7 @@ require './cron-lib.pl';
|
||||
|
||||
@jobs = &list_cron_jobs();
|
||||
$job = $jobs[$in{'idx'}];
|
||||
$job && !$job->{'name'} || &error($text{'edit_egone'});
|
||||
&can_edit_user(\%access, $job->{'user'}) || &error($text{'kill_ecannot'});
|
||||
$proc = &find_cron_process($job);
|
||||
$proc || &error($text{'kill_egone'});
|
||||
|
||||
@@ -81,6 +81,11 @@ lcedit_special_reboot=when system boots
|
||||
|
||||
save_err=Failed to save cron job
|
||||
save_ecmd=You did not enter a command to execute
|
||||
save_enewline=The command and comment cannot contain line breaks
|
||||
save_especial=Invalid special time selected
|
||||
save_etime=Invalid $1 selected
|
||||
save_ename=Missing or invalid environment variable name
|
||||
save_evalue=Invalid environment variable value
|
||||
save_euser=You must select a user
|
||||
save_euser2=User '$1' does not exist
|
||||
save_eallow=The user '$1' is not allowed to access cron
|
||||
@@ -88,6 +93,7 @@ save_ecannot=You are not allowed to create or edit cron jobs for '$1'
|
||||
save_enone=You did not choose any $1 to execute
|
||||
save_ecannot2=You are not allowed to create cron jobs
|
||||
save_eidx=Cron job was successfully saved, but cannot be run as it was not found!
|
||||
save_ecomment=Invalid characters in comment
|
||||
|
||||
allow_title=Control Cron Access
|
||||
allow_desc=This form allows you to control which users can create and run cron jobs.
|
||||
@@ -113,6 +119,8 @@ env_where2=Move environment variable
|
||||
env_top=Before all Cron jobs for user
|
||||
env_bot=After all Cron jobs
|
||||
env_leave=Current position
|
||||
env_ecannot=You are not allowed to edit environment variables
|
||||
env_egone=Environment variable does not exist
|
||||
|
||||
exec_title=Execute Cron Job
|
||||
exec_ecannot=You are not allowed to execute cron jobs for this user
|
||||
@@ -132,6 +140,7 @@ acl_gid=Users with primary group
|
||||
acl_create=Can create Cron jobs?
|
||||
acl_delete=Can delete Cron jobs?
|
||||
acl_move=Can move Cron jobs?
|
||||
acl_env=Can edit environment variables?
|
||||
acl_kill=Can terminate Cron jobs?
|
||||
acl_hourly=Limit jobs to at most hourly?
|
||||
acl_hourlydef=As set in Module Config
|
||||
|
||||
@@ -8,35 +8,32 @@ require './cron-lib.pl';
|
||||
|
||||
@jobs = &list_cron_jobs();
|
||||
$job = $jobs[$in{'idx'}];
|
||||
$job || &error($text{'edit_egone'});
|
||||
if ($in{'up'}) {
|
||||
$swap = $jobs[$in{'idx'}-1];
|
||||
$direction = "up";
|
||||
}
|
||||
elsif ($in{'down'}) {
|
||||
$swap = $jobs[$in{'idx'}+1];
|
||||
$direction = "down";
|
||||
}
|
||||
elsif ($in{'top'}) {
|
||||
for(my $i=$in{'idx'};
|
||||
$i && $jobs[$i]->{'file'} eq $job->{'file'}; $i--) {
|
||||
$swap = $jobs[$i];
|
||||
}
|
||||
$direction = "top";
|
||||
}
|
||||
elsif ($in{'bottom'}) {
|
||||
for(my $i=$in{'idx'};
|
||||
$i < @jobs && $jobs[$i]->{'file'} eq $job->{'file'}; $i++) {
|
||||
$swap = $jobs[$i];
|
||||
}
|
||||
$direction = "bottom";
|
||||
}
|
||||
else {
|
||||
&error("Unknown mode!");
|
||||
}
|
||||
$swap = &get_cron_move_target(\@jobs, $in{'idx'}, $direction);
|
||||
$swap || &error("No job to swap with found");
|
||||
$access{'move'} && &can_edit_user(\%access, $job->{'user'}) ||
|
||||
&error(&text('save_ecannot', $job->{'user'}));
|
||||
&can_edit_user(\%access, $swap->{'user'}) ||
|
||||
&error(&text('save_ecannot', $swap->{'user'}));
|
||||
$job->{'file'} eq $swap->{'file'} &&
|
||||
($job->{'type'} == 0 || $job->{'type'} == 3) &&
|
||||
($swap->{'type'} == 0 || $swap->{'type'} == 3) || &error($text{'move_etype'});
|
||||
($job->{'name'} || $job->{'type'} == 0 || $job->{'type'} == 3) &&
|
||||
($swap->{'name'} || $swap->{'type'} == 0 || $swap->{'type'} == 3) ||
|
||||
&error($text{'move_etype'});
|
||||
&lock_file($job->{'file'});
|
||||
&swap_cron_jobs($job, $swap);
|
||||
&unlock_file($job->{'file'});
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
stop=0
|
||||
env=0
|
||||
|
||||
@@ -4,5 +4,6 @@ command=1
|
||||
create=1
|
||||
delete=1
|
||||
move=1
|
||||
env=0
|
||||
kill=1
|
||||
hourly=0
|
||||
|
||||
@@ -13,6 +13,7 @@ if ($in{'new'}) {
|
||||
}
|
||||
else {
|
||||
$oldjob = $jobs[$in{'idx'}];
|
||||
$oldjob && !$oldjob->{'name'} || &error($text{'edit_egone'});
|
||||
$job->{'type'} = $oldjob->{'type'};
|
||||
$job->{'file'} = $oldjob->{'file'};
|
||||
$job->{'line'} = $oldjob->{'line'};
|
||||
@@ -37,6 +38,10 @@ foreach $f (@files) { &lock_file($f); }
|
||||
if ($in{"cmd"} !~ /\S/ && $access{'command'}) {
|
||||
&error($text{'save_ecmd'});
|
||||
}
|
||||
# A line break would add extra lines to the crontab
|
||||
if ($in{'cmd'} =~ /[\r\n]/ || $in{'comment'} =~ /[\r\n]/) {
|
||||
&error($text{'save_enewline'});
|
||||
}
|
||||
if (&supports_users()) {
|
||||
if (!$in{'user'}) {
|
||||
&error($text{'save_euser'});
|
||||
@@ -70,6 +75,7 @@ if (defined($in{'range_def'})) {
|
||||
&unconvert_range($job);
|
||||
}
|
||||
|
||||
$in{'comment'} =~ /\r|\n/ && &error($text{'save_ecomment'});
|
||||
$job->{'comment'} = $in{'comment'};
|
||||
&unconvert_comment($job);
|
||||
|
||||
|
||||
@@ -5,13 +5,16 @@
|
||||
require './cron-lib.pl';
|
||||
&error_setup($text{'env_err'});
|
||||
&ReadParse();
|
||||
$access{'env'} || &error($text{'env_ecannot'});
|
||||
|
||||
@jobs = &list_cron_jobs();
|
||||
if ($in{'new'}) {
|
||||
$access{'create'} || &error($text{'save_ecannot2'});
|
||||
$job = { };
|
||||
}
|
||||
else {
|
||||
$oldjob = $jobs[$in{'idx'}];
|
||||
$oldjob && $oldjob->{'name'} || &error($text{'env_egone'});
|
||||
$job->{'file'} = $oldjob->{'file'};
|
||||
$job->{'line'} = $oldjob->{'line'};
|
||||
}
|
||||
@@ -38,6 +41,9 @@ foreach $f (@files) { &lock_file($f); }
|
||||
if ($in{'name'} !~ /^\S+$/) {
|
||||
&error($text{'save_ename'});
|
||||
}
|
||||
if ($in{'value'} =~ /\r|\n/) {
|
||||
&error($text{'save_evalue'});
|
||||
}
|
||||
if (!$in{'user'}) {
|
||||
&error($text{'save_euser'});
|
||||
}
|
||||
|
||||
299
cron/t/run-tests.t
Normal file
@@ -0,0 +1,299 @@
|
||||
#!/usr/bin/perl
|
||||
use strict;
|
||||
use warnings;
|
||||
use Test::More;
|
||||
use Cwd qw(abs_path);
|
||||
use File::Path qw(make_path);
|
||||
use File::Temp qw(tempdir);
|
||||
use IPC::Open3 ();
|
||||
use Symbol qw(gensym);
|
||||
|
||||
my $bindir = abs_path($0);
|
||||
$bindir =~ s{/[^/]+$}{};
|
||||
my $rootdir = abs_path("$bindir/../..") or die "rootdir: $!";
|
||||
my $confdir = tempdir(CLEANUP => 1);
|
||||
my $vardir = tempdir(CLEANUP => 1);
|
||||
|
||||
open(my $cfh, ">", "$confdir/config") or die "config: $!";
|
||||
print $cfh "os_type=generic-linux\nos_version=0\n";
|
||||
close($cfh);
|
||||
open(my $vfh, ">", "$confdir/var-path") or die "var-path: $!";
|
||||
print $vfh "$vardir\n";
|
||||
close($vfh);
|
||||
make_path("$confdir/cron");
|
||||
my $miniservconf = "$confdir/miniserv.conf";
|
||||
open(my $mfh, ">", $miniservconf) or die "miniserv.conf: $!";
|
||||
print $mfh "root=$rootdir\n";
|
||||
close($mfh);
|
||||
|
||||
$ENV{'WEBMIN_CONFIG'} = $confdir;
|
||||
$ENV{'WEBMIN_VAR'} = $vardir;
|
||||
$ENV{'FOREIGN_MODULE_NAME'} = 'cron';
|
||||
$ENV{'FOREIGN_ROOT_DIRECTORY'} = $rootdir;
|
||||
|
||||
chdir("$rootdir/cron") or die "chdir: $!";
|
||||
require "$rootdir/cron/cron-lib.pl";
|
||||
|
||||
my $other = "/tmp/other-crontab";
|
||||
my $file = "/tmp/test-crontab";
|
||||
my @jobs = (
|
||||
{ 'index' => 0, 'file' => $other, 'type' => 0 },
|
||||
{ 'index' => 1, 'file' => $file, 'type' => 0 },
|
||||
{ 'index' => 2, 'file' => $file, 'type' => 0 },
|
||||
{ 'index' => 3, 'file' => $file, 'name' => 'PATH' },
|
||||
{ 'index' => 4, 'file' => $file, 'type' => 0 },
|
||||
{ 'index' => 5, 'file' => $file, 'type' => 0 },
|
||||
{ 'index' => 6, 'file' => $other, 'type' => 0 },
|
||||
);
|
||||
my @leading_jobs = (
|
||||
{ 'index' => 0, 'file' => $file, 'type' => 0 },
|
||||
{ 'index' => 1, 'file' => $file, 'type' => 0 },
|
||||
);
|
||||
|
||||
is(get_cron_move_target(\@jobs, 4, "up"), $jobs[3],
|
||||
"up targets the previous entry");
|
||||
is(get_cron_move_target(\@jobs, 2, "down"), $jobs[3],
|
||||
"down targets the next entry");
|
||||
is(get_cron_move_target(\@jobs, 5, "top"), $jobs[1],
|
||||
"top targets the first entry in the same file");
|
||||
is(get_cron_move_target(\@leading_jobs, 1, "top"), $leading_jobs[0],
|
||||
"top can target the first entry in the full list");
|
||||
is(get_cron_move_target(\@jobs, 1, "bottom"), $jobs[5],
|
||||
"bottom targets the last entry in the same file");
|
||||
is(get_cron_move_target(\@jobs, 1, "up"), $jobs[0],
|
||||
"up returns an entry from another file for caller validation");
|
||||
is(get_cron_move_target(\@jobs, 0, "top"), undef,
|
||||
"top has no target for the first entry");
|
||||
is(get_cron_move_target(\@jobs, 5, "bottom"), undef,
|
||||
"bottom has no target for the last entry in a file");
|
||||
|
||||
my $cronfile = "$vardir/crontab";
|
||||
my $crondir = "$vardir/crontabs";
|
||||
make_path($crondir);
|
||||
make_path("$vardir/cron.d");
|
||||
|
||||
# Write the Cron module config, with the given lines added.
|
||||
sub write_cron_config
|
||||
{
|
||||
my (@lines) = @_;
|
||||
open(my $fh, ">", "$confdir/cron/config") or die "cron config: $!";
|
||||
print $fh map { "$_\n" } (@lines,
|
||||
"cron_dir=$crondir",
|
||||
"system_crontab=$vardir/system-crontab",
|
||||
"cronfiles_dir=$vardir/cron.d",
|
||||
"vixie_cron=1",
|
||||
"cron_deny_all=2");
|
||||
close($fh);
|
||||
}
|
||||
write_cron_config("single_file=$cronfile");
|
||||
|
||||
# Reset the crontab fixture to its original contents.
|
||||
sub write_crontab
|
||||
{
|
||||
open(my $fh, ">", $cronfile) or die "crontab: $!";
|
||||
print $fh "* * * * * echo first\n";
|
||||
print $fh "* * * * * echo second\n";
|
||||
print $fh "PATH=/usr/bin\n";
|
||||
print $fh "* * * * * echo third\n";
|
||||
print $fh "* * * * * echo fourth\n";
|
||||
close($fh);
|
||||
}
|
||||
|
||||
# Return the current crontab fixture contents.
|
||||
sub read_crontab_fixture
|
||||
{
|
||||
open(my $fh, "<", $cronfile) or die "crontab: $!";
|
||||
local $/;
|
||||
my $contents = <$fh>;
|
||||
close($fh);
|
||||
return $contents;
|
||||
}
|
||||
|
||||
# Write the requested module ACL values for the CGI subprocess.
|
||||
sub seed_acl
|
||||
{
|
||||
my (%acl) = @_;
|
||||
open(my $fh, ">", "$confdir/cron/admin.acl") or die "admin.acl: $!";
|
||||
foreach my $key (sort keys %acl) {
|
||||
print $fh "$key=$acl{$key}\n";
|
||||
}
|
||||
close($fh);
|
||||
}
|
||||
|
||||
# Encode one form value for an application/x-www-form-urlencoded body.
|
||||
sub url_encode
|
||||
{
|
||||
my ($value) = @_;
|
||||
$value = "" if (!defined($value));
|
||||
$value =~ s/([^A-Za-z0-9._~-])/sprintf("%%%02X", ord($1))/ge;
|
||||
return $value;
|
||||
}
|
||||
|
||||
# Serialize a hash of scalar or array form values.
|
||||
sub form_body
|
||||
{
|
||||
my ($form) = @_;
|
||||
my @pairs;
|
||||
foreach my $key (sort keys %$form) {
|
||||
my @values = ref($form->{$key}) eq "ARRAY" ?
|
||||
@{$form->{$key}} : ($form->{$key});
|
||||
push(@pairs, map { url_encode($key)."=".url_encode($_) } @values);
|
||||
}
|
||||
return join("&", @pairs);
|
||||
}
|
||||
|
||||
# Run one Cron CGI with the supplied form and isolated Webmin environment.
|
||||
sub run_cgi
|
||||
{
|
||||
my ($cgi, $form) = @_;
|
||||
my $body = form_body($form);
|
||||
my %env = (
|
||||
'PATH' => $ENV{'PATH'},
|
||||
'WEBMIN_CONFIG' => $confdir,
|
||||
'WEBMIN_VAR' => $vardir,
|
||||
'FOREIGN_MODULE_NAME' => 'cron',
|
||||
'FOREIGN_ROOT_DIRECTORY' => $rootdir,
|
||||
'MINISERV_CONFIG' => $miniservconf,
|
||||
'REMOTE_USER' => 'admin',
|
||||
'BASE_REMOTE_USER' => 'admin',
|
||||
'REQUEST_METHOD' => 'POST',
|
||||
'SCRIPT_NAME' => "/cron/$cgi",
|
||||
'CONTENT_TYPE' => 'application/x-www-form-urlencoded',
|
||||
'CONTENT_LENGTH' => length($body),
|
||||
'SERVER_NAME' => 'localhost',
|
||||
'SERVER_PORT' => '10000',
|
||||
'HTTP_HOST' => 'localhost:10000',
|
||||
);
|
||||
my $errfh = gensym();
|
||||
local %ENV = %env;
|
||||
my $pid = IPC::Open3::open3(my $in, my $out, $errfh,
|
||||
$^X, "-I$rootdir", "$rootdir/cron/$cgi");
|
||||
print $in $body;
|
||||
close($in);
|
||||
local $/;
|
||||
my $stdout = <$out>;
|
||||
my $stderr = <$errfh>;
|
||||
$stdout = "" if (!defined($stdout));
|
||||
$stderr = "" if (!defined($stderr));
|
||||
close($out);
|
||||
close($errfh);
|
||||
waitpid($pid, 0);
|
||||
return { 'out' => $stdout, 'err' => $stderr, 'status' => $? >> 8 };
|
||||
}
|
||||
|
||||
my %full_acl = (
|
||||
'mode' => 0,
|
||||
'command' => 1,
|
||||
'create' => 1,
|
||||
'delete' => 1,
|
||||
'move' => 1,
|
||||
'env' => 1,
|
||||
);
|
||||
|
||||
write_crontab();
|
||||
my $original = read_crontab_fixture();
|
||||
seed_acl(%full_acl, 'env' => 0);
|
||||
my $result = run_cgi("delete_cron.cgi", { 'idx' => 2 });
|
||||
like($result->{'out'}, qr/job does not exist/i,
|
||||
"job delete endpoint rejects a variable row");
|
||||
$result = run_cgi("save_cron.cgi", { 'idx' => 2 });
|
||||
like($result->{'out'}, qr/job does not exist/i,
|
||||
"job save endpoint rejects a variable row");
|
||||
|
||||
seed_acl(%full_acl);
|
||||
$result = run_cgi("delete_env.cgi", { 'idx' => 0 });
|
||||
like($result->{'out'}, qr/environment variable does not exist/i,
|
||||
"variable delete endpoint rejects a job row");
|
||||
$result = run_cgi("save_env.cgi", { 'idx' => 0 });
|
||||
like($result->{'out'}, qr/environment variable does not exist/i,
|
||||
"variable save endpoint rejects a job row");
|
||||
|
||||
seed_acl(%full_acl, 'create' => 0);
|
||||
$result = run_cgi("save_env.cgi", { 'new' => 1 });
|
||||
like($result->{'out'}, qr/not allowed to create cron jobs/i,
|
||||
"creating a variable requires create permission");
|
||||
|
||||
seed_acl(%full_acl, 'delete' => 0);
|
||||
$result = run_cgi("delete_env.cgi", { 'idx' => 2 });
|
||||
like($result->{'out'}, qr/not allowed to edit cron jobs/i,
|
||||
"deleting a variable requires delete permission");
|
||||
|
||||
seed_acl(%full_acl, 'env' => 0);
|
||||
$result = run_cgi("delete_jobs.cgi",
|
||||
{ 'd' => [ 3, 2 ], 'delete' => 1 });
|
||||
like($result->{'out'}, qr/not allowed to edit environment variables/i,
|
||||
"bulk delete rejects a mixed selection without env permission");
|
||||
is(read_crontab_fixture(), $original,
|
||||
"denied bulk delete does not partially change the crontab");
|
||||
|
||||
$result = run_cgi("delete_jobs.cgi", { 'd' => 0, 'disable' => 1 });
|
||||
like($result->{'out'}, qr/^Location:/m,
|
||||
"a normal job can still be disabled without env permission");
|
||||
like(read_crontab_fixture(), qr/^# \* \* \* \* \* echo first/m,
|
||||
"disabling a normal job updates only that row");
|
||||
$result = run_cgi("delete_jobs.cgi", { 'd' => 0, 'enable' => 1 });
|
||||
like($result->{'out'}, qr/^Location:/m,
|
||||
"a normal job can still be enabled without env permission");
|
||||
is(read_crontab_fixture(), $original,
|
||||
"re-enabling the normal job restores the fixture");
|
||||
|
||||
# Job fields must not add lines or fields to the crontab
|
||||
seed_acl(%full_acl);
|
||||
my %edit = ( 'idx' => 0, 'user' => 'root', 'active' => 1,
|
||||
'cmd' => 'echo first', 'range_def' => 1,
|
||||
'special_def' => 0, 'all_mins' => 1, 'all_hours' => 1,
|
||||
'all_days' => 1, 'all_months' => 1, 'all_weekdays' => 1 );
|
||||
foreach my $case (
|
||||
[ "a line break in the command",
|
||||
{ 'cmd' => "echo first\nPATH=/tmp" }, qr/cannot contain line breaks/ ],
|
||||
[ "a line break in the comment",
|
||||
{ 'comment' => "x\nPATH=/tmp" }, qr/cannot contain line breaks/ ],
|
||||
[ "a special time with spaces",
|
||||
{ 'special_def' => 1, 'special' => "reboot echo x #" },
|
||||
qr/Invalid special time/ ],
|
||||
[ "a minute with spaces",
|
||||
{ 'all_mins' => 0, 'mins' => "* * * * * echo x #" },
|
||||
qr/Invalid Minutes selected/ ],
|
||||
[ "a minute with a line break",
|
||||
{ 'all_mins' => 0, 'mins' => "5\nPATH=/tmp" },
|
||||
qr/Invalid Minutes selected/ ],
|
||||
[ "a range date with shell text",
|
||||
{ 'range_def' => 0, 'range_start_day' => '1;echo x;',
|
||||
'range_start_month' => 1, 'range_start_year' => 2026,
|
||||
'range_end_day' => 31, 'range_end_month' => 12,
|
||||
'range_end_year' => 2026 }, qr/invalid start date/i ],
|
||||
) {
|
||||
my ($desc, $form, $re) = @$case;
|
||||
$result = run_cgi("save_cron.cgi", { %edit, %$form });
|
||||
like($result->{'out'}, $re, "save_cron.cgi rejects $desc");
|
||||
is(read_crontab_fixture(), $original,
|
||||
"rejected $desc leaves the crontab unchanged");
|
||||
}
|
||||
|
||||
seed_acl(%full_acl, 'env' => 0);
|
||||
$result = run_cgi("move.cgi", { 'idx' => 4, 'top' => 1 });
|
||||
like($result->{'out'}, qr/^Location:/m,
|
||||
"a job can move across a variable without env permission");
|
||||
isnt(read_crontab_fixture(), $original,
|
||||
"the permitted top move changes the crontab");
|
||||
|
||||
# Saving a job needs a real Unix user, so check a valid save in a per-user
|
||||
# crontab, as on Linux. Plain shell commands stand in for the crontab
|
||||
# command, so the real one never runs.
|
||||
write_cron_config("cron_copy_command=cat >$crondir/USER",
|
||||
"cron_delete_command=rm -f $crondir/USER");
|
||||
$cronfile = "$crondir/root";
|
||||
write_crontab();
|
||||
$result = run_cgi("save_cron.cgi",
|
||||
{ %edit, 'all_mins' => 0, 'mins' => [ 5, 6, 30 ],
|
||||
'range_def' => 0, 'range_start_day' => 1,
|
||||
'range_start_month' => 1, 'range_start_year' => 2026,
|
||||
'range_end_day' => 31, 'range_end_month' => 12,
|
||||
'range_end_year' => 2026 });
|
||||
like($result->{'out'}, qr/^Location:/m,
|
||||
"save_cron.cgi accepts valid times and dates");
|
||||
like(read_crontab_fixture(),
|
||||
qr/^5-6,30 \* \* \* \* \S+range\.pl 1-1-2026 31-12-2026 echo\\ first$/m,
|
||||
"the saved job has the expected times and date range");
|
||||
|
||||
done_testing();
|
||||
@@ -481,6 +481,11 @@ foreach my $a (@{$cmd->{'args'}}) {
|
||||
&error(&text('run_emust', $a->{'desc'}));
|
||||
}
|
||||
$rv =~ /\0/ && &error($text{'run_ezero'});
|
||||
# Stop non-path parameters from changing the editor's directory
|
||||
if ($cmd->{'edit'} && $a->{'type'} != 5 && $a->{'type'} != 6 &&
|
||||
($rv =~ /[\/\\\r\n]/ || $rv =~ /^\.\.?$/)) {
|
||||
&error($text{'view_ecannot'});
|
||||
}
|
||||
$ENV{$n} = $rv;
|
||||
$env .= "$n=".quotemeta($rv)."\n";
|
||||
$export .= " $n";
|
||||
@@ -496,6 +501,30 @@ foreach my $a (@{$cmd->{'args'}}) {
|
||||
return ($env, $export, $str, $displaystr, \@vals);
|
||||
}
|
||||
|
||||
# resolve_editor_file(template)
|
||||
# Expands environment variables and keeps the path in its fixed directory.
|
||||
sub resolve_editor_file
|
||||
{
|
||||
local ($file) = @_;
|
||||
# Leave fixed paths unchanged
|
||||
return $file if ($file !~ /\$/);
|
||||
local $template = $file;
|
||||
# Expand each supported variable once, but not variables inside its value
|
||||
$file =~ s{\$\{([A-Za-z_][A-Za-z0-9_]*)\}|
|
||||
\$([A-Za-z_][A-Za-z0-9_]*)}{
|
||||
my $name = defined($1) ? $1 : $2;
|
||||
defined($ENV{$name}) ? $ENV{$name} : "";
|
||||
}gex;
|
||||
# Resolve the fixed directory and full path before checking their locations
|
||||
$template =~ s/\$.*$//;
|
||||
$template =~ s/\/[^\/]*$// if ($template ne "/");
|
||||
$template = &simplify_path(&resolve_links($template));
|
||||
$file = &simplify_path(&resolve_links($file));
|
||||
$template && $file && &is_under_directory($template, $file) ||
|
||||
&error($text{'view_ecannot'});
|
||||
return $file;
|
||||
}
|
||||
|
||||
# list_dbi_drivers()
|
||||
# Returns a list of DBI driver details, which are actually installed
|
||||
sub list_dbi_drivers
|
||||
|
||||
@@ -18,10 +18,9 @@ if ($file !~ /^\//) {
|
||||
|
||||
# Set environment variables for parameters
|
||||
($env, $export, $str, $displayfile) = &set_parameter_envs($edit, $file);
|
||||
|
||||
if ($edit->{'envs'} || @{$edit->{'args'}}) {
|
||||
# Do environment variable substitution
|
||||
chop($file = `echo "$file"`);
|
||||
# Expand variables without invoking a shell
|
||||
$file = &resolve_editor_file($file);
|
||||
}
|
||||
|
||||
# Run the before-command
|
||||
@@ -37,14 +36,15 @@ $in{'data'} =~ s/\r//g;
|
||||
&print_tempfile(FILE, $in{'data'});
|
||||
&close_tempfile(FILE);
|
||||
|
||||
# Set permissions
|
||||
# Set file ownership and permissions without invoking a shell
|
||||
if ($edit->{'user'}) {
|
||||
&system_logged("chown $edit->{'user'}:$edit->{'group'} ".
|
||||
"$file >/dev/null 2>&1");
|
||||
# Apply the configured owner and group
|
||||
&set_ownership_permissions($edit->{'user'}, $edit->{'group'},
|
||||
undef, $file);
|
||||
}
|
||||
if ($edit->{'perms'}) {
|
||||
&system_logged("chmod $edit->{'perms'} ".
|
||||
"$file >/dev/null 2>&1");
|
||||
# Apply the configured file permissions
|
||||
&set_ownership_permissions(undef, undef, oct($edit->{'perms'}), $file);
|
||||
}
|
||||
|
||||
# Run the after-command
|
||||
|
||||
@@ -17,12 +17,11 @@ if ($file !~ /^\//) {
|
||||
|
||||
# Set environment variables for parameters
|
||||
($env, $export, $str, $displayfile) = &set_parameter_envs($edit, $file);
|
||||
$displayfile = &html_escape($displayfile);
|
||||
|
||||
if ($edit->{'envs'} || @{$edit->{'args'}}) {
|
||||
# Do environment variable substitution
|
||||
chop($file = `echo "$file"`);
|
||||
# Expand variables without invoking a shell
|
||||
$file = &resolve_editor_file($file);
|
||||
}
|
||||
$displayfile = &html_escape($displayfile);
|
||||
|
||||
# Run any before-edit command
|
||||
if ($edit->{'beforeedit'}) {
|
||||
|
||||
@@ -17,32 +17,32 @@ if ($in{'method'} eq 'plain-tar') {
|
||||
$extension = ".tar";
|
||||
$full = &validate_filename_path($in{'arch'}.$extension);
|
||||
$command = "tar cf ".quotemeta($full).
|
||||
" -C ".quotemeta($cwd);
|
||||
" -C ".quotemeta($cwd)." --";
|
||||
}
|
||||
elsif ($in{'method'} eq 'xz-tar') {
|
||||
$extension = ".tar.xz";
|
||||
$full = &validate_filename_path($in{'arch'}.$extension);
|
||||
$command = "tar cJf ".quotemeta($full).
|
||||
" -C ".quotemeta($cwd);
|
||||
" -C ".quotemeta($cwd)." --";
|
||||
}
|
||||
elsif ($in{'method'} eq 'zstd-tar') {
|
||||
$extension = ".zst";
|
||||
$full = &validate_filename_path($in{'arch'}.$extension);
|
||||
$command = "ZSTD_CLEVEL=19 tar --zstd -cf ".
|
||||
quotemeta($full).
|
||||
" -C ".quotemeta($cwd);
|
||||
" -C ".quotemeta($cwd)." --";
|
||||
}
|
||||
elsif ($in{'method'} eq 'tar') {
|
||||
$extension = ".tar.gz";
|
||||
$full = &validate_filename_path($in{'arch'}.$extension);
|
||||
$command = "tar czf ".quotemeta($full).
|
||||
" -C ".quotemeta($cwd);
|
||||
" -C ".quotemeta($cwd)." --";
|
||||
}
|
||||
elsif ($in{'method'} eq 'zip') {
|
||||
$extension = ".zip";
|
||||
$full = &validate_filename_path($in{'arch'}.$extension);
|
||||
$command = "cd ".quotemeta($cwd).
|
||||
" && zip -r ".quotemeta($full);
|
||||
" && zip -r ".quotemeta($full)." --";
|
||||
}
|
||||
else {
|
||||
&error("Unknown method!");
|
||||
|
||||
@@ -31,9 +31,9 @@ elsif ($archive_type =~ /x-7z/ ||
|
||||
elsif ($archive_type =~ /\/zip/) {
|
||||
my $unzip_out = `unzip --help`;
|
||||
my $uu = ($unzip_out =~ /-UU/ ? '-UU' : undef);
|
||||
$cmd = "unzip $uu -q -o ".
|
||||
quotemeta($full).
|
||||
" -d ".quotemeta($cwd);
|
||||
$cmd = "unzip $uu -q -o".
|
||||
" -d ".quotemeta($cwd).
|
||||
" -- ".quotemeta($full);
|
||||
}
|
||||
elsif ($archive_type =~ /\/x-rar|\/vnd\.rar/) {
|
||||
$cmd = "unrar x -r -y ".
|
||||
|
||||
@@ -11,7 +11,7 @@ eval "use File::MimeInfo";
|
||||
|
||||
our ($path, $quote_escaped_path, $urlized_path, $base, $cwd, $upload_max,
|
||||
$confdir, $template_name, $bookmarks, $page, $pagelimit, $edit_icon,
|
||||
$rename_icon, $extract_icon, $goto_icon, $root_icon, $head);
|
||||
$rename_icon, $extract_icon, $goto_icon, $root_icon);
|
||||
our (%access, %userconfig, %allowed_for_edit);
|
||||
our (@allowed_paths, @allowed_for_edit, @remote_user_info);
|
||||
|
||||
@@ -413,124 +413,9 @@ if ($tinfo{'bootstrap'}) {
|
||||
"unauthenticated/templates/dialogs.html");
|
||||
}
|
||||
|
||||
# Interface for legacy themes
|
||||
# Interface for other themes, built from the core widgets
|
||||
else {
|
||||
|
||||
# Set icons variables
|
||||
$edit_icon =
|
||||
"<img src='images/icons/quick/edit.png'" .
|
||||
" alt='$text{'edit'}' />";
|
||||
$rename_icon =
|
||||
"<img src='images/icons/quick/" .
|
||||
"rename.png' " .
|
||||
"alt='$text{'rename'}' />";
|
||||
$extract_icon =
|
||||
"<img src='images/icons/quick/" .
|
||||
"extract.png' " .
|
||||
"alt='$text{'extract_archive'}' />";
|
||||
$goto_icon =
|
||||
"<img src='images/icons/quick/" .
|
||||
"go-next.png' " .
|
||||
"alt='$text{'goto_folder'}'";
|
||||
|
||||
# Add static files
|
||||
$head = "<link rel=\"stylesheet\" " .
|
||||
"type=\"text/css\" " .
|
||||
"href=\"unauthenticated/css/" .
|
||||
"style.css\" />";
|
||||
$head .= "<script type=\"text/javascript\"" .
|
||||
" src=\"unauthenticated/jquery/" .
|
||||
"jquery.min.js\"></script>";
|
||||
$head .= "<script type=\"text/javascript\"" .
|
||||
" src=\"unauthenticated/jquery/" .
|
||||
"jquery-ui.min.js\"></script>";
|
||||
$head .= "<script type=\"text/javascript\"" .
|
||||
" src=\"unauthenticated/js/" .
|
||||
"legacy.js\"></script>";
|
||||
$head .= "<link rel=\"stylesheet\" " .
|
||||
"type=\"text/css\" " .
|
||||
"href=\"unauthenticated/jquery/" .
|
||||
"jquery-ui.min.css\" />";
|
||||
$head .= "<script type=\"text/javascript\"" .
|
||||
" src=\"unauthenticated/js/" .
|
||||
"chmod-calculator.js\"></script>";
|
||||
$head .= "<link rel=\"stylesheet\" " .
|
||||
"type=\"text/css\" " .
|
||||
"href=\"unauthenticated/dropdown/" .
|
||||
"fg.menu.css\" />";
|
||||
$head .= "<script type=\"text/javascript\"" .
|
||||
" src=\"unauthenticated/dropdown/" .
|
||||
"fg.menu.js\"></script>";
|
||||
print $head;
|
||||
|
||||
# Set "root" icon
|
||||
if ($base eq '/') {
|
||||
$root_icon =
|
||||
"<img src=\"images/icons/quick/" .
|
||||
"drive-harddisk.png\" " .
|
||||
"class=\"hdd-icon\" />";
|
||||
}
|
||||
else {
|
||||
$root_icon = "~";
|
||||
}
|
||||
# Legacy breadcrumbs
|
||||
print "<div id='bread' style='float: left;" .
|
||||
" padding-bottom: 2px;'>" .
|
||||
"<a href='index.cgi?path='>" .
|
||||
"$root_icon</a> / ";
|
||||
my @breadcr = split('/', $path);
|
||||
my $cp = '';
|
||||
for (my $i = 1;
|
||||
$i <= scalar(@breadcr)-1; $i++) {
|
||||
chomp($breadcr[$i]);
|
||||
$cp = $cp.'/'.$breadcr[$i];
|
||||
print "<a href='index.cgi?path=" .
|
||||
&urlize($cp) . "'>" .
|
||||
&html_escape($breadcr[$i]) .
|
||||
"</a> / ";
|
||||
}
|
||||
print "<br />";
|
||||
# And pagination
|
||||
$page = $in{'page'};
|
||||
$pagelimit = $userconfig{'per_page'};
|
||||
$pages = ceil((scalar(@list))/$pagelimit);
|
||||
if (not defined $page or $page > $pages) {
|
||||
$page = 1;
|
||||
}
|
||||
print "Pages: ";
|
||||
for (my $i = 1; $i <= $pages; $i++) {
|
||||
if ($page eq $i) {
|
||||
print "<a class='pages active' " .
|
||||
"href='?path=" .
|
||||
&urlize($path) .
|
||||
"&page=$i" .
|
||||
"&query=" .
|
||||
&urlize($query) .
|
||||
"'>" .
|
||||
&html_escape($i) .
|
||||
"</a>";
|
||||
}
|
||||
else {
|
||||
print "<a class='pages' " .
|
||||
"href='?path=" .
|
||||
&urlize($path) .
|
||||
"&page=$i" .
|
||||
"&query=" .
|
||||
&urlize($query) .
|
||||
"'>" .
|
||||
&html_escape($i) .
|
||||
"</a>";
|
||||
}
|
||||
}
|
||||
print "</div>";
|
||||
|
||||
# And toolbar
|
||||
print_template(
|
||||
"unauthenticated/templates/" .
|
||||
"legacy_quicks.html");
|
||||
print_template(
|
||||
"unauthenticated/templates/" .
|
||||
"legacy_dialogs.html");
|
||||
print &plain_interface_head();
|
||||
}
|
||||
my $info_total;
|
||||
my $info_files = scalar @files;
|
||||
@@ -801,6 +686,18 @@ for (my $count = 1 + $pagelimit * ($page - 1);
|
||||
print ui_columns_end();
|
||||
print &ui_hidden("path", $path),"\n";
|
||||
print &ui_form_end();
|
||||
# Close the widget page area opened by the non-Bootstrap interface
|
||||
print &ui_page_end() if (!$tinfo{'bootstrap'});
|
||||
}
|
||||
|
||||
# list_bookmarks()
|
||||
# Returns the directories the user has bookmarked
|
||||
sub list_bookmarks
|
||||
{
|
||||
$confdir = "$remote_user_info[7]/.filemin";
|
||||
return () if (!-e "$confdir/.bookmarks");
|
||||
my $bookmarks = &read_file_lines($confdir.'/.bookmarks', 1);
|
||||
return grep { $_ ne '' } @$bookmarks;
|
||||
}
|
||||
|
||||
# get_bookmarks()
|
||||
@@ -811,10 +708,8 @@ $confdir = "$remote_user_info[7]/.filemin";
|
||||
if (!-e "$confdir/.bookmarks") {
|
||||
return "<li><a>$text{'no_bookmarks'}</a></li>";
|
||||
}
|
||||
my $bookmarks =
|
||||
&read_file_lines($confdir.'/.bookmarks', 1);
|
||||
$result = '';
|
||||
foreach $bookmark (@$bookmarks) {
|
||||
foreach $bookmark (&list_bookmarks()) {
|
||||
$result .=
|
||||
"<li><a href='index.cgi?path=" .
|
||||
&urlize($bookmark) . "'>" .
|
||||
@@ -824,6 +719,486 @@ foreach $bookmark (@$bookmarks) {
|
||||
return $result;
|
||||
}
|
||||
|
||||
# plain_interface_head()
|
||||
# Returns the top of the file list for themes without Bootstrap : the
|
||||
# module assets, the breadcrumbs, the toolbar of menus and buttons, the
|
||||
# page links and the dialogs behind the toolbar, all built from the core
|
||||
# widgets. Also sets the row action icons and the pagination that the
|
||||
# shared listing code uses, and opens the widget page area that
|
||||
# print_interface closes after the listing.
|
||||
sub plain_interface_head
|
||||
{
|
||||
my $rv = "";
|
||||
|
||||
# Row action icons from the built-in icon set
|
||||
$edit_icon = &ui_svg_icon('edit', { 'title' => $text{'edit'} });
|
||||
$rename_icon = &ui_svg_icon('cursor-text', { 'title' => $text{'rename'} });
|
||||
$extract_icon = &ui_svg_icon('unarchive',
|
||||
{ 'title' => $text{'extract_archive'} });
|
||||
$goto_icon = &ui_svg_icon('arrow-right', { 'title' => $text{'goto_folder'} });
|
||||
|
||||
# Server-side pagination, with as many entries per page as the user chose
|
||||
$page = int($in{'page'} || 0) || 1;
|
||||
$pagelimit = int($userconfig{'per_page'} || 0) || 50;
|
||||
$pages = ceil(scalar(@list) / $pagelimit) || 1;
|
||||
$page = 1 if ($page > $pages);
|
||||
|
||||
# The widget page area, with the module's own stylesheet and script
|
||||
$rv .= &ui_page_start({ 'class' => 'filemin_page' });
|
||||
$rv .= &plain_asset_tags();
|
||||
|
||||
# Breadcrumbs at the left and the toolbar at the right
|
||||
$rv .= &ui_tag('div', &plain_breadcrumb().&plain_toolbar(),
|
||||
{ 'class' => 'filemin_head' });
|
||||
|
||||
# Page links, when the listing does not fit on one page. The URL is
|
||||
# relative, so a search keeps its query from page to page
|
||||
my $pager = &ui_pager({
|
||||
'page' => $page,
|
||||
'pages' => $pages,
|
||||
'href' => "?path=".&urlize($path).
|
||||
(defined($query) && $query ne '' ?
|
||||
"&query=".&urlize($query) : "").
|
||||
($in{'caseins'} ? "&caseins=1" : "").
|
||||
"&page=" });
|
||||
$rv .= &ui_tag('div', $pager, { 'class' => 'filemin_pager' }) if ($pager);
|
||||
|
||||
# The dialogs opened from the toolbar and the rows
|
||||
$rv .= &plain_dialogs();
|
||||
return $rv;
|
||||
}
|
||||
|
||||
# plain_asset_tags()
|
||||
# Returns the tags loading the module's stylesheet and script for the
|
||||
# widget interface, each keyed by its modification time so that a changed
|
||||
# file is fetched at once, and the permissions calculator shared with the
|
||||
# Bootstrap interface
|
||||
sub plain_asset_tags
|
||||
{
|
||||
my $rv = "";
|
||||
foreach my $file ('css/plain.css', 'js/plain.js') {
|
||||
my @st = stat("$module_root_directory/unauthenticated/$file");
|
||||
my $url = "unauthenticated/$file?".(@st ? $st[9] : &get_webmin_version());
|
||||
if ($file =~ /\.css$/) {
|
||||
$rv .= &ui_tag('link', undef,
|
||||
{ 'rel' => 'stylesheet', 'href' => $url })."\n";
|
||||
}
|
||||
else {
|
||||
$rv .= &ui_tag('script', undef,
|
||||
{ 'src' => $url, 'defer' => undef })."\n";
|
||||
}
|
||||
}
|
||||
$rv .= &ui_tag('script', undef,
|
||||
{ 'src' => 'unauthenticated/js/chmod-calculator.js' })."\n";
|
||||
return $rv;
|
||||
}
|
||||
|
||||
# plain_breadcrumb()
|
||||
# Returns the path to the current directory as breadcrumb links, starting
|
||||
# with the allowed base directory : the disk when it is the root, else
|
||||
# the home
|
||||
sub plain_breadcrumb
|
||||
{
|
||||
my @items = ( { 'icon' => $base eq '/' ? 'hard-drive' : 'home',
|
||||
'href' => 'index.cgi?path=',
|
||||
'title' => $base } );
|
||||
my $cp = '';
|
||||
foreach my $part (grep { $_ ne '' } split(/\//, $path)) {
|
||||
$cp .= '/'.$part;
|
||||
push(@items, { 'label' => $part,
|
||||
'href' => 'index.cgi?path='.&urlize($cp) });
|
||||
}
|
||||
return &ui_breadcrumb(\@items, { 'class' => 'filemin_crumbs' });
|
||||
}
|
||||
|
||||
# plain_toolbar()
|
||||
# Returns the toolbar : the File, Edit, Tools and Bookmarks menus, and the
|
||||
# refresh and delete buttons. Entries acting on the selected entries are
|
||||
# marked, so that plain.js asks for a selection first. Tools whose
|
||||
# command is missing are left out.
|
||||
sub plain_toolbar
|
||||
{
|
||||
my $urlpath = &urlize($path);
|
||||
my $sel = { 'data-filemin-selection' => '1' };
|
||||
my @file = (
|
||||
{ 'label' => $text{'create_file'}, 'icon' => 'file-plus',
|
||||
'dialog' => 'filemin_create_file' },
|
||||
{ 'label' => $text{'create_folder'}, 'icon' => 'folder-plus',
|
||||
'dialog' => 'filemin_create_folder' },
|
||||
'-',
|
||||
{ 'label' => $text{'upload_files'}, 'icon' => 'upload',
|
||||
'dialog' => 'filemin_upload' },
|
||||
{ 'label' => $text{'get_from_url'}, 'icon' => 'globe',
|
||||
'dialog' => 'filemin_download' },
|
||||
);
|
||||
my @edit = (
|
||||
{ 'label' => $text{'copy_selected'}, 'icon' => 'copy',
|
||||
'attrs' => { %$sel, 'data-filemin-submit' => 'copy.cgi' } },
|
||||
{ 'label' => $text{'cut_selected'}, 'icon' => 'scissors',
|
||||
'attrs' => { %$sel, 'data-filemin-submit' => 'cut.cgi' } },
|
||||
{ 'label' => $text{'paste'}, 'icon' => 'clipboard',
|
||||
'href' => 'paste.cgi?path='.$urlpath },
|
||||
'-',
|
||||
{ 'label' => $text{'select_all'}, 'icon' => 'check-square',
|
||||
'attrs' => { 'data-filemin-select' => 'all' } },
|
||||
{ 'label' => $text{'invert_selection'}, 'icon' => 'square-half',
|
||||
'attrs' => { 'data-filemin-select' => 'invert' } },
|
||||
);
|
||||
my @tools = (
|
||||
{ 'label' => $text{'search'}, 'icon' => 'search',
|
||||
'dialog' => 'filemin_search' },
|
||||
'-',
|
||||
{ 'label' => $text{'compress_selected'}, 'icon' => 'archive',
|
||||
'dialog' => 'filemin_compress', 'attrs' => $sel },
|
||||
{ 'label' => $text{'chmod_selected'}, 'icon' => 'lock',
|
||||
'dialog' => 'filemin_chmod', 'attrs' => $sel },
|
||||
{ 'label' => $text{'chown_selected'}, 'icon' => 'user',
|
||||
'dialog' => 'filemin_chown', 'attrs' => $sel },
|
||||
);
|
||||
push(@tools, { 'label' => $text{'chattr_selected'}, 'icon' => 'tag',
|
||||
'dialog' => 'filemin_chattr', 'attrs' => $sel })
|
||||
if (&has_command('chattr'));
|
||||
push(@tools, { 'label' => $text{'chcon_selected'}, 'icon' => 'shield',
|
||||
'dialog' => 'filemin_chcon', 'attrs' => $sel })
|
||||
if (&get_selinux_status());
|
||||
push(@tools, { 'label' => $text{'acls_selected'}, 'icon' => 'key',
|
||||
'dialog' => 'filemin_acls', 'attrs' => $sel })
|
||||
if (&has_command('setfacl'));
|
||||
my @bookmarks = (
|
||||
{ 'label' => $text{'bookmark_folder'}, 'icon' => 'bookmark',
|
||||
'href' => 'bookmark.cgi?path='.$urlpath },
|
||||
'-',
|
||||
);
|
||||
my @marks = &list_bookmarks();
|
||||
if (@marks) {
|
||||
push(@bookmarks, map { { 'label' => $_, 'icon' => 'folder',
|
||||
'href' => 'index.cgi?path='.&urlize($_) } }
|
||||
@marks);
|
||||
}
|
||||
else {
|
||||
push(@bookmarks, { 'label' => $text{'no_bookmarks'}, 'disabled' => 1 });
|
||||
}
|
||||
my @buttons = (
|
||||
&ui_dropdown($text{'menu_file'}, \@file, { 'icon' => 'file' }),
|
||||
&ui_dropdown($text{'menu_edit'}, \@edit, { 'icon' => 'clipboard' }),
|
||||
&ui_dropdown($text{'menu_tools'}, \@tools, { 'icon' => 'gear' }),
|
||||
&ui_dropdown($text{'menu_bookmarks'}, \@bookmarks,
|
||||
{ 'icon' => 'book', 'align' => 'end' }),
|
||||
&ui_action_button($text{'refresh'}, 'neutral',
|
||||
{ 'icon' => 'refresh', 'href' => 'index.cgi?path='.$urlpath }),
|
||||
&ui_dialog_button($text{'delete'}, 'filemin_delete', 'danger',
|
||||
{ 'icon' => 'trash', 'attrs' => $sel }),
|
||||
);
|
||||
return &ui_tag('div', join("\n", @buttons),
|
||||
{ 'class' => 'filemin_toolbar', 'role' => 'toolbar' });
|
||||
}
|
||||
|
||||
# plain_dialog_table(&rows)
|
||||
# Returns a two-column table of label and input rows for a dialog body.
|
||||
# A row with an empty label spans the table.
|
||||
sub plain_dialog_table
|
||||
{
|
||||
my ($rows) = @_;
|
||||
my $rv = &ui_table_start(undef, "width=100%", 2);
|
||||
foreach my $row (@$rows) {
|
||||
$rv .= defined($row->[0]) && $row->[0] ne '' ?
|
||||
&ui_table_row($row->[0], $row->[1]) :
|
||||
&ui_table_row(undef, $row->[1], 2);
|
||||
}
|
||||
$rv .= &ui_table_end();
|
||||
return $rv;
|
||||
}
|
||||
|
||||
# plain_dialogs()
|
||||
# Returns the dialogs behind the toolbar and the row actions. A dialog
|
||||
# acting on the selected entries carries the script to run in a
|
||||
# data-filemin-apply attribute : plain.js sends the selection form to that
|
||||
# script with the dialog's fields as URL parameters, as the action
|
||||
# scripts expect them. The other dialogs are ordinary forms posting to
|
||||
# their script.
|
||||
sub plain_dialogs
|
||||
{
|
||||
my $rv = "";
|
||||
my $hidden_path = &ui_hidden('path', $path);
|
||||
my $cancel = $text{'dialog_cancel'};
|
||||
my $recursive = &ui_checkbox('recursive', 'true', $text{'dialog_recursive'}, 0);
|
||||
my $apply = sub {
|
||||
# A form sent to the selection, closed natively if the script fails
|
||||
my ($script, $name) = @_;
|
||||
return { 'method' => 'dialog',
|
||||
'name' => $name,
|
||||
'attrs' => { 'data-filemin-apply' => $script } };
|
||||
};
|
||||
my $change = [ { 'label' => $text{'dialog_change'}, 'state' => 'success',
|
||||
'icon' => 'check' } ];
|
||||
|
||||
# Shown when an action needs a selection and nothing is checked
|
||||
$rv .= &ui_dialog({
|
||||
'id' => 'filemin_nothing',
|
||||
'title' => $text{'warning_title'},
|
||||
'state' => 'warning',
|
||||
'size' => 'small',
|
||||
'text' => $text{'nothing_selected'},
|
||||
'close' => $text{'dialog_ok'} });
|
||||
|
||||
# New file and directory
|
||||
foreach my $kind ([ 'file', 'create_file', 'new_file_name', 'file-plus' ],
|
||||
[ 'folder', 'create_folder', 'new_folder_name', 'folder-plus' ]) {
|
||||
my ($what, $title, $label, $icon) = @$kind;
|
||||
$rv .= &ui_dialog({
|
||||
'id' => 'filemin_create_'.$what,
|
||||
'title' => $text{$title},
|
||||
'icon' => $icon,
|
||||
'size' => 'small',
|
||||
'form' => 'create_'.$what.'.cgi',
|
||||
'body' => &plain_dialog_table([
|
||||
[ $text{$label},
|
||||
&ui_textbox('name', '', 30, 0, undef, 'required') ],
|
||||
]).$hidden_path,
|
||||
'buttons' => [ { 'label' => $text{'create'}, 'state' => 'success',
|
||||
'icon' => 'check' } ],
|
||||
'close' => $cancel });
|
||||
}
|
||||
|
||||
# Rename, filled in by the row link
|
||||
$rv .= &ui_dialog({
|
||||
'id' => 'filemin_rename',
|
||||
'title' => $text{'rename'},
|
||||
'icon' => 'cursor-text',
|
||||
'size' => 'small',
|
||||
'form' => 'rename.cgi',
|
||||
'body' => &plain_dialog_table([
|
||||
[ $text{'new_name'},
|
||||
&ui_textbox('name', '', 30, 0, undef, 'required') ],
|
||||
]).&ui_hidden('file', '').$hidden_path,
|
||||
'buttons' => [ { 'label' => $text{'rename'}, 'state' => 'success',
|
||||
'icon' => 'check' } ],
|
||||
'close' => $cancel });
|
||||
|
||||
# Upload. The options travel in the URL, which upload.cgi reads before
|
||||
# the files arrive, so plain.js adds them to the action on submit
|
||||
my $upload_url = "upload.cgi?path=".&urlize($path)."&id=".$upid;
|
||||
$rv .= &ui_dialog({
|
||||
'id' => 'filemin_upload',
|
||||
'title' => $text{'upload_files'},
|
||||
'icon' => 'upload',
|
||||
'form' => { 'action' => $upload_url,
|
||||
'method' => 'form-data',
|
||||
'attrs' => {
|
||||
'data-filemin-upload' => $upload_url,
|
||||
'data-filemin-tracker' =>
|
||||
&get_webprefix()."/uptracker.cgi?id=".$upid } },
|
||||
'body' => &plain_dialog_table([
|
||||
[ $text{'upload_files'},
|
||||
&ui_upload('upfiles', 40, 0, 'multiple required') ],
|
||||
[ undef,
|
||||
&ui_checkbox('opt_dirs', 1, $text{'upload_dirs'}, 0,
|
||||
'data-filemin-upload-dirs')."<br>".
|
||||
&ui_checkbox('opt_extract', 1, $text{'extract_uploaded'}, 0,
|
||||
"data-filemin-upload-option='extract_uploaded'").
|
||||
"<br>".
|
||||
&ui_checkbox('opt_overwrite', 1, $text{'overwrite_existing'}, 0,
|
||||
"data-filemin-upload-option='overwrite_existing'") ],
|
||||
]),
|
||||
'buttons' => [ { 'label' => $text{'upload_files'}, 'state' => 'success',
|
||||
'icon' => 'upload' } ],
|
||||
'close' => $cancel });
|
||||
|
||||
# Download from a URL
|
||||
$rv .= &ui_dialog({
|
||||
'id' => 'filemin_download',
|
||||
'title' => $text{'get_from_url'},
|
||||
'icon' => 'globe',
|
||||
'form' => 'http_download.cgi',
|
||||
'body' => &plain_dialog_table([
|
||||
[ $text{'dialog_file_url'},
|
||||
&ui_tag('input', undef, { 'type' => 'url', 'name' => 'link',
|
||||
'class' => 'ui_textbox', 'size' => 40,
|
||||
'autocomplete' => 'url',
|
||||
'required' => undef }) ],
|
||||
[ $text{'dialog_user_name'},
|
||||
&ui_textbox('username', '', 25, 0, undef, "autocomplete='off'") ],
|
||||
[ $text{'dialog_user_pass'},
|
||||
&ui_password('password', '', 25, 0, undef,
|
||||
"autocomplete='new-password' data-password-meter-skip") ],
|
||||
]).$hidden_path,
|
||||
'buttons' => [ { 'label' => $text{'dialog_download'}, 'state' => 'success',
|
||||
'icon' => 'download' } ],
|
||||
'close' => $cancel });
|
||||
|
||||
# Search under the current directory
|
||||
$rv .= &ui_dialog({
|
||||
'id' => 'filemin_search',
|
||||
'title' => $text{'search'},
|
||||
'icon' => 'search',
|
||||
'size' => 'small',
|
||||
'form' => 'search.cgi',
|
||||
'body' => &plain_dialog_table([
|
||||
[ $text{'search_label'},
|
||||
&ui_textbox('query', '', 30, 0, undef, 'required') ],
|
||||
[ undef, &ui_checkbox('caseins', 1, $text{'search_insensitive'}, 1) ],
|
||||
]).$hidden_path,
|
||||
'buttons' => [ { 'label' => $text{'search_go'}, 'state' => 'success',
|
||||
'icon' => 'search' } ],
|
||||
'close' => $cancel });
|
||||
|
||||
# Compress the selection into an archive
|
||||
$rv .= &ui_dialog({
|
||||
'id' => 'filemin_compress',
|
||||
'title' => $text{'compress_selected'},
|
||||
'icon' => 'archive',
|
||||
'size' => 'small',
|
||||
'form' => &$apply('compress.cgi'),
|
||||
'body' => &plain_dialog_table([
|
||||
[ $text{'archive_name'},
|
||||
&ui_textbox('arch', '', 30, 0, undef, 'required') ],
|
||||
[ $text{'type'},
|
||||
&ui_select('method', 'tar', [ [ 'plain-tar', '.tar' ],
|
||||
[ 'xz-tar', '.tar.xz' ],
|
||||
[ 'tar', '.tar.gz' ],
|
||||
[ 'zstd-tar', '.zstd' ],
|
||||
[ 'zip', '.zip' ] ]) ],
|
||||
]),
|
||||
'buttons' => [ { 'label' => $text{'dialog_compress'}, 'state' => 'success',
|
||||
'icon' => 'archive' } ],
|
||||
'close' => $cancel });
|
||||
|
||||
# Permissions. The form is named for the calculator, whose fields are
|
||||
# kept out of the parameters; the perms parameter the script reads is a
|
||||
# hidden field that plain.js keeps equal to the octal field
|
||||
my $matrix = &ui_tag_start('table', { 'class' => 'filemin_chmod_matrix' }).
|
||||
&ui_tag('tr', &ui_tag('th', '').
|
||||
join('', map { &ui_tag('th', &html_escape($text{$_})) }
|
||||
('chmod_owner', 'chmod_group', 'chmod_others')));
|
||||
foreach my $bit ([ 'chmod_read', 4 ], [ 'chmod_write', 2 ],
|
||||
[ 'chmod_execute', 1 ]) {
|
||||
$matrix .= &ui_tag('tr', &ui_tag('td', &html_escape($text{$bit->[0]})).
|
||||
join('', map { &ui_tag('td', &ui_checkbox($_.$bit->[1], $bit->[1],
|
||||
undef, 0, 'data-filemin-chmod data-filemin-skip')) }
|
||||
('owner', 'group', 'other')));
|
||||
}
|
||||
foreach my $extra ([ 'chmod_sticky', 'sticky', 1 ], [ 'chmod_setgid', 'setgid', 2 ]) {
|
||||
$matrix .= &ui_tag('tr', &ui_tag('td', &html_escape($text{$extra->[0]})).
|
||||
&ui_tag('td', &ui_checkbox($extra->[1], $extra->[2], undef, 0,
|
||||
'data-filemin-chmod data-filemin-skip')).
|
||||
&ui_tag('td', '').&ui_tag('td', ''));
|
||||
}
|
||||
$matrix .= &ui_tag_end('table');
|
||||
$rv .= &ui_dialog({
|
||||
'id' => 'filemin_chmod',
|
||||
'title' => $text{'chmod_selected'},
|
||||
'icon' => 'lock',
|
||||
'form' => &$apply('chmod.cgi', 'chmod'),
|
||||
'body' => &plain_dialog_table([
|
||||
[ $text{'permissions'},
|
||||
&ui_textbox('t_total', '0644', 4, 0, 4,
|
||||
"data-filemin-chmod-octal data-filemin-skip ".
|
||||
"pattern='[0-7]{3,4}' required")." ".
|
||||
&ui_textbox('sym_total', '', 12, 0, undef,
|
||||
'readonly data-filemin-skip').
|
||||
&ui_hidden('perms', '0644') ],
|
||||
[ undef, $matrix ],
|
||||
[ $text{'chmod_apply_to'},
|
||||
&ui_select('applyto', 1,
|
||||
[ map { [ $_->[0], $text{$_->[1]} ] }
|
||||
( [ 1, 'chmod_dir_only' ],
|
||||
[ 2, 'chmod_dir_and_its_files' ],
|
||||
[ 3, 'chmod_all' ],
|
||||
[ 4, 'chmod_dir_files_and_subs_files' ],
|
||||
[ 5, 'chmod_dir_and_subs' ] ) ]) ],
|
||||
]),
|
||||
'buttons' => $change,
|
||||
'close' => $cancel });
|
||||
|
||||
# Ownership
|
||||
$rv .= &ui_dialog({
|
||||
'id' => 'filemin_chown',
|
||||
'title' => $text{'chown_selected'},
|
||||
'icon' => 'user',
|
||||
'size' => 'small',
|
||||
'form' => &$apply('chown.cgi'),
|
||||
'body' => &plain_dialog_table([
|
||||
[ $text{'user_name'},
|
||||
&ui_textbox('owner', '', 20, 0, undef, 'required') ],
|
||||
[ $text{'group_name'},
|
||||
&ui_textbox('group', '', 20, 0, undef, 'required') ],
|
||||
[ undef, $recursive ],
|
||||
]),
|
||||
'buttons' => $change,
|
||||
'close' => $cancel });
|
||||
|
||||
# File attributes and SELinux context, which take one label each
|
||||
foreach my $tool ([ 'chattr', 'tag', 'attr_label' ],
|
||||
[ 'chcon', 'shield', 'context_label' ]) {
|
||||
my ($what, $icon, $label) = @$tool;
|
||||
$rv .= &ui_dialog({
|
||||
'id' => 'filemin_'.$what,
|
||||
'title' => $text{$what.'_selected'},
|
||||
'icon' => $icon,
|
||||
'size' => 'small',
|
||||
'form' => &$apply($what.'.cgi'),
|
||||
'body' => &plain_dialog_table([
|
||||
[ $text{$label},
|
||||
&ui_textbox('label', '', 25, 0, undef, 'required') ],
|
||||
[ undef, $recursive ],
|
||||
]),
|
||||
'buttons' => $change,
|
||||
'close' => $cancel });
|
||||
}
|
||||
|
||||
# Access control lists, when setfacl exists
|
||||
if (&has_command('setfacl')) {
|
||||
$rv .= &ui_dialog({
|
||||
'id' => 'filemin_acls',
|
||||
'title' => $text{'acls_selected'},
|
||||
'icon' => 'key',
|
||||
'form' => &$apply('setfacl.cgi'),
|
||||
'body' => &plain_dialog_table([
|
||||
[ $text{'acls_action'},
|
||||
&ui_select('action', '-m',
|
||||
[ [ '', '' ], [ '-m', 'Modify (-m)' ],
|
||||
[ '-x', 'Remove (-x)' ],
|
||||
[ '-b', 'Remove all extended (-b)' ],
|
||||
[ '-k', 'Remove default (-k)' ] ]) ],
|
||||
[ $text{'acls_applyto'},
|
||||
&ui_select('apply_to', [ ],
|
||||
[ map { [ $_->[0], $text{$_->[1]} ] }
|
||||
( [ 'u', 'acls_user' ], [ 'g', 'acls_group' ],
|
||||
[ 'm', 'acls_mask' ], [ 'o', 'acls_other' ] ) ],
|
||||
4, 1) ],
|
||||
[ $text{'acls_perms'},
|
||||
&ui_select('perms', '',
|
||||
[ map { [ $_, $_ ] }
|
||||
( '', '---', 'r--', '-w-', '--x',
|
||||
'r-x', 'rw-', '-wx', 'rwx' ) ]) ],
|
||||
[ $text{'acls_user'}, $acl_user_select ],
|
||||
[ $text{'acls_group'}, $acl_group_select ],
|
||||
[ undef, &ui_checkbox('recursive', 1, $text{'dialog_recursive'}, 0) ],
|
||||
[ undef, $acl_manual ],
|
||||
]),
|
||||
'buttons' => $change,
|
||||
'close' => $cancel });
|
||||
}
|
||||
|
||||
# Delete, after listing what is selected. Cancel takes the focus, so
|
||||
# Enter does not delete by accident
|
||||
$rv .= &ui_dialog({
|
||||
'id' => 'filemin_delete',
|
||||
'title' => $text{'remove_selected'},
|
||||
'state' => 'danger',
|
||||
'icon' => 'trash',
|
||||
'form' => &$apply('delete.cgi'),
|
||||
'body' => &ui_tag('p', &html_escape($text{'about_to_delete'})).
|
||||
&ui_tag('pre', '', { 'id' => 'filemin_delete_items',
|
||||
'class' => 'filemin_delete_items' }).
|
||||
&ui_tag('p', &html_escape($text{'are_you_sure'})),
|
||||
'buttons' => [ { 'label' => $text{'delete'}, 'state' => 'danger',
|
||||
'icon' => 'trash' } ],
|
||||
'close' => $cancel,
|
||||
'focus' => 'close' });
|
||||
return $rv;
|
||||
}
|
||||
|
||||
# get_paste_buffer_file()
|
||||
# Returns the location of the file for temporary copy/paste state
|
||||
sub get_paste_buffer_file
|
||||
@@ -1110,10 +1485,9 @@ foreach my $fref (@{$files_to_extract}) {
|
||||
my $uu = ($unzip_out =~ /-UU/
|
||||
? '-UU' : undef);
|
||||
$status = system(
|
||||
"$unzip_cmd $uu -q -o " .
|
||||
quotemeta($archive) .
|
||||
" -d " .
|
||||
quotemeta($extract_to));
|
||||
"$unzip_cmd $uu -q -o".
|
||||
" -d " .quotemeta($extract_to).
|
||||
" -- ".quotemeta($archive));
|
||||
}
|
||||
}
|
||||
elsif ($archive_type =~ /\/x-rar|\/vnd\.rar/) {
|
||||
|
||||
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 466 B |
|
Before Width: | Height: | Size: 944 B |
|
Before Width: | Height: | Size: 734 B |
|
Before Width: | Height: | Size: 631 B |
|
Before Width: | Height: | Size: 956 B |
|
Before Width: | Height: | Size: 788 B |
|
Before Width: | Height: | Size: 738 B |
|
Before Width: | Height: | Size: 529 B |
|
Before Width: | Height: | Size: 864 B |
|
Before Width: | Height: | Size: 589 B |
|
Before Width: | Height: | Size: 981 B |
|
Before Width: | Height: | Size: 884 B |
|
Before Width: | Height: | Size: 608 B |
|
Before Width: | Height: | Size: 702 B |
|
Before Width: | Height: | Size: 660 B |
|
Before Width: | Height: | Size: 557 B |
|
Before Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 537 B |
|
Before Width: | Height: | Size: 522 B |
|
Before Width: | Height: | Size: 356 B |
|
Before Width: | Height: | Size: 838 B |
|
Before Width: | Height: | Size: 736 B |
|
Before Width: | Height: | Size: 294 B |
|
Before Width: | Height: | Size: 754 B |
@@ -41,8 +41,7 @@ else {
|
||||
if (&test_allowed_paths()) {
|
||||
for $path (@allowed_paths) {
|
||||
my $slashed = $path;
|
||||
$slashed .= "/"
|
||||
if ($slashed !~ /\/$/);
|
||||
$slashed .= "/" if ($slashed !~ /\/$/);
|
||||
push @tmp_list,
|
||||
grep { $slashed =~ /^\Q$_\E\// ||
|
||||
$_ =~ /\Q$slashed\E/ } @list;
|
||||
|
||||
@@ -13,7 +13,6 @@ $query = $in{'query'};
|
||||
$text{'search_results'} . " '" .
|
||||
&html_escape($query) . "'", "");
|
||||
|
||||
print $head;
|
||||
if ($in{'caseins'}) {
|
||||
$criteria = '-iname';
|
||||
}
|
||||
|
||||
85
filemin/unauthenticated/css/plain.css
Normal file
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* plain.css
|
||||
* Layout of the File Manager for themes without Bootstrap. The toolbar,
|
||||
* its menus, the dialogs and the page links are core widgets styled by
|
||||
* ui-lib.css; this file only arranges them around the listing and
|
||||
* styles the row action links and the permissions matrix.
|
||||
*/
|
||||
|
||||
/* Breadcrumbs at the left, toolbar at the right, wrapping on a narrow
|
||||
* frame */
|
||||
.filemin_head {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 8px 16px;
|
||||
}
|
||||
.filemin_head .ui_breadcrumb {
|
||||
min-width: 0;
|
||||
font-size: 1.05em;
|
||||
}
|
||||
.filemin_toolbar {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
margin-left: auto;
|
||||
}
|
||||
.filemin_pager { display: flex; }
|
||||
.filemin_page .total { color: var(--ui-fg-muted); }
|
||||
|
||||
/* Row action links hold icons and sit side by side */
|
||||
.filemin_page .action-link {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
margin-right: 4px;
|
||||
color: var(--ui-fg-muted);
|
||||
vertical-align: middle;
|
||||
}
|
||||
.filemin_page .action-link:hover { color: var(--ui-accent); }
|
||||
.filemin_page td > a > img { vertical-align: middle; }
|
||||
|
||||
/* Dialog forms sit flush inside the dialog body, and stay within it :
|
||||
* both the theme's wrapper table and the form table take the dialog
|
||||
* width with fixed columns, the label column has a set width, and the
|
||||
* inputs fit the value column instead of widening the dialog */
|
||||
.filemin_page .ui_dialog_body > table.wrapper { margin: 0; }
|
||||
.filemin_page .ui_dialog_body table.wrapper,
|
||||
.filemin_page .ui_dialog_body table.ui_table {
|
||||
width: 100%;
|
||||
table-layout: fixed;
|
||||
}
|
||||
.filemin_page .ui_dialog_body td.ui_form_label {
|
||||
width: 8.5em;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.filemin_page .ui_dialog_body td.ui_form_value select { width: 100%; }
|
||||
.filemin_page .ui_dialog_body td.ui_form_value
|
||||
input:not([type="checkbox"]):not([type="radio"]) {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
/* The permissions matrix */
|
||||
.filemin_chmod_matrix { border-collapse: collapse; }
|
||||
.filemin_chmod_matrix th, .filemin_chmod_matrix td {
|
||||
padding: 2px 12px 2px 0;
|
||||
text-align: left;
|
||||
font-weight: normal;
|
||||
}
|
||||
.filemin_chmod_matrix th { font-weight: 600; }
|
||||
.filemin_chmod_matrix input[type="checkbox"] { margin: 0; }
|
||||
|
||||
/* The entries about to be deleted */
|
||||
.filemin_delete_items {
|
||||
max-height: 180px;
|
||||
margin: 8px 0;
|
||||
padding: 8px 10px;
|
||||
overflow: auto;
|
||||
border: 1px solid var(--ui-border-soft);
|
||||
background: var(--ui-surface-2);
|
||||
font-family: var(--ui-font-mono);
|
||||
font-size: 0.92em;
|
||||
white-space: pre-wrap;
|
||||
overflow-wrap: anywhere;
|
||||
}
|
||||
@@ -1,114 +0,0 @@
|
||||
/* Styles for jQuery menu widget
|
||||
Author: Maggie Wachs, maggie@filamentgroup.com
|
||||
Date: September 2008
|
||||
*/
|
||||
|
||||
|
||||
/* REQUIRED STYLES - the menus will only render correctly with these rules */
|
||||
|
||||
.fg-menu-container { position: absolute; top:0; left:-999px; padding: .4em; overflow: hidden; }
|
||||
.fg-menu-container.fg-menu-flyout { overflow: visible; }
|
||||
|
||||
.fg-menu, .fg-menu ul { list-style-type:none; padding: 0; margin:0; }
|
||||
|
||||
.fg-menu { position:relative; }
|
||||
.fg-menu-flyout .fg-menu { position:static; }
|
||||
|
||||
.fg-menu ul { position:absolute; top:0; }
|
||||
.fg-menu ul ul { top:-1px; }
|
||||
|
||||
.fg-menu-container.fg-menu-ipod .fg-menu-content,
|
||||
.fg-menu-container.fg-menu-ipod .fg-menu-content ul { background: none !important; }
|
||||
|
||||
.fg-menu.fg-menu-scroll,
|
||||
.fg-menu ul.fg-menu-scroll { overflow: scroll; overflow-x: hidden; }
|
||||
|
||||
.fg-menu li { clear:both; float:left; width:100%; margin: 0; padding:0; border: 0; }
|
||||
.fg-menu li li { font-size:1em; } /* inner li font size must be reset so that they don't blow up */
|
||||
|
||||
.fg-menu-flyout ul ul { padding: .4em; }
|
||||
.fg-menu-flyout li { position:relative; }
|
||||
|
||||
.fg-menu-scroll { overflow: scroll; overflow-x: hidden; }
|
||||
|
||||
.fg-menu-breadcrumb { margin: 0; padding: 0; }
|
||||
|
||||
.fg-menu-footer { margin-top: .4em; padding: .4em; }
|
||||
.fg-menu-header { margin-bottom: .4em; padding: .4em; }
|
||||
|
||||
.fg-menu-breadcrumb li { float: left; list-style: none; margin: 0; padding: 0 .2em; font-size: .9em; opacity: .7; }
|
||||
.fg-menu-breadcrumb li.fg-menu-prev-list,
|
||||
.fg-menu-breadcrumb li.fg-menu-current-crumb { clear: left; float: none; opacity: 1; }
|
||||
.fg-menu-breadcrumb li.fg-menu-current-crumb { padding-top: .2em; }
|
||||
|
||||
.fg-menu-breadcrumb a,
|
||||
.fg-menu-breadcrumb span { float: left; }
|
||||
|
||||
.fg-menu-footer a:link,
|
||||
.fg-menu-footer a:visited { float:left; width:100%; text-decoration: none; }
|
||||
.fg-menu-footer a:hover,
|
||||
.fg-menu-footer a:active { }
|
||||
|
||||
.fg-menu-footer a span { float:left; cursor: pointer; }
|
||||
|
||||
.fg-menu-breadcrumb .fg-menu-prev-list a:link,
|
||||
.fg-menu-breadcrumb .fg-menu-prev-list a:visited,
|
||||
.fg-menu-breadcrumb .fg-menu-prev-list a:hover,
|
||||
.fg-menu-breadcrumb .fg-menu-prev-list a:active { background-image: none; text-decoration:none; }
|
||||
|
||||
.fg-menu-breadcrumb .fg-menu-prev-list a { float: left; padding-right: .4em; }
|
||||
.fg-menu-breadcrumb .fg-menu-prev-list a .ui-icon { float: left; }
|
||||
|
||||
.fg-menu-breadcrumb .fg-menu-current-crumb a:link,
|
||||
.fg-menu-breadcrumb .fg-menu-current-crumb a:visited,
|
||||
.fg-menu-breadcrumb .fg-menu-current-crumb a:hover,
|
||||
.fg-menu-breadcrumb .fg-menu-current-crumb a:active { display:block; background-image:none; font-size:1.3em; text-decoration:none; }
|
||||
|
||||
|
||||
|
||||
/* REQUIRED LINK STYLES: links are "display:block" by default; if the menu options are split into
|
||||
selectable node links and 'next' links, the script floats the node links left and floats the 'next' links to the right */
|
||||
|
||||
.fg-menu a:link,
|
||||
.fg-menu a:visited,
|
||||
.fg-menu a:hover,
|
||||
.fg-menu a:active { float:left; width:92%; padding:.3em 3%; text-decoration:none; outline: 0 !important; }
|
||||
|
||||
.fg-menu a { border: 1px dashed transparent; }
|
||||
|
||||
.fg-menu a.ui-state-default:link,
|
||||
.fg-menu a.ui-state-default:visited,
|
||||
.fg-menu a.ui-state-default:hover,
|
||||
.fg-menu a.ui-state-default:active,
|
||||
.fg-menu a.ui-state-hover:link,
|
||||
.fg-menu a.ui-state-hover:visited,
|
||||
.fg-menu a.ui-state-hover:hover,
|
||||
.fg-menu a.ui-state-hover:active,
|
||||
.fg-menu a.ui-state-active:link,
|
||||
.fg-menu a.ui-state-active:visited,
|
||||
.fg-menu a.ui-state-active:hover,
|
||||
.fg-menu a.ui-state-active:active { border-style: solid; font-weight: normal; }
|
||||
|
||||
.fg-menu a span { display:block; cursor:pointer; }
|
||||
|
||||
|
||||
/* SUGGESTED STYLES - for use with jQuery UI Themeroller CSS */
|
||||
|
||||
.fg-menu-indicator span { float:left; }
|
||||
.fg-menu-indicator span.ui-icon { float:right; }
|
||||
|
||||
.fg-menu-content.ui-widget-content,
|
||||
.fg-menu-content ul.ui-widget-content { border:0; }
|
||||
|
||||
|
||||
/* ICONS AND DIVIDERS */
|
||||
|
||||
.fg-menu.fg-menu-has-icons a:link,
|
||||
.fg-menu.fg-menu-has-icons a:visited,
|
||||
.fg-menu.fg-menu-has-icons a:hover,
|
||||
.fg-menu.fg-menu-has-icons a:active { padding-left:20px; }
|
||||
|
||||
.fg-menu .horizontal-divider hr, .fg-menu .horizontal-divider span { padding:0; margin:5px .6em; }
|
||||
.fg-menu .horizontal-divider hr { border:0; height:1px; }
|
||||
.fg-menu .horizontal-divider span { font-size:.9em; text-transform: uppercase; padding-left:.2em; }
|
||||
|
||||
@@ -1,648 +0,0 @@
|
||||
/*--------------------------------------------------------------------
|
||||
Scripts for creating and manipulating custom menus based on standard <ul> markup
|
||||
Version: 3.0, 03.31.2009
|
||||
|
||||
By: Maggie Costello Wachs (maggie@filamentgroup.com) and Scott Jehl (scott@filamentgroup.com)
|
||||
http://www.filamentgroup.com
|
||||
* reference articles: http://www.filamentgroup.com/lab/jquery_ipod_style_drilldown_menu/
|
||||
|
||||
Copyright (c) 2009 Filament Group
|
||||
Dual licensed under the MIT (filamentgroup.com/examples/mit-license.txt) and GPL (filamentgroup.com/examples/gpl-license.txt) licenses.
|
||||
--------------------------------------------------------------------*/
|
||||
|
||||
|
||||
var allUIMenus = [];
|
||||
|
||||
$.fn.menu = function(options){
|
||||
var caller = this;
|
||||
var options = options;
|
||||
var m = new Menu(caller, options);
|
||||
allUIMenus.push(m);
|
||||
|
||||
$(this)
|
||||
.mousedown(function(){
|
||||
if (!m.menuOpen) { m.showLoading(); };
|
||||
})
|
||||
.click(function(){
|
||||
if (m.menuOpen == false) { m.showMenu(); }
|
||||
else { m.kill(); };
|
||||
return false;
|
||||
});
|
||||
};
|
||||
|
||||
function Menu(caller, options){
|
||||
var menu = this;
|
||||
var caller = $(caller);
|
||||
var container = $('<div class="fg-menu-container ui-widget ui-widget-content ui-corner-all">'+options.content+'</div>');
|
||||
|
||||
this.menuOpen = false;
|
||||
this.menuExists = false;
|
||||
|
||||
var options = jQuery.extend({
|
||||
content: null,
|
||||
width: 180, // width of menu container, must be set or passed in to calculate widths of child menus
|
||||
maxHeight: 180, // max height of menu (if a drilldown: height does not include breadcrumb)
|
||||
positionOpts: {
|
||||
posX: 'left',
|
||||
posY: 'bottom',
|
||||
offsetX: 0,
|
||||
offsetY: 0,
|
||||
directionH: 'right',
|
||||
directionV: 'down',
|
||||
detectH: true, // do horizontal collision detection
|
||||
detectV: true, // do vertical collision detection
|
||||
linkToFront: false
|
||||
},
|
||||
showSpeed: 200, // show/hide speed in milliseconds
|
||||
callerOnState: 'ui-state-active', // class to change the appearance of the link/button when the menu is showing
|
||||
loadingState: 'ui-state-loading', // class added to the link/button while the menu is created
|
||||
linkHover: 'ui-state-hover', // class for menu option hover state
|
||||
linkHoverSecondary: 'li-hover', // alternate class, may be used for multi-level menus
|
||||
// ----- multi-level menu defaults -----
|
||||
crossSpeed: 200, // cross-fade speed for multi-level menus
|
||||
crumbDefaultText: 'Choose an option:',
|
||||
backLink: true, // in the ipod-style menu: instead of breadcrumbs, show only a 'back' link
|
||||
backLinkText: 'Back',
|
||||
flyOut: false, // multi-level menus are ipod-style by default; this parameter overrides to make a flyout instead
|
||||
flyOutOnState: 'ui-state-default',
|
||||
nextMenuLink: 'ui-icon-triangle-1-e', // class to style the link (specifically, a span within the link) used in the multi-level menu to show the next level
|
||||
topLinkText: 'All',
|
||||
nextCrumbLink: 'ui-icon-carat-1-e'
|
||||
}, options);
|
||||
|
||||
var killAllMenus = function(){
|
||||
$.each(allUIMenus, function(i){
|
||||
if (allUIMenus[i].menuOpen) { allUIMenus[i].kill(); };
|
||||
});
|
||||
};
|
||||
|
||||
this.kill = function(){
|
||||
caller
|
||||
.removeClass(options.loadingState)
|
||||
.removeClass('fg-menu-open')
|
||||
.removeClass(options.callerOnState);
|
||||
container.find('li').removeClass(options.linkHoverSecondary).find('a').removeClass(options.linkHover);
|
||||
if (options.flyOutOnState) { container.find('li a').removeClass(options.flyOutOnState); };
|
||||
if (options.callerOnState) { caller.removeClass(options.callerOnState); };
|
||||
if (container.is('.fg-menu-ipod')) { menu.resetDrilldownMenu(); };
|
||||
if (container.is('.fg-menu-flyout')) { menu.resetFlyoutMenu(); };
|
||||
container.parent().hide();
|
||||
menu.menuOpen = false;
|
||||
$(document).unbind('click', killAllMenus);
|
||||
$(document).unbind('keydown');
|
||||
};
|
||||
|
||||
this.showLoading = function(){
|
||||
caller.addClass(options.loadingState);
|
||||
};
|
||||
|
||||
this.showMenu = function(){
|
||||
killAllMenus();
|
||||
if (!menu.menuExists) { menu.create() };
|
||||
caller
|
||||
.addClass('fg-menu-open')
|
||||
.addClass(options.callerOnState);
|
||||
container.parent().show().click(function(){ menu.kill(); return false; });
|
||||
container.hide().slideDown(options.showSpeed).find('.fg-menu:eq(0)');
|
||||
menu.menuOpen = true;
|
||||
caller.removeClass(options.loadingState);
|
||||
$(document).click(killAllMenus);
|
||||
|
||||
// assign key events
|
||||
$(document).keydown(function(event){
|
||||
var e;
|
||||
if (event.which !="") { e = event.which; }
|
||||
else if (event.charCode != "") { e = event.charCode; }
|
||||
else if (event.keyCode != "") { e = event.keyCode; }
|
||||
|
||||
var menuType = ($(event.target).parents('div').is('.fg-menu-flyout')) ? 'flyout' : 'ipod' ;
|
||||
|
||||
switch(e) {
|
||||
case 37: // left arrow
|
||||
if (menuType == 'flyout') {
|
||||
$(event.target).trigger('mouseout');
|
||||
if ($('.'+options.flyOutOnState).length > 0) { $('.'+options.flyOutOnState).trigger('mouseover'); };
|
||||
};
|
||||
|
||||
if (menuType == 'ipod') {
|
||||
$(event.target).trigger('mouseout');
|
||||
if ($('.fg-menu-footer').find('a').length > 0) { $('.fg-menu-footer').find('a').trigger('click'); };
|
||||
if ($('.fg-menu-header').find('a').length > 0) { $('.fg-menu-current-crumb').prev().find('a').trigger('click'); };
|
||||
if ($('.fg-menu-current').prev().is('.fg-menu-indicator')) {
|
||||
$('.fg-menu-current').prev().trigger('mouseover');
|
||||
};
|
||||
};
|
||||
return false;
|
||||
break;
|
||||
|
||||
case 38: // up arrow
|
||||
if ($(event.target).is('.' + options.linkHover)) {
|
||||
var prevLink = $(event.target).parent().prev().find('a:eq(0)');
|
||||
if (prevLink.length > 0) {
|
||||
$(event.target).trigger('mouseout');
|
||||
prevLink.trigger('mouseover');
|
||||
};
|
||||
}
|
||||
else { container.find('a:eq(0)').trigger('mouseover'); }
|
||||
return false;
|
||||
break;
|
||||
|
||||
case 39: // right arrow
|
||||
if ($(event.target).is('.fg-menu-indicator')) {
|
||||
if (menuType == 'flyout') {
|
||||
$(event.target).next().find('a:eq(0)').trigger('mouseover');
|
||||
}
|
||||
else if (menuType == 'ipod') {
|
||||
$(event.target).trigger('click');
|
||||
setTimeout(function(){
|
||||
$(event.target).next().find('a:eq(0)').trigger('mouseover');
|
||||
}, options.crossSpeed);
|
||||
};
|
||||
};
|
||||
return false;
|
||||
break;
|
||||
|
||||
case 40: // down arrow
|
||||
if ($(event.target).is('.' + options.linkHover)) {
|
||||
var nextLink = $(event.target).parent().next().find('a:eq(0)');
|
||||
if (nextLink.length > 0) {
|
||||
$(event.target).trigger('mouseout');
|
||||
nextLink.trigger('mouseover');
|
||||
};
|
||||
}
|
||||
else { container.find('a:eq(0)').trigger('mouseover'); }
|
||||
return false;
|
||||
break;
|
||||
|
||||
case 27: // escape
|
||||
killAllMenus();
|
||||
break;
|
||||
|
||||
case 13: // enter
|
||||
if ($(event.target).is('.fg-menu-indicator') && menuType == 'ipod') {
|
||||
$(event.target).trigger('click');
|
||||
setTimeout(function(){
|
||||
$(event.target).next().find('a:eq(0)').trigger('mouseover');
|
||||
}, options.crossSpeed);
|
||||
};
|
||||
break;
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
this.create = function() {
|
||||
container.css({ width: options.width }).appendTo('body').find('ul:first').not('.fg-menu-breadcrumb').addClass('fg-menu');
|
||||
container.find('ul, li a').addClass('ui-corner-all');
|
||||
|
||||
// aria roles & attributes
|
||||
container.find('ul').attr('role', 'menu').eq(0).attr('aria-activedescendant','active-menuitem').attr('aria-labelledby', caller.attr('id'));
|
||||
container.find('li').attr('role', 'menuitem');
|
||||
container.find('li:has(ul)').attr('aria-haspopup', 'true').find('ul').attr('aria-expanded', 'false');
|
||||
container.find('a').attr('tabindex', '-1');
|
||||
|
||||
// when there are multiple levels of hierarchy, create flyout or drilldown menu
|
||||
if (container.find('ul').length > 1) {
|
||||
if (options.flyOut) { menu.flyout(container, options); }
|
||||
else { menu.drilldown(container, options); }
|
||||
}
|
||||
else {
|
||||
container.find('a').click(function(){
|
||||
menu.chooseItem(this);
|
||||
return false;
|
||||
});
|
||||
};
|
||||
|
||||
if (options.linkHover) {
|
||||
var allLinks = container.find('.fg-menu li a');
|
||||
allLinks.hover(
|
||||
function(){
|
||||
var menuitem = $(this);
|
||||
$('.'+options.linkHover).removeClass(options.linkHover).blur().parent().removeAttr('id');
|
||||
$(this).addClass(options.linkHover).focus().parent().attr('id','active-menuitem');
|
||||
},
|
||||
function(){
|
||||
$(this).removeClass(options.linkHover).blur().parent().removeAttr('id');
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
if (options.linkHoverSecondary) {
|
||||
container.find('.fg-menu li').hover(
|
||||
function(){
|
||||
$(this).siblings('li').removeClass(options.linkHoverSecondary);
|
||||
if (options.flyOutOnState) { $(this).siblings('li').find('a').removeClass(options.flyOutOnState); }
|
||||
$(this).addClass(options.linkHoverSecondary);
|
||||
},
|
||||
function(){ $(this).removeClass(options.linkHoverSecondary); }
|
||||
);
|
||||
};
|
||||
|
||||
menu.setPosition(container, caller, options);
|
||||
menu.menuExists = true;
|
||||
|
||||
// Hide empty
|
||||
container.find('a:empty').parent('li').hide()
|
||||
};
|
||||
|
||||
this.chooseItem = function(item){
|
||||
menu.kill();
|
||||
// edit this for your own custom function/callback:
|
||||
$('#menuSelection').text($(item).text());
|
||||
location.href = $(item).attr('href');
|
||||
};
|
||||
};
|
||||
|
||||
Menu.prototype.flyout = function(container, options) {
|
||||
var menu = this;
|
||||
|
||||
this.resetFlyoutMenu = function(){
|
||||
var allLists = container.find('ul ul');
|
||||
allLists.removeClass('ui-widget-content').hide();
|
||||
};
|
||||
|
||||
container.addClass('fg-menu-flyout').find('li:has(ul)').each(function(){
|
||||
var linkWidth = container.width();
|
||||
var showTimer, hideTimer;
|
||||
var allSubLists = $(this).find('ul');
|
||||
|
||||
allSubLists.css({ left: linkWidth, width: linkWidth }).hide();
|
||||
|
||||
$(this).find('a:eq(0)').addClass('fg-menu-indicator').html('<span>' + $(this).find('a:eq(0)').text() + '</span><span class="ui-icon '+options.nextMenuLink+'"></span>').hover(
|
||||
function(){
|
||||
clearTimeout(hideTimer);
|
||||
var subList = $(this).next();
|
||||
if (!fitVertical(subList, $(this).offset().top)) { subList.css({ top: 'auto', bottom: 0 }); };
|
||||
if (!fitHorizontal(subList, $(this).offset().left + 100)) { subList.css({ left: 'auto', right: linkWidth, 'z-index': 999 }); };
|
||||
showTimer = setTimeout(function(){
|
||||
subList.addClass('ui-widget-content').show(options.showSpeed).attr('aria-expanded', 'true');
|
||||
}, 300);
|
||||
},
|
||||
function(){
|
||||
clearTimeout(showTimer);
|
||||
var subList = $(this).next();
|
||||
hideTimer = setTimeout(function(){
|
||||
subList.removeClass('ui-widget-content').hide(options.showSpeed).attr('aria-expanded', 'false');
|
||||
}, 400);
|
||||
}
|
||||
);
|
||||
|
||||
$(this).find('ul a').hover(
|
||||
function(){
|
||||
clearTimeout(hideTimer);
|
||||
if ($(this).parents('ul').prev().is('a.fg-menu-indicator')) {
|
||||
$(this).parents('ul').prev().addClass(options.flyOutOnState);
|
||||
}
|
||||
},
|
||||
function(){
|
||||
hideTimer = setTimeout(function(){
|
||||
allSubLists.hide(options.showSpeed);
|
||||
container.find(options.flyOutOnState).removeClass(options.flyOutOnState);
|
||||
}, 500);
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
container.find('a').click(function(){
|
||||
menu.chooseItem(this);
|
||||
return false;
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
Menu.prototype.drilldown = function(container, options) {
|
||||
var menu = this;
|
||||
var topList = container.find('.fg-menu');
|
||||
var breadcrumb = $('<ul class="fg-menu-breadcrumb ui-widget-header ui-corner-all ui-helper-clearfix"></ul>');
|
||||
var crumbDefaultHeader = $('<li class="fg-menu-breadcrumb-text">'+options.crumbDefaultText+'</li>');
|
||||
var firstCrumbText = (options.backLink) ? options.backLinkText : options.topLinkText;
|
||||
var firstCrumbClass = (options.backLink) ? 'fg-menu-prev-list' : 'fg-menu-all-lists';
|
||||
var firstCrumbLinkClass = (options.backLink) ? 'ui-state-default ui-corner-all' : '';
|
||||
var firstCrumbIcon = (options.backLink) ? '<span class="ui-icon ui-icon-triangle-1-w"></span>' : '';
|
||||
var firstCrumb = $('<li class="'+firstCrumbClass+'"><a href="#" class="'+firstCrumbLinkClass+'">'+firstCrumbIcon+firstCrumbText+'</a></li>');
|
||||
|
||||
container.addClass('fg-menu-ipod');
|
||||
|
||||
if (options.backLink) { breadcrumb.addClass('fg-menu-footer').appendTo(container).hide(); }
|
||||
else { breadcrumb.addClass('fg-menu-header').prependTo(container); };
|
||||
breadcrumb.append(crumbDefaultHeader);
|
||||
|
||||
var checkMenuHeight = function(el){
|
||||
if (el.height() > options.maxHeight) { el.addClass('fg-menu-scroll') };
|
||||
el.css({ height: options.maxHeight });
|
||||
};
|
||||
|
||||
var resetChildMenu = function(el){ el.removeClass('fg-menu-scroll').removeClass('fg-menu-current').height('auto'); };
|
||||
|
||||
this.resetDrilldownMenu = function(){
|
||||
$('.fg-menu-current').removeClass('fg-menu-current');
|
||||
topList.animate({ left: 0 }, options.crossSpeed, function(){
|
||||
$(this).find('ul').each(function(){
|
||||
$(this).hide();
|
||||
resetChildMenu($(this));
|
||||
});
|
||||
topList.addClass('fg-menu-current');
|
||||
});
|
||||
$('.fg-menu-all-lists').find('span').remove();
|
||||
breadcrumb.empty().append(crumbDefaultHeader);
|
||||
$('.fg-menu-footer').empty().hide();
|
||||
checkMenuHeight(topList);
|
||||
};
|
||||
|
||||
topList
|
||||
.addClass('fg-menu-content fg-menu-current ui-widget-content ui-helper-clearfix')
|
||||
.css({ width: container.width() })
|
||||
.find('ul')
|
||||
.css({ width: container.width(), left: container.width() })
|
||||
.addClass('ui-widget-content')
|
||||
.hide();
|
||||
checkMenuHeight(topList);
|
||||
|
||||
topList.find('a').each(function(){
|
||||
// if the link opens a child menu:
|
||||
if ($(this).next().is('ul')) {
|
||||
$(this)
|
||||
.addClass('fg-menu-indicator')
|
||||
.each(function(){ $(this).html('<span>' + $(this).text() + '</span><span class="ui-icon '+options.nextMenuLink+'"></span>'); })
|
||||
.click(function(){ // ----- show the next menu
|
||||
var nextList = $(this).next();
|
||||
var parentUl = $(this).parents('ul:eq(0)');
|
||||
var parentLeft = (parentUl.is('.fg-menu-content')) ? 0 : parseFloat(topList.css('left'));
|
||||
var nextLeftVal = Math.round(parentLeft - parseFloat(container.width()));
|
||||
var footer = $('.fg-menu-footer');
|
||||
|
||||
// show next menu
|
||||
resetChildMenu(parentUl);
|
||||
checkMenuHeight(nextList);
|
||||
topList.animate({ left: nextLeftVal }, options.crossSpeed);
|
||||
nextList.show().addClass('fg-menu-current').attr('aria-expanded', 'true');
|
||||
|
||||
var setPrevMenu = function(backlink){
|
||||
var b = backlink;
|
||||
var c = $('.fg-menu-current');
|
||||
var prevList = c.parents('ul:eq(0)');
|
||||
c.hide().attr('aria-expanded', 'false');
|
||||
resetChildMenu(c);
|
||||
checkMenuHeight(prevList);
|
||||
prevList.addClass('fg-menu-current').attr('aria-expanded', 'true');
|
||||
if (prevList.hasClass('fg-menu-content')) { b.remove(); footer.hide(); };
|
||||
};
|
||||
|
||||
// initialize "back" link
|
||||
if (options.backLink) {
|
||||
if (footer.find('a').length == 0) {
|
||||
footer.show();
|
||||
$('<a href="#"><span class="ui-icon ui-icon-triangle-1-w"></span> <span>Back</span></a>')
|
||||
.appendTo(footer)
|
||||
.click(function(){ // ----- show the previous menu
|
||||
var b = $(this);
|
||||
var prevLeftVal = parseFloat(topList.css('left')) + container.width();
|
||||
topList.animate({ left: prevLeftVal }, options.crossSpeed, function(){
|
||||
setPrevMenu(b);
|
||||
});
|
||||
return false;
|
||||
});
|
||||
}
|
||||
}
|
||||
// or initialize top breadcrumb
|
||||
else {
|
||||
if (breadcrumb.find('li').length == 1){
|
||||
breadcrumb.empty().append(firstCrumb);
|
||||
firstCrumb.find('a').click(function(){
|
||||
menu.resetDrilldownMenu();
|
||||
return false;
|
||||
});
|
||||
}
|
||||
$('.fg-menu-current-crumb').removeClass('fg-menu-current-crumb');
|
||||
var crumbText = $(this).find('span:eq(0)').text();
|
||||
var newCrumb = $('<li class="fg-menu-current-crumb"><a href="javascript://" class="fg-menu-crumb">'+crumbText+'</a></li>');
|
||||
newCrumb
|
||||
.appendTo(breadcrumb)
|
||||
.find('a').click(function(){
|
||||
if ($(this).parent().is('.fg-menu-current-crumb')){
|
||||
menu.chooseItem(this);
|
||||
}
|
||||
else {
|
||||
var newLeftVal = - ($('.fg-menu-current').parents('ul').length - 1) * 180;
|
||||
topList.animate({ left: newLeftVal }, options.crossSpeed, function(){
|
||||
setPrevMenu();
|
||||
});
|
||||
|
||||
// make this the current crumb, delete all breadcrumbs after this one, and navigate to the relevant menu
|
||||
$(this).parent().addClass('fg-menu-current-crumb').find('span').remove();
|
||||
$(this).parent().nextAll().remove();
|
||||
};
|
||||
return false;
|
||||
});
|
||||
newCrumb.prev().append(' <span class="ui-icon '+options.nextCrumbLink+'"></span>');
|
||||
};
|
||||
return false;
|
||||
});
|
||||
}
|
||||
// if the link is a leaf node (doesn't open a child menu)
|
||||
else {
|
||||
$(this).click(function(){
|
||||
menu.chooseItem(this);
|
||||
return false;
|
||||
});
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
/* Menu.prototype.setPosition parameters (defaults noted with *):
|
||||
referrer = the link (or other element) used to show the overlaid object
|
||||
settings = can override the defaults:
|
||||
- posX/Y: where the top left corner of the object should be positioned in relation to its referrer.
|
||||
X: left*, center, right
|
||||
Y: top, center, bottom*
|
||||
- offsetX/Y: the number of pixels to be offset from the x or y position. Can be a positive or negative number.
|
||||
- directionH/V: where the entire menu should appear in relation to its referrer.
|
||||
Horizontal: left*, right
|
||||
Vertical: up, down*
|
||||
- detectH/V: detect the viewport horizontally / vertically
|
||||
- linkToFront: copy the menu link and place it on top of the menu (visual effect to make it look like it overlaps the object) */
|
||||
|
||||
Menu.prototype.setPosition = function(widget, caller, options) {
|
||||
var el = widget;
|
||||
var referrer = caller;
|
||||
var dims = {
|
||||
refX: referrer.offset().left,
|
||||
refY: referrer.offset().top,
|
||||
refW: referrer.getTotalWidth(),
|
||||
refH: referrer.getTotalHeight()
|
||||
};
|
||||
var options = options;
|
||||
var xVal, yVal;
|
||||
|
||||
var helper = $('<div class="positionHelper"></div>');
|
||||
helper.css({ position: 'absolute', left: dims.refX, top: dims.refY, width: dims.refW, height: dims.refH });
|
||||
el.wrap(helper);
|
||||
|
||||
// get X pos
|
||||
switch(options.positionOpts.posX) {
|
||||
case 'left': xVal = 0;
|
||||
break;
|
||||
case 'center': xVal = dims.refW / 2;
|
||||
break;
|
||||
case 'right': xVal = dims.refW;
|
||||
break;
|
||||
};
|
||||
|
||||
// get Y pos
|
||||
switch(options.positionOpts.posY) {
|
||||
case 'top': yVal = 0;
|
||||
break;
|
||||
case 'center': yVal = dims.refH / 2;
|
||||
break;
|
||||
case 'bottom': yVal = dims.refH;
|
||||
break;
|
||||
};
|
||||
|
||||
// add the offsets (zero by default)
|
||||
xVal += options.positionOpts.offsetX;
|
||||
yVal += options.positionOpts.offsetY;
|
||||
|
||||
// position the object vertically
|
||||
if (options.positionOpts.directionV == 'up') {
|
||||
el.css({ top: 'auto', bottom: yVal });
|
||||
if (options.positionOpts.detectV && !fitVertical(el)) {
|
||||
el.css({ bottom: 'auto', top: yVal });
|
||||
}
|
||||
}
|
||||
else {
|
||||
el.css({ bottom: 'auto', top: yVal });
|
||||
if (options.positionOpts.detectV && !fitVertical(el)) {
|
||||
el.css({ top: 'auto', bottom: yVal });
|
||||
}
|
||||
};
|
||||
|
||||
// and horizontally
|
||||
if (options.positionOpts.directionH == 'left') {
|
||||
el.css({ left: 'auto', right: xVal });
|
||||
if (options.positionOpts.detectH && !fitHorizontal(el)) {
|
||||
el.css({ right: 'auto', left: xVal });
|
||||
}
|
||||
}
|
||||
else {
|
||||
el.css({ right: 'auto', left: xVal });
|
||||
if (options.positionOpts.detectH && !fitHorizontal(el)) {
|
||||
el.css({ left: 'auto', right: xVal });
|
||||
}
|
||||
};
|
||||
|
||||
// if specified, clone the referring element and position it so that it appears on top of the menu
|
||||
if (options.positionOpts.linkToFront) {
|
||||
referrer.clone().addClass('linkClone').css({
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
right: 'auto',
|
||||
bottom: 'auto',
|
||||
left: 0,
|
||||
width: referrer.width(),
|
||||
height: referrer.height()
|
||||
}).insertAfter(el);
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/* Utilities to sort and find viewport dimensions */
|
||||
|
||||
function sortBigToSmall(a, b) { return b - a; };
|
||||
|
||||
jQuery.fn.getTotalWidth = function(){
|
||||
return $(this).width() + parseInt($(this).css('paddingRight')) + parseInt($(this).css('paddingLeft')) + parseInt($(this).css('borderRightWidth')) + parseInt($(this).css('borderLeftWidth'));
|
||||
};
|
||||
|
||||
jQuery.fn.getTotalHeight = function(){
|
||||
return $(this).height() + parseInt($(this).css('paddingTop')) + parseInt($(this).css('paddingBottom')) + parseInt($(this).css('borderTopWidth')) + parseInt($(this).css('borderBottomWidth'));
|
||||
};
|
||||
|
||||
function getScrollTop(){
|
||||
return self.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;
|
||||
};
|
||||
|
||||
function getScrollLeft(){
|
||||
return self.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft;
|
||||
};
|
||||
|
||||
function getWindowHeight(){
|
||||
var de = document.documentElement;
|
||||
return self.innerHeight || (de && de.clientHeight) || document.body.clientHeight;
|
||||
};
|
||||
|
||||
function getWindowWidth(){
|
||||
var de = document.documentElement;
|
||||
return self.innerWidth || (de && de.clientWidth) || document.body.clientWidth;
|
||||
};
|
||||
|
||||
/* Utilities to test whether an element will fit in the viewport
|
||||
Parameters:
|
||||
el = element to position, required
|
||||
leftOffset / topOffset = optional parameter if the offset cannot be calculated (i.e., if the object is in the DOM but is set to display: 'none') */
|
||||
|
||||
function fitHorizontal(el, leftOffset){
|
||||
var leftVal = parseInt(leftOffset) || $(el).offset().left;
|
||||
return (leftVal + $(el).width() <= getWindowWidth() + getScrollLeft() && leftVal - getScrollLeft() >= 0);
|
||||
};
|
||||
|
||||
function fitVertical(el, topOffset){
|
||||
var topVal = parseInt(topOffset) || $(el).offset().top;
|
||||
return (topVal + $(el).height() <= getWindowHeight() + getScrollTop() && topVal - getScrollTop() >= 0);
|
||||
};
|
||||
|
||||
/*--------------------------------------------------------------------
|
||||
* javascript method: "pxToEm"
|
||||
* by:
|
||||
Scott Jehl (scott@filamentgroup.com)
|
||||
Maggie Wachs (maggie@filamentgroup.com)
|
||||
http://www.filamentgroup.com
|
||||
*
|
||||
* Copyright (c) 2008 Filament Group
|
||||
* Dual licensed under the MIT (filamentgroup.com/examples/mit-license.txt) and GPL (filamentgroup.com/examples/gpl-license.txt) licenses.
|
||||
*
|
||||
* Description: Extends the native Number and String objects with pxToEm method. pxToEm converts a pixel value to ems depending on inherited font size.
|
||||
* Article: http://www.filamentgroup.com/lab/retaining_scalable_interfaces_with_pixel_to_em_conversion/
|
||||
* Demo: http://www.filamentgroup.com/examples/pxToEm/
|
||||
*
|
||||
* Options:
|
||||
scope: string or jQuery selector for font-size scoping
|
||||
reverse: Boolean, true reverses the conversion to em-px
|
||||
* Dependencies: jQuery library
|
||||
* Usage Example: myPixelValue.pxToEm(); or myPixelValue.pxToEm({'scope':'#navigation', reverse: true});
|
||||
*
|
||||
* Version: 2.0, 08.01.2008
|
||||
* Changelog:
|
||||
* 08.02.2007 initial Version 1.0
|
||||
* 08.01.2008 - fixed font-size calculation for IE
|
||||
--------------------------------------------------------------------*/
|
||||
|
||||
Number.prototype.pxToEm = String.prototype.pxToEm = function(settings){
|
||||
//set defaults
|
||||
settings = jQuery.extend({
|
||||
scope: 'body',
|
||||
reverse: false
|
||||
}, settings);
|
||||
|
||||
var pxVal = (this == '') ? 0 : parseFloat(this);
|
||||
var scopeVal;
|
||||
var getWindowWidth = function(){
|
||||
var de = document.documentElement;
|
||||
return self.innerWidth || (de && de.clientWidth) || document.body.clientWidth;
|
||||
};
|
||||
|
||||
/* When a percentage-based font-size is set on the body, IE returns that percent of the window width as the font-size.
|
||||
For example, if the body font-size is 62.5% and the window width is 1000px, IE will return 625px as the font-size.
|
||||
When this happens, we calculate the correct body font-size (%) and multiply it by 16 (the standard browser font size)
|
||||
to get an accurate em value. */
|
||||
|
||||
if (settings.scope == 'body' && $.browser.msie && (parseFloat($('body').css('font-size')) / getWindowWidth()).toFixed(1) > 0.0) {
|
||||
var calcFontSize = function(){
|
||||
return (parseFloat($('body').css('font-size'))/getWindowWidth()).toFixed(3) * 16;
|
||||
};
|
||||
scopeVal = calcFontSize();
|
||||
}
|
||||
else { scopeVal = parseFloat(jQuery(settings.scope).css("font-size")); };
|
||||
|
||||
var result = (settings.reverse == true) ? (pxVal * scopeVal).toFixed(2) + 'px' : (pxVal / scopeVal).toFixed(2) + 'em';
|
||||
return result;
|
||||
};
|
||||
|
Before Width: | Height: | Size: 6.9 KiB |
|
Before Width: | Height: | Size: 6.9 KiB |
|
Before Width: | Height: | Size: 4.5 KiB |
|
Before Width: | Height: | Size: 6.9 KiB |
|
Before Width: | Height: | Size: 4.5 KiB |
|
Before Width: | Height: | Size: 6.3 KiB |
2
filemin/unauthenticated/jquery/jquery.min.js
vendored
@@ -1,475 +0,0 @@
|
||||
$( document ).ready(function() {
|
||||
/*
|
||||
$( "input[title]" ).tooltip({
|
||||
position: {
|
||||
my: "left top",
|
||||
at: "right+5 top-5"
|
||||
}
|
||||
});
|
||||
/*
|
||||
$( "a[title]" ).tooltip({
|
||||
position: {
|
||||
my: "bottom center",
|
||||
at: "bottom+30"
|
||||
}
|
||||
});*/
|
||||
$('tr').removeAttr('onmouseover');
|
||||
$('tr').removeAttr('onmouseout');
|
||||
$('input').removeAttr('onclick');
|
||||
$('._select-unselect_').change(function() { selectUnselect($(this)); });
|
||||
|
||||
// BUTTONS
|
||||
$('.fg-button').hover(
|
||||
function(){ $(this).removeClass('ui-state-default').addClass('ui-state-focus'); },
|
||||
function(){ $(this).removeClass('ui-state-focus').addClass('ui-state-default'); }
|
||||
);
|
||||
|
||||
// MENUS
|
||||
$('#flat').menu({
|
||||
content: $('#flat').next().html(), // grab content from this page
|
||||
showSpeed: 100
|
||||
});
|
||||
});
|
||||
|
||||
window.onload = function() {
|
||||
var checkboxes = document.getElementsByClassName('ui_checkbox');
|
||||
for(var i = 0; i < checkboxes.length; i++) {
|
||||
checkboxes[i].onclick = function() {
|
||||
var row = this.parentNode.parentNode;
|
||||
if (this.checked) {
|
||||
row.className = row.className + ' checked';
|
||||
}
|
||||
else {
|
||||
row.className = row.className.replace(' checked', '');
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function countUploads(files) {
|
||||
if(files.files.length = 0) return;
|
||||
var info = '';
|
||||
for (i = 0; i < files.files.length; i++) {
|
||||
info += files.files[i].name + '<br>';
|
||||
}
|
||||
$('#readyForUploadList').html(info);
|
||||
}
|
||||
|
||||
function selectAll() {
|
||||
var rows = document.getElementsByClassName('ui_checked_columns');
|
||||
|
||||
for (i = 0; i < rows.length; i++) {
|
||||
var input = rows[i].getElementsByTagName('input')[0];
|
||||
if (!input.checked) {
|
||||
rowClick(rows[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function invertSelection() {
|
||||
var rows = document.getElementsByClassName('ui_checked_columns');
|
||||
|
||||
for (i = 0; i < rows.length; i++)
|
||||
rowClick(rows[i]);
|
||||
}
|
||||
|
||||
function compressDialog() {
|
||||
if(checkSelected()) {
|
||||
$( "#compressDialog" ).dialog({
|
||||
modal: true,
|
||||
buttons: {
|
||||
"Compress": function() {
|
||||
compressSelected();
|
||||
},
|
||||
"Cancel": function() {
|
||||
$( this ).dialog( "close" );
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function compressSelected() {
|
||||
var filename = $('#compressSelectedForm input[name=filename]').val();
|
||||
if (filename != null && filename != "") {
|
||||
var method = $('#compressSelectedForm select[name=method] option:selected').val();
|
||||
$('#list_form').attr('action', "compress.cgi?arch=" + filename + "&method=" + method);
|
||||
$('#list_form').submit();
|
||||
}
|
||||
}
|
||||
|
||||
function removeSelected() {
|
||||
if(checkSelected()) {
|
||||
$('#items-to-remove').html('');
|
||||
|
||||
$(".ui_checked_checkbox input[type='checkbox']:checked").each(function() {
|
||||
$('#items-to-remove').append($(this).val() + '<br>');
|
||||
});
|
||||
|
||||
$( "#removeDialog" ).dialog({
|
||||
modal: true,
|
||||
buttons: {
|
||||
"YES": function() {
|
||||
document.forms['list_form'].action = "delete.cgi";
|
||||
document.forms['list_form'].submit();
|
||||
},
|
||||
"NO": function() {
|
||||
$( this ).dialog( "close" );
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function chmodDialog() {
|
||||
if(checkSelected()) {
|
||||
$( "#chmodDialog" ).dialog({
|
||||
modal: true,
|
||||
minWidth: 550,
|
||||
buttons: {
|
||||
"Change": function() {
|
||||
chmodSelected();
|
||||
},
|
||||
"Cancel": function() {
|
||||
$( this ).dialog( "close" );
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function chmodSelected() {
|
||||
var perms = $('#perms').val();
|
||||
if (perms != null && perms != "") {
|
||||
var applyto = $('#chmodForm select[name=applyto] option:selected').val();
|
||||
$('#list_form').attr('action', "chmod.cgi?perms=" + perms + "&applyto=" + applyto);
|
||||
$('#list_form').submit();
|
||||
}
|
||||
}
|
||||
|
||||
function chownDialog() {
|
||||
if(checkSelected()) {
|
||||
$( "#chownDialog" ).dialog({
|
||||
modal: true,
|
||||
buttons: {
|
||||
"Change": function() {
|
||||
chownSelected();
|
||||
},
|
||||
"Cancel": function() {
|
||||
$( this ).dialog( "close" );
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function chownSelected() {
|
||||
var owner = $('#chownForm input[name=owner]').val();
|
||||
var group = $('#chownForm input[name=group]').val();
|
||||
var recursive = $('#chown-recursive').prop('checked');
|
||||
|
||||
if (owner != null && owner != "" && group != null && group != "") {
|
||||
$('#list_form').attr('action', "chown.cgi?owner=" + owner + "&group=" + group + "&recursive=" + recursive);
|
||||
$('#list_form').submit();
|
||||
}
|
||||
}
|
||||
|
||||
function chattrDialog() {
|
||||
if(checkSelected()) {
|
||||
$( "#chattrDialog" ).dialog({
|
||||
modal: true,
|
||||
buttons: {
|
||||
"Change": function() {
|
||||
chattrSelected();
|
||||
},
|
||||
"Cancel": function() {
|
||||
$( this ).dialog( "close" );
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function chattrSelected() {
|
||||
var label = $('#chattrForm input[name=label]').val(),
|
||||
recursive = $('#chattr-recursive').prop('checked');
|
||||
|
||||
if (label != null && label != "") {
|
||||
$('#list_form').attr('action', "chattr.cgi?label=" + encodeURIComponent(label) + "&recursive=" + recursive);
|
||||
$('#list_form').submit();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function chconDialog() {
|
||||
if(checkSelected()) {
|
||||
$( "#chconDialog" ).dialog({
|
||||
modal: true,
|
||||
buttons: {
|
||||
"Change": function() {
|
||||
chconSelected();
|
||||
},
|
||||
"Cancel": function() {
|
||||
$( this ).dialog( "close" );
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function chconSelected() {
|
||||
var label = $('#chconForm input[name=label]').val(),
|
||||
recursive = $('#chcon-recursive').prop('checked');
|
||||
|
||||
if (label != null && label != "") {
|
||||
$('#list_form').attr('action', "chcon.cgi?label=" + label + "&recursive=" + recursive);
|
||||
$('#list_form').submit();
|
||||
}
|
||||
}
|
||||
|
||||
function aclsDialog() {
|
||||
if(checkSelected()) {
|
||||
$( "#aclsDialog" ).dialog({
|
||||
modal: true,
|
||||
buttons: {
|
||||
"Change": function() {
|
||||
aclsSelected();
|
||||
},
|
||||
"Cancel": function() {
|
||||
$( this ).dialog( "close" );
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function aclsSelected() {
|
||||
var aclsForm = $('#aclsForm').serialize();
|
||||
$('#list_form').attr('action', "setfacl.cgi?" + aclsForm);
|
||||
$('#list_form').submit();
|
||||
}
|
||||
|
||||
function renameDialog(file) {
|
||||
$("#renameForm input[name=name]").val(file);
|
||||
$("#renameForm input[name=file]").val(file);
|
||||
$( "#renameDialog" ).dialog({
|
||||
modal: true,
|
||||
buttons: {
|
||||
"Rename": function() {
|
||||
renameSelected();
|
||||
},
|
||||
"Cancel": function() {
|
||||
$( this ).dialog( "close" );
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function renameSelected() {
|
||||
var name = $('#renameForm input[name=name]').val();
|
||||
var file = $('#renameForm input[name=file]').val();
|
||||
if (name != null && name != "" && name != file) {
|
||||
$('#renameForm').submit();
|
||||
}
|
||||
}
|
||||
|
||||
function copySelected() {
|
||||
if(checkSelected()) {
|
||||
document.forms['list_form'].action = "copy.cgi";
|
||||
document.forms['list_form'].submit();
|
||||
}
|
||||
}
|
||||
|
||||
function cutSelected() {
|
||||
if(checkSelected()) {
|
||||
document.forms['list_form'].action = "cut.cgi";
|
||||
document.forms['list_form'].submit();
|
||||
}
|
||||
}
|
||||
|
||||
function viewReadyForUpload() {
|
||||
$( "#readyForUploadDialog" ).dialog({
|
||||
modal: true,
|
||||
buttons: {
|
||||
"OK": function() {
|
||||
uploadFiles();
|
||||
},
|
||||
"Cancel": function() {
|
||||
$( this ).dialog( "close" );
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function browseForUpload() {
|
||||
var files = document.getElementById('upfiles');
|
||||
files.click();
|
||||
return true;
|
||||
}
|
||||
|
||||
function uploadFiles() {
|
||||
var files = document.getElementById('upfiles');
|
||||
if (files.files.length > 0)
|
||||
$('#upload-form').submit();
|
||||
else
|
||||
files.click();
|
||||
}
|
||||
|
||||
function createFolderDialog() {
|
||||
$( "#createFolderDialog" ).dialog({
|
||||
modal: true,
|
||||
buttons: {
|
||||
"Create": function() {
|
||||
createFolder();
|
||||
},
|
||||
"Cancel": function() {
|
||||
$( this ).dialog( "close" );
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function createFolder() {
|
||||
var name = $('#createFolderForm input[name=name]').val();
|
||||
if (name != null && name != "")
|
||||
$("#createFolderForm").submit();
|
||||
else {
|
||||
/* var tooltip = $('#createFolderForm input[name=name]').tooltip({
|
||||
position: {
|
||||
my: "left top",
|
||||
at: "right+5 top-5"
|
||||
}
|
||||
});
|
||||
tooltip.tooltip('open');*/
|
||||
$('#createFolderForm input[name=name]').tooltip('open');
|
||||
}
|
||||
}
|
||||
|
||||
function createFileDialog() {
|
||||
$( "#createFileDialog" ).dialog({
|
||||
modal: true,
|
||||
buttons: {
|
||||
"Create": function() {
|
||||
createFile();
|
||||
},
|
||||
"Cancel": function() {
|
||||
$( this ).dialog( "close" );
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function createFile() {
|
||||
var name = $('#createFileForm input[name=name]').val();
|
||||
if (name != null && name != "") {
|
||||
$("#createFileForm").submit();
|
||||
}
|
||||
}
|
||||
|
||||
function downFromUrlDialog() {
|
||||
$( "#downFromUrlDialog" ).dialog({
|
||||
modal: true,
|
||||
buttons: {
|
||||
"Download": function() {
|
||||
downFromUrl();
|
||||
},
|
||||
"Cancel": function() {
|
||||
$( this ).dialog( "close" );
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function downFromUrl() {
|
||||
var link = $('#downFromUrlForm input[name=link]').val();
|
||||
if (link != null && link != "")
|
||||
$('#downFromUrlForm').submit();
|
||||
}
|
||||
|
||||
function selectUnselect(cb) {
|
||||
var rows = $('.ui_checked_columns');
|
||||
for (i = 0; i < rows.length; i++) {
|
||||
switch(cb.is(":checked")) {
|
||||
case true:
|
||||
selectRow(rows[i]);
|
||||
break;
|
||||
case false:
|
||||
unselectRow(rows[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function rowClick(row) {
|
||||
var input = row.getElementsByTagName('input')[0];
|
||||
input.checked = !input.checked;
|
||||
if (input.checked) {
|
||||
row.className = row.className + ' checked';
|
||||
}
|
||||
else {
|
||||
row.className = row.className.replace(' checked', '');
|
||||
}
|
||||
}
|
||||
|
||||
function selectRow(row) {
|
||||
var input = row.getElementsByTagName('input')[0];
|
||||
if(!input.checked) {
|
||||
input.checked = true;
|
||||
row.className = row.className + ' checked';
|
||||
}
|
||||
}
|
||||
|
||||
function unselectRow(row) {
|
||||
var input = row.getElementsByTagName('input')[0];
|
||||
if(input.checked) {
|
||||
input.checked = false;
|
||||
row.className = row.className.replace(' checked', '');
|
||||
}
|
||||
}
|
||||
function checkSelected() {
|
||||
var checkboxes = $('.ui_checkbox');
|
||||
for(var i = 0; i < checkboxes.length; i++) {
|
||||
if(checkboxes[i].checked) return true;
|
||||
}
|
||||
$( "#nothingSelected" ).dialog({
|
||||
modal: true,
|
||||
buttons: {
|
||||
"OK": function() {
|
||||
$( this ).dialog( "close" );
|
||||
}
|
||||
}
|
||||
});
|
||||
return false;
|
||||
}
|
||||
|
||||
function searchDialog() {
|
||||
$( "#searchDialog" ).dialog({
|
||||
modal: true,
|
||||
buttons: {
|
||||
"Search": function() {
|
||||
search();
|
||||
},
|
||||
"Cancel": function() {
|
||||
$( this ).dialog( "close" );
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function search() {
|
||||
var query = $('#searchForm input[name=query]').val();
|
||||
if (query != null && query != "")
|
||||
$("#searchForm").submit();
|
||||
}
|
||||
|
||||
/*
|
||||
function checkSelected() {
|
||||
var checkboxes = document.getElementsByClassName('ui_checkbox');
|
||||
for(var i = 0; i < checkboxes.length; i++) {
|
||||
if(checkboxes[i].checked) return true;
|
||||
}
|
||||
alert('Nothing selected');
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
183
filemin/unauthenticated/js/plain.js
Normal file
@@ -0,0 +1,183 @@
|
||||
/*
|
||||
* plain.js
|
||||
* Behavior of the File Manager for themes without Bootstrap, on top of
|
||||
* the core widget script : row selection, the selection check before an
|
||||
* action on the selected entries, sending the selection form to an
|
||||
* action script with a dialog's fields as parameters, the rename and
|
||||
* delete dialogs, the permissions calculator and the upload options.
|
||||
* Everything is delegated from the document, keyed off data-filemin-*
|
||||
* attributes, so no handlers are generated in the markup.
|
||||
*/
|
||||
(function () {
|
||||
'use strict';
|
||||
var widgets = window.webminUiWidgets;
|
||||
|
||||
// The selection form and its row checkboxes
|
||||
function listForm() {
|
||||
return document.getElementById('list_form');
|
||||
}
|
||||
function rowBoxes() {
|
||||
var form = listForm();
|
||||
return form ? Array.prototype.slice.call(
|
||||
form.querySelectorAll('input[type="checkbox"][name="name"]')) : [];
|
||||
}
|
||||
function selectedBoxes() {
|
||||
return rowBoxes().filter(function (box) { return box.checked; });
|
||||
}
|
||||
function selectRows(mode) {
|
||||
rowBoxes().forEach(function (box) {
|
||||
box.checked = mode === 'all' ? true :
|
||||
mode === 'none' ? false : !box.checked;
|
||||
});
|
||||
}
|
||||
|
||||
// Called by the checkbox in the table heading
|
||||
window.selectUnselect = function (master) {
|
||||
selectRows(master.checked ? 'all' : 'none');
|
||||
};
|
||||
// Called by the rename link of a row, with the entry's name
|
||||
window.renameDialog = function (file) {
|
||||
widgets.openDialog('filemin_rename', { name: file, file: file });
|
||||
};
|
||||
|
||||
// Send the selection form to a script, with parameters in its URL
|
||||
function submitSelection(script, params) {
|
||||
var form = listForm();
|
||||
if (!form) return;
|
||||
var url = script;
|
||||
var query = params ? params.toString() : '';
|
||||
if (query) url += (url.indexOf('?') >= 0 ? '&' : '?') + query;
|
||||
form.setAttribute('action', url);
|
||||
form.submit();
|
||||
}
|
||||
// The named, enabled fields of a dialog form as URL parameters,
|
||||
// leaving out the calculator's own fields
|
||||
function formParams(form) {
|
||||
var params = new URLSearchParams();
|
||||
Array.prototype.forEach.call(form.elements, function (field) {
|
||||
if (!field.name || field.disabled ||
|
||||
field.hasAttribute('data-filemin-skip')) return;
|
||||
if (/^(?:file|submit|button|reset)$/.test(field.type)) return;
|
||||
if ((field.type === 'checkbox' || field.type === 'radio') &&
|
||||
!field.checked) return;
|
||||
if (field.tagName === 'SELECT' && field.multiple) {
|
||||
Array.prototype.forEach.call(field.options, function (option) {
|
||||
if (option.selected) params.append(field.name, option.value);
|
||||
});
|
||||
return;
|
||||
}
|
||||
params.append(field.name, field.value);
|
||||
});
|
||||
return params;
|
||||
}
|
||||
|
||||
// Toolbar entries : selecting rows, actions that need a selection,
|
||||
// and actions that send the selection straight to a script. Caught
|
||||
// before the widget script, so a dialog is not opened for an empty
|
||||
// selection.
|
||||
document.addEventListener('click', function (e) {
|
||||
var control = e.target.closest && e.target.closest(
|
||||
'[data-filemin-select], [data-filemin-selection], [data-filemin-submit]');
|
||||
if (!control) return;
|
||||
if (control.hasAttribute('data-filemin-select')) {
|
||||
e.preventDefault();
|
||||
selectRows(control.getAttribute('data-filemin-select'));
|
||||
return;
|
||||
}
|
||||
if (control.hasAttribute('data-filemin-selection') && !selectedBoxes().length) {
|
||||
e.preventDefault();
|
||||
e.stopImmediatePropagation();
|
||||
widgets.openDialog('filemin_nothing');
|
||||
return;
|
||||
}
|
||||
var script = control.getAttribute('data-filemin-submit');
|
||||
if (script) {
|
||||
e.preventDefault();
|
||||
submitSelection(script);
|
||||
}
|
||||
}, true);
|
||||
|
||||
document.addEventListener('submit', function (e) {
|
||||
var form = e.target;
|
||||
if (!form.getAttribute) return;
|
||||
// A dialog acting on the selection : its fields become the
|
||||
// parameters of the action script
|
||||
var script = form.getAttribute('data-filemin-apply');
|
||||
if (script) {
|
||||
e.preventDefault();
|
||||
var dialog = form.closest('dialog');
|
||||
if (dialog && dialog.open) dialog.close();
|
||||
submitSelection(script, formParams(form));
|
||||
return;
|
||||
}
|
||||
// An upload : the options go in the URL, which the server reads
|
||||
// before the files arrive, and progress is shown in a popup
|
||||
var upload = form.getAttribute('data-filemin-upload');
|
||||
if (upload) {
|
||||
var action = upload;
|
||||
form.querySelectorAll('[data-filemin-upload-option]').forEach(function (box) {
|
||||
if (box.checked) {
|
||||
action += '&' + box.getAttribute('data-filemin-upload-option') + '=1';
|
||||
}
|
||||
});
|
||||
form.setAttribute('action', action);
|
||||
var tracker = form.getAttribute('data-filemin-tracker');
|
||||
if (tracker) {
|
||||
window.open(tracker, 'uptracker',
|
||||
'toolbar=no,menubar=no,scrollbars=no,location=no,resizable=no,' +
|
||||
'width=' + window.screen.width + ',height=' + window.screen.height);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Directory upload : the file input picks directories instead
|
||||
document.addEventListener('change', function (e) {
|
||||
var box = e.target;
|
||||
if (box.matches && box.matches('[data-filemin-upload-dirs]')) {
|
||||
var input = box.form && box.form.querySelector('input[type="file"]');
|
||||
if (input) input.toggleAttribute('webkitdirectory', box.checked);
|
||||
}
|
||||
});
|
||||
|
||||
// The delete dialog lists the selected entries as it opens
|
||||
document.addEventListener('ui-dialog-open', function (e) {
|
||||
if (e.target.id !== 'filemin_delete') return;
|
||||
var list = e.target.querySelector('#filemin_delete_items');
|
||||
if (list) {
|
||||
list.textContent = selectedBoxes().map(function (box) {
|
||||
return box.value;
|
||||
}).join('\n');
|
||||
}
|
||||
});
|
||||
|
||||
// Permissions : the octal field, the checkbox matrix and the hidden
|
||||
// perms parameter stay in step through the shared calculator
|
||||
function syncPerms(fromMatrix) {
|
||||
var form = document.forms['chmod'];
|
||||
if (!form || typeof window.calc_chmod !== 'function') return;
|
||||
if (fromMatrix) {
|
||||
window.calc_chmod();
|
||||
}
|
||||
else if (/^[0-7]{4}$/.test(form.t_total.value) &&
|
||||
typeof window.octalchange === 'function') {
|
||||
window.octalchange();
|
||||
}
|
||||
var perms = form.querySelector('input[name="perms"]');
|
||||
if (perms) perms.value = form.t_total.value;
|
||||
}
|
||||
document.addEventListener('input', function (e) {
|
||||
if (e.target.matches && e.target.matches('[data-filemin-chmod-octal]')) {
|
||||
syncPerms(false);
|
||||
}
|
||||
});
|
||||
document.addEventListener('change', function (e) {
|
||||
if (e.target.matches && e.target.matches('[data-filemin-chmod]')) {
|
||||
syncPerms(true);
|
||||
}
|
||||
});
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', function () { syncPerms(false); });
|
||||
} else {
|
||||
syncPerms(false);
|
||||
}
|
||||
})();
|
||||
@@ -1,246 +0,0 @@
|
||||
<div id="nothingSelected" class="modal">
|
||||
<h3>$text{'nothing_selected'}</h3>
|
||||
</div>
|
||||
|
||||
<div id="createFolderDialog" class="modal">
|
||||
<form id="createFolderForm" action="create_folder.cgi" method="post">
|
||||
<div class="form-group">
|
||||
<label>$text{'new_folder_name'}</label>
|
||||
<input id="name" name="name" type="text" title="$text{'provide_folder_name'}">
|
||||
<input type='hidden' name='path' value='$quote_escaped_path'>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div id="createFileDialog" class="modal">
|
||||
<form id="createFileForm" action="create_file.cgi" method="post">
|
||||
<div class="form-group">
|
||||
<label>$text{'new_file_name'}</label>
|
||||
<input name="name" type="text">
|
||||
<input type='hidden' name='path' value='$quote_escaped_path'>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div id="renameDialog" class="modal">
|
||||
<form id="renameForm" action="rename.cgi" method="post">
|
||||
<div class="form-group">
|
||||
<label>$text{'new_name'}</label>
|
||||
<input name="name" type="text">
|
||||
<input type='hidden' name='file' value='' required>
|
||||
<input type='hidden' name='path' value='$quote_escaped_path'>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div id="compressDialog" class="modal">
|
||||
<form id="compressSelectedForm" action="compress.cgi" method="post">
|
||||
<div class="form-group">
|
||||
<label>$text{'archive_name'}</label>
|
||||
<input name="filename" type="text">
|
||||
<select name="method">
|
||||
<option value="plain-tar">.tar</option>
|
||||
<option value="xz-tar">.tar.xz</option>
|
||||
<option selected value="tar">.tar.gz</option>
|
||||
<option value="zstd-tar">.zstd</option>
|
||||
<option value="zip">.zip</option>
|
||||
</select>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div id="removeDialog" class="modal">
|
||||
<p>$text{'about_to_delete'}</p>
|
||||
<pre id="items-to-remove">
|
||||
</pre>
|
||||
$text{'are_you_sure'}
|
||||
</div>
|
||||
|
||||
<div id="chownDialog" class="modal">
|
||||
<form id="chownForm">
|
||||
<div class="form-group">
|
||||
<label>$text{'user_name'}</label><br>
|
||||
<input name="owner" type="text"><br>
|
||||
<label>$text{'group_name'}</label><br>
|
||||
<input name="group" type="text"><br><br>
|
||||
<label>$text{'dialog_recursive'}</label>
|
||||
<input id="chown-recursive" type="checkbox" name="recursive">
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div id="chattrDialog" class="modal">
|
||||
<form id="chattrForm">
|
||||
<div class="form-group">
|
||||
<label>$text{'attr_label'}</label><br>
|
||||
<input name="label" type="text"><br><br>
|
||||
<label>$text{'dialog_recursive'}</label>
|
||||
<input id="chattr-recursive" type="checkbox" name="recursive">
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div id="chconDialog" class="modal">
|
||||
<form id="chconForm">
|
||||
<div class="form-group">
|
||||
<label>$text{'context_label'}</label><br>
|
||||
<input name="label" type="text"><br><br>
|
||||
<label>$text{'dialog_recursive'}</label>
|
||||
<input id="chcon-recursive" type="checkbox" name="recursive">
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div id="aclsDialog" class="modal">
|
||||
<form id="aclsForm">
|
||||
<div class="form-group">
|
||||
<label>$text{'acls_action'}</label><br>
|
||||
<select name="action">
|
||||
<option value=""></option>
|
||||
<option selected value="-m">Modify (-m)</option>
|
||||
<option value="-x">Remove (-x)</option>
|
||||
<option value="-b">Remove all extended (-b)</option>
|
||||
<option value="-k">Remove default (-k)</option>
|
||||
</select><br><br>
|
||||
|
||||
<label>$text{'acls_applyto'}</label><br>
|
||||
<select multiple size=4 name="apply_to">
|
||||
<option value="u">$text{'acls_user'}</option>
|
||||
<option value="g">$text{'acls_group'}</option>
|
||||
<option value="m">$text{'acls_mask'}</option>
|
||||
<option value="o">$text{'acls_other'}</option>
|
||||
</select><br><br>
|
||||
|
||||
<label>$text{'acls_perms'}</label><br>
|
||||
<select name="perms">
|
||||
<option value=""></option>
|
||||
<option value="---">---</option>
|
||||
<option value="r--">r--</option>
|
||||
<option value="-w-">-w-</option>
|
||||
<option value="--x">--x</option>
|
||||
<option value="r-x">r-x</option>
|
||||
<option value="rw-">rw-</option>
|
||||
<option value="-wx">-wx</option>
|
||||
<option value="rwx">rwx</option>
|
||||
</select><br><br>
|
||||
|
||||
<label>$text{'acls_user'}</label><br>
|
||||
$acl_user_select<br><br>
|
||||
|
||||
<label>$text{'acls_group'}</label><br>
|
||||
$acl_group_select<br><br>
|
||||
|
||||
<label>$text{'dialog_recursive'}</label>
|
||||
<input id="acls-recursive" type="checkbox" name="recursive">
|
||||
|
||||
<br><br>
|
||||
$acl_manual
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div id="downFromUrlDialog" class="modal">
|
||||
<form id="downFromUrlForm" action="http_download.cgi" method="post">
|
||||
<div class="form-group">
|
||||
<label style="display: block;">$text{'dialog_file_url'} <sup class="text-danger"> *</sup><br>
|
||||
<input name="link" type="url" data-placement="top" data-content="$text{'provide_url'}" data-trigger="manual" autocomplete="url" style="font-weight: normal;">
|
||||
</label>
|
||||
<label style="display: block;">$text{'dialog_user_name'}<br>
|
||||
<input name="username" type="text" autocomplete="off" style="font-weight: normal;">
|
||||
</label>
|
||||
<label style="display: block;">$text{'dialog_user_pass'}<br>
|
||||
<input name="password" type="password" autocomplete="new-password" style="font-weight: normal;">
|
||||
</label>
|
||||
<input type='hidden' name='path' value='$quote_escaped_path'>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div id="readyForUploadDialog" class="modal">
|
||||
<form id='upload-form' method='post' onsubmit="this.extract_upload.checked=false" action='upload.cgi?path=$urlized_path&id=$upid' enctype='multipart/form-data' onsubmit='window.open("@{[&get_webprefix()]}/uptracker.cgi?id=$upid&uid=$uid", "uptracker", "toolbar=no, menubar=no, scrollbars=no, location=no, resizable=no, width=screen.width, height=screen.height")'>
|
||||
<input type='file' id='upfiles' name='upfiles' multiple onchange='countUploads(this)'>
|
||||
<input type='hidden' name='path' value='$quote_escaped_path'>
|
||||
<br>
|
||||
<br>
|
||||
<input type="checkbox" id="filetype" onchange="this.parentElement.querySelector('#upfiles').toggleAttribute('webkitdirectory')"><label for="filetype"> $text{'upload_dirs'}</label>
|
||||
<br>
|
||||
<input type="checkbox" id="extract_upload" onchange="t=document.querySelector('#upload-form'),v=t.getAttribute('action'),x='&extract_uploaded=1',this.checked?t.setAttribute('action', t.getAttribute('action') + x):t.setAttribute('action',t.getAttribute('action').replace(x,''))"><label for="extract_upload"> $text{'extract_uploaded'}</label>
|
||||
<br>
|
||||
<input type="checkbox" id="overwrite_existing" onchange="t=document.querySelector('#upload-form'),v=t.getAttribute('action'),x='&overwrite_existing=1',this.checked?t.setAttribute('action', t.getAttribute('action') + x):t.setAttribute('action',t.getAttribute('action').replace(x,''))"><label for="overwrite_existing"> $text{'overwrite_existing'}</label>
|
||||
</form>
|
||||
<div id="readyForUploadList" class="well" style="max-height: 180px;">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="chmodDialog" class="modal fade">
|
||||
<form name="chmod" id="chmodForm">
|
||||
<div class="form-group">
|
||||
<label for="t_total">$text{'permissions'}: </label><br>
|
||||
<input id="perms" type="text" oninput="if(this.value.length>4)this.value=this.value.slice(0,4)" name="t_total" value="0644" size="4" onKeyUp="octalchange()" class="form-group-item">
|
||||
<input type="text" name="sym_total" value="" size="12" readonly="true" class="form-group-item">
|
||||
</div>
|
||||
<table class="table">
|
||||
<tr>
|
||||
<th></th>
|
||||
<th><b>$text{'chmod_owner'}</b></th>
|
||||
<th><b>$text{'chmod_group'}</b></th>
|
||||
<th><b>$text{'chmod_others'}<b></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>$text{'chmod_read'}</td>
|
||||
<td><input type="checkbox" name="owner4" value="4" onchange="calc_chmod()"></td>
|
||||
<td><input type="checkbox" name="group4" value="4" onchange="calc_chmod()"></td>
|
||||
<td><input type="checkbox" name="other4" value="4" onchange="calc_chmod()"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>$text{'chmod_write'}</td>
|
||||
<td><input type="checkbox" name="owner2" value="2" onchange="calc_chmod()"></td>
|
||||
<td><input type="checkbox" name="group2" value="2" onchange="calc_chmod()"></td>
|
||||
<td><input type="checkbox" name="other2" value="2" onchange="calc_chmod()"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>$text{'chmod_execute'}</td>
|
||||
<td><input type="checkbox" name="owner1" value="1" onchange="calc_chmod()"></td>
|
||||
<td><input type="checkbox" name="group1" value="1" onchange="calc_chmod()"></td>
|
||||
<td><input type="checkbox" name="other1" value="1" onchange="calc_chmod()"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>----------</td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>$text{'chmod_sticky'}</td>
|
||||
<td><input type="checkbox" name="sticky" value="1" onchange="calc_chmod()"></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>$text{'chmod_setgid'}</td>
|
||||
<td><input type="checkbox" name="setgid" value="2" onchange="calc_chmod()"></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</table>
|
||||
<label>$text{'chmod_apply_to'}: </label>
|
||||
<select name="applyto">
|
||||
<option value="1">$text{'chmod_dir_only'}</option>
|
||||
<option value="2">$text{'chmod_dir_and_its_files'}</option>
|
||||
<option value="3">$text{'chmod_all'}</option>
|
||||
<option value="4">$text{'chmod_dir_files_and_subs_files'}</option>
|
||||
<option value="5">$text{'chmod_dir_and_subs'}</option>
|
||||
</select>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div id="searchDialog" class="modal">
|
||||
<form id="searchForm" action="search.cgi" method="post">
|
||||
<div class="form-group">
|
||||
<label>$text{'search_label'}</label>
|
||||
<input id="query" name="query" type="text" title="$text{'provide_search_query'}"><br><br>
|
||||
<input id="caseins" name="caseins" type="checkbox" checked="checked"> $text{'search_insensitive'}
|
||||
<input type='hidden' name='path' value='$quote_escaped_path'>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
@@ -1,29 +0,0 @@
|
||||
<div id="quicks" style="float:right">
|
||||
<a href="javascript:void(0)" onclick='searchDialog()' title="$text{'search'}"><img src='images/icons/quick/edit-find.png' alt="$text{'search'}" /></a>
|
||||
<a href="bookmark.cgi?path=$urlized_path" title="$text{'bookmark_folder'}"><img src='images/icons/quick/bookmark-new.png' alt="$text{'bookmark_folder'}" /></a>
|
||||
<a tabindex="0" class="fg-button fg-button-icon-right ui-widget ui-state-default ui-corner-all" id="flat">
|
||||
<img src="images/icons/quick/go-down.png" alt="$text{'config_bookmarks'}">
|
||||
</a>
|
||||
<div id="bookmarks" class="ui-helper-hidden">
|
||||
<ul>
|
||||
$bookmarks
|
||||
</ul>
|
||||
</div>
|
||||
<a href="javascript:void(0)" onclick='selectAll()' title="$text{'select_all'}"><img src='images/icons/quick/select-all.png' alt="$text{'select_all'}" /></a>
|
||||
<a href="javascript:void(0)" onclick='invertSelection()' title="$text{'invert_selection'}"><img src='images/icons/quick/invert.png' alt="$text{'invert_selection'}" /></a>
|
||||
<a href="javascript:void(0)" onclick='copySelected()' title="$text{'copy_selected'}"><img src='images/icons/quick/edit-copy.png' alt="$text{'copy_selected'}" /></a>
|
||||
<a href="javascript:void(0)" onclick='cutSelected()' title="$text{'cut_selected'}"><img src='images/icons/quick/edit-cut.png' alt="$text{'cut_selected'}" /></a>
|
||||
<a href='paste.cgi?path=$urlized_path' title="$text{'paste'}"><img src='images/icons/quick/edit-paste.png' alt="$text{'paste'}" /></a>
|
||||
<a href="javascript:void(0)" onclick='createFolderDialog()' title="$text{'create_folder'}"><img src='images/icons/quick/folder-new.png' alt="$text{'create_folder'}" /></a>
|
||||
<a href="javascript:void(0)" onclick='createFileDialog()' title="$text{'create_file'}"><img src='images/icons/quick/document-new.png' alt="$text{'create_file'}" /></a>
|
||||
<a href="javascript:void(0)" onclick='compressDialog()' title="$text{'compress_selected'}"><img src='images/icons/quick/compress.png' alt="$text{'compress_selected'}" /></a>
|
||||
<a href="javascript:void(0)" onclick='chmodDialog()' title="$text{'chmod_selected'}"><img src='images/icons/quick/chmod.png' alt="$text{'chmod_selected'}" /></a>
|
||||
<a href="javascript:void(0)" onclick='chownDialog()' title="$text{'chown_selected'}"><img src='images/icons/quick/chown.png' alt="$text{'chown_selected'}" /></a>
|
||||
<a href="javascript:void(0)" onclick='chattrDialog()' title="$text{'chattr_selected'}"><img src='images/icons/quick/chattr.png' alt="$text{'chattr_selected'}" /></a>
|
||||
<a href="javascript:void(0)" onclick='chconDialog()' title="$text{'chcon_selected'}"><img src='images/icons/quick/chcon.png' alt="$text{'chcon_selected'}" /></a>
|
||||
<a href="javascript:void(0)" onclick='aclsDialog()' title="$text{'acls_selected'}"><img src='images/icons/quick/acls.png' alt="$text{'acls_selected'}" /></a>
|
||||
<a href="javascript:void(0)" onclick='removeSelected()' title="$text{'remove_selected'}"><img src='images/icons/quick/remove.png' alt="$text{'remove_selected'}" /></a>
|
||||
<a href="javascript:void(0)" onclick='viewReadyForUpload()' title="$text{'upload_files'}"><img src='images/icons/quick/upload.png' alt="$text{'upload_files'}" /></a>
|
||||
<a href="javascript:void(0)" onclick='downFromUrlDialog()' title="$text{'get_from_url'}"><img src='images/icons/quick/from-url.png' alt="$text{'get_from_url'}" /></a>
|
||||
</div>
|
||||
<div id="info" style="float:right"></div>
|
||||
@@ -1,67 +0,0 @@
|
||||
<div class="btn-group pull-right" role="group">
|
||||
<button class="btn btn-inverse" onclick='searchDialog()' title="$text{'search'}" data-toggle="tooltip" data-placement="bottom" data-container="body">
|
||||
<i class="fa fa-search" aria-hidden="true"></i>
|
||||
</button>
|
||||
<button class="btn btn-inverse" onclick="location.href='bookmark.cgi?path=$urlized_path'" title="$text{'bookmark_folder'}" data-toggle="tooltip" data-placement="bottom" data-container="body">
|
||||
<i class="fa fa-bookmark-o" aria-hidden="true"></i>
|
||||
</button>
|
||||
<div class="btn-group">
|
||||
<button type="button" class="btn btn-inverse dropdown-toggle" data-toggle="dropdown" data-hover="dropdown" title="$text{'config_bookmarks'}">
|
||||
<i class="fa fa-book" aria-hidden="true"></i>
|
||||
</button>
|
||||
<ul class="dropdown-menu" aria-labelledby="dropdownMenu1">
|
||||
$bookmarks
|
||||
</ul>
|
||||
</div>
|
||||
<button class="btn btn-inverse" onclick='window.location.href="index.cgi?path=$urlized_path"' title="$text{'refresh'}" data-toggle="tooltip" data-placement="bottom" data-container="body">
|
||||
<i class="fa fa-refresh" aria-hidden="true"></i>
|
||||
</button>
|
||||
<button class="btn btn-inverse" onclick='selectAll()' title="$text{'select_all'}" data-toggle="tooltip" data-placement="bottom" data-container="body">
|
||||
<i class="fa fa-check-square-o" aria-hidden="true"></i>
|
||||
</button>
|
||||
<button class="btn btn-inverse" onclick='invertSelection()' title="$text{'invert_selection'}" data-toggle="tooltip" data-placement="bottom" data-container="body">
|
||||
<i class="fa fa-check-square" aria-hidden="true"></i>
|
||||
</button>
|
||||
<button class="btn btn-inverse" onclick='copySelected()' title="$text{'copy_selected'}" data-toggle="tooltip" data-placement="bottom" data-container="body">
|
||||
<i class="fa fa-copy" aria-hidden="true"></i>
|
||||
</button>
|
||||
<button class="btn btn-inverse" onclick='cutSelected()' title="$text{'cut_selected'}" data-toggle="tooltip" data-placement="bottom" data-container="body">
|
||||
<i class="fa fa-cut" aria-hidden="true"></i>
|
||||
</button>
|
||||
<button class="btn btn-inverse" onclick="location.href='paste.cgi?path=$urlized_path'" title="$text{'paste'}" data-toggle="tooltip" data-placement="bottom" data-container="body">
|
||||
<i class="fa fa-paste" aria-hidden="true"></i>
|
||||
</button>
|
||||
<button class="btn btn-inverse" onclick='createFolderDialog()' title="$text{'create_folder'}" data-toggle="tooltip" data-placement="bottom" data-container="body">
|
||||
<i class="fa fa-folder-o" aria-hidden="true"></i>
|
||||
</button>
|
||||
<button class="btn btn-inverse" onclick='createFileDialog()' title="$text{'create_file'}" data-toggle="tooltip" data-placement="bottom" data-container="body">
|
||||
<i class="fa fa-file-o" aria-hidden="true"></i>
|
||||
</button>
|
||||
<button class="btn btn-inverse" onclick='compressDialog()' title="$text{'compress_selected'}" data-toggle="tooltip" data-placement="bottom" data-container="body">
|
||||
<i class="fa fa-file-archive-o" aria-hidden="true"></i>
|
||||
</button>
|
||||
<button class="btn btn-inverse" onclick='chmodDialog()' title="$text{'chmod_selected'}" data-toggle="tooltip" data-placement="bottom" data-container="body">
|
||||
<i class="fa fa-gears" aria-hidden="true"></i>
|
||||
</button>
|
||||
<button class="btn btn-inverse" onclick='chownDialog()' title="$text{'chown_selected'}" data-toggle="tooltip" data-placement="bottom" data-container="body">
|
||||
<i class="fa fa-users" aria-hidden="true"></i>
|
||||
</button>
|
||||
<button class="btn btn-inverse" onclick='chattrDialog()' title="$text{'chattr_selected'}" data-toggle="tooltip" data-placement="bottom" data-container="body">
|
||||
<i class="fa fa-tags" aria-hidden="true"></i>
|
||||
</button>
|
||||
<button class="btn btn-inverse" onclick='chconDialog()' title="$text{'chcon_selected'}" data-toggle="tooltip" data-placement="bottom" data-container="body">
|
||||
<i class="fa fa-shield" aria-hidden="true"></i>
|
||||
</button>
|
||||
<button class="btn btn-inverse" onclick='aclsDialog()' title="$text{'acls_selected'}" data-toggle="tooltip" data-placement="bottom" data-container="body">
|
||||
<i class="fa fa-account-key" aria-hidden="true"></i>
|
||||
</button>
|
||||
<button class="btn btn-inverse" onclick='removeDialog()' title="$text{'remove_selected'}" data-toggle="tooltip" data-placement="bottom" data-container="body">
|
||||
<i class="fa fa-trash-o" aria-hidden="true"></i>
|
||||
</button>
|
||||
<button class="btn btn-inverse" onclick='viewReadyForUpload()' title="$text{'upload_files'}" data-toggle="tooltip" data-placement="bottom" data-container="body">
|
||||
<i class="fa fa-upload" aria-hidden="true"></i>
|
||||
</button>
|
||||
<button class="btn btn-inverse" onclick='downFromUrlDialog()' title="$text{'get_from_url'}" data-toggle="tooltip" data-placement="bottom" data-container="body">
|
||||
<i class="fa fa-globe" aria-hidden="true"></i>
|
||||
</button>
|
||||
</div>
|
||||
@@ -7,7 +7,7 @@ index_ecommands=Ninguno de los comandos de respaldo de sistemas de archivo (como
|
||||
index_return=lista de respaldos
|
||||
|
||||
dump_dir=Directorio a respaldar
|
||||
dump_dirs=Directorios a rspaldar
|
||||
dump_dirs=Directorios a respaldar
|
||||
dump_fs=Sistema de archivos
|
||||
dump_sched=¿Programado?
|
||||
dump_when=Horas programadas para respaldar
|
||||
|
||||
@@ -55,6 +55,13 @@ print &ui_table_row($text{'edright_fsize'},
|
||||
&ui_opt_textbox("fsize", $sects->{'fsize'}, 6, $text{'edright_fsizedef'}).
|
||||
" ".$text{'edright_pixels'});
|
||||
|
||||
# Light or dark colors
|
||||
print &ui_table_row($text{'edright_scheme'},
|
||||
&ui_select("scheme", $sects->{'scheme'},
|
||||
[ [ "", $text{'edright_scheme_auto'} ],
|
||||
[ "light", $text{'edright_scheme_light'} ],
|
||||
[ "dark", $text{'edright_scheme_dark'} ] ]));
|
||||
|
||||
# Show search box
|
||||
print &ui_table_row($text{'edright_search'},
|
||||
&ui_yesno_radio("search", !$sects->{'nosearch'}));
|
||||
|
||||
107
gray-theme/images/logos/cloudmin-dark.svg
Normal file
@@ -0,0 +1,107 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="228.1" height="48.3" version="1.0" viewBox="1.6 0 228.1 48.3" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
|
||||
<defs>
|
||||
<clipPath id="clipPath4328">
|
||||
<path d="m113.96 371.7h91.873v-100.26h-91.873z"/>
|
||||
</clipPath>
|
||||
<mask id="mask4348" x="0" y="0" width="1" height="1" maskUnits="userSpaceOnUse">
|
||||
<path d="m-32768 32767h65535v-65534h-65535z" fill="url(#linearGradient4340)"/>
|
||||
</mask>
|
||||
<linearGradient id="linearGradient4340" x2="1" gradientTransform="matrix(33.95 -35.09 35.09 33.95 142.92 339.12)" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#fff" offset="0"/>
|
||||
<stop stop-color="#fff" stop-opacity=".50196" offset=".27058"/>
|
||||
<stop stop-color="#fff" stop-opacity="0" offset="1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="linearGradient4364" x2="1" gradientTransform="matrix(33.95 -35.09 35.09 33.95 142.92 339.12)" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#fff" offset="0"/>
|
||||
<stop stop-color="#fff" offset=".27058"/>
|
||||
<stop stop-color="#fff" offset="1"/>
|
||||
</linearGradient>
|
||||
<clipPath id="clipPath4378">
|
||||
<path d="M 0,595.28 H 841.89 V 0 H 0 Z"/>
|
||||
</clipPath>
|
||||
<clipPath id="clipPath4390">
|
||||
<path d="m131.92 321.57c0-27.621 16.525-50.021 36.902-50.021 20.378 0 36.902 22.4 36.902 50.021s-16.524 50.02-36.902 50.02c-20.377 0-36.902-22.399-36.902-50.02"/>
|
||||
</clipPath>
|
||||
<mask id="mask4408" x="0" y="0" width="1" height="1" maskUnits="userSpaceOnUse">
|
||||
<path d="m-32768 32767h65535v-65534h-65535z" fill="url(#linearGradient4402)"/>
|
||||
</mask>
|
||||
<linearGradient id="linearGradient4402" x2="1" gradientTransform="matrix(97.961 -60.001 48.314 121.66 81.162 375.26)" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#fff" offset="0"/>
|
||||
<stop stop-color="#fff" stop-opacity="0" offset="1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="linearGradient4424" x2="1" gradientTransform="matrix(97.961 -60.001 48.314 121.66 81.162 375.26)" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#fff" offset="0"/>
|
||||
<stop stop-color="#fff" offset="1"/>
|
||||
</linearGradient>
|
||||
<clipPath id="clipPath4436">
|
||||
<path d="M 0,595.28 H 841.89 V 0 H 0 Z"/>
|
||||
</clipPath>
|
||||
<clipPath id="clipPath4444">
|
||||
<path d="m142.87 379.77h78.912v-124.42h-78.912z"/>
|
||||
</clipPath>
|
||||
<clipPath id="clipPath4448">
|
||||
<path d="m142.87 379.77h78.912v-124.42h-78.912z"/>
|
||||
</clipPath>
|
||||
<clipPath id="clipPath4472">
|
||||
<path d="m241.04 377.98h44.544v-55.296h-44.544z"/>
|
||||
</clipPath>
|
||||
<clipPath id="clipPath4476">
|
||||
<path d="m241.04 377.98h44.544v-55.296h-44.544z"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
<metadata>
|
||||
<rdf:RDF>
|
||||
<cc:Work rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
|
||||
<dc:title/>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g transform="matrix(.33763 0 0 -.3804 -21.217 147.81)">
|
||||
<g clip-path="url(#clipPath4328)">
|
||||
<g mask="url(#mask4348)">
|
||||
<path d="m113.96 371.7h91.873v-100.26h-91.873z" fill="url(#linearGradient4364)"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g transform="matrix(.3804 0 0 -.3804 -45.383 147.81)">
|
||||
<g clip-path="url(#clipPath4378)">
|
||||
<g transform="translate(188.69 382.73)">
|
||||
<path d="m0 0c40.231-1.537 22.668-21.769 73.743-8.284 43.506 11.486 52.259-59.513 6.705-55.023-31.707 3.126-18.03-51.842-80.448-55.274-34.592 0-62.645 26.551-62.645 59.291 0 32.739 28.053 59.29 62.645 59.29" fill="#e67e38"/>
|
||||
</g>
|
||||
</g>
|
||||
<g clip-path="url(#clipPath4390)">
|
||||
<g mask="url(#mask4408)">
|
||||
<path d="m131.92 321.57c0-27.621 16.525-50.021 36.902-50.021 20.378 0 36.902 22.4 36.902 50.021s-16.524 50.02-36.902 50.02c-20.377 0-36.902-22.399-36.902-50.02" fill="url(#linearGradient4424)"/>
|
||||
</g>
|
||||
</g>
|
||||
<g clip-path="url(#clipPath4436)">
|
||||
<g clip-path="url(#clipPath4444)">
|
||||
<g clip-path="url(#clipPath4448)">
|
||||
<g transform="matrix(1 0 0 -1 142.87 284.15)" fill="#fff">
|
||||
<path d="m75.456-71.654c-6.912-8.8704-18.432-11.981-27.533-11.981-25.459 0-44.006 16.704-44.006 42.854s18.547 42.854 44.006 42.854c11.174 0 22.694-4.4928 29.491-14.17l-14.976-11.174c-3.6864 5.5296-9.5616 8.7552-16.819 8.7552-13.018 0-23.04-11.059-23.04-26.266s10.022-26.266 23.616-26.266c6.6816 0 11.866 2.4192 15.437 6.6816z"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g clip-path="url(#clipPath4472)">
|
||||
<g clip-path="url(#clipPath4476)">
|
||||
<g transform="matrix(1 0 0 -1 241.04 335.48)" fill="#fff">
|
||||
<path d="m2.7136 0h7.68v-12.39c0-3.2256 0.6144-6.3488 4.608-6.3488 3.5328 0 3.4304 3.7376 3.4304 5.5808v13.158h7.68v-13.158c0-3.072 1.1264-5.5808 4.6592-5.5808 2.5088 0 3.3792 1.9456 3.3792 4.2496v14.49h7.68v-14.694c0-6.0416-2.048-10.803-8.8064-10.803-3.6864 0-6.0928 1.28-7.8848 4.4544-1.3312-3.0208-4.1984-4.4544-7.68-4.4544-3.7376 0-6.2464 2.048-7.2704 3.9936h-0.1024v-3.3792h-7.3728z"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g transform="matrix(.5897 0 0 .5897 77.062 37.421)" fill="#e6e8ea">
|
||||
<path d="m39.84-36.96c-3.42-4.5-9.3-6.6-14.88-6.6-13.08 0-22.14 9.48-22.14 22.68 0 10.68 8.34 21.96 21.84 21.96 9.72 0 14.82-5.7 16.08-7.44l-4.86-3.66c-2.52 3.54-6.24 5.7-11.1 5.7-9.9 0-15.84-7.62-15.84-16.56 0-9.66 6.3-17.28 15.84-17.28 3.9 0 7.86 1.74 10.26 4.86z"/>
|
||||
<path d="m46.74 0h5.4v-45.36h-5.4z"/>
|
||||
<path d="m65.1-14.22c0-5.76 3.6-9.9 9.36-9.9s9.36 4.14 9.36 9.9-3.6 9.9-9.36 9.9-9.36-4.14-9.36-9.9zm-5.76 0c0 8.28 6.66 14.94 15.12 14.94s15.12-6.66 15.12-14.94-6.66-14.94-15.12-14.94-15.12 6.66-15.12 14.94z"/>
|
||||
<path d="m121.56-28.44h-5.4v14.64c0 6.6-3.42 9.48-7.92 9.48-3.42 0-6.48-1.98-6.48-7.32v-16.8h-5.4v18.3c0 7.56 4.8 10.86 10.32 10.86 4.38 0 7.98-2.1 9.36-5.1h0.12v4.38h5.4z"/>
|
||||
<path d="m158.22-45.36h-5.4v21h-0.12c-1.92-2.94-5.82-4.8-9.9-4.8-8.76 0-14.46 6.42-14.46 14.94 0 8.4 5.64 14.94 14.46 14.94 3.84 0 7.8-1.74 9.9-4.8h0.12v4.08h5.4zm-14.76 41.04c-5.76 0-9.36-4.14-9.36-9.9s3.6-9.9 9.36-9.9 9.36 4.14 9.36 9.9-3.6 9.9-9.36 9.9z"/>
|
||||
<path d="m166.38 0h5.4v-14.76c0-6.42 3.48-9.36 7.38-9.36 5.22 0 6 3.84 6 9.24v14.88h5.4v-15.54c0-5.04 2.04-8.58 7.26-8.58s6.12 3.96 6.12 8.28v15.84h5.4v-16.56c0-6.36-2.04-12.6-10.8-12.6-3.42 0-7.14 1.8-9 5.28-1.8-3.48-4.68-5.28-8.88-5.28-5.1 0-8.58 3.48-9.12 5.16h-0.12v-4.44h-5.04z"/>
|
||||
<path d="m217.92 0h5.4v-28.44h-5.4zm-1.26-38.64c0 2.16 1.8 3.96 3.96 3.96s3.96-1.8 3.96-3.96-1.8-3.96-3.96-3.96-3.96 1.8-3.96 3.96z"/>
|
||||
<path d="m231.9 0h5.4v-14.64c0-6.6 3.42-9.48 7.92-9.48 3.42 0 6.48 1.98 6.48 7.32v16.8h5.4v-18.3c0-7.56-4.8-10.86-10.32-10.86-4.38 0-7.98 2.1-9.36 5.1h-0.12v-4.38h-5.4z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 6.4 KiB |
107
gray-theme/images/logos/cloudmin.svg
Normal file
@@ -0,0 +1,107 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="228.1" height="48.3" version="1.0" viewBox="1.6 0 228.1 48.3" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
|
||||
<defs>
|
||||
<clipPath id="clipPath4328">
|
||||
<path d="m113.96 371.7h91.873v-100.26h-91.873z"/>
|
||||
</clipPath>
|
||||
<mask id="mask4348" x="0" y="0" width="1" height="1" maskUnits="userSpaceOnUse">
|
||||
<path d="m-32768 32767h65535v-65534h-65535z" fill="url(#linearGradient4340)"/>
|
||||
</mask>
|
||||
<linearGradient id="linearGradient4340" x2="1" gradientTransform="matrix(33.95 -35.09 35.09 33.95 142.92 339.12)" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#fff" offset="0"/>
|
||||
<stop stop-color="#fff" stop-opacity=".50196" offset=".27058"/>
|
||||
<stop stop-color="#fff" stop-opacity="0" offset="1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="linearGradient4364" x2="1" gradientTransform="matrix(33.95 -35.09 35.09 33.95 142.92 339.12)" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#fff" offset="0"/>
|
||||
<stop stop-color="#fff" offset=".27058"/>
|
||||
<stop stop-color="#fff" offset="1"/>
|
||||
</linearGradient>
|
||||
<clipPath id="clipPath4378">
|
||||
<path d="M 0,595.28 H 841.89 V 0 H 0 Z"/>
|
||||
</clipPath>
|
||||
<clipPath id="clipPath4390">
|
||||
<path d="m131.92 321.57c0-27.621 16.525-50.021 36.902-50.021 20.378 0 36.902 22.4 36.902 50.021s-16.524 50.02-36.902 50.02c-20.377 0-36.902-22.399-36.902-50.02"/>
|
||||
</clipPath>
|
||||
<mask id="mask4408" x="0" y="0" width="1" height="1" maskUnits="userSpaceOnUse">
|
||||
<path d="m-32768 32767h65535v-65534h-65535z" fill="url(#linearGradient4402)"/>
|
||||
</mask>
|
||||
<linearGradient id="linearGradient4402" x2="1" gradientTransform="matrix(97.961 -60.001 48.314 121.66 81.162 375.26)" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#fff" offset="0"/>
|
||||
<stop stop-color="#fff" stop-opacity="0" offset="1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="linearGradient4424" x2="1" gradientTransform="matrix(97.961 -60.001 48.314 121.66 81.162 375.26)" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#fff" offset="0"/>
|
||||
<stop stop-color="#fff" offset="1"/>
|
||||
</linearGradient>
|
||||
<clipPath id="clipPath4436">
|
||||
<path d="M 0,595.28 H 841.89 V 0 H 0 Z"/>
|
||||
</clipPath>
|
||||
<clipPath id="clipPath4444">
|
||||
<path d="m142.87 379.77h78.912v-124.42h-78.912z"/>
|
||||
</clipPath>
|
||||
<clipPath id="clipPath4448">
|
||||
<path d="m142.87 379.77h78.912v-124.42h-78.912z"/>
|
||||
</clipPath>
|
||||
<clipPath id="clipPath4472">
|
||||
<path d="m241.04 377.98h44.544v-55.296h-44.544z"/>
|
||||
</clipPath>
|
||||
<clipPath id="clipPath4476">
|
||||
<path d="m241.04 377.98h44.544v-55.296h-44.544z"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
<metadata>
|
||||
<rdf:RDF>
|
||||
<cc:Work rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
|
||||
<dc:title/>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g transform="matrix(.33763 0 0 -.3804 -21.217 147.81)">
|
||||
<g clip-path="url(#clipPath4328)">
|
||||
<g mask="url(#mask4348)">
|
||||
<path d="m113.96 371.7h91.873v-100.26h-91.873z" fill="url(#linearGradient4364)"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g transform="matrix(.3804 0 0 -.3804 -45.383 147.81)">
|
||||
<g clip-path="url(#clipPath4378)">
|
||||
<g transform="translate(188.69 382.73)">
|
||||
<path d="m0 0c40.231-1.537 22.668-21.769 73.743-8.284 43.506 11.486 52.259-59.513 6.705-55.023-31.707 3.126-18.03-51.842-80.448-55.274-34.592 0-62.645 26.551-62.645 59.291 0 32.739 28.053 59.29 62.645 59.29" fill="#e67e38"/>
|
||||
</g>
|
||||
</g>
|
||||
<g clip-path="url(#clipPath4390)">
|
||||
<g mask="url(#mask4408)">
|
||||
<path d="m131.92 321.57c0-27.621 16.525-50.021 36.902-50.021 20.378 0 36.902 22.4 36.902 50.021s-16.524 50.02-36.902 50.02c-20.377 0-36.902-22.399-36.902-50.02" fill="url(#linearGradient4424)"/>
|
||||
</g>
|
||||
</g>
|
||||
<g clip-path="url(#clipPath4436)">
|
||||
<g clip-path="url(#clipPath4444)">
|
||||
<g clip-path="url(#clipPath4448)">
|
||||
<g transform="matrix(1 0 0 -1 142.87 284.15)" fill="#fff">
|
||||
<path d="m75.456-71.654c-6.912-8.8704-18.432-11.981-27.533-11.981-25.459 0-44.006 16.704-44.006 42.854s18.547 42.854 44.006 42.854c11.174 0 22.694-4.4928 29.491-14.17l-14.976-11.174c-3.6864 5.5296-9.5616 8.7552-16.819 8.7552-13.018 0-23.04-11.059-23.04-26.266s10.022-26.266 23.616-26.266c6.6816 0 11.866 2.4192 15.437 6.6816z"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g clip-path="url(#clipPath4472)">
|
||||
<g clip-path="url(#clipPath4476)">
|
||||
<g transform="matrix(1 0 0 -1 241.04 335.48)" fill="#fff">
|
||||
<path d="m2.7136 0h7.68v-12.39c0-3.2256 0.6144-6.3488 4.608-6.3488 3.5328 0 3.4304 3.7376 3.4304 5.5808v13.158h7.68v-13.158c0-3.072 1.1264-5.5808 4.6592-5.5808 2.5088 0 3.3792 1.9456 3.3792 4.2496v14.49h7.68v-14.694c0-6.0416-2.048-10.803-8.8064-10.803-3.6864 0-6.0928 1.28-7.8848 4.4544-1.3312-3.0208-4.1984-4.4544-7.68-4.4544-3.7376 0-6.2464 2.048-7.2704 3.9936h-0.1024v-3.3792h-7.3728z"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g transform="matrix(.5897 0 0 .5897 77.062 37.421)" fill="#4d4c4e">
|
||||
<path d="m39.84-36.96c-3.42-4.5-9.3-6.6-14.88-6.6-13.08 0-22.14 9.48-22.14 22.68 0 10.68 8.34 21.96 21.84 21.96 9.72 0 14.82-5.7 16.08-7.44l-4.86-3.66c-2.52 3.54-6.24 5.7-11.1 5.7-9.9 0-15.84-7.62-15.84-16.56 0-9.66 6.3-17.28 15.84-17.28 3.9 0 7.86 1.74 10.26 4.86z"/>
|
||||
<path d="m46.74 0h5.4v-45.36h-5.4z"/>
|
||||
<path d="m65.1-14.22c0-5.76 3.6-9.9 9.36-9.9s9.36 4.14 9.36 9.9-3.6 9.9-9.36 9.9-9.36-4.14-9.36-9.9zm-5.76 0c0 8.28 6.66 14.94 15.12 14.94s15.12-6.66 15.12-14.94-6.66-14.94-15.12-14.94-15.12 6.66-15.12 14.94z"/>
|
||||
<path d="m121.56-28.44h-5.4v14.64c0 6.6-3.42 9.48-7.92 9.48-3.42 0-6.48-1.98-6.48-7.32v-16.8h-5.4v18.3c0 7.56 4.8 10.86 10.32 10.86 4.38 0 7.98-2.1 9.36-5.1h0.12v4.38h5.4z"/>
|
||||
<path d="m158.22-45.36h-5.4v21h-0.12c-1.92-2.94-5.82-4.8-9.9-4.8-8.76 0-14.46 6.42-14.46 14.94 0 8.4 5.64 14.94 14.46 14.94 3.84 0 7.8-1.74 9.9-4.8h0.12v4.08h5.4zm-14.76 41.04c-5.76 0-9.36-4.14-9.36-9.9s3.6-9.9 9.36-9.9 9.36 4.14 9.36 9.9-3.6 9.9-9.36 9.9z"/>
|
||||
<path d="m166.38 0h5.4v-14.76c0-6.42 3.48-9.36 7.38-9.36 5.22 0 6 3.84 6 9.24v14.88h5.4v-15.54c0-5.04 2.04-8.58 7.26-8.58s6.12 3.96 6.12 8.28v15.84h5.4v-16.56c0-6.36-2.04-12.6-10.8-12.6-3.42 0-7.14 1.8-9 5.28-1.8-3.48-4.68-5.28-8.88-5.28-5.1 0-8.58 3.48-9.12 5.16h-0.12v-4.44h-5.04z"/>
|
||||
<path d="m217.92 0h5.4v-28.44h-5.4zm-1.26-38.64c0 2.16 1.8 3.96 3.96 3.96s3.96-1.8 3.96-3.96-1.8-3.96-3.96-3.96-3.96 1.8-3.96 3.96z"/>
|
||||
<path d="m231.9 0h5.4v-14.64c0-6.6 3.42-9.48 7.92-9.48 3.42 0 6.48 1.98 6.48 7.32v16.8h5.4v-18.3c0-7.56-4.8-10.86-10.32-10.86-4.38 0-7.98 2.1-9.36 5.1h-0.12v-4.38h-5.4z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 6.4 KiB |
27
gray-theme/images/logos/usermin-dark.svg
Normal file
@@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="515.9" height="101.7" version="1.0" viewBox="-0.2 5.6 515.9 101.7" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
|
||||
<metadata>
|
||||
<rdf:RDF>
|
||||
<cc:Work rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
|
||||
<dc:title/>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g transform="translate(-14.846 -49.258)">
|
||||
<path d="m90.72 155.26c-1.9595-0.19682-3.8581-0.75152-5.7044-1.6666-1.1733-0.58155-1.6331-0.84822-10.072-5.8415l-5.4628-3.2324-7.3547 4.1067c-7.8541 4.3855-8.6069 4.783-9.9302 5.2438-1.6577 0.5772-2.5891 0.7383-4.6412 0.80273-1.6804 0.0528-2.124 0.0282-3.3287-0.18456-3.1105-0.54929-5.9997-1.7248-8.3579-3.4007-1.1896-0.84536-3.2742-3.0493-4.0841-4.3177-2.2185-3.4747-3.2734-7.4041-3.0949-11.528 0.03596-0.83071 0.09689-1.6983 0.1354-1.9279 0.05815-0.34669 0.03567-0.42985-0.13224-0.48988-0.82586-0.29521-2.4336-1.0671-3.3797-1.6226-1.4917-0.87585-2.4031-1.5918-3.755-2.9498-4.1931-4.2119-5.9524-9.5734-5.0119-15.274 0.50928-3.0867 1.6192-5.8788 3.2467-8.1672 0.78341-1.1016 2.4542-2.8002 3.5605-3.6198 0.80231-0.5944 8.6121-5.4194 13.253-8.1877l1.8684-1.1146-0.07537-8.9504c-0.08215-9.7553-0.0596-10.335 0.48759-12.54 0.78222-3.1512 2.3563-5.8541 4.9154-8.4406 3.0226-3.0548 6.045-4.7237 9.7448-5.3805 1.8737-0.33265 5.1287-0.25586 7.0092 0.16538 2.9691 0.66508 5.8463 1.9977 8.4005 3.8908l0.72355 0.53628 1.0549-0.81808c2.8403-2.2027 5.6171-3.4674 9.0308-4.1129 1.7099-0.32334 5.0788-0.35381 6.5903-0.05964 3.7692 0.7336 6.9142 2.5 9.7786 5.4922 2.87 2.998 4.4944 6.1791 5.1753 10.135 0.23853 1.3857 0.24695 3.3304 0.0545 12.561-0.094 4.5059-0.11484 7.3979-0.0538 7.4594 0.17782 0.17933 3.2269 1.9865 8.1583 4.8354 7.4248 4.2893 7.8433 4.5704 9.7135 6.5233 2.398 2.504 3.9711 5.6684 4.7011 9.4567 0.33021 1.7135 0.36039 5.0233 0.059 6.475-0.62284 3.0005-1.8314 5.4972-3.9007 8.058-2.0406 2.5254-5.1175 4.7162-8.261 5.882l-0.96961 0.3596-0.0196 2.8984c-0.0216 3.1813-0.12995 3.9984-0.83545 6.2973-1.097 3.5746-3.4712 6.9972-6.2841 9.0591-1.2498 0.91615-3.424 2.023-5.0624 2.5773-2.7677 0.93628-5.3471 1.267-7.8896 1.0117zm4.4243-11.784c1.8838-0.65915 3.1037-1.9053 3.9232-4.0075 0.36505-0.93646 0.45026-2.4135 0.19863-3.4435-0.63313-2.5918-1.7897-3.5225-11.158-8.9796-8.6264-5.0247-8.9097-5.2049-9.9169-6.3069-1.0737-1.1748-1.5004-2.2389-1.5004-3.7416 0-1.1466 0.29948-2.1182 0.97734-3.1709 0.66523-1.0331 1.2212-1.5471 2.2001-2.0339 1.0358-0.51516 2.0735-0.68707 3.1505-0.52191 1.7548 0.2691 1.7616 0.27257 11.229 5.7286 3.8803 2.2362 7.4266 4.2313 7.8807 4.4334 1.4624 0.65106 2.977 0.98949 4.4522 0.99482 1.2374 4e-3 1.3238-0.0107 2.0263-0.3563 1.3864-0.68208 2.9425-2.5724 3.4216-4.1564 0.45358-1.4997 0.38272-3.2049-0.18509-4.4546-0.50996-1.1223-1.7244-2.256-3.9465-3.684-0.91361-0.58713-8.2605-4.9075-13.003-7.6464-3.8904-2.2469-4.5416-2.7812-5.2334-4.2944-0.73202-1.6011-0.72627-1.4932-0.61639-11.578 0.05411-4.9635 0.06285-9.7545 0.01952-10.647-0.14089-2.8964-0.55697-4.1774-1.7641-5.4313-2.3891-2.4816-6.9286-2.6171-9.1926-0.27444-1.0482 1.0846-1.661 2.4019-2.0818 4.4751-0.20117 0.99121-0.22257 1.7228-0.31739 10.852-0.07818 7.5248-0.13703 10.009-0.25447 10.739-0.40717 2.5307-2.153 4.4792-4.4706 4.9896-3.5303 0.77745-6.6774-1.3822-7.2775-4.9942-0.13589-0.81799-0.14564-2.2161-0.06825-9.7882 0.04967-4.8587 0.05326-9.5909 8e-3 -10.516-0.14464-2.96-0.55091-4.222-1.7651-5.4832-2.3891-2.4816-6.9286-2.6171-9.1926-0.27444-1.0464 1.0827-1.6566 2.3928-2.0844 4.4751-0.20622 1.0036-0.22294 1.6238-0.30005 11.132-0.05456 6.7253-0.12152 10.243-0.20168 10.593-0.47513 2.0748-1.5588 3.5921-3.3293 4.6616-0.39842 0.24068-2.0573 1.2434-3.6864 2.2283-1.6291 0.98488-4.61 2.7604-6.6242 3.9457-5.303 3.1206-6.6801 4.049-7.6667 5.1688-0.84283 0.95666-1.2522 2.1578-1.2541 3.6794-0.0023 1.7115 0.74744 3.4202 2.1124 4.8156 1.6443 1.6809 3.5857 1.9079 6.9161 0.80846 1.3384-0.44183 2.4913-1.0512 6.7857-3.5866 4.2636-2.5172 4.9789-2.9313 8.2469-4.7734 2.4491-1.3805 3.1867-1.6922 4.4547-1.8826 2.2371-0.33596 4.1226 0.53769 5.4128 2.5081 0.77996 1.1911 1.0431 2.1194 0.98584 3.4784-0.03814 0.90595-0.09185 1.1376-0.44039 1.8999-0.41817 0.91465-1.2796 1.9679-2.0725 2.5341-0.66473 0.47466-2.2635 1.4095-7.7551 4.5344-6.1279 3.487-7.4951 4.303-9.1015 5.432-1.9674 1.3828-2.7289 2.3299-3.181 3.9563-0.28103 1.0111-0.17979 2.803 0.2091 3.7006 0.6296 1.4533 2.0366 2.962 3.3488 3.5911 0.71026 0.3405 1.7097 0.60438 2.2891 0.60438 1.1058 0 3.2263-0.65177 4.8198-1.4814 1.1254-0.58593 5.4662-3.0152 10.448-5.847 6.2588-3.5578 6.4792-3.6552 8.2937-3.6665 1.8057-0.0112 2.9141 0.38888 5.8164 2.0995 13.708 8.08 15.249 8.9216 16.891 9.2272 0.9198 0.17114 2.185 0.0639 3.1242-0.26468z" fill="#5fd24f" style="paint-order:stroke fill markers"/>
|
||||
|
||||
<g transform="scale(.9803 1.0201)" fill="#5fd24f" stroke-width="1.0297" aria-label="usermin">
|
||||
<path d="m157.89 115.02v-19.474c0-1.6805-0.69196-3.1632-1.8782-4.4483-1.2851-1.1862-2.7678-1.8782-4.4483-1.8782-1.7793 0-3.2621 0.69196-4.4483 1.8782-1.2851 1.2851-1.8782 2.7678-1.8782 4.4483v19.474c0 3.5586 0.59311 6.9196 1.977 9.9839 1.3839 3.1632 3.2621 5.8322 5.6345 8.2046 2.3724 2.3724 5.1402 4.1517 8.3035 5.4368 3.1632 1.3839 6.5242 1.977 10.083 1.977s7.0184-0.5931 10.182-1.977c3.1632-1.2851 5.8322-3.0644 8.2046-5.4368 2.3724-2.2736 4.1517-4.9425 5.5357-8.1058 1.3839-3.1632 2.0759-6.5242 2.0759-10.083v-19.474c0-1.6805-0.69195-3.1632-1.8782-4.4483-1.2851-1.1862-2.7678-1.8782-4.4483-1.8782-1.7793 0-3.2621 0.69196-4.4483 1.8782-1.2851 1.2851-1.8782 2.7678-1.8782 4.4483v19.474c0 1.977-0.3954 3.7563-0.98851 5.4368-0.69196 1.6805-1.5816 3.1632-2.7678 4.4483-1.1862 1.2851-2.669 2.2736-4.2506 3.0644-1.5816 0.7908-3.3609 1.0874-5.338 1.0874s-3.8552-0.29656-5.4368-1.0874c-1.5816-0.79081-2.9655-1.7793-4.1517-3.0644s-2.1747-2.7678-2.7678-4.4483c-0.69196-1.6805-0.98851-3.4598-0.98851-5.4368z"/>
|
||||
<path d="m228.57 129.65c-2.1747 0-3.8552-0.1977-5.2391-0.79081-1.3839-0.5931-2.669-1.1862-3.6575-1.7793-1.0874-0.59311-2.0759-1.1862-2.9655-1.7793-0.88966-0.5931-1.8782-0.88966-2.8667-0.88966-1.5816 0-2.9655 0.59311-4.0529 1.6805-1.1862 1.0874-1.6805 2.4713-1.6805 4.1517 0 1.1862 0.49426 2.4713 1.4828 3.6575 0.9885 1.1862 2.3724 2.2736 4.1517 3.2621 1.7793 0.98851 3.954 1.8782 6.5242 2.4713 2.4713 0.69196 5.2391 0.98851 8.2046 0.98851 2.7678 0 5.338-0.29655 7.9081-1.0874 2.5701-0.69195 4.8437-1.6805 6.8207-3.0644 1.977-1.3839 3.4598-2.9655 4.646-4.9425s1.7793-4.1517 1.7793-6.623c0-2.9655-0.79081-5.338-2.1747-7.2161-1.4828-1.7793-3.3609-3.2621-5.5356-4.3494s-4.5471-1.977-7.1173-2.5701c-2.5701-0.59311-4.9425-1.0874-7.1173-1.6805-2.1747-0.49425-4.0529-1.0874-5.4368-1.7793-1.4828-0.59311-2.1747-1.5816-2.1747-2.9655 0-1.1862 0.59311-2.1747 1.8782-3.0644 1.2851-0.7908 3.3609-1.2851 6.1288-1.2851 1.7793 0 3.4598 0.29655 4.8437 0.79081 1.3839 0.5931 2.669 1.1862 3.8552 1.7793 0.69196 0.3954 1.4828 0.88965 2.4713 1.4828 0.88965 0.5931 1.8782 0.88966 3.0644 0.88966 1.7793 0 3.1632-0.59311 4.0529-1.7793s1.3839-2.3724 1.3839-3.7563c0-1.0874-0.49425-2.2736-1.2851-3.4598-0.88966-1.1862-2.1747-2.2736-3.8552-3.2621-1.6805-0.98851-3.7563-1.7793-6.1288-2.3724-2.4713-0.59311-5.2391-0.98851-8.3035-0.98851-2.9655 0-5.7334 0.3954-8.1058 1.1862-2.4713 0.79081-4.5471 1.8782-6.3265 3.2621-1.7793 1.3839-3.0644 3.0644-4.0529 4.8437-0.98851 1.7793-1.3839 3.7563-1.3839 5.7334 0 3.1632 0.69196 5.7334 2.0759 7.6115 1.3839 1.977 3.2621 3.4598 5.4368 4.646s4.4483 1.977 6.9196 2.5701c2.4713 0.5931 4.8437 1.1862 7.0184 1.6805 2.1747 0.49426 3.954 1.0874 5.338 1.6805 1.3839 0.69195 2.1747 1.6805 2.1747 2.8667 0 1.3839-0.88966 2.4713-2.4713 3.1632-1.5816 0.79081-3.6575 1.0874-6.2276 1.0874z"/>
|
||||
<path d="m272.16 119.97h29.556c2.0759 0 3.8552-0.69195 5.2391-2.0759 1.3839-1.3839 2.1747-3.1632 2.1747-5.3379 0-2.8667-0.69196-5.7334-1.8782-8.5012-1.2851-2.7678-2.9655-5.2391-5.1402-7.4138-2.1747-2.1747-4.8437-3.8552-7.8092-5.2391-2.9655-1.3839-6.2276-2.0759-9.6874-2.0759-3.5586 0-6.8207 0.69196-9.8851 1.977-3.1632 1.3839-5.8322 3.1632-8.1058 5.4368-2.3724 2.3724-4.1517 5.0414-5.5356 8.1058-1.3839 3.1632-2.0759 6.4253-2.0759 9.9839 0 3.5586 0.59311 6.9196 1.977 10.083 1.2851 3.1632 3.0644 5.8322 5.4368 8.2046s5.1402 4.1517 8.3035 5.5356c3.1632 1.3839 6.5242 1.977 10.28 1.977 2.3724 0 4.4483-0.0988 6.2276-0.3954 1.7793-0.1977 3.2621-0.59311 4.646-0.98851 1.2851-0.3954 2.3724-0.79081 3.1632-1.1862 0.7908-0.39541 1.4828-0.79081 1.977-1.0874 0.88966-0.59311 1.6805-1.3839 2.3724-2.2736 0.5931-0.88966 0.9885-1.977 0.9885-3.3609 0-1.5816-0.5931-2.8667-1.6805-3.954-1.1862-0.98851-2.5701-1.5816-4.1517-1.5816-1.5816 0-3.0644 0.49425-4.5471 1.4828-0.79081 0.59311-1.8782 0.98851-3.3609 1.3839-1.4828 0.39541-3.3609 0.59311-5.6345 0.59311-1.4828 0-2.9655-0.1977-4.3494-0.69196-1.3839-0.3954-2.669-1.0874-3.8552-1.8782-1.1862-0.7908-2.1747-1.7793-2.9655-2.9655-0.88966-1.1862-1.4828-2.3724-1.6805-3.7563zm12.455-19.474c1.5816 0 3.1632 0.29655 4.646 0.88965 1.4828 0.59311 2.7678 1.2851 3.8552 2.1747 1.0874 0.88966 1.977 1.8782 2.669 3.0644 0.69195 1.1862 1.1862 2.2736 1.3839 3.3609h-25.009c0.1977-1.1862 0.69196-2.2736 1.4828-3.4598 0.69195-1.0874 1.5816-2.0759 2.7678-2.9655 1.0874-0.88965 2.3724-1.5816 3.7563-2.1747 1.3839-0.5931 2.8667-0.88965 4.4483-0.88965z"/>
|
||||
<path d="m447.03 134.3v-20.66c0-3.5586-0.69196-6.9196-1.977-9.9839-1.2851-2.9655-3.0644-5.5357-5.2391-7.7104-2.2736-2.0759-4.8437-3.7563-7.8092-4.9425-2.9655-1.1862-6.0299-1.7793-9.1931-1.7793-3.5586 0-6.9196 0.69196-9.8851 2.0759-2.9655 1.3839-5.6345 3.2621-7.9081 5.7334-2.2736-2.3724-4.9426-4.3494-8.0069-5.7334-3.1632-1.3839-6.4253-2.0759-9.7862-2.0759s-6.4253 0.5931-9.3908 1.7793-5.5356 2.8667-7.7104 5.0414-3.954 4.7448-5.2391 7.7104c-1.3839 2.9655-1.977 6.3264-1.977 9.8851v20.66c0 1.7793 0.5931 3.2621 1.8782 4.4483 1.1862 1.2851 2.669 1.8782 4.4483 1.8782 1.6805 0 3.1632-0.5931 4.4483-1.8782 1.1862-1.1862 1.8782-2.669 1.8782-4.4483v-21.747c0-3.6575 1.0874-6.5242 3.3609-8.6 2.1747-2.0759 4.9426-3.1632 8.3035-3.1632 1.5816 0 3.0644 0.29655 4.4483 0.79081 1.3839 0.5931 2.5701 1.3839 3.5586 2.3724s1.8782 2.2736 2.4713 3.6575c0.59311 1.4828 0.98851 3.1632 0.98851 4.9426v21.747c0 1.7793 0.59311 3.2621 1.8782 4.4483 1.1862 1.2851 2.669 1.8782 4.4483 1.8782 1.6805 0 3.1632-0.5931 4.3494-1.8782 1.1862-1.1862 1.8782-2.669 1.8782-4.4483v-21.747c0-1.7793 0.29656-3.4598 0.88966-4.9426 0.59311-1.3839 1.4828-2.669 2.4713-3.6575 0.9885-0.98851 2.2736-1.7793 3.6575-2.3724 1.3839-0.49426 2.9655-0.79081 4.5471-0.79081 3.3609 0 6.1288 1.0874 8.3035 3.1632 2.1747 2.1747 3.3609 5.0414 3.3609 8.6v21.747c0 1.7793 0.5931 3.2621 1.8782 4.4483 1.1862 1.2851 2.669 1.8782 4.4483 1.8782 1.6805 0 3.1632-0.5931 4.3494-1.8782 1.1862-1.1862 1.8782-2.669 1.8782-4.4483z"/>
|
||||
<path d="m473.92 134.3v-37.761c0-1.6805-0.69195-3.1632-1.8782-4.4483-1.2851-1.1862-2.7678-1.8782-4.4483-1.8782-1.7793 0-3.2621 0.69196-4.4483 1.8782-1.2851 1.2851-1.8782 2.7678-1.8782 4.4483v37.761c0 1.7793 0.5931 3.2621 1.8782 4.4483 1.1862 1.2851 2.669 1.8782 4.4483 1.8782 1.6805 0 3.1632-0.5931 4.4483-1.8782 1.1862-1.1862 1.8782-2.669 1.8782-4.4483zm-14.037-57.136c0 2.1747 0.69196 3.954 2.2736 5.4368 1.4828 1.5816 3.2621 2.2736 5.4368 2.2736 2.0759 0 3.8552-0.69196 5.4368-2.2736 1.4828-1.4828 2.2736-3.2621 2.2736-5.4368 0-2.0759-0.79081-3.8552-2.2736-5.4368-1.5816-1.4828-3.3609-2.2736-5.4368-2.2736-2.1747 0-3.954 0.79081-5.4368 2.2736-1.5816 1.5816-2.2736 3.3609-2.2736 5.4368z"/>
|
||||
<path d="m527.49 114.83v19.474c0 1.7793 0.59311 3.2621 1.8782 4.4483 1.1862 1.2851 2.669 1.8782 4.4483 1.8782 1.6805 0 3.1632-0.5931 4.4483-1.8782 1.1862-1.1862 1.8782-2.669 1.8782-4.4483v-19.474c0-3.5586-0.69196-6.8207-2.0759-9.9839-1.3839-3.0644-3.1632-5.7334-5.5356-8.1058-2.3724-2.3724-5.1402-4.1517-8.3035-5.5356-3.1632-1.2851-6.5242-1.977-10.083-1.977-3.6575 0-7.0184 0.69196-10.182 1.977-3.1632 1.3839-5.9311 3.1632-8.3035 5.4368-2.3724 2.3724-4.1517 5.0414-5.5356 8.2046-1.3839 3.1632-1.977 6.4253-1.977 9.9839v19.474c0 1.7793 0.59311 3.2621 1.8782 4.4483 1.1862 1.2851 2.669 1.8782 4.4483 1.8782 1.6805 0 3.1632-0.5931 4.4483-1.8782 1.1862-1.1862 1.8782-2.669 1.8782-4.4483v-19.474c0-1.8782 0.29655-3.6575 0.98851-5.338 0.5931-1.6805 1.5816-3.1632 2.7678-4.4483s2.5701-2.2736 4.1517-3.0644 3.4598-1.1862 5.4368-1.1862 3.7563 0.3954 5.338 1.1862c1.5816 0.79081 3.0644 1.7793 4.2506 3.0644s2.0759 2.7678 2.7678 4.4483c0.59311 1.6805 0.98851 3.4598 0.98851 5.338z"/>
|
||||
</g>
|
||||
<g transform="scale(1.0955 .91286)" fill="#5fd24f" aria-label="r">
|
||||
<path d="m298.81 155.22q-1.7655 1.9732-4.5696 1.9732-2.8041 0-4.5696-1.9732-1.7655-1.9732-1.7655-4.7773v-42.996q0-2.8041 1.7655-4.7773 1.7655-1.9732 4.5696-1.9732 5.0889 0 6.2313 4.7773l0.10386 2.2848h0.20771q5.0889-7.6853 11.528-7.6853 3.1156 0 5.0889 1.9732 1.9732 1.8694 1.9732 4.6735 0 2.3887-1.6617 4.0503-1.5578 1.6617-6.439 2.9079-5.8159 1.454-8.2046 4.7773-2.3887 3.2195-2.3887 8.8277v23.16q0 2.8041-1.8694 4.7773z" fill="#5fd24f" stroke-width="1.0818"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 13 KiB |
27
gray-theme/images/logos/usermin.svg
Normal file
@@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="515.9" height="101.7" version="1.0" viewBox="-0.2 5.6 515.9 101.7" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
|
||||
<metadata>
|
||||
<rdf:RDF>
|
||||
<cc:Work rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
|
||||
<dc:title/>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g transform="translate(-14.846 -49.258)">
|
||||
<path d="m90.72 155.26c-1.9595-0.19682-3.8581-0.75152-5.7044-1.6666-1.1733-0.58155-1.6331-0.84822-10.072-5.8415l-5.4628-3.2324-7.3547 4.1067c-7.8541 4.3855-8.6069 4.783-9.9302 5.2438-1.6577 0.5772-2.5891 0.7383-4.6412 0.80273-1.6804 0.0528-2.124 0.0282-3.3287-0.18456-3.1105-0.54929-5.9997-1.7248-8.3579-3.4007-1.1896-0.84536-3.2742-3.0493-4.0841-4.3177-2.2185-3.4747-3.2734-7.4041-3.0949-11.528 0.03596-0.83071 0.09689-1.6983 0.1354-1.9279 0.05815-0.34669 0.03567-0.42985-0.13224-0.48988-0.82586-0.29521-2.4336-1.0671-3.3797-1.6226-1.4917-0.87585-2.4031-1.5918-3.755-2.9498-4.1931-4.2119-5.9524-9.5734-5.0119-15.274 0.50928-3.0867 1.6192-5.8788 3.2467-8.1672 0.78341-1.1016 2.4542-2.8002 3.5605-3.6198 0.80231-0.5944 8.6121-5.4194 13.253-8.1877l1.8684-1.1146-0.07537-8.9504c-0.08215-9.7553-0.0596-10.335 0.48759-12.54 0.78222-3.1512 2.3563-5.8541 4.9154-8.4406 3.0226-3.0548 6.045-4.7237 9.7448-5.3805 1.8737-0.33265 5.1287-0.25586 7.0092 0.16538 2.9691 0.66508 5.8463 1.9977 8.4005 3.8908l0.72355 0.53628 1.0549-0.81808c2.8403-2.2027 5.6171-3.4674 9.0308-4.1129 1.7099-0.32334 5.0788-0.35381 6.5903-0.05964 3.7692 0.7336 6.9142 2.5 9.7786 5.4922 2.87 2.998 4.4944 6.1791 5.1753 10.135 0.23853 1.3857 0.24695 3.3304 0.0545 12.561-0.094 4.5059-0.11484 7.3979-0.0538 7.4594 0.17782 0.17933 3.2269 1.9865 8.1583 4.8354 7.4248 4.2893 7.8433 4.5704 9.7135 6.5233 2.398 2.504 3.9711 5.6684 4.7011 9.4567 0.33021 1.7135 0.36039 5.0233 0.059 6.475-0.62284 3.0005-1.8314 5.4972-3.9007 8.058-2.0406 2.5254-5.1175 4.7162-8.261 5.882l-0.96961 0.3596-0.0196 2.8984c-0.0216 3.1813-0.12995 3.9984-0.83545 6.2973-1.097 3.5746-3.4712 6.9972-6.2841 9.0591-1.2498 0.91615-3.424 2.023-5.0624 2.5773-2.7677 0.93628-5.3471 1.267-7.8896 1.0117zm4.4243-11.784c1.8838-0.65915 3.1037-1.9053 3.9232-4.0075 0.36505-0.93646 0.45026-2.4135 0.19863-3.4435-0.63313-2.5918-1.7897-3.5225-11.158-8.9796-8.6264-5.0247-8.9097-5.2049-9.9169-6.3069-1.0737-1.1748-1.5004-2.2389-1.5004-3.7416 0-1.1466 0.29948-2.1182 0.97734-3.1709 0.66523-1.0331 1.2212-1.5471 2.2001-2.0339 1.0358-0.51516 2.0735-0.68707 3.1505-0.52191 1.7548 0.2691 1.7616 0.27257 11.229 5.7286 3.8803 2.2362 7.4266 4.2313 7.8807 4.4334 1.4624 0.65106 2.977 0.98949 4.4522 0.99482 1.2374 4e-3 1.3238-0.0107 2.0263-0.3563 1.3864-0.68208 2.9425-2.5724 3.4216-4.1564 0.45358-1.4997 0.38272-3.2049-0.18509-4.4546-0.50996-1.1223-1.7244-2.256-3.9465-3.684-0.91361-0.58713-8.2605-4.9075-13.003-7.6464-3.8904-2.2469-4.5416-2.7812-5.2334-4.2944-0.73202-1.6011-0.72627-1.4932-0.61639-11.578 0.05411-4.9635 0.06285-9.7545 0.01952-10.647-0.14089-2.8964-0.55697-4.1774-1.7641-5.4313-2.3891-2.4816-6.9286-2.6171-9.1926-0.27444-1.0482 1.0846-1.661 2.4019-2.0818 4.4751-0.20117 0.99121-0.22257 1.7228-0.31739 10.852-0.07818 7.5248-0.13703 10.009-0.25447 10.739-0.40717 2.5307-2.153 4.4792-4.4706 4.9896-3.5303 0.77745-6.6774-1.3822-7.2775-4.9942-0.13589-0.81799-0.14564-2.2161-0.06825-9.7882 0.04967-4.8587 0.05326-9.5909 8e-3 -10.516-0.14464-2.96-0.55091-4.222-1.7651-5.4832-2.3891-2.4816-6.9286-2.6171-9.1926-0.27444-1.0464 1.0827-1.6566 2.3928-2.0844 4.4751-0.20622 1.0036-0.22294 1.6238-0.30005 11.132-0.05456 6.7253-0.12152 10.243-0.20168 10.593-0.47513 2.0748-1.5588 3.5921-3.3293 4.6616-0.39842 0.24068-2.0573 1.2434-3.6864 2.2283-1.6291 0.98488-4.61 2.7604-6.6242 3.9457-5.303 3.1206-6.6801 4.049-7.6667 5.1688-0.84283 0.95666-1.2522 2.1578-1.2541 3.6794-0.0023 1.7115 0.74744 3.4202 2.1124 4.8156 1.6443 1.6809 3.5857 1.9079 6.9161 0.80846 1.3384-0.44183 2.4913-1.0512 6.7857-3.5866 4.2636-2.5172 4.9789-2.9313 8.2469-4.7734 2.4491-1.3805 3.1867-1.6922 4.4547-1.8826 2.2371-0.33596 4.1226 0.53769 5.4128 2.5081 0.77996 1.1911 1.0431 2.1194 0.98584 3.4784-0.03814 0.90595-0.09185 1.1376-0.44039 1.8999-0.41817 0.91465-1.2796 1.9679-2.0725 2.5341-0.66473 0.47466-2.2635 1.4095-7.7551 4.5344-6.1279 3.487-7.4951 4.303-9.1015 5.432-1.9674 1.3828-2.7289 2.3299-3.181 3.9563-0.28103 1.0111-0.17979 2.803 0.2091 3.7006 0.6296 1.4533 2.0366 2.962 3.3488 3.5911 0.71026 0.3405 1.7097 0.60438 2.2891 0.60438 1.1058 0 3.2263-0.65177 4.8198-1.4814 1.1254-0.58593 5.4662-3.0152 10.448-5.847 6.2588-3.5578 6.4792-3.6552 8.2937-3.6665 1.8057-0.0112 2.9141 0.38888 5.8164 2.0995 13.708 8.08 15.249 8.9216 16.891 9.2272 0.9198 0.17114 2.185 0.0639 3.1242-0.26468z" fill="#19b70e" style="paint-order:stroke fill markers"/>
|
||||
|
||||
<g transform="scale(.9803 1.0201)" fill="#19b70e" stroke-width="1.0297" aria-label="usermin">
|
||||
<path d="m157.89 115.02v-19.474c0-1.6805-0.69196-3.1632-1.8782-4.4483-1.2851-1.1862-2.7678-1.8782-4.4483-1.8782-1.7793 0-3.2621 0.69196-4.4483 1.8782-1.2851 1.2851-1.8782 2.7678-1.8782 4.4483v19.474c0 3.5586 0.59311 6.9196 1.977 9.9839 1.3839 3.1632 3.2621 5.8322 5.6345 8.2046 2.3724 2.3724 5.1402 4.1517 8.3035 5.4368 3.1632 1.3839 6.5242 1.977 10.083 1.977s7.0184-0.5931 10.182-1.977c3.1632-1.2851 5.8322-3.0644 8.2046-5.4368 2.3724-2.2736 4.1517-4.9425 5.5357-8.1058 1.3839-3.1632 2.0759-6.5242 2.0759-10.083v-19.474c0-1.6805-0.69195-3.1632-1.8782-4.4483-1.2851-1.1862-2.7678-1.8782-4.4483-1.8782-1.7793 0-3.2621 0.69196-4.4483 1.8782-1.2851 1.2851-1.8782 2.7678-1.8782 4.4483v19.474c0 1.977-0.3954 3.7563-0.98851 5.4368-0.69196 1.6805-1.5816 3.1632-2.7678 4.4483-1.1862 1.2851-2.669 2.2736-4.2506 3.0644-1.5816 0.7908-3.3609 1.0874-5.338 1.0874s-3.8552-0.29656-5.4368-1.0874c-1.5816-0.79081-2.9655-1.7793-4.1517-3.0644s-2.1747-2.7678-2.7678-4.4483c-0.69196-1.6805-0.98851-3.4598-0.98851-5.4368z"/>
|
||||
<path d="m228.57 129.65c-2.1747 0-3.8552-0.1977-5.2391-0.79081-1.3839-0.5931-2.669-1.1862-3.6575-1.7793-1.0874-0.59311-2.0759-1.1862-2.9655-1.7793-0.88966-0.5931-1.8782-0.88966-2.8667-0.88966-1.5816 0-2.9655 0.59311-4.0529 1.6805-1.1862 1.0874-1.6805 2.4713-1.6805 4.1517 0 1.1862 0.49426 2.4713 1.4828 3.6575 0.9885 1.1862 2.3724 2.2736 4.1517 3.2621 1.7793 0.98851 3.954 1.8782 6.5242 2.4713 2.4713 0.69196 5.2391 0.98851 8.2046 0.98851 2.7678 0 5.338-0.29655 7.9081-1.0874 2.5701-0.69195 4.8437-1.6805 6.8207-3.0644 1.977-1.3839 3.4598-2.9655 4.646-4.9425s1.7793-4.1517 1.7793-6.623c0-2.9655-0.79081-5.338-2.1747-7.2161-1.4828-1.7793-3.3609-3.2621-5.5356-4.3494s-4.5471-1.977-7.1173-2.5701c-2.5701-0.59311-4.9425-1.0874-7.1173-1.6805-2.1747-0.49425-4.0529-1.0874-5.4368-1.7793-1.4828-0.59311-2.1747-1.5816-2.1747-2.9655 0-1.1862 0.59311-2.1747 1.8782-3.0644 1.2851-0.7908 3.3609-1.2851 6.1288-1.2851 1.7793 0 3.4598 0.29655 4.8437 0.79081 1.3839 0.5931 2.669 1.1862 3.8552 1.7793 0.69196 0.3954 1.4828 0.88965 2.4713 1.4828 0.88965 0.5931 1.8782 0.88966 3.0644 0.88966 1.7793 0 3.1632-0.59311 4.0529-1.7793s1.3839-2.3724 1.3839-3.7563c0-1.0874-0.49425-2.2736-1.2851-3.4598-0.88966-1.1862-2.1747-2.2736-3.8552-3.2621-1.6805-0.98851-3.7563-1.7793-6.1288-2.3724-2.4713-0.59311-5.2391-0.98851-8.3035-0.98851-2.9655 0-5.7334 0.3954-8.1058 1.1862-2.4713 0.79081-4.5471 1.8782-6.3265 3.2621-1.7793 1.3839-3.0644 3.0644-4.0529 4.8437-0.98851 1.7793-1.3839 3.7563-1.3839 5.7334 0 3.1632 0.69196 5.7334 2.0759 7.6115 1.3839 1.977 3.2621 3.4598 5.4368 4.646s4.4483 1.977 6.9196 2.5701c2.4713 0.5931 4.8437 1.1862 7.0184 1.6805 2.1747 0.49426 3.954 1.0874 5.338 1.6805 1.3839 0.69195 2.1747 1.6805 2.1747 2.8667 0 1.3839-0.88966 2.4713-2.4713 3.1632-1.5816 0.79081-3.6575 1.0874-6.2276 1.0874z"/>
|
||||
<path d="m272.16 119.97h29.556c2.0759 0 3.8552-0.69195 5.2391-2.0759 1.3839-1.3839 2.1747-3.1632 2.1747-5.3379 0-2.8667-0.69196-5.7334-1.8782-8.5012-1.2851-2.7678-2.9655-5.2391-5.1402-7.4138-2.1747-2.1747-4.8437-3.8552-7.8092-5.2391-2.9655-1.3839-6.2276-2.0759-9.6874-2.0759-3.5586 0-6.8207 0.69196-9.8851 1.977-3.1632 1.3839-5.8322 3.1632-8.1058 5.4368-2.3724 2.3724-4.1517 5.0414-5.5356 8.1058-1.3839 3.1632-2.0759 6.4253-2.0759 9.9839 0 3.5586 0.59311 6.9196 1.977 10.083 1.2851 3.1632 3.0644 5.8322 5.4368 8.2046s5.1402 4.1517 8.3035 5.5356c3.1632 1.3839 6.5242 1.977 10.28 1.977 2.3724 0 4.4483-0.0988 6.2276-0.3954 1.7793-0.1977 3.2621-0.59311 4.646-0.98851 1.2851-0.3954 2.3724-0.79081 3.1632-1.1862 0.7908-0.39541 1.4828-0.79081 1.977-1.0874 0.88966-0.59311 1.6805-1.3839 2.3724-2.2736 0.5931-0.88966 0.9885-1.977 0.9885-3.3609 0-1.5816-0.5931-2.8667-1.6805-3.954-1.1862-0.98851-2.5701-1.5816-4.1517-1.5816-1.5816 0-3.0644 0.49425-4.5471 1.4828-0.79081 0.59311-1.8782 0.98851-3.3609 1.3839-1.4828 0.39541-3.3609 0.59311-5.6345 0.59311-1.4828 0-2.9655-0.1977-4.3494-0.69196-1.3839-0.3954-2.669-1.0874-3.8552-1.8782-1.1862-0.7908-2.1747-1.7793-2.9655-2.9655-0.88966-1.1862-1.4828-2.3724-1.6805-3.7563zm12.455-19.474c1.5816 0 3.1632 0.29655 4.646 0.88965 1.4828 0.59311 2.7678 1.2851 3.8552 2.1747 1.0874 0.88966 1.977 1.8782 2.669 3.0644 0.69195 1.1862 1.1862 2.2736 1.3839 3.3609h-25.009c0.1977-1.1862 0.69196-2.2736 1.4828-3.4598 0.69195-1.0874 1.5816-2.0759 2.7678-2.9655 1.0874-0.88965 2.3724-1.5816 3.7563-2.1747 1.3839-0.5931 2.8667-0.88965 4.4483-0.88965z"/>
|
||||
<path d="m447.03 134.3v-20.66c0-3.5586-0.69196-6.9196-1.977-9.9839-1.2851-2.9655-3.0644-5.5357-5.2391-7.7104-2.2736-2.0759-4.8437-3.7563-7.8092-4.9425-2.9655-1.1862-6.0299-1.7793-9.1931-1.7793-3.5586 0-6.9196 0.69196-9.8851 2.0759-2.9655 1.3839-5.6345 3.2621-7.9081 5.7334-2.2736-2.3724-4.9426-4.3494-8.0069-5.7334-3.1632-1.3839-6.4253-2.0759-9.7862-2.0759s-6.4253 0.5931-9.3908 1.7793-5.5356 2.8667-7.7104 5.0414-3.954 4.7448-5.2391 7.7104c-1.3839 2.9655-1.977 6.3264-1.977 9.8851v20.66c0 1.7793 0.5931 3.2621 1.8782 4.4483 1.1862 1.2851 2.669 1.8782 4.4483 1.8782 1.6805 0 3.1632-0.5931 4.4483-1.8782 1.1862-1.1862 1.8782-2.669 1.8782-4.4483v-21.747c0-3.6575 1.0874-6.5242 3.3609-8.6 2.1747-2.0759 4.9426-3.1632 8.3035-3.1632 1.5816 0 3.0644 0.29655 4.4483 0.79081 1.3839 0.5931 2.5701 1.3839 3.5586 2.3724s1.8782 2.2736 2.4713 3.6575c0.59311 1.4828 0.98851 3.1632 0.98851 4.9426v21.747c0 1.7793 0.59311 3.2621 1.8782 4.4483 1.1862 1.2851 2.669 1.8782 4.4483 1.8782 1.6805 0 3.1632-0.5931 4.3494-1.8782 1.1862-1.1862 1.8782-2.669 1.8782-4.4483v-21.747c0-1.7793 0.29656-3.4598 0.88966-4.9426 0.59311-1.3839 1.4828-2.669 2.4713-3.6575 0.9885-0.98851 2.2736-1.7793 3.6575-2.3724 1.3839-0.49426 2.9655-0.79081 4.5471-0.79081 3.3609 0 6.1288 1.0874 8.3035 3.1632 2.1747 2.1747 3.3609 5.0414 3.3609 8.6v21.747c0 1.7793 0.5931 3.2621 1.8782 4.4483 1.1862 1.2851 2.669 1.8782 4.4483 1.8782 1.6805 0 3.1632-0.5931 4.3494-1.8782 1.1862-1.1862 1.8782-2.669 1.8782-4.4483z"/>
|
||||
<path d="m473.92 134.3v-37.761c0-1.6805-0.69195-3.1632-1.8782-4.4483-1.2851-1.1862-2.7678-1.8782-4.4483-1.8782-1.7793 0-3.2621 0.69196-4.4483 1.8782-1.2851 1.2851-1.8782 2.7678-1.8782 4.4483v37.761c0 1.7793 0.5931 3.2621 1.8782 4.4483 1.1862 1.2851 2.669 1.8782 4.4483 1.8782 1.6805 0 3.1632-0.5931 4.4483-1.8782 1.1862-1.1862 1.8782-2.669 1.8782-4.4483zm-14.037-57.136c0 2.1747 0.69196 3.954 2.2736 5.4368 1.4828 1.5816 3.2621 2.2736 5.4368 2.2736 2.0759 0 3.8552-0.69196 5.4368-2.2736 1.4828-1.4828 2.2736-3.2621 2.2736-5.4368 0-2.0759-0.79081-3.8552-2.2736-5.4368-1.5816-1.4828-3.3609-2.2736-5.4368-2.2736-2.1747 0-3.954 0.79081-5.4368 2.2736-1.5816 1.5816-2.2736 3.3609-2.2736 5.4368z"/>
|
||||
<path d="m527.49 114.83v19.474c0 1.7793 0.59311 3.2621 1.8782 4.4483 1.1862 1.2851 2.669 1.8782 4.4483 1.8782 1.6805 0 3.1632-0.5931 4.4483-1.8782 1.1862-1.1862 1.8782-2.669 1.8782-4.4483v-19.474c0-3.5586-0.69196-6.8207-2.0759-9.9839-1.3839-3.0644-3.1632-5.7334-5.5356-8.1058-2.3724-2.3724-5.1402-4.1517-8.3035-5.5356-3.1632-1.2851-6.5242-1.977-10.083-1.977-3.6575 0-7.0184 0.69196-10.182 1.977-3.1632 1.3839-5.9311 3.1632-8.3035 5.4368-2.3724 2.3724-4.1517 5.0414-5.5356 8.2046-1.3839 3.1632-1.977 6.4253-1.977 9.9839v19.474c0 1.7793 0.59311 3.2621 1.8782 4.4483 1.1862 1.2851 2.669 1.8782 4.4483 1.8782 1.6805 0 3.1632-0.5931 4.4483-1.8782 1.1862-1.1862 1.8782-2.669 1.8782-4.4483v-19.474c0-1.8782 0.29655-3.6575 0.98851-5.338 0.5931-1.6805 1.5816-3.1632 2.7678-4.4483s2.5701-2.2736 4.1517-3.0644 3.4598-1.1862 5.4368-1.1862 3.7563 0.3954 5.338 1.1862c1.5816 0.79081 3.0644 1.7793 4.2506 3.0644s2.0759 2.7678 2.7678 4.4483c0.59311 1.6805 0.98851 3.4598 0.98851 5.338z"/>
|
||||
</g>
|
||||
<g transform="scale(1.0955 .91286)" fill="#19b70e" aria-label="r">
|
||||
<path d="m298.81 155.22q-1.7655 1.9732-4.5696 1.9732-2.8041 0-4.5696-1.9732-1.7655-1.9732-1.7655-4.7773v-42.996q0-2.8041 1.7655-4.7773 1.7655-1.9732 4.5696-1.9732 5.0889 0 6.2313 4.7773l0.10386 2.2848h0.20771q5.0889-7.6853 11.528-7.6853 3.1156 0 5.0889 1.9732 1.9732 1.8694 1.9732 4.6735 0 2.3887-1.6617 4.0503-1.5578 1.6617-6.439 2.9079-5.8159 1.454-8.2046 4.7773-2.3887 3.2195-2.3887 8.8277v23.16q0 2.8041-1.8694 4.7773z" fill="#19b70e" stroke-width="1.0818"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 13 KiB |
1
gray-theme/images/logos/virtualmin.svg
Normal file
|
After Width: | Height: | Size: 5.3 KiB |
24
gray-theme/images/logos/webmin-dark.svg
Normal file
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="517.8" height="101.7" version="1.0" viewBox="-1.2 5.6 517.8 101.7" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
|
||||
<metadata>
|
||||
<rdf:RDF>
|
||||
<cc:Work rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
|
||||
<dc:title/>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g transform="translate(-14.846 -49.258)">
|
||||
<g transform="matrix(.9803 0 0 1.0201 1.7678 0)" fill="#6aa8f0" stroke-width="1.0297" aria-label="webmin">
|
||||
<path d="m145.24 95.55v20.66c0 3.7563 0.59311 7.1173 1.8782 10.083s3.0644 5.5356 5.338 7.6115c2.1747 2.1747 4.7448 3.7563 7.7104 4.9426 2.8667 1.1862 5.931 1.7793 9.292 1.7793 3.5586 0 6.8207-0.5931 9.7862-1.977s5.6345-3.2621 8.0069-5.8322c2.1747 2.4713 4.8437 4.3494 8.0069 5.7334 3.0644 1.3839 6.3264 2.0759 9.7862 2.0759 3.1632 0 6.3264-0.5931 9.292-1.7793 2.9655-1.1862 5.5356-2.7678 7.7104-4.9426s3.954-4.7448 5.338-7.7104c1.2851-2.9655 1.977-6.3265 1.977-9.9839v-20.66c0-1.6805-0.69196-3.1632-1.8782-4.4483-1.2851-1.1862-2.7678-1.8782-4.4483-1.8782-1.7793 0-3.2621 0.69196-4.4483 1.8782-1.2851 1.2851-1.8782 2.7678-1.8782 4.4483v21.747c0 3.7563-1.1862 6.623-3.3609 8.6989-2.2736 2.0759-5.0414 3.0644-8.3035 3.0644-1.5816 0-3.0644-0.19771-4.4483-0.79081-1.3839-0.49426-2.669-1.2851-3.6575-2.2736s-1.8782-2.2736-2.4713-3.7563c-0.59311-1.3839-0.88966-3.0644-0.88966-4.9425v-21.747c0-1.6805-0.69196-3.1632-1.8782-4.4483-1.2851-1.1862-2.7678-1.8782-4.4483-1.8782-1.7793 0-3.2621 0.69196-4.4483 1.8782-1.1862 1.2851-1.7793 2.7678-1.7793 4.4483v21.747c0 1.8782-0.39541 3.5586-0.98851 4.9425-0.59311 1.4828-1.4828 2.7678-2.4713 3.7563-0.98851 0.98851-2.2736 1.7793-3.6575 2.2736-1.3839 0.5931-2.8667 0.79081-4.4483 0.79081-3.3609 0-6.2276-0.98851-8.4023-3.1632-2.1747-2.0759-3.2621-4.9426-3.2621-8.6v-21.747c0-1.6805-0.69196-3.1632-1.8782-4.4483-1.2851-1.1862-2.7678-1.8782-4.4483-1.8782-1.7793 0-3.2621 0.69196-4.4483 1.8782-1.1862 1.2851-1.7793 2.7678-1.7793 4.4483z"/>
|
||||
<path d="m252.89 119.97h29.556c2.0759 0 3.8552-0.69195 5.2391-2.0759 1.3839-1.3839 2.1747-3.1632 2.1747-5.3379 0-2.8667-0.69195-5.7334-1.8782-8.5012-1.2851-2.7678-2.9655-5.2391-5.1402-7.4138s-4.8437-3.8552-7.8092-5.2391-6.2276-2.0759-9.6874-2.0759c-3.5586 0-6.8207 0.69196-9.8851 1.977-3.1632 1.3839-5.8322 3.1632-8.1058 5.4368-2.3724 2.3724-4.1517 5.0414-5.5356 8.1058-1.3839 3.1632-2.0759 6.4253-2.0759 9.9839s0.5931 6.9196 1.977 10.083c1.2851 3.1632 3.0644 5.8322 5.4368 8.2046s5.1402 4.1517 8.3035 5.5356c3.1632 1.3839 6.5242 1.977 10.28 1.977 2.3724 0 4.4483-0.0988 6.2276-0.3954 1.7793-0.1977 3.2621-0.59311 4.646-0.98851 1.2851-0.3954 2.3724-0.79081 3.1632-1.1862 0.79081-0.39541 1.4828-0.79081 1.977-1.0874 0.88966-0.59311 1.6805-1.3839 2.3724-2.2736 0.59311-0.88966 0.98851-1.977 0.98851-3.3609 0-1.5816-0.5931-2.8667-1.6805-3.954-1.1862-0.98851-2.5701-1.5816-4.1517-1.5816s-3.0644 0.49425-4.5471 1.4828c-0.79081 0.59311-1.8782 0.98851-3.3609 1.3839-1.4828 0.39541-3.3609 0.59311-5.6345 0.59311-1.4828 0-2.9655-0.1977-4.3494-0.69196-1.3839-0.3954-2.669-1.0874-3.8552-1.8782s-2.1747-1.7793-2.9655-2.9655c-0.88966-1.1862-1.4828-2.3724-1.6805-3.7563zm12.455-19.474c1.5816 0 3.1632 0.29655 4.646 0.88965 1.4828 0.59311 2.7678 1.2851 3.8552 2.1747 1.0874 0.88966 1.977 1.8782 2.669 3.0644 0.69196 1.1862 1.1862 2.2736 1.3839 3.3609h-25.009c0.1977-1.1862 0.69195-2.2736 1.4828-3.4598 0.69196-1.0874 1.5816-2.0759 2.7678-2.9655 1.0874-0.88965 2.3724-1.5816 3.7563-2.1747s2.8667-0.88965 4.4483-0.88965z"/>
|
||||
<path d="m300.24 71.826v62.474c0 1.7793 0.5931 3.2621 1.8782 4.4483 1.1862 1.2851 2.669 1.8782 4.4483 1.8782 0.7908 0 1.5816-0.0988 2.3724-0.49425 0.69195-0.29656 1.2851-0.69196 1.8782-1.2851 0.49426-0.49426 0.88966-1.0874 1.1862-1.6805 0.29656-0.59311 0.49426-1.2851 0.49426-1.8782 1.2851 1.1862 3.0644 2.3724 5.4368 3.5586 2.2736 1.1862 5.1402 1.7793 8.6989 1.7793 3.3609 0 6.623-0.5931 9.6874-1.977s5.7334-3.1632 8.0069-5.5356c2.1747-2.2736 3.954-5.0414 5.338-8.2046 1.2851-3.1632 1.977-6.5242 1.977-10.083 0-3.5586-0.69195-6.8207-2.0759-9.9839-1.3839-3.1632-3.1632-5.8322-5.5356-8.2046-2.3724-2.2736-5.0414-4.0529-8.1058-5.4368-3.0644-1.2851-6.3265-1.977-9.6874-1.977-3.2621 0-6.0299 0.5931-8.3035 1.7793s-3.954 2.3724-5.0414 3.4598v-22.637c0-1.6805-0.69195-3.1632-1.8782-4.4483-1.2851-1.1862-2.7678-1.8782-4.4483-1.8782-1.7793 0-3.2621 0.69196-4.4483 1.8782-1.2851 1.2851-1.8782 2.7678-1.8782 4.4483zm11.664 43c0-1.977 0.29656-3.7563 0.98851-5.5356 0.69196-1.6805 1.6805-3.1632 2.8667-4.4483 1.1862-1.1862 2.669-2.1747 4.3494-2.9655 1.6805-0.69196 3.5586-1.0874 5.5356-1.0874s3.7563 0.3954 5.4368 1.1862c1.6805 0.79081 3.1632 1.7793 4.4483 3.0644 1.1862 1.2851 2.1747 2.7678 2.9655 4.4483 0.69195 1.6805 1.0874 3.4598 1.0874 5.338 0 1.977-0.39541 3.7563-1.0874 5.4368-0.69196 1.7793-1.6805 3.2621-2.8667 4.5471-1.2851 1.3839-2.7678 2.3724-4.4483 3.1632-1.7793 0.7908-3.5586 1.1862-5.5356 1.1862s-3.8552-0.29656-5.5356-1.0874c-1.6805-0.69196-3.1632-1.6805-4.3494-2.9655s-2.1747-2.7678-2.8667-4.5471c-0.69195-1.7793-0.98851-3.6575-0.98851-5.7334z"/>
|
||||
<path d="m446.14 134.3v-20.66c0-3.5586-0.69196-6.9196-1.977-9.9839-1.2851-2.9655-3.0644-5.5357-5.2391-7.7104-2.2736-2.0759-4.8437-3.7563-7.8092-4.9425s-6.0299-1.7793-9.1931-1.7793c-3.5586 0-6.9196 0.69196-9.8851 2.0759-2.9655 1.3839-5.6345 3.2621-7.9081 5.7334-2.2736-2.3724-4.9426-4.3494-8.0069-5.7334-3.1632-1.3839-6.4253-2.0759-9.7862-2.0759s-6.4253 0.5931-9.3908 1.7793-5.5356 2.8667-7.7104 5.0414-3.954 4.7448-5.2391 7.7104c-1.3839 2.9655-1.977 6.3264-1.977 9.8851v20.66c0 1.7793 0.5931 3.2621 1.8782 4.4483 1.1862 1.2851 2.669 1.8782 4.4483 1.8782 1.6805 0 3.1632-0.5931 4.4483-1.8782 1.1862-1.1862 1.8782-2.669 1.8782-4.4483v-21.747c0-3.6575 1.0874-6.5242 3.3609-8.6 2.1747-2.0759 4.9426-3.1632 8.3035-3.1632 1.5816 0 3.0644 0.29655 4.4483 0.79081 1.3839 0.5931 2.5701 1.3839 3.5586 2.3724s1.8782 2.2736 2.4713 3.6575c0.59311 1.4828 0.98851 3.1632 0.98851 4.9426v21.747c0 1.7793 0.59311 3.2621 1.8782 4.4483 1.1862 1.2851 2.669 1.8782 4.4483 1.8782 1.6805 0 3.1632-0.5931 4.3494-1.8782 1.1862-1.1862 1.8782-2.669 1.8782-4.4483v-21.747c0-1.7793 0.29656-3.4598 0.88966-4.9426 0.59311-1.3839 1.4828-2.669 2.4713-3.6575 0.9885-0.98851 2.2736-1.7793 3.6575-2.3724 1.3839-0.49426 2.9655-0.79081 4.5471-0.79081 3.3609 0 6.1288 1.0874 8.3035 3.1632 2.1747 2.1747 3.3609 5.0414 3.3609 8.6v21.747c0 1.7793 0.5931 3.2621 1.8782 4.4483 1.1862 1.2851 2.669 1.8782 4.4483 1.8782 1.6805 0 3.1632-0.5931 4.3494-1.8782 1.1862-1.1862 1.8782-2.669 1.8782-4.4483z"/>
|
||||
<path d="m473.03 134.3v-37.761c0-1.6805-0.69195-3.1632-1.8782-4.4483-1.2851-1.1862-2.7678-1.8782-4.4483-1.8782-1.7793 0-3.2621 0.69196-4.4483 1.8782-1.2851 1.2851-1.8782 2.7678-1.8782 4.4483v37.761c0 1.7793 0.5931 3.2621 1.8782 4.4483 1.1862 1.2851 2.669 1.8782 4.4483 1.8782 1.6805 0 3.1632-0.5931 4.4483-1.8782 1.1862-1.1862 1.8782-2.669 1.8782-4.4483zm-14.037-57.136c0 2.1747 0.69196 3.954 2.2736 5.4368 1.4828 1.5816 3.2621 2.2736 5.4368 2.2736 2.0759 0 3.8552-0.69196 5.4368-2.2736 1.4828-1.4828 2.2736-3.2621 2.2736-5.4368 0-2.0759-0.79081-3.8552-2.2736-5.4368-1.5816-1.4828-3.3609-2.2736-5.4368-2.2736-2.1747 0-3.954 0.79081-5.4368 2.2736-1.5816 1.5816-2.2736 3.3609-2.2736 5.4368z"/>
|
||||
<path d="m526.6 114.83v19.474c0 1.7793 0.59311 3.2621 1.8782 4.4483 1.1862 1.2851 2.669 1.8782 4.4483 1.8782 1.6805 0 3.1632-0.5931 4.4483-1.8782 1.1862-1.1862 1.8782-2.669 1.8782-4.4483v-19.474c0-3.5586-0.69196-6.8207-2.0759-9.9839-1.3839-3.0644-3.1632-5.7334-5.5356-8.1058s-5.1402-4.1517-8.3035-5.5356c-3.1632-1.2851-6.5242-1.977-10.083-1.977-3.6575 0-7.0184 0.69196-10.182 1.977-3.1632 1.3839-5.9311 3.1632-8.3035 5.4368-2.3724 2.3724-4.1517 5.0414-5.5356 8.2046s-1.977 6.4253-1.977 9.9839v19.474c0 1.7793 0.59311 3.2621 1.8782 4.4483 1.1862 1.2851 2.669 1.8782 4.4483 1.8782 1.6805 0 3.1632-0.5931 4.4483-1.8782 1.1862-1.1862 1.8782-2.669 1.8782-4.4483v-19.474c0-1.8782 0.29655-3.6575 0.98851-5.338 0.5931-1.6805 1.5816-3.1632 2.7678-4.4483s2.5701-2.2736 4.1517-3.0644 3.4598-1.1862 5.4368-1.1862 3.7563 0.3954 5.338 1.1862c1.5816 0.79081 3.0644 1.7793 4.2506 3.0644s2.0759 2.7678 2.7678 4.4483c0.59311 1.6805 0.98851 3.4598 0.98851 5.338z"/>
|
||||
</g>
|
||||
<path d="m89.712 155.26c-1.9595-0.19682-3.8581-0.75152-5.7044-1.6666-1.1733-0.58155-1.6331-0.84822-10.072-5.8415l-5.4628-3.2324-7.3547 4.1067c-7.8541 4.3855-8.6069 4.783-9.9302 5.2438-1.6577 0.5772-2.5891 0.7383-4.6412 0.80273-1.6804 0.0528-2.124 0.0282-3.3287-0.18456-3.1105-0.54929-5.9997-1.7248-8.3579-3.4007-1.1896-0.84536-3.2742-3.0493-4.0841-4.3177-2.2185-3.4747-3.2734-7.4041-3.0949-11.528 0.03596-0.83071 0.09689-1.6983 0.1354-1.9279 0.05815-0.34669 0.03567-0.42985-0.13224-0.48988-0.82586-0.29521-2.4336-1.0671-3.3797-1.6226-1.4917-0.87585-2.4031-1.5918-3.755-2.9498-4.1931-4.2119-5.9524-9.5734-5.0119-15.274 0.50928-3.0867 1.6192-5.8788 3.2467-8.1672 0.78341-1.1016 2.4542-2.8002 3.5605-3.6198 0.80231-0.5944 8.6121-5.4194 13.253-8.1877l1.8684-1.1146-0.07537-8.9504c-0.08215-9.7553-0.0596-10.335 0.48759-12.54 0.78222-3.1512 2.3563-5.8541 4.9154-8.4406 3.0226-3.0548 6.045-4.7237 9.7448-5.3805 1.8737-0.33265 5.1287-0.25586 7.0092 0.16538 2.9691 0.66508 5.8463 1.9977 8.4005 3.8908l0.72355 0.53628 1.0549-0.81808c2.8403-2.2027 5.6171-3.4674 9.0308-4.1129 1.7099-0.32334 5.0788-0.35381 6.5903-0.05964 3.7692 0.7336 6.9142 2.5 9.7786 5.4922 2.87 2.998 4.4944 6.1791 5.1753 10.135 0.23853 1.3857 0.24695 3.3304 0.0545 12.561-0.094 4.5059-0.11484 7.3979-0.0538 7.4594 0.17782 0.17933 3.2269 1.9865 8.1583 4.8354 7.4248 4.2893 7.8433 4.5704 9.7135 6.5233 2.398 2.504 3.9711 5.6684 4.7011 9.4567 0.33021 1.7135 0.36039 5.0233 0.059 6.475-0.62284 3.0005-1.8314 5.4972-3.9007 8.058-2.0406 2.5254-5.1175 4.7162-8.261 5.882l-0.96961 0.3596-0.0196 2.8984c-0.0216 3.1813-0.12995 3.9984-0.83545 6.2973-1.097 3.5746-3.4712 6.9972-6.2841 9.0591-1.2498 0.91615-3.424 2.023-5.0624 2.5773-2.7677 0.93628-5.3471 1.267-7.8896 1.0117zm4.4243-11.784c1.8838-0.65915 3.1037-1.9053 3.9232-4.0075 0.36505-0.93646 0.45026-2.4135 0.19863-3.4435-0.63313-2.5918-1.7897-3.5225-11.158-8.9796-8.6264-5.0247-8.9097-5.2049-9.9169-6.3069-1.0737-1.1748-1.5004-2.2389-1.5004-3.7416 0-1.1466 0.29948-2.1182 0.97734-3.1709 0.66523-1.0331 1.2212-1.5471 2.2001-2.0339 1.0358-0.51516 2.0735-0.68707 3.1505-0.52191 1.7548 0.2691 1.7616 0.27257 11.229 5.7286 3.8803 2.2362 7.4266 4.2313 7.8807 4.4334 1.4624 0.65106 2.977 0.98949 4.4522 0.99482 1.2374 4e-3 1.3238-0.0107 2.0263-0.3563 1.3864-0.68208 2.9425-2.5724 3.4216-4.1564 0.45358-1.4997 0.38272-3.2049-0.18509-4.4546-0.50996-1.1223-1.7244-2.256-3.9465-3.684-0.91361-0.58713-8.2605-4.9075-13.003-7.6464-3.8904-2.2469-4.5416-2.7812-5.2334-4.2944-0.73202-1.6011-0.72627-1.4932-0.61639-11.578 0.05411-4.9635 0.06285-9.7545 0.01952-10.647-0.14089-2.8964-0.55697-4.1774-1.7641-5.4313-2.3891-2.4816-6.9286-2.6171-9.1926-0.27444-1.0482 1.0846-1.661 2.4019-2.0818 4.4751-0.20117 0.99121-0.22257 1.7228-0.31739 10.852-0.07818 7.5248-0.13703 10.009-0.25447 10.739-0.40717 2.5307-2.153 4.4792-4.4706 4.9896-3.5303 0.77745-6.6774-1.3822-7.2775-4.9942-0.13589-0.81799-0.14564-2.2161-0.06825-9.7882 0.04967-4.8587 0.05326-9.5909 8e-3 -10.516-0.14464-2.96-0.55091-4.222-1.7651-5.4832-2.3891-2.4816-6.9286-2.6171-9.1926-0.27444-1.0464 1.0827-1.6566 2.3928-2.0844 4.4751-0.20622 1.0036-0.22294 1.6238-0.30005 11.132-0.05456 6.7253-0.12152 10.243-0.20168 10.593-0.47513 2.0748-1.5588 3.5921-3.3293 4.6616-0.39842 0.24068-2.0573 1.2434-3.6864 2.2283-1.6291 0.98488-4.61 2.7604-6.6242 3.9457-5.303 3.1206-6.6801 4.049-7.6667 5.1688-0.84283 0.95666-1.2522 2.1578-1.2541 3.6794-0.0023 1.7115 0.74744 3.4202 2.1124 4.8156 1.6443 1.6809 3.5857 1.9079 6.9161 0.80846 1.3384-0.44183 2.4913-1.0512 6.7857-3.5866 4.2636-2.5172 4.9789-2.9313 8.2469-4.7734 2.4491-1.3805 3.1867-1.6922 4.4547-1.8826 2.2371-0.33596 4.1226 0.53769 5.4128 2.5081 0.77996 1.1911 1.0431 2.1194 0.98584 3.4784-0.03814 0.90595-0.09185 1.1376-0.44039 1.8999-0.41817 0.91465-1.2796 1.9679-2.0725 2.5341-0.66473 0.47466-2.2635 1.4095-7.7551 4.5344-6.1279 3.487-7.4951 4.303-9.1015 5.432-1.9674 1.3828-2.7289 2.3299-3.181 3.9563-0.28103 1.0111-0.17979 2.803 0.2091 3.7006 0.6296 1.4533 2.0366 2.962 3.3488 3.5911 0.71026 0.3405 1.7097 0.60438 2.2891 0.60438 1.1058 0 3.2263-0.65177 4.8198-1.4814 1.1254-0.58593 5.4662-3.0152 10.448-5.847 6.2588-3.5578 6.4792-3.6552 8.2937-3.6665 1.8057-0.0112 2.9141 0.38888 5.8164 2.0995 13.708 8.08 15.249 8.9216 16.891 9.2272 0.9198 0.17114 2.185 0.0639 3.1242-0.26468z" fill="#6aa8f0" stroke="#3164b4" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.1646" style="paint-order:stroke fill markers"/>
|
||||
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 12 KiB |
24
gray-theme/images/logos/webmin.svg
Normal file
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="517.8" height="101.7" version="1.0" viewBox="-1.2 5.6 517.8 101.7" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
|
||||
<metadata>
|
||||
<rdf:RDF>
|
||||
<cc:Work rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
|
||||
<dc:title/>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g transform="translate(-14.846 -49.258)">
|
||||
<g transform="matrix(.9803 0 0 1.0201 1.7678 0)" fill="#005ebd" stroke-width="1.0297" aria-label="webmin">
|
||||
<path d="m145.24 95.55v20.66c0 3.7563 0.59311 7.1173 1.8782 10.083s3.0644 5.5356 5.338 7.6115c2.1747 2.1747 4.7448 3.7563 7.7104 4.9426 2.8667 1.1862 5.931 1.7793 9.292 1.7793 3.5586 0 6.8207-0.5931 9.7862-1.977s5.6345-3.2621 8.0069-5.8322c2.1747 2.4713 4.8437 4.3494 8.0069 5.7334 3.0644 1.3839 6.3264 2.0759 9.7862 2.0759 3.1632 0 6.3264-0.5931 9.292-1.7793 2.9655-1.1862 5.5356-2.7678 7.7104-4.9426s3.954-4.7448 5.338-7.7104c1.2851-2.9655 1.977-6.3265 1.977-9.9839v-20.66c0-1.6805-0.69196-3.1632-1.8782-4.4483-1.2851-1.1862-2.7678-1.8782-4.4483-1.8782-1.7793 0-3.2621 0.69196-4.4483 1.8782-1.2851 1.2851-1.8782 2.7678-1.8782 4.4483v21.747c0 3.7563-1.1862 6.623-3.3609 8.6989-2.2736 2.0759-5.0414 3.0644-8.3035 3.0644-1.5816 0-3.0644-0.19771-4.4483-0.79081-1.3839-0.49426-2.669-1.2851-3.6575-2.2736s-1.8782-2.2736-2.4713-3.7563c-0.59311-1.3839-0.88966-3.0644-0.88966-4.9425v-21.747c0-1.6805-0.69196-3.1632-1.8782-4.4483-1.2851-1.1862-2.7678-1.8782-4.4483-1.8782-1.7793 0-3.2621 0.69196-4.4483 1.8782-1.1862 1.2851-1.7793 2.7678-1.7793 4.4483v21.747c0 1.8782-0.39541 3.5586-0.98851 4.9425-0.59311 1.4828-1.4828 2.7678-2.4713 3.7563-0.98851 0.98851-2.2736 1.7793-3.6575 2.2736-1.3839 0.5931-2.8667 0.79081-4.4483 0.79081-3.3609 0-6.2276-0.98851-8.4023-3.1632-2.1747-2.0759-3.2621-4.9426-3.2621-8.6v-21.747c0-1.6805-0.69196-3.1632-1.8782-4.4483-1.2851-1.1862-2.7678-1.8782-4.4483-1.8782-1.7793 0-3.2621 0.69196-4.4483 1.8782-1.1862 1.2851-1.7793 2.7678-1.7793 4.4483z"/>
|
||||
<path d="m252.89 119.97h29.556c2.0759 0 3.8552-0.69195 5.2391-2.0759 1.3839-1.3839 2.1747-3.1632 2.1747-5.3379 0-2.8667-0.69195-5.7334-1.8782-8.5012-1.2851-2.7678-2.9655-5.2391-5.1402-7.4138s-4.8437-3.8552-7.8092-5.2391-6.2276-2.0759-9.6874-2.0759c-3.5586 0-6.8207 0.69196-9.8851 1.977-3.1632 1.3839-5.8322 3.1632-8.1058 5.4368-2.3724 2.3724-4.1517 5.0414-5.5356 8.1058-1.3839 3.1632-2.0759 6.4253-2.0759 9.9839s0.5931 6.9196 1.977 10.083c1.2851 3.1632 3.0644 5.8322 5.4368 8.2046s5.1402 4.1517 8.3035 5.5356c3.1632 1.3839 6.5242 1.977 10.28 1.977 2.3724 0 4.4483-0.0988 6.2276-0.3954 1.7793-0.1977 3.2621-0.59311 4.646-0.98851 1.2851-0.3954 2.3724-0.79081 3.1632-1.1862 0.79081-0.39541 1.4828-0.79081 1.977-1.0874 0.88966-0.59311 1.6805-1.3839 2.3724-2.2736 0.59311-0.88966 0.98851-1.977 0.98851-3.3609 0-1.5816-0.5931-2.8667-1.6805-3.954-1.1862-0.98851-2.5701-1.5816-4.1517-1.5816s-3.0644 0.49425-4.5471 1.4828c-0.79081 0.59311-1.8782 0.98851-3.3609 1.3839-1.4828 0.39541-3.3609 0.59311-5.6345 0.59311-1.4828 0-2.9655-0.1977-4.3494-0.69196-1.3839-0.3954-2.669-1.0874-3.8552-1.8782s-2.1747-1.7793-2.9655-2.9655c-0.88966-1.1862-1.4828-2.3724-1.6805-3.7563zm12.455-19.474c1.5816 0 3.1632 0.29655 4.646 0.88965 1.4828 0.59311 2.7678 1.2851 3.8552 2.1747 1.0874 0.88966 1.977 1.8782 2.669 3.0644 0.69196 1.1862 1.1862 2.2736 1.3839 3.3609h-25.009c0.1977-1.1862 0.69195-2.2736 1.4828-3.4598 0.69196-1.0874 1.5816-2.0759 2.7678-2.9655 1.0874-0.88965 2.3724-1.5816 3.7563-2.1747s2.8667-0.88965 4.4483-0.88965z"/>
|
||||
<path d="m300.24 71.826v62.474c0 1.7793 0.5931 3.2621 1.8782 4.4483 1.1862 1.2851 2.669 1.8782 4.4483 1.8782 0.7908 0 1.5816-0.0988 2.3724-0.49425 0.69195-0.29656 1.2851-0.69196 1.8782-1.2851 0.49426-0.49426 0.88966-1.0874 1.1862-1.6805 0.29656-0.59311 0.49426-1.2851 0.49426-1.8782 1.2851 1.1862 3.0644 2.3724 5.4368 3.5586 2.2736 1.1862 5.1402 1.7793 8.6989 1.7793 3.3609 0 6.623-0.5931 9.6874-1.977s5.7334-3.1632 8.0069-5.5356c2.1747-2.2736 3.954-5.0414 5.338-8.2046 1.2851-3.1632 1.977-6.5242 1.977-10.083 0-3.5586-0.69195-6.8207-2.0759-9.9839-1.3839-3.1632-3.1632-5.8322-5.5356-8.2046-2.3724-2.2736-5.0414-4.0529-8.1058-5.4368-3.0644-1.2851-6.3265-1.977-9.6874-1.977-3.2621 0-6.0299 0.5931-8.3035 1.7793s-3.954 2.3724-5.0414 3.4598v-22.637c0-1.6805-0.69195-3.1632-1.8782-4.4483-1.2851-1.1862-2.7678-1.8782-4.4483-1.8782-1.7793 0-3.2621 0.69196-4.4483 1.8782-1.2851 1.2851-1.8782 2.7678-1.8782 4.4483zm11.664 43c0-1.977 0.29656-3.7563 0.98851-5.5356 0.69196-1.6805 1.6805-3.1632 2.8667-4.4483 1.1862-1.1862 2.669-2.1747 4.3494-2.9655 1.6805-0.69196 3.5586-1.0874 5.5356-1.0874s3.7563 0.3954 5.4368 1.1862c1.6805 0.79081 3.1632 1.7793 4.4483 3.0644 1.1862 1.2851 2.1747 2.7678 2.9655 4.4483 0.69195 1.6805 1.0874 3.4598 1.0874 5.338 0 1.977-0.39541 3.7563-1.0874 5.4368-0.69196 1.7793-1.6805 3.2621-2.8667 4.5471-1.2851 1.3839-2.7678 2.3724-4.4483 3.1632-1.7793 0.7908-3.5586 1.1862-5.5356 1.1862s-3.8552-0.29656-5.5356-1.0874c-1.6805-0.69196-3.1632-1.6805-4.3494-2.9655s-2.1747-2.7678-2.8667-4.5471c-0.69195-1.7793-0.98851-3.6575-0.98851-5.7334z"/>
|
||||
<path d="m446.14 134.3v-20.66c0-3.5586-0.69196-6.9196-1.977-9.9839-1.2851-2.9655-3.0644-5.5357-5.2391-7.7104-2.2736-2.0759-4.8437-3.7563-7.8092-4.9425s-6.0299-1.7793-9.1931-1.7793c-3.5586 0-6.9196 0.69196-9.8851 2.0759-2.9655 1.3839-5.6345 3.2621-7.9081 5.7334-2.2736-2.3724-4.9426-4.3494-8.0069-5.7334-3.1632-1.3839-6.4253-2.0759-9.7862-2.0759s-6.4253 0.5931-9.3908 1.7793-5.5356 2.8667-7.7104 5.0414-3.954 4.7448-5.2391 7.7104c-1.3839 2.9655-1.977 6.3264-1.977 9.8851v20.66c0 1.7793 0.5931 3.2621 1.8782 4.4483 1.1862 1.2851 2.669 1.8782 4.4483 1.8782 1.6805 0 3.1632-0.5931 4.4483-1.8782 1.1862-1.1862 1.8782-2.669 1.8782-4.4483v-21.747c0-3.6575 1.0874-6.5242 3.3609-8.6 2.1747-2.0759 4.9426-3.1632 8.3035-3.1632 1.5816 0 3.0644 0.29655 4.4483 0.79081 1.3839 0.5931 2.5701 1.3839 3.5586 2.3724s1.8782 2.2736 2.4713 3.6575c0.59311 1.4828 0.98851 3.1632 0.98851 4.9426v21.747c0 1.7793 0.59311 3.2621 1.8782 4.4483 1.1862 1.2851 2.669 1.8782 4.4483 1.8782 1.6805 0 3.1632-0.5931 4.3494-1.8782 1.1862-1.1862 1.8782-2.669 1.8782-4.4483v-21.747c0-1.7793 0.29656-3.4598 0.88966-4.9426 0.59311-1.3839 1.4828-2.669 2.4713-3.6575 0.9885-0.98851 2.2736-1.7793 3.6575-2.3724 1.3839-0.49426 2.9655-0.79081 4.5471-0.79081 3.3609 0 6.1288 1.0874 8.3035 3.1632 2.1747 2.1747 3.3609 5.0414 3.3609 8.6v21.747c0 1.7793 0.5931 3.2621 1.8782 4.4483 1.1862 1.2851 2.669 1.8782 4.4483 1.8782 1.6805 0 3.1632-0.5931 4.3494-1.8782 1.1862-1.1862 1.8782-2.669 1.8782-4.4483z"/>
|
||||
<path d="m473.03 134.3v-37.761c0-1.6805-0.69195-3.1632-1.8782-4.4483-1.2851-1.1862-2.7678-1.8782-4.4483-1.8782-1.7793 0-3.2621 0.69196-4.4483 1.8782-1.2851 1.2851-1.8782 2.7678-1.8782 4.4483v37.761c0 1.7793 0.5931 3.2621 1.8782 4.4483 1.1862 1.2851 2.669 1.8782 4.4483 1.8782 1.6805 0 3.1632-0.5931 4.4483-1.8782 1.1862-1.1862 1.8782-2.669 1.8782-4.4483zm-14.037-57.136c0 2.1747 0.69196 3.954 2.2736 5.4368 1.4828 1.5816 3.2621 2.2736 5.4368 2.2736 2.0759 0 3.8552-0.69196 5.4368-2.2736 1.4828-1.4828 2.2736-3.2621 2.2736-5.4368 0-2.0759-0.79081-3.8552-2.2736-5.4368-1.5816-1.4828-3.3609-2.2736-5.4368-2.2736-2.1747 0-3.954 0.79081-5.4368 2.2736-1.5816 1.5816-2.2736 3.3609-2.2736 5.4368z"/>
|
||||
<path d="m526.6 114.83v19.474c0 1.7793 0.59311 3.2621 1.8782 4.4483 1.1862 1.2851 2.669 1.8782 4.4483 1.8782 1.6805 0 3.1632-0.5931 4.4483-1.8782 1.1862-1.1862 1.8782-2.669 1.8782-4.4483v-19.474c0-3.5586-0.69196-6.8207-2.0759-9.9839-1.3839-3.0644-3.1632-5.7334-5.5356-8.1058s-5.1402-4.1517-8.3035-5.5356c-3.1632-1.2851-6.5242-1.977-10.083-1.977-3.6575 0-7.0184 0.69196-10.182 1.977-3.1632 1.3839-5.9311 3.1632-8.3035 5.4368-2.3724 2.3724-4.1517 5.0414-5.5356 8.2046s-1.977 6.4253-1.977 9.9839v19.474c0 1.7793 0.59311 3.2621 1.8782 4.4483 1.1862 1.2851 2.669 1.8782 4.4483 1.8782 1.6805 0 3.1632-0.5931 4.4483-1.8782 1.1862-1.1862 1.8782-2.669 1.8782-4.4483v-19.474c0-1.8782 0.29655-3.6575 0.98851-5.338 0.5931-1.6805 1.5816-3.1632 2.7678-4.4483s2.5701-2.2736 4.1517-3.0644 3.4598-1.1862 5.4368-1.1862 3.7563 0.3954 5.338 1.1862c1.5816 0.79081 3.0644 1.7793 4.2506 3.0644s2.0759 2.7678 2.7678 4.4483c0.59311 1.6805 0.98851 3.4598 0.98851 5.338z"/>
|
||||
</g>
|
||||
<path d="m89.712 155.26c-1.9595-0.19682-3.8581-0.75152-5.7044-1.6666-1.1733-0.58155-1.6331-0.84822-10.072-5.8415l-5.4628-3.2324-7.3547 4.1067c-7.8541 4.3855-8.6069 4.783-9.9302 5.2438-1.6577 0.5772-2.5891 0.7383-4.6412 0.80273-1.6804 0.0528-2.124 0.0282-3.3287-0.18456-3.1105-0.54929-5.9997-1.7248-8.3579-3.4007-1.1896-0.84536-3.2742-3.0493-4.0841-4.3177-2.2185-3.4747-3.2734-7.4041-3.0949-11.528 0.03596-0.83071 0.09689-1.6983 0.1354-1.9279 0.05815-0.34669 0.03567-0.42985-0.13224-0.48988-0.82586-0.29521-2.4336-1.0671-3.3797-1.6226-1.4917-0.87585-2.4031-1.5918-3.755-2.9498-4.1931-4.2119-5.9524-9.5734-5.0119-15.274 0.50928-3.0867 1.6192-5.8788 3.2467-8.1672 0.78341-1.1016 2.4542-2.8002 3.5605-3.6198 0.80231-0.5944 8.6121-5.4194 13.253-8.1877l1.8684-1.1146-0.07537-8.9504c-0.08215-9.7553-0.0596-10.335 0.48759-12.54 0.78222-3.1512 2.3563-5.8541 4.9154-8.4406 3.0226-3.0548 6.045-4.7237 9.7448-5.3805 1.8737-0.33265 5.1287-0.25586 7.0092 0.16538 2.9691 0.66508 5.8463 1.9977 8.4005 3.8908l0.72355 0.53628 1.0549-0.81808c2.8403-2.2027 5.6171-3.4674 9.0308-4.1129 1.7099-0.32334 5.0788-0.35381 6.5903-0.05964 3.7692 0.7336 6.9142 2.5 9.7786 5.4922 2.87 2.998 4.4944 6.1791 5.1753 10.135 0.23853 1.3857 0.24695 3.3304 0.0545 12.561-0.094 4.5059-0.11484 7.3979-0.0538 7.4594 0.17782 0.17933 3.2269 1.9865 8.1583 4.8354 7.4248 4.2893 7.8433 4.5704 9.7135 6.5233 2.398 2.504 3.9711 5.6684 4.7011 9.4567 0.33021 1.7135 0.36039 5.0233 0.059 6.475-0.62284 3.0005-1.8314 5.4972-3.9007 8.058-2.0406 2.5254-5.1175 4.7162-8.261 5.882l-0.96961 0.3596-0.0196 2.8984c-0.0216 3.1813-0.12995 3.9984-0.83545 6.2973-1.097 3.5746-3.4712 6.9972-6.2841 9.0591-1.2498 0.91615-3.424 2.023-5.0624 2.5773-2.7677 0.93628-5.3471 1.267-7.8896 1.0117zm4.4243-11.784c1.8838-0.65915 3.1037-1.9053 3.9232-4.0075 0.36505-0.93646 0.45026-2.4135 0.19863-3.4435-0.63313-2.5918-1.7897-3.5225-11.158-8.9796-8.6264-5.0247-8.9097-5.2049-9.9169-6.3069-1.0737-1.1748-1.5004-2.2389-1.5004-3.7416 0-1.1466 0.29948-2.1182 0.97734-3.1709 0.66523-1.0331 1.2212-1.5471 2.2001-2.0339 1.0358-0.51516 2.0735-0.68707 3.1505-0.52191 1.7548 0.2691 1.7616 0.27257 11.229 5.7286 3.8803 2.2362 7.4266 4.2313 7.8807 4.4334 1.4624 0.65106 2.977 0.98949 4.4522 0.99482 1.2374 4e-3 1.3238-0.0107 2.0263-0.3563 1.3864-0.68208 2.9425-2.5724 3.4216-4.1564 0.45358-1.4997 0.38272-3.2049-0.18509-4.4546-0.50996-1.1223-1.7244-2.256-3.9465-3.684-0.91361-0.58713-8.2605-4.9075-13.003-7.6464-3.8904-2.2469-4.5416-2.7812-5.2334-4.2944-0.73202-1.6011-0.72627-1.4932-0.61639-11.578 0.05411-4.9635 0.06285-9.7545 0.01952-10.647-0.14089-2.8964-0.55697-4.1774-1.7641-5.4313-2.3891-2.4816-6.9286-2.6171-9.1926-0.27444-1.0482 1.0846-1.661 2.4019-2.0818 4.4751-0.20117 0.99121-0.22257 1.7228-0.31739 10.852-0.07818 7.5248-0.13703 10.009-0.25447 10.739-0.40717 2.5307-2.153 4.4792-4.4706 4.9896-3.5303 0.77745-6.6774-1.3822-7.2775-4.9942-0.13589-0.81799-0.14564-2.2161-0.06825-9.7882 0.04967-4.8587 0.05326-9.5909 8e-3 -10.516-0.14464-2.96-0.55091-4.222-1.7651-5.4832-2.3891-2.4816-6.9286-2.6171-9.1926-0.27444-1.0464 1.0827-1.6566 2.3928-2.0844 4.4751-0.20622 1.0036-0.22294 1.6238-0.30005 11.132-0.05456 6.7253-0.12152 10.243-0.20168 10.593-0.47513 2.0748-1.5588 3.5921-3.3293 4.6616-0.39842 0.24068-2.0573 1.2434-3.6864 2.2283-1.6291 0.98488-4.61 2.7604-6.6242 3.9457-5.303 3.1206-6.6801 4.049-7.6667 5.1688-0.84283 0.95666-1.2522 2.1578-1.2541 3.6794-0.0023 1.7115 0.74744 3.4202 2.1124 4.8156 1.6443 1.6809 3.5857 1.9079 6.9161 0.80846 1.3384-0.44183 2.4913-1.0512 6.7857-3.5866 4.2636-2.5172 4.9789-2.9313 8.2469-4.7734 2.4491-1.3805 3.1867-1.6922 4.4547-1.8826 2.2371-0.33596 4.1226 0.53769 5.4128 2.5081 0.77996 1.1911 1.0431 2.1194 0.98584 3.4784-0.03814 0.90595-0.09185 1.1376-0.44039 1.8999-0.41817 0.91465-1.2796 1.9679-2.0725 2.5341-0.66473 0.47466-2.2635 1.4095-7.7551 4.5344-6.1279 3.487-7.4951 4.303-9.1015 5.432-1.9674 1.3828-2.7289 2.3299-3.181 3.9563-0.28103 1.0111-0.17979 2.803 0.2091 3.7006 0.6296 1.4533 2.0366 2.962 3.3488 3.5911 0.71026 0.3405 1.7097 0.60438 2.2891 0.60438 1.1058 0 3.2263-0.65177 4.8198-1.4814 1.1254-0.58593 5.4662-3.0152 10.448-5.847 6.2588-3.5578 6.4792-3.6552 8.2937-3.6665 1.8057-0.0112 2.9141 0.38888 5.8164 2.0995 13.708 8.08 15.249 8.9216 16.891 9.2272 0.9198 0.17114 2.185 0.0639 3.1242-0.26468z" fill="#005ebd" stroke="#3164b4" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.1646" style="paint-order:stroke fill markers"/>
|
||||
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 12 KiB |
@@ -93,9 +93,18 @@ if ($current_lang_info->{'rtl'} || $current_lang eq "ar") {
|
||||
$fscols = "*,$cols";
|
||||
}
|
||||
|
||||
# Page header
|
||||
print "<html>\n";
|
||||
# Page head. The frameset declares the same color scheme as its frames,
|
||||
# since browsers give a frame the scheme of the page holding it. When no
|
||||
# scheme is forced, the script keeps it steady across reloads. The
|
||||
# stylesheet paints the page ground behind a frame that is still loading.
|
||||
$scheme = &theme_color_scheme();
|
||||
print "<html".($scheme ? " data-scheme='$scheme'" : "").">\n";
|
||||
print "<head>\n";
|
||||
print "<meta name='color-scheme' content='".($scheme || "light dark")."'>\n";
|
||||
print &theme_scheme_script() if (!$scheme);
|
||||
print "<link rel='stylesheet' type='text/css' href='".&get_webprefix().
|
||||
"/unauthenticated/gray-theme.css?".
|
||||
&theme_asset_key("gray-theme.css")."'>\n";
|
||||
print &ui_switch_theme_javascript();
|
||||
print "<title>$title</title>\n";
|
||||
my $imgdir = "@{[&get_webprefix()]}/images";
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
left_home=System Information
|
||||
left_search=Search
|
||||
left_dom=Virtual server
|
||||
left_sid=Managed system
|
||||
left_dname=Virtual server
|
||||
|
||||
right_virtver=Virtualmin version $1 or higher is now required by this theme!
|
||||
right_vm2ver=Cloudmin version $1 or higher is now required by this theme!
|
||||
@@ -59,6 +62,11 @@ edright_search=Show search box below left menu?
|
||||
edright_fsizedef=Decide automatically
|
||||
edright_pixels=pixels
|
||||
edright_efsize=Missing or invalid left frame width in pixels
|
||||
edright_scheme=Color scheme
|
||||
edright_scheme_auto=Follow the browser setting
|
||||
edright_scheme_light=Light
|
||||
edright_scheme_dark=Dark
|
||||
edright_escheme=Invalid color scheme
|
||||
edright_ecannot=You are not allowed to customize this page
|
||||
|
||||
has_virtualmin=Virtualmin
|
||||
|
||||