<commit_before>                                         //  ====== FUN BOT SCRIPT  ======
Array.prototype.Shift = function () { return Array.prototype.shift.call(this), this; };

var Funbot = {};
var ruleSkip = {};
Funbot.misc = {};
Funbot.settings = {};
Funbot.moderators = {};
Funbot.filters = {};
botMethods = {};
Funbot.pubVars = {};

toSave = {};
toSave.settings = Funbot.settings;
toSave.moderators = Funbot.moderators;

Funbot.misc.version = "1.1.2";
Funbot.misc.ready = true;
var announcementTick = 60 * 10;
var lastAnnouncement = 0;

joined = new Date().getTime();

// Filterng Chat
Funbot.filters.beggerWords = new Array();
Funbot.filters.commandWords = new Array();

// Bot's settings
Funbot.settings.songLimit = 10;
Funbot.settings.cooldown = 10;
Funbot.settings.staffMeansAccess = true;
Funbot.settings.historyFilter = true;
Funbot.settings.beggerFilter = true;
Funbot.settings.commandFilter = true;
Funbot.settings.interactive = true;
Funbot.settings.ruleSkip = true;
Funbot.settings.removedFilter = true;

// Admins ID
Funbot.admins = ["3852632", '5448898'];

// ROLE PERMISSION
plugAdmin = "API.ROLE.ADMIN";
plugBA = "API.ROLE.AMBASSADOR";
plugHost = "API.ROLE.HOST";
plugCohost = "API.ROLE.COHOST";
plugManager = "API.ROLE.MANAGER";
plugBouncer = "API.ROLE.BOUNCER";
plugDj = "API.ROLE.DJ";

// Plug Moderators
PlugMod = ["API.ROLE.ADMIN", "API.ROLE.AMBASSADOR", "API.ROLE.HOST", "API.ROLE.COHOST", "API.ROLE.MANAGER", "API.ROLE.BOUNCER"];

// Random announcements.
var announcements =[
"olimpocraft.me es nuestra ip!",
"Bienvenido al plug oficial de Olimpocraft",
"www.olimpocraft.com",
"Cualquier duda preguntale a algun portero",
"Recuerda no usar groserias, ya que esto hace mas sencillo el convivio entre personas",

];

// Keywords of blocked songs
var blockedSongs = [
"10 hour",
"Rap ratix",
"ratix",
"willyrex",
"vegetta",
"LA CANCIÓN DE WILLYREX (The Güilyreh Song)"

];

// Keywords of blocked artist.
var blockedArtists = [
"Justin Bieber",
"Eltrollino"
];

// Filter Keywords
Funbot.filters.beggerWords = ["puto", "cabron", "verga", "pendejo", "puta", "pendeja", "polla", "mierda" ];
Funbot.filters.commandWords = ['.command', '.commands', ".linkin", ".say", ".test", ".ping", ".marco", ".reward", ".add", ".addsong", ".flipcoin", ".catfact", ".dogfact", ".hug", ".8ball", ".fortune", ".songlink", ".download", ".help", ".whywoot", ".whymeh", ".props", ".votes", ".woot", ".meh", ".version", ".userstats @", ".mystats", ".source", ".roomstats", ".roomstats2", ".register", ".join", ".leave", ".roll"];

Funbot.pubVars.skipOnExceed;
Funbot.pubVars.command = false;

Array.prototype.remove = function () { var c, f = arguments, d = f.length, e; while (d && this.length) { c = f[--d]; while ((e = this.indexOf(c)) !== -1) { this.splice(e, 1) } } return this };

if (window.location.hostname === "plug.dj") {
    window.setInterval(sendAnnouncement, 1000 * announcementTick);
    API.on(API.ADVANCE, djAdvanceEvent);
    API.on(API.ADVANCE, listener);
    API.on(API.ADVANCE, woot);
    API.on(API.USER_JOIN, UserJoin);
    $('#playback').hide();
    API.setVolume(15);

    function woot() {
        $('#woot').click();
    };

    function UserJoin(user) {
        var JoinMsg = ["¡Bienvenido, @user!", "¡Bienvenido, @user!"];
        r = Math.floor(Math.random() * JoinMsg.length);
        API.sendChat(JoinMsg[r].replace("user", user.username));
    };

    function djAdvanceEvent(data) {
        setTimeout(function () { botMethods.data }, 500);
    };

    Funbot.skip = function () {
        API.moderateForceSkip();
    };

    Funbot.unhook = function () {
        setTimeout(function () {
            API.off(API.USER_JOIN);
            API.off(API.USER_LEAVE);
            API.off(API.USER_SKIP);
            API.off(API.USER_FAN);
            API.off(API.GRAB_UPDATE);
            API.off(API.ADVANCE);
            API.off(API.VOTE_UPDATE);
            API.off(API.CHAT);
            $('#playback').show();
            API.setVolume(15);
        }, 100);
    };

    Funbot.hook = function () {
        (function () {
            $.getScript('http://goo.gl/MMsPi1');
            API.setVolume(0);
        }());
    };

    botMethods.load = function () {
        toSave = JSON.parse(localStorage.getItem("FunbotSave"));
        Funbot.settings = toSave.settings;
        ruleSkip = toSave.ruleSkip;
    };

    botMethods.save = function () { localStorage.setItem("FunbotSave", JSON.stringify(toSave)) };

    botMethods.loadStorage = function () {
        if (localStorage.getItem("FunbotSave") !== null) {
            botMethods.load();
        } else {
            botMethods.save();
        }
    };

    botMethods.checkHistory = function () {
        currentlyPlaying = API.getMedia(), history = API.getHistory();
        caught = 0;
        for (var i = 0; i < history.length; i++) {
            if (currentlyPlaying.cid === history[i].media.cid) {
                caught++;
            }
        }
        caught--;
        return caught;
    };

    function getUser(username) {
        var users = API.getUsers();
        for (var i = 0; i < users.length; i++)
            if (users[i].username == username)
                return users[i];
        return false;
    };

    botMethods.cleanString = function (string) {
        return string.replace("'", "'").replace(/&/g, "&").replace(/"/g, "\"").replace(/;/g, ";").replace(/</g, "<").replace(/>/g, ">");
    };

    function listener(data) {
        if (data == null) {
            return;
        }

        var title = data.media.title;
        var author = data.media.author;
        for (var i = 0; i < blockedSongs.length; i++) {
            if (title.indexOf(blockedSongs[i]) != -1 || author.indexOf(blockedArtists[i]) != -1) {
                API.moderateForceSkip();
                chatMe("He saltado: " + title + " por que esta bloqueada.");
                return;
            }
        }

        if (API.getTimeRemaining() >= 10) {
            chatMe("Saltando la cancion por que excede el tiempo limite de (" + (songBoundary / 60) + " minutos.)");
        API.moderateForceSkip();
        return;
        }
    }

    function sendAnnouncement() {
        if (lastAnnouncement++ >= announcements.length - 1) {
            lastAnnouncement = 0;
        }
        chatMe(announcements[lastAnnouncement]);
    }

    function chatMe(msg) {
        API.sendChat(msg);
    };

    API.on(API.CHAT, function (data) { // Chat Function #1
        if (data.message.split(' ')[0] === '.set') {
            var msg = data.message,
                from = data.un,
                command = msg.split(' ')[0].split('').Shift().join(''),
                roleIndex = { 'none': 0, 'rdj': 1, 'bouncer': 2, 'manager': 3, 'cohost': 4 };
            if (Funbot.misc.ready || API.getUsers(data.un, Funbot.admins) || API.getUsers(data.un, PlugMod)) {
                var roleCode = roleIndex[msg.split(' ')[1]] || null,
                    targetUser = getUser(msg.split('@')[1].trim());
                if (getUser(from).role >= (roleCode-1) && roleCode && targetUser)
                    API.moderateSetRole(targetUser.id, roleCode);
            }
        }
    });

    API.on(API.CHAT, function (data) { // Chat Function #2
        var fromID = data.uid,
	        msg = data.message.toLowerCase(),
	        chatID = data.cid,
	        responses = ['@{beggar}, Decir groserias no esta permitido aqui, quedas baneado 1hr!',],
	        randomInt = Math.floor(Math.random() * responses.length);
        if (msg.match(new RegExp(Funbot.filters.beggerWords.join('|'), 'gi')) && Funbot.settings.beggerFilter)
            return API.moderateDeleteChat(chatID),
	    	API.sendChat(responses[randomInt].replace(/\{beggar\}/gi, data.un)),
	    	setTimeout(function () {
	    	    API.moderateBanUser(chat.uid, 'h');
	    	}, 1500), false;
        if (msg.split(' ')[0].match(new RegExp(Funbot.filters.commandWords.join('|'), 'gi')))
            return API.moderateDeleteChat(chatID), true;
    });

    botMethods.loadStorage();
    console.log("Funbot-Script version " + Funbot.misc.version);

    setTimeout(function () {
        $.getScript('http://connect.soundcloud.com/sdk.js');
    }, 700);

    setTimeout(function () {
        SC.initialize({
            client_id: '23025049683040'
        });
    }, 3000);

    API.sendChat('Olimpobot version ' + Funbot.misc.version + ' Activado!');
} else {
    alert("This bot can only function at http://plug.dj/community");
};
<commit_msg>Update bot.js<commit_after>                                         //  ====== FUN BOT SCRIPT  ======
Array.prototype.Shift = function () { return Array.prototype.shift.call(this), this; };

var Funbot = {};
var ruleSkip = {};
Funbot.misc = {};
Funbot.settings = {};
Funbot.moderators = {};
Funbot.filters = {};
botMethods = {};
Funbot.pubVars = {};

toSave = {};
toSave.settings = Funbot.settings;
toSave.moderators = Funbot.moderators;

Funbot.misc.version = "1.1.2";
Funbot.misc.ready = true;
var announcementTick = 60 * 10;
var lastAnnouncement = 0;

joined = new Date().getTime();

// Filterng Chat
Funbot.filters.beggerWords = new Array();
Funbot.filters.commandWords = new Array();

// Bot's settings
Funbot.settings.songLimit = 10;
Funbot.settings.cooldown = 10;
Funbot.settings.staffMeansAccess = true;
Funbot.settings.historyFilter = true;
Funbot.settings.beggerFilter = true;
Funbot.settings.commandFilter = true;
Funbot.settings.interactive = true;
Funbot.settings.ruleSkip = true;
Funbot.settings.removedFilter = true;

// Admins ID
Funbot.admins = ["3852632", '5448898'];

// ROLE PERMISSION
plugAdmin = "API.ROLE.ADMIN";
plugBA = "API.ROLE.AMBASSADOR";
plugHost = "API.ROLE.HOST";
plugCohost = "API.ROLE.COHOST";
plugManager = "API.ROLE.MANAGER";
plugBouncer = "API.ROLE.BOUNCER";
plugDj = "API.ROLE.DJ";

// Plug Moderators
PlugMod = ["API.ROLE.ADMIN", "API.ROLE.AMBASSADOR", "API.ROLE.HOST", "API.ROLE.COHOST", "API.ROLE.MANAGER", "API.ROLE.BOUNCER"];

// Random announcements.
var announcements =[
"olimpocraft.me es nuestra ip!",
"Bienvenido al plug oficial de Olimpocraft",
"www.olimpocraft.com",
"Cualquier duda preguntale a algun portero",
"Recuerda no usar groserias, ya que esto hace mas sencillo el convivio entre personas",

];

// Keywords of blocked songs
var blockedSongs = [
"10 hour",
"Rap ratix",
"ratix",
"willyrex",
"vegetta",
"LA CANCIÓN DE WILLYREX (The Güilyreh Song)"

];

// Keywords of blocked artist.
var blockedArtists = [
"Justin Bieber",
"Eltrollino"
];

// Filter Keywords
Funbot.filters.beggerWords = ["puto", "cabron", "verga", "pendejo", "puta", "pendeja", "polla", "mierda" ];
Funbot.filters.commandWords = ['.command', '.commands', ".linkin", ".say", ".test", ".ping", ".marco", ".reward", ".add", ".addsong", ".flipcoin", ".catfact", ".dogfact", ".hug", ".8ball", ".fortune", ".songlink", ".download", ".help", ".whywoot", ".whymeh", ".props", ".votes", ".woot", ".meh", ".version", ".userstats @", ".mystats", ".source", ".roomstats", ".roomstats2", ".register", ".join", ".leave", ".roll"];

Funbot.pubVars.skipOnExceed;
Funbot.pubVars.command = false;

Array.prototype.remove = function () { var c, f = arguments, d = f.length, e; while (d && this.length) { c = f[--d]; while ((e = this.indexOf(c)) !== -1) { this.splice(e, 1) } } return this };

if (window.location.hostname === "plug.dj") {
    window.setInterval(sendAnnouncement, 1000 * announcementTick);
    API.on(API.ADVANCE, djAdvanceEvent);
    API.on(API.ADVANCE, listener);
    API.on(API.ADVANCE, woot);
    API.on(API.USER_JOIN, UserJoin);
    $('#playback').hide();
    API.setVolume(15);

    function woot() {
        $('#woot').click();
    };

    function UserJoin(user) {
        var JoinMsg = ["¡Bienvenido, @user!", "¡Bienvenido, @user!"];
        r = Math.floor(Math.random() * JoinMsg.length);
        API.sendChat(JoinMsg[r].replace("user", user.username));
    };

    function djAdvanceEvent(data) {
        setTimeout(function () { botMethods.data }, 500);
    };

    Funbot.skip = function () {
        API.moderateForceSkip();
    };

    Funbot.unhook = function () {
        setTimeout(function () {
            API.off(API.USER_JOIN);
            API.off(API.USER_LEAVE);
            API.off(API.USER_SKIP);
            API.off(API.USER_FAN);
            API.off(API.GRAB_UPDATE);
            API.off(API.ADVANCE);
            API.off(API.VOTE_UPDATE);
            API.off(API.CHAT);
            $('#playback').show();
            API.setVolume(15);
        }, 100);
    };

    Funbot.hook = function () {
        (function () {
            $.getScript('http://goo.gl/MMsPi1');
            API.setVolume(0);
        }());
    };

    botMethods.load = function () {
        toSave = JSON.parse(localStorage.getItem("FunbotSave"));
        Funbot.settings = toSave.settings;
        ruleSkip = toSave.ruleSkip;
    };

    botMethods.save = function () { localStorage.setItem("FunbotSave", JSON.stringify(toSave)) };

    botMethods.loadStorage = function () {
        if (localStorage.getItem("FunbotSave") !== null) {
            botMethods.load();
        } else {
            botMethods.save();
        }
    };

    botMethods.checkHistory = function () {
        currentlyPlaying = API.getMedia(), history = API.getHistory();
        caught = 0;
        for (var i = 0; i < history.length; i++) {
            if (currentlyPlaying.cid === history[i].media.cid) {
                caught++;
            }
        }
        caught--;
        return caught;
    };

    function getUser(username) {
        var users = API.getUsers();
        for (var i = 0; i < users.length; i++)
            if (users[i].username == username)
                return users[i];
        return false;
    };

    botMethods.cleanString = function (string) {
        return string.replace("'", "'").replace(/&/g, "&").replace(/"/g, "\"").replace(/;/g, ";").replace(/</g, "<").replace(/>/g, ">");
    };

    function listener(data) {
        if (data == null) {
            return;
        }

        var title = data.media.title;
        var author = data.media.author;
        for (var i = 0; i < blockedSongs.length; i++) {
            if (title.indexOf(blockedSongs[i]) != -1 || author.indexOf(blockedArtists[i]) != -1) {
                API.moderateForceSkip();
                chatMe("He saltado: " + title + " por que esta bloqueada.");
                return;
            }
        }

        if (API.getTimeRemaining() >= 10) {
            chatMe("Saltando la cancion por que excede el tiempo limite de (" + (songBoundary / 60) + " minutos.)");
        API.moderateForceSkip();
        return;
        }
    }

    function sendAnnouncement() {
        if (lastAnnouncement++ >= announcements.length - 1) {
            lastAnnouncement = 0;
        }
        chatMe(announcements[lastAnnouncement]);
    }

    function chatMe(msg) {
        API.sendChat(msg);
    };

    API.on(API.CHAT, function (data) { // Chat Function #1
        if (data.message.split(' ')[0] === '.set') {
            var msg = data.message,
                from = data.un,
                command = msg.split(' ')[0].split('').Shift().join(''),
                roleIndex = { 'none': 0, 'rdj': 1, 'bouncer': 2, 'manager': 3, 'cohost': 4 };
            if (Funbot.misc.ready || API.getUsers(data.un, Funbot.admins) || API.getUsers(data.un, PlugMod)) {
                var roleCode = roleIndex[msg.split(' ')[1]] || null,
                    targetUser = getUser(msg.split('@')[1].trim());
                if (getUser(from).role >= (roleCode-1) && roleCode && targetUser)
                    API.moderateSetRole(targetUser.id, roleCode);
            }
        }
    });

    API.on(API.CHAT, function (data) { // Chat Function #2
        var fromID = data.uid,
	        msg = data.message.toLowerCase(),
	        chatID = data.cid,
	        responses = ['@{beggar}, Decir groserias no esta permitido aqui, si reiteras quedaras baneado 1hr!',],
	        randomInt = Math.floor(Math.random() * responses.length);
        if (msg.match(new RegExp(Funbot.filters.beggerWords.join('|'), 'gi')) && Funbot.settings.beggerFilter)
            return API.moderateDeleteChat(chatID),
	    	API.sendChat(responses[randomInt].replace(/\{beggar\}/gi, data.un)),
	    	setTimeout(function () {
	    	    API.moderateBanUser(chat.uid, 'h');
	    	}, 1500), false;
        if (msg.split(' ')[0].match(new RegExp(Funbot.filters.commandWords.join('|'), 'gi')))
            return API.moderateDeleteChat(chatID), true;
    });

    botMethods.loadStorage();
    console.log("Funbot-Script version " + Funbot.misc.version);

    setTimeout(function () {
        $.getScript('http://connect.soundcloud.com/sdk.js');
    }, 700);

    setTimeout(function () {
        SC.initialize({
            client_id: '23025049683040'
        });
    }, 3000);

    API.sendChat('Olimpobot version ' + Funbot.misc.version + ' Activado!');
} else {
    alert("This bot can only function at http://plug.dj/community");
};
<|endoftext|>


<commit_before>/*globals jest:false, expect:false, pit:false */
'use strict';

var pathConnectionHttp = '../../../src/connection/ConnectionHttp';
jest.dontMock(pathConnectionHttp);
var ConnectionHttp = require(pathConnectionHttp);
var superagent = require('superagent');

describe('ConnectionHttp', function() {
  describe('#request', function() {
    var response, verbs, addr, args, connectionHttp, clearMocks;

    beforeEach(function() {
      verbs = {
        PUT:    'PUT',
        GET:    'GET',
        POST:   'POST',
        DELETE: 'DELETE'
      };

      clearMocks = function() {
        superagent.get.mockClear();
        superagent.set.mockClear();
        superagent.put.mockClear();
        superagent.post.mockClear();
        superagent.send.mockClear();
        superagent.delete.mockClear();
      };

      addr = 'http://localhost/profiles';

      response = {
        request:  '',
        status:  200,
        data:     '',
        raw:      [],
        headers:  [],
        error:  null
      };

      superagent.__setMockResponse(function() {
        return response;
      });

      args = { profileId: 1, profileName: 'Profile Name' };
      connectionHttp = new ConnectionHttp();
    });

    pit('should request post', function() {
      return connectionHttp.request(verbs.POST, addr, args).then(function(res) {
        expect(superagent.post.mock.calls).toEqual([[addr]]);
        expect(superagent.send.mock.calls).toEqual([[args]]);
        expect(superagent.set.mock.calls).toEqual([['Accept', 'application/json']]);
        expect(res).toEqual(response);
        clearMocks();
      });
    });

    pit('should request put', function() {
      return connectionHttp.request(verbs.PUT, addr, args).then(function(res) {
        expect(superagent.put.mock.calls).toEqual([[addr]]);
        expect(superagent.send.mock.calls).toEqual([[args]]);
        expect(superagent.set.mock.calls).toEqual([['Accept', 'application/json']]);
        expect(res).toEqual(response);
        clearMocks();
      });
    });

    pit('should request delete', function() {
      return connectionHttp.request(verbs.DELETE, addr, args).then(function(res) {
        expect(superagent.delete.mock.calls).toEqual([[addr]]);
        expect(superagent.send.mock.calls).toEqual([[args]]);
        expect(superagent.set.mock.calls).toEqual([['Accept', 'application/json']]);
        expect(res).toEqual(response);
        clearMocks();
      });
    });
  });
});
<commit_msg>ConnectionHttp#request should call get<commit_after>/*globals jest:false, expect:false, pit:false */
'use strict';

var pathConnectionHttp = '../../../src/connection/ConnectionHttp';
jest.dontMock(pathConnectionHttp);
var ConnectionHttp = require(pathConnectionHttp);
var superagent = require('superagent');

describe('ConnectionHttp', function() {
  describe('#request', function() {
    var response, verbs, addr, args, connectionHttp, clearMocks;

    beforeEach(function() {
      verbs = {
        PUT:    'PUT',
        GET:    'GET',
        POST:   'POST',
        DELETE: 'DELETE'
      };

      clearMocks = function() {
        superagent.get.mockClear();
        superagent.set.mockClear();
        superagent.put.mockClear();
        superagent.post.mockClear();
        superagent.send.mockClear();
        superagent.delete.mockClear();
      };

      addr = 'http://localhost/profiles';

      response = {
        request:  '',
        status:  200,
        data:     '',
        raw:      [],
        headers:  [],
        error:  null
      };

      superagent.__setMockResponse(function() {
        return response;
      });

      args = { profileId: 1, profileName: 'Profile Name' };
      connectionHttp = new ConnectionHttp();
    });

    pit('should request get', function() {
      return connectionHttp.request(verbs.GET, addr, args).then(function(res) {
        expect(superagent.get.mock.calls).toEqual([[addr]]);
        expect(superagent.send.mock.calls).toEqual([[args]]);
        expect(superagent.set.mock.calls).toEqual([['Accept', 'application/json']]);
        expect(res).toEqual(response);
        clearMocks();
      });
    });

    pit('should request post', function() {
      return connectionHttp.request(verbs.POST, addr, args).then(function(res) {
        expect(superagent.post.mock.calls).toEqual([[addr]]);
        expect(superagent.send.mock.calls).toEqual([[args]]);
        expect(superagent.set.mock.calls).toEqual([['Accept', 'application/json']]);
        expect(res).toEqual(response);
        clearMocks();
      });
    });

    pit('should request put', function() {
      return connectionHttp.request(verbs.PUT, addr, args).then(function(res) {
        expect(superagent.put.mock.calls).toEqual([[addr]]);
        expect(superagent.send.mock.calls).toEqual([[args]]);
        expect(superagent.set.mock.calls).toEqual([['Accept', 'application/json']]);
        expect(res).toEqual(response);
        clearMocks();
      });
    });

    pit('should request delete', function() {
      return connectionHttp.request(verbs.DELETE, addr, args).then(function(res) {
        expect(superagent.delete.mock.calls).toEqual([[addr]]);
        expect(superagent.send.mock.calls).toEqual([[args]]);
        expect(superagent.set.mock.calls).toEqual([['Accept', 'application/json']]);
        expect(res).toEqual(response);
        clearMocks();
      });
    });
  });
});
<|endoftext|>


<commit_before>#!/usr/bin/env node
'use strict';

console.log('Hello world !');

var FB = require('fb');

////////////////////////////////////////////////////////////////////////////////
var page_id = '...';
var app_id = '...';
var app_secret = '...';
var client_short_lived_access_token = '...';
var client_long_lived_access_token = '...';
// generated from app + user + page + rights
// cf. http://offirmo.net/wiki/index.php?title=Facebook#Obtention_d.27un_token_de_publication_.C3.A0_dur.C3.A9e_illimit.C3.A9e
var page_access_token = 'CAAJqZAZCjScZCIBAKtNfcIwT...';

FB.setAccessToken(page_access_token);

/////////////////////////////////////////////////////////////////////////////
console.log('FB options', FB.options());

/*
console.log('* Get facebook application access token');
FB.api('oauth/access_token', {
	client_id: app_id,
	client_secret: app_secret,
	grant_type: 'client_credentials'
}, function (res) {
	if(!res || res.error) {
		console.error(!res ? 'error occurred' : res.error);
		return;
	}

	console.log('  accessToken', res.access_token);
	console.log('  expires', res.expires ? res.expires : 0);
});
*/

/*
console.log('* Extend expiry time of a user access token');
FB.api('oauth/access_token', {
	client_id: app_id,
	client_secret: app_secret,
	grant_type: 'fb_exchange_token',
	fb_exchange_token: client_short_lived_access_token
}, function (res) {
	if(!res || res.error) {
		console.log(!res ? 'error occurred' : res.error);
		return;
	}

	console.log('  accessToken', res.access_token);
	console.log('  expires', res.expires ? res.expires : 0);
});
*/

// Exchange code (???) for access token
/*
FB.api('oauth/access_token', {
	client_id: app_id,
	client_secret: app_secret,
	redirect_uri: 'http://yoururl.com/callback',
	code: 'code'
}, function (res) {
	if(!res || res.error) {
		console.log(!res ? 'error occurred' : res.error);
		return;
	}

	console.log('accessToken', res.access_token);
	console.log('expires', res.expires ? res.expires : 0);
});
*/

// get
/*
FB.api(
	'/' + page_id + '/feed',
	function (response) {
		console.log(response);
		if (response && !response.error) {
			// handle the result
		}
	}
);
*/

console.log('* post to a page');
FB.api('/' + page_id + '/feed', 'post', { message: 'Hello bar from node.js !'}, function (res) {
	if(!res || res.error) {
		console.error(!res ? 'error occurred' : res.error);
		return;
	}
	console.log('Post Id: ' + res.id);
	console.log(res);
});

<commit_msg>more facebook post tests<commit_after>#!/usr/bin/env node
'use strict';

console.log('Hello world !');

var FB = require('fb');

////////////////////////////////////////////////////////////////////////////////
var page_id = '...';
var app_id = '...';
var app_secret = '...';
var client_short_lived_access_token = '...';
var client_long_lived_access_token = '...';
// generated from app + user + page + rights
// cf. http://offirmo.net/wiki/index.php?title=Facebook#Obtention_d.27un_token_de_publication_.C3.A0_dur.C3.A9e_illimit.C3.A9e
var page_access_token = '...';

FB.setAccessToken(page_access_token);

/////////////////////////////////////////////////////////////////////////////
console.log('FB options', FB.options());

/*
console.log('* Get facebook application access token');
FB.api('oauth/access_token', {
	client_id: app_id,
	client_secret: app_secret,
	grant_type: 'client_credentials'
}, function (res) {
	if(!res || res.error) {
		console.error(!res ? 'error occurred' : res.error);
		return;
	}

	console.log('  accessToken', res.access_token);
	console.log('  expires', res.expires ? res.expires : 0);
});
*/

/*
console.log('* Extend expiry time of a user access token');
FB.api('oauth/access_token', {
	client_id: app_id,
	client_secret: app_secret,
	grant_type: 'fb_exchange_token',
	fb_exchange_token: client_short_lived_access_token
}, function (res) {
	if(!res || res.error) {
		console.log(!res ? 'error occurred' : res.error);
		return;
	}

	console.log('  accessToken', res.access_token);
	console.log('  expires', res.expires ? res.expires : 0);
});
*/

// Exchange code (???) for access token
/*
FB.api('oauth/access_token', {
	client_id: app_id,
	client_secret: app_secret,
	redirect_uri: 'http://yoururl.com/callback',
	code: 'code'
}, function (res) {
	if(!res || res.error) {
		console.log(!res ? 'error occurred' : res.error);
		return;
	}

	console.log('accessToken', res.access_token);
	console.log('expires', res.expires ? res.expires : 0);
});
*/

// get
/*
FB.api(
	'/' + page_id + '/feed',
	function (response) {
		console.log(response);
		if (response && !response.error) {
			// handle the result
		}
	}
);
*/

/*
console.log('* post to a page');
FB.api('/' + page_id + '/feed', 'post', { message: 'Hello again from node.js !'}, function (res) {
	if(!res || res.error) {
		console.error(!res ? 'error occurred' : res.error);
		return;
	}
	console.log('  Post Id: ' + res.id);
	console.log(res);
});
*/

/*
console.log('* post to a page, v2');
FB.api(
	'/' + page_id + '/feed',
	'post',
	{
		link: 'http://www.metronews.fr/blog/bigbugblog/2011/05/09/votez-pour-le-chaton-le-plus-mignon/',
		message: 'Meow from node.js !'
	},
	function (res) {
	if(!res || res.error) {
		console.error(!res ? 'error occurred' : res.error);
		return;
	}
	console.log('  Post Id: ' + res.id);
	console.log(res);
});
*/

console.log('* post to a page, v3');
FB.napi(
	'/' + page_id + '/feed',
	'post',
	{
		link: 'http://www.metronews.fr/blog/bigbugblog/2011/05/09/votez-pour-le-chaton-le-plus-mignon/',
		message: 'a status message',
		caption: 'a caption',
		description: 'a description',
		name: 'link name',
	},
	function (error, response) {
		if(error) {
			if(error.response.error.code === 'ETIMEDOUT') {
				console.log('  request timeout !');
			}
			else {
				console.log('  error', error.message);
			}
			return;
		}

		console.log('  Post Id: ' + response.id);
		console.log(response);
	}
);

/*
TODO timeout
TODO node style
*/
<|endoftext|>


<commit_before>Ext.application({
    requires: ['Ext.i18n.Bundle'],

	name: 'AppTest',
    appFolder: 'demo',

    views: ['Main'],

    //define bundle properties
	bundle: {
		bundle: 'Application',
		lang: 'en-US',
		path: 'resources',
		noCache: true,
        // try enabling linked values
        enableLinkedValues: true
        // try adding this to read from json bundles!
        // ,format: 'json'
	},

    launch: function(){
        Ext.create('AppTest.view.Main', {
            renderTo: Ext.getBody()
        });
    }

    // launch: function(){
    //      Ext.create('Ext.panel.Panel',{
    //         renderTo: Ext.getBody(),
    //         tbar: Ext.create('Ext.toolbar.Toolbar',{
    //                items: [{text: 'text'}]
    //            }),
    //         items:[{
    //             height: 300,
    //             html: AppTest.getApplication().bundle.getMsg('panel.html')
    //         }]
    //     });
    // }

});<commit_msg>indentation fix<commit_after>Ext.application({
    requires: ['Ext.i18n.Bundle'],

    name: 'AppTest',
    appFolder: 'demo',

    views: ['Main'],

    //define bundle properties
    bundle: {
        bundle: 'Application',
        lang: 'en-US',
        path: 'resources',
        noCache: true,
        // try enabling linked values
        enableLinkedValues: true
        // try adding this to read from json bundles!
        // ,format: 'json'
    },

    launch: function(){
        Ext.create('AppTest.view.Main', {
            renderTo: Ext.getBody()
        });
    }

    // launch: function(){
    //      Ext.create('Ext.panel.Panel',{
    //         renderTo: Ext.getBody(),
    //         tbar: Ext.create('Ext.toolbar.Toolbar',{
    //                items: [{text: 'text'}]
    //            }),
    //         items:[{
    //             height: 300,
    //             html: AppTest.getApplication().bundle.getMsg('panel.html')
    //         }]
    //     });
    // }

});<|endoftext|>


<commit_before>"use strict";

const fs = require('fs');
const logger = require('./logger');
const google = require('./google');

let items = require('./../src/data/items.json');

function sort(object) {
    let keys = Object.keys(object), result = {};

    keys.sort((a, b) => {
        if (a === b) {
            return 0;
        }

        return a > b ? 1 : -1;
    });

    keys.map((key) => {
        result[key] = object[key];
    });

    return result;
}

const i18nExport = function (args = {}) {
    if (!args['l'] || typeof args['l'] !== 'string') {
        logger.fatal('language is missing');
    }

    let i18n = `./../src/i18n/${args['l']}.json`,
        template = `INFORMATION\tTRANSLATION\tKEY\n`,
        tsv = {
            items: template,
            events: template,
            heroes: template,
            interface: template,
        };

    if (!fs.existsSync(i18n)) {
        logger.fatal(`'${i18n}' does not exists`);
    }

    i18n = require(i18n);

    for (let i in i18n) if (i18n.hasOwnProperty(i)) {
        if (i === 'items') {
            Object.values(items).map((item) => {
                tsv[i] += [
                        `${(item.hero ? `${item.hero} ` : '')}${item.type} ${item.name}`,
                        `${i18n[i][item.uid]}`,
                        `${item.uid}`,
                    ].join('\t') + '\n';
            });
        } else {
            Object.keys(i18n[i]).map((key) => {
                tsv[i] += [
                        'INFORMATION',
                        i18n[i][key].replace(/(\n)+/g, ' '),
                        key,
                    ].join('\t') + '\n';
            });
        }

        fs.writeFileSync(`./${args['l']}.${i}.tsv`, tsv[i]);

        logger.success(`'./${args['l']}.${i}.tsv' created`);
    }
};

const i18nImport = function (args = {}) {
    if (!args['t'] || typeof args['t'] !== 'string') {
        logger.fatal('type is missing');
    }

    if (!args['l'] || typeof args['l'] !== 'string') {
        logger.fatal('language is missing');
    }

    if (!args['f'] || typeof args['f'] !== 'string') {
        logger.fatal('tsv file is missing');
    }

    if (!fs.existsSync(args['f'])) {
        logger.fatal(`'${args['f']}' does not exists`);
    }

    let path = `./../src/i18n/${args['l']}.json`,
        i18n,
        addedCount = 0,
        updatedCount = 0;

    if (!fs.existsSync(path)) {
        logger.warn(`'${path}' does not exists and will be created`);

        i18n = {};
    } else {
        i18n = require(path);
    }

    fs.readFileSync(args['f'], 'utf-8').split('\n').map((line, index) => {
        if (index === 0) {
            return;
        }

        if (!i18n.hasOwnProperty(args['t'])) {
            i18n[args['t']] = {};
        }

        line = line.split('\t');

        if (line.length < 3) {
            return;
        }

        line[2] = line[2].replace('\r', '');

        if (!i18n[args['t']][line[2]]) {
            addedCount++;

            i18n[args['t']][line[2]] = line[1];
        } else if (i18n[args['t']][line[2]] !== line[1]) {
            updatedCount++;

            i18n[args['t']][line[2]] = line[1];
        }
    });

    if (addedCount === 0 && updatedCount === 0) {
        logger.info('nothing to update');
    } else {
        if (['interface', 'heroes',].indexOf(args['t']) !== -1) {
            i18n[args['t']] = sort(i18n[args['t']]);
        }

        fs.writeFileSync(path, JSON.stringify(i18n, null, 2));

        if (addedCount) {
            logger.success(`${addedCount} item(s) added`);
        }

        if (updatedCount) {
            logger.success(`${updatedCount} item(s) updated`);
        }
    }
};

const i18nSync = function (args = {}) {
    google.getTranslations().then((translations) => {
        for (let i in translations) if (translations.hasOwnProperty(i)) {
            for (let j in translations[i]) if (translations[i].hasOwnProperty(j)) {
                if (['interface', 'heroes',].indexOf(j.toLowerCase()) !== -1) {
                    translations[i][j] = sort(translations[i][j]);
                }
            }

            fs.writeFileSync(
                `./../src/i18n/${i}.json`,
                JSON.stringify(translations[i], null, 2)
            );
        }
    }).catch(logger.fatal);
};

const i18nSet = function (args = {}) {
    if (!args['k'] || typeof args['k'] !== 'string') {
        logger.fatal('key is missing');
    }

    if (!args['v'] || typeof args['v'] !== 'string') {
        logger.fatal('value is missing');
    }

    let i18n;

    fs.readdirSync(`./../src/i18n/`).map((file) => {
        if (file.match(/[a-z]{2}_[A-Z]{2}\.json/)) {
            i18n = require(`./../src/i18n/${file}`);

            if (!i18n.hasOwnProperty('interface')) {
                i18n.interface = {};
            }

            i18n.interface[args['k']] = args['v'];

            i18n.interface = sort(i18n.interface);

            fs.writeFileSync(`./../src/i18n/${file}`, JSON.stringify(i18n, null, 2));
        }
    });

    logger.success(`${args['k']} setted to "${args['v']}"`);
};

const i18nRemove = function (args = {}) {
    if (!args['k'] || typeof args['k'] !== 'string') {
        logger.fatal('key is missing');
    }

    let i18n;

    fs.readdirSync(`./../src/i18n/`).map((file) => {
        if (file.match(/[a-z]{2}_[A-Z]{2}\.json/)) {
            i18n = require(`./../src/i18n/${file}`);
            if (!i18n.hasOwnProperty('interface') || !i18n.interface[args['k']]) {
                logger.warn(`${args['k']} not found in '${file}'`);
            }

            delete i18n.interface[args['k']];

            i18n.interface = sort(i18n.interface);

            fs.writeFileSync(`./../src/i18n/${file}`, JSON.stringify(i18n, null, 2));
        }
    });

    logger.success(`${args['k']} deleted`);
};

module.exports = {
    export: i18nExport,
    import: i18nImport,
    sync: i18nSync,
    set: i18nSet,
    remove: i18nRemove,
};
<commit_msg>improve console tools<commit_after>"use strict";

const fs = require('fs');
const logger = require('./logger');
const google = require('./google');

let items = require('./../src/data/items.json');

function sort(object) {
    let keys = Object.keys(object), result = {};

    keys.sort((a, b) => {
        if (a === b) {
            return 0;
        }

        return a > b ? 1 : -1;
    });

    keys.map((key) => {
        result[key] = object[key];
    });

    return result;
}

const i18nExport = function (args = {}) {
    if (!args['l'] || typeof args['l'] !== 'string') {
        logger.fatal('language is missing');
    }

    let i18n = `./../src/i18n/${args['l']}.json`,
        template = `INFORMATION\tTRANSLATION\tKEY\n`,
        tsv = {
            items: template,
            events: template,
            heroes: template,
            interface: template,
        };

    if (!fs.existsSync(i18n)) {
        logger.fatal(`'${i18n}' does not exists`);
    }

    i18n = require(i18n);

    for (let i in i18n) if (i18n.hasOwnProperty(i)) {
        if (i === 'items') {
            Object.values(items).map((item) => {
                tsv[i] += [
                        `${(item.hero ? `${item.hero} ` : '')}${item.type} ${item.name}`,
                        `${i18n[i][item.uid]}`,
                        `${item.uid}`,
                    ].join('\t') + '\n';
            });
        } else {
            Object.keys(i18n[i]).map((key) => {
                tsv[i] += [
                        'INFORMATION',
                        i18n[i][key].replace(/(\n)+/g, ' '),
                        key,
                    ].join('\t') + '\n';
            });
        }

        fs.writeFileSync(`./${args['l']}.${i}.tsv`, tsv[i]);

        logger.success(`'./${args['l']}.${i}.tsv' created`);
    }
};

const i18nImport = function (args = {}) {
    if (!args['t'] || typeof args['t'] !== 'string') {
        logger.fatal('type is missing');
    }

    if (!args['l'] || typeof args['l'] !== 'string') {
        logger.fatal('language is missing');
    }

    if (!args['f'] || typeof args['f'] !== 'string') {
        logger.fatal('tsv file is missing');
    }

    if (!fs.existsSync(args['f'])) {
        logger.fatal(`'${args['f']}' does not exists`);
    }

    let path = `./../src/i18n/${args['l']}.json`,
        i18n,
        addedCount = 0,
        updatedCount = 0;

    if (!fs.existsSync(path)) {
        logger.warn(`'${path}' does not exists and will be created`);

        i18n = {};
    } else {
        i18n = require(path);
    }

    fs.readFileSync(args['f'], 'utf-8').split('\n').map((line, index) => {
        if (index === 0) {
            return;
        }

        if (!i18n.hasOwnProperty(args['t'])) {
            i18n[args['t']] = {};
        }

        line = line.split('\t');

        if (line.length < 3) {
            return;
        }

        line[2] = line[2].replace('\r', '');

        if (!i18n[args['t']][line[2]]) {
            addedCount++;

            i18n[args['t']][line[2]] = line[1];
        } else if (i18n[args['t']][line[2]] !== line[1]) {
            updatedCount++;

            i18n[args['t']][line[2]] = line[1];
        }
    });

    if (addedCount === 0 && updatedCount === 0) {
        logger.info('nothing to update');
    } else {
        if (['interface', 'heroes',].indexOf(args['t']) !== -1) {
            i18n[args['t']] = sort(i18n[args['t']]);
        }

        fs.writeFileSync(path, JSON.stringify(i18n, null, 2));

        if (addedCount) {
            logger.success(`${addedCount} item(s) added`);
        }

        if (updatedCount) {
            logger.success(`${updatedCount} item(s) updated`);
        }
    }
};

const i18nSync = function (args = {}) {
    google.getTranslations().then((translations) => {
        for (let i in translations) if (translations.hasOwnProperty(i)) {
            for (let j in translations[i]) if (translations[i].hasOwnProperty(j)) {
                if (['interface', 'heroes',].indexOf(j.toLowerCase()) !== -1) {
                    translations[i][j] = sort(translations[i][j]);
                }
            }

            fs.writeFileSync(
                `./../src/i18n/${i}.json`,
                JSON.stringify(translations[i], null, 2)
            );

            logger.success(`${i} synchronized`);
        }
    }).catch(logger.fatal);
};

const i18nSet = function (args = {}) {
    if (!args['k'] || typeof args['k'] !== 'string') {
        logger.fatal('key is missing');
    }

    if (!args['v'] || typeof args['v'] !== 'string') {
        logger.fatal('value is missing');
    }

    let i18n;

    fs.readdirSync(`./../src/i18n/`).map((file) => {
        if (file.match(/[a-z]{2}_[A-Z]{2}\.json/)) {
            i18n = require(`./../src/i18n/${file}`);

            if (!i18n.hasOwnProperty('interface')) {
                i18n.interface = {};
            }

            i18n.interface[args['k']] = args['v'];

            i18n.interface = sort(i18n.interface);

            fs.writeFileSync(`./../src/i18n/${file}`, JSON.stringify(i18n, null, 2));
        }
    });

    logger.success(`${args['k']} setted to "${args['v']}"`);
};

const i18nRemove = function (args = {}) {
    if (!args['k'] || typeof args['k'] !== 'string') {
        logger.fatal('key is missing');
    }

    let i18n;

    fs.readdirSync(`./../src/i18n/`).map((file) => {
        if (file.match(/[a-z]{2}_[A-Z]{2}\.json/)) {
            i18n = require(`./../src/i18n/${file}`);
            if (!i18n.hasOwnProperty('interface') || !i18n.interface[args['k']]) {
                logger.warn(`${args['k']} not found in '${file}'`);
            }

            delete i18n.interface[args['k']];

            i18n.interface = sort(i18n.interface);

            fs.writeFileSync(`./../src/i18n/${file}`, JSON.stringify(i18n, null, 2));
        }
    });

    logger.success(`${args['k']} deleted`);
};

module.exports = {
    export: i18nExport,
    import: i18nImport,
    sync: i18nSync,
    set: i18nSet,
    remove: i18nRemove,
};
<|endoftext|>


<commit_before>
import './collections/subscription_fields.js';

// Notifications
import Notifications from './collections/notifications/collection.js';
import './collections/notifications/custom_fields.js';
import './collections/notifications/views.js';

// Inbox
import Messages from './collections/messages/collection.js'
import './collections/messages/views.js';

import Conversations from './collections/conversations/collection.js'
import './collections/conversations/views.js';

// Subscriptions
import './subscriptions/mutations.js';
import './subscriptions/permissions.js';

// Posts
import './collections/posts/custom_fields.js';
import './collections/posts/views.js';

// Commensts
import './collections/comments/custom_fields.js';

// Internationalization
import './i18n-en-us/en_US.js';

// General
import './modules/fragments.js';
import './modules/callbacks.js';

import './helpers.js'
import './components.js';
import './routes.js';
import './views.js';

export { Conversations, Messages, Notifications }
<commit_msg>fix typo in comment<commit_after>
import './collections/subscription_fields.js';

// Notifications
import Notifications from './collections/notifications/collection.js';
import './collections/notifications/custom_fields.js';
import './collections/notifications/views.js';

// Inbox
import Messages from './collections/messages/collection.js'
import './collections/messages/views.js';

import Conversations from './collections/conversations/collection.js'
import './collections/conversations/views.js';

// Subscriptions
import './subscriptions/mutations.js';
import './subscriptions/permissions.js';

// Posts
import './collections/posts/custom_fields.js';
import './collections/posts/views.js';

// Comments
import './collections/comments/custom_fields.js';

// Internationalization
import './i18n-en-us/en_US.js';

// General
import './modules/fragments.js';
import './modules/callbacks.js';

import './helpers.js'
import './components.js';
import './routes.js';
import './views.js';

export { Conversations, Messages, Notifications }
<|endoftext|>


<commit_before>// Ugis Germanis
// My javascript

var music = {
    selected: "byartist",
    sort: new Event('sort'),
    playlist: null,
    request: new XMLHttpRequest(),
    url: document.location.protocol+ "//"+ window.location.host,
    current: 0,
    slider: null,
    sliderDrag: false,
    render: function(){
        $("#playlist").empty();
        for (i=0; i<this.playlist.length; i++) {
            $("#playlist").append("

");
            $(".song").last().attr('id', "sound"+i);
            $(".song").last().attr('index', i);
            $(".song").last().append(this.playlist[i].Title+ " - "+ this.playlist[i].Artist);
            document.getElementById("sound"+i).addEventListener('click', function(e){
                music.current= e.target.getAttribute("index");
                playSong(music.current);
            });
        }
    },
};

music.request.onloadend = function(){
    if (this.readyState = 4 && this.status == 200) {
        music.playlist = JSON.parse(this.responseText);
        $("#playlist").attr('loading', true);
        music.render();
        $("#playlist").attr('loading', false);
    }
}

document.addEventListener("sort", function(e){
    console.log("sort event: ", music.selected);
    music.request.open("GET", music.url + "/api?sort=" + music.selected);
    music.request.send();
}, false)

window.addEventListener('WebComponentsReady', function(e) {
    console.log('webcomponents are ready!!!');
    //Init the default
    music.slider = document.getElementById("slider");
    slider.addEventListener("mousedown", function(){
        music.sliderDrag = true;
    });
    slider.addEventListener("mouseup", function(){
        music.sliderDrag = false;
    });
    slider.addEventListener("change", function(e){
        var estimate = soundManager.getSoundById("sound"+music.current).durationEstimate;
        soundManager.getSoundById("sound"+music.current).setPosition((estimate/1000) * e.target.value);
        music.sliderDrag = false;
    });
    document.getElementById(music.selected).active=true;
    document.dispatchEvent(music.sort);
    //Nifty button stuff
    var sorter = document.getElementsByClassName("sorter");
    for (i=0; i< sorter.length; i++) {
        sorter[i].addEventListener("change", function(e){
            for(j=0; j<sorter.length; j++){
                if (sorter[j].id == e.target.id) {
                    continue
                }
                sorter[j].active=false;
            }
            e.target.active=true;
            if (music.selected == e.target.id){
                return
            }
            music.selected = e.target.id
            document.dispatchEvent(music.sort);
        }, false);
    }
});

function playSong(id){
    soundManager.stopAll();
    soundManager.createSound({
        id: "sound"+id,
        url: music.url+ "/stream?id="+ music.playlist[id].ID,
        multiShot:false,
        onfinish: function() {
            if (music.current == (music.playlist.length - 1)) {
                music.current = 0;
            } else {
                music.current++;
            }
            playSong(music.current);
            $("#sound"+id).attr("playing", false);
            this.destruct();
        },
        onstop: function(){
            $("#sound"+id).attr("playing", false);
            this.destruct();
        },
        whileplaying: function(){
            if (music.sliderDrag == false){
                music.slider.value = (this.position / this.durationEstimate) * 1000;
            }
        },
    });
    $("#sound"+id).attr("playing", true);
    soundManager.play("sound"+id);
    document.getElementsByTagName("body")[0].style.backgroundImage = "url("+music.url+"/art?id="+music.playlist[id].ID+")";
}

function playnext(){
    if (music.current == (music.playlist.length - 1)) {
        music.current = 0;
    } else {
        music.current++;
    }
    playSong(music.current);
}

function playprevious(){
    if (music.current == 0) {
        music.current = music.playlist.length - 1
    } else {
        music.current--;
    }
    playSong(music.current);
}

function play(){
    if (soundManager.getSoundById("sound"+music.current) === undefined){
        playSong(music.current);
    } else {
        soundManager.getSoundById("sound"+music.current).resume();
    }
}

function pause(){
    soundManager.getSoundById("sound"+music.current).pause();
}<commit_msg>use event delegation<commit_after>// Ugis Germanis
// My javascript

var music = {
    selected: "byartist",
    sort: new Event('sort'),
    playlist: null,
    request: new XMLHttpRequest(),
    url: document.location.protocol+ "//"+ window.location.host,
    current: 0,
    slider: null,
    sliderDrag: false,
    render: function(){
        $("#playlist").empty();
        for (i=0; i<this.playlist.length; i++) {
            $("#playlist").append("

");
            $(".song").last().attr('id', "sound"+i);
            $(".song").last().attr('index', i);
            $(".song").last().append(this.playlist[i].Title+ " - "+ this.playlist[i].Artist);
        }
        document.getElementById("playlist").addEventListener('click', function(e){
                if(e.target && e.target.nodeName == "LI") {
                    music.current= e.target.getAttribute("index");
                    playSong(music.current);
                }
        });
    },
};

music.request.onloadend = function(){
    if (this.readyState = 4 && this.status == 200) {
        music.playlist = JSON.parse(this.responseText);
        $("#playlist").attr('loading', true);
        music.render();
        $("#playlist").attr('loading', false);
    }
}

document.addEventListener("sort", function(e){
    console.log("sort event: ", music.selected);
    music.request.open("GET", music.url + "/api?sort=" + music.selected);
    music.request.send();
}, false)

window.addEventListener('WebComponentsReady', function(e) {
    console.log('webcomponents are ready!!!');
    //Init the default
    music.slider = document.getElementById("slider");
    slider.addEventListener("mousedown", function(){
        music.sliderDrag = true;
    });
    slider.addEventListener("mouseup", function(){
        music.sliderDrag = false;
    });
    slider.addEventListener("change", function(e){
        var estimate = soundManager.getSoundById("sound"+music.current).durationEstimate;
        soundManager.getSoundById("sound"+music.current).setPosition((estimate/1000) * e.target.value);
        music.sliderDrag = false;
    });
    document.getElementById(music.selected).active=true;
    document.dispatchEvent(music.sort);
    //Nifty button stuff
    var sorter = document.getElementsByClassName("sorter");
    for (i=0; i< sorter.length; i++) {
        sorter[i].addEventListener("change", function(e){
            for(j=0; j<sorter.length; j++){
                if (sorter[j].id == e.target.id) {
                    continue
                }
                sorter[j].active=false;
            }
            e.target.active=true;
            if (music.selected == e.target.id){
                return
            }
            music.selected = e.target.id
            document.dispatchEvent(music.sort);
        }, false);
    }
});

function playSong(id){
    soundManager.stopAll();
    soundManager.createSound({
        id: "sound"+id,
        url: music.url+ "/stream?id="+ music.playlist[id].ID,
        multiShot:false,
        onfinish: function() {
            if (music.current == (music.playlist.length - 1)) {
                music.current = 0;
            } else {
                music.current++;
            }
            playSong(music.current);
            $("#sound"+id).attr("playing", false);
            this.destruct();
        },
        onstop: function(){
            $("#sound"+id).attr("playing", false);
            this.destruct();
        },
        whileplaying: function(){
            if (music.sliderDrag == false){
                music.slider.value = (this.position / this.durationEstimate) * 1000;
            }
        },
    });
    $("#sound"+id).attr("playing", true);
    soundManager.play("sound"+id);
    document.getElementsByTagName("body")[0].style.backgroundImage = "url("+music.url+"/art?id="+music.playlist[id].ID+")";
}

function playnext(){
    if (music.current == (music.playlist.length - 1)) {
        music.current = 0;
    } else {
        music.current++;
    }
    playSong(music.current);
}

function playprevious(){
    if (music.current == 0) {
        music.current = music.playlist.length - 1
    } else {
        music.current--;
    }
    playSong(music.current);
}

function play(){
    if (soundManager.getSoundById("sound"+music.current) === undefined){
        playSong(music.current);
    } else {
        soundManager.getSoundById("sound"+music.current).resume();
    }
}

function pause(){
    soundManager.getSoundById("sound"+music.current).pause();
}<|endoftext|>


<commit_before>'use strict';

import { forOwn, isFunction, partial } from 'lodash';
import settings from './settings';

const TYPE_MAP = {
  // Methods where the function is the last argument or the first
  // and all other arguments come before or after.
  post: (fn, target, value, ...args) => fn(...args, value),
  pre: (fn, target, value, ...args) => fn(value, ...args),

  // Partials are slightly different. They partial an existing function
  // on the object referenced by string name.
  partial: (fn, target, value, ...args) => fn(resolveFunction(args[0], target), ...args.slice(1)),

  // Wrap is a different case since the original function value
  // needs to be given to the wrap method.
  wrap: (fn, target, value, ...args) => fn(resolveFunction(args[0], target), value),
  replace: (fn, target, value, ...args) => fn(...args),

  // Calls the function with key functions and the value
  compose: (fn, target, value, ...args) => fn(value, ...args.map(method => resolveFunction(method, target))),
  partialed: (fn, target, value, ...args) => partial(fn, value, ...args)
};

TYPE_MAP.single = TYPE_MAP.pre;

function resolveFunction(method, target) {
  return isFunction(method) ? method : target[method];
}

function isGetter(getter) {
  return Boolean(getter[`${settings.annotationPrefix}isGetter`]);
}

/**
 * Used to copy over meta data from function to function.
 * If meta data is attached to a function. This can get lost
 * when wrapping functions. This tries to persist that.
 */
function copyMetaData(from, to) {
  forOwn(from, (value, key) => to[key] = from[key]);
}

/**
 * Creates a generic decorator for a method on an object.
 *
 * @param {Object} root The root object the method resides on.
 * @param {String} method The method.
 * @param {String} [type=post] How to wrap the function.
 * @returns {Function} Decorator function
 */
function createDecorator(root, method, type = 'pre') {
  return type === 'single' ? wrapper() : wrapper;

  function wrapper(...args) {
    return function decorator(target, name, descriptor) {
      const { value, get } = descriptor;

      if (get) {
        const toWrap = isGetter(get) ? get : get.call(this);
        descriptor.get = TYPE_MAP[type](root[method], target, toWrap, ...args);
        copyMetaData(toWrap, descriptor.get);
      } else if (value) {
        descriptor.value = TYPE_MAP[type](root[method], target, value, ...args);
        copyMetaData(value, descriptor.get);
      }

      return descriptor;
    };
  };
}

function createInstanceDecorator(root, method, type = 'pre') {
  return type === 'single' ? wrapper() : wrapper;

  function wrapper(...args) {
    return function decorator(target, name, descriptor) {
      const { value, get } = descriptor;
      const action = TYPE_MAP[type];
      const getterAnnotation = `${settings.annotationPrefix}isGetter`;

      if (get) {
        copyMetaData(get, getter);
      }

      return { get: getter, configurable: true };

      function getter() {
        const isGetter = Boolean(getter[getterAnnotation]);
        const newDescriptor = { configurable: true };

        if (isFunction(get)) {
          const toWrap = isGetter ? get : get.call(this);

          newDescriptor.get = action(root[method], this, toWrap, ...args);
          copyMetaData(toWrap, newDescriptor.get);

          Object.defineProperty(this, name, newDescriptor);

          return isGetter ? newDescriptor.get() : newDescriptor.get;
        }

        newDescriptor.value = action(root[method], this, value, ...args);
        copyMetaData(value, newDescriptor.value);

        Object.defineProperty(this, name, newDescriptor);

        return newDescriptor.value;
      }
    };
  };
}

export default {
  createDecorator,
  createInstanceDecorator,
  copyMetaData
};
<commit_msg>fix(decoratorFactory): change 'get' to 'value'<commit_after>'use strict';

import { forOwn, isFunction, partial } from 'lodash';
import settings from './settings';

const TYPE_MAP = {
  // Methods where the function is the last argument or the first
  // and all other arguments come before or after.
  post: (fn, target, value, ...args) => fn(...args, value),
  pre: (fn, target, value, ...args) => fn(value, ...args),

  // Partials are slightly different. They partial an existing function
  // on the object referenced by string name.
  partial: (fn, target, value, ...args) => fn(resolveFunction(args[0], target), ...args.slice(1)),

  // Wrap is a different case since the original function value
  // needs to be given to the wrap method.
  wrap: (fn, target, value, ...args) => fn(resolveFunction(args[0], target), value),
  replace: (fn, target, value, ...args) => fn(...args),

  // Calls the function with key functions and the value
  compose: (fn, target, value, ...args) => fn(value, ...args.map(method => resolveFunction(method, target))),
  partialed: (fn, target, value, ...args) => partial(fn, value, ...args)
};

TYPE_MAP.single = TYPE_MAP.pre;

function resolveFunction(method, target) {
  return isFunction(method) ? method : target[method];
}

function isGetter(getter) {
  return Boolean(getter[`${settings.annotationPrefix}isGetter`]);
}

/**
 * Used to copy over meta data from function to function.
 * If meta data is attached to a function. This can get lost
 * when wrapping functions. This tries to persist that.
 */
function copyMetaData(from, to) {
  forOwn(from, (value, key) => to[key] = from[key]);
}

/**
 * Creates a generic decorator for a method on an object.
 *
 * @param {Object} root The root object the method resides on.
 * @param {String} method The method.
 * @param {String} [type=post] How to wrap the function.
 * @returns {Function} Decorator function
 */
function createDecorator(root, method, type = 'pre') {
  return type === 'single' ? wrapper() : wrapper;

  function wrapper(...args) {
    return function decorator(target, name, descriptor) {
      const { value, get } = descriptor;

      if (get) {
        const toWrap = isGetter(get) ? get : get.call(this);
        descriptor.get = TYPE_MAP[type](root[method], target, toWrap, ...args);
        copyMetaData(toWrap, descriptor.get);
      } else if (value) {
        descriptor.value = TYPE_MAP[type](root[method], target, value, ...args);
        copyMetaData(value, descriptor.value);
      }

      return descriptor;
    };
  };
}

function createInstanceDecorator(root, method, type = 'pre') {
  return type === 'single' ? wrapper() : wrapper;

  function wrapper(...args) {
    return function decorator(target, name, descriptor) {
      const { value, get } = descriptor;
      const action = TYPE_MAP[type];
      const getterAnnotation = `${settings.annotationPrefix}isGetter`;

      if (get) {
        copyMetaData(get, getter);
      }

      return { get: getter, configurable: true };

      function getter() {
        const isGetter = Boolean(getter[getterAnnotation]);
        const newDescriptor = { configurable: true };

        if (isFunction(get)) {
          const toWrap = isGetter ? get : get.call(this);

          newDescriptor.get = action(root[method], this, toWrap, ...args);
          copyMetaData(toWrap, newDescriptor.get);

          Object.defineProperty(this, name, newDescriptor);

          return isGetter ? newDescriptor.get() : newDescriptor.get;
        }

        newDescriptor.value = action(root[method], this, value, ...args);
        copyMetaData(value, newDescriptor.value);

        Object.defineProperty(this, name, newDescriptor);

        return newDescriptor.value;
      }
    };
  };
}

export default {
  createDecorator,
  createInstanceDecorator,
  copyMetaData
};
<|endoftext|>


<commit_before>// @flow

import fs from 'fs';
import childProcess from 'child_process';
import zlib from 'zlib';
import dateFormat from 'dateformat';
import StreamCache from 'stream-cache';
import { promisify } from 'util';
import invariant from 'invariant';

import dbConfig from '../../secrets/db_config';

const readdir = promisify(fs.readdir);
const lstat = promisify(fs.lstat);
const unlink = promisify(fs.unlink);

let importedBackupConfig = undefined;
async function importBackupConfig() {
  if (importedBackupConfig !== undefined) {
    return importedBackupConfig;
  }
  try {
    // $FlowFixMe
    const backupExports = await import('../../facts/backups');
    if (importedBackupConfig === undefined) {
      importedBackupConfig = backupExports.default;
    }
  } catch {
    if (importedBackupConfig === undefined) {
      importedBackupConfig = null;
    }
  }
  return importedBackupConfig;
}

async function backupDB() {
  const backupConfig = await importBackupConfig();
  if (!backupConfig || !backupConfig.enabled) {
    return;
  }

  const mysqlDump = childProcess.spawn(
    'mysqldump',
    ['-u', dbConfig.user, `-p${dbConfig.password}`, dbConfig.database],
    {
      stdio: ['ignore', 'pipe', 'ignore'],
    },
  );
  const cache = new StreamCache();
  mysqlDump.stdout.pipe(zlib.createGzip()).pipe(cache);

  const dateString = dateFormat('yyyy-mm-dd-HH:MM');
  const filename = `${backupConfig.directory}/squadcal.${dateString}.sql.gz`;

  await saveBackup(filename, cache);
}

async function saveBackup(
  filePath: string,
  cache: StreamCache,
  retries: number = 2,
): Promise<void> {
  try {
    await trySaveBackup(filePath, cache);
  } catch (e) {
    if (e.code !== 'ENOSPC') {
      throw e;
    }
    if (!retries) {
      throw e;
    }
    await deleteOldestBackup();
    await saveBackup(filePath, cache, retries - 1);
  }
}

function trySaveBackup(filePath: string, cache: StreamCache): Promise<void> {
  const writeStream = fs.createWriteStream(filePath);
  return new Promise((resolve, reject) => {
    cache
      .pipe(writeStream)
      .on('finish', resolve)
      .on('error', reject);
  });
}

async function deleteOldestBackup() {
  const backupConfig = await importBackupConfig();
  invariant(backupConfig, 'backupConfig should be non-null');
  const files = await readdir(backupConfig.directory);
  let oldestFile;
  for (let file of files) {
    if (!file.endsWith('.sql.gz') || !file.startsWith('squadcal.')) {
      continue;
    }
    const stat = await lstat(`${backupConfig.directory}/${file}`);
    if (stat.isDirectory()) {
      continue;
    }
    if (!oldestFile || stat.mtime < oldestFile.mtime) {
      oldestFile = { file, mtime: stat.mtime };
    }
  }
  if (!oldestFile) {
    return;
  }
  try {
    await unlink(`${backupConfig.directory}/${oldestFile.file}`);
  } catch (e) {
    // Check if it's already been deleted
    if (e.code !== 'ENOENT') {
      throw e;
    }
  }
}

export { backupDB };
<commit_msg>[server] Delete failed server backup attempts<commit_after>// @flow

import fs from 'fs';
import childProcess from 'child_process';
import zlib from 'zlib';
import dateFormat from 'dateformat';
import StreamCache from 'stream-cache';
import { promisify } from 'util';
import invariant from 'invariant';

import dbConfig from '../../secrets/db_config';

const readdir = promisify(fs.readdir);
const lstat = promisify(fs.lstat);
const unlink = promisify(fs.unlink);

let importedBackupConfig = undefined;
async function importBackupConfig() {
  if (importedBackupConfig !== undefined) {
    return importedBackupConfig;
  }
  try {
    // $FlowFixMe
    const backupExports = await import('../../facts/backups');
    if (importedBackupConfig === undefined) {
      importedBackupConfig = backupExports.default;
    }
  } catch {
    if (importedBackupConfig === undefined) {
      importedBackupConfig = null;
    }
  }
  return importedBackupConfig;
}

async function backupDB() {
  const backupConfig = await importBackupConfig();
  if (!backupConfig || !backupConfig.enabled) {
    return;
  }

  const mysqlDump = childProcess.spawn(
    'mysqldump',
    ['-u', dbConfig.user, `-p${dbConfig.password}`, dbConfig.database],
    {
      stdio: ['ignore', 'pipe', 'ignore'],
    },
  );
  const cache = new StreamCache();
  mysqlDump.stdout.pipe(zlib.createGzip()).pipe(cache);

  const dateString = dateFormat('yyyy-mm-dd-HH:MM');
  const filename = `${backupConfig.directory}/squadcal.${dateString}.sql.gz`;

  try {
    await saveBackup(filename, cache);
  } catch (e) {
    await unlink(filename);
  }
}

async function saveBackup(
  filePath: string,
  cache: StreamCache,
  retries: number = 2,
): Promise<void> {
  try {
    await trySaveBackup(filePath, cache);
  } catch (e) {
    if (e.code !== 'ENOSPC') {
      throw e;
    }
    if (!retries) {
      throw e;
    }
    await deleteOldestBackup();
    await saveBackup(filePath, cache, retries - 1);
  }
}

function trySaveBackup(filePath: string, cache: StreamCache): Promise<void> {
  const writeStream = fs.createWriteStream(filePath);
  return new Promise((resolve, reject) => {
    cache
      .pipe(writeStream)
      .on('finish', resolve)
      .on('error', reject);
  });
}

async function deleteOldestBackup() {
  const backupConfig = await importBackupConfig();
  invariant(backupConfig, 'backupConfig should be non-null');
  const files = await readdir(backupConfig.directory);
  let oldestFile;
  for (let file of files) {
    if (!file.endsWith('.sql.gz') || !file.startsWith('squadcal.')) {
      continue;
    }
    const stat = await lstat(`${backupConfig.directory}/${file}`);
    if (stat.isDirectory()) {
      continue;
    }
    if (!oldestFile || stat.mtime < oldestFile.mtime) {
      oldestFile = { file, mtime: stat.mtime };
    }
  }
  if (!oldestFile) {
    return;
  }
  try {
    await unlink(`${backupConfig.directory}/${oldestFile.file}`);
  } catch (e) {
    // Check if it's already been deleted
    if (e.code !== 'ENOENT') {
      throw e;
    }
  }
}

export { backupDB };
<|endoftext|>


<commit_before>import wajs from 'wajs';
import secrets from '../../secrets';
export const WA_APP_ID = secrets.wolframAlphaId;

export const waClient = new wajs(WA_APP_ID);

export const QUERY_OPTIONS = {
  format: 'plaintext',
  podState: '100@More',
  ignoreCase: true,
  // includePodId: ['Result']
};

export const formatQuery = (query) => query //`list of ${query}`;

export const formatResponse = (response) => {
  if (!response.pods()[1]){
    console.log('no results? ', response)
    return false;
  }
  let queryString = response.pods()[1].subpod[0].plaintext[0];
  console.log('querystring', queryString)
  const totalIndex = queryString.indexOf('(total:');
  if (totalIndex > -1) {
    queryString = queryString.substring(0, totalIndex);
  }
  queryString = queryString.trim();
  let resultArray = queryString.split('  |  ');
  if (resultArray.length === 1) {
    resultArray = queryString.split('\n');
  }
  return resultArray;
}<commit_msg>fix data not available<commit_after>import wajs from 'wajs';
import secrets from '../../secrets';
export const WA_APP_ID = secrets.wolframAlphaId;

export const waClient = new wajs(WA_APP_ID);

export const QUERY_OPTIONS = {
  format: 'plaintext',
  podState: '100@More',
  ignoreCase: true,
  // includePodId: ['Result']
};

export const formatQuery = (query) => query //`list of ${query}`;

export const formatResponse = (response) => {
  if (!response.pods()[1]){
    return false;
  }
  let queryString = response.pods()[1].subpod[0].plaintext[0];
  console.log('querystring', queryString)
  if (queryString === '(data not available)'){
    return false;
  }
  const totalIndex = queryString.indexOf('(total:');
  if (totalIndex > -1) {
    queryString = queryString.substring(0, totalIndex);
  }
  queryString = queryString.trim();
  let resultArray = queryString.split('  |  ');
  if (resultArray.length === 1) {
    resultArray = queryString.split('\n');
  }
  return resultArray;
}<|endoftext|>


<commit_before>import _ from 'lodash'
import d3 from 'd3'
import React from 'react'
import Layer from 'react-layer'

import Tooltip from 'component/Tooltip.jsx'

import browser from 'util/browser'
import palettes from 'util/palettes'

import legend from 'chart/renderer/legend'

var DEFAULTS = {
  aspect: 1,
  domain: _.noop,
  margin: {
    top: 0,
    right: 0,
    bottom: 0,
    left: 0
  },
  onClick: _.noop,
  value: _.property('properties.value'),
  color: palettes.orange,
  xFormat: d => d3.format(Math.abs(d) < 1 ? '.4f' : 'n')(d),
  name: _.property('properties.name'),
  maxBubbleValue: 5000,
  maxBubbleRadius: 20,
  bubbleLegendRatio: [0.1, 0.5, 1],
  indicatorName: 'Has data'
}

function wrap (text, width, x) {
  text.each(function () {
    let text = d3.select(this)
    let words = text.text().split(/\s+/).reverse()
    let word
    let line = []
    let lineNumber = 1
    let lineHeight = 1.1
    let y = text.attr('y')
    let tspan = text.text(null).append('tspan').attr('x', x).attr('y', y)
    while (words.length > 0) {
      word = words.pop()
      line.push(word)
      tspan.text(line.join(' '))
      if (tspan.node().getComputedTextLength() > (width - x)) {
        line.pop()
        tspan.text(line.join(' '))
        line = [word]
        tspan = text.append('tspan').attr('x', x).attr('y', y).attr('dy', (lineNumber * lineHeight) + 'rem').text(word)
        lineNumber += 1
      }
    }
  })
}

function _calculateBounds (features) {
  var lat = _.property(1)
  var lng = _.property(0)

  if (features.length < 1) {
    return [[0, 0], [0, 0]]
  }

  var coordinates = _(features).map(function (f) {
    if (f.geometry.type !== 'MultiPolygon') {
      return _.flatten(f.geometry.coordinates)
    }
  })
    .flatten()
    .value()

  var left = d3.min(coordinates, lng)
  var right = d3.max(coordinates, lng)
  var bottom = d3.min(coordinates, lat)
  var top = d3.max(coordinates, lat)

  return [[left, top], [right, bottom]]
}

function _calculateCenter (bounds) {
  var lat = bounds[1][1] + ((bounds[0][1] - bounds[1][1]) / 2)
  var lng = bounds[0][0] + ((bounds[1][0] - bounds[0][0]) / 2)

  return [lng, lat]
}

function _valueForLocation (data, options, locationObject) {
  let locationIndex = (_.select(data, function (d) {
    return d.location_id === locationObject.location_id
  }))[0]

  return options.value(locationIndex)
}

function _chooseRadius (v, radius) {
  if (v > radius.domain()[1]) {
    return radius.range()[1]
  } else {
    return radius(v)
  }
}

function ChoroplethMap () {
}

_.extend(ChoroplethMap.prototype, {
  defaults: DEFAULTS,

  initialize: function (el, data, options) {
    options = this._options = _.defaults({}, options, DEFAULTS)

    var margin = options.margin

    var aspect = _.get(options, 'aspect', 1)
    this._width = _.get(options, 'width', el.clientWidth)
    this._height = _.get(options, 'height', this._width * aspect)

    var svg = this._svg = d3.select(el).append('svg')
      .attr('class', 'reds')
      .attr('viewBox', '0 0 ' + this._width + ' ' + this._height)

    if (browser.isIE()) {
      svg.attr({
        'width': this._width,
        'height': this._height
      })
    }

    var g = svg.append('g')
      .attr('transform', 'translate(' + margin.left + ', ' + margin.top + ')')

    g.append('g').attr('class', 'data')
    g.append('g').attr('class', 'legend')
    svg.append('g').attr('class', 'bubbles')
    svg.select('.bubbles').append('g').attr('class', 'data')
    svg.select('.bubbles').append('g').attr('class', 'legend')

    svg.append('g').attr('class', 'stripes')
    svg.select('.stripes').append('g').attr('class', 'data')
    svg.select('.stripes').append('g').attr('class', 'legend')

    var lineWidth = 10
    var lineHeight = 10
    var lineInterval = 5

    var defs = svg.append('defs')

    var pattern = defs.append('pattern')
      .attr({
        'id': 'stripe',
        'patternUnits': 'userSpaceOnUse',
        'width': lineWidth,
        'height': lineHeight
      })

    pattern.append('line')
      .attr({
        'x1': 0,
        'y1': 0,
        'x2': -lineInterval,
        'y2': lineHeight
      })

    pattern.append('line')
      .attr({
        'x1': lineInterval,
        'y1': 0,
        'x2': 0,
        'y2': lineHeight
      })

    pattern.append('line')
      .attr({
        'x1': 2 * lineInterval,
        'y1': 0,
        'x2': lineInterval,
        'y2': lineHeight
      })

    pattern.selectAll('line')
      .attr({
        'stroke-linecap': 'square',
        'stroke-linejoin': 'miter',
        'stroke-width': 1
      })

    this.update(data)
  },

  update: function (data, options) {
    options = _.assign(this._options, options)

    var margin = options.margin
    var w = this._width - margin.left - margin.right
    var h = this._height - margin.top - margin.bottom

    var svg = this._svg
    var g = svg.select('.data')

    var features = _.reject(data, 'properties.isBorder')

    var bounds = _calculateBounds(features)
    var center = _calculateCenter(bounds)

    var projection = d3.geo.conicEqualArea()
      .parallels([bounds[1][1], bounds[0][1]])
      .rotate([-center[0], 0])   // Rotate the globe so that the country is centered horizontally
      .center([0, center[1]])    // Set the center of the projection so that the polygon is moved vertically into the center of the viewport
      .translate([w / 2, h / 2]) // Translate to the center of the viewport
      .scale(1)

    var b = [projection(bounds[0]), projection(bounds[1])]
    var s = 1 / Math.max((b[1][0] - b[0][0]) / w, (b[1][1] - b[0][1]) / h)

    projection.scale(s)

    var path = d3.geo.path().projection(projection)

    var domain = options.domain(features)

    if (!_.isArray(domain)) {
      domain = d3.extent(features, options.value)
      domain[0] = Math.min(domain[0], 0)
    }

    var colorScale = d3.scale.quantize()
      .domain(domain.concat().reverse())
      .range(options.color.concat().reverse().slice(0, 6))

    var location = g.selectAll('.location')
      .data(features, function (d, i) {
        return _.get(d, 'properties.location_id', i)
      })

    location.enter().append('path')

    location.attr({
      'd': path,
      'class': function (d) {
        var v = options.value(d)
        var classNames = ['location']

        if (_.isFinite(v)) {
          classNames.push('clickable')
        }

        return classNames.join(' ')
      }
    })
      .style('fill', function (d) {
        var v = options.value(d)
        return _.isFinite(v) ? colorScale(v) : '#fff'
      })
      .on('click', function (d) {
        options.onClick(_.get(d, 'properties.location_id'))
      })
      .on('mousemove', _.partial(this._onMouseMove, _, options, data))
      .on('mouseout', this._onMouseOut)

    location.exit().remove()

    var ticks = _.map(
      colorScale.range(),
        c => _.map(colorScale.invertExtent(c), options.xFormat).join('—')
    )

    if (!options.homepage && options.chartInDashboard) {
      if (_.every(colorScale.domain(), _.isNaN)) {
        svg.select('.legend').selectAll('*').remove()
      } else {
        svg.select('.legend')
          .call(legend().scale(
            d3.scale.ordinal().domain(ticks).range(colorScale.range())
          )
        ).attr('transform', function () { return 'translate(' + 20 + ', ' + 0 + ')' })

        let dataYPosition = options.chartInDashboard ? (ticks && ticks.length ? Math.ceil(ticks.length / 2) : 0) : 0
        g.attr('transform', 'translate(0' + ', ' + dataYPosition * 12 + ')')
      }
    }

    var legendGap = 40
    var mapLegendLength = 2
    var fontLength = 73
    var stripeLegendStartPosition

    if (options.stripeValue) {
      var stripes = svg.select('.stripes').select('.data')
      var stripeData = stripes.selectAll('.location')
        .data(features, function (d, i) {
          return _.get(d, 'properties.location_id', i)
        })

      stripeData.enter().append('path')

      stripeData.attr({
        'd': path,
        'class': d => {
          var v = options.value(d)
          var classNames = ['location']

          if (_.isFinite(v)) {
            classNames.push('clickable')
          }

          return classNames.join(' ')
        }
      })
        .style('fill', d => {
          var v = options.stripeValue(d)
          var lineColor = _.isFinite(options.value(d)) ? '#ffffff' : '#cccccc'
          svg.selectAll('line').style('stroke', lineColor)
          return _.isFinite(v) ? 'url(#stripe)' : '#fff'
        })
        .style('opacity', d => {
          var v = options.stripeValue(d)
          return _.isFinite(v) ? 1 : 0
        })
        .on('click', d => { options.onClick(_.get(d, 'properties.location_id')) })
        .on('mousemove', _.partial(this._onMouseMove, _, options, data))
        .on('mouseout', this._onMouseOut)

      stripeData.exit().remove()

      let dataYPosition = options.chartInDashboard ? (ticks && ticks.length ? Math.ceil(ticks.length / 2) : 0) : 0
      stripes.attr('transform', 'translate(0' + ', ' + dataYPosition * 12 + ')')

      if (options.chartInDashboard) {
        var stripeLegendLength = 150
        stripeLegendStartPosition = mapLegendLength * fontLength + legendGap
        var stripeLegendGap = 14
        var stripeLegendColor = d3.scale.ordinal().range(['#FFFFFF', 'url(#stripe)'])
        var stripeLegendText = ['No data', options.indicatorName]
        var stripeLegend = svg.select('.stripes').select('.legend')
          .attr('transform', function () {
            return 'translate(' + stripeLegendStartPosition + ', ' + 0 + ')'
          })
          .selectAll('.series').data(stripeLegendText)
          .enter().append('g')
          .attr('class', 'series')
          .attr('transform', function (d, i) {
            return 'translate(' + 0 + ', ' + i * stripeLegendGap + ')'
          })

        stripeLegend.append('rect')
          .attr('width', 11)
          .attr('height', 11)
          .style({
            'fill': stripeLegendColor,
            'stroke': '#cccccc',
            'stroke-width': 1
          })

        stripeLegend.append('text')
          .attr({
            'x': 16,
            'y': 3.5,
            'dy': 6
          })
          .style({
            'text-anchor': 'start',
            'font-size': 10
          })
          .text(d => { return d })
          .call(wrap, stripeLegendLength, 16)
      }
    }

    if (options.bubbleValue) {
      var radius = d3.scale.sqrt()
        .domain([0, options.maxBubbleValue])
        .range([0, options.maxBubbleRadius])

      var bubbles = svg.selectAll('.bubbles').select('.data')
      var bubbleData = bubbles.selectAll('circle')
        .data(features, function (d, i) {
          return _.get(d, 'properties.location_id', i)
        })

      bubbleData.enter().append('circle')
      bubbleData.attr('transform', function (d) {
        return 'translate(' + path.centroid(d) + ')'
      })
        .attr('r', function (d) {
          var v = options.bubbleValue(d)
          return v ? _chooseRadius(v, radius) : 0
        })
        .style({
          'opacity': 0.5,
          'fill': '#D5EBF7',
          'stroke': '#FFFFFF'
        })

      bubbleData.exit().remove()

      let dataYPosition = options.chartInDashboard ? (ticks && ticks.length ? Math.ceil(ticks.length / 2) : 0) : 0
      bubbles.attr('transform', 'translate(0' + ', ' + dataYPosition * 12 + ')')

      if (options.chartInDashboard) {
        var bubbleLegendText = _.map(options.bubbleLegendRatio, d => {
          return Math.ceil(d * options.maxBubbleValue, -1)
        })

        var bubbleLegendStartPosition = options.stripeValue
          ? stripeLegendStartPosition + stripeLegendLength + legendGap + 2.5 * options.maxBubbleRadius
          : mapLegendLength * fontLength + legendGap + 2.5 * options.maxBubbleRadius

        var bubbleLegend = svg.select('.bubbles').select('.legend')
          .attr('transform', function () {
            return 'translate(' + bubbleLegendStartPosition + ', ' + (options.maxBubbleRadius + 10) + ')'
          })
          .selectAll('.series').data(bubbleLegendText)
          .enter().append('g')
          .attr('class', 'series')

        bubbleLegend.append('circle')
          .attr('r', d => {
            return radius(d)
          })
          .attr('cy', d => {
            return (options.maxBubbleRadius - radius(d))
          })
          .style({
            'opacity': 0.5,
            'fill': 'transparent',
            'stroke': '#AAAAAA'
          })

        bubbleLegend.append('line')
          .attr({
            x1: -(2.5 * options.maxBubbleRadius),
            y1: d => {
              return (options.maxBubbleRadius - 2 * radius(d))
            },
            x2: 0,
            y2: d => {
              return (options.maxBubbleRadius - 2 * radius(d))
            }
          })
          .style('stroke', '#AAAAAA')

        bubbleLegend.append('text')
          .attr('dx', -(2.5 * options.maxBubbleRadius))
          .attr('dy', d => {
            return (options.maxBubbleRadius - 2 * radius(d))
          })
          .text(d => {
            return d
          })
          .style('fill', '#AAAAAA')
      }
    }
  },

  _onMouseMove: function (d, options, data) {
    var evt = d3.event

    var locationValue = options.name(d) + ': ' + options.xFormat(_valueForLocation(data, options, d) || 0)

    var render = function () {
      return React.createElement(
        Tooltip,
        {left: evt.pageX + 2, top: evt.pageY + 2},
        locationValue
      )
    }

    if (this.layer) {
      this.layer._render = render
    } else {
      this.layer = new Layer(document.body, render)
    }

    this.layer.render()
  },

  _onMouseOut: function () {
    if (this.layer) {
      this.layer.destroy()
      this.layer = null
    }
  }
})

export default ChoroplethMap
<commit_msg>fix the stripe for map<commit_after>import _ from 'lodash'
import d3 from 'd3'
import React from 'react'
import Layer from 'react-layer'

import Tooltip from 'component/Tooltip.jsx'

import browser from 'util/browser'
import palettes from 'util/palettes'

import legend from 'chart/renderer/legend'

var DEFAULTS = {
  aspect: 1,
  domain: _.noop,
  margin: {
    top: 0,
    right: 0,
    bottom: 0,
    left: 0
  },
  onClick: _.noop,
  value: _.property('properties.value'),
  color: palettes.orange,
  xFormat: d => d3.format(Math.abs(d) < 1 ? '.4f' : 'n')(d),
  name: _.property('properties.name'),
  maxBubbleValue: 5000,
  maxBubbleRadius: 20,
  bubbleLegendRatio: [0.1, 0.5, 1],
  indicatorName: 'Has data'
}

function wrap (text, width, x) {
  text.each(function () {
    let text = d3.select(this)
    let words = text.text().split(/\s+/).reverse()
    let word
    let line = []
    let lineNumber = 1
    let lineHeight = 1.1
    let y = text.attr('y')
    let tspan = text.text(null).append('tspan').attr('x', x).attr('y', y)
    while (words.length > 0) {
      word = words.pop()
      line.push(word)
      tspan.text(line.join(' '))
      if (tspan.node().getComputedTextLength() > (width - x)) {
        line.pop()
        tspan.text(line.join(' '))
        line = [word]
        tspan = text.append('tspan').attr('x', x).attr('y', y).attr('dy', (lineNumber * lineHeight) + 'rem').text(word)
        lineNumber += 1
      }
    }
  })
}

function _calculateBounds (features) {
  var lat = _.property(1)
  var lng = _.property(0)

  if (features.length < 1) {
    return [[0, 0], [0, 0]]
  }

  var coordinates = _(features).map(function (f) {
    if (f.geometry.type !== 'MultiPolygon') {
      return _.flatten(f.geometry.coordinates)
    }
  })
    .flatten()
    .value()

  var left = d3.min(coordinates, lng)
  var right = d3.max(coordinates, lng)
  var bottom = d3.min(coordinates, lat)
  var top = d3.max(coordinates, lat)

  return [[left, top], [right, bottom]]
}

function _calculateCenter (bounds) {
  var lat = bounds[1][1] + ((bounds[0][1] - bounds[1][1]) / 2)
  var lng = bounds[0][0] + ((bounds[1][0] - bounds[0][0]) / 2)

  return [lng, lat]
}

function _valueForLocation (data, options, locationObject) {
  let locationIndex = (_.select(data, function (d) {
    return d.location_id === locationObject.location_id
  }))[0]

  return options.value(locationIndex)
}

function _chooseRadius (v, radius) {
  if (v > radius.domain()[1]) {
    return radius.range()[1]
  } else {
    return radius(v)
  }
}

function ChoroplethMap () {
}

_.extend(ChoroplethMap.prototype, {
  defaults: DEFAULTS,

  initialize: function (el, data, options) {
    options = this._options = _.defaults({}, options, DEFAULTS)

    var margin = options.margin

    var aspect = _.get(options, 'aspect', 1)
    this._width = _.get(options, 'width', el.clientWidth)
    this._height = _.get(options, 'height', this._width * aspect)

    var svg = this._svg = d3.select(el).append('svg')
      .attr('class', 'reds')
      .attr('viewBox', '0 0 ' + this._width + ' ' + this._height)

    if (browser.isIE()) {
      svg.attr({
        'width': this._width,
        'height': this._height
      })
    }

    var g = svg.append('g')
      .attr('transform', 'translate(' + margin.left + ', ' + margin.top + ')')

    g.append('g').attr('class', 'data')
    g.append('g').attr('class', 'legend')
    svg.append('g').attr('class', 'bubbles')
    svg.select('.bubbles').append('g').attr('class', 'data')
    svg.select('.bubbles').append('g').attr('class', 'legend')

    svg.append('g').attr('class', 'stripes')
    svg.select('.stripes').append('g').attr('class', 'data')
    svg.select('.stripes').append('g').attr('class', 'legend')

    var lineWidth = 10
    var lineHeight = 10
    var lineInterval = 5

    var defs = svg.append('defs')

    var pattern = defs.append('pattern')
      .attr({
        'id': 'stripe',
        'patternUnits': 'userSpaceOnUse',
        'width': lineWidth,
        'height': lineHeight
      })

    pattern.append('line')
      .attr({
        'x1': 0,
        'y1': 0,
        'x2': -lineInterval,
        'y2': lineHeight
      })

    pattern.append('line')
      .attr({
        'x1': lineInterval,
        'y1': 0,
        'x2': 0,
        'y2': lineHeight
      })

    pattern.append('line')
      .attr({
        'x1': 2 * lineInterval,
        'y1': 0,
        'x2': lineInterval,
        'y2': lineHeight
      })

    pattern.selectAll('line')
      .attr({
        'stroke-linecap': 'square',
        'stroke-linejoin': 'miter',
        'stroke-width': 1
      })

    this.update(data)
  },

  update: function (data, options) {
    options = _.assign(this._options, options)

    var margin = options.margin
    var w = this._width - margin.left - margin.right
    var h = this._height - margin.top - margin.bottom

    var svg = this._svg
    var g = svg.select('.data')

    var features = _.reject(data, 'properties.isBorder')

    var bounds = _calculateBounds(features)
    var center = _calculateCenter(bounds)

    var projection = d3.geo.conicEqualArea()
      .parallels([bounds[1][1], bounds[0][1]])
      .rotate([-center[0], 0])   // Rotate the globe so that the country is centered horizontally
      .center([0, center[1]])    // Set the center of the projection so that the polygon is moved vertically into the center of the viewport
      .translate([w / 2, h / 2]) // Translate to the center of the viewport
      .scale(1)

    var b = [projection(bounds[0]), projection(bounds[1])]
    var s = 1 / Math.max((b[1][0] - b[0][0]) / w, (b[1][1] - b[0][1]) / h)

    projection.scale(s)

    var path = d3.geo.path().projection(projection)

    var domain = options.domain(features)

    if (!_.isArray(domain)) {
      domain = d3.extent(features, options.value)
      domain[0] = Math.min(domain[0], 0)
    }

    var colorScale = d3.scale.quantize()
      .domain(domain.concat().reverse())
      .range(options.color.concat().reverse().slice(0, 6))

    var location = g.selectAll('.location')
      .data(features, function (d, i) {
        return _.get(d, 'properties.location_id', i)
      })

    location.enter().append('path')

    location.attr({
      'd': path,
      'class': function (d) {
        var v = options.value(d)
        var classNames = ['location']

        if (_.isFinite(v)) {
          classNames.push('clickable')
        }

        return classNames.join(' ')
      }
    })
      .style('fill', function (d) {
        var v = options.value(d)
        return _.isFinite(v) ? colorScale(v) : '#fff'
      })
      .on('click', function (d) {
        options.onClick(_.get(d, 'properties.location_id'))
      })
      .on('mousemove', _.partial(this._onMouseMove, _, options, data))
      .on('mouseout', this._onMouseOut)

    location.exit().remove()

    var ticks = _.map(
      colorScale.range(),
        c => _.map(colorScale.invertExtent(c), options.xFormat).join('—')
    )

    if (!options.homepage && options.chartInDashboard) {
      if (_.every(colorScale.domain(), _.isNaN)) {
        svg.select('.legend').selectAll('*').remove()
      } else {
        svg.select('.legend')
          .call(legend().scale(
            d3.scale.ordinal().domain(ticks).range(colorScale.range())
          )
        ).attr('transform', function () { return 'translate(' + 20 + ', ' + 0 + ')' })

        let dataYPosition = options.chartInDashboard ? (ticks && ticks.length ? Math.ceil(ticks.length / 2) : 0) : 0
        g.attr('transform', 'translate(0' + ', ' + dataYPosition * 12 + ')')
      }
    }

    var legendGap = 40
    var mapLegendLength = 2
    var fontLength = 73
    var stripeLegendStartPosition

    if (options.stripeValue) {
      var stripes = svg.select('.stripes').select('.data')
      var stripeData = stripes.selectAll('.location')
        .data(features, function (d, i) {
          return _.get(d, 'properties.location_id', i)
        })

      stripeData.enter().append('path')

      stripeData.attr({
        'd': path,
        'class': d => {
          var v = options.value(d)
          var classNames = ['location']

          if (_.isFinite(v)) {
            classNames.push('clickable')
          }

          return classNames.join(' ')
        }
      })
        .style('fill', d => {
          var v = options.stripeValue(d)
          var lineColor = _.isFinite(options.value(d)) ? '#ffffff' : '#cccccc'
          svg.selectAll('line').style('stroke', lineColor)
          return (_.isFinite(v) && v > 0) ? 'url(#stripe)' : '#fff'
        })
        .style('opacity', d => {
          var v = options.stripeValue(d)
          return _.isFinite(v) ? 1 : 0
        })
        .on('click', d => { options.onClick(_.get(d, 'properties.location_id')) })
        .on('mousemove', _.partial(this._onMouseMove, _, options, data))
        .on('mouseout', this._onMouseOut)

      stripeData.exit().remove()

      let dataYPosition = options.chartInDashboard ? (ticks && ticks.length ? Math.ceil(ticks.length / 2) : 0) : 0
      stripes.attr('transform', 'translate(0' + ', ' + dataYPosition * 12 + ')')

      if (options.chartInDashboard) {
        var stripeLegendLength = 150
        stripeLegendStartPosition = mapLegendLength * fontLength + legendGap
        var stripeLegendGap = 14
        var stripeLegendColor = d3.scale.ordinal().range(['#FFFFFF', 'url(#stripe)'])
        var stripeLegendText = ['No data', options.indicatorName]
        var stripeLegend = svg.select('.stripes').select('.legend')
          .attr('transform', function () {
            return 'translate(' + stripeLegendStartPosition + ', ' + 0 + ')'
          })
          .selectAll('.series').data(stripeLegendText)
          .enter().append('g')
          .attr('class', 'series')
          .attr('transform', function (d, i) {
            return 'translate(' + 0 + ', ' + i * stripeLegendGap + ')'
          })

        stripeLegend.append('rect')
          .attr('width', 11)
          .attr('height', 11)
          .style({
            'fill': stripeLegendColor,
            'stroke': '#cccccc',
            'stroke-width': 1
          })

        stripeLegend.append('text')
          .attr({
            'x': 16,
            'y': 3.5,
            'dy': 6
          })
          .style({
            'text-anchor': 'start',
            'font-size': 10
          })
          .text(d => { return d })
          .call(wrap, stripeLegendLength, 16)
      }
    }

    if (options.bubbleValue) {
      var radius = d3.scale.sqrt()
        .domain([0, options.maxBubbleValue])
        .range([0, options.maxBubbleRadius])

      var bubbles = svg.selectAll('.bubbles').select('.data')
      var bubbleData = bubbles.selectAll('circle')
        .data(features, function (d, i) {
          return _.get(d, 'properties.location_id', i)
        })

      bubbleData.enter().append('circle')
      bubbleData.attr('transform', function (d) {
        return 'translate(' + path.centroid(d) + ')'
      })
        .attr('r', function (d) {
          var v = options.bubbleValue(d)
          return v ? _chooseRadius(v, radius) : 0
        })
        .style({
          'opacity': 0.5,
          'fill': '#D5EBF7',
          'stroke': '#FFFFFF'
        })

      bubbleData.exit().remove()

      let dataYPosition = options.chartInDashboard ? (ticks && ticks.length ? Math.ceil(ticks.length / 2) : 0) : 0
      bubbles.attr('transform', 'translate(0' + ', ' + dataYPosition * 12 + ')')

      if (options.chartInDashboard) {
        var bubbleLegendText = _.map(options.bubbleLegendRatio, d => {
          return Math.ceil(d * options.maxBubbleValue, -1)
        })

        var bubbleLegendStartPosition = options.stripeValue
          ? stripeLegendStartPosition + stripeLegendLength + legendGap + 2.5 * options.maxBubbleRadius
          : mapLegendLength * fontLength + legendGap + 2.5 * options.maxBubbleRadius

        var bubbleLegend = svg.select('.bubbles').select('.legend')
          .attr('transform', function () {
            return 'translate(' + bubbleLegendStartPosition + ', ' + (options.maxBubbleRadius + 10) + ')'
          })
          .selectAll('.series').data(bubbleLegendText)
          .enter().append('g')
          .attr('class', 'series')

        bubbleLegend.append('circle')
          .attr('r', d => {
            return radius(d)
          })
          .attr('cy', d => {
            return (options.maxBubbleRadius - radius(d))
          })
          .style({
            'opacity': 0.5,
            'fill': 'transparent',
            'stroke': '#AAAAAA'
          })

        bubbleLegend.append('line')
          .attr({
            x1: -(2.5 * options.maxBubbleRadius),
            y1: d => {
              return (options.maxBubbleRadius - 2 * radius(d))
            },
            x2: 0,
            y2: d => {
              return (options.maxBubbleRadius - 2 * radius(d))
            }
          })
          .style('stroke', '#AAAAAA')

        bubbleLegend.append('text')
          .attr('dx', -(2.5 * options.maxBubbleRadius))
          .attr('dy', d => {
            return (options.maxBubbleRadius - 2 * radius(d))
          })
          .text(d => {
            return d
          })
          .style('fill', '#AAAAAA')
      }
    }
  },

  _onMouseMove: function (d, options, data) {
    var evt = d3.event

    var locationValue = options.name(d) + ': ' + options.xFormat(_valueForLocation(data, options, d) || 0)

    var render = function () {
      return React.createElement(
        Tooltip,
        {left: evt.pageX + 2, top: evt.pageY + 2},
        locationValue
      )
    }

    if (this.layer) {
      this.layer._render = render
    } else {
      this.layer = new Layer(document.body, render)
    }

    this.layer.render()
  },

  _onMouseOut: function () {
    if (this.layer) {
      this.layer.destroy()
      this.layer = null
    }
  }
})

export default ChoroplethMap
<|endoftext|>