This time, it's personal.

This is a somewhat tongue-in-cheek rebuttal to Curtis Franklin Jr.’s InformationWeek article, “9 Reasons Flash Must Die, and Soon“.

I’ve employed his article almost verbatim, changing only a few key terms and occasionally adding a few words to demonstrate how the current hysteria about Flash security could readily be turned against JavaScript, HTML5, and browsers. The major difference between Curtis’ post and mine, like most current articles critical of Flash, is that I provide links to back up all of my assertions whereas other articles rely primarily on ambiguous and sometimes entirely false rhetoric.

JavaScript is hungry

Let’s run this down: The world is going mobile. There’s no doubt that more and more of our computing lives happen on handheld devices. Those handheld devices are getting smaller. It won’t be long before you can use the edge of a smart phone to take care of unwanted body hair. And with the thinner devices comes a smaller set of batteries.

Because JavaScript is an interpreted language, it’s heavy — so heavy that, in conjunction with the way HTML renders video, it’s an absolute battery killer.

And it’s not just a battery killer on mobile devices. Want to see how quickly the battery on your laptop can run to zero? Load your browser with a bunch of JavaScript-heavy pages in tabs and let them all run. You can hear the giant electronic sucking sound as the battery winds toward zero.

JavaScript is naive

Many development systems have numerous internal checks to make sure that the code developed is safe for distribution to the big wide world. JavaScript isn’t one of those systems. JavaScript has, historically, allowed all kinds of code to run. To make life better, JavaScript has provided access to a variety of juicy system components in its attempt to allow the best and most impressive animation.

Now, the good folks at W3C have improved JavaScript and its security over the years, but there are still several qualities that make JavaScript a security weakness — we’ll get to those shortly. In the meantime, know that JavaScript’s naive trust in developers and code would be charming — if it were running on someone else’s system.

Many browsers are closed

There’s a lot of really good software out there that’s proprietary. There’s also a lot of very good software that comes from one or another open ecosystem. When you’re looking for weakness, though, a closed system can legitimately be considered a point that’s not particularly strong.

It’s not only that many popular JavaScript interpreters, the browsers, are closed: They’re really pretty darned closed. That closed nature means that many of the security researchers who might work on improvements in open systems are locked out — something that seems to be of little concern to criminals and hackers.

Funny, that.

H.264 is YAMF (Yet Another Media Format)

When you want to save a graphics file or animated selection, you’re generally presented with an extensive list of options. The newer* H.264 video format, with its lovely .mp4 (a format used by nothing else) presents you with yet another media file type to keep track of, store, and consider in the panoply of files that go into a modern website.

Is a file format inherently evil? Well, no, but life is complicated enough. When there are animation options available that don’t require you to use YAMF, do yourself a favor and cut through the media clutter.

* – Newer than Flash

JavaScript isn’t HTML5 isn’t ActionScript

HTML5 is erroneously typified as the new foundation of Web page development and that it eliminates virtually all need for Flash. And here’s the thing: HTML5 is not a programming language despite notable similarities to HTML4. Flash uses ActionScript which is a close cousin of JavaScript, the actual native programming language of the modern browser.

Flash isn’t the single most complicated programming environment to learn and use, but unless you live your entire professional life inside the Adobe Creative Cloud it’s different from any of the other languages you use (except JavaScript and other ECMAScript-inspired languages). Who really needs that kind of complication? Go with an established standard, and use the time you save for more productive activities — like watching more cat videos.

Browsers are Whack-A-Mole Central

Browsers have presented such a rich set of targets to hackers that developers have spent the last decade (and more) chasing an ever-evolving series of vulnerabilities and exploits. And the nature of browsers means that this game is going to continue.

To a certain extent, this is a game that every set of developers plays with the hackers determined to keep them busy. In browsers’ cases, though, their nature as integrated development systems, interpreters, and embedded technologies means many more holes in which those darned hacker-moles can hide. Not even W3C’s standards can provide enough recommendations to use on their pointy little heads.

Browsers let you be stupid

Remember that game of Whack-a-Mole we mentioned? One of the ways that browser programmers deal with the exploits is by releasing updates. And users of the browsers can blithely ignore each and every one of them.

There are thousands of users now using versions of browsers that date back years — versions filled to overflowing with known vulnerabilities and problems. If some of those users are on your payroll, then they might well provide a path from their funny coffee-break animated shorts straight into your corporate files.

JavaScript makes browsers more complicated

JavaScript is most often deployed as an integrated interpreter. On one hand, that means that JavaScript elements can be active as soon as they load on a Web page. On the other, allowing that “always on” capability means your browser gets heavier and heavier, with a number of side effects — all of them bad.

Heavy browsers are less stable, more power-hungry, slower, and less secure. That combination is one of the reasons LinkedIn and Facebook announced that they’re dropping HTML5 and JavaScript in favour of native code by default.

Now, if you then want inetractivity, you have to go into the controls and re-enable JavaScript — yet another complication.

Browsers kill productivity

Have you ever found a great Web video and then another, and another? Then you looked up and an hour had passed? So have your employees. And we’re blaming browsers.

Cute Web video is the greatest enemy of productivity since March Madness. Without all those nifty singing cartoons about the latest crop of moronic politicians, we could all probably work three-day weeks and get as much done.

Darn you, brilliant video producers!

See, an article like this is proof positive that you don’t need Flash to take up your time. Great sarcasm can do that job just fine, thank you.

July 20th, 2015

Posted In: Development / Coding

Tags: , , , , , ,

Leave a Comment

MovieClips have been the stalwart workhorse of Flash since the very earliest days of ActionScript, so I’ll skip the details and gushing adoration and instead move on to some of the shortcomings:

  • MovieClips only play forward from the current frame. When building out animations without extra MovieClip functionality, playing animations backwards — a character in a game reversing, for example –requires a whole new timeline with the animation reversed. This produces a little extra memory overhead, even if symbols are re-used, but more importantly makes cross-linking the “forward” and “backward” clips challenging. For example, if a character is in a specific position on frame 5 of a “forward” animation, that frame might appear in frame 45 of the “backward” animation.
  • MovieClips only play at the global frame rate. Effectively, your game character can only run at one speed unless you include other MovieClips and then match them up, as best as possible, to the target speed.
  • MovieClips play holistically. When you play them, you must monitor their current frame if you want to stop at a specific point otherwise they’ll play all the way through. If you want to do this backwards, that’s even more work. If you want to play at a specific rate, ditto.
  • MovieClips have no triggers. If you want to know if frame 5 (or some label) has been reached, for example, you once again need to monitor the clip. Setting up multiple playback monitors is a bit of a pain.

So you can now probably guess what SwagMovieClip does.

As with most of the SwAG classes, SwagMovieClip doesn’t make assumptions about how it’s going to be used. You can either extend it:

import core.instances.SwagMovieClip;
public class myMovieClip extends SwagMovieClip {

…or you can instantiate it (just make sure to pass a reference to the MovieClip instance you want to control to the constructor):

import flash.display.MovieClip;
import core.instances.SwagMovieClip;
public class myMovieClip extends MovieClip {
   var swgClip:SwagMovieClip;
   public function myMovieClip() {
      this.swgClip=new SwagMovieClip(this);

If you’re extending SwagMovieClip, all of the class’ methods can be invoked using simply “this”. For example, to play the clip 3 times at double speed from the “startAnimation” frame to the “endAnimation” frame would look like:

this.playRange("startAnimation", "endAnimation", false, true, 3, 2);

Using the instantiation method, this would be:

swgClip.playRange("startAnimation", "endAnimation", false, true, 3, 2);

As you can probably guess, the playRange method plays from a starting frame (label or index), to an ending frame (label or index), optionally resetting to the start of the animation when done, optionally looping (including a specified number of loops), and at an optional playback speed (2 for double speed, 0.5 for half speed, etc.) This works just as well if the starting frame comes after the ending frame — the clip will play backwards with the specified parameters. Essentially, this one function covers the first three shortcomings I mentioned above.

A related method is playToNextLabel which, as the name suggests, will play the clip from its current position with the supplied parameters until the next label is detected. As with the playRange method, the label might precede the current (starting) frame. Here’s the method signature from the SwagMovieClip class showing all the parameters:

playToNextLabel(startFrame:*, includeLabelFrame:Boolean=false, resetOnEnd:Boolean=false, loop:Boolean=false, repeatLoops:uint=0, playSpeed:Number=1)

The addition of a pause method might seem a little redundant but it comes in handy when you need to determine if an active animation is currently in progress (and paused), or simply stopped. One great reason for wanting this information is to know whether to play out the remaining animation loop such as when a game character is coming to a rest after moving. In fact, games are primarily why I built SwagMovieClip (I used similar functionality to control the animations in the Sidekicks vs. Villains game).

Along these lines I also added a frame trigger mechanism, a method call that’s made whenever a target frame is reached during an animation. Here’s an example (minus the “this” or “swgClip” part):

public function myFrameTrigger():void {
 trace ("Frame 9 was just reached in the animation");
 addFrameTrigger(9, myFrameTrigger);

Obviously I skipped a detail; the addFrameTrigger call belongs in a function somewhere, but otherwise this is pretty much all you’d need. In this case, the myFrameTrigger method will be triggered any time frame 9 of the animation is reached. Since the other methods (playRange, etc.) are responsible for actually starting the animation, all of their features can be used in combination with addFrameTrigger. Here’s a slightly extended example from the one above:

public function myFrameTrigger():void {
 trace ("Frame 9 was just reached in the animation");
 addFrameTrigger(9, myFrameTrigger);
 playRange (10, 8);

Here we’re playing the clip backwards from frame 10 to frame 8 (all other parameters are default — no looping or custom speed), and the myFrameTrigger method should be invoked on frame 9 of the animation. To loop the animation 7 times (stopping on the last frame), at half the current frame rate, the same code would be updated to:

public function myFrameTrigger():void {
 trace ("Frame 9 was just reached in the animation");
 addFrameTrigger(9, myFrameTrigger);
 playRange (10, 8, false, true, 7, 0.5);

Every time frame 9 is encountered here during playback our trigger will be invoked.

Triggers are useful for figuring out how a game character is supposed to be interacting with an environment, for example. If your game character is picking something up from a table, the target object should be “attached” to the character’s hand only when the hand animation is at a certain position. This isn’t hard to achieve by hardcoding frame values into your code but becomes cumbersome if you need to change the animation length, and even more difficult when you need to start playing the animation in various non-standard ways.

Most of SwagMovieClip‘s other functionality comes straight from MovieClip along with expected behaviours. As with any other SwAG class, I won’t recommend using SwagMovieClip unless you actually have a need for such functionality (why bloat your code?) but if you find you’re struggling with customizing your MovieClip animations then this might be worth a gander.

P.S. Thanks for another mention, Adobe!

September 19th, 2014

Posted In: Development / Coding, Internet / Web

Tags: , , , , , , , ,

One Comment

SocialCastr is, in a nutshell, a censorship-resistant, peer to peer, personal broadcasting system.

You can grab yourself a compiled copy here:
And you can download the source code here: (you’ll need Adobe Flash to compile it at the moment)

SocialCastr works with Adobe’s RTMFP, a UDP-based protocol for low-latency peer to peer data delivery. The latency is low enough that you can comfortably transmit audio/video streams from a home computer (with a typical residential network connection), among other neat things — I covered a few in a previous post.

What makes RTMFP especially interesting is how it’s able to propagate things like audio/video streams to other peers. When doing so, you only need to send data to two or three peers and they in turn re-distribute that data to a few others peers, effectively amplifying your bandwidth. This means that you can send data (like an audio/video stream), using a standard computer with a basic internet connection to a potential audience of millions. At least in theory (I was never able to get an audience of millions to test with).

Like most peer to peer protocols, RTMFP depends on a centralized host to introduce peers to each other — the Rendezvous Server. I went over a few options for this in that previous post I’d mentioned above. For the SocialCastr project I decided to test with Cumulus since it’s open source and can eventually be bundled into the application package. Plus, Cumulus is programmable via LUA so it’s a really nice option. You’ll find Cumulus (including the C++ source code), in the GitHub repository for SocialCastr. You can also go with Cirrus or Adobe Media Server, and ArcusNode for Node.js seems like another good alternative (though I haven’t tested it).

SocialCastr uses a “Live Timeline” system — synchronized events like live audio and video effects. The audio and video stream continue to run as-is “beneath” the Live Timeline with the effects applied in realtime on the peer’s computer/device. Although I’ve only tested a couple of effects like video fades and blurs, it can support much more: subtitles, picture in picture, starting or cueing pre-recorded video/audio,  Pixel Bender filters, graphical overlays, audio effects (echo, pitch shift), and so on. Creating a LiveTimeline effect requires only that your class extends the socialcastr.core.timeline.BaseTimelineEffect class and that it then be triggered somehow during a broadcast (I used keystrokes for this). You can see this in action in the socialcastr.core.timeline.SimpleVideoEffect class.

On top of this, I built SocialCastr to be very customizable. The web-based SocialCastr player (Receivr), for example, can be entirely stripped of any identifying UI elements. You don’t like the logo I designed? No problem, just tell the player to strip it out. Or use your own. Up to you.

With SocialCastr I had to deal with the problem of connecting people to each other. Basically, once connected to the Rendezvous Server (to which everyone is connected), how do you establish private or semi-private groups without first agreeing to specific group names or specs?

I did this in one-and-a-half ways:

  1. The AnnounceChannel (socialcastr.core.AnnounceChannel), which all peers join in order to get a list of broadcasters. It’s essentially a public directory of everyone who’s currently connected and broadcasting.
  2. The SocialCastr ID system (socialcastr.core.SCID), which is used to connect a peer directly to an existing stream identified by the SCID (read more about it here). The SCID system runs on top of the AnnounceChannel (hence the “half”), but bypasses the AnnounceChannel’s default “list all broadcasters” call.

This is something that sometimes trips people up when they first start working with RTMFP (or any p2p technology, actually). I don’t know if the AnnounceChannel is the most elegant solution, but it certainly works so I figure it might be a good launchpad for someone trying to do the same thing.

So as with all the other projects I’ve posted about, even if SocialCastr isn’t the type of software you might end up using, it might at least help you to work around some of the hurdles and headaches of getting a robust peer to peer network up and running with RTMFP. If you’ve read about how peer to peer networking works in SwAG, you’re already halfway there.

P.S. Thanks for the mention, Adobe!

September 4th, 2014

Posted In: Internet / Web, Privacy / Surveillance

Tags: , , , , , , , ,

Leave a Comment

I admit to having more than a soft spot for Adobe’s technology, but that’s not why I was so peeved when Steve Jobs made his much ballyhooed announcement that Flash on mobile was just the worst thing since Hitler.

For starters, much of Jobs’ characterization was just plain wrong. His problems with Flash not being “open” were gloriously misinformed as Adobe’s open source efforts, which included Flash and Flex, plus many of the video, audio, and networking technologies they contain, were already well established as open source technologies at that point.

If the argument is that the Flash virtual machine isn’t open source, one can easily turn that around and correctly state that Safari, the virtual machine for HTML5 / JavaScript, is also not open source. To say that Apple has been a champion of giving people choice is not exactly true, so claiming that they’re championing HTML5 “for the people” is equally as dubious. In fact, HTML5 itself is not as open as some may claim.

Jobs’ insistence that HTML5 is a “standard” was equally incorrect, as the myriad of sites, services, and projects that have sprung up trying to either work around or at least document the many incompatibilities, quirks, and just old plain lack of support in the HTML5 “standard” attest to. This lack of standardization is so pronounced that it alone can be used to successfully identify individual browsers and de-anonymize users (perhaps even much worse).

Jobs didn’t think Flash was needed to access video since HTML5 formats like H.264 (MP4) were so ubiquitous. On this point I’d have to agree, but that was never the sole reason that Flash became synonymous with online video. The reason Adobe’s player won out was because of a robust server architecture that, coupled with Adobe’s edge Content Delivery Networks, makes the technology a viable solution. Delivering MP4 streams over HTTP to browsers from a server farm is a lot more prohibitive, with cost being just one factor.

In his Flash critique, Jobs made the unsubstantiated claim that Flash was the number one reason why Macs crashed, a statement he never bothered to back up and which, as far as I know, was purely fictional or at best incredibly scape-goaty.

While Flash wasn’t a great mobile experience, mostly because it wasn’t set up to both deal with mobile gestures and co-exist on a web page, the same could be said of unresponsive or badly designed HTML5 sites. And whatever shortcomings the Flash player had, I’m sure they could have been addressed.

I’m not the only person to think that Flash was done away with unjustly. Amazon is trying to revive it for their devices, BlackBerry never lost it, and it Android can’t quite seem to shake itself of it. Judging by the popularity of the “How do I manually install Flash on my mobile device?” topic over at Adobe — 24.7 million views as of today– Flash is far from fading away.

The biggest injustice in this debacle, however, is the one I see being imposed on web developers.

As someone who has worked in ActionScript 3 for years, going to HTML5 / CSS3 / JavaScript was like taking a step ten years into the past. The same issues we were dealing with in Flash back then — performance, load times, code organization — are all back with a vengeance.

Even something as basic as frame-based animation is only partially supported in most modern HTML5-capable browsers with most requiring reams of code and workarounds for “full compatibility”.

Rudimentary sound support, along with the same issues we were grappling with in Flash many years ago (synchronization, maximum mixing channels, etc.), has made it’s way into HTML5. Instantly, developers learned that the web “standard” wasn’t quite up living up to its name.

Companies too have learned that they prematurely jumped on the HTML5 bandwagon and have had to re-think their approaches.

But it’s not that HTML5 is terrible.

In fact, as devices get faster and capable of handling more complex code, the mobile browser will slowly evolve to become it’s own robust virtual machine, much as Java and the Flash player are now. Eventually, much of what is today erroneously called a “standard” will actually become one, mostly, give or take, across most browsers. But we’re not even close to getting there yet.

Still, now that I’ve had time to truly immerse myself in HTML5 and experience how it works across browsers and devices, I see the potential for a much improved web experience.

As I mentioned, HTML5 to me seems like Flash circa 2003, around version 7 , with the additional complexity of browser fragmentation. Under the hood, there isn’t much that close-to-metal developers have at their disposal. Execution speed, JavaScript functionality, even things like error handling, are up to the whims of the browser manufacturers. jQuery definitely helps a lot, but cross-browser compatibility requires that you don’t push things to the bleeding edge.

Up front, the only real improvements are in the tools available for expression — better ways to animate, addition of sound and audio, improved font handling, dynamic drawing APIs, and so on. This can all be put together to produce nice, expressive web sites and games, examples of which are more quite numerous these days. I’ve even done a couple myself. And it’s because of this exposure that I can’t recommend HTML5 for anything other than nice, expressive sites and somewhat basic interactive games. The so-called “standards” required for more demanding code are simply not up to snuff and are more often a hindrance than a help.

The fact that HTML, regardless of version, is still the de facto markup language, and that JavaScript is still the de facto functional language, means that they simply aren’t likely to go away any time soon. That’s not necessarily a bad thing, but we really should be checking our (often deluded) exuberance about the browser technologies at the door.

August 14th, 2014

Posted In: Development / Coding, Internet / Web

Tags: , , , , , , ,

One Comment

Yeah,  application frameworks are a dime a dozen these days. That’s why SwAG isn’t a framework but rather a toolkit — the Swiss Army Gear toolkit for ActionScript 3, to be exact.

As the name implies, this small-ish library contains useful code that can be employed wherever needed, as needed, without the full weight or presumptuousness of a full-on framework. In other words, it should be useful for you whether you have a project that’s well under way or are just starting out.

Because the library has lots of disparate features, I’ll be dedicating a number of future posts discussing them in detail and providing (hopefully) useful examples. Here is a brief preview:

  • Peer-to-peer networking, streaming, data sharing using RTMFP (via and
  • Decoupled or source-optional event broadcasting (via swag.core.SwagDispatcher)
  • Extended MovieClip playback control (via swag.core.instances.SwagMovieClip)
  • SQLite database functionality for Adobe AIR (via swag.core.instances.SQLiteDatabase)
  • Extended date/time manipulation and comparison functionality (via swag.core.instances.SwagDate and swag.core.instances.SwagTime)
  • Extensive data analysis/conversion functionality (via swag.core.SwagDataTools)
  • ZIP data access and extraction (via swag.core.instances.SwagZip)
  • Extended runtime introspection (via swag.core.SwagSystem)
  • Extended HTTP/HTTPS data loading functionality (via swag.core.instances.SwagLoader)

Some of these are used extensively in SocialCastr and Araknid and they definitely made my life easier. SwAG doesn’t presume to be the only code running so adding it or removing it, mid-project or otherwise, is easy and straightforward. I’ve chosen to not include it in pure AS3 projects like TorAS or WRASE because they’re much more useful as autonomous libraries. Applications, however, are meant to be used rather than incorporated into other projects, so in those cases I happily stick SwAG into every nook and cranny.

SwAG had additional functionality which has been yanked since these make way more sense as individual projects:

  • BMPImage, for loading and displaying Windows Bitmap (BMP) images
  • RSSChannel, for reading and manipulating RSS feed (XML) data
  • XLSXFile, for reading and manipulating a Microsoft Office Open XML Format Spreadsheet (Excel) file

I don’t know if / when I’ll get around to updating and publishing these but I’m not averse to sharing if you want to get in touch with me directly.

Otherwise, grab yourself a copy of the pretty-well-documented toolkit here:
…and stay tuned for SwAG fun and frolic.

January 29th, 2014

Posted In: Development / Coding, Internet / Web

Tags: , , , , , , , ,


I imagine that this application would benefit from a little TorAS integration but in the meantime it’s still pretty useful [downloads are at the bottom of this post].

Since I spent time figuring out how to describe it on Google Code, I thought I’d rather post that than hurt my brain again. So here’s what Araknid does:

[Araknid is] An Adobe AIR application that crawls and archives web pages and assets such as images and scripts into a searchable/convertible SQLite database file. Use it to create a deep search index of your (or any other) site, your intranet, or even the whole web. Uses user-defined regular expressions to match and extrapolate links and other dynamic site information. Built on SwAG Toolkit ActionScript 3 application framework, user interface developed in Flash CS6 (.fla file). Dynamically supports latest versions of Adobe AIR on mobile.

Araknid is still quite new, meaning database interactions will need to be optimized, regular expressions will need to be tweaked, and some important features will need to be added (for example, crawl only under a specific URL or domain). But core functionality should be there, along with plenty of room for growth for anyone who wants to fiddle with the source code.

Here’s what you’ll see when you run the software…the legend is below:

Araknid User Interface Legend

1. Click here to select where the Araknis database (SQLite) will be stored. Once set, clicking here will open the SQLLite database file in the default application.
2. Pauses and unpauses any currently running crawl.
3. Opens the currently running crawl URL (#6) in a new browser window (if you’re curious to see what’s being crawled).
4. Variable crawl delay (in seconds). Prevents servers from flagging Araknid as an attacker or malware.
5. The percentage loaded of the currently running crawl URL (#6).
6. The currently running crawl URL. Pause Araknid, enter your own URL, and unpause to start a new crawl.
7. Countdown clock showing when the next crawl will happen (in seconds). Based on the crawl delay (#4).
8. A list of URLs extracted from the currently running crawl URL. These are added to the database (if not already crawled), and queued for subsequent crawls.

TIP: Rename or delete the database file to reset Araknid (like a new install).

ADVANCED TIP: You can update the regular expressions used to filter / extract URLs from various HTML tags. To do this:
1. Shut down Araknid.
2. Update the configuration XML file (config.xml) in the Araknid installation directory (for example, C:\Program Files (x86)\Araknid\config.xml).
3. Delete the Araknid application storage folder: C:\Users\[YOUR USER NAME]\AppData\Roaming\Araknid\Local Store
 WARNING: This step resets your application settings (you’ll need to re-select the database file on next startup if you want to continue previous crawls).
4. On next restart, Araknid will use the new regular expressions for subsequent crawls.

Araknid v1.0 Downloads

All desktop operating systems:

  1. Download and execute Adobe AIR installer:
  2. Download and install Araknid:

Windows (32/64-bit):

Source code (ActionScript / Flash CS6 user interface):

…and something to view the resulting SQLite database:

January 21st, 2014

Posted In: Development / Coding, Internet / Web

Tags: , , , ,

Leave a Comment

This TorAS thing is going to be a lengthy project — there’s still lots left to implement and older code to one day upgrade — but I received some great feedback about the appropriateness of communicating over Tor using unencrypted HTTP (it’s not very appropriate in many situations). So I’ve branched the current stable version and added TLS/SSL support (courtesy of as3crypto), in a development branch:

I’ll add it back into the main branch as soon as I get some time to document it fully, but the bulk of the new functionality has been covered in the updated Developers Guide:

I may also have added source code comments so have a peek.

TorAS ActionScript source code is made public under a liberal license (MIT), developed on open source technology (FlashDevelop), incorporating open source technology (Tor “Expert Bundle” binary , released under a similar license and spirit),  and comes with a handy step-by-step guide. It’s most powerful on Windows (on account of the bundled Tor binary), but you should be able to use it on AIR for Android with something like Orbot (is there an official Tor router app for iOS?), and in fact anywhere AIR and Tor can run together.

January 21st, 2014

Posted In: Development / Coding, Internet / Web, Privacy / Surveillance

Tags: , , , , , , ,