<commit_before>var FS = require("fs");
var Path = require("path");
var SWFRenderer = require("../third_party/SwfImgRenderer/index.js");
var SWFParser = require("../third_party/Gordon/parser.js");
var Settings = require("./settings.js");

var kItemsDir;
var kDoneFile;

function* extract() {
  kItemsDir = window.userDataDir + "/ItemCache";
  kDoneFile = Path.join(kItemsDir, "_done.dat");

  var alreadyExtracted = yield prepareOutputDir();
  if (alreadyExtracted)
    return true;

  var swfObjects = [];
  var idToName = {};
  yield parseSWF(swfObjects, idToName);

  var swfRenderer = new SWFRenderer();
  var generators = [];
  swfObjects.forEach(function(swfObject) {
    generators.push(writeSWFObject(swfObject, swfRenderer, idToName));
  });
  yield generators;

  yield finalizeOutputDir();

  console.log("Success extracting images from SWF");
  return true;
}

// Make sure our Image Cache exists. Returns true if we've already extracted
// all the images.
function* prepareOutputDir() {
  const caller = yield;
  FS.access(kDoneFile, function(err) {
    if (!err) return caller.success(true);  // already extracted
    FS.mkdir(kItemsDir, function(err) {
      caller.success(false);
    });
  });
}

// Parse the SWF file, collecting all the objects and their names.
// Both arguments are out params.
function* parseSWF(swfObjects, idToName) {
  const caller = yield;

  var swfPath = getSWFPath();
  FS.readFile(swfPath, function(err, swfData) {
    if (err) return caller.failure(err);

    var parser = new SWFParser();
    parser.parse(swfPath, swfData, function(swfObject) {
      if (swfObject.type == "image") {
        swfObjects[swfObject.id] = swfObject;
      } else if (swfObject.symbolClasses) {
        for (var name in swfObject.symbolClasses)
          idToName[swfObject.symbolClasses[name]] = name;
      }
    }, function(err) {
      if (err) return caller.failure(err);
      caller.success();
    });
  });
}

// Write all the SWF objects out to PNG files.
function* writeSWFObject(swfObject, swfRenderer, idToName) {
  const caller = yield;
  swfRenderer.render(swfObject, function(obj, png) {
    var tagName = idToName[obj.id];
    var match = /ImagePack_items_Embeds__e_([0-9]+)_(.*)/.exec(tagName);
    var name = match ? match[2] : "Unnamed";
    var path = Path.join(kItemsDir, name + "_i" + obj.id + ".png");
    FS.writeFile(path, png, function(err) {
      if (err) {
        console.warn("Failed to save: ", path, ": ", err);
        return caller.failure(err);
      }
      caller.success();
    });
  });
}

// Mark the Image Cache as "finished".
function* finalizeOutputDir() {
  const caller = yield;
  FS.writeFile(kDoneFile, "true", function(err) {
    if (err) return caller.failure(new Error("Failed to write done file"));
    caller.success();
  });
}

function getSWFPath() {
  var path = Path.join(Settings.getLeagueRoot(),
      "RADS/projects/lol_air_client/releases/");
  var version = "0.0.1.140";
  var versions = FS.readdirSync(path);
  for (var i in versions) {
    if (/^[0-9]+\.[0-9]+/.exec(versions[i]))
      version = versions[i];
  }
  path = Path.join(path, version);
  path = Path.join(path, "deploy/assets/imagePacks/ImagePack_items.swf");
  return path;
}

function resolveItemPath(file) {
  // Our HTML runs in the context of the lib/ directory, so go up 1.
  return Path.join(kItemsDir, file);
}

function* markDirty() {
  const caller = yield;
  FS.unlink(kDoneFile, caller.success);
}

exports.extract = extract;
exports.resolveItemPath = resolveItemPath;
exports.markDirty = markDirty;
<commit_msg>swfExtractor uses asyncified FS<commit_after>var Path = require("path");
var SWFRenderer = require("../third_party/SwfImgRenderer/index.js");
var SWFParser = require("../third_party/Gordon/parser.js");
var Settings = require("./settings.js");
var Async = require("./async.js");
var FS = Async.asyncifyNodeModule(require("fs"));

var kItemsDir;
var kDoneFile;

function* extract() {
  kItemsDir = window.userDataDir + "/ItemCache";
  kDoneFile = Path.join(kItemsDir, "_done.dat");

  var alreadyExtracted = yield prepareOutputDir();
  if (alreadyExtracted)
    return true;

  var swfObjects = [];
  var idToName = {};
  yield parseSWF(swfObjects, idToName);

  var swfRenderer = new SWFRenderer();
  var generators = [];
  swfObjects.forEach(function(swfObject) {
    generators.push(writeSWFObject(swfObject, swfRenderer, idToName));
  });
  yield generators;

  yield finalizeOutputDir();

  console.log("Success extracting images from SWF");
  return true;
}

// Make sure our Image Cache exists. Returns true if we've already extracted
// all the images.
function* prepareOutputDir() {
  try {
    yield FS.accessAsync(kDoneFile);
    return true;
  } catch(e) { }

  try {
    yield FS.mkdirAsync(kItemsDir);
  } finally {
    return false;
  }
}

// Parse the SWF file, collecting all the objects and their names.
// Both arguments are out params.
function* parseSWF(swfObjects, idToName) {
  const caller = yield;

  var swfPath = getSWFPath();
  var swfData = yield FS.readFileAsync(swfPath);

  var parser = new SWFParser();
  parser.parse(swfPath, swfData, function(swfObject) {
    if (swfObject.type == "image") {
      swfObjects[swfObject.id] = swfObject;
    } else if (swfObject.symbolClasses) {
      for (var name in swfObject.symbolClasses)
        idToName[swfObject.symbolClasses[name]] = name;
    }
  }, function(err) {
    if (err) return caller.failure(err);
    caller.success();
  });
}

// Write all the SWF objects out to PNG files.
function* writeSWFObject(swfObject, swfRenderer, idToName) {
  const caller = yield;
  swfRenderer.render(swfObject, function(obj, png) {
    var tagName = idToName[obj.id];
    var match = /ImagePack_items_Embeds__e_([0-9]+)_(.*)/.exec(tagName);
    var name = match ? match[2] : "Unnamed";
    var path = Path.join(kItemsDir, name + "_i" + obj.id + ".png");
    FS.writeFile(path, png, function(err) {
      if (err) {
        console.warn("Failed to save: ", path, ": ", err);
        return caller.failure(err);
      }
      caller.success();
    });
  });
}

// Mark the Image Cache as "finished".
function* finalizeOutputDir() {
  try {
    yield FS.writeFileAsync(kDoneFile, "true");
    return true;
  } catch(e) {
    throw new Error("Failed to write done file: " + e);
  }
}

function getSWFPath() {
  var path = Path.join(Settings.getLeagueRoot(),
      "RADS/projects/lol_air_client/releases/");
  var version = "0.0.1.140";
  var versions = FS.readdirSync(path);
  for (var i in versions) {
    if (/^[0-9]+\.[0-9]+/.exec(versions[i]))
      version = versions[i];
  }
  path = Path.join(path, version);
  path = Path.join(path, "deploy/assets/imagePacks/ImagePack_items.swf");
  return path;
}

function resolveItemPath(file) {
  // Our HTML runs in the context of the lib/ directory, so go up 1.
  return Path.join(kItemsDir, file);
}

function* markDirty() {
  const caller = yield;
  FS.unlink(kDoneFile, caller.success);
}

exports.extract = extract;
exports.resolveItemPath = resolveItemPath;
exports.markDirty = markDirty;
<|endoftext|>


<commit_before>jasmine.ConsoleReporter = function(doc, logErrors) {
  this.logErrors = logErrors == false ? false : true
};

jasmine.ConsoleReporter.prototype.reportRunnerStarting = function(runner) {
  var showPassed, showSkipped;
  var suites = runner.suites();
  this.startedAt = new Date();
};

jasmine.ConsoleReporter.prototype.reportRunnerResults = function(runner) {
  var results = runner.results();
  var specs = runner.specs();
  var specCount = specs.legnth;
  var message = "" + specCount + " spec" + (specCount == 1 ? "" : "s" ) + ", " + results.failedCount + " failure" + ((results.failedCount == 1) ? "" : "s");
  message += " in " + ((new Date().getTime() - this.startedAt.getTime()) / 1000) + "s";

  $native.exit(results.failedCount > 0 ? 1 : 0)
};

jasmine.ConsoleReporter.prototype.reportSuiteResults = function(suite) {
};

jasmine.ConsoleReporter.prototype.reportSpecResults = function(spec) {
  var results = spec.results();
  var status = results.passed() ? 'passed' : 'failed';
  if (results.skipped) {
    status = 'skipped';
  }
  var resultItems = results.getItems();
  for (var i = 0; i < resultItems.length; i++) {
    var result = resultItems[i];
    if (this.logErrors && result.type == 'expect' && result.passed && !result.passed()) {
      console.log("ERROR: %s", spec.getFullName())
      if (result.trace.stack) {
        console.log(result.trace.stack)
      }
      else {
       console.log(result.message)
      }
    }
  }
};

jasmine.ConsoleReporter.prototype.specFilter = function(spec) {
  return true;
};
<commit_msg>Better spec error output when running headless<commit_after>jasmine.ConsoleReporter = function(doc, logErrors) {
  this.logErrors = logErrors == false ? false : true
};

jasmine.ConsoleReporter.prototype.reportRunnerStarting = function(runner) {
  var showPassed, showSkipped;
  var suites = runner.suites();
  this.startedAt = new Date();
};

jasmine.ConsoleReporter.prototype.reportRunnerResults = function(runner) {
  var results = runner.results();
  var specs = runner.specs();
  var specCount = specs.legnth;
  var message = "" + specCount + " spec" + (specCount == 1 ? "" : "s" ) + ", " + results.failedCount + " failure" + ((results.failedCount == 1) ? "" : "s");
  message += " in " + ((new Date().getTime() - this.startedAt.getTime()) / 1000) + "s";

  $native.exit(results.failedCount > 0 ? 1 : 0)
};

jasmine.ConsoleReporter.prototype.reportSuiteResults = function(suite) {
};

jasmine.ConsoleReporter.prototype.reportSpecResults = function(spec) {
  var results = spec.results();
  var status = results.passed() ? 'passed' : 'failed';
  if (results.skipped) {
    status = 'skipped';
  }
  var resultItems = results.getItems();
  for (var i = 0; i < resultItems.length; i++) {
    var result = resultItems[i];
    if (this.logErrors && result.type == 'expect' && result.passed && !result.passed()) {
      console.log("ERROR: " + spec.getFullName())
      if (result.trace.stack) {
        console.log(result.trace.stack)
      }
      else {
       console.log(result.message)
      }
    }
  }
};

jasmine.ConsoleReporter.prototype.specFilter = function(spec) {
  return true;
};
<|endoftext|>


<commit_before>describe('FileTransfer', function() {
    it("should exist and be constructable", function() {
        var ft = new FileTransfer();
        expect(ft).toBeDefined();
    });
    it("should contain proper functions", function() {
        var ft = new FileTransfer();
        expect(typeof ft.upload).toBe('function');
        expect(typeof ft.download).toBe('function');
    });
    describe('FileTransferError', function() {
        it("FileTransferError constants should be defined", function() {
            expect(FileTransferError.FILE_NOT_FOUND_ERR).toBe(1);
            expect(FileTransferError.INVALID_URL_ERR).toBe(2);
            expect(FileTransferError.CONNECTION_ERR).toBe(3);
        });
    });
    describe('download method', function() {
        it("should be able to download a file", function() {
            var fail = jasmine.createSpy();
            var remoteFile = "https://ajax.googleapis.com/ajax/libs/dojo/1.7.2/dojo/dojo.js";
            var localFileName = remoteFile.substring(remoteFile.lastIndexOf('/')+1);
            var downloadWin = jasmine.createSpy().andCallFake(function(entry) {
                expect(entry.name).toBe(localFileName);
            });
            var fileWin = function(fileEntry) {
                var ft = new FileTransfer();
                ft.download(remoteFile, fileEntry.fullPath, downloadWin);
            };

            // root is defined in the html page containing these tests
            runs(function() {
                root.getFile(localFileName, {create: true, exclusive: false}, fileWin, fail);
            });

            waitsFor(function() { return downloadWin.wasCalled; }, "downloadWin", Tests.TEST_TIMEOUT);

            runs(function() {
                expect(downloadWin).toHaveBeenCalled();
                expect(fail).not.toHaveBeenCalled();
            });
        });
    });
});
<commit_msg>[CB-798] FileTransfer tests for HTTP status<commit_after>describe('FileTransfer', function() {

    // https://github.com/don/cordova-filetransfer
    var server = "http://cordova-filetransfer.jitsu.com";

    // deletes and re-creates the specified content
    var writeFile = function(fileName, fileContent, success, error) {
        var content = fileContent;
        deleteEntry(fileName, function() {
            root.getFile(fileName, {create: true}, function(fileEntry) {
                fileEntry.createWriter(function (writer) {

                    writer.onwrite = function(evt) {
                        success(fileEntry);
                    };

                    writer.onabort = function(evt) {
                        error(evt);
                    };

                    writer.error = function(evt) {
                        error(evt);
                    };

                    writer.write(content + "\n");
                }, error);
            }, error);
        }, error);
    };

    var getMalformedUrl = function() {
        if (device.platform.match(/Android/i)) {
            // bad protocol causes a MalformedUrlException on Android
            return "httpssss://example.com";
        } else {
            // iOS doesn't care about protocol, space in hostname causes error
            return "httpssss://exa mple.com";
        }
    };

    // NOTE: copied from file.tests.js
    // deletes specified file or directory
    var deleteEntry = function(name, success, error) {
        // deletes entry, if it exists
        window.resolveLocalFileSystemURI(root.toURL() + '/' + name,
            function(entry) {
                if (entry.isDirectory === true) {
                    entry.removeRecursively(success, error);
                } else {
                    entry.remove(success, error);
                }
            }, success);
    };
    // deletes and re-creates the specified file
    var createFile = function(fileName, success, error) {
        deleteEntry(fileName, function() {
            root.getFile(fileName, {create: true}, success, error);
        }, error);
    };
    // deletes file, if it exists, then invokes callback
    var deleteFile = function(fileName, callback) {
        root.getFile(fileName, null,
            // remove file system entry
            function(entry) {
                entry.remove(callback, function() { console.log('[ERROR] deleteFile cleanup method invoked fail callback.'); });
            },
            // doesn't exist
            callback);
    };
    // end copied from file.tests.js

    it("should exist and be constructable", function() {
        var ft = new FileTransfer();
        expect(ft).toBeDefined();
    });
    it("should contain proper functions", function() {
        var ft = new FileTransfer();
        expect(typeof ft.upload).toBe('function');
        expect(typeof ft.download).toBe('function');
    });
    describe('FileTransferError', function() {
        it("FileTransferError constants should be defined", function() {
            expect(FileTransferError.FILE_NOT_FOUND_ERR).toBe(1);
            expect(FileTransferError.INVALID_URL_ERR).toBe(2);
            expect(FileTransferError.CONNECTION_ERR).toBe(3);
        });
    });

    describe('download method', function() {

        // NOTE: if download tests are failing, check the white list
        // Android
        //   <access origin="httpssss://example.com"/>
        //   <access origin="apache.org" subdomains="true" />
        //   <access origin="cordova-filetransfer.jitsu.com"/>
        // iOS
        //   # Cordova.plist
        //   ExternalHosts
        //     - Item 1 String cordova-filetransfer.jitsu.com
        //     - Item 2 String *.apache.org

        it("should be able to download a file", function() {
            var fail = jasmine.createSpy();
            var remoteFile = server + "/robots.txt"
            var localFileName = remoteFile.substring(remoteFile.lastIndexOf('/')+1);
            var downloadWin = jasmine.createSpy().andCallFake(function(entry) {
                expect(entry.name).toBe(localFileName);
                deleteFile(localFileName);
            });

            runs(function() {
                var ft = new FileTransfer();
                ft.download(remoteFile, root.fullPath + "/" + localFileName, downloadWin, fail);
            });

            waitsFor(function() { return downloadWin.wasCalled; }, "downloadWin", Tests.TEST_TIMEOUT);

            runs(function() {
                expect(downloadWin).toHaveBeenCalled();
                expect(fail).not.toHaveBeenCalled();
            });
        });
        it("should get http status on failure", function() {
            var downloadWin = jasmine.createSpy();

            var remoteFile = server + "/404";
            var localFileName = remoteFile.substring(remoteFile.lastIndexOf('/')+1);
            var downloadFail = jasmine.createSpy().andCallFake(function(error) {
                expect(error.http_status).toBe(404);
                expect(error.http_status).not.toBe(401, "Ensure " + remoteFile + " is in the white list");
                deleteFile(localFileName);
            });

            runs(function() {
                var ft = new FileTransfer();
                ft.download(remoteFile, root.fullPath + "/" + localFileName, downloadWin, downloadFail);
            });

            waitsFor(function() { return downloadFail.wasCalled; }, "downloadFail", Tests.TEST_TIMEOUT);

            runs(function() {
                expect(downloadFail).toHaveBeenCalled();
                expect(downloadWin).not.toHaveBeenCalled();
            });
        });
        it("should handle malformed urls", function() {

            var downloadWin = jasmine.createSpy();

            var remoteFile = getMalformedUrl();
            var localFileName = "download_malformed_url.txt";
            var downloadFail = jasmine.createSpy().andCallFake(function(error) {

                // Note: Android needs the bad protocol to be added to the access list
                // <access origin=".*"/> won't match because ^https?:// is prepended to the regex
                // The bad protocol must begin with http to avoid automatic prefix
                expect(error.http_status).not.toBe(401, "Ensure " + remoteFile + " is in the white list");
                expect(error.code).toBe(FileTransferError.INVALID_URL_ERR);
                deleteFile(localFileName);
            });

            runs(function() {
                var ft = new FileTransfer();
                ft.download(remoteFile, root.fullPath + "/" + localFileName, downloadWin, downloadFail);
            });

            waitsFor(function() { return downloadFail.wasCalled; }, "downloadFail", Tests.TEST_TIMEOUT);

            runs(function() {
                expect(downloadFail).toHaveBeenCalled();
                expect(downloadWin).not.toHaveBeenCalled();
            });
        });
        it("should handle unknown host", function() {
            var downloadWin = jasmine.createSpy();

            var remoteFile = "http://foobar.apache.org/index.html";
            var localFileName = remoteFile.substring(remoteFile.lastIndexOf('/')+1);
            var downloadFail = jasmine.createSpy().andCallFake(function(error) {
                expect(error.code).toBe(FileTransferError.CONNECTION_ERR);
            });

            runs(function() {
                var ft = new FileTransfer();
                ft.download(remoteFile, root.fullPath + "/" + localFileName, downloadWin, downloadFail);
            });

            waitsFor(function() { return downloadFail.wasCalled; }, "downloadFail", Tests.TEST_TIMEOUT);

            runs(function() {
                expect(downloadFail).toHaveBeenCalled();
                expect(downloadWin).not.toHaveBeenCalled();
            });
        });
        it("should handle bad file path", function() {
            var fail = jasmine.createSpy();
            var downloadWin = jasmine.createSpy();

            var remoteFile = server;
            var badFilePath = "c:\\54321";
            var downloadFail = jasmine.createSpy().andCallFake(function(error) {
                expect(error.code).toBe(FileTransferError.FILE_NOT_FOUND_ERR);
            });

            runs(function() {
                var ft = new FileTransfer();
                ft.download(remoteFile, badFilePath, downloadWin, downloadFail);
            });

            waitsFor(function() { return downloadFail.wasCalled; }, "downloadFail", Tests.TEST_TIMEOUT);

            runs(function() {
                expect(downloadFail).toHaveBeenCalled();
                expect(downloadWin).not.toHaveBeenCalled();
                expect(fail).not.toHaveBeenCalled();
            });
        });
    });
    describe('upload method', function() {

        it("should be able to upload a file", function() {
            var fail = jasmine.createSpy();
            var uploadFail = jasmine.createSpy();

            var remoteFile = server + "/upload";
            var localFileName = "upload.txt";

            var uploadWin = jasmine.createSpy().andCallFake(function(uploadResult) {
                expect(uploadResult.bytesSent).toBeGreaterThan(0);
                expect(uploadResult.responseCode).toBe(200);
                expect(uploadResult.response).toBeDefined();
                deleteEntry(localFileName);
            });

            var fileWin = function(fileEntry) {
                ft = new FileTransfer();

                var options = new FileUploadOptions();
                options.fileKey = "file";
                options.fileName = localFileName;
                options.mimeType = "text/plain";

                var params = new Object();
                params.value1 = "test";
                params.value2 = "param";
                options.params = params;

                // removing options cause Android to timeout
                ft.upload(fileEntry.fullPath, remoteFile, uploadWin, uploadFail, options);
            };

            runs(function() {
                writeFile(localFileName, "this file should upload", fileWin, fail);
            });

            waitsFor(function() { return uploadWin.wasCalled; }, "uploadWin", Tests.TEST_TIMEOUT);

            runs(function() {
                expect(uploadWin).toHaveBeenCalled();
                expect(uploadFail).not.toHaveBeenCalled();
                expect(fail).not.toHaveBeenCalled();
            });
        });
        it("should get http status on failure", function() {
            var fail = jasmine.createSpy();
            var uploadWin = jasmine.createSpy();

            var remoteFile = server + "/403";
            var localFileName = "upload_expect_fail.txt";
            var uploadFail = jasmine.createSpy().andCallFake(function(error) {
                expect(error.http_status).toBe(403);
                expect(error.http_status).not.toBe(401, "Ensure " + remoteFile + " is in the white list");
                deleteEntry(localFileName);
            });

            var fileWin = function(fileEntry) {
                var ft = new FileTransfer();

                var options = new FileUploadOptions();
                options.fileKey="file";
                options.fileName=fileEntry.name;
                options.mimeType="text/plain";

                ft.upload(fileEntry.fullPath, remoteFile, uploadWin, uploadFail, options);
            };

            runs(function() {
                writeFile(localFileName, "this file should fail to upload", fileWin, fail);
            });

            waitsFor(function() { return uploadFail.wasCalled; }, "Expecting file upload to fail", Tests.TEST_TIMEOUT);

            runs(function() {
                expect(uploadFail).toHaveBeenCalled();
                expect(uploadWin).not.toHaveBeenCalled();
                expect(fail).not.toHaveBeenCalled();
            });
        });
        it("should handle malformed urls", function() {
            var fail = jasmine.createSpy();
            var uploadWin = jasmine.createSpy();

            var remoteFile = getMalformedUrl();
            var localFileName = "malformed_url.txt";
            var uploadFail = jasmine.createSpy().andCallFake(function(error) {
                expect(error.code).toBe(FileTransferError.INVALID_URL_ERR);
                expect(error.http_status).not.toBe(401, "Ensure " + remoteFile + " is in the white list");
                deleteFile(localFileName);
            });
            var fileWin = function(fileEntry) {
                var ft = new FileTransfer();
                ft.upload(fileEntry.fullPath, remoteFile, uploadWin, uploadFail, {});
            };

            runs(function() {
                writeFile(localFileName, "Some content", fileWin, fail);
            });

            waitsFor(function() { return uploadFail.wasCalled; }, "uploadFail", Tests.TEST_TIMEOUT);

            runs(function() {
                expect(uploadFail).toHaveBeenCalled();
                expect(uploadWin).not.toHaveBeenCalled();
                expect(fail).not.toHaveBeenCalled();
            });
        });
        it("should handle unknown host", function() {
            var fail = jasmine.createSpy();
            var uploadWin = jasmine.createSpy();

            var remoteFile = "http://foobar.apache.org/robots.txt";
            var localFileName = remoteFile.substring(remoteFile.lastIndexOf('/')+1);
            var uploadFail = jasmine.createSpy().andCallFake(function(error) {
                expect(error.code).toBe(FileTransferError.CONNECTION_ERR);
                expect(error.http_status).not.toBe(401, "Ensure " + remoteFile + " is in the white list");
                deleteFile(localFileName);
            });
            var fileWin = function(fileEntry) {
                var ft = new FileTransfer();
                ft.upload(fileEntry.fullPath, remoteFile, uploadWin, uploadFail, {});
            };

            runs(function() {
                writeFile(localFileName, "# allow all", fileWin, fail);
            });

            waitsFor(function() { return uploadFail.wasCalled; }, "uploadFail", Tests.TEST_TIMEOUT);

            runs(function() {
                expect(uploadFail).toHaveBeenCalled();
                expect(uploadWin).not.toHaveBeenCalled();
                expect(fail).not.toHaveBeenCalled();
            });
        });
        it("should handle missing file", function() {
            var fail = jasmine.createSpy();
            var uploadWin = jasmine.createSpy();

            var remoteFile = server + "/upload";
            var localFileName = "does_not_exist.txt";

            var uploadFail = jasmine.createSpy().andCallFake(function(error) {
                expect(error.code).toBe(FileTransferError.FILE_NOT_FOUND_ERR);
                expect(error.http_status).not.toBe(401, "Ensure " + remoteFile + " is in the white list");
            });

            runs(function() {
                deleteFile(localFileName, function(fileEntry) {
                    var ft = new FileTransfer();
                    ft.upload(fileEntry.fullPath, remoteFile, uploadWin, uploadFail);
                }, fail);
            });

            waitsFor(function() { return uploadFail.wasCalled; }, "uploadFail", Tests.TEST_TIMEOUT);

            runs(function() {
                expect(uploadFail).toHaveBeenCalled();
                expect(uploadWin).not.toHaveBeenCalled();
                expect(fail).not.toHaveBeenCalled();
            });
        });
        it("should handle bad file path", function() {
            var uploadWin = jasmine.createSpy();

            var remoteFile = server + "/upload";

            var uploadFail = jasmine.createSpy().andCallFake(function(error) {
                expect(error.code).toBe(FileTransferError.FILE_NOT_FOUND_ERR);
                expect(error.http_status).not.toBe(401, "Ensure " + remoteFile + " is in the white list");
            });

            runs(function() {
                var ft = new FileTransfer();
                ft.upload("/usr/local/bad/file/path.txt", remoteFile, uploadWin, uploadFail);
            });

            waitsFor(function() { return uploadFail.wasCalled; }, "uploadFail", Tests.TEST_TIMEOUT);

            runs(function() {
                expect(uploadFail).toHaveBeenCalled();
                expect(uploadWin).not.toHaveBeenCalled();
            });

        });

    });
});
<|endoftext|>


<commit_before>module.exports = async function handler(ctx) {
  try {
    const { token } = this.settings
    const { commands, hears, on } = this.actions
    const { scenes } = this.flow
    const { user_id, body, text, payload, attachments = [] } = ctx
    const types = attachments.map(item => item.type)
    const flow = !!this.redis && await this.redis.get(`flow_${token}_${user_id}`)

    if (flow) {
      const { scene, step, session } = flow
      const { [scene]: callbacks } = scenes
      const callback = callbacks[step]

      return callback({
        ...flow,
        ...ctx,
        session,
      })
    }

    const command = commands.find(item => item.command === (payload ? text : body))
    const hear = hears.find(item => item.command.test(payload ? text : body))
    const reserved = on
      .sort((a, b) => b.type == 'message' ? -1 : 1)
      .find(({ type }) => types.indexOf(type) !== -1 || type === 'message')

    if (command) {
      command.callback(ctx)
    } else if (hear) {
      hear.callback(ctx)
    } else if (reserved) {
      reserved.callback(ctx)
    }
  } catch (err) {
    throw err
  }
}
<commit_msg>fixed<commit_after>module.exports = async function handler(ctx) {
  try {
    const { token } = this.settings
    const { commands, hears, on } = this.actions
    const { scenes } = this.flow
    const { user_id, body, text, attachments = [] } = ctx
    const types = attachments.map(item => item.type)
    const flow = !!this.redis && await this.redis.get(`flow_${token}_${user_id}`)

    if (flow) {
      const { scene, step, session } = flow
      const { [scene]: callbacks } = scenes
      const callback = callbacks[step]

      return callback({
        ...flow,
        ...ctx,
        session,
      })
    }

    const command = commands.find(item => item.command === (body || text))
    const hear = hears.find(item => item.command.test(body || text))
    const reserved = on
      .sort((a, b) => b.type == 'message' ? -1 : 1)
      .find(({ type }) => types.indexOf(type) !== -1 || type === 'message')

    if (command) {
      command.callback(ctx)
    } else if (hear) {
      hear.callback(ctx)
    } else if (reserved) {
      reserved.callback(ctx)
    }
  } catch (err) {
    throw err
  }
}
<|endoftext|>


<commit_before>(function() {
  'use strict';

  module.exports = function createSendToken( node, user , res, register ) {
    var payload = {
      sub: user._id.toString(),
      exp: node.moment().add(10, 'days').unix()
    };

    var token = node.jwt.encode( payload, 'shhh..');
    node.verifyEmail.verify(node, token, user.email, res);
    return res.json({
      user: user.toJSON(),
      token: token
    });
  };
}());
<commit_msg>delete verified email in createSendToken<commit_after>(function() {
  'use strict';

  module.exports = function createSendToken( node, user , res, register ) {
    var payload = {
      sub: user._id.toString(),
      exp: node.moment().add(10, 'days').unix()
    };

    var token = node.jwt.encode( payload, 'shhh..');
    //node.verifyEmail.verify(node, token, user.email, res);
    return res.json({
      user: user.toJSON(),
      token: token
    });
  };
}());
<|endoftext|>


<commit_before>var cli = require('cli-define');
var Flag = cli.Flag;

var env = require('cli-env');
var handler = require('../help');

var environ;

/**
 *  Adds a help flag to the program.
 *
 *  @param name The argument name.
 *  @param description The argument description.
 *  @param action A function to invoke.
 *  @param disable A boolean that disables loading help
 *  configuration from the environment.
 */
module.exports = function help(name, description, action, disable) {
  var conf = this.configure();
  var config = conf.help || {};
  if(!disable && !environ) {
    // initialize help configuration
    // from the environment
    environ = env({
      prefix: 'cli_toolkit_help',
      match: /^cli_toolkit_help_/i,
      initialize: true,
      native: true
    });
    var ignore = ['sections', 'messages', 'titles'];
    for(var z in environ) {
      if(~ignore.indexOf(z)) continue;
      conf.help[z] = environ[z];
    }
  }

  if(typeof name == 'function') {
    action = name;
    name = null;
  }
  action = action || config.action || handler;
  name = name || config.name;
  var flag = new Flag(name, description, {action: action});
  flag.key('helpopt');
  //flag.value(undefined);
  this.flag(flag);
  return this;
}

module.exports.action = handler;
<commit_msg>Fix description for --help.<commit_after>var cli = require('cli-define');
var Flag = cli.Flag;

var env = require('cli-env');
var handler = require('../help');

var environ;

/**
 *  Adds a help flag to the program.
 *
 *  @param name The argument name.
 *  @param description The argument description.
 *  @param action A function to invoke.
 *  @param disable A boolean that disables loading help
 *  configuration from the environment.
 */
module.exports = function help(name, description, action, disable) {
  var conf = this.configure()
    , config = conf.help || {}
    , z, ignore

  if(!disable && !environ) {

    // initialize help configuration
    // from the environment
    environ = env({
      prefix: 'cli_toolkit_help',
      match: /^cli_toolkit_help_/i,
      initialize: true,
      native: true
    });
    ignore = ['sections', 'messages', 'titles'];
    for(z in environ) {
      if(~ignore.indexOf(z)) continue;
      conf.help[z] = environ[z];
    }
  }

  if(typeof name == 'function') {
    action = name;
    name = null;
  }

  name = name || config.name;
  description = description || config.description;
  action = action || config.action || handler;

  var flag = new Flag(name, description, {action: action});
  flag.key('helpopt');
  //flag.value(undefined);
  this.flag(flag);
  return this;
}

module.exports.action = handler;
<|endoftext|>


<commit_before>/**
 * Module dependencies.
 */

var mongoose = require('mongoose')
  , Schema = mongoose.Schema
  , ObjectId = Schema.ObjectId
  , log = require('debug')('proposal:model');

/*
 * Proposal Schema
 */

var ProposalSchema = new Schema({
    title: {type: String, required: true, min: 8, max: 256 }
  , essay: { type: String, min: 512, max: 2048 }
  , tag: { type: ObjectId, ref: 'Tag' }
  , author: { type: ObjectId, required: true, ref: 'Citizen' }
  , links: [{ type: String }]
  , census: [{type: ObjectId, ref: 'Citizen' }]
  , vote: {
      census: [{ type: ObjectId, ref: 'Citizen' }]
    , positive: [{ type: ObjectId, ref: 'Citizen' }]
    , negative: [{ type: ObjectId, ref: 'Citizen' }]
  }
  , createdAt: { type: Date, default: Date.now }
});

/**
 * Get reduced `abstract` from `proposal.essay`,
 * up to 150 chars with `[...]` concatenated
 *
 * @return {String}
 * @api public
 */

ProposalSchema.virtual('abstract').get(function() {
  var abstract = this.essay.substr(0, 150)
    , endOfSentence = abstract.indexOf('.');

  // if(~endOfSentence < abstract.length) abstract = abstract.substr(0, endOfSentence);

  return abstract.concat('[...]');
});

/**
 * Gets `comments` from `Comment` Model
 * where comment references this context and item
 *
 * @param {Function} cb callback for query
 * @api public
 */
ProposalSchema.methods.loadComments = function(cb) {
  return this.model('Comment')
    .find({context: 'proposal', reference: this._id}, null, {sort: {createdAt: -1}})
    .populate('author')
    .exec(cb);
};

/**
 * Expose Mongoose model loaded
 */
module.exports = mongoose.model('Proposal', ProposalSchema);<commit_msg>[models] - renamed 'census' to 'participants'<commit_after>/**
 * Module dependencies.
 */

var mongoose = require('mongoose')
  , Schema = mongoose.Schema
  , ObjectId = Schema.ObjectId
  , log = require('debug')('proposal:model');

/*
 * Proposal Schema
 */

var ProposalSchema = new Schema({
    title: {type: String, required: true, min: 8, max: 256 }
  , essay: { type: String, min: 512, max: 2048 }
  , tag: { type: ObjectId, ref: 'Tag' }
  , author: { type: ObjectId, required: true, ref: 'Citizen' }
  , links: [{ type: String }]
  , participants: [{type: ObjectId, ref: 'Citizen' }]
  , vote: {
      census: [{ type: ObjectId, ref: 'Citizen' }]
    , positive: [{ type: ObjectId, ref: 'Citizen' }]
    , negative: [{ type: ObjectId, ref: 'Citizen' }]
  }
  , createdAt: { type: Date, default: Date.now }
});

/**
 * Get reduced `abstract` from `proposal.essay`,
 * up to 150 chars with `[...]` concatenated
 *
 * @return {String}
 * @api public
 */

ProposalSchema.virtual('abstract').get(function() {
  var abstract = this.essay.substr(0, 150)
    , endOfSentence = abstract.indexOf('.');

  // if(~endOfSentence < abstract.length) abstract = abstract.substr(0, endOfSentence);

  return abstract.concat('[...]');
});

/**
 * Gets `comments` from `Comment` Model
 * where comment references this context and item
 *
 * @param {Function} cb callback for query
 * @api public
 */
ProposalSchema.methods.loadComments = function(cb) {
  return this.model('Comment')
    .find({context: 'proposal', reference: this._id}, null, {sort: {createdAt: -1}})
    .populate('author')
    .exec(cb);
};

/**
 * Expose Mongoose model loaded
 */
module.exports = mongoose.model('Proposal', ProposalSchema);<|endoftext|>


<commit_before>/**
 * @module  web
 * methods for browsers and business requirement

 * - domready
 * - data storage
 * - getLocation
 * - UA
 */

;(function(K, undef){

/**
 * get the readable location object of current page
 */
function getCurrentLocation(){
	var L, H;

	// IE may throw an exception when accessing
	// a field from document.location if document.domain has been set
	// ref:
	// stackoverflow.com/questions/1498788/reading-window-location-after-setting-document-domain-in-ie6
	try {
		L = DOC.location;
		H = L.href;
	} catch(e) {

		// Use the href attribute of an A element
		// since IE will modify it given document.location
		H = DOC.createElement('a');
		H.href = EMPTY;
		H = H.href;

		L = parseLocation(H);
	}

	return L;
};

/**
 * parse a link to location object
 * @param {string} H
 * @return {Object} custom location object
 */
function parseLocation(H){
	var E = nullOrEmpty, port, search;

	H = H.match(REGEX_URL);

	port = H[3];
	search = E(H[5]);

	return {
		href: 		H[0],
		protocol:	H[1],
		host:		H[2] + (port ? ':' + port : EMPTY),
		hostname:	H[2],
		port:		E( port ),
		pathname:	E( H[4] ),

		// attension!
		search:		search === '?' ? '' : search,
		hash:		E( H[6] )
	};
};

function nullOrEmpty(str){
	return str || EMPTY;
};

var

// @const
WIN = K.__HOST,
DOC = WIN.document,
EMPTY = '',

/*
REGEX_URL = /^
	([\w\+\.\-]+:)		// protocol
	\/\/
	([^\/?#:]+)			// domain
(?::
	(\d+)				// port
)?
	(/[^?#]*)?			// pathname
	(\?[^?#]*)?			// search
	(#.*)?				// hash
$/
*/

REGEX_URL = /^([\w\+\.\-]+:)\/\/([^\/?#:]+)(?::(\d+))?(\/[^?#]*)?(\?[^#]*)?(#.*)?$/;

/**
 * @param {string} href
 * @return {Object}
 *	- if href undefined, returns the current location
 *	- if href is a string, returns the parsed loaction
 */
K.getLocation = function(href){
	return href ?
		parseLocation(href)
	:	getCurrentLocation();
};

})(NR);

/**
 TODO:
 - add constructor for NR.data
 - syntax checking for uri

 change log:
 2012-09-14  Kael:
 - fix NR.getLocation(href).search

 2011-07-05  Kael:
 - remove UA.fullversion
 - add adapter for Browser.Platform

 2011-06-12  Kael:
 - fix a bug about the regular expression of location pattern that more than one question mark should be allowed in search query
 - add UA.chrome.

 2011-04-26  Kael:
 - adapt mootools.Browser
 - remove ua.chrome, ua.safari, add ua.webkit

 2011-04-12  Kael Zhang:
 - fix a bug that domready could not be properly fired
 - add NR.getLocation method,
 	1. to fix the bug of ie6, which will cause an exception when fetching the value of window.location if document.domain is already specified
 	2. which can split an specified uri into different parts

 2010-12-31  Kael Zhang:
 - migrate domready event out from mootools to here, and change some way
 - migrate .data and .delay methods from core/lang to here

 */<commit_msg>lang/web: add change log<commit_after>/**
 * @module  web
 * methods for browsers and business requirement

 * - domready
 * - data storage
 * - getLocation
 * - UA
 */

;(function(K, undef){

/**
 * get the readable location object of current page
 */
function getCurrentLocation(){
	var L, H;

	// IE may throw an exception when accessing
	// a field from document.location if document.domain has been set
	// ref:
	// stackoverflow.com/questions/1498788/reading-window-location-after-setting-document-domain-in-ie6
	try {
		L = DOC.location;
		H = L.href;
	} catch(e) {

		// Use the href attribute of an A element
		// since IE will modify it given document.location
		H = DOC.createElement('a');
		H.href = EMPTY;
		H = H.href;

		L = parseLocation(H);
	}

	return L;
};

/**
 * parse a link to location object
 * @param {string} H
 * @return {Object} custom location object
 */
function parseLocation(H){
	var E = nullOrEmpty, port, search;

	H = H.match(REGEX_URL);

	port = H[3];
	search = E(H[5]);

	return {
		href: 		H[0],
		protocol:	H[1],
		host:		H[2] + (port ? ':' + port : EMPTY),
		hostname:	H[2],
		port:		E( port ),
		pathname:	E( H[4] ),

		// attension!
		search:		search === '?' ? '' : search,
		hash:		E( H[6] )
	};
};

function nullOrEmpty(str){
	return str || EMPTY;
};

var

// @const
WIN = K.__HOST,
DOC = WIN.document,
EMPTY = '',

/*
REGEX_URL = /^
	([\w\+\.\-]+:)		// protocol
	\/\/
	([^\/?#:]+)			// domain
(?::
	(\d+)				// port
)?
	(/[^?#]*)?			// pathname
	(\?[^?#]*)?			// search
	(#.*)?				// hash
$/
*/

REGEX_URL = /^([\w\+\.\-]+:)\/\/([^\/?#:]+)(?::(\d+))?(\/[^?#]*)?(\?[^#]*)?(#.*)?$/;

/**
 * @param {string} href
 * @return {Object}
 *	- if href undefined, returns the current location
 *	- if href is a string, returns the parsed loaction
 */
K.getLocation = function(href){
	return href ?
		parseLocation(href)
	:	getCurrentLocation();
};

})(NR);

/**
 TODO:
 - add constructor for NR.data
 - syntax checking for uri

 change log:
 2012-09-14  Kael:
 - fix NR.getLocation(href).search that if search query is `'?'`, location.search should be an empty string

 2011-07-05  Kael:
 - remove UA.fullversion
 - add adapter for Browser.Platform

 2011-06-12  Kael:
 - fix a bug about the regular expression of location pattern that more than one question mark should be allowed in search query
 - add UA.chrome.

 2011-04-26  Kael:
 - adapt mootools.Browser
 - remove ua.chrome, ua.safari, add ua.webkit

 2011-04-12  Kael Zhang:
 - fix a bug that domready could not be properly fired
 - add NR.getLocation method,
 	1. to fix the bug of ie6, which will cause an exception when fetching the value of window.location if document.domain is already specified
 	2. which can split an specified uri into different parts

 2010-12-31  Kael Zhang:
 - migrate domready event out from mootools to here, and change some way
 - migrate .data and .delay methods from core/lang to here

 */<|endoftext|>


<commit_before>StudyNetEnhancement.Converter = function() {
	var
		// Container to house our new content
		container = $(''),

		// Navigation list
		navigation = $('
'),

		// Resources aside
		resources = $(''),

		// Reference counter for assigning unique IDs
		refCounter = 0;

	function fetch(url) {
		return $.ajax({url: url, async: false}).responseText;
	};

	function rewrite(e, href) {
		var base = href.split('/').slice(0, -1).join('/') + '/';

		$('a', e).not('[href^="http"],[href^="https"],[href^="mailto:"],[href^="#"]').each(function() {
			$(this).attr('href', function(index, value) {
				return base + value;
			});
		});

		$('[src]', e).not('[src^="http"],[src^="https"],[src^="#"]').each(function() {
			$(this).attr('src', function(index, value) {
				return base + value;
			});
		});
	};

	function unit() {
		// Fetch unit
		var content = $(fetch($(this).attr('href'))).find('.rightFeature');

		// Rename unit's header text and id
		var header = content
			.find('.genericHead')
			.text($(this).text())
			.attr('id', 'id' + refCounter++);

		// Create sub navigation element for this unit
		var subnav = $('
');

		// Add unit to navigation
		navigation.append($('
').append($('').attr('href', '#' + header.attr('id')).text(header.text())).append(subnav));

		// Rewrite unit relative URLs to absolute
		rewrite(content, $(this).attr('href'));

		// remove "Study Unit *" button
		var buttons = content.find('.genericButton').remove();

		// Remove session list and attempt to get first session link
		var first = $(':header:contains(Sessions), :header:contains(Activities)', content)
			.nextAll('ul, ol')
			.first()
			.remove()
			.find('a');

		// If there was a session button, favour that over the list
		if (buttons.length) {
			first = buttons.first().find('a');
		}

		if (first.length > 0) {
			// Fetch first session, enabling us to find the others
			var sess = $(fetch(first.attr('href')));

			// Rewrite session relative URLs to absolute
			rewrite(sess, first.attr('href'));

			// Create an aside for resource links
			resources.append(
				$('
')
					.attr('id', 'resources_'+header.attr('id'))
					.append(sess.find('.rightFeature')));

			// Find all sessions in this unit
			sess.find('#row3row1 span, #row3row1 a').each(function() {
				if ($(this).is('span')) {
					session.call(first, content, subnav, $(this).text());
				} else {
					session.call(this, content, subnav, $(this).text());
				}
			});
		}

		// Add article with unit's content
		container.append(
			$('
')
				.attr('data-scroll-id', header.attr('id'))
				.append(content));
	}

	function session(content, subnav, title) {
		var session = fetch($(this).attr('href'));

		// Get the session's tab content
		var tab = $('#tabArea', $(session));

		// Rename session
		var header = $('
')
			.text(title)
			.attr('id', 'id' + refCounter++);

		// Add session to unit's navigation list
		subnav.append($('
').append($('').attr('href', '#' + header.attr('id')).text(header.text())));

		// Rewrite session relative URLs to absolute
		rewrite(tab, $(this).attr('href'));

		content.append(
			$('
')
				.attr('data-scroll-id', header.attr('id'))
				.append(header)
				.append(tab));
	}

	// Remove stylesheets & scripts
	$('head').find('[type="text/css"]').remove();
	$('head').find('[type="text/javascript"]').remove();

	// Add our stylesheets
	$('head')
		.append($('<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans" type="text/css">'))
		.append($('<link rel="stylesheet" href="https://saracen.github.io/studynet-enhancement/microsite-single-document-viewer.css" type="text/css">'));

	// Rewrite document's urls so that they're absolute
	rewrite(document.body, window.location.href);

	// Fetch units
	$('.leftFeature ul li a').each(unit);

	// Make images more responsive
	container.find('img[width]').each(function() {
		$(this).css({ 'max-width': '100%' });
		$(this).removeAttr('width');
		$(this).removeAttr('height');
	});

	// Highlight current navigation elements
	$(window).bind('scroll', function(e) {
		var position = {top: $(this).scrollTop(), left: $(this).scrollLeft()};

		$('#sidebar nav ul .active').removeClass('active');
		$('#sidebar .resource').hide();

		container.find('[data-scroll-id]').each(function() {
			if (position.top > $(this).position().top - 130 && position.top < $(this).position().top + $(this).height()) {
				var id = $(this).attr('data-scroll-id');

				$('#sidebar nav ul li').has('[href=#'+id+']').addClass('active');
				$('#resources_'+id).show();
			}
		});
	});

	// Reimplement answer reveal functionality
	container.find('input.shBtn').click(function() {
		$(this).next('.solution').toggle();
	});

	// Reimplement answer check functionality
	container.find('input[onclick]').each(function() {
		// Remove onclick/onkeypress events
		$(this)
			.removeAttr('onclick')
			.removeAttr('onkeypress');

		$(this).click(function() {
			var groups = [];
			var form = $(this).closest('form');

			// Remove previous classes
			form.find('.correct, .incorrect, .warning').removeClass('correct incorrect warning');

			// Find radio groupings
			form.find(':radio').each(function() {
				groups[this.name] = true;
			})

			// Add classes to correct/incorrect selects
			form.find(':selected').each(function() {
				if ($(this).val() == 1) {
					$(this).closest('select').addClass('correct');
				} else {
					$(this).closest('select').addClass('incorrect');
				}
			});

			// Perform select/incorrect logic on groups of radio inputs
			for (var group in groups) {
				var chosen = form.find('[name="'+ group + '"]:checked');

				if (chosen.length == 0) {
					form.find('[name="'+ group + '"]').next('label').addClass('warning');
				} else if (chosen.val() == 1) {
					chosen.next('label').addClass('correct');
				} else {
					chosen.next('label').addClass('incorrect');
				}
			}
		});
	});

	// Remove root content
	$('#root').remove();

	// Add our new container
	$(document.body).append($('
').append($('').append(navigation)).append(resources));
	$(document.body).append(container);
};

if (document.getElementById('root') && document.getElementsByClassName('ModuleOverview').length > 0) {
	var toggle = function() {
		if (localStorage.getItem('microsite-single-document-viewer') === 'enabled') {
			localStorage.removeItem('microsite-single-document-viewer');
		} else {
			localStorage.setItem('microsite-single-document-viewer', 'enabled');
		}
		window.location.reload();
	};

	var button = document.createElement('button');
	button.innerText = 'Enter single document view';
	button.id = 'btn-single';
	button.addEventListener('click', toggle);
	document.body.appendChild(button);

	if (localStorage.getItem('microsite-single-document-viewer') === 'enabled') {
		button.innerText = 'Exit single document view';
		StudyNetEnhancement.Converter();
	}
}<commit_msg>Microsite viewer: Used jquery to insert button, making the script compatible with Firefox<commit_after>StudyNetEnhancement.Converter = function() {
	var
		// Container to house our new content
		container = $(''),

		// Navigation list
		navigation = $('
'),

		// Resources aside
		resources = $(''),

		// Reference counter for assigning unique IDs
		refCounter = 0;

	function fetch(url) {
		return $.ajax({url: url, async: false}).responseText;
	};

	function rewrite(e, href) {
		var base = href.split('/').slice(0, -1).join('/') + '/';

		$('a', e).not('[href^="http"],[href^="https"],[href^="mailto:"],[href^="#"]').each(function() {
			$(this).attr('href', function(index, value) {
				return base + value;
			});
		});

		$('[src]', e).not('[src^="http"],[src^="https"],[src^="#"]').each(function() {
			$(this).attr('src', function(index, value) {
				return base + value;
			});
		});
	};

	function unit() {
		// Fetch unit
		var content = $(fetch($(this).attr('href'))).find('.rightFeature');

		// Rename unit's header text and id
		var header = content
			.find('.genericHead')
			.text($(this).text())
			.attr('id', 'id' + refCounter++);

		// Create sub navigation element for this unit
		var subnav = $('
');

		// Add unit to navigation
		navigation.append($('
').append($('').attr('href', '#' + header.attr('id')).text(header.text())).append(subnav));

		// Rewrite unit relative URLs to absolute
		rewrite(content, $(this).attr('href'));

		// remove "Study Unit *" button
		var buttons = content.find('.genericButton').remove();

		// Remove session list and attempt to get first session link
		var first = $(':header:contains(Sessions), :header:contains(Activities)', content)
			.nextAll('ul, ol')
			.first()
			.remove()
			.find('a');

		// If there was a session button, favour that over the list
		if (buttons.length) {
			first = buttons.first().find('a');
		}

		if (first.length > 0) {
			// Fetch first session, enabling us to find the others
			var sess = $(fetch(first.attr('href')));

			// Rewrite session relative URLs to absolute
			rewrite(sess, first.attr('href'));

			// Create an aside for resource links
			resources.append(
				$('
')
					.attr('id', 'resources_'+header.attr('id'))
					.append(sess.find('.rightFeature')));

			// Find all sessions in this unit
			sess.find('#row3row1 span, #row3row1 a').each(function() {
				if ($(this).is('span')) {
					session.call(first, content, subnav, $(this).text());
				} else {
					session.call(this, content, subnav, $(this).text());
				}
			});
		}

		// Add article with unit's content
		container.append(
			$('
')
				.attr('data-scroll-id', header.attr('id'))
				.append(content));
	}

	function session(content, subnav, title) {
		var session = fetch($(this).attr('href'));

		// Get the session's tab content
		var tab = $('#tabArea', $(session));

		// Rename session
		var header = $('
')
			.text(title)
			.attr('id', 'id' + refCounter++);

		// Add session to unit's navigation list
		subnav.append($('
').append($('').attr('href', '#' + header.attr('id')).text(header.text())));

		// Rewrite session relative URLs to absolute
		rewrite(tab, $(this).attr('href'));

		content.append(
			$('
')
				.attr('data-scroll-id', header.attr('id'))
				.append(header)
				.append(tab));
	}

	// Remove stylesheets & scripts
	$('head').find('[type="text/css"]').remove();
	$('head').find('[type="text/javascript"]').remove();

	// Add our stylesheets
	$('head')
		.append($('<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans" type="text/css">'))
		.append($('<link rel="stylesheet" href="https://saracen.github.io/studynet-enhancement/microsite-single-document-viewer.css" type="text/css">'));

	// Rewrite document's urls so that they're absolute
	rewrite(document.body, window.location.href);

	// Fetch units
	$('.leftFeature ul li a').each(unit);

	// Make images more responsive
	container.find('img[width]').each(function() {
		$(this).css({ 'max-width': '100%' });
		$(this).removeAttr('width');
		$(this).removeAttr('height');
	});

	// Highlight current navigation elements
	$(window).bind('scroll', function(e) {
		var position = {top: $(this).scrollTop(), left: $(this).scrollLeft()};

		$('#sidebar nav ul .active').removeClass('active');
		$('#sidebar .resource').hide();

		container.find('[data-scroll-id]').each(function() {
			if (position.top > $(this).position().top - 130 && position.top < $(this).position().top + $(this).height()) {
				var id = $(this).attr('data-scroll-id');

				$('#sidebar nav ul li').has('[href=#'+id+']').addClass('active');
				$('#resources_'+id).show();
			}
		});
	});

	// Reimplement answer reveal functionality
	container.find('input.shBtn').click(function() {
		$(this).next('.solution').toggle();
	});

	// Reimplement answer check functionality
	container.find('input[onclick]').each(function() {
		// Remove onclick/onkeypress events
		$(this)
			.removeAttr('onclick')
			.removeAttr('onkeypress');

		$(this).click(function() {
			var groups = [];
			var form = $(this).closest('form');

			// Remove previous classes
			form.find('.correct, .incorrect, .warning').removeClass('correct incorrect warning');

			// Find radio groupings
			form.find(':radio').each(function() {
				groups[this.name] = true;
			})

			// Add classes to correct/incorrect selects
			form.find(':selected').each(function() {
				if ($(this).val() == 1) {
					$(this).closest('select').addClass('correct');
				} else {
					$(this).closest('select').addClass('incorrect');
				}
			});

			// Perform select/incorrect logic on groups of radio inputs
			for (var group in groups) {
				var chosen = form.find('[name="'+ group + '"]:checked');

				if (chosen.length == 0) {
					form.find('[name="'+ group + '"]').next('label').addClass('warning');
				} else if (chosen.val() == 1) {
					chosen.next('label').addClass('correct');
				} else {
					chosen.next('label').addClass('incorrect');
				}
			}
		});
	});

	// Remove root content
	$('#root').remove();

	// Add our new container
	$(document.body).append($('
').append($('').append(navigation)).append(resources));
	$(document.body).append(container);
};

if (document.getElementById('root') && document.getElementsByClassName('ModuleOverview').length > 0) {
	var toggle = function() {
		if (localStorage.getItem('microsite-single-document-viewer') === 'enabled') {
			localStorage.removeItem('microsite-single-document-viewer');
		} else {
			localStorage.setItem('microsite-single-document-viewer', 'enabled');
		}
		window.location.reload();
	};

	var button = $('<button id="btn-single">')
		.click(toggle)
		.text('Enter single document view');

	$('body').append(button);

	if (localStorage.getItem('microsite-single-document-viewer') === 'enabled') {
		button.text('Exit single document view');
		StudyNetEnhancement.Converter();
	}
}<|endoftext|>


<commit_before>'use strict';

const _      = require('lodash');
const chalk  = require('chalk');
const events = require('./events');

const log = fn => (data, info) => console.log(fn(data, info));

module.exports = (parser, options = {}) => {

    //noinspection FallThroughInSwitchStatementJS
    switch (options.verbosity) {
        case 2:
        case 1:
            parser.useCombine({

                [events.RUN_ACTION]: log(action => chalk.bold(`\n> ${action}\n`)),
                [events.DONE]:       log((_, info) => chalk.green(`\n✔ [${info.context.scope.action}]\n`))
            });
        default:
            parser.useCombine({

                [events.RESULT]: result => {
                    const data = result.get('data');
                    if (_.isString(data) || _.isNumber(data)) console.log(data);
                    else console.log(JSON.stringify(data, null, 2));
                },
                [events.ERROR]:  log(error => chalk.red(`\n${error}\n`))
            });
    }
};<commit_msg>more verbose output if result is undefined<commit_after>'use strict';

const _      = require('lodash');
const chalk  = require('chalk');
const events = require('./events');

const log = fn => (data, info) => console.log(fn(data, info));

module.exports = (parser, options = {}) => {

    //noinspection FallThroughInSwitchStatementJS
    switch (options.verbosity) {
        case 2:
        case 1:
            parser.useCombine({

                [events.RUN_ACTION]: log(action => chalk.bold(`\n> ${action}\n`)),
                [events.DONE]:       log((_, info) => chalk.green(`\n✔ [${info.context.scope.action}]\n`))
            });
        default:
            parser.useCombine({

                [events.RESULT]: (result, info) => {
                    const data = result.get('data');
                    if (_.isUndefined(data))
                        console.log(options.verbosity >= 2 ? chalk.grey(`${info.context.scope.action} returned undefined`) : '');
                    else if (_.isString(data) || _.isNumber(data)) console.log(data);
                    else console.log(JSON.stringify(data, null, 2));
                },
                [events.ERROR]:  log(error => chalk.red(`\n${error}\n`))
            });
    }
};<|endoftext|>


<commit_before>'use strict';
var child = require('child_process');

module.exports = SocketsMonitor;

/**
 * Monitor class for performing monitoring on:
 * - number of **open** sockets
 * - number of **pending** sockets
 * - number of **open** files
 * @class
 */
function SocketsMonitor (monitor, prefix, interval) {
  this.monitor = monitor;
  this.prefix = prefix;
  this.interval = interval;
}

/**
 * Start capturing of the sockets stats data.
 */
SocketsMonitor.prototype.start = function () {
  if (!this.intervalId) {
    this.intervalId = setInterval(this._captureSocketStats.bind(this), this.interval);
  }
};

/**
 * Stop capturing of the sockets stats data.
 */
SocketsMonitor.prototype.stop = function () {
  if (this.intervalId) {
    clearInterval(this.intervalId);
    this.intervalId = null;
  }
};

SocketsMonitor.prototype._captureSocketStats = function () {
  var sockets = require('http').globalAgent.sockets;
  var request = require('http').globalAgent.requests;
  var key;

  var pidTag = 'pid:' + process.pid;

  for (key in sockets) {
    var action = this.prefix + '.sockets_open';
    this.monitor.gauge(action, sockets[key].length, 1, ['target:' + key, pidTag]);
  }

  for (key in request) {
    var action = this.prefix + '.sockets_pending';
    this.monitor.gauge(action, request[key].length, 1, ['target:' + key, pidTag]);
  }

  child.exec('lsof -p ' + process.pid + ' | wc -l', function (err, stdout) {
    if (err) { return; }
    var action = this.prefix + '.openFiles';
    this.monitor.gauge(action, parseInt(stdout), 1, [pidTag]);
  }.bind(this));
};
<commit_msg>minors<commit_after>'use strict';
var child = require('child_process');
var globalAgent = require('http').globalAgent;
/**
 * @module monitor-dog:sockets-monitor
 * @author Anand Kumar Patel
 * @author Anton Podviaznikov
 */
module.exports = SocketsMonitor;

/**
 * Monitor class for performing monitoring on:
 * - number of **open** sockets
 * - number of **pending** sockets
 * - number of **open** files
 * @class
 */
function SocketsMonitor (monitor, prefix, interval) {
  this.monitor = monitor;
  this.prefix = prefix;
  this.interval = interval;
}

/**
 * Start capturing of the sockets stats data.
 */
SocketsMonitor.prototype.start = function () {
  if (!this.intervalId) {
    this.intervalId = setInterval(this._captureSocketStats.bind(this), this.interval);
  }
};

/**
 * Stop capturing of the sockets stats data.
 */
SocketsMonitor.prototype.stop = function () {
  if (this.intervalId) {
    clearInterval(this.intervalId);
    this.intervalId = null;
  }
};

SocketsMonitor.prototype._captureSocketStats = function () {
  var sockets = globalAgent.sockets;
  var request = globalAgent.requests;
  var key;

  var pidTag = 'pid:' + process.pid;

  for (key in sockets) {
    var action = this.prefix + '.sockets_open';
    this.monitor.gauge(action, sockets[key].length, 1, ['target:' + key, pidTag]);
  }

  for (key in request) {
    var action = this.prefix + '.sockets_pending';
    this.monitor.gauge(action, request[key].length, 1, ['target:' + key, pidTag]);
  }

  child.exec('lsof -p ' + process.pid + ' | wc -l', function (err, stdout) {
    if (err) { return; }
    var action = this.prefix + '.openFiles';
    this.monitor.gauge(action, parseInt(stdout), 1, [pidTag]);
  }.bind(this));
};
<|endoftext|>


<commit_before>register_namespace('ui.infoblock');

ui.infoblock.convert_wiki = function (elem) {
    elem.find('a').each(function(){
        var html = '' + $(this).text() + '';
        if ($(this).hasClass('bbcode_artist')) {
            var artist = $(this).attr('href');
            artist = artist.replace('http://www.last.fm/music/', '');
            artist = util.string.urldecode(artist);
            html = '' + $(this).text() + ''
        }
        if ($(this).hasClass('bbcode_tag')) {
            var tag = $(this).attr('href');
            tag = tag.replace('http://www.last.fm/tag/', '');
            tag = util.string.urldecode(tag);
            html = '' + $(this).text() + ''
        }
        $(html).insertAfter($(this));
        $(this).remove();
    });
};

ui.infoblock.add_comments = function(elem, type, name) {
    var title = name + ' (в приложении «Твоёрадио»)';
    var hash = 'info/' + type + '/' + util.string.urlencode(name)
    var url = 'http://' + config.app_domain + '/app/vkredir/?hash=' + hash;
    var hash = util.string.md5(type + ' ' + name)
    var id = 'infoblock_' + type + util.random.randint(0, 100500);
    elem.find('.infoblock__comments').attr('id', id + '__comments');
    network.vkontakte.Widgets.Comments(
        id + '__comments',
        {
            'autoPublish': 1,
            'limit': 5,
            'mini': 1,
            'pageTitle': title,
            'pageUrl': url
        },
        hash
    );
}

ui.infoblock.show_artist = function(elem, name) {
    network.lastfm.api(
        'artist.getInfo',
        {
            'artist': name,
            'lang': 'ru'
        },
        function(data) {
            data.artist.url = data.artist.url.replace('http://www.last.fm', 'http://www.lastfm.ru');
            var context = {
                'name': data.artist.name,
                'wiki_summary': data.artist.bio.summary,
                'wiki': data.artist.bio.content,
                'similar': network.lastfm.arrayize(data.artist.similar.artist),
                'tags': network.lastfm.arrayize(data.artist.tags.tag),
                'image': network.lastfm.select_image(data.artist.image, 'large'),
                'lastfm_url': data.artist.url,
                'lastfm_url_text': util.string.urldecode(data.artist.url),
                'stations': [
                    {
                        'type': 'similar',
                        'name': data.artist.name,
                        'html': player.station.similar.get_html(data.artist.name)
                    },
                    {
                        'type': 'artist',
                        'name': data.artist.name,
                        'html': player.station.artist.get_html(data.artist.name)
                    }
                ]
            };
            elem.html(ich.tpl_infoblock_artist(context));
            ui.infoblock.convert_wiki($('.infoblock__wiki'));
            ui.infoblock.add_comments(elem, 'artist', name);
        },
        function(data) {
            if (data.error == 6) {
                $(elem).text('Нет такого исполнителя.');
                return true;
            }
        }
    );
};

ui.infoblock.show_tag = function(elem, name) {
    network.lastfm.api(
        'tag.getInfo',
        {
            'tag': name,
            'lang': 'ru'
        },
        function(data) {
            data.tag.url = data.tag.url.replace('http://www.last.fm', 'http://www.lastfm.ru');
            var context = {
                'name': data.tag.name,
                'wiki_summary': data.tag.wiki.summary,
                'wiki': data.tag.wiki.content,
                'lastfm_url': data.tag.url,
                'lastfm_url_text': util.string.urldecode(data.tag.url),
                'stations': [
                    {
                        'type': 'tag',
                        'name': data.tag.name,
                        'html': player.station.tag.get_html(data.tag.name)
                    }
                ]
            };
            elem.html(ich.tpl_infoblock_tag(context));
            ui.infoblock.convert_wiki($('.infoblock__wiki'));
            ui.infoblock.add_comments(elem, 'tag', name);

            network.lastfm.api(
                'tag.getTopArtists',
                {
                    'tag': name,
                    'limit': 25
                },
                function(data) {
                    context['top_artists'] = [];
                    var artists = context['artists'] = network.lastfm.arrayize(data.topartists.artist);
                    for (var i = 0; i < 4; i++) {
                        context['top_artists'].push({
                            'name': artists[i].name,
                            'image': network.lastfm.select_image(artists[i].image, 'medium', true)
                        });
                    }
                    var html = ich.tpl_infoblock_tag(context).find('.infoblock__artists').html();
                    elem.find('.infoblock__artists').html(html);
                    var html = ich.tpl_infoblock_tag(context).find('.infoblock__photos').html();
                    elem.find('.infoblock__photos').html(html);
                }
            );

            network.lastfm.api(
                'tag.getSimilar',
                {
                    'tag': name
                },
                function(data) {
                    context['tags'] = network.lastfm.arrayize(data.similartags.tag).splice(0, 10);
                    var html = ich.tpl_infoblock_tag(context).find('.infoblock__tags').html();
                    elem.find('.infoblock__tags').html(html);
                }
            );
        },
        function(data) {
            if (data.error == 6) {
                $(elem).text('Нет такого тега.');
                return true;
            }
        }
    );
};

ui.infoblock.show_user = function(elem, name) {
    network.lastfm.api(
        'user.getInfo',
        {
            'user': name
        },
        function(data) {
            data.user.url = data.user.url.replace('http://www.last.fm', 'http://www.lastfm.ru');
            var context = {
                'name': data.user.name,
                'image': network.lastfm.select_image(data.user.image, 'large'),
                'lastfm_url': data.user.url,
                'lastfm_url_text': util.string.urldecode(data.user.url),
                'it_is_you': (data.user.name == network.lastfm.user),
                'stations': [
                    {
                        'type': 'library',
                        'name': data.user.name,
                        'html': player.station.library.get_html(data.user.name)
                    },
                    {
                        'type': 'loved',
                        'name': data.user.name,
                        'html': player.station.loved.get_html(data.user.name)
                    }
                ]
            };
            if (data.user.name == network.lastfm.user) {
                context['stations'].push({
                    'type': 'recommendations',
                    'name': data.user.name,
                    'html': player.station.recommendations.get_html(data.user.name)
                });
            }
            elem.html(ich.tpl_infoblock_user(context));

            network.lastfm.api(
                'user.getTopArtists',
                {
                    'user': name,
                    'period': 'overall'
                },
                function(data) {
                    var artists = network.lastfm.arrayize(data.topartists.artist);
                    context['artists'] = [];
                    for (var i = 0; i < artists.length; i++) {
                        var image = network.lastfm.select_image(artists[i].image, 'medium', true);
                        if (image) {
                            context['artists'].push({
                                'name': artists[i].name,
                                'image': image
                            });
                        }
                    }
                    elem.html(ich.tpl_infoblock_user(context));
                    network.lastfm.api(
                        'user.getNeighbours',
                        {
                            'user': name,
                            'limit': 10
                        },
                        function(data) {
                            var neighbours = network.lastfm.arrayize(data.neighbours.user);
                            context['neighbours'] = [];
                            for (var i = 0; i < neighbours.length; i++) {
                                context['neighbours'].push({
                                    'name': neighbours[i].name
                                });
                            }
                            elem.html(ich.tpl_infoblock_user(context));
                        }
                    );
                    network.lastfm.api(
                        'user.getFriends',
                        {
                            'user': name,
                            'limit': 1000
                        },
                        function(data) {
                            var friends = network.lastfm.arrayize(data.friends.user);
                            context['friends'] = [];
                            for (var i = 0; i < friends.length; i++) {
                                context['friends'].push({
                                    'name': friends[i].name
                                });
                            }
                            elem.html(ich.tpl_infoblock_user(context));
                        }
                    );
                    if ((network.lastfm.authorized)&&(name != network.lastfm.user)) {
                        network.lastfm.api(
                            'tasteometer.compare',
                            {
                                'type1': 'user',
                                'value1': network.lastfm.user,
                                'type2': 'user',
                                'value2': name
                            },
                            function(data) {
                                context['tasteometer'] = Math.round(data.comparison.result.score * 100);
                                elem.html(ich.tpl_infoblock_user(context));
                            }
                        );
                    }
                },
                function(data) {
                    if (data.error == 6) {
                        $(elem).text('Нет такого пользователя на Last.fm.');
                        return true;
                    }
                }
            );
        }
    );
};

ui.infoblock.show = function(elem, type, name) {
    elem.html('

');
    ui.infoblock['show_' + type](elem, name);
};

ui.infoblock.show_popup = function(type, name) {
    ui.popup.show(name);
    ui.infoblock.show($('.popup .popup__content'), type, name);
};

$('.nav-infoblock').live('click', function(e) {
    e.preventDefault();
    ui.infoblock.show_popup($(this).data('type'), (($(this).data('name'))||$(this).text()));
});

<commit_msg>Исправлен баг с комментариями.<commit_after>register_namespace('ui.infoblock');

ui.infoblock.convert_wiki = function (elem) {
    elem.find('a').each(function(){
        var html = '' + $(this).text() + '';
        if ($(this).hasClass('bbcode_artist')) {
            var artist = $(this).attr('href');
            artist = artist.replace('http://www.last.fm/music/', '');
            artist = util.string.urldecode(artist);
            html = '' + $(this).text() + ''
        }
        if ($(this).hasClass('bbcode_tag')) {
            var tag = $(this).attr('href');
            tag = tag.replace('http://www.last.fm/tag/', '');
            tag = util.string.urldecode(tag);
            html = '' + $(this).text() + ''
        }
        $(html).insertAfter($(this));
        $(this).remove();
    });
};

ui.infoblock.add_comments = function(elem, type, name) {
    var title = name + ' (в приложении «Твоёрадио»)';
    var hash = 'info/' + type + '/' + util.string.urlencode(name)
    var url = 'http://' + config.app_domain + '/app/vkredir/?hash=' + hash;
    var hash = util.string.md5(type + ' ' + name)
    var id = 'infoblock_' + type + util.random.randint(0, 100500);
    elem.find('.infoblock__comments').attr('id', id + '__comments');
    network.vkontakte.Widgets.Comments(
        id + '__comments',
        {
            'autoPublish': 1,
            'limit': 5,
            'mini': 1,
            'pageTitle': title,
            'pageUrl': url
        },
        hash
    );
}

ui.infoblock.show_artist = function(elem, name) {
    network.lastfm.api(
        'artist.getInfo',
        {
            'artist': name,
            'lang': 'ru'
        },
        function(data) {
            data.artist.url = data.artist.url.replace('http://www.last.fm', 'http://www.lastfm.ru');
            var context = {
                'name': data.artist.name,
                'wiki_summary': data.artist.bio.summary,
                'wiki': data.artist.bio.content,
                'similar': network.lastfm.arrayize(data.artist.similar.artist),
                'tags': network.lastfm.arrayize(data.artist.tags.tag),
                'image': network.lastfm.select_image(data.artist.image, 'large'),
                'lastfm_url': data.artist.url,
                'lastfm_url_text': util.string.urldecode(data.artist.url),
                'stations': [
                    {
                        'type': 'similar',
                        'name': data.artist.name,
                        'html': player.station.similar.get_html(data.artist.name)
                    },
                    {
                        'type': 'artist',
                        'name': data.artist.name,
                        'html': player.station.artist.get_html(data.artist.name)
                    }
                ]
            };
            elem.html(ich.tpl_infoblock_artist(context));
            ui.infoblock.convert_wiki($('.infoblock__wiki'));
            ui.infoblock.add_comments(elem, 'artist', data.artist.name);
        },
        function(data) {
            if (data.error == 6) {
                $(elem).text('Нет такого исполнителя.');
                return true;
            }
        }
    );
};

ui.infoblock.show_tag = function(elem, name) {
    network.lastfm.api(
        'tag.getInfo',
        {
            'tag': name,
            'lang': 'ru'
        },
        function(data) {
            data.tag.url = data.tag.url.replace('http://www.last.fm', 'http://www.lastfm.ru');
            var context = {
                'name': data.tag.name,
                'wiki_summary': data.tag.wiki.summary,
                'wiki': data.tag.wiki.content,
                'lastfm_url': data.tag.url,
                'lastfm_url_text': util.string.urldecode(data.tag.url),
                'stations': [
                    {
                        'type': 'tag',
                        'name': data.tag.name,
                        'html': player.station.tag.get_html(data.tag.name)
                    }
                ]
            };
            elem.html(ich.tpl_infoblock_tag(context));
            ui.infoblock.convert_wiki($('.infoblock__wiki'));
            ui.infoblock.add_comments(elem, 'tag', data.tag.name);

            network.lastfm.api(
                'tag.getTopArtists',
                {
                    'tag': name,
                    'limit': 25
                },
                function(data) {
                    context['top_artists'] = [];
                    var artists = context['artists'] = network.lastfm.arrayize(data.topartists.artist);
                    for (var i = 0; i < 4; i++) {
                        context['top_artists'].push({
                            'name': artists[i].name,
                            'image': network.lastfm.select_image(artists[i].image, 'medium', true)
                        });
                    }
                    var html = ich.tpl_infoblock_tag(context).find('.infoblock__artists').html();
                    elem.find('.infoblock__artists').html(html);
                    var html = ich.tpl_infoblock_tag(context).find('.infoblock__photos').html();
                    elem.find('.infoblock__photos').html(html);
                }
            );

            network.lastfm.api(
                'tag.getSimilar',
                {
                    'tag': name
                },
                function(data) {
                    context['tags'] = network.lastfm.arrayize(data.similartags.tag).splice(0, 10);
                    var html = ich.tpl_infoblock_tag(context).find('.infoblock__tags').html();
                    elem.find('.infoblock__tags').html(html);
                }
            );
        },
        function(data) {
            if (data.error == 6) {
                $(elem).text('Нет такого тега.');
                return true;
            }
        }
    );
};

ui.infoblock.show_user = function(elem, name) {
    network.lastfm.api(
        'user.getInfo',
        {
            'user': name
        },
        function(data) {
            data.user.url = data.user.url.replace('http://www.last.fm', 'http://www.lastfm.ru');
            var context = {
                'name': data.user.name,
                'image': network.lastfm.select_image(data.user.image, 'large'),
                'lastfm_url': data.user.url,
                'lastfm_url_text': util.string.urldecode(data.user.url),
                'it_is_you': (data.user.name == network.lastfm.user),
                'stations': [
                    {
                        'type': 'library',
                        'name': data.user.name,
                        'html': player.station.library.get_html(data.user.name)
                    },
                    {
                        'type': 'loved',
                        'name': data.user.name,
                        'html': player.station.loved.get_html(data.user.name)
                    }
                ]
            };
            if (data.user.name == network.lastfm.user) {
                context['stations'].push({
                    'type': 'recommendations',
                    'name': data.user.name,
                    'html': player.station.recommendations.get_html(data.user.name)
                });
            }
            elem.html(ich.tpl_infoblock_user(context));

            network.lastfm.api(
                'user.getTopArtists',
                {
                    'user': name,
                    'period': 'overall'
                },
                function(data) {
                    var artists = network.lastfm.arrayize(data.topartists.artist);
                    context['artists'] = [];
                    for (var i = 0; i < artists.length; i++) {
                        var image = network.lastfm.select_image(artists[i].image, 'medium', true);
                        if (image) {
                            context['artists'].push({
                                'name': artists[i].name,
                                'image': image
                            });
                        }
                    }
                    elem.html(ich.tpl_infoblock_user(context));
                    network.lastfm.api(
                        'user.getNeighbours',
                        {
                            'user': name,
                            'limit': 10
                        },
                        function(data) {
                            var neighbours = network.lastfm.arrayize(data.neighbours.user);
                            context['neighbours'] = [];
                            for (var i = 0; i < neighbours.length; i++) {
                                context['neighbours'].push({
                                    'name': neighbours[i].name
                                });
                            }
                            elem.html(ich.tpl_infoblock_user(context));
                        }
                    );
                    network.lastfm.api(
                        'user.getFriends',
                        {
                            'user': name,
                            'limit': 1000
                        },
                        function(data) {
                            var friends = network.lastfm.arrayize(data.friends.user);
                            context['friends'] = [];
                            for (var i = 0; i < friends.length; i++) {
                                context['friends'].push({
                                    'name': friends[i].name
                                });
                            }
                            elem.html(ich.tpl_infoblock_user(context));
                        }
                    );
                    if ((network.lastfm.authorized)&&(name != network.lastfm.user)) {
                        network.lastfm.api(
                            'tasteometer.compare',
                            {
                                'type1': 'user',
                                'value1': network.lastfm.user,
                                'type2': 'user',
                                'value2': name
                            },
                            function(data) {
                                context['tasteometer'] = Math.round(data.comparison.result.score * 100);
                                elem.html(ich.tpl_infoblock_user(context));
                            }
                        );
                    }
                },
                function(data) {
                    if (data.error == 6) {
                        $(elem).text('Нет такого пользователя на Last.fm.');
                        return true;
                    }
                }
            );
        }
    );
};

ui.infoblock.show = function(elem, type, name) {
    elem.html('

');
    ui.infoblock['show_' + type](elem, name);
};

ui.infoblock.show_popup = function(type, name) {
    ui.popup.show(name);
    ui.infoblock.show($('.popup .popup__content'), type, name);
};

$('.nav-infoblock').live('click', function(e) {
    e.preventDefault();
    ui.infoblock.show_popup($(this).data('type'), (($(this).data('name'))||$(this).text()));
});

<|endoftext|>


<commit_before>'use strict';

var xhr = require('../utils/xhr');
var ReactX = require('../utils/ReactX');

var currentUser = ReactX.currentUser;

var AuthStore = {
    getCurrentUser: function () {
        return currentUser;
    },

    login: function (credentials) {
        return xhr('/login', 'POST', credentials).then(function (result) {
            if (result.error) {
                throw new Error(result.message);
            } else {
                currentUser = result.user;
            }
        });
    }
};

module.exports = AuthStore;<commit_msg>fix authStore<commit_after>'use strict';

var xhr = require('../utils/xhr');
var ReactX = require('../utils/ReactX');

var AuthStore = {
    getCurrentUser: function () {
        return ReactX.currentUser;
    },

    login: function (credentials) {
        return xhr('/login', 'POST', credentials).then(function (result) {
            if (result.error) {
                throw new Error(result.message);
            } else {
                ReactX.currentUser = result.user;
            }
        });
    }
};

module.exports = AuthStore;<|endoftext|>


<commit_before>var bluetoothDevice;

function onDisconnectButtonClick() {
  if (!bluetoothDevice) {
    return;
  }
  log('Disconnecting from Bluetooth Device...');
  if (bluetoothDevice.gatt.connected) {
    bluetoothDevice.gatt.disconnect();
    log('> Bluetooth Device connected: ' + bluetoothDevice.gatt.connected);
  } else {
    log('> Bluetooth Device is already disconnected');
  }
}

function onDisconnected() {
  log('> Bluetooth Device disconnected');
}

function onScanButtonClick() {
  let options = {filters: []};

  let filterService = document.querySelector('#service').value;
  if (filterService.startsWith('0x')) {
    filterService = parseInt(filterService, 16);
  }
  if (filterService) {
    options.filters.push({services: [filterService]});
  }

  let filterName = document.querySelector('#name').value;
  if (filterName) {
    options.filters.push({name: filterName});
  }

  let filterNamePrefix = document.querySelector('#namePrefix').value;
  if (filterNamePrefix) {
    options.filters.push({namePrefix: filterNamePrefix});
  }

  bluetoothDevice = null;
  log('Requesting Bluetooth Device...');
  navigator.bluetooth.requestDevice(options)
  .then(device => {
    bluetoothDevice = device;
    bluetoothDevice.addEventListener('gattserverdisconnected', onDisconnected);
    return connect();
  })
  .catch(error => {
    log('Argh! ' + error);
  });
}

function onReconnectButtonClick() {
  if (!bluetoothDevice) {
    return;
  }
  if (bluetoothDevice.gatt.connected) {
    log('> Bluetooth Device is already connected');
    return;
  }
  connect()
  .catch(error => {
    log('Argh! ' + error);
  });
}

function connect() {
  log('Connecting to Bluetooth Device...');
  return bluetoothDevice.gatt.connect()
  .then(gattServer => {
    log('> Bluetooth Device connected: ' + bluetoothDevice.gatt.connected);
  });
}
<commit_msg>Fix disconnect behaviour (#341)<commit_after>var bluetoothDevice;

function onDisconnectButtonClick() {
  if (!bluetoothDevice) {
    return;
  }
  log('Disconnecting from Bluetooth Device...');
  if (bluetoothDevice.gatt.connected) {
    bluetoothDevice.gatt.disconnect();
  } else {
    log('> Bluetooth Device is already disconnected');
  }
}

function onDisconnected() {
  log('> Bluetooth Device disconnected');
}

function onScanButtonClick() {
  let options = {filters: []};

  let filterService = document.querySelector('#service').value;
  if (filterService.startsWith('0x')) {
    filterService = parseInt(filterService, 16);
  }
  if (filterService) {
    options.filters.push({services: [filterService]});
  }

  let filterName = document.querySelector('#name').value;
  if (filterName) {
    options.filters.push({name: filterName});
  }

  let filterNamePrefix = document.querySelector('#namePrefix').value;
  if (filterNamePrefix) {
    options.filters.push({namePrefix: filterNamePrefix});
  }

  bluetoothDevice = null;
  log('Requesting Bluetooth Device...');
  navigator.bluetooth.requestDevice(options)
  .then(device => {
    bluetoothDevice = device;
    bluetoothDevice.addEventListener('gattserverdisconnected', onDisconnected);
    return connect();
  })
  .catch(error => {
    log('Argh! ' + error);
  });
}

function onReconnectButtonClick() {
  if (!bluetoothDevice) {
    return;
  }
  if (bluetoothDevice.gatt.connected) {
    log('> Bluetooth Device is already connected');
    return;
  }
  connect()
  .catch(error => {
    log('Argh! ' + error);
  });
}

function connect() {
  log('Connecting to Bluetooth Device...');
  return bluetoothDevice.gatt.connect()
  .then(gattServer => {
    log('> Bluetooth Device connected');
  });
}
<|endoftext|>