diff --git a/esp_meas.pro.user b/esp_meas.pro.user index 5ff4caf..e949521 100644 --- a/esp_meas.pro.user +++ b/esp_meas.pro.user @@ -1,6 +1,6 @@ - + EnvironmentId diff --git a/html/css/app.css b/html/css/app.css new file mode 100644 index 0000000..b3a1bae --- /dev/null +++ b/html/css/app.css @@ -0,0 +1,1077 @@ +@charset "UTF-8"; +/* normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */ +/** + * 1. Set default font family to sans-serif. + * 2. Prevent iOS and IE text size adjust after device orientation change, + * without disabling user zoom. + */ +*, *:before, *:after { + box-sizing: border-box; } + +html { + font-family: sans-serif; + /* 1 */ + -ms-text-size-adjust: 100%; + /* 2 */ + -webkit-text-size-adjust: 100%; + /* 2 */ } + +/** + * Remove default margin. + */ +body { + margin: 0; } + +/* HTML5 display definitions + ========================================================================== */ +/** + * Correct `block` display not defined for any HTML5 element in IE 8/9. + * Correct `block` display not defined for `details` or `summary` in IE 10/11 + * and Firefox. + * Correct `block` display not defined for `main` in IE 11. + */ +figure, +nav { + display: block; } + +/** + * 1. Correct `inline-block` display not defined in IE 8/9. + * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera. + */ +canvas, +progress { + display: inline-block; + /* 1 */ + vertical-align: baseline; + /* 2 */ } + +/** + * Prevent modern browsers from displaying `audio` without controls. + * Remove excess height in iOS 5 devices. + */ +/** + * Address `[hidden]` styling not present in IE 8/9/10. + * Hide the `template` element in IE 8/9/10/11, Safari, and Firefox < 22. + */ +[hidden] { + display: none; } + +/* Links + ========================================================================== */ +/** + * Remove the gray background color from active links in IE 10. + */ +a { + background-color: transparent; } + +/** + * Improve readability of focused elements when they are also in an + * active/hover state. + */ +a:active, +a:hover { + outline: 0; } + +/* Text-level semantics + ========================================================================== */ +/** + * Address styling not present in IE 8/9/10/11, Safari, and Chrome. + */ +/** + * Address style set to `bolder` in Firefox 4+, Safari, and Chrome. + */ +b { + font-weight: bold; } + +/** + * Address styling not present in Safari and Chrome. + */ +/** + * Address variable `h1` font-size and margin within `section` and `article` + * contexts in Firefox 4+, Safari, and Chrome. + */ +h1 { + font-size: 2em; + margin: 0.67em 0; } + +h2 { + font-size: 2em; + margin: 0.67em 0; } + +/** + * Address styling not present in IE 8/9. + */ +/** + * Address inconsistent and variable font size in all browsers. + */ +small { + font-size: 80%; } + +/** + * Prevent `sub` and `sup` affecting `line-height` in all browsers. + */ +sub, +sup { + font-size: 75%; + line-height: 0; + position: relative; + vertical-align: baseline; } + +sup { + top: -0.5em; } + +sub { + bottom: -0.25em; } + +/* Embedded content + ========================================================================== */ +/** + * Remove border when inside `a` element in IE 8/9/10. + */ +img { + border: 0; } + +/** + * Correct overflow not hidden in IE 9/10/11. + */ +svg:not(:root) { + overflow: hidden; } + +/* Grouping content + ========================================================================== */ +/** + * Address margin not present in IE 8/9 and Safari. + */ +/** + * Address differences between Firefox and other browsers. + */ +hr { + box-sizing: content-box; + height: 0; } + +/** + * Contain overflow in all browsers. + */ +pre { + overflow: auto; } + +/** + * Address odd `em`-unit font size rendering in all browsers. + */ +code, +pre { + font-family: monospace; + font-size: 1em; } + +/* Forms + ========================================================================== */ +/** + * Known limitation: by default, Chrome and Safari on OS X allow very limited + * styling of `select`, unless a `border` property is set. + */ +/** + * 1. Correct color not being inherited. + * Known issue: affects color of disabled elements. + * 2. Correct font properties not being inherited. + * 3. Address margins set differently in Firefox 4+, Safari, and Chrome. + */ +button, +input, +select, +textarea { + color: inherit; + /* 1 */ + font: inherit; + /* 2 */ + margin: 0; + /* 3 */ } + +/** + * Address `overflow` set to `hidden` in IE 8/9/10/11. + */ +button { + overflow: visible; } + +/** + * Address inconsistent `text-transform` inheritance for `button` and `select`. + * All other form control elements do not inherit `text-transform` values. + * Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera. + * Correct `select` style inheritance in Firefox. + */ +button, +select { + text-transform: none; } + +/** + * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` + * and `video` controls. + * 2. Correct inability to style clickable `input` types in iOS. + * 3. Improve usability and consistency of cursor style between image-type + * `input` and others. + */ +button, +input[type="reset"], +input[type="submit"] { + -webkit-appearance: button; + /* 2 */ + cursor: pointer; + /* 3 */ } + +/** + * Re-set default cursor for disabled elements. + */ +button[disabled], +html input[disabled] { + cursor: default; } + +/** + * Remove inner padding and border in Firefox 4+. + */ +button::-moz-focus-inner, +input::-moz-focus-inner { + border: 0; + padding: 0; } + +/** + * Address Firefox 4+ setting `line-height` on `input` using `!important` in + * the UA stylesheet. + */ +input { + line-height: normal; } + +/** + * It's recommended that you don't attempt to style these elements. + * Firefox's implementation doesn't respect box-sizing, padding, or width. + * + * 1. Address box sizing set to `content-box` in IE 8/9/10. + * 2. Remove excess padding in IE 8/9/10. + */ +input[type="checkbox"], +input[type="radio"] { + box-sizing: border-box; + /* 1 */ + padding: 0; + /* 2 */ } + +/** + * Fix the cursor style for Chrome's increment/decrement buttons. For certain + * `font-size` values of the `input`, it causes the cursor style of the + * decrement button to change from `default` to `text`. + */ +/** + * 1. Address `appearance` set to `searchfield` in Safari and Chrome. + * 2. Address `box-sizing` set to `border-box` in Safari and Chrome. + */ +/** + * Remove inner padding and search cancel button in Safari and Chrome on OS X. + * Safari (but not Chrome) clips the cancel button when the search input has + * padding (and `textfield` appearance). + */ +/** + * Define consistent border, margin, and padding. + */ +/** + * 1. Correct `color` not being inherited in IE 8/9/10/11. + * 2. Remove padding so people aren't caught out if they zero out fieldsets. + */ +legend { + border: 0; + /* 1 */ + padding: 0; + /* 2 */ } + +/** + * Remove default vertical scrollbar in IE 8/9/10/11. + */ +textarea { + overflow: auto; } + +/** + * Don't inherit the `font-weight` (applied by a rule above). + * NOTE: the default cannot safely be changed in Chrome and Safari on OS X. + */ +/* Tables + ========================================================================== */ +/** + * Remove most spacing between table cells. + */ +table { + border-collapse: collapse; + border-spacing: 0; } + +td, +th { + padding: 0; } + +html { + box-sizing: border-box; } + +*, *::after, *::before { + box-sizing: inherit; } + +.center { + text-align: center; } + +html { + font-family: Arial, sans-serif; + color: #D0D0D0; + background: #131315; } + +html, body { + border: 0 none; + margin: 0; + padding: 0; + text-decoration: none; + width: 100%; + height: 100%; + overflow: hidden; } + +/* Main outer container */ +#outer { + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + position: absolute; + width: 100%; + height: 100%; + left: 0; + right: 0; + top: 0; + bottom: 0; + overflow: hidden; + -webkit-box-orient: horizontal; + -webkit-box-direction: normal; + -webkit-flex-direction: row; + -ms-flex-direction: row; + flex-direction: row; } + +@media screen and (max-width: 544px) { + #outer { + display: block; + overflow-y: scroll; } } + +#menu { + -webkit-box-flex: 0; + -webkit-flex: 0 0 15rem; + -ms-flex: 0 0 15rem; + flex: 0 0 15rem; + background: #2bab5f; } + #menu > * { + display: block; + text-decoration: none; + padding: 0.6180469716rem 1rem; + white-space: nowrap; + word-wrap: normal; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; } + #menu #brand { + color: white; + background: #218248; + font-size: 120%; + text-align: center; + position: relative; + margin-bottom: 1rem; } + @media screen and (max-width: 544px) { + #menu #brand { + background: #2bab5f; + cursor: pointer; } + #menu #brand:after { + position: absolute; + color: rgba(0, 0, 0, 0.2); + right: 1rem; + content: '>'; + top: 50%; + font-size: 120%; + font-weight: bold; + -webkit-transform: translate(0, -50%) rotate(90deg); + transform: translate(0, -50%) rotate(90deg); } } + #menu.expanded #brand { + background: #218248; } + @media screen and (max-width: 544px) { + #menu.expanded #brand:after { + -webkit-transform: translate(0, -50%) rotate(-90deg); + transform: translate(0, -50%) rotate(-90deg); } } + #menu a { + font-size: 130%; + color: white; + -webkit-transition: background-color 0.2s; + transition: background-color 0.2s; + text-shadow: 0 0 5px rgba(0, 0, 0, 0.4); } + #menu a:hover, #menu a.selected { + background: #1bd886; + text-shadow: 0 0 5px rgba(0, 0, 0, 0.6); } + #menu a.selected { + position: relative; + box-shadow: 0 0 5px rgba(0, 0, 0, 0.5); } + #menu a:before { + content: "▸"; + padding-right: .5rem; + position: relative; + top: -0.1rem; } + @media screen and (max-width: 544px) { + #menu a { + display: none; } } + #menu.expanded a { + display: block; } + @media screen and (min-width: 545px) and (max-width: 1000px) { + #menu { + -webkit-flex-basis: 10rem; + -ms-flex-preferred-size: 10rem; + flex-basis: 10rem; } + #menu #brand { + font-size: 95%; + margin-bottom: 0.6180469716rem; } + #menu a { + font-size: 105%; } + #menu > * { + padding: 0.3819820591rem 0.6180469716rem; } } + +#content { + -webkit-box-flex: 1; + -webkit-flex-grow: 1; + -ms-flex-positive: 1; + flex-grow: 1; + overflow-y: auto; + padding: 1rem; } + @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; } + #content h1 { + text-align: center; + font-size: 2.2806973457em; + margin-top: 0; + margin-bottom: 1rem; } + #content h2 { + font-size: 1.423828125em; + margin-bottom: 0.6180469716rem; } + #content td, #content th { + padding: 0.3819820591rem; } + #content tbody th { + text-align: right; + width: 130px; + color: white; } + +.Box { + display: block; + max-width: 900px; + margin-top: 1rem; + padding: 0.6180469716rem; + border-radius: 3px; + background-color: rgba(255, 255, 255, 0.07); } + @media screen and (max-width: 544px) { + .Box { + margin-top: 0.6180469716rem; } } + h1 + .Box { + margin-top: 0; } + .Box h2 { + margin-top: 0; } + .Box.wide { + width: initial; + max-width: initial; } + +.Modal { + position: fixed; + width: 100%; + height: 100%; + left: 0; + top: 0; + right: 0; + bottom: 0; + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-box-pack: center; + -webkit-justify-content: center; + -ms-flex-pack: center; + justify-content: center; + -webkit-box-align: center; + -webkit-align-items: center; + -ms-flex-align: center; + align-items: center; + -webkit-transition: opacity .5s; + transition: opacity .5s; + background: rgba(0, 0, 0, 0.65); + opacity: 0; } + .Modal.visible { + opacity: 1; } + .Modal.hidden { + display: none; } + +.Dialog { + margin: 0.6180469716rem; + padding: 1rem 0.6180469716rem; + overflow: hidden; + max-width: 100%; + max-height: 100%; + -webkit-box-flex: 0; + -webkit-flex: 0 1 30rem; + -ms-flex: 0 1 30rem; + flex: 0 1 30rem; + background: #1c1c1e; + border-left: 6px solid #217b3a; + border-right: 6px solid #217b3a; + 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 { + text-align: center; + cursor: pointer; + display: inline-block; + border-radius: 2px; + padding: 0 0.6em; + border: 0 none; + outline: 0 none !important; + line-height: 1.8em; + font-size: 1.1em; + margin-bottom: 3px; + min-width: 5em; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + /* &::before { + margin-right: .4em; + } + + &.icononly::before { + 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 { + position: relative; + top: 2px; } + button.narrow, input[type="button"].narrow, input[type="reset"].narrow, input[type="submit"].narrow, a.button.narrow { + min-width: initial; } + +input[type="submit"], .btn-green { + background-color: #2ca94b; + box-shadow: 0 3px 0 #1d7032; + 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; } + input[type="submit"]:hover, input[type="submit"].selected, input[type="submit"].active, .btn-green:hover, .btn-green.selected, .btn-green.active { + box-shadow: 0 3px 0 #1a773b; } + input[type="submit"]:active, .btn-green:active { + box-shadow: 0 1px 0 #1a773b; } + +input[type="reset"], .btn-red { + background-color: #D04E51; + box-shadow: 0 3px 0 #aa2d30; + 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; } + input[type="reset"]:hover, input[type="reset"].selected, input[type="reset"].active, .btn-red:hover, .btn-red.selected, .btn-red.active { + box-shadow: 0 3px 0 #9e2423; } + input[type="reset"]:active, .btn-red:active { + box-shadow: 0 1px 0 #9e2423; } + +/* + +&[type="submit"], +&.gray-green { + @include fancy-btn-colors-full( + $btn-gray-f, $btn-gray-b, $btn-gray-l, + $btn-green-fa, $btn-green-ba, darken($btn-green-ba, 16) + ) +} + +&.gray-blue { + @include fancy-btn-colors-full( + $btn-gray-f, $btn-gray-b, $btn-gray-l, + $btn-blue-fa, $btn-blue-ba, darken($btn-blue-ba, 16) + ) +} + +&.gray-red { + @include fancy-btn-colors-full( + $btn-gray-f, $btn-gray-b, $btn-gray-l, + $btn-red-fa, $btn-red-ba, darken($btn-red-ba, 16) + ) +} + +&.gray-orange { + @include fancy-btn-colors-full( + $btn-gray-f, $btn-gray-b, $btn-gray-l, + $btn-orange-fa, $btn-orange-ba, darken($btn-orange-ba, 16) + ) +} + +// No change on hover - to be used for disabled buttons +&.gray-gray { + @include fancy-btn-colors-full( + $btn-gray-f, $btn-gray-b, $btn-gray-l, + $btn-gray-f, $btn-gray-b, $btn-gray-l + ) +} + +*/ +button, input[type="button"], input[type="reset"], input[type="submit"], a.button { + text-align: center; + cursor: pointer; + display: inline-block; + border-radius: 2px; + padding: 0 0.6em; + border: 0 none; + outline: 0 none !important; + line-height: 1.8em; + font-size: 1.1em; + margin-bottom: 3px; + min-width: 5em; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + /* &::before { + margin-right: .4em; + } + + &.icononly::before { + 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 { + position: relative; + top: 2px; } + button.narrow, input[type="button"].narrow, input[type="reset"].narrow, input[type="submit"].narrow, a.button.narrow { + min-width: initial; } + +input[type="submit"], .btn-green { + background-color: #2ca94b; + box-shadow: 0 3px 0 #1d7032; + 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; } + input[type="submit"]:hover, input[type="submit"].selected, input[type="submit"].active, .btn-green:hover, .btn-green.selected, .btn-green.active { + box-shadow: 0 3px 0 #1a773b; } + input[type="submit"]:active, .btn-green:active { + box-shadow: 0 1px 0 #1a773b; } + +input[type="reset"], .btn-red { + background-color: #D04E51; + box-shadow: 0 3px 0 #aa2d30; + 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; } + input[type="reset"]:hover, input[type="reset"].selected, input[type="reset"].active, .btn-red:hover, .btn-red.selected, .btn-red.active { + box-shadow: 0 3px 0 #9e2423; } + input[type="reset"]:active, .btn-red:active { + box-shadow: 0 1px 0 #9e2423; } + +/* + +&[type="submit"], +&.gray-green { + @include fancy-btn-colors-full( + $btn-gray-f, $btn-gray-b, $btn-gray-l, + $btn-green-fa, $btn-green-ba, darken($btn-green-ba, 16) + ) +} + +&.gray-blue { + @include fancy-btn-colors-full( + $btn-gray-f, $btn-gray-b, $btn-gray-l, + $btn-blue-fa, $btn-blue-ba, darken($btn-blue-ba, 16) + ) +} + +&.gray-red { + @include fancy-btn-colors-full( + $btn-gray-f, $btn-gray-b, $btn-gray-l, + $btn-red-fa, $btn-red-ba, darken($btn-red-ba, 16) + ) +} + +&.gray-orange { + @include fancy-btn-colors-full( + $btn-gray-f, $btn-gray-b, $btn-gray-l, + $btn-orange-fa, $btn-orange-ba, darken($btn-orange-ba, 16) + ) +} + +// No change on hover - to be used for disabled buttons +&.gray-gray { + @include fancy-btn-colors-full( + $btn-gray-f, $btn-gray-b, $btn-gray-l, + $btn-gray-f, $btn-gray-b, $btn-gray-l + ) +} + +*/ +input[type="number"], input[type="password"], input[type="text"], textarea, select { + border: 0 none; + border-bottom: 2px solid #217b3a; + background-color: #303030; + color: white; + padding: 6px; + line-height: 1em; + outline: 0 none !important; + -moz-outline: 0 none !important; + font-weight: normal; } + input[type="number"]:focus, input[type="number"]:hover, input[type="password"]:focus, input[type="password"]:hover, input[type="text"]:focus, input[type="text"]:hover, textarea:focus, textarea:hover, select:focus, select:hover { + border-bottom-color: #28bc65; } + +input[type="number"], input[type="password"], input[type="text"], textarea { + -webkit-user-select: text; + -khtml-user-select: text; + -moz-user-select: text; + -ms-user-select: text; + user-select: text; + cursor: text; } + +textarea { + font-family: monospace; + line-height: 1.2em; + display: block; } + +@media screen and (-webkit-min-device-pixel-ratio: 0) { + select { + padding-right: 18px; } } + +select { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + cursor: pointer; + line-height: 1.4em; + padding: 3.5px; + padding-right: 1em; } + select:-moz-focusring { + color: transparent; + text-shadow: 0 0 0 white; } + select option { + background: #303030; } + +label.select-wrap { + position: relative; + display: inline !important; + margin: 0 !important; + padding: 0 !important; + width: auto !important; } + label.select-wrap:after { + content: '<>'; + /* will be rotated */ + font-family: "Consolas", monospace; + font-weight: bold; + color: #28bc65; + top: 50%; + -webkit-transform: translate(0, -50%) rotate(90deg); + transform: translate(0, -50%) rotate(90deg); + right: 2px; + position: absolute; + z-index: 100; + pointer-events: none; } + +form { + border: 0 none; + margin: 0; + padding: 0; + text-decoration: none; } + +input[type="number"], input[type="password"], input[type="text"], textarea, select, label.select-wrap { + width: 250px; } + +form .Row { + vertical-align: middle; + margin: 14px auto; + text-align: left; + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-box-orient: horizontal; + -webkit-box-direction: normal; + -webkit-flex-direction: row; + -ms-flex-direction: row; + flex-direction: row; } + form .Row:first-child { + margin-top: 0; } + form .Row:last-child { + margin-bottom: 0; } + form .Row .spacer { + width: 130px; } + @media screen and (max-width: 544px) { + form .Row .spacer { + display: none; } } + form .Row.buttons input, form .Row.buttons .button { + margin-right: 0.6180469716rem; } + form .Row.centered { + -webkit-box-pack: center; + -webkit-justify-content: center; + -ms-flex-pack: center; + justify-content: center; } + form .Row.message { + font-size: 1em; + text-shadow: 1px 1px 3px black; + text-align: center; } + form .Row.message.error { + color: crimson; } + form .Row.message.ok { + color: #0fe851; } + form .Row.separator { + padding-top: 14px; + border-top: 2px solid rgba(255, 255, 255, 0.1); } + form .Row textarea { + display: inline-block; + vertical-align: top; + min-height: 10rem; + -webkit-box-flex: 1; + -webkit-flex-grow: 1; + -ms-flex-positive: 1; + flex-grow: 1; + resize: vertical; } + form .Row label { + font-weight: bold; + color: white; + display: inline-block; + width: 130px; + text-align: right; + text-shadow: 1px 1px 3px black; + padding: 8px; + -webkit-align-self: flex-start; + -ms-flex-item-align: start; + align-self: flex-start; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; } + form .Row .checkbox-wrap { + display: inline-block; + width: 130px; + padding: 8px; + text-align: right; + -webkit-align-self: flex-start; + -ms-flex-item-align: start; + align-self: flex-start; } + form .Row .checkbox-wrap input[type=checkbox] { + margin: auto; + width: auto; + height: auto; } + form .Row .checkbox-wrap + label { + width: 250px; + padding-left: 0; + text-align: left; + cursor: pointer; } + @media screen and (max-width: 544px) { + form .Row { + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -webkit-flex-direction: column; + -ms-flex-direction: column; + flex-direction: column; } + form .Row.buttons, form .Row.centered { + -webkit-box-orient: horizontal; + -webkit-box-direction: normal; + -webkit-flex-direction: row; + -ms-flex-direction: row; + flex-direction: row; } + form .Row.buttons { + -webkit-box-pack: center; + -webkit-justify-content: center; + -ms-flex-pack: center; + justify-content: center; } + form .Row.buttons :last-child { + margin-right: 0; } + form .Row label { + padding-left: 0; + text-align: left; + width: auto; } + form .Row .checkbox-wrap { + -webkit-box-ordinal-group: 2; + -webkit-order: 1; + -ms-flex-order: 1; + order: 1; + text-align: left; + padding-bottom: 0; + border-radius: .4px; + width: auto; } + form .Row .checkbox-wrap + label { + width: auto; } + form .Row input[type="number"], form .Row input[type="password"], form .Row input[type="text"], form .Row textarea, form .Row textarea { + width: 100%; } } + +form span.required { + color: red; } + +.RadioGroup { + display: inline-block; + line-height: 1.5em; + vertical-align: middle; } + .RadioGroup label { + width: auto; + text-align: left; + cursor: pointer; + font-weight: normal; } + .RadioGroup input[type="radio"] { + vertical-align: middle; + margin: 0 0 0 5px; } + +@media screen and (-webkit-min-device-pixel-ratio: 0) { + select { + padding-right: 18px; } } + +select { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + cursor: pointer; + line-height: 1.4em; + padding: 3.5px; + padding-right: 1em; } + select:-moz-focusring { + color: transparent; + text-shadow: 0 0 0 white; } + select option { + background: #303030; } + +label.select-wrap { + position: relative; + display: inline !important; + margin: 0 !important; + padding: 0 !important; + width: auto !important; } + label.select-wrap:after { + content: '<>'; + /* will be rotated */ + font-family: "Consolas", monospace; + font-weight: bold; + color: #28bc65; + top: 50%; + -webkit-transform: translate(0, -50%) rotate(90deg); + transform: translate(0, -50%) rotate(90deg); + right: 2px; + position: absolute; + z-index: 100; + pointer-events: none; } + +#ap-list { + -webkit-column-count: 3; + -moz-column-count: 3; + column-count: 3; + -webkit-column-gap: 0; + -moz-column-gap: 0; + column-gap: 0; + margin: 0 -0.2360828548rem; } + @media screen and (min-width: 545px) and (max-width: 1000px) { + #ap-list { + -webkit-column-count: 2; + -moz-column-count: 2; + column-count: 2; } } + @media screen and (max-width: 544px) { + #ap-list { + -webkit-column-count: 1; + -moz-column-count: 1; + column-count: 1; } } + +#ap-loader { + background: rgba(255, 255, 255, 0.1); + border-radius: 5px; + padding: 0.3819820591rem; + margin-bottom: 0.3819820591rem; } + +#ap-box { + padding-bottom: 0.3819820591rem; } + +#psk-modal form { + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-box-align: center; + -webkit-align-items: center; + -ms-flex-align: center; + align-items: center; + margin: 0.3819820591rem; } + #psk-modal form > * { + margin-left: 0.3819820591rem; + margin-right: 0.3819820591rem; } + #psk-modal form > *:first-child { + margin-left: 0; } + #psk-modal form > *:last-child { + margin-right: 0; } + #psk-modal form input[type=password] { + min-width: 5rem; } + +.AP { + -webkit-column-break-inside: avoid; + page-break-inside: avoid; + break-inside: avoid-column; + max-width: 500px; + padding: 0.2360828548rem; } + .AP.selected .inner { + background: #43de81 !important; + cursor: default; + top: 0 !important; } + .AP .inner { + cursor: pointer; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + position: relative; + border-radius: 3px; + color: #222; + background: #afafaf; + -webkit-transition: background-color 0.5s; + transition: background-color 0.5s; + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; } + .AP .inner:active { + left: 0; + top: 1px; } + .AP .inner:hover { + background: white; } + .AP .inner > * { + padding: 0.6180469716rem; + white-space: nowrap; + word-wrap: normal; } + .AP .inner .rssi { + min-width: 2rem; + -webkit-box-flex: 0; + -webkit-flex: 0 0 15%; + -ms-flex: 0 0 15%; + flex: 0 0 15%; + text-align: right; } + .AP .inner .rssi:after { + padding-left: 0.090179415rem; + content: '%'; + font-size: 0.8888888889em; } + .AP .inner .essid { + -webkit-box-flex: 1; + -webkit-flex: 1 1 70%; + -ms-flex: 1 1 70%; + flex: 1 1 70%; + min-width: 0; + text-overflow: ellipsis; + overflow: hidden; + font-weight: bold; } + .AP .inner .auth { + -webkit-box-flex: 0; + -webkit-flex: 0 0 15%; + -ms-flex: 0 0 15%; + flex: 0 0 15%; } + +/*# sourceMappingURL=app.css.map */ diff --git a/html/js/all.min.js b/html/js/all.min.js new file mode 100644 index 0000000..2510b18 --- /dev/null +++ b/html/js/all.min.js @@ -0,0 +1,950 @@ +function bool(x) { + return (x === 1 || x === '1' || x === true || x === 'true'); +} + +/** html entities */ +function e(x) { + return String(x) + .replace(/&/g, '&') + .replace(/"/g, '"') + .replace(/'/g, ''') + .replace(//g, '>'); +} + +/** 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, '\\$&'); +} + +/** 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); + + // 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('
{0}
'.format(Math.round(ap.rssi / 2.55))) + .htmlAppend('
{0}
'.format(e(ap.essid))) + .htmlAppend('
{0}
'.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'; + + var readyfn = [], + loadedfn = [], + domready = false, + pageloaded = false, + jsonpcount = 0, + d = document, + w = window; + + // Fire any function calls on ready event + function fireReady() { + var i; + domready = true; + for (i = 0; i < readyfn.length; i += 1) { + readyfn[i](); + } + readyfn = []; + } + + // Fire any function calls on loaded event + function fireLoaded() { + var i; + pageloaded = true; + // For browsers with no DOM loaded support + if (!domready) { + fireReady(); + } + for (i = 0; i < loadedfn.length; i += 1) { + loadedfn[i](); + } + loadedfn = []; + } + + // Check DOM ready, page loaded + if (d.addEventListener) { + // Standards + d.addEventListener('DOMContentLoaded', fireReady, false); + w.addEventListener('load', fireLoaded, false); + } else if (d.attachEvent) { + // IE + d.attachEvent('onreadystatechange', fireReady); + // IE < 9 + w.attachEvent('onload', fireLoaded); + } else { + // Anything else + w.onload = fireLoaded; + } + + // Utility functions + + // Loop through node array + function nodeLoop(fn, nodes) { + var i; + // Good idea to walk up the DOM + for (i = nodes.length - 1; i >= 0; i -= 1) { + fn(nodes[i]); + } + } + + // Convert to camel case + function cssCamel(property) { + return property.replace(/-\w/g, function (result) {return result.charAt(1).toUpperCase(); }); + } + + // Get computed style + function computeStyle(elm, property) { + // IE, everything else or null + return (elm.currentStyle) ? elm.currentStyle[cssCamel(property)] : (w.getComputedStyle) ? w.getComputedStyle(elm, null).getPropertyValue(property) : null; + + } + + // Returns URI encoded query string pair + function queryPair(name, value) { + return encodeURIComponent(name).replace(/%20/g, '+') + '=' + encodeURIComponent(value).replace(/%20/g, '+'); + } + + // Set CSS, important to wrap in try to prevent error thown on unsupported property + function setCss(elm, property, value) { + try { + elm.style[cssCamel(property)] = value; + } catch (e) {} + } + + // Show CSS + function showCss(elm) { + elm.style.display = ''; + // For elements still hidden by style block + if (computeStyle(elm, 'display') === 'none') { + elm.style.display = 'block'; + } + } + + // Serialize form & JSON values + function serializeData(nodes) { + var querystring = '', subelm, i, j; + if (nodes.constructor === Object) { // Serialize JSON data + for (subelm in nodes) { + if (nodes.hasOwnProperty(subelm)) { + if (nodes[subelm].constructor === Array) { + for (i = 0; i < nodes[subelm].length; i += 1) { + querystring += '&' + queryPair(subelm, nodes[subelm][i]); + } + } else { + querystring += '&' + queryPair(subelm, nodes[subelm]); + } + } + } + } else { // Serialize node data + nodeLoop(function (elm) { + if (elm.nodeName === 'FORM') { + for (i = 0; i < elm.elements.length; i += 1) { + subelm = elm.elements[i]; + + if (!subelm.disabled) { + switch (subelm.type) { + // Ignore buttons, unsupported XHR 1 form fields + case 'button': + case 'image': + case 'file': + case 'submit': + case 'reset': + break; + + case 'select-one': + if (subelm.length > 0) { + querystring += '&' + queryPair(subelm.name, subelm.value); + } + break; + + case 'select-multiple': + for (j = 0; j < subelm.length; j += 1) { + if (subelm[j].selected) { + querystring += '&' + queryPair(subelm.name, subelm[j].value); + } + } + break; + + case 'checkbox': + case 'radio': + if (subelm.checked) { + querystring += '&' + queryPair(subelm.name, subelm.value); + } + break; + + // Everything else including shinny new HTML5 input types + default: + querystring += '&' + queryPair(subelm.name, subelm.value); + } + } + } + } + }, nodes); + } + // Tidy up first & + return (querystring.length > 0) ? querystring.substring(1) : ''; + } + + // Class helper + function classHelper(classes, action, nodes) { + var classarray, search, i, has = false; + if (classes) { + // Trim any whitespace + classarray = classes.split(/\s+/); + nodeLoop(function (elm) { + for (i = 0; i < classarray.length; i += 1) { + search = new RegExp('\\b' + classarray[i] + '\\b', 'g'); + if (action === 'remove') { + elm.className = elm.className.replace(search, ''); + } else if (action === 'toggle') { + elm.className = (elm.className.match(search)) ? elm.className.replace(search, '') : elm.className + ' ' + classarray[i]; + } else if (action === 'has') { + if (elm.className.match(search)) { + has = true; + break; + } + } + } + }, nodes); + } + return has; + } + + // HTML insertion helper + function insertHtml(value, position, nodes) { + var tmpnodes, tmpnode; + if (value) { + nodeLoop(function (elm) { + // No insertAdjacentHTML support for FF < 8 and IE doesn't allow insertAdjacentHTML table manipulation, so use this instead + // Convert string to node. We can't innerHTML on a document fragment + tmpnodes = d.createElement('div'); + tmpnodes.innerHTML = value; + while ((tmpnode = tmpnodes.lastChild) !== null) { + // Catch error in unlikely case elm has been removed + try { + if (position === 'before') { + elm.parentNode.insertBefore(tmpnode, elm); + } else if (position === 'after') { + elm.parentNode.insertBefore(tmpnode, elm.nextSibling); + } else if (position === 'append') { + elm.appendChild(tmpnode); + } else if (position === 'prepend') { + elm.insertBefore(tmpnode, elm.firstChild); + } + } catch (e) {break; } + } + }, nodes); + } + } + + // Get nodes and return chibi + function chibi(selector) { + var cb, nodes = [], json = false, nodelist, i; + + if (selector) { + + // Element node, would prefer to use (selector instanceof HTMLElement) but no IE support + if (selector.nodeType && selector.nodeType === 1) { + nodes = [selector]; // return element as node list + } else if (typeof selector === 'object') { + // JSON, document object or node list, would prefer to use (selector instanceof NodeList) but no IE support + json = (typeof selector.length !== 'number'); + nodes = selector; + } else if (typeof selector === 'string') { + + // A very light querySelectorAll polyfill for IE < 8. It suits my needs but is restricted to IE CSS support, is no speed demon, and does leave older mobile browsers in the cold (that support neither querySelectorAll nor currentStyle/getComputedStyle). If you want to use a fuller featured selector engine like Qwery, Sizzle et al, just return results to the nodes array: nodes = altselectorengine(selector) + + // IE < 8 + if (!d.querySelectorAll) { + // Polyfill querySelectorAll + d.querySelectorAll = function (selector) { + + var style, head = d.getElementsByTagName('head')[0], allnodes, selectednodes = [], i; + + style = d.createElement('STYLE'); + style.type = 'text/css'; + + if (style.styleSheet) { + style.styleSheet.cssText = selector + ' {a:b}'; + + head.appendChild(style); + + allnodes = d.getElementsByTagName('*'); + + for (i = 0; i < allnodes.length; i += 1) { + if (computeStyle(allnodes[i], 'a') === 'b') { + selectednodes.push(allnodes[i]); + } + } + + head.removeChild(style); + } + + return selectednodes; + }; + } + + nodelist = d.querySelectorAll(selector); + + // Convert node list to array so results have full access to array methods + // Array.prototype.slice.call not supported in IE < 9 and often slower than loop anyway + for (i = 0; i < nodelist.length; i += 1) { + nodes[i] = nodelist[i]; + } + + } + } + + // Only attach nodes if not JSON + cb = json ? {} : nodes; + + // Public functions + + // Fire on DOM ready + cb.ready = function (fn) { + if (fn) { + if (domready) { + fn(); + return cb; + } else { + readyfn.push(fn); + } + } + }; + // Fire on page loaded + cb.loaded = function (fn) { + if (fn) { + if (pageloaded) { + fn(); + return cb; + } else { + loadedfn.push(fn); + } + } + }; + // Executes a function on nodes + cb.each = function (fn) { + if (typeof fn === 'function') { + nodeLoop(function (elm) { + // <= IE 8 loses scope so need to apply + return fn.apply(elm, arguments); + }, nodes); + } + return cb; + }; + // Find first + cb.first = function () { + return chibi(nodes.shift()); + }; + // Find last + cb.last = function () { + return chibi(nodes.pop()); + }; + // Find odd + cb.odd = function () { + var odds = [], i; + for (i = 0; i < nodes.length; i += 2) { + odds.push(nodes[i]); + } + return chibi(odds); + }; + // Find even + cb.even = function () { + var evens = [], i; + for (i = 1; i < nodes.length; i += 2) { + evens.push(nodes[i]); + } + return chibi(evens); + }; + // Hide node + cb.hide = function () { + nodeLoop(function (elm) { + elm.style.display = 'none'; + }, nodes); + return cb; + }; + // Show node + cb.show = function () { + nodeLoop(function (elm) { + showCss(elm); + }, nodes); + return cb; + }; + // Toggle node display + cb.toggle = function (state) { + if (typeof state != 'undefined') { // ADDED + if(state) + cb.show(); + else + cb.hide(); + } else { + nodeLoop(function (elm) { + // computeStyle instead of style.display == 'none' catches elements that are hidden via style block + if (computeStyle(elm, 'display') === 'none') { + showCss(elm); + } else { + elm.style.display = 'none'; + } + + }, nodes); + } + return cb; + }; + // Remove node + cb.remove = function () { + nodeLoop(function (elm) { + // Catch error in unlikely case elm has been removed + try { + elm.parentNode.removeChild(elm); + } catch (e) {} + }, nodes); + return chibi(); + }; + // Get/Set CSS + cb.css = function (property, value) { + if (property) { + if (value || value === '') { + nodeLoop(function (elm) { + setCss(elm, property, value); + }, nodes); + return cb; + } + if (nodes[0]) { + if (nodes[0].style[cssCamel(property)]) { + return nodes[0].style[cssCamel(property)]; + } + if (computeStyle(nodes[0], property)) { + return computeStyle(nodes[0], property); + } + } + } + }; + // Get class(es) + cb.getClass = function () { + if (nodes[0] && nodes[0].className.length > 0) { + // Weak IE trim support + return nodes[0].className.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '').replace(/\s+/,' '); + } + }; + // Set (replaces) classes + cb.setClass = function (classes) { + if (classes || classes === '') { + nodeLoop(function (elm) { + elm.className = classes; + }, nodes); + } + return cb; + }; + // Add class + cb.addClass = function (classes) { + if (classes) { + nodeLoop(function (elm) { + elm.className += ' ' + classes; + }, nodes); + } + return cb; + }; + // Remove class + cb.removeClass = function (classes) { + classHelper(classes, 'remove', nodes); + return cb; + }; + // Toggle class + cb.toggleClass = function (classes) { + classHelper(classes, 'toggle', nodes); + return cb; + }; + // Has class + cb.hasClass = function (classes) { + return classHelper(classes, 'has', nodes); + }; + // Get/set HTML + cb.html = function (value) { + if (value || value === '') { + nodeLoop(function (elm) { + elm.innerHTML = value; + }, nodes); + return cb; + } + if (nodes[0]) { + return nodes[0].innerHTML; + } + }; + // Insert HTML before selector + cb.htmlBefore = function (value) { + insertHtml(value, 'before', nodes); + return cb; + }; + // Insert HTML after selector + cb.htmlAfter = function (value) { + insertHtml(value, 'after', nodes); + return cb; + }; + // Insert HTML after selector innerHTML + cb.htmlAppend = function (value) { + insertHtml(value, 'append', nodes); + return cb; + }; + // Insert HTML before selector innerHTML + cb.htmlPrepend = function (value) { + insertHtml(value, 'prepend', nodes); + return cb; + }; + // Get/Set HTML attributes + cb.attr = function (property, value) { + if (property) { + property = property.toLowerCase(); + // IE < 9 doesn't allow style or class via get/setAttribute so switch. cssText returns prettier CSS anyway + if (typeof value !== 'undefined') {//FIXED BUG HERE + nodeLoop(function (elm) { + if (property === 'style') { + elm.style.cssText = value; + } else if (property === 'class') { + elm.className = value; + } else { + elm.setAttribute(property, value); + } + }, nodes); + return cb; + } + if (nodes[0]) { + if (property === 'style') { + if (nodes[0].style.cssText) { + return nodes[0].style.cssText; + } + } else if (property === 'class') { + if (nodes[0].className) { + return nodes[0].className; + } + } else { + if (nodes[0].getAttribute(property)) { + return nodes[0].getAttribute(property); + } + } + } + } + }; + // Get/Set HTML data property + cb.data = function (key, value) { + if (key) { + return cb.attr('data-'+key, value); + } + }; + // Get/Set form element values + cb.val = function (value) { + var values, i, j; + if (value || value === '') { + nodeLoop(function (elm) { + switch (elm.nodeName) { + case 'SELECT': + if (typeof value === 'string' || typeof value === 'number') { + value = [value]; + } + for (i = 0; i < elm.length; i += 1) { + // Multiple select + for (j = 0; j < value.length; j += 1) { + elm[i].selected = ''; + if (elm[i].value === value[j]) { + elm[i].selected = 'selected'; + break; + } + } + } + break; + case 'INPUT': + case 'TEXTAREA': + case 'BUTTON': + elm.value = value; + break; + } + }, nodes); + + return cb; + } + if (nodes[0]) { + switch (nodes[0].nodeName) { + case 'SELECT': + values = []; + for (i = 0; i < nodes[0].length; i += 1) { + if (nodes[0][i].selected) { + values.push(nodes[0][i].value); + } + } + return (values.length > 1) ? values : values[0]; + case 'INPUT': + case 'TEXTAREA': + case 'BUTTON': + return nodes[0].value; + } + } + }; + // Return matching checked checkbox or radios + cb.checked = function (check) { + if (typeof check === 'boolean') { + nodeLoop(function (elm) { + if (elm.nodeName === 'INPUT' && (elm.type === 'checkbox' || elm.type === 'radio')) { + elm.checked = check; + } + }, nodes); + return cb; + } + if (nodes[0] && nodes[0].nodeName === 'INPUT' && (nodes[0].type === 'checkbox' || nodes[0].type === 'radio')) { + return (!!nodes[0].checked); + } + }; + // Add event handler + cb.on = function (event, fn) { + if (selector === w || selector === d) { + nodes = [selector]; + } + nodeLoop(function (elm) { + if (d.addEventListener) { + elm.addEventListener(event, fn, false); + } else if (d.attachEvent) { + // <= IE 8 loses scope so need to apply, we add this to object so we can detach later (can't detach anonymous functions) + elm[event + fn] = function () { return fn.apply(elm, arguments); }; + elm.attachEvent('on' + event, elm[event + fn]); + } + }, nodes); + return cb; + }; + // Remove event handler + cb.off = function (event, fn) { + if (selector === w || selector === d) { + nodes = [selector]; + } + nodeLoop(function (elm) { + if (d.addEventListener) { + elm.removeEventListener(event, fn, false); + } else if (d.attachEvent) { + elm.detachEvent('on' + event, elm[event + fn]); + // Tidy up + elm[event + fn] = null; + } + }, nodes); + return cb; + }; + // Basic XHR 1, no file support. Shakes fist at IE + cb.ajax = function (url, method, callback, nocache, nojsonp) { + var xhr, + query = serializeData(nodes), + type = (method) ? method.toUpperCase() : 'GET', + hostsearch = new RegExp('http[s]?://(.*?)/', 'gi'), + domain = hostsearch.exec(url), + timestamp = '_ts=' + (+new Date()), + head = d.getElementsByTagName('head')[0], + jsonpcallback = 'chibi' + (+new Date()) + (jsonpcount += 1), + script; + + if (query && (type === 'GET' || type === 'DELETE')) { + url += (url.indexOf('?') === -1) ? '?' + query : '&' + query; + query = null; + } + + // JSONP if cross domain url + if (type === 'GET' && !nojsonp && domain && w.location.host !== domain[1]) { + + if (nocache) { + url += (url.indexOf('?') === -1) ? '?' + timestamp : '&' + timestamp; + } + + // Replace possible encoded ? + url = url.replace('=%3F', '=?'); + + // Replace jsonp ? with callback + if (callback && url.indexOf('=?') !== -1) { + + url = url.replace('=?', '=' + jsonpcallback); + + w[jsonpcallback] = function (data) { + try { + callback(data, 200); + } catch (e) {} + + // Tidy up + w[jsonpcallback] = undefined; + }; + } + + // JSONP + script = document.createElement('script'); + script.async = true; + script.src = url; + + // Tidy up + script.onload = function () { + head.removeChild(script); + }; + + head.appendChild(script); + + } else { + + if (w.XMLHttpRequest) { + xhr = new XMLHttpRequest(); + } else if (w.ActiveXObject) { + xhr = new ActiveXObject('Microsoft.XMLHTTP'); // IE < 9 + } + + if (xhr) { + + if (nocache) { + url += (url.indexOf('?') === -1) ? '?' + timestamp : '&' + timestamp; + } + + // Douglas Crockford: "Synchronous programming is disrespectful and should not be employed in applications which are used by people" + xhr.open(type, url, true); + + xhr.onreadystatechange = function () { + if (xhr.readyState === 4) { + if (callback) { + callback(xhr.responseText, xhr.status); + } + } + }; + + xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); + + if (type === 'POST' || type === 'PUT') { + xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); + } + + xhr.send(query); + + } + } + return cb; + }; + // Alias to cb.ajax(url, 'get', callback, nocache, nojsonp) + cb.get = function (url, callback, nocache, nojsonp) { + return cb.ajax(url, 'get', callback, nocache, nojsonp); + }; + // Alias to cb.ajax(url, 'post', callback, nocache) + cb.post = function (url, callback, nocache) { + return cb.ajax(url, 'post', callback, nocache); + }; + + return cb; + } + + // Set Chibi's global namespace here ($) + w.$ = chibi; + +}()); + +//# sourceMappingURL=all.min.js.map diff --git a/html/pages/home.tpl b/html/pages/home.tpl new file mode 100644 index 0000000..59fb117 --- /dev/null +++ b/html/pages/home.tpl @@ -0,0 +1,38 @@ + + + + + + + + Home - Current analyzer + + + + + + + + + +
+ +
+ +

System Status

+ +
This page was shown %counter% times.
+ + +
+
+ + diff --git a/html/pages/wifi.tpl b/html/pages/wifi.tpl new file mode 100644 index 0000000..e32e265 --- /dev/null +++ b/html/pages/wifi.tpl @@ -0,0 +1,75 @@ + + + + + + + + WiFi config - Current analyzer + + + + + + + + + +
+ +
+ +

Wireless Setup

+ +
+ + + + + + + + + + + +
WiFi mode:%WiFiMode%
Note:%WiFiapwarn%
+ +
+ +
+

Select AP to join

+
Scanning.
+ +
+ + + + + + +
+
+ + diff --git a/html/chibi.js b/html~/chibi.js similarity index 100% rename from html/chibi.js rename to html~/chibi.js diff --git a/html/foo/index.tpl b/html~/foo/index.tpl similarity index 100% rename from html/foo/index.tpl rename to html~/foo/index.tpl diff --git a/html~/home.tpl b/html~/home.tpl new file mode 100644 index 0000000..2e8f44d --- /dev/null +++ b/html~/home.tpl @@ -0,0 +1,38 @@ + + + + + + + + Home - Current analyzer + + + + + + + + + +
+ +
+ +

System Status

+ +
TODO
+ + +
+
+ + diff --git a/html/index.tpl b/html~/index.tpl similarity index 100% rename from html/index.tpl rename to html~/index.tpl diff --git a/html~/multipart.tpl b/html~/multipart.tpl new file mode 100644 index 0000000..9ce194e --- /dev/null +++ b/html~/multipart.tpl @@ -0,0 +1,14 @@ + + +ESP8266 web server + + + +
+

Multipart

+ +