├── redirect.php ├── images ├── bg.jpg ├── bg1.jpg ├── bg2.jpg ├── bg3.jpg ├── bg4.jpg ├── bg5.jpeg ├── bg6.jpg ├── nft.jpg ├── overlay.png ├── arduino.jpeg ├── grow_box.jpeg ├── breadboard.jpeg ├── full_thing.jpeg ├── hydroponics_introduction.jpg └── hydroponics_introduction1.jpg ├── assets ├── fonts │ ├── FontAwesome.otf │ ├── fontawesome-webfont.eot │ ├── fontawesome-webfont.ttf │ ├── fontawesome-webfont.woff │ └── fontawesome-webfont.woff2 ├── sass │ ├── components │ │ ├── _icon.scss │ │ ├── _box.scss │ │ ├── _icons.scss │ │ ├── _list.scss │ │ ├── _table.scss │ │ ├── _image.scss │ │ ├── _button.scss │ │ ├── _actions.scss │ │ └── _form.scss │ ├── layout │ │ ├── _wrapper.scss │ │ ├── _footer.scss │ │ ├── _bg.scss │ │ ├── _main.scss │ │ └── _header.scss │ ├── noscript.scss │ ├── libs │ │ ├── _vars.scss │ │ ├── _mixins.scss │ │ ├── _functions.scss │ │ ├── _breakpoints.scss │ │ └── _vendor.scss │ ├── base │ │ ├── _page.scss │ │ ├── _reset.scss │ │ └── _typography.scss │ └── main.scss ├── css │ ├── noscript.css │ ├── normalize.min.css │ ├── style.css │ └── font-awesome.min.css ├── js │ ├── index.js │ ├── browser.min.js │ ├── breakpoints.min.js │ ├── main.js │ └── util.js └── scss │ └── style.scss ├── logout.php ├── .github └── ISSUE_TEMPLATE │ ├── custom.md │ ├── feature_request.md │ └── bug_report.md ├── Arduino ├── Water_Pump.ino ├── Temperature.ino ├── Soil_Moisture_Sensor.ino ├── DHT22.ino ├── Water_Level_Sensor.ino ├── PH_Sensor.ino ├── ESP8266.ino ├── Water_Pump_w_L298.ino └── Hydroponics.ino ├── errors.php ├── LICENSE ├── ajax.php ├── server.php ├── home.php ├── index.php └── README.md /redirect.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /images/bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/race2infinity/Hydroponics/HEAD/images/bg.jpg -------------------------------------------------------------------------------- /images/bg1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/race2infinity/Hydroponics/HEAD/images/bg1.jpg -------------------------------------------------------------------------------- /images/bg2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/race2infinity/Hydroponics/HEAD/images/bg2.jpg -------------------------------------------------------------------------------- /images/bg3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/race2infinity/Hydroponics/HEAD/images/bg3.jpg -------------------------------------------------------------------------------- /images/bg4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/race2infinity/Hydroponics/HEAD/images/bg4.jpg -------------------------------------------------------------------------------- /images/bg5.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/race2infinity/Hydroponics/HEAD/images/bg5.jpeg -------------------------------------------------------------------------------- /images/bg6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/race2infinity/Hydroponics/HEAD/images/bg6.jpg -------------------------------------------------------------------------------- /images/nft.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/race2infinity/Hydroponics/HEAD/images/nft.jpg -------------------------------------------------------------------------------- /images/overlay.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/race2infinity/Hydroponics/HEAD/images/overlay.png -------------------------------------------------------------------------------- /images/arduino.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/race2infinity/Hydroponics/HEAD/images/arduino.jpeg -------------------------------------------------------------------------------- /images/grow_box.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/race2infinity/Hydroponics/HEAD/images/grow_box.jpeg -------------------------------------------------------------------------------- /images/breadboard.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/race2infinity/Hydroponics/HEAD/images/breadboard.jpeg -------------------------------------------------------------------------------- /images/full_thing.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/race2infinity/Hydroponics/HEAD/images/full_thing.jpeg -------------------------------------------------------------------------------- /assets/fonts/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/race2infinity/Hydroponics/HEAD/assets/fonts/FontAwesome.otf -------------------------------------------------------------------------------- /assets/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/race2infinity/Hydroponics/HEAD/assets/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /assets/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/race2infinity/Hydroponics/HEAD/assets/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /images/hydroponics_introduction.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/race2infinity/Hydroponics/HEAD/images/hydroponics_introduction.jpg -------------------------------------------------------------------------------- /images/hydroponics_introduction1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/race2infinity/Hydroponics/HEAD/images/hydroponics_introduction1.jpg -------------------------------------------------------------------------------- /assets/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/race2infinity/Hydroponics/HEAD/assets/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /assets/fonts/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/race2infinity/Hydroponics/HEAD/assets/fonts/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /logout.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/custom.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Custom issue template 3 | about: Describe this issue template's purpose here. 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | 11 | -------------------------------------------------------------------------------- /Arduino/Water_Pump.ino: -------------------------------------------------------------------------------- 1 | void setup() { 2 | Serial.begin(9600); 3 | pinMode(13, OUTPUT); 4 | } 5 | 6 | void loop() { // LOW = ON, HIGH = OFF 7 | digitalWrite(13, LOW); 8 | delay(500); 9 | } 10 | -------------------------------------------------------------------------------- /errors.php: -------------------------------------------------------------------------------- 1 | 0) : ?> 2 |
3 | 4 |

5 | 6 |
7 | -------------------------------------------------------------------------------- /Arduino/Temperature.ino: -------------------------------------------------------------------------------- 1 | int waterTemp() { 2 | int sensorValue = analogRead(A2); 3 | Serial.print("Temperature: "); 4 | Serial.println(sensorValue); 5 | return sensorValue; 6 | } 7 | 8 | void setup() { 9 | Serial.begin(9600); 10 | } 11 | 12 | void loop() { 13 | delay(2000); 14 | int valSensorWaterTemp = waterTemp(); 15 | } 16 | -------------------------------------------------------------------------------- /Arduino/Soil_Moisture_Sensor.ino: -------------------------------------------------------------------------------- 1 | int soilMoistVal() { 2 | int sensorValue = analogRead(A1); 3 | Serial.print("Soil Moisture: "); 4 | Serial.println(sensorValue); 5 | return sensorValue; 6 | } 7 | 8 | void setup() { 9 | Serial.begin(9600); 10 | } 11 | 12 | void loop() { 13 | delay(2000); 14 | int valSensorSoil = soilMoistVal(); 15 | } 16 | -------------------------------------------------------------------------------- /assets/sass/components/_icon.scss: -------------------------------------------------------------------------------- 1 | /// 2 | /// Dimension by HTML5 UP 3 | /// html5up.net | @ajlkn 4 | /// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) 5 | /// 6 | 7 | /* Icon */ 8 | 9 | .icon { 10 | @include icon; 11 | border-bottom: none; 12 | position: relative; 13 | 14 | > .label { 15 | display: none; 16 | } 17 | } -------------------------------------------------------------------------------- /Arduino/DHT22.ino: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define DHTPIN 7 4 | #define DHTTYPE DHT22 5 | 6 | DHT dht(DHTPIN, DHTTYPE); 7 | 8 | int chk; 9 | float hum; //Stores humidity value 10 | float temp; //Stores temperature value 11 | 12 | void setup() { 13 | Serial.begin(9600); 14 | dht.begin(); 15 | } 16 | 17 | void loop() { 18 | delay(2000); 19 | hum = dht.readHumidity(); 20 | temp= dht.readTemperature(); 21 | Serial.print("Humidity: "); 22 | Serial.print(hum); 23 | Serial.print(" %, Temp: "); 24 | Serial.print(temp); 25 | Serial.println(" Celsius"); 26 | } 27 | -------------------------------------------------------------------------------- /assets/sass/components/_box.scss: -------------------------------------------------------------------------------- 1 | /// 2 | /// Dimension by HTML5 UP 3 | /// html5up.net | @ajlkn 4 | /// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) 5 | /// 6 | 7 | /* Box */ 8 | 9 | .box { 10 | border-radius: _size(border-radius); 11 | border: solid _size(border-width) _palette(border); 12 | margin-bottom: _size(element-margin); 13 | padding: 1.5em; 14 | 15 | > :last-child, 16 | > :last-child > :last-child, 17 | > :last-child > :last-child > :last-child { 18 | margin-bottom: 0; 19 | } 20 | 21 | &.alt { 22 | border: 0; 23 | border-radius: 0; 24 | padding: 0; 25 | } 26 | } -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /assets/css/noscript.css: -------------------------------------------------------------------------------- 1 | /* 2 | Dimension by HTML5 UP 3 | html5up.net | @ajlkn 4 | Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) 5 | */ 6 | 7 | /* BG */ 8 | 9 | body.is-preload #bg:before { 10 | background-color: transparent; 11 | } 12 | 13 | /* Header */ 14 | 15 | body.is-preload #header { 16 | -moz-filter: none; 17 | -webkit-filter: none; 18 | -ms-filter: none; 19 | filter: none; 20 | } 21 | 22 | body.is-preload #header > * { 23 | opacity: 1; 24 | } 25 | 26 | body.is-preload #header .content .inner { 27 | max-height: none; 28 | padding: 3rem 2rem; 29 | opacity: 1; 30 | } 31 | 32 | /* Main */ 33 | 34 | #main article { 35 | opacity: 1; 36 | margin: 4rem 0 0 0; 37 | } -------------------------------------------------------------------------------- /Arduino/Water_Level_Sensor.ino: -------------------------------------------------------------------------------- 1 | void setup() { 2 | Serial.begin(9600); 3 | } 4 | 5 | int waterLevel() { 6 | const int sensorMin = 0; 7 | const int sensorMax = 1024; 8 | int sensorReading = analogRead(A0); 9 | int range = map(sensorReading, sensorMin, sensorMax, 0, 3); 10 | switch (range) { 11 | case 0: { 12 | Serial.println("Water level full!"); 13 | break; 14 | } 15 | case 1: { 16 | Serial.println("Water level warning!"); 17 | break; 18 | } 19 | case 2: { 20 | Serial.println("Not enough water!"); 21 | break; 22 | } 23 | } 24 | return sensorReading; 25 | } 26 | 27 | void loop() { 28 | delay(2000); 29 | int valSensorWaterLevel = waterLevel(); 30 | Serial.println(valSensorWaterLevel); 31 | } 32 | -------------------------------------------------------------------------------- /assets/sass/components/_icons.scss: -------------------------------------------------------------------------------- 1 | /// 2 | /// Dimension by HTML5 UP 3 | /// html5up.net | @ajlkn 4 | /// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) 5 | /// 6 | 7 | /* Icons */ 8 | 9 | ul.icons { 10 | cursor: default; 11 | list-style: none; 12 | padding-left: 0; 13 | 14 | li { 15 | display: inline-block; 16 | padding: 0 0.75em 0 0; 17 | 18 | &:last-child { 19 | padding-right: 0; 20 | } 21 | 22 | a { 23 | border-radius: 100%; 24 | box-shadow: inset 0 0 0 _size(border-width) _palette(border); 25 | display: inline-block; 26 | height: 2.25rem; 27 | line-height: 2.25rem; 28 | text-align: center; 29 | width: 2.25rem; 30 | 31 | &:hover { 32 | background-color: _palette(border-bg); 33 | } 34 | 35 | &:active { 36 | background-color: _palette(border-bg-alt); 37 | } 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /assets/sass/layout/_wrapper.scss: -------------------------------------------------------------------------------- 1 | /// 2 | /// Dimension by HTML5 UP 3 | /// html5up.net | @ajlkn 4 | /// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) 5 | /// 6 | 7 | /* Wrapper */ 8 | 9 | #wrapper { 10 | @include vendor('display', 'flex'); 11 | @include vendor('flex-direction', 'column'); 12 | @include vendor('align-items', 'center'); 13 | @include vendor('justify-content', 'space-between'); 14 | position: relative; 15 | min-height: 100vh; 16 | width: 100%; 17 | padding: 4rem 2rem; 18 | z-index: 3; 19 | 20 | &:before { 21 | content: ''; 22 | display: block; 23 | } 24 | 25 | @include breakpoint('<=xlarge') { 26 | padding: 3rem 2rem; 27 | } 28 | 29 | @include breakpoint('<=small') { 30 | padding: 2rem 1rem; 31 | } 32 | 33 | @include breakpoint('<=xsmall') { 34 | padding: 1rem; 35 | } 36 | } -------------------------------------------------------------------------------- /assets/sass/noscript.scss: -------------------------------------------------------------------------------- 1 | @import 'libs/vars'; 2 | @import 'libs/functions'; 3 | @import 'libs/mixins'; 4 | @import 'libs/vendor'; 5 | @import 'libs/breakpoints'; 6 | 7 | /* 8 | Dimension by HTML5 UP 9 | html5up.net | @ajlkn 10 | Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) 11 | */ 12 | 13 | /* BG */ 14 | 15 | #bg { 16 | body.is-preload & { 17 | &:before { 18 | background-color: transparent; 19 | } 20 | } 21 | } 22 | 23 | /* Header */ 24 | 25 | #header { 26 | body.is-preload & { 27 | > * { 28 | opacity: 1; 29 | } 30 | 31 | @include vendor('filter', 'none'); 32 | 33 | .content { 34 | .inner { 35 | max-height: none; 36 | padding: 3rem 2rem; 37 | opacity: 1; 38 | } 39 | } 40 | } 41 | } 42 | 43 | /* Main */ 44 | 45 | #main { 46 | article { 47 | opacity: 1; 48 | margin: (_size(element-margin) * 2) 0 0 0; 49 | } 50 | } -------------------------------------------------------------------------------- /assets/sass/layout/_footer.scss: -------------------------------------------------------------------------------- 1 | /// 2 | /// Dimension by HTML5 UP 3 | /// html5up.net | @ajlkn 4 | /// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) 5 | /// 6 | 7 | /* Footer */ 8 | 9 | #footer { 10 | @include vendor('transition', ( 11 | 'transform #{_duration(article)} ease-in-out', 12 | 'filter #{_duration(article)} ease-in-out', 13 | 'opacity #{_duration(article)} ease-in-out', 14 | )); 15 | width: 100%; 16 | max-width: 100%; 17 | margin-top: 2rem; 18 | text-align: center; 19 | 20 | .copyright { 21 | letter-spacing: _font(letter-spacing); 22 | font-size: 0.6rem; 23 | opacity: 0.75; 24 | margin-bottom: 0; 25 | text-transform: uppercase; 26 | } 27 | 28 | body.is-article-visible & { 29 | @include vendor('transform', 'scale(0.95)'); 30 | @include vendor('filter', 'blur(0.1rem)'); 31 | opacity: 0; 32 | } 33 | 34 | body.is-preload & { 35 | opacity: 0; 36 | } 37 | } -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Smartphone (please complete the following information):** 32 | - Device: [e.g. iPhone6] 33 | - OS: [e.g. iOS8.1] 34 | - Browser [e.g. stock browser, safari] 35 | - Version [e.g. 22] 36 | 37 | **Additional context** 38 | Add any other context about the problem here. 39 | -------------------------------------------------------------------------------- /assets/sass/libs/_vars.scss: -------------------------------------------------------------------------------- 1 | // Misc. 2 | $misc: ( 3 | z-index-base: 10000 4 | ); 5 | 6 | // Duration. 7 | $duration: ( 8 | transition: 0.2s, 9 | bg: 2.5s, 10 | intro: 0.75s, 11 | article: 0.325s 12 | ); 13 | 14 | // Size. 15 | $size: ( 16 | border-radius: 4px, 17 | border-width: 1px, 18 | element-height: 2.75rem, 19 | element-margin: 2rem 20 | ); 21 | 22 | // Font. 23 | $font: ( 24 | family: ('Source Sans Pro', sans-serif), 25 | family-fixed: ('Courier New', monospace), 26 | weight: 300, 27 | weight-bold: 600, 28 | letter-spacing: 0.2rem, 29 | letter-spacing-heading: 0.5rem 30 | ); 31 | 32 | // Palette. 33 | $palette: ( 34 | bg: #1b1f22, 35 | bg-alt: #000000, 36 | bg-overlay: rgba(19,21,25,0.5), 37 | fg: #ffffff, 38 | fg-bold: #ffffff, 39 | fg-light: rgba(255,255,255,0.5), 40 | border: #ffffff, 41 | border-bg: rgba(255,255,255,0.075), 42 | border-bg-alt: rgba(255,255,255,0.175) 43 | ); -------------------------------------------------------------------------------- /assets/sass/base/_page.scss: -------------------------------------------------------------------------------- 1 | /// 2 | /// Dimension by HTML5 UP 3 | /// html5up.net | @ajlkn 4 | /// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) 5 | /// 6 | 7 | /* Basic */ 8 | 9 | // MSIE: Required for IEMobile. 10 | @-ms-viewport { 11 | width: device-width; 12 | } 13 | 14 | // Ensures page width is always >=320px. 15 | @include breakpoint('<=xsmall') { 16 | html, body { 17 | min-width: 320px; 18 | } 19 | } 20 | 21 | // Set box model to border-box. 22 | // Based on css-tricks.com/inheriting-box-sizing-probably-slightly-better-best-practice 23 | html { 24 | box-sizing: border-box; 25 | } 26 | 27 | *, *:before, *:after { 28 | box-sizing: inherit; 29 | } 30 | 31 | body { 32 | background: _palette(bg); 33 | 34 | // Stops initial animations until page loads. 35 | &.is-preload { 36 | *, *:before, *:after { 37 | @include vendor('animation', 'none !important'); 38 | @include vendor('transition', 'none !important'); 39 | } 40 | } 41 | 42 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Kyle Lobo 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /assets/js/index.js: -------------------------------------------------------------------------------- 1 | $('.form').find('input, textarea').on('keyup blur focus', function (e) { 2 | 3 | var $this = $(this), 4 | label = $this.prev('label'); 5 | 6 | if (e.type === 'keyup') { 7 | if ($this.val() === '') { 8 | label.removeClass('active highlight'); 9 | } else { 10 | label.addClass('active highlight'); 11 | } 12 | } else if (e.type === 'blur') { 13 | if( $this.val() === '' ) { 14 | label.removeClass('active highlight'); 15 | } else { 16 | label.removeClass('highlight'); 17 | } 18 | } else if (e.type === 'focus') { 19 | 20 | if( $this.val() === '' ) { 21 | label.removeClass('highlight'); 22 | } 23 | else if( $this.val() !== '' ) { 24 | label.addClass('highlight'); 25 | } 26 | } 27 | 28 | }); 29 | 30 | $('.tab a').on('click', function (e) { 31 | 32 | e.preventDefault(); 33 | 34 | $(this).parent().addClass('active'); 35 | $(this).parent().siblings().removeClass('active'); 36 | 37 | target = $(this).attr('href'); 38 | 39 | $('.tab-content > div').not(target).hide(); 40 | 41 | $(target).fadeIn(600); 42 | 43 | }); -------------------------------------------------------------------------------- /assets/sass/components/_list.scss: -------------------------------------------------------------------------------- 1 | /// 2 | /// Dimension by HTML5 UP 3 | /// html5up.net | @ajlkn 4 | /// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) 5 | /// 6 | 7 | /* List */ 8 | 9 | ol { 10 | list-style: decimal; 11 | margin: 0 0 _size(element-margin) 0; 12 | padding-left: 1.25em; 13 | 14 | li { 15 | padding-left: 0.25em; 16 | } 17 | } 18 | 19 | ul { 20 | list-style: disc; 21 | margin: 0 0 _size(element-margin) 0; 22 | padding-left: 1em; 23 | 24 | li { 25 | padding-left: 0.5em; 26 | } 27 | 28 | &.alt { 29 | list-style: none; 30 | padding-left: 0; 31 | 32 | li { 33 | border-top: solid _size(border-width) _palette(border); 34 | padding: 0.5em 0; 35 | 36 | &:first-child { 37 | border-top: 0; 38 | padding-top: 0; 39 | } 40 | } 41 | } 42 | } 43 | 44 | dl { 45 | margin: 0 0 _size(element-margin) 0; 46 | 47 | dt { 48 | display: block; 49 | font-weight: _font(weight-bold); 50 | margin: 0 0 (_size(element-margin) * 0.5) 0; 51 | } 52 | 53 | dd { 54 | margin-left: _size(element-margin); 55 | } 56 | } -------------------------------------------------------------------------------- /assets/sass/main.scss: -------------------------------------------------------------------------------- 1 | @import 'libs/vars'; 2 | @import 'libs/functions'; 3 | @import 'libs/mixins'; 4 | @import 'libs/vendor'; 5 | @import 'libs/breakpoints'; 6 | @import 'font-awesome.min.css'; 7 | @import url('https://fonts.googleapis.com/css?family=Source+Sans+Pro:300italic,600italic,300,600'); 8 | 9 | /* 10 | Dimension by HTML5 UP 11 | html5up.net | @ajlkn 12 | Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) 13 | */ 14 | 15 | // Breakpoints. 16 | 17 | @include breakpoints(( 18 | xlarge: ( 1281px, 1680px ), 19 | large: ( 981px, 1280px ), 20 | medium: ( 737px, 980px ), 21 | small: ( 481px, 736px ), 22 | xsmall: ( 361px, 480px ), 23 | xxsmall: ( null, 360px ) 24 | )); 25 | 26 | // Base. 27 | 28 | @import 'base/reset'; 29 | @import 'base/page'; 30 | @import 'base/typography'; 31 | 32 | // Component. 33 | 34 | @import 'components/form'; 35 | @import 'components/box'; 36 | @import 'components/icon'; 37 | @import 'components/image'; 38 | @import 'components/list'; 39 | @import 'components/actions'; 40 | @import 'components/icons'; 41 | @import 'components/table'; 42 | @import 'components/button'; 43 | 44 | // Layout. 45 | 46 | @import 'layout/bg'; 47 | @import 'layout/wrapper'; 48 | @import 'layout/header'; 49 | @import 'layout/main'; 50 | @import 'layout/footer'; -------------------------------------------------------------------------------- /assets/sass/components/_table.scss: -------------------------------------------------------------------------------- 1 | /// 2 | /// Dimension by HTML5 UP 3 | /// html5up.net | @ajlkn 4 | /// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) 5 | /// 6 | 7 | /* Table */ 8 | 9 | .table-wrapper { 10 | -webkit-overflow-scrolling: touch; 11 | overflow-x: auto; 12 | } 13 | 14 | table { 15 | margin: 0 0 _size(element-margin) 0; 16 | width: 100%; 17 | 18 | tbody { 19 | tr { 20 | border: solid _size(border-width) _palette(border); 21 | border-left: 0; 22 | border-right: 0; 23 | 24 | &:nth-child(2n + 1) { 25 | background-color: _palette(border-bg); 26 | } 27 | } 28 | } 29 | 30 | td { 31 | padding: 0.75em 0.75em; 32 | } 33 | 34 | th { 35 | color: _palette(fg-bold); 36 | font-size: 0.9em; 37 | font-weight: _font(weight-bold); 38 | padding: 0 0.75em 0.75em 0.75em; 39 | text-align: left; 40 | } 41 | 42 | thead { 43 | border-bottom: solid (_size(border-width) * 2) _palette(border); 44 | } 45 | 46 | tfoot { 47 | border-top: solid (_size(border-width) * 2) _palette(border); 48 | } 49 | 50 | &.alt { 51 | border-collapse: separate; 52 | 53 | tbody { 54 | tr { 55 | td { 56 | border: solid _size(border-width) _palette(border); 57 | border-left-width: 0; 58 | border-top-width: 0; 59 | 60 | &:first-child { 61 | border-left-width: _size(border-width); 62 | } 63 | } 64 | 65 | &:first-child { 66 | td { 67 | border-top-width: _size(border-width); 68 | } 69 | } 70 | } 71 | } 72 | 73 | thead { 74 | border-bottom: 0; 75 | } 76 | 77 | tfoot { 78 | border-top: 0; 79 | } 80 | } 81 | } -------------------------------------------------------------------------------- /assets/js/browser.min.js: -------------------------------------------------------------------------------- 1 | /* browser.js v1.0 | @ajlkn | MIT licensed */ 2 | var browser=function(){"use strict";var e={name:null,version:null,os:null,osVersion:null,touch:null,mobile:null,_canUse:null,canUse:function(n){e._canUse||(e._canUse=document.createElement("div"));var o=e._canUse.style,r=n.charAt(0).toUpperCase()+n.slice(1);return n in o||"Moz"+r in o||"Webkit"+r in o||"O"+r in o||"ms"+r in o},init:function(){var n,o,r,i,t=navigator.userAgent;for(n="other",o=0,r=[["firefox",/Firefox\/([0-9\.]+)/],["bb",/BlackBerry.+Version\/([0-9\.]+)/],["bb",/BB[0-9]+.+Version\/([0-9\.]+)/],["opera",/OPR\/([0-9\.]+)/],["opera",/Opera\/([0-9\.]+)/],["edge",/Edge\/([0-9\.]+)/],["safari",/Version\/([0-9\.]+).+Safari/],["chrome",/Chrome\/([0-9\.]+)/],["ie",/MSIE ([0-9]+)/],["ie",/Trident\/.+rv:([0-9]+)/]],i=0;i0:!!("ontouchstart"in window),e.mobile="wp"==e.os||"android"==e.os||"ios"==e.os||"bb"==e.os}};return e.init(),e}();!function(e,n){"function"==typeof define&&define.amd?define([],n):"object"==typeof exports?module.exports=n():e.browser=n()}(this,function(){return browser}); 3 | -------------------------------------------------------------------------------- /assets/sass/components/_image.scss: -------------------------------------------------------------------------------- 1 | /// 2 | /// Dimension by HTML5 UP 3 | /// html5up.net | @ajlkn 4 | /// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) 5 | /// 6 | 7 | /* Image */ 8 | 9 | .image { 10 | border-radius: _size(border-radius); 11 | border: 0; 12 | display: inline-block; 13 | position: relative; 14 | 15 | &:before { 16 | @include vendor('pointer-events', 'none'); 17 | background-image: url('../../images/overlay.png'); 18 | background-color: _palette(bg-overlay); 19 | border-radius: _size(border-radius); 20 | content: ''; 21 | display: block; 22 | height: 100%; 23 | left: 0; 24 | opacity: 0.5; 25 | position: absolute; 26 | top: 0; 27 | width: 100%; 28 | } 29 | 30 | img { 31 | border-radius: _size(border-radius); 32 | display: block; 33 | } 34 | 35 | &.left, 36 | &.right { 37 | max-width: 40%; 38 | 39 | img { 40 | width: 100%; 41 | } 42 | } 43 | 44 | &.left { 45 | float: left; 46 | padding: 0 1.5em 1em 0; 47 | top: 0.25em; 48 | } 49 | 50 | &.right { 51 | float: right; 52 | padding: 0 0 1em 1.5em; 53 | top: 0.25em; 54 | } 55 | 56 | &.fit { 57 | display: block; 58 | margin: 0 0 _size(element-margin) 0; 59 | width: 100%; 60 | 61 | img { 62 | width: 100%; 63 | } 64 | } 65 | 66 | &.main { 67 | display: block; 68 | margin: (_size(element-margin) * 1.25) 0; 69 | width: 100%; 70 | 71 | img { 72 | width: 100%; 73 | } 74 | } 75 | 76 | @include breakpoint('<=small') { 77 | &.main { 78 | margin: (_size(element-margin) * 1) 0; 79 | } 80 | } 81 | 82 | @include breakpoint('<=xsmall') { 83 | &.main { 84 | margin: (_size(element-margin) * 0.75) 0; 85 | } 86 | } 87 | } -------------------------------------------------------------------------------- /assets/sass/base/_reset.scss: -------------------------------------------------------------------------------- 1 | /// 2 | /// Dimension by HTML5 UP 3 | /// html5up.net | @ajlkn 4 | /// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) 5 | /// 6 | 7 | // Reset. 8 | // Based on meyerweb.com/eric/tools/css/reset (v2.0 | 20110126 | License: public domain) 9 | 10 | html, body, div, span, applet, object, 11 | iframe, h1, h2, h3, h4, h5, h6, p, blockquote, 12 | pre, a, abbr, acronym, address, big, cite, 13 | code, del, dfn, em, img, ins, kbd, q, s, samp, 14 | small, strike, strong, sub, sup, tt, var, b, 15 | u, i, center, dl, dt, dd, ol, ul, li, fieldset, 16 | form, label, legend, table, caption, tbody, 17 | tfoot, thead, tr, th, td, article, aside, 18 | canvas, details, embed, figure, figcaption, 19 | footer, header, hgroup, menu, nav, output, ruby, 20 | section, summary, time, mark, audio, video { 21 | margin: 0; 22 | padding: 0; 23 | border: 0; 24 | font-size: 100%; 25 | font: inherit; 26 | vertical-align: baseline; 27 | } 28 | 29 | article, aside, details, figcaption, figure, 30 | footer, header, hgroup, menu, nav, section { 31 | display: block; 32 | } 33 | 34 | body { 35 | line-height: 1; 36 | } 37 | 38 | ol, ul { 39 | list-style:none; 40 | } 41 | 42 | blockquote, q { 43 | quotes: none; 44 | 45 | &:before, 46 | &:after { 47 | content: ''; 48 | content: none; 49 | } 50 | } 51 | 52 | table { 53 | border-collapse: collapse; 54 | border-spacing: 0; 55 | } 56 | 57 | body { 58 | -webkit-text-size-adjust: none; 59 | } 60 | 61 | mark { 62 | background-color: transparent; 63 | color: inherit; 64 | } 65 | 66 | input::-moz-focus-inner { 67 | border: 0; 68 | padding: 0; 69 | } 70 | 71 | input, select, textarea { 72 | -moz-appearance: none; 73 | -webkit-appearance: none; 74 | -ms-appearance: none; 75 | appearance: none; 76 | } -------------------------------------------------------------------------------- /assets/sass/layout/_bg.scss: -------------------------------------------------------------------------------- 1 | /// 2 | /// Dimension by HTML5 UP 3 | /// html5up.net | @ajlkn 4 | /// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) 5 | /// 6 | 7 | /* BG */ 8 | 9 | #bg { 10 | @include vendor('transform', 'scale(1.0)'); 11 | -webkit-backface-visibility: hidden; 12 | position: fixed; 13 | top: 0; 14 | left: 0; 15 | width: 100%; 16 | height: 100vh; 17 | z-index: 1; 18 | 19 | &:before, &:after { 20 | content: ''; 21 | display: block; 22 | position: absolute; 23 | top: 0; 24 | left: 0; 25 | width: 100%; 26 | height: 100%; 27 | } 28 | 29 | &:before { 30 | @include vendor('transition', 'background-color #{_duration(bg)} ease-in-out'); 31 | @include vendor('transition-delay', '#{_duration(intro)}'); 32 | background-image: linear-gradient(to top, #{_palette(bg-overlay)}, #{_palette(bg-overlay)}), 33 | url('../../images/overlay.png'); 34 | background-size: auto, 35 | 256px 256px; 36 | background-position: center, 37 | center; 38 | background-repeat: no-repeat, 39 | repeat; 40 | z-index: 2; 41 | } 42 | 43 | &:after { 44 | @include vendor('transform', 'scale(1.125)'); 45 | @include vendor('transition', ( 46 | 'transform #{_duration(article)} ease-in-out', 47 | 'filter #{_duration(article)} ease-in-out' 48 | )); 49 | background-image: url('../../images/bg.jpg'); 50 | background-position: center; 51 | background-size: cover; 52 | background-repeat: no-repeat; 53 | z-index: 1; 54 | } 55 | 56 | body.is-article-visible & { 57 | &:after { 58 | @include vendor('transform', 'scale(1.0825)'); 59 | @include vendor('filter', 'blur(0.2rem)'); 60 | } 61 | } 62 | 63 | body.is-preload & { 64 | &:before { 65 | background-color: _palette(bg-alt); 66 | } 67 | } 68 | } -------------------------------------------------------------------------------- /assets/sass/libs/_mixins.scss: -------------------------------------------------------------------------------- 1 | /// Makes an element's :before pseudoelement a FontAwesome icon. 2 | /// @param {string} $content Optional content value to use. 3 | /// @param {string} $where Optional pseudoelement to target (before or after). 4 | @mixin icon($content: false, $where: before) { 5 | 6 | text-decoration: none; 7 | 8 | &:#{$where} { 9 | 10 | @if $content { 11 | content: $content; 12 | } 13 | 14 | -moz-osx-font-smoothing: grayscale; 15 | -webkit-font-smoothing: antialiased; 16 | font-family: FontAwesome; 17 | font-style: normal; 18 | font-weight: normal; 19 | text-transform: none !important; 20 | 21 | } 22 | 23 | } 24 | 25 | /// Applies padding to an element, taking the current element-margin value into account. 26 | /// @param {mixed} $tb Top/bottom padding. 27 | /// @param {mixed} $lr Left/right padding. 28 | /// @param {list} $pad Optional extra padding (in the following order top, right, bottom, left) 29 | /// @param {bool} $important If true, adds !important. 30 | @mixin padding($tb, $lr, $pad: (0,0,0,0), $important: null) { 31 | 32 | @if $important { 33 | $important: '!important'; 34 | } 35 | 36 | $x: 0.1em; 37 | 38 | @if unit(_size(element-margin)) == 'rem' { 39 | $x: 0.1rem; 40 | } 41 | 42 | padding: ($tb + nth($pad,1)) ($lr + nth($pad,2)) max($x, $tb - _size(element-margin) + nth($pad,3)) ($lr + nth($pad,4)) #{$important}; 43 | 44 | } 45 | 46 | /// Encodes a SVG data URL so IE doesn't choke (via codepen.io/jakob-e/pen/YXXBrp). 47 | /// @param {string} $svg SVG data URL. 48 | /// @return {string} Encoded SVG data URL. 49 | @function svg-url($svg) { 50 | 51 | $svg: str-replace($svg, '"', '\''); 52 | $svg: str-replace($svg, '%', '%25'); 53 | $svg: str-replace($svg, '<', '%3C'); 54 | $svg: str-replace($svg, '>', '%3E'); 55 | $svg: str-replace($svg, '&', '%26'); 56 | $svg: str-replace($svg, '#', '%23'); 57 | $svg: str-replace($svg, '{', '%7B'); 58 | $svg: str-replace($svg, '}', '%7D'); 59 | $svg: str-replace($svg, ';', '%3B'); 60 | 61 | @return url("data:image/svg+xml;charset=utf8,#{$svg}"); 62 | 63 | } -------------------------------------------------------------------------------- /assets/css/normalize.min.css: -------------------------------------------------------------------------------- 1 | button,hr,input{overflow:visible}audio,canvas,progress,video{display:inline-block}progress,sub,sup{vertical-align:baseline}html{font-family:sans-serif;line-height:1.15;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0} menu,article,aside,details,footer,header,nav,section{display:block}h1{font-size:2em;margin:.67em 0}figcaption,figure,main{display:block}figure{margin:1em 40px}hr{box-sizing:content-box;height:0}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}a{background-color:transparent;-webkit-text-decoration-skip:objects}a:active,a:hover{outline-width:0}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:bolder}dfn{font-style:italic}mark{background-color:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}audio:not([controls]){display:none;height:0}img{border-style:none}svg:not(:root){overflow:hidden}button,input,optgroup,select,textarea{font-family:sans-serif;font-size:100%;line-height:1.15;margin:0}button,input{}button,select{text-transform:none}[type=submit], [type=reset],button,html [type=button]{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:ButtonText dotted 1px}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}[hidden],template{display:none}/*# sourceMappingURL=normalize.min.css.map */ 2 | -------------------------------------------------------------------------------- /Arduino/PH_Sensor.ino: -------------------------------------------------------------------------------- 1 | #define SensorPin A3 2 | #define Offset 0.00 3 | #define samplingInterval 20 4 | #define printInterval 800 5 | #define ArrayLenth 40 6 | 7 | int pHArray[ArrayLenth]; 8 | int pHArrayIndex = 0; 9 | int countTrueCommand; 10 | int countTimeCommand; 11 | boolean found = false; 12 | 13 | float phVal() { 14 | static unsigned long samplingTime = millis(); 15 | static unsigned long printTime = millis(); 16 | static float pHValue, voltage; 17 | if(millis()-samplingTime > samplingInterval) { 18 | pHArray[pHArrayIndex++] = analogRead(SensorPin); 19 | if(pHArrayIndex == ArrayLenth) { 20 | pHArrayIndex = 0; 21 | } 22 | voltage = avergearray(pHArray, ArrayLenth)*5.0/1024; 23 | pHValue = 3.5*voltage+Offset; 24 | samplingTime = millis(); 25 | } 26 | if(millis()-printTime > printInterval) { 27 | Serial.print("Voltage:"); 28 | Serial.print(voltage,2); 29 | Serial.print(" pH value: "); 30 | Serial.println(pHValue,2); 31 | printTime = millis(); 32 | } 33 | return pHValue; 34 | } 35 | 36 | double avergearray(int* arr, int number) { 37 | int i; 38 | int max,min; 39 | double avg; 40 | long amount = 0; 41 | if(number <= 0) { 42 | Serial.println("Error number for the array to avraging!/n"); 43 | return 0; 44 | } 45 | if(number < 5) { 46 | for(i = 0; i < number; i++) { 47 | amount += arr[i]; 48 | } 49 | avg = amount/number; 50 | return avg; 51 | } 52 | else { 53 | if(arr[0] < arr[1]) { 54 | min = arr[0]; 55 | max = arr[1]; 56 | } 57 | else { 58 | min = arr[1]; 59 | max = arr[0]; 60 | } 61 | for(i = 2; i < number; i++) { 62 | if(arr[i] < min) { 63 | amount += min; 64 | min = arr[i]; 65 | } 66 | else { 67 | if(arr[i] > max) { 68 | amount += max; 69 | max = arr[i]; 70 | } 71 | else { 72 | amount += arr[i]; 73 | } 74 | } 75 | } 76 | avg = (double)amount/(number-2); 77 | } 78 | return avg; 79 | } 80 | 81 | void setup() { 82 | Serial.begin(9600); 83 | } 84 | 85 | void loop() { 86 | delay(2000); 87 | int valSensorPH = phVal(); 88 | } 89 | -------------------------------------------------------------------------------- /assets/sass/components/_button.scss: -------------------------------------------------------------------------------- 1 | /// 2 | /// Dimension by HTML5 UP 3 | /// html5up.net | @ajlkn 4 | /// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) 5 | /// 6 | 7 | /* Button */ 8 | 9 | input[type="submit"], 10 | input[type="reset"], 11 | input[type="button"], 12 | button, 13 | .button { 14 | @include vendor('appearance', 'none'); 15 | @include vendor('transition', 'background-color #{_duration(transition)} ease-in-out, color #{_duration(transition)} ease-in-out'); 16 | background-color: transparent; 17 | border-radius: _size(border-radius); 18 | border: 0; 19 | box-shadow: inset 0 0 0 _size(border-width) _palette(border); 20 | color: _palette(fg-bold) !important; 21 | cursor: pointer; 22 | display: inline-block; 23 | font-size: 0.8rem; 24 | font-weight: _font(weight); 25 | height: _size(element-height); 26 | letter-spacing: _font(letter-spacing); 27 | line-height: _size(element-height); 28 | outline: 0; 29 | padding: 0 1.25rem 0 (1.25rem + (_font(letter-spacing) * 0.5)); 30 | text-align: center; 31 | text-decoration: none; 32 | text-transform: uppercase; 33 | white-space: nowrap; 34 | 35 | &:hover { 36 | background-color: _palette(border-bg); 37 | } 38 | 39 | &:active { 40 | background-color: _palette(border-bg-alt); 41 | } 42 | 43 | &.icon { 44 | &:before { 45 | margin-right: 0.5em; 46 | } 47 | } 48 | 49 | &.fit { 50 | width: 100%; 51 | } 52 | 53 | &.small { 54 | font-size: 0.6rem; 55 | height: (_size(element-height) * 0.75); 56 | line-height: (_size(element-height) * 0.75); 57 | } 58 | 59 | &.primary { 60 | background-color: _palette(fg-bold); 61 | color: _palette(bg) !important; 62 | font-weight: _font(weight-bold); 63 | 64 | &:hover { 65 | } 66 | 67 | &:active { 68 | } 69 | } 70 | 71 | &.disabled, 72 | &:disabled { 73 | @include vendor('pointer-events', 'none'); 74 | cursor: default; 75 | opacity: 0.25; 76 | } 77 | } 78 | 79 | input[type="submit"], 80 | input[type="reset"], 81 | input[type="button"], 82 | button { 83 | line-height: calc(#{_size(element-height)} - 2px); 84 | } -------------------------------------------------------------------------------- /assets/sass/components/_actions.scss: -------------------------------------------------------------------------------- 1 | /// 2 | /// Dimension by HTML5 UP 3 | /// html5up.net | @ajlkn 4 | /// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) 5 | /// 6 | 7 | /* Actions */ 8 | 9 | ul.actions { 10 | @include vendor('display', 'flex'); 11 | cursor: default; 12 | list-style: none; 13 | margin-left: (_size(element-margin) * -0.5); 14 | padding-left: 0; 15 | 16 | li { 17 | padding: 0 0 0 (_size(element-margin) * 0.5); 18 | vertical-align: middle; 19 | } 20 | 21 | &.special { 22 | @include vendor('justify-content', 'center'); 23 | width: 100%; 24 | margin-left: 0; 25 | 26 | li { 27 | &:first-child { 28 | padding-left: 0; 29 | } 30 | } 31 | } 32 | 33 | &.stacked { 34 | @include vendor('flex-direction', 'column'); 35 | margin-left: 0; 36 | 37 | li { 38 | padding: (_size(element-margin) * 0.65) 0 0 0; 39 | 40 | &:first-child { 41 | padding-top: 0; 42 | } 43 | } 44 | } 45 | 46 | &.fit { 47 | width: calc(100% + #{_size(element-margin) * 0.5}); 48 | 49 | li { 50 | @include vendor('flex-grow', '1'); 51 | @include vendor('flex-shrink', '1'); 52 | width: 100%; 53 | 54 | > * { 55 | width: 100%; 56 | } 57 | } 58 | 59 | &.stacked { 60 | width: 100%; 61 | } 62 | } 63 | 64 | @include breakpoint('<=xsmall') { 65 | &:not(.fixed) { 66 | @include vendor('flex-direction', 'column'); 67 | margin-left: 0; 68 | width: 100% !important; 69 | 70 | li { 71 | @include vendor('flex-grow', '1'); 72 | @include vendor('flex-shrink', '1'); 73 | padding: (_size(element-margin) * 0.5) 0 0 0; 74 | text-align: center; 75 | width: 100%; 76 | 77 | > * { 78 | width: 100%; 79 | } 80 | 81 | &:first-child { 82 | padding-top: 0; 83 | } 84 | 85 | input[type="submit"], 86 | input[type="reset"], 87 | input[type="button"], 88 | button, 89 | .button { 90 | width: 100%; 91 | 92 | &.icon { 93 | &:before { 94 | margin-left: -0.5em; 95 | } 96 | } 97 | } 98 | } 99 | } 100 | } 101 | } -------------------------------------------------------------------------------- /assets/sass/libs/_functions.scss: -------------------------------------------------------------------------------- 1 | /// Removes a specific item from a list. 2 | /// @author Hugo Giraudel 3 | /// @param {list} $list List. 4 | /// @param {integer} $index Index. 5 | /// @return {list} Updated list. 6 | @function remove-nth($list, $index) { 7 | 8 | $result: null; 9 | 10 | @if type-of($index) != number { 11 | @warn "$index: #{quote($index)} is not a number for `remove-nth`."; 12 | } 13 | @else if $index == 0 { 14 | @warn "List index 0 must be a non-zero integer for `remove-nth`."; 15 | } 16 | @else if abs($index) > length($list) { 17 | @warn "List index is #{$index} but list is only #{length($list)} item long for `remove-nth`."; 18 | } 19 | @else { 20 | 21 | $result: (); 22 | $index: if($index < 0, length($list) + $index + 1, $index); 23 | 24 | @for $i from 1 through length($list) { 25 | 26 | @if $i != $index { 27 | $result: append($result, nth($list, $i)); 28 | } 29 | 30 | } 31 | 32 | } 33 | 34 | @return $result; 35 | 36 | } 37 | 38 | /// Gets a value from a map. 39 | /// @author Hugo Giraudel 40 | /// @param {map} $map Map. 41 | /// @param {string} $keys Key(s). 42 | /// @return {string} Value. 43 | @function val($map, $keys...) { 44 | 45 | @if nth($keys, 1) == null { 46 | $keys: remove-nth($keys, 1); 47 | } 48 | 49 | @each $key in $keys { 50 | $map: map-get($map, $key); 51 | } 52 | 53 | @return $map; 54 | 55 | } 56 | 57 | /// Gets a duration value. 58 | /// @param {string} $keys Key(s). 59 | /// @return {string} Value. 60 | @function _duration($keys...) { 61 | @return val($duration, $keys...); 62 | } 63 | 64 | /// Gets a font value. 65 | /// @param {string} $keys Key(s). 66 | /// @return {string} Value. 67 | @function _font($keys...) { 68 | @return val($font, $keys...); 69 | } 70 | 71 | /// Gets a misc value. 72 | /// @param {string} $keys Key(s). 73 | /// @return {string} Value. 74 | @function _misc($keys...) { 75 | @return val($misc, $keys...); 76 | } 77 | 78 | /// Gets a palette value. 79 | /// @param {string} $keys Key(s). 80 | /// @return {string} Value. 81 | @function _palette($keys...) { 82 | @return val($palette, $keys...); 83 | } 84 | 85 | /// Gets a size value. 86 | /// @param {string} $keys Key(s). 87 | /// @return {string} Value. 88 | @function _size($keys...) { 89 | @return val($size, $keys...); 90 | } -------------------------------------------------------------------------------- /assets/js/breakpoints.min.js: -------------------------------------------------------------------------------- 1 | /* breakpoints.js v1.0 | @ajlkn | MIT licensed */ 2 | var breakpoints=function(){"use strict";function e(e){t.init(e)}var t={list:null,media:{},events:[],init:function(e){t.list=e,window.addEventListener("resize",t.poll),window.addEventListener("orientationchange",t.poll),window.addEventListener("load",t.poll),window.addEventListener("fullscreenchange",t.poll)},active:function(e){var n,a,s,i,r,d,c;if(!(e in t.media)){if(">="==e.substr(0,2)?(a="gte",n=e.substr(2)):"<="==e.substr(0,2)?(a="lte",n=e.substr(2)):">"==e.substr(0,1)?(a="gt",n=e.substr(1)):"<"==e.substr(0,1)?(a="lt",n=e.substr(1)):"!"==e.substr(0,1)?(a="not",n=e.substr(1)):(a="eq",n=e),n&&n in t.list)if(i=t.list[n],Array.isArray(i)){if(r=parseInt(i[0]),d=parseInt(i[1]),isNaN(r)){if(isNaN(d))return;c=i[1].substr(String(d).length)}else c=i[0].substr(String(r).length);if(isNaN(r))switch(a){case"gte":s="screen";break;case"lte":s="screen and (max-width: "+d+c+")";break;case"gt":s="screen and (min-width: "+(d+1)+c+")";break;case"lt":s="screen and (max-width: -1px)";break;case"not":s="screen and (min-width: "+(d+1)+c+")";break;default:s="screen and (max-width: "+d+c+")"}else if(isNaN(d))switch(a){case"gte":s="screen and (min-width: "+r+c+")";break;case"lte":s="screen";break;case"gt":s="screen and (max-width: -1px)";break;case"lt":s="screen and (max-width: "+(r-1)+c+")";break;case"not":s="screen and (max-width: "+(r-1)+c+")";break;default:s="screen and (min-width: "+r+c+")"}else switch(a){case"gte":s="screen and (min-width: "+r+c+")";break;case"lte":s="screen and (max-width: "+d+c+")";break;case"gt":s="screen and (min-width: "+(d+1)+c+")";break;case"lt":s="screen and (max-width: "+(r-1)+c+")";break;case"not":s="screen and (max-width: "+(r-1)+c+"), screen and (min-width: "+(d+1)+c+")";break;default:s="screen and (min-width: "+r+c+") and (max-width: "+d+c+")"}}else s="("==i.charAt(0)?"screen and "+i:i;t.media[e]=!!s&&s}return t.media[e]!==!1&&window.matchMedia(t.media[e]).matches},on:function(e,n){t.events.push({query:e,handler:n,state:!1}),t.active(e)&&n()},poll:function(){var e,n;for(e=0;e 2 | #include 3 | #include 4 | #include 5 | 6 | #define RX 10 7 | #define TX 11 8 | 9 | #define DHTPIN 7 10 | #define DHTTYPE DHT22 11 | 12 | DHT dht(DHTPIN, DHTTYPE); 13 | 14 | WiFiClient client; 15 | 16 | String AP = ""; // CHANGE ME 17 | String PASS = ""; // CHANGE ME 18 | String API = ""; // CHANGE ME 19 | String HOST = "api.thingspeak.com"; 20 | String PORT = "80"; 21 | String field1 = "field1"; 22 | String field2 = "field2"; 23 | int countTrueCommand; 24 | int countTimeCommand; 25 | boolean found = false; 26 | int valSensor1 = 1; 27 | int valSensor2 = 1; 28 | int valSensor3 = 1; 29 | int valSensor4 = 1; 30 | int valSensor5 = 1; 31 | SoftwareSerial esp8266(RX, TX); 32 | 33 | void setup() { 34 | Serial.begin(9600); 35 | dht.begin(); 36 | ThingSpeak.begin(client); 37 | esp8266.begin(115200); 38 | sendCommand("AT", 5, "OK"); 39 | sendCommand("AT+CWMODE=1", 5, "OK"); 40 | sendCommand("AT+CWJAP=\"" + AP + "\",\"" + PASS + "\"", 20, "OK"); 41 | } 42 | void loop() { 43 | valSensor1 = dht.readTemperature(); 44 | valSensor2 = dht.readHumidity(); 45 | ThingSpeak.setField(1, valSensor1); 46 | ThingSpeak.setField(2, valSensor2); 47 | ThingSpeak.writeFields(592525, "UWH8BKGIQVRARD0W"); 48 | String getData = "GET /update?api_key=" + API + "&" + field1 + "=" + String(valSensor1) + "&" + field2 + "=" + String(valSensor2); 49 | sendCommand("AT+CIPMUX=1", 5, "OK"); 50 | sendCommand("AT+CIPSTART=0,\"TCP\",\"" + HOST + "\"," + PORT, 15, "OK"); 51 | sendCommand("AT+CIPSEND=0," + String(getData.length() + 4), 6, ">"); 52 | esp8266.println(getData); delay(2500); countTrueCommand++; 53 | sendCommand("AT+CIPCLOSE=0", 5, "OK"); 54 | } 55 | 56 | void sendCommand(String command, int maxTime, char readReplay[]) { 57 | Serial.print(countTrueCommand); 58 | Serial.print(". at command => "); 59 | Serial.print(command); 60 | Serial.print(" "); 61 | while (countTimeCommand < (maxTime * 1)) { 62 | esp8266.println(command);//at+cipsend 63 | if (esp8266.find(readReplay)) //ok { 64 | found = true; 65 | break; 66 | } 67 | countTimeCommand++; 68 | } 69 | 70 | if (found == true) { 71 | Serial.println("OYI"); 72 | countTrueCommand++; 73 | countTimeCommand = 0; 74 | } 75 | 76 | if (found == false) { 77 | Serial.println("Fail"); 78 | countTrueCommand = 0; 79 | countTimeCommand = 0; 80 | } 81 | found = false; 82 | } 83 | -------------------------------------------------------------------------------- /ajax.php: -------------------------------------------------------------------------------- 1 | 8 | 9 | 10 | 11 | 12 | Sensor Data 13 | 14 | 15 | 16 | 17 | 18 | 30 | 31 | 32 | 33 |

Welcome

34 |

35 | 36 | 37 |

Sensor Data


38 | 39 |

40 | 41 | 42 |

43 |

44 | 45 |
46 | 47 | 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /server.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/sass/layout/_main.scss: -------------------------------------------------------------------------------- 1 | /// 2 | /// Dimension by HTML5 UP 3 | /// html5up.net | @ajlkn 4 | /// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) 5 | /// 6 | 7 | /* Main */ 8 | 9 | #main { 10 | @include vendor('flex-grow', '1'); 11 | @include vendor('flex-shrink', '1'); 12 | @include vendor('display', 'flex'); 13 | @include vendor('align-items', 'center'); 14 | @include vendor('justify-content', 'center'); 15 | @include vendor('flex-direction', 'column'); 16 | position: relative; 17 | max-width: 100%; 18 | z-index: 3; 19 | 20 | article { 21 | @include vendor('transform', 'translateY(0.25rem)'); 22 | @include vendor('transition', ( 23 | 'opacity #{_duration(article)} ease-in-out', 24 | 'transform #{_duration(article)} ease-in-out' 25 | )); 26 | @include padding(2.5rem, 2.5rem, (2rem, 0, 1rem, 0)); 27 | position: relative; 28 | width: 40rem; 29 | max-width: 100%; 30 | background-color: transparentize(_palette(bg), 0.15); 31 | border-radius: _size(border-radius); 32 | opacity: 0; 33 | 34 | &.active { 35 | @include vendor('transform', 'translateY(0)'); 36 | opacity: 1; 37 | } 38 | 39 | .close { 40 | display: block; 41 | position: absolute; 42 | top: 0; 43 | right: 0; 44 | width: 4rem; 45 | height: 4rem; 46 | cursor: pointer; 47 | text-indent: 4rem; 48 | overflow: hidden; 49 | white-space: nowrap; 50 | 51 | &:before { 52 | @include vendor('transition', 'background-color #{_duration(transition)} ease-in-out'); 53 | content: ''; 54 | display: block; 55 | position: absolute; 56 | top: 0.75rem; 57 | left: 0.75rem; 58 | width: 2.5rem; 59 | height: 2.5rem; 60 | border-radius: 100%; 61 | background-position: center; 62 | background-image: svg-url(''); 63 | background-size: 20px 20px; 64 | background-repeat: no-repeat; 65 | } 66 | 67 | &:hover { 68 | &:before { 69 | background-color: _palette(border-bg); 70 | } 71 | } 72 | 73 | &:active { 74 | &:before { 75 | background-color: _palette(border-bg-alt); 76 | } 77 | } 78 | } 79 | } 80 | 81 | @include breakpoint('<=small') { 82 | article { 83 | @include padding(2rem, 2rem, (1.5rem, 0, 0.5rem, 0)); 84 | 85 | .close { 86 | &:before { 87 | top: 0.875rem; 88 | left: 0.875rem; 89 | width: 2.25rem; 90 | height: 2.25rem; 91 | background-size: 14px 14px; 92 | } 93 | } 94 | } 95 | } 96 | 97 | @include breakpoint('<=xsmall') { 98 | article { 99 | @include padding(2rem, 1.5rem, (1rem, 0, 0.5rem, 0)); 100 | } 101 | } 102 | } -------------------------------------------------------------------------------- /home.php: -------------------------------------------------------------------------------- 1 | 8 | 9 | 10 | 11 | 12 | Sensor Data 13 | 14 | 15 | 16 | 17 | 18 | 29 | 30 | 31 | 32 |

33 |

Sensor Graphs


34 |
35 | 36 | 49 | 50 | 51 | 52 | 55 | 56 | 57 | 60 | 63 | 64 | 65 | 68 | 71 | 72 | 73 | 76 | 79 | 80 |
53 |

Data Collection Dashboard

54 |
58 | 59 | 61 | 62 |
66 | 67 | 69 | 70 |
74 | 75 | 77 | 78 |
81 | 82 | 83 | 84 | -------------------------------------------------------------------------------- /assets/css/style.css: -------------------------------------------------------------------------------- 1 | *, *:before, *:after { 2 | box-sizing: border-box; 3 | } 4 | 5 | html { 6 | overflow-y: scroll; 7 | } 8 | 9 | body { 10 | background: #c1bdba; 11 | font-family: 'Titillium Web', sans-serif; 12 | } 13 | 14 | a { 15 | text-decoration: none; 16 | color: #FFFFFF; 17 | transition: .5s ease; 18 | } 19 | a:hover { 20 | color: #FFFFFF; 21 | } 22 | 23 | .form { 24 | background: rgba(19, 35, 47, 0.9); 25 | padding: 40px; 26 | max-width: 600px; 27 | margin: 40px auto; 28 | border-radius: 4px; 29 | box-shadow: 0 4px 10px 4px rgba(19, 35, 47, 0.3); 30 | } 31 | 32 | .tab-group { 33 | list-style: none; 34 | padding: 0; 35 | margin: 0 0 40px 0; 36 | } 37 | .tab-group:after { 38 | content: ""; 39 | display: table; 40 | clear: both; 41 | } 42 | .tab-group li a { 43 | display: block; 44 | text-decoration: none; 45 | padding: 15px; 46 | background: rgba(160, 179, 176, 0.25); 47 | color: #a0b3b0; 48 | font-size: 20px; 49 | float: left; 50 | width: 50%; 51 | text-align: center; 52 | cursor: pointer; 53 | transition: .5s ease; 54 | } 55 | .tab-group li a:hover { 56 | background: #179b77; 57 | color: #ffffff; 58 | } 59 | .tab-group .active a { 60 | background: #1ab188; 61 | color: #ffffff; 62 | } 63 | 64 | .tab-content > div:last-child { 65 | display: none; 66 | } 67 | 68 | h1 { 69 | text-align: center; 70 | color: #ffffff; 71 | font-weight: 300; 72 | margin: 0 0 40px; 73 | } 74 | 75 | label { 76 | position: absolute; 77 | -webkit-transform: translateY(6px); 78 | transform: translateY(6px); 79 | left: 13px; 80 | color: rgba(255, 255, 255, 0.5); 81 | transition: all 0.25s ease; 82 | -webkit-backface-visibility: hidden; 83 | pointer-events: none; 84 | font-size: 22px; 85 | } 86 | label .req { 87 | margin: 2px; 88 | color: #1ab188; 89 | } 90 | 91 | label.active { 92 | -webkit-transform: translateY(50px); 93 | transform: translateY(50px); 94 | left: 2px; 95 | font-size: 14px; 96 | } 97 | label.active .req { 98 | opacity: 0; 99 | } 100 | 101 | label.highlight { 102 | color: #ffffff; 103 | } 104 | 105 | input, textarea { 106 | font-size: 22px; 107 | display: block; 108 | width: 100%; 109 | height: 100%; 110 | padding: 5px 10px; 111 | background: none; 112 | background-image: none; 113 | border: 1px solid #a0b3b0; 114 | color: #ffffff; 115 | border-radius: 0; 116 | transition: border-color .25s ease, box-shadow .25s ease; 117 | } 118 | input:focus, textarea:focus { 119 | outline: 0; 120 | border-color: #1ab188; 121 | } 122 | 123 | textarea { 124 | border: 2px solid #a0b3b0; 125 | resize: vertical; 126 | } 127 | 128 | .field-wrap { 129 | position: relative; 130 | margin-bottom: 40px; 131 | } 132 | 133 | .top-row:after { 134 | content: ""; 135 | display: table; 136 | clear: both; 137 | } 138 | .top-row > div { 139 | float: left; 140 | width: 48%; 141 | margin-right: 4%; 142 | } 143 | .top-row > div:last-child { 144 | margin: 0; 145 | } 146 | 147 | .button { 148 | border: 0; 149 | outline: none; 150 | border-radius: 0; 151 | padding: 15px 10; 152 | font-size: 1.6rem; 153 | font-weight: 600; 154 | text-transform: uppercase; 155 | letter-spacing: .1em; 156 | background: #1ab188; 157 | color: #ffffff; 158 | transition: all 0.5s ease; 159 | -webkit-appearance: none; 160 | } 161 | .button:hover, .button:focus { 162 | background: #179b77; 163 | } 164 | 165 | .button-block { 166 | display: block; 167 | width: 100%; 168 | } 169 | 170 | .forgot { 171 | margin-top: -20px; 172 | text-align: right; 173 | } 174 | -------------------------------------------------------------------------------- /Arduino/Water_Pump_w_L298.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #define RX 10 3 | #define TX 11 4 | #define DHTPIN 2 5 | #define DHTTYPE DHT22 6 | DHT dht(DHTPIN, DHTTYPE); 7 | 8 | #define SensorPin A0 9 | #define Offset 0.00 10 | #define samplingInterval 20 11 | #define printInterval 800 12 | #define ArrayLenth 40 13 | int pHArray[ArrayLenth]; 14 | int pHArrayIndex=0; 15 | 16 | const int sensorMin = 0; 17 | const int sensorMax = 1024; 18 | 19 | int countTrueCommand; 20 | int countTimeCommand; 21 | boolean found = false; 22 | int valSensor1 = 1; 23 | int valSensor2 = 1; 24 | float valSensor3 = 1; 25 | int valSensor4 = 1; 26 | int valSensor5 = 1; 27 | float phVal(); 28 | int soilMoistVal(); 29 | int waterLevel(); 30 | 31 | void setup() { 32 | Serial.begin(9600); 33 | dht.begin(); 34 | } 35 | 36 | void loop() { 37 | valSensor1 = dht.readTemperature(); 38 | valSensor2 = dht.readHumidity(); 39 | Serial.println("Temperature : "); 40 | Serial.println(valSensor1); 41 | Serial.println("Humidity :"); 42 | Serial.println(valSensor2); 43 | //valSensor4 = soilMoistVal(); 44 | valSensor5 = waterLevel(); 45 | delay(5000); 46 | } 47 | 48 | int waterLevel() { 49 | int sensorReading = analogRead(A3); 50 | int range = map(sensorReading, sensorMin, sensorMax, 0, 3); 51 | 52 | switch (range) { 53 | case 0: { 54 | Serial.println("Flood"); 55 | break; 56 | } 57 | case 1: { 58 | Serial.println("Rain Warning"); 59 | break; 60 | } 61 | case 2: { 62 | Serial.println("Not Raining"); 63 | break; 64 | } 65 | return range; 66 | } 67 | } 68 | 69 | int soilMoistVal() { 70 | int sensorValue = analogRead(A1); 71 | Serial.println("Soil Moisture:"); 72 | Serial.println(sensorValue); 73 | return sensorValue; 74 | } 75 | 76 | float phVal() { 77 | static unsigned long samplingTime = millis(); 78 | static unsigned long printTime = millis(); 79 | static float pHValue,voltage; 80 | if(millis()-samplingTime > samplingInterval) { 81 | pHArray[pHArrayIndex++]=analogRead(SensorPin); 82 | if(pHArrayIndex==ArrayLenth) pHArrayIndex=0; 83 | voltage = avergearray(pHArray, ArrayLenth)*5.0/1024; 84 | pHValue = 3.5*voltage+Offset; 85 | samplingTime=millis(); 86 | } 87 | if(millis() - printTime > printInterval) { 88 | Serial.print("Voltage:"); 89 | Serial.print(voltage,2); 90 | Serial.print(" pH value: "); 91 | Serial.println(pHValue,2); 92 | printTime=millis(); 93 | } 94 | return pHValue; 95 | } 96 | 97 | double avergearray(int* arr, int number){ 98 | int i; 99 | int max,min; 100 | double avg; 101 | long amount = 0; 102 | if(number <= 0){ 103 | Serial.println("Error number for the array to avraging!/n"); 104 | return 0; 105 | } 106 | if(number < 5) { 107 | for(i = 0; i < number; i++) { 108 | amount += arr[i]; 109 | } 110 | avg = amount/number; 111 | return avg; 112 | } else { 113 | if(arr[0] < arr[1]) { 114 | min = arr[0]; 115 | max = arr[1]; 116 | } 117 | else { 118 | min = arr[1]; 119 | max = arr[0]; 120 | } 121 | for(i = 2; i < number; i++) { 122 | if(arr[i] < min) { 123 | amount += min; 124 | min = arr[i]; 125 | } else { 126 | if(arr[i] > max) { 127 | amount += max; 128 | max = arr[i]; 129 | } else { 130 | amount += arr[i]; 131 | } 132 | } 133 | } 134 | avg = (double)amount/(number-2); 135 | } 136 | return avg; 137 | } 138 | 139 | -------------------------------------------------------------------------------- /assets/scss/style.scss: -------------------------------------------------------------------------------- 1 | @import "compass/css3"; 2 | 3 | $body-bg: #c1bdba; 4 | $form-bg: #13232f; 5 | $white: #ffffff; 6 | 7 | $main: #1ab188; 8 | $main-light: lighten($main,5%); 9 | $main-dark: darken($main,5%); 10 | 11 | $gray-light: #a0b3b0; 12 | $gray: #ddd; 13 | 14 | $thin: 300; 15 | $normal: 400; 16 | $bold: 600; 17 | $br: 4px; 18 | 19 | *, *:before, *:after { 20 | box-sizing: border-box; 21 | } 22 | 23 | html { 24 | overflow-y: scroll; 25 | } 26 | 27 | body { 28 | background:$body-bg; 29 | font-family: 'Titillium Web', sans-serif; 30 | } 31 | 32 | a { 33 | text-decoration:none; 34 | color:$main; 35 | transition:.5s ease; 36 | &:hover { 37 | color:$main-dark; 38 | } 39 | } 40 | 41 | .form { 42 | background:rgba($form-bg,.9); 43 | padding: 40px; 44 | max-width:600px; 45 | margin:40px auto; 46 | border-radius:$br; 47 | box-shadow:0 4px 10px 4px rgba($form-bg,.3); 48 | } 49 | 50 | .tab-group { 51 | list-style:none; 52 | padding:0; 53 | margin:0 0 40px 0; 54 | &:after { 55 | content: ""; 56 | display: table; 57 | clear: both; 58 | } 59 | li a { 60 | display:block; 61 | text-decoration:none; 62 | padding:15px; 63 | background:rgba($gray-light,.25); 64 | color:$gray-light; 65 | font-size:20px; 66 | float:left; 67 | width:50%; 68 | text-align:center; 69 | cursor:pointer; 70 | transition:.5s ease; 71 | &:hover { 72 | background:$main-dark; 73 | color:$white; 74 | } 75 | } 76 | .active a { 77 | background:$main; 78 | color:$white; 79 | } 80 | } 81 | 82 | .tab-content > div:last-child { 83 | display:none; 84 | } 85 | 86 | 87 | h1 { 88 | text-align:center; 89 | color:$white; 90 | font-weight:$thin; 91 | margin:0 0 40px; 92 | } 93 | 94 | label { 95 | position:absolute; 96 | transform:translateY(6px); 97 | left:13px; 98 | color:rgba($white,.5); 99 | transition:all 0.25s ease; 100 | -webkit-backface-visibility: hidden; 101 | pointer-events: none; 102 | font-size:22px; 103 | .req { 104 | margin:2px; 105 | color:$main; 106 | } 107 | } 108 | 109 | label.active { 110 | transform:translateY(50px); 111 | left:2px; 112 | font-size:14px; 113 | .req { 114 | opacity:0; 115 | } 116 | } 117 | 118 | label.highlight { 119 | color:$white; 120 | } 121 | 122 | input, textarea { 123 | font-size:22px; 124 | display:block; 125 | width:100%; 126 | height:100%; 127 | padding:5px 10px; 128 | background:none; 129 | background-image:none; 130 | border:1px solid $gray-light; 131 | color:$white; 132 | border-radius:0; 133 | transition:border-color .25s ease, box-shadow .25s ease; 134 | &:focus { 135 | outline:0; 136 | border-color:$main; 137 | } 138 | } 139 | 140 | textarea { 141 | border:2px solid $gray-light; 142 | resize: vertical; 143 | } 144 | 145 | .field-wrap { 146 | position:relative; 147 | margin-bottom:40px; 148 | } 149 | 150 | .top-row { 151 | &:after { 152 | content: ""; 153 | display: table; 154 | clear: both; 155 | } 156 | 157 | > div { 158 | float:left; 159 | width:48%; 160 | margin-right:4%; 161 | &:last-child { 162 | margin:0; 163 | } 164 | } 165 | } 166 | 167 | .button { 168 | border:0; 169 | outline:none; 170 | border-radius:0; 171 | padding:15px 0; 172 | font-size:2rem; 173 | font-weight:$bold; 174 | text-transform:uppercase; 175 | letter-spacing:.1em; 176 | background:$main; 177 | color:$white; 178 | transition:all.5s ease; 179 | -webkit-appearance: none; 180 | &:hover, &:focus { 181 | background:$main-dark; 182 | } 183 | } 184 | 185 | .button-block { 186 | display:block; 187 | width:100%; 188 | } 189 | 190 | .forgot { 191 | margin-top:-20px; 192 | text-align:right; 193 | } -------------------------------------------------------------------------------- /assets/sass/base/_typography.scss: -------------------------------------------------------------------------------- 1 | /// 2 | /// Dimension by HTML5 UP 3 | /// html5up.net | @ajlkn 4 | /// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) 5 | /// 6 | 7 | /* Type */ 8 | 9 | html { 10 | font-size: 16pt; 11 | 12 | @include breakpoint('<=xlarge') { 13 | font-size: 12pt; 14 | } 15 | 16 | @include breakpoint('<=small') { 17 | font-size: 11pt; 18 | } 19 | 20 | @include breakpoint('<=xxsmall') { 21 | font-size: 10pt; 22 | } 23 | } 24 | 25 | body, input, select, textarea { 26 | color: _palette(fg); 27 | font-family: _font(family); 28 | font-weight: _font(weight); 29 | font-size: 1rem; 30 | line-height: 1.65; 31 | } 32 | 33 | a { 34 | @include vendor('transition', ( 35 | 'color #{_duration(transition)} ease-in-out', 36 | 'background-color #{_duration(transition)} ease-in-out', 37 | 'border-bottom-color #{_duration(transition)} ease-in-out' 38 | )); 39 | border-bottom: dotted 1px _palette(fg-light); 40 | text-decoration: none; 41 | color: inherit; 42 | 43 | &:hover { 44 | border-bottom-color: transparent; 45 | } 46 | } 47 | 48 | strong, b { 49 | color: _palette(fg-bold); 50 | font-weight: _font(weight-bold); 51 | } 52 | 53 | em, i { 54 | font-style: italic; 55 | } 56 | 57 | p { 58 | margin: 0 0 _size(element-margin) 0; 59 | } 60 | 61 | h1, h2, h3, h4, h5, h6 { 62 | color: _palette(fg-bold); 63 | font-weight: _font(weight-bold); 64 | line-height: 1.5; 65 | margin: 0 0 (_size(element-margin) * 0.5) 0; 66 | text-transform: uppercase; 67 | letter-spacing: _font(letter-spacing); 68 | 69 | a { 70 | color: inherit; 71 | text-decoration: none; 72 | } 73 | 74 | &.major { 75 | border-bottom: solid _size(border-width) _palette(border); 76 | width: -moz-max-content; 77 | width: -webkit-max-content; 78 | width: -ms-max-content; 79 | width: max-content; 80 | padding-bottom: 0.5rem; 81 | margin: 0 0 (_size(element-margin) * 1) 0; 82 | } 83 | } 84 | 85 | h1 { 86 | font-size: 2.25rem; 87 | line-height: 1.3; 88 | letter-spacing: _font(letter-spacing-heading); 89 | } 90 | 91 | h2 { 92 | font-size: 1.5rem; 93 | line-height: 1.4; 94 | letter-spacing: _font(letter-spacing-heading); 95 | } 96 | 97 | h3 { 98 | font-size: 1rem; 99 | } 100 | 101 | h4 { 102 | font-size: 0.8rem; 103 | } 104 | 105 | h5 { 106 | font-size: 0.7rem; 107 | } 108 | 109 | h6 { 110 | font-size: 0.6rem; 111 | } 112 | 113 | @include breakpoint('<=small') { 114 | h1 { 115 | font-size: 1.75rem; 116 | line-height: 1.4; 117 | } 118 | 119 | h2 { 120 | font-size: 1.25em; 121 | line-height: 1.5; 122 | } 123 | } 124 | 125 | sub { 126 | font-size: 0.8rem; 127 | position: relative; 128 | top: 0.5rem; 129 | } 130 | 131 | sup { 132 | font-size: 0.8rem; 133 | position: relative; 134 | top: -0.5rem; 135 | } 136 | 137 | blockquote { 138 | border-left: solid (_size(border-width) * 4) _palette(border); 139 | font-style: italic; 140 | margin: 0 0 _size(element-margin) 0; 141 | padding: (_size(element-margin) / 4) 0 (_size(element-margin) / 4) _size(element-margin); 142 | } 143 | 144 | code { 145 | background: _palette(border-bg); 146 | border-radius: _size(border-radius); 147 | font-family: _font(family-fixed); 148 | font-size: 0.9rem; 149 | margin: 0 0.25rem; 150 | padding: 0.25rem 0.65rem; 151 | } 152 | 153 | pre { 154 | -webkit-overflow-scrolling: touch; 155 | font-family: _font(family-fixed); 156 | font-size: 0.9rem; 157 | margin: 0 0 _size(element-margin) 0; 158 | 159 | code { 160 | display: block; 161 | line-height: 1.75; 162 | padding: 1rem 1.5rem; 163 | overflow-x: auto; 164 | } 165 | } 166 | 167 | hr { 168 | border: 0; 169 | border-bottom: solid _size(border-width) _palette(border); 170 | margin: (_size(element-margin) * 1.375) 0; 171 | } 172 | 173 | .align-left { 174 | text-align: left; 175 | } 176 | 177 | .align-center { 178 | text-align: center; 179 | } 180 | 181 | .align-right { 182 | text-align: right; 183 | } -------------------------------------------------------------------------------- /assets/sass/libs/_breakpoints.scss: -------------------------------------------------------------------------------- 1 | // breakpoints.scss v1.0 | @ajlkn | MIT licensed */ 2 | 3 | // Vars. 4 | 5 | /// Breakpoints. 6 | /// @var {list} 7 | $breakpoints: () !global; 8 | 9 | // Mixins. 10 | 11 | /// Sets breakpoints. 12 | /// @param {map} $x Breakpoints. 13 | @mixin breakpoints($x: ()) { 14 | $breakpoints: $x !global; 15 | } 16 | 17 | /// Wraps @content in a @media block targeting a specific orientation. 18 | /// @param {string} $orientation Orientation. 19 | @mixin orientation($orientation) { 20 | @media screen and (orientation: #{$orientation}) { 21 | @content; 22 | } 23 | } 24 | 25 | /// Wraps @content in a @media block using a given query. 26 | /// @param {string} $query Query. 27 | @mixin breakpoint($query: null) { 28 | 29 | $breakpoint: null; 30 | $op: null; 31 | $media: null; 32 | 33 | // Determine operator, breakpoint. 34 | 35 | // Greater than or equal. 36 | @if (str-slice($query, 0, 2) == '>=') { 37 | 38 | $op: 'gte'; 39 | $breakpoint: str-slice($query, 3); 40 | 41 | } 42 | 43 | // Less than or equal. 44 | @elseif (str-slice($query, 0, 2) == '<=') { 45 | 46 | $op: 'lte'; 47 | $breakpoint: str-slice($query, 3); 48 | 49 | } 50 | 51 | // Greater than. 52 | @elseif (str-slice($query, 0, 1) == '>') { 53 | 54 | $op: 'gt'; 55 | $breakpoint: str-slice($query, 2); 56 | 57 | } 58 | 59 | // Less than. 60 | @elseif (str-slice($query, 0, 1) == '<') { 61 | 62 | $op: 'lt'; 63 | $breakpoint: str-slice($query, 2); 64 | 65 | } 66 | 67 | // Not. 68 | @elseif (str-slice($query, 0, 1) == '!') { 69 | 70 | $op: 'not'; 71 | $breakpoint: str-slice($query, 2); 72 | 73 | } 74 | 75 | // Equal. 76 | @else { 77 | 78 | $op: 'eq'; 79 | $breakpoint: $query; 80 | 81 | } 82 | 83 | // Build media. 84 | @if ($breakpoint and map-has-key($breakpoints, $breakpoint)) { 85 | 86 | $a: map-get($breakpoints, $breakpoint); 87 | 88 | // Range. 89 | @if (type-of($a) == 'list') { 90 | 91 | $x: nth($a, 1); 92 | $y: nth($a, 2); 93 | 94 | // Max only. 95 | @if ($x == null) { 96 | 97 | // Greater than or equal (>= 0 / anything) 98 | @if ($op == 'gte') { 99 | $media: 'screen'; 100 | } 101 | 102 | // Less than or equal (<= y) 103 | @elseif ($op == 'lte') { 104 | $media: 'screen and (max-width: ' + $y + ')'; 105 | } 106 | 107 | // Greater than (> y) 108 | @elseif ($op == 'gt') { 109 | $media: 'screen and (min-width: ' + ($y + 1) + ')'; 110 | } 111 | 112 | // Less than (< 0 / invalid) 113 | @elseif ($op == 'lt') { 114 | $media: 'screen and (max-width: -1px)'; 115 | } 116 | 117 | // Not (> y) 118 | @elseif ($op == 'not') { 119 | $media: 'screen and (min-width: ' + ($y + 1) + ')'; 120 | } 121 | 122 | // Equal (<= y) 123 | @else { 124 | $media: 'screen and (max-width: ' + $y + ')'; 125 | } 126 | 127 | } 128 | 129 | // Min only. 130 | @else if ($y == null) { 131 | 132 | // Greater than or equal (>= x) 133 | @if ($op == 'gte') { 134 | $media: 'screen and (min-width: ' + $x + ')'; 135 | } 136 | 137 | // Less than or equal (<= inf / anything) 138 | @elseif ($op == 'lte') { 139 | $media: 'screen'; 140 | } 141 | 142 | // Greater than (> inf / invalid) 143 | @elseif ($op == 'gt') { 144 | $media: 'screen and (max-width: -1px)'; 145 | } 146 | 147 | // Less than (< x) 148 | @elseif ($op == 'lt') { 149 | $media: 'screen and (max-width: ' + ($x - 1) + ')'; 150 | } 151 | 152 | // Not (< x) 153 | @elseif ($op == 'not') { 154 | $media: 'screen and (max-width: ' + ($x - 1) + ')'; 155 | } 156 | 157 | // Equal (>= x) 158 | @else { 159 | $media: 'screen and (min-width: ' + $x + ')'; 160 | } 161 | 162 | } 163 | 164 | // Min and max. 165 | @else { 166 | 167 | // Greater than or equal (>= x) 168 | @if ($op == 'gte') { 169 | $media: 'screen and (min-width: ' + $x + ')'; 170 | } 171 | 172 | // Less than or equal (<= y) 173 | @elseif ($op == 'lte') { 174 | $media: 'screen and (max-width: ' + $y + ')'; 175 | } 176 | 177 | // Greater than (> y) 178 | @elseif ($op == 'gt') { 179 | $media: 'screen and (min-width: ' + ($y + 1) + ')'; 180 | } 181 | 182 | // Less than (< x) 183 | @elseif ($op == 'lt') { 184 | $media: 'screen and (max-width: ' + ($x - 1) + ')'; 185 | } 186 | 187 | // Not (< x and > y) 188 | @elseif ($op == 'not') { 189 | $media: 'screen and (max-width: ' + ($x - 1) + '), screen and (min-width: ' + ($y + 1) + ')'; 190 | } 191 | 192 | // Equal (>= x and <= y) 193 | @else { 194 | $media: 'screen and (min-width: ' + $x + ') and (max-width: ' + $y + ')'; 195 | } 196 | 197 | } 198 | 199 | } 200 | 201 | // String. 202 | @else { 203 | 204 | // Missing a media type? Prefix with "screen". 205 | @if (str-slice($a, 0, 1) == '(') { 206 | $media: 'screen and ' + $a; 207 | } 208 | 209 | // Otherwise, use as-is. 210 | @else { 211 | $media: $a; 212 | } 213 | 214 | } 215 | 216 | } 217 | 218 | // Output. 219 | @media #{$media} { 220 | @content; 221 | } 222 | 223 | } -------------------------------------------------------------------------------- /Arduino/Hydroponics.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #define DHTPIN 7 7 | #define DHTTYPE DHT22 8 | #define RX 10 9 | #define TX 11 10 | 11 | DHT dht(DHTPIN, DHTTYPE); 12 | //WiFiClient client; 13 | #define SensorPin A3 14 | #define Offset 0.00 15 | #define samplingInterval 20 16 | #define printInterval 800 17 | #define ArrayLenth 40 18 | int pHArray[ArrayLenth]; 19 | int pHArrayIndex = 0; 20 | int countTrueCommand; 21 | int countTimeCommand; 22 | boolean found = false; 23 | String AP = ""; // CHANGE ME 24 | String PASS = ""; // CHANGE ME 25 | String API = ""; // CHANGE ME 26 | String HOST = "api.thingspeak.com"; 27 | String PORT = "80"; 28 | String field1 = "field1"; 29 | String field2 = "field2"; 30 | int valSensor1 = 1; 31 | int valSensor2 = 1; 32 | int valSensor3 = 1; 33 | int valSensor4 = 1; 34 | int valSensor5 = 1; 35 | SoftwareSerial esp8266(RX, TX); 36 | 37 | int chk; 38 | float hum; //Stores humidity value 39 | float temp; //Stores temperature value 40 | 41 | float phVal() { 42 | static unsigned long samplingTime = millis(); 43 | static unsigned long printTime = millis(); 44 | static float pHValue, voltage; 45 | if (millis() - samplingTime > samplingInterval) { 46 | pHArray[pHArrayIndex++] = analogRead(SensorPin); 47 | if (pHArrayIndex == ArrayLenth) { 48 | pHArrayIndex = 0; 49 | } 50 | voltage = avergearray(pHArray, ArrayLenth) * 5.0 / 1024; 51 | pHValue = 3.5 * voltage + Offset; 52 | samplingTime = millis(); 53 | } 54 | if (millis() - printTime > printInterval) { 55 | Serial.print("Voltage:"); 56 | Serial.print(voltage, 2); 57 | Serial.print(" pH value: "); 58 | Serial.println(pHValue, 2); 59 | printTime = millis(); 60 | } 61 | return pHValue; 62 | } 63 | 64 | double avergearray(int* arr, int number) { 65 | int i; 66 | int max, min; 67 | double avg; 68 | long amount = 0; 69 | if (number <= 0) { 70 | Serial.println("Error number for the array to avraging!/n"); 71 | return 0; 72 | } 73 | if (number < 5) { 74 | for (i = 0; i < number; i++) { 75 | amount += arr[i]; 76 | } 77 | avg = amount / number; 78 | return avg; 79 | } 80 | else { 81 | if (arr[0] < arr[1]) { 82 | min = arr[0]; 83 | max = arr[1]; 84 | } 85 | else { 86 | min = arr[1]; 87 | max = arr[0]; 88 | } 89 | for (i = 2; i < number; i++) { 90 | if (arr[i] < min) { 91 | amount += min; 92 | min = arr[i]; 93 | } 94 | else { 95 | if (arr[i] > max) { 96 | amount += max; 97 | max = arr[i]; 98 | } 99 | else { 100 | amount += arr[i]; 101 | } 102 | } 103 | } 104 | avg = (double)amount / (number - 2); 105 | } 106 | return avg; 107 | } 108 | 109 | int soilMoistVal() { 110 | int sensorValue = analogRead(A1); 111 | Serial.print("Soil Moisture: "); 112 | Serial.println(sensorValue); 113 | return sensorValue; 114 | } 115 | 116 | int waterTemp() { 117 | int sensorValue = analogRead(A2); 118 | Serial.print("Temperature: "); 119 | Serial.println(sensorValue); 120 | return sensorValue; 121 | } 122 | 123 | int waterLevel() { 124 | const int sensorMin = 0; 125 | const int sensorMax = 1024; 126 | int sensorReading = analogRead(A0); 127 | int range = map(sensorReading, sensorMin, sensorMax, 0, 3); 128 | switch (range) { 129 | case 0: { 130 | Serial.println("Water level full!"); 131 | break; 132 | } 133 | case 1: { 134 | Serial.println("Water level warning!"); 135 | break; 136 | } 137 | case 2: { 138 | Serial.println("Not enough water!"); 139 | break; 140 | } 141 | } 142 | return sensorReading; 143 | } 144 | 145 | void setup() { 146 | Serial.begin(9600); 147 | pinMode(13, OUTPUT); 148 | dht.begin(); 149 | ThingSpeak.begin(client); 150 | esp8266.begin(115200); 151 | sendCommand("AT", 5, "OK"); 152 | sendCommand("AT+CWMODE=1", 5, "OK"); 153 | sendCommand("AT+CWJAP=\"" + AP + "\",\"" + PASS + "\"", 20, "OK"); 154 | } 155 | 156 | void loop() { 157 | delay(2000); 158 | hum = dht.readHumidity(); 159 | temp = dht.readTemperature(); 160 | 161 | Serial.print("Humidity: "); 162 | Serial.print(hum); 163 | 164 | Serial.print(" %, Temp: "); 165 | Serial.print(temp); 166 | 167 | Serial.println(" Celsius"); 168 | 169 | delay(2000); 170 | 171 | int valSensorPH = phVal(); 172 | 173 | delay(2000); 174 | 175 | int valSensorSoil = soilMoistVal(); 176 | 177 | delay(2000); 178 | 179 | int valSensorWaterTemp = waterTemp(); 180 | 181 | delay(2000); 182 | 183 | int valSensorWaterLevel = waterLevel(); 184 | Serial.println(valSensorWaterLevel); 185 | 186 | delay(2000); 187 | 188 | digitalWrite(13, LOW); 189 | 190 | delay(2000); 191 | 192 | ThingSpeak.setField(1, temp); 193 | ThingSpeak.setField(2, hum); 194 | ThingSpeak.writeFields(592525, "UWH8BKGIQVRARD0W"); 195 | String getData = "GET /update?api_key=" + API + "&" + field1 + "=" + String(valSensor1) + "&" + field2 + "=" + String(valSensor2); 196 | sendCommand("AT+CIPMUX=1", 5, "OK"); 197 | sendCommand("AT+CIPSTART=0,\"TCP\",\"" + HOST + "\"," + PORT, 15, "OK"); 198 | sendCommand("AT+CIPSEND=0," + String(getData.length() + 4), 6, ">"); 199 | esp8266.println(getData); delay(2500); countTrueCommand++; 200 | sendCommand("AT+CIPCLOSE=0", 5, "OK"); 201 | } 202 | 203 | void sendCommand(String command, int maxTime, char readReplay[]) { 204 | Serial.print(countTrueCommand); 205 | Serial.print(". at command => "); 206 | Serial.print(command); 207 | Serial.print(" "); 208 | while (countTimeCommand < (maxTime * 1)) { 209 | esp8266.println(command);//at+cipsend 210 | if (esp8266.find(readReplay)) //ok { 211 | found = true; 212 | break; 213 | } 214 | countTimeCommand++; 215 | } 216 | 217 | if (found == true) { 218 | Serial.println("OYI"); 219 | countTrueCommand++; 220 | countTimeCommand = 0; 221 | } 222 | 223 | if (found == false) { 224 | Serial.println("Fail"); 225 | countTrueCommand = 0; 226 | countTimeCommand = 0; 227 | } 228 | 229 | found = false; 230 | } 231 | -------------------------------------------------------------------------------- /assets/sass/layout/_header.scss: -------------------------------------------------------------------------------- 1 | /// 2 | /// Dimension by HTML5 UP 3 | /// html5up.net | @ajlkn 4 | /// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) 5 | /// 6 | 7 | /* Header */ 8 | 9 | #header { 10 | @include vendor('display', 'flex'); 11 | @include vendor('flex-direction', 'column'); 12 | @include vendor('align-items', 'center'); 13 | @include vendor('transition', ( 14 | 'transform #{_duration(article)} ease-in-out', 15 | 'filter #{_duration(article)} ease-in-out', 16 | 'opacity #{_duration(article)} ease-in-out', 17 | )); 18 | background-image: -moz-radial-gradient(rgba(0,0,0,0.25) 25%, rgba(0,0,0,0) 55%); 19 | background-image: -webkit-radial-gradient(rgba(0,0,0,0.25) 25%, rgba(0,0,0,0) 55%); 20 | background-image: -ms-radial-gradient(rgba(0,0,0,0.25) 25%, rgba(0,0,0,0) 55%); 21 | background-image: radial-gradient(rgba(0,0,0,0.25) 25%, rgba(0,0,0,0) 55%); 22 | max-width: 100%; 23 | text-align: center; 24 | 25 | > * { 26 | @include vendor('transition', 'opacity #{_duration(article)} ease-in-out'); 27 | position: relative; 28 | margin-top: 3.5rem; 29 | 30 | &:before { 31 | content: ''; 32 | display: block; 33 | position: absolute; 34 | top: calc(-3.5rem - 1px); 35 | left: calc(50% - #{_size(border-width) * 1}); 36 | width: _size(border-width); 37 | height: calc(3.5rem + 1px); 38 | background: _palette(border); 39 | } 40 | } 41 | 42 | > :first-child { 43 | margin-top: 0; 44 | 45 | &:before { 46 | display: none; 47 | } 48 | } 49 | 50 | .logo { 51 | width: 5.5rem; 52 | height: 5.5rem; 53 | line-height: 5.5rem; 54 | border: solid _size(border-width) _palette(border); 55 | border-radius: 100%; 56 | 57 | .icon { 58 | &:before { 59 | font-size: 2rem; 60 | } 61 | } 62 | } 63 | 64 | .content { 65 | border-style: solid; 66 | border-color: _palette(border); 67 | border-top-width: _size(border-width); 68 | border-bottom-width: _size(border-width); 69 | max-width: 100%; 70 | 71 | .inner { 72 | @include vendor('transition', ( 73 | 'max-height #{_duration(intro)} ease', 74 | 'padding #{_duration(intro)} ease', 75 | 'opacity #{_duration(article)} ease-in-out' 76 | )); 77 | @include vendor('transition-delay', '0.25s'); 78 | padding: 3rem 2rem; 79 | max-height: 40rem; 80 | overflow: hidden; 81 | 82 | > :last-child { 83 | margin-bottom: 0; 84 | } 85 | } 86 | 87 | p { 88 | text-transform: uppercase; 89 | letter-spacing: _font(letter-spacing); 90 | font-size: 0.8rem; 91 | line-height: 2; 92 | } 93 | } 94 | 95 | nav { 96 | ul { 97 | @include vendor('display', 'flex'); 98 | margin-bottom: 0; 99 | list-style: none; 100 | padding-left: 0; 101 | border: solid _size(border-width) _palette(border); 102 | border-radius: _size(border-radius); 103 | 104 | li { 105 | padding-left: 0; 106 | border-left: solid _size(border-width) _palette(border); 107 | 108 | &:first-child { 109 | border-left: 0; 110 | } 111 | 112 | a { 113 | display: block; 114 | min-width: 7.5rem; 115 | height: 2.75rem; 116 | line-height: 2.75rem; 117 | padding: 0 1.25rem 0 (1.25rem + _font(letter-spacing)); 118 | text-transform: uppercase; 119 | letter-spacing: _font(letter-spacing); 120 | font-size: 0.8rem; 121 | border-bottom: 0; 122 | 123 | &:hover { 124 | background-color: _palette(border-bg); 125 | } 126 | 127 | &:active { 128 | background-color: _palette(border-bg-alt); 129 | } 130 | } 131 | } 132 | } 133 | 134 | &.use-middle { 135 | &:after { 136 | content: ''; 137 | display: block; 138 | position: absolute; 139 | top: 0; 140 | left: calc(50% - #{_size(border-width) * 1}); 141 | width: _size(border-width); 142 | height: 100%; 143 | background: _palette(border); 144 | } 145 | 146 | ul { 147 | li { 148 | &.is-middle { 149 | border-left: 0; 150 | } 151 | } 152 | } 153 | } 154 | } 155 | 156 | body.is-article-visible & { 157 | @include vendor('transform', 'scale(0.95)'); 158 | @include vendor('filter', 'blur(0.1rem)'); 159 | opacity: 0; 160 | } 161 | 162 | body.is-preload & { 163 | > * { 164 | opacity: 0; 165 | } 166 | 167 | @include vendor('filter', 'blur(0.125rem)'); 168 | 169 | .content { 170 | .inner { 171 | max-height: 0; 172 | padding-top: 0; 173 | padding-bottom: 0; 174 | opacity: 0; 175 | } 176 | } 177 | } 178 | 179 | @include breakpoint('<=medium') { 180 | .content { 181 | p { 182 | br { 183 | display: none; 184 | } 185 | } 186 | } 187 | } 188 | 189 | @include breakpoint('<=small') { 190 | > * { 191 | margin-top: 2rem; 192 | 193 | &:before { 194 | top: calc(-2rem - 1px); 195 | height: calc(2rem + 1px); 196 | } 197 | } 198 | 199 | .logo { 200 | width: 4.75rem; 201 | height: 4.75rem; 202 | line-height: 4.75rem; 203 | 204 | .icon { 205 | &:before { 206 | font-size: 1.75rem; 207 | } 208 | } 209 | } 210 | 211 | .content { 212 | .inner { 213 | padding: 2.5rem 1rem; 214 | } 215 | 216 | p { 217 | line-height: 1.875; 218 | } 219 | } 220 | } 221 | 222 | @include breakpoint('<=xsmall') { 223 | padding: 1.5rem 0; 224 | 225 | .content { 226 | .inner { 227 | padding: 2.5rem 0; 228 | } 229 | } 230 | 231 | nav { 232 | ul { 233 | @include vendor('flex-direction', 'column'); 234 | min-width: 10rem; 235 | max-width: 100%; 236 | 237 | li { 238 | border-left: 0; 239 | border-top: solid _size(border-width) _palette(border); 240 | 241 | &:first-child { 242 | border-top: 0; 243 | } 244 | 245 | a { 246 | height: 3rem; 247 | line-height: 3rem; 248 | min-width: 0; 249 | width: 100%; 250 | } 251 | } 252 | } 253 | 254 | &.use-middle { 255 | &:after { 256 | display: none; 257 | } 258 | } 259 | } 260 | } 261 | } -------------------------------------------------------------------------------- /assets/sass/components/_form.scss: -------------------------------------------------------------------------------- 1 | /// 2 | /// Dimension by HTML5 UP 3 | /// html5up.net | @ajlkn 4 | /// Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) 5 | /// 6 | 7 | /* Form */ 8 | 9 | form { 10 | margin: 0 0 _size(element-margin) 0; 11 | 12 | > :last-child { 13 | margin-bottom: 0; 14 | } 15 | 16 | > .fields { 17 | $gutter: (_size(element-margin) * 0.75); 18 | 19 | @include vendor('display', 'flex'); 20 | @include vendor('flex-wrap', 'wrap'); 21 | width: calc(100% + #{$gutter * 2}); 22 | margin: ($gutter * -1) 0 _size(element-margin) ($gutter * -1); 23 | 24 | > .field { 25 | @include vendor('flex-grow', '0'); 26 | @include vendor('flex-shrink', '0'); 27 | padding: $gutter 0 0 $gutter; 28 | width: calc(100% - #{$gutter * 1}); 29 | 30 | &.half { 31 | width: calc(50% - #{$gutter * 0.5}); 32 | } 33 | 34 | &.third { 35 | width: calc(#{100% / 3} - #{$gutter * (1 / 3)}); 36 | } 37 | 38 | &.quarter { 39 | width: calc(25% - #{$gutter * 0.25}); 40 | } 41 | } 42 | } 43 | 44 | @include breakpoint('<=xsmall') { 45 | > .fields { 46 | $gutter: (_size(element-margin) * 0.75); 47 | 48 | width: calc(100% + #{$gutter * 2}); 49 | margin: ($gutter * -1) 0 _size(element-margin) ($gutter * -1); 50 | 51 | > .field { 52 | padding: $gutter 0 0 $gutter; 53 | width: calc(100% - #{$gutter * 1}); 54 | 55 | &.half { 56 | width: calc(100% - #{$gutter * 1}); 57 | } 58 | 59 | &.third { 60 | width: calc(100% - #{$gutter * 1}); 61 | } 62 | 63 | &.quarter { 64 | width: calc(100% - #{$gutter * 1}); 65 | } 66 | } 67 | } 68 | } 69 | } 70 | 71 | label { 72 | color: _palette(fg-bold); 73 | display: block; 74 | font-size: 0.8rem; 75 | font-weight: _font(weight); 76 | letter-spacing: _font(letter-spacing); 77 | line-height: 1.5; 78 | margin: 0 0 (_size(element-margin) * 0.5) 0; 79 | text-transform: uppercase; 80 | } 81 | 82 | input[type="text"], 83 | input[type="password"], 84 | input[type="email"], 85 | input[type="tel"], 86 | select, 87 | textarea { 88 | @include vendor('appearance', 'none'); 89 | @include vendor('transition', ( 90 | 'border-color #{_duration(transition)} ease-in-out', 91 | 'box-shadow #{_duration(transition)} ease-in-out', 92 | 'background-color #{_duration(transition)} ease-in-out' 93 | )); 94 | background-color: transparent; 95 | border-radius: _size(border-radius); 96 | border: solid _size(border-width) _palette(border); 97 | color: inherit; 98 | display: block; 99 | outline: 0; 100 | padding: 0 1rem; 101 | text-decoration: none; 102 | width: 100%; 103 | 104 | &:invalid { 105 | box-shadow: none; 106 | } 107 | 108 | &:focus { 109 | background: _palette(border-bg); 110 | border-color: _palette(fg-bold); 111 | box-shadow: 0 0 0 _size(border-width) _palette(fg-bold); 112 | } 113 | } 114 | 115 | select { 116 | background-image: svg-url(""); 117 | background-size: 1.25rem; 118 | background-repeat: no-repeat; 119 | background-position: calc(100% - 1rem) center; 120 | height: _size(element-height); 121 | padding-right: _size(element-height); 122 | text-overflow: ellipsis; 123 | 124 | option { 125 | color: _palette(fg); 126 | background: _palette(bg); 127 | } 128 | 129 | &:focus { 130 | &::-ms-value { 131 | background-color: transparent; 132 | } 133 | } 134 | 135 | &::-ms-expand { 136 | display: none; 137 | } 138 | } 139 | 140 | input[type="text"], 141 | input[type="password"], 142 | input[type="email"], 143 | select { 144 | height: _size(element-height); 145 | } 146 | 147 | textarea { 148 | padding: 0.75rem 1rem; 149 | } 150 | 151 | input[type="checkbox"], 152 | input[type="radio"], { 153 | @include vendor('appearance', 'none'); 154 | display: block; 155 | float: left; 156 | margin-right: -2rem; 157 | opacity: 0; 158 | width: 1rem; 159 | z-index: -1; 160 | 161 | & + label { 162 | @include icon; 163 | @include vendor('user-select', 'none'); 164 | color: _palette(fg); 165 | cursor: pointer; 166 | display: inline-block; 167 | font-size: 0.8rem; 168 | font-weight: _font(weight); 169 | margin: 0 0 (_size(element-margin) * 0.25) 0; 170 | padding-left: (_size(element-height) * 0.6) + 1rem; 171 | padding-right: 0.75rem; 172 | position: relative; 173 | 174 | &:before { 175 | @include vendor('transition', ( 176 | 'border-color #{_duration(transition)} ease-in-out', 177 | 'box-shadow #{_duration(transition)} ease-in-out', 178 | 'background-color #{_duration(transition)} ease-in-out' 179 | )); 180 | border-radius: _size(border-radius); 181 | border: solid _size(border-width) _palette(border); 182 | content: ''; 183 | display: inline-block; 184 | height: (_size(element-height) * 0.6); 185 | left: 0; 186 | //line-height: (_size(element-height) * 0.575); 187 | line-height: calc(#{_size(element-height) * 0.575} + 0em); 188 | position: absolute; 189 | text-align: center; 190 | top: -0.125rem; 191 | width: (_size(element-height) * 0.6); 192 | } 193 | } 194 | 195 | &:checked + label { 196 | &:before { 197 | background: _palette(fg-bold) !important; 198 | border-color: _palette(fg-bold) !important; 199 | color: _palette(bg); 200 | content: '\f00c'; 201 | } 202 | } 203 | 204 | &:focus + label { 205 | &:before { 206 | background: _palette(border-bg); 207 | border-color: _palette(fg-bold); 208 | box-shadow: 0 0 0 _size(border-width) _palette(fg-bold); 209 | } 210 | } 211 | } 212 | 213 | input[type="checkbox"] { 214 | & + label { 215 | &:before { 216 | border-radius: _size(border-radius); 217 | } 218 | } 219 | } 220 | 221 | input[type="radio"] { 222 | & + label { 223 | &:before { 224 | border-radius: 100%; 225 | } 226 | } 227 | } 228 | 229 | ::-webkit-input-placeholder { 230 | color: _palette(fg-light) !important; 231 | opacity: 1.0; 232 | } 233 | 234 | :-moz-placeholder { 235 | color: _palette(fg-light) !important; 236 | opacity: 1.0; 237 | } 238 | 239 | ::-moz-placeholder { 240 | color: _palette(fg-light) !important; 241 | opacity: 1.0; 242 | } 243 | 244 | :-ms-input-placeholder { 245 | color: _palette(fg-light) !important; 246 | opacity: 1.0; 247 | } 248 | 249 | .formerize-placeholder { 250 | color: _palette(fg-light) !important; 251 | opacity: 1.0; 252 | } -------------------------------------------------------------------------------- /index.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Hydroponics using Arduino 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 22 |
23 | 42 | 43 | 44 |
45 | 46 | 47 |
48 |

Intro

49 | 50 | 51 |

Hydroponics is a subset of hydroculture, the method of growing plants without soil, using mineral nutrient solutions in a water solvent. Terrestrial plants may be grown with only their roots exposed to the mineral solution, or the roots may be supported by an inert medium, such as perlite or gravel. The nutrients in hydroponics can come from an array of different sources; these can include but are not limited to byproduct from fish waste, duck manure, or commercial fertilisers.
52 |
Growing with hydroponics comes with many advantages, the biggest of which is a greatly increased rate of growth in your plants. With a proper setup, your plants will mature up to 25% faster and produce up to 30% more than the same plants grown in soil.
53 |
Plants in a hydroponic system grow more quickly because they have food and water available to them all the time. They produce bigger crops because they can devote their energy to producing their crop rather than producing large roots such as would be needed in soil to seek out water and nutrients. Hydroponically-grown plants have smaller root systems because the roots do not need to go out looking for nutrients and water.
54 |
All of this is possible through careful control of the nutrient solution and pH levels. A hydroponic system will also use 70-90% less water than soil based plants because the system is enclosed, which results in less evaporation. Hydroponics is better for the environment because it reduces waste and pollution from soil runoff.

55 |
56 | 57 | 58 |
59 |

Work

60 | 61 | 62 | 63 | 64 |
65 | 66 | 67 |
68 |

About

69 | 70 |

The entire system mainly consists of a grow box, a water reservoir, a water pump and few sensors.
71 |
The water pumps are attached to the nutrient solution, reservoir, water reservoir and the pH up down solutions. The water level sensor, temperature sensor, EC sensor, pH sensor are installed in the reservoir.
72 |
When the EC sensor detects low-salt levels it indicates nutrient deficiencies. Therefore, in such situations, the water pump pumps the nutrient solution to the reservoir. The presence of high salt levels/low water levels indicates that fresh water needs to be pumped to the reservoir.
73 |
Overlooking pH control can be perilous for plants, particularly those that rely on water supplies with high alkalinity.
74 | The pH of the nutrient solution is a major factor in determining the uptake rate of many essential nutrient ions. Run pH too high and the dreaded nutrient lockout looms.
75 | The pH sensor detects the pH level of the water and prompts the pH up/ pH down pump to balance out the pH levels in the reservoir.
76 |
The grow box has a drainage system which allows continous flow of nutrient solution runs over the plants roots.
77 |
This type of system works very well because the roots of a plant absorb more oxygen from the air than from the nutrient solution itself. Since only the tips of the roots come in contact with the nutrient solution, the plant is able to get more oxygen which fascilitates a faster rate of growth.

78 |
79 | 80 | 81 |
82 |

Join Us

83 |
84 | 88 | 89 |
90 |
91 |

Sign Up for Free

92 |
93 | 94 |
95 |
96 | 99 | 100 |
101 |
102 | 105 | 106 |
107 |
108 |
109 | 112 | 113 |
114 |
115 | 118 | 119 |
120 | 121 |
122 |
123 | 124 |
125 |

Welcome Back!

126 |
127 |
128 | 131 | 132 |
133 |
134 | 137 | 138 |
139 |

Forgot Password?

140 | 141 |
142 |
143 |
144 | 145 | 146 | 147 | 148 |
149 |
150 | 151 | 152 | 155 |
156 | 157 | 158 |
159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | -------------------------------------------------------------------------------- /assets/sass/libs/_vendor.scss: -------------------------------------------------------------------------------- 1 | // vendor.scss v1.0 | @ajlkn | MIT licensed */ 2 | 3 | // Vars. 4 | 5 | /// Vendor prefixes. 6 | /// @var {list} 7 | $vendor-prefixes: ( 8 | '-moz-', 9 | '-webkit-', 10 | '-ms-', 11 | '' 12 | ); 13 | 14 | /// Properties that should be vendorized. 15 | /// Data via caniuse.com, github.com/postcss/autoprefixer, and developer.mozilla.org 16 | /// @var {list} 17 | $vendor-properties: ( 18 | 19 | // Animation. 20 | 'animation', 21 | 'animation-delay', 22 | 'animation-direction', 23 | 'animation-duration', 24 | 'animation-fill-mode', 25 | 'animation-iteration-count', 26 | 'animation-name', 27 | 'animation-play-state', 28 | 'animation-timing-function', 29 | 30 | // Appearance. 31 | 'appearance', 32 | 33 | // Backdrop filter. 34 | 'backdrop-filter', 35 | 36 | // Background image options. 37 | 'background-clip', 38 | 'background-origin', 39 | 'background-size', 40 | 41 | // Box sizing. 42 | 'box-sizing', 43 | 44 | // Clip path. 45 | 'clip-path', 46 | 47 | // Filter effects. 48 | 'filter', 49 | 50 | // Flexbox. 51 | 'align-content', 52 | 'align-items', 53 | 'align-self', 54 | 'flex', 55 | 'flex-basis', 56 | 'flex-direction', 57 | 'flex-flow', 58 | 'flex-grow', 59 | 'flex-shrink', 60 | 'flex-wrap', 61 | 'justify-content', 62 | 'order', 63 | 64 | // Font feature. 65 | 'font-feature-settings', 66 | 'font-language-override', 67 | 'font-variant-ligatures', 68 | 69 | // Font kerning. 70 | 'font-kerning', 71 | 72 | // Fragmented borders and backgrounds. 73 | 'box-decoration-break', 74 | 75 | // Grid layout. 76 | 'grid-column', 77 | 'grid-column-align', 78 | 'grid-column-end', 79 | 'grid-column-start', 80 | 'grid-row', 81 | 'grid-row-align', 82 | 'grid-row-end', 83 | 'grid-row-start', 84 | 'grid-template-columns', 85 | 'grid-template-rows', 86 | 87 | // Hyphens. 88 | 'hyphens', 89 | 'word-break', 90 | 91 | // Masks. 92 | 'mask', 93 | 'mask-border', 94 | 'mask-border-outset', 95 | 'mask-border-repeat', 96 | 'mask-border-slice', 97 | 'mask-border-source', 98 | 'mask-border-width', 99 | 'mask-clip', 100 | 'mask-composite', 101 | 'mask-image', 102 | 'mask-origin', 103 | 'mask-position', 104 | 'mask-repeat', 105 | 'mask-size', 106 | 107 | // Multicolumn. 108 | 'break-after', 109 | 'break-before', 110 | 'break-inside', 111 | 'column-count', 112 | 'column-fill', 113 | 'column-gap', 114 | 'column-rule', 115 | 'column-rule-color', 116 | 'column-rule-style', 117 | 'column-rule-width', 118 | 'column-span', 119 | 'column-width', 120 | 'columns', 121 | 122 | // Object fit. 123 | 'object-fit', 124 | 'object-position', 125 | 126 | // Regions. 127 | 'flow-from', 128 | 'flow-into', 129 | 'region-fragment', 130 | 131 | // Scroll snap points. 132 | 'scroll-snap-coordinate', 133 | 'scroll-snap-destination', 134 | 'scroll-snap-points-x', 135 | 'scroll-snap-points-y', 136 | 'scroll-snap-type', 137 | 138 | // Shapes. 139 | 'shape-image-threshold', 140 | 'shape-margin', 141 | 'shape-outside', 142 | 143 | // Tab size. 144 | 'tab-size', 145 | 146 | // Text align last. 147 | 'text-align-last', 148 | 149 | // Text decoration. 150 | 'text-decoration-color', 151 | 'text-decoration-line', 152 | 'text-decoration-skip', 153 | 'text-decoration-style', 154 | 155 | // Text emphasis. 156 | 'text-emphasis', 157 | 'text-emphasis-color', 158 | 'text-emphasis-position', 159 | 'text-emphasis-style', 160 | 161 | // Text size adjust. 162 | 'text-size-adjust', 163 | 164 | // Text spacing. 165 | 'text-spacing', 166 | 167 | // Transform. 168 | 'transform', 169 | 'transform-origin', 170 | 171 | // Transform 3D. 172 | 'backface-visibility', 173 | 'perspective', 174 | 'perspective-origin', 175 | 'transform-style', 176 | 177 | // Transition. 178 | 'transition', 179 | 'transition-delay', 180 | 'transition-duration', 181 | 'transition-property', 182 | 'transition-timing-function', 183 | 184 | // Unicode bidi. 185 | 'unicode-bidi', 186 | 187 | // User select. 188 | 'user-select', 189 | 190 | // Writing mode. 191 | 'writing-mode', 192 | 193 | ); 194 | 195 | /// Values that should be vendorized. 196 | /// Data via caniuse.com, github.com/postcss/autoprefixer, and developer.mozilla.org 197 | /// @var {list} 198 | $vendor-values: ( 199 | 200 | // Cross fade. 201 | 'cross-fade', 202 | 203 | // Element function. 204 | 'element', 205 | 206 | // Filter function. 207 | 'filter', 208 | 209 | // Flexbox. 210 | 'flex', 211 | 'inline-flex', 212 | 213 | // Grab cursors. 214 | 'grab', 215 | 'grabbing', 216 | 217 | // Gradients. 218 | 'linear-gradient', 219 | 'repeating-linear-gradient', 220 | 'radial-gradient', 221 | 'repeating-radial-gradient', 222 | 223 | // Grid layout. 224 | 'grid', 225 | 'inline-grid', 226 | 227 | // Image set. 228 | 'image-set', 229 | 230 | // Intrinsic width. 231 | 'max-content', 232 | 'min-content', 233 | 'fit-content', 234 | 'fill', 235 | 'fill-available', 236 | 'stretch', 237 | 238 | // Sticky position. 239 | 'sticky', 240 | 241 | // Transform. 242 | 'transform', 243 | 244 | // Zoom cursors. 245 | 'zoom-in', 246 | 'zoom-out', 247 | 248 | ); 249 | 250 | // Functions. 251 | 252 | /// Removes a specific item from a list. 253 | /// @author Hugo Giraudel 254 | /// @param {list} $list List. 255 | /// @param {integer} $index Index. 256 | /// @return {list} Updated list. 257 | @function remove-nth($list, $index) { 258 | 259 | $result: null; 260 | 261 | @if type-of($index) != number { 262 | @warn "$index: #{quote($index)} is not a number for `remove-nth`."; 263 | } 264 | @else if $index == 0 { 265 | @warn "List index 0 must be a non-zero integer for `remove-nth`."; 266 | } 267 | @else if abs($index) > length($list) { 268 | @warn "List index is #{$index} but list is only #{length($list)} item long for `remove-nth`."; 269 | } 270 | @else { 271 | 272 | $result: (); 273 | $index: if($index < 0, length($list) + $index + 1, $index); 274 | 275 | @for $i from 1 through length($list) { 276 | 277 | @if $i != $index { 278 | $result: append($result, nth($list, $i)); 279 | } 280 | 281 | } 282 | 283 | } 284 | 285 | @return $result; 286 | 287 | } 288 | 289 | /// Replaces a substring within another string. 290 | /// @author Hugo Giraudel 291 | /// @param {string} $string String. 292 | /// @param {string} $search Substring. 293 | /// @param {string} $replace Replacement. 294 | /// @return {string} Updated string. 295 | @function str-replace($string, $search, $replace: '') { 296 | 297 | $index: str-index($string, $search); 298 | 299 | @if $index { 300 | @return str-slice($string, 1, $index - 1) + $replace + str-replace(str-slice($string, $index + str-length($search)), $search, $replace); 301 | } 302 | 303 | @return $string; 304 | 305 | } 306 | 307 | /// Replaces a substring within each string in a list. 308 | /// @param {list} $strings List of strings. 309 | /// @param {string} $search Substring. 310 | /// @param {string} $replace Replacement. 311 | /// @return {list} Updated list of strings. 312 | @function str-replace-all($strings, $search, $replace: '') { 313 | 314 | @each $string in $strings { 315 | $strings: set-nth($strings, index($strings, $string), str-replace($string, $search, $replace)); 316 | } 317 | 318 | @return $strings; 319 | 320 | } 321 | 322 | // Mixins. 323 | 324 | /// Wraps @content in vendorized keyframe blocks. 325 | /// @param {string} $name Name. 326 | @mixin keyframes($name) { 327 | 328 | @-moz-keyframes #{$name} { @content; } 329 | @-webkit-keyframes #{$name} { @content; } 330 | @-ms-keyframes #{$name} { @content; } 331 | @keyframes #{$name} { @content; } 332 | 333 | } 334 | 335 | /// Vendorizes a declaration's property and/or value(s). 336 | /// @param {string} $property Property. 337 | /// @param {mixed} $value String/list of value(s). 338 | @mixin vendor($property, $value) { 339 | 340 | // Determine if property should expand. 341 | $expandProperty: index($vendor-properties, $property); 342 | 343 | // Determine if value should expand (and if so, add '-prefix-' placeholder). 344 | $expandValue: false; 345 | 346 | @each $x in $value { 347 | @each $y in $vendor-values { 348 | @if $y == str-slice($x, 1, str-length($y)) { 349 | 350 | $value: set-nth($value, index($value, $x), '-prefix-' + $x); 351 | $expandValue: true; 352 | 353 | } 354 | } 355 | } 356 | 357 | // Expand property? 358 | @if $expandProperty { 359 | @each $vendor in $vendor-prefixes { 360 | #{$vendor}#{$property}: #{str-replace-all($value, '-prefix-', $vendor)}; 361 | } 362 | } 363 | 364 | // Expand just the value? 365 | @elseif $expandValue { 366 | @each $vendor in $vendor-prefixes { 367 | #{$property}: #{str-replace-all($value, '-prefix-', $vendor)}; 368 | } 369 | } 370 | 371 | // Neither? Treat them as a normal declaration. 372 | @else { 373 | #{$property}: #{$value}; 374 | } 375 | 376 | } -------------------------------------------------------------------------------- /assets/js/main.js: -------------------------------------------------------------------------------- 1 | /* 2 | Dimension by HTML5 UP 3 | html5up.net | @ajlkn 4 | Free for personal and commercial use under the CCA 3.0 license (html5up.net/license) 5 | */ 6 | 7 | (function($) { 8 | 9 | var $window = $(window), 10 | $body = $('body'), 11 | $wrapper = $('#wrapper'), 12 | $header = $('#header'), 13 | $footer = $('#footer'), 14 | $main = $('#main'), 15 | $main_articles = $main.children('article'); 16 | 17 | // Breakpoints. 18 | breakpoints({ 19 | xlarge: [ '1281px', '1680px' ], 20 | large: [ '981px', '1280px' ], 21 | medium: [ '737px', '980px' ], 22 | small: [ '481px', '736px' ], 23 | xsmall: [ '361px', '480px' ], 24 | xxsmall: [ null, '360px' ] 25 | }); 26 | 27 | // Play initial animations on page load. 28 | $window.on('load', function() { 29 | window.setTimeout(function() { 30 | $body.removeClass('is-preload'); 31 | }, 100); 32 | }); 33 | 34 | // Fix: Flexbox min-height bug on IE. 35 | if (browser.name == 'ie') { 36 | 37 | var flexboxFixTimeoutId; 38 | 39 | $window.on('resize.flexbox-fix', function() { 40 | 41 | clearTimeout(flexboxFixTimeoutId); 42 | 43 | flexboxFixTimeoutId = setTimeout(function() { 44 | 45 | if ($wrapper.prop('scrollHeight') > $window.height()) 46 | $wrapper.css('height', 'auto'); 47 | else 48 | $wrapper.css('height', '100vh'); 49 | 50 | }, 250); 51 | 52 | }).triggerHandler('resize.flexbox-fix'); 53 | 54 | } 55 | 56 | // Nav. 57 | var $nav = $header.children('nav'), 58 | $nav_li = $nav.find('li'); 59 | 60 | // Add "middle" alignment classes if we're dealing with an even number of items. 61 | if ($nav_li.length % 2 == 0) { 62 | 63 | $nav.addClass('use-middle'); 64 | $nav_li.eq( ($nav_li.length / 2) ).addClass('is-middle'); 65 | 66 | } 67 | 68 | // Main. 69 | var delay = 325, 70 | locked = false; 71 | 72 | // Methods. 73 | $main._show = function(id, initial) { 74 | 75 | var $article = $main_articles.filter('#' + id); 76 | 77 | // No such article? Bail. 78 | if ($article.length == 0) 79 | return; 80 | 81 | // Handle lock. 82 | 83 | // Already locked? Speed through "show" steps w/o delays. 84 | if (locked || (typeof initial != 'undefined' && initial === true)) { 85 | 86 | // Mark as switching. 87 | $body.addClass('is-switching'); 88 | 89 | // Mark as visible. 90 | $body.addClass('is-article-visible'); 91 | 92 | // Deactivate all articles (just in case one's already active). 93 | $main_articles.removeClass('active'); 94 | 95 | // Hide header, footer. 96 | $header.hide(); 97 | $footer.hide(); 98 | 99 | // Show main, article. 100 | $main.show(); 101 | $article.show(); 102 | 103 | // Activate article. 104 | $article.addClass('active'); 105 | 106 | // Unlock. 107 | locked = false; 108 | 109 | // Unmark as switching. 110 | setTimeout(function() { 111 | $body.removeClass('is-switching'); 112 | }, (initial ? 1000 : 0)); 113 | 114 | return; 115 | 116 | } 117 | 118 | // Lock. 119 | locked = true; 120 | 121 | // Article already visible? Just swap articles. 122 | if ($body.hasClass('is-article-visible')) { 123 | 124 | // Deactivate current article. 125 | var $currentArticle = $main_articles.filter('.active'); 126 | 127 | $currentArticle.removeClass('active'); 128 | 129 | // Show article. 130 | setTimeout(function() { 131 | 132 | // Hide current article. 133 | $currentArticle.hide(); 134 | 135 | // Show article. 136 | $article.show(); 137 | 138 | // Activate article. 139 | setTimeout(function() { 140 | 141 | $article.addClass('active'); 142 | 143 | // Window stuff. 144 | $window 145 | .scrollTop(0) 146 | .triggerHandler('resize.flexbox-fix'); 147 | 148 | // Unlock. 149 | setTimeout(function() { 150 | locked = false; 151 | }, delay); 152 | 153 | }, 25); 154 | 155 | }, delay); 156 | 157 | } 158 | 159 | // Otherwise, handle as normal. 160 | else { 161 | 162 | // Mark as visible. 163 | $body 164 | .addClass('is-article-visible'); 165 | 166 | // Show article. 167 | setTimeout(function() { 168 | 169 | // Hide header, footer. 170 | $header.hide(); 171 | $footer.hide(); 172 | 173 | // Show main, article. 174 | $main.show(); 175 | $article.show(); 176 | 177 | // Activate article. 178 | setTimeout(function() { 179 | 180 | $article.addClass('active'); 181 | 182 | // Window stuff. 183 | $window 184 | .scrollTop(0) 185 | .triggerHandler('resize.flexbox-fix'); 186 | 187 | // Unlock. 188 | setTimeout(function() { 189 | locked = false; 190 | }, delay); 191 | 192 | }, 25); 193 | 194 | }, delay); 195 | 196 | } 197 | 198 | }; 199 | 200 | $main._hide = function(addState) { 201 | 202 | var $article = $main_articles.filter('.active'); 203 | 204 | // Article not visible? Bail. 205 | if (!$body.hasClass('is-article-visible')) 206 | return; 207 | 208 | // Add state? 209 | if (typeof addState != 'undefined' 210 | && addState === true) 211 | history.pushState(null, null, '#'); 212 | 213 | // Handle lock. 214 | 215 | // Already locked? Speed through "hide" steps w/o delays. 216 | if (locked) { 217 | 218 | // Mark as switching. 219 | $body.addClass('is-switching'); 220 | 221 | // Deactivate article. 222 | $article.removeClass('active'); 223 | 224 | // Hide article, main. 225 | $article.hide(); 226 | $main.hide(); 227 | 228 | // Show footer, header. 229 | $footer.show(); 230 | $header.show(); 231 | 232 | // Unmark as visible. 233 | $body.removeClass('is-article-visible'); 234 | 235 | // Unlock. 236 | locked = false; 237 | 238 | // Unmark as switching. 239 | $body.removeClass('is-switching'); 240 | 241 | // Window stuff. 242 | $window 243 | .scrollTop(0) 244 | .triggerHandler('resize.flexbox-fix'); 245 | 246 | return; 247 | 248 | } 249 | 250 | // Lock. 251 | locked = true; 252 | 253 | // Deactivate article. 254 | $article.removeClass('active'); 255 | 256 | // Hide article. 257 | setTimeout(function() { 258 | 259 | // Hide article, main. 260 | $article.hide(); 261 | $main.hide(); 262 | 263 | // Show footer, header. 264 | $footer.show(); 265 | $header.show(); 266 | 267 | // Unmark as visible. 268 | setTimeout(function() { 269 | 270 | $body.removeClass('is-article-visible'); 271 | 272 | // Window stuff. 273 | $window 274 | .scrollTop(0) 275 | .triggerHandler('resize.flexbox-fix'); 276 | 277 | // Unlock. 278 | setTimeout(function() { 279 | locked = false; 280 | }, delay); 281 | 282 | }, 25); 283 | 284 | }, delay); 285 | 286 | 287 | }; 288 | 289 | // Articles. 290 | $main_articles.each(function() { 291 | 292 | var $this = $(this); 293 | 294 | // Close. 295 | $('
Close
') 296 | .appendTo($this) 297 | .on('click', function() { 298 | location.hash = ''; 299 | }); 300 | 301 | // Prevent clicks from inside article from bubbling. 302 | $this.on('click', function(event) { 303 | event.stopPropagation(); 304 | }); 305 | 306 | }); 307 | 308 | // Events. 309 | $body.on('click', function(event) { 310 | 311 | // Article visible? Hide. 312 | if ($body.hasClass('is-article-visible')) 313 | $main._hide(true); 314 | 315 | }); 316 | 317 | $window.on('keyup', function(event) { 318 | 319 | switch (event.keyCode) { 320 | 321 | case 27: 322 | 323 | // Article visible? Hide. 324 | if ($body.hasClass('is-article-visible')) 325 | $main._hide(true); 326 | 327 | break; 328 | 329 | default: 330 | break; 331 | 332 | } 333 | 334 | }); 335 | 336 | $window.on('hashchange', function(event) { 337 | 338 | // Empty hash? 339 | if (location.hash == '' 340 | || location.hash == '#') { 341 | 342 | // Prevent default. 343 | event.preventDefault(); 344 | event.stopPropagation(); 345 | 346 | // Hide. 347 | $main._hide(); 348 | 349 | } 350 | 351 | // Otherwise, check for a matching article. 352 | else if ($main_articles.filter(location.hash).length > 0) { 353 | 354 | // Prevent default. 355 | event.preventDefault(); 356 | event.stopPropagation(); 357 | 358 | // Show article. 359 | $main._show(location.hash.substr(1)); 360 | 361 | } 362 | 363 | }); 364 | 365 | // Scroll restoration. 366 | // This prevents the page from scrolling back to the top on a hashchange. 367 | if ('scrollRestoration' in history) 368 | history.scrollRestoration = 'manual'; 369 | else { 370 | 371 | var oldScrollPos = 0, 372 | scrollPos = 0, 373 | $htmlbody = $('html,body'); 374 | 375 | $window 376 | .on('scroll', function() { 377 | 378 | oldScrollPos = scrollPos; 379 | scrollPos = $htmlbody.scrollTop(); 380 | 381 | }) 382 | .on('hashchange', function() { 383 | $window.scrollTop(oldScrollPos); 384 | }); 385 | 386 | } 387 | 388 | // Initialize. 389 | 390 | // Hide main, articles. 391 | $main.hide(); 392 | $main_articles.hide(); 393 | 394 | // Initial article. 395 | if (location.hash != '' 396 | && location.hash != '#') 397 | $window.on('load', function() { 398 | $main._show(location.hash.substr(1), true); 399 | }); 400 | 401 | })(jQuery); -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 | NFT 4 |

5 | 6 |

Automated Hydroponics using Arduino Mega

7 | 8 |
9 | 10 | [![Status](https://img.shields.io/badge/status-active-success.svg)]() 11 | [![GitHub Issues](https://img.shields.io/github/issues/kylelobo/Hydroponics.svg)](https://github.com/kylelobo/Hydroponics/issues) 12 | [![GitHub Pull Requests](https://img.shields.io/github/issues-pr/kylelobo/Hydroponics.svg)](https://github.com/kylelobo/Hydroponics/pulls) 13 | [![License](https://img.shields.io/badge/license-MIT-blue.svg)](/LICENSE) 14 | 15 | [![Tweet](https://img.shields.io/twitter/url/https/shields.io.svg?style=social)](https://twitter.com/intent/tweet?text=Automated%20Hydroponics%20using%20Arduino%20Mega&url=https://github.com/kylelobo/Hydroponics) 16 | 17 |
18 | 19 | --- 20 | 21 |

🌱 Hydroponics is a subset of hydroculture, the method of growing plants without soil, using mineral nutrient solutions in a water solvent.

22 | 23 | 24 | ## 📝 Index 25 | - [Working](#working) 26 | - [Description](#description) 27 | - [Problem Definition](#problem_definition) 28 | - [Screenshots](#screenshots) 29 | - [Sensors Used](#hardware_used) 30 | - [Software Requirements](#software_requirements) 31 | - [Arduino Libraries Used](#arduino_libraries_used) 32 | - [Running the code](#running_the_code) 33 | - [Conclusion](#conclusion) 34 | - [References](#references) 35 | 36 | 37 | ## 🎈 Description 38 | - Hydroponics is a subset of hydroculture, the method of growing plants without soil, using mineral nutrient solutions in a water solvent. Terrestrial plants may be grown with only their roots exposed to the mineral solution, or the roots may be supported by an inert medium, such as perlite or gravel.The nutrients in hydroponics can come from an array of different sources; these can include but are not limited to byproduct from fish waste, duck manure, or commercial fertilisers. [[1]](#1) 39 | 40 | - Growing with hydroponics comes with many advantages, the biggest of which is a greatly increased rate of growth in your plants. With a proper setup, your plants will mature up to 25% faster and produce up to 30% more than the same plants grown in soil. [[2]](#2) 41 | 42 | - Plants in a hydroponic system grow more quickly because they have food and water available to them all the time. They produce bigger crops because they can devote their energy to producing their crop rather than producing large roots such as would be needed in soil to seek out water and nutrients. Hydroponically-grown plants have smaller root systems because the roots do not need to go out looking for nutrients and water. 43 | 44 | - All of this is possible through careful control of the nutrient solution and pH levels. A hydroponic system will also use 70-90% less water than soil based plants because the system is enclosed, which results in less evaporation. Hydroponics is better for the environment because it reduces waste and pollution from soil runoff. [[2]](#2) 45 | 46 | 47 | ## 📍 Problem Definition 48 | - Traditional agriculture isn’t possible in places with arid climates such as Arizona, Israel. 49 | 50 | - Similarly, hydroponics is useful in dense urban areas, where land is at a premium. In Tokyo, hydroponics is used in lieu of traditional soil-based plant growth. 51 | 52 | - Hydroponics is also useful in places which have land shortage problems, such as Singapore. With so little space available for planting, hydroponic systems take around 20 percent of the land usually required for crop growth. This allows the citizens to enjoy year-round local produce without the expense and delay of importation. 53 | 54 | - Finally, areas that don't receive consistent sunlight or warm weather can benefit from hydroponics. Places like Alaska and Russia, where growing seasons are shorter, can use hydroponic greenhouses, where light and temperature can be controlled to produce higher crop yields. [[3]](#3) 55 | 56 | - Hydroponics allows farmers to adapt to any situation, whether it’s Antarctica’s frozen tundra, Saudi Arabia’s windswept and barren deserts, southern Arizona’s Sonoran Desert, or even a space station. 57 | 58 | 59 | ## ⚙️ Working 60 | - The entire system mainly consists of a grow box, a reservoir and a water reservoir. 61 | 62 | - The DC water pumps are attached to the nutrient solution, reservoir, water reservoir and the pH up down solutions. The water level sensor, temperature sensor, EC sensor, pH sensor are installed in the reservoir. 63 | 64 | - When the EC sensor detects low-salt levels it indicates nutrient deficiencies. Therefore, in such situations, the DC water pump pumps the nutrient solution to the reservoir. The presence of high salt levels / low water levels indicates that fresh water needs to be pumped to the reservoir. 65 | 66 | - Overlooking pH control can be perilous for plants, particularly those that rely on water supplies with high alkalinity. The pH of the nutrient solution is a major factor in determining the uptake rate of many essential nutrient ions. Run pH too high and the dreaded nutrient lockout looms. The pH sensor detects the pH level of the water and prompts the pH up / pH down pump to balance out the pH levels in the reservoir. 67 | 68 | - The grow box has a drainage system which allows continous flow of nutrient solution runs over the plants roots. 69 | 70 | - This type of system works very well because the roots of a plant absorb more oxygen from the air than from the nutrient solution itself. Since only the tips of the roots come in contact with the nutrient solution, the plant is able to get more oxygen which fascilitates a faster rate of growth. 71 | 72 | - All this can be monitored on the website for this project. 73 | 74 | - The below video shows a brief working of this project: (💡 **PS -** Due to financial constraints, we have not used the EC sensor & pH up / down solutions) 75 | 76 |
77 | 78 | [![Video Demonstration](http://img.youtube.com/vi/mIO8MYL-RWc/0.jpg)](http://www.youtube.com/watch?v=mIO8MYL-RWc "Video Demonstration") 79 | 80 |
81 | 82 | 83 | ## 🎞️ Screenshots 84 | ![Home Page](https://imgur.com/UK5jDZZ.jpg) 85 | ![Intro 1](https://imgur.com/fPFmyoV.jpg) 86 | ![Intro 2](https://imgur.com/ZWgLvBh.jpg) 87 | ![Intro 3](https://imgur.com/11USWBp.jpg) 88 | ![Work 1](https://imgur.com/PHxcO7v.jpg) 89 | ![Work 2](https://imgur.com/PuKdpfC.jpg) 90 | ![About 1](https://imgur.com/l2F1xYg.jpg) 91 | ![About 2](https://imgur.com/pmIM7Nl.jpg) 92 | ![Log in](https://imgur.com/foOHpH1.jpg) 93 | ![Sign up](https://imgur.com/HEoo0pT.jpg) 94 | ![Sensor Data (Tabular)](https://i.imgur.com/Pe3MPlg.jpg) 95 | ![Sensor Data (Graphical)](https://i.imgur.com/Q6NAUEZ.jpg) 96 | 97 | 98 | ## 🔩 Hardware Used 99 | 1. **Arduino Mega 2560** - The hardware will most likely fit perfectly in the UNO, the problem will be the program size that may not fit in the UNOs 32kB. Plus, such a project might be increased and a mega board will allow that more easily. 100 | 101 | 2. **Water-Level Sensor** - A water-level sensor is a device used in the detection of the water level. 102 | 103 | 3. **pH Sensor** - Optimal pH levels are critical to healthy plants and high yields in both soil and hydroponics gardening. Maintaining those optimal levels, especially in soilless growing systems, calls for frequent, accurate pH testing. Ideal pH levels maximize a plant’s nutrient uptake. Those nutrients, in turn, increase a plant’s vigor and productivity. 104 | 105 | 4. **EC Sensor** - To maximize the benefits of growing hydroponically, it’s important to know how to fine-tune your nutrient regimen to ensure your plants are getting everything they need, in the right doses. To do that, you need to learn how to measure EC, or electrical conductivity, which tells you the amounts of fertilizer salts in your water, and use those readings to feed your plants the right mix of elements for optimal growth and yields. 106 | 107 | 5. **Water Temperature Sensor** - The pH value of the solution changes with the temperature i.e. an increase in any solutions’ temperature will cause a decrease in it’s viscosity and an increase in the mobility of its ions in solution. An increase in temperature may also lead to an increase in the number of ions in solution due to the dissociation of molecules. As pH is a measure of the hydrogen ion concentration, a change in the temperature of the solution will be reflected by a subsequent 108 | change in pH. [[4]](#4) 109 | 110 | 6. **Soil Moisture Sensor** - This soil moisture sensor can be used to detect the moisture of soil or judge if there is water around the sensor, let's you know if the plants in the mesh pot require water or not. 111 | 112 | 7. **DHT22 Temperature/Humidity Sensor** - The DHT22 is a humidity and temperature sensor with a single wire digital interface. The sensor is calibrated so you can get right to measuring relative humidity and temperature. 113 | 114 | 8. **ESP8266** - ESP8266 is a WiFi module which helps us track all the sensor data on the website. 115 | 116 | 9. **DC Water Pump** - A DC Water Pump is used to pump water from the water reservoir to the substrate. 117 | 118 | 10. **5V Relay** - A relay is an electromagnetic switch operated by a relatively small electric current that can turn on or off a much larger electric current. It is going to be used to control the DC Water Pump 119 | 120 | 121 | ## 💻 Software Requirements 122 | - Arduino IDE 123 | - A Linux Environment 124 | - Git Version Control 125 | - Editor 126 | - ThingSpeak 127 | 128 | 129 | ## 🖥️ Arduino Libraries Used 130 | - DHT Sensor Library 131 | - ThingSpeak 132 | - WiFi101 133 | - Adafruit_IO_Arduino 134 | 135 | 136 | ## 🔧 Running the code 137 | 1. Install [Apache](https://www.digitalocean.com/community/tutorials/how-to-install-linux-apache-mysql-php-lamp-stack-on-ubuntu-16-04#step-1-install-apache-and-allow-in-firewall) 138 | 2. Install [MySQL](https://www.digitalocean.com/community/tutorials/how-to-install-linux-apache-mysql-php-lamp-stack-on-ubuntu-16-04#step-2-install-mysql) 139 | 3. Install [PHP](https://www.digitalocean.com/community/tutorials/how-to-install-linux-apache-mysql-php-lamp-stack-on-ubuntu-16-04#step-3-install-php) 140 | 4. Clone or Download the repository 141 | ``` 142 | $ git clone https://github.com/Hydroponics/Reddit-Bot.git 143 | ``` 144 | 5. Move the Hydroponics folder to ```/var/www/``` 145 | ``` 146 | $ sudo mv Hydroponics/ /var/www 147 | ``` 148 | 6. In your browser, open [localhost](http://localhost/) 149 | 150 | 151 | ## 🔍 Conclusion 152 | The aim of this project is to: 153 | - Reduction of water wastage caused by traditional agriculture systems 154 | - Providing a scaled down solution for urban gardening 155 | - Growing healthier plants at a faster rate due to a controlled growing environment 156 | - Simplifying the process of Hydroponics using IOT and Internet Programming 157 | 158 | 159 | ## 🗒️ References 160 | [1] [Hydroponics](https://en.wikipedia.org/wiki/Hydroponics) - _Wikipedia_
161 | [2] [Hydroponic Systems 101](http://www.fullbloomhydroponics.net/hydroponic-systems-101/) - _Fullbloom Hydroponics_
162 | [3] [How Hydroponics Works](https://home.howstuffworks.com/lawn-garden/professional-landscaping/hydroponics2.htm) - _Bambi Turner_
163 | [4] [pH Meters in Hydroponics](https://manicbotanix.com/ph-meters/) - _Med-Tek_
164 | [5] [Urban Hydroponic Oasis](https://devpost.com/software/urban-hydroponic-oasis) - _Paul Langdon_ 165 | 166 | 167 | ## ✍️ Authors 168 | - [@kylelobo](https://github.com/kylelobo) 169 | - [@sephiroth7712](https://github.com/sephiroth7712) 170 | - [@rudij7](https://github.com/rudij7) 171 | - [@chaitanyadukkipaty](https://github.com/chaitanyadukkipaty) 172 | -------------------------------------------------------------------------------- /assets/js/util.js: -------------------------------------------------------------------------------- 1 | (function($) { 2 | 3 | /** 4 | * Generate an indented list of links from a nav. Meant for use with panel(). 5 | * @return {jQuery} jQuery object. 6 | */ 7 | $.fn.navList = function() { 8 | 9 | var $this = $(this); 10 | $a = $this.find('a'), 11 | b = []; 12 | 13 | $a.each(function() { 14 | 15 | var $this = $(this), 16 | indent = Math.max(0, $this.parents('li').length - 1), 17 | href = $this.attr('href'), 18 | target = $this.attr('target'); 19 | 20 | b.push( 21 | '' + 26 | '' + 27 | $this.text() + 28 | '' 29 | ); 30 | 31 | }); 32 | 33 | return b.join(''); 34 | 35 | }; 36 | 37 | /** 38 | * Panel-ify an element. 39 | * @param {object} userConfig User config. 40 | * @return {jQuery} jQuery object. 41 | */ 42 | $.fn.panel = function(userConfig) { 43 | 44 | // No elements? 45 | if (this.length == 0) 46 | return $this; 47 | 48 | // Multiple elements? 49 | if (this.length > 1) { 50 | 51 | for (var i=0; i < this.length; i++) 52 | $(this[i]).panel(userConfig); 53 | 54 | return $this; 55 | 56 | } 57 | 58 | // Vars. 59 | var $this = $(this), 60 | $body = $('body'), 61 | $window = $(window), 62 | id = $this.attr('id'), 63 | config; 64 | 65 | // Config. 66 | config = $.extend({ 67 | 68 | // Delay. 69 | delay: 0, 70 | 71 | // Hide panel on link click. 72 | hideOnClick: false, 73 | 74 | // Hide panel on escape keypress. 75 | hideOnEscape: false, 76 | 77 | // Hide panel on swipe. 78 | hideOnSwipe: false, 79 | 80 | // Reset scroll position on hide. 81 | resetScroll: false, 82 | 83 | // Reset forms on hide. 84 | resetForms: false, 85 | 86 | // Side of viewport the panel will appear. 87 | side: null, 88 | 89 | // Target element for "class". 90 | target: $this, 91 | 92 | // Class to toggle. 93 | visibleClass: 'visible' 94 | 95 | }, userConfig); 96 | 97 | // Expand "target" if it's not a jQuery object already. 98 | if (typeof config.target != 'jQuery') 99 | config.target = $(config.target); 100 | 101 | // Panel. 102 | 103 | // Methods. 104 | $this._hide = function(event) { 105 | 106 | // Already hidden? Bail. 107 | if (!config.target.hasClass(config.visibleClass)) 108 | return; 109 | 110 | // If an event was provided, cancel it. 111 | if (event) { 112 | 113 | event.preventDefault(); 114 | event.stopPropagation(); 115 | 116 | } 117 | 118 | // Hide. 119 | config.target.removeClass(config.visibleClass); 120 | 121 | // Post-hide stuff. 122 | window.setTimeout(function() { 123 | 124 | // Reset scroll position. 125 | if (config.resetScroll) 126 | $this.scrollTop(0); 127 | 128 | // Reset forms. 129 | if (config.resetForms) 130 | $this.find('form').each(function() { 131 | this.reset(); 132 | }); 133 | 134 | }, config.delay); 135 | 136 | }; 137 | 138 | // Vendor fixes. 139 | $this 140 | .css('-ms-overflow-style', '-ms-autohiding-scrollbar') 141 | .css('-webkit-overflow-scrolling', 'touch'); 142 | 143 | // Hide on click. 144 | if (config.hideOnClick) { 145 | 146 | $this.find('a') 147 | .css('-webkit-tap-highlight-color', 'rgba(0,0,0,0)'); 148 | 149 | $this 150 | .on('click', 'a', function(event) { 151 | 152 | var $a = $(this), 153 | href = $a.attr('href'), 154 | target = $a.attr('target'); 155 | 156 | if (!href || href == '#' || href == '' || href == '#' + id) 157 | return; 158 | 159 | // Cancel original event. 160 | event.preventDefault(); 161 | event.stopPropagation(); 162 | 163 | // Hide panel. 164 | $this._hide(); 165 | 166 | // Redirect to href. 167 | window.setTimeout(function() { 168 | 169 | if (target == '_blank') 170 | window.open(href); 171 | else 172 | window.location.href = href; 173 | 174 | }, config.delay + 10); 175 | 176 | }); 177 | 178 | } 179 | 180 | // Event: Touch stuff. 181 | $this.on('touchstart', function(event) { 182 | 183 | $this.touchPosX = event.originalEvent.touches[0].pageX; 184 | $this.touchPosY = event.originalEvent.touches[0].pageY; 185 | 186 | }) 187 | 188 | $this.on('touchmove', function(event) { 189 | 190 | if ($this.touchPosX === null 191 | || $this.touchPosY === null) 192 | return; 193 | 194 | var diffX = $this.touchPosX - event.originalEvent.touches[0].pageX, 195 | diffY = $this.touchPosY - event.originalEvent.touches[0].pageY, 196 | th = $this.outerHeight(), 197 | ts = ($this.get(0).scrollHeight - $this.scrollTop()); 198 | 199 | // Hide on swipe? 200 | if (config.hideOnSwipe) { 201 | 202 | var result = false, 203 | boundary = 20, 204 | delta = 50; 205 | 206 | switch (config.side) { 207 | 208 | case 'left': 209 | result = (diffY < boundary && diffY > (-1 * boundary)) && (diffX > delta); 210 | break; 211 | 212 | case 'right': 213 | result = (diffY < boundary && diffY > (-1 * boundary)) && (diffX < (-1 * delta)); 214 | break; 215 | 216 | case 'top': 217 | result = (diffX < boundary && diffX > (-1 * boundary)) && (diffY > delta); 218 | break; 219 | 220 | case 'bottom': 221 | result = (diffX < boundary && diffX > (-1 * boundary)) && (diffY < (-1 * delta)); 222 | break; 223 | 224 | default: 225 | break; 226 | 227 | } 228 | 229 | if (result) { 230 | 231 | $this.touchPosX = null; 232 | $this.touchPosY = null; 233 | $this._hide(); 234 | 235 | return false; 236 | 237 | } 238 | 239 | } 240 | 241 | // Prevent vertical scrolling past the top or bottom. 242 | if (($this.scrollTop() < 0 && diffY < 0) 243 | || (ts > (th - 2) && ts < (th + 2) && diffY > 0)) { 244 | 245 | event.preventDefault(); 246 | event.stopPropagation(); 247 | 248 | } 249 | 250 | }); 251 | 252 | // Event: Prevent certain events inside the panel from bubbling. 253 | $this.on('click touchend touchstart touchmove', function(event) { 254 | event.stopPropagation(); 255 | }); 256 | 257 | // Event: Hide panel if a child anchor tag pointing to its ID is clicked. 258 | $this.on('click', 'a[href="#' + id + '"]', function(event) { 259 | 260 | event.preventDefault(); 261 | event.stopPropagation(); 262 | 263 | config.target.removeClass(config.visibleClass); 264 | 265 | }); 266 | 267 | // Body. 268 | 269 | // Event: Hide panel on body click/tap. 270 | $body.on('click touchend', function(event) { 271 | $this._hide(event); 272 | }); 273 | 274 | // Event: Toggle. 275 | $body.on('click', 'a[href="#' + id + '"]', function(event) { 276 | 277 | event.preventDefault(); 278 | event.stopPropagation(); 279 | 280 | config.target.toggleClass(config.visibleClass); 281 | 282 | }); 283 | 284 | // Window. 285 | 286 | // Event: Hide on ESC. 287 | if (config.hideOnEscape) 288 | $window.on('keydown', function(event) { 289 | 290 | if (event.keyCode == 27) 291 | $this._hide(event); 292 | 293 | }); 294 | 295 | return $this; 296 | 297 | }; 298 | 299 | /** 300 | * Apply "placeholder" attribute polyfill to one or more forms. 301 | * @return {jQuery} jQuery object. 302 | */ 303 | $.fn.placeholder = function() { 304 | 305 | // Browser natively supports placeholders? Bail. 306 | if (typeof (document.createElement('input')).placeholder != 'undefined') 307 | return $(this); 308 | 309 | // No elements? 310 | if (this.length == 0) 311 | return $this; 312 | 313 | // Multiple elements? 314 | if (this.length > 1) { 315 | 316 | for (var i=0; i < this.length; i++) 317 | $(this[i]).placeholder(); 318 | 319 | return $this; 320 | 321 | } 322 | 323 | // Vars. 324 | var $this = $(this); 325 | 326 | // Text, TextArea. 327 | $this.find('input[type=text],textarea') 328 | .each(function() { 329 | 330 | var i = $(this); 331 | 332 | if (i.val() == '' 333 | || i.val() == i.attr('placeholder')) 334 | i 335 | .addClass('polyfill-placeholder') 336 | .val(i.attr('placeholder')); 337 | 338 | }) 339 | .on('blur', function() { 340 | 341 | var i = $(this); 342 | 343 | if (i.attr('name').match(/-polyfill-field$/)) 344 | return; 345 | 346 | if (i.val() == '') 347 | i 348 | .addClass('polyfill-placeholder') 349 | .val(i.attr('placeholder')); 350 | 351 | }) 352 | .on('focus', function() { 353 | 354 | var i = $(this); 355 | 356 | if (i.attr('name').match(/-polyfill-field$/)) 357 | return; 358 | 359 | if (i.val() == i.attr('placeholder')) 360 | i 361 | .removeClass('polyfill-placeholder') 362 | .val(''); 363 | 364 | }); 365 | 366 | // Password. 367 | $this.find('input[type=password]') 368 | .each(function() { 369 | 370 | var i = $(this); 371 | var x = $( 372 | $('
') 373 | .append(i.clone()) 374 | .remove() 375 | .html() 376 | .replace(/type="password"/i, 'type="text"') 377 | .replace(/type=password/i, 'type=text') 378 | ); 379 | 380 | if (i.attr('id') != '') 381 | x.attr('id', i.attr('id') + '-polyfill-field'); 382 | 383 | if (i.attr('name') != '') 384 | x.attr('name', i.attr('name') + '-polyfill-field'); 385 | 386 | x.addClass('polyfill-placeholder') 387 | .val(x.attr('placeholder')).insertAfter(i); 388 | 389 | if (i.val() == '') 390 | i.hide(); 391 | else 392 | x.hide(); 393 | 394 | i 395 | .on('blur', function(event) { 396 | 397 | event.preventDefault(); 398 | 399 | var x = i.parent().find('input[name=' + i.attr('name') + '-polyfill-field]'); 400 | 401 | if (i.val() == '') { 402 | 403 | i.hide(); 404 | x.show(); 405 | 406 | } 407 | 408 | }); 409 | 410 | x 411 | .on('focus', function(event) { 412 | 413 | event.preventDefault(); 414 | 415 | var i = x.parent().find('input[name=' + x.attr('name').replace('-polyfill-field', '') + ']'); 416 | 417 | x.hide(); 418 | 419 | i 420 | .show() 421 | .focus(); 422 | 423 | }) 424 | .on('keypress', function(event) { 425 | 426 | event.preventDefault(); 427 | x.val(''); 428 | 429 | }); 430 | 431 | }); 432 | 433 | // Events. 434 | $this 435 | .on('submit', function() { 436 | 437 | $this.find('input[type=text],input[type=password],textarea') 438 | .each(function(event) { 439 | 440 | var i = $(this); 441 | 442 | if (i.attr('name').match(/-polyfill-field$/)) 443 | i.attr('name', ''); 444 | 445 | if (i.val() == i.attr('placeholder')) { 446 | 447 | i.removeClass('polyfill-placeholder'); 448 | i.val(''); 449 | 450 | } 451 | 452 | }); 453 | 454 | }) 455 | .on('reset', function(event) { 456 | 457 | event.preventDefault(); 458 | 459 | $this.find('select') 460 | .val($('option:first').val()); 461 | 462 | $this.find('input,textarea') 463 | .each(function() { 464 | 465 | var i = $(this), 466 | x; 467 | 468 | i.removeClass('polyfill-placeholder'); 469 | 470 | switch (this.type) { 471 | 472 | case 'submit': 473 | case 'reset': 474 | break; 475 | 476 | case 'password': 477 | i.val(i.attr('defaultValue')); 478 | 479 | x = i.parent().find('input[name=' + i.attr('name') + '-polyfill-field]'); 480 | 481 | if (i.val() == '') { 482 | i.hide(); 483 | x.show(); 484 | } 485 | else { 486 | i.show(); 487 | x.hide(); 488 | } 489 | 490 | break; 491 | 492 | case 'checkbox': 493 | case 'radio': 494 | i.attr('checked', i.attr('defaultValue')); 495 | break; 496 | 497 | case 'text': 498 | case 'textarea': 499 | i.val(i.attr('defaultValue')); 500 | 501 | if (i.val() == '') { 502 | i.addClass('polyfill-placeholder'); 503 | i.val(i.attr('placeholder')); 504 | } 505 | 506 | break; 507 | 508 | default: 509 | i.val(i.attr('defaultValue')); 510 | break; 511 | 512 | } 513 | }); 514 | 515 | }); 516 | 517 | return $this; 518 | 519 | }; 520 | 521 | /** 522 | * Moves elements to/from the first positions of their respective parents. 523 | * @param {jQuery} $elements Elements (or selector) to move. 524 | * @param {bool} condition If true, moves elements to the top. Otherwise, moves elements back to their original locations. 525 | */ 526 | $.prioritize = function($elements, condition) { 527 | 528 | var key = '__prioritize'; 529 | 530 | // Expand $elements if it's not already a jQuery object. 531 | if (typeof $elements != 'jQuery') 532 | $elements = $($elements); 533 | 534 | // Step through elements. 535 | $elements.each(function() { 536 | 537 | var $e = $(this), $p, 538 | $parent = $e.parent(); 539 | 540 | // No parent? Bail. 541 | if ($parent.length == 0) 542 | return; 543 | 544 | // Not moved? Move it. 545 | if (!$e.data(key)) { 546 | 547 | // Condition is false? Bail. 548 | if (!condition) 549 | return; 550 | 551 | // Get placeholder (which will serve as our point of reference for when this element needs to move back). 552 | $p = $e.prev(); 553 | 554 | // Couldn't find anything? Means this element's already at the top, so bail. 555 | if ($p.length == 0) 556 | return; 557 | 558 | // Move element to top of parent. 559 | $e.prependTo($parent); 560 | 561 | // Mark element as moved. 562 | $e.data(key, $p); 563 | 564 | } 565 | 566 | // Moved already? 567 | else { 568 | 569 | // Condition is true? Bail. 570 | if (condition) 571 | return; 572 | 573 | $p = $e.data(key); 574 | 575 | // Move element back to its original location (using our placeholder). 576 | $e.insertAfter($p); 577 | 578 | // Unmark element as moved. 579 | $e.removeData(key); 580 | 581 | } 582 | 583 | }); 584 | 585 | }; 586 | 587 | })(jQuery); -------------------------------------------------------------------------------- /assets/css/font-awesome.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome 3 | * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) 4 | */@font-face{font-family:'FontAwesome';src:url('../fonts/fontawesome-webfont.eot?v=4.7.0');src:url('../fonts/fontawesome-webfont.eot?#iefix&v=4.7.0') format('embedded-opentype'),url('../fonts/fontawesome-webfont.woff2?v=4.7.0') format('woff2'),url('../fonts/fontawesome-webfont.woff?v=4.7.0') format('woff'),url('../fonts/fontawesome-webfont.ttf?v=4.7.0') format('truetype'),url('../fonts/fontawesome-webfont.svg?v=4.7.0#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-remove:before,.fa-close:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook-f:before,.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-feed:before,.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before,.fa-gratipay:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}.fa-mortar-board:before,.fa-graduation-cap:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper-pp:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-resistance:before,.fa-rebel:before{content:"\f1d0"}.fa-ge:before,.fa-empire:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-y-combinator-square:before,.fa-yc-square:before,.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"}.fa-buysellads:before{content:"\f20d"}.fa-connectdevelop:before{content:"\f20e"}.fa-dashcube:before{content:"\f210"}.fa-forumbee:before{content:"\f211"}.fa-leanpub:before{content:"\f212"}.fa-sellsy:before{content:"\f213"}.fa-shirtsinbulk:before{content:"\f214"}.fa-simplybuilt:before{content:"\f215"}.fa-skyatlas:before{content:"\f216"}.fa-cart-plus:before{content:"\f217"}.fa-cart-arrow-down:before{content:"\f218"}.fa-diamond:before{content:"\f219"}.fa-ship:before{content:"\f21a"}.fa-user-secret:before{content:"\f21b"}.fa-motorcycle:before{content:"\f21c"}.fa-street-view:before{content:"\f21d"}.fa-heartbeat:before{content:"\f21e"}.fa-venus:before{content:"\f221"}.fa-mars:before{content:"\f222"}.fa-mercury:before{content:"\f223"}.fa-intersex:before,.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-venus-double:before{content:"\f226"}.fa-mars-double:before{content:"\f227"}.fa-venus-mars:before{content:"\f228"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-neuter:before{content:"\f22c"}.fa-genderless:before{content:"\f22d"}.fa-facebook-official:before{content:"\f230"}.fa-pinterest-p:before{content:"\f231"}.fa-whatsapp:before{content:"\f232"}.fa-server:before{content:"\f233"}.fa-user-plus:before{content:"\f234"}.fa-user-times:before{content:"\f235"}.fa-hotel:before,.fa-bed:before{content:"\f236"}.fa-viacoin:before{content:"\f237"}.fa-train:before{content:"\f238"}.fa-subway:before{content:"\f239"}.fa-medium:before{content:"\f23a"}.fa-yc:before,.fa-y-combinator:before{content:"\f23b"}.fa-optin-monster:before{content:"\f23c"}.fa-opencart:before{content:"\f23d"}.fa-expeditedssl:before{content:"\f23e"}.fa-battery-4:before,.fa-battery:before,.fa-battery-full:before{content:"\f240"}.fa-battery-3:before,.fa-battery-three-quarters:before{content:"\f241"}.fa-battery-2:before,.fa-battery-half:before{content:"\f242"}.fa-battery-1:before,.fa-battery-quarter:before{content:"\f243"}.fa-battery-0:before,.fa-battery-empty:before{content:"\f244"}.fa-mouse-pointer:before{content:"\f245"}.fa-i-cursor:before{content:"\f246"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-sticky-note:before{content:"\f249"}.fa-sticky-note-o:before{content:"\f24a"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-diners-club:before{content:"\f24c"}.fa-clone:before{content:"\f24d"}.fa-balance-scale:before{content:"\f24e"}.fa-hourglass-o:before{content:"\f250"}.fa-hourglass-1:before,.fa-hourglass-start:before{content:"\f251"}.fa-hourglass-2:before,.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-3:before,.fa-hourglass-end:before{content:"\f253"}.fa-hourglass:before{content:"\f254"}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:"\f255"}.fa-hand-stop-o:before,.fa-hand-paper-o:before{content:"\f256"}.fa-hand-scissors-o:before{content:"\f257"}.fa-hand-lizard-o:before{content:"\f258"}.fa-hand-spock-o:before{content:"\f259"}.fa-hand-pointer-o:before{content:"\f25a"}.fa-hand-peace-o:before{content:"\f25b"}.fa-trademark:before{content:"\f25c"}.fa-registered:before{content:"\f25d"}.fa-creative-commons:before{content:"\f25e"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-tripadvisor:before{content:"\f262"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-get-pocket:before{content:"\f265"}.fa-wikipedia-w:before{content:"\f266"}.fa-safari:before{content:"\f267"}.fa-chrome:before{content:"\f268"}.fa-firefox:before{content:"\f269"}.fa-opera:before{content:"\f26a"}.fa-internet-explorer:before{content:"\f26b"}.fa-tv:before,.fa-television:before{content:"\f26c"}.fa-contao:before{content:"\f26d"}.fa-500px:before{content:"\f26e"}.fa-amazon:before{content:"\f270"}.fa-calendar-plus-o:before{content:"\f271"}.fa-calendar-minus-o:before{content:"\f272"}.fa-calendar-times-o:before{content:"\f273"}.fa-calendar-check-o:before{content:"\f274"}.fa-industry:before{content:"\f275"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-map-o:before{content:"\f278"}.fa-map:before{content:"\f279"}.fa-commenting:before{content:"\f27a"}.fa-commenting-o:before{content:"\f27b"}.fa-houzz:before{content:"\f27c"}.fa-vimeo:before{content:"\f27d"}.fa-black-tie:before{content:"\f27e"}.fa-fonticons:before{content:"\f280"}.fa-reddit-alien:before{content:"\f281"}.fa-edge:before{content:"\f282"}.fa-credit-card-alt:before{content:"\f283"}.fa-codiepie:before{content:"\f284"}.fa-modx:before{content:"\f285"}.fa-fort-awesome:before{content:"\f286"}.fa-usb:before{content:"\f287"}.fa-product-hunt:before{content:"\f288"}.fa-mixcloud:before{content:"\f289"}.fa-scribd:before{content:"\f28a"}.fa-pause-circle:before{content:"\f28b"}.fa-pause-circle-o:before{content:"\f28c"}.fa-stop-circle:before{content:"\f28d"}.fa-stop-circle-o:before{content:"\f28e"}.fa-shopping-bag:before{content:"\f290"}.fa-shopping-basket:before{content:"\f291"}.fa-hashtag:before{content:"\f292"}.fa-bluetooth:before{content:"\f293"}.fa-bluetooth-b:before{content:"\f294"}.fa-percent:before{content:"\f295"}.fa-gitlab:before{content:"\f296"}.fa-wpbeginner:before{content:"\f297"}.fa-wpforms:before{content:"\f298"}.fa-envira:before{content:"\f299"}.fa-universal-access:before{content:"\f29a"}.fa-wheelchair-alt:before{content:"\f29b"}.fa-question-circle-o:before{content:"\f29c"}.fa-blind:before{content:"\f29d"}.fa-audio-description:before{content:"\f29e"}.fa-volume-control-phone:before{content:"\f2a0"}.fa-braille:before{content:"\f2a1"}.fa-assistive-listening-systems:before{content:"\f2a2"}.fa-asl-interpreting:before,.fa-american-sign-language-interpreting:before{content:"\f2a3"}.fa-deafness:before,.fa-hard-of-hearing:before,.fa-deaf:before{content:"\f2a4"}.fa-glide:before{content:"\f2a5"}.fa-glide-g:before{content:"\f2a6"}.fa-signing:before,.fa-sign-language:before{content:"\f2a7"}.fa-low-vision:before{content:"\f2a8"}.fa-viadeo:before{content:"\f2a9"}.fa-viadeo-square:before{content:"\f2aa"}.fa-snapchat:before{content:"\f2ab"}.fa-snapchat-ghost:before{content:"\f2ac"}.fa-snapchat-square:before{content:"\f2ad"}.fa-pied-piper:before{content:"\f2ae"}.fa-first-order:before{content:"\f2b0"}.fa-yoast:before{content:"\f2b1"}.fa-themeisle:before{content:"\f2b2"}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:"\f2b3"}.fa-fa:before,.fa-font-awesome:before{content:"\f2b4"}.fa-handshake-o:before{content:"\f2b5"}.fa-envelope-open:before{content:"\f2b6"}.fa-envelope-open-o:before{content:"\f2b7"}.fa-linode:before{content:"\f2b8"}.fa-address-book:before{content:"\f2b9"}.fa-address-book-o:before{content:"\f2ba"}.fa-vcard:before,.fa-address-card:before{content:"\f2bb"}.fa-vcard-o:before,.fa-address-card-o:before{content:"\f2bc"}.fa-user-circle:before{content:"\f2bd"}.fa-user-circle-o:before{content:"\f2be"}.fa-user-o:before{content:"\f2c0"}.fa-id-badge:before{content:"\f2c1"}.fa-drivers-license:before,.fa-id-card:before{content:"\f2c2"}.fa-drivers-license-o:before,.fa-id-card-o:before{content:"\f2c3"}.fa-quora:before{content:"\f2c4"}.fa-free-code-camp:before{content:"\f2c5"}.fa-telegram:before{content:"\f2c6"}.fa-thermometer-4:before,.fa-thermometer:before,.fa-thermometer-full:before{content:"\f2c7"}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:"\f2c8"}.fa-thermometer-2:before,.fa-thermometer-half:before{content:"\f2c9"}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:"\f2ca"}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:"\f2cb"}.fa-shower:before{content:"\f2cc"}.fa-bathtub:before,.fa-s15:before,.fa-bath:before{content:"\f2cd"}.fa-podcast:before{content:"\f2ce"}.fa-window-maximize:before{content:"\f2d0"}.fa-window-minimize:before{content:"\f2d1"}.fa-window-restore:before{content:"\f2d2"}.fa-times-rectangle:before,.fa-window-close:before{content:"\f2d3"}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:"\f2d4"}.fa-bandcamp:before{content:"\f2d5"}.fa-grav:before{content:"\f2d6"}.fa-etsy:before{content:"\f2d7"}.fa-imdb:before{content:"\f2d8"}.fa-ravelry:before{content:"\f2d9"}.fa-eercast:before{content:"\f2da"}.fa-microchip:before{content:"\f2db"}.fa-snowflake-o:before{content:"\f2dc"}.fa-superpowers:before{content:"\f2dd"}.fa-wpexplorer:before{content:"\f2de"}.fa-meetup:before{content:"\f2e0"}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto} 5 | 6 | --------------------------------------------------------------------------------