Bitcoin Forum
December 15, 2019, 06:10:07 AM *
News: Latest Bitcoin Core release: 0.19.0.1 [Torrent]
 
   Home   Help Search Login Register More  
Pages: [1] 2 3 4 5 6 7 »  All
  Print  
Author Topic: In which language top gambling sites are coded ?  (Read 12507 times)
RocketSingh
Legendary
*
Offline Offline

Activity: 1624
Merit: 1032


View Profile
September 22, 2014, 08:59:54 PM
Last edit: March 31, 2019, 11:58:56 AM by RocketSingh
Merited by LoyceV (4), DarkStar_ (4), Welsh (2), tyz (1), xandry (1)
 #1

Busy gambling sites need to provide high security as well as serve high traffic. In which language today's top sites are coded ? Which DB are they using ?

I'm listing a few sites below. Please post if u know about their configuration. If u know about a site which is not in the list, please post that too...

Following table is updated as per latest data found in this thread...


SiteServerBackendSocket libDB/StorageFrontend
Just-Dice.com                    Node.js               socket.io             redis+MySQL      
PrimeDice.comCowboyNode.jssocket.ioPostgreSQLEmberJS
DiceBitco.innginxNode.js+ExpressPrimusAngularJS
Dicenow.comnginxNode.js+Expresssocket.ioAngularJS
Satoshibet.comnginxNode.jssocket.iomySQL+mongoDB
MoneyPot.comCowboyNode.jssocket.ioPostgreSQLReact
PRCDice.euMS-IIS.NETSignalR
Win88.meMS-IIS.NETServiceStackAngularJS
Peerbet.orgMS-IIS.NET---
Dice.ninjacyclonePythonsockjs-cycloneMySQL
luckyb.itPython+Flask---
Rollin.ioApachePHP+laravelsocket.io
BitDice.menginxRoR+RabbitMQRedis+MySQL
PocketDice.ionginxPHPsocket.io---AngularJS
FastSlots.covanillanode.jssocket.iomySQLbackbone
FastDice.comApachePHP---------
777Coin.com---PHP---------
Bitvest.io---PHP---------


1576390207
Hero Member
*
Offline Offline

Posts: 1576390207

View Profile Personal Message (Offline)

Ignore
1576390207
Reply with quote  #2

1576390207
Report to moderator
Advertised sites are not endorsed by the Bitcoin Forum. They may be unsafe, untrustworthy, or illegal in your jurisdiction. Advertise here.
RoooooR
Legendary
*
Offline Offline

Activity: 1008
Merit: 1000


GigTricks.io | A CRYPTO ECOSYSTEM FOR ON-DEMAND EC


View Profile
September 22, 2014, 09:02:28 PM
 #2

0. Just-Dice.com - I don't know,

1. PrimeDice.com - EmberJS

2. DiceBitco.in - Angular, probably with Mean

4. PRCDice.eu - I don't want to know

3. Dice.ninja - Python

5. Win88.me - I don't know

6. Rollin.io - Php, it's copy from satoshibet.com, as all-dice

PD and JD must be using hadoop too, I'd like to know what SQL they are using.


            █ █ █ █ █
         ██           ██
       ██     █ █ █ █   ██
     ██    ██        ██
   ██   ██               
  ██   ██     ████████                  ██████████
            ███          ██   █████████     ██      ██████  ██   ███████  ██    ███   ███████
 ██   ██    ███              ██      ███    ██      ██          ███       ██   ███  ██
 ██   ██    ███  ██████  ██  ██      ███    ██      ██      ██  ███       ██  ███   ██
            ███      ██  ██  ██      ███    ██      ██      ██  ███       ██████     ███████
 ██   ██    ███      ██  ██  ██      ███    ██      ██      ██  ███       ██  ██           ██
             ██      ██  ██  ██      ███    ██      ██      ██  ███       ██   ███         ██
 ██   ██      ███████    ██   █████████     ██      ██      ██   ███████  ██    ███  ███████
  ██   ██                           ███
   ██    ██          ██            ███
     ██    ██ █ █ █ █   ██
       ██             ██
          █ █ █ █ █ █
























Telegram     Facebook     Twitter     Medium
-------------------------------------------------------------------
.WEBSITE. |█| .WHITEPAPER.












......BOUNTY......
-----------------------------------
..ANN THREAD..
RocketSingh
Legendary
*
Offline Offline

Activity: 1624
Merit: 1032


View Profile
September 22, 2014, 09:12:16 PM
 #3

0. Just-Dice.com - I don't know,

1. PrimeDice.com - EmberJS

2. DiceBitco.in - Angular, probably with Mean

4. PRCDice.eu - I don't want to know

3. Dice.ninja - Python

5. Win88.me - I don't know

6. Rollin.io - Php, it's copy from satoshibet.com, as all-dice

PD and JD must be using hadoop too, I'd like to know what SQL they are using.

If your info is correct, then the high volume sites are avoiding PHP-MySQL. Why so ? I have seen PHP-MySQL to efficiently handle big traffic. What may be the average concurrent connection of the top 3 ? Is there any security problem with PHP-MySQL coded gambling sites ?
RoooooR
Legendary
*
Offline Offline

Activity: 1008
Merit: 1000


GigTricks.io | A CRYPTO ECOSYSTEM FOR ON-DEMAND EC


View Profile
September 22, 2014, 09:18:26 PM
 #4

0. Just-Dice.com - I don't know,

1. PrimeDice.com - EmberJS

2. DiceBitco.in - Angular, probably with Mean

4. PRCDice.eu - I don't want to know

3. Dice.ninja - Python

5. Win88.me - I don't know

6. Rollin.io - Php, it's copy from satoshibet.com, as all-dice

PD and JD must be using hadoop too, I'd like to know what SQL they are using.

If your info is correct, then the high volume sites are avoiding PHP-MySQL. Why so ? I have seen PHP-MySQL to efficiently handle big traffic. What may be the average concurrent connection of the top 3 ? Is there any security problem with PHP-MySQL coded gambling sites ?
I don't have deep knowledge in security and SQL stuff, as I said, I'd like to know it too Smiley
Also that list is based on my prediction.


            █ █ █ █ █
         ██           ██
       ██     █ █ █ █   ██
     ██    ██        ██
   ██   ██               
  ██   ██     ████████                  ██████████
            ███          ██   █████████     ██      ██████  ██   ███████  ██    ███   ███████
 ██   ██    ███              ██      ███    ██      ██          ███       ██   ███  ██
 ██   ██    ███  ██████  ██  ██      ███    ██      ██      ██  ███       ██  ███   ██
            ███      ██  ██  ██      ███    ██      ██      ██  ███       ██████     ███████
 ██   ██    ███      ██  ██  ██      ███    ██      ██      ██  ███       ██  ██           ██
             ██      ██  ██  ██      ███    ██      ██      ██  ███       ██   ███         ██
 ██   ██      ███████    ██   █████████     ██      ██      ██   ███████  ██    ███  ███████
  ██   ██                           ███
   ██    ██          ██            ███
     ██    ██ █ █ █ █   ██
       ██             ██
          █ █ █ █ █ █
























Telegram     Facebook     Twitter     Medium
-------------------------------------------------------------------
.WEBSITE. |█| .WHITEPAPER.












......BOUNTY......
-----------------------------------
..ANN THREAD..
jspielberg
Sr. Member
****
Offline Offline

Activity: 448
Merit: 250



View Profile
September 23, 2014, 01:15:41 AM
 #5

I am under the impression that PrimeDice backend is written in php with a socket server in nodejs

I guess we gotta wait for stunna for comment on this
DaveSaldana123
Full Member
***
Offline Offline

Activity: 135
Merit: 100

A.K.A The Black Marvel


View Profile
September 23, 2014, 03:26:11 AM
 #6

I am under the impression that PrimeDice backend is written in php with a socket server in nodejs

I guess we gotta wait for stunna for comment on this

Hey stunna, did you wrote this code in php?

Stunna
Legendary
*
Offline Offline

Activity: 2450
Merit: 1143


Advisor @ Primedice.com, Stake.com


View Profile WWW
September 23, 2014, 04:06:32 AM
 #7

I am under the impression that PrimeDice backend is written in php with a socket server in nodejs

I guess we gotta wait for stunna for comment on this

Primedice uses Node.js alongside PostgreSQL. Ember.js (front end) 100% PHP free. We are able to handle a significant amount of load with clustered servers and heavy DB optimization. We completely threw away all the problematic PHP code that was used for PD2.


Stake.com Fastest growing crypto casino
Primedice.com The original bitcoin instant dice game
RocketSingh
Legendary
*
Offline Offline

Activity: 1624
Merit: 1032


View Profile
September 23, 2014, 09:19:55 AM
 #8

I am under the impression that PrimeDice backend is written in php with a socket server in nodejs

I guess we gotta wait for stunna for comment on this

Primedice uses Node.js alongside PostgreSQL. Ember.js (front end) 100% PHP free. We are able to handle a significant amount of load with clustered servers and heavy DB optimization. We completely threw away all the problematic PHP code that was used for PD2.



Thank U Stunna for dropping by. So, does it mean that till PD2 a few months ago PHP-PostgreSQL was doing fine in handling traffic ? I'm asking this because elsewhere another Dice site owner is moving from PHP to Java for better performance. Is PHP less efficient in handling concurrency just because it does not support threading like Java ? Then, how come FaceBook is running primarily on PHP ?

Since you bought the site in June it seems like there was less than 20 BTC wagered total. How much revenue did that generate?

We don't release the numbers, but it was a decent amount for a smaller site.

Why r u doing the next version with investment feature in Java instead of PHP ?

Java is better language and gives us the same performance as an exchange.

I'm sorry to contradict U in this regard. Why r u saying that Java is better than PHP ? Does not it depend on the coder ? Otherwise, how Facebook is primarily running on PHP ? AFAIK tomcat is not good to support big traffic, U need to go for JBOSS.

Moreover, if someone buys your PHP script, it would be difficult for him/her to upgrade to the next version, if that's written in Java. Not only the Xamp settings need to be exported to Tomcat, but also DB connection etc. need to be changed.


No we used mysql and tomcat proxy thru nginx is great for high concurrency. But this isn't the place to debate that.

Ok... one last question. What is the highest no. of concurrent connections u have experienced on FastBluff.com as per Google Analytics or whatever u have used ?

We were getting a good amount of people a day using the site (Not really going to release that since this is such a low starting bid, to be honest this deal is a steal, if that doesn't show that we don't care about the profit on the sale of site, I don't know what would. We want the site to have a good home and help some budding person get a good start if dice sites are something they want to do). The concurrency was more of a database issue, when we would be going to investments and rolls. We were getting a lot of rolls at once, that were taking down the site, so the php code actually has a limiter on it. With the java code we would be able remove that limiter, as well as we would be able to do investments better and faster.

I am not going to use this form to debate why I choose to move on from the php code to java, it was a decision that was made, when we were 100% sure we wanted to pursuit that, and just as music comes to musicians heads, we found other interest that made us want to build and do those.

The amount of things you are getting for 1 BTC is ridiculous you are getting 2 complete sites, 3 domain names.

We are a private company and start opening the books look like that, isn't something we choose to do now.

Also if my answers before where confusing, it was because I was on a phone now I am at a computer and can write out long descriptions to answer questions.

I'd also like to hear from site owners that allows investment whether PHP has any constraint about doing instant profit sharing ?
grux
Member
**
Offline Offline

Activity: 67
Merit: 10


View Profile
September 23, 2014, 03:25:58 PM
 #9


Thank U Stunna for dropping by. So, does it mean that till PD2 a few months ago PHP-PostgreSQL was doing fine in handling traffic ? I'm asking this because elsewhere another Dice site owner is moving from PHP to Java for better performance. Is PHP less efficient in handling concurrency just because it does not support threading like Java ? Then, how come FaceBook is running primarily on PHP ?


It's not that PHP or mySQL is necessarily bad, it can handle traffic just fine under the right conditions.Facebook and PHP can kinda be seen as a mistake from their end, they've put crazy amounts of money of compiling it to C++ to avoid the pitfalls of PHP. Node.js offers interesting and easy handling of async. PHP should have no effect on profit...
addi
Hero Member
*****
Offline Offline

Activity: 627
Merit: 500


https://satoshibet.com


View Profile WWW
September 23, 2014, 03:35:32 PM
 #10

SatoshiBet.com is coded in node.js

m19
Full Member
***
Offline Offline

Activity: 186
Merit: 100


View Profile
September 23, 2014, 04:38:31 PM
 #11

Most sites use Node.js for the backend. Mainly because it's the easiest (not always the best though) way to built a real time site handling a nice amount of users.

But my guess is we'll be seeing a lot more Go in the coming years. Built a small dice project in that handling 10.000 rolls in about 500ms.

Just Dice was also built in Node.js + MySQL by the way.
dooglus
Legendary
*
Offline Offline

Activity: 2758
Merit: 1210



View Profile
September 23, 2014, 05:11:22 PM
 #12

Most sites use Node.js for the backend. Mainly because it's the easiest (not always the best though) way to built a real time site handling a nice amount of users.

But my guess is we'll be seeing a lot more Go in the coming years. Built a small dice project in that handling 10.000 rolls in about 500ms.

Just Dice was also built in Node.js + MySQL by the way.

Just-Dice uses redis as well as MySQL.

Just-Dice                 ██             
          ██████████         
      ██████████████████     
  ██████████████████████████ 
██████████████████████████████
██████████████████████████████
██████████████████████████████
██████████████████████████████
██████████████████████████████
██████████████████████████████
██████████████████████████████
██████████████████████████████
██████████████████████████████
    ██████████████████████   
        ██████████████       
            ██████           
   Play or Invest                 ██             
          ██████████         
      ██████████████████     
  ██████████████████████████ 
██████████████████████████████
██████████████████████████████
██████████████████████████████
██████████████████████████████
██████████████████████████████
██████████████████████████████
██████████████████████████████
██████████████████████████████
██████████████████████████████
    ██████████████████████   
        ██████████████       
            ██████           
   1% House Edge
grux
Member
**
Offline Offline

Activity: 67
Merit: 10


View Profile
September 23, 2014, 05:28:57 PM
 #13

Most sites use Node.js for the backend. Mainly because it's the easiest (not always the best though) way to built a real time site handling a nice amount of users.

But my guess is we'll be seeing a lot more Go in the coming years. Built a small dice project in that handling 10.000 rolls in about 500ms.

Just Dice was also built in Node.js + MySQL by the way.

Just-Dice uses redis as well as MySQL.

Did you store all the J-D bets on the MySQL DB, I've been trying to figure out a cool way to store crazy amounts of bets (think tens of terrabytes) without having the weirdest SQL database on earth.
Dobry Den
Newbie
*
Offline Offline

Activity: 41
Merit: 0


View Profile
September 23, 2014, 05:33:19 PM
 #14

The main point of focus for building a gambling site is ensuring data/domain integrity at the database level.

You need to be able to answer questions like:

- What happens to in-flight DB transactions when they fail or the app crashes?
- Are all of your domain-atomic data updates wrapped in transactions? For example, if the server crashes right after you increment my account balance but before you decrement your house bankroll, is my balance rolled back or did you just persist a bad ledger?
- If your provably-fair mechanism depends on sequential, gapless nonces (like Just-Dice's "bet number"), can you actually guarantee a gapless sequence? For example, AUTOINCREMENT in MySQL and SERIAL In Postgres do not produce gapless sequences.
- What do you do when the values change out from under your DB transactions? If some button should only increment a value in the DB once per hour and someone double-clicks it (launches two queries in flight at once), is the value incremented twice (bad)? Is it incremented once only because the queries both incremented the initial value (bad)? Or is it only incremented once because the second query fails because of your one-increment-per-hour domain constraint (good)?

The stack you use for your application layer matters very little because what matters is your ability to sufficiently answer these types of questions.
m19
Full Member
***
Offline Offline

Activity: 186
Merit: 100


View Profile
September 23, 2014, 05:46:55 PM
 #15

The main point of focus for building a gambling site is ensuring data/domain integrity at the database level.

You need to be able to answer questions like:

- What happens to in-flight DB transactions when they fail or the app crashes?
- Are all of your domain-atomic data updates wrapped in transactions? For example, if the server crashes right after you increment my account balance but before you decrement your house bankroll, is my balance rolled back or did you just persist a bad ledger?
- If your provably-fair mechanism depends on sequential, gapless nonces (like Just-Dice's "bet number"), can you actually guarantee a gapless sequence? For example, AUTOINCREMENT in MySQL and SERIAL In Postgres do not produce gapless sequences.
- What do you do when the values change out from under your DB transactions? If some button should only increment a value in the DB once per hour and someone double-clicks it (launches two queries in flight at once), is the value incremented twice (bad)? Is it incremented once only because the queries both incremented the initial value (bad)? Or is it only incremented once because the second query fails because of your one-increment-per-hour domain constraint (good)?

The stack you use for your application layer matters very little because what matters is your ability to sufficiently answer these types of questions.

You shouldn't use the ID for nonces in my opinion. Just add an extra DB field for the nonce. Only way to really prove it.

I like your thoughts on transactions. This should be used more often I think. Using transactions they will only be committed when all are successful. Nothing will (should) happen if one query fails / the app crashes.

How would you deal with your last point? This is always interesting and I haven't found a very good way to deal with it.
RoooooR
Legendary
*
Offline Offline

Activity: 1008
Merit: 1000


GigTricks.io | A CRYPTO ECOSYSTEM FOR ON-DEMAND EC


View Profile
September 23, 2014, 06:28:47 PM
 #16

But my guess is we'll be seeing a lot more Go in the coming years. Built a small dice project in that handling 10.000 rolls in about 500ms.


10K bets in 500ms?.. incredible. I really wonder how did you achieve that? I mean, there are stuffs like calculating lucky number, inserting to DB, broadcasting to user again etc..


            █ █ █ █ █
         ██           ██
       ██     █ █ █ █   ██
     ██    ██        ██
   ██   ██               
  ██   ██     ████████                  ██████████
            ███          ██   █████████     ██      ██████  ██   ███████  ██    ███   ███████
 ██   ██    ███              ██      ███    ██      ██          ███       ██   ███  ██
 ██   ██    ███  ██████  ██  ██      ███    ██      ██      ██  ███       ██  ███   ██
            ███      ██  ██  ██      ███    ██      ██      ██  ███       ██████     ███████
 ██   ██    ███      ██  ██  ██      ███    ██      ██      ██  ███       ██  ██           ██
             ██      ██  ██  ██      ███    ██      ██      ██  ███       ██   ███         ██
 ██   ██      ███████    ██   █████████     ██      ██      ██   ███████  ██    ███  ███████
  ██   ██                           ███
   ██    ██          ██            ███
     ██    ██ █ █ █ █   ██
       ██             ██
          █ █ █ █ █ █
























Telegram     Facebook     Twitter     Medium
-------------------------------------------------------------------
.WEBSITE. |█| .WHITEPAPER.












......BOUNTY......
-----------------------------------
..ANN THREAD..
m19
Full Member
***
Offline Offline

Activity: 186
Merit: 100


View Profile
September 23, 2014, 07:19:40 PM
 #17

But my guess is we'll be seeing a lot more Go in the coming years. Built a small dice project in that handling 10.000 rolls in about 500ms.


10K bets in 500ms?.. incredible. I really wonder how did you achieve that? I mean, there are stuffs like calculating lucky number, inserting to DB, broadcasting to user again etc..

Hehe, I should have mentioned it only returned the profit/loss of those rolls combined to the user. It did simulate (so calculate the lucky number etc) and insert 10.000 rolls in the DB at once though, so with a single query, not repeating an insert query 10.000 times. It also updated the user balance at once too after all the rolls were done.

I bet this will be fast in other languages too.
RocketSingh
Legendary
*
Offline Offline

Activity: 1624
Merit: 1032


View Profile
September 24, 2014, 10:16:04 AM
 #18

But my guess is we'll be seeing a lot more Go in the coming years. Built a small dice project in that handling 10.000 rolls in about 500ms.


10K bets in 500ms?.. incredible. I really wonder how did you achieve that? I mean, there are stuffs like calculating lucky number, inserting to DB, broadcasting to user again etc..

Hehe, I should have mentioned it only returned the profit/loss of those rolls combined to the user. It did simulate (so calculate the lucky number etc) and insert 10.000 rolls in the DB at once though, so with a single query, not repeating an insert query 10.000 times. It also updated the user balance at once too after all the rolls were done.

I bet this will be fast in other languages too.

Committing 10k rolls at a time may go against the atomic consistency of the DB resulting in unexpected effect to the bankroll (+ve/-ve).
dogedice.me
Hero Member
*****
Offline Offline

Activity: 742
Merit: 517



View Profile WWW
September 24, 2014, 12:55:27 PM
 #19

BitDice.me and family use RoR with Redis & RabbitMQ as backend, MySQL as main database.

Most sites choose node.js because of websockets.

.BitDice.               ▄▄███▄▄
           ▄▄██▀▀ ▄ ▀▀██▄▄
      ▄▄█ ▀▀  ▄▄█████▄▄  ▀▀ █▄▄
  ▄▄██▀▀     ▀▀ █████ ▀▀     ▀▀██▄▄
██▀▀ ▄▄██▀      ▀███▀      ▀██▄▄ ▀▀██
██  ████▄▄       ███       ▄▄████  ██
██  █▀▀████▄▄  ▄█████▄  ▄▄████▀▀█  ██
██  ▀     ▀▀▀███████████▀▀▀     ▀  ██
             ███████████
██  ▄     ▄▄▄███████████▄▄▄     ▄  ██
██  █▄▄████▀▀  ▀█████▀  ▀▀████▄▄█  ██
██  ████▀▀       ███       ▀▀████  ██
██▄▄ ▀▀██▄      ▄███▄      ▄██▀▀ ▄▄██
  ▀▀██▄▄     ▄▄ █████ ▄▄     ▄▄██▀▀
      ▀▀█ ▄▄  ▀▀█████▀▀  ▄▄ █▀▀
           ▀▀██▄▄ ▀ ▄▄██▀▀
               ▀▀███▀▀
        ▄▄███████▄▄
     ▄███████████████▄
    ████▀▀       ▀▀████
   ████▀           ▀████
   ████             ████
   ████ ▄▄▄▄▄▄▄▄▄▄▄ ████
▄█████████████████████████▄
██████████▀▀▀▀▀▀▀██████████
████                   ████
████                   ████
████                   ████
████                   ████
████                   ████
████▄                 ▄████
████████▄▄▄     ▄▄▄████████
  ▀▀▀█████████████████▀▀▀
        ▀▀▀█████▀▀▀
▄▄████████████████████████████████▄▄
██████████████████████████████████████
█████                            █████
█████                            █████
█████                            █████
█████                            █████
█████                     ▄▄▄▄▄▄▄▄▄▄
█████                   ▄█▀▀▀▀▀▀▀▀▀▀█▄
█████                   ██          ██
█████                   ██          ██
█████                   ██          ██
██████████████████▀▀███ ██          ██
 ████████████████▄  ▄██ ██          ██
   ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀ ██          ██
             ██████████ ██          ██
           ▄███████████ ██████▀▀██████
          █████████████  ▀████▄▄████▀
[/]
Dobry Den
Newbie
*
Offline Offline

Activity: 41
Merit: 0


View Profile
September 24, 2014, 03:12:12 PM
 #20

Committing 10k rolls at a time may go against the atomic consistency of the DB resulting in unexpected effect to the bankroll (+ve/-ve).

The bulk insert is applied atomically, but each inserted row still has to respect its constraints.

One big reason you'd want to accumulate rolls in-memory and then commit them to the DB in bulk is if each roll needs to be applied sequentially to the DB and you don't want sequential roll insertion to be the bottleneck.

For example, imagine if each roll needs to calculate the total house bankroll to adjust the edge of the roll. The bankroll changes each roll. If each roll has to hit the DB server, then you're going to be dealing with a lot of insert contention.

Instead, let's say you only make one DB insertion at the turn of each second. As rolls come in, you buffer the results in memory (assured that the DB cannot change during this time) and then commit all the rolls at once.

Here's an idea: imagine if you write a function `roll(prevDB, params)` that returns `newDB` where prevDB and newDB are just associative datastructures that represent the state of the DB in memory.

That means you can `reduce(roll, prevDB, [params, ...])` where `[params, ...]` is a sequence of user roll parameters coming down, say, a websocket.

At the turn of each second, you stop the reduction, take the latest newDB value (the result of all the buffered rolls), and commit it to the DB. The post-commit value of the DB is now your `prevDB` that you feed back into the reduction and resume processing rolls.

Pages: [1] 2 3 4 5 6 7 »  All
  Print  
 
Jump to:  

Sponsored by , a Bitcoin-accepting VPN.
Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!