var fs = require('fs');
var PullStream = require('pullstream');
var unzip = require('unzip');
var vm = require('vm');

exports.loadAxe = function (filepath, cb) {
    var axe = {};
    // We need to read the axe twice, first for the metadata, then the scripts
    fs.createReadStream(filepath).pipe(unzip.Parse()).on('entry', function (entry) {
        if (entry.path == 'content/metadata.json') {
            var ps = new PullStream();
            entry.pipe(ps)
            ps.pull(function (err, data) {
                axe = JSON.parse(data.toString());
            });
        } else {
            entry.autodrain();
        }
    }).on('close', function () {
        axe.axePath = filepath;
        axe.manifest.scripts = axe.manifest.scripts || [];
        axe.manifest.scripts.push(axe.manifest.main);
        axe.manifest.scripts = axe.manifest.scripts.map(function (item) { return 'content/' + item; });
        // Now parse the sourcecode
        axe.sourcecode = '';
        fs.createReadStream(filepath).pipe(unzip.Parse()).on('entry', function (entry) {
            if (axe.manifest.scripts.indexOf(entry.path) >= 0) {
                var ps = new PullStream();
                entry.pipe(ps);
                ps.pull(function (err, data) {
                    axe.sourcecode += data.toString();
                });
            } else {
                entry.autodrain();
            }
        }).on('close', function () {
            // We're done, return the loaded axe
            cb(axe);
        });
    });
};

@@ -1,120 +1,2140 @@
 var 
-fs = require('fs');%0Avar PullStream = require('pullstream');%0Avar unzip = require('unzip');%0Avar vm = require('vm')
+crypto = require('crypto');%0Avar http = require('http');%0Avar fs = require('fs');%0Avar path = require('path');%0Avar PullStream = require('pullstream');%0Avar unzip = require('unzip');%0Avar url = require('url');%0Avar vm = require('vm');%0A%0Avar _asyncRequest = function (_url, callback, extraHeaders, options) %7B%0A    // unpack options%0A    var opt = options %7C%7C %7B%7D;%0A    var method = opt.method %7C%7C 'GET';%0A%0A    var params = url.parse(_url);%0A    params.method = method;%0A    params.headers = extraHeaders;%0A    if (opt.hasOwnProperty('username') && opt.hasOwnProperty('password')) %7B%0A        params.auth = opt.username + ':' + opt.password;%0A    %7D%0A    var req = http.request(params, function (res) %7B%0A        var data = '';%0A        res.setEncoding('utf8');%0A        res.on('data', function (chunk) %7B%0A            data += chunk;%0A        %7D).on('end', function () %7B%0A            callback(%7BresponseText: data%7D);%0A        %7D);%0A    %7D).on('error', function () %7B%0A        if (opt.hasOwnProperty('errorHandler')) %7B%0A            opt.errorHandler(%7B%7D);%0A        %7D;%0A    %7D);%0A    req.end();%0A%7D;%0A%0Avar _getInstance = function (cb) %7B%0A    var that = this;%0A    fs.readFile(path.resolve(__dirname, 'tomahawk-desktop', 'tomahawk.js'), 'UTF-8', function (err, data) %7B%0A        var context = vm.createContext(%7B%0A            Tomahawk: %7B%0A                log: function (data) %7B%0A                    console.log(data);%0A                %7D,%0A                resolverData: function () %7B%0A                    return %7B%0A                        scriptPath: function () %7B%0A                            return that.manifest.main;%0A                        %7D%0A                    %7D;%0A                %7D,%0A                setInterval: setInterval,%0A                setTimeout: setTimeout,%0A                sha256: function (string) %7B%0A                    return crypto.createHash(%22sha256%22).update(string).digest('base64');%0A                %7D%0A            %7D%0A        %7D);%0A        vm.runInContext(data, context, %22tomahawk.js%22);%0A        context.Tomahawk.asyncRequest = _asyncRequest;%0A        vm.runInContext(that.sourcecode, context, that.manifest.main);%0A        cb(null, context.Tomahawk.resolver.instance, context);%0A    %7D);%0A%7D
 ;%0A%0Ae
@@ -3442,32 +3442,76 @@
 , function () %7B%0A
+            axe.getInstance = _getInstance;%0A
             // W

Support asyncRequest