]> arthur.barton.de Git - netdata.git/blob - web/index.html
214d4b19d1e03843899a73b4c962dcb25533129a
[netdata.git] / web / index.html
1 <!DOCTYPE html>
2 <html lang="en">
3 <head>
4     <title>netdata dashboard</title>
5     <meta name="application-name" content="netdata">
6
7     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
8     <meta charset="utf-8">
9     <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
10     <meta name="viewport" content="width=device-width, initial-scale=1">
11     <meta name="apple-mobile-web-app-capable" content="yes">
12     <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
13     <meta name="author" content="costa@tsaousis.gr">
14
15     <link rel="shortcut icon" href="images/seo-performance-multi-size.ico">
16
17     <link rel="apple-touch-icon" href="images/seo-performance-72.png">
18     <link rel="apple-touch-icon" sizes="72x72" href="images/seo-performance-72.png">
19     <link rel="apple-touch-icon" sizes="114x114" href="images/seo-performance-114.png">
20
21     <link rel="icon" type="image/png" sizes="512x512" href="images/seo-performance-512.png">
22     <link rel="icon" type="image/png" sizes="256x256" href="images/seo-performance-256.png">
23     <link rel="icon" type="image/png" sizes="128x128" href="images/seo-performance-128.png">
24     <link rel="icon" type="image/png" sizes="64x64" href="images/seo-performance-64.png">
25     <link rel="icon" type="image/png" sizes="48x48" href="images/seo-performance-48.png">
26     <link rel="icon" type="image/png" sizes="32x32" href="images/seo-performance-32.png">
27     <link rel="icon" type="image/png" sizes="24x24" href="images/seo-performance-24.png">
28     <link rel="icon" type="image/png" sizes="16x16" href="images/seo-performance-16.png">
29
30     <meta property="og:locale" content="en_US" />
31     <meta property="og:image" content="http://my-netdata.io/images/post.png"/>
32     <meta property="og:url" content="http://my-netdata.io/"/>
33     <meta property="og:type" content="website"/>
34     <meta property="og:site_name" content="netdata"/>
35     <meta property="og:title" content="netdata - real-time performance monitoring, done right!"/>
36     <meta property="og:description" content="Stunning real-time dashboards, blazingly fast and extremely interactive. Zero configuration, zero dependencies, zero maintenance." />
37
38     <style>
39
40     /* prevent body from hiding under the navbar */
41     body {
42         padding-top: 50px;
43     }
44
45     .loadOverlay {
46         position: absolute;
47         top: 0px;
48         left: 0px;
49         width: 100%;
50         height:100%;
51         z-index: 2000;
52         font-size: 10vh;
53         font-family: sans-serif;
54         padding: 40vh 0 40vh 0;
55         font-weight: bold;
56         text-align: center;
57     }
58
59     .modal-wide .modal-dialog {
60         width: 80%;
61     }
62
63     /* fix # anchors scrolling under the navbar
64        https://github.com/twbs/bootstrap/issues/1768#issuecomment-46519033
65      */
66     h1 {
67         position: relative;
68         z-index: -1;
69     }
70     h2 {
71         position: relative;
72         z-index: -2;
73     }
74     h1:before, h2:before {
75         display: block;
76         content: " ";
77         margin-top: -70px;
78         height: 70px;
79         visibility: hidden;
80     }
81
82     .p {
83         display: block;
84         margin-top: 15px;
85     }
86
87     .option-row,
88     .option-control {
89         vertical-align: top;
90         padding: 10px;
91         padding-top: 30px;
92         padding-left: 30px;
93     }
94
95     .option-info {
96         padding: 10px;
97     }
98
99     .chart-message {
100         display: block;
101         margin-top: 10px;
102     }
103
104     #masthead h1 {
105         /*font-size: 30px;*/
106         line-height: 1;
107         padding-top: 30px;
108     }
109
110     #masthead .well {
111         margin-top:4%;
112     }
113
114     /* fix the navbar shifting when a modal is open */
115     /* https://github.com/twbs/bootstrap/issues/14040#issuecomment-159891033 */
116     body.modal-open{
117         width: 100% !important;
118         padding-right: 0 !important;
119 /*      overflow-y: scroll !important; */
120 /*      position: fixed !important;*/
121         overflow: visible;
122     }
123
124     /* make accordion use the whole header bar for expand/collapse */
125     .panel-title a {
126         display: block;
127         padding: 10px 15px;
128         margin: -10px -15px;
129     }
130
131     /*
132      * Side navigation
133      *
134      * Scrollspy and affixed enhanced navigation to highlight sections and secondary
135      * sections of docs content.
136      */
137
138     .affix {
139         position: static;
140         top: 70px !important;
141         /*width: 220px;*/
142     }
143
144     .affix-top {
145         /*width: 220px;*/
146     }
147
148     .dashboard-sidebar {
149         max-height: calc(100% - 70px) !important;
150         overflow-y: auto;
151         /*width: 220px !important;*/
152     }
153
154     /* By default it's not affixed in mobile views, so undo that */
155     .dashboard-sidebar.affix {
156         position: static;
157     }
158
159     @media (min-width: 768px) {
160         .dashboard-sidebar {
161             padding-left: 20px;
162         }
163     }
164
165     /* First level of nav */
166     .dashboard-sidenav {
167         margin-top: 20px;
168         margin-bottom: 20px;
169     }
170
171     /* All levels of nav */
172     .dashboard-sidebar .nav > li > a {
173         display: block;
174         padding: 4px 20px;
175         font-size: 13px;
176         font-weight: 500;
177         color: #767676;
178     }
179     .dashboard-sidebar .nav > li > a:hover,
180     .dashboard-sidebar .nav > li > a:focus {
181         padding-left: 19px;
182         color: #563d7c;
183         text-decoration: none;
184         background-color: transparent;
185         border-left: 1px solid #563d7c;
186     }
187     .dashboard-sidebar .nav > .active > a,
188     .dashboard-sidebar .nav > .active:hover > a,
189     .dashboard-sidebar .nav > .active:focus > a {
190         padding-left: 18px;
191         font-weight: bold;
192         color: #563d7c;
193         background-color: transparent;
194         border-left: 2px solid #563d7c;
195     }
196
197     /* Nav: second level (shown on .active) */
198     .dashboard-sidebar .nav .nav {
199         display: none; /* Hide by default, but at >768px, show it */
200         padding-bottom: 10px;
201     }
202     .dashboard-sidebar .nav .nav > li > a {
203         padding-top: 1px;
204         padding-bottom: 1px;
205         padding-left: 30px;
206         font-size: 12px;
207         font-weight: normal;
208     }
209     .dashboard-sidebar .nav .nav > li > a:hover,
210     .dashboard-sidebar .nav .nav > li > a:focus {
211         padding-left: 29px;
212     }
213     .dashboard-sidebar .nav .nav > .active > a,
214     .dashboard-sidebar .nav .nav > .active:hover > a,
215     .dashboard-sidebar .nav .nav > .active:focus > a {
216         padding-left: 28px;
217         font-weight: 500;
218     }
219
220     .dropdown-menu {
221         min-width: 200px;
222     }
223     .dropdown-menu.columns-2 {
224         margin: 0;
225         padding: 0;
226         width: 400px;
227     }
228     .dropdown-menu li a {
229         padding: 5px 15px;
230         font-weight: 300;
231     }
232     .dropdown-menu.multi-column {
233         overflow-x: hidden;
234     }
235     .multi-column-dropdown {
236         list-style: none;
237         padding: 0;
238     }
239     .multi-column-dropdown li a {
240         display: block;
241         clear: both;
242         line-height: 1.428571429;
243         white-space: normal;
244     }
245     .multi-column-dropdown li a:hover {
246         text-decoration: none;
247         color: #f5f5f5;
248         background-color: #262626;
249     }
250     .scrollable-menu {
251         height: auto;
252         max-height: 80vh;
253         overflow-x: hidden;
254     }
255
256     /* Back to top (hidden on mobile) */
257     .back-to-top,
258     .dashboard-theme-toggle {
259         display: none;
260         padding: 4px 10px;
261         margin-top: 10px;
262         margin-left: 10px;
263         font-size: 12px;
264         font-weight: 500;
265         color: #999;
266     }
267     .back-to-top:hover,
268     .dashboard-theme-toggle:hover {
269         color: #563d7c;
270         text-decoration: none;
271     }
272     .dashboard-theme-toggle {
273         margin-top: 0;
274     }
275
276     .container {
277         width: calc(100% - 20px) !important;
278     }
279
280     .charts-body {
281         display: inline-block;
282         width: 100%;
283     }
284
285     .sidebar-body {
286         position: absolute;
287         display: none;
288     }
289
290     @media (min-width: 768px) {
291         .charts-body {
292             padding-left: 0%;
293             padding-right: 0%;
294         }
295
296         .back-to-top,
297         .dashboard-theme-toggle {
298             display: block;
299         }
300     }
301
302     /* Show and affix the side nav when space allows it */
303     @media (min-width: 992px) {
304         .container {
305             padding-left: 0% !important;
306         }
307
308         .charts-body {
309             width: calc(100% - 213px) !important;
310             padding-left: 1% !important;
311             padding-right: 0% !important;
312         }
313
314         .sidebar-body {
315             display: inline-block !important;
316             width: 213px !important;
317         }
318
319         .dashboard-sidebar .nav > .active > ul {
320             display: block;
321         }
322
323         /* Widen the fixed sidebar */
324         .dashboard-sidebar.affix,
325         .dashboard-sidebar.affix-top,
326         .dashboard-sidebar.affix-bottom {
327             width: 213px !important;
328         }
329         .dashboard-sidebar.affix {
330             position: fixed; /* Undo the static from mobile first approach */
331             top: 20px;
332         }
333         .dashboard-sidebar.affix-bottom {
334             position: absolute; /* Undo the static from mobile first approach */
335         }
336         .dashboard-sidebar.affix-bottom .dashboard-sidenav,
337         .dashboard-sidebar.affix .dashboard-sidenav {
338             margin-top: 0;
339             margin-bottom: 0;
340         }
341     }
342
343     @media (min-width: 1200px) {
344         .container {
345             padding-left: 2% !important;
346         }
347
348         .charts-body {
349             width: calc(100% - 233px) !important;
350             padding-left: 1% !important;
351             padding-right: 1% !important;
352         }
353
354         .sidebar-body {
355             display: inline-block !important;
356             width: 233px !important;
357         }
358
359         /* Widen the fixed sidebar again */
360         .dashboard-sidebar.affix,
361         .dashboard-sidebar.affix-top,
362         .dashboard-sidebar.affix-bottom {
363             width: 233px !important;
364         }
365     }
366     
367     @media (min-width: 1360px) {
368         .container {
369             padding-left: 3% !important;
370         }
371
372         .charts-body {
373             width: calc(100% - 263px) !important;
374             padding-left: 1% !important;
375             padding-right: 2% !important;
376         }
377
378         .sidebar-body {
379             display: inline-block !important;
380             width: 263px !important;
381         }
382
383         /* Widen the fixed sidebar again */
384         .dashboard-sidebar.affix,
385         .dashboard-sidebar.affix-top,
386         .dashboard-sidebar.affix-bottom {
387             width: 263px !important;
388         }
389     }
390
391     </style>
392
393     <!-- check which theme to use -->
394     <script type="text/javascript">
395         // enable alarms checking and notifications
396         var netdataShowAlarms = true;
397
398         // enable registry updates
399         var netdataRegistry = true;
400         
401         // --------------------------------------------------------------------
402         // urlOptions
403
404         var urlOptions = {
405             hash: '#',
406             theme: null,
407             help: null,
408             pan_and_zoom: false,
409             after: 0,
410             before: 0,
411             nowelcome: 0,
412             show_alarms: 0,
413             chart: null,
414             family: null,
415             hasProperty: function(property) {
416                 // console.log('checking property ' + property + ' of type ' + typeof(this[property]));
417                 return typeof this[property] !== 'undefined';
418             }
419         };
420
421         function netdataPanAndZoomCallback(status, after, before) {
422             urlOptions.pan_and_zoom = status;
423             urlOptions.after = after;
424             urlOptions.before = before;
425             netdataHashUpdate();
426         }
427
428         function netdataHashUpdate() {
429             history.replaceState(null, '', netdataHash());
430         }
431
432         function netdataHash() {
433             var hash = urlOptions.hash;
434
435             if(urlOptions.pan_and_zoom === true) {
436                 hash += ';after='  + urlOptions.after.toString() +
437                         ';before=' + urlOptions.before.toString();
438             }
439
440             if(urlOptions.theme !== null)
441                 hash += ';theme=' + urlOptions.theme.toString();
442
443             if(urlOptions.help !== null)
444                 hash += ';help=' + urlOptions.help.toString();
445
446             return hash;
447         }
448
449         function netdataHashParse() {
450             var variables = document.location.hash.split(';');
451             var len = variables.length;
452             while(len--) {
453                 if(len !== 0) {
454                     var p = variables[len].split('=');
455                     if(urlOptions.hasProperty(p[0]) && typeof p[1] !== 'undefined')
456                         urlOptions[p[0]] = p[1];
457                 }
458                 else {
459                     if(variables[len].length > 0)
460                         urlOptions.hash = variables[len];
461                 }
462             }
463
464             if(urlOptions.before > 0 && urlOptions.after > 0)
465                 urlOptions.pan_and_zoom = true;
466
467             // console.log(urlOptions);
468         }
469
470         netdataHashParse();
471
472         // --------------------------------------------------------------------
473         // check options that should be processed before loading netdata.js
474         
475         function loadLocalStorage(name) {
476             var ret = null;
477
478             try {
479                 if(typeof Storage !== "undefined" && typeof localStorage === 'object')
480                     ret = localStorage.getItem(name);
481             }
482             catch(error) {
483                 ;
484             }
485
486             if(typeof ret === 'undefined' || ret === null)
487                 return null;
488
489             // console.log('loaded: ' + name.toString() + ' = ' + ret.toString());
490
491             return ret;
492         }
493
494         function saveLocalStorage(name, value) {
495             // console.log('saving: ' + name.toString() + ' = ' + value.toString());
496             try {
497                 if(typeof Storage !== "undefined" && typeof localStorage === 'object') {
498                     localStorage.setItem(name, value.toString());
499                     return true;
500                 }
501             }
502             catch(error) {
503                 ;
504             }
505
506             return false;
507         }
508
509         function getTheme(def) {
510             var ret = loadLocalStorage('netdataTheme');
511             if(typeof ret === 'undefined' || ret === null || ret === 'undefined')
512                 return def;
513             else
514                 return ret;
515         }
516
517         function setTheme(theme) {
518             if(theme === netdataTheme) return false;
519             return saveLocalStorage('netdataTheme', theme);
520         }
521
522         var netdataTheme = getTheme('slate');
523         var netdataShowHelp = true;
524
525         if(urlOptions.theme !== null) {
526             setTheme(urlOptions.theme);
527             netdataTheme = urlOptions.theme;
528         }
529         else
530             urlOptions.theme = netdataTheme;
531
532         if(urlOptions.help !== null) {
533             saveLocalStorage('options.show_help', urlOptions.help);
534             netdataShowHelp = urlOptions.help;
535         }
536         else {
537             urlOptions.help = loadLocalStorage('options.show_help');
538         }
539
540         // --------------------------------------------------------------------
541         // registry call back to render my-netdata menu
542
543         var netdataRegistryCallback = function(machines_array) {
544             var el = '';
545             var a1 = '';
546             var found = 0;
547
548             if(machines_array) {
549                 function name_comparator_desc(a, b) {
550                     if (a.name > b.name) return -1;
551                     if (a.name < b.name) return 1;
552                     return 0;
553                 }
554
555                 var machines = machines_array.sort(name_comparator_desc);
556                 var len = machines.length;
557                 while(len--) {
558                     var u = machines[len];
559                     found++;
560                     el += '<li id="registry_server_' + u.guid + '"><a class="registry_link" href="' + u.url + '" onClick="return gotoServerModalHandler(\'' + u.guid + '\');">' + u.name + '</a></li>';
561                     a1 += '<li id="registry_action_' + u.guid + '"><a href="#" onclick="deleteRegistryModalHandler(\'' + u.guid + '\',\'' + u.name + '\',\'' + u.url + '\'); return false;"><i class="fa fa-trash-o" aria-hidden="true" style="color: #999;"></i></a></li>';
562                 }
563             }
564
565             if(!found) {
566                 if(machines)
567                     el += '<li><a href="https://github.com/firehol/netdata/wiki/mynetdata-menu-item" style="color: #666;" target="_blank">your netdata server list is empty...</a></li>';
568                 else
569                     el += '<li><a href="https://github.com/firehol/netdata/wiki/mynetdata-menu-item" style="color: #666;" target="_blank">failed to contact the registry...</a></li>';
570
571                 a1 += '<li><a href="#" onClick="return false;">&nbsp;</a></li>';
572
573                 el += '<li role="separator" class="divider"></li>' +
574                         '<li><a href="//london.netdata.rocks/default.html">EU - London (DigitalOcean.com)</a></li>' +
575                         '<li><a href="//atlanta.netdata.rocks/default.html">US - Atlanta (CDN77.com)</a></li>' +
576                         '<li><a href="//athens.netdata.rocks/default.html">EU - Athens</a></li>';
577                 a1 += '<li role="separator" class="divider"></li>' +
578                         '<li><a href="#">&nbsp;</a></li>' +
579                         '<li><a href="#">&nbsp;</a></li>'+
580                         '<li><a href="#">&nbsp;</a></li>';
581             }
582
583             el += '<li role="separator" class="divider"></li>';
584             a1 += '<li role="separator" class="divider"></li>';
585
586             el += '<li><a href="https://github.com/firehol/netdata/wiki/mynetdata-menu-item" style="color: #999;" target="_blank">What is this?</a></li>';
587             a1 += '<li><a href="#" style="color: #999;" onclick="switchRegistryModalHandler(); return false;"><i class="fa fa-sliders" aria-hidden="true" style="color: #999;"></i></a></li>'
588
589             document.getElementById('mynetdata_servers').innerHTML = el;
590             document.getElementById('mynetdata_servers2').innerHTML = el;
591             document.getElementById('mynetdata_actions1').innerHTML = a1;
592
593             gotoServerInit();
594         };
595
596     </script>
597
598     <!-- load the dashboard manager - it will do the rest -->
599     <script type="text/javascript" src="dashboard.js?v46"></script>
600 </head>
601 <body data-spy="scroll" data-target="#sidebar">
602     <div id="loadOverlay" class="loadOverlay" style="background-color: #888; color: #888;">
603         netdata<br/><div style="font-size: 3vh;">Real-time performance monitoring, done right!</div>
604     </div>
605     <script type="text/javascript">
606         // change the loadOverlay colors ASAP to match the theme
607         document.getElementById('loadOverlay').style = (urlOptions.theme === 'slate')?"background-color:#272b30; color: #373b40;":"background-color:#fff; color: #ddd;";
608     </script>
609     <nav class="navbar navbar-default navbar-fixed-top" role="banner">
610         <div class="container">
611             <nav id="mynetdata_nav" class="collapse navbar-collapse navbar-left hidden-sm hidden-xs" role="navigation" style="padding-right: 20px;">
612                 <ul class="nav navbar-nav">
613                     <li class="dropdown">
614                         <a href="#" class="dropdown-toggle" data-toggle="dropdown" id="current_view">my-netdata <strong class="caret"></strong></a>
615                         <ul class="dropdown-menu scrollable-menu inpagemenu multi-column columns-2" role="menu">
616                             <div class="row">
617                                 <div class="col-sm-6" style="width: 85%; padding-right: 0;">
618                                     <ul id="mynetdata_servers" class="multi-column-dropdown">
619                                         <li><a href="#" onclick="return false;" style="color: #999;">loading...</a></li>
620                                     </ul>
621                                 </div>
622                                 <div class="col-sm-3 hidden-xs" style="width: 15%; padding-left: 0;">
623                                     <ul id="mynetdata_actions1" class="multi-column-dropdown">
624                                     <li style="color: #999;">&nbsp;</li>
625                                     </ul>
626                                 </div>
627                             </div>
628                         </ul>
629                     </li>
630                 </ul>
631             </nav>
632             <div class="navbar-header">
633                 <button class="navbar-toggle" type="button" data-toggle="collapse" data-target=".navbar-collapse">
634                     <span class="sr-only">Toggle navigation</span>
635                     <span class="icon-bar"></span>
636                     <span class="icon-bar"></span>
637                     <span class="icon-bar"></span>
638                 </button>
639                 <a href="/" class="navbar-brand" id="hostname" title="reload the dashboard">netdata</a>
640             </div>
641             <nav class="collapse navbar-collapse navbar-right" role="navigation">
642                 <ul class="nav navbar-nav">
643                     <li><a href="#" class="btn" data-toggle="modal" data-target="#alarmsModal" title="alarms"><i class="fa fa-bell"></i></span>&nbsp;<span class="hidden-sm">Alarms&nbsp;</span><span id="alarms_count_badge" class="badge"></a></li>
644                     <li><a href="#" class="btn" data-toggle="modal" data-target="#optionsModal" title="dashboard settings"><i class="fa fa-sliders"></i>&nbsp;<span class="hidden-sm">Settings</span></a></li>
645                     <li><a href="https://github.com/firehol/netdata/wiki" class="btn" target="_blank" title="netdata community"><i class="fa fa-github"></i>&nbsp;<span class="hidden-sm hidden-md">Community</span></a></li>
646                     <li class="hidden-sm" id="updateButton"><a href="#" class="btn" data-toggle="modal" data-target="#updateModal" title="check for update"><i class="fa fa-cloud-download"></i><span id="update_badge" class="badge"></span>&nbsp;<span class="hidden-sm hidden-md">Update</span></a></li>
647                     <li class="hidden-sm"><a href="#" class="btn" data-toggle="modal" data-target="#helpModal" title="dashboard help"><i class="fa fa-question-circle"></i>&nbsp;<span class="hidden-sm hidden-md">Help</span></a></li>
648                     <!--
649                     <li class="dropdown hidden-md hidden-lg hidden-xs">
650                         <a href="#" class="dropdown-toggle" data-toggle="dropdown" id="current_view">Menu <strong class="caret"></strong></a>
651                         <ul class="dropdown-menu scrollable-menu inpagemenu" role="menu">
652                             <li><a href="#" class="btn" data-toggle="modal" data-target="#alarmsModal"><i class="fa fa-bell"></i> alarms</a></li>
653                             <li><a href="#" class="btn" data-toggle="modal" data-target="#optionsModal"><i class="fa fa-sliders"></i> settings</a></li>
654                             <li><a href="https://github.com/firehol/netdata/wiki" class="btn" target="_blank"><i class="fa fa-github"></i> community</a></li>
655                             <li><a href="#" class="btn" data-toggle="modal" data-target="#helpModal"><i class="fa fa-question-circle"></i> help</a></li>
656                         </ul>
657                     </li>
658                     -->
659                     <li class="dropdown hidden-sm hidden-md hidden-lg">
660                         <a href="#" class="dropdown-toggle" data-toggle="dropdown" id="current_view">my-netdata <strong class="caret"></strong></a>
661                         <ul id="mynetdata_servers2" class="dropdown-menu scrollable-menu inpagemenu" role="menu">
662                             <li><a href="#" onclick="return false;" style="color: #999;">loading...</a></li>
663                         </ul>
664                     </li>
665                 </ul>
666             </nav>
667     </nav>
668         </div>
669     </nav>
670
671     <div id="masthead" style="display: none;">
672         <div class="container">
673             <div class="row">
674                 <div class="col-md-7">
675                     <h1>Netdata
676                         <p class="lead">Real-time performance monitoring, in the greatest possible detail</p>
677                     </h1>
678                 </div>
679                 <div class="col-md-5">
680                     <div class="well well-lg">
681                         <div class="row">
682                         <div class="col-md-6">
683                             <b>Drag</b> charts to pan.
684                             <b>Shift + wheel</b> on them, to zoom in and out.
685                             <b>Double-click</b> on them, to reset.
686                             <b>Hover</b> on them too!
687                             </div>
688                         <div class="col-md-6">
689                             <div data-netdata="system.intr" data-chart-library="dygraph" data-dygraph-theme="sparkline" data-dygraph-type="line" data-dygraph-strokewidth="3" data-dygraph-smooth="true" data-dygraph-highlightcirclesize="6" data-after="-90" data-height="60px" data-colors="#C66"></div>
690                             </div>
691                         </div>
692                     </div>
693                 </div>
694             </div>
695         </div>
696     </div>
697
698     <div class="container">
699         <div class="row">
700             <div class="charts-body" role="main">
701                 <div id="charts_div"></div>
702             </div>
703             <div class="sidebar-body hidden-xs hidden-sm" role="complementary">
704                 <nav class="dashboard-sidebar hidden-print hidden-xs hidden-sm" id="sidebar" role="menu"></nav>
705             </div>
706         </div>
707     </div>
708
709     <div id="footer" class="container" style="display: none;">
710         <div class="row">
711             <div class="col-md-10" role="main">
712                 <div class="p">
713                     <big><a href="https://github.com/firehol/netdata/wiki" target="_blank">netdata</a></big><br/>
714                     <i class="fa fa-copyright"></i> Copyright 2016, Costa Tsaousis.<br/>
715                     Released under <a href="http://www.gnu.org/licenses/gpl-3.0.en.html" target="_blank">GPL v3 or later</a>.<br/>
716                 </div>
717                 <div class="p">
718                     <small>
719                         <a href="https://github.com/firehol/netdata/wiki" target="_blank">netdata</a> re-distributes these software tools:
720
721                         <i class="fa fa-circle"></i> The excellent <a href="http://dygraphs.com/" target="_blank">Dygraphs.com</a> web chart library,
722                         <i class="fa fa-copyright"></i> Copyright 2009, Dan Vanderkam, <a href="http://dygraphs.com/legal.html" target="_blank">MIT License</a>
723
724                         <i class="fa fa-circle"></i> <a href="http://omnipotent.net/jquery.sparkline/" target="_blank">jQuery Sparklines</a> web chart library,
725                         <i class="fa fa-copyright"></i> Copyright 2009-2012, Splunk Inc., <a href="http://opensource.org/licenses/BSD-3-Clause" target="_blank">New BSD License</a>
726
727                         <i class="fa fa-circle"></i> <a href="http://benpickles.github.io/peity/" target="_blank">Peity</a> web chart library,
728                         <i class="fa fa-copyright"></i> Copyright 2009-2015, Ben Pickles, <a href="https://github.com/benpickles/peity/blob/master/MIT-LICENCE" target="_blank">MIT License</a>
729
730                         <i class="fa fa-circle"></i> <a href="https://rendro.github.io/easy-pie-chart/" target="_blank">Easy Pie Chart</a> web chart library,
731                         <i class="fa fa-copyright"></i> Copyright 2013, Robert Fleischmann, <a href="https://github.com/rendro/easy-pie-chart/blob/master/LICENSE" target="_blank">MIT License</a>
732
733                         <i class="fa fa-circle"></i> <a href="http://bernii.github.io/gauge.js/" target="_blank">Gauge.js</a> web chart library,
734                         <i class="fa fa-copyright"></i> Copyright, Bernard Kobos, <a href="http://bernii.github.io/gauge.js/" target="_blank">MIT License</a>
735
736                         <i class="fa fa-circle"></i> <a href="https://jquery.org/" target="_blank">jQuery</a>,
737                         <i class="fa fa-copyright"></i> Copyright 2015, jQuery Foundation, <a href="https://jquery.org/license/" target="_blank">MIT License</a>
738
739                         <i class="fa fa-circle"></i> <a href="http://getbootstrap.com/getting-started/" target="_blank">Bootstrap</a>,
740                         <i class="fa fa-copyright"></i> Copyright 2015, Twitter, <a href="http://getbootstrap.com/getting-started/#license-faqs" target="_blank">MIT License</a>
741
742                         <i class="fa fa-circle"></i> <a href="http://www.bootstraptoggle.com/" target="_blank">Bootstrap Toggle</a>,
743                         <i class="fa fa-copyright"></i> Copyright (c) 2011-2014 Min Hur, The New York Times Company, <a href="https://github.com/minhur/bootstrap-toggle/blob/master/LICENSE" target="_blank">MIT License</a>
744
745                         <i class="fa fa-circle"></i> <a href="https://jamesflorentino.github.io/nanoScrollerJS/" target="_blank">NanoScroller</a>,
746                         <i class="fa fa-copyright"></i> Copyright 2012, James Florentino, <a href="https://github.com/jamesflorentino/nanoScrollerJS/blob/master/LICENSE" target="_blank">MIT License</a>
747
748                         <i class="fa fa-circle"></i> <a href="https://github.com/marcj/css-element-queries" target="_blank">CSS Element Queries</a>,
749                         <i class="fa fa-copyright"></i> Copyright Marc J. Schmidt, <a href="https://github.com/marcj/css-element-queries/blob/master/LICENSE" target="_blank">MIT License</a>
750
751                         <i class="fa fa-circle"></i> <a href="https://fortawesome.github.io/Font-Awesome/" target="_blank">FontAwesome</a>,
752                         <i class="fa fa-copyright"></i> Created by Dave Gandy, Font: <a href="http://scripts.sil.org/OFL" target="_blank">SIL OFL 1.1 License</a>, CSS: <a href="http://opensource.org/licenses/mit-license.html" target="_blank">MIT License</a>
753
754                         <i class="fa fa-circle"></i> <a href="http://www.iconsdb.com/soylent-red-icons/seo-performance-icon.html" target="_blank">IconsDB.com Icons</a>, Icons provided as CC0 1.0 Universal (CC0 1.0) Public Domain Dedication.
755
756                         <i class="fa fa-circle"></i> <a href="http://morrisjs.github.io/morris.js/" target="_blank">morris.js</a>,
757                         <i class="fa fa-copyright"></i> Copyright 2013, Olly Smith, <a href="http://morrisjs.github.io/morris.js/" target="_blank">Simplified BSD License</a>
758
759                         <i class="fa fa-circle"></i> <a href="http://raphaeljs.com/" target="_blank">Raphaël</a>,
760                         <i class="fa fa-copyright"></i> Copyright 2008, Dmitry Baranovskiy, <a href="http://raphaeljs.com/license.html" target="_blank">MIT License</a>
761
762                         <i class="fa fa-circle"></i> <a href="http://C3js.org/" target="_blank">C3</a>,
763                         <i class="fa fa-copyright"></i> Copyright 2013, Masayuki Tanaka, <a href="https://github.com/masayuki0812/c3/blob/master/LICENSE" target="_blank">MIT License</a>
764
765                         <i class="fa fa-circle"></i> <a href="http://D3js.org/" target="_blank">D3</a>,
766                         <i class="fa fa-copyright"></i> Copyright 2015, Mike Bostock, <a href="http://opensource.org/licenses/BSD-3-Clause" target="_blank">BSD License</a>
767
768                     </small>
769                 </div>
770             </div>
771         </div>
772     </div>
773
774     <div class="modal fade" id="welcomeModal" tabindex="-1" role="dialog" aria-labelledby="welcomeModalLabel">
775         <div class="modal-dialog modal-lg" role="document">
776             <div class="modal-content">
777                 <div class="modal-header">
778                     <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
779                     <h4 class="modal-title" id="welcomeModalLabel">Welcome!</h4>
780                 </div>
781                 <div class="modal-body">
782                         <div class="p">
783                         <b><a href="https://github.com/firehol/netdata/wiki" target="_blank">netdata</a></b> is the fastest way to visualize metrics. It is a resource efficient, highly optimized system for collecting and visualizing any type of real-time time series data, from CPU usage, disk activity, SQL queries, API calls, web site visitors, etc.
784                         </div>
785                         <div class="p">
786                         <b><a href="https://github.com/firehol/netdata/wiki" target="_blank">netdata</a></b> tries to visualize the truth of <b>now</b>, in its <b>greatest detail</b>, so that you can get insights of what is happening now and what just happened, on your systems and applications.
787                         </div>
788                         <div class="p">
789                         To make a chart in <b><a href="https://github.com/firehol/netdata/wiki" target="_blank">netdata</a></b>, you just need a <b>number</b>. Just a number you can read somehow. <b><a href="https://github.com/firehol/netdata/wiki" target="_blank">netdata</a></b> will turn this number to a real time, interactive, web chart. For collecting these numbers, it supports <a href="https://github.com/firehol/netdata/wiki/External-Plugins" target="_blank">external plugins</a>, even <a href="https://github.com/firehol/netdata/wiki/General-Info---charts.d" target="_blank">shell</a> or <a href="https://github.com/firehol/netdata/wiki/General-Info---charts.d" target="_blank">node.js</a> plugins. Any computer program, in any language, that can print a few lines of text on its standard output, can be a netdata data collector.
790                         </div>
791                         <div class="p">
792                         <b><a href="https://github.com/firehol/netdata/wiki" target="_blank">netdata</a></b> can embed charts everywhere, like this one <div data-netdata="system.cpu" data-dimensions="system" data-after="-120" data-width="25%" data-height="15px" data-chart-library="dygraph" data-dygraph-theme="sparkline" data-show-value-of-system-at="system.cpu.system.modal.1"></div> (my CPU system usage which is <span id="system.cpu.system.modal.1" style="display: inline-block; width: 40px; text-align: right;"></span>%),
793                         or this one <div data-netdata="ipv4.tcppackets" data-dimensions="received" data-after="-120" data-width="25%" data-height="15px" data-chart-library="dygraph" data-dygraph-theme="sparkline" data-show-value-of-received-at="ipv4.tcppackets.received.modal.1"></div> (my IPv4 received TCP packets, which are <span id="ipv4.tcppackets.received.modal.1" style="display: inline-block; width: 60px; text-align: right;"></span>/second).
794                         </div>
795                         <div class="p">
796                         You can have <b><a href="https://github.com/firehol/netdata/wiki" target="_blank">netdata</a></b> charts on your site too. Just give it a <code>div</code> and a real time chart, zoomable and draggable will appear (try it even on these tiny ones - <b>drag</b> them to pan horizontally, <b>shift + drag</b> to zoom in, on <b>chrome shift + mouse wheel</b> to zoom in/out, <b>double click</b> on them to reset them - don't be afraid of <b><a href="https://github.com/firehol/netdata/wiki" target="_blank">netdata</a></b> performance - <a href="https://github.com/firehol/netdata/wiki/Performance" target="_blank">a raspberry pi 2 can sustain 300 charts updates per second</a>!).
797                         </div>
798                         <div class="p">
799                         For more information please refer to the <b><a href="https://github.com/firehol/netdata/wiki" target="_blank">netdata wiki</a></b>.
800                         </div>
801                 </div>
802                 <div class="modal-footer">
803                     <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
804                 </div>
805             </div>
806         </div>
807     </div>
808
809     <div class="modal fade" id="helpModal" tabindex="-1" role="dialog" aria-labelledby="helpModalLabel">
810         <div class="modal-dialog modal-lg" role="document">
811             <div class="modal-content">
812                 <div class="modal-header">
813                     <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
814                     <h4 class="modal-title" id="helpModalLabel">Dashboard Help</h4>
815                 </div>
816                 <div class="modal-body">
817
818                     <h4>Dygraphs (line, area and stacked area charts)</h4>
819
820                     <!-- Nav tabs -->
821                     <ul class="nav nav-tabs" role="tablist">
822                         <li role="presentation" class="active"><a href="#help_mouse" aria-controls="help_mouse" role="tab" data-toggle="tab">Mouse Interface</a></li>
823                         <li role="presentation"><a href="#help_touch" aria-controls="help_touch" role="tab" data-toggle="tab">Touch Interface</a></li>
824                     </ul>
825
826                     <!-- Tab panes -->
827                     <div class="tab-content">
828                         <div role="tabpanel" class="tab-pane active" id="help_mouse">
829                             <div class="p">
830                                 <h4>Mouse Over / Hover</h4>
831                                 Mouse over on a chart to show, at its legend, the values for the timestamp under the mouse (the chart will also highlight the point at the chart).
832                                 <br/>
833                                 All the other visible charts will also show and highlight their values for the same timestamp.
834                             </div>
835                             <hr/>
836                             <div class="p">
837                                 <h4>Drag Chart Contents</h4>
838                                 Drag the contents of a chart to pan it horizontally.
839                                 <br/>
840                                 All the charts will follow soon after you let the chart alone (this little delay is by design: it speeds up your browser and lets you focus on what you are exploring).
841                                 <br/>
842                                 Once a chart is panned, auto refreshing stops for all charts. To enable it again, <b>double click</b> a panned chart.
843                             </div>
844                             <hr/>
845                             <div class="p">
846                                 <h4>Double Click</h4>
847                                 Double Click a chart to reset all the charts to their default auto-refreshing state.
848                             </div>
849                             <hr/>
850                             <div class="p">
851                                 <h4>SHIFT + Drag</h4>
852                                 While pressing the shift key, click on the contents of a chart and move the mouse to select an area, to zoom in. The other charts will follow too. Zooming is performed in two phases:
853                                 <ul>
854                                     <li>The already loaded chart contents are zoomed (low resolution)</li>
855                                     <li>New data are transferred from the netdata server, to refresh the chart with possibly more detail.</li>
856                                 </ul>
857                                 Once a chart is zoomed, auto refreshing stops for all charts. To enable it again, <b>double click</b> a zoomed chart.
858                             </div>
859                             <hr/>
860                             <div class="p">
861                                 <h4>SHIFT + Mouse Wheel <small>(does not work on firefox and IE/Edge)</small></h4>
862                                 While pressing the shift key and the mouse pointer is over the contents of a chart, scroll the mouse wheel to zoom in or out. This kind of zooming is aligned to center below the mouse pointer. The other charts will follow too.
863                                 <br/>
864                                 Once a chart is zoomed, auto refreshing stops for all charts. To enable it again, <b>double click</b> a zoomed chart.
865                             </div>
866                             <hr/>
867                             <div class="p">
868                                 <h4>Legend Operations</h4>
869                                 Click on the label or value of a dimension, will select / un-select this dimension.
870                                 <br/>
871                                 You can press any of the SHIFT or CONTROL keys and then click on legend labels or values, to select / un-select multiple dimensions.
872                             </div>
873                         </div>
874                         <div role="tabpanel" class="tab-pane" id="help_touch">
875                             <div class="p">
876                                 <h4>Single Tap</h4>
877                                 Single Tap on the contents of a chart to show, at its legend, the values for the timestamp tapped (the chart will also highlight the point at the chart).
878                                 <br/>
879                                 All the other visible charts will also show and highlight their values for the same timestamp.
880                             </div>
881                             <hr/>
882                             <div class="p">
883                                 <h4>Drag Chart Contents</h4>
884                                 Touch and Drag the contents of a chart to pan it horizontally.
885                                 <br/>
886                                 All the charts will follow soon after you let the chart alone (this little delay is by design: it speeds up your browser and lets you focus on what you are exploring).
887                                 <br/>
888                                 Once a chart is panned, auto refreshing stops for all charts. To enable it again, <b>double tap</b> a panned chart.
889                             </div>
890                             <hr/>
891                             <div class="p">
892                                 <h4>Double Tap</h4>
893                                 Double tap a chart to reset all the charts to their default auto-refreshing state.
894                             </div>
895                             <hr/>
896                             <div class="p">
897                                 <h4>Zoom <small>(does not work on firefox and IE/Edge)</small></h4>
898                                 With two fingers, zoom in or out.
899                                 <br/>
900                                 Once a chart is zoomed, auto refreshing stops for all charts. To enable it again, <b>double click</b> a zoomed chart.
901                             </div>
902                             <hr/>
903                             <div class="p">
904                                 <h4>Legend Operations</h4>
905                                 Tap on the label or value of a dimension, will select / un-select this dimension.
906                             </div>
907                         </div>
908                     </div>
909                 </div>
910                 <div class="modal-footer">
911                     <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
912                 </div>
913             </div>
914         </div>
915     </div>
916
917     <div class="modal fade" id="alarmsModal" tabindex="-1" role="dialog" aria-labelledby="alarmsModalLabel">
918         <div class="modal-dialog modal-lg" role="document">
919             <div class="modal-content">
920                 <div class="modal-header">
921                     <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
922                     <h4 class="modal-title" id="alarmsModalLabel">netdata alarms</h4>
923                 </div>
924                 <div class="modal-body">
925                     <!-- Nav tabs -->
926                     <ul class="nav nav-tabs" role="tablist">
927                         <li role="presentation" class="active"><a href="#alarms_active" aria-controls="alarms_active" role="tab" data-toggle="tab">Active</a></li>
928                         <li role="presentation"><a href="#alarms_all" aria-controls="alarms_all" role="tab" data-toggle="tab">All</a></li>
929                         <li role="presentation"><a href="#alarms_log" aria-controls="alarms_log" role="tab" data-toggle="tab">Log</a></li>
930                     </ul>
931
932                     <!-- Tab panes -->
933                     <div class="tab-content">
934                         <div role="tabpanel" class="tab-pane active" id="alarms_active">
935                             loading...
936                         </div>
937                         <div role="tabpanel" class="tab-pane" id="alarms_all">
938                             loading...
939                         </div>
940                         <div role="tabpanel" class="tab-pane" id="alarms_log">
941                             loading...
942                         </div>
943                     </div>
944                 </div>
945                 <div class="modal-footer">
946                     <!-- <a href="#" onclick="alarmsUpdateModal(); return false;" type="button" class="btn btn-default">Update</a> -->
947                     <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
948                 </div>
949             </div>
950         </div>
951     </div>
952
953     <div class="modal fade" id="optionsModal" tabindex="-1" role="dialog" aria-labelledby="optionsModalLabel">
954         <div class="modal-dialog modal-lg" role="document">
955             <div class="modal-content">
956                 <div class="modal-header">
957                     <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
958                     <h4 class="modal-title" id="optionsModalLabel">netdata dashboard options</h4>
959                 </div>
960                 <div class="modal-body">
961                     <center>
962                         <small style="color: #BBBBBB;">These are browser settings. Each viewer has its own. They do not affect the operation of your netdata server.
963                         <br/>
964                         Settings take effect immediately and are saved permanently to browser local storage (except the refresh on focus / always option).
965                         <br/>
966                         To reset all options (including charts sizes) to their defaults, click <a href="#" onclick="resetDashboardOptions(); return false;">here</a>.</small>
967                     </center>
968                     <div style="padding: 10px;"></div>
969
970                     <!-- Nav tabs -->
971                     <ul class="nav nav-tabs" role="tablist">
972                         <li role="presentation" class="active"><a href="#settings_performance" aria-controls="settings_performance" role="tab" data-toggle="tab">Performance</a></li>
973                         <li role="presentation"><a href="#settings_sync" aria-controls="settings_sync" role="tab" data-toggle="tab">Synchronization</a></li>
974                         <li role="presentation"><a href="#settings_visual" aria-controls="settings_visual" role="tab" data-toggle="tab">Visual</a></li>
975                     </ul>
976
977                     <!-- Tab panes -->
978                     <div class="tab-content">
979                         <div role="tabpanel" class="tab-pane active" id="settings_performance">
980                             <form id="optionsForm1" method="get" class="form-horizontal">
981                                 <div class="form-group">
982                                     <table>
983                                     <tr class="option-row">
984                                         <td class="option-control"><input id="stop_updates_when_focus_is_lost" type="checkbox" checked data-toggle="toggle" data-offstyle="danger" data-onstyle="success" data-on="On Focus" data-off="Always" data-width="110px"></td>
985                                         <td class="option-info"><strong>When to refresh the charts?</strong><br/>
986                                             <small>When set to <b>On Focus</b>, the charts will stop being updated if the page / tab does not have the focus of the user. When set to <b>Always</b>, the charts will always be refreshed. Set it to <b>On Focus</b> it to lower the CPU requirements of the browser (and extend the battery of laptops and tablets) when this page does not have your focus. Set to <b>Always</b> to work on another window (i.e. change the settings of something) and have the charts auto-refresh in this window.</small>
987                                         </td>
988                                         </tr>
989                                     <tr class="option-row">
990                                         <td class="option-control">
991                                         <input id="eliminate_zero_dimensions" type="checkbox" checked data-toggle="toggle" data-on="Non Zero" data-off="All" data-width="110px">
992                                         </td>
993                                         <td class="option-info"><strong>Which dimensions to show?</strong><br/>
994                                             <small>When set to <b>Non Zero</b>, dimensions that have all their values (within the current view) set to zero will not be transferred from the netdata server (except if all dimensions of the chart are zero, in which case this setting does nothing - all dimensions are transferred and shown). When set to <b>All</b>, all dimensions will always be shown. Set it to <b>Non Zero</b> to lower the data transferred between netdata and your browser, lower the CPU requirements of your browser (fewer lines to draw) and increase the focus on the legends (fewer entries at the legends).</small>
995                                         </td>
996                                         </tr>
997                                     <tr class="option-row">
998                                         <td class="option-control"><input id="destroy_on_hide" type="checkbox" data-toggle="toggle" data-on="Destroy" data-off="Hide" data-width="110px"></td>
999                                         <td class="option-info"><strong>How to handle hidden charts?</strong><br/>
1000                                             <small>When set to <b>Destroy</b>, charts that are not in the current viewport of the browser (are above, or below the visible area of the page), will be destroyed and re-created if and when they become visible again. When set to <b>Hide</b>, the not-visible charts will be just hidden, to simplify the DOM and speed up your browser. Set it to <b>Destroy</b>, to lower the memory requirements of your browser. Set it to <b>Hide</b> for smoother page scrolling.</small>
1001                                         </td>
1002                                         </tr>
1003                                     </table>
1004                                 </div>
1005                             </form>
1006                         </div>
1007                         <div role="tabpanel" class="tab-pane" id="settings_sync">
1008                             <form id="optionsForm2" method="get" class="form-horizontal">
1009                                 <div class="form-group">
1010                                     <table>
1011                                     <tr class="option-row">
1012                                         <td class="option-control"><input id="parallel_refresher" type="checkbox" checked data-toggle="toggle" data-on="Parallel" data-off="Sequential" data-width="110px"></td>
1013                                         <td class="option-info"><strong>Which chart refresh policy to use?</strong><br/>
1014                                             <small>When set to <b>parallel</b>, visible charts are refreshed in parallel (all queries are sent to netdata server in parallel) and are rendered asynchronously. When set to <b>sequential</b> charts are refreshed one after another. Set it to parallel if your browser can cope with it (most modern browsers do), set it to sequential if you work on an older/slower computer.</small>
1015                                         </td>
1016                                         </tr>
1017                                     <tr class="option-row" id="concurrent_refreshes_row">
1018                                         <td class="option-control"></td>
1019                                         <td class="option-info">
1020                                             <table>
1021                                             <tr class="option-row">
1022                                             <td class="option-control">
1023                                             <input id="concurrent_refreshes" type="checkbox" checked data-toggle="toggle" data-on="Resync" data-off="Best Effort" data-width="110px">
1024                                             </td>
1025                                             <td class="option-info">
1026                                             <strong>Shall we re-sync chart refreshes?</strong><br/>
1027                                             <small>When set to <b>Resync</b>, the dashboard will attempt to re-synchronize all the charts so that they are refreshed concurrently. When set to <b>Best Effort</b>, each chart may be refreshed with a little time difference to the others. Normally, the dashboard starts refreshing them in parallel, but depending on the speed of your computer and the network latencies, charts start having a slight time difference. Setting this to <b>Resync</b> will attempt to re-synchronize the charts on every update. Setting it to <b>Best Effort</b> may lower the pressure on your browser and the network.</small>
1028                                             </td>
1029                                             </tr>
1030                                             </table>
1031                                         </td>
1032                                         </tr>
1033                                     <tr class="option-row">
1034                                         <td class="option-control"><input id="sync_selection" type="checkbox" checked data-toggle="toggle" data-on="Sync" data-off="Don't Sync" data-onstyle="success" data-offstyle="danger" data-width="110px"></td>
1035                                         <td class="option-info"><strong>Sync hover selection on all charts?</strong><br/>
1036                                             <small>When enabled, a selection on one chart will automatically select the same time on all other visible charts and the legends of all visible charts will be updated to show the selected values. When disabled, only the chart getting the user's attention will be selected. Enable it to get better insights of the data. Disable it if you are on a very slow computer that cannot actually do it.</small>
1037                                         </td>
1038                                         </tr>
1039                                     <tr class="option-row">
1040                                         <td class="option-control"><input id="sync_pan_and_zoom" type="checkbox" checked data-toggle="toggle"  data-on="Sync" data-off="Don't Sync" data-onstyle="success" data-offstyle="danger" data-width="110px"></td>
1041                                         <td class="option-info"><strong>Sync pan and zoom on all charts?</strong><br/>
1042                                             <small>When enabled, pan and zoom operations on a chart will be replicated to all charts (even the ones that are not currently visible - of course only when they will become visible). When disabled, pan and zoom operations will not be propagated to other charts.</small>
1043                                         </td>
1044                                         </tr>
1045                                     </table>
1046                                 </div>
1047                             </form>
1048                         </div>
1049                         <div role="tabpanel" class="tab-pane" id="settings_visual">
1050                             <form id="optionsForm3" method="get" class="form-horizontal">
1051                                 <div class="form-group">
1052                                     <table>
1053                                     <tr class="option-row">
1054                                         <td class="option-control"><input id="netdata_theme_control" type="checkbox" checked data-toggle="toggle" data-offstyle="danger" data-onstyle="success" data-on="Dark" data-off="White" data-width="110px"></td>
1055                                         <td class="option-info"><strong>Which theme to use?</strong><br/>
1056                                             <small>Netdata comes with two themes: <b>Dark</b> (the default) and <b>White</b>.
1057                                             <br/>
1058                                             <b>Switching this will reload the dashboard</b>.
1059                                             </small>
1060                                         </td>
1061                                         </tr>
1062                                     <tr class="option-row">
1063                                         <td class="option-control"><input id="show_help" type="checkbox" checked data-toggle="toggle" data-on="Help Me" data-off="No Help" data-width="110px"></td>
1064                                         <td class="option-info"><strong>Do you need help?</strong><br/>
1065                                             <small>Netdata can show some help in some areas to help you use the dashboard. If all these balloons bother you, disable them using this switch.
1066                                             <br/>
1067                                             <b>Switching this will reload the dashboard</b>.
1068                                             </small>
1069                                         </td>
1070                                         </tr>
1071                                     <tr class="option-row">
1072                                         <td class="option-control"><input id="pan_and_zoom_data_padding" type="checkbox" checked data-toggle="toggle"  data-on="Pad" data-off="Don't Pad" data-width="110px"></td>
1073                                         <td class="option-info"><strong>Enable data padding when panning and zooming?</strong><br/>
1074                                             <small>When set to <b>Pad</b> the charts will be padded with more data, both before and after the visible area, thus giving the impression the whole database is loaded. This padding will happen only after the first pan or zoom operation on the chart (initially all charts have only the visible data). When set to <b>Don't Pad</b> only the visible data will be transfered from the netdata server, even after the first pan and zoom operation.</small>
1075                                         </td>
1076                                         </tr>
1077                                     <tr class="option-row">
1078                                         <td class="option-control"><input id="smooth_plot" type="checkbox" checked data-toggle="toggle"  data-on="Smooth" data-off="Rough" data-width="110px"></td>
1079                                         <td class="option-info"><strong>Enable Bézier lines on charts?</strong><br/>
1080                                             <small>When set to <b>Smooth</b> the charts libraries that support it, will plot smooth curves instead of simple straight lines to connect the points.
1081                                             <br/>
1082                                             Keep in mind <a href="http://dygraphs.com" target="_blank">dygraphs</a>, the main charting library in netdata dashboards, can only smooth line charts. It cannot smooth area or stacked charts. When set to <b>Rough</b>, this setting can lower the CPU resources consumed by your browser.</small>
1083                                         </td>
1084                                         </tr>
1085                                     </table>
1086                                 </div>
1087                             </form>
1088                         </div>
1089                     </div>
1090                 </div>
1091                 <div class="modal-footer">
1092                     <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
1093                 </div>
1094             </div>
1095         </div>
1096     </div>
1097
1098
1099     <div class="modal fade" id="updateModal" tabindex="-1" role="dialog" aria-labelledby="updateModalLabel">
1100         <div class="modal-dialog" role="document">
1101             <div class="modal-content">
1102                 <div class="modal-header">
1103                     <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
1104                     <h4 class="modal-title" id="updateModalLabel">Update Check</h4>
1105                 </div>
1106                 <div class="modal-body">
1107                     Your netdata version: <b><code><span id="netdataVersion">Unknown</span></code></b>
1108                     <br/>
1109                     <div style="padding: 10px;"></div>
1110                     <div id="versionCheckLog">Not checked yet. Please press the Check Now button.</div>
1111                 </div>
1112                 <div class="modal-footer">
1113                     <a href="#" onclick="notifyForUpdate(true); return false;" type="button" class="btn btn-default">Check Now</a>
1114                     <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
1115                 </div>
1116             </div>
1117         </div>
1118     </div>
1119
1120     <div class="modal fade" id="deleteRegistryModal" tabindex="-1" role="dialog" aria-labelledby="deleteRegistryModalLabel">
1121         <div class="modal-dialog" role="document">
1122             <div class="modal-content">
1123                 <div class="modal-header">
1124                     <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
1125                     <h4 class="modal-title" id="deleteRegistryModalLabel">Delete <span id="deleteRegistryServerName"></span>?</h4>
1126                 </div>
1127                 <div class="modal-body">
1128                     You are about to delete, from your personal list of netdata servers, the following server:
1129                     <p style="text-align: center; padding-top: 10px; padding-bottom: 10px; line-height: 2;">
1130                     <b><span id="deleteRegistryServerName2"></span></b>
1131                     <br/>
1132                     <b><span id="deleteRegistryServerURL"></span></b>
1133                     </p>
1134                     Are you sure you want to do this?
1135                     <br/>
1136                     <div style="padding: 10px;"></div>
1137                     <small>Keep in mind, this server will be added back if and when you visit it again.</small>
1138                     <br/>
1139                     <div id="deleteRegistryResponse" style="display: block; width: 100%; text-align: center; padding-top: 20px;"></div>
1140                 </div>
1141                 <div class="modal-footer">
1142                     <button type="button" class="btn btn-success" data-dismiss="modal">keep it</button>
1143                     <a href="#" onclick="notifyForDeleteRegistry(true); return false;" type="button" class="btn btn-danger">delete it</a>
1144                 </div>
1145             </div>
1146         </div>
1147     </div>
1148
1149     <div class="modal fade" id="switchRegistryModal" tabindex="-1" role="dialog" aria-labelledby="switchRegistryModalLabel">
1150         <div class="modal-dialog" role="document">
1151             <div class="modal-content">
1152                 <div class="modal-header">
1153                     <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
1154                     <h4 class="modal-title" id="switchRegistryModalLabel">Switch Netdata Registry Identity</h4>
1155                 </div>
1156                 <div class="modal-body">
1157                     You can copy and paste the following ID to all your browsers (e.g. work and home).
1158                     <br/>
1159                     All the browsers with the same ID will identify <b>you</b>, so please don't share this with others.
1160                     <p style="text-align: center; padding-top: 10px; padding-bottom: 10px; line-height: 2;">
1161                     <form action="#">
1162                     <input type="text" class="form-control" id="switchRegistryPersonGUID" placeholder="your personal ID" maxlength="36" autocomplete="off" style="text-align: center; font-size: 1.4em;">
1163                     </form>
1164                     </p>
1165                     Either copy this ID and paste it to another browser, or paste here the ID you have taken from another browser.
1166                     <p style="padding-top: 10px;"><small>
1167                         Keep in mind that:
1168                         <ul>
1169                             <li>when you switch ID, your previous ID will be lost forever - this is irreversible.</li>
1170                             <li>both IDs (your old and the new) must list this netdata at their personal lists.</li>
1171                             <li>both IDs have to be known by the registry: <b><span id="switchRegistryURL"></span></b>.</li>
1172                             <li>to get a new ID, just clear your browser cookies.</li>
1173                         </ul>
1174                     </small></p>
1175                     <div id="switchRegistryResponse" style="display: block; width: 100%; text-align: center; padding-top: 20px;"></div>
1176                 </div>
1177                 <div class="modal-footer">
1178                     <button type="button" class="btn btn-success" data-dismiss="modal">cancel</button>
1179                     <a href="#" onclick="notifyForSwitchRegistry(true); return false;" type="button" class="btn btn-danger">impersonate</a>
1180                 </div>
1181             </div>
1182         </div>
1183     </div>
1184
1185     <div class="modal fade" id="gotoServerModal" tabindex="-1" role="dialog" aria-labelledby="gotoServerModalLabel">
1186         <div class="modal-dialog" role="document">
1187             <div class="modal-content">
1188                 <div class="modal-header">
1189                     <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
1190                     <h4 class="modal-title" id="gotoServerModalLabel"><span id="gotoServerName"></span></h4>
1191                 </div>
1192                 <div class="modal-body">
1193                     Checking known URLs for this server...
1194                     <div  style="padding-top: 20px;">
1195                         <table id="gotoServerList">
1196                         </table>
1197                     </div>
1198                     <p style="padding-top: 10px;"><small>
1199                         Checks may fail if you are viewing an HTTPS page and the server to be checked is HTTP only.
1200                     </small></p>
1201                     <div id="gotoServerResponse" style="display: block; width: 100%; text-align: center; padding-top: 20px;"></div>
1202                 </div>
1203                 <div class="modal-footer">
1204                     <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
1205                 </div>
1206             </div>
1207         </div>
1208     </div>
1209
1210 <script type="text/javascript">
1211 var this_is_demo = null;
1212 function isdemo() {
1213     if(this_is_demo !== null) return this_is_demo;
1214     this_is_demo = false;
1215
1216     try {
1217         if(typeof document.location.hostname === 'string') {
1218             if(document.location.hostname.endsWith('.my-netdata.io') ||
1219                     document.location.hostname.endsWith('.mynetdata.io') ||
1220                     document.location.hostname.endsWith('.netdata.rocks') ||
1221                     document.location.hostname.endsWith('.firehol.org') ||
1222                     document.location.hostname.endsWith('.netdata.online'))
1223                     this_is_demo = true;
1224         }
1225     }
1226     catch(error) {
1227         ;
1228     }
1229
1230     return this_is_demo;
1231 }
1232
1233 if(isdemo()) {
1234     document.getElementById('masthead').style.display = 'block';
1235 }
1236
1237 function netdataURL(url) {
1238     if(typeof url === 'undefined')
1239         url = document.location.toString();
1240
1241     if(url.indexOf('#') !== -1)
1242         url = url.substring(0, url.indexOf('#'));
1243
1244     var hash = netdataHash();
1245
1246     // console.log('netdataURL: ' + url + hash);
1247
1248     return url + hash;
1249 }
1250
1251 function netdataReload(url) {
1252     var t = netdataURL(url);
1253     // console.log('netdataReload: ' + t);
1254     document.location = t;
1255
1256     // since we play with hash
1257     // this is needed to reload the page
1258     location.reload();
1259 }
1260
1261 var gotoServerValidateRemaining = 0;
1262 var gotoServerMiddleClick = false;
1263 var gotoServerStop = false;
1264 function gotoServerValidateUrl(id, guid, url) {
1265     var penaldy = 0;
1266     if(document.location.toString().startsWith('http://') && url.toString().startsWith('https://'))
1267             // we penalize https only if the current url is http
1268             // to allow the user walk through all its servers.
1269             penaldy = 500;
1270
1271     var finalURL = netdataURL(url);
1272
1273     setTimeout(function() {
1274         document.getElementById('gotoServerList').innerHTML += '<tr><td style="padding-left: 20px;"><a href="' + finalURL + '" target="_blank">' + url + '</a></td><td style="padding-left: 30px;"><code id="' + guid + '-' + id + '-status">checking...</code></td></tr>';
1275
1276         NETDATA.registry.hello(url, function(data) {
1277             if (data) {
1278                 // console.log('OK ' + id + ' URL: ' + url);
1279                 document.getElementById(guid + '-' + id + '-status').innerHTML = "OK";
1280
1281                 if(!gotoServerStop) {
1282                     gotoServerStop = true;
1283
1284                     if(gotoServerMiddleClick) {
1285                         window.open(finalURL, '_blank');
1286                         gotoServerMiddleClick = false;
1287                         document.getElementById('gotoServerResponse').innerHTML = '<b>Opening new window to ' + NETDATA.registry.machines[guid].name + '<br/><a href="' + finalURL + '">' + url + '</a></b><br/>(check your pop-up blocker if it fails)';
1288                     }
1289                     else
1290                         document.location = finalURL;
1291                 }
1292             }
1293             else {
1294                 document.getElementById(guid + '-' + id + '-status').innerHTML = "failed!";
1295                 gotoServerValidateRemaining--;
1296                 if(gotoServerValidateRemaining <= 0) {
1297                     gotoServerMiddleClick = false;
1298                     document.getElementById('gotoServerResponse').innerHTML = '<b>Sorry! I cannot find any operational URL for this server</b>';
1299                 }
1300             }
1301         });
1302     }, (id * 50) + penaldy);
1303 }
1304
1305 function gotoServerModalHandler(guid) {
1306     // console.log('goto server: ' + guid);
1307
1308     gotoServerStop = false;
1309     var len = NETDATA.registry.machines[guid].alternate_urls.length;
1310
1311     document.getElementById('gotoServerResponse').innerHTML = '';
1312     document.getElementById('gotoServerList').innerHTML = '';
1313     document.getElementById('gotoServerName').innerHTML = NETDATA.registry.machines[guid].name;
1314     $('#gotoServerModal').modal('show');
1315
1316     gotoServerValidateRemaining = len;
1317     while(len--)
1318         gotoServerValidateUrl(len, guid, NETDATA.registry.machines[guid].alternate_urls[len]);
1319
1320     return false;
1321 }
1322
1323 function gotoServerInit() {
1324     $(".registry_link").on('click', function(e) {
1325         if(e.which === 2) {
1326             e.preventDefault();
1327             gotoServerMiddleClick = true;
1328         }
1329         else {
1330             gotoServerMiddleClick = false;
1331         }
1332
1333         return true;
1334     });
1335 }
1336
1337 function switchRegistryModalHandler() {
1338     document.getElementById('switchRegistryPersonGUID').value = NETDATA.registry.person_guid;
1339     document.getElementById('switchRegistryURL').innerHTML = NETDATA.registry.server;
1340     document.getElementById('switchRegistryResponse').innerHTML = '';
1341     $('#switchRegistryModal').modal('show');
1342 }
1343
1344 function notifyForSwitchRegistry() {
1345     var n = document.getElementById('switchRegistryPersonGUID').value;
1346
1347     if(n !== '' && n.length === 36) {
1348         NETDATA.registry.switch(n, function(result) {
1349             if(result !== null) {
1350                 $('#switchRegistryModal').modal('hide');
1351                 NETDATA.registry.init();
1352             }
1353             else {
1354                 document.getElementById('switchRegistryResponse').innerHTML = "<b>Sorry! The registry rejected your request.</b>";
1355             }
1356         });
1357     }
1358     else
1359         document.getElementById('switchRegistryResponse').innerHTML = "<b>The ID you have entered is not a GUID.</b>";
1360 }
1361
1362 var deleteRegistryUrl = null;
1363 function deleteRegistryModalHandler(guid, name, url) {
1364     deleteRegistryUrl = url;
1365     document.getElementById('deleteRegistryServerName').innerHTML = name;
1366     document.getElementById('deleteRegistryServerName2').innerHTML = name;
1367     document.getElementById('deleteRegistryServerURL').innerHTML = url;
1368     document.getElementById('deleteRegistryResponse').innerHTML = '';
1369     $('#deleteRegistryModal').modal('show');
1370 }
1371
1372 function notifyForDeleteRegistry() {
1373     if(deleteRegistryUrl) {
1374         NETDATA.registry.delete(deleteRegistryUrl, function(result) {
1375             if(result !== null) {
1376                 deleteRegistryUrl = null;
1377                 $('#deleteRegistryModal').modal('hide');
1378                 NETDATA.registry.init();
1379             }
1380             else {
1381                 document.getElementById('deleteRegistryResponse').innerHTML = "<b>Sorry! this command was rejected by the registry server.</b>";
1382             }
1383         });
1384     }
1385 }
1386
1387 var options = {
1388     sparklines_registry: {},
1389     menus: {},
1390     submenu_names: {},
1391     data: null,
1392     hostname: 'netdata_server', // will be overwritten by the netdata server
1393     categories: new Array(),
1394     categories_idx: {},
1395     families: new Array(),
1396     families_idx: {},
1397
1398     chartsPerRow: 0,
1399     chartsMinWidth: 1450,
1400     chartsHeight: 180,
1401     sparklinesHeight: 60,
1402 };
1403
1404 // generate a sparkline
1405 // used in the documentation
1406 function sparkline(chart, dimension, units) {
1407     var key = chart + '.' + dimension;
1408
1409     if(typeof units === 'undefined')
1410         units = '';
1411
1412     if(typeof options.sparklines_registry[key] === 'undefined')
1413         options.sparklines_registry[key] = { count: 1 };
1414     else
1415         options.sparklines_registry[key].count++;
1416
1417     key = key + '.' + options.sparklines_registry[key].count;
1418
1419     var h = '<div data-netdata="' + chart + '" data-after="-120" data-width="25%" data-height="15px" data-chart-library="dygraph" data-dygraph-theme="sparkline" data-dimensions="' + dimension + '" data-show-value-of-' + dimension + '-at="' + key + '"></div> (<span id="' + key + '" style="display: inline-block; min-width: 50px; text-align: right;">X</span>' + units + ')';
1420
1421     return h;
1422 }
1423
1424 function chartsPerRow(total) {
1425     if(options.chartsPerRow === 0) {
1426         width = Math.floor(total / options.chartsMinWidth);
1427         if(width === 0) width = 1;
1428         return width;
1429     }
1430     else return options.chartsPerRow;
1431 }
1432
1433 function prioritySort(a, b) {
1434     if(a.priority < b.priority) return -1;
1435     if(a.priority > b.priority) return 1;
1436     if(a.name < b.name) return -1;
1437     return 1;
1438 }
1439
1440 function sortObjectByPriority(object) {
1441     var idx = {};
1442     var sorted = new Array();
1443
1444     for(var i in object) {
1445         if(typeof idx[i] === 'undefined') {
1446             idx[i] = object[i];
1447             sorted.push(i);
1448         }
1449     }
1450
1451     sorted.sort(function(a, b) {
1452         if(idx[a].priority < idx[b].priority) return -1;
1453         if(idx[a].priority > idx[b].priority) return 1;
1454         if(a < b) return -1;
1455         return 1;
1456     });
1457
1458     return sorted;
1459 }
1460
1461
1462 // ----------------------------------------------------------------------------
1463 // scroll to a section, without changing the browser history
1464
1465 function scrollToId(hash) {
1466     if(hash && hash != '') {
1467         var offset = $('#' + hash).offset();
1468         if(typeof offset !== 'undefined')
1469             $('html, body').animate({ scrollTop: offset.top }, 0);
1470     }
1471
1472     // we must return false to prevent the default action
1473     return false;
1474 }
1475
1476 // ----------------------------------------------------------------------------
1477
1478 function gaugeChart(title, width, dimensions, colors) {
1479     if(typeof colors === 'undefined')
1480         colors = '';
1481
1482     if(typeof dimensions === 'undefined')
1483         dimensions = '';
1484
1485     return '<div data-netdata="CHART_UNIQUE_ID"'
1486                             + ' data-dimensions="' + dimensions + '"'
1487                             + ' data-chart-library="gauge"'
1488                             + ' data-gauge-adjust="width"'
1489                             + ' data-title="' + title + '"'
1490                             + ' data-width="' + width + '"'
1491                             + ' data-before="0"'
1492                             + ' data-after="-CHART_DURATION"'
1493                             + ' data-points="CHART_DURATION"'
1494                             + ' data-colors="' + colors + '"'
1495                             + ' role="application"></div>';
1496 }
1497
1498 // ----------------------------------------------------------------------------
1499
1500 var menuData = {
1501     'system': {
1502         title: 'System Overview',
1503         icon: '<i class="fa fa-bookmark" aria-hidden="true"></i>',
1504         info: 'Overview of the key system metrics.'
1505     },
1506
1507     'ap': {
1508         title: 'Access Points',
1509         icon: '<i class="fa fa-wifi" aria-hidden="true"></i>',
1510         info: undefined
1511     },
1512
1513     'tc': {
1514         title: 'Quality of Service',
1515         icon: '<i class="fa fa-globe" aria-hidden="true"></i>',
1516         info: 'Netdata collects and visualizes tc class utilization using its <a href="https://github.com/firehol/netdata/blob/master/plugins.d/tc-qos-helper.sh" target="_blank">tc-helper plugin</a>. If you also use <a href="http://firehol.org/#fireqos" target="_blank">FireQOS</a> for setting up QoS, netdata automatically collects interface and class names. If your QoS configuration includes overheads calculation, the values shown here will include these overheads (the total bandwidth for the same interface as reported in the Network Interfaces section, will be lower than the total bandwidth reported here). Also, data collection may have a slight time difference compared to the interface (QoS data collection is implemented with a BASH script, so a shift in data collection of a few milliseconds should be justified).'
1517     },
1518
1519     'net': {
1520         title: 'Network Interfaces',
1521         icon: '<i class="fa fa-share-alt" aria-hidden="true"></i>',
1522         info: 'Per network interface statistics collected from <code>/proc/net/dev</code>.'
1523     },
1524
1525     'ipv4': {
1526         title: 'IPv4 Networking',
1527         icon: '<i class="fa fa-cloud" aria-hidden="true"></i>',
1528         info: undefined
1529     },
1530
1531     'ipv6': {
1532         title: 'IPv6 Networking',
1533         icon: '<i class="fa fa-cloud" aria-hidden="true"></i>',
1534         info: undefined
1535     },
1536
1537     'ipvs': {
1538         title: 'IP Virtual Server',
1539         icon: '<i class="fa fa-eye" aria-hidden="true"></i>',
1540         info: undefined
1541     },
1542
1543     'netfilter': {
1544         title: 'Firewall (netfilter)',
1545         icon: '<i class="fa fa-shield" aria-hidden="true"></i>',
1546         info: undefined
1547     },
1548
1549     'cpu': {
1550         title: 'CPUs',
1551         icon: '<i class="fa fa-bolt" aria-hidden="true"></i>',
1552         info: undefined
1553     },
1554
1555     'mem': {
1556         title: 'Memory',
1557         icon: '<i class="fa fa-bolt" aria-hidden="true"></i>',
1558         info: undefined
1559     },
1560
1561     'disk': {
1562         title: 'Disks',
1563         icon: '<i class="fa fa-folder" aria-hidden="true"></i>',
1564         info: 'Charts with performance information for all the system disks. Special care has been given to present disk performance metrics in a way compatible with <code>iostat -x</code>. netdata by default prevents rendering performance charts for individual partitions and unmounted virtual disks. Disabled charts can still be enabled by altering the relative settings in the netdata configuration file.'
1565     },
1566
1567     'sensors': {
1568         title: 'Sensors',
1569         icon: '<i class="fa fa-leaf" aria-hidden="true"></i>',
1570         info: undefined
1571     },
1572
1573     'nfsd': {
1574         title: 'File Server (nfsd)',
1575         icon: '<i class="fa fa-folder-open" aria-hidden="true"></i>',
1576         info: undefined
1577     },
1578
1579     'apps': {
1580         title: 'Applications',
1581         icon: '<i class="fa fa-heartbeat" aria-hidden="true"></i>',
1582         info: 'Per application statistics are collected using netdata\'s <code>apps.plugin</code>. This plugin walks through the entire <code>/proc</code> filesystem and aggregates statistics for applications of interest, defined in <code>/etc/netdata/apps_groups.conf</code> (the default is <a href="https://github.com/firehol/netdata/blob/master/conf.d/apps_groups.conf" target="_blank">here</a>). The plugin internally builds a process tree (much like <code>ps fax</code> does), and groups processes together (evaluating both child and parent processes) so that the result is always a chart with a predefined set of dimensions (of course, only application groups found running are reported). The reported values are compatible with <code>top</code>, although the netdata plugin counts also the resources of exited children (unlike <code>top</code> which shows only the resources of the currently running processes). So for processes like shell scripts, the reported values include the resources used by the commands these scripts run within each timeframe.',
1583         height: 1.5
1584     },
1585
1586     'users': {
1587         title: 'Users',
1588         icon: '<i class="fa fa-user" aria-hidden="true"></i>',
1589         info: 'Per user statistics are collected using netdata\'s <code>apps.plugin</code>. This plugin walks through the entire <code>/proc</code> filesystem and aggregates statistics per user. The reported values are compatible with <code>top</code>, although the netdata plugin counts also the resources of exited children (unlike <code>top</code> which shows only the resources of the currently running processes). So for processes like shell scripts, the reported values include the resources used by the commands these scripts run within each timeframe.',
1590         height: 1.5
1591     },
1592
1593     'groups': {
1594         title: 'User Groups',
1595         icon: '<i class="fa fa-users" aria-hidden="true"></i>',
1596         info: 'Per user group statistics are collected using netdata\'s <code>apps.plugin</code>. This plugin walks through the entire <code>/proc</code> filesystem and aggregates statistics per user group. The reported values are compatible with <code>top</code>, although the netdata plugin counts also the resources of exited children (unlike <code>top</code> which shows only the resources of the currently running processes). So for processes like shell scripts, the reported values include the resources used by the commands these scripts run within each timeframe.',
1597         height: 1.5
1598     },
1599
1600     'netdata': {
1601         title: 'Netdata Monitoring',
1602         icon: '<i class="fa fa-bar-chart" aria-hidden="true"></i>',
1603         info: undefined
1604     },
1605
1606     'example': {
1607         title: 'Example Charts',
1608         info: undefined
1609     },
1610
1611     'cgroup': {
1612         title: '',
1613         icon: '<i class="fa fa-th" aria-hidden="true"></i>',
1614         info: undefined
1615     },
1616
1617     'cgqemu': {
1618         title: '',
1619         icon: '<i class="fa fa-th-large" aria-hidden="true"></i>',
1620         info: undefined
1621     },
1622
1623     'memcached': {
1624         title: 'memcached',
1625         icon: '<i class="fa fa-database" aria-hidden="true"></i>',
1626         info: undefined
1627     },
1628
1629     'mysql': {
1630         title: 'MySQL',
1631         icon: '<i class="fa fa-database" aria-hidden="true"></i>',
1632         info: undefined
1633     },
1634
1635     'redis': {
1636         title: 'Redis',
1637         icon: '<i class="fa fa-database" aria-hidden="true"></i>',
1638         info: undefined
1639     },
1640
1641     'retroshare': {
1642         title: 'RetroShare',
1643         icon: '<i class="fa fa-share-alt" aria-hidden="true"></i>',
1644         info: undefined
1645     },
1646
1647     'ipfs': {
1648         title: 'IPFS',
1649         icon: '<i class="fa fa-folder-open" aria-hidden="true"></i>',
1650         info: undefined
1651     },
1652
1653     'phpfpm': {
1654         title: 'PHP-FPM',
1655         icon: '<i class="fa fa-eye" aria-hidden="true"></i>',
1656         info: undefined,
1657     },
1658
1659     'postfix': {
1660         title: 'postfix',
1661         icon: '<i class="fa fa-envelope" aria-hidden="true"></i>',
1662         info: undefined,
1663     },
1664
1665     'nginx': {
1666         title: 'nginx',
1667         icon: '<i class="fa fa-eye" aria-hidden="true"></i>',
1668         info: undefined,
1669     },
1670
1671     'apache': {
1672         title: 'Apache',
1673         icon: '<i class="fa fa-eye" aria-hidden="true"></i>',
1674         info: undefined,
1675     },
1676
1677     'named': {
1678         title: 'named',
1679         icon: '<i class="fa fa-tag" aria-hidden="true"></i>',
1680         info: undefined
1681     },
1682
1683     'squid': {
1684         title: 'squid',
1685         icon: '<i class="fa fa-exchange" aria-hidden="true"></i>',
1686         info: undefined
1687     },
1688
1689     'nut': {
1690         title: 'UPS',
1691         icon: '<i class="fa fa-battery-half" aria-hidden="true"></i>',
1692         info: undefined
1693     },
1694
1695     'smawebbox': {
1696         title: 'Solar Power',
1697         icon: '<i class="fa fa-sun-o" aria-hidden="true"></i>',
1698         info: undefined
1699     },
1700
1701     'snmp': {
1702         title: 'SNMP',
1703         icon: '<i class="fa fa-random" aria-hidden="true"></i>',
1704         info: undefined
1705     }
1706 };
1707
1708 var submenuData = {
1709     'mem.ksm': {
1710         title: 'Memory Deduper',
1711         info: 'Kernel Same-page Merging (KSM) performance monitoring, read from several files in <code>/sys/kernel/mm/ksm/</code>. KSM is a memory-saving de-duplication feature in the Linux kernel (since version 2.6.32). The KSM daemon ksmd periodically scans those areas of user memory which have been registered with it, looking for pages of identical content which can be replaced by a single write-protected page (which is automatically copied if a process later wants to update its content). KSM was originally developed for use with KVM (where it was known as Kernel Shared Memory), to fit more virtual machines into physical memory, by sharing the data common between them.  But it can be useful to any application which generates many instances of the same data.'
1712     },
1713
1714     'netfilter.conntrack': {
1715         title: 'Connection Tracker',
1716         info: 'Netfilter Connection Tracker performance monitoring, read from <code>/proc/net/stat/nf_conntrack</code>. The connection tracker keeps track of all connections of the machine, inbound and outbound. It works by keeping a database with all open connections, tracking network and address translation and connection expectations.'
1717     },
1718
1719     'netfilter.nfacct': {
1720         title: 'Bandwidth Accounting',
1721         info: 'The following information is read using the <code>nfacct.plugin</code>.'
1722     },
1723
1724     'netfilter.synproxy': {
1725         title: 'DDoS Protection',
1726         info: 'DDoS Protection performance monitoring read from <code>/proc/net/stat/synproxy</code>. <a href="https://github.com/firehol/firehol/wiki/Working-with-SYNPROXY" target="_blank">SYNPROXY</a> is a TCP SYN packets proxy. It is used to protect any TCP server (like a web server) from SYN floods and similar DDoS attacks. It is a netfilter module, in the Linux kernel (since version 3.12). It is optimized to handle millions of packets per second utilizing all CPUs available without any concurrency locking between the connections. It can be used for any kind of TCP traffic (even encrypted), since it does not interfere with the content itself.'
1727     }
1728 };
1729
1730 //
1731 // chartData works on the context of a chart
1732 // Its purpose is to set:
1733 //
1734 // info: the text above the charts
1735 // heads: the representation of the chart at the top the subsection (second level menu)
1736 // mainheads: the representation of the chart at the top of the section (first level menu)
1737 // colors: the dimension colors of the chart (the default colors are appended)
1738 // height: the ratio of the chart height relative to the default
1739 //
1740 var chartData = {
1741     'system.cpu': {
1742         info: 'Total CPU utilization (all cores). 100% here means there is no CPU idle time at all. You can get per core usage at the <a href="#cpu">CPUs</a> section and per application usage at the <a href="#apps">Applications Monitoring</a> section.<br/>Keep an eye on <b>iowait</b> ' + sparkline('system.cpu', 'iowait', '%') + '. If it is constantly high, your disks are a bottleneck and they slow your system down.<br/>Another important metric worth monitoring, is <b>softirq</b> ' + sparkline('system.cpu', 'softirq', '%') + '. A constantly high percentage of softirq may indicate network drivers issues.'
1743     },
1744
1745     'system.load': {
1746         info: 'Current system load, i.e. the number of processes using CPU or waiting for system resources (usually CPU and disk). The 3 metrics refer to 1, 5 and 15 minute averages. Linux calculates this once every 5 seconds. Netdata reads them from <code>/proc/loadavg</code>. For more information check <a href="https://en.wikipedia.org/wiki/Load_(computing)" target="_blank">this wikipedia article</a>',
1747         height: 0.7
1748     },
1749
1750     'system.io': {
1751         info: 'Total Disk I/O, for all disks, read from <code>/proc/vmstat</code>. You can get detailed information about each disk at the <a href="#disk">Disks</a> section and per application Disk usage at the <a href="#apps">Applications Monitoring</a> section.'
1752     },
1753
1754     'system.swapio': {
1755         info: 'Total Swap I/O, read from <code>/proc/vmstat</code>. (netdata measures both <code>in</code> and <code>out</code>. If either of them is not shown in the chart, it is because it is zero - you can change the page settings to always render all the available dimensions on all charts).'
1756     },
1757
1758     'system.pgfaults': {
1759         info: 'Total page faults, read from <code>/proc/vmstat</code>. <b>Major page faults</b> indicates that the system is using its swap. You can find which applications use the swap at the <a href="#apps">Applications Monitoring</a> section.'
1760     },
1761
1762     'system.entropy': {
1763         colors: '#CC22AA',
1764         info: '<a href="https://en.wikipedia.org/wiki/Entropy_(computing)" target="_blank">Entropy</a>, read from <code>/proc/sys/kernel/random/entropy_avail</code>, is like a pool of random numbers that are mainly used in cryptography. It is advised that the pool remains always <a href="https://blog.cloudflare.com/ensuring-randomness-with-linuxs-random-number-generator/" target="_blank">above 200</a>. If the pool of entropy gets empty, you risk your security to be predictable and you should install a user-space random numbers generating daemon, like <a href="http://www.issihosts.com/haveged/" target="_blank">haveged</a>, to keep the pool in healthy levels.'
1765     },
1766
1767     'system.forks': {
1768         colors: '#5555DD',
1769         info: 'The number of new processes created per second, read from <code>/proc/stat</code>.'
1770     },
1771
1772     'system.intr': {
1773         colors: '#DD5555',
1774         info: 'Total number of CPU interrupts, read from <code>/proc/stat</code>. Check <code>system.interrupts</code> that gives more detail about each interrupt and also the <a href="#cpu">CPUs</a> section where interrupts are analyzed per CPU core.'
1775     },
1776
1777     'system.interrupts': {
1778         info: 'CPU interrupts in detail, read from <code>/proc/interrupts</code>. At the <a href="#cpu">CPUs</a> section, interrupts are analyzed per CPU core.'
1779     },
1780
1781     'system.softirqs': {
1782         info: 'CPU softirqs in detail, read from <code>/proc/softirqs</code>. At the <a href="#cpu">CPUs</a> section, softirqs are analyzed per CPU core.'
1783     },
1784
1785     'system.processes': {
1786         info: 'System processes, read from <code>/proc/stat</code>. <b>Running</b> are the processes in the CPU. <b>Blocked</b> are processes that are willing to enter the CPU, but they cannot, e.g. because they wait for disk activity.'
1787     },
1788
1789     'system.active_processes': {
1790         info: 'All system processes, read from <code>/proc/loadavg</code>.'
1791     },
1792
1793     'system.ctxt': {
1794         info: '<a href="https://en.wikipedia.org/wiki/Context_switch" target="_blank">Context Switches</a>, read from <code>/proc/stat</code>, is the switching of the CPU from one process, task or thread to another. If there are many processes or threads willing to execute and very few CPU cores available to handle them, the system is making more context switching to balance the CPU resources among them. The whole process is computationally intensive. The more the context switches, the slower the system gets.'
1795     },
1796
1797     'system.idlejitter': {
1798         colors: '#5555AA',
1799         info: 'Idle jitter is calculated by netdata. A thread is spawned that requests to sleep for a few microseconds. When the system wakes it up, it measures how many microseconds have passed. The difference between the requested and the actual duration of the sleep, is the <b>idle jitter</b>. This number is useful in real-time environments, where CPU jitter can affect the quality of the service (like VoIP media gateways).'
1800     },
1801
1802     'system.ipv4': {
1803         info: 'Total IPv4 Traffic, read from <code>/proc/net/netstat</code>.'
1804     },
1805
1806     'system.ipv6': {
1807         info: 'Total IPv6 Traffic, read from <code>/proc/net/snmp6</code>.'
1808     },
1809
1810     'system.ram': {
1811         info: 'System memory, read from <code>/proc/meminfo</code>.'
1812     },
1813
1814     'system.swap': {
1815         info: 'System swap memory, read from <code>/proc/meminfo</code>.'
1816     },
1817
1818     // ------------------------------------------------------------------------
1819     // MEMORY
1820
1821     'mem.ksm_savings': {
1822         heads: [
1823             gaugeChart('Saved', '12%', 'savings', '#0099CC')
1824         ]
1825     },
1826
1827     'mem.ksm_ratios': {
1828         heads: [
1829             function(id) {
1830                 return  '<div data-netdata="' + id + '"'
1831                     + ' data-gauge-max-value="100"'
1832                     + ' data-chart-library="gauge"'
1833                     + ' data-title="Savings"'
1834                     + ' data-units="percentage %"'
1835                     + ' data-gauge-adjust="width"'
1836                     + ' data-width="12%"'
1837                     + ' data-before="0"'
1838                     + ' data-after="-CHART_DURATION"'
1839                     + ' data-points="CHART_DURATION"'
1840                     + ' role="application"></div>';
1841             }
1842         ]
1843     },
1844
1845     'mem.committed': {
1846         colors: NETDATA.colors[3]
1847     },
1848
1849     // ------------------------------------------------------------------------
1850     // APPS
1851
1852     'apps.cpu': {
1853         height: 2.0
1854     },
1855
1856     'apps.preads': {
1857         height: 2.0
1858     },
1859
1860     'apps.pwrites': {
1861         height: 2.0
1862     },
1863
1864     // ------------------------------------------------------------------------
1865     // USERS
1866
1867     'users.cpu': {
1868         height: 2.0
1869     },
1870
1871     'users.preads': {
1872         height: 2.0
1873     },
1874
1875     'users.pwrites': {
1876         height: 2.0
1877     },
1878
1879     // ------------------------------------------------------------------------
1880     // GROUPS
1881
1882     'groups.cpu': {
1883         height: 2.0
1884     },
1885
1886     'groups.preads': {
1887         height: 2.0
1888     },
1889
1890     'groups.pwrites': {
1891         height: 2.0
1892     },
1893
1894     // ------------------------------------------------------------------------
1895     // NETWORK QoS
1896
1897     'tc.qos': {
1898         heads: [
1899             function(id) {
1900                 if(id.match(/.*-ifb$/))
1901                     return gaugeChart('Inbound', '12%', '', '#5555AA');
1902                 else
1903                     return gaugeChart('Outbound', '12%', '', '#AA9900');
1904             }
1905         ]
1906     },
1907
1908     // ------------------------------------------------------------------------
1909     // NETWORK INTERFACES
1910
1911     'net.net': {
1912         heads: [
1913             gaugeChart('Received', '12%', 'received'),
1914             gaugeChart('Sent', '12%', 'sent')
1915         ]
1916     },
1917
1918     // ------------------------------------------------------------------------
1919     // NETFILTER
1920
1921     'netfilter.sockets': {
1922         colors: '#88AA00',
1923         heads: [
1924             gaugeChart('Active Connections', '12%', '', '#88AA00')
1925         ]
1926     },
1927
1928     'netfilter.new': {
1929         heads: [
1930             gaugeChart('New Connections', '12%', 'new', '#5555AA')
1931         ]
1932     },
1933
1934     // ------------------------------------------------------------------------
1935     // DISKS
1936
1937     'disk.util': {
1938         colors: '#FF5588',
1939         heads: [
1940             gaugeChart('Utilization', '12%', '', '#FF5588')
1941         ],
1942         info: 'Disk Utilization measures the amount of time the disk was busy with something. This is not related to its performance. 100% means that the Linux kernel always had an outstanding operation on the disk. Keep in mind that depending on the underlying technology of the disk, 100% here may or may not be an indication of congestion.'
1943     },
1944
1945     'disk.backlog': {
1946         colors: '#0099CC',
1947         info: 'Backlog is an indication of the duration of pending disk operations. On every I/O event the Linux kernel is multiplying the time spent doing I/O since the last update of this field with the number of pending operations. While not accurate, this metric can provide an indication of the expected completion time of the operations in progress.'
1948     },
1949
1950     'disk.io': {
1951         heads: [
1952             gaugeChart('Read', '12%', 'reads'),
1953             gaugeChart('Write', '12%', 'writes')
1954         ],
1955         info: 'Amount of data transferred to and from disk.'
1956     },
1957
1958     'disk.ops': {
1959         info: 'Completed disk I/O operations. Keep in mind the number of operations requested might be higher, since the Linux kernel is able to merge adjacent to each other (see merged operations chart).'
1960     },
1961
1962     'disk.qops': {
1963         info: 'I/O operations currently in progress. This metric is a snapshot - it is not an average over the last interval.'
1964     },
1965
1966     'disk.iotime': {
1967         height: 0.5,
1968         info: 'The sum of the duration of all completed I/O operations. This number can exceed the interval if the disk is able to execute I/O operations in parallel.'
1969     },
1970     'disk.mops': {
1971         height: 0.5,
1972         info: 'The number of merged disk operations. The Linux kernel is able to merge adjacent I/O operations, for example two 4KB reads can become one 8KB read before given to disk.'
1973     },
1974     'disk.svctm': {
1975         height: 0.5,
1976         info: 'The average service time for completed I/O operations. This metric is calculated using the total busy time of the disk and the number of completed operations. If the disk is able to execute multiple parallel operations the reporting average service time will be misleading.'
1977     },
1978     'disk.avgsz': {
1979         height: 0.5,
1980         info: 'The average I/O operation size.'
1981     },
1982     'disk.await': {
1983         height: 0.5,
1984         info: 'The average time for I/O requests issued to the device to be served. This includes the time spent by the requests in queue and the time spent servicing them.'
1985     },
1986
1987     'disk.space': {
1988         info: 'Disk space utilization. reserved for root is automatically reserved by the system to prevent the root user from getting out of space.'
1989     },
1990     'disk.inodes': {
1991         info: 'inodes (or index nodes) are filesystem objects (e.g. files and directories). On many types of file system implementations, the maximum number of inodes is fixed at filesystem creation, limiting the maximum number of files the filesystem can hold. It is possible for a device to run out of inodes. When this happens, new files cannot be created on the device, even though there may be free space available.'
1992     },
1993
1994     'mysql.net': {
1995         info: 'The amount of data sent to mysql clients (<strong>out</strong>) and received from mysql clients (<strong>in</strong>).'
1996     },
1997
1998     // ------------------------------------------------------------------------
1999     // MYSQL
2000
2001     'mysql.queries': {
2002         info: 'The number of statements executed by the server.<ul>' +
2003         '<li><strong>queries</strong> counts the statements executed within stored SQL programs.</li>' +
2004         '<li><strong>questions</strong> counts the statements sent to the mysql server by mysql clients.</li>' +
2005         '<li><strong>slow queries</strong> counts the number of statements that took more than <a href="http://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html#sysvar_long_query_time" target="_blank">long_query_time</a> seconds to be executed.' +
2006         ' For more information about slow queries check the mysql <a href="http://dev.mysql.com/doc/refman/5.7/en/slow-query-log.html" target="_blank">slow query log</a>.</li>' +
2007         '</ul>'
2008     },
2009
2010     'mysql.handlers': {
2011         info: 'Usage of the internal handlers of mysql. This chart provides very good insights of what the mysql server is actually doing.' +
2012         ' (if the chart is not showing all these dimensions it is because they are zero - set <strong>Which dimensions to show?</strong> to <strong>All</strong> from the dashboard settings, to render even the zero values)<ul>' +
2013         '<li><strong>commit</strong>, the number of internal <a href="http://dev.mysql.com/doc/refman/5.7/en/commit.html" target="_blank">COMMIT</a> statements.</li>' +
2014         '<li><strong>delete</strong>, the number of times that rows have been deleted from tables.</li>' +
2015         '<li><strong>prepare</strong>, a counter for the prepare phase of two-phase commit operations.</li>' +
2016         '<li><strong>read first</strong>, the number of times the first entry in an index was read. A high value suggests that the server is doing a lot of full index scans; e.g. <strong>SELECT col1 FROM foo</strong>, with col1 indexed.</li>' +
2017         '<li><strong>read key</strong>, the number of requests to read a row based on a key. If this value is high, it is a good indication that your tables are properly indexed for your queries.</li>' +
2018         '<li><strong>read next</strong>, the number of requests to read the next row in key order. This value is incremented if you are querying an index column with a range constraint or if you are doing an index scan.</li>' +
2019         '<li><strong>read prev</strong>, the number of requests to read the previous row in key order. This read method is mainly used to optimize <strong>ORDER BY ... DESC</strong>.</li>' +
2020         '<li><strong>read rnd</strong>, the number of requests to read a row based on a fixed position. A high value indicates you are doing a lot of queries that require sorting of the result. You probably have a lot of queries that require MySQL to scan entire tables or you have joins that do not use keys properly.</li>' +
2021         '<li><strong>read rnd next</strong>, the number of requests to read the next row in the data file. This value is high if you are doing a lot of table scans. Generally this suggests that your tables are not properly indexed or that your queries are not written to take advantage of the indexes you have.</li>' +
2022         '<li><strong>rollback</strong>, the number of requests for a storage engine to perform a rollback operation.</li>' +
2023         '<li><strong>savepoint</strong>, the number of requests for a storage engine to place a savepoint.</li>' +
2024         '<li><strong>savepoint rollback</strong>, the number of requests for a storage engine to roll back to a savepoint.</li>' +
2025         '<li><strong>update</strong>, the number of requests to update a row in a table.</li>' +
2026         '<li><strong>write</strong>, the number of requests to insert a row in a table.</li>' +
2027         '</ul>'
2028     },
2029
2030     'mysql.table_locks': {
2031         info: 'MySQL table locks counters: <ul>' +
2032         '<li><strong>immediate</strong>, the number of times that a request for a table lock could be granted immediately.</li>' +
2033         '<li><strong>waited</strong>, the number of times that a request for a table lock could not be granted immediately and a wait was needed. If this is high and you have performance problems, you should first optimize your queries, and then either split your table or tables or use replication.</li>' +
2034         '</ul>'
2035     },
2036
2037     // ------------------------------------------------------------------------
2038     // APACHE
2039
2040     'apache.connections': {
2041         colors: NETDATA.colors[4],
2042         mainheads: [
2043             gaugeChart('Connections', '12%', '', NETDATA.colors[4])
2044         ]
2045     },
2046
2047     'apache.requests': {
2048         colors: NETDATA.colors[0],
2049         mainheads: [
2050             gaugeChart('Requests', '12%', '', NETDATA.colors[0])
2051         ]
2052     },
2053
2054     'apache.net': {
2055         colors: NETDATA.colors[3],
2056         mainheads: [
2057             gaugeChart('Bandwidth', '12%', '', NETDATA.colors[3])
2058         ]
2059     },
2060
2061     'apache.workers': {
2062         mainheads: [
2063             function(id) {
2064                 return  '<div data-netdata="' + id + '"'
2065                     + ' data-dimensions="busy"'
2066                     + ' data-append-options="percentage"'
2067                     + ' data-gauge-max-value="100"'
2068                     + ' data-chart-library="gauge"'
2069                     + ' data-title="Workers Utilization"'
2070                     + ' data-units="percentage %"'
2071                     + ' data-gauge-adjust="width"'
2072                     + ' data-width="12%"'
2073                     + ' data-before="0"'
2074                     + ' data-after="-CHART_DURATION"'
2075                     + ' data-points="CHART_DURATION"'
2076                     + ' role="application"></div>';
2077             }
2078         ]
2079     },
2080
2081     'apache.bytesperreq': {
2082         colors: NETDATA.colors[3],
2083         height: 0.5
2084     },
2085
2086     'apache.reqpersec': {
2087         colors: NETDATA.colors[4],
2088         height: 0.5
2089     },
2090
2091     'apache.bytespersec': {
2092         colors: NETDATA.colors[6],
2093         height: 0.5
2094     },
2095
2096
2097     // ------------------------------------------------------------------------
2098     // NGINX
2099
2100     'nginx.connections': {
2101         colors: NETDATA.colors[4],
2102         mainheads: [
2103             gaugeChart('Connections', '12%', '', NETDATA.colors[4])
2104         ]
2105     },
2106
2107     'nginx.requests': {
2108         colors: NETDATA.colors[0],
2109         mainheads: [
2110             gaugeChart('Requests', '12%', '', NETDATA.colors[0])
2111         ]
2112     },
2113
2114     // ------------------------------------------------------------------------
2115     // NETDATA
2116
2117     'netdata.response_time': {
2118         info: 'The netdata API response time measures the time netdata needed to serve requests. This time includes everything, from the reception of the first byte of a request, to the dispatch of the last byte of its reply, therefore it includes all network latencies involved (i.e. a client over a slow network will influence these metrics).'
2119     },
2120
2121     // ------------------------------------------------------------------------
2122     // RETROSHARE
2123     'retroshare.bandwidth': {
2124         info: 'Shows inbound and outbound traffic.',
2125         mainheads: [
2126             gaugeChart('Received', '12%', 'bandwidth_down_kb'),
2127             gaugeChart('Sent', '12%', 'bandwidth_up_kb')
2128         ]
2129     },
2130
2131     'retroshare.peers': {
2132         info: 'Shows the number of (connected) friends.',
2133         mainheads: [
2134             function(id) {
2135                 return  '<div data-netdata="' + id + '"'
2136                     + ' data-dimensions="peers_connected"'
2137                     + ' data-append-options="friends"'
2138                     + ' data-chart-library="easypiechart"'
2139                     + ' data-title="connected friends"'
2140                     + ' data-units=""'
2141                     + ' data-width="8%"'
2142                     + ' data-before="0"'
2143                     + ' data-after="-CHART_DURATION"'
2144                     + ' data-points="CHART_DURATION"'
2145                     + ' role="application"></div>';
2146             }
2147         ]
2148     },
2149
2150     'retroshare.dht': {
2151         info: 'Shows statistics about RetroShare\'s DHT. These values are estimated!'
2152     }
2153 };
2154
2155 function anyAttribute(obj, attr, key, def) {
2156     if(typeof obj[key] !== 'undefined') {
2157         if(typeof obj[key][attr] !== 'undefined')
2158             return obj[key][attr];
2159     }
2160     return def;
2161 }
2162
2163 function menuTitle(chart) {
2164     if(typeof chart.menu_pattern !== 'undefined') {
2165         return (anyAttribute(menuData, 'title', chart.menu_pattern, chart.menu_pattern).toString()
2166                 + '&nbsp;' + chart.type.slice(-(chart.type.length - chart.menu_pattern.length - 1)).toString()).replace(/_/g, ' ');
2167     }
2168
2169     return (anyAttribute(menuData, 'title', chart.menu, chart.menu)).toString().replace(/_/g, ' ');
2170 }
2171
2172 function menuIcon(chart) {
2173     if(typeof chart.menu_pattern !== 'undefined')
2174         return anyAttribute(menuData, 'icon', chart.menu_pattern, '<i class="fa fa-puzzle-piece" aria-hidden="true"></i>').toString();
2175
2176     return anyAttribute(menuData, 'icon', chart.menu, '<i class="fa fa-puzzle-piece" aria-hidden="true"></i>');
2177 }
2178
2179 function menuInfo(menu) {
2180     return anyAttribute(menuData, 'info', menu, null);
2181 }
2182
2183 function menuHeight(menu, relative) {
2184     return anyAttribute(menuData, 'height', menu, 1.0) * relative;
2185 }
2186
2187 function submenuTitle(menu, submenu) {
2188     var key = menu + '.' + submenu;
2189     var title = anyAttribute(submenuData, 'title', key, submenu).toString().replace(/_/g, ' ');;
2190     if(title.length > 28) {
2191         var a = title.substring(0, 13);
2192         var b = title.substring(title.length - 12, title.length);
2193         return a + '...' + b;
2194     }
2195     return title;
2196 }
2197
2198 function submenuInfo(menu, submenu) {
2199     var key = menu + '.' + submenu;
2200     return anyAttribute(submenuData, 'info', key, null);
2201 }
2202
2203 function submenuHeight(menu, submenu, relative) {
2204     var key = menu + '.' + submenu;
2205     return anyAttribute(submenuData, 'height', key, 1.0) * relative;
2206 }
2207
2208
2209 function chartInfo(id) {
2210     if(typeof chartData[id] !== 'undefined' && typeof chartData[id].info !== 'undefined')
2211         return '<div class="chart-message netdata-chart-alignment" role="document">' + chartData[id].info + '</div>';
2212     else
2213         return '';
2214 }
2215
2216 function chartHeight(id, def) {
2217     if(typeof chartData[id] !== 'undefined' && typeof chartData[id].height !== 'undefined')
2218         return def * chartData[id].height;
2219     else
2220         return def;
2221 }
2222
2223
2224 // ----------------------------------------------------------------------------
2225
2226 // enrich the data structure returned by netdata
2227 // to reflect our menu system and content
2228 function enrichChartData(chart) {
2229     var tmp = chart.type.split('_')[0];
2230
2231     switch(tmp) {
2232         case 'ap':
2233         case 'net':
2234         case 'disk':
2235             chart.menu = tmp;
2236             break;
2237
2238         case 'cgroup':
2239             chart.menu = chart.type;
2240             if(chart.id.match(/.*[\._\/-:]qemu[\._\/-:]*/) || chart.id.match(/.*[\._\/-:]kvm[\._\/-:]*/))
2241                 chart.menu_pattern = 'cgqemu';
2242             else
2243                 chart.menu_pattern = 'cgroup';
2244             break;
2245
2246         case 'apache':
2247         case 'exim':
2248         case 'memcached':
2249         case 'mysql':
2250         case 'named':
2251         case 'nginx':
2252         case 'nut':
2253         case 'phpfpm':
2254         case 'postfix':
2255         case 'redis':
2256         case 'retroshare':
2257         case 'ipfs':
2258         case 'smawebbox':
2259         case 'squid':
2260         case 'snmp':
2261         case 'tomcat':
2262             chart.menu = chart.type;
2263             chart.menu_pattern = tmp;
2264             break;
2265
2266         case 'tc':
2267             chart.menu = tmp;
2268
2269             // find a name for this device from fireqos info
2270             // we strip '_(in|out)' or '(in|out)_'
2271             if(typeof options.submenu_names[chart.family] === 'undefined' || options.submenu_names[chart.family] === chart.family) {
2272                 var n = chart.name.split('.')[1];
2273                 if(n.endsWith('_in'))
2274                     options.submenu_names[chart.family] = n.slice(0, n.lastIndexOf('_in'));
2275                 else if(n.endsWith('_out'))
2276                     options.submenu_names[chart.family] = n.slice(0, n.lastIndexOf('_out'));
2277                 else if(n.startsWith('in_'))
2278                     options.submenu_names[chart.family] = n.slice(3, n.length);
2279                 else if(n.startsWith('out_'))
2280                     options.submenu_names[chart.family] = n.slice(4, n.length);
2281             }
2282
2283             // increase the priority of IFB devices
2284             // to have inbound appear before outbound
2285             if(chart.id.match(/.*-ifb$/))
2286                 chart.priority--;
2287
2288             break;
2289
2290         default:
2291             chart.menu = chart.type;
2292             break;
2293     }
2294
2295     chart.submenu = chart.family;
2296 }
2297
2298 // ----------------------------------------------------------------------------
2299
2300 function name2id(s) {
2301     return s
2302         .replace(/ /g, '_')
2303         .replace(/\(/g, '_')
2304         .replace(/\)/g, '_')
2305         .replace(/\./g, '_')
2306         .replace(/\//g, '_');
2307 }
2308
2309 function headMain(charts, duration) {
2310     var head = '';
2311
2312     if(typeof charts['system.swap'] !== 'undefined')
2313         head += '<div style="margin-right: 10px;" data-netdata="system.swap"'
2314         + ' data-dimensions="free"'
2315         + ' data-append-options="percentage"'
2316         + ' data-chart-library="easypiechart"'
2317         + ' data-title="Free Swap"'
2318         + ' data-units="%"'
2319         + ' data-easypiechart-max-value="100"'
2320         + ' data-width="8%"'
2321         + ' data-before="0"'
2322         + ' data-after="-' + duration.toString() + '"'
2323         + ' data-points="' + duration.toString() + '"'
2324         + ' data-colors="#DD4400"'
2325         + ' role="application"></div>';
2326
2327     if(typeof charts['system.io'] !== 'undefined') {
2328         head += '<div style="margin-right: 10px;" data-netdata="system.io"'
2329         + ' data-dimensions="in"'
2330         + ' data-chart-library="easypiechart"'
2331         + ' data-title="Disk Read"'
2332         + ' data-width="10%"'
2333         + ' data-before="0"'
2334         + ' data-after="-' + duration.toString() + '"'
2335         + ' data-points="' + duration.toString() + '"'
2336         + ' role="application"></div>';
2337
2338         head += '<div style="margin-right: 10px;" data-netdata="system.io"'
2339         + ' data-dimensions="out"'
2340         + ' data-chart-library="easypiechart"'
2341         + ' data-title="Disk Write"'
2342         + ' data-width="10%"'
2343         + ' data-before="0"'
2344         + ' data-after="-' + duration.toString() + '"'
2345         + ' data-points="' + duration.toString() + '"'
2346         + ' role="application"></div>';
2347     }
2348
2349     if(typeof charts['system.cpu'] !== 'undefined')
2350         head += '<div data-netdata="system.cpu"'
2351         + ' data-chart-library="gauge"'
2352         + ' data-title="CPU"'
2353         + ' data-units="%"'
2354         + ' data-gauge-max-value="100"'
2355         + ' data-width="18%"'
2356         + ' data-after="-' + duration.toString() + '"'
2357         + ' data-points="' + duration.toString() + '"'
2358         + ' data-colors="' + NETDATA.colors[12] + '"'
2359         + ' role="application"></div>';
2360
2361     if(typeof charts['system.ipv4'] !== 'undefined') {
2362         head += '<div style="margin-right: 10px;" data-netdata="system.ipv4"'
2363         + ' data-dimensions="received"'
2364         + ' data-chart-library="easypiechart"'
2365         + ' data-title="IPv4 Inbound"'
2366         + ' data-width="10%"'
2367         + ' data-before="0"'
2368         + ' data-after="-' + duration.toString() + '"'
2369         + ' data-points="' + duration.toString() + '"'
2370         + ' role="application"></div>';
2371
2372         head += '<div style="margin-right: 10px;" data-netdata="system.ipv4"'
2373         + ' data-dimensions="sent"'
2374         + ' data-chart-library="easypiechart"'
2375         + ' data-title="IPv4 Outbound"'
2376         + ' data-width="10%"'
2377         + ' data-before="0"'
2378         + ' data-after="-' + duration.toString() + '"'
2379         + ' data-points="' + duration.toString() + '"'
2380         + ' role="application"></div>';
2381     }
2382     else if(typeof charts['system.ipv6'] !== 'undefined') {
2383         head += '<div style="margin-right: 10px;" data-netdata="system.ipv6"'
2384         + ' data-dimensions="received"'
2385         + ' data-chart-library="easypiechart"'
2386         + ' data-title="IPv6 Inbound"'
2387         + ' data-units="kbps"'
2388         + ' data-width="10%"'
2389         + ' data-before="0"'
2390         + ' data-after="-' + duration.toString() + '"'
2391         + ' data-points="' + duration.toString() + '"'
2392         + ' role="application"></div>';
2393
2394         head += '<div style="margin-right: 10px;" data-netdata="system.ipv6"'
2395         + ' data-dimensions="sent"'
2396         + ' data-chart-library="easypiechart"'
2397         + ' data-title="IPv6 Outbound"'
2398         + ' data-units="kbps"'
2399         + ' data-width="10%"'
2400         + ' data-before="0"'
2401         + ' data-after="-' + duration.toString() + '"'
2402         + ' data-points="' + duration.toString() + '"'
2403         + ' role="application"></div>';
2404     }
2405
2406     if(typeof charts['system.ram'] !== 'undefined')
2407         head += '<div style="margin-right: 10px;" data-netdata="system.ram"'
2408         + ' data-dimensions="cached|free"'
2409         + ' data-append-options="percentage"'
2410         + ' data-chart-library="easypiechart"'
2411         + ' data-title="Available RAM"'
2412         + ' data-units="%"'
2413         + ' data-easypiechart-max-value="100"'
2414         + ' data-width="8%"'
2415         + ' data-after="-' + duration.toString() + '"'
2416         + ' data-points="' + duration.toString() + '"'
2417         + ' data-colors="' + NETDATA.colors[7] + '"'
2418         + ' role="application"></div>';
2419
2420     return head;
2421 }
2422
2423 function generateHeadCharts(type, chart, duration) {
2424     var head = '';
2425     var hcharts = anyAttribute(chartData, type, chart.context, []);
2426     if(hcharts.length > 0) {
2427         var hi = 0, hlen = hcharts.length;
2428         while(hi < hlen) {
2429             if(typeof hcharts[hi] === 'function')
2430                 head += hcharts[hi](chart.id).replace('CHART_DURATION', duration.toString()).replace('CHART_UNIQUE_ID', chart.id);
2431             else
2432                 head += hcharts[hi].replace('CHART_DURATION', duration.toString()).replace('CHART_UNIQUE_ID', chart.id);
2433             hi++;
2434         }
2435     }
2436     return head;
2437 }
2438
2439 function renderPage(menus, data) {
2440     var div = document.getElementById('charts_div');
2441     var pcent_width = Math.floor(100 / chartsPerRow($(div).width()));
2442
2443     // find the proper duration for per-second updates
2444     var duration = Math.round(($(div).width() * pcent_width / 100 * data.update_every / 3) / 60) * 60;
2445     var html = '';
2446     var sidebar = '<ul class="nav dashboard-sidenav" data-spy="affix" id="sidebar_ul">';
2447     var mainhead = headMain(data.charts, duration);
2448
2449     // sort the menus
2450     var main = sortObjectByPriority(menus);
2451     var i = 0, len = main.length;
2452     while(i < len) {
2453         var menu = main[i++];
2454
2455         // generate an entry at the main menu
2456
2457         var menuid = name2id(menu);
2458         sidebar += '<li class=""><a href="#' + menuid + '" onClick="return scrollToId(\'' + menuid + '\');">' + menus[menu].icon + ' ' + menus[menu].title + '</a><ul class="nav">';
2459         html += '<div role="section"><div role="sectionhead"><h1 id="' + menuid + '" role="heading">' + menus[menu].title + '</h1></div><div id="menu_' + menuid + '" role="document">';
2460
2461         if(menus[menu].info !== null)
2462             html += menus[menu].info;
2463
2464         // console.log(' >> ' + menu + ' (' + menus[menu].priority + '): ' + menus[menu].title);
2465
2466         var shtml = '';
2467         var mhead = '<div class="netdata-chart-row">' + mainhead;
2468         mainhead = '';
2469
2470         // sort the submenus of this menu
2471         var sub = sortObjectByPriority(menus[menu].submenus);
2472         var si = 0, slen = sub.length;
2473         while(si < slen) {
2474             var submenu = sub[si++];
2475
2476             // generate an entry at the submenu
2477             var submenuid = name2id(menu + '_' + submenu);
2478             sidebar += '<li class><a href="#' + submenuid + '" onClick="return scrollToId(\'' + submenuid + '\');">' + menus[menu].submenus[submenu].title + '</a></li>';
2479             shtml += '<div class="netdata-group-container" id="submenu_' + submenuid + '" style="display: inline-block; width: ' + pcent_width.toString() + '%"><h2 id="' + submenuid + '" class="netdata-chart-alignment" role="heading">' + menus[menu].submenus[submenu].title + '</h2>';
2480
2481             if(menus[menu].submenus[submenu].info !== null)
2482                 shtml += '<div class="chart-message netdata-chart-alignment" role="document">' + menus[menu].submenus[submenu].info + '</div>';
2483
2484             var head = '<div class="netdata-chart-row">';
2485             var chtml = '';
2486
2487             // console.log('    \------- ' + submenu + ' (' + menus[menu].submenus[submenu].priority + '): ' + menus[menu].submenus[submenu].title);
2488
2489             // sort the charts in this submenu of this menu
2490             menus[menu].submenus[submenu].charts.sort(prioritySort);
2491             var ci = 0, clen = menus[menu].submenus[submenu].charts.length;
2492             while(ci < clen) {
2493                 var chart = menus[menu].submenus[submenu].charts[ci++];
2494
2495                 // generate the submenu heading charts
2496                 mhead += generateHeadCharts('mainheads', chart, duration);
2497                 head += generateHeadCharts('heads', chart, duration);
2498
2499                 // generate the chart
2500                 chtml += chartInfo(chart.context) + '<div data-netdata="' + chart.id + '"'
2501                     + ' data-width="' + pcent_width.toString() + '%"'
2502                     + ' data-height="' + chartHeight(chart.context, options.chartsHeight).toString() + 'px"'
2503                     + ' data-before="0"'
2504                     + ' data-after="-' + duration.toString() + '"'
2505                     + ' data-id="' + name2id(options.hostname + '/' + chart.id) + '"'
2506                     + ' data-colors="' + anyAttribute(chartData, 'colors', chart.context, '') + '"'
2507                     + ' role="application"></div>';
2508
2509                 // console.log('         \------- ' + chart.id + ' (' + chart.priority + '): ' + chart.context  + ' height: ' + menus[menu].submenus[submenu].height);
2510             }
2511
2512             head += '</div>';
2513             shtml += head + chtml + '</div>';
2514         }
2515
2516         mhead += '</div>';
2517         sidebar += '</ul></li>';
2518         html += mhead + shtml + '</div></div><hr role="separator"/>';
2519     }
2520
2521     sidebar += '</ul>';
2522     div.innerHTML = html;
2523     document.getElementById('sidebar').innerHTML = sidebar;
2524     finalizePage();
2525 }
2526
2527 function renderChartsAndMenu(data) {
2528     var menus = options.menus;
2529     var charts = data.charts;
2530
2531     for(var c in charts) {
2532         enrichChartData(charts[c]);
2533
2534         // create the menu
2535         if(typeof menus[charts[c].menu] === 'undefined') {
2536             menus[charts[c].menu] = {
2537                 priority: charts[c].priority,
2538                 submenus: {},
2539                 title: menuTitle(charts[c]),
2540                 icon: menuIcon(charts[c]),
2541                 info: menuInfo(charts[c].menu),
2542                 height: menuHeight(charts[c].menu, options.chartsHeight)
2543             };
2544         }
2545
2546         if(charts[c].priority < menus[charts[c].menu].priority)
2547             menus[charts[c].menu].priority = charts[c].priority;
2548
2549         // create the submenu
2550         if(typeof menus[charts[c].menu].submenus[charts[c].submenu] === 'undefined') {
2551             menus[charts[c].menu].submenus[charts[c].submenu] = {
2552                 priority: charts[c].priority,
2553                 charts: new Array(),
2554                 title: null,
2555                 info: submenuInfo(charts[c].menu, charts[c].submenu),
2556                 height: submenuHeight(charts[c].menu, charts[c].submenu, menus[charts[c].menu].height)
2557             };
2558         }
2559
2560         if(charts[c].priority < menus[charts[c].menu].submenus[charts[c].submenu].priority)
2561             menus[charts[c].menu].submenus[charts[c].submenu].priority = charts[c].priority;
2562
2563         // index the chart in the menu/submenu
2564         menus[charts[c].menu].submenus[charts[c].submenu].charts.push(charts[c]);
2565
2566         // console.log(urlOptions.chart + ' === ' + c);
2567         if(urlOptions.chart === c) {
2568             urlOptions.hash = '#' + name2id(charts[c].menu + '_' + charts[c].submenu)
2569             // console.log('hash = ' + urlOptions.hash);
2570         }
2571     }
2572
2573     // propagate the descriptive subname given to QoS
2574     // to all the other submenus with the same name
2575     for(var m in menus) {
2576         for(var s in menus[m].submenus) {
2577             // set the family using a name
2578             if(typeof options.submenu_names[s] !== 'undefined') {
2579                 menus[m].submenus[s].title = s + ' (' + options.submenu_names[s] + ')';
2580             }
2581             else {
2582                 menus[m].submenus[s].title = submenuTitle(m, s);
2583             }
2584         }
2585     }
2586
2587     renderPage(menus, data);
2588 }
2589
2590 // ----------------------------------------------------------------------------
2591
2592 function alarmsUpdateModal() {
2593     var active = '<h3>Raised Alarms</h3><table class="table">';
2594     var all = '<h3>All Running Alarms</h3><div class="panel-group" id="alarms_all_accordion" role="tablist" aria-multiselectable="true">';
2595     var log = '<h3>Alarm Log</h3><table class="table"><tr><th>When</th><th>Chart</th><th>Alarm</th><th>Status</th>';
2596     var footer = '<hr/><a href="https://github.com/firehol/netdata/wiki/Generating-Badges" target="_blank">netdata badges</a> refresh automatically. Their color indicates the state of the alarm: <span style="color: #e05d44"><b>&nbsp;red&nbsp;</b></span> is critical, <span style="color:#fe7d37"><b>&nbsp;orange&nbsp;</b></span> is warning, <span style="color: #4c1"><b>&nbsp;bright green&nbsp;</b></span> is ok, <span style="color: #9f9f9f"><b>&nbsp;light grey&nbsp;</b></span> is undefined (i.e. no data or no status), <span style="color: #000"><b>&nbsp;black&nbsp;</b></span> is not initialized. You can copy and paste their URLs to embed them in any web page.';
2597
2598     NETDATA.alarms.get('all', function(data) {
2599         options.alarm_families = new Array();
2600
2601         alarmsCallback(data);
2602
2603         if(data === null) {
2604             document.getElementById('alarms_active').innerHTML =
2605                     document.getElementById('alarms_all').innerHTML =
2606                             document.getElementById('alarms_log').innerHTML =
2607                                     'failed to load alarm data!';
2608             return;
2609         }
2610
2611         function frequency_text(seconds, sfx) {
2612             if(seconds === 0)
2613                 return 'now';
2614
2615             var suffix = '';
2616             if(seconds < 0) {
2617                 seconds = -seconds;
2618                 if(sfx) suffix = '&nbsp;ago';
2619             }
2620
2621             var hours = Math.floor(seconds / 3600);
2622             seconds -= (hours * 3600);
2623
2624             var minutes = Math.floor(seconds / 60);
2625             seconds -= (minutes * 60);
2626
2627             var txt = '';
2628             
2629             if(hours > 1) txt += hours.toString() + '&nbsp;hours';
2630             else if(hours === 1) txt += hours.toString() + '&nbsp;hour';
2631
2632             if(hours > 0 && minutes > 0 && seconds == 0)
2633                 txt += '&nbsp;and&nbsp;';
2634             else if(hours > 0 && minutes > 0 && seconds > 0)
2635                 txt += ',&nbsp;';
2636
2637             if(minutes > 1) txt += minutes.toString() + '&nbsp;minutes';
2638             else if(minutes === 1) txt += minutes.toString() + '&nbsp;minute';
2639
2640             if((minutes > 0 || minutes > 0) && seconds > 0)
2641                 txt += '&nbsp;and&nbsp;';
2642
2643             if(seconds > 1) txt += seconds.toString() + '&nbsp;seconds';
2644             else if(seconds === 1) txt += seconds.toString() + '&nbsp;second';
2645
2646             return txt + suffix;
2647         }
2648
2649         function alarm_lookup_explain(alarm, chart) {
2650             var dimensions = ' of all values ';
2651
2652             if(chart.dimensions.length > 1)
2653                 dimensions = ' of the sum of all dimensions ';
2654
2655             if(typeof alarm.lookup_dimensions !== 'undefined') {
2656                 var d = alarm.lookup_dimensions.replace('|', ',');
2657                 var x = d.split(',');
2658                 if(x.length > 1)
2659                     dimensions = 'of the sum of dimensions <code>' + alarm.lookup_dimensions + '</code> ';
2660                 else
2661                     dimensions = 'of all values of dimension <code>' + alarm.lookup_dimensions + '</code> ';
2662             }
2663
2664             return '<code>' + alarm.lookup_method + '</code> '
2665                 + dimensions + ', of chart <code>' + alarm.chart + '</code>'
2666                 + ', starting <code>' + frequency_text(alarm.lookup_after + alarm.lookup_before, true) + '</code> and up to <code>' + frequency_text(alarm.lookup_before, true) + '</code>'
2667                 + ((alarm.lookup_options)?(', with options <code>' + alarm.lookup_options.replace(' ', ',&nbsp;') + '</code>'):'')
2668                 + '.';
2669         }
2670
2671         function alarm_to_html(alarm, full) {
2672             var chart = options.data.charts[alarm.chart];
2673
2674             var html = '<tr><td class="text-center" style="vertical-align:middle" width="40%"><b>' + alarm.chart + '</b><br/>&nbsp;<br/><embed src="' + NETDATA.alarms.server + '/api/v1/badge.svg?chart=' + alarm.chart + '&alarm=' + alarm.name + '&refresh=auto" type="image/svg+xml" height="20" /><br/>&nbsp;<br/><span style="font-size: 18px">' + alarm.info + '</span><br/>&nbsp;<br/>role: <b>' + alarm.recipient + '</b></td>'
2675                 + '<td><table class="table">'
2676                 + ((typeof alarm.warn !== 'undefined')?('<tr><td width="10%" style="text-align:right">warning&nbsp;when</td><td><span style="font-family: monospace; color:#fe7d37; font-weight: bold;">' + alarm.warn + '</span></td></tr>'):'')
2677                 + ((typeof alarm.crit !== 'undefined')?('<tr><td width="10%" style="text-align:right">critical&nbsp;when</td><td><span style="font-family: monospace; color: #e05d44; font-weight: bold;">' + alarm.crit + '</span></td></tr>'):'');
2678
2679             if(full === true) {
2680                     html += ((typeof alarm.lookup_after !== 'undefined')?('<tr><td width="10%" style="text-align:right">db&nbsp;lookup</td><td>' + alarm_lookup_explain(alarm, chart) + '</td></tr>'):'')
2681                     + ((typeof alarm.calc !== 'undefined')?('<tr><td width="10%" style="text-align:right">calculation</td><td><span style="font-family: monospace;">' + alarm.calc + '</span></td></tr>'):'')
2682                     + ((chart.green !== null)?('<tr><td width="10%" style="text-align:right">green&nbsp;threshold</td><td><code>' + chart.green + ' ' + chart.units + '</code></td></tr>'):'')
2683                     + ((chart.red !== null)?('<tr><td width="10%" style="text-align:right">red&nbsp;threshold</td><td><code>' + chart.red + ' ' + chart.units + '</code></td></tr>'):'');
2684             }
2685
2686             html += '<tr><td width="10%" style="text-align:right">check&nbsp;every</td><td>' + frequency_text(alarm.update_every) + '</td></tr>'
2687                 + '<tr><td width="10%" style="text-align:right">execute</td><td><span style="font-family: monospace;">' + alarm.exec + '</span></td></tr>'
2688                 + '<tr><td width="10%" style="text-align:right">source</td><td><span style="font-family: monospace;">' + alarm.source + '</span></td></tr>'
2689                 + '</table></td></tr>';
2690
2691             return html;
2692         }
2693
2694         function alarm_family_show(id) {
2695             var html = '<table class="table">';
2696             var family = options.alarm_families[id];
2697             var len = family.arr.length;
2698             while(len--) {
2699                 var alarm = family.arr[len];
2700                 html += alarm_to_html(alarm, true);
2701             }
2702             html += '</table>';
2703
2704             $('#alarm_all_' + id.toString()).html(html);
2705         }
2706
2707         // find the proper family of each alarm
2708         var now = new Date().getTime();
2709         var x;
2710         var count_active = 0;
2711         var count_all = 0;
2712         var families = {};
2713         var families_sort = new Array();
2714         for(x in data.alarms) {
2715             var alarm = data.alarms[x];
2716             var family = alarm.family;
2717
2718             // find the chart
2719             var chart = options.data.charts[alarm.chart];
2720             if(typeof chart === 'undefined')
2721                 chart = options.data.charts_by_name[alarm.chart];
2722
2723             // not found - this should never happen!
2724             if(typeof chart === 'undefined') {
2725                 console.log('WARNING: alarm ' + x + ' is linked to chart ' + alarm.chart + ', which is not found in the list of chart got from the server.');
2726                 chart = { priority: 9999999 };
2727             }
2728             else if(typeof chart.menu !== 'undefined' && typeof chart.submenu !== 'undefined')
2729                 // the family based on the chart
2730                 family = chart.menu + ' - ' + chart.submenu;
2731
2732             if(typeof families[family] === 'undefined') {
2733                 families[family] = {
2734                     name: family,
2735                     arr: new Array(),
2736                     priority: chart.priority
2737                 };
2738
2739                 families_sort.push(families[family]);
2740             }
2741
2742             if(chart.priority < families[family].priority)
2743                 families[family].priority = chart.priority;
2744
2745             families[family].arr.push(alarm);
2746         }
2747
2748         // sort the families, like the dashboard menu does
2749         var families_sorted = families_sort.sort(function (a, b) {
2750             if (a.priority > b.priority) return -1;
2751             if (a.priority < b.priority) return 1;
2752             if (a.name < b.name) return 1;
2753             if (a.name > b.name) return -1;
2754             return 0;
2755         });
2756
2757         var fc = 0;
2758         var len = families_sorted.length;
2759         while(len--) {
2760             var family = families_sorted[len].name;
2761             var active_family_added = false;
2762             var expanded = 'true';
2763             var collapsed = '';
2764             var cin = 'in';
2765
2766             if(fc !== 0) {
2767                 all += "</table></div></div></div>";
2768                 expanded = 'false';
2769                 collapsed = 'class="collapsed"'
2770                 cin = '';
2771             }
2772
2773             all += '<div class="panel panel-default"><div class="panel-heading" role="tab" id="alarm_all_heading_' + fc.toString() + '"><h4 class="panel-title"><a ' + collapsed + ' role="button" data-toggle="collapse" data-parent="#alarms_all_accordion" href="#alarm_all_' + fc.toString() + '" aria-expanded="' + expanded + '" aria-controls="alarm_all_' + fc.toString() + '">' + family.toString() + '</a></h4></div><div id="alarm_all_' + fc.toString() + '" class="panel-collapse collapse ' + cin + '" role="tabpanel" aria-labelledby="alarm_all_heading_' + fc.toString() + '" data-alarm-id="' + fc.toString() + '"><div class="panel-body" id="alarm_all_body_' + fc.toString() + '">';
2774
2775             options.alarm_families[fc] = families[family];
2776
2777             fc++;
2778
2779             var arr = families[family].arr;
2780             var c = arr.length;
2781             while(c--) {
2782                 var alarm = arr[c];
2783                 if(alarm.status === 'WARNING' || alarm.status === 'CRITICAL') {
2784                     if(!active_family_added) {
2785                         active_family_added = true;
2786                         active += '<tr><th class="text-center" colspan="2"><h4>' + family + '</h4></th></tr>';
2787                     }
2788                     count_active++;
2789                     active += alarm_to_html(alarm, true);
2790                 }
2791
2792                 count_all++;
2793             }
2794         }
2795         active += "</table>";
2796         if(families_sorted.length > 0) all += "</div></div></div>";
2797         all += "</div>";
2798
2799         if(!count_active)
2800             active += "<h4>Everything is normal. No raised alarms.</h4>";
2801         else
2802             active += footer;
2803
2804         if(!count_all)
2805             all += "<h4>No alarms are running in this system.</h4>";
2806         else
2807             all += footer;
2808
2809         document.getElementById('alarms_active').innerHTML = active;
2810         document.getElementById('alarms_all').innerHTML = all;
2811
2812         if(families_sorted.length > 0) alarm_family_show(0);
2813
2814         // register bootstrap events
2815         $('#alarms_all_accordion').on('show.bs.collapse', function (d) {
2816             var target = $(d.target);
2817             var id = $(target).data('alarm-id');
2818             alarm_family_show(id);
2819         });
2820         $('#alarms_all_accordion').on('hidden.bs.collapse', function (d) {
2821             var target = $(d.target);
2822             var id = $(target).data('alarm-id');
2823             $('#alarm_all_' + id.toString()).html('');
2824         });
2825
2826         NETDATA.alarms.get_log(0, function(data) {
2827             if(data === null) {
2828                 document.getElementById('alarms_log').innerHTML =
2829                         'failed to load alarm data!';
2830                 return;
2831             }
2832
2833             var i = 0;
2834             var len = data.length;
2835             if(len > 50) len = 50;
2836             while(i < len) {
2837                 var time = new Date(data[i].when * 1000);
2838                 log += '<tr><td>'
2839                         + time.toLocaleDateString() + ' '
2840                         + time.toLocaleTimeString() + '</td><td>'
2841                         + data[i].chart.toString() + '</td><td>'
2842                         + data[i].name.toString() + ' = ' + ((data[i].value !== null)?Math.floor(data[i].value):'NaN').toString() + ' ' + data[i].units.toString() + '</td><td>'
2843                         + data[i].status.toString() + '</td></tr>';
2844                 i++;
2845             }
2846             log += "</table>";
2847
2848             if(i == 0)
2849                 log += "<h4>No alarms have been logged in this system.</h4>";
2850
2851             document.getElementById('alarms_log').innerHTML = log;
2852         })
2853     });
2854 }
2855
2856 function alarmsCallback(data) {
2857     var count = 0;
2858     for(x in data.alarms) {
2859         var alarm = data.alarms[x];
2860         if(alarm.status === 'WARNING' || alarm.status === 'CRITICAL')
2861             count++;
2862     }
2863
2864     if(count > 0)
2865         document.getElementById('alarms_count_badge').innerHTML = count.toString();
2866     else
2867         document.getElementById('alarms_count_badge').innerHTML = '';
2868 }
2869
2870 function downloadAllCharts(netdata_url) {
2871     if(typeof netdata_url === 'undefined' || netdata_url === null)
2872         netdata_url = NETDATA.serverDefault;
2873
2874     NETDATA.pause(function() {
2875         $("#loadOverlay").css("display","none");
2876
2877         NETDATA.alarms.callback = alarmsCallback;
2878
2879         // download all the charts the server knows
2880         NETDATA.chartRegistry.downloadAll(netdata_url, function(data) {
2881
2882             if(data !== null) {
2883                 options.hostname = data.hostname;
2884                 options.data = data;
2885
2886                 // create a chart_by_name index
2887                 data.charts_by_name = {};
2888                 var charts = data.charts;
2889                 var x;
2890                 for(x in charts) {
2891                     var chart = charts[x];
2892                     data.charts_by_name[chart.name] = chart;
2893                 }
2894
2895                 // update the dashboard hostname
2896                 document.getElementById('hostname').innerHTML = options.hostname;
2897                 document.getElementById('hostname').href = NETDATA.serverDefault;
2898
2899                 // update the dashboard title
2900                 document.title = options.hostname + ' netdata dashboard';
2901
2902                 // render all charts
2903                 renderChartsAndMenu(data);
2904             }
2905         });
2906     });
2907 }
2908
2909 // ----------------------------------------------------------------------------
2910
2911 function versionLog(msg) {
2912     document.getElementById('versionCheckLog').innerHTML = msg;
2913 }
2914
2915 function getNetdataVersion(callback) {
2916     versionLog('Downloading installed version info from netdata...');
2917
2918     $.ajax({
2919         url: 'version.txt',
2920         async: true,
2921         cache: false
2922     })
2923     .done(function(data) {
2924         data = data.replace(/(\r\n|\n|\r| |\t)/gm,"");
2925         if(data.length !== 40) {
2926             versionLog('Received version string is invalid.');
2927             callback(null);
2928         }
2929         else {
2930             versionLog('Installed version of netdata is ' + data);
2931             document.getElementById('netdataVersion').innerHTML = data;
2932             callback(data);
2933         }
2934     })
2935     .fail(function() {
2936         versionLog('Failed to download installed version info from netdata!');
2937         callback(null);
2938     });
2939 }
2940
2941 function getGithubLatestCommit(callback) {
2942     versionLog('Downloading latest version info from github...');
2943
2944     $.ajax({
2945         url: 'https://api.github.com/repos/firehol/netdata/commits',
2946         async: true,
2947         cache: false
2948     })
2949     .done(function(data) {
2950         versionLog('Latest version info from github is ' + data[0].sha);
2951         callback(data[0].sha);
2952     })
2953     .fail(function() {
2954         versionLog('Failed to download installed version info from github!');
2955         callback(null);
2956     });
2957 }
2958
2959 function checkForUpdate(callback) {
2960     getNetdataVersion(function(sha1) {
2961         if(sha1 === null) callback(null, null);
2962
2963         getGithubLatestCommit(function(sha2) {
2964             callback(sha1, sha2);
2965         });
2966     });
2967
2968     return null;
2969 }
2970
2971 function notifyForUpdate(force) {
2972     versionLog('<p>checking for updates...</p>');
2973
2974     var now = new Date().getTime();
2975
2976     if(typeof force === 'undefined' || force !== true) {
2977         var last = loadLocalStorage('last_update_check');
2978
2979         if(typeof last === 'string')
2980             last = parseInt(last);
2981         else
2982             last = 0;
2983
2984         if(now - last < 3600000 * 8) {
2985             // no need to check it - too soon
2986             return;
2987         }
2988     }
2989
2990     checkForUpdate(function(sha1, sha2) {
2991         var save = false;
2992
2993         if(sha1 === null) {
2994             save = false;
2995             versionLog('<p><big>Failed to get your netdata version!</big></p><p>You can always get the latest version of netdata from <a href="https://github.com/firehol/netdata" target="_blank">its github page</a>.</p>');
2996         }
2997         else if(sha2 === null) {
2998             save = false;
2999             versionLog('<p><big>Failed to get the latest version from github.</big></p><p>You can always get the latest version of netdata from <a href="https://github.com/firehol/netdata" target="_blank">its github page</a>.</p>');
3000         }
3001         else if(sha1 === sha2) {
3002             save = true;
3003             versionLog('<p><big>You already have the latest version of netdata!</big></p><p>No update yet?<br/>Probably, we need some motivation to keep going on!</p><p>If you haven\'t already, <a href="https://github.com/firehol/netdata" target="_blank">give netdata a <b>Star</b> at its github page</a>.</p>');
3004         }
3005         else {
3006             save = true;
3007             var compare = 'https://github.com/firehol/netdata/compare/' + sha1.toString() + '...' + sha2.toString();
3008
3009             versionLog('<p><big><strong>New version of netdata available!</strong></big></p><p>Latest version: ' + sha2.toString() + '</p><p><a href="' + compare + '" target="_blank">Click here for the changes log</a> since your installed version, and<br/><a href="https://github.com/firehol/netdata/wiki/Updating-Netdata" target="_blank">click here for directions on updating</a> your netdata installation.</p><p>We suggest to review the changes log for new features you may be interested, or important bug fixes you may need.<br/>Keeping your netdata updated, is generally a good idea.</p>');
3010
3011             document.getElementById('update_badge').innerHTML = '!';
3012         }
3013
3014         if(save)
3015             saveLocalStorage('last_update_check', now.toString());
3016     });
3017 }
3018
3019 // ----------------------------------------------------------------------------
3020
3021 function finalizePage() {
3022     // resize all charts - without starting the background thread
3023     // this has to be done while NETDATA is paused
3024     // if we ommit this, the affix menu will be wrong, since all
3025     // the Dom elements are initially zero-sized
3026     NETDATA.parseDom();
3027
3028     if(urlOptions.pan_and_zoom === true) {
3029         urlOptions.nowelcome = true;
3030         NETDATA.globalPanAndZoom.setMaster(NETDATA.options.targets[0], urlOptions.after, urlOptions.before);
3031     }
3032
3033     // ------------------------------------------------------------------------
3034     // https://github.com/viralpatel/jquery.shorten/blob/master/src/jquery.shorten.js
3035     $.fn.shorten = function(settings) {
3036         "use strict";
3037
3038         var config = {
3039             showChars: 750,
3040             minHideChars: 10,
3041             ellipsesText: "...",
3042             moreText: '<i class="fa fa-expand" aria-hidden="true"></i> show more information',
3043             lessText: '<i class="fa fa-compress" aria-hidden="true"></i> show less information',
3044             onLess: function() { NETDATA.onscroll(); },
3045             onMore: function() { NETDATA.onscroll(); },
3046             errMsg: null,
3047             force: false
3048         };
3049
3050         if (settings) {
3051             $.extend(config, settings);
3052         }
3053
3054         if ($(this).data('jquery.shorten') && !config.force) {
3055             return false;
3056         }
3057         $(this).data('jquery.shorten', true);
3058
3059         $(document).off("click", '.morelink');
3060
3061         $(document).on({
3062             click: function() {
3063
3064                 var $this = $(this);
3065                 if ($this.hasClass('less')) {
3066                     $this.removeClass('less');
3067                     $this.html(config.moreText);
3068                     $this.parent().prev().animate({'height':'0'+'%'}, 0, function () { $this.parent().prev().prev().show(); }).hide(0, function() {
3069                         config.onLess();
3070                     });
3071
3072                 } else {
3073                     $this.addClass('less');
3074                     $this.html(config.lessText);
3075                     $this.parent().prev().animate({'height':'100'+'%'}, 0, function () { $this.parent().prev().prev().hide(); }).show(0, function() {
3076                         config.onMore();
3077                     });
3078                 }
3079                 return false;
3080             }
3081         }, '.morelink');
3082
3083         return this.each(function() {
3084             var $this = $(this);
3085
3086             var content = $this.html();
3087             var contentlen = $this.text().length;
3088             if (contentlen > config.showChars + config.minHideChars) {
3089                 var c = content.substr(0, config.showChars);
3090                 if (c.indexOf('<') >= 0) // If there's HTML don't want to cut it
3091                 {
3092                     var inTag = false; // I'm in a tag?
3093                     var bag = ''; // Put the characters to be shown here
3094                     var countChars = 0; // Current bag size
3095                     var openTags = []; // Stack for opened tags, so I can close them later
3096                     var tagName = null;
3097
3098                     for (var i = 0, r = 0; r <= config.showChars; i++) {
3099                         if (content[i] == '<' && !inTag) {
3100                             inTag = true;
3101
3102                             // This could be "tag" or "/tag"
3103                             tagName = content.substring(i + 1, content.indexOf('>', i));
3104
3105                             // If its a closing tag
3106                             if (tagName[0] == '/') {
3107
3108
3109                                 if (tagName != '/' + openTags[0]) {
3110                                     config.errMsg = 'ERROR en HTML: the top of the stack should be the tag that closes';
3111                                 } else {
3112                                     openTags.shift(); // Pops the last tag from the open tag stack (the tag is closed in the retult HTML!)
3113                                 }
3114
3115                             } else {
3116                                 // There are some nasty tags that don't have a close tag like <br/>
3117                                 if (tagName.toLowerCase() != 'br') {
3118                                     openTags.unshift(tagName); // Add to start the name of the tag that opens
3119                                 }
3120                             }
3121                         }
3122                         if (inTag && content[i] == '>') {
3123                             inTag = false;
3124                         }
3125
3126                         if (inTag) { bag += content.charAt(i); } // Add tag name chars to the result
3127                         else {
3128                             r++;
3129                             if (countChars <= config.showChars) {
3130                                 bag += content.charAt(i); // Fix to ie 7 not allowing you to reference string characters using the []
3131                                 countChars++;
3132                             } else // Now I have the characters needed
3133                             {
3134                                 if (openTags.length > 0) // I have unclosed tags
3135                                 {
3136                                     //console.log('They were open tags');
3137                                     //console.log(openTags);
3138                                     for (j = 0; j < openTags.length; j++) {
3139                                         //console.log('Cierro tag ' + openTags[j]);
3140                                         bag += '</' + openTags[j] + '>'; // Close all tags that were opened
3141
3142                                         // You could shift the tag from the stack to check if you end with an empty stack, that means you have closed all open tags
3143                                     }
3144                                     break;
3145                                 }
3146                             }
3147                         }
3148                     }
3149                     c = $('<div/>').html(bag + '<span class="ellip">' + config.ellipsesText + '</span>').html();
3150                 }else{
3151                     c+=config.ellipsesText;
3152                 }
3153
3154                 var html = '<div class="shortcontent">' + c +
3155                         '</div><div class="allcontent">' + content +
3156                         '</div><span><a href="javascript://nop/" class="morelink">' + config.moreText + '</a></span>';
3157
3158                 $this.html(html);
3159                 $this.find(".allcontent").hide(); // Hide all text
3160                 $('.shortcontent p:last', $this).css('margin-bottom', 0); //Remove bottom margin on last paragraph as it's likely shortened
3161             }
3162         });
3163
3164     };
3165     $(".chart-message").shorten();
3166     // ------------------------------------------------------------------------
3167
3168     // callback for us to track PanAndZoom operations
3169     NETDATA.globalPanAndZoom.callback = netdataPanAndZoomCallback;
3170
3171     // let it run (update the charts)
3172     NETDATA.unpause();
3173
3174     // check if we have to jump to a specific section
3175     scrollToId(urlOptions.hash.replace('#',''));
3176
3177     /* activate bootstrap sidebar (affix) */
3178     $('#sidebar').affix({
3179         offset: {
3180             top: (isdemo())?150:0,
3181             bottom: 0
3182         }
3183     });
3184
3185     /* fix scrolling of very long affix lists
3186        http://stackoverflow.com/questions/21691585/bootstrap-3-1-0-affix-too-long
3187      */
3188     $('#sidebar').on('affixed.bs.affix', function() {
3189         $(this).removeAttr('style');
3190     });
3191
3192     /* activate bootstrap scrollspy (needed for sidebar) */
3193     $(document.body).scrollspy({
3194         target: '#sidebar',
3195         offset: $(window).height() / 5 // controls the diff of the <hX> element to the top, to select it
3196     });
3197
3198     // change the URL based on the current position of the screen
3199     $('#sidebar').on('activate.bs.scrollspy', function (e) {
3200         var el = $(e.target);
3201         if(el.find('ul').size() == 0) {
3202             var hash = el.find('a').attr('href');
3203             if(typeof hash === 'string' && hash.substring(0, 1) == '#') {
3204                 urlOptions.hash = hash;
3205                 // console.log(urlOptions.hash);
3206                 netdataHashUpdate();
3207             }
3208         }
3209     });
3210
3211     document.getElementById('footer').style.display = 'block';
3212
3213     var update_options_modal = function() {
3214         // console.log('update_options_modal');
3215
3216         var sync_option = function(option) {
3217             var self = $('#' + option);
3218
3219             if(self.prop('checked') !== NETDATA.getOption(option)) {
3220                 // console.log('switching ' + option.toString());
3221                 self.bootstrapToggle(NETDATA.getOption(option)?'on':'off');
3222             }
3223         }
3224
3225         var theme_sync_option = function(option) {
3226             var self = $('#' + option);
3227
3228             self.bootstrapToggle(netdataTheme === 'slate'?'on':'off');
3229         }
3230
3231         sync_option('eliminate_zero_dimensions');
3232         sync_option('destroy_on_hide');
3233         sync_option('parallel_refresher');
3234         sync_option('concurrent_refreshes');
3235         sync_option('sync_selection');
3236         sync_option('sync_pan_and_zoom');
3237         sync_option('stop_updates_when_focus_is_lost');
3238         sync_option('smooth_plot');
3239         sync_option('pan_and_zoom_data_padding');
3240         sync_option('show_help');
3241         theme_sync_option('netdata_theme_control');
3242
3243         if(NETDATA.getOption('parallel_refresher') === false) {
3244             $('#concurrent_refreshes_row').hide();
3245         }
3246         else {
3247             $('#concurrent_refreshes_row').show();
3248         }
3249     };
3250     NETDATA.setOption('setOptionCallback', update_options_modal);
3251
3252     // handle options changes
3253     $('#eliminate_zero_dimensions').change(function()       { NETDATA.setOption('eliminate_zero_dimensions', $(this).prop('checked')); });
3254     $('#destroy_on_hide').change(function()                 { NETDATA.setOption('destroy_on_hide', $(this).prop('checked')); });
3255     $('#parallel_refresher').change(function()              { NETDATA.setOption('parallel_refresher', $(this).prop('checked')); });
3256     $('#concurrent_refreshes').change(function()            { NETDATA.setOption('concurrent_refreshes', $(this).prop('checked')); });
3257     $('#sync_selection').change(function()                  { NETDATA.setOption('sync_selection', $(this).prop('checked')); });
3258     $('#sync_pan_and_zoom').change(function()               { NETDATA.setOption('sync_pan_and_zoom', $(this).prop('checked')); });
3259     $('#stop_updates_when_focus_is_lost').change(function() { NETDATA.setOption('stop_updates_when_focus_is_lost', $(this).prop('checked')); });
3260     $('#smooth_plot').change(function()                     { NETDATA.setOption('smooth_plot', $(this).prop('checked')); });
3261     $('#pan_and_zoom_data_padding').change(function()       { NETDATA.setOption('pan_and_zoom_data_padding', $(this).prop('checked')); });
3262     $('#show_help').change(function()                       {
3263         urlOptions.help = $(this).prop('checked');
3264         NETDATA.setOption('show_help', urlOptions.help);
3265         netdataReload();
3266     });
3267
3268     // this has to be the last
3269     // it reloads the page
3270     $('#netdata_theme_control').change(function() {
3271         urlOptions.theme = $(this).prop('checked')?'slate':'white';
3272         if(setTheme(urlOptions.theme))
3273             netdataReload();
3274     });
3275
3276     $('#updateModal').on('shown.bs.modal', function() {
3277         notifyForUpdate(true);
3278     });
3279
3280     $('#alarmsModal').on('shown.bs.modal', function() {
3281         NETDATA.pause(alarmsUpdateModal);
3282     });
3283
3284     $('#alarmsModal').on('hidden.bs.modal', function() {
3285         NETDATA.unpause();
3286         document.getElementById('alarms_active').innerHTML =
3287                 document.getElementById('alarms_all').innerHTML =
3288                 document.getElementById('alarms_log').innerHTML =
3289                         'loading...';
3290     });
3291
3292     $('#deleteRegistryModal').on('hidden.bs.modal', function() {
3293         deleteRegistryGuid = null;
3294     });
3295
3296     if(isdemo()) {
3297         if(!urlOptions.nowelcome) {
3298             setTimeout(function() {
3299                 $('#welcomeModal').modal();
3300             }, 1000);
3301         }
3302
3303         // google analytics when this is used for the home page of the demo sites
3304         // this does not run on user's installations
3305         setTimeout(function() {
3306             (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
3307             (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
3308             m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
3309             })(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
3310
3311             ga('create', 'UA-64295674-3', 'auto');
3312             ga('send', 'pageview');
3313         }, 2000);
3314     }
3315     else notifyForUpdate();
3316
3317     if(urlOptions.show_alarms === 'true')
3318         setTimeout(function() { $('#alarmsModal').modal('show'); }, 1000);
3319 }
3320
3321 function resetDashboardOptions() {
3322     var help = NETDATA.options.current.show_help;
3323
3324     NETDATA.resetOptions();
3325     if(setTheme('slate'))
3326         netdataReload();
3327
3328     if(help !== NETDATA.options.current.show_help)
3329         netdataReload();
3330 }
3331
3332 downloadAllCharts();
3333
3334 </script>
3335
3336 </body>
3337 </html>