Browse Source

more crap

Former-commit-id: 6c97ad16f16e48f56fea7a007d5d8136c51a268c
master
Ondřej Hruška 6 years ago
parent
commit
f77caa03f2
  1. 7
      _web-build_do.sh
  2. 161
      esp_f105motor.pro
  3. 167
      esp_meas.pro
  4. 2
      html/css/app.css
  5. 4
      html/js/all.js
  6. 77
      html/pages/about.tpl
  7. 102
      html/pages/fft.html
  8. 49
      html/pages/home.tpl
  9. 102
      html/pages/monitoring.tpl
  10. 79
      html/pages/sgm.html
  11. 128
      html/pages/status.tpl
  12. 91
      html/pages/wfm.html
  13. 6
      html/pages/wifi.tpl
  14. 12
      html_src/_start.php
  15. 2
      html_src/css/app.css
  16. 11
      html_src/gulpfile.js
  17. 2
      html_src/js-src/lib/chibi.js
  18. 285
      html_src/js-src/lib/lodash.custom.js
  19. 11
      html_src/js-src/page_home.js
  20. 91
      html_src/js-src/page_mon.js
  21. 356
      html_src/js-src/page_spectrogram.js
  22. 88
      html_src/js-src/page_status.js
  23. 271
      html_src/js-src/page_waveform.js
  24. 4
      html_src/js/all.js
  25. 1
      html_src/node_modules.tar.REMOVED.git-id
  26. 48
      html_src/page_about.php
  27. 73
      html_src/page_fft.php
  28. 21
      html_src/page_home.php
  29. 73
      html_src/page_monitoring.php
  30. 50
      html_src/page_spectrogram.php
  31. 99
      html_src/page_status.php
  32. 62
      html_src/page_waveform.php
  33. 3
      html_src/page_wifi.php
  34. 8
      html_src/sass/app.scss
  35. 4
      html_src/sass/layout/_menu.scss
  36. 17
      html_src/sass/pages/_about.scss
  37. 24
      html_src/sass/pages/_home.scss
  38. 101
      html_src/sass/pages/_wfm.scss
  39. 71
      html_src/x_page_layout.php
  40. 8
      libesphttpd/core/auth.c
  41. 2
      libesphttpd/include/auth.h
  42. 2
      libesphttpd/include/esp8266.h
  43. 2
      libesphttpd/include/logging.h
  44. 1
      libesphttpd/include/platform.h
  45. 9
      user/datalink.h
  46. 83
      user/page_about.c
  47. 23
      user/page_home.c
  48. 2
      user/page_home.h
  49. 189
      user/page_monitoring.c
  50. 15
      user/page_monitoring.h
  51. 159
      user/page_status.c
  52. 8
      user/page_status.h
  53. 191
      user/page_waveform.c
  54. 10
      user/page_waveform.h
  55. 40
      user/pers_cfg.c
  56. 23
      user/pers_cfg.h
  57. 259
      user/reporting.c
  58. 52
      user/reporting.h
  59. 33
      user/routes.c
  60. 277
      user/sampling.c
  61. 75
      user/sampling.h
  62. 2
      user/sbmp_config.h
  63. 13
      user/user_main.c
  64. 10
      user/wificontrol.c

7
_web-build_do.sh

@ -23,10 +23,5 @@ find "$BLDDIR" -name "*.map" -delete
mkdir -p "$BLDDIR/pages"
php "$SRCDIR/page_status.php" > "$BLDDIR/pages/status.tpl"
php "$SRCDIR/page_about.php" > "$BLDDIR/pages/about.tpl"
php "$SRCDIR/page_home.php" > "$BLDDIR/pages/home.tpl"
php "$SRCDIR/page_wifi.php" > "$BLDDIR/pages/wifi.tpl"
php "$SRCDIR/page_monitoring.php" > "$BLDDIR/pages/monitoring.tpl"
php "$SRCDIR/page_waveform.php" > "$BLDDIR/pages/wfm.html" # no substitutions, .html allows to gzip it.
php "$SRCDIR/page_fft.php" > "$BLDDIR/pages/fft.html" # same
php "$SRCDIR/page_spectrogram.php" > "$BLDDIR/pages/sgm.html" # same

161
esp_f105motor.pro

@ -0,0 +1,161 @@
TEMPLATE = app
CONFIG += console
CONFIG -= app_bundle
CONFIG -= qt
DEFINES = ESPFS_HEATSHRINK HTTPD_MAX_CONNECTIONS=4 __ets__
INCLUDEPATH = . \
esp_iot_sdk_v1.5.2/include \
include \
user \
esphttpclient \
libesphttpd/include \
libesphttpd/espfs \
libesphttpd/core \
libesphttpd/lib/heatshrink \
sbmp/library \
/home/ondra/devel/esp/sdk/esp-open-sdk/xtensa-lx106-elf/xtensa-lx106-elf/include
SOURCES += \
libesphttpd/core/auth.c \
libesphttpd/core/base64.c \
libesphttpd/core/httpd-freertos.c \
libesphttpd/core/httpd-nonos.c \
libesphttpd/core/httpd.c \
libesphttpd/core/httpdespfs.c \
libesphttpd/core/sha1.c \
libesphttpd/espfs/espfstest/main.c \
libesphttpd/espfs/mkespfsimage/heatshrink_encoder.c \
libesphttpd/espfs/mkespfsimage/main.c \
libesphttpd/espfs/espfs.c \
libesphttpd/espfs/heatshrink_decoder.c \
libesphttpd/lib/heatshrink/heatshrink.c \
libesphttpd/lib/heatshrink/heatshrink_decoder.c \
libesphttpd/lib/heatshrink/heatshrink_encoder.c \
libesphttpd/lib/heatshrink/test_heatshrink_dynamic.c \
libesphttpd/lib/heatshrink/test_heatshrink_dynamic_theft.c \
libesphttpd/lib/heatshrink/test_heatshrink_static.c \
libesphttpd/mkupgimg/mkupgimg.c \
libesphttpd/util/captdns.c \
libesphttpd/util/cgiflash.c \
libesphttpd/util/cgiwebsocket.c \
libesphttpd/util/cgiwifi.c \
user/cgi-test.c \
user/io.c \
user/user_main.c \
user/uart_driver.c \
sbmp/library/crc32.c \
sbmp/library/sbmp_checksum.c \
sbmp/library/sbmp_datagram.c \
sbmp/library/sbmp_frame.c \
sbmp/library/sbmp_session.c \
sbmp/library/sbmp_bulk.c \
user/datalink.c \
user/serial.c \
user/uptime.c \
sbmp/library/payload_parser.c \
user/sampling.c \
user/ftoa.c \
user/routes.c \
user/utils.c \
sbmp/library/payload_builder.c \
user/cgi_reset.c \
user/cgi_ping.c \
esphttpclient/test/httpclient_test.c \
esphttpclient/httpclient.c \
user/wificontrol.c \
user/page_home.c \
user/pers_cfg.c
HEADERS += \
include/uart_hw.h \
include/user_config.h \
libesphttpd/core/base64.h \
libesphttpd/core/httpd-platform.h \
libesphttpd/espfs/espfsformat.h \
libesphttpd/espfs/heatshrink_config_custom.h \
libesphttpd/include/auth.h \
libesphttpd/include/captdns.h \
libesphttpd/include/cgiflash.h \
libesphttpd/include/cgiwebsocket.h \
libesphttpd/include/cgiwifi.h \
libesphttpd/include/esp8266.h \
libesphttpd/include/espfs.h \
libesphttpd/include/httpd.h \
libesphttpd/include/httpdespfs.h \
libesphttpd/include/platform.h \
libesphttpd/include/sha1.h \
libesphttpd/include/user_config.h \
libesphttpd/include/webpages-espfs.h \
libesphttpd/lib/heatshrink/greatest.h \
libesphttpd/lib/heatshrink/heatshrink_common.h \
libesphttpd/lib/heatshrink/heatshrink_config.h \
libesphttpd/lib/heatshrink/heatshrink_decoder.h \
libesphttpd/lib/heatshrink/heatshrink_encoder.h \
user/cgi-test.h \
user/io.h \
user/uart_register.h \
esp_iot_sdk_v1.5.2/include/json/json.h \
esp_iot_sdk_v1.5.2/include/json/jsonparse.h \
esp_iot_sdk_v1.5.2/include/json/jsontree.h \
esp_iot_sdk_v1.5.2/include/airkiss.h \
esp_iot_sdk_v1.5.2/include/at_custom.h \
esp_iot_sdk_v1.5.2/include/c_types.h \
esp_iot_sdk_v1.5.2/include/eagle_soc.h \
esp_iot_sdk_v1.5.2/include/esp_sdk_ver.h \
esp_iot_sdk_v1.5.2/include/espconn.h \
esp_iot_sdk_v1.5.2/include/espnow.h \
esp_iot_sdk_v1.5.2/include/ets_sys.h \
esp_iot_sdk_v1.5.2/include/gpio.h \
esp_iot_sdk_v1.5.2/include/ip_addr.h \
esp_iot_sdk_v1.5.2/include/mem.h \
esp_iot_sdk_v1.5.2/include/mesh.h \
esp_iot_sdk_v1.5.2/include/os_type.h \
esp_iot_sdk_v1.5.2/include/osapi.h \
esp_iot_sdk_v1.5.2/include/ping.h \
esp_iot_sdk_v1.5.2/include/pwm.h \
esp_iot_sdk_v1.5.2/include/queue.h \
esp_iot_sdk_v1.5.2/include/slc_register.h \
esp_iot_sdk_v1.5.2/include/smartconfig.h \
esp_iot_sdk_v1.5.2/include/sntp.h \
esp_iot_sdk_v1.5.2/include/spi_flash.h \
esp_iot_sdk_v1.5.2/include/spi_register.h \
esp_iot_sdk_v1.5.2/include/uart_register.h \
esp_iot_sdk_v1.5.2/include/upgrade.h \
esp_iot_sdk_v1.5.2/include/user_interface.h \
user/uart_driver.h \
sbmp/library/crc32.h \
sbmp/library/sbmp.h \
sbmp/library/sbmp_checksum.h \
sbmp/library/sbmp_config.h \
sbmp/library/sbmp_datagram.h \
sbmp/library/sbmp_frame.h \
sbmp/library/sbmp_logging.h \
sbmp/library/sbmp_session.h \
sbmp/library/sbmp_bulk.h \
user/datalink.h \
user/serial.h \
libesphttpd/include/logging.h \
user/uptime.h \
sbmp/library/payload_parser.h \
user/sampling.h \
user/sbmp_config.h \
sbmp/library/sbmp_config.example.h \
user/ftoa.h \
user/routes.h \
libesphttpd/include/espmissingprotos.h \
user/utils.h \
sbmp/library/payload_builder.h \
user/fw_version.h \
user/cgi_reset.h \
user/cgi_ping.h \
esphttpclient/espmissingincludes.h \
esphttpclient/httpclient.h \
user/wificontrol.h \
user/page_home.h \
user/pers_cfg.h
DISTFILES += \
style.astylerc \
Makefile

167
esp_meas.pro

@ -1,167 +0,0 @@
TEMPLATE = app
CONFIG += console
CONFIG -= app_bundle
CONFIG -= qt
DEFINES = ESPFS_HEATSHRINK HTTPD_MAX_CONNECTIONS=4 __ets__
INCLUDEPATH = . \
esp_iot_sdk_v1.5.2/include \
include \
user \
esphttpclient \
libesphttpd/include \
libesphttpd/espfs \
libesphttpd/core \
libesphttpd/lib/heatshrink \
sbmp/library \
/home/ondra/devel/esp/sdk/esp-open-sdk/xtensa-lx106-elf/xtensa-lx106-elf/include
SOURCES += \
libesphttpd/core/auth.c \
libesphttpd/core/base64.c \
libesphttpd/core/httpd-freertos.c \
libesphttpd/core/httpd-nonos.c \
libesphttpd/core/httpd.c \
libesphttpd/core/httpdespfs.c \
libesphttpd/core/sha1.c \
libesphttpd/espfs/espfstest/main.c \
libesphttpd/espfs/mkespfsimage/heatshrink_encoder.c \
libesphttpd/espfs/mkespfsimage/main.c \
libesphttpd/espfs/espfs.c \
libesphttpd/espfs/heatshrink_decoder.c \
libesphttpd/lib/heatshrink/heatshrink.c \
libesphttpd/lib/heatshrink/heatshrink_decoder.c \
libesphttpd/lib/heatshrink/heatshrink_encoder.c \
libesphttpd/lib/heatshrink/test_heatshrink_dynamic.c \
libesphttpd/lib/heatshrink/test_heatshrink_dynamic_theft.c \
libesphttpd/lib/heatshrink/test_heatshrink_static.c \
libesphttpd/mkupgimg/mkupgimg.c \
libesphttpd/util/captdns.c \
libesphttpd/util/cgiflash.c \
libesphttpd/util/cgiwebsocket.c \
libesphttpd/util/cgiwifi.c \
user/cgi-test.c \
user/io.c \
user/user_main.c \
user/uart_driver.c \
sbmp/library/crc32.c \
sbmp/library/sbmp_checksum.c \
sbmp/library/sbmp_datagram.c \
sbmp/library/sbmp_frame.c \
sbmp/library/sbmp_session.c \
sbmp/library/sbmp_bulk.c \
user/datalink.c \
user/serial.c \
user/uptime.c \
sbmp/library/payload_parser.c \
user/sampling.c \
user/ftoa.c \
user/routes.c \
user/page_status.c \
user/page_waveform.c \
user/utils.c \
sbmp/library/payload_builder.c \
user/page_about.c \
user/cgi_reset.c \
user/cgi_ping.c \
esphttpclient/test/httpclient_test.c \
esphttpclient/httpclient.c \
user/page_monitoring.c \
user/reporting.c \
user/wificontrol.c
HEADERS += \
include/uart_hw.h \
include/user_config.h \
libesphttpd/core/base64.h \
libesphttpd/core/httpd-platform.h \
libesphttpd/espfs/espfsformat.h \
libesphttpd/espfs/heatshrink_config_custom.h \
libesphttpd/include/auth.h \
libesphttpd/include/captdns.h \
libesphttpd/include/cgiflash.h \
libesphttpd/include/cgiwebsocket.h \
libesphttpd/include/cgiwifi.h \
libesphttpd/include/esp8266.h \
libesphttpd/include/espfs.h \
libesphttpd/include/httpd.h \
libesphttpd/include/httpdespfs.h \
libesphttpd/include/platform.h \
libesphttpd/include/sha1.h \
libesphttpd/include/user_config.h \
libesphttpd/include/webpages-espfs.h \
libesphttpd/lib/heatshrink/greatest.h \
libesphttpd/lib/heatshrink/heatshrink_common.h \
libesphttpd/lib/heatshrink/heatshrink_config.h \
libesphttpd/lib/heatshrink/heatshrink_decoder.h \
libesphttpd/lib/heatshrink/heatshrink_encoder.h \
user/cgi-test.h \
user/io.h \
user/uart_register.h \
esp_iot_sdk_v1.5.2/include/json/json.h \
esp_iot_sdk_v1.5.2/include/json/jsonparse.h \
esp_iot_sdk_v1.5.2/include/json/jsontree.h \
esp_iot_sdk_v1.5.2/include/airkiss.h \
esp_iot_sdk_v1.5.2/include/at_custom.h \
esp_iot_sdk_v1.5.2/include/c_types.h \
esp_iot_sdk_v1.5.2/include/eagle_soc.h \
esp_iot_sdk_v1.5.2/include/esp_sdk_ver.h \
esp_iot_sdk_v1.5.2/include/espconn.h \
esp_iot_sdk_v1.5.2/include/espnow.h \
esp_iot_sdk_v1.5.2/include/ets_sys.h \
esp_iot_sdk_v1.5.2/include/gpio.h \
esp_iot_sdk_v1.5.2/include/ip_addr.h \
esp_iot_sdk_v1.5.2/include/mem.h \
esp_iot_sdk_v1.5.2/include/mesh.h \
esp_iot_sdk_v1.5.2/include/os_type.h \
esp_iot_sdk_v1.5.2/include/osapi.h \
esp_iot_sdk_v1.5.2/include/ping.h \
esp_iot_sdk_v1.5.2/include/pwm.h \
esp_iot_sdk_v1.5.2/include/queue.h \
esp_iot_sdk_v1.5.2/include/slc_register.h \
esp_iot_sdk_v1.5.2/include/smartconfig.h \
esp_iot_sdk_v1.5.2/include/sntp.h \
esp_iot_sdk_v1.5.2/include/spi_flash.h \
esp_iot_sdk_v1.5.2/include/spi_register.h \
esp_iot_sdk_v1.5.2/include/uart_register.h \
esp_iot_sdk_v1.5.2/include/upgrade.h \
esp_iot_sdk_v1.5.2/include/user_interface.h \
user/uart_driver.h \
sbmp/library/crc32.h \
sbmp/library/sbmp.h \
sbmp/library/sbmp_checksum.h \
sbmp/library/sbmp_config.h \
sbmp/library/sbmp_datagram.h \
sbmp/library/sbmp_frame.h \
sbmp/library/sbmp_logging.h \
sbmp/library/sbmp_session.h \
sbmp/library/sbmp_bulk.h \
user/datalink.h \
user/serial.h \
libesphttpd/include/logging.h \
user/uptime.h \
sbmp/library/payload_parser.h \
user/sampling.h \
user/sbmp_config.h \
sbmp/library/sbmp_config.example.h \
user/ftoa.h \
user/routes.h \
user/page_status.h \
user/page_waveform.h \
libesphttpd/include/espmissingprotos.h \
user/utils.h \
sbmp/library/payload_builder.h \
user/page_about.h \
user/fw_version.h \
user/cgi_reset.h \
user/cgi_ping.h \
esphttpclient/espmissingincludes.h \
esphttpclient/httpclient.h \
user/page_monitoring.h \
user/reporting.h \
user/wificontrol.h
DISTFILES += \
style.astylerc \
Makefile

2
html/css/app.css

File diff suppressed because one or more lines are too long

4
html/js/all.js

File diff suppressed because one or more lines are too long

77
html/pages/about.tpl

@ -1,77 +0,0 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>About - Current Analyser</title>
<link href="/css/app.css" rel="stylesheet">
<script src="/js/all.js"></script>
<script>
// server root (or URL) - used for local development with remote AJAX calls
// (this needs CORS working on the target - which I added to esp-httpd)
var _root = "";
</script>
</head>
<body class="page-about">
<div id="outer">
<nav id="menu">
<div id="brand" onclick="$('#menu').toggleClass('expanded')">Current Analyser</div>
<a href="/status">Home</a><a href="/wifi">WiFi config</a><a href="/waveform">Waveform</a><a href="/fft">FFT</a><a href="/spectrogram">Spectrogram</a><a href="/monitoring">Monitoring</a><a href="/about" class="selected">About</a></nav>
<div id="content">
<img src="/img/loader.gif" alt="Loading…" id="loader">
<h1>About</h1>
<div class="Box">
<img src="/img/cvut.svg" id="logo" class="mq-tablet-min">
<h2>Current Analyser</h2>
<img src="/img/cvut.svg" id="logo2" class="mq-phone">
<p>&copy; Ondřej Hruška, 2016 &lt;<a href="mailto:ondra@ondrovo.com" target="blank">ondra@ondrovo.com</a>&gt;</p>
<p><a href="http://measure.feld.cvut.cz/" target="blank">Katedra měření, FEL ČVUT</a><br>Department of Measurement, FEE CTU</p>
</div>
<div class="Box">
<h2>Firmware</h2>
<table>
<tr>
<th>Firmware</th>
<td>v%vers_fw%, build <i>%date%</i> at <i>%time%</i></td>
</tr>
<tr>
<th>esp-httpd&nbsp;lib</th>
<td>v%vers_httpd%</td>
</tr>
<tr>
<th>SBMP&nbsp;lib</th>
<td>v%vers_sbmp%</td>
</tr>
<tr>
<th>ESP&nbsp;IoT&nbsp;SDK</th>
<td>v%vers_sdk%</td>
</tr>
<tr>
<th>STM32&nbsp;firmware</th>
<td>v%vers_stm%</td>
</tr>
</table>
<p>
The webserver was built using the great <a href="https://github.com/Spritetm/esphttpd" target="blank">esp-httpd</a>
library by Jeroen Domburg.
</p>
</div>
<div class="NotifyMsg hidden" id="notif"></div>
</div><!-- content -->
</div><!-- outer -->
</body>
</html>

102
html/pages/fft.html

@ -1,102 +0,0 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>FFT - Current Analyser</title>
<link href="/css/app.css" rel="stylesheet">
<script src="/js/all.js"></script>
<script>
// server root (or URL) - used for local development with remote AJAX calls
// (this needs CORS working on the target - which I added to esp-httpd)
var _root = "";
</script>
</head>
<body class="page-fft">
<div id="outer">
<nav id="menu">
<div id="brand" onclick="$('#menu').toggleClass('expanded')">Current Analyser</div>
<a href="/status">Home</a><a href="/wifi">WiFi config</a><a href="/waveform">Waveform</a><a href="/fft" class="selected">FFT</a><a href="/spectrogram">Spectrogram</a><a href="/monitoring">Monitoring</a><a href="/about">About</a></nav>
<div id="content">
<img src="/img/loader.gif" alt="Loading…" id="loader">
<h1>FFT</h1>
<div class="Box center" id="samp-ctrl">
<div>
<label for="count">Bins</label>
<label for="count" class="select-wrap">
<select name="count" id="count">
<option value="16">8
<option value="32">16
<option value="64">32
<option value="128">64
<option value="256">128
<option value="512">256
<option value="1024">512
<option value="2048" selected>1024
</select>
</label>
</div>
<div>
<label for="freq">f<sub>bw</sub> <span class="mq-normal-min nb">=</span><span class="mq-tablet-max nb">(Hz)</span></label>
<input id="freq" type="number" value="2048">
<span class="mq-normal-min">Hz</span>
</div>
<div>
<a id="load" class="button btn-green">Load</a>
</div>
</div>
<div class="Box medium chartbox">
<div id="chart" class="ct-chart ct-wide ct-with-area"></div>
<div class="stats invis">
<table>
<tr>
<th>Samples</th>
<td id="stat-count"></td>
</tr>
<tr>
<th>f<sub>s</sub></th>
<td id="stat-f-s"></td>
</tr>
<tr>
<th>I<sub>peak</sub></th>
<td id="stat-i-peak"></td>
</tr>
<tr>
<th>I<sub>RMS</sub></th>
<td id="stat-i-rms"></td>
</tr>
</table>
<div class="ar"><!-- auto reload -->
<input type="number" id="ar-time" step="100" value="1000" min="0">&nbsp;ms
<input type="button" id="ar-btn" class="btn-blue narrow" value="Auto">
</div>
</div>
</div>
<div class="Box chartexport hidden">
Copy:
<a data-sep="space">1·2·3</a>
<a data-sep="comma">1,2,3</a>
<a data-sep="newline">1↵2↵3</a>
<a data-sep="csv">CSV</a>
<br>
<textarea id="copybox" class="hidden" readonly onfocus="this.select();" onmouseup="return false"></textarea>
</div>
<script>
$().ready(page_waveform.init('fft'));
</script>
<div class="NotifyMsg hidden" id="notif"></div>
</div><!-- content -->
</div><!-- outer -->
</body>
</html>

49
html/pages/home.tpl

@ -0,0 +1,49 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Home - WiFi Demo</title>
<link href="/css/app.css" rel="stylesheet">
<script src="/js/all.js"></script>
<script>
// server root (or URL) - used for local development with remote AJAX calls
// (this needs CORS working on the target - which I added to esp-httpd)
var _root = "";
</script>
</head>
<body class="page-home">
<div id="outer">
<nav id="menu">
<div id="brand" onclick="$('#menu').toggleClass('expanded')">WiFi Demo</div>
<a href="/home" class="selected">Home</a><a href="/wifi">WiFi config</a></nav>
<div id="content">
<img src="/img/loader.gif" alt="Loading…" id="loader">
<h1>Home</h1>
<div class="Box">
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Accusamus cum eius molestias nesciunt nihil sequi? Laboriosam molestiae nesciunt
quis! Aut eius esse in laudantium obcaecati possimus quis repudiandae tenetur velit.</p>
</div>
<div class="Box">
<h2>Firmware</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Accusamus cum eius molestias nesciunt nihil sequi? Laboriosam molestiae nesciunt
quis! Aut eius esse in laudantium obcaecati possimus quis repudiandae tenetur velit.</p>
</div>
<script>
$().ready(page_home.init);
</script>
<div class="NotifyMsg hidden" id="notif"></div>
</div><!-- content -->
</div><!-- outer -->
</body>
</html>

102
html/pages/monitoring.tpl

@ -1,102 +0,0 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Monitoring - Current Analyser</title>
<link href="/css/app.css" rel="stylesheet">
<script src="/js/all.js"></script>
<script>
// server root (or URL) - used for local development with remote AJAX calls
// (this needs CORS working on the target - which I added to esp-httpd)
var _root = "";
</script>
</head>
<body class="page-monitoring">
<div id="outer">
<nav id="menu">
<div id="brand" onclick="$('#menu').toggleClass('expanded')">Current Analyser</div>
<a href="/status">Home</a><a href="/wifi">WiFi config</a><a href="/waveform">Waveform</a><a href="/fft">FFT</a><a href="/spectrogram">Spectrogram</a><a href="/monitoring" class="selected">Monitoring</a><a href="/about">About</a></nav>
<div id="content">
<img src="/img/loader.gif" alt="Loading…" id="loader">
<h1>Monitoring &amp; Reporting</h1>
<div class="Box">
<h2>Status</h2>
<table>
<tr>
<th>Reference:</th>
<td>
<span id="hasref" class="Valfield">%refStored%</span>
<a onclick="page_mon.captureRef()" class="button btn-green">Capture</a>
</td>
</tr>
<tr>
<th>Status:</th>
<td>
<span class="Valfield" style="vertical-align:middle;">
Δ = <span id="actual-dev">%curDeviation%</span><br>
I<sub>RMS</sub> = <span id="actual-rms">%curRMS%</span>&nbsp;mA
</span>
<a onclick="page_mon.compareNow()" class="button btn-blue">Measure</a>
</td>
</tr>
</table>
</div>
<div class="Box">
<h2>Reporting</h2>
<form action="/mon/config" method="POST">
<table>
<tr>
<th><label for="rep-on">Reporting:</label></th>
<td>
<input type="checkbox" id="rep-on" name="enabled" value="1" %rep_en%><!--
-->&nbsp;<label for="rep-on">enabled</label>
</td>
</tr>
<tr>
<th><label for="rep-interval">Interval:</label></th>
<td>
<input type="number" name="interval" id="rep-interval" style="max-width: 10em" value="%repInterval%"><!--
-->&nbsp;seconds
</td>
</tr>
<tr>
<th>Service:</th>
<td>
<input type="radio" name="service" value="xv" id="rep-svc-xv" %svc_xv%>&nbsp;<label for="rep-svc-xv">Xively</label>&nbsp;
<input type="radio" name="service" value="ts" id="rep-svc-ts" %svc_ts%>&nbsp;<label for="rep-svc-ts">ThingSpeak</label>
</td>
</tr>
<tr>
<th><label for="rep-key">API key:</label></th>
<td><input type="text" name="key" id="rep-key" value="%repKey%"></td>
</tr>
<tr class="xv-only">
<th><label for="rep-feed">Feed ID:</label></th>
<td><input type="text" name="feed" id="rep-feed" value="%repFeed%"></td>
</tr>
<tr>
<th>&nbsp;</th>
<td><input type="submit" value="Save changes"></td>
</tr>
</table>
</form>
</div>
<script>
$().ready(page_mon.init);
</script>
<div class="NotifyMsg hidden" id="notif"></div>
</div><!-- content -->
</div><!-- outer -->
</body>
</html>

79
html/pages/sgm.html

@ -1,79 +0,0 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Spectrogram - Current Analyser</title>
<link href="/css/app.css" rel="stylesheet">
<script src="/js/all.js"></script>
<script>
// server root (or URL) - used for local development with remote AJAX calls
// (this needs CORS working on the target - which I added to esp-httpd)
var _root = "";
</script>
</head>
<body class="page-spectrogram">
<div id="outer">
<nav id="menu">
<div id="brand" onclick="$('#menu').toggleClass('expanded')">Current Analyser</div>
<a href="/status">Home</a><a href="/wifi">WiFi config</a><a href="/waveform">Waveform</a><a href="/fft">FFT</a><a href="/spectrogram" class="selected">Spectrogram</a><a href="/monitoring">Monitoring</a><a href="/about">About</a></nav>
<div id="content">
<img src="/img/loader.gif" alt="Loading…" id="loader">
<h1>Spectrogram</h1>
<div class="Box center" id="samp-ctrl">
<div>
<label for="count">Bins</label>
<label for="count" class="select-wrap">
<select name="count" id="count">
<option value="16">8
<option value="32">16
<option value="64">32
<option value="128">64
<option value="256">128
<option value="512">256
<option value="1024" selected>512
<option value="2048">1024
</select>
</label>
</div>
<div id="tile-cfg">
<label for="tile-x">Tile</label>
<input id="tile-x" type="number" min=1 step=1 value=4>
×
<input id="tile-y" type="number" min=1 step=1 value=1>
</div>
<div>
<label for="freq">f<sub>bw</sub> <span class="mq-normal-min nb">=</span><span class="mq-tablet-max nb">(Hz)</span></label>
<input id="freq" type="number" value="2048">
<span class="mq-normal-min">Hz</span>
</div>
<div>
<label for="interval">Interval <span class="mq-tablet-max" style="font-weight:normal;">(ms)</span></label>
<input id="interval" type="number" value="0" step=100 min=0>
<span class="mq-normal-min">ms</span>
</div>
<div>
<a id="go-btn" class="button btn-green">Start</a>
</div>
</div>
<div class="Box center">
<canvas id="sg" width=860 height=530></canvas>
</div>
<script>
$().ready(page_spectrogram.init());
</script>
<div class="NotifyMsg hidden" id="notif"></div>
</div><!-- content -->
</div><!-- outer -->
</body>
</html>

128
html/pages/status.tpl

@ -1,128 +0,0 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Home - Current Analyser</title>
<link href="/css/app.css" rel="stylesheet">
<script src="/js/all.js"></script>
<script>
// server root (or URL) - used for local development with remote AJAX calls
// (this needs CORS working on the target - which I added to esp-httpd)
var _root = "";
</script>
</head>
<body class="page-home">
<div id="outer">
<nav id="menu">
<div id="brand" onclick="$('#menu').toggleClass('expanded')">Current Analyser</div>
<a href="/status" class="selected">Home</a><a href="/wifi">WiFi config</a><a href="/waveform">Waveform</a><a href="/fft">FFT</a><a href="/spectrogram">Spectrogram</a><a href="/monitoring">Monitoring</a><a href="/about">About</a></nav>
<div id="content">
<img src="/img/loader.gif" alt="Loading…" id="loader">
<h1>System Status</h1>
<div class="Box">
<h2>Runtime</h2>
<table>
<tr>
<th>Uptime:</th>
<td id="uptime">%uptime%</td>
</tr>
<tr>
<th>Free heap:</th>
<td id="heap">%heap%</td>
</tr>
<tr>
<th></th>
<td><a onclick="page_status.trigReset()" class="button btn-red">Restart system</a></td>
</tr>
</table>
</div>
<div class="Box">
<h2>WiFi</h2>
<table>
<tr>
<th>WiFi mode:</th>
<td id="wmode">%wifiMode%</td>
</tr>
</table>
</div>
<!-- WiFi info is read & updated using AJAX -->
<div class="Box sta-only" style="display:none">
<h2>WiFi Station</h2>
<table>
<tr>
<th>SSID:</th>
<td id="staSSID"></td>
</tr>
<tr>
<th>RSSI:</th>
<td>
<span id="staRSSIperc"></span>,
<span id="staRSSI"></span>
</td>
</tr>
<tr>
<th>MAC:</th>
<td id="staMAC"></td>
</tr>
</table>
</div>
<div class="Box ap-only" style="display:none">
<h2>WiFi AP</h2>
<table>
<tr>
<th>SSID:</th>
<td id="apSSID"></td>
</tr>
<tr>
<th>Hidden:</th>
<td id="apHidden"></td>
</tr>
<tr>
<th>Auth. mode:</th>
<td id="apAuth"></td>
</tr>
<tr class="ap-auth-only">
<th>Password:</th>
<td id="apPwd"></td>
</tr>
<tr>
<th>Channel:</th>
<td id="apChan"></td>
</tr>
<tr>
<th>MAC:</th>
<td id="apMAC"></td>
</tr>
</table>
</div>
<div class="Modal hidden no-close" id="reset-modal">
<div class="Dialog center">
<h2>The device has been reset.</h2>
<p class="ap-only">If you're connected to the AP, you'll have to re-connect.</p>
<p>This dialog should close when the restart is complete, please wait around 15 seconds..</p>
<p><a onclick="location.reload()" class="button btn-blue">Reload the page</a></p>
</div>
</div>
<script>
$().ready(page_status.init);
</script>
<div class="NotifyMsg hidden" id="notif"></div>
</div><!-- content -->
</div><!-- outer -->
</body>
</html>

91
html/pages/wfm.html

@ -1,91 +0,0 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Waveform - Current Analyser</title>
<link href="/css/app.css" rel="stylesheet">
<script src="/js/all.js"></script>
<script>
// server root (or URL) - used for local development with remote AJAX calls
// (this needs CORS working on the target - which I added to esp-httpd)
var _root = "";
</script>
</head>
<body class="page-waveform">
<div id="outer">
<nav id="menu">
<div id="brand" onclick="$('#menu').toggleClass('expanded')">Current Analyser</div>
<a href="/status">Home</a><a href="/wifi">WiFi config</a><a href="/waveform" class="selected">Waveform</a><a href="/fft">FFT</a><a href="/spectrogram">Spectrogram</a><a href="/monitoring">Monitoring</a><a href="/about">About</a></nav>
<div id="content">
<img src="/img/loader.gif" alt="Loading…" id="loader">
<h1>Waveform</h1>
<div class="Box center" id="samp-ctrl">
<div>
<label for="count">Samples</label>
<input id="count" type="number" value="500">
</div>
<div>
<label for="freq">f<sub>s</sub> <span class="mq-normal-min nb">=</span><span class="mq-tablet-max nb">(Hz)</span></label>
<input id="freq" type="number" value="2048">
<span class="mq-normal-min">Hz</span>
</div>
<div>
<a id="load" class="button btn-green">Load</a>
</div>
</div>
<div class="Box medium chartbox">
<div id="chart" class="ct-chart ct-wide"></div>
<div class="stats invis">
<table>
<tr>
<th>Samples</th>
<td id="stat-count"></td>
</tr>
<tr>
<th>f<sub>s</sub></th>
<td id="stat-f-s"></td>
</tr>
<tr>
<th>I<sub>peak</sub></th>
<td id="stat-i-peak"></td>
</tr>
<tr>
<th>I<sub>RMS</sub></th>
<td id="stat-i-rms"></td>
</tr>
</table>
<div class="ar"><!-- auto reload -->
<input type="number" id="ar-time" step="100" value="1000" min="0">&nbsp;ms
<input type="button" id="ar-btn" class="btn-blue narrow" value="Auto">
</div>
</div>
</div>
<div class="Box chartexport hidden">
Copy:
<a data-sep="space">1·2·3</a>
<a data-sep="comma">1,2,3</a>
<a data-sep="newline">1↵2↵3</a>
<a data-sep="csv">CSV</a>
<br>
<textarea id="copybox" class="hidden" readonly onfocus="this.select();" onmouseup="return false"></textarea>
</div>
<script>
$().ready(page_waveform.init('raw'));
</script>
<div class="NotifyMsg hidden" id="notif"></div>
</div><!-- content -->
</div><!-- outer -->
</body>
</html>

6
html/pages/wifi.tpl

@ -5,7 +5,7 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>WiFi config - Current Analyser</title>
<title>WiFi config - WiFi Demo</title>
<link href="/css/app.css" rel="stylesheet">
<script src="/js/all.js"></script>
@ -18,8 +18,8 @@
<body class="page-wifi">
<div id="outer">
<nav id="menu">
<div id="brand" onclick="$('#menu').toggleClass('expanded')">Current Analyser</div>
<a href="/status">Home</a><a href="/wifi" class="selected">WiFi config</a><a href="/waveform">Waveform</a><a href="/fft">FFT</a><a href="/spectrogram">Spectrogram</a><a href="/monitoring">Monitoring</a><a href="/about">About</a></nav>
<div id="brand" onclick="$('#menu').toggleClass('expanded')">WiFi Demo</div>
<a href="/home">Home</a><a href="/wifi" class="selected">WiFi config</a></nav>
<div id="content">
<img src="/img/loader.gif" alt="Loading…" id="loader">

12
html_src/_start.php

@ -4,17 +4,11 @@
$root = $prod ? '' : 'http://192.168.1.13';
$menu = [
'home' => [ $prod ? '/status' : '/page_status.php', 'Home' ],
'wifi' => [ $prod ? '/wifi' : '/page_wifi.php', 'WiFi config' ],
'waveform' => [ $prod ? '/waveform' : '/page_waveform.php', 'Waveform' ],
'fft' => [ $prod ? '/fft' : '/page_fft.php', 'FFT' ],
'spectrogram' => [ $prod ? '/spectrogram' : '/page_spectrogram.php','Spectrogram' ],
'monitoring' => [ $prod ? '/monitoring' : '/page_monitoring.php', 'Monitoring' ],
// 'transient' => [ '/transient', 'Power-on transient' ],
'about' => [ $prod ? '/about' : '/page_about.php', 'About' ],
'home' => [ $prod ? '/home' : '/page_home.php', 'Home' ],
'wifi' => [ $prod ? '/wifi' : '/page_wifi.php', 'WiFi config' ],
];
$appname = 'Current Analyser';
$appname = 'WiFi Demo';
function e($s) {
return htmlspecialchars($s, ENT_HTML5|ENT_QUOTES);

2
html_src/css/app.css

File diff suppressed because one or more lines are too long

11
html_src/gulpfile.js

@ -21,18 +21,15 @@ 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/lib/chartist.js',
//'js-src/lib/chartist.axis-title.js',
//'js-src/lib/chartist.zoom.js',
'js-src/lib/lodash.custom.js',
'js-src/utils.js',
'js-src/modal.js',
'js-src/notif.js',
'js-src/app.js',
'js-src/page_wifi.js',
'js-src/page_waveform.js',
'js-src/page_spectrogram.js',
'js-src/page_status.js',
'js-src/page_mon.js',
'js-src/page_home.js',
], 'js/all.js');
});

2
html_src/js-src/lib/chibi.js

@ -615,7 +615,7 @@
if (_.isNumber(options)) options = {timeout: options};
var opts = Chartist.extend({}, {
var opts = _.extend({}, {
nocache: true,
timeout: 5000,
loader: true,

285
html_src/js-src/lib/lodash.custom.js

@ -1,7 +1,7 @@
/**
* @license
* lodash 4.6.1 (Custom Build) <https://lodash.com/>
* Build: `lodash include="range,isArray,isObject,escape,unescape,escapeRegExp,each,replace,map,isNumber,isUndefined" exports="global" -d`
* Build: `lodash include="range,isArray,isObject,escape,unescape,escapeRegExp,each,replace,map,isNumber,isUndefined,extend" exports="global" -d`
* Copyright 2012-2016 The Dojo Foundation <http://dojofoundation.org/>
* Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
* Copyright 2009-2016 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
@ -18,6 +18,9 @@
/** Used as the size to enable large array optimizations. */
var LARGE_ARRAY_SIZE = 200;
/** Used as the `TypeError` message for "Functions" methods. */
var FUNC_ERROR_TEXT = 'Expected a function';
/** Used to stand-in for `undefined` hash values. */
var HASH_UNDEFINED = '__lodash_hash_undefined__';
@ -28,6 +31,7 @@
/** Used as references for various `Number` constants. */
var INFINITY = 1 / 0,
MAX_SAFE_INTEGER = 9007199254740991,
MAX_INTEGER = 1.7976931348623157e+308,
NAN = 0 / 0;
/** `Object#toString` result references. */
@ -223,6 +227,27 @@
return set;
}
/**
* A faster alternative to `Function#apply`, this function invokes `func`
* with the `this` binding of `thisArg` and the arguments of `args`.
*
* @private
* @param {Function} func The function to invoke.
* @param {*} thisArg The `this` binding of `func`.
* @param {...*} args The arguments to invoke `func` with.
* @returns {*} Returns the result of `func`.
*/
function apply(func, thisArg, args) {
var length = args.length;
switch (length) {
case 0: return func.call(thisArg);
case 1: return func.call(thisArg, args[0]);
case 2: return func.call(thisArg, args[0], args[1]);
case 3: return func.call(thisArg, args[0], args[1], args[2]);
}
return func.apply(thisArg, args);
}
/**
* A specialized version of `_.forEach` for arrays without support for
* iteratee shorthands.
@ -398,6 +423,23 @@
return value > -1 && value % 1 == 0 && value < length;
}
/**
* Converts `iterator` to an array.
*
* @private
* @param {Object} iterator The iterator to convert.
* @returns {Array} Returns the converted array.
*/
function iteratorToArray(iterator) {
var data,
result = [];
while (!(data = iterator.next()).done) {
result.push(data.value);
}
return result;
}
/**
* Converts `map` to an array.
*
@ -469,8 +511,10 @@
/** Built-in value references. */
var Buffer = moduleExports ? root.Buffer : undefined,
Reflect = root.Reflect,
Symbol = root.Symbol,
Uint8Array = root.Uint8Array,
enumerate = Reflect ? Reflect.enumerate : undefined,
getPrototypeOf = Object.getPrototypeOf,
getOwnPropertySymbols = Object.getOwnPropertySymbols,
objectCreate = Object.create,
@ -488,6 +532,9 @@
WeakMap = getNative(root, 'WeakMap'),
nativeCreate = getNative(Object, 'create');
/** Detect if properties shadowing those on `Object.prototype` are non-enumerable. */
var nonEnumShadows = !propertyIsEnumerable.call({ 'valueOf': 1 }, 'valueOf');
/** Used to lookup unminified function names. */
var realNames = {};
@ -1372,6 +1419,31 @@
return nativeKeys(Object(object));
}
/**
* The base implementation of `_.keysIn` which doesn't skip the constructor
* property of prototypes or treat sparse arrays as dense.
*
* @private
* @param {Object} object The object to query.
* @returns {Array} Returns the array of property names.
*/
function baseKeysIn(object) {
object = object == null ? object : Object(object);
var result = [];
for (var key in object) {
result.push(key);
}
return result;
}
// Fallback for IE < 9 with es6-shim.
if (enumerate && !propertyIsEnumerable.call({ 'valueOf': 1 }, 'valueOf')) {
baseKeysIn = function(object) {
return iteratorToArray(enumerate(object));
};
}
/**
* The base implementation of `_.map` without support for iteratee shorthands.
*
@ -1674,6 +1746,39 @@
return copyObject(source, getSymbols(source), object);
}
/**
* Creates a function like `_.assign`.
*
* @private
* @param {Function} assigner The function to assign values.
* @returns {Function} Returns the new assigner function.
*/
function createAssigner(assigner) {
return rest(function(object, sources) {
var index = -1,
length = sources.length,
customizer = length > 1 ? sources[length - 1] : undefined,
guard = length > 2 ? sources[2] : undefined;
customizer = typeof customizer == 'function'
? (length--, customizer)
: undefined;
if (guard && isIterateeCall(sources[0], sources[1], guard)) {
customizer = length < 3 ? undefined : customizer;
length = 1;
}
object = Object(object);
while (++index < length) {
var source = sources[index];
if (source) {
assigner(object, source, index, customizer);
}
}
return object;
});
}
/**
* Creates a `baseEach` or `baseEachRight` function.
*
@ -2397,6 +2502,59 @@
/*------------------------------------------------------------------------*/
/**
* Creates a function that invokes `func` with the `this` binding of the
* created function and arguments from `start` and beyond provided as an array.
*
* **Note:** This method is based on the [rest parameter](https://mdn.io/rest_parameters).
*
* @static
* @memberOf _
* @category Function
* @param {Function} func The function to apply a rest parameter to.
* @param {number} [start=func.length-1] The start position of the rest parameter.
* @returns {Function} Returns the new function.
* @example
*
* var say = _.rest(function(what, names) {
* return what + ' ' + _.initial(names).join(', ') +
* (_.size(names) > 1 ? ', & ' : '') + _.last(names);
* });
*
* say('hello', 'fred', 'barney', 'pebbles');
* // => 'hello fred, barney, & pebbles'
*/
function rest(func, start) {
if (typeof func != 'function') {
throw new TypeError(FUNC_ERROR_TEXT);
}
start = nativeMax(start === undefined ? (func.length - 1) : toInteger(start), 0);
return function() {
var args = arguments,
index = -1,
length = nativeMax(args.length - start, 0),
array = Array(length);
while (++index < length) {
array[index] = args[start + index];
}
switch (start) {
case 0: return func.call(this, array);
case 1: return func.call(this, args[0], array);
case 2: return func.call(this, args[0], args[1], array);
}
var otherArgs = Array(start + 1);
index = -1;
while (++index < start) {
otherArgs[index] = args[index];
}
otherArgs[start] = array;
return apply(func, this, otherArgs);
};
}
/*------------------------------------------------------------------------*/
/**
* Performs a [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)
* comparison between two values to determine if they are equivalent.
@ -2801,6 +2959,43 @@
return value === undefined;
}
/**
* Converts `value` to an integer.
*
* **Note:** This function is loosely based on [`ToInteger`](http://www.ecma-international.org/ecma-262/6.0/#sec-tointeger).
*
* @static
* @memberOf _
* @category Lang
* @param {*} value The value to convert.
* @returns {number} Returns the converted integer.
* @example
*
* _.toInteger(3);
* // => 3
*
* _.toInteger(Number.MIN_VALUE);
* // => 0
*
* _.toInteger(Infinity);
* // => 1.7976931348623157e+308
*
* _.toInteger('3');
* // => 3
*/
function toInteger(value) {
if (!value) {
return value === 0 ? value : 0;
}
value = toNumber(value);
if (value === INFINITY || value === -INFINITY) {
var sign = (value < 0 ? -1 : 1);
return sign * MAX_INTEGER;
}
var remainder = value % 1;
return value === value ? (remainder ? value - remainder : value) : 0;
}
/**
* Converts `value` to a number.
*
@ -2875,6 +3070,45 @@
/*------------------------------------------------------------------------*/
/**
* This method is like `_.assign` except that it iterates over own and
* inherited source properties.
*
* **Note:** This method mutates `object`.
*
* @static
* @memberOf _
* @alias extend
* @category Object
* @param {Object} object The destination object.
* @param {...Object} [sources] The source objects.
* @returns {Object} Returns `object`.
* @example
*
* function Foo() {
* this.b = 2;
* }
*
* function Bar() {
* this.d = 4;
* }
*
* Foo.prototype.c = 3;
* Bar.prototype.e = 5;
*
* _.assignIn({ 'a': 1 }, new Foo, new Bar);
* // => { 'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5 }
*/
var assignIn = createAssigner(function(object, source) {
if (nonEnumShadows || isPrototype(source) || isArrayLike(source)) {
copyObject(source, keysIn(source), object);
return;
}
for (var key in source) {
assignValue(object, key, source[key]);
}
});
/**
* Gets the value at `path` of `object`. If the resolved value is
* `undefined` the `defaultValue` is used in its place.
@ -2980,6 +3214,48 @@
return result;
}
/**
* Creates an array of the own and inherited enumerable property names of `object`.
*
* **Note:** Non-object values are coerced to objects.
*
* @static
* @memberOf _
* @category Object
* @param {Object} object The object to query.
* @returns {Array} Returns the array of property names.
* @example
*
* function Foo() {
* this.a = 1;
* this.b = 2;
* }
*
* Foo.prototype.c = 3;
*
* _.keysIn(new Foo);
* // => ['a', 'b', 'c'] (iteration order is not guaranteed)
*/
function keysIn(object) {
var index = -1,
isProto = isPrototype(object),
props = baseKeysIn(object),
propsLength = props.length,
indexes = indexKeys(object),
skipIndexes = !!indexes,
result = indexes || [],
length = result.length;
while (++index < propsLength) {
var key = props[index];
if (!(skipIndexes && (key == 'length' || isIndex(key, length))) &&
!(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {
result.push(key);
}
}
return result;
}
/**
* Creates an array of own enumerable key-value pairs for `object` which
* can be consumed by `_.fromPairs`.
@ -3279,14 +3555,20 @@
Stack.prototype.set = stackSet;
// Add functions that return wrapped values when chaining.
lodash.assignIn = assignIn;
lodash.constant = constant;
lodash.iteratee = iteratee;
lodash.keys = keys;
lodash.keysIn = keysIn;
lodash.map = map;
lodash.property = property;
lodash.range = range;
lodash.rest = rest;
lodash.toPairs = toPairs;
// Add aliases.
lodash.extend = assignIn;
/*------------------------------------------------------------------------*/
// Add functions that return unwrapped values when chaining.
@ -3314,6 +3596,7 @@
lodash.isUndefined = isUndefined;
lodash.last = last;
lodash.replace = replace;
lodash.toInteger = toInteger;
lodash.toNumber = toNumber;
lodash.toString = toString;
lodash.unescape = unescape;