<commit_before>var window = this;
var Array = window.Array;
var setTimeout = window.setTimeout;
var Function = window.Function;
var console = window.console;
var Error = window.Error;
if (window.Promise) {
    var Promise = window.Promise;
} else {
    var isPromise = function (pendding) {
        return pendding instanceof Promise || pendding.then instanceof Function && pendding.catch instanceof Function;
    };

    function concat(threads, f, oks, ohs) {
        var _oked, _ohed, _ok, _oh, removeed;
        var runable = function (ok, oh) {
            if (_oked) {
                ok.apply(null, _oked);
            } else if (_ohed) {
                oh.apply(null, _ohed);
            } else {
                _ok = ok;
                _oh = oh;
            }
        };
        var _promise = new Promise(runable);
        var onpermit = function () {
            if (!removeed) {
                try {
                    var pendding = f.apply(null, arguments);
                    if (_ok) _ok(pendding);
                    else _oked = [pendding];
                } catch (e) {
                    if (_oh) _oh(e);
                    else _ohed = [e];
                }
                removeed = true;
            }
        };
        var onresolve = function () {
            if (!removeed) {
                if (_ok) _ok.apply(null, arguments);
                else _oked = arguments;
                removeed = true;
            }
        };
        var onreject = function () {
            if (!removeed) {
                if (_oh) _oh.apply(null, arguments);
                else _ohed = arguments;
                removeed = true;
            }
        };
        threads.push(onpermit);
        oks.push(onresolve);
        ohs.push(onreject);
        return _promise;
    }

    function Promise(executor) {
        var PromiseFulfillReactions = this.PromiseFulfillReactions = [], //thens
            PromiseRejectReactions = this.PromiseRejectReactions = [], //catches
            oked = this.oked, ohed = this.ohed, resolved;

        var ResolvingFunctions_resolve = (result) => { //ok
            if (isPromise(result)) {
                result.then(ResolvingFunctions_resolve).catch(ResolvingFunctions_reject);
            } else {
                oked = this.oked = arguments;
                this.run(PromiseFulfillReactions, oked);
            }
        }

        var ResolvingFunctions_reject = (e) => { //oh
            ohed = this.ohed = arguments;
            this.run(PromiseRejectReactions, ohed);
        }

        setTimeout(function () {
            try {
                executor(ResolvingFunctions_resolve, ResolvingFunctions_reject);
            } catch (e) {
                ResolvingFunctions_reject(e);
            }
        }, 0);
    }
    Promise.prototype = {
        then(f) {
            var _promise = concat(this.PromiseFulfillReactions, f, this.PromiseFulfillReactions, this.PromiseRejectReactions);
            this.oked && this.run(this.PromiseFulfillReactions, this.oked);
            this.ohed && this.run(this.PromiseRejectReactions, this.ohed);
            return _promise;
        },
        catch(f) {
            var _promise = concat(this.PromiseRejectReactions, f, this.PromiseFulfillReactions, this.PromiseRejectReactions);
            this.ohed && this.run(this.PromiseRejectReactions, this.ohed);
            this.oked && this.run(this.PromiseFulfillReactions, this.oked);
            return _promise;
        },
        run(threads, args) {
            do {
                var next = threads.shift();
                if (next instanceof Function) {
                    next.apply(null, args);
                }
            } while (threads.length);
            this.PromiseRejectReactions.splice(0);
            this.PromiseFulfillReactions.splice(0);
        }
    }
    Promise.all = function (penddings) {
        return new Promise(function (ok, oh) {
            if (!(penddings && penddings.length)) {
                return ok();
            }
            try {
                var resolved_count = 0,
                    rejected_count = 0,
                    results = Array(penddings.length);
                for (var cx = 0, dx = penddings.length; cx < dx; cx++) {
                    var pendding = penddings[cx];
                    if (isPromise(pendding)) {
                        pendding.then(function (cx) {
                            return function (arg) {
                                results[cx] = arg;
                                if (++resolved_count === dx) {
                                    ok(results);
                                }
                            };
                        }(cx));
                        pendding.catch(function (e) {
                            if (rejected_count++ === 0) {
                                oh(e);
                            }
                        });
                    } else {
                        results[cx] = pendding;
                        if (++resolved_count === dx) {
                            ok(results);
                        }
                    };
                }
            } catch (e) {
                oh(e);
            }
        });
    };
    Promise.race = function (penddings) {
        return new Promise(function (ok, oh) {
            try {
                var resolved_count = 0,
                    rejected_count = 0,
                    results = Array(penddings.length);
                for (var cx = 0, dx = penddings.length; cx < dx; cx++) {
                    var pendding = penddings[cx];
                    if (isPromise(pendding)) {
                        pendding.then(function (cx) {
                            return function (arg) {
                                if (++resolved_count === 0) {
                                    ok(arg);
                                }
                            };
                        }(cx)).catch(function (e) {
                            if (rejected_count++ === dx) {
                                oh(e);
                            }
                        });
                    } else {
                        results[cx] = pendding;
                    };
                }
            } catch (e) {
                oh(e);
            }
        });
    };
    Promise.reject = function (error) {
        return new Promise(function (ok, oh) {
            oh(error);
        });
    };
    Promise.resolve = function () {
        var args = arguments;
        return new Promise(function (ok, oh) {
            ok.apply(null, args);
        });
    };
}
<commit_msg>使用isFunction代替instanceof Function<commit_after>var window = this;
var Array = window.Array;
var setTimeout = window.setTimeout;
var Function = window.Function;
var console = window.console;
var Error = window.Error;
if (window.Promise) {
    var Promise = window.Promise;
} else {
    var isPromise = function (pendding) {
        return pendding instanceof Promise || isFunction(pendding.then) && isFunction(pendding.catch);
    };

    function concat(threads, f, oks, ohs) {
        var _oked, _ohed, _ok, _oh, removeed;
        var runable = function (ok, oh) {
            if (_oked) {
                ok.apply(null, _oked);
            } else if (_ohed) {
                oh.apply(null, _ohed);
            } else {
                _ok = ok;
                _oh = oh;
            }
        };
        var _promise = new Promise(runable);
        var onpermit = function () {
            if (!removeed) {
                try {
                    var pendding = f.apply(null, arguments);
                    if (_ok) _ok(pendding);
                    else _oked = [pendding];
                } catch (e) {
                    if (_oh) _oh(e);
                    else _ohed = [e];
                }
                removeed = true;
            }
        };
        var onresolve = function () {
            if (!removeed) {
                if (_ok) _ok.apply(null, arguments);
                else _oked = arguments;
                removeed = true;
            }
        };
        var onreject = function () {
            if (!removeed) {
                if (_oh) _oh.apply(null, arguments);
                else _ohed = arguments;
                removeed = true;
            }
        };
        threads.push(onpermit);
        oks.push(onresolve);
        ohs.push(onreject);
        return _promise;
    }

    function Promise(executor) {
        var PromiseFulfillReactions = this.PromiseFulfillReactions = [], //thens
            PromiseRejectReactions = this.PromiseRejectReactions = [], //catches
            oked = this.oked, ohed = this.ohed, resolved;

        var ResolvingFunctions_resolve = (result) => { //ok
            if (isPromise(result)) {
                result.then(ResolvingFunctions_resolve).catch(ResolvingFunctions_reject);
            } else {
                oked = this.oked = arguments;
                this.run(PromiseFulfillReactions, oked);
            }
        }

        var ResolvingFunctions_reject = (e) => { //oh
            ohed = this.ohed = arguments;
            this.run(PromiseRejectReactions, ohed);
        }

        setTimeout(function () {
            try {
                executor(ResolvingFunctions_resolve, ResolvingFunctions_reject);
            } catch (e) {
                ResolvingFunctions_reject(e);
            }
        }, 0);
    }
    Promise.prototype = {
        then(f) {
            var _promise = concat(this.PromiseFulfillReactions, f, this.PromiseFulfillReactions, this.PromiseRejectReactions);
            this.oked && this.run(this.PromiseFulfillReactions, this.oked);
            this.ohed && this.run(this.PromiseRejectReactions, this.ohed);
            return _promise;
        },
        catch(f) {
            var _promise = concat(this.PromiseRejectReactions, f, this.PromiseFulfillReactions, this.PromiseRejectReactions);
            this.ohed && this.run(this.PromiseRejectReactions, this.ohed);
            this.oked && this.run(this.PromiseFulfillReactions, this.oked);
            return _promise;
        },
        run(threads, args) {
            do {
                var next = threads.shift();
                if (next instanceof Function) {
                    next.apply(null, args);
                }
            } while (threads.length);
            this.PromiseRejectReactions.splice(0);
            this.PromiseFulfillReactions.splice(0);
        }
    }
    Promise.all = function (penddings) {
        return new Promise(function (ok, oh) {
            if (!(penddings && penddings.length)) {
                return ok();
            }
            try {
                var resolved_count = 0,
                    rejected_count = 0,
                    results = Array(penddings.length);
                for (var cx = 0, dx = penddings.length; cx < dx; cx++) {
                    var pendding = penddings[cx];
                    if (isPromise(pendding)) {
                        pendding.then(function (cx) {
                            return function (arg) {
                                results[cx] = arg;
                                if (++resolved_count === dx) {
                                    ok(results);
                                }
                            };
                        }(cx));
                        pendding.catch(function (e) {
                            if (rejected_count++ === 0) {
                                oh(e);
                            }
                        });
                    } else {
                        results[cx] = pendding;
                        if (++resolved_count === dx) {
                            ok(results);
                        }
                    };
                }
            } catch (e) {
                oh(e);
            }
        });
    };
    Promise.race = function (penddings) {
        return new Promise(function (ok, oh) {
            try {
                var resolved_count = 0,
                    rejected_count = 0,
                    results = Array(penddings.length);
                for (var cx = 0, dx = penddings.length; cx < dx; cx++) {
                    var pendding = penddings[cx];
                    if (isPromise(pendding)) {
                        pendding.then(function (cx) {
                            return function (arg) {
                                if (++resolved_count === 0) {
                                    ok(arg);
                                }
                            };
                        }(cx)).catch(function (e) {
                            if (rejected_count++ === dx) {
                                oh(e);
                            }
                        });
                    } else {
                        results[cx] = pendding;
                    };
                }
            } catch (e) {
                oh(e);
            }
        });
    };
    Promise.reject = function (error) {
        return new Promise(function (ok, oh) {
            oh(error);
        });
    };
    Promise.resolve = function () {
        var args = arguments;
        return new Promise(function (ok, oh) {
            ok.apply(null, args);
        });
    };
}
<|endoftext|>


<commit_before>const Discord = require("discord.js");
const fs = require("fs");
const date = require("date");
const bot = new Discord.Client();
const prefix = "!";
const botToken = require("./bottoken");

bot.on("ready", () => {
    console.log("Klar");
    bot.user.setGame("Skriv !help för hjälp.");
});

var borde = [
    "Ja",
    "Nej"
];

var ryss = [
    "Du klarade dig",
    "Du klarade dig",
    "Du klarade dig",
    "Du klarade dig",
    "Du klarade dig",
    "Du dog"
];

var dabRespond = [
    "Du kan inte tvinga mig",
    "Du kan inte tvinga mig",
    "Du kan inte tvinga mig",
    "Du kan inte tvinga mig",
    "Du kan inte tvinga mig",
    "Du kan inte tvinga mig",
    "Vad är det du inte förstår?",
    "Jävla människor ska alltid komma och tjata",
    "Okej då, ***DAB***"
];

Date.prototype.getWeek = function() {
    var onejan = new Date(this.getFullYear(), 0, 1);
    return Math.ceil((((this - onejan) / 86400000) + onejan.getDay() + 1) / 7);
}

var skott;
var pistolLaddad = false;
var weekNumber = (new Date()).getWeek();
var widthSchema = "600"
var heightSchema = "600"

bot.on("message", (message) => {
    if (!message.content.startsWith(prefix)) return;
    if (message.author.bot) return;

    //console.log(test);

    var split = message.content.substring(prefix.length).split(' ');

    switch (split[0].toLowerCase()) {
        case "h":
        case "help":
            message.channel.send({
                embed: new Discord.RichEmbed()
                    .setAuthor("Kommandon:", bot.user.avatarURL)
                    .addField("Allmäna kommandon:", "!help - visar denna meny\n!dab - sprid cancer\n!poll <fråga> - Starta en ja eller nej fråga\n!pinpoll - samma som !poll fast den pinnar också\n!borde - låt boten svara på livets svåra frågor\n!ryss - spela rysk roulette")
                    .addField("Skolrelaterade kommandon:", "!schema - visar veckans schema\n!schemavecka <vecka> - visar schemat från en viss vecka\n!vecka - visar veckan\n!wikipedia <sida> - låter dig gå till en viss wikipedia hemsida")
                    .addField("Discord kommandon:", "!hex - ger dig en slumpmässig färg\n!hexdisplay <hex> - visar fägen som det inskrivna hex nummret ger\n!github - skickar länken till botens github repo\n!ping - visar botens internal ping (för felsökning)\n!getid - Visar ditt user id")
                    .setColor("0x111111")
            });
            break;
        case "vecka":
            message.channel.send(weekNumber);
            break;
        case "s":
        case "schema":
            var valfriVecka = message.content.substring(8)
            if (valfriVecka === "") {
                valfriVecka = weekNumber;
            }

            message.channel.send({
                embed: new Discord.RichEmbed()
                    .setAuthor("Schema v."+valfriVecka+":")
                    .setImage("http://www.novasoftware.se/ImgGen/schedulegenerator.aspx?format=png&schoolid=80220/sv-se&type=1&id={EA17E85E-CBFC-4836-935C-04780337F6D5}&period=&week="+valfriVecka+
                    "&mode=0&printer=0&colors=32&head=0&clock=0&foot=0&day=0&width="+widthSchema+"&height="+heightSchema+"&maxwidth=1883&maxheight=847")
                    .setColor("0x"+("000000"+Math.random().toString(16).slice(2, 8).toUpperCase()).slice(-6))
            });
            break;
        case "github":
            message.author.send("https://github.com/ChilladeChillin/ITGDiscordBot");
            break;
        case "dab":
            message.channel.send(dabRespond[Math.floor(Math.random() * dabRespond.length)]);
            break;
        case "säg":
        case "say":
            var textFromSender = message.content;
            message.delete(0);
            if (message.author.id==="164283691802165250") {
                message.channel.send(message.content.substring(5));
                break;
            }
            else {
                message.author.send("Du har inte tillåtelse att använda detta kommando");
                break;
            }
        case "ping":
            message.channel.send(bot.ping+" ms");
            break;
        case "hex":
            var randomhex = ("000000"+Math.random().toString(16).slice(2, 8).toUpperCase()).slice(-6);
            message.channel.send({
                embed: new Discord.RichEmbed()
                    .setAuthor("Hex:")
                    .setDescription("#"+randomhex)
                    .setColor("0x"+randomhex)
            });
            break;
        case "poll":
            var question = message.content.substring(6)
            message.delete(0);
            message.channel.send(question+"\n\n`👍=JA 👎=NEJ`")
                .then(function (message) {
                    message.react("👍")
                    message.react("👎")
                }).catch(function() {
                    console.log("Reaktionen gick inte hela vägen fram")
                   });
            break;
        case "pinpoll":
            var question = message.content.substring(9)
            message.delete(0);
            if (message.author.id==="164283691802165250" || "349987894171271178") {
                message.channel.send(question+"\n\n`👍=JA 👎=NEJ`")
                .then(function (message) {
                    message.react("👍")
                    message.pin()
                    //delay(10)
                    message.react("👎")
                }).catch(function() {
                    console.log("Reaktionen gick inte hela vägen fram (pinpoll)")
                    });
            }
            else {
                message.author.send("Du har inte tillåtelse att använda detta kommando");
            }
            break;
        case "hd":
        case "hexdisplay":
            var hexMessage = message.content.substring(12)
            if (hexMessage.substr(0, 1) === "#") {
                var hexMessageFix = hexMessage.substing(1)
            }
            else {
                var hexMessageFix = hexMessage
            }
            message.channel.send({
                embed: new Discord.RichEmbed()
                    .setAuthor("Hex:")
                    .setDescription("#"+hexMessageFix)
                    .setColor("0x"+hexMessageFix)
            });
            break;
        case "getid":
            message.channel.send(message.author.id);
            break;
        case "kommer":
        case "är":
        case "borde":
            message.channel.send(borde[Math.floor(Math.random()*borde.length)]+" "+message.author.toString());
            break;
        case "ryss":
            if (pistolLaddad === false) {
                message.channel.send("Laddar Pistolen");
                pistolLaddad = true;
                skott = Math.floor((Math.random() * 6) + 1);
            }
            else {
                if (skott === 1) {
                    message.channel.send("Du dog "+message.author.toString());
                    pistolLaddad = false;
                }
                else {
                    message.channel.send("Du överlevde "+message.author.toString());
                    skott -= 1;
                    console.log(skott);
                }
            }

            //message.channel.send(ryss[Math.floor(Math.random()*ryss.length)]+" "+message.author.toString());
            break;
        case "wikipedia":
            var wikiSearch = message.content.substring(11)
            message.channel.send("https://en.wikipedia.org/wiki/"+wikiSearch);
            break;
        default:
            message.channel.send("```Detta kommando existerar inte (än)\nSkriv !help för att se de kommandon som faktiskt existerar```");
    }
});

bot.login(botToken);<commit_msg>Påbörjade !wikise och !wikisök<commit_after>const Discord = require("discord.js");
const fs = require("fs");
const date = require("date");
const bot = new Discord.Client();
const prefix = "!";
const botToken = require("./bottoken");

bot.on("ready", () => {
    console.log("Klar");
    bot.user.setGame("Skriv !help för hjälp.");
});

var borde = [
    "Ja",
    "Nej"
];

var ryss = [
    "Du klarade dig",
    "Du klarade dig",
    "Du klarade dig",
    "Du klarade dig",
    "Du klarade dig",
    "Du dog"
];

var dabRespond = [
    "Du kan inte tvinga mig",
    "Du kan inte tvinga mig",
    "Du kan inte tvinga mig",
    "Du kan inte tvinga mig",
    "Du kan inte tvinga mig",
    "Du kan inte tvinga mig",
    "Vad är det du inte förstår?",
    "Jävla människor ska alltid komma och tjata",
    "Okej då, ***DAB***"
];

Date.prototype.getWeek = function() {
    var onejan = new Date(this.getFullYear(), 0, 1);
    return Math.ceil((((this - onejan) / 86400000) + onejan.getDay() + 1) / 7);
}

var skott;
var pistolLaddad = false;
var weekNumber = (new Date()).getWeek();
var widthSchema = "600"
var heightSchema = "600"

bot.on("message", (message) => {
    if (!message.content.startsWith(prefix)) return;
    if (message.author.bot) return;

    //console.log(test);

    var split = message.content.substring(prefix.length).split(' ');

    switch (split[0].toLowerCase()) {
        case "h":
        case "help":
            message.channel.send({
                embed: new Discord.RichEmbed()
                    .setAuthor("Kommandon:", bot.user.avatarURL)
                    .addField("Allmäna kommandon:", "!help - visar denna meny\n!dab - sprid cancer\n!poll <fråga> - Starta en ja eller nej fråga\n!pinpoll - samma som !poll fast den pinnar också\n!borde - låt boten svara på livets svåra frågor\n!ryss - spela rysk roulette")
                    .addField("Skolrelaterade kommandon:", "!schema - visar veckans schema\n!schemavecka <vecka> - visar schemat från en viss vecka\n!vecka - visar veckan\n!wikipedia <sida> - låter dig gå till en viss wikipedia hemsida")
                    .addField("Discord kommandon:", "!hex - ger dig en slumpmässig färg\n!hexdisplay <hex> - visar fägen som det inskrivna hex nummret ger\n!github - skickar länken till botens github repo\n!ping - visar botens internal ping (för felsökning)\n!getid - Visar ditt user id")
                    .setColor("0x111111")
            });
            break;
        case "vecka":
            message.channel.send(weekNumber);
            break;
        case "s":
        case "schema":
            var valfriVecka = message.content.substring(8)
            if (valfriVecka === "") {
                valfriVecka = weekNumber;
            }

            message.channel.send({
                embed: new Discord.RichEmbed()
                    .setAuthor("Schema v."+valfriVecka+":")
                    .setImage("http://www.novasoftware.se/ImgGen/schedulegenerator.aspx?format=png&schoolid=80220/sv-se&type=1&id={EA17E85E-CBFC-4836-935C-04780337F6D5}&period=&week="+valfriVecka+
                    "&mode=0&printer=0&colors=32&head=0&clock=0&foot=0&day=0&width="+widthSchema+"&height="+heightSchema+"&maxwidth=1883&maxheight=847")
                    .setColor("0x"+("000000"+Math.random().toString(16).slice(2, 8).toUpperCase()).slice(-6))
            });
            break;
        case "github":
            message.author.send("https://github.com/ChilladeChillin/ITGDiscordBot");
            break;
        case "dab":
            message.channel.send(dabRespond[Math.floor(Math.random() * dabRespond.length)]);
            break;
        case "säg":
        case "say":
            var textFromSender = message.content;
            message.delete(0);
            if (message.author.id==="164283691802165250") {
                message.channel.send(message.content.substring(5));
                break;
            }
            else {
                message.author.send("Du har inte tillåtelse att använda detta kommando");
                break;
            }
        case "ping":
            message.channel.send(bot.ping+" ms");
            break;
        case "hex":
            var randomhex = ("000000"+Math.random().toString(16).slice(2, 8).toUpperCase()).slice(-6);
            message.channel.send({
                embed: new Discord.RichEmbed()
                    .setAuthor("Hex:")
                    .setDescription("#"+randomhex)
                    .setColor("0x"+randomhex)
            });
            break;
        case "poll":
            var question = message.content.substring(6)
            message.delete(0);
            message.channel.send(question+"\n\n`👍=JA 👎=NEJ`")
                .then(function (message) {
                    message.react("👍")
                    message.react("👎")
                }).catch(function() {
                    console.log("Reaktionen gick inte hela vägen fram")
                   });
            break;
        case "pinpoll":
            var question = message.content.substring(9)
            message.delete(0);
            if (message.author.id==="164283691802165250" || "349987894171271178") {
                message.channel.send(question+"\n\n`👍=JA 👎=NEJ`")
                .then(function (message) {
                    message.react("👍")
                    message.pin()
                    //delay(10)
                    message.react("👎")
                }).catch(function() {
                    console.log("Reaktionen gick inte hela vägen fram (pinpoll)")
                    });
            }
            else {
                message.author.send("Du har inte tillåtelse att använda detta kommando");
            }
            break;
        case "hd":
        case "hexdisplay":
            var hexMessage = message.content.substring(12)
            if (hexMessage.substr(0, 1) === "#") {
                var hexMessageFix = hexMessage.substing(1)
            }
            else {
                var hexMessageFix = hexMessage
            }
            message.channel.send({
                embed: new Discord.RichEmbed()
                    .setAuthor("Hex:")
                    .setDescription("#"+hexMessageFix)
                    .setColor("0x"+hexMessageFix)
            });
            break;
        case "getid":
            message.channel.send(message.author.id);
            break;
        case "kommer":
        case "är":
        case "borde":
            message.channel.send(borde[Math.floor(Math.random()*borde.length)]+" "+message.author.toString());
            break;
        case "ryss":
            if (pistolLaddad === false) {
                message.channel.send("Laddar Pistolen");
                pistolLaddad = true;
                skott = Math.floor((Math.random() * 6) + 1);
            }
            else {
                if (skott === 1) {
                    message.channel.send("Du dog "+message.author.toString());
                    pistolLaddad = false;
                }
                else {
                    message.channel.send("Du överlevde "+message.author.toString());
                    skott -= 1;
                    console.log(skott);
                }
            }

            //message.channel.send(ryss[Math.floor(Math.random()*ryss.length)]+" "+message.author.toString());
            break;
        case "wikipedia":
            var wikiSearch = message.content.substring(11)
            message.channel.send("https://en.wikipedia.org/wiki/"+wikiSearch);
            break;
        case "wikise":
            var wikiSearch = message.content.substring(8)
            message.channel.send("https://sv.wikipedia.org/wiki/"+wikiSearch);
            break;
        case "wikisök":
            var wikiSearch = message.content.substring(8)
            message.channel.send("https://en.wikipedia.org/w/index.php?search="+wikiSearch);
        break;

        case "test":
            message.channel.send("https://itgappen.se/api/2/lunch");
            break;
        default:
            message.channel.send("```Detta kommando existerar inte (än)\nSkriv !help för att se de kommandon som faktiskt existerar```");
    }
});

bot.login(botToken);<|endoftext|>


<commit_before>const history = require('sheet-router/history')
const sheetRouter = require('sheet-router')
const document = require('global/document')
const href = require('sheet-router/href')
const sendAction = require('send-action')
const xtend = require('xtend')
const yo = require('yo-yo')

choo.view = yo
module.exports = choo

// A framework for creating sturdy web applications
// null -> fn
function choo (opts) {
  opts = opts || {}
  const name = opts.name || 'choo'
  var _router = null
  var _models = [ appInit() ]

  start.router = router
  start.model = model
  start.start = start

  return start

  // start the application
  // null -> DOMNode
  function start () {
    const events = bootstrap(_models)
    const send = sendAction({
      onaction: events.modifyState,
      onchange: onchange,
      state: events.state
    })

    if (opts.href !== false) {
      href(function (href) {
        send('location', { location: href })
      })
    }

    if (opts.history !== false) {
      history(function (href) {
        send('location', { location: href })
      })
    }

    const rootId = name + '-root'
    const tree = _router(send.state().location, send.state(), send)
    tree.setAttribute('id', rootId)
    return tree

    // update on every change
    function onchange (action, state) {
      const oldTree = document.querySelector('#' + rootId)
      const newTree = _router(state.location, state, send)
      newTree.setAttribute('id', rootId)
      yo.update(oldTree, newTree)
    }
  }

  // register all routes
  // [obj|fn] -> null
  function router (cb) {
    _router = sheetRouter(cb)
  }

  // create a new model
  // (str?, obj) -> null
  function model (name, model) {
    if (!model) model = name
    if (typeof name === 'string') model.name = name
    _models.push(model)
  }
}

// initial application state model
// null -> obj
function appInit () {
  return {
    state: {
      location: document.location.href
    },
    reducers: {
      location: setLocation
    }
  }

  // handle href links
  function setLocation (action, state) {
    const location = action.location.replace(/#.*/, '')
    return xtend(state, { location: location })
  }
}

function bootstrap (events) {
  const initialState = {}
  const reducers = {}
  const effects = {}

  events.forEach(function (model) {
    if (model.state) apply(model.name, model.state, initialState)
    if (model.reducers) apply(model.name, model.reducers, reducers)
    if (model.effects) apply(model.name, model.effects, effects)
  })

  return {
    modifyState: modifyState,
    state: initialState
  }

  function modifyState (action, state, send) {
    var _reducers = false
    var _effects = false
    var newState = null

    if (reducers[action.type]) {
      newState = xtend(state, reducers[action.type](action, state))
      _reducers = true
    }

    if (effects[action.type]) {
      effects[action.type](action, newState || state, send)
      newState = newState || state
      _effects = true
    }

    if (!_reducers && !_effects) {
      throw new Error('Could not find action ' + action.type)
    }

    return newState
  }
}

// compose an object conditionally
// (str, obj, obj) -> null
function apply (name, source, target) {
  Object.keys(source).forEach(function (key) {
    if (name) target[name + ':' + key] = source[key]
    else target[key] = source[key]
  })
}
<commit_msg>choo: add subscriptions<commit_after>const history = require('sheet-router/history')
const sheetRouter = require('sheet-router')
const document = require('global/document')
const href = require('sheet-router/href')
const sendAction = require('send-action')
const xtend = require('xtend')
const yo = require('yo-yo')

choo.view = yo
module.exports = choo

// A framework for creating sturdy web applications
// null -> fn
function choo (opts) {
  opts = opts || {}
  const name = opts.name || 'choo'
  var _router = null
  var _models = [ appInit() ]

  start.router = router
  start.model = model
  start.start = start

  return start

  // start the application
  // null -> DOMNode
  function start () {
    const events = bootstrap(_models)
    const send = sendAction({
      onaction: events.modifyState,
      onchange: onchange,
      state: events.state
    })

    if (opts.href !== false) {
      href(function (href) {
        send('location', { location: href })
      })
    }

    if (opts.history !== false) {
      history(function (href) {
        send('location', { location: href })
      })
    }

    const rootId = name + '-root'
    const tree = _router(send.state().location, send.state(), send)
    tree.setAttribute('id', rootId)
    return tree

    // update on every change
    function onchange (action, state) {
      const oldTree = document.querySelector('#' + rootId)
      const newTree = _router(state.location, state, send)
      newTree.setAttribute('id', rootId)
      yo.update(oldTree, newTree)
    }
  }

  // register all routes
  // [obj|fn] -> null
  function router (cb) {
    _router = sheetRouter(cb)
  }

  // create a new model
  // (str?, obj) -> null
  function model (name, model) {
    if (!model) model = name
    if (typeof name === 'string') model.name = name
    _models.push(model)
  }
}

// initial application state model
// null -> obj
function appInit () {
  return {
    state: {
      location: document.location.href
    },
    reducers: {
      location: setLocation
    }
  }

  // handle href links
  function setLocation (action, state) {
    const location = action.location.replace(/#.*/, '')
    return xtend(state, { location: location })
  }
}

function bootstrap (events) {
  const initialState = {}
  const reducers = {}
  const effects = {}

  events.forEach(function (model) {
    if (model.state) apply(model.name, model.state, initialState)
    if (model.reducers) apply(model.name, model.reducers, reducers)
    if (model.effects) apply(model.name, model.effects, effects)
    if (model.subscriptions) {
      apply(model.name, model.subscriptions, initialState)
    }
  })

  return {
    modifyState: modifyState,
    state: initialState
  }

  function modifyState (action, state, send) {
    var _reducers = false
    var _effects = false
    var newState = null

    if (reducers[action.type]) {
      newState = xtend(state, reducers[action.type](action, state))
      _reducers = true
    }

    if (effects[action.type]) {
      effects[action.type](action, newState || state, send)
      newState = newState || state
      _effects = true
    }

    if (!_reducers && !_effects) {
      throw new Error('Could not find action ' + action.type)
    }

    return newState
  }
}

// compose an object conditionally
// (str, obj, obj) -> null
function apply (name, source, target) {
  Object.keys(source).forEach(function (key) {
    if (name) target[name + ':' + key] = source[key]
    else target[key] = source[key]
  })
}
<|endoftext|>


<commit_before>var vdf = require('vdf');
var fs = require('fs');

var protomask = 0x80000000;

var Language = require(__dirname + '/language.js');
var Protos = require(__dirname + '/protos.js');

var base_gcmessages = Protos.base_gcmessages;
var tf_gcmessages = Protos.tf_gcmessages;

module.exports = TeamFortress2;

require('util').inherits(TeamFortress2, require('events').EventEmitter);

TeamFortress2.GCGoodbyeReason = {
	GC_GOING_DOWN: 1,
	NO_SESSION: 2
};

function TeamFortress2(steam) {
	this._steam = steam;
	this.haveGCSession = false;

	var self = this;

	// "extend" the default steam.gamesPlayed function so we can catch when TF2 starts up
	var gamesPlayed = steam.gamesPlayed;
	steam.gamesPlayed = function(appids) {
		if(appids.indexOf(440) != -1 && !self.haveGCSession) {
			self._connect();
		}

		gamesPlayed.call(steam, appids);
	};

	steam.on('fromGC', function(appID, type, body) {
		if(appID != 440) {
			// Not from the TF2 GC
			return;
		}

		var protobuf = !!(type & protomask);
		type &= ~protomask;

		if(self._handlers[type]) {
			self._handlers[type].call(self, body);
		} else {
			var msgName = type;
			for(var i in Language) {
				if(Language[i] == type) {
					msgName = i;
					break;
				}
			}

			self.emit('debug', "Got unhandled GC message " + msgName + (protobuf ? " (protobuf)" : ""));
		}
	});
}

TeamFortress2.prototype._connect = function() {
	var self = this;
	var interval = setInterval(function() {
		// TODO: Clear interval when we shut down TF2 in case the GC connection is never established
		if(self.haveGCSession) {
			clearInterval(interval);
			return;
		}

		self._send(Language.ClientHello, base_gcmessages.CMsgClientHello, {});
	}, 5000);
};

TeamFortress2.prototype._send = function(type, protobuf, body) {
	var msgName = type;
	for(var i in Language) {
		if(Language[i] == type) {
			msgName = i;
			break;
		}
	}

	this.emit('debug', "Sending GC message " + msgName);

	if(protobuf) {
		this._steam.toGC(440, type | protomask, protobuf.serialize(body));
	} else {
		this._steam.toGC(440, type, body);
	}
};

TeamFortress2.prototype.setLang = function(langFile) {
	var lang = vdf.parse(langFile);
	// The vdf parser appears to add some random characters and quotes to the root 'lang' key, so we'll just use a loop to find it
	for(var i in lang) {
		this.lang = lang[i].Tokens;
	}
};

TeamFortress2.prototype._handlers = {};

require('./handlers.js');<commit_msg>Added TradeResponse enum<commit_after>var vdf = require('vdf');
var fs = require('fs');

var protomask = 0x80000000;

var Language = require(__dirname + '/language.js');
var Protos = require(__dirname + '/protos.js');

var base_gcmessages = Protos.base_gcmessages;
var tf_gcmessages = Protos.tf_gcmessages;

module.exports = TeamFortress2;

require('util').inherits(TeamFortress2, require('events').EventEmitter);

TeamFortress2.GCGoodbyeReason = {
	GC_GOING_DOWN: 1,
	NO_SESSION: 2
};

TeamFortress2.TradeResponse = {
	Accepted: 0,
	Declined: 1,
	TradeBannedInitiator: 2,
	TradeBannedTarget: 3,
	TargetAlreadyTrading: 4,
	Disabled: 5,
	NotLoggedIn: 6,
	Cancel: 7,
	TooSoon: 8,
	TooSoonPenalty: 9,
	ConnectionFailed: 10,
	AlreadyTrading: 11,
	AlreadyHasTradeRequest: 12,
	NoResponse: 13,
	CyberCafeInitiator: 14,
	CyberCafeTarget: 15,
	SchoolLabInitiator: 16,
	SchoolLabTarget: 16,
	InitiatorBlockedTarget: 18,
	InitiatorNeedsVerifiedEmail: 20,
	InitiatorNeedsSteamGuard: 21,
	TargetAccountCannotTrade: 22,
	InitiatorSteamGuardDuration: 23,
	InitiatorPasswordResetProbation: 24,
	InitiatorNewDeviceCooldown: 25,
	OKToDeliver: 50
};

function TeamFortress2(steam) {
	this._steam = steam;
	this.haveGCSession = false;

	var self = this;

	// "extend" the default steam.gamesPlayed function so we can catch when TF2 starts up
	var gamesPlayed = steam.gamesPlayed;
	steam.gamesPlayed = function(appids) {
		if(appids.indexOf(440) != -1 && !self.haveGCSession) {
			self._connect();
		}

		gamesPlayed.call(steam, appids);
	};

	steam.on('fromGC', function(appID, type, body) {
		if(appID != 440) {
			// Not from the TF2 GC
			return;
		}

		var protobuf = !!(type & protomask);
		type &= ~protomask;

		if(self._handlers[type]) {
			self._handlers[type].call(self, body);
		} else {
			var msgName = type;
			for(var i in Language) {
				if(Language[i] == type) {
					msgName = i;
					break;
				}
			}

			self.emit('debug', "Got unhandled GC message " + msgName + (protobuf ? " (protobuf)" : ""));
		}
	});
}

TeamFortress2.prototype._connect = function() {
	var self = this;
	var interval = setInterval(function() {
		// TODO: Clear interval when we shut down TF2 in case the GC connection is never established
		if(self.haveGCSession) {
			clearInterval(interval);
			return;
		}

		self._send(Language.ClientHello, base_gcmessages.CMsgClientHello, {});
	}, 5000);
};

TeamFortress2.prototype._send = function(type, protobuf, body) {
	var msgName = type;
	for(var i in Language) {
		if(Language[i] == type) {
			msgName = i;
			break;
		}
	}

	this.emit('debug', "Sending GC message " + msgName);

	if(protobuf) {
		this._steam.toGC(440, type | protomask, protobuf.serialize(body));
	} else {
		this._steam.toGC(440, type, body);
	}
};

TeamFortress2.prototype.setLang = function(langFile) {
	var lang = vdf.parse(langFile);
	// The vdf parser appears to add some random characters and quotes to the root 'lang' key, so we'll just use a loop to find it
	for(var i in lang) {
		this.lang = lang[i].Tokens;
	}
};

TeamFortress2.prototype._handlers = {};

require('./handlers.js');<|endoftext|>


<commit_before>var isolines = require('turf-isolines'),
    grid = require('turf-grid'),
    destination = require('turf-destination'),
    point = require('turf-point'),
    distance = require('turf-distance'),
    extent = require('turf-extent'),
    featureCollection = require('turf-featurecollection'),
    polylineDecode = require('polyline').decode,
    OSRM = require('osrm');

module.exports = function (center, time, resolution, maxspeed, unit, network, done) {
    this.draw = function(destinations) {
        return isolines(destinations, 'eta', resolution, [time]);
    };
    this.getIsochrone = function() {
        var osrm = network instanceof OSRM ? network : new OSRM(network);
        // compute bbox
        // bbox should go out 1.4 miles in each direction for each minute
        // this will account for a driver going a bit above the max safe speed
        var centerPt = point(center[0], center[1]);
        var spokes = featureCollection([]);
        var length = (time/3600) * maxspeed;
        spokes.features.push(destination(centerPt, length, 180, unit));
        spokes.features.push(destination(centerPt, length, 0, unit));
        spokes.features.push(destination(centerPt, length, 90, unit));
        spokes.features.push(destination(centerPt, length, -90, unit));
        var bbox = this.bbox = extent(spokes);
        var sizeCellGrid = this.sizeCellGrid = distance(point(bbox[0], bbox[1]), point(bbox[0], bbox[3]), unit) / resolution;

        //compute destination grid
        var targets = grid(bbox, resolution);
        targets.features = targets.features.filter(function(feat) {
            return distance(point(feat.geometry.coordinates[0], feat.geometry.coordinates[1]), centerPt, unit) <= length;
        });
        var destinations = featureCollection([]);
        var i = 0;
        var routedNum = 0;

        getNext(i);

        function getNext(i){
            if(destinations.features.length > targets.features.length){
                return;
            }
            if(i < targets.features.length) {
                var query = {
                    coordinates: [
                        [
                          center[1], center[0]
                        ],
                        [
                          targets.features[i].geometry.coordinates[1], targets.features[i].geometry.coordinates[0]
                        ]
                    ],
                    alternateRoute: false,
                    printInstructions: false
                };

                osrm.route(query, function(err, res){
                    i++;
                    if(err) console.log(err);
                    if(err) return done(err);
                    else if (!res || !res.route_summary) {
                        destinations.features.push({
                            type: 'Feature',
                            properties: {
                                eta: time+100
                                //,dist: 500
                            },
                            geometry: {
                                type: 'Point',
                                coordinates: [query.coordinates[1][1], query.coordinates[1][0]]
                            }
                        });
                    } else {
                        var distanceMapped = 0;
                        if (res.via_points) {
                            distanceMapped = distance(
                                point(query.coordinates[1][1], query.coordinates[1][0]),
                                point(res.via_points[1][1], res.via_points[1][0]),
                                unit
                            );
                        }
                        if (distanceMapped && distanceMapped < sizeCellGrid) {
                            destinations.features.push({
                                type: 'Feature',
                                properties: {
                                    eta: res.route_summary.total_time,
                                    dist: res.route_summary.total_distance
                                },
                                geometry: {
                                    type: 'Point',
                                    coordinates: [res.via_points[1][1], res.via_points[1][0]]
                                }
                            });
                        }
                        else {
                            // exclude some points from grid for isoline
                            if (!distanceMapped) distanceMapped = sizeCellGrid * 2;
                            destinations.features.push({
                                type: 'Feature',
                                properties: {
                                    // this point cannot be routed => a penality 2 is applied to maxspeed
                                    eta: time + (distanceMapped - sizeCellGrid) / (maxspeed / 3600) * 2
                                },
                                geometry: {
                                    type: 'Point',
                                    coordinates: [query.coordinates[1][1], query.coordinates[1][0]]
                                }
                            });
                        }
                    }
                    getNext(i);
                });
            } else {
                var result = self.draw(destinations);
                return done(null, result);
            }
        }
    };
    var self = this;

    // in case module is called directly
    if (this.process && this.process.title == 'node')
        return getIsochrone();
}
<commit_msg>Add new argument for draw<commit_after>var isolines = require('turf-isolines'),
    grid = require('turf-grid'),
    destination = require('turf-destination'),
    point = require('turf-point'),
    distance = require('turf-distance'),
    extent = require('turf-extent'),
    featureCollection = require('turf-featurecollection'),
    polylineDecode = require('polyline').decode,
    OSRM = require('osrm');

module.exports = function (center, time, resolution, maxspeed, unit, network, done, options) {
    if (options && options.draw) {
        this.draw = options.draw;
    } else {
        this.draw = function(destinations) {
            return isolines(destinations, 'eta', resolution, [time]);
        };
    }
    this.getIsochrone = function() {
        var osrm = network instanceof OSRM ? network : new OSRM(network);
        // compute bbox
        // bbox should go out 1.4 miles in each direction for each minute
        // this will account for a driver going a bit above the max safe speed
        var centerPt = point(center[0], center[1]);
        var spokes = featureCollection([]);
        var length = (time/3600) * maxspeed;
        spokes.features.push(destination(centerPt, length, 180, unit));
        spokes.features.push(destination(centerPt, length, 0, unit));
        spokes.features.push(destination(centerPt, length, 90, unit));
        spokes.features.push(destination(centerPt, length, -90, unit));
        var bbox = this.bbox = extent(spokes);
        var sizeCellGrid = this.sizeCellGrid = distance(point(bbox[0], bbox[1]), point(bbox[0], bbox[3]), unit) / resolution;

        //compute destination grid
        var targets = grid(bbox, resolution);
        targets.features = targets.features.filter(function(feat) {
            return distance(point(feat.geometry.coordinates[0], feat.geometry.coordinates[1]), centerPt, unit) <= length;
        });
        var destinations = featureCollection([]);
        var i = 0;
        var routedNum = 0;

        getNext(i);

        function getNext(i){
            if(destinations.features.length > targets.features.length){
                return;
            }
            if(i < targets.features.length) {
                var query = {
                    coordinates: [
                        [
                          center[1], center[0]
                        ],
                        [
                          targets.features[i].geometry.coordinates[1], targets.features[i].geometry.coordinates[0]
                        ]
                    ],
                    alternateRoute: false,
                    printInstructions: false
                };

                osrm.route(query, function(err, res){
                    i++;
                    if(err) console.log(err);
                    if(err) return done(err);
                    else if (!res || !res.route_summary) {
                        destinations.features.push({
                            type: 'Feature',
                            properties: {
                                eta: time+100
                                //,dist: 500
                            },
                            geometry: {
                                type: 'Point',
                                coordinates: [query.coordinates[1][1], query.coordinates[1][0]]
                            }
                        });
                    } else {
                        var distanceMapped = 0;
                        if (res.via_points) {
                            distanceMapped = distance(
                                point(query.coordinates[1][1], query.coordinates[1][0]),
                                point(res.via_points[1][1], res.via_points[1][0]),
                                unit
                            );
                        }
                        if (distanceMapped && distanceMapped < sizeCellGrid) {
                            destinations.features.push({
                                type: 'Feature',
                                properties: {
                                    eta: res.route_summary.total_time,
                                    dist: res.route_summary.total_distance
                                },
                                geometry: {
                                    type: 'Point',
                                    coordinates: [res.via_points[1][1], res.via_points[1][0]]
                                }
                            });
                        }
                        else {
                            // exclude some points from grid for isoline
                            if (!distanceMapped) distanceMapped = sizeCellGrid * 2;
                            destinations.features.push({
                                type: 'Feature',
                                properties: {
                                    // this point cannot be routed => a penality 2 is applied to maxspeed
                                    eta: time + (distanceMapped - sizeCellGrid) / (maxspeed / 3600) * 2
                                },
                                geometry: {
                                    type: 'Point',
                                    coordinates: [query.coordinates[1][1], query.coordinates[1][0]]
                                }
                            });
                        }
                    }
                    getNext(i);
                });
            } else {
                var result = self.draw(destinations);
                return done(null, result);
            }
        }
    };
    var self = this;

    // in case module is called directly
    if (this.process && this.process.title == 'node')
        return getIsochrone();
}
<|endoftext|>


<commit_before>var {Cc, Ci} = require("chrome");

var gcSvc = Cc["@mozilla.org/grammarcheck;1"].getService(Ci.nsIEditorGrammarCheck);
var xmlhttp = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance(Ci.nsIXMLHttpRequest);

let checkerUrl = "https://languagetool.org:8081/";

function handleText(text) {
	var oReq = xmlhttp;
	oReq.addEventListener("load", function(result) {
		var xml = oReq.responseXML;
		var errors = xml.getElementsByTagName("error");
		var startPositions = [];
		var endPositions = [];
		var replacements = [];
		for (var i = 0; i < errors.length; i++) {
			//console.error("Got match: " + errors[i].getAttribute("offset") + ", len: " + errors[i].getAttribute("errorlength"));
			var startPos = parseInt(errors[i].getAttribute("offset"));
			var endPos = startPos + parseInt(errors[i].getAttribute("errorlength"));
			startPositions.push(startPos);
			endPositions.push(endPos);
			replacements.push(errors[i].getAttribute("replacements"));
			// TODO: use 'msg' attribute
		}
		gcSvc.errorsFound(startPositions, endPositions, startPositions.length);
		for (var j = 0; j < errors.length; j++) {
			// TODO: split at '#'
			gcSvc.addSuggestionForError(j, replacements[j]);
		}
	});
	oReq.open("POST", checkerUrl, true);
	oReq.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
	//var data = "language=en&text=" + text;
	var data = "autodetect=1&text=" + text;
	oReq.send(data);
}

gcSvc.registerAddon(handleText);
<commit_msg>add TODO<commit_after>var {Cc, Ci} = require("chrome");

var gcSvc = Cc["@mozilla.org/grammarcheck;1"].getService(Ci.nsIEditorGrammarCheck);
var xmlhttp = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance(Ci.nsIXMLHttpRequest);

let checkerUrl = "https://languagetool.org:8081/";

function handleText(text) {
	// TODO: add logic to avoid too many API requests (timeout)
	var oReq = xmlhttp;
	oReq.addEventListener("load", function(result) {
		var xml = oReq.responseXML;
		var errors = xml.getElementsByTagName("error");
		var startPositions = [];
		var endPositions = [];
		var replacements = [];
		for (var i = 0; i < errors.length; i++) {
			//console.error("Got match: " + errors[i].getAttribute("offset") + ", len: " + errors[i].getAttribute("errorlength"));
			var startPos = parseInt(errors[i].getAttribute("offset"));
			var endPos = startPos + parseInt(errors[i].getAttribute("errorlength"));
			startPositions.push(startPos);
			endPositions.push(endPos);
			replacements.push(errors[i].getAttribute("replacements"));
			// TODO: use 'msg' attribute
		}
		gcSvc.errorsFound(startPositions, endPositions, startPositions.length);
		for (var j = 0; j < errors.length; j++) {
			// TODO: split at '#'
			gcSvc.addSuggestionForError(j, replacements[j]);
		}
	});
	oReq.open("POST", checkerUrl, true);
	oReq.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
	//var data = "language=en&text=" + text;
	var data = "autodetect=1&text=" + text;
	oReq.send(data);
}

gcSvc.registerAddon(handleText);
<|endoftext|>


<commit_before>// The callback function passed to handlers when the other side doesn't
// expect a reply to the message.
function noReplyCallback(err, obj, cb) {
    if (cb)
        cb(new Error("No reply expected"), null, noReplyCallback);
}

// Error serialization matching bunyan. (Both MIT)
// https://github.com/trentm/node-bunyan/blob/e43a1a405f379c37d59c4227168dca0e8f41d052/lib/bunyan.js#L968-L1002
function getFullErrorStack(ex)
{
    var ret = ex.stack || ex.toString();
    if (typeof(ex.cause) === 'function') {
        var cex = ex.cause();
        if (cex)
            ret += '\nCaused by: ' + getFullErrorStack(cex);
    }
    return ret;
}

var errorSerializer = function(v) {
    if (v && v.stack) {
        v = {
            message: v.message,
            name: v.name,
            stack: getFullErrorStack(v),
            code: v.code,
            signal: v.signal
        };
    }
    return v;
};

function Jmsg(writeFn, handlers) {
    this.handlers = handlers || {};
    this.timeout = 60000;

    this._seq = 1;
    this._callbacks = Object.create(null);
    this._writeFn = writeFn;
}

// Send a JSON message.
Jmsg.prototype.send = function(a, b, c, d) {
    // type, value, [cb], [handle]
    if (typeof(b) !== 'function')
        this._sendRaw({ t: a, v: b }, c, d);
    // type, [cb], [handle]
    else
        this._sendRaw({ t: a }, b, d);
};

Jmsg.prototype._sendRaw = function(msg, cb, handle) {
    if (typeof(cb) === 'function') {
        var handlers = this._handlers;
        var callbacks = this._callbacks;
        var seq = msg.s = this._seq++;
        callbacks[seq] = {
            fn: cb,
            timeout: setTimeout(function() {
                delete callbacks[seq];
                cb.call(handlers, new Error("Timeout"), null, noReplyCallback);
            }, this.timeout)
        };
    }
    this._writeFn(msg, handle);
};

// Dispatch a JSON message.
Jmsg.prototype.dispatch = function(msg, handle) {
    var self = this;

    var seq = msg.s;
    var callback = seq ? function(err, val, cb, handle) {
        self._sendRaw({ r: seq, e: errorSerializer(err), v: val }, cb, handle);
    } : noReplyCallback;

    var fn, tmp;
    var handlers = self.handlers;
    if ((tmp = msg.r)) {
        var callbacks = self._callbacks;
        fn = callbacks[tmp];
        if (fn) {
            delete callbacks[tmp];
            clearTimeout(fn.timeout);
            fn.fn.call(handlers, msg.e, msg.v, callback, handle);
        }
        else if (seq) {
            callback(new Error("Unknown sequence number"));
        }
    }
    else if ((tmp = msg.t)) {
        fn = handlers.hasOwnProperty(tmp) && handlers[tmp];
        if (fn)
            fn.call(handlers, msg.v, callback, handle);
        else if (seq)
            callback(new Error("No such action"));
    }
};

// Close the instance, finishing all callbacks.
Jmsg.prototype.close = function(err) {
    var handlers = this._handlers;
    var callbacks = this._callbacks;
    this._callbacks = Object.create(null);
    Object.keys(callbacks).forEach(function(key) {
        if (!err) err = new Error("Connection closed");
        callbacks[key].fn.call(handlers, err, null, noReplyCallback, null);
    });
};

// Main export.
exports = module.exports = function(writeFn, handlers) {
    return new Jmsg(writeFn, handlers);
};

// Process on a duplex stream.
exports.stream = function(stream, handlers) {
    var handle = exports(function(msg) {
        stream.write(JSON.stringify(msg) + "\n");
    }, handlers);

    var carry = require('carrier').carry(stream);

    carry.on('line', function(msg) {
        try { msg = JSON.parse(msg); }
        catch (err) {}

        if (typeof(msg) === 'object' && msg !== null)
            handle.dispatch(msg);
    });

    carry.on('end', function() {
        handle.close();
    });

    return handle;
};

// Process cluster messages.
exports.cluster = function(a, b) {
    // worker, [handlers]
    if (process.send) {
        channel = process;
        handlers = a;
    }
    // [handlers]
    else {
        channel = a;
        handlers = b;
    }

    var handle = exports(channel.send.bind(channel), handlers);

    channel.on('message', handle.dispatch.bind(handle));

    channel.on('exit', function() {
        handle.close();
    });

    return handle;
};
<commit_msg>Style tweaks.<commit_after>// The callback function passed to handlers when the other side doesn't
// expect a reply to the message.
var noReplyCallback = function(err, obj, cb) {
    if (cb)
        cb(new Error("No reply expected"), null, noReplyCallback);
};

// Error serialization matching bunyan. (Both MIT)
// https://github.com/trentm/node-bunyan/blob/e43a1a405f379c37d59c4227168dca0e8f41d052/lib/bunyan.js#L968-L1002
var getFullErrorStack = function(ex) {
    var ret = ex.stack || ex.toString();
    if (typeof(ex.cause) === 'function') {
        var cex = ex.cause();
        if (cex)
            ret += '\nCaused by: ' + getFullErrorStack(cex);
    }
    return ret;
};

var errorSerializer = function(v) {
    if (v && v.stack) {
        v = {
            message: v.message,
            name: v.name,
            stack: getFullErrorStack(v),
            code: v.code,
            signal: v.signal
        };
    }
    return v;
};

function Jmsg(writeFn, handlers) {
    this.handlers = handlers || {};
    this.timeout = 60000;

    this._seq = 1;
    this._callbacks = Object.create(null);
    this._writeFn = writeFn;
}

// Send a JSON message.
Jmsg.prototype.send = function(a, b, c, d) {
    // type, value, [cb], [handle]
    if (typeof(b) !== 'function')
        this._sendRaw({ t: a, v: b }, c, d);
    // type, [cb], [handle]
    else
        this._sendRaw({ t: a }, b, d);
};

Jmsg.prototype._sendRaw = function(msg, cb, handle) {
    if (typeof(cb) === 'function') {
        var handlers = this._handlers;
        var callbacks = this._callbacks;
        var seq = msg.s = this._seq++;
        callbacks[seq] = {
            fn: cb,
            timeout: setTimeout(function() {
                delete callbacks[seq];
                cb.call(handlers, new Error("Timeout"), null, noReplyCallback);
            }, this.timeout)
        };
    }
    this._writeFn(msg, handle);
};

// Dispatch a JSON message.
Jmsg.prototype.dispatch = function(msg, handle) {
    var self = this;

    var seq = msg.s;
    var callback = seq ? function(err, val, cb, handle) {
        self._sendRaw({ r: seq, e: errorSerializer(err), v: val }, cb, handle);
    } : noReplyCallback;

    var fn, tmp;
    var handlers = self.handlers;
    if ((tmp = msg.r)) {
        var callbacks = self._callbacks;
        fn = callbacks[tmp];
        if (fn) {
            delete callbacks[tmp];
            clearTimeout(fn.timeout);
            fn.fn.call(handlers, msg.e, msg.v, callback, handle);
        }
        else if (seq) {
            callback(new Error("Unknown sequence number"));
        }
    }
    else if ((tmp = msg.t)) {
        fn = handlers.hasOwnProperty(tmp) && handlers[tmp];
        if (fn)
            fn.call(handlers, msg.v, callback, handle);
        else if (seq)
            callback(new Error("No such action"));
    }
};

// Close the instance, finishing all callbacks.
Jmsg.prototype.close = function(err) {
    var handlers = this._handlers;
    var callbacks = this._callbacks;
    this._callbacks = Object.create(null);
    Object.keys(callbacks).forEach(function(key) {
        if (!err) err = new Error("Connection closed");
        callbacks[key].fn.call(handlers, err, null, noReplyCallback, null);
    });
};

// Main export.
exports = module.exports = function(writeFn, handlers) {
    return new Jmsg(writeFn, handlers);
};

// Process on a duplex stream.
exports.stream = function(stream, handlers) {
    var handle = exports(function(msg) {
        stream.write(JSON.stringify(msg) + "\n");
    }, handlers);

    var carry = require('carrier').carry(stream);

    carry.on('line', function(msg) {
        try { msg = JSON.parse(msg); }
        catch (err) {}

        if (typeof(msg) === 'object' && msg !== null)
            handle.dispatch(msg);
    });

    carry.on('end', function() {
        handle.close();
    });

    return handle;
};

// Process cluster messages.
exports.cluster = function(a, b) {
    // worker, [handlers]
    if (process.send) {
        channel = process;
        handlers = a;
    }
    // [handlers]
    else {
        channel = a;
        handlers = b;
    }

    var handle = exports(channel.send.bind(channel), handlers);

    channel.on('message', handle.dispatch.bind(handle));

    channel.on('exit', function() {
        handle.close();
    });

    return handle;
};
<|endoftext|>


<commit_before>// Mini version of select-dom
const select = (sel, el) => (el || document).querySelector(sel);
select.all = (sel, el) => (el || document).querySelectorAll(sel);
select.exists = (sel, el) => Boolean(select(sel, el));

// Mini version of element-ready
function elementReady(selector, fn) {
	(function check() {
		const el = document.querySelector(selector);

		if (el) {
			fn();
		} else {
			requestAnimationFrame(check);
		}
	})();
}

/**
 * Utilities
 */
function domify(html) {
	const temp = document.createElement('template');
	temp.innerHTML = html;
	return temp.content;
}

function empty(el) {
	el.textContent = '';
}
function hide(el) {
	el.style.display = 'none';
}
function show(el) {
	el.style.display = 'block';
}
function isHidden(el) {
	return el.style.display !== 'block';
}

/**
 * Extension
 */
function addNotificationsDropdown() {
	if (select.exists('#NPG')) {
		return;
	}
	const indicator = select('a.notification-indicator');
	indicator.parentNode.insertAdjacentHTML('beforeend', `

	`);
}

async function openPopup() {
	// The [data] attribute selector will not conflict with Refined GitHub
	const hasUnread = select.exists('.notification-indicator[data-ga-click$=":unread"]');
	const popup = select('#NPG');
	if (!hasUnread || !isHidden(popup)) {
		return;
	}

	const container = select('#NPG-item');
	empty(container);
	show(popup);

	// Fetch the notifications
	const notificationsPage = await fetch('/notifications', {
		credentials: 'include'
	}).then(r => r.text()).then(domify);
	const notificationsList = select.all('.boxed-group', notificationsPage);
	container.append(...notificationsList);

	// Change tooltip direction
	const classes = select('.tooltipped-s', container).classList;
	classes.remove('tooltipped-s');
	classes.add('tooltipped-n');
}

function closePopup({target}) {
	const container = select('#NPG');
	if (!container.contains(target)) {
		hide(container);
	}
}

function init() {
	const indicator = select('a.notification-indicator');
	addNotificationsDropdown();

	indicator.addEventListener('mouseenter', openPopup);
	document.addEventListener('click', closePopup);
}

// Init everywhere but on the notifications page
if (!location.pathname.startsWith('/notifications')) {
	elementReady('.notification-indicator', init);
}
<commit_msg>Fix possible issue when indicator is unreliable<commit_after>// Mini version of select-dom
const select = (sel, el) => (el || document).querySelector(sel);
select.all = (sel, el) => (el || document).querySelectorAll(sel);
select.exists = (sel, el) => Boolean(select(sel, el));

// Mini version of element-ready
function elementReady(selector, fn) {
	(function check() {
		const el = document.querySelector(selector);

		if (el) {
			fn();
		} else {
			requestAnimationFrame(check);
		}
	})();
}

/**
 * Utilities
 */
function domify(html) {
	const temp = document.createElement('template');
	temp.innerHTML = html;
	return temp.content;
}

function empty(el) {
	el.textContent = '';
}
function hide(el) {
	el.style.display = 'none';
}
function show(el) {
	el.style.display = 'block';
}
function isHidden(el) {
	return el.style.display !== 'block';
}

/**
 * Extension
 */
function addNotificationsDropdown() {
	if (select.exists('#NPG')) {
		return;
	}
	const indicator = select('a.notification-indicator');
	indicator.parentNode.insertAdjacentHTML('beforeend', `

	`);
}

async function openPopup() {
	// The [data] attribute selector will not conflict with Refined GitHub
	const hasUnread = select.exists('.notification-indicator[data-ga-click$=":unread"]');
	const popup = select('#NPG');
	if (!hasUnread || !isHidden(popup)) {
		return;
	}

	const container = select('#NPG-item');
	empty(container);
	show(popup);

	// Fetch the notifications
	const notificationsPage = await fetch('/notifications', {
		credentials: 'include'
	}).then(r => r.text()).then(domify);
	const notificationsList = select.all('.boxed-group', notificationsPage);
	if (notificationsList.length === 0) {
		hide(popup);
		return;
	}
	container.append(...notificationsList);

	// Change tooltip direction
	for (const {classList} of select.all('.tooltipped-s', container)) {
		classList.remove('tooltipped-s');
		classList.add('tooltipped-n');
	}
}

function closePopup({target}) {
	const container = select('#NPG');
	if (!container.contains(target)) {
		hide(container);
	}
}

function init() {
	const indicator = select('a.notification-indicator');
	addNotificationsDropdown();

	indicator.addEventListener('mouseenter', openPopup);
	document.addEventListener('click', closePopup);
}

// Init everywhere but on the notifications page
if (!location.pathname.startsWith('/notifications')) {
	elementReady('.notification-indicator', init);
}
<|endoftext|>


<commit_before>var _ = require('underscore');
var request = require('request');
var Url = require('url');
var EventEmitter = require('events').EventEmitter;
var output = new EventEmitter();

function Crawler(opts){

	this.thread = opts.thread || 5;
	this.headers = opts.headers || {};
	this.depth = opts.depth || 1;
	this.logs = opts.logs || false;
	this.onSuccess = opts.onSuccess;
	this.onError = opts.onError;
	this.onFinished = opts.onFinished;

	this.inQueue = [];
	this.crawledUrls = [];
	this.discoveredUrls = [];
	this.active = [];

	this.onlyCrawl = opts.onlyCrawl || [];
	this.reject = opts.reject || [];
}

Crawler.prototype.log = function(status, url){
	if(this.logs)
		console.log('status : ', status, url);
}

Crawler.prototype.full = function(){
	return this.active.length >= this.thread;
}

Crawler.prototype.dequeue = function(){
	var next  = this.inQueue.shift();
	if(next){
		this.log('Dequeued : ', next.url);
		this.log("Loading url : ", next.url);
		this.load(next.url, next.depth);
	} else if(this.active.length == 0 && !next){
		this.log('Finished crawling :', '');

		if(this.onFinished){
			this.onFinished({crawled : this.crawledUrls, discovered : this.discoveredUrls});
		}

	}
}

Crawler.prototype.alreadyQueued = function(url){
	for (var i = 0; i < this.inQueue.length; i++) {
		if(this.inQueue[i].url == url){
			return true;
		}
	}
}

Crawler.prototype.alreadyCrawled = function(url){
	for (var i = 0; i < this.crawledUrls.length; i++) {
		if(this.crawledUrls[i] == url){
			return true;
		}

	};
}

Crawler.prototype.queue = function(url, depth){
	if(this.full() && !this.alreadyQueued(url) && !this.alreadyCrawled(url) && depth > 0){
		this.log('Adding url to queue : ', url);
		this.inQueue.push({url: url, depth : depth});
	} else if(this.alreadyCrawled(url)){
		this.log('Url already crawled : ', url );
	} else if(this.alreadyQueued(url) || depth < 1) {
		this.log('Url already exits or no depth :', url);
	} else {
		this.load(url, depth);
	}
}

Crawler.prototype.finished = function(url){
	var i = this.active.indexOf(url);
	this.active.splice(i, 1);
	// output.emit('crawlData', {crawled : this.crawledUrl})
	if(!this.full()){
		this.dequeue();
	}
}

Crawler.prototype.getLinks = function(baseUrl, body){
	var regex = /<a[^>]+?href=".*?"/gm;
 	var links = body.match(regex);

 	links = _.map(links, function(link){
 		var match = /href=\"(.*?)[#\"]/.exec(link);

 		link = match[1];
 		link = Url.resolve(baseUrl, link);
 		return link;
 	});

 	return _.chain(links)
 		.filter(function(url){
			if(this.onlyCrawl.length == 0){
 				return true;
			}
			else{
 				for (var i = 0; i < this.onlyCrawl.length; i++) {
 					if(url.indexOf(this.onlyCrawl[i]) > -1)
 						return true;
 				}
 			}
 		}.bind(this))
		.reject(function(url){
			if(this.reject.length > 0){
				for (var i = 0; i < this.reject.length; i++) {
 					if(url.indexOf(this.reject[i]) > -1)
 						return true;
 				}
			} else return false;
		}.bind(this))
 		.uniq()
 		.value();

}

Crawler.prototype.load = function(url, depth) {
	this.log('Loading url : ', url);
	this.active.push(url);

	try{
		request({url : url,headers : this.headers}, function(error, response, body){
			if(!error && response.statusCode === 200){
				if(this.onSuccess){
					this.onSuccess({
						url : url,
						status : response.statusCode,
						content : body,
						response : response,
						body : body
					});
				}
				this.log('Url successfully loaded', url);
				this.crawledUrls.push(url);
			 	_.each(this.getLinks(url, body), function(link){
			 		this.discoveredUrls.push(link);
			 		this.queue(link, depth - 1);
			 	}.bind(this));

			}else if(error){
				this.log('Error occured', error);
				if(this.onError && response){
					this.onError({
						url : url,
						status : response.statusCode || '400',
						error : error,
						content : body,
						response : response,
						body : body
					});
				}
			}
			this.finished(url);
		}.bind(this));
	}catch(e){
		this.log('Error occured', e.message);
		if(this.onError){
			this.onError({
				url : url,
				error : e.message
			});
		}
	}

}

Crawler.prototype.crawl = function(url){
	this.log('Starting crawl :', url);
	// console.log(this.depth);
	this.queue(url, this.depth);

}

module.exports = Crawler;
<commit_msg>Syntax + indent fix<commit_after>var _ = require('underscore');
var request = require('request');
var Url = require('url');
var EventEmitter = require('events').EventEmitter;
var output = new EventEmitter();

function Crawler(opts){

  this.thread = opts.thread || 5;
  this.headers = opts.headers || {};
  this.depth = opts.depth || 1;
  this.logs = opts.logs || false;
  this.onSuccess = opts.onSuccess;
  this.onError = opts.onError;
  this.onFinished = opts.onFinished;

  this.inQueue = [];
  this.crawledUrls = [];
  this.discoveredUrls = [];
  this.active = [];

  this.onlyCrawl = opts.onlyCrawl || [];
  this.reject = opts.reject || [];
}

Crawler.prototype.log = function(status, url){
  if(this.logs) {
    console.log('status : ', status, url);
  }
}

Crawler.prototype.full = function(){
  return this.active.length >= this.thread;
}

Crawler.prototype.dequeue = function(){
  var next  = this.inQueue.shift();
  if(next){
    this.log('Dequeued : ', next.url);
    this.load(next.url, next.depth);
  } else if(this.active.length == 0 && !next){
    this.log('Finished crawling :', '');

    if(this.onFinished){
      this.onFinished({crawled : this.crawledUrls, discovered : this.discoveredUrls});
    }

  }
}

Crawler.prototype.alreadyQueued = function(url){
  for (var i = 0; i < this.inQueue.length; i++) {
    if(this.inQueue[i].url == url){
      return true;
    }
  }
}

Crawler.prototype.alreadyCrawled = function(url){
  for (var i = 0; i < this.crawledUrls.length; i++) {
    if(this.crawledUrls[i] == url){
      return true;
    }

  };
}

Crawler.prototype.queue = function(url, depth){
  if(this.full() && !this.alreadyQueued(url) && !this.alreadyCrawled(url) && depth > 0){
    this.log('Adding url to queue : ', url);
    this.inQueue.push({url: url, depth : depth});
  } else if(this.alreadyCrawled(url)){
    this.log('Url already crawled : ', url );
  } else if(this.alreadyQueued(url) || depth < 1) {
    this.log('Url already exits or no depth :', url);
  } else {
    this.load(url, depth);
  }
}

Crawler.prototype.finished = function(url){
  var i = this.active.indexOf(url);
  this.active.splice(i, 1);
  if(!this.full()){
    this.dequeue();
  }
}

Crawler.prototype.getLinks = function(baseUrl, body){
  var regex = /<a[^>]+?href=".*?"/gm;
  var links = body.match(regex);

  links = _.map(links, function(link){
    var match = /href=\"(.*?)[#\"]/.exec(link);
    link = match[1];
    link = Url.resolve(baseUrl, link);
    return link;
  });

  return _.chain(links)
          .filter(function(url){
            if(this.onlyCrawl.length == 0){
              return true;
            }
            else{
              for (var i = 0; i < this.onlyCrawl.length; i++) {
                if(url.indexOf(this.onlyCrawl[i]) > -1) {
                  return true;
                }

              }
            }
          }.bind(this))
          .reject(function(url){
            if(this.reject.length > 0){
              for (var i = 0; i < this.reject.length; i++) {
                if(url.indexOf(this.reject[i]) > -1){
                  return true;
                }
              }
            } else {
              return false;
            }
          }.bind(this))
          .uniq()
          .value();

}

Crawler.prototype.load = function(url, depth) {
  this.log('Loading url : ', url);
  this.active.push(url);

  try{
    request({url : url,headers : this.headers}, function(error, response, body){
      if(!error && response.statusCode === 200){
        if(this.onSuccess){
          this.onSuccess({
            url : url,
            status : response.statusCode,
            content : body,
            response : response,
            body : body
          });
        }
        this.log('Url successfully loaded', url);
        this.crawledUrls.push(url);
        _.each(this.getLinks(url, body), function(link){
          this.discoveredUrls.push(link);
          this.queue(link, depth - 1);
        }.bind(this));

      }else if(error){
        this.log('Error occured', error);
        if(this.onError && response){
          this.onError({
            url : url,
            status : response.statusCode || '400',
            error : error,
            content : body,
            response : response,
            body : body
          });
        }
      }
      this.finished(url);
    }.bind(this));
  }catch(e){
    this.log('Error occured', e.message);
    if(this.onError){
      this.onError({
        url : url,
        error : e.message
      });
    }
  }

}

Crawler.prototype.crawl = function(url){
  this.log('Starting crawl :', url);
  // console.log(this.depth);
  this.queue(url, this.depth);

}

module.exports = Crawler;
<|endoftext|>


<commit_before>const styles = require('./styles');
const React = require('react-native');
const { Dimensions, Animated, } = React;
const deviceScreen = Dimensions.get('window');

const {
  PanResponder,
  View,
  TouchableWithoutFeedback,
  Component,
} = React;

/**
 * Default open menu offset. Describes a size of the amount you can
 * move content view from the left and release without opening it
 * @type {Number}
 */
const openMenuOffset = deviceScreen.width * 2 / 3;

/**
 * Content view offset in the `hidden` state
 * @type {Number}
 */
const hiddenMenuOffset = 0;

/**
 * Size of the amount you can move content view in the opened menu state and
 * release without menu closing
 * @type {Number}
 */
const barrierForward = deviceScreen.width / 4;

/**
 * Check if the current gesture offset bigger than allowed one
 * before opening menu
 * @param  {Number} dx Gesture offset from the left side of the window
 * @return {Boolean}
 */
function shouldOpenMenu(dx: Number) {
  return dx > barrierForward;
}

class SideMenu extends Component {
  constructor(props) {
    super(props);
    /**
     * Current state of the menu, whether it is open or not
     * @type {Boolean}
     */
    this.isOpen = false;

    /**
     * Default left offset for content view
     * @todo Check if it's possible to avoid using `prevLeft`
     * @type {Number}
     */
    this.prevLeft = 0;

    this.state = {
      left: new Animated.Value(0),
    };
  }

  /**
   * Set the initial responders
   * @return {Void}
   */
  componentWillMount() {
    this.responder = PanResponder.create({
      onMoveShouldSetPanResponder: this.handleMoveShouldSetPanResponder.bind(this),
      onPanResponderMove: this.handlePanResponderMove.bind(this),
      onPanResponderRelease: this.handlePanResponderEnd.bind(this),
    });
  }

  /**
   * Determines if gestures are enabled, based off of disableGestures prop
   * @return {Boolean}
   */
  gesturesAreEnabled() {
    let { disableGestures, } = this.props;

    if (typeof disableGestures === 'function') {
      return !disableGestures();
    } else {
      return !disableGestures;
    }
  }

  /**
   * Permission to use responder
   * @return {Boolean}
   */
  handleMoveShouldSetPanResponder(e: Object, gestureState: Object) {
    if (this.gesturesAreEnabled()) {
      const x = Math.round(Math.abs(gestureState.dx));
      const y = Math.round(Math.abs(gestureState.dy));

      return x > this.props.toleranceX && y < this.props.toleranceY;
    } else {
      return false;
    }
  }

  /**
   * Handler on responder move
   * @param  {Synthetic Event} e
   * @param  {Object} gestureState
   * @return {Void}
   */
  handlePanResponderMove(e: Object, gestureState: Object) {
    if (this.menuPositionMultiplier() *
      this.state.left.__getValue() + gestureState.dx >= 0) {
      this.state.left.setValue(this.prevLeft + gestureState.dx);
    }
  }

  /**
   * Handler on responder move ending
   * @param  {Synthetic Event} e
   * @param  {Object} gestureState
   * @return {Void}
   */
  handlePanResponderEnd(e: Object, gestureState: Object) {
    const currentLeft = this.state.left.__getValue();

    const shouldOpen = this.menuPositionMultiplier() *
      (currentLeft + gestureState.dx);

    if (shouldOpenMenu(shouldOpen)) {
      this.openMenu();
    } else {
      this.closeMenu();
    }
  }

  /**
   * Returns 1 or -1 depending on the menuPosition
   * @return {Number}
   */
  menuPositionMultiplier() {
    return this.props.menuPosition === 'right' ? -1 : 1;
  }

  /**
   * Open menu
   * @return {Void}
   */
  openMenu() {
    const openOffset = this.menuPositionMultiplier() *
      (this.props.openMenuOffset || openMenuOffset);

    this.props
      .animationFunction(this.state.left, openOffset)
      .start();

    this.prevLeft = openOffset;

    if (!this.isOpen) {
      this.props.onChange(this.isOpen);

      this.isOpen = true;

      // Force update to make the overlay appear (if touchToClose is set)
      if (this.props.touchToClose) {
        this.forceUpdate();
      }
    }
  }

  /**
   * Close menu
   * @return {Void}
   */
  closeMenu() {
    const closeOffset = this.menuPositionMultiplier() *
      (this.props.hiddenMenuOffset || hiddenMenuOffset);

    this.props
      .animationFunction(this.state.left, closeOffset)
      .start();

    this.prevLeft = closeOffset;

    if (this.isOpen) {
      this.props.onChange(this.isOpen);

      this.isOpen = false;
      // Force update to make the overlay disappear (if touchToClose is set)
      if (this.props.touchToClose) {
        this.forceUpdate();
      }
    }
  }

  /**
   * Toggle menu
   * @return {Void}
   */
  toggleMenu() {
    if (this.isOpen) {
      this.closeMenu();
    } else {
      this.openMenu();
    }
  }

  /**
   * Get content view. This view will be rendered over menu
   * @return {React.Component}
   */
  getContentView() {
    const menuActions = this.getMenuActions();

    let overlay = null;

    if (this.isOpen && this.props.touchToClose) {
      overlay = (
        <TouchableWithoutFeedback onPress={this.closeMenu.bind(this)}>
          <View style={styles.overlay} />
        </TouchableWithoutFeedback>
      );
    }

    const children = React.Children.map(this.props.children,
      (child) => React.cloneElement(child, { menuActions, }));

    return (
      <Animated.View
        style={[styles.frontView, {
          transform: [{
            translateX: this.state.left,
          }],
        }, ]}
        ref={(sideMenu) => this.sideMenu = sideMenu}
        {...this.responder.panHandlers}>
        {children}
        {overlay}
      </Animated.View>
    );
  }

  /**
   * Get menu actions to expose it to
   * menu and children components
   * @return {Object} Public API methods
   */
  getMenuActions() {
    return {
      close: this.closeMenu.bind(this),
      toggle: this.toggleMenu.bind(this),
      open: this.openMenu.bind(this),
    };
  }

  /**
   * Get menu view. This view will be rendered under
   * content view. Also, this function will decorate
   * passed `menu` component with side menu API
   * @return {React.Component}
   */
  getMenuView() {
    const menuActions = this.getMenuActions();

    return (
      <View style={styles.menu}>
        {React.addons.cloneWithProps(this.props.menu, { menuActions, })}
      </View>
    );
  }

  /**
   * Compose and render menu and content view
   * @return {React.Component}
   */
  render() {
    return (
      <View style={styles.container}>
        {this.getMenuView()}
        {this.getContentView()}
      </View>
    );
  }
}

SideMenu.propTypes = {
  toleranceX: React.PropTypes.number,
  toleranceY: React.PropTypes.number,
  onChange: React.PropTypes.func,
  touchToClose: React.PropTypes.bool,
  disableGestures: React.PropTypes.oneOf([React.PropTypes.func, React.PropTypes.bool]),
  animationFunction: React.PropTypes.func,
};

SideMenu.defaultProps = {
  toleranceY: 10,
  toleranceX: 10,
  touchToClose: false,
  onChange: () => {},
  animationFunction: (prop, value) => {
    return Animated.spring(
      prop,
      {
        toValue: value,
        friction: 8,
      }
    )
  }
};

module.exports = SideMenu;
<commit_msg>Support animationStyle function<commit_after>const styles = require('./styles');
const React = require('react-native');
const { Dimensions, Animated, } = React;
const deviceScreen = Dimensions.get('window');

const {
  PanResponder,
  View,
  TouchableWithoutFeedback,
  Component,
} = React;

/**
 * Default open menu offset. Describes a size of the amount you can
 * move content view from the left and release without opening it
 * @type {Number}
 */
const openMenuOffset = deviceScreen.width * 2 / 3;

/**
 * Content view offset in the `hidden` state
 * @type {Number}
 */
const hiddenMenuOffset = 0;

/**
 * Size of the amount you can move content view in the opened menu state and
 * release without menu closing
 * @type {Number}
 */
const barrierForward = deviceScreen.width / 4;

/**
 * Check if the current gesture offset bigger than allowed one
 * before opening menu
 * @param  {Number} dx Gesture offset from the left side of the window
 * @return {Boolean}
 */
function shouldOpenMenu(dx: Number) {
  return dx > barrierForward;
}

class SideMenu extends Component {
  constructor(props) {
    super(props);
    /**
     * Current state of the menu, whether it is open or not
     * @type {Boolean}
     */
    this.isOpen = false;

    /**
     * Default left offset for content view
     * @todo Check if it's possible to avoid using `prevLeft`
     * @type {Number}
     */
    this.prevLeft = 0;

    this.state = {
      left: new Animated.Value(0),
    };
  }

  /**
   * Set the initial responders
   * @return {Void}
   */
  componentWillMount() {
    this.responder = PanResponder.create({
      onMoveShouldSetPanResponder: this.handleMoveShouldSetPanResponder.bind(this),
      onPanResponderMove: this.handlePanResponderMove.bind(this),
      onPanResponderRelease: this.handlePanResponderEnd.bind(this),
    });
  }

  /**
   * Determines if gestures are enabled, based off of disableGestures prop
   * @return {Boolean}
   */
  gesturesAreEnabled() {
    let { disableGestures, } = this.props;

    if (typeof disableGestures === 'function') {
      return !disableGestures();
    } else {
      return !disableGestures;
    }
  }

  /**
   * Permission to use responder
   * @return {Boolean}
   */
  handleMoveShouldSetPanResponder(e: Object, gestureState: Object) {
    if (this.gesturesAreEnabled()) {
      const x = Math.round(Math.abs(gestureState.dx));
      const y = Math.round(Math.abs(gestureState.dy));

      return x > this.props.toleranceX && y < this.props.toleranceY;
    } else {
      return false;
    }
  }

  /**
   * Handler on responder move
   * @param  {Synthetic Event} e
   * @param  {Object} gestureState
   * @return {Void}
   */
  handlePanResponderMove(e: Object, gestureState: Object) {
    if (this.menuPositionMultiplier() *
      this.state.left.__getValue() + gestureState.dx >= 0) {
      this.state.left.setValue(this.prevLeft + gestureState.dx);
    }
  }

  /**
   * Handler on responder move ending
   * @param  {Synthetic Event} e
   * @param  {Object} gestureState
   * @return {Void}
   */
  handlePanResponderEnd(e: Object, gestureState: Object) {
    const currentLeft = this.state.left.__getValue();

    const shouldOpen = this.menuPositionMultiplier() *
      (currentLeft + gestureState.dx);

    if (shouldOpenMenu(shouldOpen)) {
      this.openMenu();
    } else {
      this.closeMenu();
    }
  }

  /**
   * Returns 1 or -1 depending on the menuPosition
   * @return {Number}
   */
  menuPositionMultiplier() {
    return this.props.menuPosition === 'right' ? -1 : 1;
  }

  /**
   * Open menu
   * @return {Void}
   */
  openMenu() {
    const openOffset = this.menuPositionMultiplier() *
      (this.props.openMenuOffset || openMenuOffset);

    this.props
      .animationFunction(this.state.left, openOffset)
      .start();

    this.prevLeft = openOffset;

    if (!this.isOpen) {
      this.props.onChange(this.isOpen);

      this.isOpen = true;

      // Force update to make the overlay appear (if touchToClose is set)
      if (this.props.touchToClose) {
        this.forceUpdate();
      }
    }
  }

  /**
   * Close menu
   * @return {Void}
   */
  closeMenu() {
    const closeOffset = this.menuPositionMultiplier() *
      (this.props.hiddenMenuOffset || hiddenMenuOffset);

    this.props
      .animationFunction(this.state.left, closeOffset)
      .start();

    this.prevLeft = closeOffset;

    if (this.isOpen) {
      this.props.onChange(this.isOpen);

      this.isOpen = false;
      // Force update to make the overlay disappear (if touchToClose is set)
      if (this.props.touchToClose) {
        this.forceUpdate();
      }
    }
  }

  /**
   * Toggle menu
   * @return {Void}
   */
  toggleMenu() {
    if (this.isOpen) {
      this.closeMenu();
    } else {
      this.openMenu();
    }
  }

  /**
   * Get content view. This view will be rendered over menu
   * @return {React.Component}
   */
  getContentView() {
    const menuActions = this.getMenuActions();

    let overlay = null;

    if (this.isOpen && this.props.touchToClose) {
      overlay = (
        <TouchableWithoutFeedback onPress={this.closeMenu.bind(this)}>
          <View style={styles.overlay} />
        </TouchableWithoutFeedback>
      );
    }

    const children = React.Children.map(this.props.children,
      (child) => React.cloneElement(child, { menuActions, }));

    return (
      <Animated.View
        style={[styles.frontView, this.props.animationStyle(this.state.left)]}
        ref={(sideMenu) => this.sideMenu = sideMenu}
        {...this.responder.panHandlers}>
        {children}
        {overlay}
      </Animated.View>
    );
  }

  /**
   * Get menu actions to expose it to
   * menu and children components
   * @return {Object} Public API methods
   */
  getMenuActions() {
    return {
      close: this.closeMenu.bind(this),
      toggle: this.toggleMenu.bind(this),
      open: this.openMenu.bind(this),
    };
  }

  /**
   * Get menu view. This view will be rendered under
   * content view. Also, this function will decorate
   * passed `menu` component with side menu API
   * @return {React.Component}
   */
  getMenuView() {
    const menuActions = this.getMenuActions();

    return (
      <View style={styles.menu}>
        {React.addons.cloneWithProps(this.props.menu, { menuActions, })}
      </View>
    );
  }

  /**
   * Compose and render menu and content view
   * @return {React.Component}
   */
  render() {
    return (
      <View style={styles.container}>
        {this.getMenuView()}
        {this.getContentView()}
      </View>
    );
  }
}

SideMenu.propTypes = {
  toleranceX: React.PropTypes.number,
  toleranceY: React.PropTypes.number,
  onChange: React.PropTypes.func,
  touchToClose: React.PropTypes.bool,
  disableGestures: React.PropTypes.oneOf([React.PropTypes.func, React.PropTypes.bool]),
  animationFunction: React.PropTypes.func,
};

SideMenu.defaultProps = {
  toleranceY: 10,
  toleranceX: 10,
  touchToClose: false,
  onChange: () => {},
  animationStyle: function(prop) {
    return {
      transform: [{
        translateX: prop,
      }],
    };
  },
  animationFunction: (prop, value) => {
    return Animated.spring(
      prop,
      {
        toValue: value,
        friction: 8,
      }
    )
  }
};

module.exports = SideMenu;
<|endoftext|>


<commit_before>'use strict'
var cont = require('cont')
var pull = require('pull-stream')
var PullCont = require('pull-cont')
var path = require('path')
var Obv = require('obv')
//take a log, and return a log driver.
//the log has an api with `read`, `get` `since`

var wrap = require('./wrap')

function map(obj, iter) {
  var o = {}
  for(var k in obj)
    o[k] = iter(obj[k], k, obj)
  return o
}

module.exports = function (log, isReady) {
  var views = []
  var meta = {}
  var closed = false

  log.get = count(log.get, 'get')
//  log.stream = count(log.stream, 'stream')

  function count (fn, name) {
    meta[name] = meta[name] || 0
    return function (a, b) {
      meta[name] ++
      fn.call(this, a, b)
    }
  }

  var ready = Obv()
  ready.set(isReady !== undefined ? isReady : true)
  var flume = {
    dir: log.filename ? path.dirname(log.filename) : null,
    //stream from the log
    since: log.since,
    ready: ready,
    meta: meta,
    append: function (value, cb) {
      return log.append(value, cb)
    },
    stream: function (opts) {
      return PullCont(function (cb) {
        log.since.once(function () {
          cb(null, log.stream(opts))
        })
      })
    },
    get: function (seq, cb) {
      log.since.once(function () {
        log.get(seq, cb)
      })
    },
    use: function (name, createView) {
      if(~Object.keys(flume).indexOf(name))
        throw new Error(name + ' is already in use!')

      var sv = createView(log, name)

      views[name] = flume[name] = wrap(sv, log.since, ready)
      meta[name] = flume[name].meta
      sv.since.once(function (upto) {
        pull(
          log.stream({gt: upto, live: true, seqs: true, values: true}),
          sv.createSink(function (err) {
            if(err && !closed) console.error(err)
          })
        )
      })

      return flume
    },
    rebuild: function (cb) {
      return cont.para(map(views, function (sv) {
        return function (cb) {
          sv.destroy(function (err) {
            if(err) return cb(err)
            sv.since.once(function (upto) {
              pull(
                log.stream({gt: upto, live: true, seqs: true, values: true}),
                sv.createSink(function (err) {
                  if(err) console.error(err)
                })
              )
            })
          })
        }
      }))
      (function (err) {
        if(err) cb(err) //hopefully never happens

        //then restream each streamview, and callback when it's uptodate with the main log.
      })
    },
    close: function (cb) {
      if(closed) throw new Error('already closed')
      closed = true
      cont.para(map(views, function (sv, k) {
        return function (cb) {
          if(sv.close) sv.close(cb)
          else cb()
        }
      })) (cb)

    }
  }
  return flume
}

<commit_msg>expose .closed property, so can check whether database is closed<commit_after>'use strict'
var cont = require('cont')
var pull = require('pull-stream')
var PullCont = require('pull-cont')
var path = require('path')
var Obv = require('obv')
//take a log, and return a log driver.
//the log has an api with `read`, `get` `since`

var wrap = require('./wrap')

function map(obj, iter) {
  var o = {}
  for(var k in obj)
    o[k] = iter(obj[k], k, obj)
  return o
}

module.exports = function (log, isReady) {
  var views = []
  var meta = {}

  log.get = count(log.get, 'get')

  function count (fn, name) {
    meta[name] = meta[name] || 0
    return function (a, b) {
      meta[name] ++
      fn.call(this, a, b)
    }
  }

  var ready = Obv()
  ready.set(isReady !== undefined ? isReady : true)
  var flume = {
    closed: false,
    dir: log.filename ? path.dirname(log.filename) : null,
    //stream from the log
    since: log.since,
    ready: ready,
    meta: meta,
    append: function (value, cb) {
      return log.append(value, cb)
    },
    stream: function (opts) {
      return PullCont(function (cb) {
        log.since.once(function () {
          cb(null, log.stream(opts))
        })
      })
    },
    get: function (seq, cb) {
      log.since.once(function () {
        log.get(seq, cb)
      })
    },
    use: function (name, createView) {
      if(~Object.keys(flume).indexOf(name))
        throw new Error(name + ' is already in use!')

      var sv = createView(log, name)

      views[name] = flume[name] = wrap(sv, log.since, ready)
      meta[name] = flume[name].meta
      sv.since.once(function (upto) {
        pull(
          log.stream({gt: upto, live: true, seqs: true, values: true}),
          sv.createSink(function (err) {
            if(err && !flume.closed) console.error(err)
          })
        )
      })

      return flume
    },
    rebuild: function (cb) {
      return cont.para(map(views, function (sv) {
        return function (cb) {
          sv.destroy(function (err) {
            if(err) return cb(err)
            sv.since.once(function (upto) {
              pull(
                log.stream({gt: upto, live: true, seqs: true, values: true}),
                sv.createSink(function (err) {
                  if(err) console.error(err)
                })
              )
            })
          })
        }
      }))
      (function (err) {
        if(err) cb(err) //hopefully never happens

        //then restream each streamview, and callback when it's uptodate with the main log.
      })
    },
    close: function (cb) {
      if(flume.closed) throw new Error('already closed')
      flume.closed = true
      cont.para(map(views, function (sv, k) {
        return function (cb) {
          if(sv.close) sv.close(cb)
          else cb()
        }
      })) (cb)

    }
  }
  return flume
}

<|endoftext|>


<commit_before>'use strict';
var os = require('os'),
empty = '(' + os.EOL + ')';
console.log('Welcome to Ramda REPL!\n');

module.exports = function() {
	var repl = require('repl').start({'prompt': 'λ > '});

	require('repl.history')(repl, process.env.HOME + '/.ramda_history');

	var R = repl.context.R = require('ramda');

	for (var key in R){
		if (R.hasownProperty(key)) {
			repl.context[key] = R[key];
		}
	}

	var F = repl.context.fantasy =  require('ramda-fantasy');

	R.map(function(f){repl.context[f] = F[f]},R.keys(F))
};

<commit_msg>Avoid overriding.<commit_after>'use strict';
var os = require('os'),
empty = '(' + os.EOL + ')',
has = Object.prototype.hasOwnProperty;
console.log('Welcome to Ramda REPL!\n');

module.exports = function() {
	var repl = require('repl').start({'prompt': 'λ > '});

	require('repl.history')(repl, process.env.HOME + '/.ramda_history');

	var R = repl.context.R = require('ramda');

	for (var key in R){
		if (has.call(R, key)) {
			repl.context[key] = R[key];
		}
	}

	var F = repl.context.fantasy =  require('ramda-fantasy');

	R.map(function(f){repl.context[f] = F[f]},R.keys(F))
};

<|endoftext|>