diff options
Diffstat (limited to 'web/gui/index.html')
-rw-r--r-- | web/gui/index.html | 5791 |
1 files changed, 5791 insertions, 0 deletions
diff --git a/web/gui/index.html b/web/gui/index.html new file mode 100644 index 0000000000..6a498760d4 --- /dev/null +++ b/web/gui/index.html @@ -0,0 +1,5791 @@ +<!DOCTYPE html> +<!-- SPDX-License-Identifier: GPL-3.0-or-later --> +<html lang="en"> +<head> + <title>netdata dashboard</title> + <meta name="application-name" content="netdata"> + + <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> + <meta charset="utf-8"> + <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> + <meta name="viewport" content="width=device-width, initial-scale=1"> + <meta name="apple-mobile-web-app-capable" content="yes"> + <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent"> + <meta name="author" content="costa@tsaousis.gr"> + + <!-- <link rel="shortcut icon" href="images/seo-performance-multi-size.ico"> --> + + <!-- <link rel="apple-touch-icon" href="images/seo-performance-72.png"> --> + <!-- <link rel="apple-touch-icon" sizes="72x72" href="images/seo-performance-72.png"> --> + <!-- <link rel="apple-touch-icon" sizes="114x114" href="images/seo-performance-114.png"> --> + + <!-- <link rel="icon" type="image/png" sizes="512x512" href="images/seo-performance-512.png"> --> + <!-- <link rel="icon" type="image/png" sizes="256x256" href="images/seo-performance-256.png"> --> + <!-- <link rel="icon" type="image/png" sizes="128x128" href="images/seo-performance-128.png"> --> + <!-- <link rel="icon" type="image/png" sizes="64x64" href="images/seo-performance-64.png"> --> + <!-- <link rel="icon" type="image/png" sizes="48x48" href="images/seo-performance-48.png"> --> + <!-- <link rel="icon" type="image/png" sizes="24x24" href="images/seo-performance-24.png"> --> + <!-- <link rel="icon" type="image/png" sizes="16x16" href="images/seo-performance-16.png"> --> + <!-- <link rel="icon" type="image/png" sizes="32x32" href="images/seo-performance-32.png"> --> + + <link rel="icon" type="image/png" sizes="32x32" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAACNklEQVRYhcXXv2tUQRAH8M+FEIJISBHCIWIhIQSUILERi4AiiqCggiIiomAjlhaC4j+ghYWISgqNohZaCBZBC8Ei8QdEUCutFBsxCBqDYkgci/cunkfuJffjJQPD8mZm5/vd2WV2HzlJ0Bs8CvrywsgCHwy+BpGOg0sJfjj4nYKX9FdwKG9gwZlgtgK8pLOpPxfw1mCoCnClDgWtzQTvCEYWCV7SkWAlFBoEb8dlDKBF8t2bMWUSH/AHr3CiEfz5CPUusPJLkRCdk5ZqyeqUrQv4R7E5TwK7M3zTeIKduRAIitiWEfIY69GdCwGcRFuG/xqONRkzkaA7+J5x+MaDtWmHvJ4HgeEM8Nn0bridfv9HoOFyBAdwJCPkqqTzHWwUaz7wgeBHxupfBKuCj2W25mxBsCGYyAB/FxTT27HcPlyep64tCLbjKbqqhLzBlgKfF8pVE4FgRXABI+ioEnYfOyzcFWsCbg+OV+xlpU4ER4O+4HVwL51b3xYEXcGu4Ao+YQhr5gmdxHmsQyfG0b/YxbWmLfRWmnxa0s06VbTMCpnBS9zFzQKTwR5cXCzwHIE02Sl8wSZsRI/kgLVJqjSd+t9LVjiG1diPszhdK3A5gR48k5zYMTwscC59sfT799CYKvA8EttbSeXgTr3gJQKl91kR+yTlvyG5uUbLYh9gb+ovltkb6qYtNSRo3kOygsBSzGlKsubf43USWLYK5CLLXoFWyU/CtzLbVDpW2n+m40yN9ukqdvAX9ac/EIgOapcAAAAASUVORK5CYII="> + + <link rel="mask-icon" href="images/netdata.svg" color="red" /> + + <meta property="og:locale" content="en_US" /> + <meta property="og:url" content="https://my-netdata.io" /> + <meta property="og:type" content="website" /> + <meta property="og:site_name" content="netdata"/> + <meta property="og:title" content="Get control of your Linux Servers. Simple. Effective. Awesome." /> + <meta property="og:description" content="Unparalleled insights, in real-time, of everything happening on your Linux systems and applications, with stunning, interactive web dashboards and powerful performance and health alarms." /> + <meta property="og:image" content="https://cloud.githubusercontent.com/assets/2662304/22945737/e98cd0c6-f2fd-11e6-96f1-5501934b0955.png" /> + <meta property="og:image:type" content="image/png" /> + <meta property="fb:app_id" content="1200089276712916" /> + + <meta name="twitter:card" content="summary" /> + <meta name="twitter:site" content="@linuxnetdata" /> + <meta name="twitter:title" content="Get control of your Linux Servers. Simple. Effective. Awesome." /> + <meta name="twitter:description" content="Unparalleled insights, in real-time, of everything happening on your Linux systems and applications, with stunning, interactive web dashboards and powerful performance and health alarms." /> + <meta name="twitter:image" content="https://cloud.githubusercontent.com/assets/2662304/14092712/93b039ea-f551-11e5-822c-beadbf2b2a2e.gif" /> + + <style> + + /* force the vertical window scrollbar */ + html { + overflow-y: scroll; + } + + /* prevent body from hiding under the navbar */ + body { + padding-top: 50px; + } + + .loadOverlay { + position: absolute; + top: 0px; + left: 0px; + width: 100%; + height:100%; + z-index: 2000; + font-size: 10vh; + font-family: sans-serif; + padding: 40vh 0 40vh 0; + font-weight: bold; + text-align: center; + } + + .navbar-highlight { + display: none; + position: fixed; + margin-top: 5px; + height: 26px; + width: 100%; + text-align: center; + overflow: hidden; + z-index: 30; + pointer-events: none !important; + } + + .navbar-highlight-content { + position: relative; + display: inline-block; + margin: 0 auto; + height: 26px; + min-width: 500px; + background-color:rgba(0, 0, 0, 0.7); + padding-top: 2px; + padding-bottom: 2px; + padding-left: 15px; + padding-right: 15px; + border-radius:10px; + color: lightgrey; + pointer-events: auto !important; + } + + .navbar-highlight-bar { + cursor: pointer; + } + .navbar-highlight-button-right { + cursor: pointer; + padding-left: 10px; + } + + .modal-wide .modal-dialog { + width: 80%; + } + + /* fix # anchors scrolling under the navbar + https://github.com/twbs/bootstrap/issues/1768#issuecomment-46519033 + */ + h1 { + position: relative; + z-index: -1; + } + h2 { + position: relative; + z-index: -2; + } + h1:before, h2:before { + display: block; + content: " "; + margin-top: -70px; + height: 70px; + visibility: hidden; + } + + .p { + display: block; + margin-top: 15px; + } + + .option-row, + .option-control { + vertical-align: top; + padding: 10px; + padding-top: 30px; + padding-left: 30px; + } + + .option-info { + padding: 10px; + } + + .dashboard-submenu-info { + display: block; + margin-top: 10px; + } + + .dashboard-context-info { + display: block; + margin-top: 10px; + } + + #masthead h1 { + /*font-size: 30px;*/ + line-height: 1; + padding-top: 30px; + } + + #masthead .well { + margin-top:4%; + } + + /* fix the navbar shifting when a modal is open */ + /* https://github.com/twbs/bootstrap/issues/14040#issuecomment-159891033 */ + body.modal-open{ + width: 100% !important; + padding-right: 0 !important; +/* overflow-y: scroll !important; */ +/* position: fixed !important;*/ + overflow: visible; + } + + /* make accordion use the whole header bar for expand/collapse */ + .panel-title a { + display: block; + padding: 10px 15px; + margin: -10px -15px; + } + + /* + * Side navigation + * + * Scrollspy and affixed enhanced navigation to highlight sections and secondary + * sections of docs content. + */ + + .affix { + position: static; + top: 70px !important; + /*width: 220px;*/ + } + + .affix-top { + /*width: 220px;*/ + } + + .dashboard-sidebar { + max-height: calc(100% - 70px) !important; + overflow-y: auto; + /*width: 220px !important;*/ + } + + /* By default it's not affixed in mobile views, so undo that */ + .dashboard-sidebar.affix { + position: static; + } + + @media (min-width: 768px) { + .dashboard-sidebar { + padding-left: 20px; + } + } + + /* First level of nav */ + .dashboard-sidenav { + margin-top: 20px; + margin-bottom: 20px; + } + + /* All levels of nav */ + .dashboard-sidebar .nav > li > a { + display: block; + padding: 4px 20px; + font-size: 13px; + font-weight: 500; + color: #767676; + } + .dashboard-sidebar .nav > li > a > .svg-inline--fa { + width: 20px; + text-align: center; + } + .dashboard-sidebar .nav > li > a:hover, + .dashboard-sidebar .nav > li > a:focus { + padding-left: 19px; + color: #563d7c; + text-decoration: none; + background-color: transparent; + border-left: 1px solid #563d7c; + } + .dashboard-sidebar .nav > .active > a, + .dashboard-sidebar .nav > .active:hover > a, + .dashboard-sidebar .nav > .active:focus > a { + padding-left: 18px; + font-weight: bold; + color: #563d7c; + background-color: transparent; + border-left: 2px solid #563d7c; + } + + /* Nav: second level (shown on .active) */ + .dashboard-sidebar .nav .nav { + display: none; /* Hide by default, but at >768px, show it */ + padding-bottom: 10px; + } + .dashboard-sidebar .nav .nav > li > a { + padding-top: 1px; + padding-bottom: 1px; + padding-left: 30px; + font-size: 12px; + font-weight: normal; + } + .dashboard-sidebar .nav .nav > li > a:hover, + .dashboard-sidebar .nav .nav > li > a:focus { + padding-left: 29px; + } + .dashboard-sidebar .nav .nav > .active > a, + .dashboard-sidebar .nav .nav > .active:hover > a, + .dashboard-sidebar .nav .nav > .active:focus > a { + padding-left: 28px; + font-weight: 500; + } + + .dropdown-menu { + min-width: 200px; + } + .dropdown-menu.columns-2 { + margin: 0; + padding: 0; + width: 400px; + } + .dropdown-menu li a { + padding: 5px 15px; + font-weight: 300; + } + .dropdown-menu.multi-column { + overflow-x: hidden; + } + .multi-column-dropdown { + list-style: none; + padding: 0; + } + .multi-column-dropdown li a { + display: block; + clear: both; + line-height: 1.428571429; + white-space: normal; + } + .multi-column-dropdown li a:hover { + text-decoration: none; + color: #f5f5f5; + background-color: #262626; + } + .scrollable-menu { + height: auto; + max-height: 80vh; + overflow-x: hidden; + } + .scrollable-menu-50 { + height: auto; + max-height: 50vh; + overflow-x: hidden; + } + + /* Back to top (hidden on mobile) */ + .back-to-top, + .dashboard-theme-toggle { + display: none; + padding: 4px 10px; + margin-top: 10px; + margin-left: 10px; + font-size: 12px; + font-weight: 500; + color: #999; + } + .back-to-top:hover, + .dashboard-theme-toggle:hover { + color: #563d7c; + text-decoration: none; + } + .dashboard-theme-toggle { + margin-top: 0; + } + + .container { + width: calc(100% - 20px) !important; + } + + .charts-body { + display: inline-block; + width: 100%; + } + + .sidebar-body { + position: absolute; + display: none; + } + + .dashboard-section-container { + display: block; + width: 100%; + page-break-before: auto; + page-break-after: auto; + page-break-inside: auto; + } + + .dashboard-print-row { + display: block; + width: 100%; + page-break-before: auto; + page-break-after: auto; + page-break-inside: avoid; + } + + .netdata-chartblock-container { + display: inline-block; + } + + /* https://github.com/seiyria/bootstrap-slider/issues/746 */ + .tooltip { + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + } + + @media print { + body { + overflow: visible !important; + -webkit-print-color-adjust: exact; + page-break-inside: auto; + page-break-before: auto; + page-break-after: auto; + } + + .dashboard-section { + page-break-inside: auto; + page-break-before: auto; + page-break-after: auto; + } + + .dashboard-subsection { + page-break-before: avoid; + page-break-after: auto; + page-break-inside: auto; + } + + .charts-body { + padding-left: 0%; + padding-right: 0%; + display: block; + page-break-inside: auto; + page-break-before: auto; + page-break-after: auto; + } + + .back-to-top, + .dashboard-theme-toggle { + display: block; + } + } + + @media (min-width: 768px) { + .charts-body { + padding-left: 0%; + padding-right: 0%; + } + + .back-to-top, + .dashboard-theme-toggle { + display: block; + } + } + + /* Show and affix the side nav when space allows it */ + @media (min-width: 992px) { + .container { + padding-left: 0% !important; + } + + .charts-body { + width: calc(100% - 213px) !important; + padding-left: 1% !important; + padding-right: 0% !important; + } + + .sidebar-body { + display: inline-block !important; + width: 213px !important; + } + + .dashboard-sidebar .nav > .active > ul { + display: block; + } + + /* Widen the fixed sidebar */ + .dashboard-sidebar.affix, + .dashboard-sidebar.affix-top, + .dashboard-sidebar.affix-bottom { + width: 213px !important; + } + .dashboard-sidebar.affix { + position: fixed; /* Undo the static from mobile first approach */ + top: 20px; + } + .dashboard-sidebar.affix-bottom { + position: absolute; /* Undo the static from mobile first approach */ + } + .dashboard-sidebar.affix-bottom .dashboard-sidenav, + .dashboard-sidebar.affix .dashboard-sidenav { + margin-top: 0; + margin-bottom: 0; + } + } + + @media (min-width: 1200px) { + .container { + padding-left: 2% !important; + } + + .charts-body { + width: calc(100% - 233px) !important; + padding-left: 1% !important; + padding-right: 1% !important; + } + + .sidebar-body { + display: inline-block !important; + width: 233px !important; + } + + /* Widen the fixed sidebar again */ + .dashboard-sidebar.affix, + .dashboard-sidebar.affix-top, + .dashboard-sidebar.affix-bottom { + width: 233px !important; + } + } + + @media (min-width: 1360px) { + .container { + padding-left: 3% !important; + } + + .charts-body { + width: calc(100% - 263px) !important; + padding-left: 1% !important; + padding-right: 2% !important; + } + + .sidebar-body { + display: inline-block !important; + width: 263px !important; + } + + /* Widen the fixed sidebar again */ + .dashboard-sidebar.affix, + .dashboard-sidebar.affix-top, + .dashboard-sidebar.affix-bottom { + width: 263px !important; + } + } + + .action-button { + position: relative; + display: inline-block; + color: gray; + cursor: pointer; + margin: 0 auto; + width: 30px; + height: 30px; + font-size: 25px; + } + + .ripple { + position: relative; + /*overflow: hidden;*/ + transform: translate3d(0, 0, 0) + } + + .ripple:after { + content: ""; + display: block; + position: absolute; + width: 100%; + height: 100%; + top: 0; + left: 0; + pointer-events: none; + background-image: radial-gradient(circle, #000 10%, transparent 10.01%); + background-repeat: no-repeat; + background-position: 50%; + transform: scale(18, 18); /* the size of the ripple */ + opacity: 0; + transition: transform .5s, opacity 1s + } + + .ripple:active:after { + transform: scale(0, 0); + opacity: .2; + transition: 0s + } + </style> + + <!-- check which theme to use --> + <script type="text/javascript"> + // netdata snapshot data + var netdataSnapshotData = null; + + // enable alarms checking and notifications + var netdataShowAlarms = true; + + // enable registry updates + var netdataRegistry = true; + + // forward definition only - not used here + var netdataServer = undefined; + var netdataServerStatic = undefined; + var netdataCheckXSS = undefined; + + // control the welcome modal and analytics + var this_is_demo = null; + + function escapeUserInputHTML(s) { + return s.toString() + .replace(/&/g, '&') + .replace(/</g, '<') + .replace(/>/g, '>') + .replace(/"/g, '"') + .replace(/#/g, '#') + .replace(/'/g, ''') + .replace(/\(/g,'(') + .replace(/\)/g,')') + .replace(/\//g,'/'); + } + + function verifyURL(s) { + if(typeof(s) === 'string' && (s.startsWith('http://') || s.startsWith('https://'))) + return s + .replace(/'/g, '%22') + .replace(/"/g, '%27') + .replace(/\)/g, '%28') + .replace(/\(/g, '%29'); + + console.log('invalid URL detected:'); + console.log(s); + return 'javascript:alert("invalid url");'; + } + + // -------------------------------------------------------------------- + // urlOptions + + var urlOptions = { + hash: '#', + theme: null, + help: null, + mode: 'live', // 'live', 'print' + update_always: false, + pan_and_zoom: false, + server: null, + after: 0, + before: 0, + highlight: false, + highlight_after: 0, + highlight_before: 0, + nowelcome: false, + show_alarms: false, + chart: null, + family: null, + alarm: null, + alarm_unique_id: 0, + alarm_id: 0, + alarm_event_id: 0, + + hasProperty: function(property) { + // console.log('checking property ' + property + ' of type ' + typeof(this[property])); + return typeof this[property] !== 'undefined'; + }, + + genHash: function(forReload) { + var hash = urlOptions.hash; + + if(urlOptions.pan_and_zoom === true) { + hash += ';after=' + urlOptions.after.toString() + + ';before=' + urlOptions.before.toString(); + } + + if(urlOptions.highlight === true) { + hash += ';highlight_after=' + urlOptions.highlight_after.toString() + + ';highlight_before=' + urlOptions.highlight_before.toString(); + } + + if(urlOptions.theme !== null) + hash += ';theme=' + urlOptions.theme.toString(); + + if(urlOptions.help !== null) + hash += ';help=' + urlOptions.help.toString(); + + if(urlOptions.update_always === true) + hash += ';update_always=true'; + + if(forReload === true && urlOptions.server !== null) + hash += ';server=' + urlOptions.server.toString(); + + if(urlOptions.mode !== 'live') + hash += ';mode=' + urlOptions.mode; + + return hash; + }, + + parseHash: function() { + var variables = document.location.hash.split(';'); + var len = variables.length; + while(len--) { + if(len !== 0) { + var p = variables[len].split('='); + if(urlOptions.hasProperty(p[0]) && typeof p[1] !== 'undefined') + urlOptions[p[0]] = decodeURIComponent(p[1]); + } + else { + if(variables[len].length > 0) + urlOptions.hash = variables[len]; + } + } + + var booleans = [ 'nowelcome', 'show_alarms', 'update_always' ]; + len = booleans.length; + while(len--) { + if(urlOptions[booleans[len]] === 'true' || urlOptions[booleans[len]] === true || urlOptions[booleans[len]] === '1' || urlOptions[booleans[len]] === 1) + urlOptions[booleans[len]] = true; + else + urlOptions[booleans[len]] = false; + } + + var numeric = [ 'after', 'before', 'highlight_after', 'highlight_before' ]; + len = numeric.length; + while(len--) { + if(typeof urlOptions[numeric[len]] === 'string') { + try { + urlOptions[numeric[len]] = parseInt(urlOptions[numeric[len]]); + } + catch(e) { + console.log('failed to parse URL hash parameter ' + numeric[len]); + urlOptions[numeric[len]] = 0; + } + } + } + + if(urlOptions.server !== null && urlOptions.server !== '') { + netdataServerStatic = document.location.origin.toString() + document.location.pathname.toString(); + netdataServer = urlOptions.server; + netdataCheckXSS = true; + } + else + urlOptions.server = null; + + if(urlOptions.before > 0 && urlOptions.after > 0) { + urlOptions.pan_and_zoom = true; + urlOptions.nowelcome = true; + } + else + urlOptions.pan_and_zoom = false; + + if(urlOptions.highlight_before > 0 && urlOptions.highlight_after > 0) { + urlOptions.highlight = true; + } + else + urlOptions.highlight = false; + + switch(urlOptions.mode) { + case 'print': + urlOptions.theme = 'white'; + urlOptions.welcome = false; + urlOptions.help = false; + urlOptions.show_alarms = false; + + if(urlOptions.pan_and_zoom === false) { + urlOptions.pan_and_zoom = true; + urlOptions.before = Date.now(); + urlOptions.after = urlOptions.before - 600000; + } + + netdataShowAlarms = false; + netdataRegistry = false; + this_is_demo = false; + break; + + case 'live': + default: + urlOptions.mode = 'live'; + break; + } + + // console.log(urlOptions); + }, + + hashUpdate: function() { + history.replaceState(null, '', urlOptions.genHash(true)); + }, + + netdataPanAndZoomCallback: function(status, after, before) { + //console.log(1); + //console.log(new Error().stack); + + if(netdataSnapshotData === null) { + urlOptions.pan_and_zoom = status; + urlOptions.after = after; + urlOptions.before = before; + urlOptions.hashUpdate(); + } + }, + + netdataHighlightCallback: function(status, after, before) { + //console.log(2); + //console.log(new Error().stack); + + if(status === true && (after === null || before === null || after <= 0 || before <= 0 || after >= before)) { + status = false; + after = 0; + before = 0; + } + + if(netdataSnapshotData === null) + urlOptions.highlight = status; + else + urlOptions.highlight = false; + + urlOptions.highlight_after = Math.round(after); + urlOptions.highlight_before = Math.round(before); + urlOptions.hashUpdate(); + + var show_eye = NETDATA.globalChartUnderlay.hasViewport(); + + if(status === true && after > 0 && before > 0 && after < before) { + var d1 = NETDATA.dateTime.localeDateString(after); + var d2 = NETDATA.dateTime.localeDateString(before); + if(d1 === d2) d2 = ''; + document.getElementById('navbar-highlight-content').innerHTML = + ((show_eye === true)?'<span class="navbar-highlight-bar highlight-tooltip" onclick="urlOptions.showHighlight();" title="restore the highlighted view" data-toggle="tooltip" data-placement="bottom">':'<span>').toString() + + 'highlighted time-frame' + + ' <b>' + d1 + ' <code>' + NETDATA.dateTime.localeTimeString(after) + '</code></b> to ' + + ' <b>' + d2 + ' <code>' + NETDATA.dateTime.localeTimeString(before) + '</code></b>, ' + + 'duration <b>' + NETDATA.seconds4human(Math.round((before - after) / 1000)) + '</b>' + + '</span>' + + '<span class="navbar-highlight-button-right highlight-tooltip" onclick="urlOptions.clearHighlight();" title="clear the highlighted time-frame" data-toggle="tooltip" data-placement="bottom"><i class="fas fa-times"></i></span>'; + + $('.navbar-highlight').show(); + + $('.highlight-tooltip').tooltip({ + html: true, + delay: {show: 500, hide: 0}, + container: 'body' + }); + } + else + $('.navbar-highlight').hide(); + }, + + clearHighlight: function() { + NETDATA.globalChartUnderlay.clear(); + + if(NETDATA.globalPanAndZoom.isActive() === true) + NETDATA.globalPanAndZoom.clearMaster(); + }, + + showHighlight: function() { + NETDATA.globalChartUnderlay.focus(); + } + }; + + urlOptions.parseHash(); + + // -------------------------------------------------------------------- + // check options that should be processed before loading netdata.js + + var localStorageTested = -1; + function localStorageTest() { + if(localStorageTested !== -1) + return localStorageTested; + + if(typeof Storage !== "undefined" && typeof localStorage === 'object') { + var test = 'test'; + try { + localStorage.setItem(test, test); + localStorage.removeItem(test); + localStorageTested = true; + } + catch (e) { + console.log(e); + localStorageTested = false; + } + } + else + localStorageTested = false; + + return localStorageTested; + } + + function loadLocalStorage(name) { + var ret = null; + + try { + if(localStorageTest() === true) + ret = localStorage.getItem(name); + else + console.log('localStorage is not available'); + } + catch(error) { + console.log(error); + return null; + } + + if(typeof ret === 'undefined' || ret === null) + return null; + + // console.log('loaded: ' + name.toString() + ' = ' + ret.toString()); + + return ret; + } + + function saveLocalStorage(name, value) { + // console.log('saving: ' + name.toString() + ' = ' + value.toString()); + try { + if(localStorageTest() === true) { + localStorage.setItem(name, value.toString()); + return true; + } + } + catch(error) { + console.log(error); + } + + return false; + } + + function getTheme(def) { + if(urlOptions.mode === 'print') + return 'white'; + + var ret = loadLocalStorage('netdataTheme'); + if(typeof ret === 'undefined' || ret === null || ret === 'undefined') + return def; + else + return ret; + } + + function setTheme(theme) { + if(urlOptions.mode === 'print') return false; + + if(theme === netdataTheme) return false; + return saveLocalStorage('netdataTheme', theme); + } + + var netdataTheme = getTheme('slate'); + var netdataShowHelp = true; + + if(urlOptions.theme !== null) { + setTheme(urlOptions.theme); + netdataTheme = urlOptions.theme; + } + else + urlOptions.theme = netdataTheme; + + if(urlOptions.help !== null) { + saveLocalStorage('options.show_help', urlOptions.help); + netdataShowHelp = urlOptions.help; + } + else { + urlOptions.help = loadLocalStorage('options.show_help'); + } + + // -------------------------------------------------------------------- + // natural sorting + // http://www.davekoelle.com/files/alphanum.js - LGPL + + function naturalSortChunkify(t) { + var tz = []; + var x = 0, y = -1, n = 0, i, j; + + while (i = (j = t.charAt(x++)).charCodeAt(0)) { + var m = (i >= 48 && i <= 57); + if (m !== n) { + tz[++y] = ""; + n = m; + } + tz[y] += j; + } + + return tz; + } + + function naturalSortCompare(a, b) { + var aa = naturalSortChunkify(a.toLowerCase()); + var bb = naturalSortChunkify(b.toLowerCase()); + + for (var x = 0; aa[x] && bb[x]; x++) { + if (aa[x] !== bb[x]) { + var c = Number(aa[x]), d = Number(bb[x]); + if (c.toString() === aa[x] && d.toString() === bb[x]) + return c - d; + else + return (aa[x] > bb[x]) ? 1 : -1; + } + } + + return aa.length - bb.length; + } + + // -------------------------------------------------------------------- + // saving files to client + + function saveTextToClient(data, filename) { + var blob = new Blob( [ data ], { + type: 'application/octet-stream' + }); + + var url = URL.createObjectURL( blob ); + var link = document.createElement( 'a' ); + link.setAttribute( 'href', url ); + link.setAttribute( 'download', filename ); + + var el = document.getElementById('hiddenDownloadLinks'); + el.innerHTML = ''; + el.appendChild(link); + + setTimeout(function(){ + el.removeChild(link); + URL.revokeObjectURL(url); + }, 60); + + link.click(); + } + + function saveObjectToClient(data, filename) { + saveTextToClient(JSON.stringify(data), filename); + } + + // -------------------------------------------------------------------- + // registry call back to render my-netdata menu + + var netdataRegistryCallback = function(machines_array) { + var el = ''; + var a1 = ''; + var found = 0, hosted = 0; + var len, i, url, hostname, icon; + + if(options.hosts.length > 1) { + // there are mirrored hosts here + + el += '<li><a href="#" onClick="return false;" style="color: #666;" target="_blank">databases available on this host</a></li>'; + a1 += '<li><a href="#" onClick="return false;"><i class="fas fa-info-circle" style="color: #666;"></i></a></li>'; |