chart updated etc

master
Ondřej Hruška 8 years ago
parent 3fcd234ad8
commit 04087f80de
  1. 3
      html_src/_end.php
  2. 89
      html_src/chart.php
  3. 42
      html_src/css/app.css
  4. 2
      html_src/css/app.css.map
  5. 12
      html_src/gulpfile.js
  6. 1
      html_src/home.php
  7. 242
      html_src/js-src/app.js
  8. 0
      html_src/js-src/lib/chartist.axis-title.js
  9. 10
      html_src/js-src/lib/chartist.js
  10. 0
      html_src/js-src/lib/chartist.zoom.js
  11. 0
      html_src/js-src/lib/chibi.js
  12. 40
      html_src/js-src/modal.js
  13. 72
      html_src/js-src/utils.js
  14. 92
      html_src/js-src/waveform.js
  15. 119
      html_src/js-src/wifi.js
  16. 613
      html_src/js/all.js
  17. 2
      html_src/js/all.js.map
  18. 1
      html_src/package.json-
  19. 2
      html_src/sass/form/_buttons.scss
  20. 6
      html_src/sass/form/_fancy_button_mixins.scss
  21. 10
      html_src/sass/layout/_base.scss
  22. 10
      html_src/sass/layout/_content.scss

@ -1,6 +1,3 @@
<script>
$().ready(initDef);
</script>
</div>
</div>
</body>

File diff suppressed because one or more lines are too long

@ -490,6 +490,14 @@ html, body {
height: 100%;
overflow: hidden; }
a, a:visited, a:link {
color: #5abfff;
text-decoration: none; }
a:hover {
color: #5abfff;
text-decoration: underline; }
/* Main outer container */
#outer {
display: flex;
@ -586,12 +594,6 @@ html, body {
@media screen and (max-width: 544px) {
#content {
padding: 0.6180469716rem; } }
#content a, #content a:visited, #content a:link {
color: #5abfff;
text-decoration: none; }
#content a:hover {
color: #5abfff;
text-decoration: underline; }
#content > * {
margin-left: auto;
margin-right: auto; }
@ -662,7 +664,7 @@ html, body {
box-shadow: 0 0 2px 0 #434349, 0 0 6px 0 black;
border-radius: 6px; }
button, input[type="button"], input[type="reset"], input[type="submit"], a.button {
button, input[type="button"], input[type="reset"], input[type="submit"], .button {
text-align: center;
cursor: pointer;
display: inline-block;
@ -687,16 +689,18 @@ button, input[type="button"], input[type="reset"], input[type="submit"], a.butto
margin-right: 0;
}*/
text-shadow: 1.5px 1.5px 2px rgba(0, 0, 0, 0.8); }
button:active, input[type="button"]:active, input[type="reset"]:active, input[type="submit"]:active, a.button:active {
button:active, input[type="button"]:active, input[type="reset"]:active, input[type="submit"]:active, .button:active {
position: relative;
top: 2px; }
button.narrow, input[type="button"].narrow, input[type="reset"].narrow, input[type="submit"].narrow, a.button.narrow {
button.narrow, input[type="button"].narrow, input[type="reset"].narrow, input[type="submit"].narrow, .button.narrow {
min-width: initial; }
input[type="submit"], .btn-green {
background-color: #2ca94b;
box-shadow: 0 3px 0 #1d7032;
color: #FEFEFE; }
text-decoration: none !important; }
input[type="submit"], input[type="submit"]:link, input[type="submit"]:visited, .btn-green, .btn-green:link, .btn-green:visited {
color: #FEFEFE; }
input[type="submit"]:hover, input[type="submit"]:active, input[type="submit"].active, input[type="submit"].selected, .btn-green:hover, .btn-green:active, .btn-green.active, .btn-green.selected {
background-color: #28ba5c;
color: #FEFEFE; }
@ -708,7 +712,9 @@ input[type="submit"], .btn-green {
input[type="reset"], .btn-red {
background-color: #D04E51;
box-shadow: 0 3px 0 #aa2d30;
color: #FEFEFE; }
text-decoration: none !important; }
input[type="reset"], input[type="reset"]:link, input[type="reset"]:visited, .btn-red, .btn-red:link, .btn-red:visited {
color: #FEFEFE; }
input[type="reset"]:hover, input[type="reset"]:active, input[type="reset"].active, input[type="reset"].selected, .btn-red:hover, .btn-red:active, .btn-red.active, .btn-red.selected {
background-color: #d4403f;
color: #FEFEFE; }
@ -757,7 +763,7 @@ input[type="reset"], .btn-red {
}
*/
button, input[type="button"], input[type="reset"], input[type="submit"], a.button {
button, input[type="button"], input[type="reset"], input[type="submit"], .button {
text-align: center;
cursor: pointer;
display: inline-block;
@ -782,16 +788,18 @@ button, input[type="button"], input[type="reset"], input[type="submit"], a.butto
margin-right: 0;
}*/
text-shadow: 1.5px 1.5px 2px rgba(0, 0, 0, 0.8); }
button:active, input[type="button"]:active, input[type="reset"]:active, input[type="submit"]:active, a.button:active {
button:active, input[type="button"]:active, input[type="reset"]:active, input[type="submit"]:active, .button:active {
position: relative;
top: 2px; }
button.narrow, input[type="button"].narrow, input[type="reset"].narrow, input[type="submit"].narrow, a.button.narrow {
button.narrow, input[type="button"].narrow, input[type="reset"].narrow, input[type="submit"].narrow, .button.narrow {
min-width: initial; }
input[type="submit"], .btn-green {
background-color: #2ca94b;
box-shadow: 0 3px 0 #1d7032;
color: #FEFEFE; }
text-decoration: none !important; }
input[type="submit"], input[type="submit"]:link, input[type="submit"]:visited, .btn-green, .btn-green:link, .btn-green:visited {
color: #FEFEFE; }
input[type="submit"]:hover, input[type="submit"]:active, input[type="submit"].active, input[type="submit"].selected, .btn-green:hover, .btn-green:active, .btn-green.active, .btn-green.selected {
background-color: #28ba5c;
color: #FEFEFE; }
@ -803,7 +811,9 @@ input[type="submit"], .btn-green {
input[type="reset"], .btn-red {
background-color: #D04E51;
box-shadow: 0 3px 0 #aa2d30;
color: #FEFEFE; }
text-decoration: none !important; }
input[type="reset"], input[type="reset"]:link, input[type="reset"]:visited, .btn-red, .btn-red:link, .btn-red:visited {
color: #FEFEFE; }
input[type="reset"]:hover, input[type="reset"]:active, input[type="reset"].active, input[type="reset"].selected, .btn-red:hover, .btn-red:active, .btn-red.active, .btn-red.selected {
background-color: #d4403f;
color: #FEFEFE; }

File diff suppressed because one or more lines are too long

@ -17,10 +17,14 @@ elixir(function (mix) {
// JS libs
mix.scripts([
'js-src/lib/chibi.js',
'js-src/lib/chartist.js',
'js-src/lib/chartist.axis-title.js',
'js-src/lib/chartist.zoom.js',
'js-src/utils.js',
'js-src/modal.js',
'js-src/app.js',
'js-src/chibi.js',
'js-src/chartist.js',
'js-src/chartist.axis-title.js',
'js-src/chartist.zoom.js',
'js-src/wifi.js',
'js-src/waveform.js',
], 'js/all.js');
});

@ -70,6 +70,7 @@
$('#rssi-dbm').html(staRSSI);
}
// TODO use json + ajax instead
setTimeout(function(){location.reload()}, 10000);
});
</script>

@ -1,241 +1,15 @@
function bool(x) {
return (x === 1 || x === '1' || x === true || x === 'true');
}
// requires other modules...
/** html entities */
function e(x) {
return String(x)
.replace(/&/g, '&amp;')
.replace(/"/g, '&quot;')
.replace(/'/g, '&#39;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;');
}
// - utils.js
// - modal.js
// - wifi.js
/** Returns true if argument is array [] */
function isArray(obj) {
return Object.prototype.toString.call(obj) === '[object Array]';
}
/** Returns true if argument is object {} */
function isObject(obj) {
return Object.prototype.toString.call(obj) === '[object Object]';
}
/** escape a string to have no special meaning in regex */
function regexEscape(s) {
return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
}
/** Convert RSSI 0-255 to % */
function rssiPerc(rssi) {
var r = parseInt(rssi);
if (r > -50) return 100; // 100%
if (r < -100) return 0; // 0%
return Math.round(2 * (r + 100)); // approximation
}
/** Perform a substitution in the given string.
*
* Arguments - array or list of replacements.
* Arguments numeric keys will replace {0}, {1} etc.
* Named keys also work, ie. {foo: "bar"} -> replaces {foo} with bar.
*
* Braces are added to keys if missing.
*
* @returns {String} result
*/
String.prototype.format = function () {
var out = this;
var repl = arguments;
if (arguments.length == 1 && (isArray(arguments[0]) || isObject(arguments[0]))) {
repl = arguments[0];
}
for (var ph in repl) {
if (repl.hasOwnProperty(ph)) {
var ph_orig = ph;
if (!ph.match(/^\{.*\}$/)) {
ph = '{' + ph + '}';
}
// replace all occurrences
var pattern = new RegExp(regexEscape(ph), "g");
out = out.replace(pattern, repl[ph_orig]);
}
}
return out;
};
/** Module for toggling a modal overlay */
var modal = (function () {
var modal = {};
modal.show = function (sel) {
var $m = $(sel);
$m.removeClass('hidden visible');
setTimeout(function () {
$m.addClass('visible');
}, 1);
};
modal.hide = function (sel) {
var $m = $(sel);
$m.removeClass('visible');
setTimeout(function () {
$m.addClass('hidden');
}, 500); // transition time
};
modal.init = function () {
// close modal by click outside the dialog
$('.Modal').on('click', function () {
modal.hide(this);
});
$('.Dialog').on('click', function (e) {
e.stopImmediatePropagation();
});
// Hide all modals on esc
$(window).on('keydown', function (e) {
if (e.which == 27) {
modal.hide('.Modal');
}
});
};
return modal;
})();
/** Wifi page */
var wifi = (function () {
var wifi = {};
var authStr = ['Open', 'WEP', 'WPA', 'WPA2', 'WPA/WPA2'];
/** Update display for received response */
function onScan(resp, status) {
if (status != 200) {
// bad response
rescan(5000); // wait 5sm then retry
return;
}
resp = JSON.parse(resp);
var done = !bool(resp.result.inProgress) && (resp.result.APs.length > 0);
rescan(done ? 15000 : 1000);
if (!done) return; // no redraw yet
// clear the AP list
var $list = $('#ap-list');
// remove old APs
$('.AP').remove();
$list.toggle(done);
$('#ap-loader').toggle(!done);
// scan done
resp.result.APs
.sort(function (a, b) {
return b.rssi - a.rssi
})
.forEach(function (ap) {
ap.enc = parseInt(ap.enc);
if (ap.enc > 4) return; // hide unsupported auths
var item = document.createElement('div');
var $item = $(item)
.data('ssid', ap.essid)
.data('pwd', ap.enc != 0)
.addClass('AP');
// mark current SSID
if (ap.essid == wifi.current) {
$item.addClass('selected');
}
var inner = document.createElement('div');
var $inner = $(inner).addClass('inner')
.htmlAppend('<div class="rssi">{0}</div>'.format(rssiPerc(ap.rssi)))
.htmlAppend('<div class="essid" title="{0}">{0}</div>'.format(e(ap.essid)))
.htmlAppend('<div class="auth">{0}</div>'.format(authStr[ap.enc]));
$item.on('click', function () {
var $th = $(this);
// populate the form
$('#conn-essid').val($th.data('ssid'));
$('#conn-passwd').val(''); // clear
if ($th.data('pwd')) {
// this AP needs a password
modal.show('#psk-modal');
} else {
$('#conn-form').submit();
}
});
item.appendChild(inner);
$list[0].appendChild(item);
});
}
/** Ask the CGI what APs are visible (async) */
function scanAPs() {
$().get('/wifi/scan.cgi', onScan, true, true); // no cache, no jsonp
}
function rescan(time) {
setTimeout(scanAPs, time);
}
/** Set up the WiFi page */
wifi.init = function () {
//var ap_json = {
// "result": {
// "inProgress": "0",
// "APs": [
// {"essid": "Chlivek", "bssid": "88:f7:c7:52:b3:99", "rssi": "204", "enc": "4", "channel": "1"},
// {"essid": "TyNikdy", "bssid": "5c:f4:ab:0d:f1:1b", "rssi": "164", "enc": "3", "channel": "1"},
// {"essid": "UPC5616805", "bssid": "08:95:2a:0c:84:3f", "rssi": "164", "enc": "4", "channel": "1"},
// {"essid": "Sitovina", "bssid": "20:cf:30:98:cb:3a", "rssi": "166", "enc": "3", "channel": "1"},
// {"essid": "Tramp", "bssid": "c4:e9:84:6f:6c:e0", "rssi": "170", "enc": "3", "channel": "2"},
// {"essid": "KV2", "bssid": "4c:5e:0c:2c:84:9b", "rssi": "172", "enc": "3", "channel": "3"},
// {"essid": "UPC373123", "bssid": "e8:40:f2:ae:0e:f4", "rssi": "164", "enc": "3", "channel": "1"},
// {"essid": "www.podoli.org prazak", "bssid": "00:00:00:00:00:00", "rssi": "165", "enc": "0", "channel": "4"},
// {"essid": "Medvjedov", "bssid": "00:00:00:00:00:00", "rssi": "181", "enc": "4", "channel": "6"},
// {"essid": "MARIAN-PC", "bssid": "f8:d1:11:af:d7:72", "rssi": "175", "enc": "3", "channel": "6"},
// {"essid": "UPC3226244", "bssid": "64:7c:34:9a:6f:7c", "rssi": "169", "enc": "4", "channel": "6"},
// {"essid": "molly", "bssid": "00:00:00:00:00:00", "rssi": "168", "enc": "3", "channel": "7"},
// {"essid": "UPC2607759", "bssid": "88:f7:c7:4e:c1:b2", "rssi": "164", "enc": "4", "channel": "8"},
// {"essid": "blondyna", "bssid": "98:fc:11:bd:0f:b8", "rssi": "166", "enc": "4", "channel": "9"},
// {"essid": "UPC246587811", "bssid": "80:f5:03:20:6c:85", "rssi": "171", "enc": "3", "channel": "11"},
// {"essid": "UPC930648", "bssid": "4c:72:b9:50:6d:38", "rssi": "167", "enc": "3", "channel": "11"},
// {"essid": "PRAHA4.NET-R21-2", "bssid": "00:00:00:00:00:00", "rssi": "173", "enc": "0", "channel": "12"},
// {"essid": "Internet_B0", "bssid": "5c:f4:ab:11:3b:b3", "rssi": "166", "enc": "3", "channel": "13"}
// ]
// }
//};
//onScan(ap_json, 200);
scanAPs();
};
return wifi;
})();
// all must be included after 3rd party libs
/** Global generic init */
function initDef() {
$().ready(function () {
// loader dots...
setInterval(function () {
$('.anim-dots').each(function (x) {
@ -247,4 +21,4 @@ function initDef() {
}, 1000);
modal.init();
}
});

@ -906,19 +906,23 @@ var Chartist = {
positionalData[axis.units.len] = length;
positionalData[axis.counterUnits.len] = axisOffset - 10;
var lblText = labels[index];
//round (!! will brak for non-numeric)
lblText = Math.round(+lblText*100)/100;
if(useForeignObject) {
// We need to set width and height explicitly to px as span will not expand with width and height being
// 100% in all browsers
var content = '<span class="' + classes.join(' ') + '" style="' +
axis.units.len + ': ' + Math.round(positionalData[axis.units.len]) + 'px; ' +
axis.counterUnits.len + ': ' + Math.round(positionalData[axis.counterUnits.len]) + 'px">' +
labels[index] + '</span>';
lblText + '</span>';
labelElement = group.foreignObject(content, Chartist.extend({
style: 'overflow: visible;'
}, positionalData));
} else {
labelElement = group.elem('text', positionalData, classes.join(' ')).text(labels[index]);
labelElement = group.elem('text', positionalData, classes.join(' ')).text(lblText);
}
eventEmitter.emit('draw', Chartist.extend({
@ -927,7 +931,7 @@ var Chartist = {
index: index,
group: group,
element: labelElement,
text: labels[index]
text: lblText
}, positionalData));
};

@ -0,0 +1,40 @@
/** Module for toggling a modal overlay */
var modal = (function () {
var modal = {};
modal.show = function (sel) {
var $m = $(sel);
$m.removeClass('hidden visible');
setTimeout(function () {
$m.addClass('visible');
}, 1);
};
modal.hide = function (sel) {
var $m = $(sel);
$m.removeClass('visible');
setTimeout(function () {
$m.addClass('hidden');
}, 500); // transition time
};
modal.init = function () {
// close modal by click outside the dialog
$('.Modal').on('click', function () {
modal.hide(this);
});
$('.Dialog').on('click', function (e) {
e.stopImmediatePropagation();
});
// Hide all modals on esc
$(window).on('keydown', function (e) {
if (e.which == 27) {
modal.hide('.Modal');
}
});
};
return modal;
})();

@ -0,0 +1,72 @@
function bool(x) {
return (x === 1 || x === '1' || x === true || x === 'true');
}
/** html entities */
function e(x) {
return String(x)
.replace(/&/g, '&amp;')
.replace(/"/g, '&quot;')
.replace(/'/g, '&#39;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;');
}
/** Returns true if argument is array [] */
function isArray(obj) {
return Object.prototype.toString.call(obj) === '[object Array]';
}
/** Returns true if argument is object {} */
function isObject(obj) {
return Object.prototype.toString.call(obj) === '[object Object]';
}
/** escape a string to have no special meaning in regex */
function regexEscape(s) {
return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
}
/** Convert RSSI 0-255 to % */
function rssiPerc(rssi) {
var r = parseInt(rssi);
if (r > -50) return 100; // 100%
if (r < -100) return 0; // 0%
return Math.round(2 * (r + 100)); // approximation
}
/** Perform a substitution in the given string.
*
* Arguments - array or list of replacements.
* Arguments numeric keys will replace {0}, {1} etc.
* Named keys also work, ie. {foo: "bar"} -> replaces {foo} with bar.
*
* Braces are added to keys if missing.
*
* @returns {String} result
*/
String.prototype.format = function () {
var out = this;
var repl = arguments;
if (arguments.length == 1 && (isArray(arguments[0]) || isObject(arguments[0]))) {
repl = arguments[0];
}
for (var ph in repl) {
if (repl.hasOwnProperty(ph)) {
var ph_orig = ph;
if (!ph.match(/^\{.*\}$/)) {
ph = '{' + ph + '}';
}
// replace all occurrences
var pattern = new RegExp(regexEscape(ph), "g");
out = out.replace(pattern, repl[ph_orig]);
}
}
return out;
};

@ -0,0 +1,92 @@
var wfm = (function () {
var wfm = {};
function buildChart(samples, xlabel, ylabel) {
var data = [];
samples.forEach(function (a, i) {
data.push({x: i, y: a});
});
// Build the chart
var plugins = [];
var mql = window.matchMedia('screen and (min-width: 544px)');
var isPhone = !mql.matches;
if (!isPhone) {
// larger than phone
plugins.push(
Chartist.plugins.ctAxisTitle({
axisX: {
axisTitle: xlabel,
offset: {
x: 0,
y: 55
}
},
axisY: {
axisTitle: ylabel,
flipText: true,
offset: {
x: 0,
y: 15
}
}
})
);
}
new Chartist.Line('#chart', {
series: [
{
name: 'a',
data: data
},
]
}, {
showPoint: false,
// showArea: true,
fullWidth: true,
chartPadding: (isPhone ? {right: 20, bottom: 5, left: 0} : {right: 25, bottom: 30, left: 25}),
series: {
'a': {
lineSmooth: Chartist.Interpolation.none()
}
},
axisX: {
type: Chartist.AutoScaleAxis,
onlyInteger: true
},
axisY: {
type: Chartist.AutoScaleAxis,
//onlyInteger: true
},
plugins: plugins
});
}
function onRxData(resp, status) {
if (status != 200) {
// bad response
alert("Request failed.");
return;
}
var json = JSON.parse(resp);
if (!json.success) {
alert("Sampling failed.");
return;
}
buildChart(resp.samples, 'Sample Nr.', 'ADC value');
}
wfm.init = function() {
$('#load').on('click', function() {
var samples = $('#count').val();
$().get('http://192.168.1.13/api/raw.json?count='+samples, onRxData, true, true);
});
};
return wfm;
})();

@ -0,0 +1,119 @@
/** Wifi page */
var wifi = (function () {
var wifi = {};
var authStr = ['Open', 'WEP', 'WPA', 'WPA2', 'WPA/WPA2'];
/** Update display for received response */
function onScan(resp, status) {
if (status != 200) {
// bad response
rescan(5000); // wait 5sm then retry
return;
}
resp = JSON.parse(resp);
var done = !bool(resp.result.inProgress) && (resp.result.APs.length > 0);
rescan(done ? 15000 : 1000);
if (!done) return; // no redraw yet
// clear the AP list
var $list = $('#ap-list');
// remove old APs
$('.AP').remove();
$list.toggle(done);
$('#ap-loader').toggle(!done);
// scan done
resp.result.APs
.sort(function (a, b) {
return b.rssi - a.rssi
})
.forEach(function (ap) {
ap.enc = parseInt(ap.enc);
if (ap.enc > 4) return; // hide unsupported auths
var item = document.createElement('div');
var $item = $(item)
.data('ssid', ap.essid)
.data('pwd', ap.enc != 0)
.addClass('AP');
// mark current SSID
if (ap.essid == wifi.current) {
$item.addClass('selected');
}
var inner = document.createElement('div');
var $inner = $(inner).addClass('inner')
.htmlAppend('<div class="rssi">{0}</div>'.format(rssiPerc(ap.rssi)))
.htmlAppend('<div class="essid" title="{0}">{0}</div>'.format(e(ap.essid)))
.htmlAppend('<div class="auth">{0}</div>'.format(authStr[ap.enc]));
$item.on('click', function () {
var $th = $(this);
// populate the form
$('#conn-essid').val($th.data('ssid'));
$('#conn-passwd').val(''); // clear
if ($th.data('pwd')) {
// this AP needs a password
modal.show('#psk-modal');
} else {
$('#conn-form').submit();
}
});
item.appendChild(inner);
$list[0].appendChild(item);
});
}
/** Ask the CGI what APs are visible (async) */
function scanAPs() {
$().get('/wifi/scan.cgi', onScan, true, true); // no cache, no jsonp
}
function rescan(time) {
setTimeout(scanAPs, time);
}
/** Set up the WiFi page */
wifi.init = function () {
//var ap_json = {
// "result": {
// "inProgress": "0",
// "APs": [
// {"essid": "Chlivek", "bssid": "88:f7:c7:52:b3:99", "rssi": "204", "enc": "4", "channel": "1"},
// {"essid": "TyNikdy", "bssid": "5c:f4:ab:0d:f1:1b", "rssi": "164", "enc": "3", "channel": "1"},
// {"essid": "UPC5616805", "bssid": "08:95:2a:0c:84:3f", "rssi": "164", "enc": "4", "channel": "1"},
// {"essid": "Sitovina", "bssid": "20:cf:30:98:cb:3a", "rssi": "166", "enc": "3", "channel": "1"},
// {"essid": "Tramp", "bssid": "c4:e9:84:6f:6c:e0", "rssi": "170", "enc": "3", "channel": "2"},
// {"essid": "KV2", "bssid": "4c:5e:0c:2c:84:9b", "rssi": "172", "enc": "3", "channel": "3"},
// {"essid": "UPC373123", "bssid": "e8:40:f2:ae:0e:f4", "rssi": "164", "enc": "3", "channel": "1"},
// {"essid": "www.podoli.org prazak", "bssid": "00:00:00:00:00:00", "rssi": "165", "enc": "0", "channel": "4"},
// {"essid": "Medvjedov", "bssid": "00:00:00:00:00:00", "rssi": "181", "enc": "4", "channel": "6"},
// {"essid": "MARIAN-PC", "bssid": "f8:d1:11:af:d7:72", "rssi": "175", "enc": "3", "channel": "6"},
// {"essid": "UPC3226244", "bssid": "64:7c:34:9a:6f:7c", "rssi": "169", "enc": "4", "channel": "6"},
// {"essid": "molly", "bssid": "00:00:00:00:00:00", "rssi": "168", "enc": "3", "channel": "7"},
// {"essid": "UPC2607759", "bssid": "88:f7:c7:4e:c1:b2", "rssi": "164", "enc": "4", "channel": "8"},
// {"essid": "blondyna", "bssid": "98:fc:11:bd:0f:b8", "rssi": "166", "enc": "4", "channel": "9"},
// {"essid": "UPC246587811", "bssid": "80:f5:03:20:6c:85", "rssi": "171", "enc": "3", "channel": "11"},
// {"essid": "UPC930648", "bssid": "4c:72:b9:50:6d:38", "rssi": "167", "enc": "3", "channel": "11"},
// {"essid": "PRAHA4.NET-R21-2", "bssid": "00:00:00:00:00:00", "rssi": "173", "enc": "0", "channel": "12"},
// {"essid": "Internet_B0", "bssid": "5c:f4:ab:11:3b:b3", "rssi": "166", "enc": "3", "channel": "13"}
// ]
// }
//};
//onScan(ap_json, 200);
scanAPs();
};
return wifi;
})();

@ -1,254 +1,3 @@
function bool(x) {
return (x === 1 || x === '1' || x === true || x === 'true');
}
/** html entities */
function e(x) {
return String(x)
.replace(/&/g, '&amp;')
.replace(/"/g, '&quot;')
.replace(/'/g, '&#39;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;');
}
/** Returns true if argument is array [] */
function isArray(obj) {
return Object.prototype.toString.call(obj) === '[object Array]';
}
/** Returns true if argument is object {} */
function isObject(obj) {
return Object.prototype.toString.call(obj) === '[object Object]';
}
/** escape a string to have no special meaning in regex */
function regexEscape(s) {
return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
}
/** Convert RSSI 0-255 to % */
function rssiPerc(rssi) {
var r = parseInt(rssi);
if (r > -50) return 100; // 100%
if (r < -100) return 0; // 0%
return Math.round(2 * (r + 100)); // approximation
}
/** Perform a substitution in the given string.
*
* Arguments - array or list of replacements.
* Arguments numeric keys will replace {0}, {1} etc.
* Named keys also work, ie. {foo: "bar"} -> replaces {foo} with bar.
*
* Braces are added to keys if missing.
*
* @returns {String} result
*/
String.prototype.format = function () {
var out = this;
var repl = arguments;
if (arguments.length == 1 && (isArray(arguments[0]) || isObject(arguments[0]))) {
repl = arguments[0];
}
for (var ph in repl) {
if (repl.hasOwnProperty(ph)) {
var ph_orig = ph;
if (!ph.match(/^\{.*\}$/)) {
ph = '{' + ph + '}';
}
// replace all occurrences
var pattern = new RegExp(regexEscape(ph), "g");
out = out.replace(pattern, repl[ph_orig]);
}
}
return out;
};
/** Module for toggling a modal overlay */
var modal = (function () {
var modal = {};
modal.show = function (sel) {
var $m = $(sel);
$m.removeClass('hidden visible');
setTimeout(function () {
$m.addClass('visible');
}, 1);
};
modal.hide = function (sel) {
var $m = $(sel);
$m.removeClass('visible');
setTimeout(function () {
$m.addClass('hidden');
}, 500); // transition time
};
modal.init = function () {
// close modal by click outside the dialog
$('.Modal').on('click', function () {
modal.hide(this);
});
$('.Dialog').on('click', function (e) {
e.stopImmediatePropagation();
});
// Hide all modals on esc
$(window).on('keydown', function (e) {
if (e.which == 27) {
modal.hide('.Modal');
}
});
};
return modal;
})();
/** Wifi page */
var wifi = (function () {
var wifi = {};
var authStr = ['Open', 'WEP', 'WPA', 'WPA2', 'WPA/WPA2'];
/** Update display for received response */
function onScan(resp, status) {
if (status != 200) {
// bad response
rescan(5000); // wait 5sm then retry
return;
}
resp = JSON.parse(resp);
var done = !bool(resp.result.inProgress) && (resp.result.APs.length > 0);
rescan(done ? 15000 : 1000);
if (!done) return; // no redraw yet
// clear the AP list
var $list = $('#ap-list');
// remove old APs
$('.AP').remove();
$list.toggle(done);
$('#ap-loader').toggle(!done);
// scan done
resp.result.APs
.sort(function (a, b) {
return b.rssi - a.rssi
})
.forEach(function (ap) {
ap.enc = parseInt(ap.enc);
if (ap.enc > 4) return; // hide unsupported auths
var item = document.createElement('div');
var $item = $(item)
.data('ssid', ap.essid)
.data('pwd', ap.enc != 0)
.addClass('AP');
// mark current SSID
if (ap.essid == wifi.current) {
$item.addClass('selected');
}
var inner = document.createElement('div');
var $inner = $(inner).addClass('inner')
.htmlAppend('<div class="rssi">{0}</div>'.format(rssiPerc(ap.rssi)))
.htmlAppend('<div class="essid" title="{0}">{0}</div>'.format(e(ap.essid)))
.htmlAppend('<div class="auth">{0}</div>'.format(authStr[ap.enc]));
$item.on('click', function () {
var $th = $(this);
// populate the form
$('#conn-essid').val($th.data('ssid'));
$('#conn-passwd').val(''); // clear
if ($th.data('pwd')) {
// this AP needs a password
modal.show('#psk-modal');
} else {
$('#conn-form').submit();
}
});
item.appendChild(inner);
$list[0].appendChild(item);
});
}
/** Ask the CGI what APs are visible (async) */
function scanAPs() {
$().get('/wifi/scan.cgi', onScan, true, true); // no cache, no jsonp
}
function rescan(time) {
setTimeout(scanAPs, time);
}
/** Set up the WiFi page */
wifi.init = function () {
//var ap_json = {
// "result": {
// "inProgress": "0",
// "APs": [
// {"essid": "Chlivek", "bssid": "88:f7:c7:52:b3:99", "rssi": "204", "enc": "4", "channel": "1"},
// {"essid": "TyNikdy", "bssid": "5c:f4:ab:0d:f1:1b", "rssi": "164", "enc": "3", "channel": "1"},
// {"essid": "UPC5616805", "bssid": "08:95:2a:0c:84:3f", "rssi": "164", "enc": "4", "channel": "1"},
// {"essid": "Sitovina", "bssid": "20:cf:30:98:cb:3a", "rssi": "166", "enc": "3", "channel": "1"},
// {"essid": "Tramp", "bssid": "c4:e9:84:6f:6c:e0", "rssi": "170", "enc": "3", "channel": "2"},
// {"essid": "KV2", "bssid": "4c:5e:0c:2c:84:9b", "rssi": "172", "enc": "3", "channel": "3"},
// {"essid": "UPC373123", "bssid": "e8:40:f2:ae:0e:f4", "rssi": "164", "enc": "3", "channel": "1"},
// {"essid": "www.podoli.org prazak", "bssid": "00:00:00:00:00:00", "rssi": "165", "enc": "0", "channel": "4"},
// {"essid": "Medvjedov", "bssid": "00:00:00:00:00:00", "rssi": "181", "enc": "4", "channel": "6"},
// {"essid": "MARIAN-PC", "bssid": "f8:d1:11:af:d7:72", "rssi": "175", "enc": "3", "channel": "6"},
// {"essid": "UPC3226244", "bssid": "64:7c:34:9a:6f:7c", "rssi": "169", "enc": "4", "channel": "6"},
// {"essid": "molly", "bssid": "00:00:00:00:00:00", "rssi": "168", "enc": "3", "channel": "7"},
// {"essid": "UPC2607759", "bssid": "88:f7:c7:4e:c1:b2", "rssi": "164", "enc": "4", "channel": "8"},
// {"essid": "blondyna", "bssid": "98:fc:11:bd:0f:b8", "rssi": "166", "enc": "4", "channel": "9"},
// {"essid": "UPC246587811", "bssid": "80:f5:03:20:6c:85", "rssi": "171", "enc": "3", "channel": "11"},
// {"essid": "UPC930648", "bssid": "4c:72:b9:50:6d:38", "rssi": "167", "enc": "3", "channel": "11"},
// {"essid": "PRAHA4.NET-R21-2", "bssid": "00:00:00:00:00:00", "rssi": "173", "enc": "0", "channel": "12"},
// {"essid": "Internet_B0", "bssid": "5c:f4:ab:11:3b:b3", "rssi": "166", "enc": "3", "channel": "13"}
// ]
// }
//};
//onScan(ap_json, 200);
scanAPs();
};
return wifi;
})();
/** Global generic init */
function initDef() {
// loader dots...
setInterval(function () {
$('.anim-dots').each(function (x) {
var $x = $(x);
var dots = $x.html() + '.';
if (dots.length == 5) dots = '.';
$x.html(dots);
});
}, 1000);
modal.init();
}
/*!chibi 3.0.7, Copyright 2012-2016 Kyle Barrow, released under MIT license */
(function () {
'use strict';
@ -1864,19 +1613,23 @@ var Chartist = {
positionalData[axis.units.len] = length;
positionalData[axis.counterUnits.len] = axisOffset - 10;
var lblText = labels[index];
//round (!! will brak for non-numeric)
lblText = Math.round(+lblText*100)/100;
if(useForeignObject) {
// We need to set width and height explicitly to px as span will not expand with width and height being
// 100% in all browsers
var content = '<span class="' + classes.join(' ') + '" style="' +
axis.units.len + ': ' + Math.round(positionalData[axis.units.len]) + 'px; ' +
axis.counterUnits.len + ': ' + Math.round(positionalData[axis.counterUnits.len]) + 'px">' +
labels[index] + '</span>';
lblText + '</span>';
labelElement = group.foreignObject(content, Chartist.extend({
style: 'overflow: visible;'
}, positionalData));
} else {
labelElement = group.elem('text', positionalData, classes.join(' ')).text(labels[index]);
labelElement = group.elem('text', positionalData, classes.join(' ')).text(lblText);
}
eventEmitter.emit('draw', Chartist.extend({
@ -1885,7 +1638,7 @@ var Chartist = {
index: index,
group: group,
element: labelElement,
text: labels[index]
text: lblText
}, positionalData));
};
@ -5174,4 +4927,356 @@ return Chartist;
}));
function bool(x) {
return (x === 1 || x === '1' || x === true || x === 'true');
}
/** html entities */
function e(x) {
return String(x)
.replace(/&/g, '&amp;')
.replace(/"/g, '&quot;')
.replace(/'/g, '&#39;')
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;');
}
/** Returns true if argument is array [] */
function isArray(obj) {
return Object.prototype.toString.call(obj) === '[object Array]';
}
/** Returns true if argument is object {} */
function isObject(obj) {
return Object.prototype.toString.call(obj) === '[object Object]';
}
/** escape a string to have no special meaning in regex */
function regexEscape(s) {
return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
}
/** Convert RSSI 0-255 to % */
function rssiPerc(rssi) {
var r = parseInt(rssi);
if (r > -50) return 100; // 100%
if (r < -100) return 0; // 0%
return Math.round(2 * (r + 100)); // approximation
}
/** Perform a substitution in the given string.
*
* Arguments - array or list of replacements.
* Arguments numeric keys will replace {0}, {1} etc.
* Named keys also work, ie. {foo: "bar"} -> replaces {foo} with bar.
*
* Braces are added to keys if missing.
*
* @returns {String} result
*/
String.prototype.format = function () {
var out = this;
var repl = arguments;
if (arguments.length == 1 && (isArray(arguments[0]) || isObject(arguments[0]))) {
repl = arguments[0];
}
for (var ph in repl) {
if (repl.hasOwnProperty(ph)) {
var ph_orig = ph;
if (!ph.match(/^\{.*\}$/)) {
ph = '{' + ph + '}';
}
// replace all occurrences
var pattern = new RegExp(regexEscape(ph), "g");
out = out.replace(pattern, repl[ph_orig]);
}
}
return out;
};
/** Module for toggling a modal overlay */
var modal = (function () {
var modal = {};
modal.show = function (sel) {
var $m = $(sel);
$m.removeClass('hidden visible');
setTimeout(function () {
$m.addClass('visible');
}, 1);
};
modal.hide = function (sel) {
var $m = $(sel);
$m.removeClass('visible');
setTimeout(function () {
$m.addClass('hidden');
}, 500); // transition time
};
modal.init = function () {
// close modal by click outside the dialog
$('.Modal').on('click', function () {
modal.hide(this);
});
$('.Dialog').on('click', function (e) {
e.stopImmediatePropagation();
});
// Hide all modals on esc
$(window).on('keydown', function (e) {
if (e.which == 27) {
modal.hide('.Modal');
}
});
};
return modal;
})();
// requires other modules...
// - utils.js
// - modal.js
// - wifi.js
// all must be included after 3rd party libs
/** Global generic init */
$().ready(function () {
// loader dots...
setInterval(function () {
$('.anim-dots').each(function (x) {
var $x = $(x);
var dots = $x.html() + '.';
if (dots.length == 5) dots = '.';
$x.html(dots);
});
}, 1000);
modal.init();
});
/** Wifi page */
var wifi = (function () {
var wifi = {};
var authStr = ['Open', 'WEP', 'WPA', 'WPA2', 'WPA/WPA2'];
/** Update display for received response */
function onScan(resp, status) {
if (status != 200) {
// bad response
rescan(5000); // wait 5sm then retry
return;
}
resp = JSON.parse(resp);
var done = !bool(resp.result.inProgress) && (resp.result.APs.length > 0);
rescan(done ? 15000 : 1000);
if (!done) return; // no redraw yet
// clear the AP list
var $list = $('#ap-list');
// remove old APs
$('.AP').remove();
$list.toggle(done);
$('#ap-loader').toggle(!done);
// scan done
resp.result.APs
.sort(function (a, b) {
return b.rssi - a.rssi
})
.forEach(function (ap) {
ap.enc = parseInt(ap.enc);
if (ap.enc > 4) return; // hide unsupported auths
var item = document.createElement('div');
var $item = $(item)
.data('ssid', ap.essid)
.data('pwd', ap.enc != 0)
.addClass('AP');
// mark current SSID
if (ap.essid == wifi.current) {
$item.addClass('selected');
}
var inner = document.createElement('div');
var $inner = $(inner).addClass('inner')
.htmlAppend('<div class="rssi">{0}</div>'.format(rssiPerc(ap.rssi)))
.htmlAppend('<div class="essid" title="{0}">{0}</div>'.format(e(ap.essid)))
.htmlAppend('<div class="auth">{0}</div>'.format(authStr[ap.enc]));
$item.on('click', function () {
var $th = $(this);
// populate the form
$('#conn-essid').val($th.data('ssid'));
$('#conn-passwd').val(''); // clear
if ($th.data('pwd')) {
// this AP needs a password
modal.show('#psk-modal');
} else {
$('#conn-form').submit();
}
});
item.appendChild(inner);
$list[0].appendChild(item);
});
}
/** Ask the CGI what APs are visible (async) */
function scanAPs() {
$().get('/wifi/scan.cgi', onScan, true, true); // no cache, no jsonp
}
function rescan(time) {
setTimeout(scanAPs, time);
}
/** Set up the WiFi page */
wifi.init = function () {
//var ap_json = {
// "result": {
// "inProgress": "0",
// "APs": [
// {"essid": "Chlivek", "bssid": "88:f7:c7:52:b3:99", "rssi": "204", "enc": "4", "channel": "1"},
// {"essid": "TyNikdy", "bssid": "5c:f4:ab:0d:f1:1b", "rssi": "164", "enc": "3", "channel": "1"},
// {"essid": "UPC5616805", "bssid": "08:95:2a:0c:84:3f", "rssi": "164", "enc": "4", "channel": "1"},
// {"essid": "Sitovina", "bssid": "20:cf:30:98:cb:3a", "rssi": "166", "enc": "3", "channel": "1"},
// {"essid": "Tramp", "bssid": "c4:e9:84:6f:6c:e0", "rssi": "170", "enc": "3", "channel": "2"},
// {"essid": "KV2", "bssid": "4c:5e:0c:2c:84:9b", "rssi": "172", "enc": "3", "channel": "3"},
// {"essid": "UPC373123", "bssid": "e8:40:f2:ae:0e:f4", "rssi": "164", "enc": "3", "channel": "1"},
// {"essid": "www.podoli.org prazak", "bssid": "00:00:00:00:00:00", "rssi": "165", "enc": "0", "channel": "4"},
// {"essid": "Medvjedov", "bssid": "00:00:00:00:00:00", "rssi": "181", "enc": "4", "channel": "6"},
// {"essid": "MARIAN-PC", "bssid": "f8:d1:11:af:d7:72", "rssi": "175", "enc": "3", "channel": "6"},
// {"essid": "UPC3226244", "bssid": "64:7c:34:9a:6f:7c", "rssi": "169", "enc": "4", "channel": "6"},
// {"essid": "molly", "bssid": "00:00:00:00:00:00", "rssi": "168", "enc": "3", "channel": "7"},
// {"essid": "UPC2607759", "bssid": "88:f7:c7:4e:c1:b2", "rssi": "164", "enc": "4", "channel": "8"},
// {"essid": "blondyna", "bssid": "98:fc:11:bd:0f:b8", "rssi": "166", "enc": "4", "channel": "9"},
// {"essid": "UPC246587811", "bssid": "80:f5:03:20:6c:85", "rssi": "171", "enc": "3", "channel": "11"},
// {"essid": "UPC930648", "bssid": "4c:72:b9:50:6d:38", "rssi": "167", "enc": "3", "channel": "11"},
// {"essid": "PRAHA4.NET-R21-2", "bssid": "00:00:00:00:00:00", "rssi": "173", "enc": "0", "channel": "12"},
// {"essid": "Internet_B0", "bssid": "5c:f4:ab:11:3b:b3", "rssi": "166", "enc": "3", "channel": "13"}
// ]
// }
//};
//onScan(ap_json, 200);
scanAPs();
};
return wifi;
})();