<commit_before>/**
 *
 */

var assert=require('assert');
assert.equal(true, true);

var ws=require('ws');

var testNumber=0;

function EchoTest(BridgeProxy, AutoConnectProxy, config, callbackFn){

	var cleanup=function(){}; //reassigned

	var callback=function(err, msg){
		callbackFn(err, msg);
		cleanup();
		callback=function(){}; //avoid multiple executions, but don't worry about it below.
	}

	var test=testNumber;
	testNumber++;
	console.log('Running Test: '+test);
	//a ws server that just echos back all messages...
	var echo=(new ws.Server({
		port: config.echo
	},function(){

		cleanup=function(){
			echo.close();
		}

		var basicauth='';
		basicauth='nickolanack:nick';

//		a bridge server. pairs clients with autoconnect proxy connections.
		var WSBridge=require('../bridgeproxy.js');
		var bridge=new WSBridge({
			port:config.bridge,
			basicauth:basicauth
		}, function(){

			var WSAuto=require('../autoconnectproxy.js');

			if(basicauth.length){
				basicauth=basicauth+'@';
			}
			var autoconnect=new WSAuto({source:'ws://'+basicauth+'localhost:'+config.bridge, destination:'ws://localhost:'+config.echo});

			var clients=0;

			if(typeof(config.beforeTest)=='function'){
				config.beforeTest({
					echo:echo,
					bridge:bridge,
					autoconnect:autoconnect
				});
			}

			cleanup=function(){
				echo.close();
				bridge.close();
				autoconnect.close();
			}

			var num=config.count;
			for(var i=0;i< num; i++){

				clients++;
				(function(i){
					var success=false;
					var client=new ws('ws://localhost:'+config.bridge);

					client.on('open', function(){
						setTimeout(function(){
							var tm=setTimeout(function(){
								callback(new Error('test '+test+' client#'+i+' expected response by now.'));
							}, 10000);
								client.on('message',function(message){

									if(message!=='hello world'){
										callback(new Error('test '+test+' client#'+i+' expected "hello world", recieved "'+message+'"'));
									}else{

										//was logging a success message here.

									}

									success=true;
									clearTimeout(tm);
									this.close();
									clients--;
									if(clients==0){

										setTimeout(function(){
											callback(null); //success
											cleanup();
										},100);

									}
								});
								//console.log('test client #'+i+' sends: hello world');

								client.send('hello world');

						}, i*100);

					}).on('close', function(code, message){

						if(!success){
							callback(new Error('test '+test+' client#'+i+' closed before sending anything: '+code+(message?' - '+message:'')));

						}

					}).on('error',function(error){

						callback(new Error('test '+test+' client#'+i+' error: '+error));

					});

					if((typeof config.eachClient)=='function'){
						config.eachClient(client, i);
					}

				})(i);

			}

		});

	})).on('connection', function(wsclient){

		wsclient.on('message',function(message){
			wsclient.send(message);
			//console.log('endpoint echos: '+message);
		})

	});

}

//helper
function logAutoconnectProxy(acp){

	acp.on('source.connect',function(source){

		source.on('open',function(){
			log('autoconnect created proxy: there are '+me._primedConnections.length+' ready sockets');
		}).on('message', function message(data, flags) {
			log('autoconnect proxy source sends: '+(typeof data));
		}).on('close',function(code, message){
			console.log('autoconnect proxy source close: '+code+' '+message);
		}).on('error',function(error){
			console.log('autoconnect proxy source error: '+error);
		});

	}).on('destination.connect',function(destination){

		destination.on('message', function message(data, flags) {
			log('autoconnect proxy destination sends: '+(typeof data));
		}).on('error',function(error){
			console.error('autoconnect proxy destination error: '+error+' | '+(typeof error));
		}).on('close',function(code, message){
			console.log('autoconnect proxy destination close: '+code+' '+message);
		});

	});

}

var series=require("async").series(
		[
		 function(callback){
			 //test direct load
			 EchoTest(require('../bridgeproxy.js'), require('../autoconnectproxy.js'), {echo:9001, bridge:9002, count:20, eachClient:function(client, i){
				 client.on('message',function(m){
					 console.log('test 0, client '+i+' success');
				 });
			 }}, function(err, message){

				 if(err){
					 assert.fail(err);
				 }

				 callback(null);

			 });
		 },
		 function(callback){
			 // test same ports - cleanup must complete
			 EchoTest(require('../bridgeproxy.js'), require('../autoconnectproxy.js'), {echo:9001, bridge:9002, count:5, eachClient:function(client, i){
				 client.on('message',function(m){
					 console.log('test 0, client '+i+' success');
				 });
			 }}, function(err, message){

				 if(err){
					 assert.fail(err);
				 }
				 callback(null);

			 });
		 },
		 function(callback){
			 //test using index, this should be the same as require('node-rproxy')
			 EchoTest(require('../index.js').AutoConnect, require('../index.js').Bridge, {echo:9003, bridge:9004, count:5, eachClient:function(client, i){
				 client.on('message',function(m){
					 console.log('test 0, client '+i+' success');
				 });
			 }}, function(err, message){

				 if(err){
					 assert.fail(err);
				 }
				 callback(null);

			 });

		 },function(callback){

			 //trigger errors. application stops running
			 EchoTest(require('../index.js').AutoConnect, require('../index.js').Bridge, {echo:9001, bridge:9002, count:1, beforeTest:function(sockets){

				 sockets.echo.close(); //kill the 'application server' but keep the proxies
				 logAutoconnectProxy(sockets.autoconnect);

			 }}, function(err, message){

				 if(!err){
					 assert.fail(err.message);
				 }
				 callback(null);

			 });

		 }
		 ],
		 function(err, results) {
			if(err){
				assert.fail(err.message||err);
			}
			console.log('tests completed successfully');
		});

<commit_msg>added test message<commit_after>/**
 *
 */

var assert=require('assert');
assert.equal(true, true);

var ws=require('ws');

var testNumber=0;

function EchoTest(BridgeProxy, AutoConnectProxy, config, callbackFn){

	var cleanup=function(){}; //reassigned

	var callback=function(err, msg){
		callbackFn(err, msg);
		cleanup();
		callback=function(){}; //avoid multiple executions, but don't worry about it below.
	}

	var test=testNumber;
	testNumber++;
	console.log('Running Test: '+test);
	//a ws server that just echos back all messages...
	var echo=(new ws.Server({
		port: config.echo
	},function(){

		cleanup=function(){
			echo.close();
		}

		var basicauth='';
		basicauth='nickolanack:nick';

//		a bridge server. pairs clients with autoconnect proxy connections.
		var WSBridge=require('../bridgeproxy.js');
		var bridge=new WSBridge({
			port:config.bridge,
			basicauth:basicauth
		}, function(){

			var WSAuto=require('../autoconnectproxy.js');

			if(basicauth.length){
				basicauth=basicauth+'@';
			}
			var autoconnect=new WSAuto({source:'ws://'+basicauth+'localhost:'+config.bridge, destination:'ws://localhost:'+config.echo});

			var clients=0;

			if(typeof(config.beforeTest)=='function'){
				config.beforeTest({
					echo:echo,
					bridge:bridge,
					autoconnect:autoconnect
				});
			}

			cleanup=function(){
				echo.close();
				bridge.close();
				autoconnect.close();
			}

			var num=config.count;
			for(var i=0;i< num; i++){

				clients++;
				(function(i){
					var success=false;
					var client=new ws('ws://localhost:'+config.bridge);

					client.on('open', function(){
						setTimeout(function(){
							var tm=setTimeout(function(){
								callback(new Error('test '+test+' client#'+i+' expected response by now.'));
							}, 10000);
								client.on('message',function(message){

									if(message!=='hello world'){
										callback(new Error('test '+test+' client#'+i+' expected "hello world", recieved "'+message+'"'));
									}else{

										//was logging a success message here.

									}

									success=true;
									clearTimeout(tm);
									this.close();
									clients--;
									if(clients==0){

										setTimeout(function(){
											callback(null); //success
											cleanup();
										},100);

									}
								});
								//console.log('test client #'+i+' sends: hello world');

								client.send('hello world');

						}, i*100);

					}).on('close', function(code, message){

						if(!success){
							callback(new Error('test '+test+' client#'+i+' closed before sending anything: '+code+(message?' - '+message:'')));

						}

					}).on('error',function(error){

						callback(new Error('test '+test+' client#'+i+' error: '+error));

					});

					if((typeof config.eachClient)=='function'){
						config.eachClient(client, i);
					}

				})(i);

			}

		});

	})).on('connection', function(wsclient){

		wsclient.on('message',function(message){
			wsclient.send(message);
			//console.log('endpoint echos: '+message);
		})

	});

}

//helper
function logAutoconnectProxy(acp){

	acp.on('source.connect',function(source){

		source.on('open',function(){
			log('autoconnect created proxy: there are '+me._primedConnections.length+' ready sockets');
		}).on('message', function message(data, flags) {
			log('autoconnect proxy source sends: '+(typeof data));
		}).on('close',function(code, message){
			console.log('autoconnect proxy source close: '+code+' '+message);
		}).on('error',function(error){
			console.log('autoconnect proxy source error: '+error);
		});

	}).on('destination.connect',function(destination){

		destination.on('message', function message(data, flags) {
			log('autoconnect proxy destination sends: '+(typeof data));
		}).on('error',function(error){
			console.error('autoconnect proxy destination error: '+error+' | '+(typeof error));
		}).on('close',function(code, message){
			console.log('autoconnect proxy destination close: '+code+' '+message);
		});

	});

}

var series=require("async").series(
		[
		 function(callback){
			 //test direct load
			 EchoTest(require('../bridgeproxy.js'), require('../autoconnectproxy.js'), {echo:9001, bridge:9002, count:20, eachClient:function(client, i){
				 client.on('message',function(m){
					 console.log('test 0, client '+i+' success');
				 });
			 }}, function(err, message){

				 if(err){
					 assert.fail(err);
				 }

				 callback(null);

			 });
		 },
		 function(callback){
			 // test same ports - cleanup must complete
			 EchoTest(require('../bridgeproxy.js'), require('../autoconnectproxy.js'), {echo:9001, bridge:9002, count:5, eachClient:function(client, i){
				 client.on('message',function(m){
					 console.log('test 0, client '+i+' success');
				 });
			 }}, function(err, message){

				 if(err){
					 assert.fail(err);
				 }
				 callback(null);

			 });
		 },
		 function(callback){
			 //test using index, this should be the same as require('node-rproxy')
			 EchoTest(require('../index.js').AutoConnect, require('../index.js').Bridge, {echo:9003, bridge:9004, count:5, eachClient:function(client, i){
				 client.on('message',function(m){
					 console.log('test 0, client '+i+' success');
				 });
			 }}, function(err, message){

				 if(err){
					 assert.fail(err);
				 }
				 callback(null);

			 });

		 },function(callback){

			 //trigger errors. application stops running
			 EchoTest(require('../index.js').AutoConnect, require('../index.js').Bridge, {echo:9001, bridge:9002, count:1, beforeTest:function(sockets){

				 sockets.echo.close(); //kill the 'application server' but keep the proxies
				 logAutoconnectProxy(sockets.autoconnect);

			 }}, function(err, message){
				 console.log('Error Test:');
				 if(!err){
					 assert.fail('Expected connection error: No Destination Error);
				 }
				 console.log(err.message);
				 callback(null);

			 });

		 }
		 ],
		 function(err, results) {
			if(err){
				assert.fail(err.message||err);
			}
			console.log('tests completed successfully');
		});

<|endoftext|>


<commit_before><commit_msg>Built in detection of css transforms, logs removed, increased version number<commit_after><|endoftext|>


<commit_before><commit_msg>Wrap all fetchImage callbacks in if typeof function<commit_after><|endoftext|>


<commit_before>/***
* 微信分享给朋友/朋友圈
* @wxShare  {object} 分享给朋友/朋友圈的参数和成功失败回调
* wxShare.title.desc.url.imgUrl.successCallback.cancelCallback.ok()
* @return {[type]} [description]
*/
//location.href.split('#')[0]
$.get('http://course.babyfs.cn/we-chat/share/', { url: location.href.split('#')[0] }).done(function(res) {
    wx.config({
        debug: true,
        appId: res.appId,
        timestamp: res.timestamp,
        nonceStr: res.nonceStr,
        signature: res.signature,
        jsApiList: [
            'checkJsApi',
            'onMenuShareTimeline',
            'onMenuShareAppMessage',
            'onMenuShareQQ',
            'onMenuShareWeibo',
            // 'hideMenuItems',
            // 'showMenuItems',
            // 'hideAllNonBaseMenuItem',
            // 'showAllNonBaseMenuItem',
            // 'translateVoice',
            // 'startRecord',
            // 'stopRecord',
            // 'onRecordEnd',
            // 'playVoice',
            // 'pauseVoice',
            // 'stopVoice',
            // 'uploadVoice',
            // 'downloadVoice',
            // 'chooseImage',
            // 'previewImage',
            // 'uploadImage',
            // 'downloadImage',
            // 'getNetworkType',
            // 'openLocation',
            // 'getLocation',
            // 'hideOptionMenu',
            // 'showOptionMenu',
            // 'closeWindow',
            // 'scanQRCode',
            // 'chooseWXPay',
            // 'openProductSpecificView',
            // 'addCard',
            // 'chooseCard',
            // 'openCard'
        ]
    });

}).fail(function() { console.log('微信分享获取后台参数ajax失败！'); });

var wxShare = {
    ok: function() {
        var self = this;
        self.title = self.title || 'title';
        self.desc = self.desc || 'desc';
        self.link = self.link || location.href;
        self.imgUrl = self.imgUrl || location.protocol + '//' + location.host + '/logo.jpg';
        wx.ready(function() {
            wx.onMenuShareAppMessage({
                title: self.title,
                desc: self.desc,
                link: self.link,
                imgUrl: self.imgUrl,
                success: function() {
                    console.log('分享给朋友成功！');
                    if (typeof self.successCallback === 'function') {
                        self.successCallback();
                    }
                },
                cancel: function() {
                    console.log('分享给朋友失败！');
                    if (typeof self.cancelCallback === 'function') {
                        self.cancelCallback();
                    }
                }
            });
            wx.onMenuShareTimeline({
                title: self.title2 || self.title,
                desc: self.desc2 || self.desc,
                link: self.link2 || self.link,
                imgUrl: self.imgUrl2 || self.imgUrl,
                success: function() {
                    console.log('分享到朋友圈成功！');
                    if (typeof self.successCallback2 === 'function') {
                        self.successCallback2();
                    } else if (typeof self.successCallback === 'function') {
                        self.successCallback();
                    }
                },
                cancel: function() {
                    console.log('分享到朋友圈失败！');
                    if (typeof self.cancelCallback2 === 'function') {
                        self.cancelCallback2();
                    } else if (typeof self.cancelCallback === 'function') {
                        self.cancelCallback();
                    }
                }
            });
        });
    }
}<commit_msg>fenxinag<commit_after>/***
* 微信分享给朋友/朋友圈
* @wxShare  {object} 分享给朋友/朋友圈的参数和成功失败回调
* wxShare.title.desc.url.imgUrl.successCallback.cancelCallback.ok()
* @return {[type]} [description]
*/
//location.href.split('#')[0]
$.get('http://course.babyfs.cn/we-chat/share/', { url: location.href.split('#')[0] }).done(function(res) {

    wx.config(res);
    //wx.config({
        //debug: true,
        //appId: res.appId,
        //timestamp: res.timestamp,
        //nonceStr: res.nonceStr,
        //signature: res.signature,
        //jsApiList: [
        //    'checkJsApi',
        //    'onMenuShareTimeline',
        //    'onMenuShareAppMessage',
        //    'onMenuShareQQ',
        //    'onMenuShareWeibo',
            // 'hideMenuItems',
            // 'showMenuItems',
            // 'hideAllNonBaseMenuItem',
            // 'showAllNonBaseMenuItem',
            // 'translateVoice',
            // 'startRecord',
            // 'stopRecord',
            // 'onRecordEnd',
            // 'playVoice',
            // 'pauseVoice',
            // 'stopVoice',
            // 'uploadVoice',
            // 'downloadVoice',
            // 'chooseImage',
            // 'previewImage',
            // 'uploadImage',
            // 'downloadImage',
            // 'getNetworkType',
            // 'openLocation',
            // 'getLocation',
            // 'hideOptionMenu',
            // 'showOptionMenu',
            // 'closeWindow',
            // 'scanQRCode',
            // 'chooseWXPay',
            // 'openProductSpecificView',
            // 'addCard',
            // 'chooseCard',
            // 'openCard'
        //]
    //});

}).fail(function() { console.log('微信分享获取后台参数ajax失败！'); });

var wxShare = {
    ok: function() {
        var self = this;
        self.title = self.title || 'title';
        self.desc = self.desc || 'desc';
        self.link = self.link || location.href;
        self.imgUrl = self.imgUrl || location.protocol + '//' + location.host + '/logo.jpg';
        wx.ready(function() {
            wx.onMenuShareAppMessage({
                title: self.title,
                desc: self.desc,
                link: self.link,
                imgUrl: self.imgUrl,
                success: function() {
                    console.log('分享给朋友成功！');
                    if (typeof self.successCallback === 'function') {
                        self.successCallback();
                    }
                },
                cancel: function() {
                    console.log('分享给朋友失败！');
                    if (typeof self.cancelCallback === 'function') {
                        self.cancelCallback();
                    }
                }
            });
            wx.onMenuShareTimeline({
                title: self.title2 || self.title,
                desc: self.desc2 || self.desc,
                link: self.link2 || self.link,
                imgUrl: self.imgUrl2 || self.imgUrl,
                success: function() {
                    console.log('分享到朋友圈成功！');
                    if (typeof self.successCallback2 === 'function') {
                        self.successCallback2();
                    } else if (typeof self.successCallback === 'function') {
                        self.successCallback();
                    }
                },
                cancel: function() {
                    console.log('分享到朋友圈失败！');
                    if (typeof self.cancelCallback2 === 'function') {
                        self.cancelCallback2();
                    } else if (typeof self.cancelCallback === 'function') {
                        self.cancelCallback();
                    }
                }
            });
        });
    }
}<|endoftext|>


<commit_before><commit_msg>angular<commit_after><|endoftext|>


<commit_before>sap.ui.define([
	"sap/ui/test/Opa5",
	"./arrangements/Arrangement",
	"./WorklistJourney",
	"./NavigationJourney",
	"./NotFoundJourney",
	"./ObjectJourney"
], function (Opa5, Arrangement) {
	"use strict";

	Opa5.extendConfig({
		arrangements: new Arrangement(),
		viewNamespace: "sap.ui.demo.worklist.view.",
		autoWait: true
	});

});<commit_msg>Update to latest version of template (1.42)<commit_after>sap.ui.define([
	"sap/ui/test/Opa5",
	"./arrangements/Arrangement",
	"./WorklistJourney",
	"./NavigationJourney",
	"./NotFoundJourney",
	"./ObjectJourney"
], function (Opa5, Arrangement) {
	"use strict";

	Opa5.extendConfig({
		arrangements: new Arrangement(),
		viewNamespace: "sap.ui.demo.worklist.view.",
		autoWait: true
	});

});
<|endoftext|>


<commit_before>define([
	'./aspect',
	'./async',
	'./compose',
	'../has!host-browser?./dom',
	'./global',
	'./has',
	'./lang',
	'./on',
	'./request',
	'./Deferred',
	'./Evented',
	'./Promise',
	'./Registry',
	'./SideTable'
], 1);<commit_msg>Remove tests for core/Deferred for now.<commit_after>define([
	'./aspect',
	'./async',
	'./compose',
	'../has!host-browser?./dom',
	'./global',
	'./has',
	'./lang',
	'./on',
	'./request',
	// './Deferred', // remove temporarily
	'./Evented',
	'./Promise',
	'./Registry',
	'./SideTable'
], 1);<|endoftext|>


<commit_before>
theresaMay = function (){
    var self = this;

    // https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/String/includes#Polyfill
    if (!String.prototype.includes) {
        String.prototype.includes = function(search, start) {
            'use strict';
            if (typeof start !== 'number') {
                start = 0;
            }

            if (start + search.length > this.length) {
                return false;
            } else {
                return this.indexOf(search, start) !== -1;
            }
        };
    }

    //https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/includes?v=example#Polyfill
    if (!Array.prototype.includes) {
        Object.defineProperty(Array.prototype, 'includes', {
            value: function(searchElement, fromIndex) {
                if (this == null) {
                    throw new TypeError('"this" is null or not defined');
                }

                var o = Object(this);

                var len = o.length >>> 0;

                if (len === 0) {
                    return false;
                }

                var n = fromIndex | 0;
                var k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);

                function sameValueZero(x, y) {
                    return x === y || (typeof x === 'number' && typeof y === 'number' && isNaN(x) && isNaN(y));
                }

                while (k < len) {
                    if (sameValueZero(o[k], searchElement)) {
                    return true;
                    }
                    k++;
                }

                return false;
            }
        });
    }

    self.openingLines = [
        "I have been very clear, and you can see that our record speaks for itself on the matter of MATTER, and I am happy to say NONSENSE. PARTYLINE.",
        "Look, I'm absolutely clear that NONSENSE.",
        "What we will do in government is continue to put record levels of funding into THING.",
        "I would say, in answer to that question, judge us on our record of MATTER.",
        "Every vote for Jeremy Corbyn is a vote for BADTHING. Only a conservative government can deliver THING. PARTYLINE."
    ];

    self.nonsense = [
        "every vote for me and my team will strengthen my hand in those negotiations",
        "cuts to the police enable them to do a better job",
        "the money was just resting in my account"
    ];

    self.partyLines = [
        "Only the Conservative party, led by me, can deliver THING for our country",
        "When you're at the ballot box be very clear that a vote for me is a vote for five years of THING",

    ];

    self.matters = [
        "NHS funding",
        "massive police cuts",
        "swine flu",
        "holding hands with the president of the united states of America",
        "mysterious and unattributed cases of arson",
        "sales of peace keeping equipment to Saudi Arabia",
        "tax cuts for the rich",
        "the European Convention on Human Rights",
        "kicking cats to death"
    ];

    self.badThings = [
        "Jeremy Corbyn",
        "Diane Abbot",
        "uncontrolled immigration",
        "open borders",
        "brefrending the IRA",
        "a coalition of chaos"
    ];

    self.things = [
        "magic money trees",
        "leopard print shoes",
        "child poverty",
        "record levels of union jack bunting",
        "strong and stable leadership"
    ];
}

theresaMay.prototype.askQuestion = function (question) {
    var self = this;

    // The question variable is never inspected by TheresaMay.js because it
    // doesnt really have any effect on the output.
    var responseArray = [];
    var nonsenseIterator = 0;
    var nonsenseCount = Math.floor((Math.random() * 3) + 1);

    responseArray.push(self.openingLines[Math.floor(Math.random() * self.openingLines.length)]);

    for (var i = 0; i < responseArray.length; i++) {
        var responseItem = responseArray[i];

        responseItem = responseItem.replace("MATTER", self.matters[Math.floor(Math.random() * self.matters.length)]);
        responseItem = responseItem.replace("NONSENSE", self.nonsense[Math.floor(Math.random() * self.nonsense.length)]);
        responseItem = responseItem.replace("PARTYLINE", self.partyLines[Math.floor(Math.random() * self.partyLines.length)]);
        responseItem = responseItem.replace("THING", self.things[Math.floor(Math.random() * self.things.length)]);
        responseItem = responseItem.replace("BADTHING", self.badThings[Math.floor(Math.random() * self.badThings.length)]);

        responseArray[i] = responseItem;
    }

    return responseArray.join(". ", );
}<commit_msg>Crappy and quick method of making sure everything gets replaced<commit_after>
theresaMay = function (){
    var self = this;

    // https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/String/includes#Polyfill
    if (!String.prototype.includes) {
        String.prototype.includes = function(search, start) {
            'use strict';
            if (typeof start !== 'number') {
                start = 0;
            }

            if (start + search.length > this.length) {
                return false;
            } else {
                return this.indexOf(search, start) !== -1;
            }
        };
    }

    //https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/includes?v=example#Polyfill
    if (!Array.prototype.includes) {
        Object.defineProperty(Array.prototype, 'includes', {
            value: function(searchElement, fromIndex) {
                if (this == null) {
                    throw new TypeError('"this" is null or not defined');
                }

                var o = Object(this);

                var len = o.length >>> 0;

                if (len === 0) {
                    return false;
                }

                var n = fromIndex | 0;
                var k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);

                function sameValueZero(x, y) {
                    return x === y || (typeof x === 'number' && typeof y === 'number' && isNaN(x) && isNaN(y));
                }

                while (k < len) {
                    if (sameValueZero(o[k], searchElement)) {
                    return true;
                    }
                    k++;
                }

                return false;
            }
        });
    }

    self.openingLines = [
        "I have been very clear, and you can see that our record speaks for itself on the matter of MATTER, and I am happy to say NONSENSE. PARTYLINE.",
        "Look, I'm absolutely clear that NONSENSE.",
        "What we will do in government is continue to put record levels of funding into THING.",
        "I would say, in answer to that question, judge us on our record of MATTER.",
        "Every vote for Jeremy Corbyn is a vote for BADTHING. Only a conservative government can deliver THING. PARTYLINE."
    ];

    self.nonsense = [
        "every vote for me and my team will strengthen my hand in those negotiations",
        "cuts to the police enable them to do a better job",
        "the money was just resting in my account"
    ];

    self.partyLines = [
        "Only the Conservative party, led by me, can deliver THING for our country",
        "When you're at the ballot box be very clear that a vote for me is a vote for five years of THING",

    ];

    self.matters = [
        "NHS funding",
        "massive police cuts",
        "swine flu",
        "holding hands with the president of the united states of America",
        "mysterious and unattributed cases of arson",
        "sales of peace keeping equipment to Saudi Arabia",
        "tax cuts for the rich",
        "the European Convention on Human Rights",
        "kicking cats to death"
    ];

    self.badThings = [
        "Jeremy Corbyn",
        "Diane Abbot",
        "uncontrolled immigration",
        "open borders",
        "brefrending the IRA",
        "a coalition of chaos"
    ];

    self.things = [
        "magic money trees",
        "leopard print shoes",
        "child poverty",
        "record levels of union jack bunting",
        "strong and stable leadership"
    ];
}

theresaMay.prototype.askQuestion = function (question) {
    var self = this;

    // The question variable is never inspected by TheresaMay.js because it
    // doesnt really have any effect on the output.
    var responseArray = [];
    var nonsenseIterator = 0;
    var nonsenseCount = Math.floor((Math.random() * 3) + 1);

    responseArray.push(self.openingLines[Math.floor(Math.random() * self.openingLines.length)]);

    for (var i = 0; i < responseArray.length; i++) {
        var responseItem = responseArray[i];

        while (responseItem.includes("MATTER")) {
            responseItem = responseItem.replace("MATTER", self.matters[Math.floor(Math.random() * self.matters.length)]);
        }

        while (responseItem.includes("NONSENSE")) {
            responseItem = responseItem.replace("NONSENSE", self.nonsense[Math.floor(Math.random() * self.nonsense.length)]);
        }

        while (responseItem.includes("PARTYLINE")) {
            responseItem = responseItem.replace("PARTYLINE", self.partyLines[Math.floor(Math.random() * self.partyLines.length)]);
        }

        while (responseItem.includes("BADTHING")) {
            responseItem = responseItem.replace("BADTHING", self.badThings[Math.floor(Math.random() * self.badThings.length)]);
        }

        while (responseItem.includes("THING")) {
            responseItem = responseItem.replace("THING", self.things[Math.floor(Math.random() * self.things.length)]);
        }

        responseArray[i] = responseItem;
    }

    return responseArray.join(". ", );
}<|endoftext|>


<commit_before>(function(undefined) {
  // The Opal object that is exposed globally
  var Opal = this.Opal = {};

  // Very root class
  function BasicObject(){}

  // Core Object class
  function Object(){}

  // Class' class
  function Class(){}

  // the class of nil
  function NilClass(){}

  // TopScope is used for inheriting constants from the top scope
  var TopScope = function(){};

  // Opal just acts as the top scope
  TopScope.prototype = Opal;

  // To inherit scopes
  Opal.constructor  = TopScope;

  // This is a useful reference to global object inside ruby files
  Opal.global = this;

  // Minify common function calls
  var __hasOwn = Opal.hasOwnProperty;
  var __slice  = Opal.slice = Array.prototype.slice;

  // Generates unique id for every ruby object
  var unique_id = 0;

  // Return next unique id
  Opal.uid = function() {
    return unique_id++;
  };

  // Table holds all class variables
  Opal.cvars = {};

  // Globals table
  Opal.gvars = {};

  /*
   * Create a new constants scope for the given class with the given
   * base. Constants are looked up through their parents, so the base
   * scope will be the outer scope of the new klass.
   */
  function create_scope(base, klass, id) {
    var const_alloc   = function() {};
    var const_scope   = const_alloc.prototype = new base.constructor();
    klass._scope      = const_scope;
    const_scope.base  = klass;
    const_scope.constructor = const_alloc;

    if (id) {
      base[id] = base.constructor[id] = klass;
    }
  }

  /*
    Define a bridged class. Bridged classes will always be in the top level
    scope, and will always be a subclass of Object.
  */
  Opal.bridge = function(name, constructor) {
    var klass = bridge_class(constructor);

    klass._name = name;

    create_scope(Opal, klass, name);

    return klass;
  };

  Opal.klass = function(base, superklass, id, constructor) {
    var klass;
    if (typeof(base) !== 'function') {
      base = base.constructor;
    }

    if (superklass === null) {
      superklass = Object;
    }

    if (__hasOwn.call(base._scope, id)) {
      klass = base._scope[id];
    }
    else {
      klass = boot_class(superklass, constructor);

      klass._name = (base === Object ? id : base._name + '::' + id);

      create_scope(base._scope, klass);

      base[id] = base._scope[id] = klass;

      if (superklass.$inherited) {
        superklass.$inherited(klass);
      }
    }

    return klass;
  };

  // Define new module (or return existing module)
  Opal.module = function(base, id, constructor) {
    var klass;
    if (typeof(base) !== 'function') {
      base = base.constructor;
    }

    if (__hasOwn.call(base._scope, id)) {
      klass = base._scope[id];
    }
    else {
      klass = boot_class(Class, constructor);
      klass._name = (base === Object ? id : base._name + '::' + id);

      klass._included_in = [];

      create_scope(base._scope, klass, id);
    }

    return klass;
  };

  // Utility function to raise a "no block given" error
  var no_block_given = function() {
    throw new Error('no block given');
  };

  // Boot a base class (makes instances).
  var boot_defclass = function(id, constructor, superklass) {
    if (superklass) {
      var ctor           = function() {};
          ctor.prototype = superklass.prototype;

      constructor.prototype = new ctor();
    }

    var prototype = constructor.prototype;

    prototype.constructor = constructor;
    prototype.constructor      = constructor;

    constructor._name         = id;
    constructor._super        = superklass;
    constructor._methods      = [];
    constructor._smethods     = [];

    constructor['$==='] = module_eqq;
    constructor.$to_s = module_to_s;
    constructor.toString = module_to_s;

    Opal[id] = constructor;

    return constructor;
  };

  // Create generic class with given superclass.
  var boot_class = Opal.boot = function(superklass, constructor) {
    var ctor = function() {};
        ctor.prototype = superklass.prototype;

    constructor.prototype = new ctor();
    var prototype = constructor.prototype;

    prototype.constructor = constructor;

    constructor._super        = superklass;
    constructor._methods      = [];
    constructor.constructor   = Class;

    constructor['$===']  = module_eqq;
    constructor.$to_s    = module_to_s;
    constructor.toString = module_to_s;

    constructor['$[]'] = undefined;
    constructor.$call  = undefined;

    var smethods;

    smethods = superklass._smethods.slice();

    constructor._smethods = smethods;
    for (var i = 0, length = smethods.length; i < length; i++) {
      var m = smethods[i];
      constructor[m] = superklass[m];
    }

    var inherited = superklass._inherited;

    if (!inherited) {
      inherited = superklass._inherited = [];
    }

    inherited.push(constructor);

    return constructor;
  };

  var bridge_class = function(constructor) {
    constructor.prototype.constructor = constructor;

    constructor._super        = Object;
    constructor.constructor   = Class;
    constructor._methods      = [];
    constructor._smethods     = [];

    constructor['$===']  = module_eqq;
    constructor.$to_s    = module_to_s;
    constructor.toString = module_to_s;

    var smethods = constructor._smethods = Class._methods.slice();
    for (var i = 0, length = smethods.length; i < length; i++) {
      var m = smethods[i];
      constructor[m] = Object[m];
    }

    bridged_classes.push(constructor);

    var table = Object.prototype, methods = Object._methods;

    for (var i = 0, length = methods.length; i < length; i++) {
      var m = methods[i];
      constructor.prototype[m] = table[m];
    }

    constructor._smethods.push('$allocate');

    return constructor;
  };

  Opal.puts = function(a) { console.log(a); };

  // Method missing dispatcher
  Opal.mm = function(mid) {
    var dispatcher = function() {
      var args = __slice.call(arguments);

      if (this.$method_missing) {
        this.$method_missing._p = dispatcher._p;
        return this.$method_missing.apply(this, [mid].concat(args));
      }
      else {
        native_send._p = dispatcher._p;
        return native_send(this, mid, args);
      }
    };

    return dispatcher;
  };

  // send a method to a native object
  var native_send = function(obj, mid, args) {
    var prop, block = native_send._p;
    native_send._p = null;

    if (prop = native_methods[mid]) {
      return prop(obj, args, block);
    }

    prop = obj[mid];

    if (typeof(prop) === "function") {
      prop = prop.apply(obj, args.$to_native());
    }
    else if (mid.charAt(mid.length - 1) === "=") {
      prop = mid.slice(0, mid.length - 1);
      return obj[prop] = args[0];
    }

    if (prop != null) {
      return prop;
    }

    return nil;
  };

  var native_methods = {
    "==": function(obj, args) {
      return obj === args[0];
    },

    "[]": function(obj, args) {
      var prop = obj[args[0]];

      if (prop != null) {
        return prop;
      }

      return nil;
    },

    "[]=": function(obj, args) {
      var value = args[1];

      if (value === nil) {
        value = null;
      }

      return obj[args[0]] = value;
    },

    "respond_to?": function(obj, args) {
      return obj[args[0]] != null;
    },

    "each": function(obj, args, block) {
      var prop;

      if (obj.length === +obj.length) {
        for (var i = 0, len = obj.length; i < len; i++) {
          prop = obj[i];

          if (prop == null) {
            prop = nil;
          }

          block(prop);
        }
      }
      else {
        for (var key in obj) {
          prop = obj[key];

          if (prop == null) {
            prop = nil;
          }

          block(key, prop);
        }
      }

      return obj;
    },

    "to_a": function(obj, args) {
      var result = [];

      for (var i = 0, length = obj.length; i < length; i++) {
        result.push(obj[i]);
      }

      return result;
    },

    "to_h": function(obj) {
      var keys = [], values = {}, value;

      for (var key in obj) {
        keys.push(key);

        if ((value = obj[key]) == null) {
          values[key] = nil;
        }
        else {
          values[key] = value;
        }
      }

      return Opal.hash2(keys, values);
    }
  };

  // Const missing dispatcher
  Opal.cm = function(name) {
    return this.base.$const_missing(name);
  };

  // Arity count error dispatcher
  Opal.ac = function(actual, expected, object, meth) {
    var inspect = ((typeof(object) !== 'function') ? object.constructor._name + '#' : object._name + '.') + meth;
    var msg = '[' + inspect + '] wrong number of arguments(' + actual + ' for ' + expected + ')';
    throw Opal.ArgumentError.$new(msg);
  };

  /*
    Call a ruby method on a ruby object with some arguments:

      var my_array = [1, 2, 3, 4]
      Opal.send(my_array, 'length')     # => 4
      Opal.send(my_array, 'reverse!')   # => [4, 3, 2, 1]

    A missing method will be forwarded to the object via
    method_missing.

    The result of either call with be returned.

    @param [Object] recv the ruby object
    @param [String] mid ruby method to call
  */
  Opal.send = function(recv, mid) {
    var args = __slice.call(arguments, 2),
        func = recv['$' + mid];

    if (func) {
      return func.apply(recv, args);
    }

    return recv.$method_missing.apply(recv, [mid].concat(args));
  };

  Opal.block_send = function(recv, mid, block) {
    var args = __slice.call(arguments, 3),
        func = recv['$' + mid];

    if (func) {
      func._p = block;
      return func.apply(recv, args);
    }

    return recv.$method_missing.apply(recv, [mid].concat(args));
  };

  // Implementation of Class#===
  function module_eqq(object) {
    if (object == null) {
      return false;
    }

    var search = object.constructor;

    while (search) {
      if (search === this) {
        return true;
      }

      search = search._super;
    }

    return false;
  }

  // Implementation of Class#to_s
  function module_to_s() {
    return this._name;
  }

  /**
   * Donate methods for a class/module
   */
  Opal.donate = function(klass, defined, indirect) {
    var methods = klass._methods, included_in = klass._included_in;

    // if (!indirect) {
      klass._methods = methods.concat(defined);
    // }

    if (included_in) {
      for (var i = 0, length = included_in.length; i < length; i++) {
        var includee = included_in[i];
        var dest = includee.prototype;

        for (var j = 0, jj = defined.length; j < jj; j++) {
          var method = defined[j];
          dest[method] = klass.prototype[method];
        }

        if (includee._included_in) {
          Opal.donate(includee, defined, true);
        }
      }
    }
  };

  /*
    Define a singleton method on the given klass

        Opal.defs(Array, '$foo', function() {})

    @param [Function] klass
    @param [String] mid the method_id
    @param [Function] body function body
  */
  Opal.defs = function(klass, mid, body) {
    klass._smethods.push(mid);
    klass[mid] = body;

    var inherited = klass._inherited;
    if (inherited && inherited.length) {
      for (var i = 0, length = inherited.length, subclass; i < length; i++) {
        subclass = inherited[i];
        if (!subclass[mid]) {
          Opal.defs(subclass, mid, body);
        }
      }
    }
  };

  // Defines methods onto Object (which are then donated to bridged classes)
  Object._defn = function (mid, body) {
    this.prototype[mid] = body;
    Opal.donate(this, [mid]);
  };

  // Initialization
  // --------------

  boot_defclass('BasicObject', BasicObject);
  boot_defclass('Object', Object, BasicObject);
  boot_defclass('Class', Class, Object);

  Class.prototype = Function.prototype;

  BasicObject.constructor = Object.constructor = Class.constructor = Class;

  var bridged_classes = Object._included_in = [];

  Opal.base = Object;
  BasicObject._scope = Object._scope = Opal;
  Opal.Module = Opal.Class;
  Opal.Kernel = Object;

  create_scope(Opal, Class);

  Object.prototype.toString = function() {
    return this.$to_s();
  };

  Opal.top = new Object;

  Opal.klass(Object, Object, 'NilClass', NilClass);
  var nil = Opal.nil = new NilClass;
  nil.call = nil.apply = function() { throw Opal.LocalJumpError.$new('no block given'); };

  Opal.breaker  = new Error('unexpected break');

  Opal.bridge('Array', Array);
  Opal.bridge('Boolean', Boolean);
  Opal.bridge('Numeric', Number);
  Opal.bridge('String', String);
  Opal.bridge('Proc', Function);
  Opal.bridge('Exception', Error);
  Opal.bridge('Regexp', RegExp);
  Opal.bridge('Time', Date);
}).call(this);
<commit_msg>Already defined vars<commit_after>(function(undefined) {
  // The Opal object that is exposed globally
  var Opal = this.Opal = {};

  // Very root class
  function BasicObject(){}

  // Core Object class
  function Object(){}

  // Class' class
  function Class(){}

  // the class of nil
  function NilClass(){}

  // TopScope is used for inheriting constants from the top scope
  var TopScope = function(){};

  // Opal just acts as the top scope
  TopScope.prototype = Opal;

  // To inherit scopes
  Opal.constructor  = TopScope;

  // This is a useful reference to global object inside ruby files
  Opal.global = this;

  // Minify common function calls
  var __hasOwn = Opal.hasOwnProperty;
  var __slice  = Opal.slice = Array.prototype.slice;

  // Generates unique id for every ruby object
  var unique_id = 0;

  // Return next unique id
  Opal.uid = function() {
    return unique_id++;
  };

  // Table holds all class variables
  Opal.cvars = {};

  // Globals table
  Opal.gvars = {};

  /*
   * Create a new constants scope for the given class with the given
   * base. Constants are looked up through their parents, so the base
   * scope will be the outer scope of the new klass.
   */
  function create_scope(base, klass, id) {
    var const_alloc   = function() {};
    var const_scope   = const_alloc.prototype = new base.constructor();
    klass._scope      = const_scope;
    const_scope.base  = klass;
    const_scope.constructor = const_alloc;

    if (id) {
      base[id] = base.constructor[id] = klass;
    }
  }

  /*
    Define a bridged class. Bridged classes will always be in the top level
    scope, and will always be a subclass of Object.
  */
  Opal.bridge = function(name, constructor) {
    var klass = bridge_class(constructor);

    klass._name = name;

    create_scope(Opal, klass, name);

    return klass;
  };

  Opal.klass = function(base, superklass, id, constructor) {
    var klass;
    if (typeof(base) !== 'function') {
      base = base.constructor;
    }

    if (superklass === null) {
      superklass = Object;
    }

    if (__hasOwn.call(base._scope, id)) {
      klass = base._scope[id];
    }
    else {
      klass = boot_class(superklass, constructor);

      klass._name = (base === Object ? id : base._name + '::' + id);

      create_scope(base._scope, klass);

      base[id] = base._scope[id] = klass;

      if (superklass.$inherited) {
        superklass.$inherited(klass);
      }
    }

    return klass;
  };

  // Define new module (or return existing module)
  Opal.module = function(base, id, constructor) {
    var klass;
    if (typeof(base) !== 'function') {
      base = base.constructor;
    }

    if (__hasOwn.call(base._scope, id)) {
      klass = base._scope[id];
    }
    else {
      klass = boot_class(Class, constructor);
      klass._name = (base === Object ? id : base._name + '::' + id);

      klass._included_in = [];

      create_scope(base._scope, klass, id);
    }

    return klass;
  };

  // Utility function to raise a "no block given" error
  var no_block_given = function() {
    throw new Error('no block given');
  };

  // Boot a base class (makes instances).
  var boot_defclass = function(id, constructor, superklass) {
    if (superklass) {
      var ctor           = function() {};
          ctor.prototype = superklass.prototype;

      constructor.prototype = new ctor();
    }

    var prototype = constructor.prototype;

    prototype.constructor = constructor;
    prototype.constructor      = constructor;

    constructor._name         = id;
    constructor._super        = superklass;
    constructor._methods      = [];
    constructor._smethods     = [];

    constructor['$==='] = module_eqq;
    constructor.$to_s = module_to_s;
    constructor.toString = module_to_s;

    Opal[id] = constructor;

    return constructor;
  };

  // Create generic class with given superclass.
  var boot_class = Opal.boot = function(superklass, constructor) {
    var ctor = function() {};
        ctor.prototype = superklass.prototype;

    constructor.prototype = new ctor();
    var prototype = constructor.prototype;

    prototype.constructor = constructor;

    constructor._super        = superklass;
    constructor._methods      = [];
    constructor.constructor   = Class;

    constructor['$===']  = module_eqq;
    constructor.$to_s    = module_to_s;
    constructor.toString = module_to_s;

    constructor['$[]'] = undefined;
    constructor.$call  = undefined;

    var smethods;

    smethods = superklass._smethods.slice();

    constructor._smethods = smethods;
    for (var i = 0, length = smethods.length; i < length; i++) {
      var m = smethods[i];
      constructor[m] = superklass[m];
    }

    var inherited = superklass._inherited;

    if (!inherited) {
      inherited = superklass._inherited = [];
    }

    inherited.push(constructor);

    return constructor;
  };

  var bridge_class = function(constructor) {
    var i, length, m;

    constructor.prototype.constructor = constructor;

    constructor._super        = Object;
    constructor.constructor   = Class;
    constructor._methods      = [];
    constructor._smethods     = [];

    constructor['$===']  = module_eqq;
    constructor.$to_s    = module_to_s;
    constructor.toString = module_to_s;

    var smethods = constructor._smethods = Class._methods.slice();
    for (i = 0, length = smethods.length; i < length; i++) {
      m = smethods[i];
      constructor[m] = Object[m];
    }

    bridged_classes.push(constructor);

    var table = Object.prototype, methods = Object._methods;

    for (i = 0, length = methods.length; i < length; i++) {
      m = methods[i];
      constructor.prototype[m] = table[m];
    }

    constructor._smethods.push('$allocate');

    return constructor;
  };

  Opal.puts = function(a) { console.log(a); };

  // Method missing dispatcher
  Opal.mm = function(mid) {
    var dispatcher = function() {
      var args = __slice.call(arguments);

      if (this.$method_missing) {
        this.$method_missing._p = dispatcher._p;
        return this.$method_missing.apply(this, [mid].concat(args));
      }
      else {
        native_send._p = dispatcher._p;
        return native_send(this, mid, args);
      }
    };

    return dispatcher;
  };

  // send a method to a native object
  var native_send = function(obj, mid, args) {
    var prop, block = native_send._p;
    native_send._p = null;

    if (prop = native_methods[mid]) {
      return prop(obj, args, block);
    }

    prop = obj[mid];

    if (typeof(prop) === "function") {
      prop = prop.apply(obj, args.$to_native());
    }
    else if (mid.charAt(mid.length - 1) === "=") {
      prop = mid.slice(0, mid.length - 1);
      return obj[prop] = args[0];
    }

    if (prop != null) {
      return prop;
    }

    return nil;
  };

  var native_methods = {
    "==": function(obj, args) {
      return obj === args[0];
    },

    "[]": function(obj, args) {
      var prop = obj[args[0]];

      if (prop != null) {
        return prop;
      }

      return nil;
    },

    "[]=": function(obj, args) {
      var value = args[1];

      if (value === nil) {
        value = null;
      }

      return obj[args[0]] = value;
    },

    "respond_to?": function(obj, args) {
      return obj[args[0]] != null;
    },

    "each": function(obj, args, block) {
      var prop;

      if (obj.length === +obj.length) {
        for (var i = 0, len = obj.length; i < len; i++) {
          prop = obj[i];

          if (prop == null) {
            prop = nil;
          }

          block(prop);
        }
      }
      else {
        for (var key in obj) {
          prop = obj[key];

          if (prop == null) {
            prop = nil;
          }

          block(key, prop);
        }
      }

      return obj;
    },

    "to_a": function(obj, args) {
      var result = [];

      for (var i = 0, length = obj.length; i < length; i++) {
        result.push(obj[i]);
      }

      return result;
    },

    "to_h": function(obj) {
      var keys = [], values = {}, value;

      for (var key in obj) {
        keys.push(key);

        if ((value = obj[key]) == null) {
          values[key] = nil;
        }
        else {
          values[key] = value;
        }
      }

      return Opal.hash2(keys, values);
    }
  };

  // Const missing dispatcher
  Opal.cm = function(name) {
    return this.base.$const_missing(name);
  };

  // Arity count error dispatcher
  Opal.ac = function(actual, expected, object, meth) {
    var inspect = ((typeof(object) !== 'function') ? object.constructor._name + '#' : object._name + '.') + meth;
    var msg = '[' + inspect + '] wrong number of arguments(' + actual + ' for ' + expected + ')';
    throw Opal.ArgumentError.$new(msg);
  };

  /*
    Call a ruby method on a ruby object with some arguments:

      var my_array = [1, 2, 3, 4]
      Opal.send(my_array, 'length')     # => 4
      Opal.send(my_array, 'reverse!')   # => [4, 3, 2, 1]

    A missing method will be forwarded to the object via
    method_missing.

    The result of either call with be returned.

    @param [Object] recv the ruby object
    @param [String] mid ruby method to call
  */
  Opal.send = function(recv, mid) {
    var args = __slice.call(arguments, 2),
        func = recv['$' + mid];

    if (func) {
      return func.apply(recv, args);
    }

    return recv.$method_missing.apply(recv, [mid].concat(args));
  };

  Opal.block_send = function(recv, mid, block) {
    var args = __slice.call(arguments, 3),
        func = recv['$' + mid];

    if (func) {
      func._p = block;
      return func.apply(recv, args);
    }

    return recv.$method_missing.apply(recv, [mid].concat(args));
  };

  // Implementation of Class#===
  function module_eqq(object) {
    if (object == null) {
      return false;
    }

    var search = object.constructor;

    while (search) {
      if (search === this) {
        return true;
      }

      search = search._super;
    }

    return false;
  }

  // Implementation of Class#to_s
  function module_to_s() {
    return this._name;
  }

  /**
   * Donate methods for a class/module
   */
  Opal.donate = function(klass, defined, indirect) {
    var methods = klass._methods, included_in = klass._included_in;

    // if (!indirect) {
      klass._methods = methods.concat(defined);
    // }

    if (included_in) {
      for (var i = 0, length = included_in.length; i < length; i++) {
        var includee = included_in[i];
        var dest = includee.prototype;

        for (var j = 0, jj = defined.length; j < jj; j++) {
          var method = defined[j];
          dest[method] = klass.prototype[method];
        }

        if (includee._included_in) {
          Opal.donate(includee, defined, true);
        }
      }
    }
  };

  /*
    Define a singleton method on the given klass

        Opal.defs(Array, '$foo', function() {})

    @param [Function] klass
    @param [String] mid the method_id
    @param [Function] body function body
  */
  Opal.defs = function(klass, mid, body) {
    klass._smethods.push(mid);
    klass[mid] = body;

    var inherited = klass._inherited;
    if (inherited && inherited.length) {
      for (var i = 0, length = inherited.length, subclass; i < length; i++) {
        subclass = inherited[i];
        if (!subclass[mid]) {
          Opal.defs(subclass, mid, body);
        }
      }
    }
  };

  // Defines methods onto Object (which are then donated to bridged classes)
  Object._defn = function (mid, body) {
    this.prototype[mid] = body;
    Opal.donate(this, [mid]);
  };

  // Initialization
  // --------------

  boot_defclass('BasicObject', BasicObject);
  boot_defclass('Object', Object, BasicObject);
  boot_defclass('Class', Class, Object);

  Class.prototype = Function.prototype;

  BasicObject.constructor = Object.constructor = Class.constructor = Class;

  var bridged_classes = Object._included_in = [];

  Opal.base = Object;
  BasicObject._scope = Object._scope = Opal;
  Opal.Module = Opal.Class;
  Opal.Kernel = Object;

  create_scope(Opal, Class);

  Object.prototype.toString = function() {
    return this.$to_s();
  };

  Opal.top = new Object;

  Opal.klass(Object, Object, 'NilClass', NilClass);
  var nil = Opal.nil = new NilClass;
  nil.call = nil.apply = function() { throw Opal.LocalJumpError.$new('no block given'); };

  Opal.breaker  = new Error('unexpected break');

  Opal.bridge('Array', Array);
  Opal.bridge('Boolean', Boolean);
  Opal.bridge('Numeric', Number);
  Opal.bridge('String', String);
  Opal.bridge('Proc', Function);
  Opal.bridge('Exception', Error);
  Opal.bridge('Regexp', RegExp);
  Opal.bridge('Time', Date);
}).call(this);
<|endoftext|>


<commit_before>var wcMap = function () {
  var words = this.message.toLowerCase().match(/\S+/g);
  words.forEach(function (word) {
    if (word.length > 100) {
      emit(word.slice(0, 100), 1);
    } else {
      emit(word, 1);
    }
  });
};

var wcReduce = function (wordKey, wordValues) {
  var count = wordValues.reduce(function(prev, next) {
    return prev + next;
  }, 0);
  return count;
};

db.trans.mapReduce(
  wcMap,
  wcReduce,
  { out: {merge: "message_word_count"} }
);

// Get top 100 words
db.mr_message_word_count.aggregate([
    {$sort: {"value": -1}},
    {$limit: 100}
]);
<commit_msg>Update word_count_mr.js<commit_after>var wcMap = function () {
  var words = this.message.toLowerCase().match(/\S+/g);
  words.forEach(function (word) {
    if (word.length > 100) {
      emit(word.slice(0, 100), 1);
    } else {
      emit(word, 1);
    }
  });
};

var wcReduce = function (wordKey, wordValues) {
  var count = wordValues.reduce(function(prev, next) {
    return prev + next;
  }, 0);
  return count;
};

db.trans.mapReduce(
  wcMap,
  wcReduce,
  { out: {merge: "mr_message_word_count"} }
);

// Get top 100 words
db.mr_message_word_count.aggregate([
    {$sort: {"value": -1}},
    {$limit: 100}
]);
<|endoftext|>


<commit_before>/* Counting comparisons in quick sort */

'use strict';

const fs = require('fs');
const readline = require('readline');

const arr = [];
const rl = readline.createInterface({
	input: fs.createReadStream('integers.txt')
});

rl.on('line', (line) => {
	arr.push(line);
});

rl.on('close', () => {
	let sorter = new QuickSort();
	sorter.sort(arr, 0, 9999);
	console.log(sorter.comparisons);
});

class QuickSort {
	constructor() {
		this.comparisons = 0;
	}

	sort(arr, lInd, rInd) {
		let len = rInd - lInd + 1;
		if(len < 2 ) return;

		let pivotInd = lInd;
		let parInd = this._partition(arr, lInd, rInd, pivotInd);

		this.sort(arr, lInd, parInd - 1);
		this.sort(arr, parInd + 1, rInd);
	}

	_partition(arr, lInd, rInd, pivotInd) {
		let i = pivotInd + 1;
		let j = pivotInd + 1;

		while(j <= rInd) {
			if(Number(arr[j]) < Number(arr[pivotInd])) {
				[arr[i], arr[j]] = [arr[j], arr[i]];
				i++;
			}

			j++;
		}

		[arr[pivotInd], arr[i - 1]] = [arr[i - 1], arr[pivotInd]];
		this.comparisons += rInd - lInd;
		return i - 1;
	}
}<commit_msg>updated quick sort<commit_after>/* Counting comparisons in quick sort */
/* Use the "median-of-three" pivot rule */

'use strict';

const fs = require('fs');
const readline = require('readline');

const arr = [];
const rl = readline.createInterface({
	input: fs.createReadStream('integers.txt')
});

rl.on('line', (line) => {
	arr.push(line);
});

rl.on('close', () => {
	let sorter = new QuickSort();
	sorter.sort(arr, 0, 9999);
	console.log(arr)
	console.log(sorter.comparisons);
});

class QuickSort {
	constructor() {
		this.comparisons = 0;
	}

	sort(arr, lInd, rInd) {
		let len = rInd - lInd + 1;
		if(len < 2 ) return;

		let pivotInd = this._choosePivot(arr, lInd, rInd);
		// exchange pivot element with first element of sub array
		[arr[pivotInd], arr[lInd]] = [arr[lInd], arr[pivotInd]];
		let parInd = this._partition(arr, lInd, rInd, lInd);

		this.sort(arr, lInd, parInd - 1);
		this.sort(arr, parInd + 1, rInd);
	}

	_choosePivot(arr, lInd, rInd) {
		// Choose the first one if there are only two entries
		if(rInd - lInd + 1 === 2) return lInd;

		let midInd = Math.floor((rInd - lInd) / 2);
		let indices = Array.of(lInd, midInd, rInd);
		let values = indices.map(ind => arr[ind]);
		for(let ind of indices) {
			if(arr[ind] > Math.min(...values) && arr[ind] < Math.max(...values)) {
				return ind;
			}
		}
	}

	_partition(arr, lInd, rInd, pivotInd) {
		let i = pivotInd + 1;
		let j = pivotInd + 1;

		while(j <= rInd) {
			if(Number(arr[j]) < Number(arr[pivotInd])) {
				[arr[i], arr[j]] = [arr[j], arr[i]];
				i++;
			}

			j++;
		}

		[arr[pivotInd], arr[i - 1]] = [arr[i - 1], arr[pivotInd]];
		this.comparisons += rInd - lInd;
		return i - 1;
	}
}<|endoftext|>


<commit_before>var piecePadding = 10;
var pieceHeight = 70;
var pieceWidth = 50;

ThreesGame.ROWS = 4;
ThreesGame.COLUMNS = 4;

var Move = { LEFT : 0, UP : 1, RIGHT : 2, DOWN : 3 };

function ThreesController() {
  this.game = null;
  this.view = null;
}

ThreesController.prototype.randomNextValue = function() {
  var highestValue = this.game.highestValue();
  var useBonus = highestValue >= 48 && Math.random() < 1/21;
  if (useBonus) {
    var range = Math.round(Math.log(highestValue / 24) / Math.LN2);
    var randBonus = 1 + Math.floor(Math.random() * range);
    return Math.pow(2, randBonus) * 24;
  }
  var left = this.game.remaining[0] + this.game.remaining[1] + this.game.remaining[2];
  var nextCard = Math.floor(Math.random() * left);
  var r;
  if (nextCard < this.game.remaining[0]) {
    r = 1;
    this.game.remaining[0]--;
  } else if (nextCard < this.game.remaining[0] + this.game.remaining[1]) {
    r = 2;
    this.game.remaining[1]--;
  } else {
    r = 3;
    this.game.remaining[2]--;
  }
  if (left == 1) {
    this.game.remaining = [4, 4, 4];
  }
  return r;
};

ThreesController.prototype.startNewGame = function() {
  if (this.view) {
    this.view.exitDocument();
  }
  this.nextValueString = '';
  this.game = new ThreesGame();
  this.game.eventTarget = document;
  this.view = new ThreesView(this.game);
  this.view.enterDocument();
  this.view.board.focus();
  this.view.board.addEventListener('keydown', this.handleKeyDown.bind(this));

  for (var i = 0; i < (ThreesGame.ROWS - 1) * (ThreesGame.COLUMNS - 1); i++) {
    var r = Math.floor(Math.random() * 4);
    var c = Math.floor(Math.random() * 4);
    var value = this.randomNextValue();
    while (this.game.getPiece(r, c) != 0) {
      r = Math.floor(Math.random() * 4);
      c = Math.floor(Math.random() * 4);
    }
    this.game.addPiece(r, c, value);
  }
  this.game.nextValue = this.randomNextValue();
  this.view.showNextValue(); // handle with an event?
};

ThreesView.prototype.validateState = function() {
  for (var r = 0; r < ThreesGame.ROWS; r++) {
    for (var c = 0; c < ThreesGame.COLUMNS; c++) {
      if (this.pieces[r][c] == null) {
        if (this.game.getPiece(r, c) != 0) {
          throw new Error('Invalid state @ ' + r + ',' + c);
        }
      } else {
        if (this.pieces[r][c].firstChild.innerText != this.game.getPiece(r, c)) {
          throw new Error('Invalid state @ ' + r + ',' + c);
        }
      }
    }
  }
};

ThreesController.prototype.handleKeyDown = function(e) {
  this.view.validateState();
  var m;
  switch (e.keyCode) {
    case 37: // left
      m = Move.LEFT;
      break;
    case 38: // up
      m = Move.UP;
      break;
    case 39: // right
      m = Move.RIGHT;
      break;
    case 40: // down
      m = Move.DOWN;
      break;
    case 78:
      this.startNewGame();
      return;
    default:
      return;
  }
  this.move(m);
  e.preventDefault();
};

ThreesController.prototype.move = function(m) {
  var deltaR, deltaC;
  switch (m) {
    case Move.LEFT: // left
      deltaR = 0;
      deltaC = -1;
      break;
    case Move.UP: // up
      deltaR = -1;
      deltaC = 0;
      break;
    case Move.RIGHT: // right
      deltaR = 0;
      deltaC = 1;
      break;
    case Move.DOWN: // down
      deltaR = 1;
      deltaC = 0;
      break;
    default:
      throw new Error('Invalid move: ' + m);
  }
  var moved = this.game.move(deltaR, deltaC);
  if (moved.length != 0) {
    var randomEntry = moved[Math.floor(Math.random() * moved.length)];
    var randomNextValue = this.randomNextValue();
    this.nextValueString += randomNextValue + ',';
    this.game.makeNextMove(deltaR, deltaC, randomEntry, randomNextValue);
    this.view.showNextValue(); // handle with an event?
  }
  return moved.length != 0;
};

function ThreesMoveEvent(fromR, fromC, toR, toC, newValue) {
  this.fromR = fromR;
  this.fromC = fromC;
  this.toR = toR;
  this.toC = toC;
  this.newValue = newValue;
};

ThreesMoveEvent.TYPE = 'MovePiece';

function ThreesAddEvent(r, c, value) {
  this.r = r;
  this.c = c;
  this.value = value;
};

ThreesAddEvent.TYPE = 'AddPiece';

function ThreesView(game) {
  this.game = game;
  this.pieces = [];
  for (var r = 0; r < ThreesGame.ROWS; r++) {
    var row = [];
    for (var c = 0; c < ThreesGame.COLUMNS; c++) {
      if (this.game.getPiece(r, c) == 0) {
        row.push(null);
      } else {
        throw new Error("Unsupported view from non-empty game");
      }
    }
    this.pieces.push(row);
  }
}

ThreesView.prototype.exitDocument = function() {
  document.body.removeChild(this.nextPieceContainer);
  document.body.removeChild(this.board);
  document.removeEventListener(ThreesMoveEvent.TYPE, this.handleMovePiece.bind(this), false);
  document.removeEventListener(ThreesAddEvent.TYPE, this.handleAddPiece.bind(this), false);
};

ThreesView.prototype.enterDocument = function() {
  this.nextPieceContainer = document.createElement('div');
  this.nextPieceContainer.className = 'nextPiece';
  document.body.appendChild(this.nextPieceContainer);
  this.nextPiece = document.createElement('div');
  var content = document.createElement('div');
  content.className = 'pieceContent';
  this.nextPiece.appendChild(content);
  this.nextPieceContainer.appendChild(this.nextPiece);
  this.showNextValue();

  this.board = document.createElement('div');
  this.board.tabIndex = 0;
  this.board.className = 'gameBoard';
  for (var r = 0; r < ThreesGame.ROWS; r++) {
    for (var c = 0; c < ThreesGame.COLUMNS; c++) {
      var emptyPiece = document.createElement('div');
      emptyPiece.className = 'gamePiece emptyPiece';
      this.board.appendChild(emptyPiece);
      this.updatePiece(emptyPiece, r, c, null);
    }
  }
  document.body.appendChild(this.board);
  document.addEventListener(ThreesMoveEvent.TYPE, this.handleMovePiece.bind(this), false);
  document.addEventListener(ThreesAddEvent.TYPE, this.handleAddPiece.bind(this), false);
};

ThreesView.prototype.handleMovePiece = function(event) {
  var e = event.detail;
  var piece = this.pieces[e.fromR][e.fromC];
  this.updatePiece(piece, e.toR, e.toC, e.newValue);
  var pieceToRemove = this.pieces[e.toR][e.toC];
  if (pieceToRemove) {
    pieceToRemove.style.zIndex = 3;

    var board = this.board;
    // Wait until the animation has finished. This fails if you do a bunch of moves at once.
    window.setTimeout(function() {
      board.removeChild(pieceToRemove);
    }, 750);
  }
  this.pieces[e.fromR][e.fromC] = null;
  this.pieces[e.toR][e.toC] = piece;
};

ThreesView.prototype.handleAddPiece = function(event) {
  var e = event.detail;
  var newPiece = document.createElement('div');
  var content = document.createElement('div');
  content.className = 'pieceContent';
  newPiece.appendChild(content);
  this.board.appendChild(newPiece);
  this.updatePiece(newPiece, e.r, e.c, e.value);
  this.pieces[e.r][e.c] = newPiece;
};

ThreesView.prototype.showNextValue = function() {
  this.updatePieceValue(this.nextPiece, this.game.nextValue);
};

ThreesView.prototype.updatePiece = function(piece, r, c, value) {
  var left = c * (pieceWidth + piecePadding) + piecePadding;
  var top = r * (pieceHeight + piecePadding) + piecePadding;
  piece.style.left = left + 'px';
  piece.style.top = top + 'px';
  if (value != null) {
    this.updatePieceValue(piece, value);
  }
};

ThreesView.prototype.updatePieceValue = function(piece, value) {
  piece.firstChild.innerText = value;
  piece.className = 'gamePiece';
  if (value == 1) {
    piece.className += ' onePiece';
  } else if (value == 2) {
    piece.className += ' twoPiece';
  }
};

function ThreesGame(opt_existingGame) {
  if (opt_existingGame) {
    this.pieces = opt_existingGame.pieces.slice(0);
    this.remaining = opt_existingGame.remaining.slice(0);
    this.nextValue = opt_existingGame.nextValue;
  } else {
    this.pieces = [];
    for (var i = 0; i < ThreesGame.ROWS * ThreesGame.COLUMNS; i++) {
      this.pieces.push(0);
    }
    this.remaining = [4, 4, 4];
    this.nextValue = null;
  }
}

ThreesGame.deserialize = function(gameData) {
  var game = new ThreesGame();
  game.pieces = gameData.pieces;
  game.remaining = gameData.remaining;
  game.nextValue = gameData.nextValue;
  return game;
};

ThreesGame.prototype.copy = function() {
  return new ThreesGame(this);
};

ThreesGame.prototype.getPiece = function(r, c) {
  return this.pieces[r * ThreesGame.COLUMNS + c];
};

ThreesGame.prototype.setPiece = function(r, c, v) {
  this.pieces[r * ThreesGame.COLUMNS + c] = v;
};

ThreesGame.prototype.pieceCount = function() {
  var pieceCount = 0;
  for (var i = 0; i < this.pieces.length; i++) {
    if (this.pieces[i] != 0) pieceCount++;
  }
  return pieceCount;
};

ThreesGame.prototype.highestValue = function() {
  var max = 0;
  for (var i = 0; i < this.pieces.length; i++) {
    max = Math.max(max, this.pieces[i]);
  }
  return max;
};

// Returns a list of rows or columns that were moved.
ThreesGame.prototype.move = function(deltaR, deltaC) {
//  if (Math.abs(deltaC) + Math.abs(deltaR) !== 1) {
//    throw new Error("Invalid delta " + deltaR + ", " + deltaC);
//  }
  var moved = [];
  var isVertical = deltaR != 0;
  for (var r = 0; r < ThreesGame.ROWS; r++) {
    for (var c = 0; c < ThreesGame.COLUMNS; c++) {
      var rT = deltaR == 1 ? ThreesGame.ROWS - 1 - r : r;
      var cT = deltaC == 1 ? ThreesGame.COLUMNS - 1 - c : c;
      if (this.canMovePiece(rT, cT, deltaR, deltaC)) {
        this.movePiece(rT, cT, deltaR, deltaC);
        var movedEntry = isVertical ? cT : rT;
        if (moved.indexOf(movedEntry) == -1) {
          moved.push(movedEntry);
        }
      }
    }
  }
  return moved;
};

ThreesGame.prototype.makeNextMove = function(deltaR, deltaC, newPosition, newNextValue) {
  var newR, newC;
  if (deltaR != 0) {
    newC = newPosition;
  } else {
    newR = newPosition;
  }
  if (deltaR == 1) {
    newR = 0;
  } else if (deltaR == -1) {
    newR = ThreesGame.ROWS - 1;
  } else if (deltaC == 1) {
    newC = 0;
  } else if (deltaC == -1) {
    newC = ThreesGame.COLUMNS - 1;
  }
  var actualNextValue = this.nextValue;
  this.addPiece(newR, newC, actualNextValue);
  this.nextValue = newNextValue;
};

ThreesGame.prototype.addPiece = function(r, c, value) {
//  if (this.getPiece(r, c) != 0) {
//    throw new Error('Can not add piece where one exists');
//  }
  this.setPiece(r, c, value);
  if (this.eventTarget) {
    var addPieceEvent = new CustomEvent(ThreesAddEvent.TYPE,
      {'detail': new ThreesAddEvent(r, c, value)});
    this.eventTarget.dispatchEvent(addPieceEvent);
  }
};

/**
 * @returns {boolean} Whether the piece at (r,c) can move by (deltaR,deltaC).
 * If there is no piece at this position, returns false.
 */
ThreesGame.prototype.canMovePiece = function(r, c, deltaR, deltaC) {
  var fromValue = this.getPiece(r, c);
  if (fromValue == 0 || c + deltaC < 0 || c + deltaC >= ThreesGame.COLUMNS ||
      r + deltaR < 0 || r + deltaR >= ThreesGame.ROWS) {
    return false;
  }

  var toValue = this.getPiece(r + deltaR, c + deltaC);
  return toValue == 0 ||
          (toValue >= 3 && fromValue == toValue) ||
          (toValue < 3 && fromValue + toValue == 3);
};

/**
 * Moves the given piece at (r,c) by (deltaR,deltaC).
 */
ThreesGame.prototype.movePiece = function(r, c, deltaR, deltaC) {
//  if (!this.canMovePiece(r, c, deltaR, deltaC)) {
//    throw new Error("Can't move piece");
//  }
  var toR = r + deltaR;
  var toC = c + deltaC;
  this.setPiece(toR, toC, this.getPiece(toR, toC) + this.getPiece(r, c));
  this.setPiece(r, c, 0);
  if (this.eventTarget) {
    var movePieceEvent = new CustomEvent(ThreesMoveEvent.TYPE,
      {'detail': new ThreesMoveEvent(r, c, toR, toC, this.getPiece(toR, toC))});
    this.eventTarget.dispatchEvent(movePieceEvent);
  }
};<commit_msg>List initial random values chosen<commit_after>var piecePadding = 10;
var pieceHeight = 70;
var pieceWidth = 50;

ThreesGame.ROWS = 4;
ThreesGame.COLUMNS = 4;

var Move = { LEFT : 0, UP : 1, RIGHT : 2, DOWN : 3 };

function ThreesController() {
  this.game = null;
  this.view = null;
}

ThreesController.prototype.randomNextValue = function() {
  var highestValue = this.game.highestValue();
  var useBonus = highestValue >= 48 && Math.random() < 1/21;
  if (useBonus) {
    var range = Math.round(Math.log(highestValue / 24) / Math.LN2);
    var randBonus = 1 + Math.floor(Math.random() * range);
    var r = Math.pow(2, randBonus) * 24;
    this.nextValueString += r + ',';
    return r;
  }
  var left = this.game.remaining[0] + this.game.remaining[1] + this.game.remaining[2];
  var nextCard = Math.floor(Math.random() * left);
  var r;
  if (nextCard < this.game.remaining[0]) {
    r = 1;
    this.game.remaining[0]--;
  } else if (nextCard < this.game.remaining[0] + this.game.remaining[1]) {
    r = 2;
    this.game.remaining[1]--;
  } else {
    r = 3;
    this.game.remaining[2]--;
  }
  if (left == 1) {
    this.game.remaining = [4, 4, 4];
  }
  this.nextValueString += r + ',';
  return r;
};

ThreesController.prototype.startNewGame = function() {
  if (this.view) {
    this.view.exitDocument();
  }
  this.nextValueString = '';
  this.game = new ThreesGame();
  this.game.eventTarget = document;
  this.view = new ThreesView(this.game);
  this.view.enterDocument();
  this.view.board.focus();
  this.view.board.addEventListener('keydown', this.handleKeyDown.bind(this));

  for (var i = 0; i < (ThreesGame.ROWS - 1) * (ThreesGame.COLUMNS - 1); i++) {
    var r = Math.floor(Math.random() * 4);
    var c = Math.floor(Math.random() * 4);
    var value = this.randomNextValue();
    while (this.game.getPiece(r, c) != 0) {
      r = Math.floor(Math.random() * 4);
      c = Math.floor(Math.random() * 4);
    }
    this.game.addPiece(r, c, value);
  }
  this.game.nextValue = this.randomNextValue();
  this.view.showNextValue(); // handle with an event?
};

ThreesView.prototype.validateState = function() {
  for (var r = 0; r < ThreesGame.ROWS; r++) {
    for (var c = 0; c < ThreesGame.COLUMNS; c++) {
      if (this.pieces[r][c] == null) {
        if (this.game.getPiece(r, c) != 0) {
          throw new Error('Invalid state @ ' + r + ',' + c);
        }
      } else {
        if (this.pieces[r][c].firstChild.innerText != this.game.getPiece(r, c)) {
          throw new Error('Invalid state @ ' + r + ',' + c);
        }
      }
    }
  }
};

ThreesController.prototype.handleKeyDown = function(e) {
  this.view.validateState();
  var m;
  switch (e.keyCode) {
    case 37: // left
      m = Move.LEFT;
      break;
    case 38: // up
      m = Move.UP;
      break;
    case 39: // right
      m = Move.RIGHT;
      break;
    case 40: // down
      m = Move.DOWN;
      break;
    case 78:
      this.startNewGame();
      return;
    default:
      return;
  }
  this.move(m);
  e.preventDefault();
};

ThreesController.prototype.move = function(m) {
  var deltaR, deltaC;
  switch (m) {
    case Move.LEFT: // left
      deltaR = 0;
      deltaC = -1;
      break;
    case Move.UP: // up
      deltaR = -1;
      deltaC = 0;
      break;
    case Move.RIGHT: // right
      deltaR = 0;
      deltaC = 1;
      break;
    case Move.DOWN: // down
      deltaR = 1;
      deltaC = 0;
      break;
    default:
      throw new Error('Invalid move: ' + m);
  }
  var moved = this.game.move(deltaR, deltaC);
  if (moved.length != 0) {
    var randomEntry = moved[Math.floor(Math.random() * moved.length)];
    var randomNextValue = this.randomNextValue();
    this.game.makeNextMove(deltaR, deltaC, randomEntry, randomNextValue);
    this.view.showNextValue(); // handle with an event?
  }
  return moved.length != 0;
};

function ThreesMoveEvent(fromR, fromC, toR, toC, newValue) {
  this.fromR = fromR;
  this.fromC = fromC;
  this.toR = toR;
  this.toC = toC;
  this.newValue = newValue;
};

ThreesMoveEvent.TYPE = 'MovePiece';

function ThreesAddEvent(r, c, value) {
  this.r = r;
  this.c = c;
  this.value = value;
};

ThreesAddEvent.TYPE = 'AddPiece';

function ThreesView(game) {
  this.game = game;
  this.pieces = [];
  for (var r = 0; r < ThreesGame.ROWS; r++) {
    var row = [];
    for (var c = 0; c < ThreesGame.COLUMNS; c++) {
      if (this.game.getPiece(r, c) == 0) {
        row.push(null);
      } else {
        throw new Error("Unsupported view from non-empty game");
      }
    }
    this.pieces.push(row);
  }
}

ThreesView.prototype.exitDocument = function() {
  document.body.removeChild(this.nextPieceContainer);
  document.body.removeChild(this.board);
  document.removeEventListener(ThreesMoveEvent.TYPE, this.handleMovePiece.bind(this), false);
  document.removeEventListener(ThreesAddEvent.TYPE, this.handleAddPiece.bind(this), false);
};

ThreesView.prototype.enterDocument = function() {
  this.nextPieceContainer = document.createElement('div');
  this.nextPieceContainer.className = 'nextPiece';
  document.body.appendChild(this.nextPieceContainer);
  this.nextPiece = document.createElement('div');
  var content = document.createElement('div');
  content.className = 'pieceContent';
  this.nextPiece.appendChild(content);
  this.nextPieceContainer.appendChild(this.nextPiece);
  this.showNextValue();

  this.board = document.createElement('div');
  this.board.tabIndex = 0;
  this.board.className = 'gameBoard';
  for (var r = 0; r < ThreesGame.ROWS; r++) {
    for (var c = 0; c < ThreesGame.COLUMNS; c++) {
      var emptyPiece = document.createElement('div');
      emptyPiece.className = 'gamePiece emptyPiece';
      this.board.appendChild(emptyPiece);
      this.updatePiece(emptyPiece, r, c, null);
    }
  }
  document.body.appendChild(this.board);
  document.addEventListener(ThreesMoveEvent.TYPE, this.handleMovePiece.bind(this), false);
  document.addEventListener(ThreesAddEvent.TYPE, this.handleAddPiece.bind(this), false);
};

ThreesView.prototype.handleMovePiece = function(event) {
  var e = event.detail;
  var piece = this.pieces[e.fromR][e.fromC];
  this.updatePiece(piece, e.toR, e.toC, e.newValue);
  var pieceToRemove = this.pieces[e.toR][e.toC];
  if (pieceToRemove) {
    pieceToRemove.style.zIndex = 3;

    var board = this.board;
    // Wait until the animation has finished. This fails if you do a bunch of moves at once.
    window.setTimeout(function() {
      board.removeChild(pieceToRemove);
    }, 750);
  }
  this.pieces[e.fromR][e.fromC] = null;
  this.pieces[e.toR][e.toC] = piece;
};

ThreesView.prototype.handleAddPiece = function(event) {
  var e = event.detail;
  var newPiece = document.createElement('div');
  var content = document.createElement('div');
  content.className = 'pieceContent';
  newPiece.appendChild(content);
  this.board.appendChild(newPiece);
  this.updatePiece(newPiece, e.r, e.c, e.value);
  this.pieces[e.r][e.c] = newPiece;
};

ThreesView.prototype.showNextValue = function() {
  this.updatePieceValue(this.nextPiece, this.game.nextValue);
};

ThreesView.prototype.updatePiece = function(piece, r, c, value) {
  var left = c * (pieceWidth + piecePadding) + piecePadding;
  var top = r * (pieceHeight + piecePadding) + piecePadding;
  piece.style.left = left + 'px';
  piece.style.top = top + 'px';
  if (value != null) {
    this.updatePieceValue(piece, value);
  }
};

ThreesView.prototype.updatePieceValue = function(piece, value) {
  piece.firstChild.innerText = value;
  piece.className = 'gamePiece';
  if (value == 1) {
    piece.className += ' onePiece';
  } else if (value == 2) {
    piece.className += ' twoPiece';
  }
};

function ThreesGame(opt_existingGame) {
  if (opt_existingGame) {
    this.pieces = opt_existingGame.pieces.slice(0);
    this.remaining = opt_existingGame.remaining.slice(0);
    this.nextValue = opt_existingGame.nextValue;
  } else {
    this.pieces = [];
    for (var i = 0; i < ThreesGame.ROWS * ThreesGame.COLUMNS; i++) {
      this.pieces.push(0);
    }
    this.remaining = [4, 4, 4];
    this.nextValue = null;
  }
}

ThreesGame.deserialize = function(gameData) {
  var game = new ThreesGame();
  game.pieces = gameData.pieces;
  game.remaining = gameData.remaining;
  game.nextValue = gameData.nextValue;
  return game;
};

ThreesGame.prototype.copy = function() {
  return new ThreesGame(this);
};

ThreesGame.prototype.getPiece = function(r, c) {
  return this.pieces[r * ThreesGame.COLUMNS + c];
};

ThreesGame.prototype.setPiece = function(r, c, v) {
  this.pieces[r * ThreesGame.COLUMNS + c] = v;
};

ThreesGame.prototype.pieceCount = function() {
  var pieceCount = 0;
  for (var i = 0; i < this.pieces.length; i++) {
    if (this.pieces[i] != 0) pieceCount++;
  }
  return pieceCount;
};

ThreesGame.prototype.highestValue = function() {
  var max = 0;
  for (var i = 0; i < this.pieces.length; i++) {
    max = Math.max(max, this.pieces[i]);
  }
  return max;
};

// Returns a list of rows or columns that were moved.
ThreesGame.prototype.move = function(deltaR, deltaC) {
//  if (Math.abs(deltaC) + Math.abs(deltaR) !== 1) {
//    throw new Error("Invalid delta " + deltaR + ", " + deltaC);
//  }
  var moved = [];
  var isVertical = deltaR != 0;
  for (var r = 0; r < ThreesGame.ROWS; r++) {
    for (var c = 0; c < ThreesGame.COLUMNS; c++) {
      var rT = deltaR == 1 ? ThreesGame.ROWS - 1 - r : r;
      var cT = deltaC == 1 ? ThreesGame.COLUMNS - 1 - c : c;
      if (this.canMovePiece(rT, cT, deltaR, deltaC)) {
        this.movePiece(rT, cT, deltaR, deltaC);
        var movedEntry = isVertical ? cT : rT;
        if (moved.indexOf(movedEntry) == -1) {
          moved.push(movedEntry);
        }
      }
    }
  }
  return moved;
};

ThreesGame.prototype.makeNextMove = function(deltaR, deltaC, newPosition, newNextValue) {
  var newR, newC;
  if (deltaR != 0) {
    newC = newPosition;
  } else {
    newR = newPosition;
  }
  if (deltaR == 1) {
    newR = 0;
  } else if (deltaR == -1) {
    newR = ThreesGame.ROWS - 1;
  } else if (deltaC == 1) {
    newC = 0;
  } else if (deltaC == -1) {
    newC = ThreesGame.COLUMNS - 1;
  }
  var actualNextValue = this.nextValue;
  this.addPiece(newR, newC, actualNextValue);
  this.nextValue = newNextValue;
};

ThreesGame.prototype.addPiece = function(r, c, value) {
//  if (this.getPiece(r, c) != 0) {
//    throw new Error('Can not add piece where one exists');
//  }
  this.setPiece(r, c, value);
  if (this.eventTarget) {
    var addPieceEvent = new CustomEvent(ThreesAddEvent.TYPE,
      {'detail': new ThreesAddEvent(r, c, value)});
    this.eventTarget.dispatchEvent(addPieceEvent);
  }
};

/**
 * @returns {boolean} Whether the piece at (r,c) can move by (deltaR,deltaC).
 * If there is no piece at this position, returns false.
 */
ThreesGame.prototype.canMovePiece = function(r, c, deltaR, deltaC) {
  var fromValue = this.getPiece(r, c);
  if (fromValue == 0 || c + deltaC < 0 || c + deltaC >= ThreesGame.COLUMNS ||
      r + deltaR < 0 || r + deltaR >= ThreesGame.ROWS) {
    return false;
  }

  var toValue = this.getPiece(r + deltaR, c + deltaC);
  return toValue == 0 ||
          (toValue >= 3 && fromValue == toValue) ||
          (toValue < 3 && fromValue + toValue == 3);
};

/**
 * Moves the given piece at (r,c) by (deltaR,deltaC).
 */
ThreesGame.prototype.movePiece = function(r, c, deltaR, deltaC) {
//  if (!this.canMovePiece(r, c, deltaR, deltaC)) {
//    throw new Error("Can't move piece");
//  }
  var toR = r + deltaR;
  var toC = c + deltaC;
  this.setPiece(toR, toC, this.getPiece(toR, toC) + this.getPiece(r, c));
  this.setPiece(r, c, 0);
  if (this.eventTarget) {
    var movePieceEvent = new CustomEvent(ThreesMoveEvent.TYPE,
      {'detail': new ThreesMoveEvent(r, c, toR, toC, this.getPiece(toR, toC))});
    this.eventTarget.dispatchEvent(movePieceEvent);
  }
};<|endoftext|>


<commit_before>var uuid = require('node-uuid');

module.exports = {
  startPriority: 101,
  stopPriority:  999,
  loadPriority:  200,
  initialize: function(api, next){

    api.redis = {};
    api.redis.clusterCallbaks = {};
    api.redis.clusterCallbakTimeouts = {};
    api.redis.subscriptionHandlers = {};
    api.redis.status = {
      client: false,
      subscriber: false,
      subscribed: false,
      calledback: false,
    };

    if(api.config.redis.package && !api.config.redis.pkg) {
      api.log(`Depreciation warning: New versions of actionhero utilize 'pkg' instead of 'package' for redis! Please update your configuration.`);
      api.config.redis.pkg = api.config.redis.package;
    }

    var redisPackage = require(api.config.redis.pkg);
    if(api.config.redis.pkg === 'fakeredis'){
      api.log('running with fakeredis', 'warning');
      redisPackage.fast = true;
    }

    api.redis.initialize = function(callback){
      if(api.config.redis.pkg === 'fakeredis'){
        api.redis.client     = redisPackage.createClient(String(api.config.redis.host));
        api.redis.subscriber = redisPackage.createClient(String(api.config.redis.host));
      }else{
        api.redis.client     = redisPackage.createClient(api.config.redis.port, api.config.redis.host, api.config.redis.options);
        api.redis.subscriber = redisPackage.createClient(api.config.redis.port, api.config.redis.host, api.config.redis.options);
      }

      api.redis.client.on('error', function(err){
        api.log(['Redis Error (client): %s', err], 'emerg');
      });

      api.redis.subscriber.on('error', function(err){
        api.log(['Redis Error (subscriber): %s', err], 'emerg');
      });

      api.redis.client.on('end', function(){
        api.log('Redis Connection Closed (client)', 'debug');
        api.redis.status.client = false;
      });

      api.redis.subscriber.on('end', function(){
        api.log('Redis Connection Closed (subscriber)', 'debug');
        api.redis.status.subscriber = false;
        api.redis.status.subscribed = false;
      });

      api.redis.client.on('connect', function(){
        if(api.config.redis.database){ api.redis.client.select(api.config.redis.database); }
        api.log('connected to redis (client)', 'debug');
        api.redis.status.client = true;
        if(api.redis.status.client === true && api.redis.status.subscriber === true && api.redis.status.calledback === false){
          api.redis.status.calledback = true;
          callback();
        }
      });

      if(!api.redis.status.subscribed){
        api.redis.subscriber.subscribe(api.config.redis.channel);
        api.redis.status.subscribed = true;
      }

      api.redis.subscriber.on('message', function(messageChannel, message){
        try{ message = JSON.parse(message); }catch(e){ message = {}; }
        if(messageChannel === api.config.redis.channel && message.serverToken === api.config.general.serverToken){
          if(api.redis.subscriptionHandlers[message.messageType]){
            api.redis.subscriptionHandlers[message.messageType](message);
          }
        }
      });

      api.redis.subscriber.on('connect', function(){
        // if(api.config.redis.database){ api.redis.subscriber.select(api.config.redis.database); }
        api.log('connected to redis (subscriber)', 'debug');
        api.redis.status.subscriber = true;
        if(api.redis.status.client === true && api.redis.status.subscriber === true && api.redis.status.calledback === false){
          api.redis.status.calledback = true;
          callback();
        }
      });

      if(api.config.redis.pkg === 'fakeredis'){
        api.redis.status.client = true;
        api.redis.status.subscriber = true;
        process.nextTick(function(){
          api.redis.status.calledback = true;
          callback();
        });
      }
    };

    api.redis.publish = function(payload){
      var channel = api.config.redis.channel;
      api.redis.client.publish(channel, JSON.stringify(payload));
    };

    // Subsciption Handlers

    api.redis.subscriptionHandlers.do = function(message){
      if(!message.connectionId || ( api.connections && api.connections.connections[message.connectionId]) ){
        var cmdParts = message.method.split('.');
        var cmd = cmdParts.shift();
        if(cmd !== 'api'){ throw new Error('cannot operate on a method outside of the api object') }
        var method = api.utils.stringToHash(cmdParts.join('.'));

        var callback = function(){
          var responseArgs = Array.apply(null, arguments).sort();
          process.nextTick(function(){
            api.redis.respondCluster(message.requestId, responseArgs);
          });
        };
        var args = message.args;
        if(args === null){ args = []; }
        if(!Array.isArray(args)){ args = [args]; }
        args.push(callback);
        method.apply(null, args);
      }
    };

    api.redis.subscriptionHandlers.doResponse = function(message){
      if(api.redis.clusterCallbaks[message.requestId]){
        clearTimeout(api.redis.clusterCallbakTimeouts[message.requestId]);
        api.redis.clusterCallbaks[message.requestId].apply(null, message.response);
        delete api.redis.clusterCallbaks[message.requestId];
        delete api.redis.clusterCallbakTimeouts[message.requestId];
      }
    };

    // RPC

    api.redis.doCluster = function(method, args, connectionId, callback){
      var requestId = uuid.v4();
      var payload = {
        messageType  : 'do',
        serverId     : api.id,
        serverToken  : api.config.general.serverToken,
        requestId    : requestId,
        method       : method,
        connectionId : connectionId,
        args         : args,   // [1,2,3]
      };

      api.redis.publish(payload);

      if(typeof callback === 'function'){
        api.redis.clusterCallbaks[requestId] = callback;
        api.redis.clusterCallbakTimeouts[requestId] = setTimeout(function(requestId){
          if(typeof api.redis.clusterCallbaks[requestId] === 'function'){
            api.redis.clusterCallbaks[requestId](new Error('RPC Timeout'));
          }
          delete api.redis.clusterCallbaks[requestId];
          delete api.redis.clusterCallbakTimeouts[requestId];
        }, api.config.redis.rpcTimeout, requestId);
      }
    };

    api.redis.respondCluster = function(requestId, response){
      var payload = {
        messageType  : 'doResponse',
        serverId     : api.id,
        serverToken  : api.config.general.serverToken,
        requestId    : requestId,
        response     : response, // args to pass back, including error
      };

      api.redis.publish(payload);
    };

    // Boot

    api.redis.initialize(function(){
      api.redis.doCluster('api.log', [['actionhero member %s has joined the cluster', api.id]], null, null);
      process.nextTick(next);
    });

  },

  start: function(api, next){
    next();
  },

  stop: function(api, next){
    for(var i in api.redis.clusterCallbakTimeouts){
      clearTimeout( api.redis.clusterCallbakTimeouts[i] );
      delete api.redis.clusterCallbakTimeouts[i];
      delete api.redis.clusterCallbaks[i];
    }
    api.redis.doCluster('api.log', [['actionhero member %s has left the cluster', api.id]], null, null);

    process.nextTick(function(){
      api.redis.subscriber.unsubscribe();
      next();
    });
  }
};
<commit_msg>wrapping a 'package', get it?<commit_after>var uuid = require('node-uuid');

module.exports = {
  startPriority: 101,
  stopPriority:  999,
  loadPriority:  200,
  initialize: function(api, next){

    api.redis = {};
    api.redis.clusterCallbaks = {};
    api.redis.clusterCallbakTimeouts = {};
    api.redis.subscriptionHandlers = {};
    api.redis.status = {
      client: false,
      subscriber: false,
      subscribed: false,
      calledback: false,
    };

    if(api.config.redis['package'] && !api.config.redis.pkg) {
      api.log(`Depreciation warning: New versions of actionhero utilize 'pkg' instead of 'package' for redis! Please update your configuration.`);
      api.config.redis.pkg = api.config.redis['package'];
    }

    var redisPackage = require(api.config.redis.pkg);
    if(api.config.redis.pkg === 'fakeredis'){
      api.log('running with fakeredis', 'warning');
      redisPackage.fast = true;
    }

    api.redis.initialize = function(callback){
      if(api.config.redis.pkg === 'fakeredis'){
        api.redis.client     = redisPackage.createClient(String(api.config.redis.host));
        api.redis.subscriber = redisPackage.createClient(String(api.config.redis.host));
      }else{
        api.redis.client     = redisPackage.createClient(api.config.redis.port, api.config.redis.host, api.config.redis.options);
        api.redis.subscriber = redisPackage.createClient(api.config.redis.port, api.config.redis.host, api.config.redis.options);
      }

      api.redis.client.on('error', function(err){
        api.log(['Redis Error (client): %s', err], 'emerg');
      });

      api.redis.subscriber.on('error', function(err){
        api.log(['Redis Error (subscriber): %s', err], 'emerg');
      });

      api.redis.client.on('end', function(){
        api.log('Redis Connection Closed (client)', 'debug');
        api.redis.status.client = false;
      });

      api.redis.subscriber.on('end', function(){
        api.log('Redis Connection Closed (subscriber)', 'debug');
        api.redis.status.subscriber = false;
        api.redis.status.subscribed = false;
      });

      api.redis.client.on('connect', function(){
        if(api.config.redis.database){ api.redis.client.select(api.config.redis.database); }
        api.log('connected to redis (client)', 'debug');
        api.redis.status.client = true;
        if(api.redis.status.client === true && api.redis.status.subscriber === true && api.redis.status.calledback === false){
          api.redis.status.calledback = true;
          callback();
        }
      });

      if(!api.redis.status.subscribed){
        api.redis.subscriber.subscribe(api.config.redis.channel);
        api.redis.status.subscribed = true;
      }

      api.redis.subscriber.on('message', function(messageChannel, message){
        try{ message = JSON.parse(message); }catch(e){ message = {}; }
        if(messageChannel === api.config.redis.channel && message.serverToken === api.config.general.serverToken){
          if(api.redis.subscriptionHandlers[message.messageType]){
            api.redis.subscriptionHandlers[message.messageType](message);
          }
        }
      });

      api.redis.subscriber.on('connect', function(){
        // if(api.config.redis.database){ api.redis.subscriber.select(api.config.redis.database); }
        api.log('connected to redis (subscriber)', 'debug');
        api.redis.status.subscriber = true;
        if(api.redis.status.client === true && api.redis.status.subscriber === true && api.redis.status.calledback === false){
          api.redis.status.calledback = true;
          callback();
        }
      });

      if(api.config.redis.pkg === 'fakeredis'){
        api.redis.status.client = true;
        api.redis.status.subscriber = true;
        process.nextTick(function(){
          api.redis.status.calledback = true;
          callback();
        });
      }
    };

    api.redis.publish = function(payload){
      var channel = api.config.redis.channel;
      api.redis.client.publish(channel, JSON.stringify(payload));
    };

    // Subsciption Handlers

    api.redis.subscriptionHandlers.do = function(message){
      if(!message.connectionId || ( api.connections && api.connections.connections[message.connectionId]) ){
        var cmdParts = message.method.split('.');
        var cmd = cmdParts.shift();
        if(cmd !== 'api'){ throw new Error('cannot operate on a method outside of the api object') }
        var method = api.utils.stringToHash(cmdParts.join('.'));

        var callback = function(){
          var responseArgs = Array.apply(null, arguments).sort();
          process.nextTick(function(){
            api.redis.respondCluster(message.requestId, responseArgs);
          });
        };
        var args = message.args;
        if(args === null){ args = []; }
        if(!Array.isArray(args)){ args = [args]; }
        args.push(callback);
        method.apply(null, args);
      }
    };

    api.redis.subscriptionHandlers.doResponse = function(message){
      if(api.redis.clusterCallbaks[message.requestId]){
        clearTimeout(api.redis.clusterCallbakTimeouts[message.requestId]);
        api.redis.clusterCallbaks[message.requestId].apply(null, message.response);
        delete api.redis.clusterCallbaks[message.requestId];
        delete api.redis.clusterCallbakTimeouts[message.requestId];
      }
    };

    // RPC

    api.redis.doCluster = function(method, args, connectionId, callback){
      var requestId = uuid.v4();
      var payload = {
        messageType  : 'do',
        serverId     : api.id,
        serverToken  : api.config.general.serverToken,
        requestId    : requestId,
        method       : method,
        connectionId : connectionId,
        args         : args,   // [1,2,3]
      };

      api.redis.publish(payload);

      if(typeof callback === 'function'){
        api.redis.clusterCallbaks[requestId] = callback;
        api.redis.clusterCallbakTimeouts[requestId] = setTimeout(function(requestId){
          if(typeof api.redis.clusterCallbaks[requestId] === 'function'){
            api.redis.clusterCallbaks[requestId](new Error('RPC Timeout'));
          }
          delete api.redis.clusterCallbaks[requestId];
          delete api.redis.clusterCallbakTimeouts[requestId];
        }, api.config.redis.rpcTimeout, requestId);
      }
    };

    api.redis.respondCluster = function(requestId, response){
      var payload = {
        messageType  : 'doResponse',
        serverId     : api.id,
        serverToken  : api.config.general.serverToken,
        requestId    : requestId,
        response     : response, // args to pass back, including error
      };

      api.redis.publish(payload);
    };

    // Boot

    api.redis.initialize(function(){
      api.redis.doCluster('api.log', [['actionhero member %s has joined the cluster', api.id]], null, null);
      process.nextTick(next);
    });

  },

  start: function(api, next){
    next();
  },

  stop: function(api, next){
    for(var i in api.redis.clusterCallbakTimeouts){
      clearTimeout( api.redis.clusterCallbakTimeouts[i] );
      delete api.redis.clusterCallbakTimeouts[i];
      delete api.redis.clusterCallbaks[i];
    }
    api.redis.doCluster('api.log', [['actionhero member %s has left the cluster', api.id]], null, null);

    process.nextTick(function(){
      api.redis.subscriber.unsubscribe();
      next();
    });
  }
};
<|endoftext|>