<commit_before>/** Called automatically by JsDoc Toolkit. */
function publish(symbolSet) {
	publish.conf = {  // trailing slash expected for dirs
		ext:         ".html",
		outDir:      JSDOC.opt.d || SYS.pwd+"../out/jsdoc/",
		templatesDir: JSDOC.opt.t || SYS.pwd+"../templates/jsdoc/",
		staticDir:   "static/",
		symbolsDir:  "symbols/",
		srcDir:      "symbols/src/",
		cssDir:      "css/",
		fontsDir:    "css/fonts/",
		jsDir:       "javascript/",
		templateName: "Codeview",
		templateVersion: "1.3",
		templateLink: "https://github.com/quadroid/clonejs/tree/master/lib/jsdoc-toolkit/templates/codeview-jsdoc2-template"
	};

	// is source output is suppressed, just display the links to the source file
	if (JSDOC.opt.s && defined(Link) && Link.prototype._makeSrcLink) {
		Link.prototype._makeSrcLink = function(srcFilePath) {
			return "<"+srcFilePath+">";
		}
	}

	// create the folders and subfolders to hold the output
	IO.mkPath((publish.conf.outDir+publish.conf.cssDir));
	IO.mkPath((publish.conf.outDir+publish.conf.fontsDir));
	IO.mkPath((publish.conf.outDir+publish.conf.jsDir));
	IO.mkPath((publish.conf.outDir+"symbols/src").split("/"));

	// used to allow Link to check the details of things being linked to
	Link.symbolSet = symbolSet;

	// create the required templates
	try {
		var classTemplate = new JSDOC.JsPlate(publish.conf.templatesDir+"class.tmpl");
	}
	catch(e) {
		print("Couldn't create the required templates: "+e);
		quit();
	}

	// some utility filters
	function hasNoParent($) {return ($.memberOf == "")}
	function isaFile($) {return ($.is("FILE"))}
	function isaClass($) {return (($.is("CONSTRUCTOR") || $.isNamespace) && ($.alias != "_global_" || !JSDOC.opt.D.noGlobal))}

	// get an array version of the symbolset, useful for filtering
	var symbols = symbolSet.toArray();

	// create the hilited source code files
	var files = JSDOC.opt.srcFiles;
 	for (var i = 0, l = files.length; i < l; i++) {
 		var file = files[i];
 		var srcDir = publish.conf.outDir + publish.conf.srcDir;
		makeSrcFile(file, srcDir);
 	}

 	// get a list of all the classes in the symbolset
 	publish.classes = symbols.filter(isaClass).sort(makeSortby("alias"));

	// create a filemap in which outfiles must be to be named uniquely, ignoring case
	if (JSDOC.opt.u) {
		var filemapCounts = {};
		Link.filemap = {};
		for (var i = 0, l = publish.classes.length; i < l; i++) {
			var lcAlias = publish.classes[i].alias.toLowerCase();

			if (!filemapCounts[lcAlias]) filemapCounts[lcAlias] = 1;
			else filemapCounts[lcAlias]++;

			Link.filemap[publish.classes[i].alias] =
				(filemapCounts[lcAlias] > 1)?
				lcAlias+"_"+filemapCounts[lcAlias] : lcAlias;
		}
	}

	// create each of the class pages
	for (var i = 0, l = publish.classes.length; i < l; i++) {
		var symbol = publish.classes[i];

		symbol.events = symbol.getEvents();   // 1 order matters
		symbol.methods = symbol.getMethods(); // 2

		var output = "";
		output = classTemplate.process(symbol);

		IO.saveFile(publish.conf.outDir+publish.conf.symbolsDir, ((JSDOC.opt.u)? Link.filemap[symbol.alias] : symbol.alias) + publish.conf.ext, output);
	}

	// create the class index page
	try {
		var classesindexTemplate = new JSDOC.JsPlate(publish.conf.templatesDir+"allclasses.tmpl");
	}
	catch(e) { print(e.message); quit(); }

	var classesIndex = classesindexTemplate.process(publish.classes);
	IO.saveFile(publish.conf.outDir, (JSDOC.opt.D.index=="files"?"allclasses":"index")+publish.conf.ext, classesIndex);
	classesindexTemplate = classesIndex = classes = null;

	// create the file index page
	try {
		var fileindexTemplate = new JSDOC.JsPlate(publish.conf.templatesDir+"allfiles.tmpl");
	}
	catch(e) { print(e.message); quit(); }

	var documentedFiles = symbols.filter(isaFile); // files that have file-level docs
	var allFiles = []; // not all files have file-level docs, but we need to list every one

	for (var i = 0; i < files.length; i++) {
		allFiles.push(new JSDOC.Symbol(files[i], [], "FILE", new JSDOC.DocComment("/** */")));
	}

	for (var i = 0; i < documentedFiles.length; i++) {
		var offset = files.indexOf(documentedFiles[i].alias);
		allFiles[offset] = documentedFiles[i];
	}

	allFiles = allFiles.sort(makeSortby("name"));

	// output the file index page
	var filesIndex = fileindexTemplate.process(allFiles);
	IO.saveFile(publish.conf.outDir, (JSDOC.opt.D.index=="files"?"index":"files")+publish.conf.ext, filesIndex);
	fileindexTemplate = filesIndex = files = null;

	// copy static files
	IO.copyFile(publish.conf.templatesDir+"/"+publish.conf.cssDir+"all.css", publish.conf.outDir+"/"+publish.conf.cssDir);
	IO.copyFile(publish.conf.templatesDir+"/"+publish.conf.cssDir+"screen.css", publish.conf.outDir+"/"+publish.conf.cssDir);
	IO.copyFile(publish.conf.templatesDir+"/"+publish.conf.cssDir+"handheld.css", publish.conf.outDir+"/"+publish.conf.cssDir);
	IO.copyFile(publish.conf.templatesDir+"/"+publish.conf.jsDir+"all.js", publish.conf.outDir+"/"+publish.conf.jsDir);
	IO.copyFile(publish.conf.templatesDir+"/"+publish.conf.jsDir+"html5.js", publish.conf.outDir+"/"+publish.conf.jsDir);
	IO.copyFile(publish.conf.templatesDir+"/"+publish.conf.fontsDir+"mplus-1m-regular-webfont.eot", publish.conf.outDir+"/"+publish.conf.fontsDir);
	IO.copyFile(publish.conf.templatesDir+"/"+publish.conf.fontsDir+"mplus-1m-regular-webfont.svg", publish.conf.outDir+"/"+publish.conf.fontsDir);
	IO.copyFile(publish.conf.templatesDir+"/"+publish.conf.fontsDir+"mplus-1m-regular-webfont.ttf", publish.conf.outDir+"/"+publish.conf.fontsDir);
	IO.copyFile(publish.conf.templatesDir+"/"+publish.conf.fontsDir+"mplus-1m-regular-webfont.woff", publish.conf.outDir+"/"+publish.conf.fontsDir);
	IO.copyFile(publish.conf.templatesDir+"/"+publish.conf.fontsDir+"mplus-1m-bold-webfont.eot", publish.conf.outDir+"/"+publish.conf.fontsDir);
	IO.copyFile(publish.conf.templatesDir+"/"+publish.conf.fontsDir+"mplus-1m-bold-webfont.svg", publish.conf.outDir+"/"+publish.conf.fontsDir);
	IO.copyFile(publish.conf.templatesDir+"/"+publish.conf.fontsDir+"mplus-1m-bold-webfont.ttf", publish.conf.outDir+"/"+publish.conf.fontsDir);
	IO.copyFile(publish.conf.templatesDir+"/"+publish.conf.fontsDir+"mplus-1m-bold-webfont.woff", publish.conf.outDir+"/"+publish.conf.fontsDir);	}

/** Include a sub-template in the current template, specifying a data object */
function subtemplate(template, data) {
	try {
		return new JSDOC.JsPlate(publish.conf.templatesDir+template).process(data);
	}
	catch(e) { print(e.message); quit(); }
}

/** Just the first sentence (up to a full stop). Should not break on dotted variable names. */
function summarize(desc) {
	if (typeof desc != "undefined")
		return desc.match(/([\w\W]+?\.)[^a-z0-9_$]/i)? RegExp.$1 : desc;
}

/** Make a symbol sorter by some attribute. */
function makeSortby(attribute) {
	return function(a, b) {
		if (a[attribute] != undefined && b[attribute] != undefined) {
			a = a[attribute].toLowerCase();
			b = b[attribute].toLowerCase();
			if (a  b) return 1;
			return 0;
		}
	}
}

function wordwrapNamespace(classLink) {
	var classText = classLink.match(/[^<>]+(?=[<])/) + "";
	var classTextNew = classText.replace(/\./g,  " . ") + "";
	classLink = classLink.replace(/[^<>]+(?=[<])/,  classTextNew);
	return classLink;
}

/** Pull in the contents of an external file at the given path. */
function include(path) {
	var path = publish.conf.templatesDir+path;
	return IO.readFile(path);
}

/** Turn a raw source file into a code-hilited page in the docs. */
function makeSrcFile(path, srcDir, name) {
	if (JSDOC.opt.s) return;

	if (!name) {
		name = path.replace(/\.\.?[\\\/]/g, "").replace(/[\\\/]/g, "_");
		name = name.replace(/\:/g, "_");
	}

	var src = {path: path, name:name, charset: IO.encoding, hilited: ""};

	if (defined(JSDOC.PluginManager)) {
		JSDOC.PluginManager.run("onPublishSrc", src);
	}

	if (src.hilited) {
		IO.saveFile(srcDir, name+publish.conf.ext, src.hilited);
	}
}

/** Build output for displaying function parameters. */
function makeSignature(params, hideOpt) {
	if (!params) return "()";
	var signature = "("
	+
	params.filter(
		function($) {
			return $.name.indexOf(".") == -1; // don't show config params in signature
		}
	).map(
		function($) {
//            LOG.inform($.type);
            var escapeHtml = {
                '&': '&',
                '<': '<',
                '>': '>'
            };
            var argName = $.name.replace(/[&<>]/g, function(tag){
                return escapeHtml[tag] || tag;
            });
//            if($.type.indexOf('=') > 0 ){
//                argName += 'opt';
//            }
            if(!hideOpt){
                var match = $.type.match(/(=([^|]*))/);
                if(match){
                    argName += ''+ (match[2] && match[1] || 'opt') +'';
                }
            }
			return argName;
		}
	).join(", ")
	+
	")";
	return signature;
}

/** Find symbol {@link ...} strings in text and turn into html links */
function resolveLinks(str, from) {
   str = str.replace(/\{@link ([^}]+)\}/gi,
     function(match, symbolName) {
	symbolName = symbolName.trim();
	var index = symbolName.indexOf(' ');
	if (index > 0) {
	   var label = symbolName.substring(index + 1);
	   symbolName = symbolName.substring(0, index);
	   return new Link().toSymbol(symbolName).withText(label);
	} else {
	   return new Link().toSymbol(symbolName);
	}
     }
   );
   return str;
}<commit_msg>update @link tag functionality<commit_after>/** Called automatically by JsDoc Toolkit. */
function publish(symbolSet) {
	publish.conf = {  // trailing slash expected for dirs
		ext:         ".html",
		outDir:      JSDOC.opt.d || SYS.pwd+"../out/jsdoc/",
		templatesDir: JSDOC.opt.t || SYS.pwd+"../templates/jsdoc/",
		staticDir:   "static/",
		symbolsDir:  "symbols/",
		srcDir:      "symbols/src/",
		cssDir:      "css/",
		fontsDir:    "css/fonts/",
		jsDir:       "javascript/",
		templateName: "Codeview",
		templateVersion: "1.3",
		templateLink: "https://github.com/quadroid/clonejs/tree/master/lib/jsdoc-toolkit/templates/codeview-jsdoc2-template"
	};

	// is source output is suppressed, just display the links to the source file
	if (JSDOC.opt.s && defined(Link) && Link.prototype._makeSrcLink) {
		Link.prototype._makeSrcLink = function(srcFilePath) {
			return "<"+srcFilePath+">";
		}
	}

	// create the folders and subfolders to hold the output
	IO.mkPath((publish.conf.outDir+publish.conf.cssDir));
	IO.mkPath((publish.conf.outDir+publish.conf.fontsDir));
	IO.mkPath((publish.conf.outDir+publish.conf.jsDir));
	IO.mkPath((publish.conf.outDir+"symbols/src").split("/"));

	// used to allow Link to check the details of things being linked to
	Link.symbolSet = symbolSet;

	// create the required templates
	try {
		var classTemplate = new JSDOC.JsPlate(publish.conf.templatesDir+"class.tmpl");
	}
	catch(e) {
		print("Couldn't create the required templates: "+e);
		quit();
	}

	// some utility filters
	function hasNoParent($) {return ($.memberOf == "")}
	function isaFile($) {return ($.is("FILE"))}
	function isaClass($) {return (($.is("CONSTRUCTOR") || $.isNamespace) && ($.alias != "_global_" || !JSDOC.opt.D.noGlobal))}

	// get an array version of the symbolset, useful for filtering
	var symbols = symbolSet.toArray();

	// create the hilited source code files
	var files = JSDOC.opt.srcFiles;
 	for (var i = 0, l = files.length; i < l; i++) {
 		var file = files[i];
 		var srcDir = publish.conf.outDir + publish.conf.srcDir;
		makeSrcFile(file, srcDir);
 	}

 	// get a list of all the classes in the symbolset
 	publish.classes = symbols.filter(isaClass).sort(makeSortby("alias"));

	// create a filemap in which outfiles must be to be named uniquely, ignoring case
	if (JSDOC.opt.u) {
		var filemapCounts = {};
		Link.filemap = {};
		for (var i = 0, l = publish.classes.length; i < l; i++) {
			var lcAlias = publish.classes[i].alias.toLowerCase();

			if (!filemapCounts[lcAlias]) filemapCounts[lcAlias] = 1;
			else filemapCounts[lcAlias]++;

			Link.filemap[publish.classes[i].alias] =
				(filemapCounts[lcAlias] > 1)?
				lcAlias+"_"+filemapCounts[lcAlias] : lcAlias;
		}
	}

	// create each of the class pages
	for (var i = 0, l = publish.classes.length; i < l; i++) {
		var symbol = publish.classes[i];

		symbol.events = symbol.getEvents();   // 1 order matters
		symbol.methods = symbol.getMethods(); // 2

		var output = "";
		output = classTemplate.process(symbol);

		IO.saveFile(publish.conf.outDir+publish.conf.symbolsDir, ((JSDOC.opt.u)? Link.filemap[symbol.alias] : symbol.alias) + publish.conf.ext, output);
	}

	// create the class index page
	try {
		var classesindexTemplate = new JSDOC.JsPlate(publish.conf.templatesDir+"allclasses.tmpl");
	}
	catch(e) { print(e.message); quit(); }

	var classesIndex = classesindexTemplate.process(publish.classes);
	IO.saveFile(publish.conf.outDir, (JSDOC.opt.D.index=="files"?"allclasses":"index")+publish.conf.ext, classesIndex);
	classesindexTemplate = classesIndex = classes = null;

	// create the file index page
	try {
		var fileindexTemplate = new JSDOC.JsPlate(publish.conf.templatesDir+"allfiles.tmpl");
	}
	catch(e) { print(e.message); quit(); }

	var documentedFiles = symbols.filter(isaFile); // files that have file-level docs
	var allFiles = []; // not all files have file-level docs, but we need to list every one

	for (var i = 0; i < files.length; i++) {
		allFiles.push(new JSDOC.Symbol(files[i], [], "FILE", new JSDOC.DocComment("/** */")));
	}

	for (var i = 0; i < documentedFiles.length; i++) {
		var offset = files.indexOf(documentedFiles[i].alias);
		allFiles[offset] = documentedFiles[i];
	}

	allFiles = allFiles.sort(makeSortby("name"));

	// output the file index page
	var filesIndex = fileindexTemplate.process(allFiles);
	IO.saveFile(publish.conf.outDir, (JSDOC.opt.D.index=="files"?"index":"files")+publish.conf.ext, filesIndex);
	fileindexTemplate = filesIndex = files = null;

	// copy static files
	IO.copyFile(publish.conf.templatesDir+"/"+publish.conf.cssDir+"all.css", publish.conf.outDir+"/"+publish.conf.cssDir);
	IO.copyFile(publish.conf.templatesDir+"/"+publish.conf.cssDir+"screen.css", publish.conf.outDir+"/"+publish.conf.cssDir);
	IO.copyFile(publish.conf.templatesDir+"/"+publish.conf.cssDir+"handheld.css", publish.conf.outDir+"/"+publish.conf.cssDir);
	IO.copyFile(publish.conf.templatesDir+"/"+publish.conf.jsDir+"all.js", publish.conf.outDir+"/"+publish.conf.jsDir);
	IO.copyFile(publish.conf.templatesDir+"/"+publish.conf.jsDir+"html5.js", publish.conf.outDir+"/"+publish.conf.jsDir);
	IO.copyFile(publish.conf.templatesDir+"/"+publish.conf.fontsDir+"mplus-1m-regular-webfont.eot", publish.conf.outDir+"/"+publish.conf.fontsDir);
	IO.copyFile(publish.conf.templatesDir+"/"+publish.conf.fontsDir+"mplus-1m-regular-webfont.svg", publish.conf.outDir+"/"+publish.conf.fontsDir);
	IO.copyFile(publish.conf.templatesDir+"/"+publish.conf.fontsDir+"mplus-1m-regular-webfont.ttf", publish.conf.outDir+"/"+publish.conf.fontsDir);
	IO.copyFile(publish.conf.templatesDir+"/"+publish.conf.fontsDir+"mplus-1m-regular-webfont.woff", publish.conf.outDir+"/"+publish.conf.fontsDir);
	IO.copyFile(publish.conf.templatesDir+"/"+publish.conf.fontsDir+"mplus-1m-bold-webfont.eot", publish.conf.outDir+"/"+publish.conf.fontsDir);
	IO.copyFile(publish.conf.templatesDir+"/"+publish.conf.fontsDir+"mplus-1m-bold-webfont.svg", publish.conf.outDir+"/"+publish.conf.fontsDir);
	IO.copyFile(publish.conf.templatesDir+"/"+publish.conf.fontsDir+"mplus-1m-bold-webfont.ttf", publish.conf.outDir+"/"+publish.conf.fontsDir);
	IO.copyFile(publish.conf.templatesDir+"/"+publish.conf.fontsDir+"mplus-1m-bold-webfont.woff", publish.conf.outDir+"/"+publish.conf.fontsDir);	}

/** Include a sub-template in the current template, specifying a data object */
function subtemplate(template, data) {
	try {
		return new JSDOC.JsPlate(publish.conf.templatesDir+template).process(data);
	}
	catch(e) { print(e.message); quit(); }
}

/** Just the first sentence (up to a full stop). Should not break on dotted variable names. */
function summarize(desc) {
	if (typeof desc != "undefined")
		return desc.match(/([\w\W]+?\.)[^a-z0-9_$]/i)? RegExp.$1 : desc;
}

/** Make a symbol sorter by some attribute. */
function makeSortby(attribute) {
	return function(a, b) {
		if (a[attribute] != undefined && b[attribute] != undefined) {
			a = a[attribute].toLowerCase();
			b = b[attribute].toLowerCase();
			if (a  b) return 1;
			return 0;
		}
	}
}

function wordwrapNamespace(classLink) {
	var classText = classLink.match(/[^<>]+(?=[<])/) + "";
	var classTextNew = classText.replace(/\./g,  " . ") + "";
	classLink = classLink.replace(/[^<>]+(?=[<])/,  classTextNew);
	return classLink;
}

/** Pull in the contents of an external file at the given path. */
function include(path) {
	var path = publish.conf.templatesDir+path;
	return IO.readFile(path);
}

/** Turn a raw source file into a code-hilited page in the docs. */
function makeSrcFile(path, srcDir, name) {
	if (JSDOC.opt.s) return;

	if (!name) {
		name = path.replace(/\.\.?[\\\/]/g, "").replace(/[\\\/]/g, "_");
		name = name.replace(/\:/g, "_");
	}

	var src = {path: path, name:name, charset: IO.encoding, hilited: ""};

	if (defined(JSDOC.PluginManager)) {
		JSDOC.PluginManager.run("onPublishSrc", src);
	}

	if (src.hilited) {
		IO.saveFile(srcDir, name+publish.conf.ext, src.hilited);
	}
}

/** Build output for displaying function parameters. */
function makeSignature(params, hideOpt) {
	if (!params) return "()";
	var signature = "("
	+
	params.filter(
		function($) {
			return $.name.indexOf(".") == -1; // don't show config params in signature
		}
	).map(
		function($) {
//            LOG.inform($.type);
            var escapeHtml = {
                '&': '&',
                '<': '<',
                '>': '>'
            };
            var argName = $.name.replace(/[&<>]/g, function(tag){
                return escapeHtml[tag] || tag;
            });
//            if($.type.indexOf('=') > 0 ){
//                argName += 'opt';
//            }
            if(!hideOpt){
                var match = $.type.match(/(=([^|]*))/);
                if(match){
                    argName += ''+ (match[2] && match[1] || 'opt') +'';
                }
            }
			return argName;
		}
	).join(", ")
	+
	")";
	return signature;
}

/** Find symbol {@link ...} strings in text and turn into html links */
function resolveLinks(str, from) {
    str = str.replace(
        /(?:\[([^\]]+)\])?\{@link(plain|code)? ([^}]+)\}/gi,
        function(match, label, linkType, linkTo) {
            linkTo = linkTo.trim();

            var index = linkTo.indexOf(' ');
            if (index > 0) {
               label  = linkTo.substring(index + 1);
               linkTo = linkTo.substring(0, index);
            }

            var link = new Link();

            if(linkTo[0]=='/'){

                link = link.toFile(linkTo);

            }else if(linkTo[0]=='#'
                  || linkTo[0]=='.'
                  || linkTo.indexOf('http://') ===0
                  || linkTo.indexOf('https://')===0
            ){
                link.linkUrl = linkTo;
                var linkText = label ||( linkTo[0]=='#' ? linkTo.substr(1) : linkTo );
                link.toString = function(){
                    LOG.inform(from);
                    var target = (this.targetName)? " target=\""+this.targetName+"\"" : "";
                    return ""+linkText+"";
                }

            }else{
                link = link.toSymbol(linkTo);
            }

            if(label) link = link.withText(label);

            return link;
        }
    );
    return str;
}<|endoftext|>


<commit_before>var fs = require('fs');
var request = require('request');
var _a = require('async');
var progress = require('progress');
require('colors');

var BASE_SERVICE_URL = 'http://www.youtube-mp3.org';
var BASE_YT_URL = "http://www.youtube.com/watch?v=";

function pushItem(videoId, cb) {
    request.get({
        url: BASE_SERVICE_URL + '/a/pushItem/',
        qs: {
            item: BASE_YT_URL + videoId,
            el: 'na',
            bf: 'false'
        },
        headers: {
            Host: "www.youtube-mp3.org",
            Referer: "http://www.youtube-mp3.org/"
        }
    }, function (err, res, body) {
        if (err) {
            cb(err);
        } else if (!body) {
            cb({error: "Empty push response"});
        } else {
            cb(null, body);
        }
    });
}

function itemInfo(videoId, cb) {
    request.get({
        url: BASE_SERVICE_URL + '/a/itemInfo/',
        qs: {
            video_id: videoId,
            ac: 'www',
            t: 'grp'
        }
    }, function (err, res, body) {
        if (err) {
            cb(err);
        } else {
            var match = body.match(/^info = (.*);$/);
            if (!match) {
                cb({error: "Invalid response: " + body});
            } else {
                var info = JSON.parse(match[1]);

                info.videoId = videoId;

                delete info.progress_speed;
                delete info.progress;
                delete info.status;
                delete info.pf;
                delete info.ads;
                delete info.length;

                cb(null, info);
            }
        }
    });
}

function download(info, cb) {
    var now = (new Date).getTime();

    var req = request({
        url: BASE_SERVICE_URL + '/get',
        qs: {
            ab: 256,
            video_id: info.videoId,
            h: info.h,
            r: now + "." + adler32(info.videoId + now)
        }
    });

    delete info.h;

    req.on('response', function (res) {
        console.log("Downloading '" + info.title + "'");

        if (res.headers['content-type'] === 'application/octet-stream') {
            var output = fs.createWriteStream(info.title + ".mp3");

            res.pipe(output);

            var length = parseInt(res.headers['content-length'], 10);

            var bar = new progress('[:bar] :percent :etas', {
                complete: '=',
                incomplete: ' ',
                width: 40,
                total: length
            });

            res.on('data', function (chunk) {
                bar.tick(chunk.length);
            });

            output.on('finish', function () {
                console.log("Successfully downloaded '" + info.title + "'");

                cb(null, info);
            });

            output.on('error', function (err) {
                console.error("Failed to download '" + info.title + "' (" + err + ")");

                cb(err);
            });
        } else {
            console.error("Failed to start downloading '" + info.title + "' (" + err + ")");

            cb({error: "Failed to start download"});
        }
    });
}

function adler32(str) {
    var a = 1, b = 0;

    for (i = 0; i < str.length; i++) {
        a = (a + str.charCodeAt(i)) % 65521;
        b = (b + a) % 65521;
    }

    return b << 16 | a;
}

module.exports = _a.compose(download, itemInfo, pushItem);
<commit_msg>renamed progress bar<commit_after>var fs = require('fs');
var request = require('request');
var _a = require('async');
var ProgressBar = require('progress');
require('colors');

var BASE_SERVICE_URL = 'http://www.youtube-mp3.org';
var BASE_YT_URL = "http://www.youtube.com/watch?v=";

function pushItem(videoId, cb) {
    request.get({
        url: BASE_SERVICE_URL + '/a/pushItem/',
        qs: {
            item: BASE_YT_URL + videoId,
            el: 'na',
            bf: 'false'
        },
        headers: {
            Host: "www.youtube-mp3.org",
            Referer: "http://www.youtube-mp3.org/"
        }
    }, function (err, res, body) {
        if (err) {
            cb(err);
        } else if (!body) {
            cb({error: "Empty push response"});
        } else {
            cb(null, body);
        }
    });
}

function itemInfo(videoId, cb) {
    request.get({
        url: BASE_SERVICE_URL + '/a/itemInfo/',
        qs: {
            video_id: videoId,
            ac: 'www',
            t: 'grp'
        }
    }, function (err, res, body) {
        if (err) {
            cb(err);
        } else {
            var match = body.match(/^info = (.*);$/);
            if (!match) {
                cb({error: "Invalid response: " + body});
            } else {
                var info = JSON.parse(match[1]);

                info.videoId = videoId;

                delete info.progress_speed;
                delete info.progress;
                delete info.status;
                delete info.pf;
                delete info.ads;
                delete info.length;

                cb(null, info);
            }
        }
    });
}

function download(info, cb) {
    var now = (new Date).getTime();

    var req = request({
        url: BASE_SERVICE_URL + '/get',
        qs: {
            ab: 256,
            video_id: info.videoId,
            h: info.h,
            r: now + "." + adler32(info.videoId + now)
        }
    });

    delete info.h;

    req.on('response', function (res) {
        console.log("Downloading '" + info.title + "'");

        if (res.headers['content-type'] === 'application/octet-stream') {
            var output = fs.createWriteStream(info.title + ".mp3");

            res.pipe(output);

            var length = parseInt(res.headers['content-length'], 10);

            var bar = new ProgressBar('[:bar] :percent :etas', {
                complete: '=',
                incomplete: ' ',
                width: 40,
                total: length
            });

            res.on('data', function (chunk) {
                bar.tick(chunk.length);
            });

            output.on('finish', function () {
                console.log("Successfully downloaded '" + info.title + "'");

                cb(null, info);
            });

            output.on('error', function (err) {
                console.error("Failed to download '" + info.title + "' (" + err + ")");

                cb(err);
            });
        } else {
            console.error("Failed to start downloading '" + info.title + "' (" + err + ")");

            cb({error: "Failed to start download"});
        }
    });
}

function adler32(str) {
    var a = 1, b = 0;

    for (i = 0; i < str.length; i++) {
        a = (a + str.charCodeAt(i)) % 65521;
        b = (b + a) % 65521;
    }

    return b << 16 | a;
}

module.exports = _a.compose(download, itemInfo, pushItem);
<|endoftext|>


<commit_before>/**
 * Copyright (c) <2012> <Zhijie Lee / onezeros.lee at gmail.com>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 */

/**
 * implements operations in Photoshop cs6 menu:Filter->Stylize
 */

PSX.Filter.Stylize = {};

// solarize in photoshop,i.e. over exposuse
PSX.Filter.Stylize.solarize = function(src, dst)
{
	var len = src.width * src.height * 4;
	for(var i =0;  i < len; i+=4){
		for(var ch =0; ch < 3; ch++){
			var v = src.data[i + ch];
			dst.data[i + ch] = v <128 ? v:255 -v;
		}
	}
}

PSX.Filter.Stylize.emboss = function(src, _dst)
{
    var dst = _dst;
    if(dst == src){
        dst = PSX.Util.copyImageData(src);
    }
	var nChannel = 4;
	var widthStep = src.width * nChannel;
    for(var h = 1; h < src.height -1; h++){
		var psrc = nChannel + h * widthStep;
		var psrcUp = psrc - widthStep - nChannel;
		var psrcDown = psrc + widthStep + nChannel;
		var pdst = nChannel + h * widthStep;
		for(var w =1; w < src.width -1; w++){
			for(var ch =0; ch < 3; ch++){
				dst.data[pdst + ch] = PSX.Util.clamp0255(src.data[psrcUp] * 2 - src.data[psrc] - src.data[psrcDown] + 128);
			}
			psrc +=4;
			psrcUp +=4;
			psrcDown +=4;
			pdst +=4;
		}
	}
	// TODO : boarder process

    if(dst != _dst){
        _dst = PSX.Util.copyImageData(dst);
    }
}<commit_msg>emboss effect,boarder not ok<commit_after>/**
 * Copyright (c) <2012> <Zhijie Lee / onezeros.lee at gmail.com>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 */

/**
 * implements operations in Photoshop cs6 menu:Filter->Stylize
 */

PSX.Filter.Stylize = {};

// solarize in photoshop,i.e. over exposuse
PSX.Filter.Stylize.solarize = function(src, dst)
{
	var len = src.width * src.height * 4;
	for(var i =0;  i < len; i+=4){
		for(var ch =0; ch < 3; ch++){
			var v = src.data[i + ch];
			dst.data[i + ch] = v <128 ? v:255 -v;
		}
	}
}

PSX.Filter.Stylize.emboss = function(src, _dst)
{
    var dst = _dst;
    if(dst == src){
        dst = PSX.Util.cloneImageData(src);
    }
	var nChannel = 4;
	var widthStep = src.width * nChannel;
    for(var h = 1; h < src.height -1; h++){
		var psrc = nChannel + h * widthStep;
		var psrcUp = psrc - widthStep - nChannel;
		var psrcDown = psrc + widthStep + nChannel;
		var pdst = nChannel + h * widthStep;
		for(var w =1; w < src.width -1; w++){
			for(var ch =0; ch < 3; ch++){
				dst.data[pdst + ch] = PSX.Util.clamp0255(src.data[psrcUp] * 2 - src.data[psrc] - src.data[psrcDown] + 128);
			}
			psrc +=4;
			psrcUp +=4;
			psrcDown +=4;
			pdst +=4;
		}
		// TODO:boarder processing seems not work
		//duplicate two boarder of each row
		psrc = h * widthStep;
		pdst = psrc +widthStep - 4;
		for(var ch =0; ch < 3; ch++) {
		    dst.data[pdst++ ] = dst.data[pdst -4 ];
		    dst.data[psrc++ ] = dst.data[psrc + 4];
		}
	}
	var len = dst.data.length;
	var pdown = len - widthStep;
	for(var i =0 ; i < dst.width * 4; i++){
	    dst.data[i] = dst.data[i + widthStep];
	    dst.data[pdown ++] = dst.data[pdown - widthStep];
	}
    if(dst != _dst){
        PSX.Util.copyArray(dst.data,_dst.data);
    }
}<|endoftext|>


<commit_before>var model = require('../libs/model');

var Set = model.Set
  , Snapshot = model.Snapshot
  , SnapshotData = model.SnapshotData;

function getLatestId(device, name, callback) {
  Set.findOne({ devices: { $in: [device] }, name: name }, function (err, set) {
    if (err || !set)
      return callback(err || 'set not found');

    Snapshot.findOne({ setId: set._id, deleted: { $ne: true } }).sort('-date').exec(function (err, snapshot) {
      if (err || !snapshot)
        return callback(err || 'no snapshots');

      callback(null, snapshot.id);
    });
  });
}

function findDataById(id, callback) {
  SnapshotData.findOne({ snapshotId: id }, function (err, data) {
    if (data)
      return callback(null, data);

    Snapshot.find(function (err, snapshots) {
      if (err)
        return callback(err);

      var regex = new RegExp('.*' + id + '$');

      for (var i = 0; i < snapshots.length; i++) {
        if (regex.test(snapshots[i].id)) {
          return SnapshotData.findOne({ snapshotId: snapshots[i]._id }, function (err, data) {
            if (err || !data)
              return callback(err || 'data not found');

            callback(null, data);
          });
        }
      }

      return callback('snapshot not found');
    });
  });
}

function findById(id, res) {
  findDataById(id, function (err, data) {
    if (err)
      return res.json({ error: err });

    res.charset = 'utf-8';
    res.set('Content-Type', 'application/json');
    res.send(data.json);
  });
}

function findVmtById(id, req, res) {
  findDataById(id, function (err, data) {
    if (err)
      return res.send('Error: ' + err);

    var lines = [];
    var lang = req.params.lang;

    data = JSON.parse(data.json);

    var index = data[1].indexOf(lang);

    if (index === -1)
      return res.send('Error: lang not found');

    for (var i = 0; i < data.length; i++) {
      var k = (data[i][0] || '').trim();
      var v = (data[i][index] || data[i][1]).trim();

      if (k) {
        if (/_start$/.test(k))
          v = v.replace(/^\s*([0-9]+\.) ?(.+)$/mg, '$1 \\>$2\\<');

        v = v.replace(/\\/g, '\\\\').replace(/\n/g, '\\n').replace(/\r/g, '');

        lines[i] = k + ' ' + v;
      }
    }

    lines.push('');

    res.charset = 'utf-8';
    res.set('Content-Type', 'text/plain');
    res.send(lines.join('\n'));
  });
}

function findHById(id, req, res) {
  findDataById(id, function (err, data) {
    if (err)
      return res.send('Error: ' + err);

    data = JSON.parse(data.json);

    var result = '#ifndef I18N_TABLES_H\n'
               + '#define I18N_TABLES_H\n'
               + '\n';

    for (var i = 0; i < data.length; i++) {
      var k = (data[i][0] || '').trim();

      if (k)
        result += '__attribute__((used)) static const char* i18n_' + k.toUpperCase() + ' = "' + k + '";\n';
    }

    result += '\n#endif // I18N_TABLES_H';

    res.charset = 'utf-8';
    res.set('Content-Type', 'text/plain');
    res.send(result);
  });
}

exports.latestID = function (req, res) {
  getLatestId(req.params.device, req.params.name, function (err, id) {
    if (err)
      return res.send('Error: ' + err);

    res.send(id);
  });
};

exports.getJSON = function (req, res) {
  findById(req.params.id, res);
};

exports.latestJSON = function (req, res) {
  getLatestId(req.params.device, req.params.name, function (err, id) {
    if (err)
      return res.json({ error: err });

    findById(id, res);
  });
};

exports.liveJSON = function (req, res) {
  Set.findOne({ devices: { $in: [req.params.device] }, name: req.params.name }, function (err, set) {
    if (err || !set)
      return res.json({ error: err || 'set not found' });

    set.export(function (err, data) {
      if (err)
        return res.json({ error: err });

      res.charset = 'utf-8';
      res.json(data);
    });
  });
};

exports.getVMT = function (req, res) {
  findVmtById(req.params.id, req, res);
};

exports.latestVMT = function (req, res) {
  var name = req.params.name.replace(/\..*$/, '');

  getLatestId(req.params.device, name, function (err, id) {
    if (err)
      return res.send('Error: ' + err);

    findVmtById(id, req, res);
  });
};

exports.getH = function (req, res) {
  findHById(req.params.id, req, res);
};

exports.latestH = function (req, res) {
  var name = req.params.name.replace(/\..*$/, '');

  getLatestId(req.params.device, name, function (err, id) {
    if (err)
      return res.send('Error: ' + err);

    findHById(id, req, res);
  });
};

exports.getNg = function (req, res) {
	Set.findOne({ devices: { $in: [req.params.device] }, name: req.params.name }, function (err, set) {
		if (err || !set)
			return res.json({ error: err || 'set not found' });

		set.export(function (err, data) {
			if (err)
				return res.json({ error: err });

			var output = {};
			var lang = req.params.lang.replace(/\..+$/, '');
			var langIndex = data[1].indexOf(lang);

			for (var i = 0; i < data.length; i++) {
				output[data[i][0]] = data[i][langIndex];
			}

			res.charset = 'utf-8';
			res.set('Content-Type', 'application/javascript');
			res.send(JSON.stringify(output, null, 2));
		});
	});
};
<commit_msg>Omit empty keys when exporting to angular-translate format<commit_after>var model = require('../libs/model');

var Set = model.Set
  , Snapshot = model.Snapshot
  , SnapshotData = model.SnapshotData;

function getLatestId(device, name, callback) {
  Set.findOne({ devices: { $in: [device] }, name: name }, function (err, set) {
    if (err || !set)
      return callback(err || 'set not found');

    Snapshot.findOne({ setId: set._id, deleted: { $ne: true } }).sort('-date').exec(function (err, snapshot) {
      if (err || !snapshot)
        return callback(err || 'no snapshots');

      callback(null, snapshot.id);
    });
  });
}

function findDataById(id, callback) {
  SnapshotData.findOne({ snapshotId: id }, function (err, data) {
    if (data)
      return callback(null, data);

    Snapshot.find(function (err, snapshots) {
      if (err)
        return callback(err);

      var regex = new RegExp('.*' + id + '$');

      for (var i = 0; i < snapshots.length; i++) {
        if (regex.test(snapshots[i].id)) {
          return SnapshotData.findOne({ snapshotId: snapshots[i]._id }, function (err, data) {
            if (err || !data)
              return callback(err || 'data not found');

            callback(null, data);
          });
        }
      }

      return callback('snapshot not found');
    });
  });
}

function findById(id, res) {
  findDataById(id, function (err, data) {
    if (err)
      return res.json({ error: err });

    res.charset = 'utf-8';
    res.set('Content-Type', 'application/json');
    res.send(data.json);
  });
}

function findVmtById(id, req, res) {
  findDataById(id, function (err, data) {
    if (err)
      return res.send('Error: ' + err);

    var lines = [];
    var lang = req.params.lang;

    data = JSON.parse(data.json);

    var index = data[1].indexOf(lang);

    if (index === -1)
      return res.send('Error: lang not found');

    for (var i = 0; i < data.length; i++) {
      var k = (data[i][0] || '').trim();
      var v = (data[i][index] || data[i][1]).trim();

      if (k) {
        if (/_start$/.test(k))
          v = v.replace(/^\s*([0-9]+\.) ?(.+)$/mg, '$1 \\>$2\\<');

        v = v.replace(/\\/g, '\\\\').replace(/\n/g, '\\n').replace(/\r/g, '');

        lines[i] = k + ' ' + v;
      }
    }

    lines.push('');

    res.charset = 'utf-8';
    res.set('Content-Type', 'text/plain');
    res.send(lines.join('\n'));
  });
}

function findHById(id, req, res) {
  findDataById(id, function (err, data) {
    if (err)
      return res.send('Error: ' + err);

    data = JSON.parse(data.json);

    var result = '#ifndef I18N_TABLES_H\n'
               + '#define I18N_TABLES_H\n'
               + '\n';

    for (var i = 0; i < data.length; i++) {
      var k = (data[i][0] || '').trim();

      if (k)
        result += '__attribute__((used)) static const char* i18n_' + k.toUpperCase() + ' = "' + k + '";\n';
    }

    result += '\n#endif // I18N_TABLES_H';

    res.charset = 'utf-8';
    res.set('Content-Type', 'text/plain');
    res.send(result);
  });
}

exports.latestID = function (req, res) {
  getLatestId(req.params.device, req.params.name, function (err, id) {
    if (err)
      return res.send('Error: ' + err);

    res.send(id);
  });
};

exports.getJSON = function (req, res) {
  findById(req.params.id, res);
};

exports.latestJSON = function (req, res) {
  getLatestId(req.params.device, req.params.name, function (err, id) {
    if (err)
      return res.json({ error: err });

    findById(id, res);
  });
};

exports.liveJSON = function (req, res) {
  Set.findOne({ devices: { $in: [req.params.device] }, name: req.params.name }, function (err, set) {
    if (err || !set)
      return res.json({ error: err || 'set not found' });

    set.export(function (err, data) {
      if (err)
        return res.json({ error: err });

      res.charset = 'utf-8';
      res.json(data);
    });
  });
};

exports.getVMT = function (req, res) {
  findVmtById(req.params.id, req, res);
};

exports.latestVMT = function (req, res) {
  var name = req.params.name.replace(/\..*$/, '');

  getLatestId(req.params.device, name, function (err, id) {
    if (err)
      return res.send('Error: ' + err);

    findVmtById(id, req, res);
  });
};

exports.getH = function (req, res) {
  findHById(req.params.id, req, res);
};

exports.latestH = function (req, res) {
  var name = req.params.name.replace(/\..*$/, '');

  getLatestId(req.params.device, name, function (err, id) {
    if (err)
      return res.send('Error: ' + err);

    findHById(id, req, res);
  });
};

exports.getNg = function (req, res) {
	Set.findOne({ devices: { $in: [req.params.device] }, name: req.params.name }, function (err, set) {
		if (err || !set)
			return res.json({ error: err || 'set not found' });

		set.export(function (err, data) {
			if (err)
				return res.json({ error: err });

			var output = {};
			var lang = req.params.lang.replace(/\..+$/, '');
			var langIndex = data[1].indexOf(lang);

			for (var i = 0; i < data.length; i++) {
				if (data[i][langIndex]) {
					output[data[i][0]] = data[i][langIndex];
				}
			}

			res.charset = 'utf-8';
			res.set('Content-Type', 'application/javascript');
			res.send(JSON.stringify(output, null, 2));
		});
	});
};
<|endoftext|>


<commit_before>'use strict';

function Zone(parentZone, data) {
  var zone = (arguments.length) ? Object.create(parentZone) : this;

  zone.parent = parentZone;

  Object.keys(data || {}).forEach(function(property) {
    zone[property] = data[property];
  });

  return zone;
}

Zone.prototype = {
  constructor: Zone,

  fork: function (locals) {
    return new Zone(this, locals);
  },

  bind: function (fn) {
    var zone = this.fork();
    return function zoneBoundFn() {
      var result = zone.run(fn, this, arguments);
      return result;
    };
  },

  run: function run (fn, applyTo, applyWith) {
    applyWith = applyWith || [];

    var oldZone = window.zone,
        result;

    window.zone = this;

    try {
      this.onZoneEnter();
      result = fn.apply(applyTo, applyWith);
    } catch (e) {
      if (zone.onError) {
        zone.onError(e);
      }
    } finally {
      this.onZoneLeave();
      window.zone = oldZone;
    }
    return result;
  },

  onZoneEnter: function () {},
  onZoneLeave: function () {}
};

Zone.patchFn = function (obj, fnNames) {
  fnNames.forEach(function (name) {
    var delegate = obj[name];
    zone[name] = function () {
      arguments[0] = zone.bind(arguments[0]);
      return delegate.apply(obj, arguments);
    };

    obj[name] = function marker () {
      return zone[name].apply(this, arguments);
    };
  });
};

Zone.patchableFn = function (obj, fnNames) {
  fnNames.forEach(function (name) {
    var delegate = obj[name];
    zone[name] = function () {
      return delegate.apply(obj, arguments);
    };

    obj[name] = function () {
      return zone[name].apply(this, arguments);
    };
  });
}

Zone.patchProperty = function (obj, prop) {
  var desc = Object.getOwnPropertyDescriptor(obj, prop) || {
    enumerable: true,
    configurable: true
  };

  // A property descriptor cannot have getter/setter and be writable
  // deleting the writable and value properties avoids this error:
  //
  // TypeError: property descriptors must not specify a value or be writable when a
  // getter or setter has been specified
  delete desc.writable;
  delete desc.value;

  // substr(2) cuz 'onclick' -> 'click', etc
  var eventName = prop.substr(2);
  var _prop = '_' + prop;

  desc.set = function (fn) {
    if (this[_prop]) {
      this.removeEventListener(eventName, this[_prop]);
    }

    this[_prop] = fn;

    this.addEventListener(eventName, fn, false);
  };

  desc.get = function () {
    return this[_prop];
  };

  Object.defineProperty(obj, prop, desc);
};

Zone.patchProperties = function (obj) {
  Object.keys(obj).
    filter(function (propertyName) {
      return propertyName.substr(0,2) === 'on';
    }).
    forEach(function (eventName) {
      Zone.patchProperty(obj, eventName);
    });
};

Zone.patchEventTarget = function (obj) {
  var addDelegate = obj.addEventListener;
  obj.addEventListener = function (eventName, fn) {
    arguments[1] = fn._bound = zone.bind(fn);
    return addDelegate.apply(this, arguments);
  };

  var removeDelegate = obj.removeEventListener;
  obj.removeEventListener = function (eventName, fn) {
    arguments[1] = arguments[1]._bound || arguments[1];
    return removeDelegate.apply(this, arguments);
  };
};

Zone.patch = function patch () {
  Zone.patchFn(window, ['setTimeout', 'setInterval']);
  Zone.patchableFn(window, ['alert', 'prompt']);

  // patched properties depend on addEventListener, so this comes first
  Zone.patchEventTarget(EventTarget.prototype);

  Zone.patchProperties(HTMLElement.prototype);
  Zone.patchProperties(XMLHttpRequest.prototype);
};

Zone.init = function init () {
  window.zone = new Zone();
  Zone.patch();
};

Zone.init();
<commit_msg>Patch Node instead of EventTarget. fixes angular/zone.js#5<commit_after>'use strict';

function Zone(parentZone, data) {
  var zone = (arguments.length) ? Object.create(parentZone) : this;

  zone.parent = parentZone;

  Object.keys(data || {}).forEach(function(property) {
    zone[property] = data[property];
  });

  return zone;
}

Zone.prototype = {
  constructor: Zone,

  fork: function (locals) {
    return new Zone(this, locals);
  },

  bind: function (fn) {
    var zone = this.fork();
    return function zoneBoundFn() {
      var result = zone.run(fn, this, arguments);
      return result;
    };
  },

  run: function run (fn, applyTo, applyWith) {
    applyWith = applyWith || [];

    var oldZone = window.zone,
        result;

    window.zone = this;

    try {
      this.onZoneEnter();
      result = fn.apply(applyTo, applyWith);
    } catch (e) {
      if (zone.onError) {
        zone.onError(e);
      }
    } finally {
      this.onZoneLeave();
      window.zone = oldZone;
    }
    return result;
  },

  onZoneEnter: function () {},
  onZoneLeave: function () {}
};

Zone.patchFn = function (obj, fnNames) {
  fnNames.forEach(function (name) {
    var delegate = obj[name];
    zone[name] = function () {
      arguments[0] = zone.bind(arguments[0]);
      return delegate.apply(obj, arguments);
    };

    obj[name] = function marker () {
      return zone[name].apply(this, arguments);
    };
  });
};

Zone.patchableFn = function (obj, fnNames) {
  fnNames.forEach(function (name) {
    var delegate = obj[name];
    zone[name] = function () {
      return delegate.apply(obj, arguments);
    };

    obj[name] = function () {
      return zone[name].apply(this, arguments);
    };
  });
}

Zone.patchProperty = function (obj, prop) {
  var desc = Object.getOwnPropertyDescriptor(obj, prop) || {
    enumerable: true,
    configurable: true
  };

  // A property descriptor cannot have getter/setter and be writable
  // deleting the writable and value properties avoids this error:
  //
  // TypeError: property descriptors must not specify a value or be writable when a
  // getter or setter has been specified
  delete desc.writable;
  delete desc.value;

  // substr(2) cuz 'onclick' -> 'click', etc
  var eventName = prop.substr(2);
  var _prop = '_' + prop;

  desc.set = function (fn) {
    if (this[_prop]) {
      this.removeEventListener(eventName, this[_prop]);
    }

    this[_prop] = fn;

    this.addEventListener(eventName, fn, false);
  };

  desc.get = function () {
    return this[_prop];
  };

  Object.defineProperty(obj, prop, desc);
};

Zone.patchProperties = function (obj) {
  Object.keys(obj).
    filter(function (propertyName) {
      return propertyName.substr(0,2) === 'on';
    }).
    forEach(function (eventName) {
      Zone.patchProperty(obj, eventName);
    });
};

Zone.patchEventTargetMethods = function (obj) {
  var addDelegate = obj.addEventListener;
  obj.addEventListener = function (eventName, fn) {
    arguments[1] = fn._bound = zone.bind(fn);
    return addDelegate.apply(this, arguments);
  };

  var removeDelegate = obj.removeEventListener;
  obj.removeEventListener = function (eventName, fn) {
    arguments[1] = arguments[1]._bound || arguments[1];
    return removeDelegate.apply(this, arguments);
  };
};

Zone.patch = function patch () {
  Zone.patchFn(window, ['setTimeout', 'setInterval']);
  Zone.patchableFn(window, ['alert', 'prompt']);

  // patched properties depend on addEventListener, so this comes first
  // n.b. EventTarget is not available in all browsers so we patch Node here
  Zone.patchEventTargetMethods(Node.prototype);

  Zone.patchProperties(HTMLElement.prototype);
  Zone.patchProperties(XMLHttpRequest.prototype);
};

Zone.init = function init () {
  window.zone = new Zone();
  Zone.patch();
};

Zone.init();
<|endoftext|>


<commit_before>println('It is pitch black. You are likely to be eaten by a Grue.')<commit_msg>Delete zork.js<commit_after><|endoftext|>


<commit_before>b6bd3a38-973a-11e6-b514-8086f2004150<commit_msg>Put the thingie in the thingie<commit_after>b6bdfb4e-973a-11e6-b514-8086f2004150<|endoftext|>


<commit_before>b7087a0c-973a-11e6-b514-8086f2004150<commit_msg>We apologise for the previous fix. Those responsible have been sacked<commit_after>b709123c-973a-11e6-b514-8086f2004150<|endoftext|>


<commit_before>var chug = require('chug');
var figlet = require('figlet');
var pkg = require('./package');
var dir = __dirname;

figlet.text('Jymin v' + pkg.version, {font: 'Standard'}, function (e, art) {

  var pattern = /^.*\/(workspace|node_modules|lighterio)\/([\d\w-_]+)\//i;
  var url = 'https://github.com/lighterio/$2/blob/master/';
  var urls = [];

  // Concatenate and output all non-plugin scripts.
  chug('scripts')
    .each(function (asset) {
      urls.push(asset.location.replace(pattern, url));
    })
    .concat()
    .each(function (asset) {
      asset.setContent(
        "/**" + art.replace(/ +$/, '').replace(/ *\n/g, '\n * ') + "\n" +
        " *\n" +
        " * http://lighter.io/jymin\n" +
        " *\n" +
        " * If you're seeing this in production, you really should minify.\n" +
        " *\n" +
        " * Source files:\n" +
        " *   " + urls.join("\n *   ") + "\n" +
        " */\n\n\n" +
        "var Jymin = {version: '" + pkg.version + "'};\n\n" +
        "//+env:commonjs\n" +
        "// Support CommonJS.\n" +
        "if (typeof exports == 'object') {\n" +
        "  module.exports = Jymin;\n" +
        "}\n" +
        "//-env:commonjs\n\n" +
        "//+env:amd\n" +
        "// Support AMD.\n" +
        "else if (typeof define == 'function' && define.amd) {\n" +
        "  define(function() {\n" +
        "    return Jymin;\n" +
        "  });\n" +
        "}\n" +
        "//-env:amd\n\n" +
        "//+env:window\n" +
        "// Support browsers.\n" +
        "else {\n" +
        "  this.Jymin = Jymin;\n" +
        "}\n" +
        "//-env:window\n\n" +
        asset.getContent());
    })
    .cull('browser', 'ok')
    .write(dir, 'jymin.js')
    .replace(/Jymin\.([$_a-zA-Z0-9]+)(\s*=)?/g, function (match, name, equals) {
      return equals ? 'var ' + name + ' =' : name;
    })
    .cull('env', 'min')
    .wrap()
    .minify()
    .write(dir, 'jymin.min.js', 'minified');
});

function addEval(code) {
  return code.replace(
    /([$_a-z]+) ?= ?JSON\.parse\(([$_a-z]+)\)/i,
    'eval("eval.J="+$2);$1=eval.J');
}
<commit_msg>Fixing build spacing<commit_after>var chug = require('chug');
var figlet = require('figlet');
var pkg = require('./package');
var dir = __dirname;

figlet.text('Jymin v' + pkg.version, {font: 'Standard'}, function (e, art) {

  var pattern = /^.*\/(workspace|node_modules|lighterio)\/([\d\w-_]+)\//i;
  var url = 'https://github.com/lighterio/$2/blob/master/';
  var urls = [];

  // Concatenate and output all non-plugin scripts.
  chug('scripts')
    .each(function (asset) {
      urls.push(asset.location.replace(pattern, url));
    })
    .concat()
    .each(function (asset) {
      asset.setContent(
        "/**" + art.replace(/ +$/, '').replace(/ *\n/g, '\n * ') + "\n" +
        " *\n" +
        " * http://lighter.io/jymin\n" +
        " *\n" +
        " * If you're seeing this in production, you really should minify.\n" +
        " *\n" +
        " * Source files:\n" +
        " *   " + urls.join("\n *   ") + "\n" +
        " */\n\n\n" +
        "var Jymin = {version: '" + pkg.version + "'};\n\n" +
        "//+env:commonjs\n" +
        "// Support CommonJS.\n" +
        "if (typeof exports == 'object') {\n" +
        "  module.exports = Jymin;\n" +
        "}\n" +
        "//-env:commonjs\n\n" +
        "//+env:amd\n" +
        "// Support AMD.\n" +
        "else if (typeof define == 'function' && define.amd) {\n" +
        "  define(function() {\n" +
        "    return Jymin;\n" +
        "  });\n" +
        "}\n" +
        "//-env:amd\n\n" +
        "//+env:window\n" +
        "// Support browsers.\n" +
        "else {\n" +
        "  this.Jymin = Jymin;\n" +
        "}\n" +
        "//-env:window\n\n" +
        asset.getContent());
    })
    .cull('browser', 'ok')
    .replace(/ +\n/g, '\n')
    .write(dir, 'jymin.js')
    .replace(/Jymin\.([$_a-zA-Z0-9]+)(\s*=)?/g, function (match, name, equals) {
      return equals ? 'var ' + name + ' =' : name;
    })
    .cull('env', 'min')
    .replace(/ +\n/g, '\n')
    .wrap()
    .minify()
    .write(dir, 'jymin.min.js', 'minified');
});

function addEval(code) {
  return code.replace(
    /([$_a-z]+) ?= ?JSON\.parse\(([$_a-z]+)\)/i,
    'eval("eval.J="+$2);$1=eval.J');
}
<|endoftext|>


<commit_before>import * as R from 'ramda'
import Bacon from 'baconjs'
import React from 'react'
import Common from './utils/common-util'
import BduxContext from './context'
import { decorators } from './middleware'

const getDisplayName = (Component) => (
  Component.displayName || Component.name || 'Component'
)

const getDispatch = R.pathOr(
  R.F, ['dispatcher', 'dispatchAction']
)

const getBindToDispatch = R.pathOr(
  R.identity, ['dispatcher', 'bindToDispatch']
)

const subscribe = R.curry((component, store, name) => (
  // subscribe to a store.
  store.getProperty(component.props)
    // todo: workaround baconjs v2 bug causing onValue to be not synchronous.
    .doAction(state => {
      const update = {
        // under the name specified.
        [name]: state
      }

      // pass its state update to the react component.
      if (!component.isConstructed) {
        component.state = update;
      } else {
        component.setState(update)
      }
    })
    .onValue()
))

const getProperties = R.uncurryN(2, (component) => R.map(
  R.invoker(1, 'getProperty')(component.props)
))

const triggerCallbacks = (component, stores, callbacks) => (
  Bacon.combineTemplate(
    R.assoc('props', component.props,
      getProperties(component, stores))
  )
  .first()
  .map(R.of)
  .onValue(R.ap(callbacks))
)

const hasFuncs = R.allPass([
  R.is(Array),
  R.complement(R.isEmpty)
])

const pipeFuncs = R.ifElse(
  hasFuncs,
  R.apply(R.pipe),
  R.always(R.F)
)

const removeStores = R.uncurryN(2, (component) => R.forEachObjIndexed((store) => {
  store.removeProperty(component.props)
}))

export const decorateToSubscribeStores = (Component, stores = {}, callbacks = []) => (
  class extends React.Component {
    static displayName = getDisplayName(Component)
    static defaultProps = {}
    state = {}

    /* istanbul ignore next */
    constructor(props) {
      super(props)
      this.subscribeToStores()
      this.isConstructed = true
    }

    componentWillUnmount() {
      this.dispose()
      removeStores(this, stores)
    }

    subscribeToStores() {
      // pipe all dispose functions.
      this.dispose = pipeFuncs(
        // get the array of dispose functions.
        R.values(
          // subscribe to stores.
          R.mapObjIndexed(
            subscribe(this),
            stores)
        )
      )

      // trigger callbacks after subscribing to stores.
      triggerCallbacks(this, stores, callbacks)
    }

    render() {
      const element = React.createElement(
        Component, R.merge(this.props, this.state))

      // assuming server renders only once.
      if (Common.isOnServer()) {
        // unmount after rendering.
        this.componentWillUnmount()
      }

      return element
    }
  }
)

export const decorateToConsumeContext = (Component) => {
  const decorated = (props) => (
    <BduxContext.Consumer>
      {(bdux) => (
        <Component
          {...props}
          bdux={bdux}
          dispatch={getDispatch(bdux)}
          bindToDispatch={getBindToDispatch(bdux)}
        />
      )}
    </BduxContext.Consumer>
  )

  decorated.displayName = getDisplayName(Component)
  decorated.defaultProps = {}
  return decorated
}

const decorateByMiddlewares = (Component) => (
  R.isEmpty(decorators.get())
    ? Component
    : R.apply(R.pipe, decorators.get())(Component)
)

const createComponentImplement = (Component, stores = {}, ...callbacks) => (
  decorateToConsumeContext(
    decorateToSubscribeStores(
      decorateByMiddlewares(Component),
      stores,
      callbacks
    )
  )
)

const createComponentPipe = (stores = {}, ...callbacks) => (Component) => (
  // convenient to pipe decorators.
  createComponentImplement(Component, stores, ...callbacks)
)

export const createComponent = (...args) => (
  // if the first argument is a react component.
  (React.Component.isPrototypeOf(args[0]) || R.is(Function, args[0]))
    ? createComponentImplement(...args)
    : createComponentPipe(...args)
)
<commit_msg>Bind callback actions to dispatch<commit_after>import * as R from 'ramda'
import Bacon from 'baconjs'
import React from 'react'
import Common from './utils/common-util'
import BduxContext from './context'
import { decorators } from './middleware'

const getDisplayName = (Component) => (
  Component.displayName || Component.name || 'Component'
)

const getDispatch = R.pathOr(
  R.F, ['dispatcher', 'dispatchAction']
)

const getBindToDispatch = R.pathOr(
  R.identity, ['dispatcher', 'bindToDispatch']
)

const subscribe = R.curry((component, store, name) => (
  // subscribe to a store.
  store.getProperty(component.props)
    // todo: workaround baconjs v2 bug causing onValue to be not synchronous.
    .doAction(state => {
      const update = {
        // under the name specified.
        [name]: state
      }

      // pass its state update to the react component.
      if (!component.isConstructed) {
        component.state = update;
      } else {
        component.setState(update)
      }
    })
    .onValue()
))

const getProperties = R.uncurryN(2, (component) => R.map(
  R.invoker(1, 'getProperty')(component.props)
))

const triggerCallbacks = (component, stores, callbacks) => (
  Bacon.combineTemplate(
    R.assoc('props', component.props,
      getProperties(component, stores))
  )
  .first()
  .onValue(R.juxt(
    getBindToDispatch(component.props.bdux)(callbacks)
  ))
)

const hasFuncs = R.allPass([
  R.is(Array),
  R.complement(R.isEmpty)
])

const pipeFuncs = R.ifElse(
  hasFuncs,
  R.apply(R.pipe),
  R.always(R.F)
)

const removeStores = R.uncurryN(2, (component) => R.forEachObjIndexed((store) => {
  store.removeProperty(component.props)
}))

export const decorateToSubscribeStores = (Component, stores = {}, callbacks = []) => (
  class extends React.Component {
    static displayName = getDisplayName(Component)
    static defaultProps = {}
    state = {}

    /* istanbul ignore next */
    constructor(props) {
      super(props)
      this.subscribeToStores()
      this.isConstructed = true
    }

    componentWillUnmount() {
      this.dispose()
      removeStores(this, stores)
    }

    subscribeToStores() {
      // pipe all dispose functions.
      this.dispose = pipeFuncs(
        // get the array of dispose functions.
        R.values(
          // subscribe to stores.
          R.mapObjIndexed(
            subscribe(this),
            stores)
        )
      )

      // trigger callbacks after subscribing to stores.
      triggerCallbacks(this, stores, callbacks)
    }

    render() {
      const element = React.createElement(
        Component, R.merge(this.props, this.state))

      // assuming server renders only once.
      if (Common.isOnServer()) {
        // unmount after rendering.
        this.componentWillUnmount()
      }

      return element
    }
  }
)

export const decorateToConsumeContext = (Component) => {
  const decorated = (props) => (
    <BduxContext.Consumer>
      {(bdux) => (
        <Component
          {...props}
          bdux={bdux}
          dispatch={getDispatch(bdux)}
          bindToDispatch={getBindToDispatch(bdux)}
        />
      )}
    </BduxContext.Consumer>
  )

  decorated.displayName = getDisplayName(Component)
  decorated.defaultProps = {}
  return decorated
}

const decorateByMiddlewares = (Component) => (
  R.isEmpty(decorators.get())
    ? Component
    : R.apply(R.pipe, decorators.get())(Component)
)

const createComponentImplement = (Component, stores = {}, ...callbacks) => (
  decorateToConsumeContext(
    decorateToSubscribeStores(
      decorateByMiddlewares(Component),
      stores,
      callbacks
    )
  )
)

const createComponentPipe = (stores = {}, ...callbacks) => (Component) => (
  // convenient to pipe decorators.
  createComponentImplement(Component, stores, ...callbacks)
)

export const createComponent = (...args) => (
  // if the first argument is a react component.
  (React.Component.isPrototypeOf(args[0]) || R.is(Function, args[0]))
    ? createComponentImplement(...args)
    : createComponentPipe(...args)
)
<|endoftext|>


<commit_before>/*
Copyright [2014] [Graham Abbott <graham.abbott@gmail.com>]

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

/* Example Component

		<template type='text/template' id='root'>

		    [% if v.ticks == 1 %]
		      [[v.ticks]] second has passed.
		    [% else %]
		      [[v.ticks]] seconds have passed.
		    [% end %]

		</template>

*/

var mvc = (function() {
    var safe_append_to_key = function(list, key, value) {
        if (list[key] == undefined) {
            list[key] = [value];
        } else {
            list[key].push(value);
        }
        return list;
    };

    var formap = function(fun, dict) {
        for (var key in dict) {
            if (dict.hasOwnProperty(key)) {
                fun(key, dict[key]);
            }
        }
    };

    var startswith = function(first, second) {
        return first.slice(0, second.length) == second;
    };

    var ResourceTracker = function() {
        this.loaded_resources = {};
    };

    var Component = Class({
        initialize: function(state) {
            this.__data__ = {};
            this.__data__.event_listeners = {};
            this.__data__.state = state || {};
        },

        get: function(key) {
            return this.__data__.state[key];
        },

        set: function(key, value) {
            this.fire('state_will_change', {'key':key});
            this.__data__.state[key] = value;
            this.fire('state_did_change', {'key':key});
        },

        require_vars: function(l) {
            var hit = false;
            for(var i=0; i < l.length; i++) {
                if (this.get(l[i]) == undefined) {
                    console.log("MISSING VAR: " + l[i]);
                    hit = true;
                }
            }
            if (hit) {
                return false;
            } else {
                return true;
            }
        },

        on: function(type, callback) {
            safe_append_to_key(this.__data__.event_listeners, type, callback);
        },

        once: function(type, callback) {
            var comp = this;
            var inside = function() {
                callback(arguments);
                comp.off(type, inside);
            };
            safe_append_to_key(this.__data__.event_listeners, type, inside);
        },

        off: function(key, cb) {
            if (cb == undefined) {
                delete this.__data__.event_listeners[key];
            } else {
                var dict = this.__data__.event_listeners;
                if (key == null) {
                    for (var k in dict) {
                        if (dict.hasOwnProperty(k)) {
                            var len = dict[k].length;
                            var index = dict[k].indexOf(cb);
                            if (index != -1) {
                                dict[k] = dict[k].slice(0, index).concat(dict[k].slice(index+1, len));
                            }

                        }
                    }
                } else {
                    if (dict[key] !== undefined) {
                        var len = dict[key].length
                        var index = dict[key].indexOf(cb);
                        if (index != -1) {
                            dict[key] = dict[key].slice(0, index).concat(dict[key].slice(index+1, len));
                        }
                    }
                }
                this.__data__.event_listeners = dict;
            }
        },

        fire: function(type, args) {
            if (args == undefined) {
                args = {};
            }

            var target = this.__data__.event_listeners[type];

            if (target !== undefined) {
                for(var i=0; i < target.length; i++) {
                    var cb = target[i];
                    try {
                        cb.apply(this, args);
                    } catch (e) {
                        console.log(e.message);
                        console.log(e.stack);
                        console.log("error for event '" + type + "' -> ");
                        console.log(cb);
                    }
                }
                return true;
            } else {
                return false;
            }
        },

        delay_fire: function(key, delay) {
            if (delay == undefined) {
                delay = 1;
            }
            setTimeout((function(t, k) { return (function() { t.fire(k); }); })(this,key), delay);
        },

        wait: function(cb, ts) {
            setTimeout((function(t,c) { return (function() { c.apply(t, []); }); })(this,cb), ts);
        }
    });

    var GCComponent = Class(Component, {
        initialize: function(props) {
            var url = props['url'];
            var target = props['target'];
            var state = props['state'] || {};
            var smart_load = props['smart_load'] || false;

            this.$super('initialize', state);
            this.__data__.resources = [];
            this.__data__.env = new genie.Environment();

            if (target) {
                this.set_target(target);
            }

            var cache_name = 'gc_component_cache_' + url;

            if (smart_load && (localStorage.getItem(cache_name) !== null)) {
                console.log('cache hit: ' + url);
                this.load_from_content(localStorage.getItem(cache_name));
            } else {
                console.log('loading url: ' + url);
                var comp = this;
                $.get(url, function(data) {
                    if (smart_load) {
                        localStorage.setItem(cache_name, data);
                    }
                    comp.load_from_content(data);
                });
            }
        },

        load_from_content: function(data) {
            var comp = this;
            var scripts = [];

            var d = document.createElement('div');
            d.innerHTML = data;
            for(var i=0; i < d.children.length; i++) {
                var child = d.children[i];
                if (child.tagName == "STYLE" || child.tagName == "LINK") {
                    comp.__data__.resources.push(child);
                } else if (child.tagName == "SCRIPT") {
                    if (child.src) {
                        comp.__data__.resources.push(child);
                    } else {
                        var new_script = "(function(component) { " + child.innerHTML + " })";
                        scripts.push(new_script);
                    }
                } else if (child.tagName == "TEMPLATE") {
                    if (!child.id) {
                        console.log("No id for template, Ill call it root and hope.");
                        child.id = 'root';
                    }
                    comp.__data__.env.create_template(child.id, child.innerHTML);
                } else {
                    console.log("Unsupported node '" + child.tagName + "'in Component: " + url);
                }
            }

            for(var i=0; i < scripts.length; i++) {
                eval(scripts[i])(comp);
            }
            comp.delay_fire('ready');
        },

        /* I need to make sure that i'm getting the basic dom object */
        set_target: function(target) {
            if (target.jquery) {
                this._target = target[0];
            } else {
                this._target = target;
            }
        },

        load: function() {
            for(var i=0; i < this.__data__.resources.length; i++) {
                var obj = this.__data__.resources[i];
                if (obj.tagName == 'SCRIPT') {
                    var d = document.createElement('script');
                    d.src = obj.src;
                    document.head.appendChild(d);
                } else {
                    document.head.appendChild(obj);
                }
            }
            var target = this._target;
            var content = this.__data__.env.render('root', this.__data__.state);
            target.innerHTML = content;
            this.delay_fire('did_load');
        },

        reload: function() {
            var target = this._target;
            var content = this.__data__.env.render('root', this.__data__.state);
            target.innerHTML = content;
            this.fire('did_reload');
        },

        render: function(template_name, d) {
            var y = {
                'component':this
            };

            formap(function(k, v) {
                y[k] = v;
            }, this.__data__.state);

            if (d) {
                formap(function(k, v) {
                    y[k] = v;
                }, d);
            }

            var content = this.__data__.env.render(template_name, y);
            return content;
        }
    });

    // a helper function to clear the cache of templates.
    var clear_gc_cache = function() {
        var prefix = 'gc_component_cache_';
        formap(function(key, value) {
            if (startswith(key, prefix)) {
                localStorage.removeItem(key);
            }
        }, localStorage);
    };

    return {
        "Component":     Component,
        "GCComponent":   GCComponent,
        "clear_cache":   clear_gc_cache
    };
})();

if (typeof module !== 'undefined') {
    module.exports.mvc = mvc;
    module.exports.Component = mvc.Component;
    module.exports.GCComponent = mvc.GCComponent;
}
<commit_msg>last commit<commit_after>/*
Copyright [2014] [Graham Abbott <graham.abbott@gmail.com>]

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

/* Example Component

		<template type='text/template' id='root'>

		    [% if v.ticks == 1 %]
		      [[v.ticks]] second has passed.
		    [% else %]
		      [[v.ticks]] seconds have passed.
		    [% end %]

		</template>

*/

var mvc = (function() {
    var safe_append_to_key = function(list, key, value) {
        if (list[key] == undefined) {
            list[key] = [value];
        } else {
            list[key].push(value);
        }
        return list;
    };

    var formap = function(fun, dict) {
        for (var key in dict) {
            if (dict.hasOwnProperty(key)) {
                fun(key, dict[key]);
            }
        }
    };

    var startswith = function(first, second) {
        return first.slice(0, second.length) == second;
    };

    var ResourceTracker = function() {
        this.loaded_resources = {};
    };

    ResourceTracker.prototype.load_resource = function(type, resource) {
    };

    var Component = Class({
        initialize: function(state) {
            this.__data__ = {};
            this.__data__.event_listeners = {};
            this.__data__.state = state || {};
        },

        get: function(key) {
            return this.__data__.state[key];
        },

        set: function(key, value) {
            this.fire('state_will_change', {'key':key});
            this.__data__.state[key] = value;
            this.fire('state_did_change', {'key':key});
        },

        require_vars: function(l) {
            var hit = false;
            for(var i=0; i < l.length; i++) {
                if (this.get(l[i]) == undefined) {
                    console.log("MISSING VAR: " + l[i]);
                    hit = true;
                }
            }
            if (hit) {
                return false;
            } else {
                return true;
            }
        },

        on: function(type, callback) {
            safe_append_to_key(this.__data__.event_listeners, type, callback);
        },

        once: function(type, callback) {
            var comp = this;
            var inside = function() {
                callback(arguments);
                comp.off(type, inside);
            };
            safe_append_to_key(this.__data__.event_listeners, type, inside);
        },

        off: function(key, cb) {
            if (cb == undefined) {
                delete this.__data__.event_listeners[key];
            } else {
                var dict = this.__data__.event_listeners;
                if (key == null) {
                    for (var k in dict) {
                        if (dict.hasOwnProperty(k)) {
                            var len = dict[k].length;
                            var index = dict[k].indexOf(cb);
                            if (index != -1) {
                                dict[k] = dict[k].slice(0, index).concat(dict[k].slice(index+1, len));
                            }

                        }
                    }
                } else {
                    if (dict[key] !== undefined) {
                        var len = dict[key].length
                        var index = dict[key].indexOf(cb);
                        if (index != -1) {
                            dict[key] = dict[key].slice(0, index).concat(dict[key].slice(index+1, len));
                        }
                    }
                }
                this.__data__.event_listeners = dict;
            }
        },

        fire: function(type, args) {
            if (args == undefined) {
                args = {};
            }

            var target = this.__data__.event_listeners[type];

            if (target !== undefined) {
                for(var i=0; i < target.length; i++) {
                    var cb = target[i];
                    try {
                        cb.apply(this, args);
                    } catch (e) {
                        console.log(e.message);
                        console.log(e.stack);
                        console.log("error for event '" + type + "' -> ");
                        console.log(cb);
                    }
                }
                return true;
            } else {
                return false;
            }
        },

        delay_fire: function(key, delay) {
            if (delay == undefined) {
                delay = 1;
            }
            setTimeout((function(t, k) { return (function() { t.fire(k); }); })(this,key), delay);
        },

        wait: function(cb, ts) {
            setTimeout((function(t,c) { return (function() { c.apply(t, []); }); })(this,cb), ts);
        }
    });

    var GCComponent = Class(Component, {
        initialize: function(props) {
            var url = props['url'];
            var target = props['target'];
            var state = props['state'] || {};
            var smart_load = props['smart_load'] || false;

            this.$super('initialize', state);
            this.__data__.resources = [];
            this.__data__.env = new genie.Environment();

            if (target) {
                this.set_target(target);
            }

            var cache_name = 'gc_component_cache_' + url;

            if (smart_load && (localStorage.getItem(cache_name) !== null)) {
                console.log('cache hit: ' + url);
                this.load_from_content(localStorage.getItem(cache_name));
            } else {
                console.log('loading url: ' + url);
                var comp = this;
                $.get(url, function(data) {
                    if (smart_load) {
                        localStorage.setItem(cache_name, data);
                    }
                    comp.load_from_content(data);
                });
            }
        },

        load_from_content: function(data) {
            var comp = this;
            var scripts = [];

            var d = document.createElement('div');
            d.innerHTML = data;
            for(var i=0; i < d.children.length; i++) {
                var child = d.children[i];
                if (child.tagName == "STYLE" || child.tagName == "LINK") {
                    comp.__data__.resources.push(child);
                } else if (child.tagName == "SCRIPT") {
                    if (child.src) {
                        comp.__data__.resources.push(child);
                    } else {
                        var new_script = "(function(component) { " + child.innerHTML + " })";
                        scripts.push(new_script);
                    }
                } else if (child.tagName == "TEMPLATE") {
                    if (!child.id) {
                        console.log("No id for template, Ill call it root and hope.");
                        child.id = 'root';
                    }
                    comp.__data__.env.create_template(child.id, child.innerHTML);
                } else {
                    console.log("Unsupported node '" + child.tagName + "'in Component: " + url);
                }
            }

            for(var i=0; i < scripts.length; i++) {
                eval(scripts[i])(comp);
            }
            comp.delay_fire('ready');
        },

        /* I need to make sure that i'm getting the basic dom object */
        set_target: function(target) {
            if (target.jquery) {
                this._target = target[0];
            } else {
                this._target = target;
            }
        },

        load: function() {
            for(var i=0; i < this.__data__.resources.length; i++) {
                var obj = this.__data__.resources[i];
                if (obj.tagName == 'SCRIPT') {
                    var d = document.createElement('script');
                    d.src = obj.src;
                    document.head.appendChild(d);
                } else {
                    document.head.appendChild(obj);
                }
            }
            var target = this._target;
            var content = this.__data__.env.render('root', this.__data__.state);
            target.innerHTML = content;
            this.delay_fire('did_load');
        },

        reload: function() {
            var target = this._target;
            var content = this.__data__.env.render('root', this.__data__.state);
            target.innerHTML = content;
            this.fire('did_reload');
        },

        render: function(template_name, d) {
            var y = {
                'component':this
            };

            formap(function(k, v) {
                y[k] = v;
            }, this.__data__.state);

            if (d) {
                formap(function(k, v) {
                    y[k] = v;
                }, d);
            }

            var content = this.__data__.env.render(template_name, y);
            return content;
        }
    });

    // a helper function to clear the cache of templates.
    var clear_gc_cache = function() {
        var prefix = 'gc_component_cache_';
        formap(function(key, value) {
            if (startswith(key, prefix)) {
                localStorage.removeItem(key);
            }
        }, localStorage);
    };

    return {
        "Component":     Component,
        "GCComponent":   GCComponent,
        "clear_cache":   clear_gc_cache
    };
})();

if (typeof module !== 'undefined') {
    module.exports.mvc = mvc;
    module.exports.Component = mvc.Component;
    module.exports.GCComponent = mvc.GCComponent;
}
<|endoftext|>


<commit_before>/**
 * Author: krasu
 * Date: 9/17/13
 * Time: 8:39 AM
 */
define(function (require) {
	require('backbone')
	var store = require('store').getNamespace('repo-selector')

	return Backbone.Router.extend({
		initialize: function () {
			if (!localStorage) return
			var lastUrl = localStorage.getItem('supporters-last-url')
			if (lastUrl != location.hash) location.hash = lastUrl
		},
		routes: {
			'type/:type/id/:id': 'switchType',
			'type/:type/id/:id/tab/:tab': 'switchType',
			'*actions': 'switchType'
		},
		switchType: function (type, id, tab) {
			if (!store().currentType.type || type != store().currentType.type || id != store().currentType.id) {
				store().currentType = {
					type: type || 'user',
					id: id || currentUserId
				}

				store().selected.fetch()
			}

			localStorage && localStorage.setItem('supporters-last-url', location.hash)
			this.selectTab(tab)
		},
		selectTab: function () {
			var tab = Array.prototype.pop.call(arguments)
			tab = tab || 'selected-repos'
			var el = store().layout.$('.nav .tab[href="#' + tab + '"]')
			el.tab('show')
		}
	});
})
<commit_msg>fixed supporters null type<commit_after>/**
 * Author: krasu
 * Date: 9/17/13
 * Time: 8:39 AM
 */
define(function (require) {
	require('backbone')
	var store = require('store').getNamespace('repo-selector')

	return Backbone.Router.extend({
		initialize: function () {
			if (!localStorage) return
			var lastUrl = localStorage.getItem('supporters-last-url')
			if (lastUrl && lastUrl != location.hash) location.hash = lastUrl
		},
		routes: {
			'type/:type/id/:id': 'switchType',
			'type/:type/id/:id/tab/:tab': 'switchType',
			'*actions': 'switchType'
		},
		switchType: function (type, id, tab) {
			if (_.indexOf(['user', 'project', 'organization'], type) == -1) {
				type = store().currentType.type
				id = store().currentType.id
			}

			if (!store().currentType.type || type != store().currentType.type || id != store().currentType.id) {
				store().currentType = {
					type: type || 'user',
					id: id || currentUserId
				}

				store().selected.fetch()
			}

			localStorage && localStorage.setItem('supporters-last-url', location.hash)
			this.selectTab(tab)
		},
		selectTab: function () {
			var tab = Array.prototype.pop.call(arguments)
			tab = tab || 'selected-repos'
			var el = store().layout.$('.nav .tab[href="#' + tab + '"]')
			el.tab('show')
		}
	});
})
<|endoftext|>


<commit_before>define([
	"dojo/_base/declare", "dojo/on", "dojo/dom-construct",
	"dojo/_base/lang", "dojo/mouse",
	"dojo/topic", "dojo/query", "dijit/layout/ContentPane",
	"dijit/Dialog", "dijit/popup", "dijit/TooltipDialog",
	"./AdvancedDownload", "dojo/dom-class"
], function(declare, on, domConstruct,
			lang, Mouse,
			Topic, query, ContentPane,
			Dialog, popup, TooltipDialog,
			AdvancedDownload, domClass){

	return declare([TooltipDialog], {
		perspective: "Genome",
		perspectiveUrl: "",
		selection: null,
		label: "",
		subsections: {
			"Genome": [
				{label: "Overview", link: "overview"},
				{label: "Phylogeny", link: "phylogeny"},
				{label: "Browser", link: "browser"},
				{label: "Circular Viewer", link: "circular"},
				{label: "Sequences", link: "sequences"},
				{label: "Features", link: "features"},
				{label: "Specialty Genes", link: "specialtyGenes"},
				{label: "Protein Families", link: "proteinFamilies"},
				{label: "Pathways", link: "pathways"},
				{label: "Transcriptomics", link: "transcriptomics"}
			],
			"GenomeList": [
				{label: "Overview", link: "overview"},
				{label: "Genomes", link: "genomes"},
				{label: "Sequences", link: "sequences"},
				{label: "Features", link: "features"},
				{label: "Specialty Genes", link: "specialtyGenes"},
				{label: "Protein Families", link: "proteinFamilies"},
				{label: "Pathways", link: "pathways"},
				{label: "Transcriptomics", link: "transcriptomics"}
			],
			"GenomeGroup": [
				{label: "Overview", link: "overview"},
				{label: "Genomes", link: "genomes"},
				{label: "Sequences", link: "sequences"},
				{label: "Features", link: "features"},
				{label: "Specialty Genes", link: "specialtyGenes"},
				{label: "Protein Families", link: "proteinFamilies"},
				{label: "Pathways", link: "pathways"},
				{label: "Transcriptomics", link: "transcriptomics"}
			],
			"Taxonomy": [
				{label: "Overview", link: "overview"},
				{label: "Phylogeny", link: "phylogeny"},
				{label: "Taxonomy", link: "taxontree"},
				{label: "Genomes", link: "genomes"},
				{label: "Sequences", link: "sequences"},
				{label: "Features", link: "features"},
				{label: "Specialty Genes", link: "specialtyGenes"},
				{label: "Protein Families", link: "proteinFamilies"},
				{label: "Pathways", link: "pathways"},
				{label: "Transcriptomics", link: "transcriptomics"}
			],
			"Feature": [
				{label: "Overview", link: "overview"},
				{label: "Genome Browser", link: "genomeBrowser"},
				{label: "Compare Region Viewer", link: "compareRegionViewer"},
				{label: "Transcriptomics", link: "transcriptomics"},
				{label: "Correlated Genes", link: "correlatedGenes"},
				{label: "Interactions", link: "interactions"}
			],
			"FeatureList": [
				{label: "Overview", link: "overview"},
				{label: "Features", link: "features"}
			]
		},

		_setSelectionAttr: function(val){
			// console.log("DownloadTooltipDialog set selection: ", val);
			this.selection = val;
		},
		timeout: function(val){
			var _self = this;
			this._timer = setTimeout(function(){
				popup.close(_self);
			}, val || 2500);
		},

		onMouseEnter: function(){
			if(this._timer){
				clearTimeout(this._timer);
			}

			this.inherited(arguments);
		},
		onMouseLeave: function(){
			popup.close(this);
		},

		startup: function(){
			if(this._started){
				return;
			}
			on(this.domNode, Mouse.enter, lang.hitch(this, "onMouseEnter"));
			on(this.domNode, Mouse.leave, lang.hitch(this, "onMouseLeave"));
			var _self = this;
			on(this.domNode, ".wsActionTooltip:click", function(evt){
				// console.log("evt.target: ", evt.target, evt.target.attributes);
				var rel = evt.target.attributes.rel.value;

			});

			var dstContent = domConstruct.create("div", {});
			this.labelNode = domConstruct.create("div", {style: "background:#09456f;color:#fff;margin:0px;margin-bottom:4px;padding:4px;text-align:center;"}, dstContent);
			this.selectedCount = domConstruct.create("div", {}, dstContent);

			var subs = this.subsections[this.perspective];

			subs.forEach(function(sub){
				var d = domConstruct.create("div",{}, dstContent);
				domConstruct.create("a",{"class": "navigationLink", innerHTML: sub.label, href: this.perspectiveUrl + "#view_tab=" + sub.link},d);
			},this);

			this.set("content", dstContent);

			this._started = true;
			this.set("label", this.label || "Switch to " + this.perspective + " View");
			this.set("selection", this.selection);

		},

		_setLabelAttr: function(val){
			this.label = val;
			if(this._started){
				this.labelNode.innerHTML = val;
			}
		}
	});

});
<commit_msg>add genotypes<commit_after>define([
	"dojo/_base/declare", "dojo/on", "dojo/dom-construct",
	"dojo/_base/lang", "dojo/mouse",
	"dojo/topic", "dojo/query", "dijit/layout/ContentPane",
	"dijit/Dialog", "dijit/popup", "dijit/TooltipDialog",
	"./AdvancedDownload", "dojo/dom-class"
], function(declare, on, domConstruct,
			lang, Mouse,
			Topic, query, ContentPane,
			Dialog, popup, TooltipDialog,
			AdvancedDownload, domClass){

	return declare([TooltipDialog], {
		perspective: "Genome",
		perspectiveUrl: "",
		selection: null,
		label: "",
		subsections: {
			"Genome": [
				{label: "Overview", link: "overview"},
				{label: "AMR Phenotypes", link: "amr"},
				{label: "Phylogeny", link: "phylogeny"},
				{label: "Genome Browser", link: "browser"},
				{label: "Circular Viewer", link: "circular"},
				{label: "Sequences", link: "sequences"},
				{label: "Features", link: "features"},
				{label: "Specialty Genes", link: "specialtyGenes"},
				{label: "Protein Families", link: "proteinFamilies"},
				{label: "Pathways", link: "pathways"},
				{label: "Transcriptomics", link: "transcriptomics"},
				{label: "Interactions", link: "interactions"}
			],
			"GenomeList": [
				{label: "Overview", link: "overview"},
				{label: "Genomes", link: "genomes"},
				{label: "Sequences", link: "sequences"},
				{label: "Features", link: "features"},
				{label: "Specialty Genes", link: "specialtyGenes"},
				{label: "Protein Families", link: "proteinFamilies"},
				{label: "Pathways", link: "pathways"},
				{label: "Transcriptomics", link: "transcriptomics"}
			],
			"GenomeGroup": [
				{label: "Overview", link: "overview"},
				{label: "Genomes", link: "genomes"},
				{label: "Sequences", link: "sequences"},
				{label: "Features", link: "features"},
				{label: "Specialty Genes", link: "specialtyGenes"},
				{label: "Protein Families", link: "proteinFamilies"},
				{label: "Pathways", link: "pathways"},
				{label: "Transcriptomics", link: "transcriptomics"}
			],
			"Taxonomy": [
				{label: "Overview", link: "overview"},
				{label: "Phylogeny", link: "phylogeny"},
				{label: "Taxonomy", link: "taxontree"},
				{label: "Genomes", link: "genomes"},
				{label: "Sequences", link: "sequences"},
				{label: "Features", link: "features"},
				{label: "Specialty Genes", link: "specialtyGenes"},
				{label: "Protein Families", link: "proteinFamilies"},
				{label: "Pathways", link: "pathways"},
				{label: "Transcriptomics", link: "transcriptomics"}
			],
			"Feature": [
				{label: "Overview", link: "overview"},
				{label: "Genome Browser", link: "genomeBrowser"},
				{label: "Compare Region Viewer", link: "compareRegionViewer"},
				{label: "Transcriptomics", link: "transcriptomics"},
				{label: "Correlated Genes", link: "correlatedGenes"},
				{label: "Interactions", link: "interactions"}
			],
			"FeatureList": [
				{label: "Overview", link: "overview"},
				{label: "Features", link: "features"}
			]
		},

		_setSelectionAttr: function(val){
			// console.log("DownloadTooltipDialog set selection: ", val);
			this.selection = val;
		},
		timeout: function(val){
			var _self = this;
			this._timer = setTimeout(function(){
				popup.close(_self);
			}, val || 2500);
		},

		onMouseEnter: function(){
			if(this._timer){
				clearTimeout(this._timer);
			}

			this.inherited(arguments);
		},
		onMouseLeave: function(){
			popup.close(this);
		},

		startup: function(){
			if(this._started){
				return;
			}
			on(this.domNode, Mouse.enter, lang.hitch(this, "onMouseEnter"));
			on(this.domNode, Mouse.leave, lang.hitch(this, "onMouseLeave"));
			var _self = this;
			on(this.domNode, ".wsActionTooltip:click", function(evt){
				// console.log("evt.target: ", evt.target, evt.target.attributes);
				var rel = evt.target.attributes.rel.value;

			});

			var dstContent = domConstruct.create("div", {});
			this.labelNode = domConstruct.create("div", {style: "background:#09456f;color:#fff;margin:0px;margin-bottom:4px;padding:4px;text-align:center;"}, dstContent);
			this.selectedCount = domConstruct.create("div", {}, dstContent);

			var subs = this.subsections[this.perspective];

			subs.forEach(function(sub){
				var d = domConstruct.create("div",{}, dstContent);
				domConstruct.create("a",{"class": "navigationLink", innerHTML: sub.label, href: this.perspectiveUrl + "#view_tab=" + sub.link},d);
			},this);

			this.set("content", dstContent);

			this._started = true;
			this.set("label", this.label || "Switch to " + this.perspective + " View");
			this.set("selection", this.selection);

		},

		_setLabelAttr: function(val){
			this.label = val;
			if(this._started){
				this.labelNode.innerHTML = val;
			}
		}
	});

});
<|endoftext|>