<commit_before>function InputManager() {
    function initInputs(){
        $(document).keydown(function(ev) {
            handleKeyboard(ev);
        });

        $(document).keyup(function(ev) {
            handleKeyboard(ev);
        });

        $(document).mousedown(function(ev) {
            handleMouse(ev);
        });

        $(document).mouseup(function(ev) {
            handleMouse(ev);
        });

        $(document).mousemove(function(ev) {
            handleMouse(ev);
        });
    }

    function handleKeyboard(ev) {
        if (ev.type === "keydown") {
            keyboard[keyCodeToChar[ev.keyCode]] = true;
        } else if(ev.type === "keyup") {
            keyboard[keyCodeToChar[ev.keyCode]] = false;
        }
    }

    function handleMouse(ev) {
        if (ev.type === "mousedown") {
            mouse[buttonCodeToChar[ev.which]] = true;
        } else if (ev.type === "mouseup") {
            mouse[buttonCodeToChar[ev.which]] = false;
        }
        var canvas_off = canvas.offset();
        mouse.UpdatePosition(ev.clientX - canvas_off.left, ev.clientY - canvas_off.top);
        processMouse();
    }

    function processInputs() {
        game.stateMap[game.currentState].keyboard(keyboard);
        game.stateMap[game.currentState].mouse(mouse);
    }

    function processMouse() {
        game.stateMap[game.currentState].mouse(mouse);
    }

    function processKeyboard() {
        game.stateMap[game.currentState].keyboard(keyboard);
    }

    initInputs();

    keyboard = new Keyboard();
    mouse = new Mouse();

    this.processInputs = function() {
        processInputs();
    }

    this.processMouse = function() {
        processMouse();
    }

    this.processKeyboard = function() {
        processKeyboard();
    }
}

function handleCameraKeyboard(keyboard) {
    var camMove = {'x': 0, 'y': 0};
    if (keyboard.KeyDown("Left")) {
        camMove['x'] -= 5;
    }
    if (keyboard.KeyDown("Right")) {
        camMove['x'] += 5;
    }
    if (keyboard.KeyDown("Up")) {
        camMove['y'] -= 5;
    }
    if (keyboard.KeyDown("Down")) {
        camMove['y'] += 5;
    }
    camera.processMove(camMove);
}

function handleCameraMouse(mouse) {
    if (mouse.currentState == mouseStates.LeftDrag) {
        var camMove = {'x': mouse.dx, 'y': mouse.dy};
        mouse.dx = 0;
        mouse.dy = 0;
        camera.processMove(camMove);
    } else if(mouse.lastState == mouseStates.LeftDown &&
              mouse.currentState == mouseStates.LeftUp) {
        sprites["selector"].resetCurrentFrame();
        var wp = camera.transformToWorldSpace(mouse.x, mouse.y);
        if (game.world.withinWorld(wp.world_x, wp.world_y)) {
            game.selectWorld(wp.world_x, wp.world_y);
            var selectedUnit = game.world.findUnit(wp.world_x, wp.world_y);
            var selectedCell = game.world.getCell(wp.world_x, wp.world_y);
            if (selectedUnit) {
                game.currentState = "UNIT_CONTROL";
                unitControlState.unit = selectedUnit;
            } else {
                game.currentState = "CAMERA_CONTROL";
                unitControlState.unit = null;
            }
        }
    }
}

var unitControlState = {
    unit: null,
    moving: false,
    moves: null,
    attacks: null,
    path: null
}

function handleUnitKeyboard(keyboard) {
    if (keyboard.KeyDown("M")) {
        unitControlState.moving = true;
        unitControlState.moves = game.world.findAvailableMoves(unitControlState.unit);
        if (unitControlState.moving && unitControlState.path != null) {
            network.sendUnitMove(unitControlState.unit, unitControlState.path);
            keyboard["M"] = false;
        }
        console.log("M");
    } else if (keyboard.KeyDown("A")) {
        unitControlState.attacks = game.world.findAvailableAttacks(unitControlState.unit);
        console.log("A");
    } else if (keyboard.KeyDown("Esc")) {
        unitControlState.moving = false;
        unitControlState.moves = null;
        unitControlState.attacks = null;
        unitControlState.path = null;
        specialRenderer.removeLayer("moves");
        specialRenderer.removeLayer("path");
        specialRenderer.removeLayer("attacks");
    }
}

function handleUnitMouse(mouse) {
    if (!unitControlState.moving) {
        handleCameraMouse(mouse);
    } else {
        if (mouse.lastState == mouseStates.LeftDown &&
            mouse.currentState == mouseStates.LeftUp) {
            var wp = camera.transformToWorldSpace(mouse.x, mouse.y);
            if (game.world.withinWorld(wp.world_x, wp.world_y)) {
                game.selectWorld(wp.world_x, wp.world_y);
                var goal = game.world.getCell(wp.world_x, wp.world_y);
                var path = routePath(unitControlState.unit, goal.position);
                unitControlState.path = path;
            }
        }
    }
}
<commit_msg>Remove silly debug things<commit_after>function InputManager() {
    function initInputs(){
        $(document).keydown(function(ev) {
            handleKeyboard(ev);
        });

        $(document).keyup(function(ev) {
            handleKeyboard(ev);
        });

        $(document).mousedown(function(ev) {
            handleMouse(ev);
        });

        $(document).mouseup(function(ev) {
            handleMouse(ev);
        });

        $(document).mousemove(function(ev) {
            handleMouse(ev);
        });
    }

    function handleKeyboard(ev) {
        if (ev.type === "keydown") {
            keyboard[keyCodeToChar[ev.keyCode]] = true;
        } else if(ev.type === "keyup") {
            keyboard[keyCodeToChar[ev.keyCode]] = false;
        }
    }

    function handleMouse(ev) {
        if (ev.type === "mousedown") {
            mouse[buttonCodeToChar[ev.which]] = true;
        } else if (ev.type === "mouseup") {
            mouse[buttonCodeToChar[ev.which]] = false;
        }
        var canvas_off = canvas.offset();
        mouse.UpdatePosition(ev.clientX - canvas_off.left, ev.clientY - canvas_off.top);
        processMouse();
    }

    function processInputs() {
        game.stateMap[game.currentState].keyboard(keyboard);
        game.stateMap[game.currentState].mouse(mouse);
    }

    function processMouse() {
        game.stateMap[game.currentState].mouse(mouse);
    }

    function processKeyboard() {
        game.stateMap[game.currentState].keyboard(keyboard);
    }

    initInputs();

    keyboard = new Keyboard();
    mouse = new Mouse();

    this.processInputs = function() {
        processInputs();
    }

    this.processMouse = function() {
        processMouse();
    }

    this.processKeyboard = function() {
        processKeyboard();
    }
}

function handleCameraKeyboard(keyboard) {
    var camMove = {'x': 0, 'y': 0};
    if (keyboard.KeyDown("Left")) {
        camMove['x'] -= 5;
    }
    if (keyboard.KeyDown("Right")) {
        camMove['x'] += 5;
    }
    if (keyboard.KeyDown("Up")) {
        camMove['y'] -= 5;
    }
    if (keyboard.KeyDown("Down")) {
        camMove['y'] += 5;
    }
    camera.processMove(camMove);
}

function handleCameraMouse(mouse) {
    if (mouse.currentState == mouseStates.LeftDrag) {
        var camMove = {'x': mouse.dx, 'y': mouse.dy};
        mouse.dx = 0;
        mouse.dy = 0;
        camera.processMove(camMove);
    } else if(mouse.lastState == mouseStates.LeftDown &&
              mouse.currentState == mouseStates.LeftUp) {
        sprites["selector"].resetCurrentFrame();
        var wp = camera.transformToWorldSpace(mouse.x, mouse.y);
        if (game.world.withinWorld(wp.world_x, wp.world_y)) {
            game.selectWorld(wp.world_x, wp.world_y);
            var selectedUnit = game.world.findUnit(wp.world_x, wp.world_y);
            var selectedCell = game.world.getCell(wp.world_x, wp.world_y);
            if (selectedUnit) {
                game.currentState = "UNIT_CONTROL";
                unitControlState.unit = selectedUnit;
            } else {
                game.currentState = "CAMERA_CONTROL";
                unitControlState.unit = null;
            }
        }
    }
}

var unitControlState = {
    unit: null,
    moving: false,
    moves: null,
    attacks: null,
    path: null
}

function handleUnitKeyboard(keyboard) {
    if (keyboard.KeyDown("M")) {
        unitControlState.moving = true;
        unitControlState.moves = game.world.findAvailableMoves(unitControlState.unit);
        if (unitControlState.moving && unitControlState.path != null) {
            network.sendUnitMove(unitControlState.unit, unitControlState.path);
            keyboard["M"] = false;
        }
    } else if (keyboard.KeyDown("A")) {
        unitControlState.attacks = game.world.findAvailableAttacks(unitControlState.unit);
    } else if (keyboard.KeyDown("Esc")) {
        unitControlState.moving = false;
        unitControlState.moves = null;
        unitControlState.attacks = null;
        unitControlState.path = null;
        specialRenderer.removeLayer("moves");
        specialRenderer.removeLayer("path");
        specialRenderer.removeLayer("attacks");
    }
}

function handleUnitMouse(mouse) {
    if (!unitControlState.moving) {
        handleCameraMouse(mouse);
    } else {
        if (mouse.lastState == mouseStates.LeftDown &&
            mouse.currentState == mouseStates.LeftUp) {
            var wp = camera.transformToWorldSpace(mouse.x, mouse.y);
            if (game.world.withinWorld(wp.world_x, wp.world_y)) {
                game.selectWorld(wp.world_x, wp.world_y);
                var goal = game.world.getCell(wp.world_x, wp.world_y);
                var path = routePath(unitControlState.unit, goal.position);
                unitControlState.path = path;
            }
        }
    }
}
<|endoftext|>


<commit_before>/* global angular */
'use strict';

var chai = require('chai')
  , sinon = require('sinon')
  , sinonChai = require('sinon-chai')
  , mockResponse = require('traverson-mock-response')()
  , waitFor = require('poll-forever')
  , assert = chai.assert
  , expect = chai.expect
  , traversonAngular = require('./angular_test_helper');

chai.use(sinonChai);

/*
 * Tests for all of Json Walker's request methods except getResource, which is
 * tested extensively in json_get_resource.js. This test suite contains tests
 * for get, post, put, delete and patch. Each http method verb has it's own
 * describe-section. Since most of the code path is the same for getResource
 * and get, post, ..., there are just a few basic tests here for each verb.
 * The getResource tests are more comprehensive.
 */
describe('The JSON client\'s', function() {

  var get;
  var post;
  var put;
  var patch;
  var del;

  var successCallback;
  var errorCallback;

  var rootUri = 'http://api.io';
  var api = traversonAngular.from(rootUri).json();

  var getUri = rootUri + '/link/to/resource';
  var postUri = rootUri + '/post/something/here';
  var putUri = rootUri + '/put/something/here';
  var patchUri = rootUri + '/patch/me';
  var deleteUri = rootUri + '/delete/me';
  var templateUri = rootUri + '/template/{param}';

  var rootResponse = mockResponse({
    'get_link': getUri,
    'post_link': postUri,
    'put_link': putUri,
    'patch_link': patchUri,
    'delete_link': deleteUri,
    'template_link': templateUri
  });

  var result = mockResponse({ result: 'success' });

  var payload = {
    some: 'stuff',
    data: 4711
  };

  beforeEach(function() {
    get = sinon.stub();
    post = sinon.stub();
    put = sinon.stub();
    patch = sinon.stub();
    del = sinon.stub();
    api.requestModuleInstance = {
      get: get,
      post: post,
      put: put,
      patch: patch,
      del: del,
    };
    successCallback = sinon.spy();
    errorCallback = sinon.spy();

    get
    .withArgs(rootUri, {}, sinon.match.func)
    .callsArgWithAsync(2, null, rootResponse, rootResponse.body);
    get
    .withArgs(getUri, {}, sinon.match.func)
    .callsArgWithAsync(2, null, result, result.body);
    get
    .withArgs(postUri, {}, sinon.match.func)
    .callsArgWithAsync(2,
        new Error('GET is not implemented for this URL, please POST ' +
        'something'));
  });

  describe('get method', function() {

    it('should follow the links', function(done) {
      api
      .newRequest()
      .follow('get_link')
      .get()
      .then(successCallback, errorCallback);

      waitFor(
        function() { return successCallback.called; },
        function() {
          expect(successCallback).to.have.been.calledWith(result);
          expect(errorCallback).to.not.have.been.called;
          done();
        }
      );
    });

    it('should call errorCallback with err', function(done) {
      var err = new Error('test error');
      // Default stubbing from beforeEach is not what we want here.
      // IMO, get.reset() should be enough, but isnt?
      get = sinon.stub();
      api.requestModuleInstance = { get: get };
      get.callsArgWithAsync(2, err);

      api
      .newRequest()
      .get()
      .then(successCallback, errorCallback);

      waitFor(
        function() { return errorCallback.called; },
        function() {
          expect(successCallback).to.not.have.been.called;
          expect(errorCallback).to.have.been.calledWith(err);
          done();
        }
      );
    });

    it('should call errorCallback with err when walking along the links fails',
        function(done) {
      var err = new Error('test error');
      // Default stubbing from beforeEach is not what we want here.
      // IMO, get.reset() should be enough, but isnt?
      get = sinon.stub();
      api.requestModuleInstance = { get: get };
      get
      .withArgs(rootUri, {}, sinon.match.func)
      .callsArgWithAsync(2, null, rootResponse);
      get
      .withArgs(getUri, {}, sinon.match.func)
      .callsArgWithAsync(2, err);

      api
      .newRequest()
      .follow('get_link', 'another_link')
      .get()
      .then(successCallback, errorCallback);

      waitFor(
        function() { return errorCallback.called; },
        function() {
          expect(successCallback).to.not.have.been.called;
          expect(errorCallback).to.have.been.calledWith(err);
          done();
        }
      );
    });

  });

  describe('getUrl method', function() {

    it('should follow the links and yield the last URL', function(done) {
      api
      .newRequest()
      .follow('get_link')
      .getUrl()
      .then(successCallback, errorCallback);

      waitFor(
        function() { return successCallback.called; },
        function() {
          expect(successCallback).to.have.been.calledWith(getUri);
          expect(errorCallback).to.not.have.been.called;
          expect(get.callCount).to.equal(1);
          done();
        }
      );
    });

    it('should yield resolved URL if last URL is a URI template',
        function(done) {
      api
      .newRequest()
      .follow('template_link')
      .withTemplateParameters({ param: 'substituted' })
      .getUrl()
      .then(successCallback, errorCallback);

      waitFor(
        function() { return successCallback.called; },
        function() {
          expect(successCallback).to.have.been.calledWith(
              rootUri + '/template/substituted');
          expect(errorCallback).to.not.have.been.called;
          expect(get.callCount).to.equal(1);
          done();
        }
      );
    });
  });

  describe('post method', function() {

    var result = mockResponse({ result: 'success' }, 201);

    it('should follow the links and post to the last URL',
        function(done) {
      post
      .withArgs(postUri, sinon.match.object, sinon.match.func)
      .callsArgWithAsync(2, null, result);

      api
      .newRequest()
      .follow('post_link')
      .post(payload)
      .then(successCallback, errorCallback);

      waitFor(
        function() { return successCallback.called; },
        function() {
          expect(errorCallback).to.not.have.been.called;
          expect(successCallback).to.have.been.calledWith(result);
          expect(post.firstCall.args[1].body).to.exist;
          expect(post.firstCall.args[1].body).to.contain(payload.some);
          expect(post.firstCall.args[1].body).to.contain(payload.data);
          done();
        }
      );
    });

    it('should call errorCallback with err when post fails',
        function(done) {
      var err = new Error('test error');
      post
      .withArgs(postUri, sinon.match.object, sinon.match.func)
      .callsArgWithAsync(2, err);

      api
      .newRequest()
      .follow('post_link')
      .post(payload)
      .then(successCallback, errorCallback);

      waitFor(
        function() { return errorCallback.called; },
        function() {
          expect(errorCallback).to.have.been.calledWith(err);
          expect(successCallback).to.not.have.been.called;
          done();
        }
      );
    });

  });

  describe('put method', function() {

    var result = mockResponse({ result: 'success' }, 200);

    it('should follow the links and put to the last URL',
        function(done) {
      put
      .withArgs(putUri, sinon.match.object, sinon.match.func)
      .callsArgWithAsync(2, null, result);

      api
      .newRequest()
      .follow('put_link')
      .put(payload)
      .then(successCallback, errorCallback);

      waitFor(
        function() { return successCallback.called; },
        function() {
          expect(successCallback).to.have.been.calledWith(result);
          expect(errorCallback).to.not.have.been.called;
          expect(put.firstCall.args[1].body).to.exist;
          expect(put.firstCall.args[1].body).to.contain(payload.some);
          expect(put.firstCall.args[1].body).to.contain(payload.data);
          done();
        }
      );
    });

    it('should call errorCallback with err when put fails',
        function(done) {
      var err = new Error('test error');
      put
      .withArgs(putUri, sinon.match.object, sinon.match.func)
      .callsArgWithAsync(2, err);

      api
      .newRequest()
      .follow('put_link')
      .put(payload)
      .then(successCallback, errorCallback);

      waitFor(
        function() { return errorCallback.called; },
        function() {
          expect(errorCallback).to.have.been.calledWith(err);
          expect(successCallback).to.not.have.been.called;
          done();
        }
      );
    });
  });

  describe('patch method', function() {

    var result = mockResponse({ result: 'success' }, 200);

    it('should follow the links and patch the last URL',
        function(done) {
      patch
      .withArgs(patchUri, sinon.match.object, sinon.match.func)
      .callsArgWithAsync(2, null, result);

      api
      .newRequest()
      .follow('patch_link')
      .patch(payload)
      .then(successCallback, errorCallback);

      waitFor(
        function() { return successCallback.called; },
        function() {
          expect(successCallback).to.have.been.calledWith(result);
          expect(errorCallback).to.not.have.been.called;
          expect(patch.firstCall.args[1].body).to.exist;
          expect(patch.firstCall.args[1].body).to.contain(payload.some);
          expect(patch.firstCall.args[1].body).to.contain(payload.data);
          done();
        }
      );
    });

    it('should call errorCallback with err when patch fails',
        function(done) {
      var err = new Error('test error');
      patch
      .withArgs(patchUri, sinon.match.object, sinon.match.func)
      .callsArgWithAsync(2, err);

      api
      .newRequest()
      .follow('patch_link')
      .patch(payload)
      .then(successCallback, errorCallback);

      waitFor(
        function() { return errorCallback.called; },
        function() {
          expect(errorCallback).to.have.been.calledWith(err);
          expect(successCallback).to.not.have.been.called;
          done();
        }
      );
    });
  });

  describe('delete method', function() {

    var result = mockResponse(null, 204);

    it('should follow the links and delete the last URL',
        function(done) {
      del
      .withArgs(deleteUri, sinon.match.object, sinon.match.func)
      .callsArgWithAsync(2, null, result);

      api
      .newRequest()
      .follow('delete_link')
      .delete()
      .then(successCallback, errorCallback);

      waitFor(
        function() { return successCallback.called; },
        function() {
          expect(successCallback).to.have.been.calledWith(result);
          expect(errorCallback).to.not.have.been.called;
          done();
        }
      );
    });

    it('should call errorCallback with err when deleting fails',
        function(done) {
      var err = new Error('test error');
      del
      .withArgs(deleteUri, sinon.match.object, sinon.match.func)
      .callsArgWithAsync(2, err);

      api
      .newRequest()
      .follow('delete_link')
      .del()
      .then(successCallback, errorCallback);

      waitFor(
        function() { return errorCallback.called; },
        function() {
          expect(errorCallback).to.have.been.calledWith(err);
          expect(successCallback).to.not.have.been.called;
          done();
        }
      );
    });
  });
});
<commit_msg>remove usage of deprecated API<commit_after>/* global angular */
'use strict';

var chai = require('chai')
  , sinon = require('sinon')
  , sinonChai = require('sinon-chai')
  , mockResponse = require('traverson-mock-response')()
  , waitFor = require('poll-forever')
  , assert = chai.assert
  , expect = chai.expect
  , traversonAngular = require('./angular_test_helper');

chai.use(sinonChai);

/*
 * Tests for all of Json Walker's request methods except getResource, which is
 * tested extensively in json_get_resource.js. This test suite contains tests
 * for get, post, put, delete and patch. Each http method verb has it's own
 * describe-section. Since most of the code path is the same for getResource
 * and get, post, ..., there are just a few basic tests here for each verb.
 * The getResource tests are more comprehensive.
 */
describe('The JSON client\'s', function() {

  var get;
  var post;
  var put;
  var patch;
  var del;

  var successCallback;
  var errorCallback;

  var rootUri = 'http://api.io';
  var api = traversonAngular.from(rootUri).json();

  var getUri = rootUri + '/link/to/resource';
  var postUri = rootUri + '/post/something/here';
  var putUri = rootUri + '/put/something/here';
  var patchUri = rootUri + '/patch/me';
  var deleteUri = rootUri + '/delete/me';
  var templateUri = rootUri + '/template/{param}';

  var rootResponse = mockResponse({
    'get_link': getUri,
    'post_link': postUri,
    'put_link': putUri,
    'patch_link': patchUri,
    'delete_link': deleteUri,
    'template_link': templateUri
  });

  var result = mockResponse({ result: 'success' });

  var payload = {
    some: 'stuff',
    data: 4711
  };

  beforeEach(function() {
    get = sinon.stub();
    post = sinon.stub();
    put = sinon.stub();
    patch = sinon.stub();
    del = sinon.stub();
    api.requestModuleInstance = {
      get: get,
      post: post,
      put: put,
      patch: patch,
      del: del,
    };
    successCallback = sinon.spy();
    errorCallback = sinon.spy();

    get
    .withArgs(rootUri, {}, sinon.match.func)
    .callsArgWithAsync(2, null, rootResponse, rootResponse.body);
    get
    .withArgs(getUri, {}, sinon.match.func)
    .callsArgWithAsync(2, null, result, result.body);
    get
    .withArgs(postUri, {}, sinon.match.func)
    .callsArgWithAsync(2,
        new Error('GET is not implemented for this URL, please POST ' +
        'something'));
  });

  describe('get method', function() {

    it('should follow the links', function(done) {
      api
      .newRequest()
      .follow('get_link')
      .get()
      .result
      .then(successCallback, errorCallback);

      waitFor(
        function() { return successCallback.called; },
        function() {
          expect(successCallback).to.have.been.calledWith(result);
          expect(errorCallback).to.not.have.been.called;
          done();
        }
      );
    });

    it('should call errorCallback with err', function(done) {
      var err = new Error('test error');
      // Default stubbing from beforeEach is not what we want here.
      // IMO, get.reset() should be enough, but isnt?
      get = sinon.stub();
      api.requestModuleInstance = { get: get };
      get.callsArgWithAsync(2, err);

      api
      .newRequest()
      .get()
      .result
      .then(successCallback, errorCallback);

      waitFor(
        function() { return errorCallback.called; },
        function() {
          expect(successCallback).to.not.have.been.called;
          expect(errorCallback).to.have.been.calledWith(err);
          done();
        }
      );
    });

    it('should call errorCallback with err when walking along the links fails',
        function(done) {
      var err = new Error('test error');
      // Default stubbing from beforeEach is not what we want here.
      // IMO, get.reset() should be enough, but isnt?
      get = sinon.stub();
      api.requestModuleInstance = { get: get };
      get
      .withArgs(rootUri, {}, sinon.match.func)
      .callsArgWithAsync(2, null, rootResponse);
      get
      .withArgs(getUri, {}, sinon.match.func)
      .callsArgWithAsync(2, err);

      api
      .newRequest()
      .follow('get_link', 'another_link')
      .get()
      .result
      .then(successCallback, errorCallback);

      waitFor(
        function() { return errorCallback.called; },
        function() {
          expect(successCallback).to.not.have.been.called;
          expect(errorCallback).to.have.been.calledWith(err);
          done();
        }
      );
    });

  });

  describe('getUrl method', function() {

    it('should follow the links and yield the last URL', function(done) {
      api
      .newRequest()
      .follow('get_link')
      .getUrl()
      .result
      .then(successCallback, errorCallback);

      waitFor(
        function() { return successCallback.called; },
        function() {
          expect(successCallback).to.have.been.calledWith(getUri);
          expect(errorCallback).to.not.have.been.called;
          expect(get.callCount).to.equal(1);
          done();
        }
      );
    });

    it('should yield resolved URL if last URL is a URI template',
        function(done) {
      api
      .newRequest()
      .follow('template_link')
      .withTemplateParameters({ param: 'substituted' })
      .getUrl()
      .result
      .then(successCallback, errorCallback);

      waitFor(
        function() { return successCallback.called; },
        function() {
          expect(successCallback).to.have.been.calledWith(
              rootUri + '/template/substituted');
          expect(errorCallback).to.not.have.been.called;
          expect(get.callCount).to.equal(1);
          done();
        }
      );
    });
  });

  describe('post method', function() {

    var result = mockResponse({ result: 'success' }, 201);

    it('should follow the links and post to the last URL',
        function(done) {
      post
      .withArgs(postUri, sinon.match.object, sinon.match.func)
      .callsArgWithAsync(2, null, result);

      api
      .newRequest()
      .follow('post_link')
      .post(payload)
      .result
      .then(successCallback, errorCallback);

      waitFor(
        function() { return successCallback.called; },
        function() {
          expect(errorCallback).to.not.have.been.called;
          expect(successCallback).to.have.been.calledWith(result);
          expect(post.firstCall.args[1].body).to.exist;
          expect(post.firstCall.args[1].body).to.contain(payload.some);
          expect(post.firstCall.args[1].body).to.contain(payload.data);
          done();
        }
      );
    });

    it('should call errorCallback with err when post fails',
        function(done) {
      var err = new Error('test error');
      post
      .withArgs(postUri, sinon.match.object, sinon.match.func)
      .callsArgWithAsync(2, err);

      api
      .newRequest()
      .follow('post_link')
      .post(payload)
      .result
      .then(successCallback, errorCallback);

      waitFor(
        function() { return errorCallback.called; },
        function() {
          expect(errorCallback).to.have.been.calledWith(err);
          expect(successCallback).to.not.have.been.called;
          done();
        }
      );
    });

  });

  describe('put method', function() {

    var result = mockResponse({ result: 'success' }, 200);

    it('should follow the links and put to the last URL',
        function(done) {
      put
      .withArgs(putUri, sinon.match.object, sinon.match.func)
      .callsArgWithAsync(2, null, result);

      api
      .newRequest()
      .follow('put_link')
      .put(payload)
      .result
      .then(successCallback, errorCallback);

      waitFor(
        function() { return successCallback.called; },
        function() {
          expect(successCallback).to.have.been.calledWith(result);
          expect(errorCallback).to.not.have.been.called;
          expect(put.firstCall.args[1].body).to.exist;
          expect(put.firstCall.args[1].body).to.contain(payload.some);
          expect(put.firstCall.args[1].body).to.contain(payload.data);
          done();
        }
      );
    });

    it('should call errorCallback with err when put fails',
        function(done) {
      var err = new Error('test error');
      put
      .withArgs(putUri, sinon.match.object, sinon.match.func)
      .callsArgWithAsync(2, err);

      api
      .newRequest()
      .follow('put_link')
      .put(payload)
      .result
      .then(successCallback, errorCallback);

      waitFor(
        function() { return errorCallback.called; },
        function() {
          expect(errorCallback).to.have.been.calledWith(err);
          expect(successCallback).to.not.have.been.called;
          done();
        }
      );
    });
  });

  describe('patch method', function() {

    var result = mockResponse({ result: 'success' }, 200);

    it('should follow the links and patch the last URL',
        function(done) {
      patch
      .withArgs(patchUri, sinon.match.object, sinon.match.func)
      .callsArgWithAsync(2, null, result);

      api
      .newRequest()
      .follow('patch_link')
      .patch(payload)
      .result
      .then(successCallback, errorCallback);

      waitFor(
        function() { return successCallback.called; },
        function() {
          expect(successCallback).to.have.been.calledWith(result);
          expect(errorCallback).to.not.have.been.called;
          expect(patch.firstCall.args[1].body).to.exist;
          expect(patch.firstCall.args[1].body).to.contain(payload.some);
          expect(patch.firstCall.args[1].body).to.contain(payload.data);
          done();
        }
      );
    });

    it('should call errorCallback with err when patch fails',
        function(done) {
      var err = new Error('test error');
      patch
      .withArgs(patchUri, sinon.match.object, sinon.match.func)
      .callsArgWithAsync(2, err);

      api
      .newRequest()
      .follow('patch_link')
      .patch(payload)
      .result
      .then(successCallback, errorCallback);

      waitFor(
        function() { return errorCallback.called; },
        function() {
          expect(errorCallback).to.have.been.calledWith(err);
          expect(successCallback).to.not.have.been.called;
          done();
        }
      );
    });
  });

  describe('delete method', function() {

    var result = mockResponse(null, 204);

    it('should follow the links and delete the last URL',
        function(done) {
      del
      .withArgs(deleteUri, sinon.match.object, sinon.match.func)
      .callsArgWithAsync(2, null, result);

      api
      .newRequest()
      .follow('delete_link')
      .delete()
      .result
      .then(successCallback, errorCallback);

      waitFor(
        function() { return successCallback.called; },
        function() {
          expect(successCallback).to.have.been.calledWith(result);
          expect(errorCallback).to.not.have.been.called;
          done();
        }
      );
    });

    it('should call errorCallback with err when deleting fails',
        function(done) {
      var err = new Error('test error');
      del
      .withArgs(deleteUri, sinon.match.object, sinon.match.func)
      .callsArgWithAsync(2, err);

      api
      .newRequest()
      .follow('delete_link')
      .del()
      .result
      .then(successCallback, errorCallback);

      waitFor(
        function() { return errorCallback.called; },
        function() {
          expect(errorCallback).to.have.been.calledWith(err);
          expect(successCallback).to.not.have.been.called;
          done();
        }
      );
    });
  });
});
<|endoftext|>


<commit_before>App.prototype._pieChart = function( votes ) {

  var width = 150,
      height = 150,
      radius = Math.min(width, height) / 2;

  var color = d3.scale.ordinal()
      .range(["#A6A48B", "#938BA6", "#A0AED9", "#666556", "#FFB90A", "#d0743c", "#ff8c00"]);

  var arc = d3.svg.arc()
      .outerRadius(radius - 10)
      .innerRadius(0);

  var pie = d3.layout.pie()
      .sort(null)
      .value(function(d) { return d.count; });

  var svg = d3.select("#pie-chart-votes").append("svg")
      .attr("width", width)
      .attr("height", height)
    .append("g")
      .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

  var data = [];
  for ( var d in votes ) {
    if (votes[d] > 0) {
      var obj = {"type": d, "count": votes[d]};
      data.push(obj);
    }
  }

  data.forEach(function(d) {
    d.count = +d.count;
  });

  var g = svg.selectAll(".arc")
      .data(pie(data))
    .enter().append("g")
      .attr("class", "arc");

  g.append("path")
      .attr("d", arc)
      .style("fill", function(d) { return color(d.data.type); });

  g.append("text")
      .attr("transform", function(d) { return "translate(" + arc.centroid(d) + ")"; })
      .attr("dy", ".35em")
      .attr('class', 'pie-text')
      .style("text-anchor", "middle")
      .text(function(d) { return d.data.type; });

}

App.prototype._partyLinePie = function() {
  var self = this;

  var width = 150,
      height = 150,
      radius = Math.min(width, height) / 2;

  var color = d3.scale.ordinal()
      .range(["#938BA6", "#A6A48B", "#A0AED9", "#666556", "#FFB90A", "#d0743c", "#ff8c00"]);
  var arc = d3.svg.arc()
      .outerRadius(radius - 10)
      .innerRadius(0);

  var pie = d3.layout.pie()
      .sort(null)
      .value(function(d) { return d.count; });

  var svg = d3.select("#pie-chart-party-line").append("svg")
      .attr("width", width)
      .attr("height", height)
    .append("g")
      .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

  var data = [];
  for ( var d in this.partyLine ) {
    if (self.partyLine[d] > 0) {
      var obj = {"type": d, "count": self.partyLine[d]};
      data.push(obj);
    }
  }

  data.forEach(function(d) {
    d.count = +d.count;
  });

  var g = svg.selectAll(".arc")
      .data(pie(data))
    .enter().append("g")
      .attr("class", "arc");

  g.append("path")
      .attr("d", arc)
      .style("fill", function(d) { return color(d.data.type); });

  g.append("text")
      .attr("transform", function(d) { return "translate(" + arc.centroid(d) + ")"; })
      .attr("dy", ".35em")
      .attr('class', 'pie-text')
      .style("text-anchor", "middle")
      .text(function(d) { return d.data.type; });

}<commit_msg>another shot at better colors for the pie charts<commit_after>App.prototype._pieChart = function( votes ) {

  var width = 150,
      height = 150,
      radius = Math.min(width, height) / 2;

  var color = d3.scale.ordinal()
      .range(["#4DB8F6", "#2479A9", "#98D4F7", "#666556", "#FFB90A", "#d0743c", "#ff8c00"]);

  var arc = d3.svg.arc()
      .outerRadius(radius - 10)
      .innerRadius(0);

  var pie = d3.layout.pie()
      .sort(null)
      .value(function(d) { return d.count; });

  var svg = d3.select("#pie-chart-votes").append("svg")
      .attr("width", width)
      .attr("height", height)
    .append("g")
      .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

  var data = [];
  for ( var d in votes ) {
    if (votes[d] > 0) {
      var obj = {"type": d, "count": votes[d]};
      data.push(obj);
    }
  }

  data.forEach(function(d) {
    d.count = +d.count;
  });

  var g = svg.selectAll(".arc")
      .data(pie(data))
    .enter().append("g")
      .attr("class", "arc");

  g.append("path")
      .attr("d", arc)
      .style("fill", function(d) { return color(d.data.type); });

  g.append("text")
      .attr("transform", function(d) { return "translate(" + arc.centroid(d) + ")"; })
      .attr("dy", ".35em")
      .attr('class', 'pie-text')
      .style("text-anchor", "middle")
      .text(function(d) { return d.data.type; });

}

App.prototype._partyLinePie = function() {
  var self = this;

  var width = 150,
      height = 150,
      radius = Math.min(width, height) / 2;

  var color = d3.scale.ordinal()
      .range(["#4DB8F6", "#2479A9", "#98D4F7", "#666556", "#FFB90A", "#d0743c", "#ff8c00"]);
  var arc = d3.svg.arc()
      .outerRadius(radius - 10)
      .innerRadius(0);

  var pie = d3.layout.pie()
      .sort(null)
      .value(function(d) { return d.count; });

  var svg = d3.select("#pie-chart-party-line").append("svg")
      .attr("width", width)
      .attr("height", height)
    .append("g")
      .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

  var data = [];
  for ( var d in this.partyLine ) {
    if (self.partyLine[d] > 0) {
      var obj = {"type": d, "count": self.partyLine[d]};
      data.push(obj);
    }
  }

  data.forEach(function(d) {
    d.count = +d.count;
  });

  var g = svg.selectAll(".arc")
      .data(pie(data))
    .enter().append("g")
      .attr("class", "arc");

  g.append("path")
      .attr("d", arc)
      .style("fill", function(d) { return color(d.data.type); });

  g.append("text")
      .attr("transform", function(d) { return "translate(" + arc.centroid(d) + ")"; })
      .attr("dy", ".35em")
      .attr('class', 'pie-text')
      .style("text-anchor", "middle")
      .text(function(d) { return d.data.type; });

}<|endoftext|>


<commit_before>jQuery(function($) {

	var body = $('body');

	/* ==========================================================================
	   Run Highlight
	   ========================================================================== */

		function highlight() {
			$('pre code').each(function(i, e) {
				hljs.highlightBlock(e)
			});
		}
		highlight();

	/* ==========================================================================
	   Fitvids by Chris Coyier
	   ========================================================================== */

		function video() {
			$('#wrapper').fitVids();
		}
		video();

	/* ==========================================================================
	   Add class for ajax loading
	   ========================================================================== */

		function ajaxLinkClass() {
			$('.post-meta a').each(function() {
				var link = $(this);
				if (link.attr('href').indexOf('tag') > -1) {
					link.addClass('js-tag-index js-ajax-link');
				} else if (link.attr('href').indexOf('author') > -1) {
					link.addClass('js-author-index js-ajax-link');
				}
			});
			$('.pagination a').each(function() {
				var link = $(this);
				if (link.attr('href').length < 2 ) {
					link.addClass('js-show-index js-ajax-link');
				} else {
					link.addClass('js-archive-index js-ajax-link');
				}
			});
		}
		ajaxLinkClass();

	/* ==========================================================================
	   Reload all scripts after AJAX load
	   ========================================================================== */

		function reload() {
			ajaxLinkClass();
			highlight();
			video();
		}

	/* ==========================================================================
	   Ajax Loading based on Ghostwriter by Rory Gibson - https://github.com/roryg/ghostwriter
	   ========================================================================== */

    var History = window.History;
    var loading = false;
    var ajaxContainer = $('#ajax-container');

    if (!History.enabled) {
    	return false;
    }
    History.Adapter.bind(window, 'statechange', function() {
        var State = History.getState();
        $.get(State.url, function(result) {
            var $html = $(result);
            var $newContent = $('#ajax-container', $html).contents();
            var title = result.match(/<title>(.*?)<\/title>/)[1];

            ajaxContainer.fadeOut(500, function() {
                document.title = title;
                ajaxContainer.html($newContent);
                ajaxContainer.fadeIn(500);
                NProgress.done();
                reload();
                loading = false;
            });
        });
    });
    $('body').on('click', '.js-ajax-link', function(e) {
        e.preventDefault();
        if (loading === false) {
            var currentState = History.getState();
            var url = $(this).prop('href');
            var title = $(this).attr('title') || null;

            if (url.replace(/\/$/, "") !== currentState.url.replace(/\/$/, "")) {
                loading = true;
                var link = $(this);
                if (link.hasClass('js-show-post')) {
                	body.removeClass();
					body.addClass('post-template');
				} else if(link.hasClass('js-show-page')) {
                	body.removeClass();
					body.addClass('page-template').addClass('post-template');
				} else if(link.hasClass('js-show-index')) {
                	body.removeClass();
					body.addClass('home-template');
				} else if(link.hasClass('js-tag-index')) {
                	body.removeClass();
					body.addClass('tag-template');
					var tag = link.attr('href').match(/\/tag\/([^\/]+)/)[1];
					body.addClass('tag-' + tag);
				} else if(link.hasClass('js-author-index')) {
                	body.removeClass();
					body.addClass('author-template');
					var author = link.attr('href').match(/\/author\/([^\/]+)/)[1];
					body.addClass('author-' + author);
				} else if(link.hasClass('js-archive-index')) {
                	body.removeClass();
					body.addClass('archive-template');
				}
                NProgress.start();

                History.pushState({}, title, url);
            }
        }
    });

});
<commit_msg>fixed body template class fuckup<commit_after>jQuery(function($) {

	var body = $('body');

	/* ==========================================================================
	   Run Highlight
	   ========================================================================== */

		function highlight() {
			$('pre code').each(function(i, e) {
				hljs.highlightBlock(e)
			});
		}
		highlight();

	/* ==========================================================================
	   Fitvids by Chris Coyier
	   ========================================================================== */

		function video() {
			$('#wrapper').fitVids();
		}
		video();

	/* ==========================================================================
	   Add class for ajax loading
	   ========================================================================== */

		function ajaxLinkClass() {
			$('.post-meta a').each(function() {
				var link = $(this);
				if (link.attr('href').indexOf('tag') > -1) {
					link.addClass('js-tag-index js-ajax-link');
				} else if (link.attr('href').indexOf('author') > -1) {
					link.addClass('js-author-index js-ajax-link');
				}
			});
			$('.pagination a').each(function() {
				var link = $(this);
				if (link.attr('href').indexOf('page') > -1 ) {
					link.addClass('js-archive-index js-ajax-link');
					if (link.attr('href').indexOf('tag') > -1) {
						link.addClass('js-tag-index');
					} else if (link.attr('href').indexOf('author') > -1) {
						link.addClass('js-author-index');
					}
				} else {
					link.addClass('js-show-index js-ajax-link');
					if (link.attr('href').indexOf('tag') > -1) {
						link.addClass('js-tag-index');
					} else if (link.attr('href').indexOf('author') > -1) {
						link.addClass('js-author-index');
					}
				}
			});
		}
		ajaxLinkClass();

	/* ==========================================================================
	   Reload all scripts after AJAX load
	   ========================================================================== */

		function reload() {
			ajaxLinkClass();
			highlight();
			video();
		}

	/* ==========================================================================
	   Ajax Loading based on Ghostwriter by Rory Gibson - https://github.com/roryg/ghostwriter
	   ========================================================================== */

    var History = window.History;
    var loading = false;
    var ajaxContainer = $('#ajax-container');

    if (!History.enabled) {
    	return false;
    }
    History.Adapter.bind(window, 'statechange', function() {
        var State = History.getState();
        $.get(State.url, function(result) {
            var $html = $(result);
            var $newContent = $('#ajax-container', $html).contents();
            var title = result.match(/<title>(.*?)<\/title>/)[1];

            ajaxContainer.fadeOut(500, function() {
                document.title = title;
                ajaxContainer.html($newContent);
                ajaxContainer.fadeIn(500);
                NProgress.done();
                reload();
                loading = false;
            });
        });
    });
    $('body').on('click', '.js-ajax-link', function(e) {
        e.preventDefault();
        if (loading === false) {
            var currentState = History.getState();
            var url = $(this).prop('href');
            var title = $(this).attr('title') || null;

            if (url.replace(/\/$/, "") !== currentState.url.replace(/\/$/, "")) {
                loading = true;
                var link = $(this);
                if (link.hasClass('js-show-post')) {

                	body.removeClass();
					body.addClass('post-template');

				} else if(link.hasClass('js-show-page')) {

                	body.removeClass();
					body.addClass('page-template').addClass('post-template');

				} else if(link.hasClass('js-tag-index')) {

                	body.removeClass();
					body.addClass('tag-template');
					var tag = link.attr('href').match(/\/tag\/([^\/]+)/)[1];
					body.addClass('tag-' + tag);

					if(link.hasClass('js-archive-index')) {
						body.addClass('paged archive-template');
					}

				} else if(link.hasClass('js-author-index')) {

                	body.removeClass();
					body.addClass('author-template');
					var author = link.attr('href').match(/\/author\/([^\/]+)/)[1];
					body.addClass('author-' + author);

					if(link.hasClass('js-archive-index')) {
						body.addClass('paged archive-template');
					}

				} else if(link.hasClass('js-archive-index')) {

                	body.removeClass();
					body.addClass('paged archive-template');

				} else if(link.hasClass('js-show-index')) {

                	body.removeClass();
					body.addClass('home-template');

				}
                NProgress.start();

                History.pushState({}, title, url);
            }
        }
    });

});
<|endoftext|>


<commit_before>/**
 * Main JS file for Casper behaviours
 */

/* globals jQuery, document */
(function ($, undefined) {
  "use strict";

  const TRIGGER_CLICK = 'click',
      TRIGGER_HOVER = 'hover',
      TRIGGER_AUTO = 'auto',
      TRIGGER_DEFAULT = TRIGGER_CLICK;

  class Ajax {
    static call (opts) {
      opts = opts || {};
      let params = opts.params || {},
        callback = opts.callback || new Function(),
        errCb = opts.err || new Function(),
        url = opts.url,
        method = opts.method || opts.type || 'GET';

      $.ajax({
        url: url,
        type: method,
        data: params
      }).done(callback).fail(errCb);
    }

    static parser (url) {
      url = url || this.url || '';
      let parser = document.createElement('a'),
          structure = {};
      parser.href = url;

      structure = {
        protocol: parser.protocol,
        hostname: parser.hostname,
        port: parser.port,
        pathname: parser.pathname,
        search: parser.search,
        hash: parser.hash,
        host: parser.host
      };

      return structure;
    }
  };

  class u {
    static rest (arr) {
      var clone = this.clone(arr, []);
      clone.splice(0, 1);
      return clone;
    };
    static clone (thing, extender) {
      extender = extender || {};
      return jQuery.extend(true, extender, thing);
    };
  };

  class J {
    constructor ($element, options) {
      if ($.isEmptyObject(options)) {

        if ($element.data('inline')) {
          options = $element.data('inline');
        }
        else {
          var args = $element.text().split(',');
          options = args[1] ? JSON.parse(u.rest(args).join(',')) || {} : {};
          options.body = args[0];
        }

      }

      options.$element =      $element || $("<div />");
      options.body =          options.body || $element.text();
      options.src =           options.src || $element.data('src') || $element.attr('href');
      options.autoplay =      options.autoplay || false;
      options.trigger =       options.trigger || TRIGGER_DEFAULT;

      this.config = options;
      this.$element = options.$element;
    };

    generate () {
      let config = this.config;

      if (config.src.match(/streamable/)) {
        this.handleStreamableMedia(config);
      }
      else if (config.src.match(/mp4/)) {
        this.handleVidFile(config);
      }
      else if (config.src.match(/gfycat/)) {
        this.handleGfyCat(config);
      }
      else if (config.src.match(/gifv/)) {
        this.handleImgur(config);
      }
      else if (config.src.match(/gif/)) {
        this.buildIMGWith(config);
      }
      else if (config.src.match(/jpg|jpeg|png/)) {
        this.buildIMGWith(config);
      }
      else if (config.src.match(/youtube/)) {
        this.handleYouTube(config);
      }
      else {
        console.log("JOE: Link doesn't have fun media.");
      }
    }

    // Various handlers
    handleStreamableMedia () {
      let uriArray = this.config.src.split('/'),
          streamableId = uriArray[uriArray.length - 1],
          src = '//streamable.com/res/' + streamableId,
          $element = this.$element;

      this.buildiFrame({
        $element: $element,
        width: '100%',
        src: src,
        scrolling: 'no'
      });
    };

    handleGfyCat () {
      let uriArray = this.config.src.split('/'),
          gfyCatDealie = uriArray[uriArray.length - 1],
          $element = this.$element,
          that = this,
          webmSrc, mp4Src;

      Ajax.call({
        url: '//gfycat.com/cajax/get/' + gfyCatDealie,
        method: 'GET',
        callback: function (response) {
          webmSrc = response.gfyItem.webmUrl;
          mp4Src = response.gfyItem.mp4Url;
          that.buildHTML5Video({
            $element: $element,
            wrapChildSources: true,
            webmSrc: webmSrc,
            mp4Src: mp4Src
          });
        },
        errCb: function () {
          console.log("Error: Failure to retrieve response for gfycat: ", gfyCatDealie);
        }
      });

    };

    handleYouTube () {
      let src = this.config.src,
          result = Ajax.parser(src),
          ytKey = result.search.split('=')[1],
          $element = this.$element;

      this.buildiFrame({
        $element: $element,
        src: '//youtube.com/embed/' + ytKey
      });
    };

    handleImgur (opts) {
      let $element = this.config.$element,
          arr = $element.data('src').split('.');
      arr.pop();
      let src = arr.join('.'),
          webmSrc = src + '.webm',
          mp4Src = src + '.mp4';

      this.buildHTML5Video({
        $element: $element,
        wrapChildSources: true,
        webmSrc: webmSrc,
        mp4Src: mp4Src
      });

    };

    handleVidFile () {
      this.buildHTML5Video(this.config);
    };

    // f()s that build html elments
    buildHTML5Video (opts) {
      opts = opts || {};
      let height = opts.height || 450,
          width = opts.width || '100%',
          $element = opts.$element || $('<div />'),
          src = opts.src || $element.data('src'),
          autoplay = opts.autoplay,
          //webmSrc = opts.webmSrc || (src + '.webm'),
          //mp4Src = opts.mp4Src || (src + '.mp4'),
          webmSrc = opts.webmSrc || false,
          mp4Src = opts.mp4Src || false,
          wrapChildSources = opts.wrapChildSources || false,
          $video = $('<video>', {
            height: height,
            width: width,
            loop: '',
            autoplay: autoplay,
            controls: '',
            muted: 'muted'
          }),
          webmID = opts.webmID || 'webmsource',
          mp4ID = opts.mp4ID || 'mp4source',
          $webmSource, $mp4Source;

      if (wrapChildSources) {
        if (webmSrc) {
          $webmSource = $('<source>', {
            id: webmID,
            src: webmSrc,
            type: 'video/webm'
          });
          $video.append($webmSource);
        }
        if (mp4Src) {
          $mp4Source = $('<source>', {
            id: mp4ID,
            src: mp4Src,
            type: 'video/mp4'
          });
          $video.append($mp4Source);
        }
      }
      else {
        $video.attr('src', src);
      }

      this.finishItUp($element, $video, this.config);
      return $element;
    };

    buildIMGWith ($element) {
      let $img = $('<img>', {
            src: $element.data('src'),
            width: "100%"
          });

      this.finishItUp($element, $img, this.config);
    };

    buildiFrame (opts) {
      opts = opts || {}
      let height = opts.height || 450,
          width = opts.width || 710,
          scrolling = opts.scrolling || 'no',
          $element = opts.$element || $('<div />'),
          src = opts.src || $element.data('src'),
          $iframe = $('<iframe>', {
            src: src,
            frameboarder: 0,
            height: height,
            width: width,
            scrolling: scrolling,
            allowfullscreen: ''
          });

      this.finishItUp($element, $iframe, this.config);

      return $element;
    };

    finishItUp ($element, $mediaElement, opts) {
      let trigger = opts.trigger;
      switch (opts.trigger) {
        case TRIGGER_CLICK:
          this.handleClick($element, $mediaElement);
        break;
        case TRIGGER_HOVER:
          this.handleHover($element, $mediaElement);
        break;
        case TRIGGER_AUTO:
          this.showMedia($element, $mediaElement);
        break;
      }

      if (opts.body) {
        $element.text(opts.body);
      }
    };

    // event handlers
    handleClick ($trigger, $ammo) {
      $trigger.on('click', e => {
        e.preventDefault();

        if ($ammo.is(':visible')) {
          $ammo.detach();
        }
        else {
          $ammo.appendTo($trigger);
        }
      });
    };

    handleHover ($trigger, $ammo) {
      $trigger.on('click', e => e.preventDefault());
      $trigger.on('mouseenter', e => {
        if (!$ammo.is(':visible')) {
          $ammo.appendTo($trigger);
        }
      });
      $trigger.on('mouseleave', e => {
        if ($ammo.is(':visible')) {
          $ammo.detach();
        }
      });
    };

    showMedia ($trigger, $ammo) {
      $ammo.appendTo($trigger);
    };

  };

  var $document = $(document),
      dealieArray = [];

  $document.ready(function () {
    checkInlineMedia();
    setArcticScroll();
  });

  var checkInlineMedia = function () {
    // $('a[data-inline]').each(function () {
    //   var $this = $(this),
    //       src = $this.data('src'),
    //       dealie = new J({
    //         $element: $this
    //       });

    //   dealieArray.push(dealie);
    // });

    $('a').each(function () {
      let $this = $(this),
          dealie = new J($this, {});

      dealie.generate();
      dealieArray.push(dealie);
    });
  };

  // Arctic Scroll Source
  var setArcticScroll = function () {
    var $postContent = $(".post-content");
    $postContent.fitVids();

    $(".scroll-down").arctic_scroll();

    $(".menu-button, .nav-cover, .nav-close").on("click", function(e){
      e.preventDefault();
      $("body").toggleClass("nav-opened nav-closed");
    });
  };
  // Arctic Scroll by Paul Adam Davis
  // https://github.com/PaulAdamDavis/Arctic-Scroll
  $.fn.arctic_scroll = function (options) {

    var defaults = {
      elem: $(this),
      speed: 500
    },

        allOptions = $.extend(defaults, options);

    allOptions.elem.click(function (event) {
      event.preventDefault();
      var $this = $(this),
          $htmlBody = $('html, body'),
          offset = ($this.attr('data-offset')) ? $this.attr('data-offset') : false,
          position = ($this.attr('data-position')) ? $this.attr('data-position') : false,
          toMove;

      if (offset) {
        toMove = parseInt(offset);
        $htmlBody.stop(true, false).animate({scrollTop: ($(this.hash).offset().top + toMove) }, allOptions.speed);
      } else if (position) {
        toMove = parseInt(position);
        $htmlBody.stop(true, false).animate({scrollTop: toMove }, allOptions.speed);
      } else {
        $htmlBody.stop(true, false).animate({scrollTop: ($(this.hash).offset().top) }, allOptions.speed);
      }
    });

  };

})(jQuery);
<commit_msg>fixing bugs<commit_after>/**
 * Main JS file for Casper behaviours
 */

/* globals jQuery, document */
(function ($, undefined) {
  "use strict";

  const TRIGGER_CLICK = 'click',
      TRIGGER_HOVER = 'hover',
      TRIGGER_AUTO = 'auto',
      TRIGGER_DEFAULT = TRIGGER_CLICK;

  class Ajax {
    static call (opts) {
      opts = opts || {};
      let params = opts.params || {},
        callback = opts.callback || new Function(),
        errCb = opts.err || new Function(),
        url = opts.url,
        method = opts.method || opts.type || 'GET';

      $.ajax({
        url: url,
        type: method,
        data: params
      }).done(callback).fail(errCb);
    }

    static parser (url) {
      url = url || this.url || '';
      let parser = document.createElement('a'),
          structure = {};
      parser.href = url;

      structure = {
        protocol: parser.protocol,
        hostname: parser.hostname,
        port: parser.port,
        pathname: parser.pathname,
        search: parser.search,
        hash: parser.hash,
        host: parser.host
      };

      return structure;
    }
  };

  class u {
    static rest (arr) {
      var clone = this.clone(arr, []);
      clone.splice(0, 1);
      return clone;
    };
    static clone (thing, extender) {
      extender = extender || {};
      return jQuery.extend(true, extender, thing);
    };
  };

  class J {
    constructor ($element, options) {
      if ($.isEmptyObject(options)) {

        if ($element.data('inline')) {
          options = $element.data('inline');
        }
        else {
          var args = $element.text().split(',');
          options = args[1] ? JSON.parse(u.rest(args).join(',')) || {} : {};
          options.body = args[0];
        }

      }

      options.$element =      $element || $("<div />");
      options.body =          options.body || $element.text();
      options.src =           options.src || $element.data('src') || $element.attr('href');
      options.autoplay =      options.autoplay || false;
      options.trigger =       options.trigger || TRIGGER_DEFAULT;

      this.config = options;
      this.$element = options.$element;
    };

    generate () {
      let config = this.config;

      if (config.src.match(/streamable/)) {
        this.handleStreamableMedia(config);
      }
      else if (config.src.match(/mp4/)) {
        this.handleVidFile(config);
      }
      else if (config.src.match(/gfycat/)) {
        this.handleGfyCat(config);
      }
      else if (config.src.match(/gifv/)) {
        this.handleImgur(config);
      }
      else if (config.src.match(/gif/)) {
        this.buildIMGWith(config);
      }
      else if (config.src.match(/jpg|jpeg|png/)) {
        this.buildIMGWith(config);
      }
      else if (config.src.match(/youtube/)) {
        this.handleYouTube(config);
      }
      else {
        console.log("JOE: Link doesn't have fun media.");
      }
    }

    // Various handlers
    handleStreamableMedia () {
      let uriArray = this.config.src.split('/'),
          streamableId = uriArray[uriArray.length - 1],
          src = '//streamable.com/res/' + streamableId,
          $element = this.$element;

      this.buildiFrame({
        $element: $element,
        width: '100%',
        src: src,
        scrolling: 'no'
      });
    };

    handleGfyCat () {
      let uriArray = this.config.src.split('/'),
          gfyCatDealie = uriArray[uriArray.length - 1],
          $element = this.$element,
          that = this,
          webmSrc, mp4Src;

      Ajax.call({
        url: '//gfycat.com/cajax/get/' + gfyCatDealie,
        method: 'GET',
        callback: function (response) {
          webmSrc = response.gfyItem.webmUrl;
          mp4Src = response.gfyItem.mp4Url;
          that.buildHTML5Video({
            $element: $element,
            wrapChildSources: true,
            webmSrc: webmSrc,
            mp4Src: mp4Src
          });
        },
        errCb: function () {
          console.log("Error: Failure to retrieve response for gfycat: ", gfyCatDealie);
        }
      });

    };

    handleYouTube () {
      let src = this.config.src,
          result = Ajax.parser(src),
          ytKey = result.search.split('=')[1],
          $element = this.$element;

      this.buildiFrame({
        $element: $element,
        src: '//youtube.com/embed/' + ytKey
      });
    };

    handleImgur (opts) {
      let $element = this.config.$element,
          arr = $element.data('src').split('.');
      arr.pop();
      let src = arr.join('.'),
          webmSrc = src + '.webm',
          mp4Src = src + '.mp4';

      this.buildHTML5Video({
        $element: $element,
        wrapChildSources: true,
        webmSrc: webmSrc,
        mp4Src: mp4Src
      });

    };

    handleVidFile () {
      this.buildHTML5Video(this.config);
    };

    // f()s that build html elments
    buildHTML5Video (opts) {
      opts = opts || {};
      let height = opts.height || 450,
          width = opts.width || '100%',
          $element = opts.$element || $('<div />'),
          src = opts.src || $element.data('src'),
          autoplay = opts.autoplay,
          //webmSrc = opts.webmSrc || (src + '.webm'),
          //mp4Src = opts.mp4Src || (src + '.mp4'),
          webmSrc = opts.webmSrc || false,
          mp4Src = opts.mp4Src || false,
          wrapChildSources = opts.wrapChildSources || false,
          $video = $('<video>', {
            height: height,
            width: width,
            loop: '',
            autoplay: autoplay,
            controls: '',
            muted: 'muted'
          }),
          webmID = opts.webmID || 'webmsource',
          mp4ID = opts.mp4ID || 'mp4source',
          $webmSource, $mp4Source;

      if (wrapChildSources) {
        if (webmSrc) {
          $webmSource = $('<source>', {
            id: webmID,
            src: webmSrc,
            type: 'video/webm'
          });
          $video.append($webmSource);
        }
        if (mp4Src) {
          $mp4Source = $('<source>', {
            id: mp4ID,
            src: mp4Src,
            type: 'video/mp4'
          });
          $video.append($mp4Source);
        }
      }
      else {
        $video.attr('src', src);
      }

      this.finishItUp($element, $video, this.config);
      return $element;
    };

    buildIMGWith (opts) {
      let $element = opts.$element,
          $img = $('<img>', {
            src: opts.src,
            width: "100%"
          });

      this.finishItUp($element, $img, this.config);
    };

    buildiFrame (opts) {
      opts = opts || {}
      let height = opts.height || 450,
          width = opts.width || 710,
          scrolling = opts.scrolling || 'no',
          $element = opts.$element || $('<div />'),
          src = opts.src || $element.data('src'),
          $iframe = $('<iframe>', {
            src: src,
            frameboarder: 0,
            height: height,
            width: width,
            scrolling: scrolling,
            allowfullscreen: ''
          });

      this.finishItUp($element, $iframe, this.config);

      return $element;
    };

    finishItUp ($element, $mediaElement, opts) {
      let trigger = opts.trigger;
      switch (opts.trigger) {
        case TRIGGER_CLICK:
          this.handleClick($element, $mediaElement);
        break;
        case TRIGGER_HOVER:
          this.handleHover($element, $mediaElement);
        break;
        case TRIGGER_AUTO:
          this.showMedia($element, $mediaElement);
        break;
      }

      if (opts.body) {
        $element.text(opts.body);
      }
    };

    // event handlers
    handleClick ($trigger, $ammo) {
      $trigger.on('click', e => {
        e.preventDefault();

        if ($ammo.is(':visible')) {
          $ammo.detach();
        }
        else {
          $ammo.appendTo($trigger);
        }
      });
    };

    handleHover ($trigger, $ammo) {
      $trigger.on('click', e => e.preventDefault());
      $trigger.on('mouseenter', e => {
        if (!$ammo.is(':visible')) {
          $ammo.appendTo($trigger);
        }
      });
      $trigger.on('mouseleave', e => {
        if ($ammo.is(':visible')) {
          $ammo.detach();
        }
      });
    };

    showMedia ($trigger, $ammo) {
      $ammo.appendTo($trigger);
    };

  };

  var $document = $(document),
      dealieArray = [];

  $document.ready(function () {
    checkInlineMedia();
    setArcticScroll();
  });

  var checkInlineMedia = function () {
    // $('a[data-inline]').each(function () {
    //   var $this = $(this),
    //       src = $this.data('src'),
    //       dealie = new J({
    //         $element: $this
    //       });

    //   dealieArray.push(dealie);
    // });

    $('a').each(function () {
      let $this = $(this),
          dealie = new J($this, {});

      dealie.generate();
      dealieArray.push(dealie);
    });
  };

  // Arctic Scroll Source
  var setArcticScroll = function () {
    var $postContent = $(".post-content");
    $postContent.fitVids();

    $(".scroll-down").arctic_scroll();

    $(".menu-button, .nav-cover, .nav-close").on("click", function(e){
      e.preventDefault();
      $("body").toggleClass("nav-opened nav-closed");
    });
  };
  // Arctic Scroll by Paul Adam Davis
  // https://github.com/PaulAdamDavis/Arctic-Scroll
  $.fn.arctic_scroll = function (options) {

    var defaults = {
      elem: $(this),
      speed: 500
    },

        allOptions = $.extend(defaults, options);

    allOptions.elem.click(function (event) {
      event.preventDefault();
      var $this = $(this),
          $htmlBody = $('html, body'),
          offset = ($this.attr('data-offset')) ? $this.attr('data-offset') : false,
          position = ($this.attr('data-position')) ? $this.attr('data-position') : false,
          toMove;

      if (offset) {
        toMove = parseInt(offset);
        $htmlBody.stop(true, false).animate({scrollTop: ($(this.hash).offset().top + toMove) }, allOptions.speed);
      } else if (position) {
        toMove = parseInt(position);
        $htmlBody.stop(true, false).animate({scrollTop: toMove }, allOptions.speed);
      } else {
        $htmlBody.stop(true, false).animate({scrollTop: ($(this.hash).offset().top) }, allOptions.speed);
      }
    });

  };

})(jQuery);
<|endoftext|>


<commit_before>/* vim: set expandtab sw=4 ts=4: */
/**
 * Analyse and visualise trend data using the Keen.io API.
 *
 * Copyright (C) 2014-2015 Dieter Adriaenssens <ruleant@users.sourceforge.net>
 *
 * This file is part of buildtimetrend/dashboard
 * <https://github.com/buildtimetrend/dashboard/>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

// Timeframe button constants
var BUTTON_COUNT_PREFIX = "count_";
var BUTTON_COUNT_DEFAULT = "builds";
var BUTTONS_COUNT = {
    "builds": {
        "caption": "Builds",
        "keenEventCollection": "build_jobs",
        "keenTargetProperty": "job.build"
    },
    "jobs": {
        "caption": "Build jobs",
        "keenEventCollection": "build_jobs",
        "keenTargetProperty": "job.job"
    },
    "substages": {
        "caption": "Stages",
        "keenEventCollection": "build_substages",
        "keenTargetProperty": "job.job"
    }
};

var countButtons = new ButtonClass(
    BUTTONS_COUNT,
    BUTTON_COUNT_DEFAULT,
    BUTTON_COUNT_PREFIX
);
countButtons.onClick = function() { updateCountCharts(); };

var queryBuildsPerProject, queryBuildsPerProjectPie, requestBuildsPerProject, requestBuildsPerProjectPie;

function initCharts() {
    // get Update Period settings
    var updatePeriod = getUpdatePeriod();

    // initialize timeframe buttons
    timeframeButtons.initButtons();
    countButtons.initButtons();

    var keenMaxAge = updatePeriod.keenMaxAge;
    var keenTimeframe = updatePeriod.keenTimeframe;
    var keenInterval = updatePeriod.keenInterval;

    // display charts
    $('#charts').show();

    // visualization code goes here
    Keen.ready(function() {
        /* Builds per project */
        // create query
        queryBuildsPerProject = new Keen.Query("count_unique", {
            eventCollection: "build_jobs",
            targetProperty: "job.build",
            groupBy: "buildtime_trend.project_name",
            interval: keenInterval,
            timeframe: keenTimeframe,
            maxAge: keenMaxAge,
            timezone: TIMEZONE_SECS
        });
        queriesTimeframe.push(queryBuildsPerProject);
        queriesInterval.push(queryBuildsPerProject);

        // draw chart
        var chartBuildsPerProject = new Keen.Dataviz()
            .el(document.getElementById("chart_builds_per_project"))
            .chartType("columnchart")
            .height("400")
            .attributes({
                chartOptions: {
                    isStacked: true
                }
            })
           .prepare();

        requestBuildsPerProject = client.run(queryBuildsPerProject, function(err, res) {
            if (err) {
                // Display the API error
                chartBuildsPerProject.error(err.message);
            } else {
                chartBuildsPerProject
                    .parseRequest(this)
                    .title("Builds per project")
                    .render();
            }
        });
        queryRequests.push(requestBuildsPerProject);

        /* Builds per project (piechart)*/
        // create query
        queryBuildsPerProjectPie = new Keen.Query("count_unique", {
            eventCollection: "build_jobs",
            targetProperty: "job.build",
            groupBy: "buildtime_trend.project_name",
            timeframe: keenTimeframe,
            maxAge: keenMaxAge,
            timezone: TIMEZONE_SECS
        });
        queriesTimeframe.push(queryBuildsPerProjectPie);

        // draw chart
        var chartBuildsPerProjectPie = new Keen.Dataviz()
            .el(document.getElementById("chart_builds_per_project_pie"))
            .height("400")
            .prepare();

        requestBuildsPerProjectPie = client.run(queryBuildsPerProjectPie, function(err, res) {
            if (err) {
                // Display the API error
                chartBuildsPerProjectPie.error(err.message);
            } else {
                chartBuildsPerProjectPie
                    .parseRequest(this)
                    .title("Builds per project")
                    .render();
            }
        });
        queryRequests.push(requestBuildsPerProjectPie);

    });
}

/**
 * Refresh count charts eventCollection and targetProperty selected by countButtons.
 */
function updateCountCharts() {
  // get Update Period settings
  var countSettings = countButtons.getCurrentButton();

  // update queries
  queryBuildsPerProject.set({
    eventCollection: countSettings.keenEventCollection,
    targetProperty: countSettings.keenTargetProperty
  });
  queryBuildsPerProjectPie.set({
    eventCollection: countSettings.keenEventCollection,
    targetProperty: countSettings.keenTargetProperty
  });

  // refresh all query requests
  requestBuildsPerProject.refresh();
  requestBuildsPerProjectPie.refresh();
}

// initialize page
$(document).ready(function() {
    updateTitle();
    initLinks();
    initMessage();
    populateProjects();
    if (!isEmpty(keenConfig.projectId) && !isEmpty(keenConfig.readKey)) {
        initCharts();
    }
});
<commit_msg>chart parameter height is an integer<commit_after>/* vim: set expandtab sw=4 ts=4: */
/**
 * Analyse and visualise trend data using the Keen.io API.
 *
 * Copyright (C) 2014-2015 Dieter Adriaenssens <ruleant@users.sourceforge.net>
 *
 * This file is part of buildtimetrend/dashboard
 * <https://github.com/buildtimetrend/dashboard/>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
 */

// Timeframe button constants
var BUTTON_COUNT_PREFIX = "count_";
var BUTTON_COUNT_DEFAULT = "builds";
var BUTTONS_COUNT = {
    "builds": {
        "caption": "Builds",
        "keenEventCollection": "build_jobs",
        "keenTargetProperty": "job.build"
    },
    "jobs": {
        "caption": "Build jobs",
        "keenEventCollection": "build_jobs",
        "keenTargetProperty": "job.job"
    },
    "substages": {
        "caption": "Stages",
        "keenEventCollection": "build_substages",
        "keenTargetProperty": "job.job"
    }
};

var countButtons = new ButtonClass(
    BUTTONS_COUNT,
    BUTTON_COUNT_DEFAULT,
    BUTTON_COUNT_PREFIX
);
countButtons.onClick = function() { updateCountCharts(); };

var queryBuildsPerProject, queryBuildsPerProjectPie, requestBuildsPerProject, requestBuildsPerProjectPie;

function initCharts() {
    // get Update Period settings
    var updatePeriod = getUpdatePeriod();

    // initialize timeframe buttons
    timeframeButtons.initButtons();
    countButtons.initButtons();

    var keenMaxAge = updatePeriod.keenMaxAge;
    var keenTimeframe = updatePeriod.keenTimeframe;
    var keenInterval = updatePeriod.keenInterval;

    // display charts
    $('#charts').show();

    // visualization code goes here
    Keen.ready(function() {
        /* Builds per project */
        // create query
        queryBuildsPerProject = new Keen.Query("count_unique", {
            eventCollection: "build_jobs",
            targetProperty: "job.build",
            groupBy: "buildtime_trend.project_name",
            interval: keenInterval,
            timeframe: keenTimeframe,
            maxAge: keenMaxAge,
            timezone: TIMEZONE_SECS
        });
        queriesTimeframe.push(queryBuildsPerProject);
        queriesInterval.push(queryBuildsPerProject);

        // draw chart
        var chartBuildsPerProject = new Keen.Dataviz()
            .el(document.getElementById("chart_builds_per_project"))
            .chartType("columnchart")
            .height(400)
            .attributes({
                chartOptions: {
                    isStacked: true
                }
            })
           .prepare();

        requestBuildsPerProject = client.run(queryBuildsPerProject, function(err, res) {
            if (err) {
                // Display the API error
                chartBuildsPerProject.error(err.message);
            } else {
                chartBuildsPerProject
                    .parseRequest(this)
                    .title("Builds per project")
                    .render();
            }
        });
        queryRequests.push(requestBuildsPerProject);

        /* Builds per project (piechart)*/
        // create query
        queryBuildsPerProjectPie = new Keen.Query("count_unique", {
            eventCollection: "build_jobs",
            targetProperty: "job.build",
            groupBy: "buildtime_trend.project_name",
            timeframe: keenTimeframe,
            maxAge: keenMaxAge,
            timezone: TIMEZONE_SECS
        });
        queriesTimeframe.push(queryBuildsPerProjectPie);

        // draw chart
        var chartBuildsPerProjectPie = new Keen.Dataviz()
            .el(document.getElementById("chart_builds_per_project_pie"))
            .height(400)
            .prepare();

        requestBuildsPerProjectPie = client.run(queryBuildsPerProjectPie, function(err, res) {
            if (err) {
                // Display the API error
                chartBuildsPerProjectPie.error(err.message);
            } else {
                chartBuildsPerProjectPie
                    .parseRequest(this)
                    .title("Builds per project")
                    .render();
            }
        });
        queryRequests.push(requestBuildsPerProjectPie);

    });
}

/**
 * Refresh count charts eventCollection and targetProperty selected by countButtons.
 */
function updateCountCharts() {
  // get Update Period settings
  var countSettings = countButtons.getCurrentButton();

  // update queries
  queryBuildsPerProject.set({
    eventCollection: countSettings.keenEventCollection,
    targetProperty: countSettings.keenTargetProperty
  });
  queryBuildsPerProjectPie.set({
    eventCollection: countSettings.keenEventCollection,
    targetProperty: countSettings.keenTargetProperty
  });

  // refresh all query requests
  requestBuildsPerProject.refresh();
  requestBuildsPerProjectPie.refresh();
}

// initialize page
$(document).ready(function() {
    updateTitle();
    initLinks();
    initMessage();
    populateProjects();
    if (!isEmpty(keenConfig.projectId) && !isEmpty(keenConfig.readKey)) {
        initCharts();
    }
});
<|endoftext|>


<commit_before>// The MIT License (MIT)

// Typed.js | Copyright (c) 2016 Matt Boldt | www.mattboldt.com

// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:

// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

! function(window, document, $) {

	"use strict";

	var Typed = function(el, options) {
		var self = this;

		// chosen element to manipulate text
		this.el = el;

		// options
		this.options = {};
		Object.keys(defaults).forEach(function(key) {
			self.options[key] = defaults[key];
		});
		Object.keys(options).forEach(function(key) {
			self.options[key] = options[key];
		});

		// attribute to type into
		this.isInput = this.el.tagName.toLowerCase() === 'input';
		this.attr = this.options.attr;

		// show cursor
		this.showCursor = this.isInput ? false : this.options.showCursor;

		// text content of element
		this.elContent = this.attr ? this.el.getAttribute(this.attr) : this.el.textContent;

		// html or plain text
		this.contentType = this.options.contentType;

		// typing speed
		this.typeSpeed = this.options.typeSpeed;

		// add a delay before typing starts
		this.startDelay = this.options.startDelay;

		// backspacing speed
		this.backSpeed = this.options.backSpeed;

		// amount of time to wait before backspacing
		this.backDelay = this.options.backDelay;

		// Fade out instead of backspace
		this.fadeOut = this.options.fadeOut;
		this.fadeOutClass = this.options.fadeOutClass;
		this.fadeOutDelay = this.options.fadeOutDelay;

		// div containing strings
		if($ && this.options.stringsElement instanceof $) {
			this.stringsElement = this.options.stringsElement[0]
		} else {
			this.stringsElement = this.options.stringsElement;
		}

		// input strings of text
		this.strings = this.options.strings;

		// character number position of current string
		this.strPos = 0;

		// current array position
		this.arrayPos = 0;

		// number to stop backspacing on.
		// default 0, can change depending on how many chars
		// you want to remove at the time
		this.stopNum = 0;

		// Looping logic
		this.loop = this.options.loop;
		this.loopCount = this.options.loopCount;
		this.curLoop = 0;

		// for stopping
		this.stop = false;

		// custom cursor
		this.cursorChar = this.options.cursorChar;

		// shuffle the strings
		this.shuffle = this.options.shuffle;
		// the order of strings
		this.sequence = [];

		// All systems go!
		this.build();
	};

	Typed.prototype = {

		constructor: Typed,

		init: function() {
			// begin the loop w/ first current string (global self.strings)
			// current string will be passed as an argument each time after this
			var self = this;
			self.timeout = setTimeout(function() {
				for (var i=0;i<self.strings.length;++i) self.sequence[i]=i;

				// shuffle the array if true
				if(self.shuffle) self.sequence = self.shuffleArray(self.sequence);

				// Start typing
				self.typewrite(self.strings[self.sequence[self.arrayPos]], self.strPos);
			}, self.startDelay);
		},

		build: function() {
			var self = this;
			// Insert cursor
			if (this.showCursor === true) {
				this.cursor = document.createElement('span');
				this.cursor.className = 'typed-cursor';
				this.cursor.innerHTML = this.cursorChar;
				this.el.parentNode && this.el.parentNode.insertBefore(this.cursor, this.el.nextSibling);
			}
			if (this.stringsElement) {
				this.strings = [];
				this.stringsElement.style.display = 'none';
				var strings = Array.prototype.slice.apply(this.stringsElement.children);
				strings.forEach(function(stringElement){
					self.strings.push(stringElement.innerHTML);
				});
			}
			this.init();
		},

		// pass current string state to each function, types 1 char per call
		typewrite: function(curString, curStrPos) {
			// exit when stopped
			if (this.stop === true) {
				return;
			}

			if (this.fadeOut && this.el.classList.contains(this.fadeOutClass)) {
				this.el.classList.remove(this.fadeOutClass);
				this.cursor.classList.remove(this.fadeOutClass);
			}

			// varying values for setTimeout during typing
			// can't be global since number changes each time loop is executed
			var humanize = Math.round(Math.random() * (100 - 30)) + this.typeSpeed;
			var self = this;

			// ------------- optional ------------- //
			// backpaces a certain string faster
			// ------------------------------------ //
			// if (self.arrayPos == 1){
			//  self.backDelay = 50;
			// }
			// else{ self.backDelay = 500; }

			// contain typing function in a timeout humanize'd delay
			self.timeout = setTimeout(function() {
				// check for an escape character before a pause value
				// format: \^\d+ .. eg: ^1000 .. should be able to print the ^ too using ^^
				// single ^ are removed from string
				var charPause = 0;
				var substr = curString.substr(curStrPos);
				if (substr.charAt(0) === '^') {
					var skip = 1; // skip atleast 1
					if (/^\^\d+/.test(substr)) {
						substr = /\d+/.exec(substr)[0];
						skip += substr.length;
						charPause = parseInt(substr);
					}

					// strip out the escape character and pause value so they're not printed
					curString = curString.substring(0, curStrPos) + curString.substring(curStrPos + skip);
				}

				if (self.contentType === 'html') {
					// skip over html tags while typing
					var curChar = curString.substr(curStrPos).charAt(0);
					if (curChar === '<' || curChar === '&') {
						var tag = '';
						var endTag = '';
						if (curChar === '<') {
							endTag = '>'
						}
						else {
							endTag = ';'
						}
						while (curString.substr(curStrPos + 1).charAt(0) !== endTag) {
							tag += curString.substr(curStrPos).charAt(0);
							curStrPos++;
							if (curStrPos + 1 > curString.length) { break; }
						}
						curStrPos++;
						tag += endTag;
					}
				}

				// timeout for any pause after a character
				self.timeout = setTimeout(function() {
					if (curStrPos === curString.length) {
						// fires callback function
						self.options.onStringTyped(self.arrayPos);

						// is this the final string
						if (self.arrayPos === self.strings.length - 1) {
							// animation that occurs on the last typed string
							self.options.callback();

							self.curLoop++;

							// quit if we wont loop back
							if (self.loop === false || self.curLoop === self.loopCount)
								return;
						}

						self.timeout = setTimeout(function() {
							self.backspace(curString, curStrPos);
						}, self.backDelay);

					} else {

						/* call before functions if applicable */
						if (curStrPos === 0) {
							self.options.preStringTyped(self.arrayPos);
						}

						// start typing each new char into existing string
						// curString: arg, self.el.html: original text inside element
						var nextString = curString.substr(0, curStrPos + 1);
						if (self.attr) {
							self.el.setAttribute(self.attr, nextString);
						} else {
							if (self.isInput) {
								self.el.value = nextString;
							} else if (self.contentType === 'html') {
								self.el.innerHTML = nextString;
							} else {
								self.el.textContent = nextString;
							}
						}

						// add characters one by one
						curStrPos++;
						// loop the function
						self.typewrite(curString, curStrPos);
					}
					// end of character pause
				}, charPause);

				// humanized value for typing
			}, humanize);

		},

		backspace: function(curString, curStrPos) {
			var self = this;
			// exit when stopped
			if (this.stop === true) {
				return;
			}

			if (this.fadeOut){
				this.initFadeOut();
				return;
			}

			// varying values for setTimeout during typing
			// can't be global since number changes each time loop is executed
			var humanize = Math.round(Math.random() * (100 - 30)) + this.backSpeed;

			self.timeout = setTimeout(function() {

				// ----- this part is optional ----- //
				// check string array position
				// on the first string, only delete one word
				// the stopNum actually represents the amount of chars to
				// keep in the current string. In my case it's 14.
				// if (self.arrayPos == 1){
				//  self.stopNum = 14;
				// }
				//every other time, delete the whole typed string
				// else{
				//  self.stopNum = 0;
				// }

				if (self.contentType === 'html') {
					// skip over html tags while backspacing
					if (curString.substr(curStrPos).charAt(0) === '>') {
						var tag = '';
						while (curString.substr(curStrPos - 1).charAt(0) !== '<') {
							tag -= curString.substr(curStrPos).charAt(0);
							curStrPos--;
							if (curStrPos < 0) { break; }
						}
						curStrPos--;
						tag += '<';
					}
				}

				// ----- continue important stuff ----- //
				// replace text with base text + typed characters
				var nextString = curString.substr(0, curStrPos);
				self.replaceText(nextString);

				// if the number (id of character in current string) is
				// less than the stop number, keep going
				if (curStrPos > self.stopNum) {
					// subtract characters one by one
					curStrPos--;
					// loop the function
					self.backspace(curString, curStrPos);
				}
				// if the stop number has been reached, increase
				// array position to next string
				else if (curStrPos <= self.stopNum) {
					self.arrayPos++;

					if (self.arrayPos === self.strings.length) {
						self.arrayPos = 0;

						// Shuffle sequence again
						if(self.shuffle) self.sequence = self.shuffleArray(self.sequence);

						self.init();
					} else
						self.typewrite(self.strings[self.sequence[self.arrayPos]], curStrPos);
				}

				// humanized value for typing
			}, humanize);

		},

		// Adds a CSS class to fade out current string
		initFadeOut: function(){
			self = this;
			this.el.className += ' ' + this.fadeOutClass;
			this.cursor.className += ' ' + this.fadeOutClass;
			return setTimeout(function() {
				self.arrayPos++;
				self.replaceText('')
				self.typewrite(self.strings[self.sequence[self.arrayPos]], 0);
			}, self.fadeOutDelay);
		},

		// Replaces current text in the HTML element
		replaceText: function(str) {
			if (this.attr) {
				this.el.setAttribute(this.attr, str);
			} else {
				if (this.isInput) {
					this.el.value = str;
				} else if (this.contentType === 'html') {
					this.el.innerHTML = str;
				} else {
					this.el.textContent = str;
				}
			}
		},

		// Shuffles the numbers in the given array.
		shuffleArray: function(array) {
			var tmp, current, top = array.length;
			if(top) while(--top) {
				current = Math.floor(Math.random() * (top + 1));
				tmp = array[current];
				array[current] = array[top];
				array[top] = tmp;
			}
			return array;
		},

		// Start & Stop currently not working

		// , stop: function() {
		//     var self = this;

		//     self.stop = true;
		//     clearInterval(self.timeout);
		// }

		// , start: function() {
		//     var self = this;
		//     if(self.stop === false)
		//        return;

		//     this.stop = false;
		//     this.init();
		// }

		// Reset and rebuild the element
		reset: function() {
			var self = this;
			clearInterval(self.timeout);
			var id = this.el.getAttribute('id');
			this.el.textContent = '';
			if (typeof this.cursor !== 'undefined' && typeof this.cursor.parentNode !== 'undefined') {
				this.cursor.parentNode.removeChild(this.cursor);
			}
			this.strPos = 0;
			this.arrayPos = 0;
			this.curLoop = 0;
			// Send the callback
			this.options.resetCallback();
		}

	};

	Typed.new = function(selector, option) {
		var elements = Array.prototype.slice.apply(document.querySelectorAll(selector));
		elements.forEach(function(element) {
			var instance = element._typed,
			    options = typeof option == 'object' && option;
			if (instance) { instance.reset(); }
			element._typed = instance = new Typed(element, options);
			if (typeof option == 'string') instance[option]();
		});
	};

	if ($) {
		$.fn.typed = function(option) {
			return this.each(function() {
				var $this = $(this),
				    data = $this.data('typed'),
				    options = typeof option == 'object' && option;
				if (data) { data.reset(); }
				$this.data('typed', (data = new Typed(this, options)));
				if (typeof option == 'string') data[option]();
			});
		};
	}

	window.Typed = Typed;

	var defaults = {
		strings: ["These are the default values...", "You know what you should do?", "Use your own!", "Have a great day!"],
		stringsElement: null,
		// typing speed
		typeSpeed: 0,
		// time before typing starts
		startDelay: 0,
		// backspacing speed
		backSpeed: 0,
		// shuffle the strings
		shuffle: false,
		// time before backspacing
		backDelay: 500,
		// Fade out instead of backspace
		fadeOut: false,
		fadeOutClass: 'typed-fade-out',
		fadeOutDelay: 500, // milliseconds
		// loop
		loop: false,
		// false = infinite
		loopCount: false,
		// show cursor
		showCursor: true,
		// character for cursor
		cursorChar: "|",
		// attribute to type (null == text)
		attr: null,
		// either html or text
		contentType: 'html',
		// call when done callback function
		callback: function() {},
		// starting callback function before each string
		preStringTyped: function() {},
		//callback for every typed string
		onStringTyped: function() {},
		// callback for reset
		resetCallback: function() {}
	};

}(window, document, window.jQuery);
<commit_msg>Delete typed.js<commit_after><|endoftext|>


<commit_before>const THEME_DEFAULTS = {
  primary: '#1976D2',
  secondary: '#424242',
  accent: '#82B1FF',
  error: '#FF5252',
  info: '#2196F3',
  success: '#4CAF50',
  warning: '#FFC107',
  type: 'light'
}

export default function (theme) {
  theme = theme || {}

  return Object.assign({}, THEME_DEFAULTS, theme)
}
<commit_msg>refactor(theme): removed deprecated property<commit_after>const THEME_DEFAULTS = {
  primary: '#1976D2',
  secondary: '#424242',
  accent: '#82B1FF',
  error: '#FF5252',
  info: '#2196F3',
  success: '#4CAF50',
  warning: '#FFC107'
}

export default function (theme) {
  theme = theme || {}

  return Object.assign({}, THEME_DEFAULTS, theme)
}
<|endoftext|>