<commit_before>/**
 * Copyright 2016 Google Inc.
 *
 * 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.
 */

/* @flow */

import * as bb from 'bluebird';
import * as git from '../../src/git';
import {PullRequest, Label, Sender} from '../../src/github';
import {findOwnersUsernames} from '../../src/owner';
import * as crypto from 'crypto';
import * as express from 'express';
const config = require('../../config');
const GITHUB_REPO_DIR = config.get('GITHUB_REPO_DIR');
const GITHUB_BOT_USERNAME = config.get('GITHUB_BOT_USERNAME');
const SECRET_TOKEN = config.get('SECRET_TOKEN');

export const router = express.Router();

const prActionTypes: string[] = [
  'opened',
  'reopened',
  'created',
  'synchronize',
  'labeled',
  'unlabeled',
];

function getOwners(pr: PullRequest) : Promise<string[]> {
  return git.pullLatestForRepo(GITHUB_REPO_DIR, 'origin', 'master').then(() => {
    const promises = bb.all([
      pr.getFiles(),
      git.getOwnersFilesForBranch(pr.author, GITHUB_REPO_DIR, 'master'),
    ]);
    return promises.then(function(res) {
      const files = res[0];
      const ownersMap = res[1];
      return findOwnersUsernames(files, ownersMap);
    });
  });
}

function verifySignature(body: string, signature: string): bool {
  try {
    const hash = 'sha1=' + crypto.createHmac('sha1', SECRET_TOKEN)
        .update(body).digest('hex');
    return crypto.timingSafeEqual(new Buffer(hash), new Buffer(signature));
  } catch (e) {
    return false;
  }
}

router.post('/', function(req, res) {
  const signature = req.get('X-Hub-Signature') || '';
  // FIX: since we need to convert back to a string, maybe disable
  // the json body parser and parse it ourselves.
  if (process.env.NODE_ENV === 'production' &&
      (!signature || !verifySignature(JSON.stringify(req.body), signature))) {
    return res.status(500).send('Signature didn\'t match!');
  }

  const body = req.body;
  if (body && body.pull_request) {
    if (prActionTypes.indexOf(body.action) !== -1) {
      const pr = new PullRequest(body.pull_request);
      // Exclude the bot name from any reviews.
      // Temporarily only turn on for @erwinmombay and @dvoytenko
      const authorWhitelist = ['erwinmombay'];
      if (pr.author === GITHUB_BOT_USERNAME ||
            authorWhitelist.indexOf(pr.author) === -1) {
        return res.status(200).send('ok');
      }
      return tryPostStatus(res, body, pr).then(() => {
        return res.status(200).send('ok');
      });
    }
  }
  return res.status(200).send('ok');
});

function tryPostStatus(res: *, body: *, pr: PullRequest): Promise<*> {
  return getOwners(pr).then(usernames => {
    if (body.action === 'labeled') {
      const label = new Label(body.label);
      const sender = new Sender(body.sender);
      if (label.name.toLowerCase() === 'approved' &&
          usernames.indexOf(`@${sender.username}`) > -1) {
        return pr.setApprovedStatus();
      }
    } else if (body.action === 'unlabeled') {
      const label = new Label(body.label);
      // If anybody removed the approved label, automatically fail the PR again
      // this is so that we don't get into a weird state were somebody removed
      // the approved label but are still green. I'd rather fail it again.
      if (label.name.toLowerCase() === 'approved') {
        return pr.setFailureStatus();
      }
    } else if (usernames.indexOf(`@${pr.author}`) > -1) {
      return pr.setApprovedStatus();
    }
    return maybePostApproversComment(res, pr, usernames);
  }).catch(() => {
    res.status(500).send('E2: Something went wrong.');
  });
}

function maybePostApproversComment(res: *, pr: PullRequest,
    usernames: string[]): Promise<*>|void {
  const body = composeBotComment(usernames);
  return pr.findLastApproversList(GITHUB_BOT_USERNAME).then(approvers => {
    if (approvers.length) {
      // If the bot commented and the last approvers list it posted
      // is not the same as the current one we need to post a new list
      // of approvers.
      if (usernames.length === approvers.length &&
          usernames.every((v, i) => v === approvers[i])) {
        return pr.postIssuesComment(body).then(() => {
          return pr.setFailureStatus();
        });
      }
      // This means the lastApproversList is the same and we don't need to
      // do anything.
      return;
    }
    // This is the first time the bot is posting a list of approvers.
    return pr.postIssuesComment(body).then(() => {
      return pr.setFailureStatus();
    });
  });
}

function composeBotComment(usernames: string[]): string {
  const curApproversList = `/to ${usernames.join(',')}`;
  const prefix = 'Here is a list of owners that can approve this PR:\n\n';
  const suffix = '\n\nOwners can approve through the "APPROVED" label. ' +
      'If the author of the PR is an owner of the files or directory, ' +
      'the PR will be approved right away.';
  return `${prefix}${curApproversList}${suffix}`;
}
<commit_msg>should only post if NOT every username is the same.<commit_after>/**
 * Copyright 2016 Google Inc.
 *
 * 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.
 */

/* @flow */

import * as bb from 'bluebird';
import * as git from '../../src/git';
import {PullRequest, Label, Sender} from '../../src/github';
import {findOwnersUsernames} from '../../src/owner';
import * as crypto from 'crypto';
import * as express from 'express';
const config = require('../../config');
const GITHUB_REPO_DIR = config.get('GITHUB_REPO_DIR');
const GITHUB_BOT_USERNAME = config.get('GITHUB_BOT_USERNAME');
const SECRET_TOKEN = config.get('SECRET_TOKEN');

export const router = express.Router();

const prActionTypes: string[] = [
  'opened',
  'reopened',
  'created',
  'synchronize',
  'labeled',
  'unlabeled',
];

function getOwners(pr: PullRequest) : Promise<string[]> {
  return git.pullLatestForRepo(GITHUB_REPO_DIR, 'origin', 'master').then(() => {
    const promises = bb.all([
      pr.getFiles(),
      git.getOwnersFilesForBranch(pr.author, GITHUB_REPO_DIR, 'master'),
    ]);
    return promises.then(function(res) {
      const files = res[0];
      const ownersMap = res[1];
      return findOwnersUsernames(files, ownersMap);
    });
  });
}

function verifySignature(body: string, signature: string): bool {
  try {
    const hash = 'sha1=' + crypto.createHmac('sha1', SECRET_TOKEN)
        .update(body).digest('hex');
    return crypto.timingSafeEqual(new Buffer(hash), new Buffer(signature));
  } catch (e) {
    return false;
  }
}

router.post('/', function(req, res) {
  const signature = req.get('X-Hub-Signature') || '';
  // FIX: since we need to convert back to a string, maybe disable
  // the json body parser and parse it ourselves.
  if (process.env.NODE_ENV === 'production' &&
      (!signature || !verifySignature(JSON.stringify(req.body), signature))) {
    return res.status(500).send('Signature didn\'t match!');
  }

  const body = req.body;
  if (body && body.pull_request) {
    if (prActionTypes.indexOf(body.action) !== -1) {
      const pr = new PullRequest(body.pull_request);
      // Exclude the bot name from any reviews.
      // Temporarily only turn on for @erwinmombay and @dvoytenko
      const authorWhitelist = ['erwinmombay'];
      if (pr.author === GITHUB_BOT_USERNAME ||
            authorWhitelist.indexOf(pr.author) === -1) {
        return res.status(200).send('ok');
      }
      return tryPostStatus(res, body, pr).then(() => {
        return res.status(200).send('ok');
      });
    }
  }
  return res.status(200).send('ok');
});

function tryPostStatus(res: *, body: *, pr: PullRequest): Promise<*> {
  return getOwners(pr).then(usernames => {
    if (body.action === 'labeled') {
      const label = new Label(body.label);
      const sender = new Sender(body.sender);
      if (label.name.toLowerCase() === 'approved' &&
          usernames.indexOf(`@${sender.username}`) > -1) {
        return pr.setApprovedStatus();
      }
    } else if (body.action === 'unlabeled') {
      const label = new Label(body.label);
      // If anybody removed the approved label, automatically fail the PR again
      // this is so that we don't get into a weird state were somebody removed
      // the approved label but are still green. I'd rather fail it again.
      if (label.name.toLowerCase() === 'approved') {
        return pr.setFailureStatus();
      }
    } else if (usernames.indexOf(`@${pr.author}`) > -1) {
      return pr.setApprovedStatus();
    }
    return maybePostApproversComment(res, pr, usernames);
  }).catch(() => {
    res.status(500).send('E2: Something went wrong.');
  });
}

function maybePostApproversComment(res: *, pr: PullRequest,
    usernames: string[]): Promise<*>|void {
  const body = composeBotComment(usernames);
  return pr.findLastApproversList(GITHUB_BOT_USERNAME).then(approvers => {
    if (approvers.length) {
      // If the bot commented and the last approvers list it posted
      // is not the same as the current one we need to post a new list
      // of approvers.
      if (!(usernames.length === approvers.length &&
          usernames.every((v, i) => v === approvers[i]))) {
        return pr.postIssuesComment(body).then(() => {
          return pr.setFailureStatus();
        });
      }
      // This means the lastApproversList is the same and we don't need to
      // do anything.
      return;
    }
    // This is the first time the bot is posting a list of approvers.
    return pr.postIssuesComment(body).then(() => {
      return pr.setFailureStatus();
    });
  });
}

function composeBotComment(usernames: string[]): string {
  const curApproversList = `/to ${usernames.join(',')}`;
  const prefix = 'Here is a list of owners that can approve this PR:\n\n';
  const suffix = '\n\nOwners can approve through the "APPROVED" label. ' +
      'If the author of the PR is an owner of the files or directory, ' +
      'the PR will be approved right away.';
  return `${prefix}${curApproversList}${suffix}`;
}
<|endoftext|>


<commit_before>const InlineChunkWebpackPlugin = require('html-webpack-inline-chunk-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const webpack = require('webpack');
const path = require('path');

module.exports = {
  entry: {
    main: './app/js/app.jsx',
    vendor: [
      'redux',
      'react-redux',
      'react-router',
      'react-router-dom',
      'react',
      'react-dom',
    ],
  },
  output: {
    path: path.join(__dirname, 'dist', 'assets'),
    filename: '[chunkhash].bundle.js',
    publicPath: '/assets/',
  },
  resolve: {
    extensions: ['.js', '.jsx'],
    modules: [
      path.resolve('./app'),
      path.resolve('./app/js'),
      'node_modules',
    ],
  },
  plugins: [
    new webpack.DefinePlugin({
      'process.env': {
        NODE_ENV: JSON.stringify('production'),
        API_ROOT: JSON.stringify(process.env.API_ROOT || '/api/v1/'),
      },
    }),
    new webpack.optimize.CommonsChunkPlugin({ name: ['vendor', 'manifest'], minChunks: Infinity }),
    new webpack.optimize.MinChunkSizePlugin({ minChunkSize: 8192 }),
    new HtmlWebpackPlugin({
      title: 'Society of Software Engineers',
      filename: '../index.html',
      template: './app/index.ejs',
    }),
    new InlineChunkWebpackPlugin({
      inlineChunks: ['manifest'],
    }),
    new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
    new webpack.optimize.UglifyJsPlugin({
      compress: {
        screw_ie8: true,
        warnings: false,
      },
      mangle: {
        screw_ie8: true,
      },
      output: {
        comments: false,
        screw_ie8: true,
      },
      sourceMap: false,
    }),
    new ExtractTextPlugin({
      filename: '[chunkhash].bundle.css',
      allChunks: true,
    }),
  ],
  module: {
    rules: [
      {
        test: /\.jsx?$/,
        loaders: ['babel-loader'],
        exclude: /node_modules/,
      },
      {
        test: /\.md$/,
        loaders: ['raw-loader'],
      },
      {
        test: /\.s?css$/,
        loader: ExtractTextPlugin.extract(['css-loader', 'resolve-url-loader', 'sass-loader']),
      },
      {
        test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
        loader: 'url-loader?limit=10000&mimetype=application/font-woff',
      },
      {
        test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
        loader: 'file-loader',
      },
      {
        test: /\.(gif|png|jpg|jpeg)(\?[a-z0-9]+)?$/,
        loader: 'url-loader?limit=8192',
      },
    ],
  },
};
<commit_msg>edit names<commit_after>const InlineChunkWebpackPlugin = require('html-webpack-inline-chunk-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const webpack = require('webpack');
const path = require('path');

module.exports = {
  entry: {
    main: './app/js/app.jsx',
    vendor: [
      'redux',
      'react-redux',
      'react-router',
      'react-router-dom',
      'react',
      'react-dom',
    ],
  },
  output: {
    path: path.join(__dirname, 'dist', 'assets'),
    filename: '[name].[chunkhash].js',
    publicPath: '/assets/',
  },
  resolve: {
    extensions: ['.js', '.jsx'],
    modules: [
      path.resolve('./app'),
      path.resolve('./app/js'),
      'node_modules',
    ],
  },
  plugins: [
    new webpack.DefinePlugin({
      'process.env': {
        NODE_ENV: JSON.stringify('production'),
        API_ROOT: JSON.stringify(process.env.API_ROOT || '/api/v1/'),
      },
    }),
    new webpack.optimize.CommonsChunkPlugin({ name: ['vendor', 'manifest'], minChunks: Infinity }),
    new webpack.optimize.MinChunkSizePlugin({ minChunkSize: 8192 }),
    new HtmlWebpackPlugin({
      title: 'Society of Software Engineers',
      filename: '../index.html',
      template: './app/index.ejs',
    }),
    new InlineChunkWebpackPlugin({
      inlineChunks: ['manifest'],
    }),
    new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
    new webpack.optimize.UglifyJsPlugin({
      compress: {
        screw_ie8: true,
        warnings: false,
      },
      mangle: {
        screw_ie8: true,
      },
      output: {
        comments: false,
        screw_ie8: true,
      },
      sourceMap: false,
    }),
    new ExtractTextPlugin({
      filename: '[name].[chunkhash].css',
      allChunks: true,
    }),
  ],
  module: {
    rules: [
      {
        test: /\.jsx?$/,
        loaders: ['babel-loader'],
        exclude: /node_modules/,
      },
      {
        test: /\.md$/,
        loaders: ['raw-loader'],
      },
      {
        test: /\.s?css$/,
        loader: ExtractTextPlugin.extract(['css-loader', 'resolve-url-loader', 'sass-loader']),
      },
      {
        test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
        loader: 'url-loader?limit=10000&mimetype=application/font-woff',
      },
      {
        test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
        loader: 'file-loader',
      },
      {
        test: /\.(gif|png|jpg|jpeg)(\?[a-z0-9]+)?$/,
        loader: 'url-loader?limit=8192',
      },
    ],
  },
};
<|endoftext|>


<commit_before>var Task = require("nomake").task;

console.log(Task);
<commit_msg>Update test.js<commit_after>var Task = require("thrall").task;

console.log(Task);
<|endoftext|>


<commit_before>var shared = require('../public/js/shared.js')
var colors = require('colors')

var _sockets = null,
	_WIDTH = 0,
	_HEIGHT = 0,
	_start_width = 20,
	_start_height = 30,
	_extendBy = 4,
	_minSpeed = 500,
	_maxSpeed = 50,
	_field,
	_player = [],
	_blockid = 0,
	_pid = 1,
	_clearedLines = 0,
	_gameloop,
	_timeout,
	x,
	i, y,
	_gameover = false

	keymap = {
		up: function (player) {
			player.rotation = (player.rotation + 1) % 4
		},
		down: function (player) {
			player.rotation--
			if (player.rotation === -1)
				player.rotation = 3
		},
		right: function (player) {
			player.position[0]++
		},
		left: function (player) {
			player.position[0]--
		},
		space: function (player) {
			while (!isColliding(player)){
				player.position[1]++
			}
			player.position[1]--
			placePiece(player)
		}
	},
	revert = {
		up: function (player) {
			player.rotation--
			if (player.rotation === -1)
				player.rotation = 3
		},
		down: function (player) {
			player.rotation = (player.rotation + 1) % 4
		},
		right: function (player) {
			player.position[0]--
		},
		left: function (player) {
			player.position[0]++
		},
		space: function (player) {

		}
	}

if (typeof module === "object" && module && typeof module.exports === "object"){

	exports.init = function (sockets) {
		_sockets = sockets
		_sockets.on('connection', newPlayer)
	}

	exports.reset = function(req, res){
		res.end()
		startGame()
	}
}

function randomInt (low, high) {
    return Math.floor(Math.random() * (high - low) + low);
}

function sendBaseData() {
	_sockets.emit('base', {players: _player, field: _field, score:_clearedLines})
}

function gameover(){
	console.log('Game Over'.red.bold)
	stopGame()
	_sockets.emit('gameover', {players: _player, field: _field, score:_clearedLines})
	startGame()
}

function startGame(){
	clearTimeout(_gameloop)
	console.log('Starting the game'.green.underline)
	_clearedLines = 0
	_WIDTH = _start_width + (_player.length-1)
	_HEIGHT = _start_height
	_field = shared.newMatrix(_WIDTH, _HEIGHT)
	_gameover = false
	for (var i = 0; i < _player.length; i++) {
		_player[i].score = 0
		newPiece(_player[i])
	}
	gameloop()
}

function stopGame(){
	console.log('Stopping the game'.red.underline)
	_gameover = true
	clearTimeout(_gameloop)
}

function gameloop() {
	movePiecesDown()
	sendBaseData()

	timeout = Math.floor((_minSpeed-_maxSpeed)*Math.pow(Math.E, -1/20*_clearedLines)+_maxSpeed)
	if (!_gameover){
		_gameloop = setTimeout(gameloop, timeout)
	}
	if (timeout !== _timeout){
		console.log(('Line cleared. New Speed: '+timeout+'ms').italic.yellow)
	}
	_timeout = timeout
}

function newPlayer(socket) {
	if (_player.length===0){
		startGame()
	} else {
		extendField()
	}
	pid = _pid++
	_player.push({
		pid: pid,
		name: 'rnd',
		score: 0
	})
	newPiece(_player[_player.length-1])
	socket.on('update', recvUpdate)
	socket.on('disconnect', recvDisconnect)
	socket['pid']=pid
	sendBaseData()
	console.log(('Player '+pid+' joined the game').cyan)
}

function newPiece(player) {
	player.position = [randomInt(0, _WIDTH-3), 0]
	player.rotation = 0
	player.type = randomInt(0, 8),
	player.id = _blockid++
	if (isColliding(player)){
		gameover()
	}
}

function recvUpdate(data) {
	if (_gameover){return}
	for (var i = 0; i < _player.length; i++) {
		if (_player[i].pid == this.pid){
			player = _player[i]
		}
	}
	keymap[data](player)
	if (isColliding(player)){
		revert[data](player)
	}
	sendBaseData()
}

function recvDisconnect(data) {
	console.log(('Player '+this.pid+' leaved the game').grey)
	indexToDelete = -1;
	for (var i = 0; i < _player.length; i++) {
		if (_player[i].pid === this.pid){
			indexToDelete = i
		}
	}
	_player.splice(indexToDelete, 1)
	if (_player.length === 0){
		stopGame()
	} else {
		reduceField()
		sendBaseData()
	}
}

function movePiecesDown() {
	for (i = 0; i < _player.length; i++) {
		_player[i].position[1]++
		if (isColliding(_player[i])){
			_player[i].position[1]--
			placePiece(_player[i])
		}
	}
}

function clearFinishedLines(player){
	y = _HEIGHT-1
	while (y > 0) {
		cleared = true
		for (x = 0; x <_WIDTH; x++) {
			if (!_field[x][y]){
				cleared = false
			}
		}
		if (cleared){
			_clearedLines++
			player.score++
			for (i = y-1; i >= 0; i--){
				for (x = 0; x <_WIDTH; x++) {
					_field[x][i+1] = _field[x][i]
				}
			}
		} else {
			y--
		}
	}
}

function placePiece(player){
	var x = player.position[0],
		y = player.position[1],
		matrix = shared.rotateMatrix(shared.types[player.type],player.rotation)

	for (var dy = 0; dy < matrix.length; dy++){
		for (var dx = 0; dx < matrix[0].length; dx++){
			if (matrix[dy][dx]){
				if (dx+x < _WIDTH && dy+y < _HEIGHT){
					_field[dx+x][dy+y] = {type: player.type, id: player.id, owner: player.pid}
				}
			}
		}
	}
	newPiece(player)
	clearFinishedLines(player);
}

function isColliding(player){
	var x = player.position[0],
		y = player.position[1],
		matrix = shared.rotateMatrix(shared.types[player.type],player.rotation)

	for (var dy = 0; dy < matrix.length; dy++){
		for (var dx = 0; dx < matrix[0].length; dx++){
			if (matrix[dy][dx]){
				if ( dx+x < 0 || dy+y < 0 || dx+x >= _WIDTH|| dy+y >= _HEIGHT || _field[dx+x][dy+y]){
					return true
				}
			}
		}
	}
	return false
}

function extendField(){
	nMatrix = shared.newMatrix(_WIDTH+_extendBy, _HEIGHT)
	for (var x = 0; x < _WIDTH; x++) {
		for (var y = 0; y < _HEIGHT; y++) {
			nMatrix[x][y] = _field[x][y]
		}
	}
	_field = nMatrix
	_WIDTH+=_extendBy
}

function reduceField(){

	nMatrix = shared.newMatrix(_WIDTH-_extendBy, _HEIGHT)
	for (var x = 0; x < _WIDTH-_extendBy; x++) {
		for (var y = 0; y < _HEIGHT; y++) {
			nMatrix[x][y] = _field[x][y]
		}
	}
	for (var i = 0; i < _player.length; i++){
		if (_player[i].position[0] + 5 >= _WIDTH - _extendBy){
			_player[i].position[0]-=5;
		}
	}
	_WIDTH-=_extendBy
	_field = nMatrix

}
<commit_msg>added pixelid<commit_after>var shared = require('../public/js/shared.js')
var colors = require('colors')

var _sockets = null,
	_WIDTH = 0,
	_HEIGHT = 0,
	_start_width = 20,
	_start_height = 30,
	_extendBy = 4,
	_minSpeed = 500,
	_maxSpeed = 50,
	_field,
	_player = [],
	_blockid = 0,
	_pixelid = 0,
	_pid = 1,
	_clearedLines = 0,
	_gameloop,
	_timeout,
	x,
	i, y,
	_gameover = false

	keymap = {
		up: function (player) {
			player.rotation = (player.rotation + 1) % 4
		},
		down: function (player) {
			player.rotation--
			if (player.rotation === -1)
				player.rotation = 3
		},
		right: function (player) {
			player.position[0]++
		},
		left: function (player) {
			player.position[0]--
		},
		space: function (player) {
			while (!isColliding(player)){
				player.position[1]++
			}
			player.position[1]--
			placePiece(player)
		}
	},
	revert = {
		up: function (player) {
			player.rotation--
			if (player.rotation === -1)
				player.rotation = 3
		},
		down: function (player) {
			player.rotation = (player.rotation + 1) % 4
		},
		right: function (player) {
			player.position[0]--
		},
		left: function (player) {
			player.position[0]++
		},
		space: function (player) {

		}
	}

if (typeof module === "object" && module && typeof module.exports === "object"){

	exports.init = function (sockets) {
		_sockets = sockets
		_sockets.on('connection', newPlayer)
	}

	exports.reset = function(req, res){
		res.end()
		startGame()
	}
}

function randomInt (low, high) {
    return Math.floor(Math.random() * (high - low) + low);
}

function sendBaseData() {
	_sockets.emit('base', {players: _player, field: _field, score:_clearedLines})
}

function gameover(){
	console.log('Game Over'.red.bold)
	stopGame()
	_sockets.emit('gameover', {players: _player, field: _field, score:_clearedLines})
	startGame()
}

function startGame(){
	clearTimeout(_gameloop)
	console.log('Starting the game'.green.underline)
	_clearedLines = 0
	_WIDTH = _start_width + (_player.length-1)
	_HEIGHT = _start_height
	_field = shared.newMatrix(_WIDTH, _HEIGHT)
	_gameover = false
	for (var i = 0; i < _player.length; i++) {
		_player[i].score = 0
		newPiece(_player[i])
	}
	gameloop()
}

function stopGame(){
	console.log('Stopping the game'.red.underline)
	_gameover = true
	clearTimeout(_gameloop)
}

function gameloop() {
	movePiecesDown()
	sendBaseData()

	timeout = Math.floor((_minSpeed-_maxSpeed)*Math.pow(Math.E, -1/15*_clearedLines)+_maxSpeed)
	if (!_gameover){
		_gameloop = setTimeout(gameloop, timeout)
	}
	if (timeout !== _timeout){
		console.log(('Line cleared. New Speed: '+timeout+'ms').italic.yellow)
	}
	_timeout = timeout
}

function newPlayer(socket) {
	if (_player.length===0){
		startGame()
	} else {
		extendField()
	}
	pid = _pid++
	_player.push({
		pid: pid,
		name: 'rnd',
		score: 0
	})
	newPiece(_player[_player.length-1])
	socket.on('update', recvUpdate)
	socket.on('disconnect', recvDisconnect)
	socket['pid']=pid
	sendBaseData()
	console.log(('Player '+pid+' joined the game').cyan)
}

function newPiece(player) {
	player.position = [randomInt(0, _WIDTH-3), 0]
	player.rotation = 0
	player.type = randomInt(0, 8),
	player.id = _blockid++
	if (isColliding(player)){
		gameover()
	}
}

function recvUpdate(data) {
	if (_gameover){return}
	for (var i = 0; i < _player.length; i++) {
		if (_player[i].pid == this.pid){
			player = _player[i]
		}
	}
	keymap[data](player)
	if (isColliding(player)){
		revert[data](player)
	}
	sendBaseData()
}

function recvDisconnect(data) {
	console.log(('Player '+this.pid+' leaved the game').grey)
	indexToDelete = -1;
	for (var i = 0; i < _player.length; i++) {
		if (_player[i].pid === this.pid){
			indexToDelete = i
		}
	}
	_player.splice(indexToDelete, 1)
	if (_player.length === 0){
		stopGame()
	} else {
		reduceField()
		sendBaseData()
	}
}

function movePiecesDown() {
	for (i = 0; i < _player.length; i++) {
		_player[i].position[1]++
		if (isColliding(_player[i])){
			_player[i].position[1]--
			placePiece(_player[i])
		}
	}
}

function clearFinishedLines(player){
	y = _HEIGHT-1
	while (y > 0) {
		cleared = true
		for (x = 0; x <_WIDTH; x++) {
			if (!_field[x][y]){
				cleared = false
			}
		}
		if (cleared){
			_clearedLines++
			player.score++
			for (i = y-1; i >= 0; i--){
				for (x = 0; x <_WIDTH; x++) {
					_field[x][i+1] = _field[x][i]
				}
			}
		} else {
			y--
		}
	}
}

function placePiece(player){
	var x = player.position[0],
		y = player.position[1],
		matrix = shared.rotateMatrix(shared.types[player.type],player.rotation)

	for (var dy = 0; dy < matrix.length; dy++){
		for (var dx = 0; dx < matrix[0].length; dx++){
			if (matrix[dy][dx]){
				if (dx+x < _WIDTH && dy+y < _HEIGHT){
					_field[dx+x][dy+y] = {type: player.type, id: player.id, owner: player.pid, pixelid:_pixelid++}
				}
			}
		}
	}
	newPiece(player)
	clearFinishedLines(player);
}

function isColliding(player){
	var x = player.position[0],
		y = player.position[1],
		matrix = shared.rotateMatrix(shared.types[player.type],player.rotation)

	for (var dy = 0; dy < matrix.length; dy++){
		for (var dx = 0; dx < matrix[0].length; dx++){
			if (matrix[dy][dx]){
				if ( dx+x < 0 || dy+y < 0 || dx+x >= _WIDTH|| dy+y >= _HEIGHT || _field[dx+x][dy+y]){
					return true
				}
			}
		}
	}
	return false
}

function extendField(){
	nMatrix = shared.newMatrix(_WIDTH+_extendBy, _HEIGHT)
	for (var x = 0; x < _WIDTH; x++) {
		for (var y = 0; y < _HEIGHT; y++) {
			nMatrix[x][y] = _field[x][y]
		}
	}
	_field = nMatrix
	_WIDTH+=_extendBy
}

function reduceField(){

	nMatrix = shared.newMatrix(_WIDTH-_extendBy, _HEIGHT)
	for (var x = 0; x < _WIDTH-_extendBy; x++) {
		for (var y = 0; y < _HEIGHT; y++) {
			nMatrix[x][y] = _field[x][y]
		}
	}
	for (var i = 0; i < _player.length; i++){
		if (_player[i].position[0] + 5 >= _WIDTH - _extendBy){
			_player[i].position[0]-=5;
		}
	}
	_WIDTH-=_extendBy
	_field = nMatrix

}
<|endoftext|>


<commit_before>const webpack = require('webpack')
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const LodashModuleReplacementPlugin = require('lodash-webpack-plugin')
const autoprefixer = require('autoprefixer')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const htmlMinifier = require('html-minifier').minify
const ExtractTextPlugin = require("extract-text-webpack-plugin")

module.exports = {
  context: path.join(__dirname, './src'),
  entry: {
    js: './index.js',
    vendor: ['react']
  },
  output: {
    path: path.join(__dirname, './static'),
    filename: 'bundle.js'
  },
  module: {
    loaders: [
      // {
      //     test: /\.sss$/,
      //     loader: ExtractTextPlugin.extract({
      //       fallbackLoader: 'style-loader',
      //       loader: ['css', 'postcss']
      //     })
      //   },
      {
        test: /\.css$/,
        // loader: ExtractTextPlugin.extract({ loader: 'css?modules&importLoaders=1&localIdentName=[path]___[name]__[local]!postcss', fallbackLoader: 'style-loader' })

        // ExtractTextPlugin.extract({
        //   fallbackLoader: "style-loader",
        //   loader: "css-loader"

          // {
          //   loader: 'css',
          //   options: { importLoaders: 1, modules: true }
          // },

        // })
        use: [
          'style',
          {
            loader: 'css',
            options: { importLoaders: 1, modules: true }
          },
          'postcss'
        ]
      },
      {
        test: /\.(js|jsx)$/,
        exclude: /node_modules/,
        loader: 'babel',
        query: {
          presets: [['es2015', { 'modules': false }], 'stage-0', 'react'],
          plugins: ['lodash']
        }
      }
    ]
  },
  resolve: {
    extensions: ['.js', '.jsx', '.json'],
    modules: [
      path.resolve('./src'),
      'node_modules'
    ]
  },
  plugins: [
    new CopyWebpackPlugin([{ from: require.resolve('tachyons/css/tachyons.css') }]),
    new LodashModuleReplacementPlugin(),
    new webpack.LoaderOptionsPlugin({
      minimize: true,
      debug: false,
      comments: false
    }),
    // new webpack.optimize.DedupePlugin(),
    new webpack.optimize.CommonsChunkPlugin({
      name: 'vendor',
      minChunks: Infinity,
      filename: 'vendor.bundle.js',
    }),
    new webpack.optimize.UglifyJsPlugin({
      minimize: true,
      compressor: {
        warnings: false
      },
      output: {
       comments: false
      },
      mangle: true,
      beautify: false,
      sourceMap: false

    }),
    new HtmlWebpackPlugin({
      title: 'Prod App',
      template: './assets/template.html',
      minify:
         {
           useShortDoctype: true,
           removeAttributeQuotes: true,
           removeComments: true,
           removeEmptyAttributes: true,
           minifyURLs: true,
           useShortDoctype: true
         }
    }),
    new webpack.LoaderOptionsPlugin({
      test: /\.css$/,
      debug: false,
      options: {
        postcss: [
          autoprefixer({
            browsers: [
              'last 3 version',
              'ie >= 10'
            ]
          })
        ]
      }
    })
    // new ExtractTextPlugin({
    //     filename: 'styles.css',
    //     allChunks: true
    //   })
  ]
}
<commit_msg>Use extract text webpack plugin in production.<commit_after>const webpack = require('webpack')
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const LodashModuleReplacementPlugin = require('lodash-webpack-plugin')
const autoprefixer = require('autoprefixer')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const htmlMinifier = require('html-minifier').minify
const ExtractTextPlugin = require("extract-text-webpack-plugin")

module.exports = {
  context: path.join(__dirname, './src'),
  entry: {
    main: './index.js',
    vendor: ['react']
  },
  output: {
    path: path.join(__dirname, './static'),
    filename: '[name].js'
  },
  module: {
    loaders: [
      {
        test: /\.css$/,
        loader: ExtractTextPlugin.extract({
          fallbackLoader: 'style',
          loader: [
            {
                loader: 'css',
                options: {
                  importLoaders: 1,
                  modules: true
                }
              },
              'postcss'
          ]
        })
      },
      {
        test: /\.(js|jsx)$/,
        exclude: /node_modules/,
        loader: 'babel',
        query: {
          presets: [['es2015', { 'modules': false }], 'stage-0', 'react'],
          plugins: ['lodash']
        }
      }
    ]
  },
  resolve: {
    extensions: ['.js', '.jsx', '.json'],
    modules: [
      path.resolve('./src'),
      'node_modules'
    ]
  },
  plugins: [
    new CopyWebpackPlugin([{ from: require.resolve('tachyons/css/tachyons.min.css'), to: 'tachyons.css'}]),
    new ExtractTextPlugin({
      filename: "style.css",
      disable: false,
      allChunks: true
    }),
    new LodashModuleReplacementPlugin(),
    new webpack.LoaderOptionsPlugin({
      minimize: true,
      debug: false,
      comments: false
    }),

    new webpack.optimize.DedupePlugin(),
    new webpack.optimize.CommonsChunkPlugin({
      name: 'vendor',
      minChunks: Infinity,
      filename: 'vendor.bundle.js',
    }),
    new webpack.optimize.UglifyJsPlugin({
      minimize: true,
      compressor: {
        warnings: false
      },
      output: {
       comments: false
      },
      mangle: true,
      beautify: false,
      sourceMap: false

    }),
    new HtmlWebpackPlugin({
      title: 'Prod App',
      template: './assets/template.html',
      minify:
         {
           useShortDoctype: true,
           removeAttributeQuotes: true,
           removeComments: true,
           removeEmptyAttributes: true,
           minifyURLs: true,
           useShortDoctype: true
         },
      chunks: {
        head: {
          css: 'tachyons.css',

        }
      }
    }),
    new webpack.LoaderOptionsPlugin({
      test: /\.css$/,
      debug: false,
      options: {
        postcss: [
          autoprefixer({
            browsers: [
              'last 3 version',
              'ie >= 10'
            ]
          })
        ]
      }
    })
  ]
}
<|endoftext|>


<commit_before>/*globals d3*/

isic.views.ImagesViewSubViews = isic.views.ImagesViewSubViews || {};

isic.views.ImagesViewSubViews.ImageWall = isic.View.extend({
    initialize: function (settings) {
        this.image = settings.image;
        // For now we'll hard code this (and probably change it in the future),
        // depending on the page size
        this.imageSize = 128;

        this.listenTo(this.model.images, 'g:changed', this.render);
    },
    selectImage: function (imageId) {
        if (imageId !== null) {
            this.image.set('_id', imageId);
        } else {
            this.image.clear();
        }

        var sel = d3.select(this.el)
            .selectAll('img')
            .classed('selected', _.bind(function (d) {
                return d.id === this.image.id;
            }, this));
    },
    render: _.debounce(function () {
        d3.select(this.el)
          .selectAll('img')
          .remove();

        var sel = d3.select(this.el)
            .selectAll('img')
            .data(this.model.images.map(function (image) {
                return {
                    id: image.id,
                    name: image.get('name')
                };
            }));

        sel.enter()
            .append('img')
            .classed('thumb', true);

        sel.attr('src', _.bind(function (d) {
            return girder.apiRoot + '/image/' + d.id + '/thumbnail?width=' + this.imageSize;
        }, this))
            .attr('height', this.imageSize * 0.75)
            .attr('width', this.imageSize)
            .attr('data-toggle', 'tooltip')
            .attr('data-placement', 'auto')
            .attr('data-viewport', '#isic-images-imageWall')
            .on('click', _.bind(function (d) {
                this.clearTooltips();
                if (d3.event.shiftKey) {
                    new isic.views.ImageFullscreenWidget({ // eslint-disable-line no-new
                        el: $('#g-dialog-container'),
                        model: this.model.images.findWhere({_id: d.id}),
                        parentView: this
                    }).render();
                } else {
                    this.selectImage(d.id === this.image.id ? null : d.id);
                }
            }, this))
            .each(function (d) {
                $(this).tooltip({
                    title: d.name
                });
            });
    }, 50),
    clearTooltips: function () {
        $('[data-toggle="tooltip"]').tooltip('hide');
    }
});
<commit_msg>Add clarifying comment<commit_after>/*globals d3*/

isic.views.ImagesViewSubViews = isic.views.ImagesViewSubViews || {};

isic.views.ImagesViewSubViews.ImageWall = isic.View.extend({
    initialize: function (settings) {
        this.image = settings.image;
        // For now we'll hard code this (and probably change it in the future),
        // depending on the page size
        this.imageSize = 128;

        this.listenTo(this.model.images, 'g:changed', this.render);
    },
    selectImage: function (imageId) {
        if (imageId !== null) {
            this.image.set('_id', imageId);
        } else {
            this.image.clear();
        }

        var sel = d3.select(this.el)
            .selectAll('img')
            .classed('selected', _.bind(function (d) {
                return d.id === this.image.id;
            }, this));
    },
    render: _.debounce(function () {
        // Ordinarily, we would use the exit selection to clean up after
        // ourselves, but deleting all the img elements has the effect of
        // visually "streaming in" the new data, rather than updating the old
        // images, which feels error-prone.
        d3.select(this.el)
          .selectAll('img')
          .remove();

        var sel = d3.select(this.el)
            .selectAll('img')
            .data(this.model.images.map(function (image) {
                return {
                    id: image.id,
                    name: image.get('name')
                };
            }));

        sel.enter()
            .append('img')
            .classed('thumb', true);

        sel.attr('src', _.bind(function (d) {
            return girder.apiRoot + '/image/' + d.id + '/thumbnail?width=' + this.imageSize;
        }, this))
            .attr('height', this.imageSize * 0.75)
            .attr('width', this.imageSize)
            .attr('data-toggle', 'tooltip')
            .attr('data-placement', 'auto')
            .attr('data-viewport', '#isic-images-imageWall')
            .on('click', _.bind(function (d) {
                this.clearTooltips();
                if (d3.event.shiftKey) {
                    new isic.views.ImageFullscreenWidget({ // eslint-disable-line no-new
                        el: $('#g-dialog-container'),
                        model: this.model.images.findWhere({_id: d.id}),
                        parentView: this
                    }).render();
                } else {
                    this.selectImage(d.id === this.image.id ? null : d.id);
                }
            }, this))
            .each(function (d) {
                $(this).tooltip({
                    title: d.name
                });
            });
    }, 50),
    clearTooltips: function () {
        $('[data-toggle="tooltip"]').tooltip('hide');
    }
});
<|endoftext|>


<commit_before>const debug = process.env.NODE_ENV !== 'production';
const path = require('path');
const webpack = require('webpack');

const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');

module.exports = {
    mode: 'production',
    entry: [
        'bootstrap-loader', path.join(__dirname, './src/js/main.js')
    ],
    output: {
        path:  path.join(__dirname, 'dist'),
        filename: '[name].[chunkhash:8].js',
        chunkFilename: '[name].[chunkhash:8].chunk.js'
    },
    optimization: {
    splitChunks: {
        chunks: "all",
            minSize: 0
    }
},
    plugins: [
        new webpack.ProvidePlugin({
            $: 'jquery',
            Backbone: 'backbone',
            _: 'underscore'
        }),
        new CleanWebpackPlugin(['dist']),
        new HtmlWebpackPlugin({
             title: 'Exemple PEW',
             template: path.join(__dirname, 'src/index.html'),
         }),
        new webpack.SourceMapDevToolPlugin({})
    ],
    module: {
        rules: [
            {
                test: /\.js$/,
                exclude: /node_modules/,
                use: {
                    loader: 'babel-loader'
                }
            },
            {
                test: /\.scss$/,
                use: [
                    "style-loader",
                    MiniCssExtractPlugin.loader,
                    "css-loader",
                    "sass-loader"
                ]
            },
            { test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: "url-loader?limit=10000&mimetype=application/font-woff" },
            { test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: "file-loader" },
            {
                test: /\.(jpe?g|png|gif|svg)$/i,
                use: [
                    'file-loader?name=images/[name].[ext]',
                    'image-webpack-loader?bypassOnDebug'
                ]
            }
        ]
    }
};
<commit_msg>Fix production webpack config<commit_after>const debug = process.env.NODE_ENV !== 'production';
const path = require('path');
const webpack = require('webpack');

const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');

module.exports = {
    mode: 'production',

    entry: [
        'bootstrap-loader', path.join(__dirname, './src/js/main.js')
    ],
    output: {
        path:  path.join(__dirname, 'dist'),
        filename: '[name].[chunkhash:8].js',
        chunkFilename: '[name].[chunkhash:8].chunk.js'
    },
    plugins: [
        new webpack.ProvidePlugin({
            $: 'jquery',
            Backbone: 'backbone',
            _: 'underscore'
        }),
        new CleanWebpackPlugin(['dist']),
        new HtmlWebpackPlugin({
            title: 'Exemple PEW',
            template: path.join(__dirname, 'src/index.html'),
        }),
        new CopyWebpackPlugin([{from: path.join(__dirname, 'src/assets/images'), to: path.join(__dirname, 'dist/images'),}])
    ],
    module: {
        rules: [
            {
                test: /\.js$/,
                exclude: /node_modules/,
                use: {
                    loader: 'babel-loader'
                }
            },
            {
                test: /\.scss$/,
                use: [
                    "style-loader",
                    MiniCssExtractPlugin.loader,
                    "css-loader",
                    "sass-loader"
                ]
            },
            { test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: "url-loader?limit=10000&mimetype=application/font-woff" },
            { test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: "file-loader" },
            {
                test: /\.(jpe?g|png|gif|svg)$/i,
                use: [
                    'file-loader?name=images/[name].[ext]',
                    'image-webpack-loader?bypassOnDebug'
                ]
            }
        ]
    }
};
<|endoftext|>


<commit_before>'use strict';

var processingStepsMeta = require('../processing-steps-meta');

module.exports = {
	'/': {
		decorateContext: function () {
			this.processingStepsMeta = processingStepsMeta;
		},
		view: require('../view/statistics-dashboard')
	},
	files: require('../view/statistics-files-completed'),
	'files/pending': {
		decorateContext: function () {
			this.processingStepsMeta = processingStepsMeta;
		},
		view: require('../view/statistics-files-pending')
	},
	'files/accounts': require('../view/statistics-files-accounts'),
	time: {
		decorateContext: function () {
			this.processingStepsMeta = processingStepsMeta;
		},
		view: require('../view/statistics-time-per-role')
	},
	'time/per-person': {
		decorateContext: function () {
			this.processingStepsMeta = processingStepsMeta;
		},
		view: require('../view/statistics-time-per-person')
	},
	flow: {
		decorateContext: function () {
			this.processingStepsMeta = processingStepsMeta;
		},
		view: require('../view/statistics-flow-certificates')
	},
	'flow/by-role': {
		view: require('../view/statistics-flow-roles')
	},
	'flow/by-operator': {
		view: require('../view/statistics-flow-operators')
	},
	'flow/rejections': {
		view: require('../view/statistics-flow-rejections')
	},

	profile: require('../view/user-profile')
};
<commit_msg>Issue #1796. Add business process views routes<commit_after>'use strict';

var hyphenToCamel        = require('es5-ext/string/#/hyphen-to-camel')
  , matchBusinessProcess = require('./utils/inspector-match-business-process')
  , findFirstUploadKey   = require('./utils/inspector-find-first-upload-key')
  , matchUpload          = require('./utils/inspector-match-upload')
  , matchCertificate     = require('./utils/user-match-certificate')
  , processingStepsMeta  = require('../processing-steps-meta');

module.exports = function () {
	var match = matchBusinessProcess();

	return {
		// Pages with statistics information
		'/': {
			decorateContext: function () {
				this.processingStepsMeta = processingStepsMeta;
			},
			view: require('../view/statistics-dashboard')
		},
		files: require('../view/statistics-files-completed'),
		'files/pending': {
			decorateContext: function () {
				this.processingStepsMeta = processingStepsMeta;
			},
			view: require('../view/statistics-files-pending')
		},
		'files/accounts': require('../view/statistics-files-accounts'),
		time: {
			decorateContext: function () {
				this.processingStepsMeta = processingStepsMeta;
			},
			view: require('../view/statistics-time-per-role')
		},
		'time/per-person': {
			decorateContext: function () {
				this.processingStepsMeta = processingStepsMeta;
			},
			view: require('../view/statistics-time-per-person')
		},
		flow: {
			decorateContext: function () {
				this.processingStepsMeta = processingStepsMeta;
			},
			view: require('../view/statistics-flow-certificates')
		},
		'flow/by-role': {
			view: require('../view/statistics-flow-roles')
		},
		'flow/by-operator': {
			view: require('../view/statistics-flow-operators')
		},
		'flow/rejections': {
			view: require('../view/statistics-flow-rejections')
		},

		// Business process views

		'[0-9][a-z0-9]*': {
			match: function (businessProcessId) {
				return match.call(this, businessProcessId).then(function (result) {
					if (!result) return false;
					var firstUniqueKey = findFirstUploadKey.call(this, 'requirementUpload');
					if (firstUniqueKey) {
						return matchUpload.call(this, 'requirementUpload', firstUniqueKey);
					}
					return true;
				}.bind(this));
			},
			view: require('../view/business-process-official-document')
		},
		'[0-9][a-z0-9]*/documents/[a-z][a-z0-9-]*': {
			match: function (businessProcessId, uniqueKey) {
				return match.call(this, businessProcessId).then(function (result) {
					if (!result) return false;
					var firstUniqueKey = findFirstUploadKey.call(this, 'requirementUpload');
					if (!firstUniqueKey) return false;
					uniqueKey = hyphenToCamel.call(uniqueKey);
					if (firstUniqueKey === uniqueKey) return false;
					return matchUpload.call(this, 'requirementUpload', uniqueKey);
				}.bind(this));
			},
			view: require('../view/business-process-official-document')
		},
		'[0-9][a-z0-9]*/payment-receipts/[a-z][a-z0-9-]*': {
			match: function (businessProcessId, uniqueKey) {
				return match.call(this, businessProcessId).then(function (result) {
					if (!result) return false;
					return matchUpload.call(this, 'paymentReceiptUpload', hyphenToCamel.call(uniqueKey));
				}.bind(this));
			},
			view: require('../view/business-process-official-payment')
		},
		'[0-9][a-z0-9]*/certificates/[a-z][a-z0-9-]*': {
			match: function (businessProcessId, uniqueKey) {
				return match.call(this, businessProcessId).then(function (result) {
					if (!result) return false;
					return matchCertificate.call(this, hyphenToCamel.call(uniqueKey), {
						collection: 'applicable'
					});
				}.bind(this));
			},
			view: require('../view/business-process-official-certificate')
		},
		'[0-9][a-z0-9]*/data': {
			match: match,
			decorateContext: function () {
				this.dataSnapshot = this.businessProcess.dataForms.dataSnapshot.resolved;
			},
			view: require('../view/business-process-official-data')
		},

		// Other

		profile: require('../view/user-profile')
	};
};
<|endoftext|>


<commit_before>var path = require('path');
var webpack = require('webpack');

module.exports = {
  entry: [
    './website/main'
  ],
  output: {
    path: path.resolve(__dirname, 'website', 'assets', 'js'),
    filename: 'bundle.js',
    publicPath: '/js/'
  },
  plugins: [
    new webpack.optimize.OccurrenceOrderPlugin(),
    new webpack.DefinePlugin({
      'process.env': {
        'NODE_ENV': JSON.stringify('production')
      }
    }),
    new webpack.optimize.UglifyJsPlugin({
      compressor: {
        warnings: false
      }
    })
  ],
  module: {
    loaders: [{
      test: /\.js$/,
      exclude: /node_modules/,
      loaders: ['babel']
    }]
  }
};
<commit_msg>Added resolve option to webpack<commit_after>var path = require('path');
var webpack = require('webpack');

module.exports = {
  entry: './website/main',
  output: {
    path: path.resolve(__dirname, 'website', 'assets', 'js'),
    filename: 'bundle.js',
    publicPath: '/js/'
  },
  plugins: [
    new webpack.optimize.OccurrenceOrderPlugin(),
    new webpack.DefinePlugin({
      'process.env': {
        'NODE_ENV': JSON.stringify('production')
      }
    }),
    new webpack.optimize.UglifyJsPlugin({
      compressor: {
        warnings: false
      }
    })
  ],
  module: {
    loaders: [{
      test: /\.js$/,
      exclude: /node_modules/,
      loaders: ['babel']
    }]
  },
  resolve: {
    extensions: ['', '.js', '.jsx']
  }
};
<|endoftext|>


<commit_before>//User Routes
Router.route('/user/profile/', {
    name: 'userProfile',
    action: function () {
        if (Meteor.user()) {
            this.render('profile');
        } else {
            this.redirect('/');
        }
        SEO.set({title: Meteor.user().username});
    }
});

Router.route('/user/:_id/history', {
    name: 'userHistory',
    action: function () {
        this.render('history', {
            data: function () {
                return Meteor.users.findOne(this.params._id);
            }
        });
        SEO.set({title: Meteor.user().username});
    }
});

Router.route('/user/:_id/groups', {
    name: 'userGroups',
    action: function () {
        this.render('groups', {
            data: function () {
                return Meteor.users.findOne(this.params._id);
            }
        });
        SEO.set({title: 'Home - ' + Meteor.App.NAME});
    }
});

Router.route('/user/admin', {
    name: 'userGroups',
    action: function(){
        if(Meteor.user().profile.globalAdmin){
            this.render('admin', {
            });
        SEO.set({title: 'Global Settings'});
        } else {
            this.redirect('/user/profile/');
        }
    }
});<commit_msg>route conflict<commit_after>//User Routes
Router.route('/user/profile/', {
    name: 'userProfile',
    action: function () {
        if (Meteor.user()) {
            this.render('profile');
        } else {
            this.redirect('/');
        }
        SEO.set({title: Meteor.user().username});
    }
});

Router.route('/user/:_id/history', {
    name: 'userHistory',
    action: function () {
        this.render('history', {
            data: function () {
                return Meteor.users.findOne(this.params._id);
            }
        });
        SEO.set({title: Meteor.user().username});
    }
});

Router.route('/user/:_id/groups', {
    name: 'userGroups',
    action: function () {
        this.render('groups', {
            data: function () {
                return Meteor.users.findOne(this.params._id);
            }
        });
        SEO.set({title: 'Home - ' + Meteor.App.NAME});
    }
});

Router.route('/user/admin', {
    name: 'userAdminGroups',
    action: function(){
        if(Meteor.user().profile.globalAdmin){
            this.render('admin', {
            });
        SEO.set({title: 'Global Settings'});
        } else {
            this.redirect('/user/profile/');
        }
    }
});<|endoftext|>


<commit_before>var webpack = require('webpack');
var ExtractTextPlugin = require('extract-text-webpack-plugin');

module.exports = {
  devtool: 'source-map',

  entry: __dirname + "/client/index.js",

  output: {
    path: __dirname + '/static/dist/',
    filename: 'bundle.js',
  },

  resolve: {
    extensions: ['', '.js', '.jsx'],
  },

  module: {
    loaders: [
      {
        test: /\.css$/,
        loader: ExtractTextPlugin.extract('style','css?modules'),
      },
      {
        test: /\.jsx*$/,
        exclude: /node_modules/,
        loader: 'babel',
      }
    ],
  },

  plugins: [
    new webpack.optimize.OccurenceOrderPlugin(),
    new webpack.DefinePlugin({
      'process.env': {
        'NODE_ENV': JSON.stringify('production'),
      }
    }),
    new webpack.optimize.UglifyJsPlugin({
      compressor: {
        warnings: false,
      }
    }),
    new ExtractTextPlugin("app.css"),
  ],
};
<commit_msg>fix optimize<commit_after>var webpack = require('webpack');
var ExtractTextPlugin = require('extract-text-webpack-plugin');

module.exports = {
  devtool: 'source-map',

  entry: __dirname + "/client/index.js",

  output: {
    path: __dirname + '/static/dist/',
    filename: 'bundle.js',
  },

  resolve: {
    extensions: ['', '.js', '.jsx'],
  },

  module: {
    loaders: [
      {
        test: /\.css$/,
        loader: ExtractTextPlugin.extract('style','css?modules'),
      },
      {
        test: /\.jsx*$/,
        exclude: /node_modules/,
        loader: 'babel',
      }
    ],
  },

  plugins: [
    new webpack.DefinePlugin({
      'process.env': {
        'NODE_ENV': JSON.stringify('production'),
      }
    }),
    new ExtractTextPlugin("app.css"),
  ],
};
<|endoftext|>


<commit_before>var keystone = require('keystone');

exports = module.exports = function(req, res) {

	var view = new keystone.View(req, res),
		locals = res.locals;

	// Init locals
	locals.section = 'blog';
	locals.filters = {
		category: req.params.category
	};
	locals.data = {
		posts: [],
		categories: []
	};

	// Load all categories
	view.on('init', function(next) {

		keystone.list('PostCategory').model.find().sort('name').exec(function(err, results) {

			if (err || !results.length) {
				return next(err);
			}

			locals.data.categories = results;

			// Load the counts for each category
			async.each(locals.data.categories, function(category, next) {

				keystone.list('Post').model.count().where('category').in([category.id]).exec(function(err, count) {
					category.postCount = count;
					next(err);
				});

			}, function(err) {
				next(err);
			});

		});

	});

	// Load the current category filter
	view.on('init', function(next) {

		if (req.params.category) {
			keystone.list('PostCategory').model.findOne({ key: locals.filters.category }).exec(function(err, result) {
				locals.data.category = result;
				next(err);
			});
		} else {
			next();
		}

	});

	// Load the posts
	view.on('init', function(next) {

		var q = keystone.list('Post').model.find().where('state', 'published').sort('-publishedDate').populate('author categories');

		if (locals.data.category) {
			q.where('categories').in([locals.data.category]);
		}

		q.exec(function(err, results) {
			locals.data.posts = results;
			next(err);
		});

	});

	// Render the view
	view.render('site/blog');

}
<commit_msg>Fixing the blog page (when categories exist)<commit_after>var keystone = require('keystone'),
	async = require('async');

exports = module.exports = function(req, res) {

	var view = new keystone.View(req, res),
		locals = res.locals;

	// Init locals
	locals.section = 'blog';
	locals.filters = {
		category: req.params.category
	};
	locals.data = {
		posts: [],
		categories: []
	};

	// Load all categories
	view.on('init', function(next) {

		keystone.list('PostCategory').model.find().sort('name').exec(function(err, results) {

			if (err || !results.length) {
				return next(err);
			}

			locals.data.categories = results;

			// Load the counts for each category
			async.each(locals.data.categories, function(category, next) {

				keystone.list('Post').model.count().where('category').in([category.id]).exec(function(err, count) {
					category.postCount = count;
					next(err);
				});

			}, function(err) {
				next(err);
			});

		});

	});

	// Load the current category filter
	view.on('init', function(next) {

		if (req.params.category) {
			keystone.list('PostCategory').model.findOne({ key: locals.filters.category }).exec(function(err, result) {
				locals.data.category = result;
				next(err);
			});
		} else {
			next();
		}

	});

	// Load the posts
	view.on('init', function(next) {

		var q = keystone.list('Post').model.find().where('state', 'published').sort('-publishedDate').populate('author categories');

		if (locals.data.category) {
			q.where('categories').in([locals.data.category]);
		}

		q.exec(function(err, results) {
			locals.data.posts = results;
			next(err);
		});

	});

	// Render the view
	view.render('site/blog');

}
<|endoftext|>


<commit_before>const path = require('path');
const webpack = require('webpack');

module.exports = {
  devtool: 'hidden-source-map',
  entry: [
    'babel-polyfill',
    './src/Index',
  ],
  output: {
    path: path.join(__dirname, 'dist'),
    filename: 'bundle.js',
    publicPath: '/',
  },
  plugins: [
    new webpack.optimize.OccurenceOrderPlugin(),
    new webpack.DefinePlugin({
      'process.env': {
        NODE_ENV: JSON.stringify('production'),
      },
    }),
  ],
  module: {
    loaders: [
      { test: /\.js$/, exclude: /node_modules/, loaders: ['babel'] },
      { test: /\.css$/, loader: 'style!css!cssnext' },
      { test: /\.scss$/, loader: 'style!css!sass?outputStyle=expanded' },
      { test: /\.woff\d{0,1}(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: 'url-loader?' +
      'limit=10000&minetype=application/font-woff' },
      { test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: 'file-loader' },
    ],
  },
};
<commit_msg>don't set publicPath<commit_after>const path = require('path');
const webpack = require('webpack');

module.exports = {
  devtool: 'hidden-source-map',
  entry: [
    'babel-polyfill',
    './src/Index',
  ],
  output: {
    path: path.join(__dirname, 'dist'),
    filename: 'bundle.js',
    // publicPath: '/static/',
  },
  plugins: [
    new webpack.optimize.OccurenceOrderPlugin(),
    new webpack.DefinePlugin({
      'process.env': {
        NODE_ENV: JSON.stringify('production'),
      },
    }),
  ],
  module: {
    loaders: [
      { test: /\.js$/, exclude: /node_modules/, loaders: ['babel'] },
      { test: /\.css$/, loader: 'style!css!cssnext' },
      { test: /\.scss$/, loader: 'style!css!sass?outputStyle=expanded' },
      { test: /\.woff\d{0,1}(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: 'url-loader?' +
      'limit=10000&minetype=application/font-woff' },
      { test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: 'file-loader' },
    ],
  },
};
<|endoftext|>


<commit_before>'use strict';

let path = require('path');
let webpack = require('webpack');
let autoprefixer = require('autoprefixer');
let ExtractTextWebpackPlugin = require('extract-text-webpack-plugin');

const entry = require('./webpack.entry.json');
const packageJson = require('../package.json');

const alias = {};
const imageSize = 10240;
const constant = {
    NAME : packageJson.name,
    VERSION : packageJson.version,
};

let config = {
    devtool : '#source-map',
    entry,
    output : {
        filename : 'js/[name].js',
        publicPath : '',
    },
    extensions : ['.vue', '.js', '.json', '.scss'],
    resolve : {
        alias,
    },
    module : {
        loaders : [
            {
                test : /\.vue$/,
                loader : 'vue',
            },
            {
                test : /\.(png|jpg|gif|svg)$/,
                loader : `url?limit=${ imageSize }&name=../img/[name].[ext]?[hash]`,
            },
            {
                test : /\.css$/,
                loader : ExtractTextWebpackPlugin.extract('style', 'css!postcss'),
            },
            {
                test : /\.scss$/,
                loader : ExtractTextWebpackPlugin.extract('style', 'css!postcss!sass'),
            },
            {
                test : /\.js$/,
                exclude : path.join(__dirname, '../node_modules/'),
                loader : 'babel',
                query : {
                    presets : ['es2015', 'stage-0'],
                    // plugins : ['transform-remove-strict-mode'],
                    // plugins: ['transform-runtime'],
                },
            },
        ],
    },
    plugins : [
        new ExtractTextWebpackPlugin('css/[name].css'),
        new webpack.DefinePlugin((() => {
            Object.keys(constant).forEach(( key ) => {
                constant[key] = JSON.stringify(constant[key]);
            });
            return {
                'process.env' : constant,
            };
        })()),
    ],
    vue : {
        loaders : {
            sass : ExtractTextWebpackPlugin.extract('style', 'css!postcss!sass'),
            scss : ExtractTextWebpackPlugin.extract('style', 'css!postcss!sass'),
        },
    },
    postcss () {
        return [autoprefixer({ browsers : ['last 2 versions'] })];
    },
};

module.exports = config;
<commit_msg>update<commit_after>'use strict';

let path = require('path');
let webpack = require('webpack');
let autoprefixer = require('autoprefixer');
let ExtractTextWebpackPlugin = require('extract-text-webpack-plugin');

const entry = require('./webpack.entry.json');
const packageJson = require('../package.json');

const alias = {};
const imageSize = 10240;
const constant = {
    NAME : packageJson.name,
    VERSION : packageJson.version,
};

let config = {
    devtool : '#source-map',
    entry,
    output : {
        filename : 'js/[name].js',
        publicPath : '',
    },
    extensions : ['.vue', '.js', '.coffee', '.json', '.scss'],
    resolve : {
        alias,
    },
    module : {
        loaders : [
            {
                test : /\.vue$/,
                loader : 'vue',
            },
            {
                test : /\.(png|jpg|gif|svg)$/,
                loader : `url?limit=${ imageSize }&name=../img/[name].[ext]?[hash]`,
            },
            {
                test : /\.css$/,
                loader : ExtractTextWebpackPlugin.extract('style', 'css!postcss'),
            },
            {
                test : /\.scss$/,
                loader : ExtractTextWebpackPlugin.extract('style', 'css!postcss!sass'),
            },
            {
                test : /\.js$/,
                exclude : path.join(__dirname, '../node_modules/'),
                loader : 'babel',
                query : {
                    presets : ['es2015', 'stage-0'],
                    // plugins : ['transform-remove-strict-mode'],
                    // plugins: ['transform-runtime'],
                },
            },
            {
                test : /\.coffee/,
                loader : 'coffee',
            },
            {
                test : /\.(coffee\.md|litcoffee)$/,
                loader : 'coffee?literate',
            },
        ],
    },
    plugins : [
        new ExtractTextWebpackPlugin('css/[name].css'),
        new webpack.DefinePlugin((() => {
            Object.keys(constant).forEach(( key ) => {
                constant[key] = JSON.stringify(constant[key]);
            });
            return {
                'process.env' : constant,
            };
        })()),
    ],
    vue : {
        loaders : {
            sass : ExtractTextWebpackPlugin.extract('style', 'css!postcss!sass'),
            scss : ExtractTextWebpackPlugin.extract('style', 'css!postcss!sass'),
        },
    },
    postcss () {
        return [autoprefixer({ browsers : ['last 2 versions'] })];
    },
};

module.exports = config;
<|endoftext|>


<commit_before>var opentype = require('opentype.js');

/**
 * Created by josh on 7/2/17.
 */
var _fonts = { };
const DEFAULT_FONT_FAMILY = 'source';

exports.registerFont = function(binaryPath, family, weight, style, variant) {
    _fonts[family] = {
        binary: binaryPath,
        family: family,
        weight: weight,
        style: style,
        variant: variant,
        loaded: false,
        font: null,
        load: function(cb) {
            if(this.loaded) {
                if(cb)cb();
                return;
            }
            var self = this;
            opentype.load(binaryPath, function (err, font) {
                if (err) throw new Error('Could not load font: ' + err);
                self.loaded = true;
                self.font = font;
                if(cb)cb();
            });
        }
    };
    return _fonts[family];
};
exports.debug_list_of_fonts = _fonts;

function findFont(family) {
    if(_fonts[family]) return _fonts[family];
    family =  Object.keys(_fonts)[0];
    return _fonts[family];
}

exports.processTextPath = function(ctx,text,x,y, fill) {
    let font = findFont(ctx._font.family);
    var size = ctx._font.size;
    if(ctx.USE_FONT_GLYPH_CACHING) {
        var off = 0;
        for(var i=0; i<text.length; i++) {
            var ch = text[i];
            if(!cache.contains(font,size,ch)) {
                var glyph = renderGlyphToBitmap(font,ch,size);
                cache.insert(font,size,ch,glyph);
            }
            var glyph = cache.get(font,size,ch);
            var fx = x+off;
            var fy = y-glyph.ascent;
            var fpt = ctx.transform.transformPoint(fx,fy);
            ctx.copyImage(glyph.bitmap, Math.floor(fpt.x), Math.floor(fpt.y), ctx._fillColor);
            off += glyph.advance;
        }
    } else {
        var path = font.font.getPath(text, x, y, size);
        ctx.beginPath();
        path.commands.forEach(function(cmd) {
            switch(cmd.type) {
                case 'M': ctx.moveTo(cmd.x,cmd.y); break;
                case 'Q': ctx.quadraticCurveTo(cmd.x1,cmd.y1,cmd.x,cmd.y); break;
                case 'L': ctx.lineTo(cmd.x,cmd.y); break;
                case 'Z':
                {
                    ctx.closePath();
                    fill ? ctx.fill() : ctx.stroke();
                    ctx.beginPath();
                    break;
                }
            }
        });
    }
};

exports.measureText = function(ctx,text) {
    var font = _fonts[ctx._settings.font.family];
    if(!font) console.log("WARNING. Can't find font family ", ctx._settings.font.family);
    var fsize = ctx._settings.font.size;
    var glyphs = font.font.stringToGlyphs(text);
    var advance = 0;
    glyphs.forEach(function(g) { advance += g.advanceWidth; });

    return {
        width: advance/font.font.unitsPerEm*fsize,
        emHeightAscent: font.font.ascender/font.font.unitsPerEm*fsize,
        emHeightDescent: font.font.descender/font.font.unitsPerEm*fsize,
    };
};
<commit_msg>Provide docblock annotations for `text.js`<commit_after>/** @ignore */
var opentype = require('opentype.js');

/**
 * @type {object} Map containing all the fonts available for use
 */
var _fonts = { };

/**
 * The default font family to use for text
 * @type {string}
 */
const DEFAULT_FONT_FAMILY = 'source';

/**
 * Register Font
 *
 * @param {string} binaryPath Path to the font binary file
 * @param {string} family The name to give the font
 * @param {number} weight The font weight to use
 * @param {string} style Font style
 * @param {string} variant Font variant
 */
exports.registerFont = function(binaryPath, family, weight, style, variant) {
    _fonts[family] = {
        binary: binaryPath,
        family: family,
        weight: weight,
        style: style,
        variant: variant,
        loaded: false,
        font: null,
        load: function(cb) {
            if(this.loaded) {
                if(cb)cb();
                return;
            }
            var self = this;
            opentype.load(binaryPath, function (err, font) {
                if (err) throw new Error('Could not load font: ' + err);
                self.loaded = true;
                self.font = font;
                if(cb)cb();
            });
        }
    };
    return _fonts[family];
};
/**@ignore */
exports.debug_list_of_fonts = _fonts;

/**
 * Find Font
 *
 * Search the `fonts` array for a given font family name
 *
 * @param {string} family The name of the font family to search for
 *
 * @returns {object}
 */
function findFont(family) {
    if(_fonts[family]) return _fonts[family];
    family =  Object.keys(_fonts)[0];
    return _fonts[family];
}

/**
 * Process Text Path
 *
 * @param {Context} ctx The context to write to
 * @param {string} text The text to write to the given Context
 * @param {number} x X position
 * @param {number} y Y position
 * @param {boolean} fill Indicates wether or not the font should be filled
 *
 * @returns {void}
 */
exports.processTextPath = function(ctx,text,x,y, fill) {
    let font = findFont(ctx._font.family);
    var size = ctx._font.size;
    if(ctx.USE_FONT_GLYPH_CACHING) {
        var off = 0;
        for(var i=0; i<text.length; i++) {
            var ch = text[i];
            if(!cache.contains(font,size,ch)) {
                var glyph = renderGlyphToBitmap(font,ch,size);
                cache.insert(font,size,ch,glyph);
            }
            var glyph = cache.get(font,size,ch);
            var fx = x+off;
            var fy = y-glyph.ascent;
            var fpt = ctx.transform.transformPoint(fx,fy);
            ctx.copyImage(glyph.bitmap, Math.floor(fpt.x), Math.floor(fpt.y), ctx._fillColor);
            off += glyph.advance;
        }
    } else {
        var path = font.font.getPath(text, x, y, size);
        ctx.beginPath();
        path.commands.forEach(function(cmd) {
            switch(cmd.type) {
                case 'M': ctx.moveTo(cmd.x,cmd.y); break;
                case 'Q': ctx.quadraticCurveTo(cmd.x1,cmd.y1,cmd.x,cmd.y); break;
                case 'L': ctx.lineTo(cmd.x,cmd.y); break;
                case 'Z':
                {
                    ctx.closePath();
                    fill ? ctx.fill() : ctx.stroke();
                    ctx.beginPath();
                    break;
                }
            }
        });
    }
};

/**
 * Process Text Path
 *
 * @param {Context} ctx The canvas context on which to measure the text
 * @param {string} text The name to give the font
 *
 * @returns {object}
 */
exports.measureText = function(ctx,text) {
    var font = _fonts[ctx._settings.font.family];
    if(!font) console.log("WARNING. Can't find font family ", ctx._settings.font.family);
    var fsize = ctx._settings.font.size;
    var glyphs = font.font.stringToGlyphs(text);
    var advance = 0;
    glyphs.forEach(function(g) { advance += g.advanceWidth; });

    return {
        width: advance/font.font.unitsPerEm*fsize,
        emHeightAscent: font.font.ascender/font.font.unitsPerEm*fsize,
        emHeightDescent: font.font.descender/font.font.unitsPerEm*fsize,
    };
};
<|endoftext|>


<commit_before>/**
 * thar - Automatic content anchors link plugin for jQuery
 *
 * @link    https://github.com/gocom/thar
 * @license MIT
 */

/*
 * Copyright (C) 2013 Jukka Svahn
 *
 * 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.
 */

/**
 * @name jQuery
 * @class
 */

/**
 * @name fn
 * @class
 * @memberOf jQuery
 */

(function (factory)
{
    'use strict';

    if (typeof define === 'function' && define.amd)
    {
        define(['jquery'], factory);
    }
    else
    {
        factory(jQuery);
    }
}(function ($)
{
    'use strict';

    var hash = window.location.hash.substr(1), methods = {};

    /**
     * Renders content anchor links.
     *
     * @param    {Object}         [options={}]              Options
     * @param    {String|Boolean} [options.anchor=>#167] The anchor link text
     * @return   {Object}         this
     * @method   init
     * @memberof jQuery.fn.thar
     */

    methods.init = function (options)
    {
        options = $.extend({
            'anchor' : '§'
        }, options);

        return this.thar('setAnchorID').each(function ()
        {
            var $this = $(this), id = $this.attr('id'), anchor, content = $this.text();

            if ($this.hasClass('jquery-thar'))
            {
                return;
            }

            $this.addClass('jquery-thar').trigger('anchorcreate.thar');

            if (id === hash)
            {
                methods.scrollTo.apply($this);
            }

            if (options.anchor !== false)
            {
                anchor = $('')
                    .attr('href', '#' + id)
                    .on('click.thar', function (e)
                    {
                        e.preventDefault();
                        methods.scrollTo.apply($this);
                    });

                if (options.anchor === true)
                {
                    $this.wrapInner(anchor);
                }
                else
                {
                    $this.prepend(anchor.html(options.anchor)).prepend(' ');
                }
            }
        });
    };

    /**
     * Gets a contents listing.
     *
     * This method can be used to generate menus and
     * content tables based on selected headings.
     *
     * The content listing is added to the target element
     * specified with the target option. If
     * the target is left to its default NULL,
     * the list is added before the first heading.
     *
     * @param    {Object}       [options={}]          Options
     * @param    {Object|null}  [options.target=null] The target where the list is added to, takes an jQuery object
     * @return   {Object}       this
     * @method   getContentList
     * @memberof jQuery.fn.thar
     * @example
     * $('h2, h3, h4, h5, h6').thar('getContentList', {
     *  'target' : $('nav#contents')
     * });
     */

    methods.getContentList = function (options)
    {
        options = $.extend({
            target : null
        }, options);

        var previousLevel = 0, contents = '', baseLevel, target = this.filter('h1, h2, h3, h4, h5, h6');

        target.each(function ()
        {
            var $this = $(this), level = this.nodeName.substr(1, 1);

            if (!baseLevel)
            {
                baseLevel = level;
            }

            if (level > baseLevel || !$this.attr('id'))
            {
                return;
            }

            if (!previousLevel)
            {
                contents += '
';
            }
            else if (level == previousLevel)
            {
                contents += '

';
            }
            else if (level > previousLevel)
            {
                contents += new Array(level - previousLevel + 1).join('

');
            }
            else if (level < previousLevel)
            {
                contents += new Array(level - previousLevel + 1).join('

') + '

';
            }

            previousLevel = level;
            contents += $('
').html($('').text($this.clone().find('.jquery-thar-anchor').remove().end().text()).attr('href', '#' + $this.attr('id'))).html();
        });

        if (contents)
        {
            contents = $('
' + contents + new Array(previousLevel - baseLevel + 1).join('

') + '

');
            contents.find('a').on('click', function (e)
            {
                var id = $(this).attr('href').substr(1);
                e.preventDefault();
                methods.scrollTo.apply(
                    target.filter(function ()
                    {
                        return $(this).attr('id') === id;
                    })
                );
            });

            if (!options.target)
            {
                this.eq(0).before(contents);
            }
            else
            {
                options.target.html(contents);
            }
        }

        return this;
    };

    /**
     * Sets an anchor ID from the element text contents.
     *
     * @return   {Object}         this
     * @method   setAnchorID
     * @memberof jQuery.fn.thar
     */

    methods.setAnchorID = function ()
    {
        return this.each(function ()
        {
            var $this = $(this), id = $this.attr('id'), occurrences = 1, uniqueID;

            if (!id)
            {
                uniqueID = id = encodeURIComponent($this.text().replace(/\s/g, '-'))
                    .replace(/[^A-Z0-9\-]/gi, '-')
                    .substr(0, 255)
                    .replace(/^[\d\-]|-$/g, '')
                    .replace(/-{2,}/g, '-')
                    .toLowerCase() || 'thar';

                while (1)
                {
                    if (!document.getElementById(uniqueID))
                    {
                        $this.attr('id', uniqueID);
                        return;
                    }

                    uniqueID = id + '-' + (occurrences++);
                }
            }
        });
    };

    /**
     * Scrolls to the selected element.
     *
     * @return   {Object}         this
     * @method   scrollTo
     * @memberof jQuery.fn.thar
     */

    methods.scrollTo = function ()
    {
        var $this = this.eq(0).trigger('anchorScrollTo.thar'), id = $this.attr('id');

        $('html, body').animate({
            scrollTop : $this.offset().top
        }, 1000, 'swing', function ()
        {
            if (id)
            {
                window.location.hash = '#' + id;
            }
        });

        return this;
    };

    /**
     * Renders content anchor links.
     *
     * @param    {String}  [method=init] The called method
     * @param    {Object}  [options={}]  Options passed to the method
     * @class    thar
     * @memberof jQuery.fn
     */

    $.fn.thar = function (method, options)
    {
        if ($.type(method) !== 'string' || $.type(methods[method]) !== 'function')
        {
            options = method;
            method = 'init';
        }

        return methods[method].call(this, options);
    };
}));<commit_msg>Drop jquery prefix from classes.<commit_after>/**
 * thar - Automatic content anchors link plugin for jQuery
 *
 * @link    https://github.com/gocom/thar
 * @license MIT
 */

/*
 * Copyright (C) 2013 Jukka Svahn
 *
 * 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.
 */

/**
 * @name jQuery
 * @class
 */

/**
 * @name fn
 * @class
 * @memberOf jQuery
 */

(function (factory)
{
    'use strict';

    if (typeof define === 'function' && define.amd)
    {
        define(['jquery'], factory);
    }
    else
    {
        factory(jQuery);
    }
}(function ($)
{
    'use strict';

    var hash = window.location.hash.substr(1), methods = {};

    /**
     * Renders content anchor links.
     *
     * @param    {Object}         [options={}]              Options
     * @param    {String|Boolean} [options.anchor=>#167] The anchor link text
     * @return   {Object}         this
     * @method   init
     * @memberof jQuery.fn.thar
     */

    methods.init = function (options)
    {
        options = $.extend({
            'anchor' : '§'
        }, options);

        return this.thar('setAnchorID').each(function ()
        {
            var $this = $(this), id = $this.attr('id'), anchor, content = $this.text();

            if ($this.hasClass('thar'))
            {
                return;
            }

            $this.addClass('thar').trigger('anchorcreate.thar');

            if (id === hash)
            {
                methods.scrollTo.apply($this);
            }

            if (options.anchor !== false)
            {
                anchor = $('')
                    .attr('href', '#' + id)
                    .on('click.thar', function (e)
                    {
                        e.preventDefault();
                        methods.scrollTo.apply($this);
                    });

                if (options.anchor === true)
                {
                    $this.wrapInner(anchor);
                }
                else
                {
                    $this.prepend(anchor.html(options.anchor)).prepend(' ');
                }
            }
        });
    };

    /**
     * Gets a contents listing.
     *
     * This method can be used to generate menus and
     * content tables based on selected headings.
     *
     * The content listing is added to the target element
     * specified with the target option. If
     * the target is left to its default NULL,
     * the list is added before the first heading.
     *
     * @param    {Object}       [options={}]          Options
     * @param    {Object|null}  [options.target=null] The target where the list is added to, takes an jQuery object
     * @return   {Object}       this
     * @method   getContentList
     * @memberof jQuery.fn.thar
     * @example
     * $('h2, h3, h4, h5, h6').thar('getContentList', {
     *  'target' : $('nav#contents')
     * });
     */

    methods.getContentList = function (options)
    {
        options = $.extend({
            target : null
        }, options);

        var previousLevel = 0, contents = '', baseLevel, target = this.filter('h1, h2, h3, h4, h5, h6');

        target.each(function ()
        {
            var $this = $(this), level = this.nodeName.substr(1, 1);

            if (!baseLevel)
            {
                baseLevel = level;
            }

            if (level > baseLevel || !$this.attr('id'))
            {
                return;
            }

            if (!previousLevel)
            {
                contents += '
';
            }
            else if (level == previousLevel)
            {
                contents += '

';
            }
            else if (level > previousLevel)
            {
                contents += new Array(level - previousLevel + 1).join('

');
            }
            else if (level < previousLevel)
            {
                contents += new Array(level - previousLevel + 1).join('

') + '

';
            }

            previousLevel = level;
            contents += $('
').html($('').text($this.clone().find('.thar-anchor').remove().end().text()).attr('href', '#' + $this.attr('id'))).html();
        });

        if (contents)
        {
            contents = $('
' + contents + new Array(previousLevel - baseLevel + 1).join('

') + '

');
            contents.find('a').on('click', function (e)
            {
                var id = $(this).attr('href').substr(1);
                e.preventDefault();
                methods.scrollTo.apply(
                    target.filter(function ()
                    {
                        return $(this).attr('id') === id;
                    })
                );
            });

            if (!options.target)
            {
                this.eq(0).before(contents);
            }
            else
            {
                options.target.html(contents);
            }
        }

        return this;
    };

    /**
     * Sets an anchor ID from the element text contents.
     *
     * @return   {Object}         this
     * @method   setAnchorID
     * @memberof jQuery.fn.thar
     */

    methods.setAnchorID = function ()
    {
        return this.each(function ()
        {
            var $this = $(this), id = $this.attr('id'), occurrences = 1, uniqueID;

            if (!id)
            {
                uniqueID = id = encodeURIComponent($this.text().replace(/\s/g, '-'))
                    .replace(/[^A-Z0-9\-]/gi, '-')
                    .substr(0, 255)
                    .replace(/^[\d\-]|-$/g, '')
                    .replace(/-{2,}/g, '-')
                    .toLowerCase() || 'thar';

                while (1)
                {
                    if (!document.getElementById(uniqueID))
                    {
                        $this.attr('id', uniqueID);
                        return;
                    }

                    uniqueID = id + '-' + (occurrences++);
                }
            }
        });
    };

    /**
     * Scrolls to the selected element.
     *
     * @return   {Object}         this
     * @method   scrollTo
     * @memberof jQuery.fn.thar
     */

    methods.scrollTo = function ()
    {
        var $this = this.eq(0).trigger('anchorScrollTo.thar'), id = $this.attr('id');

        $('html, body').animate({
            scrollTop : $this.offset().top
        }, 1000, 'swing', function ()
        {
            if (id)
            {
                window.location.hash = '#' + id;
            }
        });

        return this;
    };

    /**
     * Renders content anchor links.
     *
     * @param    {String}  [method=init] The called method
     * @param    {Object}  [options={}]  Options passed to the method
     * @class    thar
     * @memberof jQuery.fn
     */

    $.fn.thar = function (method, options)
    {
        if ($.type(method) !== 'string' || $.type(methods[method]) !== 'function')
        {
            options = method;
            method = 'init';
        }

        return methods[method].call(this, options);
    };
}));<|endoftext|>