├── Procfile ├── app ├── public │ ├── img │ │ ├── hero.jpg │ │ ├── bubble.png │ │ ├── logo │ │ │ ├── d3.png │ │ │ ├── react.png │ │ │ ├── d3-gray.png │ │ │ ├── github.png │ │ │ ├── heroku.png │ │ │ ├── nodejs.png │ │ │ ├── twitter.png │ │ │ ├── linkedin.png │ │ │ ├── react-gray.png │ │ │ ├── socketio.png │ │ │ ├── github-gray.png │ │ │ ├── heroku-gray.png │ │ │ ├── nodejs-gray.png │ │ │ ├── twitter-gray.png │ │ │ ├── linkedin-gray.png │ │ │ └── socketio-gray.png │ │ ├── twitterment.png │ │ ├── tech-background.png │ │ ├── Twitterment_files │ │ │ ├── twitterment.png │ │ │ ├── default.js │ │ │ ├── css │ │ │ ├── default.css │ │ │ └── font-awesome.min.css │ │ └── Twitterment.html │ ├── css │ │ ├── .sass-cache │ │ │ ├── 2cceaf392f803347663abac0cd3fef79cdf69cdb │ │ │ │ └── default.scssc │ │ │ └── 7c23eecf5a23bc92480b1d81931dae77a655ae8f │ │ │ │ └── default.scssc │ │ ├── default.css.map │ │ ├── default.scss │ │ └── default.css │ └── index.html ├── app-client.jsx └── components │ ├── parts │ ├── chart │ │ ├── Line.jsx │ │ ├── XYAxes.jsx │ │ ├── GridLine.jsx │ │ ├── Axis.jsx │ │ ├── DataPoints.jsx │ │ ├── LinePath.jsx │ │ └── LineChart.jsx │ ├── TwitterStream.jsx │ ├── TweetList.jsx │ ├── Dashboard.jsx │ ├── TweetCard.jsx │ ├── SearchForm.jsx │ ├── LineChart.jsx │ └── TwitterActivityChart.jsx │ ├── Hero.jsx │ ├── Results.jsx │ ├── TechStack.jsx │ └── App.jsx ├── webpack.config.js ├── server ├── Twitter.js ├── NodeSentiment.js └── app-server.js ├── .gitignore ├── package.json └── README.md /Procfile: -------------------------------------------------------------------------------- 1 | web: node server/app-server.js -------------------------------------------------------------------------------- /app/public/img/hero.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duncanleung/twitter-sentiment/HEAD/app/public/img/hero.jpg -------------------------------------------------------------------------------- /app/public/img/bubble.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duncanleung/twitter-sentiment/HEAD/app/public/img/bubble.png -------------------------------------------------------------------------------- /app/public/img/logo/d3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duncanleung/twitter-sentiment/HEAD/app/public/img/logo/d3.png -------------------------------------------------------------------------------- /app/public/img/logo/react.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duncanleung/twitter-sentiment/HEAD/app/public/img/logo/react.png -------------------------------------------------------------------------------- /app/public/img/logo/d3-gray.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duncanleung/twitter-sentiment/HEAD/app/public/img/logo/d3-gray.png -------------------------------------------------------------------------------- /app/public/img/logo/github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duncanleung/twitter-sentiment/HEAD/app/public/img/logo/github.png -------------------------------------------------------------------------------- /app/public/img/logo/heroku.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duncanleung/twitter-sentiment/HEAD/app/public/img/logo/heroku.png -------------------------------------------------------------------------------- /app/public/img/logo/nodejs.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duncanleung/twitter-sentiment/HEAD/app/public/img/logo/nodejs.png -------------------------------------------------------------------------------- /app/public/img/logo/twitter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duncanleung/twitter-sentiment/HEAD/app/public/img/logo/twitter.png -------------------------------------------------------------------------------- /app/public/img/twitterment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duncanleung/twitter-sentiment/HEAD/app/public/img/twitterment.png -------------------------------------------------------------------------------- /app/public/img/logo/linkedin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duncanleung/twitter-sentiment/HEAD/app/public/img/logo/linkedin.png -------------------------------------------------------------------------------- /app/public/img/logo/react-gray.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duncanleung/twitter-sentiment/HEAD/app/public/img/logo/react-gray.png -------------------------------------------------------------------------------- /app/public/img/logo/socketio.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duncanleung/twitter-sentiment/HEAD/app/public/img/logo/socketio.png -------------------------------------------------------------------------------- /app/public/img/tech-background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duncanleung/twitter-sentiment/HEAD/app/public/img/tech-background.png -------------------------------------------------------------------------------- /app/public/img/logo/github-gray.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duncanleung/twitter-sentiment/HEAD/app/public/img/logo/github-gray.png -------------------------------------------------------------------------------- /app/public/img/logo/heroku-gray.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duncanleung/twitter-sentiment/HEAD/app/public/img/logo/heroku-gray.png -------------------------------------------------------------------------------- /app/public/img/logo/nodejs-gray.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duncanleung/twitter-sentiment/HEAD/app/public/img/logo/nodejs-gray.png -------------------------------------------------------------------------------- /app/public/img/logo/twitter-gray.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duncanleung/twitter-sentiment/HEAD/app/public/img/logo/twitter-gray.png -------------------------------------------------------------------------------- /app/public/img/logo/linkedin-gray.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duncanleung/twitter-sentiment/HEAD/app/public/img/logo/linkedin-gray.png -------------------------------------------------------------------------------- /app/public/img/logo/socketio-gray.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duncanleung/twitter-sentiment/HEAD/app/public/img/logo/socketio-gray.png -------------------------------------------------------------------------------- /app/public/img/Twitterment_files/twitterment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duncanleung/twitter-sentiment/HEAD/app/public/img/Twitterment_files/twitterment.png -------------------------------------------------------------------------------- /app/app-client.jsx: -------------------------------------------------------------------------------- 1 | var React = require('react'); 2 | var ReactDOM = require('react-dom'); 3 | var App = require('./components/App.jsx'); 4 | 5 | 6 | ReactDOM.render(, document.getElementById('App')); -------------------------------------------------------------------------------- /app/public/css/.sass-cache/2cceaf392f803347663abac0cd3fef79cdf69cdb/default.scssc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duncanleung/twitter-sentiment/HEAD/app/public/css/.sass-cache/2cceaf392f803347663abac0cd3fef79cdf69cdb/default.scssc -------------------------------------------------------------------------------- /app/public/css/.sass-cache/7c23eecf5a23bc92480b1d81931dae77a655ae8f/default.scssc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duncanleung/twitter-sentiment/HEAD/app/public/css/.sass-cache/7c23eecf5a23bc92480b1d81931dae77a655ae8f/default.scssc -------------------------------------------------------------------------------- /app/components/parts/chart/Line.jsx: -------------------------------------------------------------------------------- 1 | var React = require('react'); 2 | 3 | var Line = React.createClass({ 4 | render: function() { 5 | return ( 6 | 7 | ); 8 | } 9 | }); 10 | 11 | module.exports = Line; -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | entry: "./app/app-client.jsx", 3 | output: { 4 | filename: "./app/public/js/bundle.js" 5 | }, 6 | module: { 7 | loaders: [{ 8 | exclude: /(node_modules|app-server.js)/, 9 | loader: 'babel', 10 | query: 11 | { 12 | presets:['es2015', 'react'] 13 | } 14 | }] 15 | }, 16 | node: { 17 | fs: 'empty', 18 | tls: 'empty' 19 | } 20 | }; -------------------------------------------------------------------------------- /server/Twitter.js: -------------------------------------------------------------------------------- 1 | //Require Dependencies 2 | var Twit = require('twit'); 3 | var config = require('./config'); 4 | 5 | //Create Twitter Instance 6 | var Twitter = new Twit({ 7 | consumer_key: process.env.TWITTER_CONSUMER_KEY, 8 | consumer_secret: process.env.TWITTER_CONSUMER_SECRET, 9 | access_token: process.env.TWITTER_ACCESS_TOKEN_KEY, 10 | access_token_secret: process.env.TWITTER_ACCESS_TOKEN_SECRET, 11 | }); 12 | 13 | 14 | module.exports = Twitter; 15 | 16 | -------------------------------------------------------------------------------- /app/components/parts/TwitterStream.jsx: -------------------------------------------------------------------------------- 1 | var React = require('react'); 2 | var TweetList = require('./TweetList.jsx'); 3 | 4 | //TwitterStream Displays A List of All Twitter Messages as Cards 5 | //Uses TweetList.jsx 6 | var TwitterStream = React.createClass({ 7 | 8 | render: function() { 9 | //Pass collectedTweets to TweetList 10 | return ( 11 |
12 |

Twitter Stream

13 | 14 |
15 | ); 16 | } 17 | }); 18 | 19 | 20 | module.exports = TwitterStream; -------------------------------------------------------------------------------- /app/components/parts/TweetList.jsx: -------------------------------------------------------------------------------- 1 | var React = require('react'); 2 | var TweetCard = require('./TweetCard.jsx'); 3 | 4 | //TweetList Contains All Twitter Messages as Cards 5 | //Uses TweetCard.jsx 6 | var TweetList = React.createClass({ 7 | render: function() { 8 | 9 | var tweetLoop = this.props.collectedTweets.map(function(mappedTweet, index) { 10 | return (); 11 | }); 12 | 13 | return ( 14 |
15 | {tweetLoop} 16 |
17 | ) 18 | } 19 | }); 20 | 21 | module.exports = TweetList; -------------------------------------------------------------------------------- /app/components/parts/Dashboard.jsx: -------------------------------------------------------------------------------- 1 | var React = require('react'); 2 | 3 | var TwitterActivityChart = require('./TwitterActivityChart.jsx'); 4 | 5 | 6 | //Dashboard Holds the TwitterActivity Chart Component 7 | //Uses TwitterActivityChart.jsx 8 | var Dashboard = React.createClass({ 9 | 10 | render: function() { 11 | return ( 12 |
13 | 18 |
19 | ); 20 | } 21 | }); 22 | 23 | module.exports = Dashboard; -------------------------------------------------------------------------------- /app/components/Hero.jsx: -------------------------------------------------------------------------------- 1 | var React = require('react'); 2 | var SearchForm = require('./parts/SearchForm.jsx'); 3 | 4 | function Hero(props){ 5 | return( 6 |
7 |
8 |
9 |

Track your Brand Sentiment on Twitter

10 |

What are people saying about your brand?

11 |

Twitterment

12 | 13 | 14 |
15 |
16 |
17 | ); 18 | } 19 | 20 | module.exports = Hero; -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | 5 | # Runtime data 6 | pids 7 | *.pid 8 | *.seed 9 | 10 | # Directory for instrumented libs generated by jscoverage/JSCover 11 | lib-cov 12 | 13 | # Coverage directory used by tools like istanbul 14 | coverage 15 | 16 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 17 | .grunt 18 | 19 | # node-waf configuration 20 | .lock-wscript 21 | 22 | # Compiled binary addons (http://nodejs.org/api/addons.html) 23 | build/Release 24 | 25 | # Dependency directory 26 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git 27 | node_modules 28 | psd 29 | 30 | # Codekit Config 31 | *.codekit 32 | 33 | #Twitter API Keys 34 | #config.js 35 | 36 | -------------------------------------------------------------------------------- /app/components/Results.jsx: -------------------------------------------------------------------------------- 1 | var React = require('react'); 2 | 3 | var Dashboard = require('./parts/Dashboard.jsx'); 4 | var TwitterStream = require('./parts/TwitterStream.jsx'); 5 | 6 | 7 | //Results Holds the Dashboard and TwitterStream Components 8 | //Uses Dashboard.jsx and TwitterStream.jsx 9 | function Results(props){ 10 | return( 11 |
12 |
13 | 18 | 19 |
20 |
21 | ); 22 | } 23 | 24 | module.exports = Results; -------------------------------------------------------------------------------- /app/components/parts/TweetCard.jsx: -------------------------------------------------------------------------------- 1 | var React = require('react'); 2 | 3 | //TweetCard Constructs Each Tweet Card 4 | //Reusable Component 5 | var TweetCard = React.createClass({ 6 | 7 | render: function() { 8 | 9 | return ( 10 |
11 | 12 |
13 |
14 | {this.props.tweet.user.name} 15 | @{this.props.tweet.user.screen_name} 16 |
17 |
18 |
{this.props.tweet.text}
19 |
20 |
21 | ) 22 | } 23 | }); 24 | 25 | module.exports = TweetCard; -------------------------------------------------------------------------------- /app/components/parts/chart/XYAxes.jsx: -------------------------------------------------------------------------------- 1 | var React = require('react'); 2 | 3 | var Axis = require('./Axis.jsx'); 4 | 5 | //XYAxes Holds the Separate X and Y Axis Components 6 | var XYAxes = React.createClass({ 7 | 8 | //Create x and y props to Pass into 9 | render: function() { 10 | var xAxis = { 11 | className: 'x axis', 12 | translate: 'translate(0,' + this.props.height + ')', 13 | scale: this.props.xScale, 14 | orient: 'bottom', 15 | ticks: 4 16 | }; 17 | 18 | var yAxis = { 19 | className: 'y axis', 20 | translate: 'translate(0, 0)', 21 | scale: this.props.yScale, 22 | orient: 'left', 23 | ticks: 6 24 | }; 25 | 26 | //Use React to Append g Element (Usually D3 Handles This) 27 | //Append for X and Y Axis 28 | return ( 29 | 30 | 31 | 32 | 33 | ); 34 | } 35 | }); 36 | 37 | module.exports = XYAxes; -------------------------------------------------------------------------------- /app/components/parts/SearchForm.jsx: -------------------------------------------------------------------------------- 1 | var React = require('react'); 2 | var ReactDOM = require('react-dom'); 3 | 4 | class SearchForm extends React.Component { 5 | search() { 6 | var keyword = ReactDOM.findDOMNode(this.refs.keyword).value; 7 | var initTimestamp = new Date().getTime(); 8 | 9 | this.props.emit('search', { keyword: keyword }); 10 | this.props.initTimestamp({ initTimestamp: initTimestamp }); 11 | } 12 | 13 | render() { 14 | return ( 15 | 24 | ); 25 | } 26 | } 27 | 28 | module.exports = SearchForm; -------------------------------------------------------------------------------- /app/components/parts/chart/GridLine.jsx: -------------------------------------------------------------------------------- 1 | var React = require('react'); 2 | var ReactDOM = require('react-dom'); 3 | 4 | //GridLine 5 | var GridLine = React.createClass({ 6 | 7 | componentDidUpdate: function() { 8 | this.renderGridline(); 9 | }, 10 | 11 | componentDidMount: function() { 12 | this.renderGridline(); 13 | }, 14 | 15 | //Use D3 to Create Axis on 'this DOM Node' 16 | renderGridline: function() { 17 | var node = ReactDOM.findDOMNode(); 18 | 19 | var gridline = d3.svg.axis() 20 | .scale(this.props.yScale) 21 | .tickSize(-this.props.width, 0, 0) 22 | .ticks(6) 23 | .tickFormat("") 24 | .orient("left") 25 | 26 | //This is where the magic happens! 27 | d3.select(node).call(gridline); 28 | }, 29 | 30 | render: function() { 31 | var yGridline = { 32 | className: 'gridline', 33 | transform: 'translate(0, 0)', 34 | }; 35 | 36 | return( 37 | 38 | ); 39 | } 40 | }); 41 | 42 | module.exports = GridLine; -------------------------------------------------------------------------------- /server/NodeSentiment.js: -------------------------------------------------------------------------------- 1 | var nodeSentiment = require('sentiment'); 2 | 3 | var sentiment = {}; 4 | 5 | 6 | //Send Tweet Text to Sentiment Analysis 7 | sentiment.getSentiment = function(tweet, socket) { 8 | var tweetSentiment = nodeSentiment(tweet.text); 9 | 10 | if(tweetSentiment.score < 0) { 11 | tweetSentiment = 'negative'; 12 | } else if(tweetSentiment.score > 0) { 13 | tweetSentiment = 'positive'; 14 | } else { 15 | tweetSentiment = 'neutral'; 16 | } 17 | 18 | return sentiment.appendSentiment(tweet, tweetSentiment, socket); 19 | }; 20 | 21 | //Construct New Tweet Object 22 | //Send sentimentTweet to Client 23 | sentiment.appendSentiment = function(tweet, sentiment, socket) { 24 | var sentimentTweet = { 25 | sentiment: sentiment, 26 | created_at: tweet.created_at, 27 | timestamp_ms: tweet.timestamp_ms, 28 | id_str: tweet.id_str, 29 | user: { 30 | name: tweet.user.name, 31 | screen_name: tweet.user.screen_name, 32 | profile_image_url_https: tweet.user.profile_image_url_https, 33 | location: tweet.user.location, 34 | time_zone: tweet.user.time_zone 35 | }, 36 | text: tweet.text, 37 | lang: tweet.lang 38 | }; 39 | 40 | console.log(sentimentTweet.text); 41 | 42 | return sentimentTweet; 43 | }; 44 | 45 | module.exports = sentiment; -------------------------------------------------------------------------------- /app/public/img/Twitterment_files/default.js: -------------------------------------------------------------------------------- 1 | /* Handle Index Page Behavior 2 | =================*/ 3 | 4 | var elSearch = document.getElementById('search'); 5 | var elSubmit = document.getElementById('submit'); 6 | 7 | var tweetHistory = []; 8 | 9 | /*elSubmit.addEventListener('click', postSearch, true); 10 | elSearch.addEventListener('keypress', submit, true);*/ 11 | 12 | function submit(e) { 13 | var key = e.which || e.keyCode; 14 | if (key === 13) { 15 | 16 | postSearch(); 17 | } 18 | } 19 | 20 | function postSearch() { 21 | var query = { 22 | query: elSearch.value 23 | }; 24 | 25 | console.log(query); 26 | 27 | var xhr = new XMLHttpRequest(); 28 | 29 | xhr.onload = function() { 30 | if (xhr.status === 200) { 31 | response = JSON.parse(xhr.responseText); 32 | 33 | tweetHistory = tweetHistory.concat(response); 34 | 35 | console.log(tweetHistory); 36 | 37 | 38 | /*setTimeout(function() { 39 | postSearch(); 40 | 41 | console.log('stream starting'); 42 | }, 5000);*/ 43 | 44 | } 45 | }; 46 | 47 | xhr.open('POST', '/api', true); 48 | xhr.setRequestHeader('Content-Type', 'application/json;charset=UTF-8'); 49 | xhr.send(JSON.stringify(query)); 50 | } 51 | 52 | 53 | 54 | function populate(response) { 55 | var elStream = document.getElementById('stream'); 56 | 57 | var elList = document.createElement('p'); 58 | elStream.appendChild(elList); 59 | 60 | console.log(response); 61 | } -------------------------------------------------------------------------------- /app/components/TechStack.jsx: -------------------------------------------------------------------------------- 1 | var React = require('react'); 2 | 3 | function TechStack() { 4 | return ( 5 |
6 |
7 |
8 |

Twitterment was built with these technologies:

9 |
10 | 12 | 14 | 16 |
17 |
18 | 20 | 22 | 24 |
25 |
26 |
27 |
28 |

29 |
30 |
31 | ) 32 | } 33 | 34 | module.exports = TechStack; -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "twitter-sentiment", 3 | "version": "1.0.0", 4 | "description": "A Twitter sentiment dashboard for companies who want to monitor the sentiment around their brand", 5 | "main": "app.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "prestart": "webpack", 9 | "start": "node ./server/app-server.js" 10 | }, 11 | "repository": { 12 | "type": "git", 13 | "url": "git+https://github.com/duncanleung/twitter-sentiment.git" 14 | }, 15 | "keywords": [ 16 | "twitter", 17 | "sentiment" 18 | ], 19 | "author": "Duncan Leung", 20 | "license": "ISC", 21 | "bugs": { 22 | "url": "https://github.com/duncanleung/twitter-sentiment/issues" 23 | }, 24 | "homepage": "https://github.com/duncanleung/twitter-sentiment#readme", 25 | "dependencies": { 26 | "babel-core": "^6.3.26", 27 | "babel-loader": "^6.2.0", 28 | "babel-preset-es2015": "^6.3.13", 29 | "babel-preset-react": "^6.3.13", 30 | "body-parser": "^1.14.2", 31 | "bufferutil": "^1.2.1", 32 | "classnames": "^2.2.3", 33 | "d3": "^3.5.12", 34 | "datumbox": "^1.0.1", 35 | "express": "^4.13.3", 36 | "immutability-helper": "^2.1.1", 37 | "node-uuid": "^1.4.7", 38 | "react": "^15.4.2", 39 | "react-addons-update": "^15.4.2", 40 | "react-dom": "^15.4.2", 41 | "request": "^2.67.0", 42 | "sentiment": "^1.0.5", 43 | "socket.io": "^1.3.7", 44 | "socket.io-client": "^1.3.7", 45 | "twit": "^2.1.1", 46 | "underscore": "^1.8.3", 47 | "utf-8-validate": "^1.2.1", 48 | "webpack": "^1.12.9" 49 | }, 50 | "devDependencies": {} 51 | } 52 | -------------------------------------------------------------------------------- /app/components/parts/chart/Axis.jsx: -------------------------------------------------------------------------------- 1 | var React = require('react'); 2 | var ReactDOM = require('react-dom'); 3 | var d3 = require('d3'); 4 | 5 | //Axis is a Reusable Axis Creator for Charts 6 | var Axis = React.createClass({ 7 | 8 | componentDidUpdate: function() { 9 | this.renderAxis(); 10 | }, 11 | 12 | componentDidMount: function() { 13 | this.renderAxis(); 14 | this.renderXLabel(); 15 | this.renderYLabel(); 16 | }, 17 | 18 | //Use D3 to Create Axis on 'this DOM Node' 19 | renderAxis: function() { 20 | var node = ReactDOM.findDOMNode(); 21 | 22 | var axis = d3.svg.axis() 23 | .scale(this.props.scale) 24 | .orient(this.props.orient) 25 | .ticks(this.props.ticks) 26 | 27 | //This is where the magic happens! 28 | d3.select(node).call(axis); 29 | }, 30 | 31 | renderXLabel: function() { 32 | var node = ReactDOM.findDOMNode(); 33 | 34 | var xLabel = d3.select(".x.axis") 35 | .append("text") 36 | .text("Seconds Since Search") 37 | .classed("x-label", true) 38 | .attr("x", 350) 39 | .attr("y", 40) 40 | .style("text-anchor", "middle"); 41 | }, 42 | 43 | renderYLabel: function() { 44 | var node = ReactDOM.findDOMNode(); 45 | 46 | var yLabel = d3.select(".y.axis") 47 | .append("text") 48 | .text("Number of Tweets") 49 | .classed("y-label", true) 50 | .attr("x", -(this.props.height/2)) 51 | .attr("y", -35) 52 | .style("text-anchor", "middle") 53 | .attr("transform", "rotate(-90)"); 54 | }, 55 | 56 | //Use React to Append g Element (Usually D3 Handles This) 57 | render: function() { 58 | return( 59 | 60 | ); 61 | } 62 | }); 63 | 64 | module.exports = Axis; -------------------------------------------------------------------------------- /app/components/parts/chart/DataPoints.jsx: -------------------------------------------------------------------------------- 1 | var React = require('react'); 2 | var uuid = require('node-uuid'); 3 | 4 | 5 | //Datapoints Draws Each Tweet on the Chart 6 | var DataPoints = React.createClass({ 7 | 8 | //renderPoints Returns a for Each Data Point 9 | renderPoints: function(data, index) { 10 | var dataNegativeProps = { 11 | cx: this.props.xScale(data.timeBin), 12 | cy: this.props.yScale(data.negTweets), 13 | r: 4, 14 | fill: "none", 15 | stroke: "red", 16 | strokeWidth: 2, 17 | key: uuid.v4() 18 | }; 19 | 20 | var dataPositiveProps = { 21 | cx: this.props.xScale(data.timeBin), 22 | cy: this.props.yScale(data.posTweets), 23 | r: 4, 24 | fill: "none", 25 | stroke: "green", 26 | strokeWidth: 2, 27 | key: uuid.v4() 28 | }; 29 | 30 | var dataNeutralProps = { 31 | cx: this.props.xScale(data.timeBin), 32 | cy: this.props.yScale(data.neutTweets), 33 | r: 4, 34 | fill: "none", 35 | stroke: "sandybrown", 36 | strokeWidth: 2, 37 | key: uuid.v4() 38 | }; 39 | 40 | var dataTotalProps = { 41 | cx: this.props.xScale(data.timeBin), 42 | cy: this.props.yScale(data.numTweets), 43 | r: 4, 44 | fill: "none", 45 | stroke: "blue", 46 | strokeWidth: 2, 47 | key: uuid.v4() 48 | }; 49 | 50 | return ( 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | ); 62 | }, 63 | 64 | //Use React to Append g Element (Usually D3 Handles This) 65 | //Run renderBars for all binnedTweet Data Values 66 | render: function() { 67 | return { this.props.binnedTweets.map(this.renderPoints) } 68 | } 69 | }); 70 | 71 | module.exports = DataPoints; -------------------------------------------------------------------------------- /server/app-server.js: -------------------------------------------------------------------------------- 1 | //Require Dependencies 2 | var express = require('express'); 3 | 4 | var Twitter = require('./Twitter'); 5 | var sentiment = require('./NodeSentiment.js'); 6 | var twitterStream = Twitter; 7 | 8 | //Create Express Server Instance 9 | var app = express(); 10 | var port = process.env.PORT || 4000; 11 | 12 | //Routes and Serve Static Files 13 | app.use(express.static(__dirname + './../app/public')); 14 | 15 | 16 | 17 | /* 18 | Create Server and Socket.io Instance 19 | ==================*/ 20 | var server = app.listen(port); 21 | console.log('Server on port: %s', port); 22 | 23 | var io = require('socket.io').listen(server); 24 | var connections = []; 25 | 26 | //Create socket.io Connection with Client 27 | //All Socket Listeners Here 28 | io.sockets.on('connection', function(socket) { 29 | 30 | connections.push(socket); 31 | console.log('%s Connected. %s sockets connected', socket.id, connections.length); 32 | 33 | var prevSearch = false; 34 | var twitterStream; 35 | 36 | socket.on('search', function(payload) { 37 | console.log('Keyword: %s', payload.keyword); 38 | 39 | if(prevSearch) { 40 | twitterStream.stop(); 41 | console.log(prevSearch); 42 | console.log('stop stream'); 43 | 44 | } else { 45 | prevSearch = true; 46 | } 47 | 48 | twitterStream = Twitter.stream('statuses/filter', {language: 'en', track: payload.keyword}); 49 | 50 | 51 | var lastTimestamp = Date.now(), 52 | speedLimiter = 800; //800ms 53 | 54 | //Turn on Twitter Stream 55 | twitterStream.on('tweet', function(tweet) { 56 | 57 | if(tweet.timestamp_ms - lastTimestamp > speedLimiter) { 58 | 59 | lastTimestamp = Date.now(); 60 | 61 | // Send Tweet Object to Client 62 | socket.emit('sendTweet', {tweet: sentiment.getSentiment(tweet, socket)}); 63 | } 64 | }); 65 | 66 | socket.once('disconnect', function() { 67 | connections.splice(connections.indexOf(socket), 1); 68 | socket.disconnect(); 69 | twitterStream.stop(); 70 | console.log('Socket disconnected: %s sockets remaining', connections.length); 71 | }); 72 | }); 73 | 74 | }); //END io.sockets.on 75 | 76 | 77 | -------------------------------------------------------------------------------- /app/components/parts/chart/LinePath.jsx: -------------------------------------------------------------------------------- 1 | var React = require('react'); 2 | var d3 = require('d3'); 3 | 4 | var Line = require('./Line.jsx'); 5 | 6 | 7 | var LinePath = React.createClass({ 8 | 9 | render: function() { 10 | var props = this.props; 11 | var xScale = props.xScale; 12 | var yScale = props.yScale; 13 | 14 | var pathTotal = d3.svg.line() 15 | .x(function(d) { 16 | return xScale(d.timeBin); 17 | }) 18 | .y(function(d) { 19 | return yScale(d.numTweets); 20 | }) 21 | .interpolate("cardinal"); 22 | 23 | var pathPositive = d3.svg.line() 24 | .x(function(d) { 25 | return xScale(d.timeBin); 26 | }) 27 | .y(function(d) { 28 | return yScale(d.posTweets); 29 | }) 30 | .interpolate("cardinal"); 31 | 32 | var pathNegative = d3.svg.line() 33 | .x(function(d) { 34 | return xScale(d.timeBin); 35 | }) 36 | .y(function(d) { 37 | return yScale(d.negTweets); 38 | }) 39 | .interpolate("cardinal"); 40 | 41 | var pathNeutral = d3.svg.line() 42 | .x(function(d) { 43 | return xScale(d.timeBin); 44 | }) 45 | .y(function(d) { 46 | return yScale(d.neutTweets); 47 | }) 48 | .interpolate("cardinal"); 49 | 50 | return ( 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | ); 59 | } 60 | }); 61 | 62 | module.exports = LinePath; -------------------------------------------------------------------------------- /app/components/parts/LineChart.jsx: -------------------------------------------------------------------------------- 1 | var React = require('react'); 2 | 3 | var DataPoints = require('./DataPoints.jsx'); 4 | var LinePath = require('./LinePath.jsx'); 5 | var XYAxes = require('./XYAxes.jsx'); 6 | var GridLine = require('./GridLine.jsx'); 7 | 8 | 9 | //LineChart Holds All Data Points and the XYAxes 10 | var LineChart = React.createClass({ 11 | 12 | //Use D3 to Scale 'x' Data Points to Fit Chart Area 13 | //Use for Data Points and for Axis 14 | getXScale: function(props) { 15 | var xMax = d3.max(props.binnedTweets, function(d) { return d.timeBin }); 16 | 17 | return d3.scale.linear() 18 | .domain([0, xMax]) 19 | .range([0, props.width]); 20 | }, 21 | 22 | //Use D3 to Scale 'y' Data Points to Fit Chart Area 23 | //Use for Data Points and for Axis 24 | getYScale: function(props) { 25 | var yMax = d3.max(props.binnedTweets, function(d) { return d.numTweets }); 26 | 27 | return d3.scale.linear() 28 | .domain([0, yMax]) 29 | .range([props.height, 0]); 30 | }, 31 | 32 | //Use React to Append svg Element (Usually D3 Handles This) 33 | render: function() { 34 | var xScale = this.getXScale(this.props); 35 | var yScale = this.getYScale(this.props); 36 | 37 | var chartDisplay = { 38 | className: 'chart-area', 39 | transform: 'translate(' + this.props.margin.left + ', ' + this.props.margin.top + ')', 40 | }; 41 | //{...this.props} combines all props (aka. xScale, yScale) into 'props' 42 | return ( 43 | 44 | 45 | 50 | 55 | 60 | 65 | 66 | 67 | 68 | ); 69 | } 70 | }); 71 | 72 | module.exports = LineChart; -------------------------------------------------------------------------------- /app/components/parts/chart/LineChart.jsx: -------------------------------------------------------------------------------- 1 | var React = require('react'); 2 | 3 | var DataPoints = require('./DataPoints.jsx'); 4 | var LinePath = require('./LinePath.jsx'); 5 | var XYAxes = require('./XYAxes.jsx'); 6 | var GridLine = require('./GridLine.jsx'); 7 | 8 | 9 | //LineChart Holds All Data Points and the XYAxes 10 | var LineChart = React.createClass({ 11 | 12 | //Use D3 to Scale 'x' Data Points to Fit Chart Area 13 | //Use for Data Points and for Axis 14 | getXScale: function(props) { 15 | var xMax = d3.max(props.binnedTweets, function(d) { return d.timeBin }); 16 | 17 | return d3.scale.linear() 18 | .domain([0, xMax]) 19 | .range([0, props.width]); 20 | }, 21 | 22 | //Use D3 to Scale 'y' Data Points to Fit Chart Area 23 | //Use for Data Points and for Axis 24 | getYScale: function(props) { 25 | var yMax = d3.max(props.binnedTweets, function(d) { return d.numTweets }); 26 | 27 | return d3.scale.linear() 28 | .domain([0, yMax]) 29 | .range([props.height, 0]); 30 | }, 31 | 32 | //Use React to Append svg Element (Usually D3 Handles This) 33 | render: function() { 34 | var xScale = this.getXScale(this.props); 35 | var yScale = this.getYScale(this.props); 36 | 37 | var chartDisplay = { 38 | className: 'chart-area', 39 | transform: 'translate(' + this.props.margin.left + ', ' + this.props.margin.top + ')', 40 | }; 41 | //{...props} combines all props (aka. xScale, yScale) into 'props' 42 | return ( 43 | 44 | 45 | 50 | 55 | 60 | 65 | 66 | 67 | 68 | ); 69 | } 70 | }); 71 | 72 | module.exports = LineChart; -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # twitter-sentiment 2 | **Live Demo:** [twitterment.herokuapp.com](http://twitterment.herokuapp.com) 3 | 4 | _There is a daily limit on the number of Twitter Stream API requests. **Please don't leave the app running continually.**_ 5 | >_If no Tweets show up, it's because the daily limit has already been reached. Please try again the next day._ 6 | 7 | >_Or, you can also download the repo and run it on your own server with your own Twitter Stream API keys =)_ 8 | 9 | ####About 10 | Twitterment (Twitter Sentiment) Is a real-time Twitter sentiment dashboard that analyzes and graphs the sentiment of a tracked keyword. 11 | 12 | Testing out: 13 | - Socket.io 14 | - React.js 15 | - D3.js 16 | 17 | Currently in the process of refactoring to update to: 18 | - ES6 19 | - React 0.x to 15.x 20 | - React controller views and stateless functional components 21 | 22 | ####Summary 23 | Twitterment listens to the Twitter Streaming API for the searched keyword. Received Tweets are analyzed with an [AFINN-based sentiment analysis npm module](https://github.com/thisandagain/sentiment), and the analyzed Tweet object is sent to the client. 24 | 25 | Node.js (Express) and Socket.io is used on the backend to achieve real-time client-server updates when new tweets are received on the server. React.js is used as the view layer to manage DOM rendering of new Tweets in real-time with a reusable React TweetCard.jsx component. D3.js is used to render each sentiment analyzed Tweet onto a line graph to show the sentiment trend since the search started. 26 | 27 | Regarding D3 and React integration, Twitterment uses React to handle DOM manipulations for plotting Data Points (DataPoints.jsx) and Line Paths (LinePath.jsx) for the line graph. This decision was made since React already knows when to rerender the graph when new tweets are received and the tweet counts are updated in the app. 28 | 29 | ####Built With the Following Technologies: 30 | - Node (Express) 31 | - Socket.io 32 | - React.js 33 | - D3.js 34 | - Sass 35 | - Twitter Streaming API 36 | - Babel 37 | - Webpack 38 | 39 | 40 | ##To run an instance of this app, you need: 41 | 42 | 1 =========== Twitter API Key =========== 43 | - Create `config.js` in `/twitter-sentiment/server/` 44 | - `config.js` holds your own Twitter API Keys 45 | 46 | 47 | ``` 48 | config.js 49 | process.env.TWITTER_CONSUMER_KEY = 'YOUR-CONSUMER-KEY-HERE'; 50 | process.env.TWITTER_CONSUMER_SECRET = 'YOUR-CONSUMER-SECRET-HERE'; 51 | process.env.TWITTER_ACCESS_TOKEN_KEY = 'YOUR-TOKEN-HERE'; 52 | process.env.TWITTER_ACCESS_TOKEN_SECRET = 'YOUR-TOKEN-SECRET-HERE'; 53 | ``` 54 | 55 | 2 =========== Clone the Repo =========== 56 | - Run `npm install` to install dependencies 57 | - Run `node server/app-server.js` to start! 58 | - FYI: `npm start` will run webpack and bundle any changes you may make 59 | 60 | ![Twitterment Main Screen](http://res.cloudinary.com/leungd/image/upload/v1486945672/github/twitterment-1.png) 61 | ![Twitterment Stream Screen](http://res.cloudinary.com/leungd/image/upload/v1486945672/github/twitterment-2.png) 62 | ![Twitterment Technologies Screen](http://res.cloudinary.com/leungd/image/upload/v1486945672/github/twitterment-3.png) 63 | -------------------------------------------------------------------------------- /app/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Twitterment 11 | 12 | 13 |
14 |
15 | 23 |
24 |
25 | 26 |
27 |
28 | 29 |
30 |
31 |
32 |
33 |

True Real Time Tracking

34 |

See how your brand sentiment is trending at this moment.

35 |
36 |
37 |
38 |
39 |

40 |
41 | Real Time with Socket.io 42 |

43 |

44 | Twitterment's server is built with NodeJS and Socket.io to provide real-time tracking. When new Tweets are received, Socket.io immediately sends the new data to your dashboard. 45 |

46 |
47 |
48 |
49 |
50 |

51 |
52 | Twitter Streaming API 53 |

54 |

55 | Track specific keywords from Twitter's streaming API. Know exactly what's happening on Twitter, at this instant. Never miss a beat. 56 |

57 |
58 |
59 |
60 |
61 |

62 |
63 | Data Driven Documents: D3 64 |

65 |

66 | Twitterment uses D3 to provide real-time graphical updates of how your brand is trending on Twitter for each new data point. 67 |

68 |
69 |
70 |
71 |
72 |
73 |
74 | 75 |
76 |
77 |
78 |
79 |

Connect with the author:

80 | 81 | 82 |
83 |
84 |

Twitterment © 2015

85 |
86 |
87 |
88 |
89 | 90 | 91 | -------------------------------------------------------------------------------- /app/components/parts/TwitterActivityChart.jsx: -------------------------------------------------------------------------------- 1 | var React = require('react'); 2 | var ReactDOM = require('react-dom'); 3 | var d3 = require('d3'); 4 | 5 | var LineChart = require('./chart/LineChart.jsx'); 6 | 7 | 8 | var chartProps = { 9 | chartWidth: 800, 10 | chartHeight: 350, 11 | margin: { 12 | top: 30, 13 | bottom: 60, 14 | left: 60, 15 | right: 40 16 | }, 17 | }; 18 | 19 | var chartArea = { 20 | width: chartProps.chartWidth - chartProps.margin.left - chartProps.margin.right, 21 | height: chartProps.chartHeight - chartProps.margin.top - chartProps.margin.bottom, 22 | } 23 | 24 | var barProps = { 25 | chartWidth: 400, 26 | chartHeight: 100 27 | }; 28 | 29 | 30 | //TwitterActivityChart Is the LineChart Container 31 | var TwitterActivityChart = React.createClass({ 32 | 33 | componentWillUpdate: function(nextProps, nextState) { 34 | 35 | /*Counter Highlighter 36 | ===============*/ 37 | 38 | //Positive Highlighter 39 | if(Number(this.refs.positivecounter.innerHTML) != nextProps.totalTweets.posTotal) { 40 | this.refs.positivearrow.classList.add('positive'); 41 | this.refs.positivecounter.classList.add('positive'); 42 | 43 | this.refs.neutralarrow.classList.remove('neutral'); 44 | this.refs.neutralcounter.classList.remove('neutral'); 45 | this.refs.negativearrow.classList.remove('negative'); 46 | this.refs.negativecounter.classList.remove('negative'); 47 | } 48 | 49 | //Neutral Highlighter 50 | if(Number(this.refs.neutralcounter.innerHTML) != nextProps.totalTweets.neutTotal) { 51 | this.refs.neutralarrow.classList.add('neutral'); 52 | this.refs.neutralcounter.classList.add('neutral'); 53 | 54 | this.refs.positivearrow.classList.remove('positive'); 55 | this.refs.positivecounter.classList.remove('positive'); 56 | this.refs.negativearrow.classList.remove('negative'); 57 | this.refs.negativecounter.classList.remove('negative'); 58 | } 59 | 60 | //Negative Highlighter 61 | if(Number(this.refs.negativecounter.innerHTML) !== nextProps.totalTweets.negTotal) { 62 | this.refs.negativearrow.classList.add('negative'); 63 | this.refs.negativecounter.classList.add('negative'); 64 | 65 | this.refs.neutralarrow.classList.remove('neutral'); 66 | this.refs.neutralcounter.classList.remove('neutral'); 67 | this.refs.positivearrow.classList.remove('positive'); 68 | this.refs.positivecounter.classList.remove('positive'); 69 | } 70 | 71 | /*Overall Sentiment Highlighter 72 | ===============*/ 73 | if(this.props.sentiment == 'Positive') { 74 | this.refs.sentiment.classList.add('positive'); 75 | this.refs.sentiment.classList.remove('negative'); 76 | } else if(this.props.sentiment == 'Negative') { 77 | this.refs.sentiment.classList.add('negative'); 78 | this.refs.sentiment.classList.remove('positive'); 79 | } else { 80 | this.refs.sentiment.classList.remove('negative'); 81 | this.refs.sentiment.classList.remove('positive'); 82 | } 83 | 84 | }, 85 | 86 | //{...chartProps}: Properties of chartProps are copied into component's props 87 | //{...chartArea}: Properties of chartArea are copied into component's props 88 | render: function() { 89 | return( 90 |
91 |

Twitter Activity

92 | 96 | 97 |
98 |
99 |

Total Tweets

100 |
101 |
{ this.props.totalTweets.total }
102 |
103 |
104 |

Positive Tweets

105 |
106 |
{ this.props.totalTweets.posTotal }
107 |
108 |
109 |
110 |

Neutral Tweets

111 |
112 |
{ this.props.totalTweets.neutTotal }
113 |
114 |
115 |
116 |

Negative Tweets

117 |
118 |
{ this.props.totalTweets.negTotal }
119 |
120 |
121 |
122 |
123 |

Overall Sentiment

124 |

{this.props.sentiment}

125 |
126 |
127 | ); 128 | } 129 | }); 130 | 131 | module.exports = TwitterActivityChart; 132 | -------------------------------------------------------------------------------- /app/components/App.jsx: -------------------------------------------------------------------------------- 1 | var React = require('react'); 2 | var io = require('socket.io-client'); 3 | var update = require('immutability-helper'); 4 | var d3 = require('d3'); 5 | 6 | var Hero = require('./Hero.jsx'); 7 | var TechStack = require('./TechStack.jsx'); 8 | var Results = require('./Results.jsx'); 9 | 10 | 11 | //App is the Main Container 12 | class App extends React.Component { 13 | constructor(props) { 14 | super(props); 15 | this.state = { 16 | status: 'disconnected', 17 | search: false, 18 | keyword: '', 19 | initTimestamp: '', 20 | collectedTweets: [], 21 | binnedTweets: [{numTweets: 0, posTweets: 0, 22 | negTweets: 0, neutTweets: 0, timeBin: 5}], 23 | totalTweets: {total: 0, posTotal: 0, 24 | negTotal: 0, neutTotal: 0}, 25 | sentiment: 'Neutral' 26 | }; 27 | 28 | this.emit = this.emit.bind(this); 29 | this.initTimestamp = this.initTimestamp.bind(this); 30 | } 31 | 32 | //Incoming Data from Server Handlers 33 | componentWillMount() { 34 | var self = this; 35 | 36 | this.socket = io.connect(); 37 | this.socket.on('connect', this.connect.bind(this)); 38 | this.socket.on('disconnect', this.disconnect.bind(this)); 39 | this.socket.on('sendTweet', function(receivedTweet) { 40 | self.addTweet(receivedTweet.tweet); 41 | }); 42 | } 43 | 44 | //Outgoing Data to Server Handler 45 | emit(eventName, payload) { 46 | this.socket.emit(eventName, payload); 47 | 48 | // Reset Dashboard on New Search 49 | this.setState({ 50 | collectedTweets: [], 51 | binnedTweets: [{numTweets: 0, posTweets: 0, 52 | negTweets: 0, neutTweets: 0, timeBin: 5}], 53 | totalTweets: {total: 0, posTotal: 0, 54 | negTotal: 0, neutTotal: 0} 55 | }); 56 | } 57 | 58 | //Connect Handler 59 | connect() { 60 | this.setState({ status: 'connected' }); 61 | console.log('Connected on socket: %s', this.socket.id); 62 | } 63 | 64 | //Disconnect Handler 65 | disconnect() { 66 | this.setState({ status: 'disconnected' }); 67 | console.log('Disconnected: %s', this.socket.id); 68 | } 69 | 70 | initTimestamp(timestamp) { 71 | this.setState({ initTimestamp: timestamp.initTimestamp }); 72 | this.setState({ search: true }); 73 | } 74 | 75 | //Add receivedTweet onto beginning of array 76 | //Update the state of collectedTweets 77 | addTweet(tweet) { 78 | var tweets = this.state.collectedTweets; 79 | var newTweets = update(tweets, {$unshift: [tweet]}); 80 | 81 | this.setState({ collectedTweets: newTweets }); 82 | this.binTweets(tweet.timestamp_ms, tweet.sentiment); 83 | this.countTweets(tweet.sentiment); 84 | this.overallSentiment(); 85 | } 86 | 87 | //Inspect Sentiment Value. Increase count of Sentiment 88 | //Update the state of totalTweets 89 | countTweets(sentiment) { 90 | var totalTweets = this.state.totalTweets; 91 | var newTotal = totalTweets; 92 | 93 | if(sentiment == "positive") { 94 | totalTweets.posTotal++; 95 | totalTweets.total++; 96 | this.setState({ totalTweets: newTotal }); 97 | 98 | } else if(sentiment == "negative") { 99 | totalTweets.negTotal++; 100 | totalTweets.total++; 101 | this.setState({ totalTweets: newTotal }); 102 | } else { 103 | totalTweets.neutTotal++; 104 | totalTweets.total++; 105 | this.setState({ totalTweets: newTotal }); 106 | } 107 | } 108 | 109 | overallSentiment() { 110 | var totalTweets = this.state.totalTweets.posTotal + this.state.totalTweets.negTotal; 111 | var posTweets = this.state.totalTweets.posTotal 112 | var sentiment = posTweets/totalTweets; 113 | 114 | if(sentiment < 0.5) { 115 | this.setState({ sentiment: 'Negative' }); 116 | } else if(sentiment > 0.5) { 117 | this.setState({ sentiment: 'Positive' }); 118 | } else { 119 | this.setState({ sentiment: 'Neutral' }); 120 | } 121 | } 122 | 123 | //Push Tweet Counts into Bins: 5sec, 10sec, etc. 124 | //Update the state of binnedTweets 125 | binTweets(tweetTimestamp, sentiment) { 126 | var initTimestamp = this.state.initTimestamp; 127 | var timeDiff = (tweetTimestamp - initTimestamp)/1000; 128 | 129 | var binnedTweets = this.state.binnedTweets; 130 | var newBinnedTweets = binnedTweets; 131 | 132 | var binIndex = binnedTweets.length - 1; 133 | var currentBin = binnedTweets[binIndex].timeBin; 134 | 135 | if(timeDiff < currentBin) { 136 | newBinnedTweets[binIndex].numTweets++; 137 | 138 | if(sentiment == "positive") { 139 | newBinnedTweets[binIndex].posTweets++; 140 | this.setState({ binnedTweets: newBinnedTweets }); 141 | 142 | } else if(sentiment == "negative") { 143 | newBinnedTweets[binIndex].negTweets++; 144 | this.setState({ binnedTweets: newBinnedTweets }); 145 | } else { 146 | newBinnedTweets[binIndex].neutTweets++; 147 | this.setState({ binnedTweets: newBinnedTweets }); 148 | } 149 | 150 | } else { 151 | 152 | if(sentiment == "positive") { 153 | newBinnedTweets.push({ numTweets: 1, posTweets: 1, negTweets: 0, neutTweets: 0, timeBin: currentBin+=5 }); 154 | this.setState({ binnedTweets: newBinnedTweets }); 155 | 156 | } else if(sentiment == "negative") { 157 | newBinnedTweets.push({ numTweets: 1, posTweets: 0, negTweets: 1, neutTweets: 0, timeBin: currentBin+=5 }); 158 | this.setState({ binnedTweets: newBinnedTweets }); 159 | } else { 160 | newBinnedTweets.push({ numTweets: 1, posTweets: 0, negTweets: 0, neutTweets: 1, timeBin: currentBin+=5 }); 161 | this.setState({ binnedTweets: newBinnedTweets }); 162 | } 163 | } 164 | } 165 | 166 | //Render the App! 167 | render() { 168 | return ( 169 |
170 | 171 | 172 | { this.state.search ? 173 | : null } 179 | 180 | 181 |
182 | ); 183 | } 184 | } 185 | // var App = React.createClass({ 186 | 187 | 188 | // }); 189 | 190 | module.exports = App; 191 | 192 | -------------------------------------------------------------------------------- /app/public/css/default.css.map: -------------------------------------------------------------------------------- 1 | { 2 | "version": 3, 3 | "mappings": "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", 4 | "sources": ["default.scss"], 5 | "names": [], 6 | "file": "default.css" 7 | } 8 | -------------------------------------------------------------------------------- /app/public/img/Twitterment_files/css: -------------------------------------------------------------------------------- 1 | /* cyrillic-ext */ 2 | @font-face { 3 | font-family: 'Open Sans'; 4 | font-style: normal; 5 | font-weight: 300; 6 | src: local('Open Sans Light'), local('OpenSans-Light'), url(https://fonts.gstatic.com/s/opensans/v13/DXI1ORHCpsQm3Vp6mXoaTQ7aC6SjiAOpAWOKfJDfVRY.woff2) format('woff2'); 7 | unicode-range: U+0460-052F, U+20B4, U+2DE0-2DFF, U+A640-A69F; 8 | } 9 | /* cyrillic */ 10 | @font-face { 11 | font-family: 'Open Sans'; 12 | font-style: normal; 13 | font-weight: 300; 14 | src: local('Open Sans Light'), local('OpenSans-Light'), url(https://fonts.gstatic.com/s/opensans/v13/DXI1ORHCpsQm3Vp6mXoaTRdwxCXfZpKo5kWAx_74bHs.woff2) format('woff2'); 15 | unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; 16 | } 17 | /* greek-ext */ 18 | @font-face { 19 | font-family: 'Open Sans'; 20 | font-style: normal; 21 | font-weight: 300; 22 | src: local('Open Sans Light'), local('OpenSans-Light'), url(https://fonts.gstatic.com/s/opensans/v13/DXI1ORHCpsQm3Vp6mXoaTZ6vnaPZw6nYDxM4SVEMFKg.woff2) format('woff2'); 23 | unicode-range: U+1F00-1FFF; 24 | } 25 | /* greek */ 26 | @font-face { 27 | font-family: 'Open Sans'; 28 | font-style: normal; 29 | font-weight: 300; 30 | src: local('Open Sans Light'), local('OpenSans-Light'), url(https://fonts.gstatic.com/s/opensans/v13/DXI1ORHCpsQm3Vp6mXoaTfy1_HTwRwgtl1cPga3Fy3Y.woff2) format('woff2'); 31 | unicode-range: U+0370-03FF; 32 | } 33 | /* vietnamese */ 34 | @font-face { 35 | font-family: 'Open Sans'; 36 | font-style: normal; 37 | font-weight: 300; 38 | src: local('Open Sans Light'), local('OpenSans-Light'), url(https://fonts.gstatic.com/s/opensans/v13/DXI1ORHCpsQm3Vp6mXoaTfgrLsWo7Jk1KvZser0olKY.woff2) format('woff2'); 39 | unicode-range: U+0102-0103, U+1EA0-1EF1, U+20AB; 40 | } 41 | /* latin-ext */ 42 | @font-face { 43 | font-family: 'Open Sans'; 44 | font-style: normal; 45 | font-weight: 300; 46 | src: local('Open Sans Light'), local('OpenSans-Light'), url(https://fonts.gstatic.com/s/opensans/v13/DXI1ORHCpsQm3Vp6mXoaTYjoYw3YTyktCCer_ilOlhE.woff2) format('woff2'); 47 | unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF; 48 | } 49 | /* latin */ 50 | @font-face { 51 | font-family: 'Open Sans'; 52 | font-style: normal; 53 | font-weight: 300; 54 | src: local('Open Sans Light'), local('OpenSans-Light'), url(https://fonts.gstatic.com/s/opensans/v13/DXI1ORHCpsQm3Vp6mXoaTRampu5_7CjHW5spxoeN3Vs.woff2) format('woff2'); 55 | unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000; 56 | } 57 | /* cyrillic-ext */ 58 | @font-face { 59 | font-family: 'Open Sans'; 60 | font-style: normal; 61 | font-weight: 400; 62 | src: local('Open Sans'), local('OpenSans'), url(https://fonts.gstatic.com/s/opensans/v13/K88pR3goAWT7BTt32Z01m4X0hVgzZQUfRDuZrPvH3D8.woff2) format('woff2'); 63 | unicode-range: U+0460-052F, U+20B4, U+2DE0-2DFF, U+A640-A69F; 64 | } 65 | /* cyrillic */ 66 | @font-face { 67 | font-family: 'Open Sans'; 68 | font-style: normal; 69 | font-weight: 400; 70 | src: local('Open Sans'), local('OpenSans'), url(https://fonts.gstatic.com/s/opensans/v13/RjgO7rYTmqiVp7vzi-Q5UYX0hVgzZQUfRDuZrPvH3D8.woff2) format('woff2'); 71 | unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; 72 | } 73 | /* greek-ext */ 74 | @font-face { 75 | font-family: 'Open Sans'; 76 | font-style: normal; 77 | font-weight: 400; 78 | src: local('Open Sans'), local('OpenSans'), url(https://fonts.gstatic.com/s/opensans/v13/LWCjsQkB6EMdfHrEVqA1KYX0hVgzZQUfRDuZrPvH3D8.woff2) format('woff2'); 79 | unicode-range: U+1F00-1FFF; 80 | } 81 | /* greek */ 82 | @font-face { 83 | font-family: 'Open Sans'; 84 | font-style: normal; 85 | font-weight: 400; 86 | src: local('Open Sans'), local('OpenSans'), url(https://fonts.gstatic.com/s/opensans/v13/xozscpT2726on7jbcb_pAoX0hVgzZQUfRDuZrPvH3D8.woff2) format('woff2'); 87 | unicode-range: U+0370-03FF; 88 | } 89 | /* vietnamese */ 90 | @font-face { 91 | font-family: 'Open Sans'; 92 | font-style: normal; 93 | font-weight: 400; 94 | src: local('Open Sans'), local('OpenSans'), url(https://fonts.gstatic.com/s/opensans/v13/59ZRklaO5bWGqF5A9baEEYX0hVgzZQUfRDuZrPvH3D8.woff2) format('woff2'); 95 | unicode-range: U+0102-0103, U+1EA0-1EF1, U+20AB; 96 | } 97 | /* latin-ext */ 98 | @font-face { 99 | font-family: 'Open Sans'; 100 | font-style: normal; 101 | font-weight: 400; 102 | src: local('Open Sans'), local('OpenSans'), url(https://fonts.gstatic.com/s/opensans/v13/u-WUoqrET9fUeobQW7jkRYX0hVgzZQUfRDuZrPvH3D8.woff2) format('woff2'); 103 | unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF; 104 | } 105 | /* latin */ 106 | @font-face { 107 | font-family: 'Open Sans'; 108 | font-style: normal; 109 | font-weight: 400; 110 | src: local('Open Sans'), local('OpenSans'), url(https://fonts.gstatic.com/s/opensans/v13/cJZKeOuBrn4kERxqtaUH3ZBw1xU1rKptJj_0jans920.woff2) format('woff2'); 111 | unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000; 112 | } 113 | /* cyrillic-ext */ 114 | @font-face { 115 | font-family: 'Open Sans'; 116 | font-style: normal; 117 | font-weight: 600; 118 | src: local('Open Sans Semibold'), local('OpenSans-Semibold'), url(https://fonts.gstatic.com/s/opensans/v13/MTP_ySUJH_bn48VBG8sNSg7aC6SjiAOpAWOKfJDfVRY.woff2) format('woff2'); 119 | unicode-range: U+0460-052F, U+20B4, U+2DE0-2DFF, U+A640-A69F; 120 | } 121 | /* cyrillic */ 122 | @font-face { 123 | font-family: 'Open Sans'; 124 | font-style: normal; 125 | font-weight: 600; 126 | src: local('Open Sans Semibold'), local('OpenSans-Semibold'), url(https://fonts.gstatic.com/s/opensans/v13/MTP_ySUJH_bn48VBG8sNShdwxCXfZpKo5kWAx_74bHs.woff2) format('woff2'); 127 | unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; 128 | } 129 | /* greek-ext */ 130 | @font-face { 131 | font-family: 'Open Sans'; 132 | font-style: normal; 133 | font-weight: 600; 134 | src: local('Open Sans Semibold'), local('OpenSans-Semibold'), url(https://fonts.gstatic.com/s/opensans/v13/MTP_ySUJH_bn48VBG8sNSp6vnaPZw6nYDxM4SVEMFKg.woff2) format('woff2'); 135 | unicode-range: U+1F00-1FFF; 136 | } 137 | /* greek */ 138 | @font-face { 139 | font-family: 'Open Sans'; 140 | font-style: normal; 141 | font-weight: 600; 142 | src: local('Open Sans Semibold'), local('OpenSans-Semibold'), url(https://fonts.gstatic.com/s/opensans/v13/MTP_ySUJH_bn48VBG8sNSvy1_HTwRwgtl1cPga3Fy3Y.woff2) format('woff2'); 143 | unicode-range: U+0370-03FF; 144 | } 145 | /* vietnamese */ 146 | @font-face { 147 | font-family: 'Open Sans'; 148 | font-style: normal; 149 | font-weight: 600; 150 | src: local('Open Sans Semibold'), local('OpenSans-Semibold'), url(https://fonts.gstatic.com/s/opensans/v13/MTP_ySUJH_bn48VBG8sNSvgrLsWo7Jk1KvZser0olKY.woff2) format('woff2'); 151 | unicode-range: U+0102-0103, U+1EA0-1EF1, U+20AB; 152 | } 153 | /* latin-ext */ 154 | @font-face { 155 | font-family: 'Open Sans'; 156 | font-style: normal; 157 | font-weight: 600; 158 | src: local('Open Sans Semibold'), local('OpenSans-Semibold'), url(https://fonts.gstatic.com/s/opensans/v13/MTP_ySUJH_bn48VBG8sNSojoYw3YTyktCCer_ilOlhE.woff2) format('woff2'); 159 | unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF; 160 | } 161 | /* latin */ 162 | @font-face { 163 | font-family: 'Open Sans'; 164 | font-style: normal; 165 | font-weight: 600; 166 | src: local('Open Sans Semibold'), local('OpenSans-Semibold'), url(https://fonts.gstatic.com/s/opensans/v13/MTP_ySUJH_bn48VBG8sNShampu5_7CjHW5spxoeN3Vs.woff2) format('woff2'); 167 | unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000; 168 | } 169 | /* cyrillic-ext */ 170 | @font-face { 171 | font-family: 'Open Sans'; 172 | font-style: normal; 173 | font-weight: 700; 174 | src: local('Open Sans Bold'), local('OpenSans-Bold'), url(https://fonts.gstatic.com/s/opensans/v13/k3k702ZOKiLJc3WVjuplzA7aC6SjiAOpAWOKfJDfVRY.woff2) format('woff2'); 175 | unicode-range: U+0460-052F, U+20B4, U+2DE0-2DFF, U+A640-A69F; 176 | } 177 | /* cyrillic */ 178 | @font-face { 179 | font-family: 'Open Sans'; 180 | font-style: normal; 181 | font-weight: 700; 182 | src: local('Open Sans Bold'), local('OpenSans-Bold'), url(https://fonts.gstatic.com/s/opensans/v13/k3k702ZOKiLJc3WVjuplzBdwxCXfZpKo5kWAx_74bHs.woff2) format('woff2'); 183 | unicode-range: U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; 184 | } 185 | /* greek-ext */ 186 | @font-face { 187 | font-family: 'Open Sans'; 188 | font-style: normal; 189 | font-weight: 700; 190 | src: local('Open Sans Bold'), local('OpenSans-Bold'), url(https://fonts.gstatic.com/s/opensans/v13/k3k702ZOKiLJc3WVjuplzJ6vnaPZw6nYDxM4SVEMFKg.woff2) format('woff2'); 191 | unicode-range: U+1F00-1FFF; 192 | } 193 | /* greek */ 194 | @font-face { 195 | font-family: 'Open Sans'; 196 | font-style: normal; 197 | font-weight: 700; 198 | src: local('Open Sans Bold'), local('OpenSans-Bold'), url(https://fonts.gstatic.com/s/opensans/v13/k3k702ZOKiLJc3WVjuplzPy1_HTwRwgtl1cPga3Fy3Y.woff2) format('woff2'); 199 | unicode-range: U+0370-03FF; 200 | } 201 | /* vietnamese */ 202 | @font-face { 203 | font-family: 'Open Sans'; 204 | font-style: normal; 205 | font-weight: 700; 206 | src: local('Open Sans Bold'), local('OpenSans-Bold'), url(https://fonts.gstatic.com/s/opensans/v13/k3k702ZOKiLJc3WVjuplzPgrLsWo7Jk1KvZser0olKY.woff2) format('woff2'); 207 | unicode-range: U+0102-0103, U+1EA0-1EF1, U+20AB; 208 | } 209 | /* latin-ext */ 210 | @font-face { 211 | font-family: 'Open Sans'; 212 | font-style: normal; 213 | font-weight: 700; 214 | src: local('Open Sans Bold'), local('OpenSans-Bold'), url(https://fonts.gstatic.com/s/opensans/v13/k3k702ZOKiLJc3WVjuplzIjoYw3YTyktCCer_ilOlhE.woff2) format('woff2'); 215 | unicode-range: U+0100-024F, U+1E00-1EFF, U+20A0-20AB, U+20AD-20CF, U+2C60-2C7F, U+A720-A7FF; 216 | } 217 | /* latin */ 218 | @font-face { 219 | font-family: 'Open Sans'; 220 | font-style: normal; 221 | font-weight: 700; 222 | src: local('Open Sans Bold'), local('OpenSans-Bold'), url(https://fonts.gstatic.com/s/opensans/v13/k3k702ZOKiLJc3WVjuplzBampu5_7CjHW5spxoeN3Vs.woff2) format('woff2'); 223 | unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2212, U+2215, U+E0FF, U+EFFD, U+F000; 224 | } 225 | -------------------------------------------------------------------------------- /app/public/img/Twitterment.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Twitterment 11 | 12 | 13 |
14 |
15 | 23 |
24 |
25 | 26 |

Track your Brand Sentiment on Twitter

What are people saying about your brand?

Twitterment was built with these technologies:

Twitter Stream

27 | 28 |
29 |
30 |
31 |
32 |

True Real Time Tracking

33 |

See how your brand sentiment is trending at this moment.

34 |
35 |
36 |
37 |
38 |

39 |
40 | Real Time with Socket.io 41 |

42 |

43 | Twitterment's server is built with NodeJS and Socket.io to provide real-time tracking. When new Tweets are received, Socket.io immediately sends the new data to your dashboard. 44 |

45 |
46 |
47 |
48 |
49 |

50 |
51 | Twitter Streaming API 52 |

53 |

54 | Track specific keywords from Twitter's streaming API. Know exactly what's happening on Twitter, at this instant. Never miss a beat. 55 |

56 |
57 |
58 |
59 |
60 |

61 |
62 | Data Driven Documents: D3 63 |

64 |

65 | Twitterment uses D3 to provide real-time graphical updates of how your brand is trending on Twitter for each new data point. 66 |

67 |
68 |
69 |
70 |
71 |
72 |
73 | 74 |
75 |
76 |
77 |
78 |

Connect with the author:

79 | 80 | 81 |
82 |
83 |

Twitterment © 2015

84 |
85 |
86 |
87 |
88 | 89 | 90 | 91 |
Window size: 1440 x 859
Viewport size: 1440 x 743
-------------------------------------------------------------------------------- /app/public/css/default.scss: -------------------------------------------------------------------------------- 1 | /* Reusable Styles 2 | ======================== */ 3 | $primary-black: #1a1a1a; 4 | $primary-green: #2bb656; 5 | $primary-blue: #1d67a7; 6 | $twitter-blue: #59BBFF; 7 | 8 | $background-dark-gray: #1a252f; 9 | $background-header-gray: #b3b3b3; 10 | $background-chart-gray: #f7f7f7; 11 | $background-light-gray: #d5d5d5; 12 | 13 | $text-black: #4d4d4d; 14 | $text-dark-gray: #666; 15 | $text-gray: #999; 16 | $CTA-green: #59cb59; 17 | $CTA-hover-green: #218d43; 18 | 19 | $total: blue; 20 | $positive: green; 21 | $neutral: sandybrown; 22 | $negative: red; 23 | 24 | $font-family: 'Open Sans', sans-serif; 25 | 26 | html, 27 | body { 28 | position: relative; 29 | font-family: $font-family; 30 | color: $text-gray; 31 | background-color: #F5F7F9; 32 | font-size: 16px; 33 | overflow-x: hidden; 34 | } 35 | 36 | .intro-text { 37 | margin-top: 20px; 38 | margin-bottom: 40px; 39 | text-align: center; 40 | color: $text-black; 41 | 42 | h2 { 43 | font-size: 35px; 44 | font-weight: 700; 45 | } 46 | 47 | p { 48 | font-weight: 400; 49 | font-size: 16px; 50 | } 51 | } 52 | 53 | 54 | /* Header and Nav Styles 55 | ======================== */ 56 | 57 | header { 58 | position: absolute; 59 | top: 0; 60 | left: 0; 61 | z-index: 100; 62 | width: 100%; 63 | 64 | nav { 65 | height: 60px; 66 | background-color: $primary-black; 67 | box-shadow: 2px 2px 2px 2px rgba(0,0,0, 0.3); 68 | 69 | ul { 70 | width: 80% !important; 71 | margin-right: auto; 72 | margin-left: auto; 73 | list-style: none; 74 | padding: 0; 75 | width: 100%; 76 | 77 | li { 78 | display: inline-block; 79 | padding-top: 22px; 80 | margin-right: 40px; 81 | 82 | a { 83 | padding: 10px 0; 84 | text-decoration: none !important; 85 | text-transform: uppercase; 86 | font-size: 15px; 87 | color: $text-gray; 88 | transition: all 0.25s ease-in-out; 89 | 90 | &:hover, 91 | &:active, 92 | &:focus { 93 | color: $primary-green; 94 | outline: none; 95 | } 96 | 97 | &:after { 98 | content: ""; 99 | padding-bottom: 7px; 100 | display: block; 101 | border-bottom: 2px solid $primary-green; 102 | width: 0; 103 | transition: all 0.25s ease-in-out; 104 | pointer-events: none; 105 | } 106 | 107 | &:hover:after { 108 | width: 100%; 109 | } 110 | } 111 | } 112 | 113 | #nav-logo { 114 | height: 25px; 115 | width: auto; 116 | margin-right: 5px; 117 | margin-bottom: 2px; 118 | } 119 | 120 | #home-nav { 121 | a { 122 | color: $twitter-blue; 123 | font-weight: 600; 124 | font-size: 17px; 125 | } 126 | } 127 | } 128 | } 129 | } 130 | 131 | /* Hero and Search Bar Styles 132 | ======================== */ 133 | .hero { 134 | height: 700px; 135 | background-image: linear-gradient(rgba(0,0,0, 0.4), rgba(0,0,0, 0.8)), url(../img/hero.jpg); 136 | background-size: cover; 137 | background-repeat: no-repeat; 138 | background-position: bottom; 139 | position: relative; 140 | 141 | .content { 142 | position: absolute; 143 | display: flex; 144 | flex-direction: column; 145 | justify-content: center; 146 | height: 800px; 147 | 148 | h1, 149 | h2 { 150 | color: white; 151 | text-align: center; 152 | } 153 | 154 | h1 { 155 | order: 3; 156 | font-size: 20px; 157 | font-weight: 300; 158 | letter-spacing: 1px; 159 | color: #cfcfcf; 160 | } 161 | 162 | h2 { 163 | order: 2; 164 | font-size: 40px; 165 | font-weight: 700; 166 | 167 | @media(max-width: 640px) { 168 | font-size: 30px; 169 | } 170 | } 171 | 172 | .text-logo { 173 | 174 | img { 175 | height: 60px; 176 | width: auto; 177 | margin-right: 10px; 178 | margin-bottom: 15px; 179 | } 180 | 181 | order: 1; 182 | font-weight: 600; 183 | font-size: 40px; 184 | color: $twitter-blue; 185 | } 186 | 187 | 188 | #search-bar { 189 | order: 4; 190 | width: 350px; 191 | margin-top: 40px; 192 | margin-right: auto; 193 | margin-left: auto; 194 | 195 | input:focus { 196 | border: 1px solid $CTA-hover-green; 197 | box-shadow: 0 0 4px $CTA-hover-green; 198 | } 199 | 200 | .btn-default { 201 | background-color: $primary-green; 202 | border-color: $primary-green; 203 | font-family: $font-family; 204 | font-weight: 300; 205 | color: white; 206 | text-transform: uppercase; 207 | transition: all 0.25s ease-in-out; 208 | 209 | &:hover { 210 | background-color: $CTA-hover-green; 211 | border-color: $CTA-hover-green; 212 | } 213 | } 214 | } 215 | } 216 | } 217 | 218 | /* Technology Stack Section Styles 219 | ======================== */ 220 | .technology-stack { 221 | padding-bottom: 20px; 222 | background-color: $background-dark-gray; 223 | background-image: url('/img/tech-background.png'); 224 | background-size: 80%; 225 | font-weight: 300; 226 | font-size: 19px; 227 | text-align: center; 228 | 229 | .technologies-container { 230 | padding-top: 20px; 231 | margin-bottom: 20px; 232 | align-items: center; 233 | 234 | .heading { 235 | color: $text-gray; 236 | margin-bottom: 30px; 237 | } 238 | 239 | .nodejs { 240 | .nodejs-logo { 241 | height: 120px; 242 | width: 200px; 243 | margin-right: auto; 244 | margin-left: auto; 245 | background-image: url("../img/logo/nodejs-gray.png"); 246 | background-repeat: no-repeat; 247 | background-position: center; 248 | background-size: 100%; 249 | transition: all 0.2s ease-in-out; 250 | 251 | &:hover { 252 | background-image: url("../img/logo/nodejs.png"); 253 | } 254 | } 255 | } 256 | 257 | .socketio { 258 | .socketio-logo { 259 | height: 120px; 260 | width: 200px; 261 | margin-right: auto; 262 | margin-left: auto; 263 | background-image: url("../img/logo/socketio-gray.png"); 264 | background-repeat: no-repeat; 265 | background-position: center; 266 | background-size: 100%; 267 | transition: all 0.2s ease-in-out; 268 | 269 | &:hover { 270 | background-image: url("../img/logo/socketio.png"); 271 | } 272 | } 273 | } 274 | 275 | .react { 276 | .react-logo { 277 | height: 120px; 278 | width: 200px; 279 | margin-right: auto; 280 | margin-left: auto; 281 | background-image: url("../img/logo/react-gray.png"); 282 | background-repeat: no-repeat; 283 | background-position: center; 284 | background-size: 100%; 285 | transition: all 0.2s ease-in-out; 286 | 287 | &:hover { 288 | background-image: url("../img/logo/react.png"); 289 | } 290 | } 291 | } 292 | 293 | .d3 { 294 | padding-bottom: 10px; 295 | .d3-logo { 296 | height: 80px; 297 | width: 80px; 298 | margin-right: auto; 299 | margin-left: auto; 300 | background-image: url("../img/logo/d3-gray.png"); 301 | background-repeat: no-repeat; 302 | background-position: center; 303 | background-size: 100%; 304 | transition: all 0.2s ease-in-out; 305 | 306 | &:hover { 307 | background-image: url("../img/logo/d3.png"); 308 | } 309 | } 310 | } 311 | 312 | .twitter { 313 | .twitter-logo { 314 | height: 120px; 315 | width: 250px; 316 | margin-right: auto; 317 | margin-left: auto; 318 | background-image: url("../img/logo/twitter-gray.png"); 319 | background-repeat: no-repeat; 320 | background-position: center; 321 | background-size: 100%; 322 | transition: all 0.2s ease-in-out; 323 | 324 | &:hover { 325 | background-image: url("../img/logo/twitter.png"); 326 | } 327 | } 328 | } 329 | 330 | .heroku { 331 | .heroku-logo { 332 | height: 120px; 333 | width: 250px; 334 | margin-right: auto; 335 | margin-left: auto; 336 | background-image: url("../img/logo/heroku-gray.png"); 337 | background-repeat: no-repeat; 338 | background-position: center; 339 | background-size: 100%; 340 | transition: all 0.2s ease-in-out; 341 | 342 | &:hover { 343 | background-image: url("../img/logo/heroku.png"); 344 | } 345 | } 346 | } 347 | 348 | } 349 | } 350 | 351 | /* About Section Styles 352 | ======================== */ 353 | #about { 354 | padding-top: 30px; 355 | 356 | .title { 357 | text-align: center; 358 | 359 | h3 { 360 | font-weight: 600; 361 | font-size: 32px; 362 | color: $primary-green; 363 | } 364 | p { 365 | color: $text-dark-gray; 366 | } 367 | } 368 | 369 | .features { 370 | margin-top: 20px; 371 | padding-bottom: 50px; 372 | 373 | .tile { 374 | min-height: 320px; 375 | padding: 0 10px 20px; 376 | border-radius: 10px; 377 | border: 1px solid $background-light-gray; 378 | box-shadow: 0 4px 8px rgba(166, 166, 166, 0.3); 379 | background-color: white; 380 | 381 | @media(max-width: 992px) { 382 | min-height: 200px; 383 | margin-top: 5px; 384 | } 385 | 386 | h3 { 387 | color: $text-black; 388 | text-align: center; 389 | margin-bottom: 30px; 390 | 391 | .circle { 392 | width: 75px; 393 | height: 75px; 394 | margin: 0 auto 30px auto; 395 | display: block; 396 | border: 3px solid rgba(0, 0, 0, 0.13); 397 | border-radius: 50%; 398 | 399 | .fa { 400 | color: $primary-green; 401 | margin-top: 15px; 402 | font-size: 40px; 403 | } 404 | } 405 | } 406 | 407 | p { 408 | color: $text-dark-gray; 409 | text-align: center; 410 | font-size: 16px; 411 | } 412 | } 413 | } 414 | } 415 | 416 | 417 | /* Results Section Styles 418 | ======================== */ 419 | .results { 420 | height: 700px; 421 | 422 | .dashboard { 423 | height: 700px; 424 | overflow-y: hidden; 425 | background-color: $background-dark-gray; 426 | 427 | h1 { 428 | color: $text-black; 429 | text-align: center; 430 | font-size: 32px; 431 | margin-bottom: 30px; 432 | } 433 | 434 | /* Activity Chart Styles 435 | ======================== */ 436 | .twitter-activity { 437 | width: 800px; 438 | margin-right: auto; 439 | margin-left: auto; 440 | display: block; 441 | 442 | h4 { 443 | margin-top: 20px; 444 | margin-bottom: 0; 445 | padding: 15px 5px 10px; 446 | color: $text-black; 447 | border-radius: 5px 5px 0 0; 448 | font-size: 20px; 449 | text-align: center; 450 | background-color: $background-header-gray; 451 | } 452 | 453 | .line-chart { 454 | background-color: $background-chart-gray; 455 | display: block; 456 | margin: auto; 457 | box-shadow: 0 0 1px 1px rgba(0,0,0, 0.2); 458 | 459 | .gridline path, 460 | .gridline line { 461 | fill: none; 462 | stroke: #ccc; 463 | shape-rendering: crispEdges; 464 | } 465 | 466 | .axis path, 467 | .axis line { 468 | fill: none; 469 | stroke: $background-dark-gray; 470 | shape-rendering: crispEdges; 471 | } 472 | 473 | .axis text { 474 | font-family: $font-family; 475 | font-size: 14px; 476 | } 477 | 478 | .axis text.x-label, 479 | .axis text.y-label { 480 | font-family: $font-family; 481 | fill: $text-gray; 482 | } 483 | } 484 | 485 | .tweet-counters { 486 | display: flex; 487 | border-top: 1px solid $background-dark-gray; 488 | 489 | .total { 490 | width: 100%; 491 | position: relative; 492 | 493 | h3 { 494 | margin: 0; 495 | padding: 10px 0; 496 | color: $text-black; 497 | font-size: 14px; 498 | text-align: center; 499 | background-color: $background-light-gray; 500 | } 501 | 502 | .total-tweets { 503 | height: 5px; 504 | background-color: $total; 505 | } 506 | 507 | .total-positive { 508 | height: 5px; 509 | background-color: $positive; 510 | } 511 | 512 | .total-neutral { 513 | height: 5px; 514 | background-color: $neutral; 515 | } 516 | 517 | .total-negative { 518 | height: 5px; 519 | background-color: $negative; 520 | } 521 | 522 | .counter { 523 | padding: 5px 0; 524 | color: #737373; 525 | font-size: 28px; 526 | font-weight: 600; 527 | text-align: center; 528 | background-color: white; 529 | transition: all 0.2s ease-in-out; 530 | 531 | &.positive { 532 | color: $positive; 533 | } 534 | 535 | 536 | &.neutral { 537 | color: $neutral; 538 | } 539 | 540 | &.negative { 541 | color: $negative; 542 | } 543 | } 544 | 545 | .total-tweets + .counter { 546 | border-radius: 0 0 0 5px; 547 | } 548 | 549 | .total-negative + .counter { 550 | border-radius: 0 0 5px 0; 551 | } 552 | 553 | .arrow { 554 | position: absolute; 555 | bottom: 20px; 556 | right: 15px; 557 | display: inline-block; 558 | width: 0; 559 | height: 0; 560 | border-left: 10px solid transparent; 561 | border-right: 10px solid transparent; 562 | transition: all 0.2s ease-in-out; 563 | 564 | &.positive { 565 | border-bottom: 10px solid $positive; 566 | } 567 | 568 | &.neutral, 569 | &.null { 570 | border-bottom: 10px solid $neutral; 571 | } 572 | 573 | &.negative { 574 | border-bottom: 10px solid $negative; 575 | } 576 | } 577 | } 578 | } 579 | 580 | .overall-sentiment { 581 | margin-top: 30px; 582 | display: inline-block; 583 | background-color: $background-chart-gray; 584 | border-radius: 5px 5px 5px 5px; 585 | 586 | h3 { 587 | display: inline-block; 588 | padding: 10px 0 10px 10px; 589 | margin: 0; 590 | width: 220px; 591 | color: $text-black; 592 | font-size: 24px; 593 | border-right: 1px solid $background-dark-gray; 594 | border-radius: 5px 0 0 5px; 595 | background-color: $background-light-gray; 596 | } 597 | 598 | p { 599 | display: inline-block; 600 | margin-bottom: 0; 601 | padding: 0 10px; 602 | font-size: 24px; 603 | color: $text-dark-gray; 604 | 605 | &.positive { 606 | color: $positive; 607 | } 608 | 609 | &.negative { 610 | color: $negative; 611 | } 612 | } 613 | } 614 | } 615 | } 616 | 617 | /* Twitter Stream Styles 618 | ======================== */ 619 | .stream { 620 | height: 700px; 621 | background-color: $background-dark-gray; 622 | padding: 0 25px 0 15px; 623 | 624 | h1 { 625 | margin-bottom: 0; 626 | padding: 15px 5px 10px; 627 | color: $text-black; 628 | border-radius: 5px 5px 0 0; 629 | font-size: 20px; 630 | text-align: center; 631 | background-color: $background-header-gray; 632 | } 633 | 634 | .tweet-list { 635 | height: 600px; 636 | background-color: $background-chart-gray; 637 | padding-bottom: 20px; 638 | overflow-y: scroll; 639 | overflow-x: hidden; 640 | box-shadow: 0 0 1px 1px rgba(0,0,0, 0.2); 641 | 642 | .tweet-card { 643 | padding: 10px 0px 10px 15px; 644 | margin: 5px 10px 5px 10px; 645 | border-bottom: 1px solid #ccc; 646 | background-color: white; 647 | box-shadow: 0 0 1px 1px rgba(0,0,0, 0.2); 648 | 649 | .profile-image { 650 | display: inline-block; 651 | vertical-align: top; 652 | margin-right: 10px; 653 | height: 50px; 654 | width: 50px; 655 | border-radius: 5px; 656 | } 657 | 658 | .content { 659 | display: inline-block; 660 | width: 80%; 661 | position: relative; 662 | 663 | .user { 664 | display: inline-block; 665 | width: 90%; 666 | 667 | .name { 668 | font-size: 14px; 669 | color: $text-black; 670 | font-weight: 700; 671 | margin-right: 10px; 672 | } 673 | 674 | .username { 675 | font-size: 14px; 676 | } 677 | } 678 | 679 | .sentiment { 680 | position: absolute; 681 | top: 5px; 682 | right: 0; 683 | display: inline-block; 684 | 685 | &.positive { 686 | width: 0; 687 | height: 0; 688 | border-left: 10px solid transparent; 689 | border-right: 10px solid transparent; 690 | border-bottom: 10px solid $positive; 691 | } 692 | 693 | &.neutral, 694 | &.null { 695 | height: 10px; 696 | width: 10px; 697 | margin-right: 5px; 698 | border-radius: 50%; 699 | background-color: $neutral; 700 | 701 | } 702 | 703 | &.negative { 704 | width: 0; 705 | height: 0; 706 | border-left: 10px solid transparent; 707 | border-right: 10px solid transparent; 708 | border-top: 10px solid $negative; 709 | } 710 | } 711 | 712 | .text { 713 | font-size: 12px; 714 | } 715 | } 716 | } 717 | } 718 | } 719 | } 720 | 721 | /* Footer Styles 722 | ======================== */ 723 | 724 | footer { 725 | height: 80px; 726 | background-color: $primary-black; 727 | 728 | .baseline-container { 729 | position: relative; 730 | 731 | .connect-container { 732 | position: absolute; 733 | right: 40px; 734 | bottom: 0; 735 | margin-right: 20px; 736 | display: flex; 737 | align-items: center; 738 | justify-content: center; 739 | z-index: 50; 740 | 741 | p { 742 | margin-top: 10px; 743 | margin-right: 20px; 744 | font-size: 14px; 745 | font-weight: 300; 746 | color: $text-gray; 747 | } 748 | 749 | .github-logo { 750 | height: 30px; 751 | width: 30px; 752 | margin-right: 10px; 753 | background-image: url("../img/logo/github-gray.png"); 754 | background-repeat: no-repeat; 755 | background-position: center; 756 | background-size: 100%; 757 | transition: all 0.2s ease-in-out; 758 | 759 | &:hover { 760 | background-image: url("../img/logo/github.png"); 761 | } 762 | } 763 | 764 | .linkedin-logo { 765 | height: 25px; 766 | width: 25px; 767 | margin-top: 5px; 768 | margin-left: 10px; 769 | background-image: url("../img/logo/linkedin-gray.png"); 770 | background-repeat: no-repeat; 771 | background-position: center; 772 | background-size: 100%; 773 | transition: all 0.2s ease-in-out; 774 | 775 | &:hover { 776 | background-image: url("../img/logo/linkedin.png"); 777 | } 778 | } 779 | 780 | @media(max-width: 930px) { 781 | position: relative; 782 | right: 0; 783 | margin-right: 0; 784 | } 785 | } 786 | 787 | .branding-container { 788 | margin-top: 30px; 789 | 790 | p { 791 | color: $text-black; 792 | font-size: 16px; 793 | } 794 | } 795 | } 796 | } 797 | 798 | 799 | 800 | 801 | 802 | 803 | 804 | 805 | 806 | 807 | 808 | 809 | 810 | 811 | 812 | 813 | 814 | 815 | 816 | 817 | 818 | 819 | 820 | 821 | 822 | 823 | 824 | 825 | 826 | -------------------------------------------------------------------------------- /app/public/img/Twitterment_files/default.css: -------------------------------------------------------------------------------- 1 | /* Reusable Styles 2 | ======================== */ 3 | /* line 26, default.scss */ 4 | html, 5 | body { 6 | position: relative; 7 | font-family: "Open Sans", sans-serif; 8 | color: #999; 9 | background-color: #F5F7F9; 10 | font-size: 16px; 11 | overflow-x: hidden; 12 | } 13 | 14 | /* line 36, default.scss */ 15 | .intro-text { 16 | margin-top: 20px; 17 | margin-bottom: 40px; 18 | text-align: center; 19 | color: #4d4d4d; 20 | } 21 | /* line 42, default.scss */ 22 | .intro-text h2 { 23 | font-size: 35px; 24 | font-weight: 700; 25 | } 26 | /* line 47, default.scss */ 27 | .intro-text p { 28 | font-weight: 400; 29 | font-size: 16px; 30 | } 31 | 32 | /* Header and Nav Styles 33 | ======================== */ 34 | /* line 57, default.scss */ 35 | header { 36 | position: absolute; 37 | top: 0; 38 | left: 0; 39 | z-index: 100; 40 | width: 100%; 41 | } 42 | /* line 64, default.scss */ 43 | header nav { 44 | height: 60px; 45 | background-color: #1a1a1a; 46 | box-shadow: 2px 2px 2px 2px rgba(0, 0, 0, 0.3); 47 | } 48 | /* line 69, default.scss */ 49 | header nav ul { 50 | width: 80% !important; 51 | margin-right: auto; 52 | margin-left: auto; 53 | list-style: none; 54 | padding: 0; 55 | width: 100%; 56 | } 57 | /* line 77, default.scss */ 58 | header nav ul li { 59 | display: inline-block; 60 | padding-top: 22px; 61 | margin-right: 40px; 62 | } 63 | /* line 82, default.scss */ 64 | header nav ul li a { 65 | padding: 10px 0; 66 | text-decoration: none !important; 67 | text-transform: uppercase; 68 | font-size: 15px; 69 | color: #999; 70 | transition: all 0.25s ease-in-out; 71 | } 72 | /* line 90, default.scss */ 73 | header nav ul li a:hover, header nav ul li a:active, header nav ul li a:focus { 74 | color: #2bb656; 75 | outline: none; 76 | } 77 | /* line 97, default.scss */ 78 | header nav ul li a:after { 79 | content: ""; 80 | padding-bottom: 7px; 81 | display: block; 82 | border-bottom: 2px solid #2bb656; 83 | width: 0; 84 | transition: all 0.25s ease-in-out; 85 | pointer-events: none; 86 | } 87 | /* line 107, default.scss */ 88 | header nav ul li a:hover:after { 89 | width: 100%; 90 | } 91 | /* line 113, default.scss */ 92 | header nav ul #nav-logo { 93 | height: 25px; 94 | width: auto; 95 | margin-right: 5px; 96 | margin-bottom: 2px; 97 | } 98 | /* line 121, default.scss */ 99 | header nav ul #home-nav a { 100 | color: #59BBFF; 101 | font-weight: 600; 102 | font-size: 17px; 103 | } 104 | 105 | /* Hero and Search Bar Styles 106 | ======================== */ 107 | /* line 133, default.scss */ 108 | .hero { 109 | height: 700px; 110 | background-image: linear-gradient(rgba(0, 0, 0, 0.4), rgba(0, 0, 0, 0.8)), url(../img/hero.jpg); 111 | background-size: cover; 112 | background-repeat: no-repeat; 113 | background-position: bottom; 114 | position: relative; 115 | } 116 | /* line 141, default.scss */ 117 | .hero .content { 118 | position: absolute; 119 | display: flex; 120 | flex-direction: column; 121 | justify-content: center; 122 | height: 800px; 123 | } 124 | /* line 148, default.scss */ 125 | .hero .content h1, 126 | .hero .content h2 { 127 | color: white; 128 | text-align: center; 129 | } 130 | /* line 154, default.scss */ 131 | .hero .content h1 { 132 | order: 3; 133 | font-size: 20px; 134 | font-weight: 300; 135 | letter-spacing: 1px; 136 | color: #cfcfcf; 137 | } 138 | /* line 162, default.scss */ 139 | .hero .content h2 { 140 | order: 2; 141 | font-size: 40px; 142 | font-weight: 700; 143 | } 144 | /* line 168, default.scss */ 145 | .hero .content .text-logo { 146 | order: 1; 147 | font-weight: 600; 148 | font-size: 40px; 149 | color: #59BBFF; 150 | } 151 | /* line 170, default.scss */ 152 | .hero .content .text-logo img { 153 | height: 60px; 154 | width: auto; 155 | margin-right: 10px; 156 | margin-bottom: 15px; 157 | } 158 | /* line 184, default.scss */ 159 | .hero .content #search-bar { 160 | order: 4; 161 | width: 350px; 162 | margin-top: 40px; 163 | margin-right: auto; 164 | margin-left: auto; 165 | } 166 | /* line 191, default.scss */ 167 | .hero .content #search-bar input:focus { 168 | border: 1px solid #218d43; 169 | box-shadow: 0 0 4px #218d43; 170 | } 171 | /* line 196, default.scss */ 172 | .hero .content #search-bar .btn-default { 173 | background-color: #2bb656; 174 | border-color: #2bb656; 175 | font-family: "Open Sans", sans-serif; 176 | font-weight: 300; 177 | color: white; 178 | text-transform: uppercase; 179 | transition: all 0.25s ease-in-out; 180 | } 181 | /* line 205, default.scss */ 182 | .hero .content #search-bar .btn-default:hover { 183 | background-color: #218d43; 184 | border-color: #218d43; 185 | } 186 | 187 | /* Technology Stack Section Styles 188 | ======================== */ 189 | /* line 216, default.scss */ 190 | .technology-stack { 191 | height: 230px; 192 | padding-bottom: 20px; 193 | background-color: #1a252f; 194 | background-image: url("/img/tech-background.png"); 195 | background-size: 80%; 196 | font-weight: 300; 197 | font-size: 19px; 198 | text-align: center; 199 | } 200 | /* line 226, default.scss */ 201 | .technology-stack .technologies-container { 202 | padding-top: 20px; 203 | margin-bottom: 20px; 204 | display: flex; 205 | flex-direction: row; 206 | flex-wrap: wrap; 207 | align-items: center; 208 | justify-content: space-around; 209 | } 210 | /* line 235, default.scss */ 211 | .technology-stack .technologies-container .heading { 212 | flex: 100%; 213 | color: #999; 214 | margin-bottom: 30px; 215 | } 216 | /* line 242, default.scss */ 217 | .technology-stack .technologies-container .nodejs .nodejs-logo { 218 | height: 120px; 219 | width: 200px; 220 | background-image: url("../img/logo/nodejs-gray.png"); 221 | background-repeat: no-repeat; 222 | background-position: center; 223 | background-size: 100%; 224 | transition: all 0.2s ease-in-out; 225 | } 226 | /* line 251, default.scss */ 227 | .technology-stack .technologies-container .nodejs .nodejs-logo:hover { 228 | background-image: url("../img/logo/nodejs.png"); 229 | } 230 | /* line 258, default.scss */ 231 | .technology-stack .technologies-container .socketio .socketio-logo { 232 | height: 120px; 233 | width: 200px; 234 | background-image: url("../img/logo/socketio-gray.png"); 235 | background-repeat: no-repeat; 236 | background-position: center; 237 | background-size: 100%; 238 | transition: all 0.2s ease-in-out; 239 | } 240 | /* line 267, default.scss */ 241 | .technology-stack .technologies-container .socketio .socketio-logo:hover { 242 | background-image: url("../img/logo/socketio.png"); 243 | } 244 | /* line 274, default.scss */ 245 | .technology-stack .technologies-container .react .react-logo { 246 | height: 120px; 247 | width: 200px; 248 | background-image: url("../img/logo/react-gray.png"); 249 | background-repeat: no-repeat; 250 | background-position: center; 251 | background-size: 100%; 252 | transition: all 0.2s ease-in-out; 253 | } 254 | /* line 283, default.scss */ 255 | .technology-stack .technologies-container .react .react-logo:hover { 256 | background-image: url("../img/logo/react.png"); 257 | } 258 | /* line 289, default.scss */ 259 | .technology-stack .technologies-container .d3 { 260 | padding-bottom: 10px; 261 | } 262 | /* line 291, default.scss */ 263 | .technology-stack .technologies-container .d3 .d3-logo { 264 | height: 80px; 265 | width: 80px; 266 | background-image: url("../img/logo/d3-gray.png"); 267 | background-repeat: no-repeat; 268 | background-position: center; 269 | background-size: 100%; 270 | transition: all 0.2s ease-in-out; 271 | } 272 | /* line 300, default.scss */ 273 | .technology-stack .technologies-container .d3 .d3-logo:hover { 274 | background-image: url("../img/logo/d3.png"); 275 | } 276 | /* line 307, default.scss */ 277 | .technology-stack .technologies-container .twitter .twitter-logo { 278 | height: 120px; 279 | width: 250px; 280 | background-image: url("../img/logo/twitter-gray.png"); 281 | background-repeat: no-repeat; 282 | background-position: center; 283 | background-size: 100%; 284 | transition: all 0.2s ease-in-out; 285 | } 286 | /* line 316, default.scss */ 287 | .technology-stack .technologies-container .twitter .twitter-logo:hover { 288 | background-image: url("../img/logo/twitter.png"); 289 | } 290 | 291 | /* About Section Styles 292 | ======================== */ 293 | /* line 326, default.scss */ 294 | #about { 295 | padding-top: 30px; 296 | } 297 | /* line 329, default.scss */ 298 | #about .title { 299 | text-align: center; 300 | } 301 | /* line 332, default.scss */ 302 | #about .title h3 { 303 | font-weight: 600; 304 | font-size: 32px; 305 | color: #2bb656; 306 | } 307 | /* line 337, default.scss */ 308 | #about .title p { 309 | color: #666; 310 | } 311 | /* line 342, default.scss */ 312 | #about .features { 313 | margin-top: 20px; 314 | padding-bottom: 50px; 315 | } 316 | /* line 346, default.scss */ 317 | #about .features .tile { 318 | min-height: 320px; 319 | padding: 0 10px 20px; 320 | border-radius: 10px; 321 | border: 1px solid #d5d5d5; 322 | box-shadow: 0 4px 8px rgba(166, 166, 166, 0.3); 323 | background-color: white; 324 | } 325 | /* line 354, default.scss */ 326 | #about .features .tile h3 { 327 | color: #4d4d4d; 328 | text-align: center; 329 | margin-bottom: 30px; 330 | } 331 | /* line 359, default.scss */ 332 | #about .features .tile h3 .circle { 333 | width: 75px; 334 | height: 75px; 335 | margin: 0 auto 30px auto; 336 | display: block; 337 | border: 3px solid rgba(0, 0, 0, 0.13); 338 | border-radius: 50%; 339 | } 340 | /* line 367, default.scss */ 341 | #about .features .tile h3 .circle .fa { 342 | color: #2bb656; 343 | margin-top: 15px; 344 | font-size: 40px; 345 | } 346 | /* line 375, default.scss */ 347 | #about .features .tile p { 348 | color: #666; 349 | text-align: center; 350 | font-size: 16px; 351 | } 352 | 353 | /* Results Section Styles 354 | ======================== */ 355 | /* line 387, default.scss */ 356 | .results { 357 | height: 700px; 358 | /* Twitter Stream Styles 359 | ======================== */ 360 | } 361 | /* line 390, default.scss */ 362 | .results .dashboard { 363 | height: 700px; 364 | overflow-y: hidden; 365 | background-color: #1a252f; 366 | /* Activity Chart Styles 367 | ======================== */ 368 | } 369 | /* line 395, default.scss */ 370 | .results .dashboard h1 { 371 | color: #4d4d4d; 372 | text-align: center; 373 | font-size: 32px; 374 | margin-bottom: 30px; 375 | } 376 | /* line 404, default.scss */ 377 | .results .dashboard .twitter-activity { 378 | width: 800px; 379 | margin-right: auto; 380 | margin-left: auto; 381 | display: block; 382 | } 383 | /* line 410, default.scss */ 384 | .results .dashboard .twitter-activity h4 { 385 | margin-top: 20px; 386 | margin-bottom: 0; 387 | padding: 15px 5px 10px; 388 | color: #4d4d4d; 389 | border-radius: 5px 5px 0 0; 390 | font-size: 20px; 391 | text-align: center; 392 | background-color: #b3b3b3; 393 | } 394 | /* line 421, default.scss */ 395 | .results .dashboard .twitter-activity .line-chart { 396 | background-color: #f7f7f7; 397 | display: block; 398 | margin: auto; 399 | box-shadow: 0 0 1px 1px rgba(0, 0, 0, 0.2); 400 | } 401 | /* line 427, default.scss */ 402 | .results .dashboard .twitter-activity .line-chart .gridline path, 403 | .results .dashboard .twitter-activity .line-chart .gridline line { 404 | fill: none; 405 | stroke: #ccc; 406 | shape-rendering: crispEdges; 407 | } 408 | /* line 434, default.scss */ 409 | .results .dashboard .twitter-activity .line-chart .axis path, 410 | .results .dashboard .twitter-activity .line-chart .axis line { 411 | fill: none; 412 | stroke: #1a252f; 413 | shape-rendering: crispEdges; 414 | } 415 | /* line 441, default.scss */ 416 | .results .dashboard .twitter-activity .line-chart .axis text { 417 | font-family: "Open Sans", sans-serif; 418 | font-size: 14px; 419 | } 420 | /* line 446, default.scss */ 421 | .results .dashboard .twitter-activity .line-chart .axis text.x-label, 422 | .results .dashboard .twitter-activity .line-chart .axis text.y-label { 423 | font-family: "Open Sans", sans-serif; 424 | fill: #999; 425 | } 426 | /* line 453, default.scss */ 427 | .results .dashboard .twitter-activity .tweet-counters { 428 | display: flex; 429 | border-top: 1px solid #1a252f; 430 | } 431 | /* line 457, default.scss */ 432 | .results .dashboard .twitter-activity .tweet-counters .total { 433 | width: 100%; 434 | position: relative; 435 | } 436 | /* line 461, default.scss */ 437 | .results .dashboard .twitter-activity .tweet-counters .total h3 { 438 | margin: 0; 439 | padding: 10px 0; 440 | color: #4d4d4d; 441 | font-size: 14px; 442 | text-align: center; 443 | background-color: #d5d5d5; 444 | } 445 | /* line 470, default.scss */ 446 | .results .dashboard .twitter-activity .tweet-counters .total .total-tweets { 447 | height: 5px; 448 | background-color: blue; 449 | } 450 | /* line 475, default.scss */ 451 | .results .dashboard .twitter-activity .tweet-counters .total .total-positive { 452 | height: 5px; 453 | background-color: green; 454 | } 455 | /* line 480, default.scss */ 456 | .results .dashboard .twitter-activity .tweet-counters .total .total-neutral { 457 | height: 5px; 458 | background-color: sandybrown; 459 | } 460 | /* line 485, default.scss */ 461 | .results .dashboard .twitter-activity .tweet-counters .total .total-negative { 462 | height: 5px; 463 | background-color: red; 464 | } 465 | /* line 490, default.scss */ 466 | .results .dashboard .twitter-activity .tweet-counters .total .counter { 467 | padding: 5px 0; 468 | color: #737373; 469 | font-size: 28px; 470 | font-weight: 600; 471 | text-align: center; 472 | background-color: white; 473 | transition: all 0.2s ease-in-out; 474 | } 475 | /* line 499, default.scss */ 476 | .results .dashboard .twitter-activity .tweet-counters .total .counter.positive { 477 | color: green; 478 | } 479 | /* line 504, default.scss */ 480 | .results .dashboard .twitter-activity .tweet-counters .total .counter.neutral { 481 | color: sandybrown; 482 | } 483 | /* line 508, default.scss */ 484 | .results .dashboard .twitter-activity .tweet-counters .total .counter.negative { 485 | color: red; 486 | } 487 | /* line 513, default.scss */ 488 | .results .dashboard .twitter-activity .tweet-counters .total .total-tweets + .counter { 489 | border-radius: 0 0 0 5px; 490 | } 491 | /* line 517, default.scss */ 492 | .results .dashboard .twitter-activity .tweet-counters .total .total-negative + .counter { 493 | border-radius: 0 0 5px 0; 494 | } 495 | /* line 521, default.scss */ 496 | .results .dashboard .twitter-activity .tweet-counters .total .arrow { 497 | position: absolute; 498 | bottom: 20px; 499 | right: 15px; 500 | display: inline-block; 501 | width: 0; 502 | height: 0; 503 | border-left: 10px solid transparent; 504 | border-right: 10px solid transparent; 505 | transition: all 0.2s ease-in-out; 506 | } 507 | /* line 532, default.scss */ 508 | .results .dashboard .twitter-activity .tweet-counters .total .arrow.positive { 509 | border-bottom: 10px solid green; 510 | } 511 | /* line 536, default.scss */ 512 | .results .dashboard .twitter-activity .tweet-counters .total .arrow.neutral, .results .dashboard .twitter-activity .tweet-counters .total .arrow.null { 513 | border-bottom: 10px solid sandybrown; 514 | } 515 | /* line 541, default.scss */ 516 | .results .dashboard .twitter-activity .tweet-counters .total .arrow.negative { 517 | border-bottom: 10px solid red; 518 | } 519 | /* line 548, default.scss */ 520 | .results .dashboard .twitter-activity .overall-sentiment { 521 | margin-top: 30px; 522 | display: inline-block; 523 | background-color: #f7f7f7; 524 | border-radius: 5px 5px 5px 5px; 525 | } 526 | /* line 554, default.scss */ 527 | .results .dashboard .twitter-activity .overall-sentiment h3 { 528 | display: inline-block; 529 | padding: 10px 0 10px 10px; 530 | margin: 0; 531 | width: 220px; 532 | color: #4d4d4d; 533 | font-size: 24px; 534 | border-right: 1px solid #1a252f; 535 | border-radius: 5px 0 0 5px; 536 | background-color: #d5d5d5; 537 | } 538 | /* line 566, default.scss */ 539 | .results .dashboard .twitter-activity .overall-sentiment p { 540 | display: inline-block; 541 | margin-bottom: 0; 542 | padding: 0 10px; 543 | font-size: 24px; 544 | color: #666; 545 | } 546 | /* line 579, default.scss */ 547 | .results .stream { 548 | height: 700px; 549 | background-color: #1a252f; 550 | padding: 0 25px 0 15px; 551 | } 552 | /* line 584, default.scss */ 553 | .results .stream h1 { 554 | margin-bottom: 0; 555 | padding: 15px 5px 10px; 556 | color: #4d4d4d; 557 | border-radius: 5px 5px 0 0; 558 | font-size: 20px; 559 | text-align: center; 560 | background-color: #b3b3b3; 561 | } 562 | /* line 594, default.scss */ 563 | .results .stream .tweet-list { 564 | height: 600px; 565 | background-color: #f7f7f7; 566 | padding-bottom: 20px; 567 | overflow-y: scroll; 568 | overflow-x: hidden; 569 | box-shadow: 0 0 1px 1px rgba(0, 0, 0, 0.2); 570 | } 571 | /* line 602, default.scss */ 572 | .results .stream .tweet-list .tweet-card { 573 | padding: 10px 0px 10px 15px; 574 | margin: 5px 10px 5px 10px; 575 | border-bottom: 1px solid #ccc; 576 | background-color: white; 577 | box-shadow: 0 0 1px 1px rgba(0, 0, 0, 0.2); 578 | } 579 | /* line 609, default.scss */ 580 | .results .stream .tweet-list .tweet-card .profile-image { 581 | display: inline-block; 582 | vertical-align: top; 583 | margin-right: 10px; 584 | height: 50px; 585 | width: 50px; 586 | border-radius: 5px; 587 | } 588 | /* line 618, default.scss */ 589 | .results .stream .tweet-list .tweet-card .content { 590 | display: inline-block; 591 | width: 80%; 592 | position: relative; 593 | } 594 | /* line 623, default.scss */ 595 | .results .stream .tweet-list .tweet-card .content .user { 596 | display: inline-block; 597 | width: 90%; 598 | } 599 | /* line 627, default.scss */ 600 | .results .stream .tweet-list .tweet-card .content .user .name { 601 | font-size: 14px; 602 | color: #4d4d4d; 603 | font-weight: 700; 604 | margin-right: 10px; 605 | } 606 | /* line 634, default.scss */ 607 | .results .stream .tweet-list .tweet-card .content .user .username { 608 | font-size: 14px; 609 | } 610 | /* line 639, default.scss */ 611 | .results .stream .tweet-list .tweet-card .content .sentiment { 612 | position: absolute; 613 | top: 5px; 614 | right: 0; 615 | display: inline-block; 616 | } 617 | /* line 645, default.scss */ 618 | .results .stream .tweet-list .tweet-card .content .sentiment.positive { 619 | width: 0; 620 | height: 0; 621 | border-left: 10px solid transparent; 622 | border-right: 10px solid transparent; 623 | border-bottom: 10px solid green; 624 | } 625 | /* line 653, default.scss */ 626 | .results .stream .tweet-list .tweet-card .content .sentiment.neutral, .results .stream .tweet-list .tweet-card .content .sentiment.null { 627 | height: 10px; 628 | width: 10px; 629 | margin-right: 5px; 630 | border-radius: 50%; 631 | background-color: sandybrown; 632 | } 633 | /* line 663, default.scss */ 634 | .results .stream .tweet-list .tweet-card .content .sentiment.negative { 635 | width: 0; 636 | height: 0; 637 | border-left: 10px solid transparent; 638 | border-right: 10px solid transparent; 639 | border-top: 10px solid red; 640 | } 641 | /* line 672, default.scss */ 642 | .results .stream .tweet-list .tweet-card .content .text { 643 | font-size: 12px; 644 | } 645 | 646 | /* Footer Styles 647 | ======================== */ 648 | /* line 684, default.scss */ 649 | footer { 650 | height: 80px; 651 | background-color: #1a1a1a; 652 | } 653 | /* line 688, default.scss */ 654 | footer .baseline-container { 655 | position: relative; 656 | } 657 | /* line 691, default.scss */ 658 | footer .baseline-container .connect-container { 659 | position: absolute; 660 | right: 40px; 661 | bottom: 0; 662 | margin-right: 20px; 663 | display: flex; 664 | align-items: center; 665 | justify-content: center; 666 | z-index: 50; 667 | } 668 | /* line 701, default.scss */ 669 | footer .baseline-container .connect-container p { 670 | margin-top: 10px; 671 | margin-right: 20px; 672 | font-size: 14px; 673 | font-weight: 300; 674 | color: #999; 675 | } 676 | /* line 709, default.scss */ 677 | footer .baseline-container .connect-container .github-logo { 678 | height: 30px; 679 | width: 30px; 680 | margin-right: 10px; 681 | background-image: url("../img/logo/github-gray.png"); 682 | background-repeat: no-repeat; 683 | background-position: center; 684 | background-size: 100%; 685 | transition: all 0.2s ease-in-out; 686 | } 687 | /* line 719, default.scss */ 688 | footer .baseline-container .connect-container .github-logo:hover { 689 | background-image: url("../img/logo/github.png"); 690 | } 691 | /* line 724, default.scss */ 692 | footer .baseline-container .connect-container .linkedin-logo { 693 | height: 25px; 694 | width: 25px; 695 | margin-top: 5px; 696 | margin-left: 10px; 697 | background-image: url("../img/logo/linkedin-gray.png"); 698 | background-repeat: no-repeat; 699 | background-position: center; 700 | background-size: 100%; 701 | transition: all 0.2s ease-in-out; 702 | } 703 | /* line 735, default.scss */ 704 | footer .baseline-container .connect-container .linkedin-logo:hover { 705 | background-image: url("../img/logo/linkedin.png"); 706 | } 707 | @media (max-width: 930px) { 708 | /* line 691, default.scss */ 709 | footer .baseline-container .connect-container { 710 | position: relative; 711 | right: 0; 712 | margin-right: 0; 713 | } 714 | } 715 | /* line 747, default.scss */ 716 | footer .baseline-container .branding-container { 717 | margin-top: 30px; 718 | } 719 | /* line 750, default.scss */ 720 | footer .baseline-container .branding-container p { 721 | color: #4d4d4d; 722 | font-size: 16px; 723 | } 724 | 725 | /*# sourceMappingURL=default.css.map */ 726 | -------------------------------------------------------------------------------- /app/public/css/default.css: -------------------------------------------------------------------------------- 1 | /* Reusable Styles 2 | ======================== */ 3 | /* line 26, default.scss */ 4 | html, 5 | body { 6 | position: relative; 7 | font-family: "Open Sans", sans-serif; 8 | color: #999; 9 | background-color: #F5F7F9; 10 | font-size: 16px; 11 | overflow-x: hidden; 12 | } 13 | 14 | /* line 36, default.scss */ 15 | .intro-text { 16 | margin-top: 20px; 17 | margin-bottom: 40px; 18 | text-align: center; 19 | color: #4d4d4d; 20 | } 21 | /* line 42, default.scss */ 22 | .intro-text h2 { 23 | font-size: 35px; 24 | font-weight: 700; 25 | } 26 | /* line 47, default.scss */ 27 | .intro-text p { 28 | font-weight: 400; 29 | font-size: 16px; 30 | } 31 | 32 | /* Header and Nav Styles 33 | ======================== */ 34 | /* line 57, default.scss */ 35 | header { 36 | position: absolute; 37 | top: 0; 38 | left: 0; 39 | z-index: 100; 40 | width: 100%; 41 | } 42 | /* line 64, default.scss */ 43 | header nav { 44 | height: 60px; 45 | background-color: #1a1a1a; 46 | box-shadow: 2px 2px 2px 2px rgba(0, 0, 0, 0.3); 47 | } 48 | /* line 69, default.scss */ 49 | header nav ul { 50 | width: 80% !important; 51 | margin-right: auto; 52 | margin-left: auto; 53 | list-style: none; 54 | padding: 0; 55 | width: 100%; 56 | } 57 | /* line 77, default.scss */ 58 | header nav ul li { 59 | display: inline-block; 60 | padding-top: 22px; 61 | margin-right: 40px; 62 | } 63 | /* line 82, default.scss */ 64 | header nav ul li a { 65 | padding: 10px 0; 66 | text-decoration: none !important; 67 | text-transform: uppercase; 68 | font-size: 15px; 69 | color: #999; 70 | transition: all 0.25s ease-in-out; 71 | } 72 | /* line 90, default.scss */ 73 | header nav ul li a:hover, header nav ul li a:active, header nav ul li a:focus { 74 | color: #2bb656; 75 | outline: none; 76 | } 77 | /* line 97, default.scss */ 78 | header nav ul li a:after { 79 | content: ""; 80 | padding-bottom: 7px; 81 | display: block; 82 | border-bottom: 2px solid #2bb656; 83 | width: 0; 84 | transition: all 0.25s ease-in-out; 85 | pointer-events: none; 86 | } 87 | /* line 107, default.scss */ 88 | header nav ul li a:hover:after { 89 | width: 100%; 90 | } 91 | /* line 113, default.scss */ 92 | header nav ul #nav-logo { 93 | height: 25px; 94 | width: auto; 95 | margin-right: 5px; 96 | margin-bottom: 2px; 97 | } 98 | /* line 121, default.scss */ 99 | header nav ul #home-nav a { 100 | color: #59BBFF; 101 | font-weight: 600; 102 | font-size: 17px; 103 | } 104 | 105 | /* Hero and Search Bar Styles 106 | ======================== */ 107 | /* line 133, default.scss */ 108 | .hero { 109 | height: 700px; 110 | background-image: linear-gradient(rgba(0, 0, 0, 0.4), rgba(0, 0, 0, 0.8)), url(../img/hero.jpg); 111 | background-size: cover; 112 | background-repeat: no-repeat; 113 | background-position: bottom; 114 | position: relative; 115 | } 116 | /* line 141, default.scss */ 117 | .hero .content { 118 | position: absolute; 119 | display: flex; 120 | flex-direction: column; 121 | justify-content: center; 122 | height: 800px; 123 | } 124 | /* line 148, default.scss */ 125 | .hero .content h1, 126 | .hero .content h2 { 127 | color: white; 128 | text-align: center; 129 | } 130 | /* line 154, default.scss */ 131 | .hero .content h1 { 132 | order: 3; 133 | font-size: 20px; 134 | font-weight: 300; 135 | letter-spacing: 1px; 136 | color: #cfcfcf; 137 | } 138 | /* line 162, default.scss */ 139 | .hero .content h2 { 140 | order: 2; 141 | font-size: 40px; 142 | font-weight: 700; 143 | } 144 | @media (max-width: 640px) { 145 | /* line 162, default.scss */ 146 | .hero .content h2 { 147 | font-size: 30px; 148 | } 149 | } 150 | /* line 172, default.scss */ 151 | .hero .content .text-logo { 152 | order: 1; 153 | font-weight: 600; 154 | font-size: 40px; 155 | color: #59BBFF; 156 | } 157 | /* line 174, default.scss */ 158 | .hero .content .text-logo img { 159 | height: 60px; 160 | width: auto; 161 | margin-right: 10px; 162 | margin-bottom: 15px; 163 | } 164 | /* line 188, default.scss */ 165 | .hero .content #search-bar { 166 | order: 4; 167 | width: 350px; 168 | margin-top: 40px; 169 | margin-right: auto; 170 | margin-left: auto; 171 | } 172 | /* line 195, default.scss */ 173 | .hero .content #search-bar input:focus { 174 | border: 1px solid #218d43; 175 | box-shadow: 0 0 4px #218d43; 176 | } 177 | /* line 200, default.scss */ 178 | .hero .content #search-bar .btn-default { 179 | background-color: #2bb656; 180 | border-color: #2bb656; 181 | font-family: "Open Sans", sans-serif; 182 | font-weight: 300; 183 | color: white; 184 | text-transform: uppercase; 185 | transition: all 0.25s ease-in-out; 186 | } 187 | /* line 209, default.scss */ 188 | .hero .content #search-bar .btn-default:hover { 189 | background-color: #218d43; 190 | border-color: #218d43; 191 | } 192 | 193 | /* Technology Stack Section Styles 194 | ======================== */ 195 | /* line 220, default.scss */ 196 | .technology-stack { 197 | padding-bottom: 20px; 198 | background-color: #1a252f; 199 | background-image: url("/img/tech-background.png"); 200 | background-size: 80%; 201 | font-weight: 300; 202 | font-size: 19px; 203 | text-align: center; 204 | } 205 | /* line 229, default.scss */ 206 | .technology-stack .technologies-container { 207 | padding-top: 20px; 208 | margin-bottom: 20px; 209 | align-items: center; 210 | } 211 | /* line 234, default.scss */ 212 | .technology-stack .technologies-container .heading { 213 | color: #999; 214 | margin-bottom: 30px; 215 | } 216 | /* line 240, default.scss */ 217 | .technology-stack .technologies-container .nodejs .nodejs-logo { 218 | height: 120px; 219 | width: 200px; 220 | margin-right: auto; 221 | margin-left: auto; 222 | background-image: url("../img/logo/nodejs-gray.png"); 223 | background-repeat: no-repeat; 224 | background-position: center; 225 | background-size: 100%; 226 | transition: all 0.2s ease-in-out; 227 | } 228 | /* line 251, default.scss */ 229 | .technology-stack .technologies-container .nodejs .nodejs-logo:hover { 230 | background-image: url("../img/logo/nodejs.png"); 231 | } 232 | /* line 258, default.scss */ 233 | .technology-stack .technologies-container .socketio .socketio-logo { 234 | height: 120px; 235 | width: 200px; 236 | margin-right: auto; 237 | margin-left: auto; 238 | background-image: url("../img/logo/socketio-gray.png"); 239 | background-repeat: no-repeat; 240 | background-position: center; 241 | background-size: 100%; 242 | transition: all 0.2s ease-in-out; 243 | } 244 | /* line 269, default.scss */ 245 | .technology-stack .technologies-container .socketio .socketio-logo:hover { 246 | background-image: url("../img/logo/socketio.png"); 247 | } 248 | /* line 276, default.scss */ 249 | .technology-stack .technologies-container .react .react-logo { 250 | height: 120px; 251 | width: 200px; 252 | margin-right: auto; 253 | margin-left: auto; 254 | background-image: url("../img/logo/react-gray.png"); 255 | background-repeat: no-repeat; 256 | background-position: center; 257 | background-size: 100%; 258 | transition: all 0.2s ease-in-out; 259 | } 260 | /* line 287, default.scss */ 261 | .technology-stack .technologies-container .react .react-logo:hover { 262 | background-image: url("../img/logo/react.png"); 263 | } 264 | /* line 293, default.scss */ 265 | .technology-stack .technologies-container .d3 { 266 | padding-bottom: 10px; 267 | } 268 | /* line 295, default.scss */ 269 | .technology-stack .technologies-container .d3 .d3-logo { 270 | height: 80px; 271 | width: 80px; 272 | margin-right: auto; 273 | margin-left: auto; 274 | background-image: url("../img/logo/d3-gray.png"); 275 | background-repeat: no-repeat; 276 | background-position: center; 277 | background-size: 100%; 278 | transition: all 0.2s ease-in-out; 279 | } 280 | /* line 306, default.scss */ 281 | .technology-stack .technologies-container .d3 .d3-logo:hover { 282 | background-image: url("../img/logo/d3.png"); 283 | } 284 | /* line 313, default.scss */ 285 | .technology-stack .technologies-container .twitter .twitter-logo { 286 | height: 120px; 287 | width: 250px; 288 | margin-right: auto; 289 | margin-left: auto; 290 | background-image: url("../img/logo/twitter-gray.png"); 291 | background-repeat: no-repeat; 292 | background-position: center; 293 | background-size: 100%; 294 | transition: all 0.2s ease-in-out; 295 | } 296 | /* line 324, default.scss */ 297 | .technology-stack .technologies-container .twitter .twitter-logo:hover { 298 | background-image: url("../img/logo/twitter.png"); 299 | } 300 | /* line 331, default.scss */ 301 | .technology-stack .technologies-container .heroku .heroku-logo { 302 | height: 120px; 303 | width: 250px; 304 | margin-right: auto; 305 | margin-left: auto; 306 | background-image: url("../img/logo/heroku-gray.png"); 307 | background-repeat: no-repeat; 308 | background-position: center; 309 | background-size: 100%; 310 | transition: all 0.2s ease-in-out; 311 | } 312 | /* line 342, default.scss */ 313 | .technology-stack .technologies-container .heroku .heroku-logo:hover { 314 | background-image: url("../img/logo/heroku.png"); 315 | } 316 | 317 | /* About Section Styles 318 | ======================== */ 319 | /* line 353, default.scss */ 320 | #about { 321 | padding-top: 30px; 322 | } 323 | /* line 356, default.scss */ 324 | #about .title { 325 | text-align: center; 326 | } 327 | /* line 359, default.scss */ 328 | #about .title h3 { 329 | font-weight: 600; 330 | font-size: 32px; 331 | color: #2bb656; 332 | } 333 | /* line 364, default.scss */ 334 | #about .title p { 335 | color: #666; 336 | } 337 | /* line 369, default.scss */ 338 | #about .features { 339 | margin-top: 20px; 340 | padding-bottom: 50px; 341 | } 342 | /* line 373, default.scss */ 343 | #about .features .tile { 344 | min-height: 320px; 345 | padding: 0 10px 20px; 346 | border-radius: 10px; 347 | border: 1px solid #d5d5d5; 348 | box-shadow: 0 4px 8px rgba(166, 166, 166, 0.3); 349 | background-color: white; 350 | } 351 | @media (max-width: 992px) { 352 | /* line 373, default.scss */ 353 | #about .features .tile { 354 | min-height: 200px; 355 | margin-top: 5px; 356 | } 357 | } 358 | /* line 386, default.scss */ 359 | #about .features .tile h3 { 360 | color: #4d4d4d; 361 | text-align: center; 362 | margin-bottom: 30px; 363 | } 364 | /* line 391, default.scss */ 365 | #about .features .tile h3 .circle { 366 | width: 75px; 367 | height: 75px; 368 | margin: 0 auto 30px auto; 369 | display: block; 370 | border: 3px solid rgba(0, 0, 0, 0.13); 371 | border-radius: 50%; 372 | } 373 | /* line 399, default.scss */ 374 | #about .features .tile h3 .circle .fa { 375 | color: #2bb656; 376 | margin-top: 15px; 377 | font-size: 40px; 378 | } 379 | /* line 407, default.scss */ 380 | #about .features .tile p { 381 | color: #666; 382 | text-align: center; 383 | font-size: 16px; 384 | } 385 | 386 | /* Results Section Styles 387 | ======================== */ 388 | /* line 419, default.scss */ 389 | .results { 390 | height: 700px; 391 | /* Twitter Stream Styles 392 | ======================== */ 393 | } 394 | /* line 422, default.scss */ 395 | .results .dashboard { 396 | height: 700px; 397 | overflow-y: hidden; 398 | background-color: #1a252f; 399 | /* Activity Chart Styles 400 | ======================== */ 401 | } 402 | /* line 427, default.scss */ 403 | .results .dashboard h1 { 404 | color: #4d4d4d; 405 | text-align: center; 406 | font-size: 32px; 407 | margin-bottom: 30px; 408 | } 409 | /* line 436, default.scss */ 410 | .results .dashboard .twitter-activity { 411 | width: 800px; 412 | margin-right: auto; 413 | margin-left: auto; 414 | display: block; 415 | } 416 | /* line 442, default.scss */ 417 | .results .dashboard .twitter-activity h4 { 418 | margin-top: 20px; 419 | margin-bottom: 0; 420 | padding: 15px 5px 10px; 421 | color: #4d4d4d; 422 | border-radius: 5px 5px 0 0; 423 | font-size: 20px; 424 | text-align: center; 425 | background-color: #b3b3b3; 426 | } 427 | /* line 453, default.scss */ 428 | .results .dashboard .twitter-activity .line-chart { 429 | background-color: #f7f7f7; 430 | display: block; 431 | margin: auto; 432 | box-shadow: 0 0 1px 1px rgba(0, 0, 0, 0.2); 433 | } 434 | /* line 459, default.scss */ 435 | .results .dashboard .twitter-activity .line-chart .gridline path, 436 | .results .dashboard .twitter-activity .line-chart .gridline line { 437 | fill: none; 438 | stroke: #ccc; 439 | shape-rendering: crispEdges; 440 | } 441 | /* line 466, default.scss */ 442 | .results .dashboard .twitter-activity .line-chart .axis path, 443 | .results .dashboard .twitter-activity .line-chart .axis line { 444 | fill: none; 445 | stroke: #1a252f; 446 | shape-rendering: crispEdges; 447 | } 448 | /* line 473, default.scss */ 449 | .results .dashboard .twitter-activity .line-chart .axis text { 450 | font-family: "Open Sans", sans-serif; 451 | font-size: 14px; 452 | } 453 | /* line 478, default.scss */ 454 | .results .dashboard .twitter-activity .line-chart .axis text.x-label, 455 | .results .dashboard .twitter-activity .line-chart .axis text.y-label { 456 | font-family: "Open Sans", sans-serif; 457 | fill: #999; 458 | } 459 | /* line 485, default.scss */ 460 | .results .dashboard .twitter-activity .tweet-counters { 461 | display: flex; 462 | border-top: 1px solid #1a252f; 463 | } 464 | /* line 489, default.scss */ 465 | .results .dashboard .twitter-activity .tweet-counters .total { 466 | width: 100%; 467 | position: relative; 468 | } 469 | /* line 493, default.scss */ 470 | .results .dashboard .twitter-activity .tweet-counters .total h3 { 471 | margin: 0; 472 | padding: 10px 0; 473 | color: #4d4d4d; 474 | font-size: 14px; 475 | text-align: center; 476 | background-color: #d5d5d5; 477 | } 478 | /* line 502, default.scss */ 479 | .results .dashboard .twitter-activity .tweet-counters .total .total-tweets { 480 | height: 5px; 481 | background-color: blue; 482 | } 483 | /* line 507, default.scss */ 484 | .results .dashboard .twitter-activity .tweet-counters .total .total-positive { 485 | height: 5px; 486 | background-color: green; 487 | } 488 | /* line 512, default.scss */ 489 | .results .dashboard .twitter-activity .tweet-counters .total .total-neutral { 490 | height: 5px; 491 | background-color: sandybrown; 492 | } 493 | /* line 517, default.scss */ 494 | .results .dashboard .twitter-activity .tweet-counters .total .total-negative { 495 | height: 5px; 496 | background-color: red; 497 | } 498 | /* line 522, default.scss */ 499 | .results .dashboard .twitter-activity .tweet-counters .total .counter { 500 | padding: 5px 0; 501 | color: #737373; 502 | font-size: 28px; 503 | font-weight: 600; 504 | text-align: center; 505 | background-color: white; 506 | transition: all 0.2s ease-in-out; 507 | } 508 | /* line 531, default.scss */ 509 | .results .dashboard .twitter-activity .tweet-counters .total .counter.positive { 510 | color: green; 511 | } 512 | /* line 536, default.scss */ 513 | .results .dashboard .twitter-activity .tweet-counters .total .counter.neutral { 514 | color: sandybrown; 515 | } 516 | /* line 540, default.scss */ 517 | .results .dashboard .twitter-activity .tweet-counters .total .counter.negative { 518 | color: red; 519 | } 520 | /* line 545, default.scss */ 521 | .results .dashboard .twitter-activity .tweet-counters .total .total-tweets + .counter { 522 | border-radius: 0 0 0 5px; 523 | } 524 | /* line 549, default.scss */ 525 | .results .dashboard .twitter-activity .tweet-counters .total .total-negative + .counter { 526 | border-radius: 0 0 5px 0; 527 | } 528 | /* line 553, default.scss */ 529 | .results .dashboard .twitter-activity .tweet-counters .total .arrow { 530 | position: absolute; 531 | bottom: 20px; 532 | right: 15px; 533 | display: inline-block; 534 | width: 0; 535 | height: 0; 536 | border-left: 10px solid transparent; 537 | border-right: 10px solid transparent; 538 | transition: all 0.2s ease-in-out; 539 | } 540 | /* line 564, default.scss */ 541 | .results .dashboard .twitter-activity .tweet-counters .total .arrow.positive { 542 | border-bottom: 10px solid green; 543 | } 544 | /* line 568, default.scss */ 545 | .results .dashboard .twitter-activity .tweet-counters .total .arrow.neutral, .results .dashboard .twitter-activity .tweet-counters .total .arrow.null { 546 | border-bottom: 10px solid sandybrown; 547 | } 548 | /* line 573, default.scss */ 549 | .results .dashboard .twitter-activity .tweet-counters .total .arrow.negative { 550 | border-bottom: 10px solid red; 551 | } 552 | /* line 580, default.scss */ 553 | .results .dashboard .twitter-activity .overall-sentiment { 554 | margin-top: 30px; 555 | display: inline-block; 556 | background-color: #f7f7f7; 557 | border-radius: 5px 5px 5px 5px; 558 | } 559 | /* line 586, default.scss */ 560 | .results .dashboard .twitter-activity .overall-sentiment h3 { 561 | display: inline-block; 562 | padding: 10px 0 10px 10px; 563 | margin: 0; 564 | width: 220px; 565 | color: #4d4d4d; 566 | font-size: 24px; 567 | border-right: 1px solid #1a252f; 568 | border-radius: 5px 0 0 5px; 569 | background-color: #d5d5d5; 570 | } 571 | /* line 598, default.scss */ 572 | .results .dashboard .twitter-activity .overall-sentiment p { 573 | display: inline-block; 574 | margin-bottom: 0; 575 | padding: 0 10px; 576 | font-size: 24px; 577 | color: #666; 578 | } 579 | /* line 605, default.scss */ 580 | .results .dashboard .twitter-activity .overall-sentiment p.positive { 581 | color: green; 582 | } 583 | /* line 609, default.scss */ 584 | .results .dashboard .twitter-activity .overall-sentiment p.negative { 585 | color: red; 586 | } 587 | /* line 619, default.scss */ 588 | .results .stream { 589 | height: 700px; 590 | background-color: #1a252f; 591 | padding: 0 25px 0 15px; 592 | } 593 | /* line 624, default.scss */ 594 | .results .stream h1 { 595 | margin-bottom: 0; 596 | padding: 15px 5px 10px; 597 | color: #4d4d4d; 598 | border-radius: 5px 5px 0 0; 599 | font-size: 20px; 600 | text-align: center; 601 | background-color: #b3b3b3; 602 | } 603 | /* line 634, default.scss */ 604 | .results .stream .tweet-list { 605 | height: 600px; 606 | background-color: #f7f7f7; 607 | padding-bottom: 20px; 608 | overflow-y: scroll; 609 | overflow-x: hidden; 610 | box-shadow: 0 0 1px 1px rgba(0, 0, 0, 0.2); 611 | } 612 | /* line 642, default.scss */ 613 | .results .stream .tweet-list .tweet-card { 614 | padding: 10px 0px 10px 15px; 615 | margin: 5px 10px 5px 10px; 616 | border-bottom: 1px solid #ccc; 617 | background-color: white; 618 | box-shadow: 0 0 1px 1px rgba(0, 0, 0, 0.2); 619 | } 620 | /* line 649, default.scss */ 621 | .results .stream .tweet-list .tweet-card .profile-image { 622 | display: inline-block; 623 | vertical-align: top; 624 | margin-right: 10px; 625 | height: 50px; 626 | width: 50px; 627 | border-radius: 5px; 628 | } 629 | /* line 658, default.scss */ 630 | .results .stream .tweet-list .tweet-card .content { 631 | display: inline-block; 632 | width: 80%; 633 | position: relative; 634 | } 635 | /* line 663, default.scss */ 636 | .results .stream .tweet-list .tweet-card .content .user { 637 | display: inline-block; 638 | width: 90%; 639 | } 640 | /* line 667, default.scss */ 641 | .results .stream .tweet-list .tweet-card .content .user .name { 642 | font-size: 14px; 643 | color: #4d4d4d; 644 | font-weight: 700; 645 | margin-right: 10px; 646 | } 647 | /* line 674, default.scss */ 648 | .results .stream .tweet-list .tweet-card .content .user .username { 649 | font-size: 14px; 650 | } 651 | /* line 679, default.scss */ 652 | .results .stream .tweet-list .tweet-card .content .sentiment { 653 | position: absolute; 654 | top: 5px; 655 | right: 0; 656 | display: inline-block; 657 | } 658 | /* line 685, default.scss */ 659 | .results .stream .tweet-list .tweet-card .content .sentiment.positive { 660 | width: 0; 661 | height: 0; 662 | border-left: 10px solid transparent; 663 | border-right: 10px solid transparent; 664 | border-bottom: 10px solid green; 665 | } 666 | /* line 693, default.scss */ 667 | .results .stream .tweet-list .tweet-card .content .sentiment.neutral, .results .stream .tweet-list .tweet-card .content .sentiment.null { 668 | height: 10px; 669 | width: 10px; 670 | margin-right: 5px; 671 | border-radius: 50%; 672 | background-color: sandybrown; 673 | } 674 | /* line 703, default.scss */ 675 | .results .stream .tweet-list .tweet-card .content .sentiment.negative { 676 | width: 0; 677 | height: 0; 678 | border-left: 10px solid transparent; 679 | border-right: 10px solid transparent; 680 | border-top: 10px solid red; 681 | } 682 | /* line 712, default.scss */ 683 | .results .stream .tweet-list .tweet-card .content .text { 684 | font-size: 12px; 685 | } 686 | 687 | /* Footer Styles 688 | ======================== */ 689 | /* line 724, default.scss */ 690 | footer { 691 | height: 80px; 692 | background-color: #1a1a1a; 693 | } 694 | /* line 728, default.scss */ 695 | footer .baseline-container { 696 | position: relative; 697 | } 698 | /* line 731, default.scss */ 699 | footer .baseline-container .connect-container { 700 | position: absolute; 701 | right: 40px; 702 | bottom: 0; 703 | margin-right: 20px; 704 | display: flex; 705 | align-items: center; 706 | justify-content: center; 707 | z-index: 50; 708 | } 709 | /* line 741, default.scss */ 710 | footer .baseline-container .connect-container p { 711 | margin-top: 10px; 712 | margin-right: 20px; 713 | font-size: 14px; 714 | font-weight: 300; 715 | color: #999; 716 | } 717 | /* line 749, default.scss */ 718 | footer .baseline-container .connect-container .github-logo { 719 | height: 30px; 720 | width: 30px; 721 | margin-right: 10px; 722 | background-image: url("../img/logo/github-gray.png"); 723 | background-repeat: no-repeat; 724 | background-position: center; 725 | background-size: 100%; 726 | transition: all 0.2s ease-in-out; 727 | } 728 | /* line 759, default.scss */ 729 | footer .baseline-container .connect-container .github-logo:hover { 730 | background-image: url("../img/logo/github.png"); 731 | } 732 | /* line 764, default.scss */ 733 | footer .baseline-container .connect-container .linkedin-logo { 734 | height: 25px; 735 | width: 25px; 736 | margin-top: 5px; 737 | margin-left: 10px; 738 | background-image: url("../img/logo/linkedin-gray.png"); 739 | background-repeat: no-repeat; 740 | background-position: center; 741 | background-size: 100%; 742 | transition: all 0.2s ease-in-out; 743 | } 744 | /* line 775, default.scss */ 745 | footer .baseline-container .connect-container .linkedin-logo:hover { 746 | background-image: url("../img/logo/linkedin.png"); 747 | } 748 | @media (max-width: 930px) { 749 | /* line 731, default.scss */ 750 | footer .baseline-container .connect-container { 751 | position: relative; 752 | right: 0; 753 | margin-right: 0; 754 | } 755 | } 756 | /* line 787, default.scss */ 757 | footer .baseline-container .branding-container { 758 | margin-top: 30px; 759 | } 760 | /* line 790, default.scss */ 761 | footer .baseline-container .branding-container p { 762 | color: #4d4d4d; 763 | font-size: 16px; 764 | } 765 | 766 | /*# sourceMappingURL=default.css.map */ 767 | -------------------------------------------------------------------------------- /app/public/img/Twitterment_files/font-awesome.min.css: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome 4.5.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.5.0');src:url('../fonts/fontawesome-webfont.eot?#iefix&v=4.5.0') format('embedded-opentype'),url('../fonts/fontawesome-webfont.woff2?v=4.5.0') format('woff2'),url('../fonts/fontawesome-webfont.woff?v=4.5.0') format('woff'),url('../fonts/fontawesome-webfont.ttf?v=4.5.0') format('truetype'),url('../fonts/fontawesome-webfont.svg?v=4.5.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{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=1);-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=2);-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{filter:progid:DXImageTransform.Microsoft.BasicImage(rotation=3);-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{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{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: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-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-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"} 5 | --------------------------------------------------------------------------------