Raspberry Pi project — Car Audio improvement

Wednesday, May 22nd, 2013

Update 2013-05-24:
Thanks to Lau­rent, I now know more about the audio capa­bil­i­ties of the Pi. Sad news is that the on-board audio out­put ain’t that great (to say the least :p). One pos­si­ble solu­tion could be to use an USB sound card or

A sec­ond solu­tion would be to hook an A2DP adapter to the RCA inputs of the car, such as this one from Logitech.

Although the sec­ond solu­tion seems over­all bet­ter (pos­si­ble to pair dif­fer­ent devices to the A2DP adapter and stream any­thing to the car’s audio sys­tem of rely­ing on the pres­ence of an USB stick on the Pi, I think I’ll go with the Pi at first (oth­er­wise all the fun is gone :p).

My cur­rent idea is to use an USB sound card, maybe with the addi­tion of an USB Wi-Fi / Blue­tooh adapter so that I can obtain at least the same func­tion­al­i­ties as with the A2DP adapter. I found some, tuto­ri­als to do what I have in mind. I’ll check that out in the com­ing days.. :)

Some other links that might be use­ful (to me that is :p):


In my last posts, I’ve explained what I cur­rently do with the two Rasp­berry Pi I own. In this post, I’ll describe one project I now have in mind that I will prob­a­bly start work­ing on in the com­ing days.

My goal with this project is to extend the audio sys­tem of my car.

Cur­rently, all I can do in my car is to either lis­ten to CDs (clas­sic or MP3, which is pretty stan­dard by now) or the radio. Appar­ently, I can’t stream music towards the car using Blue­tooth because either my car, its spe­cific firmware ver­sion or my blue­tooth device does not sup­port the cor­rect Blue­tooth pro­file (A2DP protocol).

Rather bor­ing eh? Clearly, the Rasp­berry Pi could help here ;-)

For­tu­nately, my car has an RCA stereo socket that I can take advan­tage of.

For starters, my idea is to have the Rasp­berry Pi hooked up on the RCA socket and auto­mat­i­cally play­ing any audio files it finds (either on the SD card itself or on any plugged in USB disk). So that I don’t have to worry too much about it, I also want it to do that with­out any inter­ac­tion, mean­ing that from the moment it is booted up:

  • it should start play­ing the music it finds
  • if a USB device is plugged in, it should scan it for audio files to queue

Option­ally, it should remem­ber the last played song and start from there, or it could just play songs ran­domly. For this first phase, I think that con­sole music play­ers such as these might help me get started: cmus, sox, …:

  • http://archive09.linux.com/feature/124907
  • http://www.tuxarena.com/2011/12/10-console-music-players-for-linux/
  • http://ubuntuforums.org/showthread.php?t=1699260

Later on (and if I’m not sat­is­fied with what I’ve described above), I have addi­tional ideas:

  • since I want to learn elec­tron­ics, I could add some switches to sup­port basic con­trols (play, pause, next, previous)
  • since I also have music on other devices with Wi-Fi, I could add a USB Wi-Fi don­gle and be able to send music towards the Rpi
  • if I have the USB Wi-Fi don­gle, I could also find ways to remotely con­trol music play­back using a smartphone
  • I could try to find a way to plug into the car’s dis­play sys­tem and use it, like that thing does:

As with any project, the pos­si­bil­i­ties are end­less and so are the pos­si­ble paths from start to fin­ish. We’ll see how I get there! ;-)

Raspberry Pi SSH server

Wednesday, May 22nd, 2013

In this post, I’ll describe my Rpi SSH server con­fig­u­ra­tion. The media cen­ter Rpi is also inter­est­ing, but I didn’t have to cus­tomize many things since Open­ELEC is more like an appli­ance and apart from installing exten­sions and tweak­ing the sys­tem set­tings, there’s not so much one needs to do to get up and run­ning (which is good!).

RPi SSH server

I use my Rpi SSH server as a gate­way to reach home when I’m out­side (on the train over 3G or on some Wi-Fi net­work). It basi­cally allows me to access any­thing on my per­sonal net­work in a secure fash­ion (more over this after the setup details).

The con­fig­u­ra­tion is built on top of Arch­Linux and uses OpenSSH (who would’ve guessed ^^).

I’ve cho­sen Arch­Linux mainly because I’m already famil­iar with it, I could also have installed the Debian dis­tri­b­u­tion, I don’t think it would’ve pre­vented me from doing any of the following..

For the basic setup of Arch­Linux, I’ve fol­lowed this guide: http://elinux.org/ArchLinux_Install_Guide

After boot­ing it up for the first time, I still had a few things to configure.. :)

  • First things first: chang­ing the pass­word
    passwd
  • Updat­ing every­thing
    pacman-key --init (init pacman)
    pacman -Syy (update the packages db)
    pacman -Syu (full update)
    pacman -Syu (just because I'm a tad crazy)
  • Mod­i­fy­ing the time­zone
    nano /etc/timezone
  • Mod­i­fy­ing the host­name
    hostnamectl set-hostname rpissh
  • Set­ting a sta­tic IP
    actually not done yet, I rely on a DHCP reservation for now..
  • Mod­i­fy­ing the keymap
    localectl list-keymaps
    localectl set-keymap be-latin1
  • Updat­ing the hosts file in order to eas­ily access my home machines
    nano /etc/hosts
    ...
  • Resiz­ing the root par­ti­tion (because it sucks to use only a part of the avail­able space on the SD card)
    fdisk /dev/mmcblk0
    
    Welcome to fdisk (util-linux 2.22.1).
    Changes will remain in memory only, until you decide to write them.
    Be careful before using the write command.
    Command (m for help): d
    Partition number (1-4): 2
    Partition 2 is deleted
    Command (m for help): n
    Partition type:
    p primary (1 primary, 0 extended, 3 free)
    e extended
    Select (default p): p
    Partition number (1-4, default 2): 2
    First sector (194560-31512575, default 194560):
    Using default value 194560
    Last sector, +sectors or +size{K,M,G} (194560-31512575, default 31512575):
    Using default value 31512575
    Partition 2 of type Linux and of size 15 GiB is set
    Command (m for help): w
    The partition table has been altered!
    Calling ioctl() to re-read partition table.
    WARNING: Re-reading the partition table failed with error 16: Device or resource busy.
    The kernel still uses the old table. The new table will be used at
    the next reboot or after you run partprobe(8) or kpartx(8)
    Syncing disks.
    
    After a reboot:
    
    We’re deleting the rootfs partition, and creating a new one. Since there is no space between the boot and the root partition in the first place, the new partition will start at the exact same position as the just deleted partition. This means, we’ve got a bigger partition, with a smaller filesystem in there.
    We also observe the re-reading of the partition failed, since the partition is currently in use. Therefore we have to reboot in order for the new partition table to be known to the kernel. After reboot we can perform the resizing of the file system itself
    
    And finally, I could resize the partition:
    
    resize2fs /dev/mmcblk0p2
    
    resize2fs 1.42.6 (21-Sep-2012)
    Filesystem at /dev/mmcblk0p2 is mounted on /; on-line resizing required
    old_desc_blocks = 1, new_desc_blocks = 1
    Performing an on-line resize of /dev/mmcblk0p2 to 3914752 (4k) blocks.
    The filesystem on /dev/mmcblk0p2 is now 3914752 blocks long.
  • Adding a user (which will be the only one allowed to log on via SSH)
    useradd -m -g users -s /bin/bash johndoe
        -m: create home folder
        -g: default group
        -s: shell
    passwd johndoe
    
    The same can apparently be done using:
    pacman -S adduser
    adduser
    > johndoe
  • Configuring/Hardening the SSH dae­mon
    Reference: https://wiki.archlinux.org/index.php/Secure_Shell
    
    nano /etc/ssh/sshd_config
    
    ...
    Port xxxxx # because the default port (22) is too dangerous to expose since it is targeted by all script kiddies & bots
    ServerKeyBits 4096 # because I'm paranoid even though it doesn't have huge security benefits :p
    LoginGraceTime 30 # 30 seconds to log on, after which the client is disconnected
    PermitRootLogin no # root cannot log in, even though I only allow public key authentication (again, doesn't protect me that much more, but still)
    PasswordAuthentication no # I don't allow password authentication, only public key auth
    ChallengeResponseAuthentication no # ...
    PrintMotd no # the less people know, the better I feel :)
    PrintLastLog no # same logic
    UsePrivilegeSeparation sandbox      # Default for new installations.
    AllowUsers johndoe # only user allowed to authenticate
    MaxStartups 10:30:100 # limit the number of connections -> http://stackoverflow.com/questions/4812134/in-sshd-configuration-what-is-maxstartups-103060-means

    I can prob­a­bly do more than this, but for now I’m ok with that. See my todo list below for more around this

  • Gen­er­at­ing & import­ing my pri­vate keys
    ...

Finally, since my plan was also to be able to wake up com­put­ers at home in case I need them, In installed the wol pack­age which allows to send magic pack­ets. All you need to use it is the mac address of the device you want to send a wake up call towards ;-)

pacman -S wol
su johndoe
cd ~
touch wol-pc1.sh
chmod +x wol-pc1.sh
nano wol-pc1.sh
> wol aa:bb:cc:dd:ee:ff

With that in place, I can now cre­ate a secure tun­nel from any­where towards my Rasp­berry Pi at home and feel “pretty” secure. It may not be so (I’m no secu­rity expert), but at least I’ve taken the nec­es­sary steps to ensure that only a moti­vated attacker will be able get in (using that chan­nel that is :p).

Once the SSH tun­nel is estab­lished, I can (for exam­ple) use the Rasp­berry Pi as a socks proxy to surf the Web more securely (e.g., if I’m on a pub­lic Wi-Fi hotspot).

I can also access any machine within my home net­work (router, NAS, PCs, etc) and wake them up if they’re not up and run­ning. This means that when I leave home, I can shut down every­thing and just leave the Rasp­berry up (3W ain’t gonna kill me :p) and use it to wake up the device(s) I need. I can also trans­fer files over SFTP, etc.

What I also do from time to time is estab­lish a Remote Desk­top ses­sion towards one of my Win­dows PCs using port for­ward­ing and it works sur­pris­ingly well..

My todo list for this project

  • install/configure fail2ban
  • con­fig­ure and auto­mate back­ups of the configuration
  • install/configure log­watch and send mail noti­fi­ca­tions once in a while (just in case)

Raspberry Pi

Wednesday, May 22nd, 2013

Raspberry Pi

What it looks like

The Rasp­berry Pi has opened up a lot of pos­si­bil­i­ties for many peo­ple. Even though there are prob­a­bly bet­ter alter­na­tives on the mar­ket by now, it remains a very attrac­tive plat­form for hack­ers, schools and even busi­nesses (who would’ve guessed). Many oth­ers have already cov­ered this in great lengths, so I won’t try to con­vince you for too long that the Rpi is pretty cool ^^.

This should tell you enough imho: being able to build a small (size of a credit card), pow­er­ful (capa­ble of play­ing videos in full HD), low power (ARM based, around ~3W) com­puter able to run mul­ti­ple Linux dis­tri­b­u­tions (Debian, Arch­Linux, etc) for as cheap as 50–70 EUR is just pure awe­some­ness ;).

In the upcom­ing posts, I’ll describe my cur­rent projects with the Rasp­berry Pi as well as some I still have in mind for later on.

My cur­rent config

Cur­rently, I own two of these lit­tle beasts and a third one might join these soon (more on this later). I use the first one as an SSH server, while the other one serves as a media cen­ter run­ning XBMC (Open­ELEC dis­tri­b­u­tion).

Build­ing those two didn’t take me long, although it’s the kind of never-ending project, there’s always some­thing to tweak, improve, fix, … you know what I mean.

Still I’m pretty happy with their cur­rent state ;-)

elementZapper v1.0

Sunday, May 12th, 2013

I’ve just uploaded a first ver­sion of ele­mentZap­per, a very small Google Chrome exten­sion that’ll allow you to quickly & eas­ily remove ele­ments on any Web page.

Its usage is rather sim­ple: select any­thing on the page, right click and select “Zap!” and the selected ele­ments will be removed from the page. It’s par­tic­u­larly use­ful for print­ing only what is rel­e­vant to you.

My goal with this exten­sion was to dis­cover Google Chrome’s exten­sion devel­op­ment, mainly out of curios­ity.. Now I can say that it’s pretty neat and easy to get started :)

ele­mentZap­per is avail­able on the Chrome Web Store: https://chrome.google.com/webstore/detail/elementzapper/efeljanahmlnjhckmohcfbgkfdjdmnog?hl=en

Also, for those inter­ested, the source code is avail­able on GitHub: https://github.com/dsebastien/elementZapper

Integrating exercises in my daily habits

Tuesday, February 5th, 2013

Last week I fin­ished read­ing this book called “The Power of LESS” which is all about doing less and get­ting more done. The author (Leo Babauta, also author of the Zen Habits blog) pro­vides all kinds of tips and tricks designed to help you iden­tify, pri­or­i­tize and con­cen­trate on what’s essen­tial for *you* (whether short or long term) as well as ways to avoid get­ting side­tracked along the way. The book also illus­trates how you can moti­vate your­self and change your behav­ior, which is key to cre­at­ing new habits.

Over­all, The Power of LESS is in the same cat­e­gory as David Allen’s excel­lent book called “Get­ting Things Done” which describes a sim­ple & effi­cient time man­age­ment method­ol­ogy. I see both of these books as com­ple­men­tary since they’re like two sides of the same coin. On one side you want to de-clutter your life, avoid over-commitment and con­cen­trate on what mat­ters while on the other, you want to be effi­cient in what­ever you do and the only way to achieve that is to be organized.

You might argue that such books are bor­ing as hell and/or that they are full of **** …and that might be true — to some extent. It’s true that a lot of the mate­r­ial pre­sented in these is just com­mon sense, but the thing is that most peo­ple never try to ana­lyze the use they make of their time; they just com­plain about the fact that there aren’t enough hours in a day and they fail to tackle the real prob­lem: their behav­ior, their orga­ni­za­tion, their “sys­tem”. I’ll write about my own man­age­ment “sys­tem”, but that’s for another day!

Read­ing books such as “The Power of LESS” or “Get­ting Things Done” has the huge ben­e­fit that it forces you to con­sciously think about the use that you make of your time (the sin­gle most valu­able cur­rency that we have at our dis­posal) and just by doing that, you can iden­tify waste. Try this once: ana­lyze your Inter­net usage for a week. How long do you spend surf­ing the Inter­webs each day? Is the time invest­ment worth it? Can it be reduced and spent doing some­thing else that might have more impact on your life?

At some point in his book, Leo Babauta pro­poses a set of habits that might be use­ful to inte­grate in our lives. One of these being to do some exer­cises daily. I’ve heard count­less times that exer­cis­ing reg­u­larly helps lower the risks of car­dio­vas­cu­lar dis­eases, help you con­trol your weight, etc, but at the end of the day that didn’t moti­vate me enough to start exercising.

Think­ing about that made me real­ize that it had been like for­ever since I last exer­cised (well did you ever exer­cise you may ask? … fair ques­tion for sure ;-)).

Just for fun, I then decided to inte­grate that habit in my daily routine.

Result after 15 days:

My cur­rent progress

I started with abs only. On the first day, I’ve tried doing as many as I could (just to see whether I would sur­vive, oth­er­wise there’d be no point in con­tin­u­ing :p). Ret­ro­spec­tively that was a mis­take, as I felt very demo­ti­vated a few days later. The thing is that I just set the bar too high all at once and dur­ing the days that fol­lowed, I’ve just tried to push fur­ther, but I didn’t have enough mar­gin for improve­ment (you just can’t go from 10 to 100 in two days :p

That explains the huge drop on the fifth day. After that, I felt pretty bad because I was already aban­don­ing and dur­ing the fol­low­ing days I set out to con­tinue and tried to do more each day with­out push­ing too hard.

After 15 days, I’m pretty happy with the results; I already feel a huge dif­fer­ence and as the graph shows, I keep improv­ing the num­ber of abs I’m able to do each day.

You might have noticed that I have skipped two exer­cise ses­sions in the last days. I don’t really feel bad about it because I didn’t have a choice for these two. I’ll report on my progress in the com­ing weeks.

Next to the abs ses­sions in the evening and see­ing my progress, I’ve also decided to add other habits to my daily routine:

  • speed walk­ing between the train sta­tion & my work place (5 min­utes in the morn­ing & afternoon)
  • tak­ing the stairs when­ever I can instead of lifts & escalators
Lit­tle by lit­tle, I’m push­ing fur­ther & fur­ther. Next up: push-ups.
These are sim­ple things and indeed I’m only at the very begin­ning, but basi­cally the les­son here is that cre­at­ing new habits isn’t that com­pli­cated and involves three basic and sim­ple steps:
  1. take the deci­sion & set daily reminders to cre­ate the habit: most dif­fi­cult part
  2. start small and go fur­ther pro­gres­sively: keep a mar­gin for progress
  3. keep track of your progress: visu­al­iz­ing the results of your efforts will keep you motivated
Try it out!

New in Java 7 (03) — Multi catch

Saturday, December 3rd, 2011

I wanted to con­tinue this post series but time goes by sooooo quickly (and I’m in a quite lazy mood lately).

Any­way, back for a new fea­ture that Java has brought us: mul­ti­ple catch clauses. And hon­estly, even if it’s a lit­tle one com­pared to other fea­tures, I find it a great addi­tion to the Java developer’s toolkit. We (should) always seek to improve our code and reduce main­te­nance costs through refac­tor­ing etc, but some­times the lan­guage doesn’t help.

Han­dling excep­tions has been one area where code rep­e­ti­tion often comes up. You’ve prob­a­bly all writ­ten stuff like this:

} catch (SomeException ex) {
     logger.error(ex);
     throw ex;
} catch (OtherException ex) {
     logger.error(ex);
     throw ex;
}

And you’ll be pleased to know that with Java 7, you can now refac­tor your code and do this instead:

} catch (SomeException  | SomeOtherException ex) {
     logger.error(ex);
     throw ex;
}

Yummy!

Zeebruges

Monday, August 29th, 2011

Some pic­tures from our mini-trip to Zeebruges:

New in Java 7 (02) — Switching over Strings, beyond good & evil

Tuesday, August 9th, 2011

In the first post of this series, I’ve told you a bit about the new dia­mond nota­tion which is a nice addi­tion and pro­vides for bet­ter code read­abil­ity and less ver­bosity. And not only that, but since we’re typ­ists first and pro­gram­mers sec­ond, it also allows us to increase the LOC / minute count (and whether that is a good thing is actu­ally open to debate) ;-) (sorry for those poor hunt and peck typ­ists among you).

For this sec­ond post, I want to talk about a fea­ture that has been requested about 16 YEARS ago and that was finally imple­mented in Java 7: the abil­ity to write switch state­ments with String cases. I won’t insult you with an exam­ple, if you want one, then check the offi­cial docs.. Also, I won’t cover the per­for­mance aspects, which other peo­ple have already explained quite nicely.

As many of you know, it’s a fea­ture that has been avail­able for a long time in many other pro­gram­ming lan­guages (e.g., C#, JavaScript, ruby, …) and even though hard­cod­ing String lit­er­als should be avoided when­ever pos­si­ble, there are still cases where it makes sense.

To cater for the lack of that fea­ture, mul­ti­ple workarounds were used. One of which (the ugli­est IMHO) being to use if-then-else blocks to han­dle all the cases for non-binary deci­sions (more com­plex than sim­ple if-else), which indeed leads to unreadable/unmaintainable code (even though it is con­text based and some­times if-then-else blocks make more sense than using a switch).

Another approach, which I think is way bet­ter on mul­ti­ple lev­els is to define an enum with a fromString(String) method and use the enum val­ues in a switch via the val­ueOf method. That tech­nique allows to avoid repeat­ing hard­coded Strings all over the place and keeps the code eas­ily refac­torable. Not only that, but it is also way more flex­i­ble. For exam­ple, in the from­String method (or what­ever you decide to call it), you can decide whether you want to sup­port case sen­si­tiv­ity or not, how to treat null val­ues, etc. You can find a nice writeup of that idiom there.

The sup­port for String objects in switch state­ments is very wel­come, but keep in mind that it isn’t the sil­ver bul­let and that it shouldn’t be used in all cases (haha) :)

New in Java 7 (01)

Sunday, July 31st, 2011

Java 7 has finally been released! There have been a lot of dis­cus­sions around the fea­tures that would/wouldn’t be included in Java 7. After a while, I decided to stop check­ing the news around that sub­ject since it changed so often. And appar­ently, some of the most awaited fea­tures have been deferred to Java 8 or later. Among which: JSR 294 (Lan­guage and VM sup­port for mod­u­lar pro­gram­ming), clo­sures,  or JDK mod­u­lar­iza­tion (project Jig­saw). Too bad! But any­how, now Java 7 is here and it’s time for me to check it out. In this series of posts, I’ll write about the new fea­tures that I find inter­est­ing as I dis­cover them (don’t except the list to be exhaus­tive though).

So let’s get started! Here’s the first bit I’ve just read about:

You can now replace the type argu­ments required to invoke the con­struc­tor of a generic class with an empty set of type para­me­ters (<>: infor­mally called the dia­mond) as long as the com­piler can infer the type argu­ments from the context.

If we trans­late this to actual code, it really means that instead of:

Map<Foo,Bar> fooBar = new HashMap<Foo,Bar>();

You can now write this:

Map<Foo,Bar> fooBar = new HashMap<>();

Or this:

Map<Foo,List<Bar>> fooBars = new HashMap<>();

Instead of that:

Map<Foo, List<Bar>> fooBars = new HashMap<Foo, List<Bar>>();

This is a nice addi­tion, but make sure to check out the ref­er­ence doc­u­men­ta­tion for more details, it doesn’t stop there ;-)

SyntaxHighlighter brush autoloading

Wednesday, June 15th, 2011

Syn­tax­High­lighter is a very cool syn­tax high­light­ing JavaScript library cre­ated by Alex Gor­batchev (if you don’t know about it yet, check out the demo page). As you’ll notice, I actu­ally use it on this very blog.

Using it is pretty straightforward:

  • load the XReg­exP library required by Syn­tax­High­lighter: http://xregexp.com/

  • load the main script:

    <script src="js/shCore.js" type="text/javascript"></script>
  • load one or more of the avail­able brushes (syn­tax high­light­ing scripts):

    <script src="css/shBrushJScript.js" type="text/javascript"></script>
  • include at least one of the avail­able theme stylesheets:

    <link href="css/shCore.css" rel="stylesheet" type="text/css" />
    <link href="css/shThemeDefault.css" rel="stylesheet" type="text/css"/> 
  • wrap the code to high­light in a <pre> block and spec­ify the brush that should be used:

                 <pre class="brush: js">function foo(){ ... }</pre>
               
  • finally, exe­cute the high­lighter using the following:

                 <script type="text/javascript">
                   SyntaxHighlighter.all();
                 </script>
               

The main issue with this way of con­fig­ur­ing Syn­tax­High­lighter is that you’ll either have to load exactly those brushes you need or load them all even if they’re not needed. This prob­lem remained until ver­sion 3 intro­duced the Autoloader script.

You can find all the details about its usage on that page, but basi­cally you have to load the autoloader script and tell it about all the brushes aliases that it should rec­og­nize along with the path to the cor­re­spond­ing scripts. Much bet­ter, yay!

One prob­lem I’ve had with the autoloader script is that it doesn’t seem to appre­ci­ate URIs for the loca­tion of the brush scripts when using the default syntax:

Array: [ 'alias1 alias2 /full/path/to/brush.js', ... ]

Although, it works per­fectly fine when using the alter­nate syn­tax (which is alas a lit­tle bit more verbose):

Array: [ [ 'alias1', 'alias2', '/full/path/to/brush.js' ], ... ]

Finally, I’ve come up with the fol­low­ing script, largely inspired by the exam­ple on that page but using the alter­nate syntax:

	<script type="text/javascript">
		var baseSyntaxHighlighterScriptsPath = "http://base-path-to-scripts-folder/";
		function getSyntaxHighlighterScriptPath(name){
			return name.replace('@', baseSyntaxHighlighterScriptsPath);
		}

		SyntaxHighlighter.autoloader(
			[ 'applescript', getSyntaxHighlighterScriptPath('@shBrushAppleScript.js') ],
			[ 'actionscript3', 'as3', getSyntaxHighlighterScriptPath('@shBrushAS3.js') ],
			[ 'bash', 'shell', getSyntaxHighlighterScriptPath('@shBrushBash.js') ],
			[ 'coldfusion', 'cf', getSyntaxHighlighterScriptPath('@shBrushColdFusion.js') ],
			[ 'cpp', 'c', getSyntaxHighlighterScriptPath('@shBrushCpp.js') ],
			[ 'c#', 'c-sharp', 'csharp', getSyntaxHighlighterScriptPath('@shBrushCSharp.js') ],
			[ 'css', getSyntaxHighlighterScriptPath('@shBrushCss.js') ],
			[ 'diff', 'patch', 'pas', getSyntaxHighlighterScriptPath('@shBrushDiff.js') ],
			[ 'erl', 'erlang', getSyntaxHighlighterScriptPath('@shBrushErlang.js') ],
			[ 'groovy', getSyntaxHighlighterScriptPath('@shBrushGroovy.js') ],
			[ 'java', getSyntaxHighlighterScriptPath('@shBrushJava.js') ],
			[ 'jfx', 'javafx', getSyntaxHighlighterScriptPath('@shBrushJavaFX.js') ],
			[ 'js', 'javascript', 'jscript', getSyntaxHighlighterScriptPath('@shBrushJScript.js') ],
			[ 'perl', 'pl', getSyntaxHighlighterScriptPath('@shBrushPerl.js') ],
			[ 'php', getSyntaxHighlighterScriptPath('@shBrushPhp.js') ],
			[ 'text', 'plain', getSyntaxHighlighterScriptPath('@shBrushPlain.js') ],
			[ 'py', 'python', getSyntaxHighlighterScriptPath('@shBrushPython.js') ],
			[ 'ruby', 'rails', 'ror', 'rb', getSyntaxHighlighterScriptPath('@shBrushRuby.js') ],
			[ 'sass', 'scss', getSyntaxHighlighterScriptPath('@shBrushSass.js') ],
			[ 'scala', getSyntaxHighlighterScriptPath('@shBrushScala.js') ],
			[ 'sql', getSyntaxHighlighterScriptPath('@shBrushSql.js') ],
			[ 'vb', 'vbnet', getSyntaxHighlighterScriptPath('@shBrushVb.js') ],
			[ 'xml', 'xslt', 'html', 'htm', getSyntaxHighlighterScriptPath('@shBrushXml.js') ]
		);

		SyntaxHighlighter.all();
	</script>
Get Adobe Flash playerPlugin by wpburn.com wordpress themes