<commit_before>"use strict";
process.env.NODE_ENV = 'test';

const _ = require('underscore');
const chai = require('chai');
const expect = chai.expect;
const chaiAsPromised = require('chai-as-promised');
chai.use(chaiAsPromised);

const queue = require('../../lib/queue');
const taskProcessor = require('../../lib/taskProcessor');

describe("Type Override - freqDist to timeSeries", function(){

    it.only('2 level depth', function() {

        let config = {
            "freqDist": [
                {
                    "target": "fb.author.gender",
                    "threshold": 2,
                    "then": {
                        "type": "timeSeries",
                        "interval": "day"
                    }
                }
            ]
        };

        let configTasks = taskProcessor.loadConfigTasks(config);

        return queue.queueTask(configTasks[0]).then(function(result){

            expect(result[0].male[0]).to.have.all.keys(["key", "interactions", "unique_authors"]);
            expect(result[0].female[0]).to.have.all.keys(["key", "interactions", "unique_authors"]);
            expect(result[0].male[0].key).to.be.a('number');
            expect(result[0].female[0].key).to.be.a('number');

        });
    });

});<commit_msg>Enable all tests<commit_after>"use strict";
process.env.NODE_ENV = 'test';

const _ = require('underscore');
const chai = require('chai');
const expect = chai.expect;
const chaiAsPromised = require('chai-as-promised');
chai.use(chaiAsPromised);

const queue = require('../../lib/queue');
const taskProcessor = require('../../lib/taskProcessor');

describe("Type Override - freqDist to timeSeries", function(){

    it('2 level depth', function() {

        let config = {
            "freqDist": [
                {
                    "target": "fb.author.gender",
                    "threshold": 2,
                    "then": {
                        "type": "timeSeries",
                        "interval": "day"
                    }
                }
            ]
        };

        let configTasks = taskProcessor.loadConfigTasks(config);

        return queue.queueTask(configTasks[0]).then(function(result){

            expect(result[0].male[0]).to.have.all.keys(["key", "interactions", "unique_authors"]);
            expect(result[0].female[0]).to.have.all.keys(["key", "interactions", "unique_authors"]);
            expect(result[0].male[0].key).to.be.a('number');
            expect(result[0].female[0].key).to.be.a('number');

        });
    });

});<|endoftext|>


<commit_before>window.onload = function () {
    function getElementsByAttribute(attribute)
        {
            var matchingElements = [];
            var allElements = document.getElementsByTagName('*');
            for (var i = 0, n = allElements.length; i < n; i++)
            {
                if (allElements[i].getAttribute(attribute) !== null)
                {
                    // Element exists with attribute. Add to array.
                    matchingElements.push(allElements[i]);
                }
            }
            return matchingElements;
        }

    function log(msg) {
        console.log(msg);
    }
    var ponyPets = getElementsByAttribute('data-ponypet');

    function ponyPet(canvas) {
        var ponyStates = [];
        var currentPonyState = null;
        var ponyImg;

        var elem = document.createElement("img");
        elem.setAttribute("src", "img/1.gif");
        elem.setAttribute("height", "200");
        elem.setAttribute("width", "200");
        elem.setAttribute("alt", "Best Pony");
        elem.setAttribute("id", "ponyImg");
        elem.onclick = ponyPet_clicked;

        canvas.appendChild(elem);
        ponyImg = elem;

        function changePonyTo(id) {
            ponyImg.setAttribute("src", "img/" + id + ".gif");
        }

        function pet() {
            currentPonyState.pet();
            changePonyTo(currentPonyState.id);
        }
        function eye() {
            currentPonyState.eye();
            changePonyTo(currentPonyState.id);
        }
        function boop() {
            currentPonyState.boop();
            changePonyTo(currentPonyState.id);
        }
        function mouth() {
            currentPonyState.mouth();
            changePonyTo(currentPonyState.id);
        }
        function pnpoly(nvert, vertx, verty, testx, testy) {
            var i, j, c = false;
            for (i = 0, j = nvert - 1; i < nvert; j = i++) {
                if (((verty[i] > testy) != (verty[j] > testy)) &&
                    (testx < (vertx[j] - vertx[i]) * (testy - verty[i]) / (verty[j] - verty[i]) + vertx[i])) {
                    c = !c;
                }
            }
            return c;
        }

        var petPoly = {
            vx: [75, 87, 186, 168, 178, 199, 133, 120, 111, 66, 38, 5, 13, 33, 56, 75],
            vy: [171, 199, 200, 161, 119, 104, 2, 3, 30, 5, 73, 73, 116, 164, 155, 171]
        };

        var eyesPoly = {
            vx: [57, 68, 82, 106, 113, 120, 135, 153, 139, 131, 118, 106, 107, 81, 89, 81, 67, 54, 51, 49, 59],
            vy: [92, 94, 107, 105, 85, 79, 79, 105, 135, 141, 141, 128, 105, 107, 144, 150, 150, 136, 125, 103, 93]
        };
        var boopPoly = {
            vx: [106, 107, 80, 88, 93, 106, 107, 106],
            vy: [128, 105, 107, 143, 151, 150, 146, 128]
        };
        var mouthPoly = {
            vx: [93, 106, 125, 122, 95, 85, 93],
            vy: [151, 150, 149, 167, 170, 157, 151]
        };

        function findPosition(oElement) {
            if (typeof (oElement.offsetParent) != "undefined") {
                for (var posX = 0, posY = 0; oElement; oElement = oElement.offsetParent) {
                    posX += oElement.offsetLeft;
                    posY += oElement.offsetTop;
                }
                return [posX, posY];
            }
            else {
                return [oElement.x, oElement.y];
            }
        }

        function getCoordinates(e, img) {
            var posX = 0;
            var posY = 0;
            var imgPos;
            imgPos = findPosition(img);
            if (!e) var e = window.event;
            if (e.pageX || e.pageY) {
                posX = e.pageX;
                posY = e.pageY;
            }
            else if (e.clientX || e.clientY) {
                posX = e.clientX + document.body.scrollLeft
                  + document.documentElement.scrollLeft;
                posY = e.clientY + document.body.scrollTop
                  + document.documentElement.scrollTop;
            }
            posX = posX - imgPos[0];
            posY = posY - imgPos[1];

            return { x: posX, y: posY };
            //if(pnpoly(4,vx,vy,posX,posY)) boop();
            //alert(PosX +","+PosY+": "+pnpoly(4,vx,vy,PosX,PosY));
        }
        function ponyPet_clicked(e) {
            var coordinates = getCoordinates(e, elem);

            if (pnpoly(boopPoly.vx.length, boopPoly.vx, boopPoly.vy, coordinates.x, coordinates.y)) boop();
            else if (pnpoly(mouthPoly.vx.length, mouthPoly.vx, mouthPoly.vy, coordinates.x, coordinates.y)) mouth();
            else if (pnpoly(eyesPoly.vx.length, eyesPoly.vx, eyesPoly.vy, coordinates.x, coordinates.y)) eye();
            else if (pnpoly(petPoly.vx.length, petPoly.vx, petPoly.vy, coordinates.x, coordinates.y)) pet();
            //else alert(PosX + "," + PosY + ": " + pnpoly(4, vx, vy, PosX, PosY));
        }

        function ponyStateFactory(id, pet, eye, boop, mouth) {
            return {
                id: id,
                pet: function () {
                    log("pet");
                    currentPonyState = ponyStates[pet - 1];
                    log("Now at state: " + currentPonyState.id);
                },
                eye: function () {
                    log("eye");
                    currentPonyState = ponyStates[eye - 1];
                    log("Now at state: " + currentPonyState.id);
                },
                boop: function () {
                    log("boop");
                    currentPonyState = ponyStates[boop - 1];
                    log("Now at state: " + currentPonyState.id);
                },
                mouth: function () {
                    log("mouth");
                    currentPonyState = ponyStates[mouth - 1];
                    log("Now at state: " + currentPonyState.id);
                }
            };
        }

        ponyStates.push(ponyStateFactory(1, 1, 6, 3, 13));
        ponyStates.push(ponyStateFactory(2, 3, 10, 6, 10));
        ponyStates.push(ponyStateFactory(3, 5, 11, 1, 9));
        ponyStates.push(ponyStateFactory(4, 5, 8, 3, 12));
        ponyStates.push(ponyStateFactory(5, 1, 11, 11, 13));
        ponyStates.push(ponyStateFactory(6, 7, 10, 11, 14));
        ponyStates.push(ponyStateFactory(7, 1, 10, 2, 14));
        ponyStates.push(ponyStateFactory(8, 4, 10, 11, 4));
        ponyStates.push(ponyStateFactory(9, 9, 11, 11, 1));
        ponyStates.push(ponyStateFactory(10, 2, 2, 8, 3));
        ponyStates.push(ponyStateFactory(11, 13, 13, 12, 3));
        ponyStates.push(ponyStateFactory(12, 13, 11, 11, 5));
        ponyStates.push(ponyStateFactory(13, 9, 10, 11, 5));
        ponyStates.push(ponyStateFactory(14, 13, 10, 11, 6));

        currentPonyState = ponyStates[4];

        changePonyTo(currentPonyState.id);
    };

    for (var ponyPetIndex = 0; ponyPetIndex < ponyPets.length; ponyPetIndex++) {
        new ponyPet(ponyPets[ponyPetIndex])
    }
};
<commit_msg>Change scope of some variables. Adding some comments.<commit_after>window.onload = function () {
    //For debugging
    function log(msg) {
        console.log(msg);
    }

    function getElementsByAttribute(attribute) {
        var matchingElements = [];
        var allElements = document.getElementsByTagName('*');
        for (var i = 0, n = allElements.length; i < n; i++) {
            if (allElements[i].getAttribute(attribute) !== null) {
                // Element exists with attribute. Add to array.
                matchingElements.push(allElements[i]);
            }
        }
        return matchingElements;
    }

    function pnpoly(nvert, vertx, verty, testx, testy) {
        var i, j, c = false;
        for (i = 0, j = nvert - 1; i < nvert; j = i++) {
            if (((verty[i] > testy) != (verty[j] > testy)) &&
                (testx < (vertx[j] - vertx[i]) * (testy - verty[i]) / (verty[j] - verty[i]) + vertx[i])) {
                c = !c;
            }
        }
        return c;
    }

    function findPosition(oElement) {
        if (typeof (oElement.offsetParent) != "undefined") {
            for (var posX = 0, posY = 0; oElement; oElement = oElement.offsetParent) {
                posX += oElement.offsetLeft;
                posY += oElement.offsetTop;
            }
            return [posX, posY];
        }
        else {
            return [oElement.x, oElement.y];
        }
    }

    function getCoordinates(e, img) {
        var posX = 0;
        var posY = 0;
        var imgPos;
        imgPos = findPosition(img);
        if (!e) var e = window.event;
        if (e.pageX || e.pageY) {
            posX = e.pageX;
            posY = e.pageY;
        }
        else if (e.clientX || e.clientY) {
            posX = e.clientX + document.body.scrollLeft
              + document.documentElement.scrollLeft;
            posY = e.clientY + document.body.scrollTop
              + document.documentElement.scrollTop;
        }
        posX = posX - imgPos[0];
        posY = posY - imgPos[1];

        return { x: posX, y: posY };
    }

    var petPoly = {
        vx: [75, 87, 186, 168, 178, 199, 133, 120, 111, 66, 38, 5, 13, 33, 56, 75],
        vy: [171, 199, 200, 161, 119, 104, 2, 3, 30, 5, 73, 73, 116, 164, 155, 171]
    };
    var eyesPoly = {
        vx: [57, 68, 82, 106, 113, 120, 135, 153, 139, 131, 118, 106, 107, 81, 89, 81, 67, 54, 51, 49, 59],
        vy: [92, 94, 107, 105, 85, 79, 79, 105, 135, 141, 141, 128, 105, 107, 144, 150, 150, 136, 125, 103, 93]
    };
    var boopPoly = {
        vx: [106, 107, 80, 88, 93, 106, 107, 106],
        vy: [128, 105, 107, 143, 151, 150, 146, 128]
    };
    var mouthPoly = {
        vx: [93, 106, 125, 122, 95, 85, 93],
        vy: [151, 150, 149, 167, 170, 157, 151]
    };

    function ponyPet(canvas) {
        var ponyStates = [];
        var currentPonyState;
        var ponyImg;

        function changePonyTo(id) {
            ponyImg.setAttribute("src", "img/" + id + ".gif");
        }

        function pet() {
            currentPonyState.pet();
            changePonyTo(currentPonyState.id);
        }
        function eye() {
            currentPonyState.eye();
            changePonyTo(currentPonyState.id);
        }
        function boop() {
            currentPonyState.boop();
            changePonyTo(currentPonyState.id);
        }
        function mouth() {
            currentPonyState.mouth();
            changePonyTo(currentPonyState.id);
        }

        function ponyPet_clicked(e) {
            var coordinates = getCoordinates(e, elem);

            if (pnpoly(boopPoly.vx.length, boopPoly.vx, boopPoly.vy, coordinates.x, coordinates.y)) boop();
            else if (pnpoly(mouthPoly.vx.length, mouthPoly.vx, mouthPoly.vy, coordinates.x, coordinates.y)) mouth();
            else if (pnpoly(eyesPoly.vx.length, eyesPoly.vx, eyesPoly.vy, coordinates.x, coordinates.y)) eye();
            else if (pnpoly(petPoly.vx.length, petPoly.vx, petPoly.vy, coordinates.x, coordinates.y)) pet();
        }

        //In this Pony Factory, all your hopes and dreams come true
        //This is not like the *other* factory you may have heard of... ;)
        function ponyStateFactory(id, pet, eye, boop, mouth) {
            return {
                id: id,
                pet: function () {
                    log("pet");
                    currentPonyState = ponyStates[pet - 1];
                    log("Now at state: " + currentPonyState.id);
                },
                eye: function () {
                    log("eye");
                    currentPonyState = ponyStates[eye - 1];
                    log("Now at state: " + currentPonyState.id);
                },
                boop: function () {
                    log("boop");
                    currentPonyState = ponyStates[boop - 1];
                    log("Now at state: " + currentPonyState.id);
                },
                mouth: function () {
                    log("mouth");
                    currentPonyState = ponyStates[mouth - 1];
                    log("Now at state: " + currentPonyState.id);
                }
            };
        }

        ponyStates.push(ponyStateFactory(1, 1, 6, 3, 13));
        ponyStates.push(ponyStateFactory(2, 3, 10, 6, 10));
        ponyStates.push(ponyStateFactory(3, 5, 11, 1, 9));
        ponyStates.push(ponyStateFactory(4, 5, 8, 3, 12));
        ponyStates.push(ponyStateFactory(5, 1, 11, 11, 13));
        ponyStates.push(ponyStateFactory(6, 7, 10, 11, 14));
        ponyStates.push(ponyStateFactory(7, 1, 10, 2, 14));
        ponyStates.push(ponyStateFactory(8, 4, 10, 11, 4));
        ponyStates.push(ponyStateFactory(9, 9, 11, 11, 1));
        ponyStates.push(ponyStateFactory(10, 2, 2, 8, 3));
        ponyStates.push(ponyStateFactory(11, 13, 13, 12, 3));
        ponyStates.push(ponyStateFactory(12, 13, 11, 11, 5));
        ponyStates.push(ponyStateFactory(13, 9, 10, 11, 5));
        ponyStates.push(ponyStateFactory(14, 13, 10, 11, 6));

        currentPonyState = ponyStates[4];

        var elem = document.createElement("img");
        elem.setAttribute("src", "img/1.gif");
        elem.setAttribute("height", "200");
        elem.setAttribute("width", "200");
        elem.setAttribute("alt", "Best Pony");
        elem.setAttribute("id", "ponyImg");
        elem.onclick = ponyPet_clicked;

        canvas.appendChild(elem);
        ponyImg = elem;

        changePonyTo(currentPonyState.id);
    };

    //Get every ponypet on the page and initialize them
    var ponyPets = getElementsByAttribute('data-ponypet');
    for (var ponyPetIndex = 0; ponyPetIndex < ponyPets.length; ponyPetIndex++) {
        new ponyPet(ponyPets[ponyPetIndex]);
    }
};<|endoftext|>


<commit_before>/**
 * @file test for rule title-required
 * @author nighca<nighca@live.cn>
 */

var path = require('path');
var htmlcs = require('../../../../');
var parse = require('../../../../lib/parse');

var rule = path.basename(__dirname);

describe('rule ' + rule, function () {
    var result1 = htmlcs.hintFile(path.join(__dirname, 'case1.html'));
    var result2 = htmlcs.hintFile(path.join(__dirname, 'case2.html'));
    var result3 = htmlcs.hintFile(path.join(__dirname, 'case3.html'));
    var result4 = htmlcs.hintFile(path.join(__dirname, 'case4.html'));
    var result5 = htmlcs.hintFile(path.join(__dirname, 'case5.html'));
    var result6 = htmlcs.hintFile(path.join(__dirname, 'case6.html'));

    it('should return right result', function () {
        expect(result1.length).toBe(1);
        expect(result1[0].type).toBe('WARN');
        expect(result1[0].code).toBe('024');
        expect(result1[0].line).toBe(3);
        expect(result1[0].col).toBe(1);

        expect(result2.length).toBe(1);
        expect(result2[0].type).toBe('WARN');
        expect(result2[0].code).toBe('024');
        expect(result2[0].line).toBe(3);
        expect(result2[0].col).toBe(1);

        expect(result3.length).toBe(1);
        expect(result3[0].type).toBe('WARN');
        expect(result3[0].code).toBe('025');
        expect(result3[0].line).toBe(6);
        expect(result3[0].col).toBe(5);

        expect(result4.length).toBe(1);
        expect(result4[0].type).toBe('WARN');
        expect(result4[0].code).toBe('025');
        expect(result4[0].line).toBe(4);
        expect(result4[0].col).toBe(5);

        expect(result5.length).toBe(0);
        expect(result6.length).toBe(0);
    });
});

describe('format rule ' + rule, function () {
    var head1 = parse(htmlcs.formatFile(path.join(__dirname, 'case1.html'))).querySelector('head');
    var head2 = parse(htmlcs.formatFile(path.join(__dirname, 'case2.html'))).querySelector('head');
    var head3 = parse(htmlcs.formatFile(path.join(__dirname, 'case3.html'))).querySelector('head');
    var head4 = parse(htmlcs.formatFile(path.join(__dirname, 'case4.html'))).querySelector('head');
    var head5 = parse(htmlcs.formatFile(path.join(__dirname, 'case5.html'))).querySelector('head');

    it('should format well', function () {
        var title;
        var charsetMeta;

        title = head1.querySelector('title');
        charsetMeta = head1.querySelector('meta[charset]');
        expect(title.previousElementSibling).toBe(charsetMeta);

        title = head2.querySelector('title');
        charsetMeta = head2.querySelector('meta[charset]');
        expect(title.previousElementSibling).toBe(charsetMeta);

        title = head3.querySelector('title');
        charsetMeta = head3.querySelector('meta[charset]');
        expect(title.previousElementSibling).toBe(charsetMeta);

        title = head4.querySelector('title');
        charsetMeta = head4.querySelector('meta[charset]');
        expect(title.previousElementSibling).toBe(charsetMeta);
    });
});
<commit_msg>update test for title-required<commit_after>/**
 * @file test for rule title-required
 * @author nighca<nighca@live.cn>
 */

var path = require('path');
var htmlcs = require('../../../../');
var parse = require('../../../../lib/parse');

var rule = path.basename(__dirname);

describe('rule ' + rule, function () {
    var result1 = htmlcs.hintFile(path.join(__dirname, 'case1.html'));
    var result2 = htmlcs.hintFile(path.join(__dirname, 'case2.html'));
    var result3 = htmlcs.hintFile(path.join(__dirname, 'case3.html'));
    var result4 = htmlcs.hintFile(path.join(__dirname, 'case4.html'));
    var result5 = htmlcs.hintFile(path.join(__dirname, 'case5.html'));
    var result6 = htmlcs.hintFile(path.join(__dirname, 'case6.html'));

    it('should return right result', function () {
        expect(result1.length).toBe(1);
        expect(result1[0].type).toBe('WARN');
        expect(result1[0].code).toBe('024');
        expect(result1[0].line).toBe(3);
        expect(result1[0].col).toBe(1);

        expect(result2.length).toBe(1);
        expect(result2[0].type).toBe('WARN');
        expect(result2[0].code).toBe('024');
        expect(result2[0].line).toBe(3);
        expect(result2[0].col).toBe(1);

        expect(result3.length).toBe(1);
        expect(result3[0].type).toBe('WARN');
        expect(result3[0].code).toBe('025');
        expect(result3[0].line).toBe(6);
        expect(result3[0].col).toBe(5);

        expect(result4.length).toBe(1);
        expect(result4[0].type).toBe('WARN');
        expect(result4[0].code).toBe('025');
        expect(result4[0].line).toBe(4);
        expect(result4[0].col).toBe(5);

        expect(result5.length).toBe(0);
        expect(result6.length).toBe(0);
    });
});

describe('format rule ' + rule, function () {
    var head1 = parse(htmlcs.formatFile(path.join(__dirname, 'case1.html'))).querySelector('head');
    var head2 = parse(htmlcs.formatFile(path.join(__dirname, 'case2.html'))).querySelector('head');
    var head3 = parse(htmlcs.formatFile(path.join(__dirname, 'case3.html'))).querySelector('head');
    var head4 = parse(htmlcs.formatFile(path.join(__dirname, 'case4.html'))).querySelector('head');
    var head5 = parse(htmlcs.formatFile(path.join(__dirname, 'case5.html'))).querySelector('head');

    it('should format well', function () {
        var title;
        var charsetMeta;

        title = head1.querySelector('title');
        charsetMeta = head1.querySelector('meta[charset]');
        expect(title.previousElementSibling).toBe(charsetMeta);

        title = head2.querySelector('title');
        charsetMeta = head2.querySelector('meta[charset]');
        expect(title.previousElementSibling).toBe(charsetMeta);

        title = head3.querySelector('title');
        charsetMeta = head3.querySelector('meta[charset]');
        expect(title.previousElementSibling).toBe(charsetMeta);

        title = head4.querySelector('title');
        charsetMeta = head4.querySelector('meta[charset]');
        expect(title.previousElementSibling).toBe(charsetMeta);

        expect(!head5).toBe(true);
    });
});
<|endoftext|>


<commit_before>// ==UserScript==
// @name        toolset
// @namespace   samsquanchhunter14@gmail.com
// @include     http://aimgames.forummotion.com/*
// @version     1.1
// @grant       none
// ==/UserScript==

//test thing

var css_string = "@import url(\'http://fonts.googleapis.com/css?family=Noto+Sans:400,700\');.box{width: 0px;height: 0px;position: relative;border: 0px solid #BBB;background: #EEE;font-family: \'Noto Sans\', sans-serif}.ribbon{width: 200px;background: #e43;position: absolute;top: 0px;left: -10px;text-align: center;line-height: 50px;letter-spacing: 1px;color: #ff0000;font-size: 18px}.ribbon span{width: 200px;background: #e43;position: absolute;top: 25px;left: -50px;text-align: center;line-height: 50px;letter-spacing: 1px;color: #f0f0f0;transform: rotate(-45deg);-webkit-transform: rotate(-45deg);font-size: 18px}.ribbon span::before{content: \"\";position:absolute;left:0px;top:100%;z-index:-1;border-left:3px solid #8F0808;border-right:3px solid transparent;border-bottom:3px solid transparent;border-top:3px solid #8F0808}.ribbon span::after{content:\"\";position:absolute;right:0px;top:100%;z-index:-1;border-left:3px solid transparent;border-right:3px solid #8F0808;border-bottom:3px solid transparent;border-top:3px solid #8F0808}";

var preva = "";
function get_new_msg() { //do we have a new msg
  if (document.getElementById("frame_chatbox").contentWindow.document.getElementById("chatbox").innerHTML != preva && preva != "") {
    preva = document.getElementById("frame_chatbox").contentWindow.document.getElementById("chatbox").innerHTML;
    return true;
  } else {
    preva = document.getElementById("frame_chatbox").contentWindow.document.getElementById("chatbox").innerHTML;
    return false;
  }
}

var new_msgs = 0; //how many new msgs
function get_new_msgs() {
  if (!visibleY(document.getElementById("frame_chatbox"))) { //are we not at cbox
    if (get_new_msg()) {
      new_msgs++;
      box_div.innerHTML =  '

' + new_msgs + ' new msgs

';
    }
  } else if (new_msgs != 0) {
    new_msgs = 0;
    box_div.innerHTML = '

';
  }
  //print(new_msgs);
}

function check_em() {
  document.getElementById("frame_chatbox").contentWindow.
  document.getElementById("chatbox").innerHTML = document.getElementById("frame_chatbox").contentWindow.
  document.getElementById("chatbox").innerHTML.
  replace(/\:11\]/g,
          '\:11\] CHECK \'EM');
  replace(/\:22\]/g,
          '\:22\] CHECK \'EM');
  replace(/\:33\]/g,
          '\:33\] CHECK \'EM');
  replace(/\:44\]/g,
          '\:44\] CHECK \'EM');
  replace(/\:55\]/g,
          '\:55\] CHECK \'EM');
  replace(/\:66\]/g,
          '\:66\] CHECK \'EM');
  replace(/\:77\]/g,
          '\:77\] CHECK \'EM');
  replace(/\:88\]/g,
          '\:88\] CHECK \'EM');
  replace(/\:99\]/g,
          '\:99\] CHECK \'EM');
  replace(/\:00\]/g,
          '\:00\] CHECK \'EM');

}

var gstyle;
function inject_css(css) {
    var head;
    head = document.getElementsByTagName('head')[0];
    if (!head) { return; }
    gstyle = document.createElement('style');
    gstyle.type = 'text/css';
    gstyle.innerHTML = css;
    head.appendChild(gstyle);
}

var visibleY = function(el){
    var top = el.getBoundingClientRect().top, rect, el = el.parentNode;
    do {
        rect = el.getBoundingClientRect();
        if (top <= rect.bottom === false)
            return false;
        el = el.parentNode;
    } while (el != document.body);
    // Check its within the document viewport
    return top <= document.documentElement.clientHeight;
};

var box_div; //init the box div so it can go anywhere
window.onload = function() {
  // inject our css
  inject_css(css_string);

  // make an empty div where the box will go
  var over_div = document.body;
  box_div = over_div.appendChild(document.createElement('div'));
  box_div.innerHTML =  '

';

  // get the count of new msgs
  setInterval(get_new_msgs, 500);

  function getScrollTop() { //// http://stackoverflow.com/questions/6691558/how-do-i-make-a-div-follow-me-as-i-scroll-down-the-page
      if (typeof window.pageYOffset !== 'undefined' ) {
        // Most browsers
        return window.pageYOffset;
      }

      var d = document.documentElement;
      if (d.clientHeight) {
        // IE in standards mode
        return d.scrollTop;
      }

      // IE in quirks mode
      return document.body.scrollTop;
  }

  window.onscroll = function() {
    //make the box scroll with the screen
    var box = document.getElementById('box'),
    scroll = getScrollTop();

    if (box !== null) {
      if (scroll <= 28) {
        box.style.top = "30px";
      } else {
        box.style.top = (scroll + 2) + "px";
      }
    }

    //reset the msgs if scrolled to the cbox
    if (visibleY(document.getElementById("frame_chatbox"))) { //this is not used
      is_at_cbox = true;
    } else {
      is_at_cbox = false;
    }
  };

}
// += works too

function getUserTagsOnDocument() {
  var atags = document.getElementsByTagName('a')
  var utags = [ ];
  for (var i in atags) {
  	if (atags[i] && atags[i].href && atags[i].href.match(/\/u/))
  		utags[utags.length] = atags[i];
  }
  return utags;
}
<commit_msg>fukken shit that works<commit_after>// ==UserScript==
// @name        toolset
// @namespace   samsquanchhunter14@gmail.com
// @include     http://aimgames.forummotion.com/*
// @version     1.2
// @grant       none
// ==/UserScript==

//won't work in bchat
var chatboxElement = document.getElementById('frame_chatbox').contentWindow.document.getElementById('chatbox');

var messages = chatboxElement.children;

/**
 * Returns the user who posted 'msgDOM' chatbox message
 */
function msgSender(msgDOM) {
	if (msgDOM.getElementsByClassName('user-msg')[0] !== undefined) //if this is not a "user joined"/"user dc'ed"/"user left" message
		return msgDOM.getElementsByClassName('user-msg')[0].getElementsByClassName('chatbox-username')[0].innerHTML;
	else
		return null;
}

/**
 * Returns the timestamp of 'msgDOM' chatbox message in HH:MM:SS format
 */
function msgTimestamp(msgDOM) {
	return msgDOM.getElementsByClassName('date-and-time')[0].innerHTML.substring(1, msgDOM.getElementsByClassName('date-and-time')[0].innerHTML.length-1);
}

/**
 * Returns true if 'strg' is dubs and in HH:MM:SS format
 */
function isDubs(strg) {
	strg = strg.substring(6,8); // HH:MM:SS format
	if (strg == "11")
		return true;
	if (strg == "22")
		return true;
	if (strg == "33")
		return true;
	if (strg == "44")
		return true;
	if (strg == "55")
		return true;
	if (strg == "66")
		return true;
	if (strg == "77")
		return true;
	if (strg == "88")
		return true;
	if (strg == "99")
		return true;
	if (strg == "00")
		return true;
	return false;
}

var oldMessagesAmount = messages.length;
/**
 * Returns the amount of new messages since the last time this function was called
 */
function newMsgs() {
	return messages.length - oldMessagesAmount;
}
function resetNewMsgs() {
	oldMessagesAmount = messages.length;
}

/**
 * CHECK 'EM (call this once every chat update)
 */
function checkDubs() {
	for (var i = 0; i < messages.length; i++) { //DON'T DO A FOREACH (VAR X IN Y) IN HTMLCOLLECTIONS IT WILL THROW AN ERROR
		if (isDubs(msgTimestamp(messages[i]))) {
			var dubsSpan = document.createElement('span');
			dubsSpan.style = "color:red";
			dubsSpan.innerHTML = ' CHECK \'EM';
			messages[i].children[0].appendChild(dubsSpan);
		}
	}
}

var boxElement = document.createElement('div'); //box element that holds the new msg ribbon
boxElement.className = 'box'; //not element.class
boxElement.style = 'position: fixed;left: 1%;top: 2%;';
var ribbonElement = document.createElement('div'); //new msg ribbon
ribbonElement.className = 'ribbon'; //not element.class
var ribbonText = document.createElement('span'); //new msg string (X new msgs)
ribbonElement.appendChild(ribbonText);
/**
 * Makes the 'new message!' box
 */
function makeBox() {
  console.log('is at cbox - ' + getScrollTop() + ' new msgs - ' + newMsgs());
  if (getScrollTop() <= 1700) { //are we not at cbox (doesnt work in bchat, may bug in different resolutions) --- 1700 is scroll top 1400 is scroll bottom in my resolution
    ////// QUESTION >>>> IS THIS SLOW? THIS SEEMS TO UPDATE THE DOM EVERY TIME THE FUNCTION IS CALLED; IS IT FASTER TO CHECK IF THE INNERHTML NEEDS TO BE CHANGED?
    ribbonText.innerHTML = newMsgs() + ' new msgs';
    if (newMsgs() > 0) { //note MSG NUMBER CAN BE UNDER 0!!! since the non-archive chat removes old messages or something... this may be a problem (if someone posts 1 msg and 1 is removed the new msg counter is not displayed)
      if (boxElement.children[0] === undefined) //if the box element doesnt already exist
        boxElement.appendChild(ribbonElement);
    }
    else if (boxElement.children[0] !== undefined) //if the box element wasnt added or was removed before
      boxElement.removeChild(ribbonElement);
  } else {
    resetNewMsgs(); //resets the new msgs counter; you shouldnt do this once newMsgs() is called since this function is called 2x a second so the "new msg" ribbon would only appear for half a second then disappear as the new msg counter would be 0....
    if (boxElement.children[0] !== undefined) //if the box element wasnt added or was removed before
      boxElement.removeChild(ribbonElement);
  }
}

// css for the 'new msg' ribbon
var ribbonCSS = "@import url(\'http://fonts.googleapis.com/css?family=Noto+Sans:400,700\');.box{width: 0px;height: 0px;position: relative;border: 0px solid #BBB;background: #EEE;font-family: \'Noto Sans\', sans-serif}.ribbon{width: 200px;background: #e43;position: absolute;top: 0px;left: -10px;text-align: center;line-height: 50px;letter-spacing: 1px;color: #ff0000;font-size: 18px}.ribbon span{width: 200px;background: #e43;position: absolute;top: 25px;left: -50px;text-align: center;line-height: 50px;letter-spacing: 1px;color: #f0f0f0;transform: rotate(-45deg);-webkit-transform: rotate(-45deg);font-size: 18px}.ribbon span::before{content: \"\";position:absolute;left:0px;top:100%;z-index:-1;border-left:3px solid #8F0808;border-right:3px solid transparent;border-bottom:3px solid transparent;border-top:3px solid #8F0808}.ribbon span::after{content:\"\";position:absolute;right:0px;top:100%;z-index:-1;border-left:3px solid transparent;border-right:3px solid #8F0808;border-bottom:3px solid transparent;border-top:3px solid #8F0808}";

var gstyle;
function injectCSS(css) {
    var head;
    head = document.getElementsByTagName('head')[0];
    if (!head) { return; }
    gstyle = document.createElement('style');
    gstyle.type = 'text/css';
    gstyle.innerHTML = css;
    head.appendChild(gstyle);
}
/* doesnt work wtf
function isScrolledIntoView(el) {
    var elemTop = el.getBoundingClientRect().top;
    var elemBottom = el.getBoundingClientRect().bottom;

    var isVisible = (getScrollTop() >= window.scrollY) && (elemBottom <= window.innerHeight);
    return isVisible;
}
*/
function getScrollTop() { //// http://stackoverflow.com/questions/6691558/how-do-i-make-a-div-follow-me-as-i-scroll-down-the-page
    if (window.scrollY !== undefined)
      return window.scrollY;

    if (typeof window.pageYOffset !== 'undefined' ) {
      // Most browsers
      return window.pageYOffset;
    }

    var d = document.documentElement;
    if (d.clientHeight) {
      // IE in standards mode
      return d.scrollTop;
    }

    // IE in quirks mode
    return document.body.scrollTop;
}

window.onload = function() {
  // inject our css
  injectCSS(ribbonCSS);

  // make an empty div where the box will go
  document.body.appendChild(boxElement);

  // get the count of new msgs
  setInterval(makeBox, 500);

  ////KEEPS BOX AT THE TOP OF THE SCREEN
  window.onscroll = function() {
    //make the box scroll with the screen
    var box = document.getElementById('box'),
    scroll = getScrollTop();

    if (box !== null) {
      if (scroll <= 28) {
        box.style.top = "30px";
      } else {
        box.style.top = (scroll + 2) + "px";
      }
    }
  };

}
// += works too

function getUserTagsOnDocument() {
  var atags = document.getElementsByTagName('a')
  var utags = [ ];
  for (var i in atags) {
  	if (atags[i] && atags[i].href && atags[i].href.match(/\/u/))
  		utags[utags.length] = atags[i];
  }
  return utags;
}
<|endoftext|>


<commit_before>/**
 * @author fsjohnuang
 * @version 0.5
 * @description 图片预览
 */
;(function(exports){
	var _filter = ['progid',
		'DXImageTransform.Microsoft.AlphaImageLoader',
		'(sizingMethod="scale")'];
	var useFilter = !!(document.body.filters && document.body.filters.item);
	var imgCls = 'data-preview-img';

	var _render = function(previewEl, dataURI){
		var imgs = previewEl.getElementsByClassName(imgCls), img;
		if (imgs === null || imgs.length === 0){
			img = new Image();
			img.className = imgCls;
			img.style.width = previewEl.offsetWidth + 'px';
			img.style.height = previewEl.offsetHeight + 'px';
			previewEl.appendChild(img);
		}
		else{
			img = imgs[0];
			if (_objectURL.isSupport){
				// v0.5 释放window.URL.createObjectURL生成的链接所独占的资源
				_objectURL.revoke(img.src);
			}
		}

		img.src = dataURI;
	};

	var _objectURL = {
		URL: window.webkitURL ? 'webkitURL' : window.URL ? 'URL' : '',
		fileURL: {}
	};
	_objectURL.isSupport = _objectURL.URL !== '';
	_objectURL.create = function(blob){
		var url = window[this.URL]['createObjectURL'](blob);
		this.fileURL[url] = blob;

		return url;
	};
	_objectURL.revoke = function(url){
		var blob = this.fileURL[url];
		window[this.URL]['revokeObjectURL'](blob);
	};

	var MIME_EXT_MAP = {
		'jpeg': 'image/jpeg',
		'jpg': 'image/jpg',
		'gif': 'image/gif',
		'png': 'image/png'
	};

	/*
	 * @param {HTMLFileElement} fileEl 文件上传元素
	 * @param {HTMLElement} previewEL 预览容器，建议使用div元素
	 */
	var Preview = function(fileEl, previewEl){
		if (!(this instanceof Preview)) return new Preview(fileEl, previewEl);

		var isExpectedMIME = (function(accept){
			// 正则化
			accept = accept.replace(/\*/g, function(m){
				return '[^\\u002c]+'; // 使用逗号的unicode字符编码,以便后面已逗号,作为分隔符
			});
			var acceptMIMEs = accept.split(',');

			/*
			 * @param {DOMString | Array} mimes input[type=file]元素上传文件的MIME类型
			 */
			return function(mimes){
				mimes = [].concat(mimes);
				for (var i = 0, am; am = acceptMIMEs[i++];){
					for (var j = 0, m; m = mimes[j++];){
						if (RegExp(am).test(m)) return true;
					}
				}
				return false;
			};
		}(fileEl.accept || 'image/*'));

		var readAsDataURL = null;
		// IE5.5~9
		if (useFilter){
			previewEl.style.filter = _filter[0] + ':' + _filter[1] + _filter[2];
		}
		else{
			// 修复ff3.0不支持FileReader的问题
			var fr = null;
			if (!!FileReader){
				fr = new FileReader;
				fr.addEventListener('load', function(e){
					_render(previewEl, e.target.result);
				});
			}

			readAsDataURL = function(file){
				if (!isExpectedMIME(file.type)) return;

				// v0.5 添加window.URL.createObjectURL提高性能
				if (_objectURL.isSupport){
					_render(previewEl, _objectURL.create(file));
				}
				else if (!!fr){
					fr.readAsDataURL(file);
				}
				else{
					_render(previewEl, file.readAsDataURL());
				}
			};
		}
		var evtPrefix = '', on = fileEl.addEventListener && 'addEventListener' || (evtPrefix = 'on') && 'attachEvent';
		fileEl[on](evtPrefix + 'change', function(e){
				e = e || window.event;
				if (useFilter){
					var src = e.target.value || '';
					// 解决IE11下，文档模式小于10无法通过value、getAttribute和outerHTML获取input[type=file]的真实路径问题
					if (src.search(/\w:\\fakepath/) === 0){
						e.target.select();
						src = document.selection.createRangeCollection()[0].htmlText;
					}
					var ext = src.substring(src.lastIndexOf('.') + 1);
					if (isExpectedMIME(MIME_EXT_MAP[ext])){
						previewEl.filters.item(_filter[1]).src = src;
					}
				}
				else{
					readAsDataURL(e.target.files[0]);
				}
			});
	};

	exports.Preview = Preview;
}(window));
<commit_msg>reconstruct and update version to 1.0<commit_after>/**
 * @author fsjohnuang
 * @version 1.0
 * @description 图片预览
 */
;(function(exports){
	// 工具
	var utils = {};
	utils.trim = function(str){
		return /^\s*(\S*)\s*$/.exec(str)[1];
	};

	/**
	 配置项
	**/
	var imgCls = 'data-preview-img';
	var filter = ['progid',
		'DXImageTransform.Microsoft.AlphaImageLoader',
		'(sizingMethod="scale")'];
	var MIME_EXT_MAP = {
		'jpeg': 'image/jpeg',
		'jpg': 'image/jpg',
		'gif': 'image/gif',
		'png': 'image/png'
	};

	/**
	 特征检测
	**/
	var useFilter = !!(document.body.filters && document.body.filters.item);

	/**
	 兼容性处理
	**/
	var on, off;
	document.body.addEventListener &&
		(on = function(el, evt, fn){
			el.addEventListener(evt, fn);
		},
		off = function(el, evt, fn){
			el.removeEventListener.apply(el, Array.prototype.slice.call(arguments,1));
		}) ||
		(on = function(el, evt, fn){
			el.attachEvent('on' + evt, fn);
		},
		off = function(el, evt, fn){
			var args = Array.prototype.slice.call(arguments,1);
			args[0] = 'on' + args[0];
			el.detachEvent.apply(el, args);
		});
	var URL = (function(URL){
		if (!URL) return;

		var cache = {};
		return {
			createObjectURL: function(blob){
				var url = URL.createObjectURL(blob);
				cache[url] = blob;
				return url;
			},
			revokeObjectURL: function(blob){
				URL.revokeObjectURL(blob);
			},
			popBlob: function(url){
				var blob = cache[url];
				delete cache[url];
				return blob;
			}
		};
	}(window.webkitURL || window.URL));

	/**
	 主逻辑
	**/
	/** 现代浏览器获取图片地址
	 * @param {File} file 文件对象
	 * @param {Function} cb({DOMString} dataURIScheme) 回调函数
	 */
	var readAsDataURL = function(file, cb/*({DOMString} dataURIScheme)*/){
		if (!!URL){
			// 使用window.URL.createObjectURL提高性能
			cb(URL.createObjectURL(file));
		}
		else if (!window.FileReader){
			// ff3.0不支持FileReader
			cb(file.readAsDataURL());
		}
		else{
			var fr = new window.FileReader();
			on(fr, 'load', function(e){
				cb(e.target.result);
			});
			fr.readAsDataURL(file);
		}
	};
	/** IE10以下获取图片地址
	 * @param {HTMLFileElement} fileEl 文件上传元素
	 * @return {DOMString} url
	 */
	var readPath = function(fileEl){
		var src = fileEl.value || '';
		// IE11下，文档模式小于10无法通过value、getAttribute和outerHTML获取input[type=file]的真实路径
		if (src.search(/\w:\\fakepath/) === 0){
			fileEl.select();
			src = document.selection.createRangeCollection()[0].htmlText;
		}
		return src;
	};
	var render = function(){
		render[arguments.length].apply(this, arguments);
	};
	/** 现代浏览器显示预览图
	 * @param {DOMString} src 图片地址
	 * @param {HTMLElement} previewEl 预览图元素
	 */
	render[2] = function(src, previewEl){
		var imgs = previewEl.getElementsByClassName(imgCls), img;
		if (imgs === null || imgs.length === 0){
			img = new Image();
			img.className = imgCls;
			img.style.width = previewEl.offsetWidth + 'px';
			img.style.height = previewEl.offsetHeight + 'px';
			previewEl.appendChild(img);
		}
		else{
			img = imgs[0];
			if (!!URL){
				// 释放window.URL.createObjectURL生成的链接所独占的资源
				URL.revokeObjectURL(URL.popBlob(img.src));
			}
		}

		img.src = src;
	};
	/** IE10以下显示预览图
	 * @param {DOMString} src 图片地址
	 * @param {HTMLElement} previewEl 预览图元素
	 * @param {Function} isExpectedMIME 文件后缀检测函数
	 */
	render[3] = function(src, previewEl, isExpectedMIME){
		var ext = src.substring(src.lastIndexOf('.') + 1);
		if (isExpectedMIME(MIME_EXT_MAP[ext]))
			previewEl.filters.item(filter[1]).src = src;
	}
	var exec= function(){
		exec[arguments.length].apply(this, arguments);
	};
	/** 现代浏览器执行预览操作
	 * @param {HTMLFileElement} fileEl 文件上传元素
	 * @param {HTMLElement} previewEl 预览图元素
	 */
	exec[2] = function(fileEl, previewEl){
		readAsDataURL(fileEl.files[0], function(url){
			render(url, previewEl);
		});
	};
	/** IE10以下执行预览操作
	 * @param {HTMLFileElement} fileEl 文件上传元素
	 * @param {HTMLElement} previewEl 预览图元素
	 * @param {Function} isExpectedMIME 文件后缀检测函数
	 */
	exec[3] = function(fileEl, previewEl, isExpectedMIME){
		var url = readPath(fileEl);
		render(url, previewEl, isExpectedMIME);
	};

	/** 构造图片预览组件
	 * @param {HTMLFileElement} fileEl 文件上传元素
	 * @param {HTMLElement} previewEl 预览区域元素，建议使用div
	 */
	var pv = exports.Preview = function(fileEl, previewEl){
		if (!(this instanceof pv) return new pv(fileEl, previewEl);

		// IE10以下版本浏览器进行文件后缀校验
		var isExpectedMIME = useFilter && (previewEl.style.filter = filter[0] + ':' + filter[1] + filter[2]
			, (function(accept){
				// 正则化, 将形如image/*,image/jpg正则化为image/[^\\u002c]+,image/jpg
				accept = accept.replace(/\*/g, function(m){
					return '[^\\u002c]+'; // 使用逗号的unicode字符编码,以便后面以逗号,作为分隔符
				});
				var acceptMIMEs = accept.split(/\s*,\s*/)
					, rAcceptMIMEs = [];
				for (var i = 0, am; am = acceptMIMEs[i++];)
					rAcceptMIMEs.push(RegExp(am));

				/*
				 * @param {DOMString | Array} mimes input[type=file]元素上传文件的MIME类型
				 */
				return function(mimes){
					mimes = [].concat(mimes);
					for (var i = 0, r; r = rAcceptMIMEs[i++];){
						for (var j = 0, m; m = mimes[j++];){
							if (r.test(m)) return true;
						}
					}
					return false;
				};
			}(fileEl.accept || 'image/*')));

		on(fileEl, 'change', function(){
			var args = [fileEl, previewEl];
			if (isExpectedMIME)
				args.push(isExpectedMIME);
			exec.apply(this, args);
		});
	};
}(window));
<|endoftext|>


<commit_before>import template from './add-widget-dialog.html';

const AddWidgetDialog = {
  template,
  bindings: {
    resolve: '<',
    close: '&',
    dismiss: '&',
  },
  controller($sce, toastr, Query, Widget) {
    'ngInject';

    this.dashboard = this.resolve.dashboard;
    this.saveInProgress = false;
    this.selectedVis = null;
    this.query = {};
    this.selected_query = undefined;
    this.text = '';
    this.existing_text = '';
    this.new_text = '';
    this.isHidden = false;
    this.type = 'visualization';

    this.trustAsHtml = html => $sce.trustAsHtml(html);
    this.isVisualization = () => this.type === 'visualization';
    this.isTextBox = () => this.type === 'textbox';

    this.setType = (type) => {
      this.type = type;
    };

    this.onQuerySelect = () => {
      if (!this.query.selected) {
        return;
      }

      Query.get({ id: this.query.selected.id }, (query) => {
        if (query) {
          this.selected_query = query;
          if (query.visualizations.length) {
            this.selectedVis = query.visualizations[0];
          }
        }
      });
    };

    this.searchQueries = (term) => {
      if (!term || term.length < 3) {
        return;
      }

      Query.search({ q: term }, (results) => {
        this.queries = results;
      });
    };

    this.saveWidget = () => {
      this.saveInProgress = true;

      const widget = new Widget({
        visualization_id: this.selectedVis && this.selectedVis.id,
        dashboard_id: this.dashboard.id,
        options: {
          isHidden: this.isTextBox() && this.isHidden,
          position: {},
        },
        visualization: this.selectedVis,
        text: this.text,
      });

      const position = this.dashboard.calculateNewWidgetPosition(widget);
      widget.options.position.col = position.col;
      widget.options.position.row = position.row;

      widget.$save()
        .then((response) => {
          // update dashboard layout
          this.dashboard.version = response.version;
          this.dashboard.widgets.push(new Widget(response.widget));
          this.close();
        })
        .catch(() => {
          toastr.error('Widget can not be added');
        })
        .finally(() => {
          this.saveInProgress = false;
        });
    };
  },
};

export default function init(ngModule) {
  ngModule.component('addWidgetDialog', AddWidgetDialog);
}
<commit_msg>Enable list query by one character<commit_after>import template from './add-widget-dialog.html';

const AddWidgetDialog = {
  template,
  bindings: {
    resolve: '<',
    close: '&',
    dismiss: '&',
  },
  controller($sce, toastr, Query, Widget) {
    'ngInject';

    this.dashboard = this.resolve.dashboard;
    this.saveInProgress = false;
    this.selectedVis = null;
    this.query = {};
    this.selected_query = undefined;
    this.text = '';
    this.existing_text = '';
    this.new_text = '';
    this.isHidden = false;
    this.type = 'visualization';

    this.trustAsHtml = html => $sce.trustAsHtml(html);
    this.isVisualization = () => this.type === 'visualization';
    this.isTextBox = () => this.type === 'textbox';

    this.setType = (type) => {
      this.type = type;
    };

    this.onQuerySelect = () => {
      if (!this.query.selected) {
        return;
      }

      Query.get({ id: this.query.selected.id }, (query) => {
        if (query) {
          this.selected_query = query;
          if (query.visualizations.length) {
            this.selectedVis = query.visualizations[0];
          }
        }
      });
    };

    this.searchQueries = (term) => {
      if (!term || term.length === 0) {
        this.queries = [];
        return;
      }

      Query.search({ q: term }, (results) => {
        this.queries = results;
      });
    };

    this.saveWidget = () => {
      this.saveInProgress = true;

      const widget = new Widget({
        visualization_id: this.selectedVis && this.selectedVis.id,
        dashboard_id: this.dashboard.id,
        options: {
          isHidden: this.isTextBox() && this.isHidden,
          position: {},
        },
        visualization: this.selectedVis,
        text: this.text,
      });

      const position = this.dashboard.calculateNewWidgetPosition(widget);
      widget.options.position.col = position.col;
      widget.options.position.row = position.row;

      widget.$save()
        .then((response) => {
          // update dashboard layout
          this.dashboard.version = response.version;
          this.dashboard.widgets.push(new Widget(response.widget));
          this.close();
        })
        .catch(() => {
          toastr.error('Widget can not be added');
        })
        .finally(() => {
          this.saveInProgress = false;
        });
    };
  },
};

export default function init(ngModule) {
  ngModule.component('addWidgetDialog', AddWidgetDialog);
}
<|endoftext|>


<commit_before>/* @flow */

import { validateAuthorizationHeader } from './authentication'
import { ValidationError } from './errors'

import type { Readable } from 'stream'
import type { DriverModel } from './driverModel'

export class HubServer {
  driver: DriverModel
  proofChecker: Object
  whitelist: Array<string>
  serverName: string
  readURL: ?string
  requireCorrectHubUrl: boolean
  validHubUrls: ?Array<string>
  constructor(driver: DriverModel, proofChecker: Object,
              config: { whitelist: Array<string>, servername: string,
                        readURL?: string, requireCorrectHubUrl?: boolean,
                        validHubUrls?: Array<string> }) {
    this.driver = driver
    this.proofChecker = proofChecker
    this.whitelist = config.whitelist
    this.serverName = config.servername
    this.validHubUrls = config.validHubUrls
    this.readURL = config.readURL
    this.requireCorrectHubUrl = config.requireCorrectHubUrl || false
  }

  // throws exception on validation error
  //   otherwise returns void.
  validate(address: string, requestHeaders: { authorization: string }) {
    const signingAddress = validateAuthorizationHeader(requestHeaders.authorization,
                                                       this.serverName, address,
                                                       this.requireCorrectHubUrl,
                                                       this.validHubUrls)

    if (this.whitelist && !(this.whitelist.includes(signingAddress))) {
      throw new ValidationError(`Address ${signingAddress} not authorized for writes`)
    }
  }

  handleListFiles(address: string,
                  page: ?string,
                  requestHeaders: { authorization: string }) {
    this.validate(address, requestHeaders)

    return this.driver.listFiles(address, page)
  }

  getReadURLPrefix() {
    if (this.readURL) {
      return this.readURL
    } else {
      return this.driver.getReadURLPrefix()
    }
  }

  handleRequest(address: string, path: string,
                requestHeaders: {'content-type': string,
                                 'content-length': string,
                                 authorization: string},
                stream: Readable) {
    this.validate(address, requestHeaders)

    let contentType = requestHeaders['content-type']

    if (contentType === null || contentType === undefined) {
      contentType = 'application/octet-stream'
    }

    const writeCommand = { storageTopLevel: address,
                           path, stream, contentType,
                           contentLength: parseInt(requestHeaders['content-length']) }

    return this.proofChecker.checkProofs(address, path, this.getReadURLPrefix())
      .then(() => this.driver.performWrite(writeCommand))
      .then((readURL) => {
        const driverPrefix = this.driver.getReadURLPrefix()
        const readURLPrefix = this.getReadURLPrefix()
        if (readURLPrefix !== driverPrefix && readURL.startsWith(driverPrefix)) {
          const postFix = readURL.slice(driverPrefix.length)
          return `${readURLPrefix}${postFix}`
        }
        return readURL
      })
  }
}
<commit_msg>on putFile(), if the auth token contains a scopes array, then make sure the path is compatible with at least one scope<commit_after>/* @flow */

import { validateAuthorizationHeader, getAuthenticationScopes } from './authentication'
import { ValidationError } from './errors'

import type { Readable } from 'stream'
import type { DriverModel } from './driverModel'

export class HubServer {
  driver: DriverModel
  proofChecker: Object
  whitelist: Array<string>
  serverName: string
  readURL: ?string
  requireCorrectHubUrl: boolean
  validHubUrls: ?Array<string>
  constructor(driver: DriverModel, proofChecker: Object,
              config: { whitelist: Array<string>, servername: string,
                        readURL?: string, requireCorrectHubUrl?: boolean,
                        validHubUrls?: Array<string> }) {
    this.driver = driver
    this.proofChecker = proofChecker
    this.whitelist = config.whitelist
    this.serverName = config.servername
    this.validHubUrls = config.validHubUrls
    this.readURL = config.readURL
    this.requireCorrectHubUrl = config.requireCorrectHubUrl || false
  }

  // throws exception on validation error
  //   otherwise returns void.
  validate(address: string, requestHeaders: { authorization: string }) {
    const signingAddress = validateAuthorizationHeader(requestHeaders.authorization,
                                                       this.serverName, address,
                                                       this.requireCorrectHubUrl,
                                                       this.validHubUrls)

    if (this.whitelist && !(this.whitelist.includes(signingAddress))) {
      throw new ValidationError(`Address ${signingAddress} not authorized for writes`)
    }
  }

  handleListFiles(address: string,
                  page: ?string,
                  requestHeaders: { authorization: string }) {
    this.validate(address, requestHeaders)
    return this.driver.listFiles(address, page)
  }

  getReadURLPrefix() {
    if (this.readURL) {
      return this.readURL
    } else {
      return this.driver.getReadURLPrefix()
    }
  }

  handleRequest(address: string, path: string,
                requestHeaders: {'content-type': string,
                                 'content-length': string,
                                 authorization: string},
                stream: Readable) {
    this.validate(address, requestHeaders)

    let contentType = requestHeaders['content-type']

    if (contentType === null || contentType === undefined) {
      contentType = 'application/octet-stream'
    }

    // can the caller write? if so, in what paths?
    const scopes = getAuthenticationScopes(requestHeaders.authorization)
    const writePrefixes = []
    const writePaths = []
    for (let i = 0; i < scopes.length; i++) {
      if (scopes[i].scope == 'putFilePrefix') {
        writePrefixes.push(scopes[i].domain)
      } else if (scopes[i].scope == 'putFile') {
        writePaths.push(scopes[i].domain)
      }
    }

    if (writePrefixes.length > 0 || writePaths.length > 0) {
      // we're limited to a set of prefixes and paths.
      // does the given path match any prefixes?
      let match = false
      if (writePrefixes.length > 0) {
        for (let i = 0; i < writePrefixes.length; i++) {
          if (path.startsWith(writePrefixes[i])) {
            match = true
            break
          }
        }
      }

      if (!match) {
        // check for exact paths
        for (let i = 0; i < writePaths.length; i++) {
          if (path === writePaths[i]) {
            match = true
            break
          }
        }
      }

      if (!match) {
        // not authorized to write to this path
        throw new ValidationError(`Address ${address} not authorized to write to ${path} by scopes`)
      }
    }

    const writeCommand = { storageTopLevel: address,
                           path, stream, contentType,
                           contentLength: parseInt(requestHeaders['content-length']) }

    return this.proofChecker.checkProofs(address, path, this.getReadURLPrefix())
      .then(() => this.driver.performWrite(writeCommand))
      .then((readURL) => {
        const driverPrefix = this.driver.getReadURLPrefix()
        const readURLPrefix = this.getReadURLPrefix()
        if (readURLPrefix !== driverPrefix && readURL.startsWith(driverPrefix)) {
          const postFix = readURL.slice(driverPrefix.length)
          return `${readURLPrefix}${postFix}`
        }
        return readURL
      })
  }
}
<|endoftext|>


<commit_before>import { expect } from 'chai';
import config from 'config';
import { get } from 'lodash';
import Sinon from 'sinon';

import helloworksController from '../../../server/controllers/helloworks';
import s3 from '../../../server/lib/awsS3';
import models from '../../../server/models';
import { randEmail, randUrl } from '../../stores';
import { fakeCollective, fakeExpense, fakeHost, fakeLegalDocument, fakeUser } from '../../test-helpers/fake-data';

const HELLO_WORKS_WORKFLOW_ID = get(config, 'helloworks.workflowId');

const mockCallbackPayload = ({ accountType, accountId, userId }) => {
  const email = randEmail();

  return {
    /* eslint-disable camelcase */
    audit_trail_hash: '38d5aac4a7c55932eff7c857db2b72cde0d29f373f2d4ccee99d2c83xxxxxxxx',
    data: {
      Form_jmV4rR: {
        field_5zvlrH: '12-10-1991',
        field_7G0PTT: 'Test',
        field_8JIBUU: 'No',
        field_HEJfi8: 'Benjamin Piouffle',
        field_Jj5lq3: 'No',
        field_LEHARZ: email,
        field_MdbUXZ: '',
        field_TDttcV: '00000000',
        field_VjJblP: 'France',
        field_W7cOxA: 'an individual person',
        field_XKL6pp: 'Yes',
        field_kIEVyL: '10-10-2020',
        field_nhEGv2: '666 Super street',
      },
    },
    document_hashes: {
      Form_jmV4rR: '14d1d07954f62e4139a3829d4838ccfbfdceaeead7857089c80a7axxxxxxxxxx',
    },
    id: 'W5coo8QIEn2qoJkG',
    metadata: {
      accountId: accountId,
      accountType,
      adminEmails: email,
      email: email,
      userId,
      year: '2020',
    },
    mode: 'test',
    status: 'completed',
    type: 'workflow_stopped',
    workflow_id: HELLO_WORKS_WORKFLOW_ID,
    /* eslint-enable camelcase */
  };
};

const getMockedRes = () => ({
  sendStatus: Sinon.spy(),
});

describe('server/controllers/helloworks', () => {
  let collective, host, s3Stub, expectedDocLocation;

  before(async () => {
    host = await fakeHost();
    collective = await fakeCollective({ HostCollectiveId: host.id });
    const requiredDoc = { HostCollectiveId: host.id, documentType: 'US_TAX_FORM' };
    await models.RequiredLegalDocument.create(requiredDoc);
    expectedDocLocation = randUrl();
    s3Stub = Sinon.stub(s3, 'upload');
  });

  after(() => {
    s3Stub.restore();
  });

  beforeEach(() => {
    s3Stub.reset();
    s3Stub.callsFake((_, callback) => callback(null, { Location: expectedDocLocation }));
  });

  it('works with individuals', async () => {
    const user = await fakeUser();
    const year = new Date().getFullYear();
    await fakeExpense({
      status: 'APPROVED',
      FromCollectiveId: user.collective.id,
      amount: 8000,
      currency: 'USD',
      CollectiveId: collective.id,
    });
    const document = await fakeLegalDocument({
      status: 'REQUESTED',
      CollectiveId: user.collective.id,
      year,
    });

    const req = {
      body: mockCallbackPayload({ accountType: collective.type, accountId: user.collective.id, userId: user.id }),
    };
    const res = getMockedRes();

    await helloworksController.callback(req, res);
    Sinon.assert.calledWith(res.sendStatus, 200);
    await document.reload();

    expect(s3Stub.args[0][0].Key).to.eq(`US_TAX_FORM_${year}_${user.collective.name}.pdf`);
    expect(document.requestStatus).to.eq('RECEIVED');
    expect(document.documentLink).to.eq(expectedDocLocation);
  });

  it('works with organizations', async () => {
    const organization = await fakeCollective({ type: 'ORGANIZATION' });
    const user = await fakeUser();
    await organization.addUserWithRole(user, 'ADMIN');
    const year = new Date().getFullYear();
    await fakeExpense({
      status: 'APPROVED',
      FromCollectiveId: organization.id,
      amount: 8000,
      currency: 'USD',
      CollectiveId: collective.id,
    });
    const document = await fakeLegalDocument({
      status: 'REQUESTED',
      CollectiveId: organization.id,
      year,
    });

    const req = {
      body: mockCallbackPayload({ accountType: organization.type, accountId: organization.id, userId: user.id }),
    };
    const res = getMockedRes();

    await helloworksController.callback(req, res);
    Sinon.assert.calledWith(res.sendStatus, 200);
    await document.reload();

    expect(s3Stub.args[0][0].Key).to.eq(`US_TAX_FORM_${year}_${organization.name}.pdf`);
    expect(document.requestStatus).to.eq('RECEIVED');
    expect(document.documentLink).to.eq(expectedDocLocation);
  });
});
<commit_msg>test: Fix tax forms test hardcoded year<commit_after>import { expect } from 'chai';
import config from 'config';
import { get } from 'lodash';
import Sinon from 'sinon';

import helloworksController from '../../../server/controllers/helloworks';
import s3 from '../../../server/lib/awsS3';
import models from '../../../server/models';
import { randEmail, randUrl } from '../../stores';
import { fakeCollective, fakeExpense, fakeHost, fakeLegalDocument, fakeUser } from '../../test-helpers/fake-data';

const HELLO_WORKS_WORKFLOW_ID = get(config, 'helloworks.workflowId');

const mockCallbackPayload = ({ accountType, accountId, userId, year }) => {
  const email = randEmail();

  return {
    /* eslint-disable camelcase */
    audit_trail_hash: '38d5aac4a7c55932eff7c857db2b72cde0d29f373f2d4ccee99d2c83xxxxxxxx',
    data: {
      Form_jmV4rR: {
        field_5zvlrH: '12-10-1991',
        field_7G0PTT: 'Test',
        field_8JIBUU: 'No',
        field_HEJfi8: 'Benjamin Piouffle',
        field_Jj5lq3: 'No',
        field_LEHARZ: email,
        field_MdbUXZ: '',
        field_TDttcV: '00000000',
        field_VjJblP: 'France',
        field_W7cOxA: 'an individual person',
        field_XKL6pp: 'Yes',
        field_kIEVyL: '10-10-2020',
        field_nhEGv2: '666 Super street',
      },
    },
    document_hashes: {
      Form_jmV4rR: '14d1d07954f62e4139a3829d4838ccfbfdceaeead7857089c80a7axxxxxxxxxx',
    },
    id: 'W5coo8QIEn2qoJkG',
    metadata: {
      accountId: accountId,
      accountType,
      adminEmails: email,
      email: email,
      userId,
      year,
    },
    mode: 'test',
    status: 'completed',
    type: 'workflow_stopped',
    workflow_id: HELLO_WORKS_WORKFLOW_ID,
    /* eslint-enable camelcase */
  };
};

const getMockedRes = () => ({
  sendStatus: Sinon.spy(),
});

describe('server/controllers/helloworks', () => {
  let collective, host, s3Stub, expectedDocLocation;

  before(async () => {
    host = await fakeHost();
    collective = await fakeCollective({ HostCollectiveId: host.id });
    const requiredDoc = { HostCollectiveId: host.id, documentType: 'US_TAX_FORM' };
    await models.RequiredLegalDocument.create(requiredDoc);
    expectedDocLocation = randUrl();
    s3Stub = Sinon.stub(s3, 'upload');
  });

  after(() => {
    s3Stub.restore();
  });

  beforeEach(() => {
    s3Stub.reset();
    s3Stub.callsFake((_, callback) => callback(null, { Location: expectedDocLocation }));
  });

  it('works with individuals', async () => {
    const user = await fakeUser();
    const year = new Date().getFullYear();
    await fakeExpense({
      status: 'APPROVED',
      FromCollectiveId: user.collective.id,
      amount: 8000,
      currency: 'USD',
      CollectiveId: collective.id,
    });
    const document = await fakeLegalDocument({
      status: 'REQUESTED',
      CollectiveId: user.collective.id,
      year,
    });

    const req = {
      body: mockCallbackPayload({ accountType: collective.type, accountId: user.collective.id, userId: user.id, year }),
    };
    const res = getMockedRes();

    await helloworksController.callback(req, res);
    Sinon.assert.calledWith(res.sendStatus, 200);
    await document.reload();

    expect(s3Stub.args[0][0].Key).to.eq(`US_TAX_FORM_${year}_${user.collective.name}.pdf`);
    expect(document.requestStatus).to.eq('RECEIVED');
    expect(document.documentLink).to.eq(expectedDocLocation);
  });

  it('works with organizations', async () => {
    const organization = await fakeCollective({ type: 'ORGANIZATION' });
    const user = await fakeUser();
    await organization.addUserWithRole(user, 'ADMIN');
    const year = new Date().getFullYear();
    await fakeExpense({
      status: 'APPROVED',
      FromCollectiveId: organization.id,
      amount: 8000,
      currency: 'USD',
      CollectiveId: collective.id,
    });
    const document = await fakeLegalDocument({
      status: 'REQUESTED',
      CollectiveId: organization.id,
      year,
    });

    const req = {
      body: mockCallbackPayload({ accountType: organization.type, accountId: organization.id, userId: user.id, year }),
    };
    const res = getMockedRes();

    await helloworksController.callback(req, res);
    Sinon.assert.calledWith(res.sendStatus, 200);
    await document.reload();

    expect(s3Stub.args[0][0].Key).to.eq(`US_TAX_FORM_${year}_${organization.name}.pdf`);
    expect(document.requestStatus).to.eq('RECEIVED');
    expect(document.documentLink).to.eq(expectedDocLocation);
  });
});
<|endoftext|>


<commit_before>$(".galleries-institutions-primary-carousel .gpc-carousel [class*='is-selected'] .gpc-carousel-figure").click(function() {
  var slug = $(this).attr("href").split("/")[2]

  analytics.track('Clicked Galleries Banner', {
    show_slug: slug
  })
})

$(".galleries-institutions-primary-carousel .gpc-overlays [style*='block'] [href*='/show']").click(function() {
  var slug = $(this).attr("href").split("/")[2]

  analytics.track('Clicked Galleries Banner', {
    show_slug: slug
  })
})
<commit_msg>part 3 /galleries analytics<commit_after>$(".galleries-institutions-primary-carousel .gpc-carousel [class*='is-selected'] .gpc-carousel-figure").click(function() {
  var slug = $(this).attr("href").split("/")[2]

  analytics.track('Clicked Galleries Banner', {
    show_slug: slug
  })
})

$(".galleries-institutions-primary-carousel .gpc-overlays [style*='block'] [href*='/show']").click(function() {
  var slug = $(this).attr("href").split("/")[2]

  analytics.track('Clicked Galleries Banner', {
    show_slug: slug
  })
})

$(".galleries-institutions-primary-carousel .gpc-overlays .gpc-headline").click(function() {
  var slug = $(this).attr("href").split("/")[1]

  analytics.track('Clicked Galleries Banner', {
    partner_slug: slug
  })
})
<|endoftext|>


<commit_before>#!/usr/bin/env node

var http = require("http");
var fs = require("fs");

// function sendFile(fname) {}

var server = http.createServer(function (req, res) {
    var possibleFilename = req.url.slice(1) || "dummy";

    fs.stat(possibleFilename, function (err, stats) {

        var fileBuffer;

        if (!err && stats.isFile()) {

            var fileExtension = possibleFilename.split('.');
            // we need last part of array in case of e.g. xxxx.min.css
            fileExtension = fileExtension[fileExtension.length - 1];

            console.log("Sending file: %s", possibleFilename);
            fileBuffer = fs.readFileSync(possibleFilename);
            res.writeHead(200, { 'Content-Type': 'text/' + fileExtension });
        }
        else {
            console.log("Route %s, replacing with index.html", possibleFilename);
            fileBuffer = fs.readFileSync("index.html");
            res.writeHead(200, { 'Content-Type': 'text/html' });
        }

        res.write(fileBuffer);
        res.end();
    });
});

server.listen(8080, function () { return console.log("Listening on 8080"); });
<commit_msg>Improved handling of files with version numbers<commit_after>#!/usr/bin/env node

var http = require("http");
var fs = require("fs");

// function sendFile(fname) {}

var server = http.createServer(function (req, res) {
    console.log(req.url);
    var url = req.url.split('?')[0]
    var possibleFilename = url.slice(1) || "dummy";

    fs.stat(possibleFilename, function (err, stats) {

        var fileBuffer;

        if (!err && stats.isFile()) {

            var fileExtension = possibleFilename.split('.');
            // we need last part of array in case of e.g. xxxx.min.css
            fileExtension = fileExtension[fileExtension.length - 1];

            console.log("Sending file: %s", possibleFilename);
            fileBuffer = fs.readFileSync(possibleFilename);
            res.writeHead(200, { 'Content-Type': 'text/' + fileExtension });
            // if (fileExtension == "css") {
            // } else {
            //     res.writeHead(200, { 'Content-Type': 'application/x-font-eot' });
            // }
        }
        else {
            console.log("Route %s, replacing with index.html", possibleFilename);
            fileBuffer = fs.readFileSync("index.html");
            res.writeHead(200, { 'Content-Type': 'text/html' });
        }

        res.write(fileBuffer);
        res.end();
    });
});

server.listen(8080, function () { return console.log("Listening on 8080"); });
<|endoftext|>


<commit_before>/* global google */
var $ = require('jquery');
var Backbone = require('backbone');
var Map = require('../../../../src/geo/map');
var GoogleMapsMapView = require('../../../../src/geo/gmaps/gmaps-map-view');

describe('geo/gmaps/gmaps-map-view', function () {
  var mapView;
  var map;
  var spy;
  var container;

  beforeEach(function () {
    container = $('<div>').css('height', '200px');
    map = new Map(null, {
      layersFactory: {}
    });

    spyOn(map, 'setMapViewSize').and.callThrough();
    spyOn(map, 'setPixelToLatLngConverter').and.callThrough();
    spyOn(map, 'setLatLngToPixelConverter').and.callThrough();

    mapView = new GoogleMapsMapView({
      el: container,
      mapModel: map,
      visModel: new Backbone.Model(),
      layerGroupModel: new Backbone.Model()
    });

    mapView.render();

    spy = jasmine.createSpyObj('spy', ['zoomChanged', 'centerChanged', 'scrollWheelChanged']);
    map.bind('change:zoom', spy.zoomChanged);
    map.bind('change:center', spy.centerChanged);
    map.bind('change:scrollwheel', spy.scrollWheelChanged);
  });

  it('should change zoom', function () {
    mapView._setZoom(null, 10);
    expect(spy.zoomChanged).toHaveBeenCalled();
  });

  it('should disable gmaps dragging and double click zooming when the map has drag disabled', function () {
    var container = $('<div>').css({
      'height': '200px',
      'width': '200px'
    });
    var map = new Map({
      drag: false
    }, {
      layersFactory: {}
    });
    var mapView = new GoogleMapsMapView({
      el: container,
      mapModel: map,
      visModel: new Backbone.Model(),
      layerGroupModel: new Backbone.Model()
    });
    mapView.render();

    expect(mapView._gmapsMap.get('draggable')).toBeFalsy();
    expect(mapView._gmapsMap.get('disableDoubleClickZoom')).toBeTruthy();
  });

  it('should change center and zoom when bounds are changed', function (done) {
    var spy = jasmine.createSpy('change:center');
    mapView.getSize = function () { return {x: 200, y: 200}; };
    map.bind('change:center', spy);
    spyOn(mapView, '_setCenter');
    mapView._bindModel();

    map.set({
      'view_bounds_ne': [1, 1],
      'view_bounds_sw': [-0.3, -1.2]
    });

    setTimeout(function () {
      expect(mapView._setCenter).toHaveBeenCalled();
      done();
    }, 1000);
  });

  it('should "forward" a dragend event to the map model', function () {
    var container = $('<div>').css({
      'height': '200px',
      'width': '200px'
    });
    var map = new Map({
      drag: false
    }, {
      layersFactory: {}
    });
    var mapView = new GoogleMapsMapView({
      el: container,
      mapModel: map,
      visModel: new Backbone.Model(),
      layerGroupModel: new Backbone.Model()
    });
    mapView.render();

    spyOn(map, 'trigger');
    spyOn(mapView, 'trigger');

    google.maps.event.trigger(mapView._gmapsMap, 'dragend');

    expect(map.trigger).toHaveBeenCalledWith('moveend', jasmine.any(Object));

    map.trigger.calls.reset();
    mapView.trigger.calls.reset();

    google.maps.event.trigger(mapView._gmapsMap, 'zoom_changed');

    expect(map.trigger).toHaveBeenCalledWith('moveend', jasmine.any(Object));

    map.trigger.calls.reset();
    mapView.trigger.calls.reset();
  });

  it('should set mapview size when bounds changes', function () {
    google.maps.event.trigger(mapView._gmapsMap, 'bounds_changed');
    expect(map.setMapViewSize).toHaveBeenCalled();
  });

  describe('converters', function () {
    it('should set converters', function () {
      expect(map.setPixelToLatLngConverter).toHaveBeenCalled();
      expect(map.setLatLngToPixelConverter).toHaveBeenCalled();
      expect(map._pixelToLatLngConverter).toBeDefined();
      expect(map._latLngToPixelConverter).toBeDefined();
    });

    it('should call native methods', function () {
      spyOn(mapView.projector, 'latLngToPixel').and.callThrough();
      spyOn(mapView.projector, 'pixelToLatLng').and.callThrough();

      var pixelToLatLng = map.pixelToLatLng();
      pixelToLatLng({x: 0, y: 0});
      expect(mapView.projector.pixelToLatLng).toHaveBeenCalled();

      var latLngToPixel = map.latLngToPixel();
      latLngToPixel([0, 0]);
      expect(mapView.projector.latLngToPixel).toHaveBeenCalled();
    });
  });
});
<commit_msg>Fix gmaps-map-view tests<commit_after>/* global google */
var $ = require('jquery');
var Backbone = require('backbone');
var Map = require('../../../../src/geo/map');
var GoogleMapsMapView = require('../../../../src/geo/gmaps/gmaps-map-view');

describe('geo/gmaps/gmaps-map-view', function () {
  var mapView;
  var map;
  var spy;
  var container;

  beforeEach(function () {
    container = $('<div>').css('height', '200px');
    map = new Map(null, {
      layersFactory: {}
    });

    spyOn(map, 'setMapViewSize').and.callThrough();
    spyOn(map, 'setPixelToLatLngConverter').and.callThrough();
    spyOn(map, 'setLatLngToPixelConverter').and.callThrough();

    mapView = new GoogleMapsMapView({
      el: container,
      mapModel: map,
      engine: new Backbone.Model(),
      layerGroupModel: new Backbone.Model()
    });

    mapView.render();

    spy = jasmine.createSpyObj('spy', ['zoomChanged', 'centerChanged', 'scrollWheelChanged']);
    map.bind('change:zoom', spy.zoomChanged);
    map.bind('change:center', spy.centerChanged);
    map.bind('change:scrollwheel', spy.scrollWheelChanged);
  });

  it('should change zoom', function () {
    mapView._setZoom(null, 10);
    expect(spy.zoomChanged).toHaveBeenCalled();
  });

  it('should disable gmaps dragging and double click zooming when the map has drag disabled', function () {
    var container = $('<div>').css({
      'height': '200px',
      'width': '200px'
    });
    var map = new Map({
      drag: false
    }, {
      layersFactory: {}
    });
    var mapView = new GoogleMapsMapView({
      el: container,
      mapModel: map,
      engine: new Backbone.Model(),
      layerGroupModel: new Backbone.Model()
    });
    mapView.render();

    expect(mapView._gmapsMap.get('draggable')).toBeFalsy();
    expect(mapView._gmapsMap.get('disableDoubleClickZoom')).toBeTruthy();
  });

  it('should change center and zoom when bounds are changed', function (done) {
    var spy = jasmine.createSpy('change:center');
    mapView.getSize = function () { return {x: 200, y: 200}; };
    map.bind('change:center', spy);
    spyOn(mapView, '_setCenter');
    mapView._bindModel();

    map.set({
      'view_bounds_ne': [1, 1],
      'view_bounds_sw': [-0.3, -1.2]
    });

    setTimeout(function () {
      expect(mapView._setCenter).toHaveBeenCalled();
      done();
    }, 1000);
  });

  it('should "forward" a dragend event to the map model', function () {
    var container = $('<div>').css({
      'height': '200px',
      'width': '200px'
    });
    var map = new Map({
      drag: false
    }, {
      layersFactory: {}
    });
    var mapView = new GoogleMapsMapView({
      el: container,
      mapModel: map,
      engine: new Backbone.Model(),
      layerGroupModel: new Backbone.Model()
    });
    mapView.render();

    spyOn(map, 'trigger');
    spyOn(mapView, 'trigger');

    google.maps.event.trigger(mapView._gmapsMap, 'dragend');

    expect(map.trigger).toHaveBeenCalledWith('moveend', jasmine.any(Object));

    map.trigger.calls.reset();
    mapView.trigger.calls.reset();

    google.maps.event.trigger(mapView._gmapsMap, 'zoom_changed');

    expect(map.trigger).toHaveBeenCalledWith('moveend', jasmine.any(Object));

    map.trigger.calls.reset();
    mapView.trigger.calls.reset();
  });

  it('should set mapview size when bounds changes', function () {
    google.maps.event.trigger(mapView._gmapsMap, 'bounds_changed');
    expect(map.setMapViewSize).toHaveBeenCalled();
  });

  describe('converters', function () {
    it('should set converters', function () {
      expect(map.setPixelToLatLngConverter).toHaveBeenCalled();
      expect(map.setLatLngToPixelConverter).toHaveBeenCalled();
      expect(map._pixelToLatLngConverter).toBeDefined();
      expect(map._latLngToPixelConverter).toBeDefined();
    });

    it('should call native methods', function () {
      spyOn(mapView.projector, 'latLngToPixel').and.callThrough();
      spyOn(mapView.projector, 'pixelToLatLng').and.callThrough();

      var pixelToLatLng = map.pixelToLatLng();
      pixelToLatLng({x: 0, y: 0});
      expect(mapView.projector.pixelToLatLng).toHaveBeenCalled();

      var latLngToPixel = map.latLngToPixel();
      latLngToPixel([0, 0]);
      expect(mapView.projector.latLngToPixel).toHaveBeenCalled();
    });
  });
});
<|endoftext|>


<commit_before>import { h } from 'hyperapp'
import { setInterval } from 'core-js';

export const ButtonHold = ({state, value, text, setValue})  =>
    <button
        class='button-hold'
        onmousedown={(event) => hold(event, setValue)}
        onmouseup={(event) => clearTimers(event)}
        onmouseleave={(event) => clearTimers(event)}>
        HOLD
        {text}
    </button>

var tid;
var iid;
var TIMEOUT = 4000;

const hold = (event, cb) => {
    let button = event.target;
    let button_counter = event.target.children[0];

    button_counter.textContent = to_secs(TIMEOUT);

    countdown(button_counter);

    tid = setTimeout(() => {
        cb();
        disable(button);
        clearInterval(iid);
    }, TIMEOUT);
}

const countdown = (button_counter) => {
    let counter = 1;
    iid = setInterval (()=> {
        button_counter.textContent = to_secs(TIMEOUT) - counter;
        counter++;
    }, 1000);
}

const to_secs = (t) => t/1000;

const clearTimers = (event) => {
    clearTimeout(tid);
    clearInterval(iid);
    event.target.children[0].textContent = 'HOLD';
}

const disable = (el) => {
    el.disabled = true;
    el.children[0].classList.add('button-hold__counter--disabled')
    el.style.background = 'black';
}
    <commit_msg>add ontouchevents<commit_after>import { h } from 'hyperapp'
import { setInterval } from 'core-js';

export const ButtonHold = ({state, value, text, setValue})  =>
    <button
        class='button-hold'
        onmousedown={(event) => hold(event, setValue)}
        ontouchstart={(event) => hold(event, setValue)}
        onmouseup={(event) => clearTimers(event)}
        onmouseleave={(event) => clearTimers(event)}
        ontouchend={(event) => clearTimers(event)}
        ontouchcancel={(event) => clearTimers(event)}>
        HOLD
        {text}
    </button>

var tid;
var iid;
var TIMEOUT = 4000;

const hold = (event, cb) => {
    let button = event.target;
    let button_counter = event.target.children[0];

    button_counter.textContent = to_secs(TIMEOUT);

    countdown(button_counter);

    tid = setTimeout(() => {
        cb();
        disable(button);
        clearInterval(iid);
    }, TIMEOUT);
}

const countdown = (button_counter) => {
    let counter = 1;
    iid = setInterval (()=> {
        button_counter.textContent = to_secs(TIMEOUT) - counter;
        counter++;
    }, 1000);
}

const to_secs = (t) => t/1000;

const clearTimers = (event) => {
    clearTimeout(tid);
    clearInterval(iid);
    event.target.children[0].textContent = 'HOLD';
}

const disable = (el) => {
    el.disabled = true;
    el.children[0].classList.add('button-hold__counter--disabled')
    el.style.background = 'black';
}
    <|endoftext|>


<commit_before>var nodemailer = require('nodemailer');
const MongoClient = require('mongodb').MongoClient;
const ObjectID = require('mongodb').ObjectID;
const fs = require('fs');
let url = 'mongodb://localhost:27017/mailsender';

let config = {
    group: '2',
    text: 'plain-text/flancy.txt',
    html: 'indexes/flancy.html',
    subject: 'Стальные фланцы из первых рук!',
    titleInDB : 'Стальные фланцы из первых рук!'
};

function createTransport(callback) {
    let transporter = nodemailer.createTransport({
        name: 'prodazha-optom.ru',
        pool: true,
        port: 587,
        auth: {
            user: 'user1',
            pass: 'password1'
        }
    });
    return callback(transporter);
}

MongoClient.connect(url, function (err, db) {
    console.log("Connected correctly to server");
    createTransport(function (transporter) {
        findRecipients(db, function (list, campaignID) {
            sendToList(list, transporter, db, campaignID);
        });
    });
});
//ObjectId("58c1110ccd9d47c1f1940a29")
function findRecipients(db, callback) {
    contacts_collection = db.collection('contacts');
    campaign_collection = db.collection('campaign');
    campaign_collection.findOne({title: config.titleInDB}, function (err, campaign) {
        if (campaign) {
            contacts_collection.find({
                "fields.group": config.group,
                "status": "subscriber",
                "activities.target": {
                    $ne: campaign._id
                }
            }).toArray(function (err, list) {
                console.log(`будет отправлено ${list.length}`);
                callback(list, campaign._id);
            });

        } else {
            return console.error(new Error(`Компании ${config.titleInDB} нет в базе данных!`));
        }
    });
}

function sendToList(list, transporter, db, campaignID) {
    let text = fs.readFileSync(config.text, 'utf8');
    let html = fs.readFileSync(config.html, 'utf8');
    sendAsync(0);
    function sendAsync(offset){
        if (offset == list.length) return console.log('done!');
        let _id = list[offset]._id.toString();
        let email = template(html, {email: list[offset].email, unsub: `http://prodazha-optom.ru/unsubscribe/${_id}`});
        email = addPixel(email,campaignID.toString(), _id );
        let mailOptions = {
            headers: {
                "List-Unsubscribe": `<http://prodazha-optom.ru/unsubscribe/${_id}>`,
                "X-User-ID": _id,
                "X-Campaign-ID": campaignID.toString()
            },
            from: '"ТД Армасети" <sale@prodazha-optom.ru>', // sender address
            to: list[offset].email, // list of receivers
            subject: config.subject,
            text: template(text, {email: list[offset].email, unsub: `http://prodazha-optom.ru/unsubscribe/${_id}`}),// Subject line {email: item.email}
            html: email // html body
        };
        transporter.sendMail(mailOptions, function (error, info) {
            if (error) {
                console.error(`error, try reload [${list[offset].email}] \t\t ${offset} from ${list.length}`);
                return createTransport(function (transporter) {
                    findRecipients(db, function (list, campaignID) {
                        sendToList(list, transporter, db, campaignID);
                    });
                });
            } else {
                db.collection('contacts').updateOne({email:list[offset].email}, {
                    $push: {
                        activities: {
                            action: 'send',
                            target: campaignID,
                            timestamp: new Date()
                        }
                    }
                }, function (err, resp) {
                    console.log(`[${list[offset].email}] \t\t ${offset} from ${list.length}`);
                    sendAsync(offset+1);
                });
            }
        });
    }

}

function addPixel(emailWithoutAnchor, campaignID, contactID) {
    let pixel = ``;
    return emailWithoutAnchor.replace(/]*>/,`$&${pixel}`);
}

function template(text, option){
    return Object.keys(option).reduce(function (sum, current) {
        return sum.replace(new RegExp(`\\[\\(${current}\\)\\]`, 'gi'),option[current]);
    },text);
}<commit_msg>Feature: Изменение активности для базы данных<commit_after>var nodemailer = require('nodemailer');
const MongoClient = require('mongodb').MongoClient;
const ObjectID = require('mongodb').ObjectID;
const fs = require('fs');
let url = 'mongodb://localhost:27017/mailsender';

let config = {
    group: '2',
    text: 'plain-text/flancy.txt',
    html: 'indexes/flancy.html',
    subject: 'Стальные фланцы из первых рук!',
    titleInDB : 'Стальные фланцы из первых рук!'
};

function createTransport(callback) {
    let transporter = nodemailer.createTransport({
        name: 'prodazha-optom.ru',
        pool: true,
        port: 587,
        auth: {
            user: 'user1',
            pass: 'password1'
        }
    });
    return callback(transporter);
}

MongoClient.connect(url, function (err, db) {
    console.log("Connected correctly to server");
    createTransport(function (transporter) {
        findRecipients(db, function (list, campaignID) {
            sendToList(list, transporter, db, campaignID);
        });
    });
});

function findRecipients(db, callback) {
    contacts_collection = db.collection('contacts');
    campaign_collection = db.collection('campaign');
    campaign_collection.findOne({title: config.titleInDB}, function (err, campaign) {
        if (campaign) {
            contacts_collection.find({
                "fields.group": config.group,
                "status": "subscriber",
                "activities.target": {
                    $ne: campaign._id
                }
            }).toArray(function (err, list) {
                console.log(`будет отправлено ${list.length}`);
                callback(list, campaign._id);
            });

        } else {
            return console.error(new Error(`Компании ${config.titleInDB} нет в базе данных!`));
        }
    });
}

function sendToList(list, transporter, db, campaignID) {
    let text = fs.readFileSync(config.text, 'utf8');
    let html = fs.readFileSync(config.html, 'utf8');
    sendAsync(0);
    function sendAsync(offset){
        if (offset == list.length) return console.log('done!');
        let _id = list[offset]._id.toString();
        let email = template(html, {email: list[offset].email, unsub: `http://prodazha-optom.ru/unsubscribe/${_id}`});
        email = addPixel(email,campaignID.toString(), _id );
        let mailOptions = {
            headers: {
                "List-Unsubscribe": `<http://prodazha-optom.ru/unsubscribe/${_id}>`,
                "X-User-ID": _id,
                "X-Campaign-ID": campaignID.toString()
            },
            from: '"ТД Армасети" <sale@prodazha-optom.ru>', // sender address
            to: list[offset].email, // list of receivers
            subject: config.subject,
            text: template(text, {email: list[offset].email, unsub: `http://prodazha-optom.ru/unsubscribe/${_id}`}),// Subject line {email: item.email}
            html: email // html body
        };
        transporter.sendMail(mailOptions, function (error, info) {
            if (error) {
                console.error(`error, try reload [${list[offset].email}] \t\t ${offset} from ${list.length}`);
                return createTransport(function (transporter) {
                    findRecipients(db, function (list, campaignID) {
                        sendToList(list, transporter, db, campaignID);
                    });
                });
            } else {
                db.collection('contacts').updateOne({email:list[offset].email}, {
                    $push: {
                        activities: {
                            action: 'queued',
                            target: campaignID,
                            timestamp: new Date()
                        }
                    }
                }, function (err, resp) {
                    console.log(`[${list[offset].email}] \t\t ${offset} from ${list.length}`);
                    sendAsync(offset+1);
                });
            }
        });
    }

}

function addPixel(emailWithoutAnchor, campaignID, contactID) {
    let pixel = ``;
    return emailWithoutAnchor.replace(/]*>/,`$&${pixel}`);
}

function template(text, option){
    return Object.keys(option).reduce(function (sum, current) {
        return sum.replace(new RegExp(`\\[\\(${current}\\)\\]`, 'gi'),option[current]);
    },text);
}<|endoftext|>


<commit_before>'use strict';

const SunCalc = require('suncalc');
const Redis = require('redis')

var lat = undefined;
var lon = undefined;
var db_key = undefined;

if(typeof process.env.lat !== 'undefined') {
  lat = process.env.lat;
} else {
  throw "'lat' environmental variable is not set. Set it and restart container";
}

if(typeof process.env.lon !== 'undefined') {
  lon = process.env.lon;
} else {
  throw "'lon' environmental variable is not set. Set it and restart container";
}

if(typeof process.env.db_key !== 'undefined') {
  db_key = process.env.db_key;
} else {
  throw "'db_key'(redis key for publishing sun state) environmental variable is not set. Set it and restart container";
}

console.log(`Tracking the Sun state for coordinates ${lat} ${lon}`);

var preciseState="unknown";
var state="unknown";

var preciseToNormal = {
  "sunrise" : "twilight",
  "sunriseEnd": "day",
  "goldenHourEnd": "day",
  "solarNoon": "day",
  "goldenHour": "twilight",
  "sunsetStart": "twilight",
  "sunset": "twilight",
  "dusk": "night",
  "nauticalDusk": "night",
  "night": "night",
  "nadir": "night",
  "nightEnd": "night",
  "nauticalDawn": "night",
  "dawn": "twilight"
};

var pub = Redis.createClient(6379, "redis");

function Tick() {
  var now = new Date();
//  console.log(`Current time is ${now}`);
  var times = SunCalc.getTimes(now, lat,  lon);
  var currentPrecState = "unknown";
  var currentDiff = Infinity;
  var currentPrecStateTime = undefined;
  for(var propertyName in times) { //finding current precise state
    var diff = now - times[propertyName];
    if(diff > 0 && diff <= currentDiff) {
      currentPrecState = propertyName;
      currentDiff = diff;
      currentPrecStateTime = times[propertyName];
    }
  }
  if(currentPrecState == "unknown") {
    //all the computed events are in the future. discarding until reaching one of the events
    return;
  }
  if(preciseState !== currentPrecState) {
    console.log(`new precise state: ${currentPrecState}`);
    preciseState = currentPrecState;
  }
  var currentState = preciseToNormal[currentPrecState];
  if(state !== currentState) {
    console.log(`new state: ${currentState}`);

    pub.set(db_key, currentState,function(error) {
      if(!error) {
        console.log("saved new state in the database");
        pub.publish(`${db_key}.subscription`, currentState,function (error){
        if(!error) {
          console.log("changed state notification sent");
          state = currentState;
        }
        else
          console.warn("error sending notification: "+error);
        });
      }
      else
        console.warn("error saving state: "+error);
      });
  }
}

Tick();
setInterval(Tick, 30000);
<commit_msg>Update sensor.js<commit_after>'use strict';

const SunCalc = require('suncalc');
const Redis = require('redis')

var lat = undefined;
var lon = undefined;
var db_key = undefined;

if(typeof process.env.lat !== 'undefined') {
  lat = process.env.lat;
} else {
  throw "'lat' environmental variable is not set. Set it and restart container";
}

if(typeof process.env.lon !== 'undefined') {
  lon = process.env.lon;
} else {
  throw "'lon' environmental variable is not set. Set it and restart container";
}

if(typeof process.env.db_key !== 'undefined') {
  db_key = process.env.db_key;
} else {
  throw "'db_key'(redis key for publishing sun state) environmental variable is not set. Set it and restart container";
}

console.log(`Tracking the Sun state for coordinates ${lat} ${lon}`);

var preciseState="unknown";
var state="unknown";

var preciseToNormal = {
  "sunrise" : "twilight",
  "sunriseEnd": "day",
  "goldenHourEnd": "day",
  "solarNoon": "day",
  "goldenHour": "day",
  "sunsetStart": "twilight",
  "sunset": "twilight",
  "dusk": "night",
  "nauticalDusk": "night",
  "night": "night",
  "nadir": "night",
  "nightEnd": "night",
  "nauticalDawn": "night",
  "dawn": "twilight"
};

var pub = Redis.createClient(6379, "redis");

function Tick() {
  var now = new Date();
//  console.log(`Current time is ${now}`);
  var times = SunCalc.getTimes(now, lat,  lon);
  var currentPrecState = "unknown";
  var currentDiff = Infinity;
  var currentPrecStateTime = undefined;
  for(var propertyName in times) { //finding current precise state
    var diff = now - times[propertyName];
    if(diff > 0 && diff <= currentDiff) {
      currentPrecState = propertyName;
      currentDiff = diff;
      currentPrecStateTime = times[propertyName];
    }
  }
  if(currentPrecState == "unknown") {
    //all the computed events are in the future. discarding until reaching one of the events
    return;
  }
  if(preciseState !== currentPrecState) {
    console.log(`new precise state: ${currentPrecState}`);
    preciseState = currentPrecState;
  }
  var currentState = preciseToNormal[currentPrecState];
  if(state !== currentState) {
    console.log(`new state: ${currentState}`);

    pub.set(db_key, currentState,function(error) {
      if(!error) {
        console.log("saved new state in the database");
        pub.publish(`${db_key}.subscription`, currentState,function (error){
        if(!error) {
          console.log("changed state notification sent");
          state = currentState;
        }
        else
          console.warn("error sending notification: "+error);
        });
      }
      else
        console.warn("error saving state: "+error);
      });
  }
}

Tick();
setInterval(Tick, 30000);
<|endoftext|>


<commit_before>/*!
 * Copyright 2012 Sakai Foundation (SF) Licensed under the
 * Educational Community License, Version 2.0 (the "License"); you may
 * not use this file except in compliance with the License. You may
 * obtain a copy of the License at
 *
 *     http://www.osedu.org/licenses/ECL-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an "AS IS"
 * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing
 * permissions and limitations under the License.
 */

/**
 * Bootstrap plugin that adds the ability to lock down a modal. Users will not be able
 * to dismiss a modal once `lock` has been called.
 *     e.g. $('#widget-modal').modal('lock');
 * The modal can then also be unlocked, which will re-enable all buttons and keys that
 * dismiss the modal.
 *     e.g. $('#widget-modal').modal('unlock');
 */

$.extend($.fn.modal.Constructor.prototype, {
    'lock': function() {
        // Set isShown to false. https://github.com/twitter/bootstrap/issues/1202#issuecomment-3698674
        this.$element.data('modal').isShown = false;
        // Disable buttons that dismiss the modal
        $('#' + this.$element.attr('id') + ' [data-dismiss="modal"]').attr('disabled', 'disabled');
    },
    'unlock': function() {
        // Set isShown to true. https://github.com/twitter/bootstrap/issues/1202#issuecomment-3698674
        this.$element.data('modal').isShown = true;
        // Enable buttons that dismiss the modal
        $('#' + this.$element.attr('id') + ' [data-dismiss="modal"]').removeAttr('disabled', 'disabled');
    }
});
<commit_msg>Added dependencies<commit_after>/*!
 * Copyright 2012 Sakai Foundation (SF) Licensed under the
 * Educational Community License, Version 2.0 (the "License"); you may
 * not use this file except in compliance with the License. You may
 * obtain a copy of the License at
 *
 *     http://www.osedu.org/licenses/ECL-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an "AS IS"
 * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing
 * permissions and limitations under the License.
 */

/**
 * Bootstrap plugin that adds the ability to lock down a modal. Users will not be able
 * to dismiss a modal once `lock` has been called.
 *     e.g. $('#widget-modal').modal('lock');
 * The modal can then also be unlocked, which will re-enable all buttons and keys that
 * dismiss the modal.
 *     e.g. $('#widget-modal').modal('unlock');
 */

define(['jquery', 'bootstrap'], function($, bootstrap) {
    $.extend($.fn.modal.Constructor.prototype, {
        'lock': function() {
            // Set isShown to false. https://github.com/twitter/bootstrap/issues/1202#issuecomment-3698674
            this.$element.data('modal').isShown = false;
            // Disable buttons that dismiss the modal
            $('#' + this.$element.attr('id') + ' [data-dismiss="modal"]').attr('disabled', 'disabled');
        },
        'unlock': function() {
            // Set isShown to true. https://github.com/twitter/bootstrap/issues/1202#issuecomment-3698674
            this.$element.data('modal').isShown = true;
            // Enable buttons that dismiss the modal
            $('#' + this.$element.attr('id') + ' [data-dismiss="modal"]').removeAttr('disabled', 'disabled');
        }
    });
});
<|endoftext|>