<commit_before>const canvas = document.getElementById("gamecanvas");
const context = canvas.getContext("2d");

var keys = [];
document.body.addEventListener("keydown", function (e) {
    keys[e.keyCode] = true;
});
document.body.addEventListener("keyup", function (e) {
    keys[e.keyCode] = false;
});

lastTime = (new Date()).getTime();
currentTime = 0;
deltaTime = 0;

const game = {
    demoMode: null,
    score: null,
    multiplier: null,
    lives: null,
    level: null,
    blocks: null,
    reset: function() {
        this.demoMode = true;
        this.score = 0;
        this.multiplier = 1;
        this.lives = 3;
        this.level = 1;
        this.blocks = generateLevel(this.level);
    },
}

const ball = {
    pos: {x: null, y: null},
    velocity: {x: null, y: null },
    width: null,
    height: null,
    speed: null,
    draw: function() {
        context.fillStyle = "#F8F8F2";
        context.fillRect(this.pos.x, this.pos.y, this.width, this.height);
    },
    reset: function() {
        this.pos.x = canvas.width / 2;
        this.pos.y = canvas.height - 64;
        this.speed = -300;
        this.velocity.x = (Math.random() + 0.5) * Math.pow(-1, Math.floor(Math.random() * 2)) * 60;
        if (game.demoMode) this.velocity.x += 2;
        this.velocity.y = this.speed;
        this.width = this.height = 12;
    },
};

const player = {
    pos: { x: null, y: null},
    velocity: null,
    width: null,
    height: null,
    speed: null,
    friction: null,
    draw: function() {
        context.fillStyle = "#F92672";
        context.fillRect(this.pos.x, this.pos.y, this.width, this.height);
    },
    moveLeft: function() {
        this.velocity -= this.speed;
    },
    moveRight: function() {
        this.velocity += this.speed;
    },
    updatePosition: function() {
        this.pos.x += this.velocity;
        this.velocity *= this.friction;

        if (this.pos.x+this.width/2 < 0) {
            this.pos.x = -this.width/2;
            this.velocity = 0;
        } else if (this.pos.x+this.width/2 > canvas.width) {
            this.pos.x = canvas.width-this.width/2;
            this.velocity = 0;
        }
    },
    reset: function() {
        this.width = 120;
        this.height = 16;
        this.pos.x = canvas.width / 2 - this.width / 2;
        this.pos.y = canvas.height - 32;
        this.velocity = 0;
        this.speed = 2;
        this.friction = 0.9;
    },
};

class Rectangle {
    constructor(x, y, width, height, color="#FFF") {
        this.pos = { x: x, y: y};
        this.width = width;
        this.height = height;
        this.color = color;
    }

    draw() {
        context.fillStyle = this.color;
        context.fillRect(this.pos.x, this.pos.y, this.width, this.height);
    }
}

class Block extends Rectangle {
    constructor(x, y, width, height, color="#FFE792", health=1) {
        super(x, y, width, height, color);
        this.health = health;
    }

    damage(d=1) {
        this.health -= d;
        return this.health;
    }
}

function collisionDetection(a, b) {
    if (a.pos.x < b.pos.x + b.width &&
        a.pos.x + a.width > b.pos.x &&
        a.pos.y < b.pos.y + b.height &&
        a.height + a.pos.y > b.pos.y) {
        return true;
    }
    return false;
}

// returns side on which the ball made contact
function collisionSide(ball, object) {
    // top/bottom or left/right
    if (ball.pos.x+ball.width >= object.pos.x && ball.pos.x <= object.pos.x+object.width) {
        return "top/bottom";
    } else if (ball.pos.y >= object.pos.y-object.height && object.pos.y+object.height <= object.pos.y) {
        return "left/right";
    }
    return "";
}

function generateLevel(level) {
    const blocks = [];
    const colors = ["#F92672", "#66D9EF", "#A6E22E", "#FD971F", "#AE81FF", "#FFE792", "#FFE792"];
    if (level == 1) {
        for (row = 0; row < 7; row++) {
            for (col = 0; col < 8; col++) {
                blocks.push(new Block(2+col*60, 60+row*20, 58, 16, colors[row]));
            }
        }
    } else if (level == 2) {
        for (row = 0; row < 3; row++) {
            for (col = 1; col < 7; col++) {
                blocks.push(new Block(2+col*60, 60+row*20, 58, 16, colors[row]));
            }
        }
        for (row = 0; row < 4; row++) {
            for (col = 0; col < 8; col++) {
                if (col == 2 || col == 5) continue;
                blocks.push(new Block(2+col*60, 160+row*20, 58, 16, colors[row]));
            }
        }
        for (col = 0; col < 8; col++) {
            blocks.push(new Block(2+col*60, 160+row*20, 58, 16, "grey", 2));
        }
    } else {
        // simple random level
        for (row = 0; row < 7; row++) {
            for (col = 0; col < 8; col++) {
                if (Math.random() >= 0.5) continue;
                blocks.push(new Block(2+col*60, 60+row*20, 58, 16, colors[row]));
            }
        }
    }
    return blocks;
}

function sound(src) {
    this.sound = document.createElement("audio");
    this.sound.src = src;
    this.sound.setAttribute("preload", "auto");
    this.sound.setAttribute("controls", "none");
    this.sound.style.display = "none";
    document.body.appendChild(this.sound);
    this.play = function(){
        this.sound.play();
    }
    this.stop = function(){
        this.sound.pause();
    }
}

function loop() {
    if (keys[37] && !game.demoMode) player.moveLeft();
    else if (keys[39] && !game.demoMode) player.moveRight();
    if (keys[13] && game.demoMode) {
        game.reset();
        game.demoMode = false;
        ball.reset();
        player.reset();
    }

    currentTime = (new Date()).getTime();
    deltaTime = (currentTime - lastTime) / 1000;
    lastTime = currentTime;

    player.updatePosition();

    if (ball.pos.y-ball.height/2 > canvas.height) {
        // player missed the ball
        soundLifeLost.play();
        ball.reset();
        player.reset();
        game.multiplier = 1;
        if (--game.lives == 0) game.reset();
    } else if (ball.pos.y-ball.height/2 <= 0) {
        // ball touched ceiling
        soundWallHit.play();
        ball.velocity.y = -ball.velocity.y;
    } else if (ball.pos.x-ball.width/2 <= 0 || ball.pos.x+ball.width/2 >= canvas.width) {
        // ball touched left or right wall
        soundWallHit.play();
        ball.velocity.x = -ball.velocity.x;
    }
    ball.pos.x += ball.velocity.x * deltaTime;
    ball.pos.y += ball.velocity.y * deltaTime;

    // detect ball collision with player
    if (collisionDetection(ball, player)) {
        soundPlayerHit.play();
        ball.velocity.x = ((ball.pos.x+ball.width/2) - (player.pos.x+player.width/2)) * 6;
        ball.velocity.y = -ball.velocity.y;
        game.multiplier = 1;
    }

    // detect ball collision with blocks
    game.blocks.forEach(function(block) {
        if (collisionDetection(ball, block)) {
            soundBlockHit.play();
            game.score += game.multiplier++;

            var health = block.damage();
            if (health <= 0) {
                var i = game.blocks.indexOf(block);
                game.blocks.splice(i, 1);
            }

            var side = collisionSide(ball, block);
            if (side == "top/bottom") {
                ball.velocity.y = -ball.velocity.y;
            } else {
                ball.velocity.x = -ball.velocity.x;
            }
        }
    });

    // check if level cleared
    if (game.blocks.length == 0) {
        game.blocks = generateLevel(++game.level);
        ball.reset();
        player.reset();
    }

    // draw background
    context.fillStyle = "#272822";
	context.fillRect(0, 0, canvas.width, canvas.height);

    // draw objects
    ball.draw();
    player.draw();
    game.blocks.forEach(function(block) {
        block.draw();
    });

    // draw text
    context.fillStyle = "rgba(255, 255, 255, 0.75)";
    context.font = "20px Georgia";
    context.textAlign = "left";
    context.fillText("Score: " + game.score, 10, 20);
    context.textAlign = "center";
    context.fillText("Level: " + game.level, canvas.width/2, 20);
    context.textAlign = "right";
    context.fillText("Lives: " + game.lives, canvas.width-10, 20);
    context.globalAlpha = 1;

    if (game.demoMode) {
        // AI
        if (ball.pos.y > canvas.height*0.3 && ball.pos.y < canvas.height*0.9) {
            if ((player.pos.x + player.width/2) - (ball.pos.x + ball.width/2) < 50) {
                player.moveRight();
            } else if ((player.pos.x + player.width/2) - (ball.pos.x + ball.width/2) > -50) {
                player.moveLeft();
            }
        }

        context.fillStyle = "white";
        context.textAlign = "center";
        context.fillText("Press <enter> to start playing", canvas.width / 2, canvas.height / 2);
    }
    window.requestAnimationFrame(loop);
}

game.reset();
ball.reset();
player.reset();
soundPlayerHit = new sound("sounds/playerhit.wav");
soundBlockHit = new sound("sounds/blockhit.mp3");
soundWallHit = new sound("sounds/wallhit.wav");
soundLifeLost = new sound("sounds/lifelost.mp3");
loop();<commit_msg>Turned player object into a proper class<commit_after>const canvas = document.getElementById("gamecanvas");
const context = canvas.getContext("2d");

var keys = [];
document.body.addEventListener("keydown", function (e) {
    keys[e.keyCode] = true;
});
document.body.addEventListener("keyup", function (e) {
    keys[e.keyCode] = false;
});

lastTime = (new Date()).getTime();
currentTime = 0;
deltaTime = 0;

const game = {
    demoMode: null,
    score: null,
    multiplier: null,
    lives: null,
    level: null,
    blocks: null,
    reset: function() {
        this.demoMode = true;
        this.score = 0;
        this.multiplier = 1;
        this.lives = 3;
        this.level = 1;
        this.blocks = generateLevel(this.level);
    },
}

const ball = {
    pos: {x: null, y: null},
    velocity: {x: null, y: null },
    width: null,
    height: null,
    speed: null,
    draw: function() {
        context.fillStyle = "#F8F8F2";
        context.fillRect(this.pos.x, this.pos.y, this.width, this.height);
    },
    reset: function() {
        this.pos.x = canvas.width / 2;
        this.pos.y = canvas.height - 64;
        this.speed = -300;
        this.velocity.x = (Math.random() + 0.5) * Math.pow(-1, Math.floor(Math.random() * 2)) * 60;
        if (game.demoMode) this.velocity.x += 2;
        this.velocity.y = this.speed;
        this.width = this.height = 12;
    },
};

class Rectangle {
    constructor(x, y, width, height, color="#FFF") {
        this.pos = { x: x, y: y};
        this.width = width;
        this.height = height;
        this.color = color;
    }

    get left() {
        return this.pos.x;
    }

    get right() {
        return this.pos.x + this.width;
    }

    get top() {
        return this.pos.y;
    }

    get bottom() {
        return this.pos.y + this.height;
    }

    draw() {
        context.fillStyle = this.color;
        context.fillRect(this.pos.x, this.pos.y, this.width, this.height);
    }
}

class Player extends Rectangle {
    constructor() {
        const width = 120;
        const height = 16;
        super(canvas.width / 2 - width/2, canvas.height - 32, width, height, "#F92672");
        this.velocity = 0;
        this.speed = 2;
        this.friction = 0.9;
    }

    moveLeft() {
        this.velocity -= this.speed;
    }

    moveRight() {
        this.velocity += this.speed;
    }

    updatePosition() {
        this.pos.x += this.velocity;
        this.velocity *= this.friction;

        if (this.pos.x+this.width/2 < 0) {
            this.pos.x = -this.width/2;
            this.velocity = 0;
        } else if (this.pos.x+this.width/2 > canvas.width) {
            this.pos.x = canvas.width-this.width/2;
            this.velocity = 0;
        }
    }
}

class Block extends Rectangle {
    constructor(x, y, width, height, color="#FFE792", health=1) {
        super(x, y, width, height, color);
        this.health = health;
    }

    damage(d=1) {
        this.health -= d;
        return this.health;
    }
}

function collisionDetection(a, b) {
    if (a.pos.x < b.pos.x + b.width &&
        a.pos.x + a.width > b.pos.x &&
        a.pos.y < b.pos.y + b.height &&
        a.height + a.pos.y > b.pos.y) {
        return true;
    }
    return false;
}

// returns side on which the ball made contact
function collisionSide(ball, object) {
    // top/bottom or left/right
    if (ball.pos.x+ball.width >= object.pos.x && ball.pos.x <= object.pos.x+object.width) {
        return "top/bottom";
    } else if (ball.pos.y >= object.pos.y-object.height && object.pos.y+object.height <= object.pos.y) {
        return "left/right";
    }
    return "";
}

function generateLevel(level) {
    const blocks = [];
    const colors = ["#F92672", "#66D9EF", "#A6E22E", "#FD971F", "#AE81FF", "#FFE792", "#FFE792"];
    if (level == 1) {
        for (row = 0; row < 7; row++) {
            for (col = 0; col < 8; col++) {
                blocks.push(new Block(2+col*60, 60+row*20, 58, 16, colors[row]));
            }
        }
    } else if (level == 2) {
        for (row = 0; row < 3; row++) {
            for (col = 1; col < 7; col++) {
                blocks.push(new Block(2+col*60, 60+row*20, 58, 16, colors[row]));
            }
        }
        for (row = 0; row < 4; row++) {
            for (col = 0; col < 8; col++) {
                if (col == 2 || col == 5) continue;
                blocks.push(new Block(2+col*60, 160+row*20, 58, 16, colors[row]));
            }
        }
        for (col = 0; col < 8; col++) {
            blocks.push(new Block(2+col*60, 160+row*20, 58, 16, "grey", 2));
        }
    } else {
        // simple random level
        for (row = 0; row < 7; row++) {
            for (col = 0; col < 8; col++) {
                if (Math.random() >= 0.5) continue;
                blocks.push(new Block(2+col*60, 60+row*20, 58, 16, colors[row]));
            }
        }
    }
    return blocks;
}

function sound(src) {
    this.sound = document.createElement("audio");
    this.sound.src = src;
    this.sound.setAttribute("preload", "auto");
    this.sound.setAttribute("controls", "none");
    this.sound.style.display = "none";
    document.body.appendChild(this.sound);
    this.play = function(){
        this.sound.play();
    }
    this.stop = function(){
        this.sound.pause();
    }
}

function loop() {
    if (keys[37] && !game.demoMode) player.moveLeft();
    else if (keys[39] && !game.demoMode) player.moveRight();
    if (keys[13] && game.demoMode) {
        game.reset();
        game.demoMode = false;
        ball.reset();
        player = new Player();
    }

    currentTime = (new Date()).getTime();
    deltaTime = (currentTime - lastTime) / 1000;
    lastTime = currentTime;

    player.updatePosition();

    if (ball.pos.y-ball.height/2 > canvas.height) {
        // player missed the ball
        soundLifeLost.play();
        ball.reset();
        player = new Player();
        game.multiplier = 1;
        if (--game.lives == 0) game.reset();
    } else if (ball.pos.y-ball.height/2 <= 0) {
        // ball touched ceiling
        soundWallHit.play();
        ball.velocity.y = -ball.velocity.y;
    } else if (ball.pos.x-ball.width/2 <= 0 || ball.pos.x+ball.width/2 >= canvas.width) {
        // ball touched left or right wall
        soundWallHit.play();
        ball.velocity.x = -ball.velocity.x;
    }
    ball.pos.x += ball.velocity.x * deltaTime;
    ball.pos.y += ball.velocity.y * deltaTime;

    // detect ball collision with player
    if (collisionDetection(ball, player)) {
        soundPlayerHit.play();
        ball.velocity.x = ((ball.pos.x+ball.width/2) - (player.pos.x+player.width/2)) * 6;
        ball.velocity.y = -ball.velocity.y;
        game.multiplier = 1;
    }

    // detect ball collision with blocks
    game.blocks.forEach(function(block) {
        if (collisionDetection(ball, block)) {
            soundBlockHit.play();
            game.score += game.multiplier++;

            var health = block.damage();
            if (health <= 0) {
                var i = game.blocks.indexOf(block);
                game.blocks.splice(i, 1);
            }

            var side = collisionSide(ball, block);
            if (side == "top/bottom") {
                ball.velocity.y = -ball.velocity.y;
            } else {
                ball.velocity.x = -ball.velocity.x;
            }
        }
    });

    // check if level cleared
    if (game.blocks.length == 0) {
        game.blocks = generateLevel(++game.level);
        ball.reset();
        player.reset();
    }

    // draw background
    context.fillStyle = "#272822";
	context.fillRect(0, 0, canvas.width, canvas.height);

    // draw objects
    ball.draw();
    player.draw();
    game.blocks.forEach(function(block) {
        block.draw();
    });

    // draw text
    context.fillStyle = "rgba(255, 255, 255, 0.75)";
    context.font = "20px Georgia";
    context.textAlign = "left";
    context.fillText("Score: " + game.score, 10, 20);
    context.textAlign = "center";
    context.fillText("Level: " + game.level, canvas.width/2, 20);
    context.textAlign = "right";
    context.fillText("Lives: " + game.lives, canvas.width-10, 20);
    context.globalAlpha = 1;

    if (game.demoMode) {
        // AI
        if (ball.pos.y > canvas.height*0.3 && ball.pos.y < canvas.height*0.9) {
            if ((player.pos.x + player.width/2) - (ball.pos.x + ball.width/2) < 50) {
                player.moveRight();
            } else if ((player.pos.x + player.width/2) - (ball.pos.x + ball.width/2) > -50) {
                player.moveLeft();
            }
        }

        context.fillStyle = "white";
        context.textAlign = "center";
        context.fillText("Press <enter> to start playing", canvas.width / 2, canvas.height / 2);
    }
    window.requestAnimationFrame(loop);
}

game.reset();
ball.reset();
var player = new Player();
soundPlayerHit = new sound("sounds/playerhit.wav");
soundBlockHit = new sound("sounds/blockhit.mp3");
soundWallHit = new sound("sounds/wallhit.wav");
soundLifeLost = new sound("sounds/lifelost.mp3");
loop();<|endoftext|>


<commit_before>/**
 * Created by anonymoussc on 26/11/15 5:40.
 */

(function() {
    'use strict';

    angular.module('app.controllers').controller('DashboardSimpleCtrl', function($scope, $timeout, $mdSidenav, $log) {
        $scope.toggleLeft  = buildDelayedToggler('left');
        $scope.toggleRight = buildToggler('right');
        $scope.isOpenRight = function() {
            return $mdSidenav('right').isOpen();
        };

        /**
         * Supplies a function that will continue to operate until the
         * time is up.
         */
        function debounce(func, wait, context) {
            var timer;
            return function debounced() {
                var context = $scope,
                    args    = Array.prototype.slice.call(arguments);
                $timeout.cancel(timer);
                timer       = $timeout(function() {
                    timer = undefined;
                    func.apply(context, args);
                }, wait || 10);
            };
        }

        /**
         * Build handler to open/close a SideNav; when animation finishes
         * report completion in console
         */
        function buildDelayedToggler(navID) {
            return debounce(function() {
                $mdSidenav(navID)
                    .toggle()
                    .then(function() {
                        $log.debug("toggle " + navID + " is done");
                    });
            }, 200);
        }

        function buildToggler(navID) {
            return function() {
                $mdSidenav(navID)
                    .toggle()
                    .then(function() {
                        $log.debug("toggle " + navID + " is done");
                    });
            };
        }
    });

})();

<commit_msg>Update dashboard simple.js<commit_after>/**
 * Created by anonymoussc on 26/11/15 5:40.
 */

(function() {
    'use strict';

    angular.module('app.controllers').controller('DashboardSimpleCtrl', function($scope, $timeout, $mdSidenav, $log) {
        $scope.toggleLeft  = buildDelayedToggler('left');
        $scope.toggleRight = buildToggler('right');
        $scope.isOpenRight = function() {
            return $mdSidenav('right').isOpen();
        };

        /**
         * Supplies a function that will continue to operate until the
         * time is up.
         */
        function debounce(func, wait, context) {
            var timer;
            return function debounced() {
                var context = $scope,
                    args    = Array.prototype.slice.call(arguments);
                $timeout.cancel(timer);
                timer       = $timeout(function() {
                    timer = undefined;
                    func.apply(context, args);
                }, wait || 10);
            };
        }

        /**
         * Build handler to open/close a SideNav; when animation finishes
         * report completion in console
         */
        function buildDelayedToggler(navID) {
            return debounce(function() {
                $mdSidenav(navID)
                    .toggle()
                    .then(function() {
                        // $log.debug("toggle " + navID + " is done");
                    });
            }, 200);
        }

        function buildToggler(navID) {
            return function() {
                $mdSidenav(navID)
                    .toggle()
                    .then(function() {
                        // $log.debug("toggle " + navID + " is done");
                    });
            };
        }
    });

})();

<|endoftext|>


<commit_before>module.exports = function(content, width, height, top) {
  if ($('.slider').length) {
    return false;
  }
  $block = $('

x

');
  $block.append(content)
    .appendTo('body')
    .css({
      width:  width  || 230,
      height: height || 200,
      position: 'absolute',
      top: top       || $('#elements').offset().top,
      left: -width   || -230
    })
  $block.animate({
    left: 0
  }, 400);
  $('.close-slider').click(function() {
    // prevent duplicate form clicks
    $(this).parent()
      .find('input, textarea')
      .prop('disabled', true);
    $block.animate({
      left: -width || -230
    }, 400, function() {
      $(this).remove();
    });
  });
};<commit_msg>successful fix for #23<commit_after>module.exports = function(content, width, height, top) {
  if ($('.slider').length) {
    return false;
  }
  $block = $('

x

');
  $block.append(content)
    .appendTo('body')
    .css({
      width:  width  || 230,
      height: height || 200,
      position: 'absolute',
      top: top       || $('#elements').offset().top,
      left: -width   || -230
    })
  $block.animate({
    left: 0
  }, 400);
  $('.close-slider').click(function() {
    $(this).parent()
      .find('*')
      .unbind('click');
    $block.animate({
      left: -width || -230
    }, 400, function() {
      $(this).remove();
    });
  });
};<|endoftext|>


<commit_before>//
// preTTY
//
// (c) 2016 Sanjeev Premi (spremi@ymail.com)
//
// SPDX-License-Identifier: BSD-3-Clause
//                          (http://spdx.org/licenses/BSD-3-Clause.html)
//

'use strict';

angular.module('preTtyApp')
  .service('ptPortSvc', function () {
    // AngularJS will instantiate a singleton by calling "new" on this function
  });
<commit_msg>client: pt-port-svc: Initial implementation<commit_after>//
// preTTY
//
// (c) 2016 Sanjeev Premi (spremi@ymail.com)
//
// SPDX-License-Identifier: BSD-3-Clause
//                          (http://spdx.org/licenses/BSD-3-Clause.html)
//

'use strict';

angular.module('preTtyApp')
  .service('ptPortSvc', [
    function () {
      /**
       * Array of known ports.
       *
       * All ports may not be currently active. But we may want to maintain
       * the data - in anticipation of reconnection.
       */
      this.ports = [];

      /**
       * Return list of available ports
       */
      this.list = function () {
        return this.ports;
      };
    }
  ]);
<|endoftext|>


<commit_before>import 'isomorphic-unfetch';
import App, { Container } from 'next/app';
import React from 'react';
import Head from 'next/head';
import getConfig from 'next/config';
import { ApolloProvider } from 'react-apollo';
import ApolloClient from 'apollo-boost';
import Typekit from 'react-typekit';
import withKeycloak from '../lib/withKeycloak';
import withApollo from '../lib/withApollo';
import NotAuthenticated from '../components/NotAuthenticated';
import { bp, color, fontSize } from '../variables';

const { serverRuntimeConfig, publicRuntimeConfig } = getConfig();

class MyApp extends App {
  render() {
    const { Component, pageProps, apolloClient, keycloak } = this.props;
    return (
      <Container>
        <Head>
          <link rel="stylesheet" href="/static/normalize.css" />
          <Typekit kitId="ggo2pml" />
          <script
            type="text/javascript"
            src={`${publicRuntimeConfig.KEYCLOAK_API}/js/keycloak.js`}
          />
        </Head>
        {(apolloClient && (
          <ApolloProvider client={apolloClient}>
            <Component {...pageProps} keycloak={keycloak}/>
          </ApolloProvider>
        )) || <NotAuthenticated />}
        <style jsx global>{`
          * {
            box-sizing: border-box;
          }
          body {
            color: ${color.black};
            font-family: 'source-sans-pro', sans-serif;
            ${fontSize(16)};
            height: 100%;
            line-height: 1.25rem;
            overflow-x: hidden;
            .content-wrapper {
              background-color: ${color.almostWhite};
              flex: 1 0 auto;
              width: 100%;
            }
            #__next {
              display: flex;
              flex-direction: column;
              min-height: 100vh;
            }
            a {
              color: ${color.black};
              text-decoration: none;
              &.hover-state {
                position: relative;
                transition: all 0.2s ease-in-out;
                &::before,
                &::after {
                  content: '';
                  position: absolute;
                  bottom: 0;
                  width: 0px;
                  height: 1px;
                  transition: all 0.2s ease-in-out;
                  transition-duration: 0.75s;
                  opacity: 0;
                }
                &::after {
                  left: 0;
                  background-color: ${color.linkBlue};
                }
                &:hover {
                  &::before,
                  &::after {
                    width: 100%;
                    opacity: 1;
                  }
                }
              }
            }
            p {
              margin: 0 0 1.25rem;
            }
            p a {
              text-decoration: none;
              transition: background 0.3s ease-out;
            }
            strong {
              font-weight: normal;
            }
            em {
              font-style: normal;
            }
            h2 {
              ${fontSize(36, 42)};
              font-weight: normal;
              margin: 0 0 38px;
            }
            h3 {
              ${fontSize(30, 42)};
              font-weight: normal;
              margin: 0 0 36px;
            }
            h4 {
              ${fontSize(25, 38)};
              font-weight: normal;
              margin: 4px 0 0;
            }
            ul {
              list-style: none;
              margin: 0 0 1.25rem;
              padding-left: 0;
              li {
                background-size: 8px;
                margin-bottom: 1.25rem;
                padding-left: 20px;
                a {
                  text-decoration: none;
                }
              }
            }
            ol {
              margin: 0 0 1.25rem;
              padding-left: 20px;
              li {
                margin-bottom: 1.25rem;
                a {
                  text-decoration: none;
                }
              }
            }
            .box {
              border: 1px solid ${color.lightestGrey};
              box-shadow: 0px 4px 8px 0px rgba(0, 0, 0, 0.03);
              border-radius: 3px;
              position: relative;
              width: 100%;
              &::after {
                bottom: 4px;
                content: '';
                display: block;
                height: 20px;
                left: 15px;
                position: absolute;
                transition: box-shadow 0.5s ease;
                width: calc(100% - 30px);
              }
              &:hover {
                border: 1px solid ${color.brightBlue};
                &::after {
                  box-shadow: 0px 12px 40px 0px rgba(73, 127, 250, 0.5);
                }
              }
              a {
                background-color: ${color.white};
                border-radius: 3px;
                display: block;
                height: 100%;
                overflow: hidden;
                padding: 16px 20px;
                position: relative;
                transition: background-image 0.5s ease-in-out;
                z-index: 10;
              }
            }
            .field {
              line-height: 25px;
              a {
                color: ${color.linkBlue};
              }
            }
            label {
              color: ${color.darkGrey};
              font-family: 'source-code-pro', sans-serif;
              ${fontSize(13)};
              text-transform: uppercase;
            }
            .field-wrapper {
              display: flex;
              margin-bottom: 18px;
              @media ${bp.xs_smallUp} {
                margin-bottom: 30px;
              }
              &::before {
                @media ${bp.xs_smallUp} {
                  background-position: top 11px right 14px;
                  background-repeat: no-repeat;
                  background-size: 20px;
                  border-right: 1px solid ${color.midGrey};
                  content: '';
                  display: block;
                  height: 60px;
                  left: 0;
                  margin-right: 14px;
                  min-width: calc((100vw / 16) * 1.5);
                  padding-right: 14px;
                  position: absolute;
                  width: calc((100vw / 16) * 1.5);
                }
              }
              & > div {
                @media ${bp.xs_smallUp} {
                  margin-top: 8px;
                }
              }
            }
          }
        `}</style>
      </Container>
    );
  }
}

export default withKeycloak(withApollo(MyApp));
<commit_msg>fix sidebar icon overlapping<commit_after>import 'isomorphic-unfetch';
import App, { Container } from 'next/app';
import React from 'react';
import Head from 'next/head';
import getConfig from 'next/config';
import { ApolloProvider } from 'react-apollo';
import ApolloClient from 'apollo-boost';
import Typekit from 'react-typekit';
import withKeycloak from '../lib/withKeycloak';
import withApollo from '../lib/withApollo';
import NotAuthenticated from '../components/NotAuthenticated';
import { bp, color, fontSize } from '../variables';

const { serverRuntimeConfig, publicRuntimeConfig } = getConfig();

class MyApp extends App {
  render() {
    const { Component, pageProps, apolloClient, keycloak } = this.props;
    return (
      <Container>
        <Head>
          <link rel="stylesheet" href="/static/normalize.css" />
          <Typekit kitId="ggo2pml" />
          <script
            type="text/javascript"
            src={`${publicRuntimeConfig.KEYCLOAK_API}/js/keycloak.js`}
          />
        </Head>
        {(apolloClient && (
          <ApolloProvider client={apolloClient}>
            <Component {...pageProps} keycloak={keycloak}/>
          </ApolloProvider>
        )) || <NotAuthenticated />}
        <style jsx global>{`
          * {
            box-sizing: border-box;
          }
          body {
            color: ${color.black};
            font-family: 'source-sans-pro', sans-serif;
            ${fontSize(16)};
            height: 100%;
            line-height: 1.25rem;
            overflow-x: hidden;
            .content-wrapper {
              background-color: ${color.almostWhite};
              flex: 1 0 auto;
              width: 100%;
            }
            #__next {
              display: flex;
              flex-direction: column;
              min-height: 100vh;
            }
            a {
              color: ${color.black};
              text-decoration: none;
              &.hover-state {
                position: relative;
                transition: all 0.2s ease-in-out;
                &::before,
                &::after {
                  content: '';
                  position: absolute;
                  bottom: 0;
                  width: 0px;
                  height: 1px;
                  transition: all 0.2s ease-in-out;
                  transition-duration: 0.75s;
                  opacity: 0;
                }
                &::after {
                  left: 0;
                  background-color: ${color.linkBlue};
                }
                &:hover {
                  &::before,
                  &::after {
                    width: 100%;
                    opacity: 1;
                  }
                }
              }
            }
            p {
              margin: 0 0 1.25rem;
            }
            p a {
              text-decoration: none;
              transition: background 0.3s ease-out;
            }
            strong {
              font-weight: normal;
            }
            em {
              font-style: normal;
            }
            h2 {
              ${fontSize(36, 42)};
              font-weight: normal;
              margin: 0 0 38px;
            }
            h3 {
              ${fontSize(30, 42)};
              font-weight: normal;
              margin: 0 0 36px;
            }
            h4 {
              ${fontSize(25, 38)};
              font-weight: normal;
              margin: 4px 0 0;
            }
            ul {
              list-style: none;
              margin: 0 0 1.25rem;
              padding-left: 0;
              li {
                background-size: 8px;
                margin-bottom: 1.25rem;
                padding-left: 20px;
                a {
                  text-decoration: none;
                }
              }
            }
            ol {
              margin: 0 0 1.25rem;
              padding-left: 20px;
              li {
                margin-bottom: 1.25rem;
                a {
                  text-decoration: none;
                }
              }
            }
            .box {
              border: 1px solid ${color.lightestGrey};
              box-shadow: 0px 4px 8px 0px rgba(0, 0, 0, 0.03);
              border-radius: 3px;
              position: relative;
              width: 100%;
              &::after {
                bottom: 4px;
                content: '';
                display: block;
                height: 20px;
                left: 15px;
                position: absolute;
                transition: box-shadow 0.5s ease;
                width: calc(100% - 30px);
              }
              &:hover {
                border: 1px solid ${color.brightBlue};
                &::after {
                  box-shadow: 0px 12px 40px 0px rgba(73, 127, 250, 0.5);
                }
              }
              a {
                background-color: ${color.white};
                border-radius: 3px;
                display: block;
                height: 100%;
                overflow: hidden;
                padding: 16px 20px;
                position: relative;
                transition: background-image 0.5s ease-in-out;
                z-index: 10;
              }
            }
            .field {
              line-height: 25px;
              a {
                color: ${color.linkBlue};
              }
            }
            label {
              color: ${color.darkGrey};
              font-family: 'source-code-pro', sans-serif;
              ${fontSize(13)};
              text-transform: uppercase;
            }
            .field-wrapper {
              display: flex;
              margin-bottom: 18px;
              @media ${bp.xs_smallUp} {
                margin-bottom: 30px;
              }
              &::before {
                @media ${bp.xs_smallUp} {
                  background-position: top 11px right 14px;
                  background-repeat: no-repeat;
                  background-size: 20px;
                  border-right: 1px solid ${color.midGrey};
                  content: '';
                  display: block;
                  height: 60px;
                  left: 0;
                  margin-left: calc(((100vw / 16) * 1.5) - 25px);
                  margin-right: 14px;
                  padding-right: 14px;
                  position: absolute;
                  width: 25px;
                }
              }
              & > div {
                @media ${bp.xs_smallUp} {
                  margin-top: 8px;
                }
              }
            }
          }
        `}</style>
      </Container>
    );
  }
}

export default withKeycloak(withApollo(MyApp));
<|endoftext|>


<commit_before>// @flow

const winston = require('winston');
const path = require('path');
const fs = require('fs');

// Create the logs directory if it doesn't exist yet.
const directory = path.join('.', 'logs');
if (!fs.existsSync(directory)) {
  fs.mkdirSync(directory);
}

const logger = new winston.Logger({
  exitOnError: false,
  transports: [
    new winston.transports.Console({
      level: 'debug',
      handleExceptions: true,
      json: false,
      colorize: true,
    }),
  ],
});

module.exports = logger;
<commit_msg>no log directory is needed for api<commit_after>// @flow

const winston = require('winston');

const logger = new winston.Logger({
  exitOnError: false,
  transports: [
    new winston.transports.Console({
      level: 'debug',
      handleExceptions: true,
      json: false,
      colorize: true,
    }),
  ],
});

module.exports = logger;
<|endoftext|>


<commit_before>$().ready(function () {
    setTimeout(function () {
        $('div.alert').delay(1500).fadeOut(400); // "div.alert" é a div que tem a class alert do elemento que deseja manipular.
    }, 2500); // O valor é representado em milisegundos.
});<commit_msg>Update funcoesGlobal.js<commit_after>$().ready(function () {
    setTimeout(function () {
        $('div.alert').delay(1500).fadeOut(400); // "div.alert" é a div que tem a class alert do elemento que deseja manipular.
    }, 2500); // O valor é representado em milisegundos.
});
<|endoftext|>


<commit_before>export default (grid) => {
  const coordFields = [
    ['x', 'y'],
    ['left', 'top'],
    ['right', 'bottom'],
    ['width', 'height'],
  ].filter(([xField, yField]) => xField in grid || yField in grid);

  return function (x, y) {
    const {
      range,
      limits = {
        left  : -Infinity,
        right :  Infinity,
        top   : -Infinity,
        bottom:  Infinity,
      },
    } = grid;

    const offset = offset || { x: 0, y: 0 };
    const result = { range };

    for (const [xField, yField] of coordFields) {
      const gridx = Math.round((x - offset.x) / grid[xField]);
      const gridy = Math.round((y - offset.y) / grid[yField]);

      result[xField] = Math.max(limits.left, Math.min(limits.right , gridx * grid[xField] + offset.x));
      result[yField] = Math.max(limits.top, Math.min(limits.bottom , gridy * grid[yField] + offset.y));
    }

    return result;
  };
};
<commit_msg>snappers/grid: fix offset<commit_after>export default (grid) => {
  const coordFields = [
    ['x', 'y'],
    ['left', 'top'],
    ['right', 'bottom'],
    ['width', 'height'],
  ].filter(([xField, yField]) => xField in grid || yField in grid);

  return function (x, y) {
    const {
      range,
      limits = {
        left  : -Infinity,
        right :  Infinity,
        top   : -Infinity,
        bottom:  Infinity,
      },
      offset = { x: 0, y: 0 },
    } = grid;

    const result = { range };

    for (const [xField, yField] of coordFields) {
      const gridx = Math.round((x - offset.x) / grid[xField]);
      const gridy = Math.round((y - offset.y) / grid[yField]);

      result[xField] = Math.max(limits.left, Math.min(limits.right , gridx * grid[xField] + offset.x));
      result[yField] = Math.max(limits.top, Math.min(limits.bottom , gridy * grid[yField] + offset.y));
    }

    return result;
  };
};
<|endoftext|>


<commit_before>---
---
$(document).ready(function() {
  'use strict';

  var client = algoliasearch('KDWVSZVS1I', 'ce4d584b0de36ca3f8b4727fdb83c658');
  var index = client.initIndex('grantmakers_io');

  autocomplete('#autocomplete-input', { hint: false, openOnFocus: false, minLength: 1 }, [
    {
      source: function(q, cb) {
        if (q === '') {
          cb([
            // { organization_name: 'NOVO FOUNDATION' },
            // { organization_name: 'ABBOTT FAMILY FOUNDATION' },
            // { organization_name: 'BILL AND MELINDA GATES FOUNDATION' }
          ]);
        } else {
          var defaultHits = autocomplete.sources.hits(index, { hitsPerPage: 5 });
          defaultHits(q, cb);
        }
      },
      displayKey: 'organization_name',
      templates: {
        suggestion: function(suggestion) {
          return autocomplete.escapeHighlightedString(suggestion._highlightResult) && autocomplete.escapeHighlightedString(suggestion._highlightResult.organization_name.value) || autocomplete.escapeHighlightedString(suggestion.organization_name);
        },
        footer: function(){
          return '
Search powered by
'
        },
        empty: function(){
          return '
Not finding what you need? Try our full search.
';
        }
      }
    }
  ]).on('autocomplete:selected', function(event, suggestion, dataset) {
    var ein = suggestion.ein;
    var target = 'https://www.grantmakers.io/profiles/' + ein;
    if(ein) {
      location.href = target;
    } else {
      var $toastContent = $('Something went wrong').add($('<button class="btn-flat toast-action toast-action-redirect">Try main search page</button>'));
      Materialize.toast($toastContent, 10000);
      $('.toast-action-redirect').on('click', function(){
        location.href = 'https://www.grantmakers.io';
      });
    }
  });
});
<commit_msg>Fix empty state link<commit_after>---
---
$(document).ready(function() {
  'use strict';

  var client = algoliasearch('KDWVSZVS1I', 'ce4d584b0de36ca3f8b4727fdb83c658');
  var index = client.initIndex('grantmakers_io');

  autocomplete('#autocomplete-input', { hint: false, openOnFocus: false, minLength: 1 }, [
    {
      source: function(q, cb) {
        if (q === '') {
          cb([
            // { organization_name: 'NOVO FOUNDATION' },
            // { organization_name: 'ABBOTT FAMILY FOUNDATION' },
            // { organization_name: 'BILL AND MELINDA GATES FOUNDATION' }
          ]);
        } else {
          var defaultHits = autocomplete.sources.hits(index, { hitsPerPage: 5 });
          defaultHits(q, cb);
        }
      },
      displayKey: 'organization_name',
      templates: {
        suggestion: function(suggestion) {
          return autocomplete.escapeHighlightedString(suggestion._highlightResult) && autocomplete.escapeHighlightedString(suggestion._highlightResult.organization_name.value) || autocomplete.escapeHighlightedString(suggestion.organization_name);
        },
        footer: function(){
          return '
Search powered by
'
        },
        empty: function(){
          return '
Not finding what you need? Try our full search.
';
        }
      }
    }
  ]).on('autocomplete:selected', function(event, suggestion, dataset) {
    var ein = suggestion.ein;
    var target = 'https://www.grantmakers.io/profiles/' + ein;
    if(ein) {
      location.href = target;
    } else {
      var $toastContent = $('Something went wrong').add($('<button class="btn-flat toast-action toast-action-redirect">Try main search page</button>'));
      Materialize.toast($toastContent, 10000);
      $('.toast-action-redirect').on('click', function(){
        location.href = 'https://www.grantmakers.io';
      });
    }
  });
});
<|endoftext|>


<commit_before>import { inject as service } from '@ember/service';
import Route from '@ember/routing/route';
import RSVP from 'rsvp';
import fetch from 'fetch';
import moment from 'moment';
import config from 'thirdeye-frontend/config/environment';
import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-route-mixin';
import {
  toCurrentUrn,
  toBaselineUrn,
  dateFormatFull,
  appendFilters,
  filterPrefix
} from 'thirdeye-frontend/utils/rca-utils';
import { checkStatus } from 'thirdeye-frontend/utils/utils';
import _ from 'lodash';

const ROOTCAUSE_SETUP_MODE_CONTEXT = "context";
const ROOTCAUSE_SETUP_MODE_SELECTED = "selected";
const ROOTCAUSE_SETUP_MODE_NONE = "none";

const UNIT_MAPPING = {
  NANOSECONDS: 'nanosecond',
  MILLISECONDS: 'millisecond',
  SECONDS: 'second',
  MINUTES: 'minute',
  HOURS: 'hour',
  DAYS: 'day'
};

/**
 * adjusts RCA backend granularity to a sane scale
 */
const adjustGranularity = (attrGranularity) => {
  const [count, unit] = attrGranularity.split('_');
  const granularity = [parseInt(count, 10), unit];

  if (['NANOSECONDS', 'MILLISECONDS', 'SECONDS'].includes(granularity[1])) {
    granularity[0] = 5;
    granularity[1] = 'MINUTES';
  }

  if (['MINUTES'].includes(granularity[1])) {
    granularity[0] = Math.max(granularity[0], 5);
    granularity[1] = 'MINUTES';
  }

  return granularity[0] + "_" + granularity[1];
};

/**
 * adjusts metric max time based on metric granularity
 */
const adjustMaxTime = (maxTime, metricGranularity) => {
  const time = moment(parseInt(maxTime, 10));
  const [count, unit] = metricGranularity;

  const start = time.startOf(unit);
  const remainder = start.get(unit) % count;

  return start.add(-1 * remainder, unit);
};

/**
 * converts RCA backend granularity strings into units understood by moment.js
 */
const toMetricGranularity = (attrGranularity) => {
  const [count, unit] = attrGranularity.split('_');
  return [parseInt(count, 10), UNIT_MAPPING[unit]];
};

/**
 * Returns the anomaly time range offset (in granularity units) based on metric granularity
 */
const toAnomalyOffset = (granularity) => {
  const UNIT_MAPPING = {
    minute: -30,
    hour: -3,
    day: -1
  };
  return UNIT_MAPPING[granularity[1]] || -1;
};

/**
 * Returns the analysis time range offset (in days) based on metric granularity
 */
const toAnalysisOffset = (granularity) => {
  const UNIT_MAPPING = {
    minute: -1,
    hour: -2,
    day: -7
  };
  return UNIT_MAPPING[granularity[1]] || -1;
};

export default Route.extend(AuthenticatedRouteMixin, {
  authService: service('session'),
  session: service(),

  queryParams: {
    metricId: {
      refreshModel: true,
      replace: true
    },
    sessionId: {
      refreshModel: false,
      replace: false
    },
    anomalyId: {
      refreshModel: true,
      replace: false
    }
  },

  model(params) {
    const { metricId, sessionId, anomalyId } = params;
    const isDevEnv = config.environment === 'development';

    let metricUrn, metricEntity, session, anomalyUrn, anomalyEntity, anomalySessions;

    if (metricId) {
      metricUrn = `thirdeye:metric:${metricId}`;
      metricEntity = fetch(`/rootcause/raw?framework=identity&urns=${metricUrn}`).then(checkStatus).then(res => res[0]).catch(() => {});
    }

    if (anomalyId) {
      anomalyUrn = `thirdeye:event:anomaly:${anomalyId}`;
      anomalyEntity = fetch(`/rootcause/raw?framework=identity&urns=${anomalyUrn}`).then(checkStatus).then(res => res[0]).catch(() => {});
      anomalySessions = fetch(`/session/query?anomalyId=${anomalyId}`).then(checkStatus).catch(() => {});
    }

    if (sessionId) {
      session = fetch(`/session/${sessionId}`).then(checkStatus).catch(() => {});
    }

    return RSVP.hash({
      isDevEnv,
      metricId,
      metricUrn,
      metricEntity,
      sessionId,
      session,
      anomalyId,
      anomalyUrn,
      anomalyEntity,
      anomalySessions
    });
  },

  /**
   * @description Resets any query params to allow not to have leak state or sticky query-param
   * @method resetController
   * @param {Object} controller - active controller
   * @param {Boolean} isExiting - exit status
   * @return {undefined}
   */
  resetController(controller, isExiting) {
    this._super(...arguments);
    if (isExiting) {
      controller.set('sessionId', null);
    }
  },

  afterModel(model, transition) {
    const defaultParams = {
      anomalyRangeStart: moment().startOf('hour').subtract(3, 'hour').valueOf(),
      anomalyRangeEnd: moment().startOf('hour').valueOf(),
      analysisRangeStart: moment().startOf('day').subtract(6, 'day').valueOf(),
      analysisRangeEnd: moment().startOf('day').add(1, 'day').valueOf(),
      granularity: '1_HOURS',
      compareMode: 'WoW'
    };

    // default params
    const { queryParams } = transition;
    const newModel = Object.assign(model, { ...defaultParams, ...queryParams });

    // load latest saved session for anomaly
    const { anomalySessions } = model;
    if (!_.isEmpty(anomalySessions)) {
      const mostRecent = _.last(_.sortBy(anomalySessions, 'updated'));

      Object.assign(newModel, {
        anomalyId: null,
        anomalyUrn: null,
        anomalyContext: null,
        sessionId: mostRecent.id,
        session: mostRecent
      });

      // NOTE: apparently this does not abort the ongoing transition
      this.transitionTo({ queryParams: { sessionId: mostRecent.id, anomalyId: null } });
    }

    return newModel;
  },

  setupController(controller, model) {
    this._super(...arguments);

    const {
      analysisRangeStart,
      analysisRangeEnd,
      granularity,
      compareMode,
      anomalyRangeStart,
      anomalyRangeEnd,
      metricId,
      metricUrn,
      metricEntity,
      sessionId,
      session,
      anomalyId,
      anomalyUrn,
      anomalyEntity
    } = model;

    const anomalyRange = [anomalyRangeStart, anomalyRangeEnd];
    const analysisRange = [analysisRangeStart, analysisRangeEnd];

    // default blank context
    let context = {
      urns: new Set(),
      anomalyRange,
      analysisRange,
      granularity,
      compareMode,
      anomalyUrns: new Set()
    };

    let selectedUrns = new Set();
    let sessionName = 'New Investigation (' + moment().format(dateFormatFull) + ')';
    let sessionText = '';
    let sessionOwner = this.get('authService.data.authenticated.name');
    let sessionPermissions = 'READ_WRITE';
    let sessionUpdatedBy = '';
    let sessionUpdatedTime = '';
    let sessionModified = true;
    let setupMode = ROOTCAUSE_SETUP_MODE_CONTEXT;
    let routeErrors = new Set();

    // metric-initialized context
    if (metricId && metricUrn) {
      if (!_.isEmpty(metricEntity)) {
        const granularity = adjustGranularity(metricEntity.attributes.granularity[0]);
        const metricGranularity = toMetricGranularity(granularity);
        const maxTime = adjustMaxTime(metricEntity.attributes.maxTime[0], metricGranularity);

        const anomalyRangeEnd = moment(maxTime).startOf(metricGranularity[1]).valueOf();
        const anomalyRangeStartOffset = toAnomalyOffset(metricGranularity);
        const anomalyRangeStart = moment(anomalyRangeEnd).add(anomalyRangeStartOffset, metricGranularity[1]).valueOf();
        const anomalyRange = [anomalyRangeStart, anomalyRangeEnd];

        const analysisRangeEnd = moment(anomalyRangeEnd).startOf('day').add(1, 'day').valueOf();
        const analysisRangeStartOffset = toAnalysisOffset(metricGranularity);
        const analysisRangeStart = moment(anomalyRangeEnd).add(analysisRangeStartOffset, 'day').valueOf();
        const analysisRange = [analysisRangeStart, analysisRangeEnd];

        context = {
          urns: new Set([metricUrn]),
          anomalyRange,
          analysisRange,
          granularity: (granularity === '1_DAYS') ? '1_HOURS' : granularity,
          compareMode,
          anomalyUrns: new Set()
        };

        selectedUrns = new Set([metricUrn, toCurrentUrn(metricUrn), toBaselineUrn(metricUrn)]);
        setupMode = ROOTCAUSE_SETUP_MODE_SELECTED;
      }
    }

    // anomaly-initialized context
    if (anomalyId && anomalyUrn) {
      if (!_.isEmpty(anomalyEntity)) {
        const granularity = adjustGranularity(anomalyEntity.attributes.metricGranularity[0]);
        const metricGranularity = toMetricGranularity(granularity);

        const anomalyRange = [parseInt(anomalyEntity.start, 10), parseInt(anomalyEntity.end, 10)];

        // align to local end of day
        const analysisRangeEnd = moment(anomalyRange[1]).startOf('day').add(1, 'day').valueOf();
        const analysisRangeStartOffset = toAnalysisOffset(metricGranularity);
        const analysisRangeStart = moment(anomalyRange[0]).startOf('day').add(analysisRangeStartOffset, 'day').valueOf();
        const analysisRange = [analysisRangeStart, analysisRangeEnd];

        const anomalyDimNames = anomalyEntity.attributes['dimensions'] || [];
        const anomalyFilters = [];
        anomalyDimNames.forEach(dimName => {
          anomalyEntity.attributes[dimName].forEach(dimValue => {
            anomalyFilters.pushObject([dimName, dimValue]);
          });
        });

        const anomalyMetricUrnRaw = `thirdeye:metric:${anomalyEntity.attributes['metricId'][0]}`;
        const anomalyMetricUrn = appendFilters(anomalyMetricUrnRaw, anomalyFilters);

        const anomalyFunctionUrns = [];
        if (!_.isEmpty(anomalyEntity.attributes['functionId'])) {
          const anomalyFunctionUrnRaw = `frontend:anomalyfunction:${anomalyEntity.attributes['functionId'][0]}`;
          anomalyFunctionUrns.pushObject(appendFilters(anomalyFunctionUrnRaw, anomalyFilters));
        }

        context = {
          urns: new Set([anomalyMetricUrn]),
          anomalyRange,
          analysisRange,
          granularity,
          compareMode: 'WoW',
          anomalyUrns: new Set([anomalyUrn, anomalyMetricUrn].concat(anomalyFunctionUrns))
        };

        selectedUrns = new Set([anomalyUrn, anomalyMetricUrn]);
        sessionName = 'New Investigation of #' + anomalyId + ' (' + moment().format(dateFormatFull) + ')';
        setupMode = ROOTCAUSE_SETUP_MODE_SELECTED;
        sessionText = anomalyEntity.attributes.comment[0];
      } else {
        routeErrors.add(`Could not find anomalyId ${anomalyId}`);
      }
    }

    // session-initialized context
    if (sessionId) {
      if (!_.isEmpty(session)) {
        const { name, text, updatedBy, updated, owner, permissions } = model.session;
        context = {
          urns: new Set(session.contextUrns),
          anomalyRange: [session.anomalyRangeStart, session.anomalyRangeEnd],
          analysisRange: [session.analysisRangeStart, session.analysisRangeEnd],
          granularity: session.granularity,
          compareMode: session.compareMode,
          anomalyUrns: new Set(session.anomalyUrns || [])
        };
        selectedUrns = new Set(session.selectedUrns);

        sessionName = name;
        sessionText = text;
        sessionOwner = owner;
        sessionPermissions = permissions;
        sessionUpdatedBy = updatedBy;
        sessionUpdatedTime = updated;
        sessionModified = false;
        setupMode = ROOTCAUSE_SETUP_MODE_NONE;

      } else {
        routeErrors.add(`Could not find sessionId ${sessionId}`);
      }
    }

    // update secondary metrics
    const sizeMetricUrns = new Set(filterPrefix(context.urns, 'thirdeye:metric:'));

    controller.setProperties({
      routeErrors,
      anomalyId,
      metricId,
      sessionId,
      sessionName,
      sessionText,
      sessionOwner,
      sessionPermissions,
      sessionUpdatedBy,
      sessionUpdatedTime,
      sessionModified,
      selectedUrns,
      sizeMetricUrns,
      setupMode,
      context
    });
  },

  actions: {
    /**
     * save session url for transition on login
     * @method willTransition
     */
    willTransition(transition) {
      //saving session url - TODO: add a util or service - lohuynh
      if (transition.intent.name && transition.intent.name !== 'logout') {
        this.set('session.store.fromUrl', {lastIntentTransition: transition});
      }
    },
    error() {
      // The `error` hook is also provided the failed
      // `transition`, which can be stored and later
      // `.retry()`d if desired.
      return true;
    }
  }
});
<commit_msg>[TE] frontend - aaronucsd/fixed the missing data points on valid analysis range (#3243)<commit_after>import { inject as service } from '@ember/service';
import Route from '@ember/routing/route';
import RSVP from 'rsvp';
import fetch from 'fetch';
import moment from 'moment';
import config from 'thirdeye-frontend/config/environment';
import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-route-mixin';
import {
  toCurrentUrn,
  toBaselineUrn,
  dateFormatFull,
  appendFilters,
  filterPrefix
} from 'thirdeye-frontend/utils/rca-utils';
import { checkStatus } from 'thirdeye-frontend/utils/utils';
import _ from 'lodash';

const ROOTCAUSE_SETUP_MODE_CONTEXT = "context";
const ROOTCAUSE_SETUP_MODE_SELECTED = "selected";
const ROOTCAUSE_SETUP_MODE_NONE = "none";

const UNIT_MAPPING = {
  NANOSECONDS: 'nanosecond',
  MILLISECONDS: 'millisecond',
  SECONDS: 'second',
  MINUTES: 'minute',
  HOURS: 'hour',
  DAYS: 'day'
};

/**
 * adjusts RCA backend granularity to a sane scale
 */
const adjustGranularity = (attrGranularity) => {
  const [count, unit] = attrGranularity.split('_');
  const granularity = [parseInt(count, 10), unit];

  if (['NANOSECONDS', 'MILLISECONDS', 'SECONDS'].includes(granularity[1])) {
    granularity[0] = 5;
    granularity[1] = 'MINUTES';
  }

  if (['MINUTES'].includes(granularity[1])) {
    granularity[0] = Math.max(granularity[0], 5);
    granularity[1] = 'MINUTES';
  }

  return granularity[0] + "_" + granularity[1];
};

/**
 * adjusts metric max time based on metric granularity
 */
const adjustMaxTime = (maxTime, metricGranularity) => {
  const time = moment(parseInt(maxTime, 10));
  const [count, unit] = metricGranularity;

  const start = time.startOf(unit);
  const remainder = start.get(unit) % count;

  return start.add(-1 * remainder, unit);
};

/**
 * converts RCA backend granularity strings into units understood by moment.js
 */
const toMetricGranularity = (attrGranularity) => {
  const [count, unit] = attrGranularity.split('_');
  return [parseInt(count, 10), UNIT_MAPPING[unit]];
};

/**
 * Returns the anomaly time range offset (in granularity units) based on metric granularity
 */
const toAnomalyOffset = (granularity) => {
  const UNIT_MAPPING = {
    minute: -30,
    hour: -3,
    day: -1
  };
  return UNIT_MAPPING[granularity[1]] || -1;
};

/**
 * Returns the analysis time range offset (in days) based on metric granularity
 */
const toAnalysisOffset = (granularity) => {
  const UNIT_MAPPING = {
    minute: -1,
    hour: -2,
    day: -7
  };
  return UNIT_MAPPING[granularity[1]] || -1;
};

export default Route.extend(AuthenticatedRouteMixin, {
  authService: service('session'),
  session: service(),

  queryParams: {
    metricId: {
      refreshModel: true,
      replace: true
    },
    sessionId: {
      refreshModel: false,
      replace: false
    },
    anomalyId: {
      refreshModel: true,
      replace: false
    }
  },

  model(params) {
    const { metricId, sessionId, anomalyId } = params;
    const isDevEnv = config.environment === 'development';

    let metricUrn, metricEntity, session, anomalyUrn, anomalyEntity, anomalySessions;

    if (metricId) {
      metricUrn = `thirdeye:metric:${metricId}`;
      metricEntity = fetch(`/rootcause/raw?framework=identity&urns=${metricUrn}`).then(checkStatus).then(res => res[0]).catch(() => {});
    }

    if (anomalyId) {
      anomalyUrn = `thirdeye:event:anomaly:${anomalyId}`;
      anomalyEntity = fetch(`/rootcause/raw?framework=identity&urns=${anomalyUrn}`).then(checkStatus).then(res => res[0]).catch(() => {});
      anomalySessions = fetch(`/session/query?anomalyId=${anomalyId}`).then(checkStatus).catch(() => {});
    }

    if (sessionId) {
      session = fetch(`/session/${sessionId}`).then(checkStatus).catch(() => {});
    }

    return RSVP.hash({
      isDevEnv,
      metricId,
      metricUrn,
      metricEntity,
      sessionId,
      session,
      anomalyId,
      anomalyUrn,
      anomalyEntity,
      anomalySessions
    });
  },

  /**
   * @description Resets any query params to allow not to have leak state or sticky query-param
   * @method resetController
   * @param {Object} controller - active controller
   * @param {Boolean} isExiting - exit status
   * @return {undefined}
   */
  resetController(controller, isExiting) {
    this._super(...arguments);
    if (isExiting) {
      controller.set('sessionId', null);
    }
  },

  afterModel(model, transition) {
    const defaultParams = {
      anomalyRangeStart: moment().startOf('hour').subtract(3, 'hour').valueOf(),
      anomalyRangeEnd: moment().startOf('hour').valueOf(),
      analysisRangeStart: moment().startOf('day').subtract(6, 'day').valueOf(),
      analysisRangeEnd: moment().startOf('day').add(1, 'day').valueOf(),
      granularity: '1_HOURS',
      compareMode: 'WoW'
    };

    // default params
    const { queryParams } = transition;
    const newModel = Object.assign(model, { ...defaultParams, ...queryParams });

    // load latest saved session for anomaly
    const { anomalySessions } = model;
    if (!_.isEmpty(anomalySessions)) {
      const mostRecent = _.last(_.sortBy(anomalySessions, 'updated'));

      Object.assign(newModel, {
        anomalyId: null,
        anomalyUrn: null,
        anomalyContext: null,
        sessionId: mostRecent.id,
        session: mostRecent
      });

      // NOTE: apparently this does not abort the ongoing transition
      this.transitionTo({ queryParams: { sessionId: mostRecent.id, anomalyId: null } });
    }

    return newModel;
  },

  setupController(controller, model) {
    this._super(...arguments);

    const {
      analysisRangeStart,
      analysisRangeEnd,
      granularity,
      compareMode,
      anomalyRangeStart,
      anomalyRangeEnd,
      metricId,
      metricUrn,
      metricEntity,
      sessionId,
      session,
      anomalyId,
      anomalyUrn,
      anomalyEntity
    } = model;

    const anomalyRange = [anomalyRangeStart, anomalyRangeEnd];
    const analysisRange = [analysisRangeStart, analysisRangeEnd];

    // default blank context
    let context = {
      urns: new Set(),
      anomalyRange,
      analysisRange,
      granularity,
      compareMode,
      anomalyUrns: new Set()
    };

    let selectedUrns = new Set();
    let sessionName = 'New Investigation (' + moment().format(dateFormatFull) + ')';
    let sessionText = '';
    let sessionOwner = this.get('authService.data.authenticated.name');
    let sessionPermissions = 'READ_WRITE';
    let sessionUpdatedBy = '';
    let sessionUpdatedTime = '';
    let sessionModified = true;
    let setupMode = ROOTCAUSE_SETUP_MODE_CONTEXT;
    let routeErrors = new Set();

    // metric-initialized context
    if (metricId && metricUrn) {
      if (!_.isEmpty(metricEntity)) {
        const granularity = adjustGranularity(metricEntity.attributes.granularity[0]);
        const metricGranularity = toMetricGranularity(granularity);
        const maxTime = adjustMaxTime(metricEntity.attributes.maxTime[0], metricGranularity);

        const anomalyRangeEnd = moment(maxTime).startOf(metricGranularity[1]).valueOf();
        const anomalyRangeStartOffset = toAnomalyOffset(metricGranularity);
        const anomalyRangeStart = moment(anomalyRangeEnd).add(anomalyRangeStartOffset, metricGranularity[1]).valueOf();
        const anomalyRange = [anomalyRangeStart, anomalyRangeEnd];

        const analysisRangeEnd = moment(anomalyRangeEnd).startOf('day').add(1, 'day').add(5, 'milliseconds').valueOf();
        const analysisRangeStartOffset = toAnalysisOffset(metricGranularity);
        const analysisRangeStart = moment(anomalyRangeEnd).add(analysisRangeStartOffset, 'day').valueOf();
        const analysisRange = [analysisRangeStart, analysisRangeEnd];

        context = {
          urns: new Set([metricUrn]),
          anomalyRange,
          analysisRange,
          granularity: (granularity === '1_DAYS') ? '1_HOURS' : granularity,
          compareMode,
          anomalyUrns: new Set()
        };

        selectedUrns = new Set([metricUrn, toCurrentUrn(metricUrn), toBaselineUrn(metricUrn)]);
        setupMode = ROOTCAUSE_SETUP_MODE_SELECTED;
      }
    }

    // anomaly-initialized context
    if (anomalyId && anomalyUrn) {
      if (!_.isEmpty(anomalyEntity)) {
        const granularity = adjustGranularity(anomalyEntity.attributes.metricGranularity[0]);
        const metricGranularity = toMetricGranularity(granularity);

        const anomalyRange = [parseInt(anomalyEntity.start, 10), parseInt(anomalyEntity.end, 10)];

        // align to local end of day
        const analysisRangeEnd = moment(anomalyRange[1]).startOf('day').add(1, 'day').add(5, 'milliseconds').valueOf();
        const analysisRangeStartOffset = toAnalysisOffset(metricGranularity);
        const analysisRangeStart = moment(anomalyRange[0]).startOf('day').add(analysisRangeStartOffset, 'day').valueOf();
        const analysisRange = [analysisRangeStart, analysisRangeEnd];

        const anomalyDimNames = anomalyEntity.attributes['dimensions'] || [];
        const anomalyFilters = [];
        anomalyDimNames.forEach(dimName => {
          anomalyEntity.attributes[dimName].forEach(dimValue => {
            anomalyFilters.pushObject([dimName, dimValue]);
          });
        });

        const anomalyMetricUrnRaw = `thirdeye:metric:${anomalyEntity.attributes['metricId'][0]}`;
        const anomalyMetricUrn = appendFilters(anomalyMetricUrnRaw, anomalyFilters);

        const anomalyFunctionUrns = [];
        if (!_.isEmpty(anomalyEntity.attributes['functionId'])) {
          const anomalyFunctionUrnRaw = `frontend:anomalyfunction:${anomalyEntity.attributes['functionId'][0]}`;
          anomalyFunctionUrns.pushObject(appendFilters(anomalyFunctionUrnRaw, anomalyFilters));
        }

        context = {
          urns: new Set([anomalyMetricUrn]),
          anomalyRange,
          analysisRange,
          granularity,
          compareMode: 'WoW',
          anomalyUrns: new Set([anomalyUrn, anomalyMetricUrn].concat(anomalyFunctionUrns))
        };

        selectedUrns = new Set([anomalyUrn, anomalyMetricUrn]);
        sessionName = 'New Investigation of #' + anomalyId + ' (' + moment().format(dateFormatFull) + ')';
        setupMode = ROOTCAUSE_SETUP_MODE_SELECTED;
        sessionText = anomalyEntity.attributes.comment[0];
      } else {
        routeErrors.add(`Could not find anomalyId ${anomalyId}`);
      }
    }

    // session-initialized context
    if (sessionId) {
      if (!_.isEmpty(session)) {
        const { name, text, updatedBy, updated, owner, permissions } = model.session;
        context = {
          urns: new Set(session.contextUrns),
          anomalyRange: [session.anomalyRangeStart, session.anomalyRangeEnd],
          analysisRange: [session.analysisRangeStart, session.analysisRangeEnd],
          granularity: session.granularity,
          compareMode: session.compareMode,
          anomalyUrns: new Set(session.anomalyUrns || [])
        };
        selectedUrns = new Set(session.selectedUrns);

        sessionName = name;
        sessionText = text;
        sessionOwner = owner;
        sessionPermissions = permissions;
        sessionUpdatedBy = updatedBy;
        sessionUpdatedTime = updated;
        sessionModified = false;
        setupMode = ROOTCAUSE_SETUP_MODE_NONE;

      } else {
        routeErrors.add(`Could not find sessionId ${sessionId}`);
      }
    }

    // update secondary metrics
    const sizeMetricUrns = new Set(filterPrefix(context.urns, 'thirdeye:metric:'));

    controller.setProperties({
      routeErrors,
      anomalyId,
      metricId,
      sessionId,
      sessionName,
      sessionText,
      sessionOwner,
      sessionPermissions,
      sessionUpdatedBy,
      sessionUpdatedTime,
      sessionModified,
      selectedUrns,
      sizeMetricUrns,
      setupMode,
      context
    });
  },

  actions: {
    /**
     * save session url for transition on login
     * @method willTransition
     */
    willTransition(transition) {
      //saving session url - TODO: add a util or service - lohuynh
      if (transition.intent.name && transition.intent.name !== 'logout') {
        this.set('session.store.fromUrl', {lastIntentTransition: transition});
      }
    },
    error() {
      // The `error` hook is also provided the failed
      // `transition`, which can be stored and later
      // `.retry()`d if desired.
      return true;
    }
  }
});
<|endoftext|>


<commit_before>export class CalendarController {

    constructor(
        bcCalendarConfig, bcCalendarService
    ) {
        'ngInject';

        this.bcCalendarConfig = bcCalendarConfig;
        this.bcCalendarService = bcCalendarService;

        console.log('config: ', bcCalendarConfig);

        this._activate();

    }

    _activate() {

        // Define today's date
        this.today = this.bcCalendarConfig.startDate;

        // DEFAULTS
        this.startDate = this.startDate || this.bcCalendarConfig.startDate;
        this.count = parseInt(this.bcCount || this.bcCalendarConfig.count, 10);
        this.interval = this.bcInterval || this.bcCalendarConfig.interval;
        this.weekdays = this.bcWordType ?  this.bcCalendarConfig.weekdayStyle[this.bcWordType] :
                this.bcCalendarConfig.weekdayStyle[this.bcCalendarConfig.wordType];
        this.organizeWeeks = this.bcOrganizeWeeks || this.bcCalendarConfig.organizeWeeks;

        console.log('count: ', this.count);
        console.log('interval: ', this.interval);

        // Define the calendar duration (or length)
        this.calendarDuration =
            moment.duration(this.count, this.bcCalendarConfig.interval);

        // Get the full count of days
        this.calendarDays = this.calendarDuration.asDays();
        console.log('calendarDays: ', this.calendarDays);

        // Get the current day of the month
        this.todayDayOfMonth = moment(this.startDate).date();

        // Get the current weekday
        this.todayDayOfWeek = moment(this.startDate).day();

        // Initially nothing is selected
        this.selectedDate = null;

        const DEV_DATE = {
            year: 2016,
            month: 3,
            day: 5,
        };

        /*
         *this._getDaysInMonth(this.startDate);
         *this.isDayToday(new Date(DEV_DATE.year, DEV_DATE.month, DEV_DATE.day))
         *this.isBeforeToday(new Date(DEV_DATE.year, DEV_DATE.month, DEV_DATE.day));
         */

        // loop through `interval` for `count` times
        //
        // always are building out days no matter the interval
        // interval is merely to simplify math for the end user
        //
        // if ask for 2 days
        //   collection is array with single item (month)
        //   month is array with single item (week)
        //   if weeks are turned ON
        //     week is array with 7 items (days) (backfilled for missing days)
        //   if weeks are turned OFF
        //     week is array with 2 items (days)
        //
        // if ask for 2 weeks
        //   collection is array with single item (month)
        //   month is array with 2 items (weeks)
        //   weeks are arrays with 7 items (days)
        //   if weeks are turned ON
        //     backfill for missing days
        //
        //
        // assume 'month'
        // buildMonth(start month)
        //   build out month json
        //     get all days
        //     formatMonth
        //       loop through putting weeks into arrays
        //       final collection looks like:
        //         - collection is array of months
        //         - months is an array of weeks
        //         - weeks is an array of days
        //   store month somewhere
        //   increment counter by 1
        //   if still less than this.count
        //     call buildMonth again with next month
        //

        const fakeArray = [''];

        this.calendar = this.build(this.startDate, 2);

    }

    build(start, duration, splitWeeks) {
        console.warn('in build: ', start, duration);

        let collection = [];
        let monthsBuilt = 0;

        // loop to create months
        while (monthsBuilt < duration) {
            const days = this._getDaysInMonth(moment(start).add(monthsBuilt, 'months'));

            // Add month to collection
            collection.push(days);

            // increment counter
            monthsBuilt = monthsBuilt + 1;
        }

        if (this.organizeWeeks) {
            collection = this._organizeWeeks(collection);
        }

        console.log('collection: ', collection);

        return collection;
    }

    /*
     *buildWeeks() {
     *}
     */

    /*
     *buildDays() {
     *}
     */

    /**
     * Check to see if the day is prior to the current date
     * This is used to disable the unselectable days
     *
     * @param {Date} day
     * @return {Bool}
     */
    isBeforeToday(date) {
        return moment(date).isBefore(this.startDate);
    }

    isDaySelected() {
    }

    /**
     * Check to see if the day matches the current date
     *
     * @param {Date} day
     * @return {Bool}
     */
    isDayToday(date) {
        return moment(date).isSame(this.startDate);
    }

    selectDate() {
    }

    /**
     * Return an array of dates for the passed in month
     *
     * @param {Date} startDate
     * @return {Array} days
     */
    _getDaysInMonth(startDate) {
        const firstDate = moment(startDate).startOf('month');
        const days = [];
        let date = moment(startDate).startOf('month');

        // As long as the month hasn't changed
        while (moment(date).isSame(firstDate, 'month')) {
            // Add the new day to our array
            days.push(moment(date).startOf('day').format());

            // Increment the date by one day
            date = moment(date).add(1, 'days');
        }

        return days;
    }

    /**
     * Turn a integer (e.g. '6') into an array: '[1,2,3,4,5,6]'
     *
     * @param {Integer} count
     * @return {Array} days
     */
    _integerToArray(count) {
        let i;
        const days = [];

        for (i = 0; i < count; i += 1) {
            days.push(i);
        }

        return days;

    }

    _organizeWeeks(collection) {
        const weekLength = 7;

        collection.forEach((value, index) => {
            collection[index] = this._chunk(value, weekLength);
        });

        return collection;
    }

    /**
     * Split an array into chunks and return an array of these chunks
     *
     * @param {Array} group
     * @param {Integer} groupsize
     * @return {Array} chunks
     */
    _chunk(group, groupsize) {
        const sets = [];
        let i = 0;
        const chunks = group.length / parseInt(groupsize, 10);

        while(i < chunks) {
            sets[i] = group.splice(0, groupsize);
            i = i + 1;
        }

        return sets;
    }

}

<commit_msg>wrote pad left, cleanup, comments, build working<commit_after>export class CalendarController {

    constructor(
        bcCalendarConfig, bcCalendarService
    ) {
        'ngInject';

        this.bcCalendarConfig = bcCalendarConfig;
        this.bcCalendarService = bcCalendarService;

        console.log('config: ', bcCalendarConfig);

        this._activate();

    }

    _activate() {

        // Define today's date
        this.today = this.bcCalendarConfig.startDate;

        // DEFAULTS
        this.startDate = this.startDate || this.bcCalendarConfig.startDate;
        this.count = parseInt(this.bcCount || this.bcCalendarConfig.count, 10);
        this.interval = this.bcInterval || this.bcCalendarConfig.interval;
        this.weekdays = this.bcWordType ?  this.bcCalendarConfig.weekdayStyle[this.bcWordType] :
                this.bcCalendarConfig.weekdayStyle[this.bcCalendarConfig.wordType];
        this.organizeWeeks = this.bcOrganizeWeeks || this.bcCalendarConfig.organizeWeeks;

        console.log('count: ', this.count);
        console.log('interval: ', this.interval);

        // Define the calendar duration (or length)
        this.calendarDuration =
            moment.duration(this.count, this.bcCalendarConfig.interval);

        // Get the full count of days
        this.calendarDays = this.calendarDuration.asDays();
        console.log('calendarDays: ', this.calendarDays);

        // Get the current day of the month
        this.todayDayOfMonth = moment(this.startDate).date();

        // Get the current weekday
        this.todayDayOfWeek = moment(this.startDate).day();

        // Initially nothing is selected
        this.selectedDate = null;

        const DEV_DATE = {
            year: 2016,
            month: 3,
            day: 5,
        };

        /*
         *this._getDaysInMonth(this.startDate);
         *this.isDayToday(new Date(DEV_DATE.year, DEV_DATE.month, DEV_DATE.day))
         *this.isBeforeToday(new Date(DEV_DATE.year, DEV_DATE.month, DEV_DATE.day));
         */

        // loop through `interval` for `count` times
        //
        // always are building out days no matter the interval
        // interval is merely to simplify math for the end user
        //
        // if ask for 2 days
        //   collection is array with single item (month)
        //   month is array with single item (week)
        //   if weeks are turned ON
        //     week is array with 7 items (days) (backfilled for missing days)
        //   if weeks are turned OFF
        //     week is array with 2 items (days)
        //
        // if ask for 2 weeks
        //   collection is array with single item (month)
        //   month is array with 2 items (weeks)
        //   weeks are arrays with 7 items (days)
        //   if weeks are turned ON
        //     backfill for missing days
        //
        //
        // assume 'month'
        // buildMonth(start month)
        //   build out month json
        //     get all days
        //     formatMonth
        //       loop through putting weeks into arrays
        //       final collection looks like:
        //         - collection is array of months
        //         - months is an array of weeks
        //         - weeks is an array of days
        //   store month somewhere
        //   increment counter by 1
        //   if still less than this.count
        //     call buildMonth again with next month
        //

        const fakeArray = [''];

        this.calendar = this.build(this.startDate, 2);

    }

    /**
     * Build calendar
     * TODO: Should this be a service?
     *
     * @param {String} start
     * @param {Integer} duration
     * @return {Array} collection
     */
    build(start, duration) {
        let collection = [];
        let monthsBuilt = 0;

        // Loop to create months
        while (monthsBuilt < duration) {
            let days = this._getDaysInMonth(moment(start).add(monthsBuilt, 'months'));

            // If this is the first month
            if (monthsBuilt === 0) {
                // Create the missing days for the padding
                const missingDays = this._padWeekLeft(days, this.todayDayOfWeek);

                // Add to the beginning of our existing array
                days = missingDays.concat(days);
            }

            // Add month to collection
            collection.push(days);

            // Increment counter
            monthsBuilt = monthsBuilt + 1;
        }

        if (this.organizeWeeks) {
            collection = this._organizeWeeks(collection);
        }

        console.log('collection: ', collection);

        return collection;
    }

    /**
     * Check to see if the day is prior to the current date
     * This is used to disable the unselectable days
     *
     * @param {Date} day
     * @return {Bool}
     */
    isBeforeToday(date) {
        return moment(date).isBefore(this.startDate);
    }

    /**
     * Check to see if the day matches the current date
     *
     * @param {Date} day
     * @return {Bool}
     */
    isDayToday(date) {
        return moment(date).isSame(this.startDate);
    }

    isDaySelected() {
    }

    selectDate() {
    }

    /**
     * Return an array of dates for the passed in month
     *
     * @param {Date} startDate
     * @return {Array} days
     */
    _getDaysInMonth(startDate) {
        const firstDate = moment(startDate);
        const days = [];
        let date = moment(startDate);

        // As long as the month hasn't changed
        while (moment(date).isSame(firstDate, 'month')) {
            // Add the new day to our array
            days.push(moment(date).startOf('day').format());

            // Increment the date by one day
            date = moment(date).add(1, 'days');
        }

        return days;
    }

    /**
     * Turn a integer (e.g. '6') into an array: '[1,2,3,4,5,6]'
     *
     * @param {Integer} count
     * @return {Array} days
     */
    _integerToArray(count) {
        let i;
        const days = [];

        for (i = 0; i < count; i += 1) {
            days.push(i);
        }

        return days;
    }

    /**
     * Organize collection of days into sub collections of weeks
     *
     * @param {Array} collection
     * @return {Array} collection
     */
    _organizeWeeks(collection) {
        const weekLength = 7;

        collection.forEach((value, index) => {
            collection[index] = this._chunk(value, weekLength);
        });

        return collection;
    }

    /**
     * Split an array into chunks and return an array of these chunks
     *
     * @param {Array} group
     * @param {Integer} groupsize
     * @return {Array} chunks
     */
    _chunk(group, groupsize) {
        const sets = [];
        let i = 0;
        const chunks = group.length / parseInt(groupsize, 10);

        while(i < chunks) {
            sets[i] = group.splice(0, groupsize);
            i = i + 1;
        }

        return sets;
    }

    /**
     * Pad the beginning of a week
     *
     * @param {Array} days
     * @return {Array} pad
     */
    _padWeekLeft(days, startDay) {
        const pad = [];
        const missingDays = this._integerToArray(startDay);

        // Loop through missing days
        for (const day in missingDays) {
            // How many days to go back
            const subtraction = parseInt(day, 10) + 1;

            // Find that day
            const previous = moment(this.startDate).subtract((subtraction), 'days').toISOString();
            // Add to the beginning of the array
            pad.unshift(previous);
        }

        return pad;
    }

}

<|endoftext|>


<commit_before>class TokenList{constructor(e,t){const n=[],s=/{(\w+|#)}/,o=e=>[].slice.call(e).map(e=>s.test(e.value)&&n.push(e)),r=document.createNodeIterator(e,NodeFilter.SHOW_ELEMENT|NodeFilter.SHOW_TEXT,e=>e.tagName?o(e.attributes):s.test(e.textContent)&&n.push(e),null);for(;r.nextNode(););for(e of n)(e.text=e.textContent).match(/[^{]+(?=})/g).map(t=>(this[t]||(this[t]=[])).push(e))}bind(e){Object.keys(this).map(e=>this[e].map(e=>e.textContent=e.text)&&e).map(t=>this[t].map(n=>n.textContent=n.textContent.split("{"+t+"}").join(e[t])))}}const HTMLElement=(e=>{function t(){}return t.prototype=e,t})(window.HTMLElement.prototype);(e=>{function t(e,t,n){for(n of this.querySelectorAll("[slot]"))(e.content||e).querySelector("slot[name="+n.getAttribute("slot")+"]").outerHTML=n.outerHTML;this.innerHTML=e.innerHTML}const n=new XMLHttpRequest;for(let s of document.querySelectorAll('link[id*="-"]'))n.open("GET",s.href),n.responseType="document",n.onload=function(){const e=this.response.querySelectorAll.bind(this.response),n=this.link,s=n.nextSibling;for(let o of document.querySelectorAll(n.id))t.call(o,e("template")[0].cloneNode(!0));for(let t of e("style,link,script")){let e=t.getAttribute("as"),o=document.createElement(t.localName);["src","href","textContent","rel"].map(((e,t)=>n=>t[n]&&(e[n]=t[n]))(o,t)),"style"==e&&(o.rel="stylesheet"),n.parentNode.insertBefore(o,s),"script"==e&&(n.parentNode.insertBefore(document.createElement("script"),s).src=t.href)}},n.link=s,n.send()})();const Template=function(e){return e.length&&(e=document.querySelector("template[name="+e+"]")),e.hidden=!0,e.HTML=e.innerHTML,e.bind=function(e,t){const n=document.createElement("section");for(let s of this.dependents||[])s.parentNode.removeChild(s);n.innerHTML=[].concat(e).reduce((e,t,n)=>{let s=this.HTML;"object"!=typeof t&&(t={self:t}),t["#"]=n;for(let o in t)s=s.split("{"+o+"}").join(t[o]);return e+s},""),t=this.nextSibling;for(let s of this.dependents=[].slice.call(n.childNodes))this.parentNode.insertBefore(s,t)}.bind(e),e};!window.customElements&&(window.customElements={}),new class{constructor({define:e,get:t,whenDefined:n}=customElements){window.customElements.define=this._define(void 0).bind(this)}_define(e=(e=>{})){return(t,n)=>e.apply(window.customElements,this.register(t,n))}register(e,t){return(this[e]=t).localName=e,"loading"===document.readyState?document.addEventListener("DOMContentLoaded",this.queue(...arguments)):this.queue(...arguments)(),arguments}queue(e,t){return n=>[].slice.call(document.getElementsByTagName(e)).map(this.upgrade(t))}upgrade(e){return t=>Object.setPrototypeOf(t,e.prototype).connectedCallback&&t.connectedCallback()}swizzle(e,...t){}};const ParentNode=e=>class extends e{select(){return this.selectAll(...arguments)[0]}selectAll(e,...t){return e=[].concat(e),[].slice.call(this.querySelectorAll(t.reduce((t,n)=>t+n+e.shift(),e.shift())))}},EventTarget=e=>class extends e{on(e,t){this.addEventListener(e,this.renderable(t))}renderable(e){return t=>!1!==e.call(this,t)&&t.defaultPrevented||this.render()}},GlobalEventHandlers=e=>class extends e{onconnect(){return this.templates=this.selectAll("template[name]").map(Template),this.tokens=new TokenList(this),super.onconnect&&super.onconnect(),this}reflect(e){/^on/.test(e)&&e in HTMLElement.prototype&&this.on(e.substr(2),this[e])}register(e,t,n){for(let s of e.attributes)/^on/.test(n=s.name)&&(t=(/{\s*(\w+)/.exec(e[n])||[])[1])&&(e[n]=this.renderable(this[t]))}},Custom=e=>class extends(ParentNode(EventTarget(GlobalEventHandlers(e)))){connectedCallback(){this.context={},super.initialize&&super.initialize(),Object.getOwnPropertyNames(e.prototype).map(this.reflect,this),this.onconnect().render()}render(e){for(e of this.templates)e.bind(this[e.getAttribute("name")]);this.tokens.bind(this),[this,...this.selectAll("*")].map(this.register,this),super.onidle&&super.onidle()}},Element=(e=>{const t=(e,t)=>n=>window.customElements.define(e+"",Custom(n),{constructor:t});return t.prototype=e.prototype,t})(window.Element);<commit_msg>:muscle: bump ??? distribution dist/snuggsi.min.es.js<commit_after>const HTMLElement=(e=>{function t(){}return t.prototype=window.HTMLElement.prototype,t})();class TokenList{constructor(e,t){const n=[],s=/{(\w+|#)}/,o=e=>[].slice.call(e).map(e=>s.test(e.value)&&n.push(e)),r=document.createNodeIterator(e,NodeFilter.SHOW_ELEMENT|NodeFilter.SHOW_TEXT,e=>e.tagName?o(e.attributes):s.test(e.textContent)&&n.push(e),null);for(;r.nextNode(););for(e of n)(e.text=e.textContent).match(/[^{]+(?=})/g).map(t=>(this[t]||(this[t]=[])).push(e))}bind(e){Object.keys(this).map(e=>this[e].map(e=>e.textContent=e.text)&&e).map(t=>this[t].map(n=>n.textContent=n.textContent.split("{"+t+"}").join(e[t])))}}(e=>{function t(e,t,n){for(n of this.querySelectorAll("[slot]"))(e.content||e).querySelector("slot[name="+n.getAttribute("slot")+"]").outerHTML=n.outerHTML;this.innerHTML=e.innerHTML}const n=new XMLHttpRequest;for(let s of document.querySelectorAll('link[id*="-"]'))n.open("GET",s.href),n.responseType="document",n.onload=function(){const e=this.response.querySelectorAll.bind(this.response),n=this.link,s=n.nextSibling;for(let o of document.querySelectorAll(n.id))t.call(o,e("template")[0].cloneNode(!0));for(let t of e("style,link,script")){let e=t.getAttribute("as"),o=document.createElement(t.localName);["src","href","textContent","rel"].map(((e,t)=>n=>t[n]&&(e[n]=t[n]))(o,t)),"style"==e&&(o.rel="stylesheet"),n.parentNode.insertBefore(o,s),"script"==e&&(n.parentNode.insertBefore(document.createElement("script"),s).src=t.href)}},n.link=s,n.send()})();const Template=function(e){return e.length&&(e=document.querySelector("template[name="+e+"]")),e.hidden=!0,e.HTML=e.innerHTML,e.bind=function(e,t){const n=document.createElement("section");for(let s of this.dependents||[])s.parentNode.removeChild(s);n.innerHTML=[].concat(e).reduce((e,t,n)=>{let s=this.HTML;"object"!=typeof t&&(t={self:t}),t["#"]=n;for(let o in t)s=s.split("{"+o+"}").join(t[o]);return e+s},""),t=this.nextSibling;for(let s of this.dependents=[].slice.call(n.childNodes))this.parentNode.insertBefore(s,t)}.bind(e),e};!window.customElements&&(window.customElements={}),new class{constructor({define:e,get:t,whenDefined:n}=customElements){window.customElements.define=this._define(void 0).bind(this)}_define(e=(e=>{})){return(t,n)=>e.apply(window.customElements,this.register(t,n))}register(e,t){return(this[e]=t).localName=e,"loading"===document.readyState?document.addEventListener("DOMContentLoaded",this.queue(...arguments)):this.queue(...arguments)(),arguments}queue(e,t){return n=>[].slice.call(document.getElementsByTagName(e)).map(this.upgrade(t))}upgrade(e){return t=>Object.setPrototypeOf(t,e.prototype).connectedCallback&&t.connectedCallback()}swizzle(e,...t){}};const ParentNode=e=>class extends e{select(){return this.selectAll(...arguments)[0]}selectAll(e,...t){return e=[].concat(e),[].slice.call(this.querySelectorAll(t.reduce((t,n)=>t+n+e.shift(),e.shift())))}},EventTarget=e=>class extends e{on(e,t){this.addEventListener(e,this.renderable(t))}renderable(e){return t=>!1!==e.call(this,t)&&t.defaultPrevented||this.render()}},GlobalEventHandlers=e=>class extends e{onconnect(){return this.templates=this.selectAll("template[name]").map(Template),this.tokens=new TokenList(this),super.onconnect&&super.onconnect(),this}reflect(e){/^on/.test(e)&&e in HTMLElement.prototype&&this.on(e.substr(2),this[e])}register(e,t,n){for(let s of e.attributes)/^on/.test(n=s.name)&&(t=(/{\s*(\w+)/.exec(e[n])||[])[1])&&(e[n]=this.renderable(this[t]))}},Custom=e=>class extends(ParentNode(EventTarget(GlobalEventHandlers(e)))){connectedCallback(){this.context={},super.initialize&&super.initialize(),Object.getOwnPropertyNames(e.prototype).map(this.reflect,this),this.onconnect().render()}render(e){for(e of this.templates)e.bind(this[e.getAttribute("name")]);this.tokens.bind(this),[this,...this.selectAll("*")].map(this.register,this),super.onidle&&super.onidle()}},Element=(e=>{const t=(e,t)=>n=>window.customElements.define(e+"",Custom(n),{constructor:t});return t.prototype=e.prototype,t})(window.Element);<|endoftext|>


<commit_before>/*
    TinyMCE filebrowser implementation.
*/

(function($) {

    // Define the filebrowser plugin.
    $.cms.media = {}

    // Closes the filebrowser and sends the information back to the TinyMCE editor.
    $.cms.media.complete = function(permalink, title) {
        // Get the important values from TinyMCE.
        var win = tinyMCEPopup.getWindowArg("window");
        // Get the input from the opening window.
        var input = $("#" + tinyMCEPopup.getWindowArg("input"), win.document);
        input.attr("value", permalink);
        // Set the link dialogue values.
        $("#linktitle", win.document).attr("value", title);
        // Set the image dialogue values.
        if (typeof(win.ImageDialog) != "undefined") {
            if (win.ImageDialog.getImageData) {
                win.ImageDialog.getImageData();
            }
            if (win.ImageDialog.showPreviewImage) {
                win.ImageDialog.showPreviewImage(permalink);
            }
        }
        // Close the dialogue.
        tinyMCEPopup.close();
    }

    // Initializes the popup file browser.
    $.cms.media.initBrowser = function() {
        if (tinyMCEPopup.getWindowArg("tinymce_active")) {
            // Make the changelist links clickable and remove the original inline click listener.
            $("div#changelist tr.row1 a, div#changelist tr.row2 a").attr("onclick", null).click(function() {
                var img = $("img", this);
                var title = img.attr("title");
                var permalink = img.attr("cms:permalink");
                $.cms.media.complete(permalink, title)
                return false;
            });
            // Made the add link flagged for TinyMCE.
            $("a.addlink").attr("href", $("a.addlink").attr("href") + "&_tinymce=1");
        }
    }

    // Add in the filebrowser plugin to the rich text editor.
    $.fn.cms.htmlWidget.extensions.file_browser_callback = function(field_name, url, type, win) {
        var browserURL = "/admin/media/file/?pop=1";
        if (type == "image") {
            browserURL = browserURL + '&file__iregex=\x5C.(png|gif|jpg|jpeg)$';
        }
        if (type == "media") {
            browserURL = browserURL + '&file__iregex=\x5C.(swf|flv|m4a|mov|wmv)$';
        }
        tinyMCE.activeEditor.windowManager.open({
            file: browserURL,
            title: "Select file",
            width: 800,
            height: 600,
            resizable: "yes",
            inline: "yes",
            close_previous: "no",
            popup_css: false
        }, {
            window: win,
            input: field_name,
            tinymce_active: true
        });
        return false;
    }

}(django.jQuery));<commit_msg>Fix WYSIWYG popup var<commit_after>/*
    TinyMCE filebrowser implementation.
*/

(function($) {

    // Define the filebrowser plugin.
    $.cms.media = {}

    // Closes the filebrowser and sends the information back to the TinyMCE editor.
    $.cms.media.complete = function(permalink, title) {
        // Get the important values from TinyMCE.
        var win = tinyMCEPopup.getWindowArg("window");
        // Get the input from the opening window.
        var input = $("#" + tinyMCEPopup.getWindowArg("input"), win.document);
        input.attr("value", permalink);
        // Set the link dialogue values.
        $("#linktitle", win.document).attr("value", title);
        // Set the image dialogue values.
        if (typeof(win.ImageDialog) != "undefined") {
            if (win.ImageDialog.getImageData) {
                win.ImageDialog.getImageData();
            }
            if (win.ImageDialog.showPreviewImage) {
                win.ImageDialog.showPreviewImage(permalink);
            }
        }
        // Close the dialogue.
        tinyMCEPopup.close();
    }

    // Initializes the popup file browser.
    $.cms.media.initBrowser = function() {
        if (tinyMCEPopup.getWindowArg("tinymce_active")) {
            // Make the changelist links clickable and remove the original inline click listener.
            $("div#changelist tr.row1 a, div#changelist tr.row2 a").attr("onclick", null).click(function() {
                var img = $("img", this);
                var title = img.attr("title");
                var permalink = img.attr("cms:permalink");
                $.cms.media.complete(permalink, title)
                return false;
            });
            // Made the add link flagged for TinyMCE.
            $("a.addlink").attr("href", $("a.addlink").attr("href") + "&_tinymce=1");
        }
    }

    // Add in the filebrowser plugin to the rich text editor.
    $.fn.cms.htmlWidget.extensions.file_browser_callback = function(field_name, url, type, win) {
        var browserURL = "/admin/media/file/?_popup=1";
        if (type == "image") {
            browserURL = browserURL + '&file__iregex=\x5C.(png|gif|jpg|jpeg)$';
        }
        if (type == "media") {
            browserURL = browserURL + '&file__iregex=\x5C.(swf|flv|m4a|mov|wmv)$';
        }
        tinyMCE.activeEditor.windowManager.open({
            file: browserURL,
            title: "Select file",
            width: 800,
            height: 600,
            resizable: "yes",
            inline: "yes",
            close_previous: "no",
            popup_css: false
        }, {
            window: win,
            input: field_name,
            tinymce_active: true
        });
        return false;
    }

}(django.jQuery));
<|endoftext|>


<commit_before>'use strict';
var _ = require('lodash');
var P = require('bluebird');
var FilterParser = require('./filter-parser');

function ValueStatGetter(model, params, opts) {

  function getAggregateField() {
    // jshint sub: true
    return params['aggregate_field'] || '_id';
  }

  this.perform = function () {
    return new P(function (resolve, reject) {
      var query = model.aggregate();

      if (params.filters) {
        _.each(params.filters, function (filter) {
          query = new FilterParser(model, opts).perform(query, filter.field,
            filter.value, 'match');
        });
      }

      var sum = 1;
      if (params['aggregate_field']) {
        sum = '$' + params['aggregate_field'];
      }

      query
        .group({
          _id: null,
          total: { $sum: sum }
        })
        .exec(function (err, records) {
          if (err) { return reject(err); }
          resolve({ value: records[0].total });
        });
    });
  };
}

module.exports = ValueStatGetter;
<commit_msg>Fix the value stat getter when no records available<commit_after>'use strict';
var _ = require('lodash');
var P = require('bluebird');
var FilterParser = require('./filter-parser');

function ValueStatGetter(model, params, opts) {

  function getAggregateField() {
    // jshint sub: true
    return params['aggregate_field'] || '_id';
  }

  this.perform = function () {
    return new P(function (resolve, reject) {
      var query = model.aggregate();

      if (params.filters) {
        _.each(params.filters, function (filter) {
          query = new FilterParser(model, opts).perform(query, filter.field,
            filter.value, 'match');
        });
      }

      var sum = 1;
      if (params['aggregate_field']) {
        sum = '$' + params['aggregate_field'];
      }

      query
        .group({
          _id: null,
          total: { $sum: sum }
        })
        .exec(function (err, records) {
          if (err) { return reject(err); }
          if (!records || !records.length) { return resolve({ value: 0 }); }

          resolve({ value: records[0].total });
        });
    });
  };
}

module.exports = ValueStatGetter;
<|endoftext|>