<commit_before>'use strict';

var xml2js = require('xml2js');
var path = require('path');
var _ = require('lodash');
var fs = require('fs');

module.exports = {
  Converter: ResxToJsonConverter,
};

function ResxToJsonConverter(options) {
  this.options = _.defaults(options, {
    defaultLocale: 'en',
    localeFormat: 'nggettext',
  });
  switch (this.options.localeFormat) {
    case 'nggettext': {
      this.localeFormatter = nggettextLocaleFormatter;
      break;
    }

    default: {
      this.localeFormatter = defaultLocaleFormatter;
      break;
    }
  }
}

ResxToJsonConverter.prototype.fromXmlString = ConverterFromXmlString;
ResxToJsonConverter.prototype.determineLocale = ConverterDetermineLocale;
ResxToJsonConverter.prototype.fromResxFile = ConverterFromResxFile;

function ConverterFromXmlString(xmlString, locale, callback) {
  var parser = new xml2js.Parser();
  parser.parseString(xmlString, function(err, parsed) {
    if (err) {
      return callback(err, null);
    }

    var dictionary = {};
    parsed.root.data.forEach(function(nameValuePair) {
      dictionary[nameValuePair.$.name] = nameValuePair.value[0];
    });

    var result = {};
    result[locale] = dictionary;
    return callback(null, result);
  });
}

function ConverterDetermineLocale(resxFilePath) {
  var locale = path.extname(path.parse(resxFilePath).name);
  if (!locale) {
    locale = this.options.defaultLocale;
  } else {
    locale = locale.substring(1);
  }
  return this.localeFormatter(locale);
}

function ConverterFromResxFile(resxFilePath, callback) {
  var locale = this.determineLocale(resxFilePath);
  var self = this;
  fs.readFile(resxFilePath, function(err, fileContents) {
    if (err) {
      return callback(err, null);
    }
    return self.fromXmlString(fileContents, locale, callback);
  });
}

function nggettextLocaleFormatter(locale) {
  if (locale.length > 2) {
    var split = locale.split('-');
    locale = split[0].toLowerCase() + '_' + split[1].toUpperCase();
  }
  return locale;
}

function defaultLocaleFormatter(locale) {
  return locale;
}
<commit_msg>define string and file APIs<commit_after>'use strict';

var xml2js = require('xml2js');
var path = require('path');
var _ = require('lodash');
var fs = require('fs');

module.exports = {
  Converter: ResxToJsonConverter,
};

function ResxToJsonConverter(options) {
  this.options = _.defaults(options, {
    defaultLocale: 'en',
    localeFormat: 'nggettext',
  });
  switch (this.options.localeFormat) {
    case 'nggettext': {
      this.localeFormatter = nggettextLocaleFormatter;
      break;
    }

    default: {
      this.localeFormatter = defaultLocaleFormatter;
      break;
    }
  }
}

ResxToJsonConverter.prototype.fromString = ConverterFromString;
ResxToJsonConverter.prototype.determineLocale = ConverterDetermineLocale;
ResxToJsonConverter.prototype.fromResxFile = ConverterFromResxFile;

function ConverterFromString(buffer, locale, callback) {
  var parser = new xml2js.Parser();
  parser.parseString(buffer, function(err, parsed) {
    if (err) {
      return callback(err, null);
    }

    var dictionary = {};
    parsed.root.data.forEach(function(nameValuePair) {
      dictionary[nameValuePair.$.name] = nameValuePair.value[0];
    });

    var result = {};
    result[locale] = dictionary;
    return callback(null, result);
  });
}

function ConverterDetermineLocale(resxFilePath) {
  var locale = path.extname(path.parse(resxFilePath).name);
  if (!locale) {
    locale = this.options.defaultLocale;
  } else {
    locale = locale.substring(1);
  }
  return this.localeFormatter(locale);
}

function ConverterFromResxFile(resxFilePath, callback) {
  var locale = this.determineLocale(resxFilePath);
  var self = this;
  fs.readFile(resxFilePath, function(err, fileContents) {
    if (err) {
      return callback(err, null);
    }
    return self.fromString(fileContents, locale, callback);
  });
}

function nggettextLocaleFormatter(locale) {
  if (locale.length > 2) {
    var split = locale.split('-');
    locale = split[0].toLowerCase() + '_' + split[1].toUpperCase();
  }
  return locale;
}

function defaultLocaleFormatter(locale) {
  return locale;
}
<|endoftext|>


<commit_before>'use strict';

var _ = require('lodash');
var parse = require('url-parse');
var glimpse = require('glimpse');

var _strategies = [];

var getContentTypeCategory = (function() {
    var listing = {
        'text/html':                   {'document': true},
        'text/plain':                  {'document': true},
        'application/xhtml+xml':       {'document': true},
        'text/xml':                    {'data': true},
        'application/json':            {'data': true},
        'text/css':                    {'stylesheet': true},
        'text/xsl':                    {'stylesheet': true},
        'image/jpg':                   {'image': true},
        'image/jpeg':                  {'image': true},
        'image/pjpeg':                 {'image': true},
        'image/png':                   {'image': true},
        'image/gif':                   {'image': true},
        'image/bmp':                   {'image': true},
        'image/svg+xml':               {'image': true, 'font': true, 'document': true},
        'image/vnd.microsoft.icon':    {'image': true},
        'image/webp':                  {'image': true},
        'image/x-icon':                {'image': true},
        'image/x-xbitmap':             {'image': true},
        'font/ttf':                    {'font': true},
        'font/otf':                    {'font': true},
        'font/woff':                   {'font': true},
        'font/woff2':                  {'font': true},
        'font/truetype':               {'font': true},
        'font/opentype':               {'font': true},
        'application/octet-stream':    {'font': true, 'image': true},
        'application/font-woff':       {'font': true},
        'application/font-woff2':      {'font': true},
        'application/x-font-woff':     {'font': true},
        'application/x-font-type1':    {'font': true},
        'application/x-font-ttf':      {'font': true},
        'application/x-truetype-font': {'font': true},
        'text/javascript':             {'script': true},
        'text/ecmascript':             {'script': true},
        'application/javascript':      {'script': true},
        'application/ecmascript':      {'script': true},
        'application/x-javascript':    {'script': true},
        'text/javascript1.1':          {'script': true},
        'text/javascript1.2':          {'script': true},
        'text/javascript1.3':          {'script': true},
        'text/jscript':                {'script': true},
        'text/livescript':             {'script': true},
        'text/vtt':                    {'texttrack': true},
    };

    return function(contentType) {
        if (contentType) {
            var target = '';
            for (var i = 0; i < contentType.length; i++) {
                var char = contentType[i];
                if (char == ';') {
                    break;
                }
                target += char
            }

            return listing[target];
        }
    };
})();

var getStatusCodeText = (function() {
    var listing = {
        100: 'Continue',
        101: 'Switching Protocols',
        102: 'Processing',
        200: 'OK',
        201: 'Created',
        202: 'Accepted',
        203: 'Non-Authoritative Information',
        204: 'No Content',
        205: 'Reset Content',
        206: 'Partial Content',
        207: 'Multi-Status',
        208: 'Already Reported',
        226: 'IM Used',
        300: 'Multiple Choices',
        301: 'Moved Permanentl',
        302: 'Found',
        303: 'See Other',
        304: 'Not Modified',
        305: 'Use Proxy',
        307: 'Temporary Redirect',
        308: 'Permanent Redirect',
        400: 'Bad Request',
        401: 'Unauthorized',
        402: 'Payment Required',
        403: 'Forbidden',
        404: 'Not Found',
        405: 'Method Not Allowed',
        406: 'Not Acceptable',
        407: 'Proxy Authentication Required',
        408: 'Request Timeout',
        409: 'Conflict',
        410: 'Gone',
        411: 'Length Required',
        412: 'Precondition Failed',
        413: 'Payload Too Large',
        414: 'URI Too Long',
        415: 'Unsupported Media Type',
        416: 'Range Not Satisfiable',
        417: 'Expectation Failed',
        421: 'Misdirected Request',
        422: 'Unprocessable Entity',
        423: 'Locked',
        424: 'Failed Dependency',
        425: 'Unassigned',
        426: 'Upgrade Required',
        427: 'Unassigned',
        428: 'Precondition Required',
        429: 'Too Many Requests',
        430: 'Unassigned',
        431: 'Request Header Fields Too Large',
        500: 'Internal Server Error',
        501: 'Not Implemented',
        502: 'Bad Gateway',
        503: 'Service Unavailable',
        504: 'Gateway Timeout',
        505: 'HTTP Version Not Supported',
        506: 'Variant Also Negotiates',
        507: 'Insufficient Storage',
        508: 'Loop Detected',
        509: 'Unassigned',
        510: 'Not Extended',
        511: 'Network Authentication Required'
    };

    return function(statusCode) {
        return listing[statusCode];
    };
})();
var setupIndex = function(request, type, payload) {
    if (type == 'begin-request') {
        var url = parse(payload.url);
        payload.path = url.pathname;
        payload.query = url.query;

        request._requestStartTime = payload.startTime;
        request._requestMethod = payload.method;
        request._requestUrl = payload.path + payload.query;
        request._requestIsAjax = payload.requestIsAjax;
    }
    if (type == 'end-request') {
        var contentType = payload.headers && payload.headers['Content-Type'];
        payload.contentType = contentType;

        request._responseStatusCode = payload.statusCode;
        request._responseStatusText = getStatusCodeText(payload.statusCode);
        request._responseContentType = payload.contentType;
        request._responseContentCategory = getContentTypeCategory(payload.contentType);

        payload.statusText = request._responseStatusText;
        payload.contentCategory = request._responseContentCategory;
    }
    if (type == 'user-identification') {
        request._userId = payload.userId;
    }
}

module.exports = {
    registerStrategy: function(strategy) {
        _strategies.push(strategy);

        glimpse.emit('system.request.converter.strategy.added', { strategy: strategy });
    },
    createRequest: function(requestId) {
        return {
            id: requestId,
            messages: {}
        };
    },
    convertMessages: function(request, messages) {
        var didUpdate = false;

        // setup the type index
        if (!request.types) {
            request.types = {};
        }

        _.forEach(messages, function(message) {
            if (!request.messages[message.id]) {
                // copy across the messages into the message index
                request.messages[message.id] = message;

                // copy across the messages into the type index
                _.forEach(message.types, function(type) {
                    if (!request.types[type]) {
                        request.types[type] = [];

                        // hack because we commonly use datatime in sorting and its expensive to get
                        setupIndex(request, type, message.payload);
                    }

                    request.types[type].push(message.id);
                });

                // run through the registered providers
                _.forEach(_strategies, function(action) {
                    action(request, message) || didUpdate;
                });

                didUpdate = true;
            }
        });

        return didUpdate;
    }
};

// TODO: Need to come up with a better self registration process
(function() {
    var registerStrategy = module.exports.registerStrategy;

    // NOTE: Removing for the time being... doesn't looks like this will be needed
    // TODO: Check if this can be removed
    registerStrategy(require('./request-converter-strategy-tab___TEMP'));
    registerStrategy(require('./request-converter-strategy-tab-message___TEMP'));
})();
<commit_msg>Simply converter logic a little where we are defining derived properties<commit_after>'use strict';

var _ = require('lodash');
var parse = require('url-parse');
var glimpse = require('glimpse');

var _strategies = [];

var getContentTypeCategory = (function() {
    var listing = {
        'text/html':                   {'document': true},
        'text/plain':                  {'document': true},
        'application/xhtml+xml':       {'document': true},
        'text/xml':                    {'data': true},
        'application/json':            {'data': true},
        'text/css':                    {'stylesheet': true},
        'text/xsl':                    {'stylesheet': true},
        'image/jpg':                   {'image': true},
        'image/jpeg':                  {'image': true},
        'image/pjpeg':                 {'image': true},
        'image/png':                   {'image': true},
        'image/gif':                   {'image': true},
        'image/bmp':                   {'image': true},
        'image/svg+xml':               {'image': true, 'font': true, 'document': true},
        'image/vnd.microsoft.icon':    {'image': true},
        'image/webp':                  {'image': true},
        'image/x-icon':                {'image': true},
        'image/x-xbitmap':             {'image': true},
        'font/ttf':                    {'font': true},
        'font/otf':                    {'font': true},
        'font/woff':                   {'font': true},
        'font/woff2':                  {'font': true},
        'font/truetype':               {'font': true},
        'font/opentype':               {'font': true},
        'application/octet-stream':    {'font': true, 'image': true},
        'application/font-woff':       {'font': true},
        'application/font-woff2':      {'font': true},
        'application/x-font-woff':     {'font': true},
        'application/x-font-type1':    {'font': true},
        'application/x-font-ttf':      {'font': true},
        'application/x-truetype-font': {'font': true},
        'text/javascript':             {'script': true},
        'text/ecmascript':             {'script': true},
        'application/javascript':      {'script': true},
        'application/ecmascript':      {'script': true},
        'application/x-javascript':    {'script': true},
        'text/javascript1.1':          {'script': true},
        'text/javascript1.2':          {'script': true},
        'text/javascript1.3':          {'script': true},
        'text/jscript':                {'script': true},
        'text/livescript':             {'script': true},
        'text/vtt':                    {'texttrack': true},
    };

    return function(contentType) {
        if (contentType) {
            var target = '';
            for (var i = 0; i < contentType.length; i++) {
                var char = contentType[i];
                if (char == ';') {
                    break;
                }
                target += char
            }

            return listing[target];
        }
    };
})();

var getStatusCodeText = (function() {
    var listing = {
        100: 'Continue',
        101: 'Switching Protocols',
        102: 'Processing',
        200: 'OK',
        201: 'Created',
        202: 'Accepted',
        203: 'Non-Authoritative Information',
        204: 'No Content',
        205: 'Reset Content',
        206: 'Partial Content',
        207: 'Multi-Status',
        208: 'Already Reported',
        226: 'IM Used',
        300: 'Multiple Choices',
        301: 'Moved Permanentl',
        302: 'Found',
        303: 'See Other',
        304: 'Not Modified',
        305: 'Use Proxy',
        307: 'Temporary Redirect',
        308: 'Permanent Redirect',
        400: 'Bad Request',
        401: 'Unauthorized',
        402: 'Payment Required',
        403: 'Forbidden',
        404: 'Not Found',
        405: 'Method Not Allowed',
        406: 'Not Acceptable',
        407: 'Proxy Authentication Required',
        408: 'Request Timeout',
        409: 'Conflict',
        410: 'Gone',
        411: 'Length Required',
        412: 'Precondition Failed',
        413: 'Payload Too Large',
        414: 'URI Too Long',
        415: 'Unsupported Media Type',
        416: 'Range Not Satisfiable',
        417: 'Expectation Failed',
        421: 'Misdirected Request',
        422: 'Unprocessable Entity',
        423: 'Locked',
        424: 'Failed Dependency',
        425: 'Unassigned',
        426: 'Upgrade Required',
        427: 'Unassigned',
        428: 'Precondition Required',
        429: 'Too Many Requests',
        430: 'Unassigned',
        431: 'Request Header Fields Too Large',
        500: 'Internal Server Error',
        501: 'Not Implemented',
        502: 'Bad Gateway',
        503: 'Service Unavailable',
        504: 'Gateway Timeout',
        505: 'HTTP Version Not Supported',
        506: 'Variant Also Negotiates',
        507: 'Insufficient Storage',
        508: 'Loop Detected',
        509: 'Unassigned',
        510: 'Not Extended',
        511: 'Network Authentication Required'
    };

    return function(statusCode) {
        return listing[statusCode];
    };
})();
var setupIndex = function(request, type, payload) {
    if (type == 'begin-request') {
        var url = parse(payload.url);
        payload.path = url.pathname;
        payload.query = url.query;

        request._requestStartTime = payload.startTime;
        request._requestMethod = payload.method;
        request._requestUrl = payload.path + payload.query;
        request._requestIsAjax = payload.requestIsAjax;
    }
    if (type == 'end-request') {
        var contentType = payload.headers && payload.headers['Content-Type'];
        payload.contentType = contentType;
        payload.statusText = getStatusCodeText(payload.statusCode);
        payload.contentCategory = getContentTypeCategory(payload.contentType);

        request._responseStatusCode = payload.statusCode;
        request._responseStatusText = payload.statusText;
        request._responseContentType = payload.contentType;
        request._responseContentCategory = payload.contentCategory;
    }
    if (type == 'user-identification') {
        request._userId = payload.userId;
    }
}

module.exports = {
    registerStrategy: function(strategy) {
        _strategies.push(strategy);

        glimpse.emit('system.request.converter.strategy.added', { strategy: strategy });
    },
    createRequest: function(requestId) {
        return {
            id: requestId,
            messages: {}
        };
    },
    convertMessages: function(request, messages) {
        var didUpdate = false;

        // setup the type index
        if (!request.types) {
            request.types = {};
        }

        _.forEach(messages, function(message) {
            if (!request.messages[message.id]) {
                // copy across the messages into the message index
                request.messages[message.id] = message;

                // copy across the messages into the type index
                _.forEach(message.types, function(type) {
                    if (!request.types[type]) {
                        request.types[type] = [];

                        // hack because we commonly use datatime in sorting and its expensive to get
                        setupIndex(request, type, message.payload);
                    }

                    request.types[type].push(message.id);
                });

                // run through the registered providers
                _.forEach(_strategies, function(action) {
                    action(request, message) || didUpdate;
                });

                didUpdate = true;
            }
        });

        return didUpdate;
    }
};

// TODO: Need to come up with a better self registration process
(function() {
    var registerStrategy = module.exports.registerStrategy;

    // NOTE: Removing for the time being... doesn't looks like this will be needed
    // TODO: Check if this can be removed
    registerStrategy(require('./request-converter-strategy-tab___TEMP'));
    registerStrategy(require('./request-converter-strategy-tab-message___TEMP'));
})();
<|endoftext|>


<commit_before>//global varibles
var width = 700;
var height = 700;
var bn = 8;		//number of boxs
var bs = 600/8; 		//boxsize

var board;			//canvas
var context;		//canvas context
var cArray = [];	//array of placed chits
var vArray = [];	//array of valid moves
var blackTurn;

var log;
var log1;
//initilizes empty arrays representing game state
function startGame()
{
	board = document.getElementById("board");
	context = board.getContext("2d");
	context.font = "50pt Calibri";

	//fills cArray with 0s
	for (var x = 0; x < bn; x++) {
		cArray[x] = [];
		vArray[x] = [];
		for (var y = 0; y < bn; y++) {
			cArray[x][y] = 0;
			vArray[x][y] = 0;
		}
	}

	//places starting pieces
	cArray[3][3] = -1;
	cArray[4][4] = -1;
	cArray[3][4] = 1;
	cArray[4][3] = 1;

	//sets starting player
	blackTurn = true;

	createValidMoveArray();

	//listens for clicks on the board
	board.addEventListener("mousedown",click,false);
	drawBoard();
}

//clears canvas and redraws board
function drawBoard()
{
	//clear and resize canvas
	//board.width = width;
	//board.height = height;

	//clears canvas
	context.fillStyle = "rgb(255,255,255)";
	context.fillRect(0, 0, width, height);
	context.fillStyle = "rgb(0,200,0)";
	context.fillRect(0, 0, bn*bs, bn*bs);

	//draw grid
	drawGrid();

	//draw pieces placed by players
	createValidMoveArray();
	drawPieces();

	drawScore();
}

//draws grid of lines
function drawGrid()
{
	//draw vertical lines
	for (var x=0; x<=bn*bs; x+= bs) {
		context.moveTo(x,0);
		context.lineTo(x,bn*bs);
	}

	//draw horizontal lines
	for (var y=0; y<=bn*bs; y+= bs) {
		context.moveTo(0,y);
		context.lineTo(bn*bs,y);
	}

	//fills in lines in offwhite
	context.strokeStyle = "rgb(190,190,190)";
	context.stroke();
}

//draw pieces placed by players
function drawPieces()
{
	for (var x = 0; x < bn; x++) {
		for (var y = 0; y < bn; y++) {
			if (cArray[x][y] != 0) {
				drawPiece(x,y,cArray[x][y],8);
			}
			else if (vArray[x][y] != 0) {
				drawPiece(x,y,vArray[x][y],30);
			}
		}
	}
}

//draws a single piece at x, y with color and size passed
//larger size values make smaller pieces
function drawPiece(x, y, color, size)
{
	if (color == 1) {
		context.fillStyle = "rgb(0,0,0)";
	}
	else {
		context.fillStyle = "rgb(255,255,255)";
	}

	context.fillRect(x*bs + size, y*bs + size, bs - size*2, bs - size*2);
}

//displays filled box count at the bottom of the screen
function drawScore()
{
	var redScore = findScore(1);
	context.fillStyle = "rgb(00,0,0)";
	context.fillText(redScore, 100, 660);

	var blueScore = findScore(-1);
	context.fillStyle = "rgb(200,200,200)";
	context.fillText(blueScore, 500, 660);

	//underlines the score if it is that players turn
	context.fillStyle = "rgb(200,0,0)";
	if (blackTurn) {
		context.fillRect(90, 670, 62, 4);
	}
	else {
		context.fillRect(490, 670, 62, 4);
	}
}

//counts the total boxes by the passed player color
function findScore(color) {
	score = 0;
	for (var x = 0; x < bn; x++) {
		for (var y = 0; y < bn; y++) {
			if (cArray[x][y] == color) {
				score++;
			}
		}
	}
	return score;
}

//called when the page is clicked
function click(e)
{
	var color = currentColor();
	var pos = findPos(this);
	var cord = findCord(e.pageX - pos.x, e.pageY - pos.y);
	if (cord) {
		//if line is added to board, redraw lines
		if (vArray[cord.x][cord.y] != 0) {
			var flippedChips = findFlipDirections(cord.x, cord.y, color);
			log = flippedChips;
			for (var i = 0; i < flippedChips.length; i++) {
				cArray[flippedChips[i].x][flippedChips[i].y] = color;
			}
			cArray[cord.x][cord.y] = color;

			blackTurn = !blackTurn;

			//uploads newboard state
			gapi.hangout.data.submitDelta({'cArray':JSON.stringify(cArray), board:JSON.stringify(blackTurn)});

			//drawBoard();
		}
	}
}

//if global state is changed, update global varibles and redraw board
gapi.hangout.data.onStateChanged(function (event ) {
	blackTurn = event.state[JSON.parse('blackTurn')];
 	cArray = event.state[JSON.parse('cArray')];
    drawBoard();
});

//finds which line the passed cord is closest to
function findCord(x, y)
{
	var RV = new Object; 	//return value

	//true if point is inside grid
	if (0 < x && x < bs*bn && 0 < y && y < bs*bn){
		xs = Math.floor(x/bs);
		ys = Math.floor(y/bs);

		RV.x = xs;
		RV.y = ys;
	}
	//cord not on grid; return false
	else {
		RV = false;
	}

	return RV;
}

//find valid moves
function createValidMoveArray() {
	var color = currentColor();
	for (var x = 0; x < bn; x++) {
		for (var y = 0; y < bn; y++) {
			vArray[x][y] = 0;
			if (cArray[x][y] == 0) {
				if (findFlipDirections(x,y,color).length>0){
					vArray[x][y] = color;
				}
			}
		}
	}
}

//from a given location, trys all flip directions
//returns an array of all the pieces that will be flipped if move is valid
//returns false otherwise
function findFlipDirections(x,y,color)
{
	var rv = [];
	var flippedChips;
	for (var dx	= -1;  dx<=1; dx++){
		for (var dy	= -1;  dy<=1; dy++){
			if (dx != 0 || dy != 0) {
				flippedChips = findFlipLength(x,y,dx,dy,color);
				for (var i = 0; i < flippedChips.length; i++) {
					log1 = flippedChips;
					rv[rv.length] = flippedChips[i];

				}
			}
		}
	}
	return rv;
}

//passed a location and direction
function findFlipLength(x,y,dx,dy,color)
{
	var rv = [];
	var i = 1;
	while (onBoard(x+i*dx,y+i*dy) && cArray[x+dx*i][y+dy*i] == -1*color) {
		i++;
	}

	if (i>1 && onBoard(x+i*dx,y+i*dy) && cArray[x+dx*i][y+dy*i] == color) {

		for (var j = 0; j<i; j++) {
			rv[j] = new Object;
			rv[j].x = x+j*dx;
			rv[j].y = y+j*dy;
		}
	}

	return rv;
}

//returns true if the cord is on the board
function onBoard(x, y) {
	return (0 <= x && x <= 7 && 0 <= y && y <= 7);
}

//finds color of the player
function currentColor(){
	var color;
	if (blackTurn) {
		color = 1;
	}
	else {
		color = -1 ;
	}
	return color;
}

//finds how much the canvas is offset in the frame
function findPos(obj) {
	var curleft = 0, curtop = 0;
	if (obj.offsetParent) {
		do {
			curleft += obj.offsetLeft;
			curtop += obj.offsetTop;
		} while (obj = obj.offsetParent);
		return { x: curleft, y: curtop };
	}
	return undefined;
}

//game starts when hangout API is ready
gapi.hangout.onApiReady.add(function(eventObj){
	if (eventObj.isApiReady) {
		startGame();
	}
});<commit_msg>changed server updating<commit_after>//global varibles
var width = 700;
var height = 700;
var bn = 8;		//number of boxs
var bs = 600/8; 		//boxsize

var board;			//canvas
var context;		//canvas context
var cArray = [];	//array of placed chits
var vArray = [];	//array of valid moves
var blackTurn;

var log;
var log1;
//initilizes empty arrays representing game state
function startGame()
{
	board = document.getElementById("board");
	context = board.getContext("2d");
	context.font = "50pt Calibri";

	//fills cArray with 0s
	for (var x = 0; x < bn; x++) {
		cArray[x] = [];
		vArray[x] = [];
		for (var y = 0; y < bn; y++) {
			cArray[x][y] = 0;
			vArray[x][y] = 0;
		}
	}

	//places starting pieces
	cArray[3][3] = -1;
	cArray[4][4] = -1;
	cArray[3][4] = 1;
	cArray[4][3] = 1;

	//sets starting player
	blackTurn = true;

	createValidMoveArray();

	//listens for clicks on the board
	board.addEventListener("mousedown",click,false);
	drawBoard();
}

//clears canvas and redraws board
function drawBoard()
{
	//clear and resize canvas
	//board.width = width;
	//board.height = height;

	//clears canvas
	context.fillStyle = "rgb(255,255,255)";
	context.fillRect(0, 0, width, height);
	context.fillStyle = "rgb(0,200,0)";
	context.fillRect(0, 0, bn*bs, bn*bs);

	//draw grid
	drawGrid();

	//draw pieces placed by players
	createValidMoveArray();
	drawPieces();

	drawScore();
}

//draws grid of lines
function drawGrid()
{
	//draw vertical lines
	for (var x=0; x<=bn*bs; x+= bs) {
		context.moveTo(x,0);
		context.lineTo(x,bn*bs);
	}

	//draw horizontal lines
	for (var y=0; y<=bn*bs; y+= bs) {
		context.moveTo(0,y);
		context.lineTo(bn*bs,y);
	}

	//fills in lines in offwhite
	context.strokeStyle = "rgb(190,190,190)";
	context.stroke();
}

//draw pieces placed by players
function drawPieces()
{
	for (var x = 0; x < bn; x++) {
		for (var y = 0; y < bn; y++) {
			if (cArray[x][y] != 0) {
				drawPiece(x,y,cArray[x][y],8);
			}
			else if (vArray[x][y] != 0) {
				drawPiece(x,y,vArray[x][y],30);
			}
		}
	}
}

//draws a single piece at x, y with color and size passed
//larger size values make smaller pieces
function drawPiece(x, y, color, size)
{
	if (color == 1) {
		context.fillStyle = "rgb(0,0,0)";
	}
	else {
		context.fillStyle = "rgb(255,255,255)";
	}

	context.fillRect(x*bs + size, y*bs + size, bs - size*2, bs - size*2);
}

//displays filled box count at the bottom of the screen
function drawScore()
{
	var redScore = findScore(1);
	context.fillStyle = "rgb(00,0,0)";
	context.fillText(redScore, 100, 660);

	var blueScore = findScore(-1);
	context.fillStyle = "rgb(200,200,200)";
	context.fillText(blueScore, 500, 660);

	//underlines the score if it is that players turn
	context.fillStyle = "rgb(200,0,0)";
	if (blackTurn) {
		context.fillRect(90, 670, 62, 4);
	}
	else {
		context.fillRect(490, 670, 62, 4);
	}
}

//counts the total boxes by the passed player color
function findScore(color) {
	score = 0;
	for (var x = 0; x < bn; x++) {
		for (var y = 0; y < bn; y++) {
			if (cArray[x][y] == color) {
				score++;
			}
		}
	}
	return score;
}

//called when the page is clicked
function click(e)
{
	var color = currentColor();
	var pos = findPos(this);
	var cord = findCord(e.pageX - pos.x, e.pageY - pos.y);
	if (cord) {
		//if line is added to board, redraw lines
		if (vArray[cord.x][cord.y] != 0) {
			var flippedChips = findFlipDirections(cord.x, cord.y, color);
			log = flippedChips;
			for (var i = 0; i < flippedChips.length; i++) {
				cArray[flippedChips[i].x][flippedChips[i].y] = color;
			}
			cArray[cord.x][cord.y] = color;

			blackTurn = !blackTurn;

			//uploads newboard state
			gapi.hangout.data.submitDelta({'cArray':JSON.stringify(cArray), board:JSON.stringify(blackTurn)});

			//drawBoard();
		}
	}
}

//finds which line the passed cord is closest to
function findCord(x, y)
{
	var RV = new Object; 	//return value

	//true if point is inside grid
	if (0 < x && x < bs*bn && 0 < y && y < bs*bn){
		xs = Math.floor(x/bs);
		ys = Math.floor(y/bs);

		RV.x = xs;
		RV.y = ys;
	}
	//cord not on grid; return false
	else {
		RV = false;
	}

	return RV;
}

//find valid moves
function createValidMoveArray() {
	var color = currentColor();
	for (var x = 0; x < bn; x++) {
		for (var y = 0; y < bn; y++) {
			vArray[x][y] = 0;
			if (cArray[x][y] == 0) {
				if (findFlipDirections(x,y,color).length>0){
					vArray[x][y] = color;
				}
			}
		}
	}
}

//from a given location, trys all flip directions
//returns an array of all the pieces that will be flipped if move is valid
//returns false otherwise
function findFlipDirections(x,y,color)
{
	var rv = [];
	var flippedChips;
	for (var dx	= -1;  dx<=1; dx++){
		for (var dy	= -1;  dy<=1; dy++){
			if (dx != 0 || dy != 0) {
				flippedChips = findFlipLength(x,y,dx,dy,color);
				for (var i = 0; i < flippedChips.length; i++) {
					log1 = flippedChips;
					rv[rv.length] = flippedChips[i];

				}
			}
		}
	}
	return rv;
}

//passed a location and direction
function findFlipLength(x,y,dx,dy,color)
{
	var rv = [];
	var i = 1;
	while (onBoard(x+i*dx,y+i*dy) && cArray[x+dx*i][y+dy*i] == -1*color) {
		i++;
	}

	if (i>1 && onBoard(x+i*dx,y+i*dy) && cArray[x+dx*i][y+dy*i] == color) {

		for (var j = 0; j<i; j++) {
			rv[j] = new Object;
			rv[j].x = x+j*dx;
			rv[j].y = y+j*dy;
		}
	}

	return rv;
}

//returns true if the cord is on the board
function onBoard(x, y) {
	return (0 <= x && x <= 7 && 0 <= y && y <= 7);
}

//finds color of the player
function currentColor(){
	var color;
	if (blackTurn) {
		color = 1;
	}
	else {
		color = -1 ;
	}
	return color;
}

//finds how much the canvas is offset in the frame
function findPos(obj) {
	var curleft = 0, curtop = 0;
	if (obj.offsetParent) {
		do {
			curleft += obj.offsetLeft;
			curtop += obj.offsetTop;
		} while (obj = obj.offsetParent);
		return { x: curleft, y: curtop };
	}
	return undefined;
}

//game starts when hangout API is ready
gapi.hangout.onApiReady.add(function(eventObj){
	if (eventObj.isApiReady) {
		startGame();
		gapi.hangout.data.onStateChanged.add(function(stateChangeEvent) {
          serverUpdate(stateChangeEvent.state);
		});
	}
});

//if global state is changed, update global varibles and redraw board
function serverUpdate(event){
	blackTurn = event.state[JSON.parse('blackTurn')];
 	cArray = event.state[JSON.parse('cArray')];
    drawBoard();
}
<|endoftext|>


<commit_before>view = Backbone.View.extend();

view.prototype.events = {
    'click .swatch': 'colorOpen',
    'click .swatch a[href=#save]': 'colorSave',
    'click .swatch a[href=#close]': 'colorClose',
    'click a.add': 'stylesheetAdd',
    'click a.icon': 'stylesheetDelete',
    'sortupdate .tabs': 'sortStylesheets',
    'click .status a[href=#close]': 'statusClose'
};

view.prototype.initialize = function() {
    _(this).bindAll(
        'render',
        'attach',
        'save',
        'error',
        'makeStylesheet',
        'stylesheetAdd',
        'stylesheetDelete',
        'sortStylesheets',
        'statusClose',
        'colors',
        'colorOpen',
        'colorSave',
        'colorClose'
    );
    this.model.bind('save', this.save);
    this.model.bind('saved', this.attach);
    this.model.bind('error', this.error);
    this.model.bind('poll', this.render);
    this.model.bind('poll', this.attach);
    this.render().attach();
};

view.prototype.render = function(init) {
    $(this.el).html(templates.Editor());
    this.model.get('Stylesheet').chain().each(this.makeStylesheet);
    this.$('.tabs').sortable({
        axis: 'x',
        containment: 'parent',
        tolerance: 'pointer'
    });
    return this;
};

view.prototype.attach = function() {
    this.statusClose();
    this.colors();
    return this;
};

view.prototype.save = function() {
    this.model.get('Stylesheet').forEach(function(model) {
        if (model.errors) {
            model.errors = [];
            for (i = 0; i < (model.codemirror.getValue().match(/\n/g)||[]).length+1; i++) {
                model.codemirror.clearMarker(i);
            }
        }
    });
    this.$('.tabs a.error').removeClass('error');
};

// Test for a Carto error of the form
//
//     style.mss:2 Invalid value for background-color ...
//
// and highlight the line number and stylesheet appropriately if
// found. Otherwise, display error in a modal.
view.prototype.error = function(model, resp) {
    console.log('parsing carto erro')
    if (resp.responseText) {
        // this assume Carto.js specific error array format response
        var err_message = JSON.parse(resp.responseText).message;
        var err_group = _(err_message.toString().split('\n')).compact();
        if (err_group.length == 0)
            console.log('here no error');
        for (var i = 0; i < err_group.length; i++) {
            var match = err_group[i].match(/^(Error: )?([\w.]+):([\d]+):([\d]+) (.*)$/);
            if (match) {
                var stylesheet = this.model.get('Stylesheet').get(match[2]),
                    id = 'stylesheet-' + stylesheet.id.replace(/[\.]/g, '-'),
                    lineNum = parseInt(match[3]) - 1;
                this.$('.tabs a[href=#' + id + ']').addClass('error');
                stylesheet.errors = stylesheet.errors || [];
                stylesheet.errors[lineNum] = match[5];
                stylesheet.codemirror.setMarker(lineNum, '%N%', 'error');
            } else {
                console.log('here1')
                new views.Modal(err_group[i]);
                break;
            }
        }
    } else {
        // will hit this if the server is offline and the user tries to save
        // We attach a error message to this resp object so that that the Modal can display it
        console.log('here2')
        resp.err_message = 'Could not save project "' + model.id + '"';
        new views.Modal(resp);
    }
};

view.prototype.makeStylesheet = function(model) {
    if (!CodeMirror) throw new Error('CodeMirror not found.');
    var codeEl = this.$('.code').get(0),
        self = this,
        id = 'stylesheet-' + model.id.replace(/[\.]/g, '-');
    model.el = $(templates.ProjectStylesheet(model));
    model.codemirror = CodeMirror(codeEl, {
        value: model.get('data'),
        lineNumbers: true,
        tabMode: 'shift',
        mode: {
            name: 'carto',
            reference: window.abilities.carto,
            onColor: this.colors
        },
        onCursorActivity: function() {
            model.set({'data': model.codemirror.getValue()});
        },
        onChange: function() {
            // onchange runs before this function is finished,
            // so self.codemirror is false.
            model.codemirror && model.set({
                data: model.codemirror.getValue()
            });
            _.debounce(self.colors, 500);
        },
        onGutterClick: _(function(editor, line, ev) {
            if (model.errors && model.errors[line]) {
                this.$('.status').addClass('active');
                this.$('.status .content').text(model.errors[line]);
                return false;
            }
        }).bind(this)
    });

    var cartoCompleter = cartoCompletion(
        model.codemirror,
        window.abilities.carto);

    function updateSelectors(model) {
        var ids = _.map(model.get('Layer').pluck('id'),
            function(x) { return '#' + x; });
        var classes = _(model.get('Layer').pluck('class')).chain().map(
            function(c) {
                if (c == undefined) return '';
                var cs = c.split(' ');
                if (cs[0] == '') return '';
                return _.map(cs, function(x) { return '.' + x; });
            }).flatten().compact().value();
        cartoCompleter.ids(ids);
        cartoCompleter.classes(classes);
    }

    this.model.bind('change', updateSelectors);
    updateSelectors(this.model);

    model.codemirror.setOption('onKeyEvent',
        cartoCompleter.onKeyEvent);

    model.codemirror.setOption('onHighlightComplete',
        _.throttle(cartoCompleter.setTitles, 100));

    $(model.codemirror.getWrapperElement())
        .addClass(id)
        .addClass(model.collection.indexOf(model) === 0 ? 'active' : '');
    this.$('.tabs').append(model.el);

    // Bind to the 'remove' event to teardown.
    model.bind('remove', _(function(model) {
        model.el.remove();
        $(model.codemirror.getWrapperElement()).remove();
        this.$('.tabs a.tab:last').click();
    }).bind(this));
};

view.prototype.stylesheetAdd = function(ev) {
    var model = new models.Stylesheet({}, {
        collection: this.model.get('Stylesheet')
    });
    model.bind('add', this.makeStylesheet);
    new views.Stylesheet({el:$('#popup'), model:model});
};

view.prototype.stylesheetDelete = function(ev) {
    var id = $(ev.currentTarget).attr('href').split('#').pop();
    new views.Modal({
        content: 'Are you sure you want to delete stylesheet "' + id + '"?',
        callback: _(function() {
            var model = this.model.get('Stylesheet').get(id);
            this.model.get('Stylesheet').remove(model);
        }).bind(this),
        affirmative: 'Delete'
    });
};

view.prototype.sortStylesheets = function() {
    var order = _(this.$('.tabs li a.icon')).chain()
        .map(function(el) { return $(el).attr('href').split('#').pop(); })
        .uniq()
        .value();
    this.model.get('Stylesheet').models = this.model.get('Stylesheet')
        .sortBy(function(model) { return _(order).indexOf(model.id) });
    this.model.get('Stylesheet').trigger('change');
};

view.prototype.statusClose = function(ev) {
    this.$('.status').removeClass('active');
    return false;
};

view.prototype.css2rgb = function(c) {
    var x = function(i, size) {
        return Math.round(parseInt(c.substr(i, size), 16)
            / (Math.pow(16, size) - 1) * 255);
    };
    if (c[0] === '#' && c.length == 7) {
        return {R:x(1, 2), G:x(3, 2), B:x(5, 2)};
    } else if (c[0] === '#' && c.length == 4) {
        return {R:x(1, 1), G:x(2, 1), B:x(3, 1)};
    } else {
        var rgb = c.match(/\d+/g);
        return {R:rgb[0], G:rgb[1], B:rgb[2]};
    }
};

view.prototype.colorOpen = function(ev) {
    // Colorpicker uses canvas... disable in IE for now.
    if ($.browser.msie) return;

    if (this.$('#colorpicker').size()) return;

    var swatch = $(ev.currentTarget);
    $(this.el).addClass('overlay');
    this.$('.colors').addClass('active');
    var find = swatch.attr('title');
    var hsv = Color.RGB_HSV(this.css2rgb(find));
    var picker = $(templates.Colorpicker({find:find}));
    new Color.Picker({
        hue: hsv.H,
        sat: hsv.S,
        val: hsv.V,
        element: picker.get(0),
        callback: _(function(hex) {
            $('.color', swatch).css('backgroundColor', '#'+hex);
        }).bind(this)
    });
    swatch.append(picker);
};

view.prototype.colorSave = function(ev) {
    var swatch = $(ev.currentTarget).parents('.swatch');
    var from = $('input[name=find]', swatch).val();
    var to = $('.color', swatch).css('backgroundColor');
    if (from) {
        from = from.replace('(', '\\(').replace(')', '\\)');
        from = new RegExp(from, 'g');
        to = '#' + Color.HEX_STRING(Color.RGB_HEX(this.css2rgb(to)));
        this.model.get('Stylesheet').each(function(s) {
            var data = s.get('data').replace(from, to);
            s.set({ data: data });
            var lines = data.split("\n");
            s.codemirror.replaceRange(data, {line: 0, ch: 0}, {line: lines.length, ch: lines[lines.length - 1].length });
        });
        this.model.save();
    }
    $(this.el).removeClass('overlay');
    this.$('.colors').removeClass('active');
    this.$('#colorpicker').remove();
    return false;
};

view.prototype.colorClose = function(ev) {
    var swatch = $(ev.currentTarget).parents('.swatch');
    var from = $('input[name=find]', swatch).val();
    $('.color', swatch).css('backgroundColor', from);
    $(this.el).removeClass('overlay');
    this.$('.colors').removeClass('active');
    this.$('#colorpicker').remove();
    return false;
};

view.prototype.colorList = {};
view.prototype.colors = function(color) {
    if (color) {
        this.colorList[color] = true;
    }
    // Rescan stylesheets for colors, dedupe, sort by luminosity
    // and render swatches for each one.
    this.$('.colors').empty();
    _(this.model.get('Stylesheet').pluck('data').join('\n')
        .match(/\#[A-Fa-f0-9]{6}\b|\#[A-Fa-f0-9]{3}\b|\b(rgb\s*\(\s*\d+\s*,\s*\d+\s*,\s*\d+\s*\)|rgba\s*\(\s*\d+\s*,\s*\d+\s*,\s*\d+\s*,\s*(0?\.)?\d+\s*\))/g) || []
    ).chain()
        .uniq()
        .each(_(function(color) {
            if (color[0] != '#' || this.colorList[color]) {
                var swatch = templates.ProjectSwatch({ color: color});
                this.$('.colors').append(swatch);
            }
        }).bind(this));
}

// Hook in to project view with an augment.
views.Project.augment({
    render: function(p) {
        p.call(this);
        return new views.Stylesheets({
            el:this.$('.editor'),
            model:this.model
        });
        return this;
    }
});

<commit_msg>make carto syntax errors automatically show at the bottom of page (and remove debug prints) - closes #852<commit_after>view = Backbone.View.extend();

view.prototype.events = {
    'click .swatch': 'colorOpen',
    'click .swatch a[href=#save]': 'colorSave',
    'click .swatch a[href=#close]': 'colorClose',
    'click a.add': 'stylesheetAdd',
    'click a.icon': 'stylesheetDelete',
    'sortupdate .tabs': 'sortStylesheets',
    'click .status a[href=#close]': 'statusClose'
};

view.prototype.initialize = function() {
    _(this).bindAll(
        'render',
        'attach',
        'save',
        'error',
        'makeStylesheet',
        'stylesheetAdd',
        'stylesheetDelete',
        'sortStylesheets',
        'statusClose',
        'colors',
        'colorOpen',
        'colorSave',
        'colorClose'
    );
    this.model.bind('save', this.save);
    this.model.bind('saved', this.attach);
    this.model.bind('error', this.error);
    this.model.bind('poll', this.render);
    this.model.bind('poll', this.attach);
    this.render().attach();
};

view.prototype.render = function(init) {
    $(this.el).html(templates.Editor());
    this.model.get('Stylesheet').chain().each(this.makeStylesheet);
    this.$('.tabs').sortable({
        axis: 'x',
        containment: 'parent',
        tolerance: 'pointer'
    });
    return this;
};

view.prototype.attach = function() {
    this.statusClose();
    this.colors();
    return this;
};

view.prototype.save = function() {
    this.model.get('Stylesheet').forEach(function(model) {
        if (model.errors) {
            model.errors = [];
            for (i = 0; i < (model.codemirror.getValue().match(/\n/g)||[]).length+1; i++) {
                model.codemirror.clearMarker(i);
            }
        }
    });
    this.$('.tabs a.error').removeClass('error');
};

// Test for a Carto error of the form
//
//     style.mss:2 Invalid value for background-color ...
//
// and highlight the line number and stylesheet appropriately if
// found. Otherwise, display error in a modal.
view.prototype.error = function(model, resp) {
    if (resp.responseText) {
        // this assume Carto.js specific error array format response
        var err_message = JSON.parse(resp.responseText).message;
        var err_group = _(err_message.toString().split('\n')).compact();
        for (var i = 0; i < err_group.length; i++) {
            var match = err_group[i].match(/^(Error: )?([\w.]+):([\d]+):([\d]+) (.*)$/);
            if (match) {
                var stylesheet = this.model.get('Stylesheet').get(match[2]),
                    id = 'stylesheet-' + stylesheet.id.replace(/[\.]/g, '-'),
                    lineNum = parseInt(match[3]) - 1;
                this.$('.tabs a[href=#' + id + ']').addClass('error');
                stylesheet.errors = stylesheet.errors || [];
                stylesheet.errors[lineNum] = match[5];
                stylesheet.codemirror.setMarker(lineNum, '%N%', 'error');
                var error_message = match[5] + ' (line ' + lineNum + ')';
                if (err_group.length == 1) {
                    this.$('.status').addClass('active');
                    this.$('.status .content').text(error_message);
                }
                else if (err_group.length > 1) {
                    this.$('.status').addClass('active');
                    this.$('.status .content').text("Click line number to see each error");
                }
            } else {
                new views.Modal(err_group[i]);
                break;
            }
        }
    } else {
        // will hit this if the server is offline and the user tries to save
        // We attach a error message to this resp object so that that the Modal can display it
        resp.err_message = 'Could not save project "' + model.id + '"';
        new views.Modal(resp);
    }
};

view.prototype.makeStylesheet = function(model) {
    if (!CodeMirror) throw new Error('CodeMirror not found.');
    var codeEl = this.$('.code').get(0),
        self = this,
        id = 'stylesheet-' + model.id.replace(/[\.]/g, '-');
    model.el = $(templates.ProjectStylesheet(model));
    model.codemirror = CodeMirror(codeEl, {
        value: model.get('data'),
        lineNumbers: true,
        tabMode: 'shift',
        mode: {
            name: 'carto',
            reference: window.abilities.carto,
            onColor: this.colors
        },
        onCursorActivity: function() {
            model.set({'data': model.codemirror.getValue()});
        },
        onChange: function() {
            // onchange runs before this function is finished,
            // so self.codemirror is false.
            model.codemirror && model.set({
                data: model.codemirror.getValue()
            });
            _.debounce(self.colors, 500);
        },
        onGutterClick: _(function(editor, line, ev) {
            if (model.errors && model.errors[line]) {
                this.$('.status').addClass('active');
                this.$('.status .content').text(model.errors[line]);
                return false;
            }
        }).bind(this)
    });

    var cartoCompleter = cartoCompletion(
        model.codemirror,
        window.abilities.carto);

    function updateSelectors(model) {
        var ids = _.map(model.get('Layer').pluck('id'),
            function(x) { return '#' + x; });
        var classes = _(model.get('Layer').pluck('class')).chain().map(
            function(c) {
                if (c == undefined) return '';
                var cs = c.split(' ');
                if (cs[0] == '') return '';
                return _.map(cs, function(x) { return '.' + x; });
            }).flatten().compact().value();
        cartoCompleter.ids(ids);
        cartoCompleter.classes(classes);
    }

    this.model.bind('change', updateSelectors);
    updateSelectors(this.model);

    model.codemirror.setOption('onKeyEvent',
        cartoCompleter.onKeyEvent);

    model.codemirror.setOption('onHighlightComplete',
        _.throttle(cartoCompleter.setTitles, 100));

    $(model.codemirror.getWrapperElement())
        .addClass(id)
        .addClass(model.collection.indexOf(model) === 0 ? 'active' : '');
    this.$('.tabs').append(model.el);

    // Bind to the 'remove' event to teardown.
    model.bind('remove', _(function(model) {
        model.el.remove();
        $(model.codemirror.getWrapperElement()).remove();
        this.$('.tabs a.tab:last').click();
    }).bind(this));
};

view.prototype.stylesheetAdd = function(ev) {
    var model = new models.Stylesheet({}, {
        collection: this.model.get('Stylesheet')
    });
    model.bind('add', this.makeStylesheet);
    new views.Stylesheet({el:$('#popup'), model:model});
};

view.prototype.stylesheetDelete = function(ev) {
    var id = $(ev.currentTarget).attr('href').split('#').pop();
    new views.Modal({
        content: 'Are you sure you want to delete stylesheet "' + id + '"?',
        callback: _(function() {
            var model = this.model.get('Stylesheet').get(id);
            this.model.get('Stylesheet').remove(model);
        }).bind(this),
        affirmative: 'Delete'
    });
};

view.prototype.sortStylesheets = function() {
    var order = _(this.$('.tabs li a.icon')).chain()
        .map(function(el) { return $(el).attr('href').split('#').pop(); })
        .uniq()
        .value();
    this.model.get('Stylesheet').models = this.model.get('Stylesheet')
        .sortBy(function(model) { return _(order).indexOf(model.id) });
    this.model.get('Stylesheet').trigger('change');
};

view.prototype.statusClose = function(ev) {
    this.$('.status').removeClass('active');
    return false;
};

view.prototype.css2rgb = function(c) {
    var x = function(i, size) {
        return Math.round(parseInt(c.substr(i, size), 16)
            / (Math.pow(16, size) - 1) * 255);
    };
    if (c[0] === '#' && c.length == 7) {
        return {R:x(1, 2), G:x(3, 2), B:x(5, 2)};
    } else if (c[0] === '#' && c.length == 4) {
        return {R:x(1, 1), G:x(2, 1), B:x(3, 1)};
    } else {
        var rgb = c.match(/\d+/g);
        return {R:rgb[0], G:rgb[1], B:rgb[2]};
    }
};

view.prototype.colorOpen = function(ev) {
    // Colorpicker uses canvas... disable in IE for now.
    if ($.browser.msie) return;

    if (this.$('#colorpicker').size()) return;

    var swatch = $(ev.currentTarget);
    $(this.el).addClass('overlay');
    this.$('.colors').addClass('active');
    var find = swatch.attr('title');
    var hsv = Color.RGB_HSV(this.css2rgb(find));
    var picker = $(templates.Colorpicker({find:find}));
    new Color.Picker({
        hue: hsv.H,
        sat: hsv.S,
        val: hsv.V,
        element: picker.get(0),
        callback: _(function(hex) {
            $('.color', swatch).css('backgroundColor', '#'+hex);
        }).bind(this)
    });
    swatch.append(picker);
};

view.prototype.colorSave = function(ev) {
    var swatch = $(ev.currentTarget).parents('.swatch');
    var from = $('input[name=find]', swatch).val();
    var to = $('.color', swatch).css('backgroundColor');
    if (from) {
        from = from.replace('(', '\\(').replace(')', '\\)');
        from = new RegExp(from, 'g');
        to = '#' + Color.HEX_STRING(Color.RGB_HEX(this.css2rgb(to)));
        this.model.get('Stylesheet').each(function(s) {
            var data = s.get('data').replace(from, to);
            s.set({ data: data });
            var lines = data.split("\n");
            s.codemirror.replaceRange(data, {line: 0, ch: 0}, {line: lines.length, ch: lines[lines.length - 1].length });
        });
        this.model.save();
    }
    $(this.el).removeClass('overlay');
    this.$('.colors').removeClass('active');
    this.$('#colorpicker').remove();
    return false;
};

view.prototype.colorClose = function(ev) {
    var swatch = $(ev.currentTarget).parents('.swatch');
    var from = $('input[name=find]', swatch).val();
    $('.color', swatch).css('backgroundColor', from);
    $(this.el).removeClass('overlay');
    this.$('.colors').removeClass('active');
    this.$('#colorpicker').remove();
    return false;
};

view.prototype.colorList = {};
view.prototype.colors = function(color) {
    if (color) {
        this.colorList[color] = true;
    }
    // Rescan stylesheets for colors, dedupe, sort by luminosity
    // and render swatches for each one.
    this.$('.colors').empty();
    _(this.model.get('Stylesheet').pluck('data').join('\n')
        .match(/\#[A-Fa-f0-9]{6}\b|\#[A-Fa-f0-9]{3}\b|\b(rgb\s*\(\s*\d+\s*,\s*\d+\s*,\s*\d+\s*\)|rgba\s*\(\s*\d+\s*,\s*\d+\s*,\s*\d+\s*,\s*(0?\.)?\d+\s*\))/g) || []
    ).chain()
        .uniq()
        .each(_(function(color) {
            if (color[0] != '#' || this.colorList[color]) {
                var swatch = templates.ProjectSwatch({ color: color});
                this.$('.colors').append(swatch);
            }
        }).bind(this));
}

// Hook in to project view with an augment.
views.Project.augment({
    render: function(p) {
        p.call(this);
        return new views.Stylesheets({
            el:this.$('.editor'),
            model:this.model
        });
        return this;
    }
});

<|endoftext|>


<commit_before>(function ($) {
    'use strict';

    $.extend(true, $.trumbowyg, {
        langs: {
            // jshint camelcase:false
            en: {
                fontsize: 'Font size',
                fontsizes: {
                    'x-small': 'Extra small',
                    'small': 'Small',
                    'medium': 'Regular',
                    'large': 'Large',
                    'x-large': 'Extra large',
                    'custom': 'Custom'
                },
                fontCustomSize: {
                    title: 'Custom Font Size',
                    label: 'Font Size',
                    value: '48px'
                }
            },
            es: {
                fontsize: 'Tamaño de Fuente',
                fontsizes: {
                    'x-small': 'Extra pequeña',
                    'small': 'Pegueña',
                    'medium': 'Regular',
                    'large': 'Grande',
                    'x-large': 'Extra Grande',
                    'custom': 'Customizada'
                },
                fontCustomSize: {
                    title: 'Tamaño de Fuente Customizada',
                    label: 'Tamaño de Fuente',
                    value: '48px'
                }
            },
            da: {
                fontsize: 'Skriftstørrelse',
                fontsizes: {
                    'x-small': 'Ekstra lille',
                    'small': 'Lille',
                    'medium': 'Normal',
                    'large': 'Stor',
                    'x-large': 'Ekstra stor',
                    'custom': 'Brugerdefineret'
                }
            },
            fr: {
                fontsize: 'Taille de la police',
                fontsizes: {
                    'x-small': 'Très petit',
                    'small': 'Petit',
                    'medium': 'Normal',
                    'large': 'Grand',
                    'x-large': 'Très grand',
                    'custom': 'Douane'
                }
            },
            de: {
                fontsize: 'Font size',
                fontsizes: {
                    'x-small': 'Sehr klein',
                    'small': 'Klein',
                    'medium': 'Normal',
                    'large': 'Groß',
                    'x-large': 'Sehr groß',
                    'custom': 'Benutzerdefiniert'
                }
            },
            nl: {
                fontsize: 'Lettergrootte',
                fontsizes: {
                    'x-small': 'Extra klein',
                    'small': 'Klein',
                    'medium': 'Normaal',
                    'large': 'Groot',
                    'x-large': 'Extra groot',
                    'custom': 'Tilpasset'
                }
            },
            tr: {
                fontsize: 'Yazı Boyutu',
                fontsizes: {
                    'x-small': 'Çok Küçük',
                    'small': 'Küçük',
                    'medium': 'Normal',
                    'large': 'Büyük',
                    'x-large': 'Çok Büyük',
                    'custom': 'Görenek'
                }
            },
            zh_tw: {
                fontsize: '字體大小',
                fontsizes: {
                    'x-small': '最小',
                    'small': '小',
                    'medium': '中',
                    'large': '大',
                    'x-large': '最大',
                    'custom': '自訂大小',
                },
                fontCustomSize: {
                    title: '自訂義字體大小',
                    label: '字體大小',
                    value: '48px'
                }
            }
        }
    });
    // jshint camelcase:true

    // Add dropdown with font sizes
    $.extend(true, $.trumbowyg, {
        plugins: {
            fontsize: {
                init: function (trumbowyg) {
                    trumbowyg.addBtnDef('fontsize', {
                        dropdown: buildDropdown(trumbowyg)
                    });
                }
            }
        }
    });

    function buildDropdown(trumbowyg) {
        var dropdown = [];
        var sizes = ['x-small', 'small', 'medium', 'large', 'x-large'];

        $.each(sizes, function (index, size) {
            trumbowyg.addBtnDef('fontsize_' + size, {
                text: '' + trumbowyg.lang.fontsizes[size] + '',
                hasIcon: false,
                fn: function () {
                    trumbowyg.execCmd('fontSize', index + 1, true);
                }
            });
            dropdown.push('fontsize_' + size);
        });

        var freeSizeButtonName = 'fontsize_custom',
            freeSizeBtnDef = {
                fn: function () {
                    trumbowyg.openModalInsert(trumbowyg.lang.fontCustomSize.title,
                        {
                            size: {
                                label: trumbowyg.lang.fontCustomSize.label,
                                value: trumbowyg.lang.fontCustomSize.value
                            }
                        },
                        function (values) {
                            var text = trumbowyg.range.startContainer.parentElement;
                            var selectedText = trumbowyg.getRangeText();
                            if ($(text).html() === selectedText) {
                                $(text).css('font-size', values.size);
                            } else {
                                trumbowyg.range.deleteContents();
                                var html = '' + selectedText + '';
                                var node = $(html)[0];
                                trumbowyg.range.insertNode(node);
                            }
                            trumbowyg.saveRange();
                            return true;
                        }
                    );
                },
                text: '' + trumbowyg.lang.fontsizes.custom + '',
                hasIcon: false
            };
        trumbowyg.addBtnDef(freeSizeButtonName, freeSizeBtnDef);
        dropdown.push(freeSizeButtonName);

        return dropdown;
    }
})(jQuery);<commit_msg>Update trumbowyg.fontsize.js<commit_after>(function ($) {
    'use strict';

    $.extend(true, $.trumbowyg, {
        langs: {
            // jshint camelcase:false
            en: {
                fontsize: 'Font size',
                fontsizes: {
                    'x-small': 'Extra small',
                    'small': 'Small',
                    'medium': 'Regular',
                    'large': 'Large',
                    'x-large': 'Extra large',
                    'custom': 'Custom'
                },
                fontCustomSize: {
                    title: 'Custom Font Size',
                    label: 'Font Size',
                    value: '48px'
                }
            },
            es: {
                fontsize: 'Tamaño de Fuente',
                fontsizes: {
                    'x-small': 'Extra pequeña',
                    'small': 'Pegueña',
                    'medium': 'Regular',
                    'large': 'Grande',
                    'x-large': 'Extra Grande',
                    'custom': 'Customizada'
                },
                fontCustomSize: {
                    title: 'Tamaño de Fuente Customizada',
                    label: 'Tamaño de Fuente',
                    value: '48px'
                }
            },
            da: {
                fontsize: 'Skriftstørrelse',
                fontsizes: {
                    'x-small': 'Ekstra lille',
                    'small': 'Lille',
                    'medium': 'Normal',
                    'large': 'Stor',
                    'x-large': 'Ekstra stor',
                    'custom': 'Brugerdefineret'
                }
            },
            fr: {
                fontsize: 'Taille de la police',
                fontsizes: {
                    'x-small': 'Très petit',
                    'small': 'Petit',
                    'medium': 'Normal',
                    'large': 'Grand',
                    'x-large': 'Très grand',
                    'custom': 'Douane'
                }
            },
            de: {
                fontsize: 'Font size',
                fontsizes: {
                    'x-small': 'Sehr klein',
                    'small': 'Klein',
                    'medium': 'Normal',
                    'large': 'Groß',
                    'x-large': 'Sehr groß',
                    'custom': 'Benutzerdefiniert'
                },
                fontCustomSize: {
                    title: 'Benutzerdefinierte Schriftgröße',
                    label: 'Schriftgröße',
                    value: '48px'
                }
            },
            nl: {
                fontsize: 'Lettergrootte',
                fontsizes: {
                    'x-small': 'Extra klein',
                    'small': 'Klein',
                    'medium': 'Normaal',
                    'large': 'Groot',
                    'x-large': 'Extra groot',
                    'custom': 'Tilpasset'
                }
            },
            tr: {
                fontsize: 'Yazı Boyutu',
                fontsizes: {
                    'x-small': 'Çok Küçük',
                    'small': 'Küçük',
                    'medium': 'Normal',
                    'large': 'Büyük',
                    'x-large': 'Çok Büyük',
                    'custom': 'Görenek'
                }
            },
            zh_tw: {
                fontsize: '字體大小',
                fontsizes: {
                    'x-small': '最小',
                    'small': '小',
                    'medium': '中',
                    'large': '大',
                    'x-large': '最大',
                    'custom': '自訂大小',
                },
                fontCustomSize: {
                    title: '自訂義字體大小',
                    label: '字體大小',
                    value: '48px'
                }
            }
        }
    });
    // jshint camelcase:true

    // Add dropdown with font sizes
    $.extend(true, $.trumbowyg, {
        plugins: {
            fontsize: {
                init: function (trumbowyg) {
                    trumbowyg.addBtnDef('fontsize', {
                        dropdown: buildDropdown(trumbowyg)
                    });
                }
            }
        }
    });

    function buildDropdown(trumbowyg) {
        var dropdown = [];
        var sizes = ['x-small', 'small', 'medium', 'large', 'x-large'];

        $.each(sizes, function (index, size) {
            trumbowyg.addBtnDef('fontsize_' + size, {
                text: '' + trumbowyg.lang.fontsizes[size] + '',
                hasIcon: false,
                fn: function () {
                    trumbowyg.execCmd('fontSize', index + 1, true);
                }
            });
            dropdown.push('fontsize_' + size);
        });

        var freeSizeButtonName = 'fontsize_custom',
            freeSizeBtnDef = {
                fn: function () {
                    trumbowyg.openModalInsert(trumbowyg.lang.fontCustomSize.title,
                        {
                            size: {
                                label: trumbowyg.lang.fontCustomSize.label,
                                value: trumbowyg.lang.fontCustomSize.value
                            }
                        },
                        function (values) {
                            var text = trumbowyg.range.startContainer.parentElement;
                            var selectedText = trumbowyg.getRangeText();
                            if ($(text).html() === selectedText) {
                                $(text).css('font-size', values.size);
                            } else {
                                trumbowyg.range.deleteContents();
                                var html = '' + selectedText + '';
                                var node = $(html)[0];
                                trumbowyg.range.insertNode(node);
                            }
                            trumbowyg.saveRange();
                            return true;
                        }
                    );
                },
                text: '' + trumbowyg.lang.fontsizes.custom + '',
                hasIcon: false
            };
        trumbowyg.addBtnDef(freeSizeButtonName, freeSizeBtnDef);
        dropdown.push(freeSizeButtonName);

        return dropdown;
    }
})(jQuery);
<|endoftext|>


<commit_before>/**
 * Created by truthlighting on 9/14/2016.
 */
var roleBuilder = {

    /** @param {Creep} creep **/
    run: function(creep) {
        var activeSource = creep.pos.findClosestByPath(FIND_SOURCES_ACTIVE);
        if (creep.memory.building && creep.carry.energy == 0 && (activeSource !== null)) {
            creep.memory.building = false;
            creep.memory.idling = false;
            creep.say('harvesting');
        } else if (!creep.memory.building && (creep.carry.energy == creep.carryCapacity || ((activeSource === null) && creep.carry.energy > 0))) {
            creep.memory.building = true;
            creep.memory.idling = false;
            creep.say('building');
        } else {
            creep.memory.idling = true;
            creep.say('B-idling')
        }

        if (creep.memory.building) {
            if (creep.room.find(FIND_CONSTRUCTION_SITES)) {
                var target = creep.pos.findClosestByPath(FIND_CONSTRUCTION_SITES);
                if (creep.build(target) == ERR_NOT_IN_RANGE) {
                    creep.moveTo(target);
                }
            } else {
                var repairThem = creep.room.find(FIND_STRUCTURES, {
                    filter: (structure) => {
                    return (structure.structureType == STRUCTURE_WALL &&
                    (structure.hits < 80000) &&
                    (structure.hits > 0));
                    }
                })

                if (creep.room.find(repairThem)) {
                    var target = creep.pos.findClosestByPath(repairThem);
                    if (creep.build(target) == ERR_NOT_IN_RANGE) {
                        creep.moveTo(target);
                        creep.say("Repair wall")
                    }
                }
            }
        }

        else if (!creep.memory.idling) {
            var target = creep.pos.findClosestByPath(FIND_SOURCES_ACTIVE);
            if (target) {
                if(creep.harvest(target) == ERR_NOT_IN_RANGE) {
                    creep.moveTo(target);
                }
            } else {
                //do something else
            }

        } else {
            var target = creep.pos.findClosestByPath([Game.flags.Flag1,Game.flags.Flag2]);
            creep.moveTo(target);
        }
    }
};

module.exports = roleBuilder;<commit_msg>debugging builder idle code<commit_after>/**
 * Created by truthlighting on 9/14/2016.
 */
var roleBuilder = {

    /** @param {Creep} creep **/
    run: function(creep) {
        var activeSource = creep.pos.findClosestByPath(FIND_SOURCES_ACTIVE);
        console.log(activeSource);
        if (creep.memory.building && creep.carry.energy == 0 && (activeSource !== null)) {
            creep.memory.building = false;
            creep.memory.idling = false;
            creep.say('harvesting');
        } else if (!creep.memory.building && (creep.carry.energy == creep.carryCapacity || ((activeSource === null) && creep.carry.energy > 0))) {
            creep.memory.building = true;
            creep.memory.idling = false;
            creep.say('building');
        } else {
            creep.memory.idling = true;
            creep.say('B-idling')
        }

        if (creep.memory.building) {
            if (creep.room.find(FIND_CONSTRUCTION_SITES)) {
                var target = creep.pos.findClosestByPath(FIND_CONSTRUCTION_SITES);
                if (creep.build(target) == ERR_NOT_IN_RANGE) {
                    creep.moveTo(target);
                }
            } else {
                var repairThem = creep.room.find(FIND_STRUCTURES, {
                    filter: (structure) => {
                    return (structure.structureType == STRUCTURE_WALL &&
                    (structure.hits < 80000) &&
                    (structure.hits > 0));
                    }
                })

                if (creep.room.find(repairThem)) {
                    var target = creep.pos.findClosestByPath(repairThem);
                    if (creep.build(target) == ERR_NOT_IN_RANGE) {
                        creep.moveTo(target);
                        creep.say("Repair wall")
                    }
                }
            }
        }

        else if (!creep.memory.idling) {
            var target = creep.pos.findClosestByPath(FIND_SOURCES_ACTIVE);
            if (target) {
                if(creep.harvest(target) == ERR_NOT_IN_RANGE) {
                    creep.moveTo(target);
                }
            } else {
                //do something else
            }

        } else {
            var target = creep.pos.findClosestByPath([Game.flags.Flag1,Game.flags.Flag2]);
            creep.moveTo(target);
        }
    }
};

module.exports = roleBuilder;<|endoftext|>


<commit_before>(function ($) {
    'use strict';

    $.extend(true, $.trumbowyg, {
        langs: {
            // jshint camelcase:false
            en: {
                fontsize: 'Font size',
                fontsizes: {
                    'x-small': 'Extra small',
                    'small': 'Small',
                    'medium': 'Regular',
                    'large': 'Large',
                    'x-large': 'Extra large',
                    'custom': 'Custom'
                },
                fontCustomSize: {
                    title: 'Custom Font Size',
                    label: 'Font Size',
                    value: '48px'
                }
            },
            da: {
                fontsize: 'Skriftstørrelse',
                fontsizes: {
                    'x-small': 'Ekstra lille',
                    'small': 'Lille',
                    'medium': 'Normal',
                    'large': 'Stor',
                    'x-large': 'Ekstra stor',
                    'custom': 'Brugerdefineret'
                }
            },
            de: {
                fontsize: 'Schriftgröße',
                fontsizes: {
                    'x-small': 'Sehr klein',
                    'small': 'Klein',
                    'medium': 'Normal',
                    'large': 'Groß',
                    'x-large': 'Sehr groß',
                    'custom': 'Benutzerdefiniert'
                },
                fontCustomSize: {
                    title: 'Benutzerdefinierte Schriftgröße',
                    label: 'Schriftgröße',
                    value: '48px'
                }
            },
            es: {
                fontsize: 'Tamaño de Fuente',
                fontsizes: {
                    'x-small': 'Extra pequeña',
                    'small': 'Pegueña',
                    'medium': 'Regular',
                    'large': 'Grande',
                    'x-large': 'Extra Grande',
                    'custom': 'Customizada'
                },
                fontCustomSize: {
                    title: 'Tamaño de Fuente Customizada',
                    label: 'Tamaño de Fuente',
                    value: '48px'
                }
            },
            fr: {
                fontsize: 'Taille de la police',
                fontsizes: {
                    'x-small': 'Très petit',
                    'small': 'Petit',
                    'medium': 'Normal',
                    'large': 'Grand',
                    'x-large': 'Très grand',
                    'custom': 'Taille personnalisée'
                },
                fontCustomSize: {
                    title: 'Taille de police personnalisée',
                    label: 'Taille de la police',
                    value: '48px'
                }
            },
            hu: {
                fontsize: 'Betű méret',
                fontsizes: {
                    'x-small': 'Extra kicsi',
                    'small': 'Kicsi',
                    'medium': 'Normális',
                    'large': 'Nagy',
                    'x-large': 'Extra nagy',
                    'custom': 'Egyedi'
                },
                fontCustomSize: {
                    title: 'Egyedi betű méret',
                    label: 'Betű méret',
                    value: '48px'
                }
            },
            it: {
                fontsize: 'Dimensioni del testo',
                fontsizes: {
                    'x-small': 'Molto piccolo',
                    'small': 'piccolo',
                    'regular': 'normale',
                    'large': 'grande',
                    'x-large': 'Molto grande',
                    'custom': 'Personalizzato'
                },
                fontCustomSize: {
                    title: 'Dimensioni del testo personalizzato',
                    label: 'Dimensioni del testo',
                    value: '48px'
                }
            },
            ko: {
                fontsize: '글꼴 크기',
                fontsizes: {
                    'x-small': '아주 작게',
                    'small': '작게',
                    'medium': '보통',
                    'large': '크게',
                    'x-large': '아주 크게',
                    'custom': '사용자 지정'
                },
                fontCustomSize: {
                    title: '사용자 지정 글꼴 크기',
                    label: '글꼴 크기',
                    value: '48px'
                }
            },
            nl: {
                fontsize: 'Lettergrootte',
                fontsizes: {
                    'x-small': 'Extra klein',
                    'small': 'Klein',
                    'medium': 'Normaal',
                    'large': 'Groot',
                    'x-large': 'Extra groot',
                    'custom': 'Tilpasset'
                }
            },
            pt_br: {
                fontsize: 'Tamanho da fonte',
                fontsizes: {
                    'x-small': 'Extra pequeno',
                    'small': 'Pequeno',
                    'regular': 'Médio',
                    'large': 'Grande',
                    'x-large': 'Extra grande',
                    'custom': 'Personalizado'
                },
                fontCustomSize: {
                    title: 'Tamanho de Fonte Personalizado',
                    label: 'Tamanho de Fonte',
                    value: '48px'
                }
            },
            tr: {
                fontsize: 'Yazı Boyutu',
                fontsizes: {
                    'x-small': 'Çok Küçük',
                    'small': 'Küçük',
                    'medium': 'Normal',
                    'large': 'Büyük',
                    'x-large': 'Çok Büyük',
                    'custom': 'Görenek'
                }
            },
            zh_tw: {
                fontsize: '字體大小',
                fontsizes: {
                    'x-small': '最小',
                    'small': '小',
                    'medium': '中',
                    'large': '大',
                    'x-large': '最大',
                    'custom': '自訂大小',
                },
                fontCustomSize: {
                    title: '自訂義字體大小',
                    label: '字體大小',
                    value: '48px'
                }
            },
        }
    });
    // jshint camelcase:true

    var defaultOptions = {
        sizeList: [
            'x-small',
            'small',
            'medium',
            'large',
            'x-large'
        ],
        allowCustomSize: true
    };

    // Add dropdown with font sizes
    $.extend(true, $.trumbowyg, {
        plugins: {
            fontsize: {
                init: function (trumbowyg) {
                    trumbowyg.o.plugins.fontsize = $.extend({},
                      defaultOptions,
                      trumbowyg.o.plugins.fontsize || {}
                    );

                    trumbowyg.addBtnDef('fontsize', {
                        dropdown: buildDropdown(trumbowyg)
                    });
                }
            }
        }
    });

    function setFontSize(trumbowyg, size) {
        trumbowyg.$ed.focus();
        trumbowyg.saveRange();

        // Temporary size
        trumbowyg.execCmd('fontSize', '1');

        // Find  elements that were added and change to  with chosen size
        trumbowyg.$ed.find('font[size="1"]').replaceWith(function() {
            return $('', {
                css: { 'font-size': size },
                html: this.innerHTML,
            });
        });

        // Remove and leftover  elements
        $(trumbowyg.range.startContainer.parentElement).find('span[style=""]').contents().unwrap();

        trumbowyg.restoreRange();
        trumbowyg.syncCode();
    }

    function buildDropdown(trumbowyg) {
        var dropdown = [];

        $.each(trumbowyg.o.plugins.fontsize.sizeList, function (index, size) {
            trumbowyg.addBtnDef('fontsize_' + size, {
                text: '' + (trumbowyg.lang.fontsizes[size] || size) + '',
                hasIcon: false,
                fn: function () {
                    setFontSize(trumbowyg, size);
                }
            });
            dropdown.push('fontsize_' + size);
        });

        if (trumbowyg.o.plugins.fontsize.allowCustomSize) {
            var customSizeButtonName = 'fontsize_custom';
            var customSizeBtnDef = {
                fn: function () {
                    trumbowyg.openModalInsert(trumbowyg.lang.fontCustomSize.title,
                        {
                            size: {
                                label: trumbowyg.lang.fontCustomSize.label,
                                value: trumbowyg.lang.fontCustomSize.value
                            }
                        },
                        function (form) {
                            setFontSize(trumbowyg, form.size);
                            return true;
                        }
                    );
                },
                text: '' + trumbowyg.lang.fontsizes.custom + '',
                hasIcon: false
            };
            trumbowyg.addBtnDef(customSizeButtonName, customSizeBtnDef);
            dropdown.push(customSizeButtonName);
        }

        return dropdown;
    }
})(jQuery);
<commit_msg>fix(fontsize): add missing tbwchange call<commit_after>(function ($) {
    'use strict';

    $.extend(true, $.trumbowyg, {
        langs: {
            // jshint camelcase:false
            en: {
                fontsize: 'Font size',
                fontsizes: {
                    'x-small': 'Extra small',
                    'small': 'Small',
                    'medium': 'Regular',
                    'large': 'Large',
                    'x-large': 'Extra large',
                    'custom': 'Custom'
                },
                fontCustomSize: {
                    title: 'Custom Font Size',
                    label: 'Font Size',
                    value: '48px'
                }
            },
            da: {
                fontsize: 'Skriftstørrelse',
                fontsizes: {
                    'x-small': 'Ekstra lille',
                    'small': 'Lille',
                    'medium': 'Normal',
                    'large': 'Stor',
                    'x-large': 'Ekstra stor',
                    'custom': 'Brugerdefineret'
                }
            },
            de: {
                fontsize: 'Schriftgröße',
                fontsizes: {
                    'x-small': 'Sehr klein',
                    'small': 'Klein',
                    'medium': 'Normal',
                    'large': 'Groß',
                    'x-large': 'Sehr groß',
                    'custom': 'Benutzerdefiniert'
                },
                fontCustomSize: {
                    title: 'Benutzerdefinierte Schriftgröße',
                    label: 'Schriftgröße',
                    value: '48px'
                }
            },
            es: {
                fontsize: 'Tamaño de Fuente',
                fontsizes: {
                    'x-small': 'Extra pequeña',
                    'small': 'Pegueña',
                    'medium': 'Regular',
                    'large': 'Grande',
                    'x-large': 'Extra Grande',
                    'custom': 'Customizada'
                },
                fontCustomSize: {
                    title: 'Tamaño de Fuente Customizada',
                    label: 'Tamaño de Fuente',
                    value: '48px'
                }
            },
            fr: {
                fontsize: 'Taille de la police',
                fontsizes: {
                    'x-small': 'Très petit',
                    'small': 'Petit',
                    'medium': 'Normal',
                    'large': 'Grand',
                    'x-large': 'Très grand',
                    'custom': 'Taille personnalisée'
                },
                fontCustomSize: {
                    title: 'Taille de police personnalisée',
                    label: 'Taille de la police',
                    value: '48px'
                }
            },
            hu: {
                fontsize: 'Betű méret',
                fontsizes: {
                    'x-small': 'Extra kicsi',
                    'small': 'Kicsi',
                    'medium': 'Normális',
                    'large': 'Nagy',
                    'x-large': 'Extra nagy',
                    'custom': 'Egyedi'
                },
                fontCustomSize: {
                    title: 'Egyedi betű méret',
                    label: 'Betű méret',
                    value: '48px'
                }
            },
            it: {
                fontsize: 'Dimensioni del testo',
                fontsizes: {
                    'x-small': 'Molto piccolo',
                    'small': 'piccolo',
                    'regular': 'normale',
                    'large': 'grande',
                    'x-large': 'Molto grande',
                    'custom': 'Personalizzato'
                },
                fontCustomSize: {
                    title: 'Dimensioni del testo personalizzato',
                    label: 'Dimensioni del testo',
                    value: '48px'
                }
            },
            ko: {
                fontsize: '글꼴 크기',
                fontsizes: {
                    'x-small': '아주 작게',
                    'small': '작게',
                    'medium': '보통',
                    'large': '크게',
                    'x-large': '아주 크게',
                    'custom': '사용자 지정'
                },
                fontCustomSize: {
                    title: '사용자 지정 글꼴 크기',
                    label: '글꼴 크기',
                    value: '48px'
                }
            },
            nl: {
                fontsize: 'Lettergrootte',
                fontsizes: {
                    'x-small': 'Extra klein',
                    'small': 'Klein',
                    'medium': 'Normaal',
                    'large': 'Groot',
                    'x-large': 'Extra groot',
                    'custom': 'Tilpasset'
                }
            },
            pt_br: {
                fontsize: 'Tamanho da fonte',
                fontsizes: {
                    'x-small': 'Extra pequeno',
                    'small': 'Pequeno',
                    'regular': 'Médio',
                    'large': 'Grande',
                    'x-large': 'Extra grande',
                    'custom': 'Personalizado'
                },
                fontCustomSize: {
                    title: 'Tamanho de Fonte Personalizado',
                    label: 'Tamanho de Fonte',
                    value: '48px'
                }
            },
            tr: {
                fontsize: 'Yazı Boyutu',
                fontsizes: {
                    'x-small': 'Çok Küçük',
                    'small': 'Küçük',
                    'medium': 'Normal',
                    'large': 'Büyük',
                    'x-large': 'Çok Büyük',
                    'custom': 'Görenek'
                }
            },
            zh_tw: {
                fontsize: '字體大小',
                fontsizes: {
                    'x-small': '最小',
                    'small': '小',
                    'medium': '中',
                    'large': '大',
                    'x-large': '最大',
                    'custom': '自訂大小',
                },
                fontCustomSize: {
                    title: '自訂義字體大小',
                    label: '字體大小',
                    value: '48px'
                }
            },
        }
    });
    // jshint camelcase:true

    var defaultOptions = {
        sizeList: [
            'x-small',
            'small',
            'medium',
            'large',
            'x-large'
        ],
        allowCustomSize: true
    };

    // Add dropdown with font sizes
    $.extend(true, $.trumbowyg, {
        plugins: {
            fontsize: {
                init: function (trumbowyg) {
                    trumbowyg.o.plugins.fontsize = $.extend({},
                      defaultOptions,
                      trumbowyg.o.plugins.fontsize || {}
                    );

                    trumbowyg.addBtnDef('fontsize', {
                        dropdown: buildDropdown(trumbowyg)
                    });
                }
            }
        }
    });

    function setFontSize(trumbowyg, size) {
        trumbowyg.$ed.focus();
        trumbowyg.saveRange();

        // Temporary size
        trumbowyg.execCmd('fontSize', '1');

        // Find  elements that were added and change to  with chosen size
        trumbowyg.$ed.find('font[size="1"]').replaceWith(function() {
            return $('', {
                css: { 'font-size': size },
                html: this.innerHTML,
            });
        });

        // Remove and leftover  elements
        $(trumbowyg.range.startContainer.parentElement).find('span[style=""]').contents().unwrap();

        trumbowyg.restoreRange();
        trumbowyg.syncCode();
        trumbowyg.$c.trigger('tbwchange');
    }

    function buildDropdown(trumbowyg) {
        var dropdown = [];

        $.each(trumbowyg.o.plugins.fontsize.sizeList, function (index, size) {
            trumbowyg.addBtnDef('fontsize_' + size, {
                text: '' + (trumbowyg.lang.fontsizes[size] || size) + '',
                hasIcon: false,
                fn: function () {
                    setFontSize(trumbowyg, size);
                }
            });
            dropdown.push('fontsize_' + size);
        });

        if (trumbowyg.o.plugins.fontsize.allowCustomSize) {
            var customSizeButtonName = 'fontsize_custom';
            var customSizeBtnDef = {
                fn: function () {
                    trumbowyg.openModalInsert(trumbowyg.lang.fontCustomSize.title,
                        {
                            size: {
                                label: trumbowyg.lang.fontCustomSize.label,
                                value: trumbowyg.lang.fontCustomSize.value
                            }
                        },
                        function (form) {
                            setFontSize(trumbowyg, form.size);
                            return true;
                        }
                    );
                },
                text: '' + trumbowyg.lang.fontsizes.custom + '',
                hasIcon: false
            };
            trumbowyg.addBtnDef(customSizeButtonName, customSizeBtnDef);
            dropdown.push(customSizeButtonName);
        }

        return dropdown;
    }
})(jQuery);
<|endoftext|>


<commit_before>/**
  Role Manager Middleware
  @description Provides middleware that can be inserted into a router that
    serves as an access level gateway for deciding if a user can retrieve
    the given content. Must be run *after* the Verify Authtoken middleware
    so that the current user's role is set properly.
  @author tylerFowler
**/
<commit_msg>Added role manager w/ restrict to & getfromMin functions<commit_after>/**
  Role Manager Middleware
  @description Provides middleware that can be inserted into a router that
    serves as an access level gateway for deciding if a user can retrieve
    the given content. Must be run *after* the Verify Authtoken middleware
    so that the current user's role is set properly.
  @author tylerFowler
**/
'use strict';

const _ = require('underscore');

// character that represents 'All' roles
const RoleWildcard = '*';

module.exports = exports = RoleManager;

function RoleManager(roles) {
  this.roles = roles;
}

/**
  @name RoleManager#restrictTo
  @desc Middleware that restricts access to a route to the given role list
    Note that this must be run *after* the verify token middleware or any
    middleware that sets the 'userRole' key on the request object
  @param { String[]|String } allowedRoles
  @returns 401 Unauthorized if the user role key is not present
  @returns 403 Forbidden if the request's role isn't in the allowd roles list
**/
RoleManager.prototype.restrictTo = function restrictTo(allowedRoles) {
  restrictToExpress.call(this, allowedRoles);
};

let restrictToExpress = function restrictTo(allowedRoles) {
  return (req, res, next) => {
    if (!Array.isArray(allowedRoles)) allowedRoles = [allowedRoles];

    if (_.contains(allowedRoles, RoleWildcard)) return next();
    if (!req.userRole) return res.sendStatus(401);
    if (_.contains(allowedRoles, req.userRole)) return next();

    res.sendStatus(403);
  };
};

/**
  RoleManager#getRolesFromMinimum
  @desc Gets the list of every role above & including the given min role
    Note that this assumes that the list of roles is lowest to highest priority
  @param { String } minRole => a value in the role list, case insensitive
  @returns { String[] }
  @throws InvalidRoleError if minRole is not a value in roles
**/
RoleManager.prototype.getRolesFromMinimum =
function getRolesFromMinimum(minRole) {
  return _.chain(this.roles)
  .map(r => r.toLowerCase())
  .last(roles.length - this.roles.findIndex(r => r === minRole.toLowerCase()))
  .value();
};
<|endoftext|>


<commit_before>var express = require('express');
var passport = require('passport');
var mongoPersister = require('../lib/persister/mongoPersister');
var router = express.Router();

/*
 router.get('/register', function(req, res) {
 res.render('register', { });
 });

 router.post('/register', function(req, res, next) {
 Account.register(new Account({ username : req.body.username }), req.body.password, function(err, account) {
 if (err) {
 return res.render("register", {info: "Sorry. That username already exists. Try again."});
 }

 passport.authenticate('local')(req, res, function () {
 req.session.save(function (err) {
 if (err) {
 return next(err);
 }
 res.redirect('/');
 });
 });
 });
 });
 */

router.get('/', function (req, res) {
  res.redirect('/admin/login');
});

router.get('/login', function (req, res) {
  res.render('admin/login', {user: req.user});
});

router.post('/login', passport.authenticate('local'), function (req, res, next) {
  req.session.save(function (err) {
    if (err) {
      //return next(err);
      res.redirect('/admin/login');
    }
    res.redirect('/admin/main');
  });
});

router.get('/logout', function (req, res, next) {
  req.logout();
  req.session.save(function (err) {
    if (err) {
      return next(err);
    }
    res.redirect('/admin/login');
  });
});

var isAuthenticated = function (req, res, next) {
  if (req.isAuthenticated()) return next();
  res.redirect('/admin/login');
}

router.get('/main', isAuthenticated, function (req, res) {
  res.render('admin/main', {});
});

router.post('/search', isAuthenticated, function (req, res) {

  console.log(req.body);

  mongoPersister.retrieveReservationList(req.body, function (err, result) {

    console.log(err, result);

    res.json({
      status: 'OK',
      result: result
    });

  });

});

module.exports = router;<commit_msg>이제 어느 정도 마무우우우우의리!<commit_after>var express = require('express');
var passport = require('passport');
var mongoPersister = require('../lib/persister/mongoPersister');
var router = express.Router();

var isAuthenticated = function (req, res, next) {
  if (req.isAuthenticated()) return next();
  res.redirect('/admin/login');
}

router.get('/', function (req, res) {
  res.redirect('/admin/login');
});

router.get('/login', function (req, res) {
  if (req.isAuthenticated()) {
    res.redirect('/admin/main');
  }else{
    res.render('admin/login', {user: req.user});
  }
});

router.post('/login', passport.authenticate('local'), function (req, res, next) {
  req.session.save(function (err) {
    if (err) {
      //return next(err);
      res.redirect('/admin/login');
    }
    res.redirect('/admin/main');
  });
});

router.get('/logout', function (req, res, next) {
  req.logout();
  req.session.save(function (err) {
    if (err) {
      return next(err);
    }
    res.redirect('/admin/login');
  });
});

router.get('/main', isAuthenticated, function (req, res) {
  res.render('admin/main', {});
});

router.post('/search', isAuthenticated, function (req, res) {

  console.log(req.body);

  mongoPersister.retrieveReservationList(req.body, function (err, result) {

    console.log(err, result);

    res.json({
      status: 'OK',
      result: result
    });

  });

});

module.exports = router;<|endoftext|>