├── README.md
├── background.js
├── contentscripts
├── board.js
├── button.js
├── controls.js
└── game.js
├── flappy-octocat.crx
├── icons
├── .DS_Store
├── icon-128.png
├── icon-16.png
└── icon-48.png
├── manifest.json
├── screenshot.gif
└── style.css
/README.md:
--------------------------------------------------------------------------------
1 | # Flappy Octocat
2 |
3 | > a chrome extension to play a flappy bird like game on github contributions board
4 |
5 | * Inspired by a really awesome chrome extension [Game Of Life](https://github.com/yuanchuan/game-of-life) !
6 |
7 | 
8 |
9 |
10 | 1. Install the extension from [Chrome Web Store](https://chrome.google.com/webstore/detail/flappy-octocat/jjjhhlomhbdmnfgaccmddhmjfeekjlbl?utm_source=chrome-ntp-icon)
11 | 2. Press 'Space' to jump. Have fun!
12 |
13 |
--------------------------------------------------------------------------------
/background.js:
--------------------------------------------------------------------------------
1 | function getDomainFromUrl(url){
2 | var host = "null";
3 | if(typeof url == "undefined" || null == url)
4 | url = window.location.href;
5 | var regex = /.*\:\/\/([^\/]*).*/;
6 | var match = url.match(regex);
7 | if(typeof match != "undefined" && null != match)
8 | host = match[1];
9 | return host;
10 | }
11 |
12 | function checkForValidUrl(tabId, changeInfo, tab) {
13 | if(getDomainFromUrl(tab.url).toLowerCase() == "github.com"){
14 | chrome.pageAction.show(tabId);
15 | }
16 | };
17 |
18 | chrome.tabs.onUpdated.addListener(checkForValidUrl);
19 |
--------------------------------------------------------------------------------
/contentscripts/board.js:
--------------------------------------------------------------------------------
1 | var Board = {
2 | id: 'fo-board',
3 | row: 13,
4 | col: 61,
5 | color0: '#ebedf0',
6 | color1: '#239a3b',
7 | color2: '#c6e48b',
8 | catLoc: [],
9 | tubeLocs: [],
10 | treeLocs: [],
11 | catPoints: [],
12 | barrierPoints: [],
13 | element: null
14 | }
15 |
16 | Board.cat = [
17 | [0, 0, 1, 0, 0, 0, 1],
18 | [0, 0, 1, 1, 1, 1, 1],
19 | [0, 0, 1, 2, 1, 2, 1],
20 | [1, 0, 1, 1, 1, 1, 1],
21 | [0, 1, 0, 0, 1, 0, 0],
22 | [0, 0, 1, 1, 1, 1, 1],
23 | [0, 0, 1, 0, 1, 0, 1],
24 | ]
25 |
26 | Board.tube = [
27 | [1, 1, 1, 1, 1],
28 | [1, 1, 1, 1, 1],
29 | [1, 1, 1, 1, 1],
30 | [1, 1, 1, 1, 1],
31 | ]
32 |
33 | Board.tree = [
34 | [0, 1, 1, 0, 1, 1, 0],
35 | [1, 1, 1, 1, 1, 1, 1],
36 | [1, 1, 1, 1, 1, 1, 1],
37 | ]
38 |
39 | Board.init = function() {
40 | Board.catLoc = [5, 3]
41 | Board.tubeLocs = [[20, 9], [58, 0]]
42 | Board.treeLocs = [[38, 10]]
43 | Board.catPoints = []
44 | Board.barrierPoints = []
45 | Board.timer = {}
46 | }
47 |
48 | Board.handleKeydown = function(e) {
49 | if (e.keyCode == 32 && e.target == document.body) {
50 | e.preventDefault();
51 | Board.jump()
52 | }
53 | }
54 |
55 | Board.bindKeyPress = function() {
56 | window.addEventListener('keydown', Board.handleKeydown);
57 | }
58 |
59 | Board.unbindKeyPress = function() {
60 | window.removeEventListener('keydown', Board.handleKeydown);
61 | }
62 |
63 | Board.setUpInterval = function() {
64 | Board.setUpIntervalFall()
65 | Board.setUpIntervalMove()
66 | }
67 |
68 | Board.setUpIntervalFall = function() {
69 | if (!Game.running || Game.paused) {
70 | return false
71 | }
72 | Board.timer.fall = setTimeout(function() {
73 | Board.fall()
74 | Board.setUpIntervalFall()
75 | }, Game.intervalFall)
76 | }
77 |
78 | Board.setUpIntervalMove = function() {
79 | if (!Game.running || Game.paused) {
80 | return false
81 | }
82 | Board.timer.move = setTimeout(function() {
83 | Board.move()
84 | if (Game.score % 50 == 0) {
85 | Game.intervalMove = Math.ceil(Game.intervalMove * 0.8)
86 | }
87 | Board.setUpIntervalMove()
88 | }, Game.intervalMove)
89 | }
90 |
91 | Board.pointDebug = function(li) {
92 | li.addEventListener('click', function(e) {
93 | if(!Board.color(this) || Board.color(this) == Board.color0) {
94 | Board.fill(this, Board.color1);
95 | } else {
96 | Board.fill(this, Board.color0);
97 | }
98 | })
99 | }
100 |
101 | Board.open = function() {
102 | var element = document.getElementById(Board.id)
103 | if (!element) {
104 | element = document.createElement('div')
105 | element.id = Board.id
106 | element.innerHTML = ('
' + ''.repeat(Board.row) + '
').repeat(Board.col)
107 |
108 | var i = 0
109 | element.querySelectorAll('ul').forEach(function(ul){
110 | var j = 0
111 | ul.querySelectorAll('li').forEach(function(li) {
112 | li.setAttribute('id', 'p-' + j + '-' + i)
113 | // Board.pointDebug(li)
114 | j += 1
115 | })
116 | i += 1
117 | })
118 |
119 | Board.element = element
120 | Game.container.appendChild(element)
121 |
122 | Board.refresh()
123 | }
124 | }
125 |
126 | Board.start = function() {
127 | Board.refresh()
128 | Board.bindKeyPress()
129 | Board.setUpInterval()
130 | }
131 |
132 | Board.color = function(e) {
133 | return e.getAttribute('fill')
134 | }
135 |
136 | Board.fill = function(e, color) {
137 | e.style.backgroundColor = color
138 | e.setAttribute('fill', color)
139 | }
140 |
141 | Board.clear = function() {
142 | Board.element.querySelectorAll('li').forEach(function(li){
143 | Board.fill(li, Board.color0)
144 | })
145 | Board.catPoints = []
146 | Board.barrierPoints = []
147 | }
148 |
149 | Board.draw = function(matrix, loc, type) {
150 | var p
151 | var color
152 | for (r in matrix) {
153 | for (c in matrix[r]) {
154 | y = parseInt(loc[1]) + parseInt(r)
155 | x = parseInt(loc[0]) + parseInt(c)
156 | if (x >= Board.col || x < 0) {
157 | continue
158 | }
159 | if (y >= Board.row || y < 0) {
160 | continue
161 | }
162 | id = 'p-' + y + '-' + x
163 | p = document.getElementById(id)
164 | if (matrix[r][c] != 0) {
165 | if (type == 'cat') {
166 | Board.catPoints.push(id)
167 | } else {
168 | Board.barrierPoints.push(id)
169 | }
170 | }
171 | Board.fill(p, Board['color' + matrix[r][c]])
172 | }
173 | }
174 | }
175 |
176 | Board.refresh = function() {
177 | Board.clear()
178 | Board.draw(Board.cat, Board.catLoc, 'cat')
179 | Board.tubeLocs.forEach(function(tubeLoc){
180 | Board.draw(Board.tube, tubeLoc, 'tube')
181 | })
182 | Board.treeLocs.forEach(function(treeLoc){
183 | Board.draw(Board.tree, treeLoc, 'tree')
184 | })
185 | Board.check()
186 | }
187 |
188 | Board.jump = function() {
189 | if (Game.running && !Game.paused) {
190 | var step = 2
191 | if (Board.catLoc[1] < 2) {
192 | step = Board.catLoc[1]
193 | }
194 | if (step > 0) {
195 | Board.catLoc = [Board.catLoc[0], Board.catLoc[1] - step]
196 | Board.refresh()
197 | }
198 | }
199 | }
200 |
201 | Board.fall = function() {
202 | if (Game.paused) return
203 |
204 | if (Board.catLoc[1] + Board.cat.length < Board.row) {
205 | Board.catLoc = [Board.catLoc[0], Board.catLoc[1] + 1]
206 | Board.refresh()
207 | }
208 | }
209 |
210 | Board.move = function() {
211 | if (Game.paused) return
212 |
213 | Game.addScore()
214 | var tubeLocs = Board.tubeLocs
215 | Board.tubeLocs = []
216 | tubeLocs.forEach(function(loc) {
217 | if (loc[0] + Board.tube[0].length > 0) {
218 | Board.tubeLocs.push([loc[0] - 1, loc[1]])
219 | }
220 | })
221 |
222 | var treeLocs = Board.treeLocs
223 | Board.treeLocs = []
224 | treeLocs.forEach(function(loc) {
225 | if (loc[0] + Board.tree[0].length > 0) {
226 | Board.treeLocs.push([loc[0] - 1, loc[1]])
227 | }
228 | })
229 |
230 | if ((Board.tubeLocs.length + Board.treeLocs.length) < 3 && Math.random() > 0.2) {
231 | Board.generateBarrier()
232 | }
233 |
234 | Board.refresh()
235 | }
236 |
237 | Board.generateBarrier = function() {
238 | var rand = Math.random()
239 | if (rand < 0.3) {
240 | Board.tubeLocs.push([Board.col - 1, 0])
241 | } else if (rand < 0.7) {
242 | Board.tubeLocs.push([Board.col - 1, Board.row - Board.tube.length])
243 | } else {
244 | Board.treeLocs.push([Board.col - 1, Board.row - Board.tree.length])
245 | }
246 | }
247 |
248 | Board.check = function() {
249 | if (!Game.running) {
250 | return false
251 | }
252 | Board.catPoints.every(function(p) {
253 | if (Board.barrierPoints.indexOf(p) > -1) {
254 | Board.die()
255 | return false
256 | }
257 | return true
258 | })
259 | }
260 |
261 | Board.die = function() {
262 | Game.die()
263 | Board.flash(6)
264 | }
265 |
266 | Board.flash = function(times) {
267 | if (times > 0) {
268 | Board.timer.flash = setTimeout(function(){
269 | document.getElementById(Board.id).querySelectorAll('li').forEach(function(li){
270 | if (Board.color(li) == Board.color0) {
271 | Board.fill(li, Board.color1)
272 | } else if (Board.color(li) == Board.color1) {
273 | Board.fill(li, Board.color0)
274 | }
275 | })
276 | Board.flash(times - 1)
277 | }, 150)
278 | }
279 | }
280 |
281 | Board.close = function() {
282 | if (Board.element) {
283 | Board.element.parentNode.removeChild(Board.element)
284 | Board.element = null
285 | Board.unbindKeyPress()
286 | Object.keys(Board.timer).forEach(function(n) {
287 | clearTimeout(Board.timer[n])
288 | })
289 | }
290 | }
291 |
292 | Board.init();
293 |
--------------------------------------------------------------------------------
/contentscripts/button.js:
--------------------------------------------------------------------------------
1 | var Button = {
2 | id: 'fo-button',
3 | element: null
4 | }
5 |
6 | Button.init = function() {
7 | if (Game.graph){
8 | Button.build()
9 | }
10 | }
11 |
12 | Button.build = function() {
13 | var element = document.getElementById(Button.id)
14 | if (!element){
15 | element = document.createElement('a')
16 | element.id = Button.id
17 | element.innerHTML = 'Play'
18 | element.addEventListener('click', function(e) {
19 | Board.open()
20 | Controls.open()
21 | })
22 | Game.legend.insertBefore(element, Game.legend.firstChild)
23 |
24 | Button.element = element
25 | }
26 | }
27 |
28 | Button.init()
29 |
--------------------------------------------------------------------------------
/contentscripts/controls.js:
--------------------------------------------------------------------------------
1 | var Controls = {
2 | id: "fo-controls",
3 | actions: ['start', 'restart', 'pause', 'unpause', 'close'],
4 | buttons: {},
5 | element: null
6 | }
7 |
8 | Controls.init = function() {
9 | }
10 |
11 | Controls.action = function (e) {
12 | var btn = e.target
13 | if (btn.hasAttribute('data-action') && !btn.hasAttribute('disabled')) {
14 | Controls.onclick && Controls.onclick(btn)
15 | }
16 | return false
17 | }
18 |
19 | Controls.onclick = function(btn) {
20 | var action = Game[btn.getAttribute('data-action')]
21 | action && action()
22 | Controls.refresh()
23 | }
24 |
25 | Controls.open = function() {
26 | if (!Controls.element) {
27 | var content = '0' +
28 | Controls.actions.map(function(name) {
29 | return ''
30 | }).join('')
31 |
32 | var element = document.createElement('div')
33 | element.id = Controls.id
34 | element.innerHTML = content
35 |
36 | Controls.actions.forEach(function(name) {
37 | Controls.buttons[name] = element.querySelector('[data-action="' + name + '"]')
38 | })
39 | element.addEventListener('click', Controls.action)
40 |
41 | Controls.element = element
42 | Game.container.appendChild(element)
43 | Controls.refresh()
44 | }
45 | }
46 |
47 | Controls.apply = function(operation, names, value) {
48 | if (!Array.isArray(names)) names = [names]
49 | names.forEach(function(name) {
50 | var btn = Controls.buttons[name]
51 | switch (operation) {
52 | case 'disable': btn.setAttribute('disabled', true); break
53 | case 'enable': btn.removeAttribute('disabled'); break
54 | case 'show': btn.style.display = ''; break
55 | case 'hide': btn.style.display = 'none'; break
56 | case 'setTitle': btn.title = value; break
57 | case 'setShadow': btn.firstChild.style.boxShadow = value
58 | }
59 | })
60 | return this
61 | }
62 |
63 | Controls.refreshScore = function() {
64 | var score = document.getElementById('fo-score')
65 | score.innerHTML = Game.score
66 | }
67 |
68 | Controls.refresh = function() {
69 | if (!Game.running && !Game.dead) {
70 | Controls.apply('show', ['start', 'close']).apply('hide', ['restart', 'pause', 'unpause'])
71 | } else if(!Game.running && Game.dead) {
72 | Controls.apply('show', ['restart', 'close']).apply('hide', ['start', 'pause', 'unpause'])
73 | } else if (Game.running && !Game.paused) {
74 | Controls.apply('show', ['pause', 'close']).apply('hide', ['unpause', 'start', 'restart'])
75 | } else if (Game.running && Game.paused) {
76 | Controls.apply('show', ['unpause', 'restart', 'close']).apply('hide', ['pause', 'start'])
77 | }
78 | }
79 |
80 | Controls.close = function() {
81 | if (Controls.element) {
82 | Controls.element.parentNode.removeChild(Controls.element)
83 | Controls.element = null
84 | }
85 | }
86 |
87 | Controls.init()
88 |
--------------------------------------------------------------------------------
/contentscripts/game.js:
--------------------------------------------------------------------------------
1 | var Game = {
2 | running: false,
3 | paused: false,
4 | dead: false,
5 | intervalMove: 300,
6 | intervalFall: 250,
7 | score: 0
8 | }
9 |
10 | Game.graph = document.querySelector('.js-calendar-graph')
11 | Game.container = document.querySelector('.js-calendar-graph').parentNode
12 | Game.legend = document.querySelector('.contrib-legend')
13 |
14 | Game.init = function() {
15 | Game.container.setAttribute('fo-container', '')
16 | }
17 |
18 | Game.start = function() {
19 | Game.score = 0
20 | Game.intervalMove = 300
21 | Game.running = true
22 | Game.paused = false
23 | Game.dead = false
24 | Board.init()
25 | Board.start()
26 | }
27 |
28 | Game.restart = function() {
29 | Game.start()
30 | }
31 |
32 | Game.pause = function() {
33 | Game.running = true
34 | Game.paused = true
35 | Game.dead = false
36 | }
37 |
38 | Game.unpause = function() {
39 | Game.running = true
40 | Game.paused = false
41 | Game.dead = false
42 | Board.setUpInterval()
43 | }
44 |
45 | Game.close = function() {
46 | Game.running = false
47 | Game.paused = false
48 | Game.dead = false
49 | Board.close()
50 | Controls.close()
51 | }
52 |
53 | Game.addScore = function() {
54 | Game.score += 1
55 | Controls.refreshScore()
56 | }
57 |
58 | Game.die = function() {
59 | Game.running = false
60 | Game.dead = true
61 |
62 | Controls.refresh()
63 | }
64 |
65 | Game.init()
66 |
--------------------------------------------------------------------------------
/flappy-octocat.crx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chxj1992/flappy-octocat/030b23ecc5a6a412b36ad27f462495e4ffbde899/flappy-octocat.crx
--------------------------------------------------------------------------------
/icons/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chxj1992/flappy-octocat/030b23ecc5a6a412b36ad27f462495e4ffbde899/icons/.DS_Store
--------------------------------------------------------------------------------
/icons/icon-128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chxj1992/flappy-octocat/030b23ecc5a6a412b36ad27f462495e4ffbde899/icons/icon-128.png
--------------------------------------------------------------------------------
/icons/icon-16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chxj1992/flappy-octocat/030b23ecc5a6a412b36ad27f462495e4ffbde899/icons/icon-16.png
--------------------------------------------------------------------------------
/icons/icon-48.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chxj1992/flappy-octocat/030b23ecc5a6a412b36ad27f462495e4ffbde899/icons/icon-48.png
--------------------------------------------------------------------------------
/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "manifest_version": 2,
3 |
4 | "name": "Flappy Octocat",
5 | "description": "a chrome extension to play a flappy bird like game on github contributions board!",
6 | "version": "1.0.3",
7 | "icons": {
8 | "16": "icons/icon-16.png",
9 | "48": "icons/icon-48.png",
10 | "128": "icons/icon-128.png"
11 | },
12 | "page_action": {
13 | "default_icon": "icons/icon-48.png"
14 | },
15 | "background": {
16 | "scripts": ["background.js"]
17 | },
18 | "content_scripts": [
19 | {
20 | "matches": ["https://github.com/*"],
21 | "css": ["style.css"],
22 | "js": ["contentscripts/game.js", "contentscripts/board.js", "contentscripts/controls.js", "contentscripts/button.js"]
23 | }
24 | ],
25 | "permissions": [
26 | "tabs",
27 | "https://github.com/*"
28 | ]
29 | }
30 |
--------------------------------------------------------------------------------
/screenshot.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/chxj1992/flappy-octocat/030b23ecc5a6a412b36ad27f462495e4ffbde899/screenshot.gif
--------------------------------------------------------------------------------
/style.css:
--------------------------------------------------------------------------------
1 | [fo-container] {
2 | position: relative;
3 | }
4 |
5 | .border[fo-container] {
6 | border-color: transparent !important;
7 | }
8 |
9 | [fo-container] .flash-notice {
10 | display: none;
11 | }
12 |
13 | [fo-container="running"] li[style$="238);"] {
14 | opacity: .8;
15 | }
16 |
17 | [fo-container]:not([fo-container="running"])
18 |
19 | #tetrix-board li:hover {
20 | cursor: pointer;
21 | z-index: 2;
22 | outline: 1px solid rgba(30, 104, 35, .55);
23 | }
24 |
25 | #fo-board {
26 | position: absolute;
27 | top: -4px;
28 | left: -7px;
29 | width: calc(100% + 8px);
30 | height: 100%;
31 | background: #fff;
32 | }
33 |
34 | #fo-board:after {
35 | content: '';
36 | clear: both;
37 | display: block;
38 | visibility: hidden;
39 | }
40 |
41 | #fo-board ul {
42 | float: left;
43 | }
44 |
45 | #fo-board li {
46 | display: block;
47 | font-size: 0;
48 | width: 12px;
49 | height: 12px;
50 | background-color: #eee;
51 | transition: background-color .2s ease;
52 | position: relative;
53 | z-index: 1;
54 | box-sizing: border-box;
55 | border: 1px solid #fff;
56 | }
57 |
58 | #fo-button {
59 | float: left;
60 | margin-right: 1em;
61 | padding: 0 5px 0 13px;
62 | vertical-align: middle;
63 | transition: all .2s ease;
64 | color: #8cc665;
65 | box-shadow: rgba(140, 198, 101, .25) 0px 0px 0px 1px;
66 | border-radius: 2px;
67 | cursor: pointer;
68 | }
69 |
70 | #fo-button:hover {
71 | box-shadow: rgba(140, 198, 101, .69) 0px 0px 0px 1px;
72 | text-decoration: none;
73 | }
74 |
75 | #fo-button:before {
76 | content: '';
77 | display: inline-block;
78 | width: 4px;
79 | height: 4px;
80 | margin: -5px 4px 0 0;
81 | vertical-align: middle;
82 | color: #8cc665;
83 | box-shadow:
84 | -4px 0px #8cc665,
85 | -8px 4px #8cc665,
86 | -4px 4px #8cc665,
87 | 0 4px #8cc665;
88 | }
89 |
90 | #fo-controls {
91 | position: absolute;
92 | text-align: center;
93 | width: 100%;
94 | bottom: -32px;
95 | padding-left: 40px;
96 | }
97 | #fo-controls a {
98 | display: inline-block;
99 | position: relative;
100 | width: 5em;
101 | padding: 2px 0;
102 | margin: 0 2px;
103 | transition: all .2s ease;
104 | font-size: .8em;
105 | color: rgba(140, 198, 101, .8);
106 | text-decoration: none;
107 | border: 1px solid rgba(140, 198, 101, .3);
108 | border-radius: 2px;
109 | cursor: pointer;
110 | }
111 | #fo-controls a:after {
112 | content: attr(data-action);
113 | }
114 |
115 | @keyframes rotating {
116 | from { transform: rotate(45deg); }
117 | to { transform: rotate(0) }
118 | }
119 | #fo-controls a[data-action="close"] {
120 | position: relative;
121 | width: 20px;
122 | height: 20px;
123 | line-height: 0;
124 | margin-left: 10px;
125 | vertical-align: text-top;
126 | border:none;
127 | background: none;
128 | color: #d6e685;
129 | font-size: 0;
130 | -webkit-animation: rotating .2s ease;
131 | animation: rotating .2s ease;
132 | -webkit-transfom-origin: 50% 50%;
133 | transfom-origin: 50% 50%;
134 | }
135 | #fo-controls a[data-action="close"]:before,
136 | #fo-controls a[data-action="close"]:after {
137 | content: '';
138 | position: absolute;
139 | left: 50%;
140 | top: 50%;
141 | width: 61.8%;
142 | height: 1px;
143 | background: #bfd06b;
144 | -webkit-transfom-origin: 50% 50%;
145 | transfom-origin: 50% 50%;
146 | }
147 | #fo-controls a[data-action="close"]:before {
148 | -webkit-transform: translate(-50%, 0) rotate(-45deg);
149 | transform: translate(-50%, 0) rotate(-45deg);
150 | }
151 | #fo-controls a[data-action="close"]:after {
152 | -webkit-transform: translate(-50%, 0) rotate(45deg);
153 | transform: translate(-50%, 0) rotate(45deg);
154 | }
155 | #fo-controls a[data-action="close"]:hover:before,
156 | #fo-controls a[data-action="close"]:hover:after {
157 | background-color: #d0b96b;
158 | }
159 |
160 | #fo-controls a[data-action="start"] {
161 | border-color: rgba(140, 198, 101, 0.7);
162 | background-color: rgba(192, 247, 155, .13);
163 | }
164 | #fo-controls a[data-action="pause"] {
165 | background-color: rgba(214, 230, 133, .18);
166 | border-color: #d6e685;
167 | color: #9bb517;
168 | }
169 | #fo-controls a[disabled] {
170 | background: transparent;
171 | border-color: rgba(160, 165, 157, .69);;
172 | color: rgba(160, 165, 157, .69);
173 | opacity: .5;
174 | cursor: default;
175 | }
176 | #fo-controls a[data-action="start"]:not([disabled]):hover {
177 | background-color: rgba(237, 255, 200, .35);
178 | }
179 |
180 | #fo-score {
181 | position: absolute;
182 | left: 0px;
183 | top: -10px;
184 | font-size: 12px;
185 | color: #b6b6b6;
186 | }
187 | #fo-score:before {
188 | content: 'Score: ';
189 | margin-right: 2px;
190 | }
191 |
--------------------------------------------------------------------------------