<commit_before>'use strict';

// TODO(bajtos) Move the bi-di replication to loopback core,
// add model settings to enable the replication.
// Example:
//  LocalTodo: { options: {
//    base: 'Todo',
//    replicate: {
//      target: 'Todo',
//      mode: 'push' | 'pull' | 'bidi'
//    }}}
var proquint = require('proquint');

module.exports = function(client) {
  var LocalTodo = client.models.LocalTodo;
  var RemoteTodo = client.models.RemoteTodo;

  client.network = {
    _isConnected: true,
    get isConnected() {
      console.log('isConnected?', this._isConnected);
      return this._isConnected;
    },
    set isConnected(value) {
      return this._isConnected = value;
    }
  };

  // setup model replication
  var since = { push: -1, pull: -1 };
  function sync(cb) {
    LocalTodo.replicate(
      since.push,
      RemoteTodo,
      function pushed(err, conflicts, cps) {
        since.push = cps;
        RemoteTodo.replicate(
          since.pull,
          LocalTodo,
          function pulled(err, conflicts, cps) {
            since.pull = cps;
            if (cb) cb();
          });
      });
  }

  // sync local changes if connected
  LocalTodo.on('after save', function(ctx, next) {
    next();
    sync();
  });
  LocalTodo.on('after delete', function(ctx, next) {
    next();
    sync();
  });

  client.sync = sync;

  client.getReadableModelId = function(modelId) {
    return proquint.encode(new Buffer(modelId.substring(0, 8), 'binary'));
  };
};
<commit_msg>From the docs: don't use '.on' here but '.observe'<commit_after>'use strict';

// TODO(bajtos) Move the bi-di replication to loopback core,
// add model settings to enable the replication.
// Example:
//  LocalTodo: { options: {
//    base: 'Todo',
//    replicate: {
//      target: 'Todo',
//      mode: 'push' | 'pull' | 'bidi'
//    }}}
var proquint = require('proquint');

module.exports = function(client) {
  var LocalTodo = client.models.LocalTodo;
  var RemoteTodo = client.models.RemoteTodo;

  client.network = {
    _isConnected: true,
    get isConnected() {
      console.log('isConnected?', this._isConnected);
      return this._isConnected;
    },
    set isConnected(value) {
      return this._isConnected = value;
    }
  };

  // setup model replication
  var since = { push: -1, pull: -1 };
  function sync(cb) {
    LocalTodo.replicate(
      since.push,
      RemoteTodo,
      function pushed(err, conflicts, cps) {
        since.push = cps;
        RemoteTodo.replicate(
          since.pull,
          LocalTodo,
          function pulled(err, conflicts, cps) {
            since.pull = cps;
            if (cb) cb();
          });
      });
  }

  // sync local changes if connected
  LocalTodo.observe('after save', function(ctx, next) {
    next();
    console.log('sync after save');
    sync();
  });
  LocalTodo.observe('after delete', function(ctx, next) {
    next();
    sync();
  });

  client.sync = sync;

  client.getReadableModelId = function(modelId) {
    return proquint.encode(new Buffer(modelId.substring(0, 8), 'binary'));
  };
};
<|endoftext|>


<commit_before>(function () {
    'use strict';
    angular
        .module('myApp')
        .controller('WelcomeController', WelcomeController);

    WelcomeController.$inject = ['$state', '$timeout', 'ngDialog', 'toastr', 'TokenStorage', 'LoginService', 'RegisterService'];
    function WelcomeController($state, $timeout, ngDialog, toastr, TokenStorage, LoginService, RegisterService) {
        var vm = this;

        vm.isAuthenticated = TokenStorage.isAuthenticated();
        vm.login = "";
        vm.password = "";
        vm.confirmPassword = "";
        vm.mail = "";
        vm.blurry = false;
        vm.loginSuccessful = false;
        vm.loginFailed = false;
        vm.registerSuccessful = false;

        vm.loginFunction = loginFunction;
        vm.showLoginPopup = showLoginPopup;
        vm.showRegisterPopup = showRegisterPopup;
        vm.registerFunction = registerFunction;

        function showLoginPopup() {
            vm.blurry = true;
            var dialog = ngDialog.open({
                controller: "WelcomeController",
                controllerAs: "vm",
                template: "partials/unauth/login/login.html",
                className: "ngdialog-theme-default welcome-dialog",
                width: "100%"
            });
            dialog.closePromise.then(() => vm.blurry = false)
        }

        function showRegisterPopup() {
            vm.blurry = true;
            var dialog = ngDialog.open({
                controller: "WelcomeController",
                controllerAs: "vm",
                template: "partials/unauth/register/register.html",
                className: "ngdialog-theme-default welcome-dialog",
                width: "100%"
            });
            dialog.closePromise.then(() => vm.blurry = false)

        }

        function loginFunction() {
            vm.loginFailed = false;
            LoginService.login(vm.login, vm.password)
                .$promise.then(successCallback, failureCallback);

            function successCallback(result) {
                TokenStorage.store(result.token);
                vm.loginSuccessful = true;
                $timeout(function () {
                    ngDialog.close();
                    vm.loginSuccessful = false;
                    $state.go("state1");
                }, 1000);
            }

            function failureCallback(result) {
                vm.loginFailed = true;
            }
        }

        function registerFunction() {
            if (vm.password !== vm.confirmPassword) {
                return;
            }

            RegisterService.register(vm.login, vm.password, vm.mail)
                .$promise.then(successCallback, failureCallback);

            function successCallback() {
                vm.registerSuccessful = true;
                $timeout(function () {
                    ngDialog.close();
                    vm.registerSuccessful = false;
                    showLoginPopup();
                }, 2500);
            }

            function failureCallback() {
                toastr.error("Something went wrong, please try again");
            }

        }

    }

})();<commit_msg>minor fixes<commit_after>(function () {
    'use strict';
    angular
        .module('myApp')
        .controller('WelcomeController', WelcomeController);

    WelcomeController.$inject = ['$state', '$timeout', 'ngDialog', 'TokenStorage', 'LoginService', 'RegisterService'];
    function WelcomeController($state, $timeout, ngDialog, TokenStorage, LoginService, RegisterService) {
        var vm = this;

        vm.isAuthenticated = TokenStorage.isAuthenticated();
        vm.login = "";
        vm.password = "";
        vm.confirmPassword = "";
        vm.mail = "";
        vm.blurry = false;
        vm.loginSuccessful = false;
        vm.loginFailed = false;
        vm.registerSuccessful = false;

        vm.loginFunction = loginFunction;
        vm.showLoginPopup = showLoginPopup;
        vm.showRegisterPopup = showRegisterPopup;
        vm.registerFunction = registerFunction;

        function showLoginPopup() {
            vm.blurry = true;
            var dialog = ngDialog.open({
                controller: "WelcomeController",
                controllerAs: "vm",
                template: "partials/unauth/login/login.html",
                className: "ngdialog-theme-default welcome-dialog",
                width: "100%"
            });
            dialog.closePromise.then(() => vm.blurry = false)
        }

        function showRegisterPopup() {
            vm.blurry = true;
            var dialog = ngDialog.open({
                controller: "WelcomeController",
                controllerAs: "vm",
                template: "partials/unauth/register/register.html",
                className: "ngdialog-theme-default welcome-dialog",
                width: "100%"
            });
            dialog.closePromise.then(() => vm.blurry = false)

        }

        function loginFunction() {
            vm.loginFailed = false;

            LoginService.login(vm.login, vm.password)
                .$promise.then(successCallback, failureCallback);

            function successCallback(result) {
                TokenStorage.store(result.token);
                vm.loginSuccessful = true;
                $timeout(function () {
                    ngDialog.close();
                    vm.loginSuccessful = false;
                    $state.go("state1");
                }, 1000);
            }

            function failureCallback() {
                vm.loginFailed = true;
            }
        }

        function registerFunction() {
            if (vm.password !== vm.confirmPassword) {
                return;
            }

            RegisterService.register(vm.login, vm.password, vm.mail)
                .$promise.then(successCallback, failureCallback);

            function successCallback() {
                vm.registerSuccessful = true;
                $timeout(function () {
                    ngDialog.close();
                    vm.registerSuccessful = false;
                    showLoginPopup();
                }, 2500);
            }

            function failureCallback() {
                console.log("Something went wrong, please try again");
            }

        }

    }

})();<|endoftext|>


<commit_before>// ==UserScript==
// @name         Slither.io-bot
// @namespace    http://slither.io/
// @version      0.1.4
// @description  Slither.io bot
// @author       Ermiya Eskandary & Théophile Cailliau
// @match        http://slither.io/
// @grant        none
// ==/UserScript==
// Functions needed for the bot
// Set fake mouse coordinates
window.setMouseCoordinates = function (x, y) {
    window.xm = x;
    window.ym = y;
};
// Return the coordinates relative to the center (snake position).
window.mouseRelativeToCenter = function (x, y) {
    mapX = x - getHeight() / 2;
    mapY = y - getWidth() / 2;
    return [mapX, mapY];
};
// Map to mouse coordinates
window.mapToMouse = function (x, y) {
    mouseX = (x - getX()) * gsc;
    mouseY = (y - getY()) * gsc;
    return [mouseX, mouseY];
};
// Canvas width
window.getWidth = function () {
    return window.ww;
};
// Canvas height
window.getHeight = function () {
    return window.hh;
};
// X coordinates on the screen
window.getX = function () {
    return window.px;
};
// Y coordinates on the screen
window.getY = function () {
    return window.py;
};
// Get scaling ratio
window.getScale = function () {
        return window.gsc;
};
isBotRunning = false;
    // Sets the interval for the bot loop
window.launchBot = function (d) {
    console.log("Starting Bot.");
    isBotRunning = true;
    window.mousemovelistener = window.onmousemove;
    window.onmousemove = undefined;
    return window.botInterval = setInterval(window.loop, d);
};

window.stopBot = function () {
    console.log("Stopping Bot.");
    window.onmousemove = window.mousemovelistener;
    isBotRunning = false;
    return clearInterval(window.botInterval);
};

document.oldKeyDown = document.onkeydown;
document.onkeydown = function (e) {
    document.oldKeyDown(e);
    if(e.keyCode === 84) isBotRunning ? window.stopBot() : window.launchBot(5);
};

// Sorting function, from property 'distance'
window.sortFood = function (a, b) {
    return a.distance - b.distance;
};

// Given an object (of which properties xx and yy are not null), return the object with an additional property 'distance'
window.getDistanceFromMe = function (point) {
    if (point === null) return null;
    point.distance = getDistance(px, py, point.xx, point.yy);
    return point;
};

// Get a distance from point (x1; y1) to point (x2; y2).
window.getDistance = function (x1, y1, x2, y2) {
    // Calculate the vector coordinates.
    var xDistance = (x1 - x2);
    var yDistance = (y1 - y2);
    // Get the absolute value of each coordinate
    xDistance = xDistance < 0 ? xDistance * -1 : xDistance;
    yDistance = yDistance < 0 ? yDistance * -1 : yDistance;
    //Add the coordinates of the vector to get a distance. Not the real distance, but reliable for distance comparison.
    var distance = xDistance + yDistance;
    return distance;
};
// Sort food based on distance
window.getSortedFood = function () {
    return window.foods.filter(function (val) {
        return val !== null;
    }).map(getDistanceFromMe).sort(sortFood);
};

/*
window.isInFoods = function (foodObject) {
    return (foodObject === null) ? false : (window.foods.indexOf(foodObject) >= 0);
};

window.currentFood = null;
window.sortedFood = getSortedFood();
window.loop = function () {
    if (!isInFoods(currentFood)) {
        window.sortedFood = getSortedFood();
        window.currentFood = sortedFood[0];
        var coordinatesOfClosestFood = window.mapToMouse(window.sortedFood[0].xx, window.sortedFood[0].yy);
        window.setMouseCoordinates(coordinatesOfClosestFood[0], coordinatesOfClosestFood[1]);
    }
};
*/
// Removed the onemousemove listener so we can move the snake manually by setting coordinates
window.onmousemove = function (e) {
    /*if (e = e || window.event) {
      if ("undefined" != typeof e.clientX) {
        xm = e.clientX - ww / 2;
        ym = e.clientY - hh / 2;
      }
    }*/
};
// Actual bot code

// Loop for running the bot
window.loop = function () {
        // If the game is running
        if (playing) {
            // Sort the food based on distance
            var sortedFood = getSortedFood();
            // Convert coordinates of the closest food using mapToMouse
            var coordinatesOfClosestFood = window.mapToMouse(sortedFood[0].xx, sortedFood[0].yy);
            // Set the mouse coordinates to the coordinates of the closest food
            window.setMouseCoordinates(coordinatesOfClosestFood[0], coordinatesOfClosestFood[1]);

        }
    };
    // Start the bot
window.launchBot(5);
<commit_msg>How many times do we start it ? <commit_after>// ==UserScript==
// @name         Slither.io-bot
// @namespace    http://slither.io/
// @version      0.1.4
// @description  Slither.io bot
// @author       Ermiya Eskandary & Théophile Cailliau
// @match        http://slither.io/
// @grant        none
// ==/UserScript==
// Functions needed for the bot
// Set fake mouse coordinates
window.setMouseCoordinates = function (x, y) {
    window.xm = x;
    window.ym = y;
};
// Return the coordinates relative to the center (snake position).
window.mouseRelativeToCenter = function (x, y) {
    mapX = x - getHeight() / 2;
    mapY = y - getWidth() / 2;
    return [mapX, mapY];
};
// Map to mouse coordinates
window.mapToMouse = function (x, y) {
    mouseX = (x - getX()) * gsc;
    mouseY = (y - getY()) * gsc;
    return [mouseX, mouseY];
};
// Canvas width
window.getWidth = function () {
    return window.ww;
};
// Canvas height
window.getHeight = function () {
    return window.hh;
};
// X coordinates on the screen
window.getX = function () {
    return window.px;
};
// Y coordinates on the screen
window.getY = function () {
    return window.py;
};
// Get scaling ratio
window.getScale = function () {
        return window.gsc;
};
isBotRunning = false;
    // Sets the interval for the bot loop
window.launchBot = function (d) {
    console.log("Starting Bot.");
    isBotRunning = true;
    window.mousemovelistener = window.onmousemove;
    window.onmousemove = undefined;
    return window.botInterval = setInterval(window.loop, d);
};

window.stopBot = function () {
    console.log("Stopping Bot.");
    window.onmousemove = window.mousemovelistener;
    isBotRunning = false;
    return clearInterval(window.botInterval);
};

document.oldKeyDown = document.onkeydown;
document.onkeydown = function (e) {
    document.oldKeyDown(e);
    if(e.keyCode === 84) isBotRunning ? window.stopBot() : window.launchBot(5);
};

// Sorting function, from property 'distance'
window.sortFood = function (a, b) {
    return a.distance - b.distance;
};

// Given an object (of which properties xx and yy are not null), return the object with an additional property 'distance'
window.getDistanceFromMe = function (point) {
    if (point === null) return null;
    point.distance = getDistance(px, py, point.xx, point.yy);
    return point;
};

// Get a distance from point (x1; y1) to point (x2; y2).
window.getDistance = function (x1, y1, x2, y2) {
    // Calculate the vector coordinates.
    var xDistance = (x1 - x2);
    var yDistance = (y1 - y2);
    // Get the absolute value of each coordinate
    xDistance = xDistance < 0 ? xDistance * -1 : xDistance;
    yDistance = yDistance < 0 ? yDistance * -1 : yDistance;
    //Add the coordinates of the vector to get a distance. Not the real distance, but reliable for distance comparison.
    var distance = xDistance + yDistance;
    return distance;
};
// Sort food based on distance
window.getSortedFood = function () {
    return window.foods.filter(function (val) {
        return val !== null;
    }).map(getDistanceFromMe).sort(sortFood);
};

/*
window.isInFoods = function (foodObject) {
    return (foodObject === null) ? false : (window.foods.indexOf(foodObject) >= 0);
};

window.currentFood = null;
window.sortedFood = getSortedFood();
window.loop = function () {
    if (!isInFoods(currentFood)) {
        window.sortedFood = getSortedFood();
        window.currentFood = sortedFood[0];
        var coordinatesOfClosestFood = window.mapToMouse(window.sortedFood[0].xx, window.sortedFood[0].yy);
        window.setMouseCoordinates(coordinatesOfClosestFood[0], coordinatesOfClosestFood[1]);
    }
};
*/
// Removed the onemousemove listener so we can move the snake manually by setting coordinates
window.onmousemove = function (e) {
    /*if (e = e || window.event) {
      if ("undefined" != typeof e.clientX) {
        xm = e.clientX - ww / 2;
        ym = e.clientY - hh / 2;
      }
    }*/
};
// Actual bot code

// Loop for running the bot
window.loop = function () {
        // If the game is running
        if (playing) {
            // Sort the food based on distance
            var sortedFood = getSortedFood();
            // Convert coordinates of the closest food using mapToMouse
            var coordinatesOfClosestFood = window.mapToMouse(sortedFood[0].xx, sortedFood[0].yy);
            // Set the mouse coordinates to the coordinates of the closest food
            window.setMouseCoordinates(coordinatesOfClosestFood[0], coordinatesOfClosestFood[1]);

        }
    };
<|endoftext|>


<commit_before>// `.unshift()` to put back data so that the same
// read logic will fire when .read() gives
// you more data than you wanted

// using `.unshift() prevents us from making
// unnecessary buffer copies

// build a readable parser to split on newlines

var offset = 0;

process.stdin.on('readable', function () {
	var buf = process.stdin.read();
	if (!buf) return;
	for (; offset < buf.length; offset++) {
		if (buf[offset] == 0x0a) {
			console.dir(buf.slice(0, offset).toString());
			buf = buf.slice(offset + 1);
			offset = 0;
			process.stdin.unshift(buf);
			return;
		}
	}
	process.stdin.unshift(buf);
});

// modules on npm such as `split` should be used
// instead of rolling your own line-parsing logic<commit_msg>Removed files<commit_after><|endoftext|>


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

/**
 * External dependencies
 */
//import { percySnapshot } from '@percy/puppeteer';

/**
 * Internal dependencies
 */
import { createNewStory } from '../../../utils';

describe('Inserting Media from Media Library', () => {
  // Uses the existence of the element's frame element as an indicator for successful insertion.
  it('should insert an image by clicking on it', async () => {
    await createNewStory();

    await expect(page).not.toMatchElement('[data-testid="FrameElement"]');

    // Clicking will only act on the first element.
    await expect(page).toClick('[data-testid="mediaElement"]');

    // First match is for the background element, second for the image.
    await expect(page).toMatchElement(
      '[data-testid="frameElement"]:nth-of-type(2)'
    );

    // TODO: Enable once https://github.com/google/web-stories-wp/issues/1206 is merged.
    //await percySnapshot(page, 'Inserting Media from Media Library');
  });
});
<commit_msg>Return test.<commit_after>/*
 * Copyright 2020 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * External dependencies
 */
import { percySnapshot } from '@percy/puppeteer';

/**
 * Internal dependencies
 */
import { createNewStory } from '../../../utils';

describe('Inserting Media from Media Library', () => {
  // Uses the existence of the element's frame element as an indicator for successful insertion.
  it('should insert an image by clicking on it', async () => {
    await createNewStory();

    await expect(page).not.toMatchElement('[data-testid="FrameElement"]');

    // Clicking will only act on the first element.
    await expect(page).toClick('[data-testid="mediaElement"]');

    // First match is for the background element, second for the image.
    await expect(page).toMatchElement(
      '[data-testid="frameElement"]:nth-of-type(2)'
    );

    await percySnapshot(page, 'Inserting Media from Media Library');
  });
});
<|endoftext|>


<commit_before>function getSampleData() {

    return {
        "data1": [
            // Order is optional. If not specified it will be assigned automatically
            {"id": "2f85dbeb-0845-404e-934e-218bf39750c0", "description": "Milestones", "order": 0, "tasks": [
                // Dates can be specified as string, timestamp or javascript date object. The data attribute can be used to attach a custom object
                {"id": "f55549b5-e449-4b0c-9f4b-8b33381f7d76", "subject": "Kickoff", "color": "#93C47D", "from": "2013-10-07T09:00:00", "to": "2013-10-07T10:00:00", "data": "Can contain any custom data or object"},
                {"id": "5e997eb3-4311-46b1-a1b4-7e8663ea8b0b", "subject": "Concept approval", "color": "#93C47D", "from": new Date(2013,9,18,18,0,0), "to": new Date(2013,9,18,18,0,0), "est": new Date(2013,9,16,7,0,0), "lct": new Date(2013,9,19,0,0,0)},
                {"id": "b6a1c25c-85ae-4991-8502-b2b5127bc47c", "subject": "Development finished", "color": "#93C47D", "from": new Date(2013,10,15,18,0,0), "to": new Date(2013,10,15,18,0,0)},
                {"id": "6fdfd775-7b22-42ec-a12c-21a64c9e7a9e", "subject": "Shop is running", "color": "#93C47D", "from": new Date(2013,10,22,12,0,0), "to": new Date(2013,10,22,12,0,0)},
                {"id": "c112ee80-82fc-49ba-b8de-f8efba41b5b4", "subject": "Go-live", "color": "#93C47D", "from": new Date(2013,10,29,16,0,0), "to": new Date(2013,10,29,16,0,0)}
            ], "data": "Can contain any custom data or object"},
            {"id": "b8d10927-cf50-48bd-a056-3554decab824", "description": "Status meetings", "order": 1, "tasks": [
                {"id": "301d781f-1ef0-4c35-8398-478b641c0658", "subject": "Demo", "color": "#9FC5F8", "from": new Date(2013,9,25,15,0,0), "to": new Date(2013,9,25,18,30,0)},
                {"id": "0fbf344a-cb43-4b20-8003-a789ba803ad8", "subject": "Demo", "color": "#9FC5F8", "from": new Date(2013,10,1,15,0,0), "to": new Date(2013,10,1,18,0,0)},
                {"id": "12af138c-ba21-4159-99b9-06d61b1299a2", "subject": "Demo", "color": "#9FC5F8", "from": new Date(2013,10,8,15,0,0), "to": new Date(2013,10,8,18,0,0)},
                {"id": "73294eca-de4c-4f35-aa9b-ae25480967ba", "subject": "Demo", "color": "#9FC5F8", "from": new Date(2013,10,15,15,0,0), "to": new Date(2013,10,15,18,0,0)},
                {"id": "75c3dc51-09c4-44fb-ac40-2f4548d0728e", "subject": "Demo", "color": "#9FC5F8", "from": new Date(2013,10,24,9,0,0), "to": new Date(2013,10,24,10,0,0)}
            ]},
            {"id": "c65c2672-445d-4297-a7f2-30de241b3145", "description": "Kickoff", "order": 2, "tasks": [
                {"id": "4e197e4d-02a4-490e-b920-4881c3ba8eb7", "subject": "Day 1", "color": "#9FC5F8", "from": new Date(2013,9,7,9,0,0), "to": new Date(2013,9,7,17,0,0)},
                {"id": "451046c0-9b17-4eaf-aee0-4e17fcfce6ae", "subject": "Day 2", "color": "#9FC5F8", "from": new Date(2013,9,8,9,0,0), "to": new Date(2013,9,8,17,0,0)},
                {"id": "fcc568c5-53b0-4046-8f19-265ebab34c0b", "subject": "Day 3", "color": "#9FC5F8", "from": new Date(2013,9,9,8,30,0), "to": new Date(2013,9,9,12,0,0)}
            ]},
            {"id": "dd2e7a97-1622-4521-a807-f29960218785", "description": "Create concept", "order": 3, "tasks": [
                {"id": "9c17a6c8-ce8c-4426-8693-a0965ff0fe69", "subject": "Create concept", "color": "#F1C232", "from": new Date(2013,9,10,8,0,0), "to": new Date(2013,9,16,18,0,0), "est": new Date(2013,9,8,8,0,0), "lct": new Date(2013,9,18,18,0,0)}
            ]},
            {"id": "eede0c9a-6777-4b55-9359-1eada309404e", "description": "Finalize concept", "order": 4, "tasks": [
                {"id": "30b8f544-5a45-4357-9a72-dd0181fba49f", "subject": "Finalize concept", "color": "#F1C232", "from": new Date(2013,9,17,8,0,0), "to": new Date(2013,9,18,18,0,0)}
            ]},
            {"id": "b5318fd9-5d70-4eb1-9c05-65647b9aefe6", "description": "Sprint 1", "order": 5, "tasks": [
                {"id": "d1fdf100-534c-4198-afb9-7bcaef0696f0", "subject": "Product list view", "color": "#F1C232", "from": new Date(2013,9,21,8,0,0), "to": new Date(2013,9,25,15,0,0)}
            ]},
            {"id": "cfb29cd5-1737-4027-9778-bb3058fbed9c", "description": "Sprint 2", "order": 6, "tasks": [
                {"id": "57638ba3-dfff-476d-ab9a-30fda1e44b50", "subject": "Order basket", "color": "#F1C232", "from": new Date(2013,9,28,8,0,0), "to": new Date(2013,10,1,15,0,0)}
            ]},
            {"id": "df9bb83f-e9de-4cbe-944e-36aec6db53cc", "description": "Sprint 3", "order": 7, "tasks": [
                {"id": "192adc6e-ab17-4cd1-82d8-4a5e7525b169", "subject": "Checkout", "color": "#F1C232", "from": new Date(2013,10,4,8,0,0), "to": new Date(2013,10,8,15,0,0)}
            ]},
            {"id": "48cbc052-1fd5-4262-a05f-97dad7337876", "description": "Sprint 4", "order": 8, "tasks": [
                {"id": "431dc7be-b61b-49a0-b26d-7ab5dfcadd41", "subject": "Login&Singup and admin view", "color": "#F1C232", "from": new Date(2013,10,11,8,0,0), "to": new Date(2013,10,15,15,0,0)}
            ]},
            {"id": "34473cc4-5ee5-4953-8289-98779172129e", "description": "Setup server", "order": 9, "tasks": [
                {"id": "43eb6d19-6402-493c-a281-20e59a6fab6e", "subject": "HW", "color": "#F1C232", "from": new Date(2013,10,18,8,0,0), "to": new Date(2013,10,18,12,0,0)}
            ]},
            {"id": "73cae585-5b2c-46b6-aeaf-8cf728c894f7", "description": "Config server", "order": 10, "tasks": [
                {"id": "8dbfda29-e775-4fa3-87c1-103b085d52ee", "subject": "SW / DNS/ Backups", "color": "#F1C232", "from": new Date(2013,10,18,12,0,0), "to": new Date(2013,10,21,18,0,0)}
            ]},
            {"id": "41cae585-ad2c-46b6-aeaf-8cf728c894f7", "description": "Deployment", "order": 11, "tasks": [
                {"id": "2dbfda09-e775-4fa3-87c1-103b085d52ee", "subject": "Depl. & Final testing", "color": "#F1C232", "from": new Date(2013,10,21,8,0,0), "to": new Date(2013,10,22,12,0,0)}
            ]},
            {"id": "33e1af55-52c6-4ccd-b261-1f4484ed5773", "description": "Workshop", "order": 12, "tasks": [
                {"id": "656b9240-00da-42ff-bfbd-dfe7ba393528", "subject": "On-side education", "color": "#F1C232", "from": new Date(2013,10,24,9,0,0), "to": new Date(2013,10,25,15,0,0)}
            ]},
            {"id": "bffa16c6-c134-4443-8e6e-b09410c37c9f", "description": "Content", "order": 13, "tasks": [
                {"id": "2f4ec0f1-cd7a-441a-8288-e788ec112af9", "subject": "Supervise content creation", "color": "#F1C232", "from": new Date(2013,10,26,9,0,0), "to": new Date(2013,10,29,16,0,0)}
            ]},
            {"id": "ec0c5e31-449f-42d0-9e81-45c66322b640", "description": "Documentation", "order": 14, "tasks": [
                {"id": "edf2cece-2d17-436f-bead-691edbc7386b", "subject": "Technical/User documentation", "color": "#F1C232", "from": new Date(2013,10,26,8,0,0), "to": new Date(2013,10,28,18,0,0)}
            ]}
        ]};
}<commit_msg>Adjusted sample data file<commit_after>function getSampleData() {

    return {
        "data1": [
            // Order is optional. If not specified it will be assigned automatically
            {"id": "2f85dbeb-0845-404e-934e-218bf39750c0", "description": "Milestones", "order": 0, "tasks": [
                // Dates can be specified as string, timestamp or javascript date object. The data attribute can be used to attach a custom object
                {"id": "f55549b5-e449-4b0c-9f4b-8b33381f7d76", "subject": "Kickoff", "color": "#93C47D", "from": "2013-10-07T09:00:00", "to": "2013-10-07T10:00:00", "data": "Can contain any custom data or object"},
                {"id": "5e997eb3-4311-46b1-a1b4-7e8663ea8b0b", "subject": "Concept approval", "color": "#93C47D", "from": new Date(2013,9,18,18,0,0), "to": new Date(2013,9,18,18,0,0), "est": new Date(2013,9,16,7,0,0), "lct": new Date(2013,9,19,0,0,0)},
                {"id": "b6a1c25c-85ae-4991-8502-b2b5127bc47c", "subject": "Development finished", "color": "#93C47D", "from": new Date(2013,10,15,18,0,0), "to": new Date(2013,10,15,18,0,0)},
                {"id": "6fdfd775-7b22-42ec-a12c-21a64c9e7a9e", "subject": "Shop is running", "color": "#93C47D", "from": new Date(2013,10,22,12,0,0), "to": new Date(2013,10,22,12,0,0)},
                {"id": "c112ee80-82fc-49ba-b8de-f8efba41b5b4", "subject": "Go-live", "color": "#93C47D", "from": new Date(2013,10,29,16,0,0), "to": new Date(2013,10,29,16,0,0)}
            ], "data": "Can contain any custom data or object"},
            {"id": "b8d10927-cf50-48bd-a056-3554decab824", "description": "Status meetings", "order": 1, "tasks": [
                {"id": "301d781f-1ef0-4c35-8398-478b641c0658", "subject": "Demo", "color": "#9FC5F8", "from": new Date(2013,9,25,15,0,0), "to": new Date(2013,9,25,18,30,0)},
                {"id": "0fbf344a-cb43-4b20-8003-a789ba803ad8", "subject": "Demo", "color": "#9FC5F8", "from": new Date(2013,10,1,15,0,0), "to": new Date(2013,10,1,18,0,0)},
                {"id": "12af138c-ba21-4159-99b9-06d61b1299a2", "subject": "Demo", "color": "#9FC5F8", "from": new Date(2013,10,8,15,0,0), "to": new Date(2013,10,8,18,0,0)},
                {"id": "73294eca-de4c-4f35-aa9b-ae25480967ba", "subject": "Demo", "color": "#9FC5F8", "from": new Date(2013,10,15,15,0,0), "to": new Date(2013,10,15,18,0,0)},
                {"id": "75c3dc51-09c4-44fb-ac40-2f4548d0728e", "subject": "Demo", "color": "#9FC5F8", "from": new Date(2013,10,24,9,0,0), "to": new Date(2013,10,24,10,0,0)}
            ]},
            {"id": "c65c2672-445d-4297-a7f2-30de241b3145", "description": "Kickoff", "order": 2, "tasks": [
                {"id": "4e197e4d-02a4-490e-b920-4881c3ba8eb7", "subject": "Day 1", "color": "#9FC5F8", "from": new Date(2013,9,7,9,0,0), "to": new Date(2013,9,7,17,0,0)},
                {"id": "451046c0-9b17-4eaf-aee0-4e17fcfce6ae", "subject": "Day 2", "color": "#9FC5F8", "from": new Date(2013,9,8,9,0,0), "to": new Date(2013,9,8,17,0,0)},
                {"id": "fcc568c5-53b0-4046-8f19-265ebab34c0b", "subject": "Day 3", "color": "#9FC5F8", "from": new Date(2013,9,9,8,30,0), "to": new Date(2013,9,9,12,0,0)}
            ]},
            {"id": "dd2e7a97-1622-4521-a807-f29960218785", "description": "Create concept", "order": 3, "tasks": [
                {"id": "9c17a6c8-ce8c-4426-8693-a0965ff0fe69", "subject": "Create concept", "color": "#F1C232", "from": new Date(2013,9,10,8,0,0), "to": new Date(2013,9,16,18,0,0), "est": new Date(2013,9,8,8,0,0), "lct": new Date(2013,9,18,20,0,0)}
            ]},
            {"id": "eede0c9a-6777-4b55-9359-1eada309404e", "description": "Finalize concept", "order": 4, "tasks": [
                {"id": "30b8f544-5a45-4357-9a72-dd0181fba49f", "subject": "Finalize concept", "color": "#F1C232", "from": new Date(2013,9,17,8,0,0), "to": new Date(2013,9,18,18,0,0)}
            ]},
            {"id": "b5318fd9-5d70-4eb1-9c05-65647b9aefe6", "description": "Sprint 1", "order": 5, "tasks": [
                {"id": "d1fdf100-534c-4198-afb9-7bcaef0696f0", "subject": "Product list view", "color": "#F1C232", "from": new Date(2013,9,21,8,0,0), "to": new Date(2013,9,25,15,0,0)}
            ]},
            {"id": "cfb29cd5-1737-4027-9778-bb3058fbed9c", "description": "Sprint 2", "order": 6, "tasks": [
                {"id": "57638ba3-dfff-476d-ab9a-30fda1e44b50", "subject": "Order basket", "color": "#F1C232", "from": new Date(2013,9,28,8,0,0), "to": new Date(2013,10,1,15,0,0)}
            ]},
            {"id": "df9bb83f-e9de-4cbe-944e-36aec6db53cc", "description": "Sprint 3", "order": 7, "tasks": [
                {"id": "192adc6e-ab17-4cd1-82d8-4a5e7525b169", "subject": "Checkout", "color": "#F1C232", "from": new Date(2013,10,4,8,0,0), "to": new Date(2013,10,8,15,0,0)}
            ]},
            {"id": "48cbc052-1fd5-4262-a05f-97dad7337876", "description": "Sprint 4", "order": 8, "tasks": [
                {"id": "431dc7be-b61b-49a0-b26d-7ab5dfcadd41", "subject": "Login&Singup and admin view", "color": "#F1C232", "from": new Date(2013,10,11,8,0,0), "to": new Date(2013,10,15,15,0,0)}
            ]},
            {"id": "34473cc4-5ee5-4953-8289-98779172129e", "description": "Setup server", "order": 9, "tasks": [
                {"id": "43eb6d19-6402-493c-a281-20e59a6fab6e", "subject": "HW", "color": "#F1C232", "from": new Date(2013,10,18,8,0,0), "to": new Date(2013,10,18,12,0,0)}
            ]},
            {"id": "73cae585-5b2c-46b6-aeaf-8cf728c894f7", "description": "Config server", "order": 10, "tasks": [
                {"id": "8dbfda29-e775-4fa3-87c1-103b085d52ee", "subject": "SW / DNS/ Backups", "color": "#F1C232", "from": new Date(2013,10,18,12,0,0), "to": new Date(2013,10,21,18,0,0)}
            ]},
            {"id": "41cae585-ad2c-46b6-aeaf-8cf728c894f7", "description": "Deployment", "order": 11, "tasks": [
                {"id": "2dbfda09-e775-4fa3-87c1-103b085d52ee", "subject": "Depl. & Final testing", "color": "#F1C232", "from": new Date(2013,10,21,8,0,0), "to": new Date(2013,10,22,12,0,0)}
            ]},
            {"id": "33e1af55-52c6-4ccd-b261-1f4484ed5773", "description": "Workshop", "order": 12, "tasks": [
                {"id": "656b9240-00da-42ff-bfbd-dfe7ba393528", "subject": "On-side education", "color": "#F1C232", "from": new Date(2013,10,24,9,0,0), "to": new Date(2013,10,25,15,0,0)}
            ]},
            {"id": "bffa16c6-c134-4443-8e6e-b09410c37c9f", "description": "Content", "order": 13, "tasks": [
                {"id": "2f4ec0f1-cd7a-441a-8288-e788ec112af9", "subject": "Supervise content creation", "color": "#F1C232", "from": new Date(2013,10,26,9,0,0), "to": new Date(2013,10,29,16,0,0)}
            ]},
            {"id": "ec0c5e31-449f-42d0-9e81-45c66322b640", "description": "Documentation", "order": 14, "tasks": [
                {"id": "edf2cece-2d17-436f-bead-691edbc7386b", "subject": "Technical/User documentation", "color": "#F1C232", "from": new Date(2013,10,26,8,0,0), "to": new Date(2013,10,28,18,0,0)}
            ]}
        ]};
}<|endoftext|>


<commit_before>
TouchSupport = function() {

	this.clientBrowser	= navigator.userAgent;

	this.iDevice		= this.clientBrowser.match(/(iPhone|iPad|iPod)/);
	this.bbDevice		= this.clientBrowser.match(/BlackBerry/);
	this.droidDevice	= this.clientBrowser.match(/Android/);

	this.browserEngine = function() {
		if( this.iDevice ) {
			return 1;
		} else if( this.bbDevice ) {
			return 2;
		} else if( this.droidDevice ) {
			return 3;
		}
	}

	this.isTouchDevice = function() {
		if ("ontouchstart" in document.documentElement) {
			return true;
		} else {
			return false;
		}
	};

	this.bypassDefaultMove = function(event) {
		event.preventDefault();
		window.scroll(0, 0);
		return false;
	}

	this.getX = function(event) {
		if( this.isTouchDevice() ) {
			if(this.iDevice) {
				return event.targetTouches[0].pageX;
			} else if (this.bbDevice) {
				// blackberry
			} else if (this.droidDevice) {
				// android
			}

		} else {
			if(this.isIE()) {
				return window.event.clientX;
			} else {
				return event.pageX;
			}
		}
	}

	this.getY = function(event) {
		if( this.isTouchDevice() ) {
			return event.targetTouches[0].pageY;
		} else {
			if(this.isIE()) {
				return window.event.clientY;
			} else {
				return event.pageY;
			}

		}

	}

	this.isIE = function() { // MS IE
		if (document.layers||document.getElementById&&!document.all) {
			return false;
		} else if (document.all) {
			return true; //IE
		}
	}

};<commit_msg>New browser support.<commit_after>
TouchSupport = function() {

	this.clientBrowser	= navigator.userAgent;

	this.iDevice		= this.clientBrowser.match(/(iPhone|iPad|iPod)/);
	this.bbDevice		= this.clientBrowser.match(/BlackBerry/);
	this.droidDevice	= this.clientBrowser.match(/Android/);

	this.browserEngine = function() {
		if( this.iDevice ) {
			return 1;
		} else if( this.bbDevice ) {
			return 2;
		} else if( this.droidDevice ) {
			return 3;
		}
	}

	this.isTouchDevice = function() {
		if ("ontouchstart" in document.documentElement) {
			return true;
		} else {
			return false;
		}
	};

	this.bypassDefaultMove = function(event) {
		event.preventDefault();
		window.scroll(0, 0);
		return false;
	}

	this.getX = function(event) {
		if( this.isTouchDevice() ) {
			if(this.iDevice) {
				return event.targetTouches[0].pageX;
			} else if (this.bbDevice) {
				// blackberry
			} else if (this.droidDevice) {
				// android
			}

		} else {
			if(this.isIE()) {
				return window.event.clientX;
			} else {
				return event.pageX;
			}
		}
	}

	this.getY = function(event) {
		if( this.isTouchDevice() ) {
			return event.targetTouches[0].pageY;
		} else {
			if(this.isIE()) {
				return window.event.clientY;
			} else {
				return event.pageY;
			}

		}

	}

	this.isIE = function() { // MS IE
		if (document.layers||document.getElementById&&!document.all) {
			return false;
		} else if (document.all) {
			return true; //IE
		}
	}

};<|endoftext|>


<commit_before>// Declare a variable to generate unique notification IDs
var notID = 0;

// partial URLs to the images used in the example
var asURLs = [
	"/images/inbox-64x64.png",
	"/images/inbox-08-64x64.png",
	"/images/white-64x64.png",
	"/images/africa-400x400.png",
	"/images/antartica-400x400.png",
	"/images/asia-400x400.png",
	"/images/europe-400x400.png",
	"/images/north-america-400x400.png",
	"/images/oceania-400x400.png",
	"/images/south-america-400x400.png"
];

// List of sample notifications. These are further customized
// in the code according the UI settings.
var notOptions = [
	{
		type : "basic",
		title: "Basic Notification",
		message: "Short message part",
		expandedMessage: "Longer part of the message",
	},
	{
		type : "image",
		title: "Image Notification",
		message: "Short message plus an image",
	},
	{
		type : "list",
		title: "List Notification",
		message: "List of items in a message",
		items: [
			{ title: "Item1", message: "This is item 1"},
			{ title: "Item2", message: "This is item 2"},
			{ title: "Item3", message: "This is item 3"},
			{ title: "Item4", message: "This is item 4"},
			{ title: "Item5", message: "This is item 5"},
			{ title: "Item6", message: "This is item 6"},
		]
	},
	{
		type : "progress",
		title: "Progress Notification",
		message: "Short message plus an image",
		progress: 60
	}

];

// Window initialization code. Set up the various event handlers
window.addEventListener("load", function() {
	document.getElementById("basic").addEventListener("click", doNotify);
	document.getElementById("image").addEventListener("click", doNotify);
	document.getElementById("list").addEventListener("click", doNotify);
	document.getElementById("progress").addEventListener("click", doNotify);

	// set up the event listeners
	chrome.notifications.onClosed.addListener(notificationClosed);
	chrome.notifications.onClicked.addListener(notificationClicked);
	chrome.notifications.onButtonClicked.addListener(notificationBtnClick);
});

// Create the notification with the given parameters as they are set in the UI
function doNotify(evt) {
	var path = chrome.runtime.getURL(asURLs[document.getElementById("img").options.selectedIndex]);
	var options = null;
	var sBtn1 = document.getElementById("btn1").value;
	var sBtn2 = document.getElementById("btn2").value;
	// Create the right notification for the selected type
	if (evt.srcElement.id == "basic") {
		options = notOptions[0];
	}
	else if (evt.srcElement.id == "image") {
		options = notOptions[1];
		options.imageUrl = chrome.runtime.getURL("/images/tahoe-320x215.png");
	}
	else if (evt.srcElement.id == "list") {
		options = notOptions[2];
	}
	else if (evt.srcElement.id == "progress") {
		options = notOptions[3];
	}
	else if (evt.srcElement.id == "clear") {
		options = notOptions[4];
	}

	options.iconUrl = path;
	// priority is from -2 to 2. The API makes no guarantee about how notifications are
	// visually handled by the OS - they simply represent hints that the OS can use to
	// order or display them however it wishes.
	options.priority = document.getElementById("pri").options.selectedIndex - 2;

	options.buttons = [];
	if (sBtn1.length)
		options.buttons.push({ title: sBtn1 });
	if (sBtn2.length)
		options.buttons.push({ title: sBtn2 });

    chrome.notifications.create("id"+notID++, options, creationCallback);
}

function creationCallback(notID) {
	console.log("Succesfully created " + notID + " notification");
	if(document.getElementById("clear").checked) {
      setTimeout(function() { chrome.notifications.clear(notID, function(wascleared){console.log("Notification cleared: "+wascleared)}) }, 3000);
	}
}

// Event handlers for the various notification events
function notificationClosed(notID, bByUser) {
	console.log("The notification '" + notID + "' was closed" + (bByUser ? " by the user" : ""));
}

function notificationClicked(notID) {
	console.log("The notification '" + notID + "' was clicked");
}

function notificationBtnClick(notID, iBtn) {
	console.log("The notification '" + notID + "' had button " + iBtn + " clicked");
}
<commit_msg>fixed indent<commit_after>// Declare a variable to generate unique notification IDs
var notID = 0;

// partial URLs to the images used in the example
var asURLs = [
	"/images/inbox-64x64.png",
	"/images/inbox-08-64x64.png",
	"/images/white-64x64.png",
	"/images/africa-400x400.png",
	"/images/antartica-400x400.png",
	"/images/asia-400x400.png",
	"/images/europe-400x400.png",
	"/images/north-america-400x400.png",
	"/images/oceania-400x400.png",
	"/images/south-america-400x400.png"
];

// List of sample notifications. These are further customized
// in the code according the UI settings.
var notOptions = [
	{
		type : "basic",
		title: "Basic Notification",
		message: "Short message part",
		expandedMessage: "Longer part of the message",
	},
	{
		type : "image",
		title: "Image Notification",
		message: "Short message plus an image",
	},
	{
		type : "list",
		title: "List Notification",
		message: "List of items in a message",
		items: [
			{ title: "Item1", message: "This is item 1"},
			{ title: "Item2", message: "This is item 2"},
			{ title: "Item3", message: "This is item 3"},
			{ title: "Item4", message: "This is item 4"},
			{ title: "Item5", message: "This is item 5"},
			{ title: "Item6", message: "This is item 6"},
		]
	},
	{
		type : "progress",
		title: "Progress Notification",
		message: "Short message plus an image",
		progress: 60
	}

];

// Window initialization code. Set up the various event handlers
window.addEventListener("load", function() {
	document.getElementById("basic").addEventListener("click", doNotify);
	document.getElementById("image").addEventListener("click", doNotify);
	document.getElementById("list").addEventListener("click", doNotify);
	document.getElementById("progress").addEventListener("click", doNotify);

	// set up the event listeners
	chrome.notifications.onClosed.addListener(notificationClosed);
	chrome.notifications.onClicked.addListener(notificationClicked);
	chrome.notifications.onButtonClicked.addListener(notificationBtnClick);
});

// Create the notification with the given parameters as they are set in the UI
function doNotify(evt) {
	var path = chrome.runtime.getURL(asURLs[document.getElementById("img").options.selectedIndex]);
	var options = null;
	var sBtn1 = document.getElementById("btn1").value;
	var sBtn2 = document.getElementById("btn2").value;
	// Create the right notification for the selected type
	if (evt.srcElement.id == "basic") {
		options = notOptions[0];
	}
	else if (evt.srcElement.id == "image") {
		options = notOptions[1];
		options.imageUrl = chrome.runtime.getURL("/images/tahoe-320x215.png");
	}
	else if (evt.srcElement.id == "list") {
		options = notOptions[2];
	}
	else if (evt.srcElement.id == "progress") {
		options = notOptions[3];
	}

	options.iconUrl = path;
	// priority is from -2 to 2. The API makes no guarantee about how notifications are
	// visually handled by the OS - they simply represent hints that the OS can use to
	// order or display them however it wishes.
	options.priority = document.getElementById("pri").options.selectedIndex - 2;

	options.buttons = [];
	if (sBtn1.length)
		options.buttons.push({ title: sBtn1 });
	if (sBtn2.length)
		options.buttons.push({ title: sBtn2 });

    chrome.notifications.create("id"+notID++, options, creationCallback);
}

function creationCallback(notID) {
	console.log("Succesfully created " + notID + " notification");
	if(document.getElementById("clear").checked) {
      setTimeout(function() { chrome.notifications.clear(notID, function(wascleared){console.log("Notification cleared: "+wascleared)}) }, 3000);
	}
}

// Event handlers for the various notification events
function notificationClosed(notID, bByUser) {
	console.log("The notification '" + notID + "' was closed" + (bByUser ? " by the user" : ""));
}

function notificationClicked(notID) {
	console.log("The notification '" + notID + "' was clicked");
}

function notificationBtnClick(notID, iBtn) {
	console.log("The notification '" + notID + "' had button " + iBtn + " clicked");
}
<|endoftext|>


<commit_before>/*
 * match.js -- utility functions for matches and match lists
 * requires jquery
 **/

var courier = courier || {};

courier.matchlist = (function() { // begin courier namespace

function MatchList() {
  // represents a new match list. run populate(jq) to populate into a jquery
  // object.
  this.matches = {};
  this.matchDelCb = {};
  this.populating = false;
  this.newMatchCallback = undefined;
}
MatchList.prototype.populate = function(stream, cb) {
  // Get the list of matches, and run cb when we get them all.
  if (this.populating) {
    // we're already waiting!
    return false;
  }
  this.populating = true;
  var self = this;
  courier.core.ajaxRequest("/matches", {list: true},
    function(matchstate) {
      // retreive the list of matches
      for (var l=matchstate.matches.length, i=0; i < l; i++) {
        var m = new courier.match.Match(matchstate.matches[i]);
        self.newMatch(m);
      }
      if (typeof cb == 'function') {
        cb();
      }
      if (stream) {
        self.beginStream(matchstate.history);
      }
      // finish up; release the 'lock'
      self.populating = false;
    });
};
MatchList.prototype.beginStream = function(time) {
  // start streaming since 'time'
  var self = this;
  this.sh = new courier.core.StreamingHistory("/matches?history=t",
    time,
    function (action) {
      if ('added' in action) {
        self.newMatch(new courier.match.Match(action.added));
      } else if ('removed' in action) {
        self.removeMatch(self.matches[action.removed]);
      }
    });
};
MatchList.prototype.stopStream = function() {
  // stop streaming
  if (this.sh !== undefined) {
    this.sh.stop();
  }
};
MatchList.prototype.newMatch = function(match) {
  // add the match to us
  this.matches[match.mid] = match;
  if (typeof this.newMatchCallback == 'function') {
    this.newMatchCallback(match);
  }
};
MatchList.prototype.removeMatch = function(match) {
  // delete the given match.
  if (typeof this.matchDelCb[match.mid] == 'function') {
    this.matchDelCb[match.mid](match);
  }
  delete this.matches[match.mid];
};
MatchList.prototype.onNewMatch = function(cb) {
  // run the specified callback when a new match appears!
  this.newMatchCallback = cb;
};
MatchList.prototype.onMatchDelete = function(match, cb) {
  // be sure to run this callback when we delete a match.
  this.matchDelCb[match.mid] = cb;
};

function registerMatch(pub, speed, startTimeout, lockstep) {
  // Register a new match on the server.
  // pub: Whether to show the match on the server list.
  // speed: how fast (in seconds) each step should be
  // startTimeout: how long to wait until we start
  // lockstep: whether to immediately step if all the robots have an action
  //   queued
  // you can also pass a callback: run this function when the match is
  //   registered. we'll pass a match object and the auth code in there
  //   for you.
  var cb;
  if (arguments.length > 0 && typeof arguments[arguments.length-1] == 'function') {
    cb = arguments[arguments.length-1];
  } else {
    cb = undefined;
  }
  courier.core.ajaxRequest("/matches?register=t",
      {'public': typeof pub != 'function'? pub : undefined,
        'speed': typeof speed != 'function'? speed : undefined,
        'start_timeout': typeof startTimeout != 'function'? startTimeout : undefined,
        'lockstep': typeof lockstep != 'function'? lockstep : undefined},
      function(data) {
        if (cb) {
          cb(new courier.match.Match(data.match), data.auth_code);
        }
      });
}

// public methods
return {
  MatchList: MatchList,
  registerMatch: registerMatch
};

})();  // end courier namespace
<commit_msg>We now use events instead of callbacks in the match list<commit_after>/*
 * match.js -- utility functions for matches and match lists
 * requires jquery
 **/

var courier = courier || {};

courier.matchlist = (function() { // begin courier namespace

function MatchList() {
  // represents a new match list. run populate(jq) to populate into a jquery
  // object.
  courier.core.EventEmitter.call(this);
  this.matches = {};
  this.matchDelCb = {};
  this.populating = false;
}
courier.core.inherits(MatchList, courier.core.EventEmitter);

MatchList.prototype.populate = function(stream, cb) {
  // Get the list of matches, and run cb when we get them all.
  if (this.populating) {
    // we're already waiting!
    return false;
  }
  this.populating = true;
  var self = this;
  courier.core.ajaxRequest("/matches", {list: true},
    function(matchstate) {
      // retreive the list of matches
      for (var l=matchstate.matches.length, i=0; i < l; i++) {
        var m = new courier.match.Match(matchstate.matches[i]);
        self.newMatch(m);
      }
      if (typeof cb == 'function') {
        cb();
      }
      if (stream) {
        self.beginStream(matchstate.history);
      }
      // finish up; release the 'lock'
      self.populating = false;
    });
};
MatchList.prototype.beginStream = function(time) {
  // start streaming since 'time'
  var self = this;
  this.sh = new courier.core.StreamingHistory("/matches?history=t",
    time,
    function (action) {
      if ('added' in action) {
        self.newMatch(new courier.match.Match(action.added));
      } else if ('removed' in action) {
        self.removeMatch(self.matches[action.removed]);
      }
    });
};
MatchList.prototype.stopStream = function() {
  // stop streaming
  if (this.sh !== undefined) {
    this.sh.stop();
  }
};
MatchList.prototype.newMatch = function(match) {
  // add the match to us
  this.matches[match.mid] = match;
  this.emit('newMatch', this, match);
};
MatchList.prototype.removeMatch = function(match) {
  // delete the given match.
  delete this.matches[match.mid];
  this.emit('removeMatch', match);
};

function registerMatch(pub, speed, startTimeout, lockstep) {
  // Register a new match on the server.
  // pub: Whether to show the match on the server list.
  // speed: how fast (in seconds) each step should be
  // startTimeout: how long to wait until we start
  // lockstep: whether to immediately step if all the robots have an action
  //   queued
  // you can also pass a callback: run this function when the match is
  //   registered. we'll pass a match object and the auth code in there
  //   for you.
  var cb;
  if (arguments.length > 0 && typeof arguments[arguments.length-1] == 'function') {
    cb = arguments[arguments.length-1];
  } else {
    cb = undefined;
  }
  courier.core.ajaxRequest("/matches?register=t",
      {'public': typeof pub != 'function'? pub : undefined,
        'speed': typeof speed != 'function'? speed : undefined,
        'start_timeout': typeof startTimeout != 'function'? startTimeout : undefined,
        'lockstep': typeof lockstep != 'function'? lockstep : undefined},
      function(data) {
        if (cb) {
          cb(new courier.match.Match(data.match), data.auth_code);
        }
      });
}

// public methods
return {
  MatchList: MatchList,
  registerMatch: registerMatch
};

})();  // end courier namespace
<|endoftext|>


<commit_before>angular.module('classeur.blogs.github', [])
  .directive('clGithubBlogForm',
    function () {
      return {
        restrict: 'E',
        templateUrl: 'blogs/github/githubBlogForm.html'
      }
    })
  .directive('clGithubBlogPostEntry',
    function () {
      return {
        restrict: 'E',
        templateUrl: 'blogs/github/githubBlogPostEntry.html'
      }
    })
  .directive('clGithubBlogPostForm',
    function () {
      return {
        restrict: 'E',
        templateUrl: 'blogs/github/githubBlogPostForm.html'
      }
    })
  .factory('clGithubBlogPlatform',
    function (clBlogPlatform, clConfig) {
      var clGithubBlogPlatform = clBlogPlatform({
        id: 'github',
        name: 'GitHub',
        authorizeUrl: 'https://github.com/login/oauth/authorize'
      })

      function serializeRepoUrl (blog) {
        return 'https://github.com/' + blog.user + '/' + blog.repo
      }

      clGithubBlogPlatform.defaultBlogSubForm = {
        privateRepo: true
      }

      clGithubBlogPlatform.fillBlogSubForm = function (subForm) {
        if (subForm.user && subForm.repo) {
          subForm.repoUrl = serializeRepoUrl(subForm)
        }
      }

      clGithubBlogPlatform.createBlogFromSubForm = function (subForm) {
        if (!subForm.repoUrl) {
          throw new Error('Repository URL is required.')
        }
        var parsedRepo = subForm.repoUrl.match(/[\/:]?([^\/:]+)\/([^\/]+?)(?:\.git)?$/)
        if (!parsedRepo) {
          throw new Error('Invalid repository URL format.')
        }
        var blog = {
          repo: parsedRepo[2],
          user: parsedRepo[1],
          privateRepo: subForm.privateRepo
        }
        if (blog.repo.length > 128 || blog.user.length > 128) {
          throw new Error('Repository URL is too long.')
        }
        return blog
      }

      clGithubBlogPlatform.defaultPostSubForm = {
        branch: 'master'
      }

      clGithubBlogPlatform.fillPostSubForm = function (blog, subForm) {
        subForm.repoUrl = serializeRepoUrl(blog)
      }

      clGithubBlogPlatform.createPostFromSubForm = function (subForm) {
        if (!subForm.branch) {
          throw new Error('Branch is required.')
        }
        if (subForm.branch.length > 128) {
          throw new Error('Branch name is too long.')
        }
        if (!subForm.filePath) {
          throw new Error('File path is required.')
        }
        if (subForm.filePath.length > 512) {
          throw new Error('File path is too long.')
        }
        return {
          branch: subForm.branch,
          filePath: subForm.filePath
        }
      }

      clGithubBlogPlatform.getAuthorizeParams = function (blog) {
        return {
          client_id: clConfig.githubClientId,
          response_type: 'code',
          redirect_uri: clConfig.appUri + '/oauth/github/callback',
          scope: blog.private ? 'repo' : 'public_repo'
        }
      }

      clGithubBlogPlatform.getBlogPostLocation = function (blogPost) {
        var result = [
          'https://github.com',
          blogPost.blog.user,
          blogPost.blog.repo,
          'blob',
          blogPost.branch
        ]
        return result.concat(blogPost.filePath.split('/').cl_map(encodeURIComponent)).join('/')
      }

      return clGithubBlogPlatform
    })
<commit_msg>Fixed GitHub private repo linking. Fixes #60<commit_after>angular.module('classeur.blogs.github', [])
  .directive('clGithubBlogForm',
    function () {
      return {
        restrict: 'E',
        templateUrl: 'blogs/github/githubBlogForm.html'
      }
    })
  .directive('clGithubBlogPostEntry',
    function () {
      return {
        restrict: 'E',
        templateUrl: 'blogs/github/githubBlogPostEntry.html'
      }
    })
  .directive('clGithubBlogPostForm',
    function () {
      return {
        restrict: 'E',
        templateUrl: 'blogs/github/githubBlogPostForm.html'
      }
    })
  .factory('clGithubBlogPlatform',
    function (clBlogPlatform, clConfig) {
      var clGithubBlogPlatform = clBlogPlatform({
        id: 'github',
        name: 'GitHub',
        authorizeUrl: 'https://github.com/login/oauth/authorize'
      })

      function serializeRepoUrl (blog) {
        return 'https://github.com/' + blog.user + '/' + blog.repo
      }

      clGithubBlogPlatform.defaultBlogSubForm = {
        privateRepo: true
      }

      clGithubBlogPlatform.fillBlogSubForm = function (subForm) {
        if (subForm.user && subForm.repo) {
          subForm.repoUrl = serializeRepoUrl(subForm)
        }
      }

      clGithubBlogPlatform.createBlogFromSubForm = function (subForm) {
        if (!subForm.repoUrl) {
          throw new Error('Repository URL is required.')
        }
        var parsedRepo = subForm.repoUrl.match(/[\/:]?([^\/:]+)\/([^\/]+?)(?:\.git)?$/)
        if (!parsedRepo) {
          throw new Error('Invalid repository URL format.')
        }
        var blog = {
          repo: parsedRepo[2],
          user: parsedRepo[1],
          privateRepo: subForm.privateRepo
        }
        if (blog.repo.length > 128 || blog.user.length > 128) {
          throw new Error('Repository URL is too long.')
        }
        return blog
      }

      clGithubBlogPlatform.defaultPostSubForm = {
        branch: 'master'
      }

      clGithubBlogPlatform.fillPostSubForm = function (blog, subForm) {
        subForm.repoUrl = serializeRepoUrl(blog)
      }

      clGithubBlogPlatform.createPostFromSubForm = function (subForm) {
        if (!subForm.branch) {
          throw new Error('Branch is required.')
        }
        if (subForm.branch.length > 128) {
          throw new Error('Branch name is too long.')
        }
        if (!subForm.filePath) {
          throw new Error('File path is required.')
        }
        if (subForm.filePath.length > 512) {
          throw new Error('File path is too long.')
        }
        return {
          branch: subForm.branch,
          filePath: subForm.filePath
        }
      }

      clGithubBlogPlatform.getAuthorizeParams = function (blog) {
        return {
          client_id: clConfig.githubClientId,
          response_type: 'code',
          redirect_uri: clConfig.appUri + '/oauth/github/callback',
          scope: blog.privateRepo ? 'repo' : 'public_repo'
        }
      }

      clGithubBlogPlatform.getBlogPostLocation = function (blogPost) {
        var result = [
          'https://github.com',
          blogPost.blog.user,
          blogPost.blog.repo,
          'blob',
          blogPost.branch
        ]
        return result.concat(blogPost.filePath.split('/').cl_map(encodeURIComponent)).join('/')
      }

      return clGithubBlogPlatform
    })
<|endoftext|>


<commit_before>/*
Copyright 2015 Johannes Filter, Rosario Raulin

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

var request = require('request').defaults({'proxy':'http://188.72.126.165:8085'});
var async = require('async');

var QUERY_PATH_BASE = 'http://reiseauskunft.insa.de/bin/query.exe/dny?performLocating=2&tpl=stop2json&look_maxno=20';
var QUERY_JOURNEYS_PATH_BASE = 'http://reiseauskunft.insa.de/bin/stboard.exe/dn?L=.vs_stb&L=.vs_stb.vs_stb&boardType=dep&selectDate=today&productsFilter=0000011111&additionalTime=0&start=yes&requestType=0&outputMode=undefined&maxJourneys=30';

var decodeHtmlEntity = function(str) {
  return str.replace(/&#(\d+);/g, function(match, dec) {
    return String.fromCharCode(dec);
  });
};

var removeCityNames = function(str) {
  return str.replace('Magdeburg, ','').replace('Halle (Saale), ', '').replace('Leipzig, ','');
};

var parseHtmlBodyToJSON = function(body) {
  var bodyString = body.toString('utf-8');
  var bodyStringDecoded = decodeHtmlEntity(bodyString).replace('journeysObj = ','');

  return JSON.parse(bodyStringDecoded);
};

var getDateFromInsaDate = function(insaDate) {
  var currentDate = new Date();
  var departureDate = new Date();
  var splittedDateInput = insaDate.split(':');

  departureDate.setMinutes(parseInt(splittedDateInput[1]));
  departureDate.setHours(parseInt(splittedDateInput[0]));

  if ( departureDate < currentDate ) {
    departureDate.setDate(departureDate.getDate() + 1); // increment by one day
  }

  return departureDate;
};

//TODO refactor
var getJourneyRequestCallback = function(name, callback) {
  return function (err, resp, body) {
    if (err) {
      callback(err, null);

    } else {

      var bodyJSON = parseHtmlBodyToJSON(body);
      var times = [];

      // return if no journeys are present
      if( !bodyJSON.hasOwnProperty('journey') ) {
        callback(null, times);

      } else {
        var journeys = bodyJSON.journey;

        for ( i = 0; i < journeys.length; i++ ) {
          var curRow = journeys[i];

          // taking care of wrongly inserted journeys
          if ( curRow.pr !== "" && curRow.st !== "" && curRow.ti !== "" ) {

            // INSA format of Date
            var insaDate = curRow.ti;

            var obj = {
              "line": curRow.pr,
              "direction": removeCityNames(curRow.st),
            };

            //FIX Confusing use of '!'.
            if (! curRow.rt === false) {
              obj['delay'] = {};

              if ( curRow.rt.dlm != null) {
                obj['delay']['minutes'] = curRow.rt.dlm;
              }

              if ( curRow.rt.status != null) {
                obj['delay']['status'] = curRow.rt.status;
              }

              // override original departure
              if ( curRow.rt.dlt != null) {
                insaDate = curRow.rt.dlt;
              }
            }

            var departureDate = getDateFromInsaDate(insaDate);
            obj['departure'] = departureDate.toJSON();
            times.push( obj );
          }
        }

        // Sorting because INSA don't provide it sorted
        // Compare on Dates
        times.sort(function(a, b) {
          return a.departure.localeCompare(b.departure);
        });

        callback(null, { station_info: name, departure_times: times });
      }
    }
  };
};

var getJourneyQueryPath = function(stationID) {
  var current_date = new Date();
  var string_date = current_date.getHours() + ':' + current_date.getMinutes();

  return QUERY_JOURNEYS_PATH_BASE + '&input='+ stationID + '&time=' + string_date;
};

// get journeys of one station
// productFilter= masking out ICE/IC/RE/RB/S/U
var getJourneys = function (station, callback) {
  var name = removeCityNames(station.name);
  var path = getJourneyQueryPath(station.id);

  //TODO refactor callbacks. Maybe Q Library?
  request(path, {encoding: null}, getJourneyRequestCallback(name, callback));
};

var getFormatedCoordinate = function(coordinate) {
  // The geolocations are requiered in a specific format
  // without points and only 8 digits
  var formattedCoordinate = coordinate.replace('.', '');

  while ( formattedCoordinate.length < 8 ) {
    formattedCoordinate += '0';
  }

  formattedCoordinate = formattedCoordinate.substring(0, 8);

  return formattedCoordinate;
};

// Filter out stations for IC/RB/RE/S-Bahn/U-Bahn
var getFilteredStations = function(stations) {
  var stationsWithId = [];

  for(i = 0; i < stations.length; i++) {
    if ( parseInt(stations[i].prodclass) > 31 ) {
      stationsWithId.push( {id: stations[i].extId, name: stations[i].name} );
    }
  }

  return stationsWithId;
};

var getRequestCallback = function(callback){
  return function (err, resp, body) {

      if (err) {
        callback(err, null);

      } else {
        try {
          var bodyJSON = JSON.parse(body);
          var stations = bodyJSON.stops;
          var stationsWithId = getFilteredStations(stations);

          // look for journeys of each stations
          async.map ( stationsWithId,
            // for each id
            getJourneys,
            // results saved here
            function(err, times){
              callback(null, times);
            });
        } catch (e) {
          callback(err, []); // return empty error
        }
      }
  };
};

var getQueryPath = function(longitude, latitude) {
  var formattedLongitude = getFormatedCoordinate(longitude);
  var formattedLatitude = getFormatedCoordinate(latitude);

  return QUERY_PATH_BASE + '&look_x=' + formattedLongitude + '&look_y=' + formattedLatitude;
};

var getDepartureTimes = function (long, lat, callback) {
  var path = getQueryPath(long, lat);

  //TODO refactor callbacks. Maybe Q Library?
  request(path, {encoding: null}, getRequestCallback(callback));
};

module.exports = {
  get_departure_times: getDepartureTimes
};
<commit_msg>updating proxy<commit_after>/*
Copyright 2015 Johannes Filter, Rosario Raulin

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

var request = require('request').defaults({'proxy':'188.72.126.231:8085'});
var async = require('async');

var QUERY_PATH_BASE = 'http://reiseauskunft.insa.de/bin/query.exe/dny?performLocating=2&tpl=stop2json&look_maxno=20';
var QUERY_JOURNEYS_PATH_BASE = 'http://reiseauskunft.insa.de/bin/stboard.exe/dn?L=.vs_stb&L=.vs_stb.vs_stb&boardType=dep&selectDate=today&productsFilter=0000011111&additionalTime=0&start=yes&requestType=0&outputMode=undefined&maxJourneys=30';

var decodeHtmlEntity = function(str) {
  return str.replace(/&#(\d+);/g, function(match, dec) {
    return String.fromCharCode(dec);
  });
};

var removeCityNames = function(str) {
  return str.replace('Magdeburg, ','').replace('Halle (Saale), ', '').replace('Leipzig, ','');
};

var parseHtmlBodyToJSON = function(body) {
  var bodyString = body.toString('utf-8');
  var bodyStringDecoded = decodeHtmlEntity(bodyString).replace('journeysObj = ','');

  return JSON.parse(bodyStringDecoded);
};

var getDateFromInsaDate = function(insaDate) {
  var currentDate = new Date();
  var departureDate = new Date();
  var splittedDateInput = insaDate.split(':');

  departureDate.setMinutes(parseInt(splittedDateInput[1]));
  departureDate.setHours(parseInt(splittedDateInput[0]));

  if ( departureDate < currentDate ) {
    departureDate.setDate(departureDate.getDate() + 1); // increment by one day
  }

  return departureDate;
};

//TODO refactor
var getJourneyRequestCallback = function(name, callback) {
  return function (err, resp, body) {
    if (err) {
      callback(err, null);

    } else {

      var bodyJSON = parseHtmlBodyToJSON(body);
      var times = [];

      // return if no journeys are present
      if( !bodyJSON.hasOwnProperty('journey') ) {
        callback(null, times);

      } else {
        var journeys = bodyJSON.journey;

        for ( i = 0; i < journeys.length; i++ ) {
          var curRow = journeys[i];

          // taking care of wrongly inserted journeys
          if ( curRow.pr !== "" && curRow.st !== "" && curRow.ti !== "" ) {

            // INSA format of Date
            var insaDate = curRow.ti;

            var obj = {
              "line": curRow.pr,
              "direction": removeCityNames(curRow.st),
            };

            //FIX Confusing use of '!'.
            if (! curRow.rt === false) {
              obj['delay'] = {};

              if ( curRow.rt.dlm != null) {
                obj['delay']['minutes'] = curRow.rt.dlm;
              }

              if ( curRow.rt.status != null) {
                obj['delay']['status'] = curRow.rt.status;
              }

              // override original departure
              if ( curRow.rt.dlt != null) {
                insaDate = curRow.rt.dlt;
              }
            }

            var departureDate = getDateFromInsaDate(insaDate);
            obj['departure'] = departureDate.toJSON();
            times.push( obj );
          }
        }

        // Sorting because INSA don't provide it sorted
        // Compare on Dates
        times.sort(function(a, b) {
          return a.departure.localeCompare(b.departure);
        });

        callback(null, { station_info: name, departure_times: times });
      }
    }
  };
};

var getJourneyQueryPath = function(stationID) {
  var current_date = new Date();
  var string_date = current_date.getHours() + ':' + current_date.getMinutes();

  return QUERY_JOURNEYS_PATH_BASE + '&input='+ stationID + '&time=' + string_date;
};

// get journeys of one station
// productFilter= masking out ICE/IC/RE/RB/S/U
var getJourneys = function (station, callback) {
  var name = removeCityNames(station.name);
  var path = getJourneyQueryPath(station.id);

  //TODO refactor callbacks. Maybe Q Library?
  request(path, {encoding: null}, getJourneyRequestCallback(name, callback));
};

var getFormatedCoordinate = function(coordinate) {
  // The geolocations are requiered in a specific format
  // without points and only 8 digits
  var formattedCoordinate = coordinate.replace('.', '');

  while ( formattedCoordinate.length < 8 ) {
    formattedCoordinate += '0';
  }

  formattedCoordinate = formattedCoordinate.substring(0, 8);

  return formattedCoordinate;
};

// Filter out stations for IC/RB/RE/S-Bahn/U-Bahn
var getFilteredStations = function(stations) {
  var stationsWithId = [];

  for(i = 0; i < stations.length; i++) {
    if ( parseInt(stations[i].prodclass) > 31 ) {
      stationsWithId.push( {id: stations[i].extId, name: stations[i].name} );
    }
  }

  return stationsWithId;
};

var getRequestCallback = function(callback){
  return function (err, resp, body) {

      if (err) {
        callback(err, null);

      } else {
        try {
          var bodyJSON = JSON.parse(body);
          var stations = bodyJSON.stops;
          var stationsWithId = getFilteredStations(stations);

          // look for journeys of each stations
          async.map ( stationsWithId,
            // for each id
            getJourneys,
            // results saved here
            function(err, times){
              callback(null, times);
            });
        } catch (e) {
          callback(err, []); // return empty error
        }
      }
  };
};

var getQueryPath = function(longitude, latitude) {
  var formattedLongitude = getFormatedCoordinate(longitude);
  var formattedLatitude = getFormatedCoordinate(latitude);

  return QUERY_PATH_BASE + '&look_x=' + formattedLongitude + '&look_y=' + formattedLatitude;
};

var getDepartureTimes = function (long, lat, callback) {
  var path = getQueryPath(long, lat);

  //TODO refactor callbacks. Maybe Q Library?
  request(path, {encoding: null}, getRequestCallback(callback));
};

module.exports = {
  get_departure_times: getDepartureTimes
};
<|endoftext|>


<commit_before>;
if (typeof jQuery === 'undefined') {
	throw new Error("InputFilter's JavaScript requires jQuery");
}
(function($, win, doc, undefined) {
	'use strict';

	var InputFilter = function(element, options) {
		this.options = options;
		this.element = element;
	};
	InputFilter.prototype = {
		digitFilter: function() {
			var value = this.element.value,
				options = this.options;
			if (value === undefined) {
				this.element.value = "";
				return false;
			} else if (value === "") {
				return false;
			} else if (!/^[1-9]\d*$/.test(value) || value > options.max) {
				//如果输出不符合预期，则进行过滤
				value = value.replace(/[^\d]+/g, "");
                console.info("done");
				if (options.min !== null && value < options.min) {
					value = options.min;
				}
				if (options.max !== null && value > options.max) {
					value = options.max;
				}
				this.element.value = value;
				return false;
			}
			return true;
		},
		alphaFilter: function() {
			var value = this.element.value,
				options = this.options;
			if (value === undefined) {
				this.element.value = "";
				return false;
			} else if (value === "") {
				return false;
			} else {
				var reg;
				if (options.uppercase && options.lowercase) {
					reg = /[^A-Za-z]+/g;
				} else if (options.uppercase && !options.lowercase) {
					reg = /[^A-Z]+/g;
				} else {
					reg = /[^a-z]+/g;
				}
				if (reg.test(value) && value !== "") {
					value = value.replace(reg, "");
					if (options.transform === "uppercase") {
						value = value.toUpperCase();
					} else if (options.transform === "lowercase") {
						value = value.toLowerCase();
					}
					this.element.value = value;
					return false;
				} else if (typeof options.length === "number" && value.length > options.length) {
					this.element.value = value.slice(0, options.length);
					return false;
				}
			}
			return true;
		},
		alnumFilter: function() {
			var value = this.element.value,
				options = this.options;
			if (value === undefined) {
				this.element.value = "";
				return false;
			} else if (value === "") {
				return false;
			} else {
				var reg;
				if (options.uppercase && options.lowercase) {
					reg = /[^A-Za-z0-9]+/g;
				} else if (options.uppercase && !options.lowercase) {
					reg = /[^A-Z0-9]+/g;
				} else {
					reg = /[^a-z0-9]+/g;
				}
				if (reg.test(value)) {
					value = value.replace(reg, "");
					if (options.transform === "uppercase") {
						value = value.toUpperCase();
					} else if (options.transform === "lowercase") {
						value = value.toLocaleLowerCase();
					}
					if (typeof options.length === "number") {
						value = value.slice(0, options.length);
					}
					this.element.value = value;
					return false;
				} else if (typeof options.length === "number" && value.length > options.length) {
					this.element.value = value.slice(0, options.length);
					return false;
				}
			}
			return true;
		}
	};

	$.fn.inputFilter = function(options) {
		options = $.extend({}, $.fn.inputFilter.options, options || {});
		var elements = this;
		return elements.each(function() {
			var element = this,
				valueChange = options.valueChange,
				inputFilter = new InputFilter(element, options),
				eventHandler = function() {
					//inputFilter[options.type + "Filter"]()第一次执行永远返回true
					//如果有第二次，则返回false
					//以此限制valueChange()只能执行一次
					if ("\v" === "v") {
						if (inputFilter[options.type + "Filter"]()) {
							valueChange(element, element.value);
						}
					} else {
						inputFilter[options.type + "Filter"]();
						valueChange(element, element.value);
					}
				};
			try {
				if (element.tagName !== "INPUT" || element.type === "checkbox" || element.type === "radio") {
					throw new TypeError("The Element is not sport this plugin");
				}
				if (element.addEventListener) {
					element.addEventListener("input", eventHandler, false);
				} else {
					element.attachEvent("onpropertychange", function() {
						return eventHandler.call(element);
					});
				}
			} catch (e) {
				console.error(e.name + ": " + e.message);
			}
			return this;
		});
	};
	$.fn.inputFilter.options = {
		"type": "alnum",
		"length": null,
		"min": 0,
		"max": Infinity,
		"uppercase": true,
		"lowercase": true,
		"transform": null, //也可以通过样式控制
		"valueChange": function(element, value) {}
	};
})(jQuery, window, document);<commit_msg>FixBug<commit_after>;if (typeof jQuery === 'undefined') {
	throw new Error("InputFilter's JavaScript requires jQuery");
}
(function($, win, doc, undefined) {
	'use strict';

	var InputFilter = function(element, options) {
		this.options = options;
		this.element = element;
	};
	InputFilter.prototype = {
		digitFilter: function() {
			var value = this.element.value,
				options = this.options,
				max = parseInt(options.max),
				min = parseInt(options.min);
			if (value === undefined) {
				this.element.value = "";
				return false;
			} else if (value === "") {
				return false;
			} else if (!/^[1-9]\d*$/.test(value) || value > max) {
				//如果输出不符合预期，则进行过滤
				value = value.replace(/[^\d]+/g, "");
				if (min !== null && min !== NaN && value < min) {
					value = min;
				}
				if (max !== null && max !== NaN && value > max) {
					value = max;
				}
				this.element.value = value;
				return false;
			}
			return true;
		},
		alphaFilter: function() {
			var value = this.element.value,
				options = this.options;
			if (value === undefined) {
				this.element.value = "";
				return false;
			} else if (value === "") {
				return false;
			} else {
				var reg;
				if (options.uppercase && options.lowercase) {
					reg = /[^A-Za-z]+/g;
				} else if (options.uppercase && !options.lowercase) {
					reg = /[^A-Z]+/g;
				} else {
					reg = /[^a-z]+/g;
				}
				if (reg.test(value) && value !== "") {
					value = value.replace(reg, "");
					if (options.transform === "uppercase") {
						value = value.toUpperCase();
					} else if (options.transform === "lowercase") {
						value = value.toLowerCase();
					}
					this.element.value = value;
					return false;
				} else if (typeof parseInt(options.length) !== NaN && value.length > options.length) {
					this.element.value = value.slice(0, options.length);
					return false;
				}
			}
			return true;
		},
		alnumFilter: function() {
			var value = this.element.value,
				options = this.options;
			if (value === undefined) {
				this.element.value = "";
				return false;
			} else if (value === "") {
				return false;
			} else {
				var reg;
				if (options.uppercase && options.lowercase) {
					reg = /[^A-Za-z0-9]+/g;
				} else if (options.uppercase && !options.lowercase) {
					reg = /[^A-Z0-9]+/g;
				} else {
					reg = /[^a-z0-9]+/g;
				}
				if (reg.test(value)) {
					value = value.replace(reg, "");
					if (options.transform === "uppercase") {
						value = value.toUpperCase();
					} else if (options.transform === "lowercase") {
						value = value.toLocaleLowerCase();
					}
					if (typeof parseInt(options.length) !== NaN) {
						value = value.slice(0, options.length);
					}
					this.element.value = value;
					return false;
				} else if (typeof parseInt(options.length) !== NaN && value.length > options.length) {
					this.element.value = value.slice(0, options.length);
					return false;
				}
			}
			return true;
		}
	};

	$.fn.inputFilter = function(options) {
		options = $.extend({}, $.fn.inputFilter.options, options || {});
		var elements = this;
		return elements.each(function() {
			var element = this,
				valueChange = options.valueChange,
				inputFilter = new InputFilter(element, options),
				eventHandler = function() {
					//inputFilter[options.type + "Filter"]()第一次执行永远返回true
					//如果有第二次，则返回false
					//以此限制valueChange()只能执行一次
					if ("\v" === "v") {
						if (inputFilter[options.type + "Filter"]()) {
							valueChange(element, element.value);
						}
					} else {
						inputFilter[options.type + "Filter"]();
						valueChange(element, element.value);
					}
				};
			try {
				if (element.tagName !== "INPUT" || element.type === "checkbox" || element.type === "radio") {
					throw new TypeError("The Element is not sport this plugin");
				}
				if (element.addEventListener) {
					element.addEventListener("input", eventHandler, false);
				} else {
					element.attachEvent("onpropertychange", function() {
						return eventHandler.call(element);
					});
				}
			} catch (e) {
				console.error(e.name + ": " + e.message);
			}
			return this;
		});
	};
	$.fn.inputFilter.options = {
		"type": "alnum",
		"length": null,
		"min": 0,
		"max": Infinity,
		"uppercase": true,
		"lowercase": true,
		"transform": null, //也可以通过样式控制
		"valueChange": function(element, value) {}
	};
})(jQuery, window, document);<|endoftext|>