Merge branch 'master' of github.com:laf/librenms into issue-798

Conflicts:
	includes/polling/functions.inc.php
This commit is contained in:
laf 2015-05-04 09:16:48 +01:00
commit 0bf3b518f5
2092 changed files with 222802 additions and 74703 deletions

View File

@ -20,6 +20,7 @@ Contributors to LibreNMS:
- Joubert RedRat <me+github@redrat.com.br> (joubertredrat)
- Len Lin <Ultra2D@users.noreply.github.com> (Ultra2D)
- Christopher Freas <code@packetbusters.net> (nwautomator)
- Stuart Henderson <stu@spacehopper.org> (sthen)
[1]: http://observium.org/ "Observium web site"

View File

@ -43,3 +43,6 @@ font-awesome:
vis:
$(GIT_SUBTREE) --prefix=lib/vis https://github.com/almende/vis.git master
typeahead:
$(GIT_SUBTREE) -- prefix=lib/typeahead https://github.com/twitter/typeahead.js.git master

View File

@ -163,6 +163,10 @@ function RunAlerts() {
$updet = false;
$noacc = false;
}
if( IsMaintenance($alert['device_id']) > 0 ) {
$noiss = true;
$noacc = true;
}
if( $updet ) {
dbUpdate(array('details' => gzcompress(json_encode($alert['details']),9)),'alert_log','id = ?',array($alert['id']));
}
@ -204,7 +208,7 @@ function ExtTransports($obj) {
global $config;
$tmp = false; //To keep scrutinizer from naging because it doesnt understand eval
foreach( $config['alert']['transports'] as $transport=>$opts ) {
if( file_exists($config['install_dir']."/includes/alerts/transport.".$transport.".php") ) {
if( ($opts === true || !empty($opts)) && file_exists($config['install_dir']."/includes/alerts/transport.".$transport.".php") ) {
echo $transport." => ";
eval('$tmp = function($obj,$opts) { global $config; '.file_get_contents($config['install_dir']."/includes/alerts/transport.".$transport.".php").' };');
$tmp = $tmp($obj,$opts);
@ -288,7 +292,7 @@ function DescribeAlert($alert) {
$i++;
$obj['faults'][$i] = $incident;
foreach( $incident as $k=>$v ) {
if( !empty($v) && $k != 'device_id' && (stristr($k,'id') || stristr($k,'desc')) && substr_count($k,'_') <= 1 ) {
if( !empty($v) && $k != 'device_id' && (stristr($k,'id') || stristr($k,'desc') || stristr($k,'msg')) && substr_count($k,'_') <= 1 ) {
$obj['faults'][$i]['string'] .= $k.' => '.$v."; ";
}
}

0
contrib/generate-iplist.php Executable file → Normal file
View File

0
daily.sh Normal file → Executable file
View File

View File

@ -487,6 +487,7 @@ Output:
"count": 7,
"alerts": [
{
"hostname": "localhost",
"id": "1",
"device_id": "1",
"rule_id": "1",

View File

@ -22,6 +22,11 @@ Table of Content:
- [Ports](#entity-ports)
- [Processors](#entity-processors)
- [Storage](#entity-storage)
- [Macros](#macros)
- [Device](#macros-device)
- [Port](#macros-port)
- [Time](#macros-time)
# <a name="about">About</a>
@ -316,3 +321,109 @@ __processors.processor_descr__ = The description of the processor.
__storage.storage_descr__ = The description of the storage.
__storage.storage_perc__ = The usage of the storage as a percentage.
# <a name="macros">Macros</a>
Macros are shorthands to either portion of rules or pure SQL enhanced with placeholders.
You can define your own macros in your `config.php`.
Example macro-implementation of Debian-Devices
```php
$config['alert']['macros']['rule']['is_debian'] = '%devices.features ~ "@debian@"';
```
And in the Rule:
```
... && %macros.is_debian = "1" && ...
```
This Example-macro is a Boolean-macro, it applies a form of filter to the set of results defined by the rule.
All macros that are not unary should return Boolean.
You can only apply _Equal_ or _Not-Equal_ Operations on Bollean-macros where `True` is represented by `"1"` and `False` by `"0"`.
## <a name="macros-device">Device</a> (Boolean)
Entity: `%macros.device`
Description: Only select devices that aren't deleted, ignored or disabled.
Source: `(%devices.disabled = "0" && %devices.ignore = "0")`
### <a name="macros-device-up">Device is up</a> (Boolean)
Entity: `%macros.device_up`
Description: Only select devices that are up.
Implies: %macros.device
Source: `(%devices.status = "1" && %macros.device)`
### <a name="macros-device-down">Device is down</a> (Boolean)
Entity: `%macros.device_down`
Description: Only select devices that are down.
Implies: %macros.device
Source: `(%devices.status = "0" && %macros.device)`
## <a name="macros-port">Port</a> (Boolean)
Entity: `%macros.port`
Description: Only select ports that aren't deleted, ignored or disabled.
Source: `(%ports.deleted = "0" && %ports.ignore = "0" && %ports.disabled = "0")`
### <a name="macros-port-up">Port is up</a> (Boolean)
Entity: `%macros.port_up`
Description: Only select ports that are up and also should be up.
Implies: %macros.port
Source: `(%ports.ifOperStatus = "up" && %ports.ifAdminStatus = "up" && %macros.port)`
### <a name="macros-port-down">Port is down</a> (Boolean)
Entity: `%macros.port_down`
Description: Only select ports that are down.
Implies: %macros.port
Source: `(%ports.ifOperStatus = "down" && %ports.ifAdminStatus != "down" && %macros.port)`
### <a name="macros-port-usage-perc">Port-Usage in Percent</a> (Decimal)
Entity: `%macros.port_usage_perc`
Description: Return port-usage in percent.
Source: `((%ports.ifInOctets_rate*8)/%ports.ifSpeed)*100`
## <a name="macros-time">Time</a>
### <a name="macros-time-now">Now</a> (Datetime)
Entity: `%macros.now`
Description: Alias of MySQL's NOW()
Source: `NOW()`
### <a name="macros-time-past-Nm">Past N Minutes</a> (Datetime)
Entity: `%macros.past_$m`
Description: Returns a MySQL Timestamp dated `$` Minutes in the past. `$` can only be a supported Resolution.
Example: `%macros.past_5m` is Last 5 Minutes.
Resolution: 5,10,15,30,60
Source: `DATE_SUB(NOW(),INTERVAL $ MINUTE)`

View File

@ -32,7 +32,7 @@ rdware for remote pollers. Here's a diagram of how you can scale LibreNMS out:
How you setup the distribution is entirely up to you, you can choose to host the majority of the required services on a single virtual machine or server and then a poller to actually query the devices being monitored all the way through to having a dedicated server for each of the individual roles. Below are notes on what you need to consider both from the software layer but also connectivity.
####Web / API Layer
This is typically Apache but we have setup guides for both Nginx and Lighttpd which should work perfectly fine. Their is nothing unique about the role this service is providing except that if you are adding devices from this layer then the web service will need to be able to connect to the end device via SNMP and perform an ICMP test.
This is typically Apache but we have setup guides for both Nginx and Lighttpd which should work perfectly fine. There is nothing unique about the role this service is providing except that if you are adding devices from this layer then the web service will need to be able to connect to the end device via SNMP and perform an ICMP test.
It is advisable to run RRDCached within this setup so that you don't need to share the rrd folder via a remote file share such as NFS. The web service can then generate rrd graphs via RRDCached. If RRDCached isn't an option then you can mount the rrd directory to read the RRD files directly.
@ -81,3 +81,10 @@ RRDCached:
- You will need to tune RRDCached to suite your environment.
- The following is used in this example setup "-l 0:42217 -j /var/lib/rrdcached/journal/ -F -b /opt/librenms/rrd -B -w 1800 -z 900 -p /var/run/rrdcached.pid"
```php
$config['rrdcached'] = "127.0.0.1:42217";
$config['rrd_dir'] = "/opt/librenms/rrd";
$config['rrdcached_dir'] = "";
```
$config['rrdcached_dir'] Is only needed if you are using tcp connections for rrd cached and needs only to be set if you want to store rrd files within a sub directory of your rrdcached base directory.

View File

@ -1,3 +1,17 @@
### May 2015
#### Bug fixes
- Updated nested addHosts to use variables passed (PR889)
#### Improvements
- Added loading bar to top nav (PR893)
- Added load and current for APC units (PR888)
- Improved web installer (PR887)
- Updated alerts status box (PR875)
- Updated syslog page (PR862)
- Added temperature polling for IBM Flexsystem (PR894)
- Updated typeahead libraries and relevant forms (PR882)
### Apr 2015
####Bug fixes
@ -8,6 +22,22 @@
- Fixed alerts path issue (PR756, PR760)
- Supress further port alerts when interface goes down (PR745)
- Fixed login so redirects via 303 when POST data sent (PR775)
- Fixed missing link to errored or ignored ports (PR787)
- Updated alert log query for performance improvements (PR783)
- Honour alert_rules.disabled field (PR784)
- Stop page debug if user not logged in (PR785)
- Added text filtering for new tables (PR797)
- Fixed VMWare VM detection + hardware / serial support (PR799)
- Fix links from /health/processor (PR810)
- Hide divider if no plugins installed (PR811)
- Added Nginx fix for using debug option (PR823)
- Bug fixes for device groups SQL (PR840)
- Fixed path issue when using rrdcached (PR839)
- Fixed JS issues when deleting alert maps / poller groups / device groups (PR846,PR848,PR877)
- Fixed links and popover for /health/metric=storage/ (PR847)
- Fixed lots of user permission issues (PR855)
- Fixed search ip / arp / mac pages (PR845)
- Added missing charge icon (PR878)
####Improvements
- New theme support added (light,dark and mono) (PR682,PR683,PR701)
@ -23,10 +53,33 @@
- Shorten interface names on map (PR752)
- Added PowerCode support (PR762)
- Added Autodiscovery via OSPF (PR772)
- Added visual graph of alert log (PR777)
- Added visual graph of alert log (PR777, PR809)
- Added Callback system to send anonymous stats (PR768)
- More tables converted to use bootgrid (PR729, PR761)
- New Global Cache to store common queries added (PR780)
- Added proxy support for submitting stats (PR791)
- Minor APC Polling change (PR800)
- Updated to HP switch detection (PR802)
- Added Datacom basic detection (PR816)
- Updated Cisco detection (PR815)
- Added CSV export system + ability to export ports (PR818)
- Added basic detection for PacketLogic devices (PR773)
- Added fallback support for IBM switches for Serial / Version (PR822)
- Added Juniper Inventory support (PR825)
- Sharpen graphs produced (PR826)
- Updated map to show device overview graphs and port graphs (PR826)
- Added hostname to API call for list_alerts (PR834)
- Added ability to schedule maintenance (PR835,PR841)
- Added ability to expand alert triggers for more details (PR857)
- Added support for XTM/FBX Watchguard devices (PR849)
- Updated Juniper MIBS and hardware rewrite (PR838)
- Updated OpenBSD detection (PR860)
- Added Macro support for alerting system (PR863)
- Added support for tcp connections on rrdcached (PR866)
- Added config option to enable / disable mouseover graphs (PR873)
- General cleanup of files / folders permissions (PR874)
- Added window size detection for map (PR884)
- Added text to let users know refresh is disabled (PR883)
### Mar 2015

View File

@ -10,14 +10,17 @@ IT professionals. See [README.md][2] and the references there for more
information about the kind of community we're trying to promote.
LibreNMS was forked from [the last GPL-licensed version of Observium][3].
This means you won't be able to take an existing Observium installation
<del>This means you won't be able to take an existing Observium installation
later than r3250 and just change it to LibreNMS. This would probably break
(although if you were on a version between r3250 and the next database
schema change, it might be feasible). Upgrades from versions earlier than
r3251 might work. Please try it on an unimportant system and tell us your
experiences!
experiences!</del>
Thanks to one of our users Dan Brown who has written a migration script to be able move your Observium install over to LibreNMS [Dan Brown][10]. This also takes care of moving from one cpu architect to another. Give it a try :)
How LibreNMS will be different from Observium:
- We will have an inclusive community, where it's OK to ask stupid
questions, and OK to ask for things that aren't on the roadmap. If you'd
like to see something added, add or comment on the relevant issue in our
@ -25,7 +28,7 @@ How LibreNMS will be different from Observium:
- Development decisions will be community-driven. We want to make software
that fulfills its users' needs. See the [ROADMAP][4] for more thoughts
on our current plans.
- ~~Development will probably proceed at a slower pace, at least initially.~~
- <del>Development will probably proceed at a slower pace, at least initially.</del>
- There are no plans for a paid version, and we don't anticipate this ever
changing.
- There are no current plans for paid support, but this may be added later
@ -34,13 +37,15 @@ How LibreNMS will be different from Observium:
and painless as possible to create forked or private versions.
Reasons why you might want to use Observium instead of LibreNMS:
- You have a financial investment in Observium and aren't concerned about
community contributions.
- ~~You need functionality that has been added to Observium since r3250.~~ The beauty of LibreNMS is that you can contribute missing features.
- <del>You need functionality that has been added to Observium since r3250.</del> The beauty of LibreNMS is that you can contribute missing features.
- You don't like the [GNU General Public License, version 3][5] or the
[philosophy of Free Software/copyleft][6] in general.
Reasons why you might want to use LibreNMS instead of Observium:
- You want to work with others on the project, knowing that [your
investment of time and effort will not be wasted][7].
- You want to add and experiment with features that are not a priority for
@ -65,5 +70,6 @@ Reasons why you might want to use LibreNMS instead of Observium:
"Contribution guidelines"
[9]: https://github.com/librenms/librenms/issues
"LibreNMS issue database at GitHub"
[10]: https://vlan50.com/2015/04/17/migrating-from-observium-to-librenms/
"Migrating from Observium to LibreNMS"

0
html/ajax_listports.php Executable file → Normal file
View File

View File

@ -67,10 +67,16 @@ if( isset($_GET['term'],$_GET['device_id']) ) {
$chk = $memcache->get('rule-suggest_'.$term[0]);
}
if( !(sizeof($chk) > 0) || $chk === false ) {
$tmp = dbFetchRows('SHOW COLUMNS FROM '.$term[0]);
foreach( $tmp as $tst ) {
if( isset($tst['Field']) ) {
$chk[] = $term[0].'.'.$tst['Field'];
if( $term[0] == "macros" ) {
foreach( $config['alert']['macros']['rule'] as $macro=>$v ) {
$chk[] = "macros.".$macro;
}
} else {
$tmp = dbFetchRows('SHOW COLUMNS FROM '.$term[0]);
foreach( $tmp as $tst ) {
if( isset($tst['Field']) ) {
$chk[] = $term[0].'.'.$tst['Field'];
}
}
}
}
@ -84,6 +90,7 @@ if( isset($_GET['term'],$_GET['device_id']) ) {
foreach( $tmp as $tst ) {
$chk[] = $tst['TABLE_NAME'].'.';
}
$chk[] = 'macros.';
}
}
if( sizeof($chk) > 0 ) {

29
html/ajax_search.php Executable file → Normal file
View File

@ -31,9 +31,9 @@ if (isset($_REQUEST['search']))
if( $_REQUEST['type'] == 'group' ) {
include_once('../includes/device-groups.inc.php');
foreach( dbFetchRows("SELECT name FROM device_groups WHERE name LIKE '%".$search."%'") as $group ) {
foreach( dbFetchRows("SELECT id,name FROM device_groups WHERE name LIKE '%".$search."%'") as $group ) {
if( $_REQUEST['map'] ) {
$results[] = array('name'=>'g:'.$group['name']);
$results[] = array('name'=>'g:'.$group['name'],'group_id'=>$group['id']);
} else {
$results[] = array('name'=>$group['name']);
}
@ -47,7 +47,11 @@ if (isset($_REQUEST['search']))
} elseif($_REQUEST['type'] == 'device') {
// Device search
$results = dbFetchRows("SELECT * FROM `devices` WHERE `hostname` LIKE '%" . $search . "%' OR `location` LIKE '%" . $search . "%' ORDER BY hostname LIMIT 8");
if (is_admin() === TRUE || is_read() === TRUE) {
$results = dbFetchRows("SELECT * FROM `devices` WHERE `hostname` LIKE '%" . $search . "%' OR `location` LIKE '%" . $search . "%' ORDER BY hostname LIMIT 8");
} else {
$results = dbFetchRows("SELECT * FROM `devices` AS `D`, `devices_perms` AS `P` WHERE `P`.`user_id` = ? AND `P`.`device_id` = `D`.`device_id` AND (`hostname` LIKE '%" . $search . "%' OR `location` LIKE '%" . $search . "%') ORDER BY hostname LIMIT 8", array($_SESSION['user_id']));
}
if (count($results))
{
$found = 1;
@ -72,8 +76,13 @@ if (isset($_REQUEST['search']))
{
$highlight_colour = '#008000';
}
$num_ports = dbFetchCell("SELECT COUNT(*) FROM `ports` WHERE device_id = ?", array($result['device_id']));
if (is_admin() === TRUE || is_read() === TRUE) {
$num_ports = dbFetchCell("SELECT COUNT(*) FROM `ports` WHERE device_id = ?", array($result['device_id']));
} else {
$num_ports = dbFetchCell("SELECT COUNT(*) FROM `ports` AS `I`, `devices` AS `D`, `devices_perms` AS `P` WHERE `P`.`user_id` = ? AND `P`.`device_id` = `D`.`device_id` AND `I`.`device_id` = `D`.`device_id` AND device_id = ?", array($_SESSION['user_id'],$result['device_id']));
}
$device[]=array('name'=>$name,
'device_id'=>$result['device_id'],
'url'=> generate_device_url($result),
'colours'=>$highlight_colour,
'device_ports'=>$num_ports,
@ -90,7 +99,11 @@ if (isset($_REQUEST['search']))
} elseif($_REQUEST['type'] == 'ports') {
// Search ports
$results = dbFetchRows("SELECT `ports`.*,`devices`.* FROM `ports` LEFT JOIN `devices` ON `ports`.`device_id` = `devices`.`device_id` WHERE `ifAlias` LIKE '%" . $search . "%' OR `ifDescr` LIKE '%" . $search . "%' ORDER BY ifDescr LIMIT 8");
if (is_admin() === TRUE || is_read() === TRUE) {
$results = dbFetchRows("SELECT `ports`.*,`devices`.* FROM `ports` LEFT JOIN `devices` ON `ports`.`device_id` = `devices`.`device_id` WHERE `ifAlias` LIKE '%" . $search . "%' OR `ifDescr` LIKE '%" . $search . "%' ORDER BY ifDescr LIMIT 8");
} else {
$results = dbFetchRows("SELECT DISTINCT(`I`.`port_id`), `I`.*, `D`.`hostname` FROM `ports` AS `I`, `devices` AS `D`, `devices_perms` AS `P`, `ports_perms` AS `PP` WHERE ((`P`.`user_id` = ? AND `P`.`device_id` = `D`.`device_id`) OR (`PP`.`user_id` = ? AND `PP`.`port_id` = `I`.`port_id` AND `I`.`device_id` = `D`.`device_id`)) AND `D`.`device_id` = `I`.`device_id` AND (`ifAlias` LIKE '%" . $search . "%' OR `ifDescr` LIKE '%" . $search . "%') ORDER BY ifDescr LIMIT 8", array($_SESSION['user_id'],$_SESSION['user_id']));
}
if (count($results))
{
@ -143,7 +156,11 @@ if (isset($_REQUEST['search']))
} elseif($_REQUEST['type'] == 'bgp') {
// Search bgp peers
$results = dbFetchRows("SELECT `bgpPeers`.*,`devices`.* FROM `bgpPeers` LEFT JOIN `devices` ON `bgpPeers`.`device_id` = `devices`.`device_id` WHERE `astext` LIKE '%" . $search . "%' OR `bgpPeerIdentifier` LIKE '%" . $search . "%' OR `bgpPeerRemoteAs` LIKE '%" . $search . "%' ORDER BY `astext` LIMIT 8");
if (is_admin() === TRUE || is_read() === TRUE) {
$results = dbFetchRows("SELECT `bgpPeers`.*,`devices`.* FROM `bgpPeers` LEFT JOIN `devices` ON `bgpPeers`.`device_id` = `devices`.`device_id` WHERE `astext` LIKE '%" . $search . "%' OR `bgpPeerIdentifier` LIKE '%" . $search . "%' OR `bgpPeerRemoteAs` LIKE '%" . $search . "%' ORDER BY `astext` LIMIT 8");
} else {
$results = dbFetchRows("SELECT `bgpPeers`.*,`D`.* FROM `bgpPeers`, `devices` AS `D`, `devices_perms` AS `P` WHERE `P`.`user_id` = ? AND `P`.`device_id` = `D`.`device_id` AND `bgpPeers`.`device_id`=`D`.`device_id` AND (`astext` LIKE '%" . $search . "%' OR `bgpPeerIdentifier` LIKE '%" . $search . "%' OR `bgpPeerRemoteAs` LIKE '%" . $search . "%') ORDER BY `astext` LIMIT 8", array($_SESSION['user_id']));
}
if (count($results))
{
$found = 1;

0
html/billing-graph.php Executable file → Normal file
View File

View File

@ -17,3 +17,80 @@
.twitter-typeahead .tt-hint {
border-color: #000 !important;
}
.pace {
-webkit-pointer-events: none;
pointer-events: none;
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
}
.pace-inactive {
display: none;
}
.pace .pace-progress {
background: #e30613;
position: fixed;
z-index: 2000;
top: 0;
right: 100%;
width: 100%;
height: 2px;
}
.pace .pace-progress-inner {
display: block;
position: absolute;
right: 0px;
width: 100px;
height: 100%;
box-shadow: 0 0 10px #e30613, 0 0 5px #e30613;
opacity: 1.0;
-webkit-transform: rotate(3deg) translate(0px, -4px);
-moz-transform: rotate(3deg) translate(0px, -4px);
-ms-transform: rotate(3deg) translate(0px, -4px);
-o-transform: rotate(3deg) translate(0px, -4px);
transform: rotate(3deg) translate(0px, -4px);
}
.pace .pace-activity {
display: block;
position: fixed;
z-index: 2000;
top: 16px;
right: 45px;
width: 20px;
height: 20px;
border: solid 2px transparent;
border-top-color: #e30613;
border-left-color: #e30613;
border-radius: 10px;
-webkit-animation: pace-spinner 400ms linear infinite;
-moz-animation: pace-spinner 400ms linear infinite;
-ms-animation: pace-spinner 400ms linear infinite;
-o-animation: pace-spinner 400ms linear infinite;
animation: pace-spinner 400ms linear infinite;
}
@-webkit-keyframes pace-spinner {
0% { -webkit-transform: rotate(0deg); transform: rotate(0deg); }
100% { -webkit-transform: rotate(360deg); transform: rotate(360deg); }
}
@-moz-keyframes pace-spinner {
0% { -moz-transform: rotate(0deg); transform: rotate(0deg); }
100% { -moz-transform: rotate(360deg); transform: rotate(360deg); }
}
@-o-keyframes pace-spinner {
0% { -o-transform: rotate(0deg); transform: rotate(0deg); }
100% { -o-transform: rotate(360deg); transform: rotate(360deg); }
}
@-ms-keyframes pace-spinner {
0% { -ms-transform: rotate(0deg); transform: rotate(0deg); }
100% { -ms-transform: rotate(360deg); transform: rotate(360deg); }
}
@keyframes pace-spinner {
0% { transform: rotate(0deg); transform: rotate(0deg); }
100% { transform: rotate(360deg); transform: rotate(360deg); }
}

View File

@ -1,5 +1,5 @@
.fa-nav-icons {
color: #e30613;
color: #383637;
}
.fa-col-success {
@ -14,3 +14,79 @@
color: #357ebd;
}
.pace {
-webkit-pointer-events: none;
pointer-events: none;
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
}
.pace-inactive {
display: none;
}
.pace .pace-progress {
background: #29d;
position: fixed;
z-index: 2000;
top: 0;
right: 100%;
width: 100%;
height: 2px;
}
.pace .pace-progress-inner {
display: block;
position: absolute;
right: 0px;
width: 100px;
height: 100%;
box-shadow: 0 0 10px #29d, 0 0 5px #29d;
opacity: 1.0;
-webkit-transform: rotate(3deg) translate(0px, -4px);
-moz-transform: rotate(3deg) translate(0px, -4px);
-ms-transform: rotate(3deg) translate(0px, -4px);
-o-transform: rotate(3deg) translate(0px, -4px);
transform: rotate(3deg) translate(0px, -4px);
}
.pace .pace-activity {
display: block;
position: fixed;
z-index: 2000;
top: 16px;
right: 45px;
width: 20px;
height: 20px;
border: solid 2px transparent;
border-top-color: #29d;
border-left-color: #29d;
border-radius: 10px;
-webkit-animation: pace-spinner 400ms linear infinite;
-moz-animation: pace-spinner 400ms linear infinite;
-ms-animation: pace-spinner 400ms linear infinite;
-o-animation: pace-spinner 400ms linear infinite;
animation: pace-spinner 400ms linear infinite;
}
@-webkit-keyframes pace-spinner {
0% { -webkit-transform: rotate(0deg); transform: rotate(0deg); }
100% { -webkit-transform: rotate(360deg); transform: rotate(360deg); }
}
@-moz-keyframes pace-spinner {
0% { -moz-transform: rotate(0deg); transform: rotate(0deg); }
100% { -moz-transform: rotate(360deg); transform: rotate(360deg); }
}
@-o-keyframes pace-spinner {
0% { -o-transform: rotate(0deg); transform: rotate(0deg); }
100% { -o-transform: rotate(360deg); transform: rotate(360deg); }
}
@-ms-keyframes pace-spinner {
0% { -ms-transform: rotate(0deg); transform: rotate(0deg); }
100% { -ms-transform: rotate(360deg); transform: rotate(360deg); }
}
@keyframes pace-spinner {
0% { transform: rotate(0deg); transform: rotate(0deg); }
100% { transform: rotate(360deg); transform: rotate(360deg); }
}

View File

@ -17,3 +17,80 @@
.twitter-typeahead .tt-hint {
border-color: #000 !important;
}
.pace {
-webkit-pointer-events: none;
pointer-events: none;
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
}
.pace-inactive {
display: none;
}
.pace .pace-progress {
background: #fff;
position: fixed;
z-index: 2000;
top: 0;
right: 100%;
width: 100%;
height: 2px;
}
.pace .pace-progress-inner {
display: block;
position: absolute;
right: 0px;
width: 100px;
height: 100%;
box-shadow: 0 0 10px #d6cdbe, 0 0 5px #d6cdbe;
opacity: 1.0;
-webkit-transform: rotate(3deg) translate(0px, -4px);
-moz-transform: rotate(3deg) translate(0px, -4px);
-ms-transform: rotate(3deg) translate(0px, -4px);
-o-transform: rotate(3deg) translate(0px, -4px);
transform: rotate(3deg) translate(0px, -4px);
}
.pace .pace-activity {
display: block;
position: fixed;
z-index: 2000;
top: 16px;
right: 45px;
width: 20px;
height: 20px;
border: solid 2px transparent;
border-top-color: #9a968f;
border-left-color: #9a968f;
border-radius: 10px;
-webkit-animation: pace-spinner 400ms linear infinite;
-moz-animation: pace-spinner 400ms linear infinite;
-ms-animation: pace-spinner 400ms linear infinite;
-o-animation: pace-spinner 400ms linear infinite;
animation: pace-spinner 400ms linear infinite;
}
@-webkit-keyframes pace-spinner {
0% { -webkit-transform: rotate(0deg); transform: rotate(0deg); }
100% { -webkit-transform: rotate(360deg); transform: rotate(360deg); }
}
@-moz-keyframes pace-spinner {
0% { -moz-transform: rotate(0deg); transform: rotate(0deg); }
100% { -moz-transform: rotate(360deg); transform: rotate(360deg); }
}
@-o-keyframes pace-spinner {
0% { -o-transform: rotate(0deg); transform: rotate(0deg); }
100% { -o-transform: rotate(360deg); transform: rotate(360deg); }
}
@-ms-keyframes pace-spinner {
0% { -ms-transform: rotate(0deg); transform: rotate(0deg); }
100% { -ms-transform: rotate(360deg); transform: rotate(360deg); }
}
@keyframes pace-spinner {
0% { transform: rotate(0deg); transform: rotate(0deg); }
100% { transform: rotate(360deg); transform: rotate(360deg); }
}

View File

@ -1560,20 +1560,6 @@ tr.search:nth-child(odd) {
overflow-x: hidden;
}
.tt-dropdown-menu
{
min-width: 500px;
left: -400px !important;
}
.twitter-typeahead .tt-hint {
display: block;
height: 34px;
padding: 8px 12px;
font-size: 14px;
line-height: 1.428571429;
border: 1px solid transparent;
}
.ui-autocomplete {
max-height: 100px;
@ -1603,10 +1589,68 @@ tr.search:nth-child(odd) {
#visualization {
width: 90%;
height: 600px;
min-height: 600px;
}
.threeqtr-width {
display:block;
width: 75%;
min-width: 75%;
}
.tt-menu {
position: absolute;
top: 95%;
left: 2.5%;
z-index: 100;
display: none;
min-width: 400px;
margin-bottom: 20px;
overflow: hidden;
background-color: #fff;
-webkit-border-radius: 8px;
-moz-border-radius: 8px;
border-radius: 8px;
box-shadow: 0px 0px 0px 1px green;
-webkit-box-shadow: 0 5px 10px rgba(0,0,0,.2);
-moz-box-shadow: 0 5px 10px rgba(0,0,0,.2);
box-shadow: 0 5px 10px rgba(0,0,0,.2);
}
.tt-open {
position: absolute;
top: 95%;
left: 2.5%;
z-index: 100;
display: none;
min-width: 400px;
left: -400px !important;
margin-bottom: 20px;
overflow: hidden;
padding: 8px;
background-color: #fff;
-webkit-border-radius: 8px;
-moz-border-radius: 8px;
border-radius: 8px;
box-shadow: 0px 0px 0px 1px green;
-webkit-box-shadow: 0 5px 10px rgba(0,0,0,.2);
-moz-box-shadow: 0 5px 10px rgba(0,0,0,.2);
box-shadow: 0 5px 10px rgba(0,0,0,.2);
}
.typeahead-left {
left: 0px !important;
}
.tt-selectable {
cursor: pointer;
}
.tt-suggestion:hover a {
color: #ffffff !important;
}
.tt-suggestion:hover {
background-color: #0097CF;
color: #FFFFFF;
}

View File

@ -1,49 +0,0 @@
.twitter-typeahead .tt-query,
.twitter-typeahead .tt-hint {
margin-bottom: 0;
}
.tt-dropdown-menu {
min-width: 160px;
margin-top: 2px;
padding: 5px 0;
background-color: #fff;
border: 1px solid #ccc;
border: 1px solid rgba(0,0,0,.2);
*border-right-width: 2px;
*border-bottom-width: 2px;
-webkit-border-radius: 6px;
-moz-border-radius: 6px;
border-radius: 6px;
-webkit-box-shadow: 0 5px 10px rgba(0,0,0,.2);
-moz-box-shadow: 0 5px 10px rgba(0,0,0,.2);
box-shadow: 0 5px 10px rgba(0,0,0,.2);
-webkit-background-clip: padding-box;
-moz-background-clip: padding;
background-clip: padding-box;
}
.tt-suggestion {
display: block;
padding: 3px 20px;
}
.tt-suggestion.tt-is-under-cursor {
color: #fff;
background-color: #0081c2;
background-image: -moz-linear-gradient(top, #0088cc, #0077b3);
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0077b3));
background-image: -webkit-linear-gradient(top, #0088cc, #0077b3);
background-image: -o-linear-gradient(top, #0088cc, #0077b3);
background-image: linear-gradient(to bottom, #0088cc, #0077b3);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0077b3', GradientType=0)
}
.tt-suggestion.tt-is-under-cursor a {
color: #fff;
}
.tt-suggestion p {
margin: 0;
}

View File

@ -21,6 +21,12 @@ if(!is_numeric($_POST['group_id'])) {
exit;
} else {
if(dbDelete('device_groups', "`id` = ?", array($_POST['group_id']))) {
if( dbFetchCell('SELECT COUNT(id) FROM alert_map WHERE target = ?',array('g'.$_POST['group_id'])) >= 1 ) {
foreach( dbFetchRows('SELECT id FROM alert_map WHERE target = ?',array('g'.$_POST['group_id'])) as $map ) {
$_POST['map_id'] = $map['id'];
include('forms/delete-alert-map.inc.php');
}
}
echo('group has been deleted.');
exit;
} else {

View File

@ -0,0 +1,109 @@
<?php
/*
* LibreNMS
*
* Copyright (c) 2014 Neil Lathwood <https://github.com/laf/ http://www.lathwood.co.uk/fa>
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation, either version 3 of the License, or (at your
* option) any later version. Please see LICENSE.txt at the top level of
* the source code distribution for details.
*/
if(is_admin() === false) {
die('ERROR: You need to be admin');
}
$sub_type = $_POST['sub_type'];
if ($sub_type == 'new-maintenance') {
// Defaults
$status = 'error';
$update = 0;
$schedule_id = mres($_POST['schedule_id']);
if ($schedule_id > 0) {
$update = 1;
}
$title = mres($_POST['title']);
$notes = mres($_POST['notes']);
$start = mres($_POST['start']);
$end = mres($_POST['end']);
$maps = mres($_POST['maps']);
if (empty($title)) {
$message = "Missing title<br />";
}
if (empty($start)) {
$message .= "Missing start date<br />";
}
if (empty($end)) {
$message .= "Missing end date<br />";
}
if( !is_array($_POST['maps']) ) {
$message .= "Not mapped to any groups or devices<br />";
}
if (empty($message)) {
if (empty($schedule_id)) {
$schedule_id = dbInsert(array('start'=>$start,'end'=>$end,'title'=>$title,'notes'=>$notes),'alert_schedule');
} else {
dbUpdate(array('start'=>$start,'end'=>$end,'title'=>$title,'notes'=>$notes),'alert_schedule','`schedule_id`=?',array($schedule_id));
}
if ($schedule_id > 0) {
$items = array();
$fail = 0;
if ($update == 1) {
dbDelete('alert_schedule_items', '`schedule_id`=?', array($schedule_id));
}
foreach( $_POST['maps'] as $target ) {
$target = target_to_id($target);
$item = dbInsert(array('schedule_id'=>$schedule_id,'target'=>$target),'alert_schedule_items');
if ($item > 0) {
array_push($items,$item);
} else {
$fail = 1;
}
}
if ($fail == 1 && $update == 0) {
foreach ($items as $item) {
dbDelete('alert_schedule_items', '`item_id`=?', array($item));
}
dbDelete('alert_schedule', '`schedule_id`=?', array($schedule_id));
$message = 'Issue scheduling maintenance';
} else {
$status = 'ok';
$message = 'Scheduling maintenance ok';
}
} else {
$message = "Issue scheduling maintenance";
}
}
$response = array('status'=>$status,'message'=>$message);
} elseif ($sub_type == 'parse-maintenance') {
$schedule_id = mres($_POST['schedule_id']);
$schedule = dbFetchRow("SELECT * FROM `alert_schedule` WHERE `schedule_id`=?",array($schedule_id));
$items = array();
foreach (dbFetchRows("SELECT `target` FROM `alert_schedule_items` WHERE `schedule_id`=?",array($schedule_id)) as $targets) {
$targets = id_to_target($targets['target']);
array_push($items,$targets);
}
$response = array('start'=>$schedule['start'],'end'=>$schedule['end'],'title'=>$schedule['title'],'notes'=>$schedule['notes'],'targets'=>$items);
} elseif ($sub_type == 'del-maintenance') {
$schedule_id = mres($_POST['del_schedule_id']);
dbDelete('alert_schedule_items','`schedule_id`=?',array($schedule_id));
dbDelete('alert_schedule','`schedule_id`=?', array($schedule_id));
$status = 'ok';
$message = 'Maintenance schedule has been removed';
$response = array('status'=>$status,'message'=>$message);
}
echo _json_encode($response);

0
html/graph-realtime.php Executable file → Normal file
View File

0
html/graph.php Executable file → Normal file
View File

Binary file not shown.

0
html/images/16/accept.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 781 B

After

Width:  |  Height:  |  Size: 781 B

0
html/images/16/add.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 733 B

After

Width:  |  Height:  |  Size: 733 B

0
html/images/16/anchor.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 523 B

After

Width:  |  Height:  |  Size: 523 B

0
html/images/16/application.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 464 B

After

Width:  |  Height:  |  Size: 464 B

0
html/images/16/application_add.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 619 B

After

Width:  |  Height:  |  Size: 619 B

0
html/images/16/application_cascade.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 524 B

After

Width:  |  Height:  |  Size: 524 B

0
html/images/16/application_delete.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 610 B

After

Width:  |  Height:  |  Size: 610 B

0
html/images/16/application_double.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 533 B

After

Width:  |  Height:  |  Size: 533 B

0
html/images/16/application_edit.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 703 B

After

Width:  |  Height:  |  Size: 703 B

0
html/images/16/application_error.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 656 B

After

Width:  |  Height:  |  Size: 656 B

0
html/images/16/application_form.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 467 B

After

Width:  |  Height:  |  Size: 467 B

0
html/images/16/application_form_add.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 592 B

After

Width:  |  Height:  |  Size: 592 B

0
html/images/16/application_form_delete.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 605 B

After

Width:  |  Height:  |  Size: 605 B

0
html/images/16/application_form_edit.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 714 B

After

Width:  |  Height:  |  Size: 714 B

0
html/images/16/application_form_magnify.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 612 B

After

Width:  |  Height:  |  Size: 612 B

0
html/images/16/application_get.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 581 B

After

Width:  |  Height:  |  Size: 581 B

0
html/images/16/application_go.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 634 B

After

Width:  |  Height:  |  Size: 634 B

0
html/images/16/application_home.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 685 B

After

Width:  |  Height:  |  Size: 685 B

0
html/images/16/application_key.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 670 B

After

Width:  |  Height:  |  Size: 670 B

0
html/images/16/application_lightning.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 656 B

After

Width:  |  Height:  |  Size: 656 B

0
html/images/16/application_link.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 701 B

After

Width:  |  Height:  |  Size: 701 B

0
html/images/16/application_osx.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 487 B

After

Width:  |  Height:  |  Size: 487 B

0
html/images/16/application_osx_terminal.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 525 B

After

Width:  |  Height:  |  Size: 525 B

0
html/images/16/application_put.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 585 B

After

Width:  |  Height:  |  Size: 585 B

0
html/images/16/application_side_boxes.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 478 B

After

Width:  |  Height:  |  Size: 478 B

0
html/images/16/application_side_contract.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 547 B

After

Width:  |  Height:  |  Size: 547 B

0
html/images/16/application_side_expand.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 581 B

After

Width:  |  Height:  |  Size: 581 B

0
html/images/16/application_side_list.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 510 B

After

Width:  |  Height:  |  Size: 510 B

0
html/images/16/application_side_tree.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 483 B

After

Width:  |  Height:  |  Size: 483 B

0
html/images/16/application_split.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 520 B

After

Width:  |  Height:  |  Size: 520 B

0
html/images/16/application_tile_horizontal.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 432 B

After

Width:  |  Height:  |  Size: 432 B

0
html/images/16/application_tile_vertical.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 492 B

After

Width:  |  Height:  |  Size: 492 B

0
html/images/16/application_view_columns.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 493 B

After

Width:  |  Height:  |  Size: 493 B

0
html/images/16/application_view_detail.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 576 B

After

Width:  |  Height:  |  Size: 576 B

0
html/images/16/application_view_gallery.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 555 B

After

Width:  |  Height:  |  Size: 555 B

0
html/images/16/application_view_icons.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 476 B

After

Width:  |  Height:  |  Size: 476 B

0
html/images/16/application_view_list.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 473 B

After

Width:  |  Height:  |  Size: 473 B

0
html/images/16/application_view_tile.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 465 B

After

Width:  |  Height:  |  Size: 465 B

0
html/images/16/application_xp.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 426 B

After

Width:  |  Height:  |  Size: 426 B

0
html/images/16/application_xp_terminal.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 507 B

After

Width:  |  Height:  |  Size: 507 B

0
html/images/16/arrow_branch.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 582 B

After

Width:  |  Height:  |  Size: 582 B

0
html/images/16/arrow_divide.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 677 B

After

Width:  |  Height:  |  Size: 677 B

0
html/images/16/arrow_down.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 379 B

After

Width:  |  Height:  |  Size: 379 B

0
html/images/16/arrow_in.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 600 B

After

Width:  |  Height:  |  Size: 600 B

0
html/images/16/arrow_inout.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 551 B

After

Width:  |  Height:  |  Size: 551 B

0
html/images/16/arrow_join.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 626 B

After

Width:  |  Height:  |  Size: 626 B

0
html/images/16/arrow_left.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 345 B

After

Width:  |  Height:  |  Size: 345 B

0
html/images/16/arrow_merge.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 484 B

After

Width:  |  Height:  |  Size: 484 B

0
html/images/16/arrow_out.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 384 B

After

Width:  |  Height:  |  Size: 384 B

0
html/images/16/arrow_redo.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 625 B

After

Width:  |  Height:  |  Size: 625 B

0
html/images/16/arrow_refresh.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 685 B

After

Width:  |  Height:  |  Size: 685 B

0
html/images/16/arrow_refresh_small.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 506 B

After

Width:  |  Height:  |  Size: 506 B

0
html/images/16/arrow_right.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 349 B

After

Width:  |  Height:  |  Size: 349 B

0
html/images/16/arrow_rotate_anticlockwise.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 608 B

After

Width:  |  Height:  |  Size: 608 B

0
html/images/16/arrow_rotate_clockwise.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 602 B

After

Width:  |  Height:  |  Size: 602 B

0
html/images/16/arrow_switch.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 683 B

After

Width:  |  Height:  |  Size: 683 B

0
html/images/16/arrow_turn_left.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 516 B

After

Width:  |  Height:  |  Size: 516 B

0
html/images/16/arrow_turn_right.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 489 B

After

Width:  |  Height:  |  Size: 489 B

0
html/images/16/arrow_undo.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 631 B

After

Width:  |  Height:  |  Size: 631 B

0
html/images/16/arrow_up.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 372 B

After

Width:  |  Height:  |  Size: 372 B

0
html/images/16/asterisk_orange.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 760 B

After

Width:  |  Height:  |  Size: 760 B

0
html/images/16/asterisk_yellow.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 743 B

After

Width:  |  Height:  |  Size: 743 B

0
html/images/16/attach.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 391 B

After

Width:  |  Height:  |  Size: 391 B

0
html/images/16/award_star_add.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 853 B

After

Width:  |  Height:  |  Size: 853 B

0
html/images/16/award_star_bronze_1.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 733 B

After

Width:  |  Height:  |  Size: 733 B

0
html/images/16/award_star_bronze_2.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 755 B

After

Width:  |  Height:  |  Size: 755 B

0
html/images/16/award_star_bronze_3.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 754 B

After

Width:  |  Height:  |  Size: 754 B

0
html/images/16/award_star_delete.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 849 B

After

Width:  |  Height:  |  Size: 849 B

0
html/images/16/award_star_gold_1.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 753 B

After

Width:  |  Height:  |  Size: 753 B

0
html/images/16/award_star_gold_2.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 770 B

After

Width:  |  Height:  |  Size: 770 B

0
html/images/16/award_star_gold_3.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 781 B

After

Width:  |  Height:  |  Size: 781 B

0
html/images/16/award_star_silver_1.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 714 B

After

Width:  |  Height:  |  Size: 714 B

0
html/images/16/award_star_silver_2.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 734 B

After

Width:  |  Height:  |  Size: 734 B

0
html/images/16/award_star_silver_3.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 738 B

After

Width:  |  Height:  |  Size: 738 B

0
html/images/16/basket.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 669 B

After

Width:  |  Height:  |  Size: 669 B

0
html/images/16/basket_add.png Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 752 B

After

Width:  |  Height:  |  Size: 752 B

Some files were not shown because too many files have changed in this diff Show More