[Question]
  [
## Introduction
*Last year* was my birthday (really!) and sadly I had to organise my own party. Well, now you know, couldn't you at least make the cake?
## Challenge
Given an integer `n` as input, write a *full program* to output a birthday cake with `n` candles on.
## Output
A piece of cake with one candle on is:
```
 $
 |
---
~~~
---
```
And a piece of cake with three candles on is:
```
 $ $ $
 | | |
-------
~~~~~~~
-------
```
I'm sure you can work it out from that
***However***, for input `0`, you must output the following:
```
Congratulations on your new baby! :D
```
For input less than `0`, you should output a candleless cake:
```
---
~~~
---
```
Nothing is allowed to be output to STDERR.
Trailing newlines and spaces are allowed.
## Winning
Shortest code in bytes wins.
## Leaderboard
```
var QUESTION_ID=57277;OVERRIDE_USER=30525;function answersUrl(e){return"http://api.stackexchange.com/2.2/questions/"+QUESTION_ID+"/answers?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+ANSWER_FILTER}function commentUrl(e,s){return"http://api.stackexchange.com/2.2/answers/"+s.join(";")+"/comments?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+COMMENT_FILTER}function getAnswers(){jQuery.ajax({url:answersUrl(answer_page++),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){answers.push.apply(answers,e.items),answers_hash=[],answer_ids=[],e.items.forEach(function(e){e.comments=[];var s=+e.share_link.match(/\d+/);answer_ids.push(s),answers_hash[s]=e}),e.has_more||(more_answers=!1),comment_page=1,getComments()}})}function getComments(){jQuery.ajax({url:commentUrl(comment_page++,answer_ids),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){e.items.forEach(function(e){e.owner.user_id===OVERRIDE_USER&&answers_hash[e.post_id].comments.push(e)}),e.has_more?getComments():more_answers?getAnswers():process()}})}function getAuthorName(e){return e.owner.display_name}function process(){var e=[];answers.forEach(function(s){var r=s.body;s.comments.forEach(function(e){OVERRIDE_REG.test(e.body)&&(r="<h1>"+e.body.replace(OVERRIDE_REG,"")+"</h1>")});var a=r.match(SCORE_REG);a&&e.push({user:getAuthorName(s),size:+a[2],language:a[1],link:s.share_link})}),e.sort(function(e,s){var r=e.size,a=s.size;return r-a});var s={},r=1,a=null,n=1;e.forEach(function(e){e.size!=a&&(n=r),a=e.size,++r;var t=jQuery("#answer-template").html();t=t.replace("{{PLACE}}",n+".").replace("{{NAME}}",e.user).replace("{{LANGUAGE}}",e.language).replace("{{SIZE}}",e.size).replace("{{LINK}}",e.link),t=jQuery(t),jQuery("#answers").append(t);var o=e.language;/<a/.test(o)&&(o=jQuery(o).text()),s[o]=s[o]||{lang:e.language,user:e.user,size:e.size,link:e.link}});var t=[];for(var o in s)s.hasOwnProperty(o)&&t.push(s[o]);t.sort(function(e,s){return e.lang>s.lang?1:e.lang<s.lang?-1:0});for(var c=0;c<t.length;++c){var i=jQuery("#language-template").html(),o=t[c];i=i.replace("{{LANGUAGE}}",o.lang).replace("{{NAME}}",o.user).replace("{{SIZE}}",o.size).replace("{{LINK}}",o.link),i=jQuery(i),jQuery("#languages").append(i)}}var ANSWER_FILTER="!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe",COMMENT_FILTER="!)Q2B_A2kjfAiU78X(md6BoYk",answers=[],answers_hash,answer_ids,answer_page=1,more_answers=!0,comment_page;getAnswers();var SCORE_REG=/<h\d>\s*([^\n,]*[^\s,]),.*?(\d+)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/,OVERRIDE_REG=/^Override\s*header:\s*/i;
```
```
body{text-align:left!important}#answer-list,#language-list{padding:10px;width:290px;float:left}table thead{font-weight:700}table td{padding:5px}
```
```
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b"> <div id="answer-list"> <h2>Leaderboard</h2> <table class="answer-list"> <thead> <tr><td></td><td>Author</td><td>Language</td><td>Size</td></tr></thead> <tbody id="answers"> </tbody> </table> </div><div id="language-list"> <h2>Winners by Language</h2> <table class="language-list"> <thead> <tr><td>Language</td><td>User</td><td>Score</td></tr></thead> <tbody id="languages"> </tbody> </table> </div><table style="display: none"> <tbody id="answer-template"> <tr><td>{{PLACE}}</td><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table> <table style="display: none"> <tbody id="language-template"> <tr><td>{{LANGUAGE}}</td><td>{{NAME}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table>
```
  
[Answer]
# Pyth, ~~73~~ ~~72~~ ~~71~~ ~~69~~ 67 bytes
```
?Qjb+m*+\ dQ"$|"*RhyeS,1Q"-~-""Congratulations on your new baby! :D
```
Try it [online](https://pyth.herokuapp.com/?code=%3FQjb%2Bm%2A%2B%5C+dQ%22%24%7C%22%2ARhyeS%2C1Q%22-%7E-%22%22Congratulations+on+your+new+baby%21+%3AD&input=3&debug=0).
Output for n < 0 contains 2 leading newlines, as permitted in [comments](https://codegolf.stackexchange.com/questions/57277/its-my-birthday-d/57282#comment137794_57277). To get rid of them, use
```
?QjbfT+jR*\ hQ"$|"*RhyeS,1Q"-~-""Congratulations on your new baby! :D
```
[Answer]
# CJam, ~~76~~ 75 bytes
```
ri_W>\_1e>)" $ |--~~--"2/f*Wf<N*"Congratulations on your new baby! :D"?_8>?
```
Try it online in the [CJam interpreter](http://cjam.aditsu.net/#code=ri_W%3E%5C_1e%3E)%22%20%24%20%7C--~~--%222%2Ff*Wf%3CN*%22Congratulations%20on%20your%20new%20baby!%20%3AD%22%3F_8%3E%3F&input=18).
### How it works
```
ri           e# Read an integer from STDIN.
_W>          e# Check if it is greater than -1.
\_           e# Swap input and Boolean and copy the input.
1e>)         e# Take the maximum of input and 1 and increment the result.
             e# Let's call the result R.
" $ |--~~--" e# Push that string.
2/           e# Split it into [" $" " |" "--" "~~" "--"].
f*           e# Repeat each chunk R times.
Wf<          e# Discard the last character of each repeated chunk.
N*           e# Join the repreated chunks, separating by linefeeds.
"Congratulations on your new baby! :D"
?            e# If the input is non-zero, select the cake; else, keep the string.
_8>          e# Push a copy and discard the first 8 characters (single candle).
?            e# Select the unmodified cake/string if the input was non-negative,
             e# a candleless cake otherwise.
```
[Answer]
# Ruby, 120 bytes
## Revision 1 (120 bytes)
18 bytes saved thanks to manatwork
```
n=gets.to_i
puts ['Congratulations on your new baby! :D',%w{\ $ \ | - ~ -}.map{|e|e.ljust 2*n+1,e},'---
~~~
---'][n<=>0]
```
## Revision 0 (138 bytes)
```
n=gets.to_i
n>0&&[' $',' |',?-,?~,?-].each{|e|puts''.rjust(2*n+1,e)}
puts ['Congratulations on your new baby! :D','','---
~~~
---'][n<=>0]
```
For positive numbers: this iterates through a string corresponding to each line of the cake. These are used as pad strings to right justify the empty string to length 2\*n+1. This avoids any complications with having to print an odd number of characters, when the natural repetition is equal to the pitch of the candles (i.e. 2 characters.) `n>0&&` is necessary to avoid outputting a single column in case of input zero.
For all numbers: "`n<=>0`" finds the sign of the input. The baby message is output for n=0, and an empty string for positive n (as correct output has already been given above.) For negative n, Ruby interprets the -1 as meaning the last element of the array, and outputs the candleless cake. 
[Answer]
## R, 157
```
write(if(n<-scan()){
z=matrix(c("$","|","-","~","-"),N<-2*max(1,n)+1,5,T)
z[seq(1,N,1+(n>0)),1:2]=" "
z}else"Congratulations on your new baby! :D","",N,F,"")
```
[Answer]
# JavaScript ES6, 136
Using alert for output - bad proportional font and the result is ugly. In the snippet below the alert is redirect to the snipped body, giving a better result.  
The newline inside backticks is significant and counted.
Test running the snippet in Firefox.
```
/* Redefine alert for testing purpose */ alert=x=>O.innerHTML=x;
alert((n=+prompt())?[...'$|-~-'].map((c,i)=>(i>1?c:' '+c).repeat(i>1?n>0?n-~n:3:n>0&&n)).join`
`:'Congratulations on your new baby! :D')
```
```
<pre id=O></pre>
```
**Less golfed**
```
n=+prompt(); // get input and convert to number
if (n) { // if n != 0 prepare the cake
   output = [...'$|-~-'].map( // for each char of the five lines
     (c,i) => (i>1 ? c : ' '+c) // in line 0 and 1 symbols are space separated
     // if n < 0 repeat count is 0 for line 0 and 1, 3 for the other
     // if n > 0 repeat count is n for line 0 and 1, n+n+1 for the other
     .repeat(i>1 ? n>0 ? n-~n : 3 : n>0 && n) // 
   ).join`\n`;
}
else {
    output = 'Congratulations on your new baby! :D');
}
alert(output);
```
[Answer]
# R, ~~228~~ ~~226~~ ~~220~~ 221 Bytes
---
Last edit to correct the candleless cake, was as wide as the positive one on negative cases, thanks @CathG and @jbaums for the feedback
```
n=scan()
s=strsplit
p=paste0
a=b='-~-'
if(!n)cat('Congratulations on your new baby! :D')else{
if(n>0){a=p('  ',a);b=p('$|',b)}else n=1
a=s(a,'')
b=s(b,'')
d=data.frame(rep(c(a,b),n),a)
cat(do.call(p,d),sep="\n")}
```
[Answer]
# R, 279 bytes
Interactive version (286 bytes):
```
b<-function(){
n=scan()
if(n==0)cat("Congratulations on your new baby! :D\n")
if(n>0){k=2*n+1;m=rep("-",k);cat(paste(c(rep(c(" ","$"),l=k),"\n",rep(c(" ","|"),l=k),"\n",m,"\n",rep("~",k),"\n",m,"\n"),collapse=""))}
if(n<0){m=rep("-",3);cat(paste(c(m,"\n",rep("~",3),"\n",m,"\n"),collapse=""))}
}
```
Not interactive version (279 bytes):
```
b<-function(n){
if(n==0)cat("Congratulations on your new baby! :D\n")
if(n>0){k=2*n+1;m<-rep("-",k);cat(paste(c(rep(c(" ","$"),l=k),"\n",rep(c(" ","|"),l=k),"\n",m,"\n",rep("~",k),"\n",m,"\n"),collapse=""))}
if(n<0){m=rep("-",3);cat(paste(c(m,"\n",rep("~",3),"\n",m,"\n"),collapse=""))}
}
```
[Answer]
# MATLAB / Octave, ~~194~~ ~~198~~ ~~195~~ ~~189~~ ~~171~~ 167 bytes
## Happy birthday to you Beta Decay! :)
### Thanks to HamtaroWarrior for shaving off 4 bytes!
---
```
n=input('');m='$|'.';d='  '.';if(n==0)disp('Congratulations on your new baby! :D'),break;elseif(n<0)m=d;n=1;end,disp([[d repmat([m d],1,n)];repmat('-~-'.',1,2*n+1)]);
```
---
# Sample Runs
I placed this into a script file called `happy_birthday.m`, then ran it a few times in the command prompt. Take note that when you enter in a negative number, there are two leading carriage returns, but that's allowed in this challenge:
```
>> happy_birthday
-1
---
~~~
---
>> happy_birthday
0
Congratulations on your new baby! :D
>> happy_birthday
1
 $ 
 | 
---
~~~
---
>> happy_birthday
2
 $ $ 
 | | 
-----
~~~~~
-----
>> happy_birthday
3
 $ $ $ 
 | | | 
-------
~~~~~~~
-------
>> happy_birthday
4
 $ $ $ $ 
 | | | | 
---------
~~~~~~~~~
---------
>> happy_birthday
5
 $ $ $ $ $ 
 | | | | | 
-----------
~~~~~~~~~~~
-----------
```
# Code with spacing and explanations
```
% Get the input number from the user
n=input('');
% If the number is positive, the core candle sequence is going to be a column vector of a $ followed by a | character
m='$|'.';    
%// Array of one column and it has two spaces - going to use more than once
d = '  '.';
% If the number is 0, display the congratulations message and get out
if(n==0)
    disp('Congratulations on your new baby! :D')
    break;
% m stores the core candle sequence for displaying on the screen
% If the number is negative, the core candle sequence is going to be a column of two blank spaces
elseif(n<0)
    m=d; 
    n=1; % n is set to 1 as this is the number of "blank candles" we want to display
end
% This displays candles and the base together
% The top half is the displaying of the candles
% It is a column vector of spaces, followed by pairs of $,| in a column
% and another column of spaces - repeated n times
% The bottom half is the displaying of the cake
% The bottom half is a column vector of -,~,- for the base of the cake
% and is repeated 2*n + 1 times to match the candle display
disp([[d repmat([m d],1,n)];repmat('-~-'.',1,2*n+1)]);
```
The displaying part at the end is probably the most obfuscated part of the code. This is going to display a 5 row character matrix where the first two rows consists of the candles and the last three rows consists of the base of the cake. 
The basis for the top half of the display is either two spaces in a column followed by another two spaces in another column in the case that the age is negative, or a `$,-` in a column followed by two spaces in another column. This is a 2 x 2 character matrix. The basis for the bottom half of the display is a single column vector of `-,~,-` which is a 3 x 1 character matrix.
The display command first tackles the first two rows of the cake by placing two spaces in the first column, followed pairs of a column of `$,-` or a column of spaces if `n` is negative, which gets changed to `n=1`, and another column of two spaces repeated for a total of `n` times. The next three rows simply replicate the `-,$,-` column vector for `2*n + 1` times to align the candles together with the base, thus completing the picture.
# Try it online!
You can try this online using IDEOne's Octave compiler: <http://ideone.com/4qXDdJ> - however, there is a slight bug when reading in values from standard input. As such, the script is slightly modified where you have to change the value of `n` at the beginning of the code. Fork a new version of the script and change this to whatever integer value suits you in order to see what the output looks like.
[Answer]
# JavaScript, ~~143~~ 153 Bytes
`for(v in k=' $ 0 | 0---0~~~0---'.split(+!(n=+prompt(c=''))))c+=k[v].repeat(n<0?1:n)+'\n';alert(n>0?c:n?c.slice(8):'Congratulations on your new baby! :D')`
To see output in mono space font replace 'alert' by 'console.log'
[Answer]
## Moonscript, 141 bytes
```
n=0+io.read!
m=3
f=(s='-')->print s\rep m
if n>0
 m=n
 m=1+2*m,f' $',f' |'
if n==0 print"Congratulations on your new baby! :D"else f f!,f'~'
```
[Answer]
# [rs](https://github.com/kirbyfan64/rs), 117 bytes
```
^0$/Congratulations on your new baby! :D
-.+/-1
$$r=)^^(\1)\n
$$m=-(--)^^(\1)\n
(\d+)/ ($ $r (| $r$m~(~~$r$m
^-[^-]+/
```
[Live demo and test cases.](http://kirbyfan64.github.io/rs/index.html?script=%5E0%24%2FCongratulations%20on%20your%20new%20baby!%20%3AD%0A-.%2B%2F-1%0A%24%24r%3D%29%5E%5E%28%5C1%29%5Cn%0A%24%24m%3D-%28--%29%5E%5E%28%5C1%29%5Cn%0A%28%5Cd%2B%29%2F%20%28%24%20%24r%20%28%7C%20%24r%24m~%28~~%24r%24m%0A%5E-%5B%5E-%5D%2B%2F&input=1%0A%0A3%0A%0A0%0A%0A-4)
[Answer]
# JavaScript ES6, 154 chars
```
alert((n=+prompt())?((n>0?` $
 |
`:(n=1)&&"")+`--
~~
--`).replace(/../gm,x=>x.repeat(n)).replace(/(.).*/gm,"$&$1"):"Congratulations on your new baby! :D")
```
And one more (154 too)
```
alert((n=+prompt())?` $
 |
--
~~
--`.slice(n<0?(n=1)-9:0).replace(/../gm,x=>x.repeat(n)).replace(/(.).*/gm,"$&$1"):"Congratulations on your new baby! :D")
```
To see output in monospace font (and move ouptut to the console) use
```
alert=x=>console.log(x)
```
[Answer]
# [Mouse](https://en.wikipedia.org/wiki/Mouse_(programming_language)), ~~164~~ 161 bytes
```
?N:N.0=["Congratulations on your new baby"33!'" :D"$]N.0>[#P,32!'36,N.;#P,32!'124,N.;]N.0<[1N:]2N.*1+D:#P,45,D.;#P,126,D.;#P,45,D.;$P0I:(I.2%=0=^1%!'I.1+I:)"!"@
```
Mouse is clearly not an ideal choice for this task, but it was fun.
Ungolfed:
```
? N.                               ~ Read N from STDIN
N. 0 = [                           ~ Have a baby for N == 0
  "Congratulations on your new baby" 33 !' " :D" $
]
N. 0 > [                           ~ If N > 0...
  #P, 32 !' 36, N.;                ~ Print the candle flames
  #P, 32 !' 124, N.;               ~ Print the candle sticks
]
N. 0 < [                           ~ If N < 0...
  1 N:                             ~ Set N = 1
]
2 N. * 1 + D:                      ~ Assign D = 2N + 1
#P, 45, D.;                        ~ Print the top cake layer
#P, 126, D.;                       ~ Print the middle layer
#P, 45, D.;                        ~ Print the bottom
$P                                 ~ Define the printing macro...
  0 I:                             ~ Initialize I to 0
  ( I. 2% = 0 = ^                  ~ While I != the second input
    1% !'                          ~ Print the first input
    I. 1 + I:                      ~ Increment I
  )
  "!"                              ~ Print a newline
@
```
The stack can contain only integers. `!'` takes an integer off the stack and prints the ASCII character with that code.
[Answer]
# CoffeeScript, 160 bytes
```
f=(i,l=[" $ "," | ",_="---","~~~",_])->if!i then"Congratulations on your new baby! :D"else (if i<0then[_,l[3],_]else i++;(Array(i).join r for r in l)).join "\n"
```
Ungolfed:
```
f=(i)->
  l = [" $ "," | ","---","~~~","---"] # The layers
  if i == 0
    return "Congratulations on your new baby! :D"
  else if i < 0
    return [l[2], l[3], l[2]].join("\n")
  else
    i++
    return (Array(i).join(r) for r in l).join("\n")
```
Use it like:
```
f(10) # In the CoffeeScript console
alert(f(~~prompt("Y"))) # Browser, alert popup
console.log(f(~~prompt("Y"))) # Browser, log to console, and thus has monospace font
```
Try it online: [link](http://coffeescript.org/#try:f%3D(i%2Cl%3D%5B%22%20%24%20%22%2C%22%20%7C%20%22%2C_%3D%22---%22%2C%22~~~%22%2C_%5D)-%3Eif!i%20then%22Congratulations%20on%20your%20new%20baby!%20%3AD%22else%20(if%20i%3C0then%5B_%2Cl%5B3%5D%2C_%5Delse%20i%2B%2B%3B(Array(i).join%20r%20for%20r%20in%20l)).join%20%22%5Cn%22%0A%0A%23%20Sample%20usage%2C%20would%20display%20a%20nice%20console...%0Ado-%3E%0A%20p%3Ddocument.createElement%20%22pre%22%0A%20p.style.position%3D%22fixed%22%0A%20p.style.top%3Dp.style.left%3Dp.style.right%3Dp.style.bottom%3D%220px%22%0A%20p.style.zIndex%3D%221000%22%0A%20p.style.backgroundColor%3D%22%23000%22%0A%20p.style.color%3D%22%23fff%22%0A%20p.style.margin%3D%220%22%0A%20p.style.padding%3D%2220px%22%0A%20input%20%3D%20~~prompt%20%22%3E%22%0A%20p.innerHTML%20%3D%20(%22%3E%20f(%23%7Binput%7D)%5Cn%23%7Bf(input)%7D%5Cn%5Cn%3Cb%20style%3D'color%3Ayellow'%3EClick%20to%20dismiss.%3C%2Fb%3E%5Cn%22)%0A%0A%20b%3Ddocument.createElement%20%22b%22%0A%20b.innerHTML%3D%22%E2%96%88%22%0A%20p.appendChild%20b%0A%20interval%3DsetInterval%20(-%3Eb.style.opacity%3D1-b.style.opacity)%2C400%0A%20%0A%20document.body.appendChild%20p%0A%20p.onmouseup%3D-%3Ep.remove()%3BclearInterval%20interval) (Contains some custom display code, so everything looks soo nice...)
**Ooops, almost forgot it!** Happy birthday, @BetaDecay!
[Answer]
# C, 392 bytes
(known segmentation fault if no arguments are given)
```
#include <stdio.h>
#define P(s) printf(s);
#define F for(i=0;i<n;i++)
#define A(s, e) F{P(s)}P(e "\n")
int main(int c, char**v){int i,n=atoi(v[1]);if(n<0){n=3;A("-",)A("~",)A("-",)}else if(!n)P("Congratulations on your new baby! :D\n")else{A(" $",)A(" |",)A("--","-")A("~~","~")A("--","-")}}
```
Unminified and copiously spaced
```
#include <stdio.h>
#define P(s) printf ( s ) ;
#define F for ( i = 0 ; i < n ; i++ )
#define A(s, e) F { P ( s ) } P ( e "\n" )
int main ( int c, char ** v )
{
        int i, n = atoi ( v [ 1 ] ) ; 
        if ( n < 0 ) 
        {   
                n = 3 ; 
                A ( "-", )
                A ( "~", )
                A ( "-", )
        }   
        else if ( ! n ) 
                P ( "Congratulations on your new baby! :D\n" )
        else
        {   
                A ( " $", )
                A ( " |", )
                A ( "--", "-" )
                A ( "~~", "~" )
                A ( "--", "-" )
        }   
}
```
[Answer]
# Powershell, ~~139~~ ~~134~~ ~~132~~ 126 bytes
```
$n=$args[0];if($n){$d=3;if($n-gt0){' $'*$n;' |'*$n;$d=$n*2+1}'-'*$d;'~'*$d;'-'*$d}else{'Congratulations on your new baby! :D'}
```
[Answer]
# Ceylon, ~~322~~ ~~307 ~~~~300~~ 282~~ 278~~ 260 bytes
```
shared void run(){if(exists t=process.readLine(),exists n=parseInteger(t)){String r(String s)=>s.repeat(n);print(n>0thenr(" $")+"\n"+r(" |")+"\n"+r("--")+"-\n"+r("~~")+"~\n"+r("--")+"-"else(n<0then"---\n~~~\n---"else"Congratulations on your new baby! :D"));}}
```
The not yet golfed original (assuming negative cakes have width 3 instead of –2·n+1):
```
shared void birthdayCake() {
    if (exists text = process.readLine(), exists number = parseInteger(text)) {
        switch (number <=> 0)
        case (equal) {
            print("Congratulations on your new baby! :D");
        }
        case (smaller) {
            print("---\n~~~\n---");
        }
        case (larger) {
            print(" $".repeat(number));
            print(" |".repeat(number));
            print("--".repeat(number) + "-");
            print("~~".repeat(number) + "~");
            print("--".repeat(number) + "-");
        }
    }
}
```
This features the condition list in the if statement, each condition defining a value usable in the following conditions and in the body. Because they have the `exist`, the condition is only fulfilled when the values is not null, and thus the compiler knows the values is not null for the following code. (If nothing is entered (EOF), readline returns null. If parseInteger hits a non-integer, it also returns null. Our program then does nothing. As the behavior for those cases was not defined, I guess this is okay.)
Also we have the `<=>` operator, which maps to the [`Comparable.compare`](http://modules.ceylon-lang.org/repo/1/ceylon/language/1.1.0/module-doc/api/Comparable.type.html#compare) method, and returns a `Comparison` object, i.e. one of `equal`, `smaller` and `larger`. The compiler knows that those exhaust the `Comparison` type, so no `else` clause is needed in our `switch` statement.
The [`repeat` method of class String](http://modules.ceylon-lang.org/repo/1/ceylon/language/1.1.0/module-doc/api/String.type.html#repeat) does what one would expect. It is actually inherited from the same-named method in interface Iterable (as a string is, beside other stuff, just a list of characters).
Replacing my identifiers by one-letter ones and removing unneeded white space gives 322 characters:
```
shared void b(){if(exists t=process.readLine(),exists n=parseInteger(t)){switch(n<=>0)case (equal){print("Congratulations on your new baby! :D");}case(smaller){print("---\n~~~\n---");}case(larger){print(" $".repeat(n));print(" |".repeat(n));print("--".repeat(n)+"-");print("~~".repeat(n)+"~");print("--".repeat(n)+"-");}}}
```
Replacing the series of `print` by explicit `\n`s (and one single `print`) brings it down to 307:
```
shared void b(){if(exists t=process.readLine(),exists n=parseInteger(t)){switch(n<=>0)case(equal){print("Congratulations on your new baby! :D");}case(smaller){print("---\n~~~\n---");}case(larger){print(" $".repeat(n)+"\n"+" |".repeat(n)+"\n"+"--".repeat(n)+"-\n"+"~~".repeat(n)+"~\n"+"--".repeat(n)+"-");}}}
```
I tried alias-importing of `repeat` as `r`, but it doesn't help (the import declaration adds 40 characters, and we can only save 25 by replacing `repeat` with `r`).
What slightly helps, is using `n.sign` instead of `n<=>0`. While these two expressions have the same textual length, they have different types: the latter one is of type `Comparison` mentioned before (which has the three values `smaller`, `larger` and `equal`), the former one has type `Integer`, with the values `-1`, `1`, `0` ... and because `Integer` has many more values, we also need an `else` clause. This is 300 characters long:
```
shared void b(){if(exists t=process.readLine(),exists n=parseInteger(t)){switch(n.sign)case(0){print("Congratulations on your new baby! :D");}case(-1){print("---\n~~~\n---");}case(1){print(" $".repeat(n)+"\n"+" |".repeat(n)+"\n"+"--".repeat(n)+"-\n"+"~~".repeat(n)+"~\n"+"--".repeat(n)+"-");}else{}}}
```
Here with whitespace:
```
shared void b() {
    if (exists t = process.readLine(), exists n = parseInteger(t)) {
        switch (n.sign)
        case (0) {
            print("Congratulations on your new baby! :D");
        }
        case (-1) {
            print("---\n~~~\n---");
        }
        case (1) {
            print(" $".repeat(n) + "\n" +
                        " |".repeat(n) + "\n" +
                        "--".repeat(n) + "-\n" +
                        "~~".repeat(n) + "~\n" +
                        "--".repeat(n) + "-");
        }
        else {}
    }
}
```
We can safe some more by resigning about our switch statement and using `if`, coming to 282 characters(=bytes):
```
shared void b(){if(exists t=process.readLine(),exists n=parseInteger(t)){if(n==0){print("Congratulations on your new baby! :D");}else if(n<0){print("---\n~~~\n---");}else{print(" $".repeat(n)+"\n"+" |".repeat(n)+"\n"+"--".repeat(n)+"-\n"+"~~".repeat(n)+"~\n"+"--".repeat(n)+"-");}}}
```
Formatted:
```
shared void b() {
    if (exists t = process.readLine(), exists n = parseInteger(t)) {
        if (n == 0) {
            print("Congratulations on your new baby! :D");
        } else if (n < 0) {
            print("---\n~~~\n---");
        } else {
            print(" $".repeat(n) + "\n" +
                        " |".repeat(n) + "\n" +
                        "--".repeat(n) + "-\n" +
                        "~~".repeat(n) + "~\n" +
                        "--".repeat(n) + "-");
        }
    }
}
```
We can safe another byte by swapping the cases around, since `>` is shorter than `==`.
Another "annoyance" is the repeated `repeat(n)` – we can define a local function (a closure, it remembers `n` from the defining block) with a shorter name:
```
String r(String s) => s.repeat(n);
```
This is a shorter way of writing this:
```
String r(String s) {
    return s.repeat(n);
}
```
We could use `function` instead of the return type for type inference, but this is not shorter. This gives us 278 bytes:
```
shared void b(){if(exists t=process.readLine(),exists n=parseInteger(t)){if(n>0){String r(String s)=>s.repeat(n);print(r(" $")+"\n"+r(" |")+"\n"+r("--")+"-\n"+r("~~")+"~\n"+r("--")+"-");}else if(n<0){print("---\n~~~\n---");}else{print("Congratulations on your new baby! :D");}}}
```
Formatted:
```
shared void b() {
    if (exists t = process.readLine(), exists n = parseInteger(t)) {
        if (n > 0) {
            String r(String s) => s.repeat(n);
            print(r(" $") + "\n" + r(" |") + "\n" + r("--") + "-\n" + r("~~") + "~\n" + r("--") + "-");
        } else if (n < 0) {
            print("---\n~~~\n---");
        } else {
            print("Congratulations on your new baby! :D");
        }
    }
}
```
Actually, using the `then` and `else` operators instead of the `if` statements allows us to save some calls of `print` (and some braces):
```
shared void run() {
    if (exists t = process.readLine(), exists n = parseInteger(t)) {
        String r(String s) => s.repeat(n);
        print(n > 0 then r(" $") + "\n" +
                        r(" |") + "\n" +
                        r("--") + "-\n" +
                        r("~~") + "~\n" +
                        r("--") + "-"
                    else (n < 0
                        then "---\n~~~\n---"
                        else "Congratulations on your new baby! :D"));
    }
}
```
This is just 261 bytes:
`shared void run(){if(exists t=process.readLine(),exists n=parseInteger(t)){String r(String s)=>s.repeat(n);print(n>0thenr(" $")+"\n"+r(" |")+"\n"+r("--")+"-\n"+r("~~")+"~\n"+r("--")+"-"else(n<0then"---\n~~~\n---"else"Congratulations on your new baby! :D"));}}`
(I used `run` instead of `b` for the function name because this way it can be run with `ceylon run` without passing a function name.)
My Github repository has a [commented version of this](https://github.com/ePaul/ceylon-codegolf/blob/master/source/codegolf/birthday57277/birthdayCake.ceylon).
[Answer]
# Python 2, 158 bytes
---
```
i=input()
l='\n'
s=''
if i==0:s='Congratulations on your new baby! :D'
elif i<0:s='---\n~~~\n---'
else:n=i*2+1;a=l+'-'*n;s=' $'*i+l+' |'*i+a+l+'~'*n+a
print s
```
[Answer]
# golflua, 113 characters
```
\p(c)w(S.t(c,n))~$n=I.r()+0?n==0w"Congratulations on your new baby! :D"!??n>0p" $"p" |"n=n*2+1!?n=3$p"-"p"~"p"-"$
```
Sample run:
```
bash-4.3$ golflua -e '\p(c)w(S.t(c,n))~$n=I.r()+0?n==0w"Congratulations on your new baby! :D"!??n>0p" $"p" |"n=n*2+1!?n=3$p"-"p"~"p"-"$' <<< 5
 $ $ $ $ $
 | | | | |
-----------
~~~~~~~~~~~
-----------
bash-4.3$ golflua -e '\p(c)w(S.t(c,n))~$n=I.r()+0?n==0w"Congratulations on your new baby! :D"!??n>0p" $"p" |"n=n*2+1!?n=3$p"-"p"~"p"-"$' <<< 0
Congratulations on your new baby! :D
bash-4.3$ golflua -e '\p(c)w(S.t(c,n))~$n=I.r()+0?n==0w"Congratulations on your new baby! :D"!??n>0p" $"p" |"n=n*2+1!?n=3$p"-"p"~"p"-"$' <<< -5
---
~~~
---
```
[Answer]
## Python 2, 150 bytes
```
m=input()
n=m-1
p="---"+"--"*n
g="\n~~~"+"~~"*n+"\n"
if m>0:print" $"*m,"\n"," |"*m
s=p+g+p
print s if m!=0 else"Congratulations on your new baby! :D"
```
Close to author's Python :(
[Answer]
# Perl, 139 127 117 bytes
Does not require '-n' or '-p' options.
Revision 3 (with thanks to Dom Hastings below):
```
$==<>;map{print$_ x(!$=||(/ /?$=:($=<1||$=)*2+1)).$/}!$=?'Congratulations on your new baby! :D':split 0,' $0 |0-0~0-'
```
Revision 2:
```
$n=<>;map{print$_ x($n==0?1:(/ /?$n:($n<1?1:$n)*2+1)).$/}$n==0?('Congratulations on your new baby! :D'):(' $',' |','-','~','-')
```
Revision 1:
```
$n=<>;map{print$_ x(($l=length())>2?1:($l==2?$n:($n<1?1:$n)*2+1)).$/}$n==0?('Congratulations on your new baby! :D'):(' $',' |','-','~','-')
```
Here's a version of revision 3 that doesn't have the leading blank new lines on negative input - 132 bytes.
```
$==<>;map{print$_ x(!$=||(/ /?$=:($=<1||$=)*2+1)).(/ /&&$=<0?'':$/)}!$=?'Congratulations on your new baby! :D':split 0,' $0 |0-0~0-'
```
[Answer]
# Pip, 74 + 1 = 75 bytes
Takes the age as a command-line argument. Requires the `-n` flag.
```
Y^"-~-"a?a<0?yX3(s.^"$|")XaALyX2*a+1"Congratulations on your new baby! :D"
```
[Github repository for Pip](http://github.com/dloscutoff/pip)
The command-line argument is stored in `a`. We split `"-~-"` into a list of characters and `Y`ank it into the variable `y`. The rest of the program is a big ternary expression:
* `a?`   
 If `a` is truthy (i.e. not zero):
	+ `a<0?yX3`   
	 If `a` is negative, return `y` with each element repeated 3 times: `["---";"~~~";"---"]`
	+ Else (`a` is positive):
		- `(s.^"$|")Xa`   
		 Split `"$|"` into a list of characters, prepend a space (`s`) to each, and repeat each resulting element `a` times
		- `yX2*a+1`   
		 Repeat each element of `y` `2*a+1` times
		- `AL`   
		 Append the two lists
* Else (`a` is zero), return the congratulations string
At the end of the program, the `-n` flag ensures that lists are printed with elements on separate lines, thus displaying a properly layered cake.
Here are the steps for an input of `2`:
```
Candles
["$";"|"]
[" $";" |"]
[" $ $";" | |"]
Cake
["-";"~";"-"]
["-----";"~~~~~";"-----"]
Put it together
[" $ $";" | |";"-----";"~~~~~";"-----"]
Final output
 $ $
 | |
-----
~~~~~
-----
```
Happy birthday!
[Answer]
# [K (ngn/k)](https://gitlab.com/n9n/k), 87 bytes
```
{$[x<0;3#'2_*:;x;,'/(1+2*x)#;:"Congratulations on your new baby! :D"]("  -~-";"$|-~-")}
```
[Try it online!](https://tio.run/##y9bNS8/7/z/NqlolusLGwNpYWd0oXsvKusJaR11fw1DbSKtCU9naSsk5Py@9KLGkNCexJDM/r1ghP0@hMr@0SCEvtVwhKTGpUlHBykUpVkNJQUG3TlfJWkmlBkRr1v5PUzAy/Q8A "K (ngn/k) – Try It Online")
edit: whoops, easy 1-byte reduction i missed
---
if 2 lines of whitespace is permitted where the candles would be in the x<0 case, we can save 2 bytes with
```
{$[x<0;3#'*:;x;,'/(1+2*x)#;:"Congratulations on your new baby! :D"]("  -~-";"$|-~-")}
```
[Answer]
# [05AB1E](https://github.com/Adriandmen/05AB1E), ~~45~~ 44 bytes
```
_i“Ûà€‰€ž€¢‡Í! :D“ćuìëdiU„ $„ |}…-~-`)X·>δ∍»
```
[Try it online!](https://tio.run/##yy9OTMpM/f8/PvNRw5zDsw8veNS05lHDBiB5dB@QOLToUcPCw72KClYuQPkj7aWH1xxenZIZ@qhhnoIKiKipfdSwTLdON0Ez4tB2u3NbHnX0Htr9/78xAA "05AB1E – Try It Online")
```
_i                               # if input != 0:
  “Ûà€‰€ž€¢‡Í! :D“               #  dictionary string "congratulations on your new baby! :D"
                  ćuì            #  uppercase the first character
ë                                # else:
 di        }                     #  if input >= 0:
   >V                            #   set Y = input + 1 (by default, Y is 2)
     „ $                         #   push literal " $"
        „ |                      #   push literal " |"
…-~-                             #  push literal "-~-"
    `                            #  dump each character separately
     )                           #  wrap the entire stack in a list:
                                 #   [" $", " |", "-", "~", "-"] if input > 0
                                 #   ["-", "~", "-"] if input < 0
      ε   }                      #  for each item in that list:
       Y∍                        #   extend to length Y
         û                       #   palindromize
           »                     #  join the stack by newlines
                                 # implicit output
```
[Answer]
# Perl, 144 bytes
143 bytes of code, plus one extra byte for the `-n` switch to capture stdin.
```
if($_!=0){print$_>0?" \$"x$_.$/." |"x$_.$/:""x($_=1);$_=$_*2+1;print"-"x$_.$/."~"x$_.$/."-"x$_;exit}print"Congratulations on your new baby! :D"
```
[Answer]
# SpecBAS, 164
Uses the apostrophe shortcut to move to new line
```
INPUT n: IF n=0 THEN PRINT "Congratulations on your new baby! :D" ELSE IF n<0 THEN PRINT "---"'"~~~"'"---" ELSE PRINT " $"*n'" |"*n'"-";"--"*n'"~";"~~"*n'"-";"--"*n
```
Formatted for easier reading
```
INPUT n
IF n=0 THEN PRINT "Congratulations on your new baby! :D" 
ELSE IF n<0 THEN PRINT "---"'"~~~"'"---" 
ELSE PRINT " $"*n'" |"*n'"-";"--"*n'"~";"~~"*n'"-";"--"*n
```
[Answer]
# Python 3, 169 bytes
```
n=int(input())
m=max(n*2+1,3)
f=' {}'*n+'\n'+' {}'*n+'\n'+'-'*m+'\n'+'~'*m+'\n'+'-'*m
if n==0:f='Congratulations on your new baby! :D'
print(f.format(*['$']*n+['|']*n))
```
[Answer]
# Julia, 143 bytes
```
n=int(readline())
p=println
l="\n"
n>0&&p(" \$"^n*l*" |"^n)
d=2(n<0?1:n)+1
p(d>1?"-"^d*l*"~"^d*l*"-"^d:"Congratulations on your new baby! :D")
```
Pretty straightforward. Ungolfed:
```
# Read n from STDIN and convert to an integer
n = int(readline())
# Print the candles for positive n
n > 0 && println(" \$"^n * "\n" * " |"^n)
# Define d as the width of the cake
d = 2(n < 0 ? 1 : n) + 1
# Newborns can't eat cake
if d > 1
    println("-"^d * "\n" * "~"^d * "\n" * "-"^d)
else
    println("Congratulations on your new baby! :D")
end
```
[Answer]
# Lua, 299 Bytes
```
a=0+io.read() b=string.rep p=print if a==0 then p("Congratulations on your new baby! :D") else p(b(" ",a)..b("$ ",a)..("\n")..b(" ",a)..b("| ",a)) if a<0 or a==1 then p("---\n~~~\n---") else p(b(" ",a-1).."-"..b("-",2*a).."\n"..b(" ",a-1).."~"..b("~",2*a).."\n"..b(" ",a-1).."-"..b("-",2*a))end end
```
[Answer]
# Mathematica, 164 Bytes
Completely missed the candle-less cakes for n < 0, adding an additional 15 characters 
```
r[a_,b_]:=StringRepeat[a,Abs@b];c=" $ ";t="---";m="~~~";f[n_]:=If[n>0,r[c,n]~~"\n",""]~~r[t,n]~~"\n"~~r[m,n]~~"\n"~~r[t,n];f[0]:="Congratulations on your new baby! :D"
```
]