<commit_before>var enabled = false;
var poolSetting, paramSetting;
var freqSet, voltSet;

var pools = [], avalons = [];
var jobQueue = [
	{thisId: -1, value: []},
	{thisId: -1, value: []},
	{thisId: -1, value: []},
];
var thread = new Worker("thread.js");
var workQueue = {
	value: [],
	shift: function() {
		if (workQueue.value.length < 1000)
			thread.postMessage({info: "resume"});
		return this.value.shift();
	},
	push: function(data) {
		if (workQueue.value.length >= 1023)
			thread.postMessage({info: "pause"});
		return this.value.push(data);
	},
	init: function() {
		this.value = [];
	},
};
var activePool = Infinity; // Bigger than bigger. Low id gets high priority.

var hashrates = [];
var totalHashrate = Array.apply(null, new Array(721)).map(Number.prototype.valueOf, 0);

chrome.app.runtime.onLaunched.addListener(function() {
	chrome.storage.local.get("pool", function(result) {
		poolSetting = result.pool || [];
	});
	chrome.storage.local.get("param", function(result) {
		paramSetting = result.param || [];
		freqSet = paramSetting.freqSet;
		voltSet = paramSetting.voltSet;
	});

	chrome.app.window.create("index.html", {
		innerBounds: {
			width: 1000,
			height: 700,
			minWidth: 1000,
			minHeight: 700
		},
		id: "Avalon miner"
	});

	chrome.runtime.onMessage.addListener(function(msg, sender) {
		var i;
		if (sender.url.indexOf("index.html") === -1)
			return;
		switch (msg.type) {
		case "ready":
			prelude();
			break;
		case "start":
			main();
			break;
		case "setting":
			if (msg.pool !== undefined) {
				for (i = 0; i < pools.length; i++) {
					pools[i].disconnect();
					delete(pools[i]);
				}
				poolSetting = msg.pool;
				if (enabled) {
					thread.postMessage({info: "pause"});
					activePool = Infinity;
					for (i = 0; i < poolSetting.length; i++) {
						var p = poolSetting[i];
						pools[i] = new Pool(i, p.address, p.port, p.username, p.password);
						pools[i].onJob.addListener(jobHandler);
						pools[i].onError.addListener(errorHandler);
						pools[i].connect();
					}
				}
			}
			if (msg.param !== undefined) {
				paramSetting = msg.param;
				for (var avalon in avalons) {
					if (avalon === undefined)
						continue;
					avalon.setVoltage(volt);
					avalon.setVoltage(freqs);
				}
			}
			chrome.storage.local.set({
				pool: poolSetting,
				param: paramSetting,
			});
			break;
		}
	});
});

var prelude = function() {
	chrome.runtime.sendMessage({
		type: "setting",
		pool: poolSetting,
		param: paramSetting,
	});

	scanDevices();

	chrome.hid.onDeviceAdded.addListener(function(device) {
		var id = device.deviceId;
		avalons[id] = new Avalon(device, workQueue, voltSet, freqSet);
		chrome.runtime.sendMessage({
			type: "device",
			deviceId: id,
			deviceType: avalons[id].deviceType,
		});
		avalons[id].onDetect.addListener(detectHandler);
		avalons[id].onNonce.addListener(nonceHandler);
		avalons[id].onStatus.addListener(statusHandler);
		hashrates[id] = hashrates[id] ||
			Array.apply(null, new Array(721)).map(Number.prototype.valueOf, 0);
		if (enabled)
			avalons[id].connect();
	});

	chrome.hid.onDeviceRemoved.addListener(function(deviceId) {
		for (var idx in avalons) {
			var avalon = avalons[idx];
			if (avalon.deviceId === deviceId) {
				avalon.stop();
				delete(avalons[idx]);
				delete(hashrates[idx]);
				chrome.runtime.sendMessage({type: "delete", deviceId: deviceId});
				return;
			}
		}
	});

};

var main = function() {
	var i, pool, avalon;
	enabled = true;
	activePool = Infinity;
	for (i = 0; i < poolSetting.length; i++) {
		var p = poolSetting[i];
		pools[i] = new Pool(i, p.address, p.port, p.username, p.password);
	}

	thread.onmessage = function(work) {
		workQueue.push(work.data);
	};

	chrome.sockets.tcp.onReceive.addListener(function(info) {
		for (var pool of pools)
			if (pool !== undefined && info.socketId === pool.socketId) {
				pool.receive(info.data);
				return;
			}
	});

	chrome.sockets.tcp.onReceiveError.addListener(function(info) {
		for (var pool of pools)
			if (pool !== undefined && info.socketId === pool.socketId) {
				if (pool.id === activePool) {
					thread.postMessage({info: "pause"});
					activePool++;
					workQueue.init();
					if (pool.id !== 3) {
						var jq = jobQueue[activePool];
						thread.postMessage({
							info: "newJob",
							job: jq.value[jq.thisId],
							jqId: jq.thisId,
						});
					}
				}
				chrome.runtime.sendMessage({
					info: "Failed",
					type: "pool",
					poolId: pool.id,
				});
				pool.connect();
				return;
			}
	});

	for (pool of pools) {
		pool.onJob.addListener(jobHandler);
		pool.onError.addListener(errorHandler);
		pool.connect();
	}

	calcHashrate();

	for (avalon of avalons)
		if (avalon !== undefined)
			avalon.connect();
};

var jobHandler = function(job) {
	var poolId = job.poolId;
	var jq = jobQueue[poolId];
	jq.thisId = (jq.thisId + 1) % 256;
	jq.value[jq.thisId] = job;
	if (poolId < activePool) {
		activePool = poolId;
		workQueue.init();
		chrome.runtime.sendMessage({
			info: "Active",
			type: "pool",
			poolId: poolId,
		});
	} else if (poolId > activePool) {
		chrome.runtime.sendMessage({
			info: "Inactive",
			type: "pool",
			poolId: poolId,
		});
		return;
	} else
		workQueue.init();
	thread.postMessage({info: "newJob", job: job, jqId: jq.thisId});
};

var errorHandler = function(poolId) {
	chrome.runtime.sendMessage({
		info: "Failed",
		type: "pool",
		poolId: poolId,
	});
};

var detectHandler = function(info) {
	var dna = info.dna;
	var version = info.version;
	var id = info.deviceId;
	chrome.runtime.sendMessage(
		{type: "status", deviceId: id, version: version, dna: dna}
	);
	avalons[id].run();
};

var nonceHandler = function(info) {
	if (jobQueue[info.poolId] === undefined)
		return;
	var job = jobQueue[info.poolId].value[info.jqId];
	if (job === undefined)
		return;
	var ntime = info.ntime + parseInt(job.ntime, 16);
	switch (utils.varifyWork(job, info.nonce2, ntime, info.nonce)) {
		case 2:
			// hard ware error
			return;
		case 0:
			pools[info.poolId].submit(
				job.jobId,
				utils.uInt2LeHex(info.nonce2, job.nonce2Size),
				ntime.toString(16),
				utils.uInt2LeHex(info.nonce, 4)
			);
			/* falls through */
		case 1:
			hashrates[info.deviceId][0]++;
			totalHashrate[0]++;
			return;
	}
};

var statusHandler = function(stats) {
	stats.type = "status";
	chrome.runtime.sendMessage(stats);
};

var scanDevices = function() {
	chrome.hid.getDevices(Avalon.FILTERS, function(devices) {
		if (chrome.runtime.lastError) {
			return;
		}
		for (var device of devices) {
			var id = device.deviceId;
			avalons[id] = new Avalon(device, workQueue, voltSet, freqSet);
			chrome.runtime.sendMessage({
				type: "device",
				deviceId: id,
				deviceType: avalons[id].deviceType,
			});
			avalons[id].onDetect.addListener(detectHandler);
			avalons[id].onNonce.addListener(nonceHandler);
			avalons[id].onStatus.addListener(statusHandler);
			hashrates[id] = hashrates[id] ||
				Array.apply(null, new Array(721)).map(Number.prototype.valueOf, 0);
		}
	});
};

var calcHashrate = function() {
	(function loop() {
		var hashrate = [];
		var h;
		for (var i in hashrates) {
			h = hashrates[i];
			if (h !== undefined) {
				h.unshift(0);
				hashrate.push({
					deviceId: i,
					hs1h: utils.arraySum(h.slice(1)) / 3600 * 4294967296,
					hs15m: utils.arraySum(h.slice(1, 181)) / 900 * 4294967296,
					hs5m: utils.arraySum(h.slice(1, 61)) / 300 * 4294967296,
					hs1m: utils.arraySum(h.slice(1, 13)) / 60 * 4294967296,
					hs15s: utils.arraySum(h.slice(1, 4))/ 15 * 4294967296,
					hs5s: h[1] / 5 * 4294.967296
				});
				h.pop();
			}
		}
		h = totalHashrate;
		h.unshift(0);
		hashrate.push({
			deviceId: null,
			hs1h: utils.arraySum(h.slice(1)) / 3600 * 4294967296,
			hs15m: utils.arraySum(h.slice(1, 181)) / 900 * 4294967296,
			hs5m: utils.arraySum(h.slice(1, 61)) / 300 * 4294967296,
			hs1m: utils.arraySum(h.slice(1, 13)) / 60 * 4294967296,
			hs15s: utils.arraySum(h.slice(1, 4))/ 15 * 4294967296,
			hs5s: h[1] / 5 * 4294967296
		});
		h.pop();
		chrome.runtime.sendMessage({
			type: "hashrate",
			hashrate: hashrate,
		});
		setTimeout(loop, 5000);
	})();
};
<commit_msg>APP: Fix hashrate calculation<commit_after>var enabled = false;
var poolSetting, paramSetting;
var freqSet, voltSet;

var pools = [], avalons = [];
var jobQueue = [
	{thisId: -1, value: []},
	{thisId: -1, value: []},
	{thisId: -1, value: []},
];
var thread = new Worker("thread.js");
var workQueue = {
	value: [],
	shift: function() {
		if (workQueue.value.length < 1000)
			thread.postMessage({info: "resume"});
		return this.value.shift();
	},
	push: function(data) {
		if (workQueue.value.length >= 1023)
			thread.postMessage({info: "pause"});
		return this.value.push(data);
	},
	init: function() {
		this.value = [];
	},
};
var activePool = Infinity; // Bigger than bigger. Low id gets high priority.

var hashrates = [];
var totalHashrate = Array.apply(null, new Array(721)).map(Number.prototype.valueOf, 0);

chrome.app.runtime.onLaunched.addListener(function() {
	chrome.storage.local.get("pool", function(result) {
		poolSetting = result.pool || [];
	});
	chrome.storage.local.get("param", function(result) {
		paramSetting = result.param || [];
		freqSet = paramSetting.freqSet;
		voltSet = paramSetting.voltSet;
	});

	chrome.app.window.create("index.html", {
		innerBounds: {
			width: 1000,
			height: 700,
			minWidth: 1000,
			minHeight: 700
		},
		id: "Avalon miner"
	});

	chrome.runtime.onMessage.addListener(function(msg, sender) {
		var i;
		if (sender.url.indexOf("index.html") === -1)
			return;
		switch (msg.type) {
		case "ready":
			prelude();
			break;
		case "start":
			main();
			break;
		case "setting":
			if (msg.pool !== undefined) {
				for (i = 0; i < pools.length; i++) {
					pools[i].disconnect();
					delete(pools[i]);
				}
				poolSetting = msg.pool;
				if (enabled) {
					thread.postMessage({info: "pause"});
					activePool = Infinity;
					for (i = 0; i < poolSetting.length; i++) {
						var p = poolSetting[i];
						pools[i] = new Pool(i, p.address, p.port, p.username, p.password);
						pools[i].onJob.addListener(jobHandler);
						pools[i].onError.addListener(errorHandler);
						pools[i].connect();
					}
				}
			}
			if (msg.param !== undefined) {
				paramSetting = msg.param;
				for (var avalon in avalons) {
					if (avalon === undefined)
						continue;
					avalon.setVoltage(volt);
					avalon.setVoltage(freqs);
				}
			}
			chrome.storage.local.set({
				pool: poolSetting,
				param: paramSetting,
			});
			break;
		}
	});
});

var prelude = function() {
	chrome.runtime.sendMessage({
		type: "setting",
		pool: poolSetting,
		param: paramSetting,
	});

	scanDevices();

	chrome.hid.onDeviceAdded.addListener(function(device) {
		var id = device.deviceId;
		avalons[id] = new Avalon(device, workQueue, voltSet, freqSet);
		chrome.runtime.sendMessage({
			type: "device",
			deviceId: id,
			deviceType: avalons[id].deviceType,
		});
		avalons[id].onDetect.addListener(detectHandler);
		avalons[id].onNonce.addListener(nonceHandler);
		avalons[id].onStatus.addListener(statusHandler);
		hashrates[id] = hashrates[id] ||
			Array.apply(null, new Array(721)).map(Number.prototype.valueOf, 0);
		if (enabled)
			avalons[id].connect();
	});

	chrome.hid.onDeviceRemoved.addListener(function(deviceId) {
		for (var idx in avalons) {
			var avalon = avalons[idx];
			if (avalon.deviceId === deviceId) {
				avalon.stop();
				delete(avalons[idx]);
				delete(hashrates[idx]);
				chrome.runtime.sendMessage({type: "delete", deviceId: deviceId});
				return;
			}
		}
	});

};

var main = function() {
	var i, pool, avalon;
	enabled = true;
	activePool = Infinity;
	for (i = 0; i < poolSetting.length; i++) {
		var p = poolSetting[i];
		pools[i] = new Pool(i, p.address, p.port, p.username, p.password);
	}

	thread.onmessage = function(work) {
		workQueue.push(work.data);
	};

	chrome.sockets.tcp.onReceive.addListener(function(info) {
		for (var pool of pools)
			if (pool !== undefined && info.socketId === pool.socketId) {
				pool.receive(info.data);
				return;
			}
	});

	chrome.sockets.tcp.onReceiveError.addListener(function(info) {
		for (var pool of pools)
			if (pool !== undefined && info.socketId === pool.socketId) {
				if (pool.id === activePool) {
					thread.postMessage({info: "pause"});
					activePool++;
					workQueue.init();
					if (pool.id !== 3) {
						var jq = jobQueue[activePool];
						thread.postMessage({
							info: "newJob",
							job: jq.value[jq.thisId],
							jqId: jq.thisId,
						});
					}
				}
				chrome.runtime.sendMessage({
					info: "Failed",
					type: "pool",
					poolId: pool.id,
				});
				pool.connect();
				return;
			}
	});

	for (pool of pools) {
		pool.onJob.addListener(jobHandler);
		pool.onError.addListener(errorHandler);
		pool.connect();
	}

	calcHashrate();

	for (avalon of avalons)
		if (avalon !== undefined)
			avalon.connect();
};

var jobHandler = function(job) {
	var poolId = job.poolId;
	var jq = jobQueue[poolId];
	jq.thisId = (jq.thisId + 1) % 256;
	jq.value[jq.thisId] = job;
	if (poolId < activePool) {
		activePool = poolId;
		workQueue.init();
		chrome.runtime.sendMessage({
			info: "Active",
			type: "pool",
			poolId: poolId,
		});
	} else if (poolId > activePool) {
		chrome.runtime.sendMessage({
			info: "Inactive",
			type: "pool",
			poolId: poolId,
		});
		return;
	} else
		workQueue.init();
	thread.postMessage({info: "newJob", job: job, jqId: jq.thisId});
};

var errorHandler = function(poolId) {
	chrome.runtime.sendMessage({
		info: "Failed",
		type: "pool",
		poolId: poolId,
	});
};

var detectHandler = function(info) {
	var dna = info.dna;
	var version = info.version;
	var id = info.deviceId;
	chrome.runtime.sendMessage(
		{type: "status", deviceId: id, version: version, dna: dna}
	);
	avalons[id].run();
};

var nonceHandler = function(info) {
	if (jobQueue[info.poolId] === undefined)
		return;
	var job = jobQueue[info.poolId].value[info.jqId];
	if (job === undefined)
		return;
	var ntime = info.ntime + parseInt(job.ntime, 16);
	switch (utils.varifyWork(job, info.nonce2, ntime, info.nonce)) {
		case 2:
			// hard ware error
			return;
		case 0:
			pools[info.poolId].submit(
				job.jobId,
				utils.uInt2LeHex(info.nonce2, job.nonce2Size),
				ntime.toString(16),
				utils.uInt2LeHex(info.nonce, 4)
			);
			/* falls through */
		case 1:
			hashrates[info.deviceId][0]++;
			totalHashrate[0]++;
			return;
	}
};

var statusHandler = function(stats) {
	stats.type = "status";
	chrome.runtime.sendMessage(stats);
};

var scanDevices = function() {
	chrome.hid.getDevices(Avalon.FILTERS, function(devices) {
		if (chrome.runtime.lastError) {
			return;
		}
		for (var device of devices) {
			var id = device.deviceId;
			avalons[id] = new Avalon(device, workQueue, voltSet, freqSet);
			chrome.runtime.sendMessage({
				type: "device",
				deviceId: id,
				deviceType: avalons[id].deviceType,
			});
			avalons[id].onDetect.addListener(detectHandler);
			avalons[id].onNonce.addListener(nonceHandler);
			avalons[id].onStatus.addListener(statusHandler);
			hashrates[id] = hashrates[id] ||
				Array.apply(null, new Array(721)).map(Number.prototype.valueOf, 0);
		}
	});
};

var calcHashrate = function() {
	(function loop() {
		var hashrate = [];
		var h;
		for (var i in hashrates) {
			h = hashrates[i];
			if (h !== undefined) {
				h.unshift(0);
				hashrate.push({
					deviceId: i,
					hs1h: utils.arraySum(h.slice(1)) / 3600 * 4294967296,
					hs15m: utils.arraySum(h.slice(1, 181)) / 900 * 4294967296,
					hs5m: utils.arraySum(h.slice(1, 61)) / 300 * 4294967296,
					hs1m: utils.arraySum(h.slice(1, 13)) / 60 * 4294967296,
					hs15s: utils.arraySum(h.slice(1, 4))/ 15 * 4294967296,
					hs5s: h[1] / 5 * 4294967296,
				});
				h.pop();
			}
		}
		h = totalHashrate;
		h.unshift(0);
		hashrate.push({
			deviceId: null,
			hs1h: utils.arraySum(h.slice(1)) / 3600 * 4294967296,
			hs15m: utils.arraySum(h.slice(1, 181)) / 900 * 4294967296,
			hs5m: utils.arraySum(h.slice(1, 61)) / 300 * 4294967296,
			hs1m: utils.arraySum(h.slice(1, 13)) / 60 * 4294967296,
			hs15s: utils.arraySum(h.slice(1, 4))/ 15 * 4294967296,
			hs5s: h[1] / 5 * 4294967296,
		});
		h.pop();
		chrome.runtime.sendMessage({
			type: "hashrate",
			hashrate: hashrate,
		});
		setTimeout(loop, 5000);
	})();
};
<|endoftext|>


<commit_before>// Putting this up here to serve as help for people who open this script
const USAGE = `
This script will bump package.json to a new version and commit the results to
git. If you have a 'release' script in your package.json, then it will be
executed prior to the commit. Presumably this would be to update any binaries
that need updated upon release.

All you have to do in order to create a release is push to one of the following
branches, and an appropriate release and PR will be created:

release, release/patch, release/minor, release/major

The default type is "patch". This script will automatically increment version
numbers for you based on the release type.

options:
  --script: A script to run after package.json has been update and before the
            files are committed. You can do things like run a specific build
            process for your application with this argument. When your script is
            finished, it should stage its files with 'git add' so that they will
            be committed with this version.

This script needs three environment variables:

AUTORELEASE_BASE:  The base branch for pull requests. Defaults to 'master'
AUTORELEASE_KEY:   Please create a deploy key with write access and
                   paste the private key in this environment variable. You can
                   separate multiple lines with a literal \n if necessary. You
                   can create a key on linux / osx with "ssh-keygen -f ./key"
                   and you can upload the public key to /settings/keys on your
                   repo (https://github.com/:owner/:repo/settings/keys)
AUTORELEASE_TOKEN: Create a personal access token by going to
                   https://github.com/settings/tokens
                   Check all repo

`;

const { appendFileSync, chmodSync, mkdtempSync, writeFileSync } = require('fs');
const { join, resolve } = require('path');
const { spawnSync } = require('child_process');
const { tmpdir } = require('os');
const { inc } = require('semver');
const https = require('https');

// Import environment variables
const {
  AUTORELEASE_BASE = 'master',
  AUTORELEASE_KEY,
  AUTORELEASE_TOKEN,
  HOME,
  WERCKER_GIT_BRANCH,
  WERCKER_GIT_DOMAIN,
  WERCKER_GIT_OWNER,
  WERCKER_GIT_REPOSITORY,
} = process.env;

// Process arguments
const {
  SCRIPT
} = (() => {
  const options = {};
  const argv = process.argv;

  for (let x = 2; x < argv.length; ++x) {
    const [arg, ...values] = argv.split('=');
    const value = values.join('=');

    switch (arg) {
      case '--help':
        console.log(`usage: ${USAGE}`);
        process.exit(1);
        break;
      case '--script':
        options.script = values.length ? value : argv[++x];
        break;
      default:
        console.error(`Argument "${arg}" not recognized`);
        process.exit(1);
    }
  }

  return options;
})();

// Determine which release we're going to use
const [FEATURE, RELEASE_TYPE = 'patch'] = WERCKER_GIT_BRANCH.split('/');

if (FEATURE !== 'release') {
  console.error('This is not a release branch, so not creating a release');
  process.exit(0);
}

const packageJson = require(resolve('package.json'));
const NEXT_VERSION = inc(packageJson.version, RELEASE_TYPE);

if (NEXT_VERSION)
  console.log(`Preparing ${RELEASE_TYPE} release from ${packageJson.version} to ${NEXT_VERSION}`);
else {
  console.log(
    `Cannot create ${RELEASE_TYPE} release from ${packageJson.version} to ${NEXT_VERSION}`
  );
  process.exit(1);
}

const AUTORELEASE_DIR = mkdtempSync(join(tmpdir(), 'autorelease-'));
const ID_RSA = resolve(AUTORELEASE_DIR, 'id_rsa');
const SSH_CONFIG = `${HOME}/.ssh/config`;
const KNOWN_HOSTS = `${HOME}/.ssh/known_hosts`;

/**
 * Run spawnSync
 *
 * @param {string} command The command to run
 * @param {string[]} args Arguments for the command
 * @param {object} options The options
 *
 * @return {object} The result of spawnSync
 */
function exec(command, args, options = {}) {
  console.log(command, args);
  const result = spawnSync(command, args, options);
  console.log(result.stdout.toString('ascii'));
  console.log(result.stderr.toString('ascii'));
  if (result.error) throw result.error;
  if (result.status) process.exit(1);
  return result;
}
exec('mkdir', ['.ssh'], ['-m 700']);
// Create the SSH deploy key
writeFileSync(ID_RSA, AUTORELEASE_KEY.replace(/\\n/g, '\n'));
chmodSync(ID_RSA, 0o400);
appendFileSync(SSH_CONFIG, `
Host autorelease
  User git
  HostName ${WERCKER_GIT_DOMAIN}
  IdentityFile ${ID_RSA}`);
chmodSync(SSH_CONFIG, 0o600);

// Add github.com to known_hosts
appendFileSync(
  KNOWN_HOSTS,
  'github.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6Tb' +
  'Qa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsd' +
  'lLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+S' +
  'e8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOz' +
  'QgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA' +
  '8VJiS5ap43JXiUFFAaQ=='
);

// Create a git identity

// Checkout the branch
exec('git', ['--version']);
exec('git', ['remote', 'set-url', 'origin',
  `git@autorelease:${WERCKER_GIT_OWNER}/${WERCKER_GIT_REPOSITORY}`]
);
exec('git', ['config', '-l']);
exec('git', ['fetch', 'origin']);
exec('git', ['checkout', `${WERCKER_GIT_BRANCH}`]);

// Update package.json
writeFileSync(
  resolve('package.json'),
  JSON.stringify(packageJson, null, '  ') + '\n'
);

// Run release script if provided
if (SCRIPT) exec('node', SCRIPT);

if (packageJson.scripts && packageJson.scripts.release)
  exec('npm', ['run', 'release']);

// Configure git
exec('git', ['config', 'user.name', 'Autorelease Script']);
exec('git', ['config', 'user.email', 'tarwich+autorelease@gmail.com']);

// Create the git commit
exec('git', ['add', '.']);
exec('git', ['commit', '-m', `Release ${NEXT_VERSION}\n\n[skip ci]`]);
exec('git', ['push', 'origin', WERCKER_GIT_BRANCH]);

// Create the pull request
const request = https.request({
  host: 'api.github.com',
  path: `/repos/${WERCKER_GIT_OWNER}/${WERCKER_GIT_REPOSITORY}/pulls`,
  method: 'POST',
  headers: {
    'Accept': 'application/vnd.github.v3+json',
    'Authorization': `token ${AUTORELEASE_TOKEN}`,
    'User-Agent': 'Auto-upgrade bot by @tarwich',
  },
}, response => {
  console.log('STATUS: ' + response.statusCode);
  console.log('HEADERS: ' + JSON.stringify(response.headers));
  response.setEncoding('utf8');
  response.on('data', function(chunk) {
    console.log('BODY: ' + chunk);
  });
});

request.on('error', function(e) {
  console.log('problem with request: ' + e.message);
});

request.write(JSON.stringify({
  title: `Release ${NEXT_VERSION}`,
  body: `Auto build of request ${NEXT_VERSION}`,
  head: WERCKER_GIT_BRANCH,
  base: AUTORELEASE_BASE,
}, null, '  '));

request.end();
<commit_msg>Touch file<commit_after>// Putting this up here to serve as help for people who open this script
const USAGE = `
This script will bump package.json to a new version and commit the results to
git. If you have a 'release' script in your package.json, then it will be
executed prior to the commit. Presumably this would be to update any binaries
that need updated upon release.

All you have to do in order to create a release is push to one of the following
branches, and an appropriate release and PR will be created:

release, release/patch, release/minor, release/major

The default type is "patch". This script will automatically increment version
numbers for you based on the release type.

options:
  --script: A script to run after package.json has been update and before the
            files are committed. You can do things like run a specific build
            process for your application with this argument. When your script is
            finished, it should stage its files with 'git add' so that they will
            be committed with this version.

This script needs three environment variables:

AUTORELEASE_BASE:  The base branch for pull requests. Defaults to 'master'
AUTORELEASE_KEY:   Please create a deploy key with write access and
                   paste the private key in this environment variable. You can
                   separate multiple lines with a literal \n if necessary. You
                   can create a key on linux / osx with "ssh-keygen -f ./key"
                   and you can upload the public key to /settings/keys on your
                   repo (https://github.com/:owner/:repo/settings/keys)
AUTORELEASE_TOKEN: Create a personal access token by going to
                   https://github.com/settings/tokens
                   Check all repo

`;

const { appendFileSync, chmodSync, mkdtempSync, writeFileSync } = require('fs');
const { join, resolve } = require('path');
const { spawnSync } = require('child_process');
const { tmpdir } = require('os');
const { inc } = require('semver');
const https = require('https');

// Import environment variables
const {
  AUTORELEASE_BASE = 'master',
  AUTORELEASE_KEY,
  AUTORELEASE_TOKEN,
  HOME,
  WERCKER_GIT_BRANCH,
  WERCKER_GIT_DOMAIN,
  WERCKER_GIT_OWNER,
  WERCKER_GIT_REPOSITORY,
} = process.env;

// Process arguments
const {
  SCRIPT
} = (() => {
  const options = {};
  const argv = process.argv;

  for (let x = 2; x < argv.length; ++x) {
    const [arg, ...values] = argv.split('=');
    const value = values.join('=');

    switch (arg) {
      case '--help':
        console.log(`usage: ${USAGE}`);
        process.exit(1);
        break;
      case '--script':
        options.script = values.length ? value : argv[++x];
        break;
      default:
        console.error(`Argument "${arg}" not recognized`);
        process.exit(1);
    }
  }

  return options;
})();

// Determine which release we're going to use
const [FEATURE, RELEASE_TYPE = 'patch'] = WERCKER_GIT_BRANCH.split('/');

if (FEATURE !== 'release') {
  console.error('This is not a release branch, so not creating a release');
  process.exit(0);
}

const packageJson = require(resolve('package.json'));
const NEXT_VERSION = inc(packageJson.version, RELEASE_TYPE);

if (NEXT_VERSION)
  console.log(`Preparing ${RELEASE_TYPE} release from ${packageJson.version} to ${NEXT_VERSION}`);
else {
  console.log(
    `Cannot create ${RELEASE_TYPE} release from ${packageJson.version} to ${NEXT_VERSION}`
  );
  process.exit(1);
}

const AUTORELEASE_DIR = mkdtempSync(join(tmpdir(), 'autorelease-'));
const ID_RSA = resolve(AUTORELEASE_DIR, 'id_rsa');
const SSH_CONFIG = `${HOME}/.ssh/config`;
const KNOWN_HOSTS = `${HOME}/.ssh/known_hosts`;

/**
 * Run spawnSync
 *
 * @param {string} command The command to run
 * @param {string[]} args Arguments for the command
 * @param {object} options The options
 *
 * @return {object} The result of spawnSync
 */
function exec(command, args, options = {}) {
  console.log(command, args);
  const result = spawnSync(command, args, options);
  console.log(result.stdout.toString('ascii'));
  console.log(result.stderr.toString('ascii'));
  if (result.error) throw result.error;
  if (result.status) process.exit(1);
  return result;
}
exec('mkdir', ['.ssh'], ['-m 700']);
exec('touch', [SSH_CONFIG]);
// Create the SSH deploy key
writeFileSync(ID_RSA, AUTORELEASE_KEY.replace(/\\n/g, '\n'));
chmodSync(ID_RSA, 0o400);
appendFileSync(SSH_CONFIG, `
Host autorelease
  User git
  HostName ${WERCKER_GIT_DOMAIN}
  IdentityFile ${ID_RSA}`);
chmodSync(SSH_CONFIG, 0o600);

// Add github.com to known_hosts
appendFileSync(
  KNOWN_HOSTS,
  'github.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6Tb' +
  'Qa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsd' +
  'lLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+S' +
  'e8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOz' +
  'QgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA' +
  '8VJiS5ap43JXiUFFAaQ=='
);

// Create a git identity

// Checkout the branch
exec('git', ['--version']);
exec('git', ['remote', 'set-url', 'origin',
  `git@autorelease:${WERCKER_GIT_OWNER}/${WERCKER_GIT_REPOSITORY}`]
);
exec('git', ['config', '-l']);
exec('git', ['fetch', 'origin']);
exec('git', ['checkout', `${WERCKER_GIT_BRANCH}`]);

// Update package.json
writeFileSync(
  resolve('package.json'),
  JSON.stringify(packageJson, null, '  ') + '\n'
);

// Run release script if provided
if (SCRIPT) exec('node', SCRIPT);

if (packageJson.scripts && packageJson.scripts.release)
  exec('npm', ['run', 'release']);

// Configure git
exec('git', ['config', 'user.name', 'Autorelease Script']);
exec('git', ['config', 'user.email', 'tarwich+autorelease@gmail.com']);

// Create the git commit
exec('git', ['add', '.']);
exec('git', ['commit', '-m', `Release ${NEXT_VERSION}\n\n[skip ci]`]);
exec('git', ['push', 'origin', WERCKER_GIT_BRANCH]);

// Create the pull request
const request = https.request({
  host: 'api.github.com',
  path: `/repos/${WERCKER_GIT_OWNER}/${WERCKER_GIT_REPOSITORY}/pulls`,
  method: 'POST',
  headers: {
    'Accept': 'application/vnd.github.v3+json',
    'Authorization': `token ${AUTORELEASE_TOKEN}`,
    'User-Agent': 'Auto-upgrade bot by @tarwich',
  },
}, response => {
  console.log('STATUS: ' + response.statusCode);
  console.log('HEADERS: ' + JSON.stringify(response.headers));
  response.setEncoding('utf8');
  response.on('data', function(chunk) {
    console.log('BODY: ' + chunk);
  });
});

request.on('error', function(e) {
  console.log('problem with request: ' + e.message);
});

request.write(JSON.stringify({
  title: `Release ${NEXT_VERSION}`,
  body: `Auto build of request ${NEXT_VERSION}`,
  head: WERCKER_GIT_BRANCH,
  base: AUTORELEASE_BASE,
}, null, '  '));

request.end();
<|endoftext|>


<commit_before>// This is main process of Electron, started as first thing when the Electron
// app starts, and running through entire life of your application.
// It doesn't have any windows which you can see on screen, but we can open
// window from here.

var app = require('app');
var BrowserWindow = require('browser-window');
var env = require('./vendor/electron_boilerplate/env_config');
var devHelper = require('./vendor/electron_boilerplate/dev_helper');
var windowStateKeeper = require('./vendor/electron_boilerplate/window_state');

var mainWindow;

// Preserver of the window size and position between app launches.
var mainWindowState = windowStateKeeper('main', {
    width: 1000,
    height: 600
});

app.on('ready', function () {

    mainWindow = new BrowserWindow({
        x: mainWindowState.x,
        y: mainWindowState.y,
        width: mainWindowState.width,
        height: mainWindowState.height
    });

    if (mainWindowState.isMaximized) {
        mainWindow.maximize();
    }

    if (env.name === 'test') {
        mainWindow.loadUrl('file://' + __dirname + '/spec.html');
    } else {
        mainWindow.loadUrl('file://' + __dirname + '/app.html');
    }

    if (env.name !== 'production') {
        devHelper.setDevMenu();
        mainWindow.openDevTools();
    }

    mainWindow.on('close', function () {
        mainWindowState.saveState(mainWindow);
    });
});

app.on('window-all-closed', function () {
    app.quit();
});
<commit_msg>Little grammar amendment<commit_after>// This is main process of Electron, started as first thing when your
// app starts. This script is running through entire life of your application.
// It doesn't have any windows which you can see on screen, but we can open
// window from here.

var app = require('app');
var BrowserWindow = require('browser-window');
var env = require('./vendor/electron_boilerplate/env_config');
var devHelper = require('./vendor/electron_boilerplate/dev_helper');
var windowStateKeeper = require('./vendor/electron_boilerplate/window_state');

var mainWindow;

// Preserver of the window size and position between app launches.
var mainWindowState = windowStateKeeper('main', {
    width: 1000,
    height: 600
});

app.on('ready', function () {

    mainWindow = new BrowserWindow({
        x: mainWindowState.x,
        y: mainWindowState.y,
        width: mainWindowState.width,
        height: mainWindowState.height
    });

    if (mainWindowState.isMaximized) {
        mainWindow.maximize();
    }

    if (env.name === 'test') {
        mainWindow.loadUrl('file://' + __dirname + '/spec.html');
    } else {
        mainWindow.loadUrl('file://' + __dirname + '/app.html');
    }

    if (env.name !== 'production') {
        devHelper.setDevMenu();
        mainWindow.openDevTools();
    }

    mainWindow.on('close', function () {
        mainWindowState.saveState(mainWindow);
    });
});

app.on('window-all-closed', function () {
    app.quit();
});
<|endoftext|>


<commit_before>/************************************************
 * AUTHOR:         Alexandre Cazala             *
 * CREATION_DATE:  22/11/16                      *
 * EMAIL:          alexandre.cazala@gmail.com   *
 * LICENSE:        Apache 2.0                   *
 ***********************************************/
'use strict';

var app = angular.module('facilitation');

app.controller('instanceCtrl', function (LabelsService, $scope, EventsService, $routeParams, $http, socket, Auth, $location) {

    /**
     * Remove the workshop from the user's instances
     * @type {deleteInstance}
     */
    $scope.deleteInstance = deleteInstance;

    /**
     * Display the instance feedback QRCode
     * @type {afficherQrcode}
     */
    $scope.afficherQrcode = afficherQrcode;

    /**
     * Hide/display feedback
     * @type {focusFeedback}
     */
    $scope.focusFeedback= focusFeedback;

    /**
     * Return the label color
     * @type {getLabelColorFct}
     */
    $scope.getLabelColor = getLabelColorFct;

    var currentId = $routeParams.idInstance;
    $scope.workshopInstance = "";

    function updateTimings () {
        var steps = $scope.workshopInstance.steps;
        var timingArray = steps.map(function(step, index) {
            return steps.slice(0, index).reduce(function (accumulateur, currentStep) {
                var tmp = 0;
                if (currentStep.duration.theorical) {
                    tmp = currentStep.duration.theorical;
                }
                return accumulateur + tmp;
            }, 0);
        });
        for(var i = 0; i<timingArray.length; i++) {
            var d = new Date(timingArray[i] * 60000);
            var time = d.toUTCString().split(" ");
            time = time[4].split(":");

            timingArray[i] =  time[0]+":"+time[1];
        }
        $scope.timingArray = timingArray;
    }

    $scope.$watch('workshopInstance.steps', function (newVal, oldVal) {
        if (newVal) {
            updateTimings(newVal)
        }}, true);
    var sortableEle;
    var fixHelper = function(e, ui) {
        ui.children().each(function() {
            $(this).width($(this).width());
        });
        return ui;
    };
    $scope.addStep = function() {
        console.log($scope.workshopInstance.steps);
        $scope.workshopInstance.steps.push({
            description: "nouvelle itération",
            duration: {
                practical: -1,
                theorical: 5
            },
            timing: {
                practical: -1
            },
            title: "nouvelle itération"
        })
    };

    $scope.deleteStep=function (rank) {
        $scope.workshopInstance.steps.splice(rank, 1);
    };

    $scope.updateInstance = function () {
        EventsService.updateWorkshopInstance($scope.workshopInstance._id, $scope.workshopInstance);
        $scope.setEdition("");
    };
    EventsService.getWorkshopInstance(currentId).then(function (dataResponse) {
        $scope.workshopInstance = dataResponse.data.data;
        updateTimings($scope.workshopInstance.steps);
    });
    function getLabelColorFct (label) {
        return LabelsService.getText(label);
    }

    socket.emit('join_room', currentId);

    function deleteInstance() {
        var res = $http.delete('/users/instances/'+currentId);
        res.success(function() {
            $scope.$emit('notify', {
                type: 'success',
                title: 'L\'instance de l\'atelier a bien été supprimée.',
            });
            var url = window.location.href;
            url = url.split("instances");
            window.location.replace(url[0]+'instances');
        });
        res.error(function(data, status, headers, config) {
            $scope.$emit('notify', {
                type: 'error',
                title: 'L\'instance de l\'atelier n\'a pas pu être supprimée.'
            });
        });

    }

    var bool = true;
    function afficherQrcode() {

        if(bool) {
            $('.qrcode-off').addClass('qrcode-on');
            $('.qrcode-on').removeClass('qrcode-off');
            bool = false;
        } else {
            $('.qrcode-on').addClass('qrcode-off');
            $('.qrcode-off').removeClass('qrcode-on');
            bool = true;
        }
    }

    function focusFeedback(type) {
        if($('.feedback-'+type).css("display") == "block") {
            $('#button-'+type).removeClass('active');
            $('.feedback-'+type).css("display", "none");
        } else {
            $('#button-'+type).addClass('active');
            $('.feedback-'+type).css("display", "block");
        }
    }

    $scope.whichEdition = "";
    $scope.setEdition = function (name) {
        if ($scope.whichEdition == name) {
            $scope.whichEdition = "";
        } else {
            $scope.whichEdition = name;
        }
    }
});<commit_msg>[DEV #57] V1 de l'édition d'instances en web<commit_after>/************************************************
 * AUTHOR:         Alexandre Cazala             *
 * CREATION_DATE:  22/11/16                      *
 * EMAIL:          alexandre.cazala@gmail.com   *
 * LICENSE:        Apache 2.0                   *
 ***********************************************/
'use strict';

var app = angular.module('facilitation');

app.controller('instanceCtrl', function (LabelsService, $scope, EventsService, $routeParams, $http, socket, Auth, $location) {

    /**
     * Remove the workshop from the user's instances
     * @type {deleteInstance}
     */
    $scope.deleteInstance = deleteInstance;

    /**
     * Display the instance feedback QRCode
     * @type {afficherQrcode}
     */
    $scope.afficherQrcode = afficherQrcode;

    /**
     * Hide/display feedback
     * @type {focusFeedback}
     */
    $scope.focusFeedback= focusFeedback;

    /**
     * Return the label color
     * @type {getLabelColorFct}
     */
    $scope.getLabelColor = getLabelColorFct;

    var currentId = $routeParams.idInstance;
    $scope.workshopInstance = "";

    function updateTimings () {
        var steps = $scope.workshopInstance.steps;
        var timingArray = steps.map(function(step, index) {
            return steps.slice(0, index).reduce(function (accumulateur, currentStep) {
                var tmp = 0;
                if (currentStep.duration.theorical) {
                    tmp = currentStep.duration.theorical;
                }
                return accumulateur + tmp;
            }, 0);
        });
        for(var i = 0; i<timingArray.length; i++) {
            var d = new Date(timingArray[i] * 60000);
            var time = d.toUTCString().split(" ");
            time = time[4].split(":");

            timingArray[i] =  time[0]+":"+time[1];
        }
        $scope.timingArray = timingArray;
    }

    $scope.$watch('workshopInstance.steps', function (newVal, oldVal) {
        if (newVal) {
            updateTimings(newVal)
        }}, true);
    var sortableEle;
    var fixHelper = function(e, ui) {
        ui.children().each(function() {
            $(this).width($(this).width());
        });
        return ui;
    };
    $scope.addStep = function() {
        console.log($scope.workshopInstance.steps);
        $scope.workshopInstance.steps.push({
            description: "nouvelle itération",
            duration: {
                practical: -1,
                theorical: 5
            },
            timing: {
                practical: -1
            },
            title: "nouvelle itération"
        })
    };

    $scope.deleteStep=function (rank) {
        $scope.workshopInstance.steps.splice(rank, 1);
    };

    $scope.updateInstance = function () {
        EventsService.updateWorkshopInstance($scope.workshopInstance._id, $scope.workshopInstance);
        $scope.setEdition("");
        $scope.$emit('notify', {
            type: 'success',
            title: 'Atelier mis à jour'
        });
    };
    EventsService.getWorkshopInstance(currentId).then(function (dataResponse) {
        $scope.workshopInstance = dataResponse.data.data;
        updateTimings($scope.workshopInstance.steps);
    });
    function getLabelColorFct (label) {
        return LabelsService.getText(label);
    }

    socket.emit('join_room', currentId);

    function deleteInstance() {
        var res = $http.delete('/users/instances/'+currentId);
        res.success(function() {
            $scope.$emit('notify', {
                type: 'success',
                title: 'L\'instance de l\'atelier a bien été supprimée.',
            });
            var url = window.location.href;
            url = url.split("instances");
            window.location.replace(url[0]+'instances');
        });
        res.error(function(data, status, headers, config) {
            $scope.$emit('notify', {
                type: 'error',
                title: 'L\'instance de l\'atelier n\'a pas pu être supprimée.'
            });
        });

    }

    var bool = true;
    function afficherQrcode() {

        if(bool) {
            $('.qrcode-off').addClass('qrcode-on');
            $('.qrcode-on').removeClass('qrcode-off');
            bool = false;
        } else {
            $('.qrcode-on').addClass('qrcode-off');
            $('.qrcode-off').removeClass('qrcode-on');
            bool = true;
        }
    }

    function focusFeedback(type) {
        if($('.feedback-'+type).css("display") == "block") {
            $('#button-'+type).removeClass('active');
            $('.feedback-'+type).css("display", "none");
        } else {
            $('#button-'+type).addClass('active');
            $('.feedback-'+type).css("display", "block");
        }
    }

    $scope.whichEdition = "";
    $scope.setEdition = function (name) {
        if ($scope.whichEdition == name) {
            $scope.whichEdition = "";
        } else {
            $scope.whichEdition = name;
        }
    }
});<|endoftext|>


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

    angular.module('main').controller('ModalInstanceCtrl', function ($uibModalInstance, items, $scope,uiCalendarConfig, $compile,$location) {
        var $ctrl = this;
        $ctrl.items = items;

        $ctrl.ok = function () {
            $uibModalInstance.close($ctrl.selected.item);
        };

        $ctrl.cancel = function () {
            $uibModalInstance.dismiss('cancel');
        };

        /* Email Sending */
        $scope.slider = {
            value: 'E',
            options: {
                stepsArray: '30th Jan,29th Jan,28th Jan'.split(',')
            }
        };

        var domainName = $location.protocol() + "://" + $location.host() + ":" + $location.port();
        var socket = io();// io(domainName, {}).connect();

        $scope.data ={};

        $scope.sendInvite = function () {
            console.log($scope.data);
            socket.emit("sendEmail", $scope.data);
        };

        socket.on("emailSent", function (data) {
            alert(data.success);
        });

        /* Email Sending */

        /* Events Listing */

        var date = new Date();
        var d = date.getDate();
        var m = date.getMonth();
        var y = date.getFullYear();

        $scope.changeTo = 'Hungarian';

        /* event source that contains custom events on the scope */
        $scope.events = [
            {title: 'Reception',start: new Date(2017, 0, 29, 17, 0),end: new Date(2017, 0, 29, 22, 30),allDay: false,className:['reception'],durationEditable :false
                ,startEditable: false },
            {title: 'Wedding',start: new Date(2017, 0, 30, 8, 0),end: new Date(2017, 0, 30, 22, 30),allDay: false, className:[ 'wedding'],durationEditable :false,startEditable: false},
            {title: 'Reception',start: new Date(2017, 0, 29),allDay: true,className:['reception', 'allday'],durationEditable :false,startEditable: false},
            {title: 'Wedding',start: new Date(2017, 0, 30),allDay: true,className:['wedding', 'allday'],durationEditable :false,startEditable: false}
        ];

        /* alert on eventClick */
        $scope.alertOnEventClick = function( date, jsEvent, view){
            $scope.alertMessage = (date.title + ' was clicked ');
        };

        /* Change View */
        $scope.changeView = function(view,calendar) {
            uiCalendarConfig.calendars[calendar].fullCalendar('changeView',view);
        };
        /* Change View */
        $scope.renderCalender = function(calendar) {
            if(uiCalendarConfig.calendars[calendar]){
                uiCalendarConfig.calendars[calendar].fullCalendar('render');
            }
        };
        /* Render Tooltip */
        $scope.eventRender = function( event, element, view ) {
            element.attr({'tooltip': event.title,
                'tooltip-append-to-body': true});
            $compile(element)($scope);
        };
        /* config object */
        $scope.uiConfig = {
            calendar:{
                header: {
                    left: 'prev,next',
                    center: 'title',
                    right: 'agendaWeek,agendaDay'
                },
                defaultView: 'agendaWeek',
                height: '100%',
                editable: true,
                eventClick: $scope.alertOnEventClick,
                eventRender: $scope.eventRender,
                defaultDate : new Date(2017, 0, 29, 17, 0),
                viewRender: function(currentView){
                    var minDate = new Date(2017, 0, 29, 17, 0),
                        maxDate = new Date(2017, 0, 30, 23, 0);

                    var preBtn = $(".fc-prev-button"),nextBtn = $(".fc-next-button");
                    var title = $('.fc-center h2');
                    if(currentView.name === 'agendaDay' && currentView.start === minDate){
                        title.val('RECEPTION');
                    }
                    else if(currentView.name === 'agendaDay' && currentView.start === maxDate){
                        title.val('WEDDING');
                    }
                    // Past
                    if (minDate >= currentView.start && minDate <= currentView.end) {
                        preBtn.prop('disabled', true);
                        preBtn.addClass('fc-state-disabled');
                    }
                    else {
                        preBtn.removeClass('fc-state-disabled');
                        preBtn.prop('disabled', false);
                    }
                    // Future
                    if (maxDate >= currentView.start && maxDate <= currentView.end) {
                        nextBtn.prop('disabled', true);
                        nextBtn.addClass('fc-state-disabled');
                    } else {
                        nextBtn.removeClass('fc-state-disabled');
                        nextBtn.prop('disabled', false);
                    }
                },
                businessHours: {
                    start:'08:00', /* Current Hour/Minute 24H format */
                    end: '23:00', // 5pm? set to whatever
                    dow: [0,1] // Day of week. If you don't set it, Sat/Sun are gray too
                }
            }
        };

        /* event sources array*/
        $scope.eventSources = [$scope.events];
    });
})();<commit_msg>Socket fix<commit_after>(function () {
    'use strict';

    angular.module('main').controller('ModalInstanceCtrl', function ($uibModalInstance, items, $scope,uiCalendarConfig, $compile,$location) {
        var $ctrl = this;
        $ctrl.items = items;

        $ctrl.ok = function () {
            $uibModalInstance.close($ctrl.selected.item);
        };

        $ctrl.cancel = function () {
            $uibModalInstance.dismiss('cancel');
        };

        /* Email Sending */
        $scope.slider = {
            value: 'E',
            options: {
                stepsArray: '30th Jan,29th Jan,28th Jan'.split(',')
            }
        };

        var domainName = 'ws://' + $location.host() ;
        domainName += $location.port() ?  ":" + $location.port() : '';
        var socket = new io(domainName);// io(domainName, {}).connect();

        $scope.data ={};

        $scope.sendInvite = function () {
            console.log($scope.data);
            socket.emit("sendEmail", $scope.data);
        };

        socket.on("emailSent", function (data) {
            alert(data.success);
        });

        /* Email Sending */

        /* Events Listing */

        var date = new Date();
        var d = date.getDate();
        var m = date.getMonth();
        var y = date.getFullYear();

        $scope.changeTo = 'Hungarian';

        /* event source that contains custom events on the scope */
        $scope.events = [
            {title: 'Reception',start: new Date(2017, 0, 29, 17, 0),end: new Date(2017, 0, 29, 22, 30),allDay: false,className:['reception'],durationEditable :false
                ,startEditable: false },
            {title: 'Wedding',start: new Date(2017, 0, 30, 8, 0),end: new Date(2017, 0, 30, 22, 30),allDay: false, className:[ 'wedding'],durationEditable :false,startEditable: false},
            {title: 'Reception',start: new Date(2017, 0, 29),allDay: true,className:['reception', 'allday'],durationEditable :false,startEditable: false},
            {title: 'Wedding',start: new Date(2017, 0, 30),allDay: true,className:['wedding', 'allday'],durationEditable :false,startEditable: false}
        ];

        /* alert on eventClick */
        $scope.alertOnEventClick = function( date, jsEvent, view){
            $scope.alertMessage = (date.title + ' was clicked ');
        };

        /* Change View */
        $scope.changeView = function(view,calendar) {
            uiCalendarConfig.calendars[calendar].fullCalendar('changeView',view);
        };
        /* Change View */
        $scope.renderCalender = function(calendar) {
            if(uiCalendarConfig.calendars[calendar]){
                uiCalendarConfig.calendars[calendar].fullCalendar('render');
            }
        };
        /* Render Tooltip */
        $scope.eventRender = function( event, element, view ) {
            element.attr({'tooltip': event.title,
                'tooltip-append-to-body': true});
            $compile(element)($scope);
        };
        /* config object */
        $scope.uiConfig = {
            calendar:{
                header: {
                    left: 'prev,next',
                    center: 'title',
                    right: 'agendaWeek,agendaDay'
                },
                defaultView: 'agendaWeek',
                height: '100%',
                editable: true,
                eventClick: $scope.alertOnEventClick,
                eventRender: $scope.eventRender,
                defaultDate : new Date(2017, 0, 29, 17, 0),
                viewRender: function(currentView){
                    var minDate = new Date(2017, 0, 29, 17, 0),
                        maxDate = new Date(2017, 0, 30, 23, 0);

                    var preBtn = $(".fc-prev-button"),nextBtn = $(".fc-next-button");
                    var title = $('.fc-center h2');
                    if(currentView.name === 'agendaDay' && currentView.start === minDate){
                        title.val('RECEPTION');
                    }
                    else if(currentView.name === 'agendaDay' && currentView.start === maxDate){
                        title.val('WEDDING');
                    }
                    // Past
                    if (minDate >= currentView.start && minDate <= currentView.end) {
                        preBtn.prop('disabled', true);
                        preBtn.addClass('fc-state-disabled');
                    }
                    else {
                        preBtn.removeClass('fc-state-disabled');
                        preBtn.prop('disabled', false);
                    }
                    // Future
                    if (maxDate >= currentView.start && maxDate <= currentView.end) {
                        nextBtn.prop('disabled', true);
                        nextBtn.addClass('fc-state-disabled');
                    } else {
                        nextBtn.removeClass('fc-state-disabled');
                        nextBtn.prop('disabled', false);
                    }
                },
                businessHours: {
                    start:'08:00', /* Current Hour/Minute 24H format */
                    end: '23:00', // 5pm? set to whatever
                    dow: [0,1] // Day of week. If you don't set it, Sat/Sun are gray too
                }
            }
        };

        /* event sources array*/
        $scope.eventSources = [$scope.events];
    });
})();<|endoftext|>


<commit_before>function finderRoute(path) {
	return {
		path: path,
		template: 'find',
		onBeforeAction: function() {
			// Allow setting the region in the URL by parameter '?region=Testistan'
			if (this.params.query.region) {
				var region = Regions.findOne({ name: this.params.query.region })
				if (region) Session.set('region', region._id);
			};

			this.next();
		},
		data: function() {
			return this.params;
		},
		onAfterAction: function() {
			var search = this.params.query.search
			if (search) {
				document.title = webpagename + mf('find.windowtitle', {SEARCH: search}, 'Find "{SEARCH}"');
			} else {
				document.title = webpagename + mf('startpage.windowtitle', 'What do you want to learn?');
			}
		}
	};
}

Router.map(function () {
	this.route('find', finderRoute('/find'));
	this.route('home', finderRoute('/'));
});

var hiddenFilters = ['upcomingEvent', 'needsHost', 'needsMentor', 'group', 'categories'];

var updateUrl = function(event, instance) {
	event.preventDefault();

	var filterParams = instance.filter.toParams();
	delete filterParams['region']; // HACK region is kept in the session (for bad reasons)
	var queryString = UrlTools.paramsToQueryString(filterParams);

	var options = {};
	if (queryString.length) {
		options.query = queryString;
	}
	Router.go('find', {}, options);

	return true;
}

Template.find.events({
	'submit': updateUrl,
	'change .search_field': updateUrl,
	'change .filterToggle': function(event, instance) {
		instance.filter.add('upcomingEvent', instance.$('#hasUpcomingEvent').prop('checked'));
		instance.filter.add('needsHost', instance.$('#needsHost').prop('checked'));
		instance.filter.add('needsMentor', instance.$('#needsMentor').prop('checked'));
		instance.filter.done();
		updateUrl(event, instance);
	},

	'keyup .searchInput': _.debounce(function(event, instance) {
		instance.filter.add('search', $('.searchInput').val()).done();
		// we don't updateURL() here, only after the field loses focus
	}, 200),

	'click .-findButton': function(event, instance) {
		instance.filter.add('search', $('.searchInput').val()).done();
		updateURL(event, instance);
	},

	'click .category': function(event, instance) {
		instance.filter.add('categories', ""+this).done();
		updateUrl(event, instance);
		instance.showingFilters.set(true);
		return false;
	},

	'click .removeCategoryFilter': function(event, instance) {
		instance.filter.remove('categories', ''+this).done();
		updateUrl(event, instance);
		return false;
	},

	'click .show_subcategories': function(e, instance) {
		$(".subcategory" + "." + this).toggle(0);
		e.stopPropagation(); //makes dropdown menu stay open
	},

	'click .group': function(event, instance) {
		instance.filter.add('group', ""+this).done();
		updateUrl(event, instance);
		if (!instance.showingFilters.get()) instance.showingFilters.set(true);
		window.scrollTo(0, 0);
		return false;
	},

	'click .removeGroupFilter': function(event, instance) {
		instance.filter.remove('group', ''+this._id).done();
		updateUrl(event, instance);
		return false;
	},

	'click .filter-toggle-btn': function(event, instance) {
		var showingFilters = !instance.showingFilters.get();
		instance.showingFilters.set(showingFilters);

		if (!showingFilters) {
			for (i in hiddenFilters) instance.filter.disable(hiddenFilters[i]);
			instance.filter.done();
			updateUrl(event, instance);
		}
	}
});

Template.find.helpers({
	'search': function() {
		return Template.instance().filter.get('search');
	},

	'showingFilters': function() {
		return Template.instance().showingFilters.get();
	},

	'toggleChecked': function(name) {
		return Template.instance().filter.get(name) ? 'checked' : '';
	},

	'newCourse': function() {
		var instance = Template.instance();
		var course = courseTemplate();
		course.name = instance.filter.get('search');
		return course;
	},

	'categories': function() {
		return Template.instance().filter.get('categories');
	},

	'group': function() {
		var groupId = Template.instance().filter.get('group');
		if (!groupId) return false;
		return groupId;
	},

	'availableCategories': function() {
		return Object.keys(categories);
	},

	'availableSubcategories': function(category) {
		return categories[category];
	},

	'availableGroups': function(group) {
		return groups[group];
	},

	'results': function() {
		var filterQuery = Template.instance().filter.toQuery();

		return coursesFind(filterQuery, 36);
	},

	'eventResults': function() {
		var filterQuery = Template.instance().filter.toQuery();
		filterQuery.standalone = true;
		filterQuery.after = minuteTime.get();
		return eventsFind(filterQuery, 10);
	},

	'proposeNewBlurb': function() {
		var instance = Template.instance();
		var filter = instance.filter.toParams();
		return !instance.showingFilters.get() && filter.search;
	},

	'ready': function() {
		return Template.instance().coursesReady.get();
	}
});

Template.find.onCreated(function() {
	var instance = this;

	instance.showingFilters = new ReactiveVar(false);
	instance.coursesReady = new ReactiveVar(false); // Latch

	var filter = Filtering(CoursePredicates);
	instance.filter = filter;

	// Read URL state
	instance.autorun(function() {
		var data = Template.currentData();
		var query = data.query || {};

		filter
			.clear()
			.add('region', Session.get('region'))
			.read(query)
			.done();
	});

	// When there are filters set, show the filtering pane
	for (name in filter.toParams()) {
		if (hiddenFilters.indexOf(name) > -1) {
			instance.showingFilters.set(true);
		}
	}

	// Keep old subscriptions around until the new ones are ready
	// This avoids courses blinking out and back when we renew the subscriptions
	// Can't wait for sub manager because we want the courses without future events to disappear
	// as soon as that filter comes into effect. See above.
	var courseSub = false;
	var oldSubs = [];
	var courseSubReady = function() {
		instance.coursesReady.set(true);
		_.each(oldSubs, function(sub) { sub.stop(); });
		oldSubs = [];
	}

	// Update whenever filter changes
	instance.autorun(function() {
		var filterQuery = filter.toQuery();
		if (courseSub) oldSubs.push(courseSub);
		courseSub = instance.subscribe('coursesFind', filterQuery, 36, courseSubReady);
	});

	// The event display reacts to changes in time as well
	instance.autorun(function() {
		var filterQuery = filter.toQuery();

		// Here we show events only when they're not attached to a course
		filterQuery.standalone = true;
		filterQuery.after = minuteTime.get();
		subs.subscribe('eventsFind', filterQuery, 10);
	});
});

Template.find.onRendered(function() {
	var currentPath = Router.current().route.path(this)
	$('a[href!="' + currentPath + '"].nav_link').removeClass('active');
	$('a[href="/"].nav_link').addClass('active');
	// this.$('#find').focus();    //-> conflict with opening keyboard on mobile
});
<commit_msg>streamline course subscriptions<commit_after>function finderRoute(path) {
	return {
		path: path,
		template: 'find',
		onBeforeAction: function() {
			// Allow setting the region in the URL by parameter '?region=Testistan'
			if (this.params.query.region) {
				var region = Regions.findOne({ name: this.params.query.region })
				if (region) Session.set('region', region._id);
			};

			this.next();
		},
		data: function() {
			return this.params;
		},
		onAfterAction: function() {
			var search = this.params.query.search
			if (search) {
				document.title = webpagename + mf('find.windowtitle', {SEARCH: search}, 'Find "{SEARCH}"');
			} else {
				document.title = webpagename + mf('startpage.windowtitle', 'What do you want to learn?');
			}
		}
	};
}

Router.map(function () {
	this.route('find', finderRoute('/find'));
	this.route('home', finderRoute('/'));
});

var hiddenFilters = ['upcomingEvent', 'needsHost', 'needsMentor', 'group', 'categories'];

var updateUrl = function(event, instance) {
	event.preventDefault();

	var filterParams = instance.filter.toParams();
	delete filterParams['region']; // HACK region is kept in the session (for bad reasons)
	var queryString = UrlTools.paramsToQueryString(filterParams);

	var options = {};
	if (queryString.length) {
		options.query = queryString;
	}
	Router.go('find', {}, options);

	return true;
}

Template.find.events({
	'submit': updateUrl,
	'change .search_field': updateUrl,
	'change .filterToggle': function(event, instance) {
		instance.filter.add('upcomingEvent', instance.$('#hasUpcomingEvent').prop('checked'));
		instance.filter.add('needsHost', instance.$('#needsHost').prop('checked'));
		instance.filter.add('needsMentor', instance.$('#needsMentor').prop('checked'));
		instance.filter.done();
		updateUrl(event, instance);
	},

	'keyup .searchInput': _.debounce(function(event, instance) {
		instance.filter.add('search', $('.searchInput').val()).done();
		// we don't updateURL() here, only after the field loses focus
	}, 200),

	'click .-findButton': function(event, instance) {
		instance.filter.add('search', $('.searchInput').val()).done();
		updateURL(event, instance);
	},

	'click .category': function(event, instance) {
		instance.filter.add('categories', ""+this).done();
		updateUrl(event, instance);
		instance.showingFilters.set(true);
		return false;
	},

	'click .removeCategoryFilter': function(event, instance) {
		instance.filter.remove('categories', ''+this).done();
		updateUrl(event, instance);
		return false;
	},

	'click .show_subcategories': function(e, instance) {
		$(".subcategory" + "." + this).toggle(0);
		e.stopPropagation(); //makes dropdown menu stay open
	},

	'click .group': function(event, instance) {
		instance.filter.add('group', ""+this).done();
		updateUrl(event, instance);
		if (!instance.showingFilters.get()) instance.showingFilters.set(true);
		window.scrollTo(0, 0);
		return false;
	},

	'click .removeGroupFilter': function(event, instance) {
		instance.filter.remove('group', ''+this._id).done();
		updateUrl(event, instance);
		return false;
	},

	'click .filter-toggle-btn': function(event, instance) {
		var showingFilters = !instance.showingFilters.get();
		instance.showingFilters.set(showingFilters);

		if (!showingFilters) {
			for (i in hiddenFilters) instance.filter.disable(hiddenFilters[i]);
			instance.filter.done();
			updateUrl(event, instance);
		}
	}
});

Template.find.helpers({
	'search': function() {
		return Template.instance().filter.get('search');
	},

	'showingFilters': function() {
		return Template.instance().showingFilters.get();
	},

	'toggleChecked': function(name) {
		return Template.instance().filter.get(name) ? 'checked' : '';
	},

	'newCourse': function() {
		var instance = Template.instance();
		var course = courseTemplate();
		course.name = instance.filter.get('search');
		return course;
	},

	'categories': function() {
		return Template.instance().filter.get('categories');
	},

	'group': function() {
		var groupId = Template.instance().filter.get('group');
		if (!groupId) return false;
		return groupId;
	},

	'availableCategories': function() {
		return Object.keys(categories);
	},

	'availableSubcategories': function(category) {
		return categories[category];
	},

	'availableGroups': function(group) {
		return groups[group];
	},

	'results': function() {
		var filterQuery = Template.instance().filter.toQuery();

		return coursesFind(filterQuery, 36);
	},

	'eventResults': function() {
		var filterQuery = Template.instance().filter.toQuery();
		filterQuery.standalone = true;
		filterQuery.after = minuteTime.get();
		return eventsFind(filterQuery, 10);
	},

	'proposeNewBlurb': function() {
		var instance = Template.instance();
		var filter = instance.filter.toParams();
		return !instance.showingFilters.get() && filter.search;
	},

	'ready': function() {
		return Template.instance().coursesReady.get();
	}
});

Template.find.onCreated(function() {
	var instance = this;

	instance.showingFilters = new ReactiveVar(false);
	instance.coursesReady = new ReactiveVar(false); // Latch

	var filter = Filtering(CoursePredicates);
	instance.filter = filter;

	// Read URL state
	instance.autorun(function() {
		var data = Template.currentData();
		var query = data.query || {};

		filter
			.clear()
			.add('region', Session.get('region'))
			.read(query)
			.done();
	});

	// When there are filters set, show the filtering pane
	for (name in filter.toParams()) {
		if (hiddenFilters.indexOf(name) > -1) {
			instance.showingFilters.set(true);
		}
	}

	// Update whenever filter changes
	instance.autorun(function() {
		var filterQuery = filter.toQuery();
		subs.subscribe('coursesFind', filterQuery, 36, function() {
			instance.coursesReady.set(true);
		});
	});

	// The event display reacts to changes in time as well
	instance.autorun(function() {
		var filterQuery = filter.toQuery();

		// Here we show events only when they're not attached to a course
		filterQuery.standalone = true;
		filterQuery.after = minuteTime.get();
		subs.subscribe('eventsFind', filterQuery, 10);
	});
});

Template.find.onRendered(function() {
	var currentPath = Router.current().route.path(this)
	$('a[href!="' + currentPath + '"].nav_link').removeClass('active');
	$('a[href="/"].nav_link').addClass('active');
	// this.$('#find').focus();    //-> conflict with opening keyboard on mobile
});
<|endoftext|>


<commit_before>/*

Based on drag-and-drop sample code by Luke Dingle

http://www.lukedingle.com/javascript/sortable-table-rows-with-jquery-draggable-rows/

(C) Stepan Riha, 2009
*/

jQuery(document).ready(function ($) {

	// Workaround for issue when using jQuery UI < 1.8.22 with jQuery 1.8
	// Trac 1.1.1dev @r11479 provides jQuery UI 1.8.21 and jQuery 1.8.2
	// http://bugs.jquery.com/ticket/11921
	if(!$.isFunction($.curCSS))
		$.curCSS = $.css;

	var mouseY, lastY = 0;

	//IE Doesn't stop selecting text when mousedown returns false we need to check
	// That onselectstart exists and return false if it does
	var hasOnSelectStart = document.onselectstart !== undefined;

	// Indicates whether we're dragging a row
	var dragging = false, unsaved_changes = false;

	// Disable the Apply changes button until there is a change
	$('#enumtable div input[name="apply"]').attr('disabled', true)
	$('#enumtable tbody tr input[name="default"]').click(function(){
		$('#enumtable div input[name="apply"]').attr('disabled', false)
	});

	// Insert Revert changes button after the Apply changes button
	$('<input type="submit" name="revert" value="Revert changes" disabled="disabled"/>')
		.insertAfter('#enumtable div input[name="apply"]');

	// Prompt with a dialog if leaving the page with unsaved changes to the list
	var support_beforeunload = jQuery.event.special.beforeunload !== undefined;
	var beforeunload = function() {
		if(unsaved_changes)
			return "You have unsaved changes to the order of the list. Your " +
				"changes will be lost if you Leave this Page before " +
				"selecting  Apply changes."
	};
	if (support_beforeunload) {
		$(window).bind('beforeunload', beforeunload);
	} else {
		// Workaround unsupported "beforeunload" event when jQuery < 1.4,
		// e.g. Trac 0.11.x provides jQuery 1.2.x
		window.onbeforeunload = beforeunload;
		$(window).bind('unload', function() { window.onbeforeunload = null; });
	}

	// Don't prompt with a dialog if the Apply or Revert changes button is pressed
	var button_pressed
	$('#enumtable div.buttons input').click(function(){
		button_pressed = $(this).attr('name');
	})

	$('#enumtable').submit(function(){
		if(button_pressed === 'apply' || button_pressed === 'revert') {
			if (support_beforeunload)
				$(window).unbind('beforeunload');
			else
				window.onbeforeunload = null;
		}
		if(button_pressed === 'revert'){
			// Send GET request instead of POST
			location = location;
			return false;
		}
	});

	// This keep track of current vertical coordinates
	$().mousemove(function(e) {
		mouseY = e.pageY;
	});

	// Suppress behavior on elements that should capture mouse
	$('#enumlist input, #enumlist a, #enumlist select').mousedown(function (e) {
		// Suppress drag behavior for controls and links
		if(!dragging)
			mouseY = 0;
	});

	// Begin drag
	$('#enumlist tbody tr').mousedown(function (e) {
		// Suppress drag on elements that should capture mouse
	 	if(mouseY == 0)
	 		return;

	 	dragging = true;

	 	// Remember starting mouseY
		lastY = mouseY;

		var tr = $(this);

		// This is just for flashiness. It fades the TR element out to an opacity of 0.2 while it is being moved.
		tr.find('td').fadeTo('fast', 0.2);

		// jQuery has a fantastic function called mouseenter() which fires when the mouse enters
		// This code fires a function each time the mouse enters over any TR inside the tbody -- except $(this) one
		$('tr', tr.parent() ).not(tr).bind('mouseenter', function(e){
			// Move row based on direction
			if (mouseY > lastY) {
				$(this).after(tr);
				// Store the current location of the mouse for next time a mouseenter event triggers
				lastY = e.pageY + 1;
			} else {
				$(this).before(tr);
				// Store the current location of the mouse for next time a mouseenter event triggers
				lastY = e.pageY - 1;
			}
		});

		// When mouse is released, unhook events and update values
		$('body').mouseup(function () {
			//Fade the TR element back to full opacity
			tr.find('td').fadeTo('fast', 1);
			// Remove the mouseenter events from the tbody so that the TR element stops being moved
			$('tr', tr.parent()).unbind('mouseenter');
			// Remove this mouseup function until next time
			$('body').unbind('mouseup');

			// Make text selectable for IE again with
			// The workaround for IE based browers
			if (hasOnSelectStart)
				$(document).unbind('selectstart');

			updateValues(tr);

			dragging = false;
		});

	// Preventing the default action and returning false will Stop any text in the table from being
	// highlighted (this can cause problems when dragging elements)

	e.preventDefault();

	// The workaround for IE browsers
	if (hasOnSelectStart)
			$(document).bind('selectstart', function () { return false; });
		return false;

	}).css('cursor', 'move');

	// When user changes a select value, reorder rows
	$('#enumlist select').change(function (e) {
		// Move ($this) in the right position
		var tr = $(this).parents('tr')[0];
		var val = $(this).val();
		if(val == 1) {
			$('#enumlist tbody').prepend(tr);
		} else {
			var rowIndex = 0;
			var sib = tr.previousSibling;
			while(sib != null) { rowIndex++; sib = sib.previousSibling; }
			var newIndex = val > rowIndex ? val - 1 : val - 2;
			var trBefore = $($('#enumlist tbody tr')[newIndex]);
			trBefore.after(tr);
		}
		updateValues(tr);
	});

	// Set select values based on the row they're in and highlight those that have changed
	function updateValues (tr) {
		var position = 1;
		var trSelect = $('select', $(tr))[0];
		$('#enumlist tbody tr select').each(function () {
			var select = $(this);
			if(select.val() != position) {
				select.val(position);
				select.not(trSelect).parent().effect('highlight', {}, 1000);
				unsaved_changes = true;
			}
			position += 1;
		});

		$(tr).effect('highlight', { }, 2000);
		if(unsaved_changes)
		{
			$('#enumtable div input[name="revert"]').attr('disabled', false);
			$('#enumtable div input[name="apply"]').attr('disabled', false);
		}
	}

});
<commit_msg>Refs #10693: Workaround for `select.val()` not working on IE8 with Trac 0.11.7. This appears to be due to the `option` elements not having a `value`, an issue that was fixed in later versions of jQuery. Patch by Jun Omae (jun66j5).<commit_after>/*

Based on drag-and-drop sample code by Luke Dingle

http://www.lukedingle.com/javascript/sortable-table-rows-with-jquery-draggable-rows/

(C) Stepan Riha, 2009
*/

jQuery(document).ready(function ($) {

	// Workaround for issue when using jQuery UI < 1.8.22 with jQuery 1.8
	// Trac 1.1.1dev @r11479 provides jQuery UI 1.8.21 and jQuery 1.8.2
	// http://bugs.jquery.com/ticket/11921
	if(!$.isFunction($.curCSS))
		$.curCSS = $.css;

	var mouseY, lastY = 0;

	//IE Doesn't stop selecting text when mousedown returns false we need to check
	// That onselectstart exists and return false if it does
	var hasOnSelectStart = document.onselectstart !== undefined;

	// Indicates whether we're dragging a row
	var dragging = false, unsaved_changes = false;

	// Disable the Apply changes button until there is a change
	$('#enumtable div input[name="apply"]').attr('disabled', true)
	$('#enumtable tbody tr input[name="default"]').click(function(){
		$('#enumtable div input[name="apply"]').attr('disabled', false)
	});

	// Insert Revert changes button after the Apply changes button
	$('<input type="submit" name="revert" value="Revert changes" disabled="disabled"/>')
		.insertAfter('#enumtable div input[name="apply"]');

	// Prompt with a dialog if leaving the page with unsaved changes to the list
	var support_beforeunload = jQuery.event.special.beforeunload !== undefined;
	var beforeunload = function() {
		if(unsaved_changes)
			return "You have unsaved changes to the order of the list. Your " +
				"changes will be lost if you Leave this Page before " +
				"selecting  Apply changes."
	};
	if (support_beforeunload) {
		$(window).bind('beforeunload', beforeunload);
	} else {
		// Workaround unsupported "beforeunload" event when jQuery < 1.4,
		// e.g. Trac 0.11.x provides jQuery 1.2.x
		window.onbeforeunload = beforeunload;
		$(window).bind('unload', function() { window.onbeforeunload = null; });
	}

	// Don't prompt with a dialog if the Apply or Revert changes button is pressed
	var button_pressed
	$('#enumtable div.buttons input').click(function(){
		button_pressed = $(this).attr('name');
	})

	$('#enumtable').submit(function(){
		if(button_pressed === 'apply' || button_pressed === 'revert') {
			if (support_beforeunload)
				$(window).unbind('beforeunload');
			else
				window.onbeforeunload = null;
		}
		if(button_pressed === 'revert'){
			// Send GET request instead of POST
			location = location;
			return false;
		}
	});

	// This keep track of current vertical coordinates
	$().mousemove(function(e) {
		mouseY = e.pageY;
	});

	// Suppress behavior on elements that should capture mouse
	$('#enumlist input, #enumlist a, #enumlist select').mousedown(function (e) {
		// Suppress drag behavior for controls and links
		if(!dragging)
			mouseY = 0;
	});

	// Begin drag
	$('#enumlist tbody tr').mousedown(function (e) {
		// Suppress drag on elements that should capture mouse
		if(mouseY == 0)
			return;

		dragging = true;

		// Remember starting mouseY
		lastY = mouseY;

		var tr = $(this);

		// This is just for flashiness. It fades the TR element out to an opacity of 0.2 while it is being moved.
		tr.find('td').fadeTo('fast', 0.2);

		// jQuery has a fantastic function called mouseenter() which fires when the mouse enters
		// This code fires a function each time the mouse enters over any TR inside the tbody -- except $(this) one
		$('tr', tr.parent() ).not(tr).bind('mouseenter', function(e){
			// Move row based on direction
			if (mouseY > lastY) {
				$(this).after(tr);
				// Store the current location of the mouse for next time a mouseenter event triggers
				lastY = e.pageY + 1;
			} else {
				$(this).before(tr);
				// Store the current location of the mouse for next time a mouseenter event triggers
				lastY = e.pageY - 1;
			}
		});

		// When mouse is released, unhook events and update values
		$('body').mouseup(function () {
			//Fade the TR element back to full opacity
			tr.find('td').fadeTo('fast', 1);
			// Remove the mouseenter events from the tbody so that the TR element stops being moved
			$('tr', tr.parent()).unbind('mouseenter');
			// Remove this mouseup function until next time
			$('body').unbind('mouseup');

			// Make text selectable for IE again with
			// The workaround for IE based browers
			if (hasOnSelectStart)
				$(document).unbind('selectstart');

			updateValues(tr);

			dragging = false;
		});

	// Preventing the default action and returning false will Stop any text in the table from being
	// highlighted (this can cause problems when dragging elements)

	e.preventDefault();

	// The workaround for IE browsers
	if (hasOnSelectStart)
			$(document).bind('selectstart', function () { return false; });
		return false;

	}).css('cursor', 'move');

	// When user changes a select value, reorder rows
	$('#enumlist select').change(function (e) {
		// Move ($this) in the right position
		var tr = $(this).parents('tr')[0];
        // select.val() does not work on IE8 with Trac 0.11.7 (#10693)
		var val = $(':selected', this).val();
		if(val == 1) {
			$('#enumlist tbody').prepend(tr);
		} else {
			var rowIndex = 0;
			var sib = tr.previousSibling;
			while(sib != null) { rowIndex++; sib = sib.previousSibling; }
			var newIndex = val > rowIndex ? val - 1 : val - 2;
			var trBefore = $($('#enumlist tbody tr')[newIndex]);
			trBefore.after(tr);
		}
		updateValues(tr);
	});

	// Set select values based on the row they're in and highlight those that have changed
	function updateValues (tr) {
		var position = 1;
		var trSelect = $('select', $(tr))[0];
		$('#enumlist tbody tr select').each(function () {
			var select = $(this);
            // select.val() does not work on IE8 with Trac 0.11.7 (#10693)
			if($(':selected', select).val() != position) {
				select.val(position);
				select.not(trSelect).parent().effect('highlight', {}, 1000);
				unsaved_changes = true;
			}
			position += 1;
		});

		$(tr).effect('highlight', { }, 2000);
		if(unsaved_changes)
		{
			$('#enumtable div input[name="revert"]').attr('disabled', false);
			$('#enumtable div input[name="apply"]').attr('disabled', false);
		}
	}

});
<|endoftext|>


<commit_before>import * as Util from './Util'

var canUseProxy = typeof Proxy === 'function';

var OArray = function (arr, option) {
    if (!Util.isArray(arr)) arr = [];
    if (!Util.isObject(option)) option = {};

    var _this = this;

    var afterInsertElement = option.afterInsertElement || function () {};
    var beforeDeleteElement = option.beforeDeleteElement || function () {};
    var elementEquality = option.elementEquality || function (v1, v2) {
        return v1 === v2;
    };

    Util.each(arr, function (v, i) {
        _this.assignElement(i, v);
    });

    var len = arr.length;
    Object.defineProperty(this, '__offset', {
        value: 0,
        enumerable: false
    });
    Object.defineProperty(this, '__length', {
        get: function () {
            return len;
        },
        set: function (v) {
            len = v;
            return len;
        }
    });
    Object.defineProperty(this, 'length', {
        get: function () {
            return len;
        },
        set: function (v) {
            if (!Util.isNumber(v)) return false;
            var n = parseInt(v);
            if (isNaN(n) || n < 0) return false;
            if (n > len) {
                for (var i = len; i < n; i++) {
                    _this.assignElement(i, undefined);
                }
            } else if (n < len) {
                for (var i = len - 1; i >= n; i--) {
                    _this.deleteElement(i);
                }
            }
            len = n;
            return len;
        },
        enumerable: false
    });
};

OArray.prototype = [];
OArray.prototype.constructor = OArray;

OArray.prototype.assignElement = function (i, v) {
    if (this.hasOwnProperty(i + this.__offset)) {
        this[i + this.__offset] = v;
    } else {
        Object.defineProperty(this, i + this.__offset, {
            get: function () {
                return v;
            },
            set: function (_v) {},
            configurable: true,
            enumerable: true
        });
    }
};

OArray.prototype.deleteElement = function (i) {
    if (!this.hasOwnProperty(i + this.__offset)) return false;
    delete this[i + this.__offset];
};

OArray.prototype.push = function (v) {
    this.assignElement(this.__length, v);
    this.__length++;
    return this.__length;
};

OArray.prototype.pop = function (v) {
    this.deleteElement(this.__length - 1);
    this.__length--;
    return this.__length;
};

OArray.prototype.unshift = function (v) {
    this.__offset--;
    this.assignElement(0, v);
    this.__length++;
    return this.__length;
};

OArray.prototype.shift = function (v) {
    this.deleteElement(0);
    this.__offset++;
    this.__length--;
    return this.__length;
};

OArray.prototype.splice = function (startIndex, howManyToDelete, itemToInsert) {
    if (!Util.isNumber(startIndex) || !Util.isNumber(howManyToDelete)) return [];
    if (startIndex < 0 || startIndex >= this.__length) return [];
    if (howManyToDelete < 0) howManyToDelete = 0;
    if (howManyToDelete + startIndex > this.__length) howManyToDelete = this.__length - startIndex;
    var r = [];
    for (var i = startIndex; i < startIndex + howManyToDelete; i++) {
        r.push(Util.clone(this[i + this.__offset]));
    }

    var itemsToInsert = Array.prototype.slice.call(arguments, 2);
    // TODO: delete and insert

    return r;
};

OArray.prototype.slice = function (startIndex, endIndex) {
    if (!Util.isNumber(startIndex)) return [];
    if (!Util.isNumber(endIndex)) endIndex = this.__length;
    if (startIndex < 0 || endIndex > this.__length || startIndex >= endIndex) return [];
    var r = [];
    for (var i = startIndex; i < endIndex; i++) {
        r.push(this[i + this.__offset]);
    }
    return r;
};

OArray.prototype.concat = function (arr) {};
OArray.prototype.reverse = function () {};
OArray.prototype.sort = function (sortBy) {};
OArray.prototype.forEach = function (fn) {};
OArray.prototype.filter = function (fn) {};
OArray.prototype.map = function (fn) {};
OArray.prototype.reduce = function (fn, re) {};
OArray.prototype.indexOf = function (v) {};
OArray.prototype.find = function (v) {};
OArray.prototype.findIndex = function (v) {};
OArray.prototype.fill = function (v) {};
OArray.prototype.join = function (v) {};

export default OArray
<commit_msg>fix: observable array.<commit_after>import * as Util from './Util'

var canUseProxy = typeof Proxy === 'function';

var OArray = function (arr, option) {
    if (!Util.isArray(arr)) arr = [];
    if (!Util.isObject(option)) option = {};

    Object.defineProperty(this, 'afterInsertElement', {
        value: option.afterInsertElement || function (target, p) {}
    });
    Object.defineProperty(this, 'beforeDeleteElement', {
        value: option.beforeDeleteElement || function (target, p) {}
    });
    Object.defineProperty(this, 'elementEquality', {
        value: option.elementEquality || function (v1, v2) { return v1 === v2; }
    });

    var len = 0;
    Object.defineProperty(this, '__length', {
        get: function () {
            return len;
        },
        set: function (v) {
            return len = v;
        }
    });
    Object.defineProperty(this, 'length', {
        get: function () {
            return this.__length;
        },
        set: function (v) {
            if (!Util.isNumber(v)) return false;
            var n = parseInt(v);
            if (isNaN(n) || n < 0) return false;
            if (n > this.__length) {
                for (var i = this.__length; i < n; i++)
                    this.push(undefined);
            } else if (n < this.__length) {
                for (var i = this.__length - 1; i >= n; i--)
                    this.pop();
            }
            return this.__length;
        }
    });

    var extendable = false;
    Object.defineProperty(this, '__extendable', {
        get: function () {
            return extendable;
        },
        set: function (v) {
            return extendable = !!v;
        }
    });

    var _this = this;
    this.__extendable = true;
    Util.each(arr, function (v, i) {
        _this.push(v);
    });
    this.__extendable = false;
};

OArray.prototype = [];
OArray.prototype.constructor = OArray;

OArray.prototype.assignElement = function (i, val) {
    if (!Util.isNumber(i)) return false;
    if (this.hasOwnProperty(i)) {
        this[i] = val;
    } else if (this.__extendable) {
        var v = val;
        Object.defineProperty(this, i, {
            get: function () {
                return v;
            },
            set: function (_v) {
                return v = _v;
            },
            configurable: true,
            enumerable: true
        });
    } else {
        return false;
    }
};

OArray.prototype.deleteElement = function (i) {
    if (!Util.isNumber(i) || !this.hasOwnProperty(i)) return false;
    delete this[i];
    return true;
};

OArray.prototype.push = function (v) {
    this.__extendable = true;
    this.assignElement(this.__length, v);
    this.__extendable = false;
    this.__length++;
    return this.__length;
};

OArray.prototype.pop = function (v) {
    if (this.deleteElement(this.__length - 1)) this.__length -= 1;
    return this.__length;
};

OArray.prototype.offset = function (startIndex, howManyElements, howManySteps, notClean) {
    if (!Util.isNumber(startIndex) || startIndex < 0 || startIndex >= this.__length) return false;
    if (!Util.isNumber(howManySteps) || howManySteps === 0) return false;
    if (!Util.isNumber(howManyElements) || howManyElements <= 0
        || howManyElements + startIndex > this.__length) howManyElements = this.__length - startIndex;
    this.__extendable = true;
    if (howManySteps > 0) { /* to right */
        for (var i = startIndex + howManyElements - 1 + howManySteps; i >= startIndex + howManySteps; i--) {
            this.assignElement(i, this[i - howManySteps]);
        }
        if (!notClean) {
            for (var i = startIndex; i < startIndex + howManySteps; i++) {
                this.assignElement(i, undefined);
            }
        }
        if (startIndex + howManyElements + howManySteps > this.__length) {
            this.__length = startIndex + howManyElements + howManySteps;
        }
    } else { /* to left */
        for (var i = Math.max(0, startIndex + howManySteps); i < startIndex + howManyElements + howManySteps; i++) {
            this.assignElement(i, this[i - howManySteps]);
        }
        for (var i = Math.max(0, startIndex + howManyElements + howManySteps);
            i < startIndex + howManyElements; i++) {
            this.assignElement(i, undefined);
        }
        if (startIndex + howManyElements >= this.__length) {
            this.length = Math.max(0, startIndex + howManyElements + howManySteps);
        }
    }
    this.__extendable = false;
};

OArray.prototype.unshift = function (v) {
    this.offset(0, null, 1);
    this.__extendable = true;
    this.assignElement(0, v);
    this.__extendable = false;
    return this.__length;
};

OArray.prototype.shift = function (v) {
    this.offset(0, null, -1);
    return this.__length;
};

OArray.prototype.toArray = function (notClone) {
    var r = [];
    this.forEach(function (v, i) {
        r.push(notClone ? v : Util.clone(v));
    });
    return r;
};

OArray.prototype.splice = function (startIndex, howManyToDelete, itemToInsert) {
    if (!Util.isNumber(startIndex)) return [];
    if (startIndex < 0 || startIndex >= this.__length) return [];
    if (!Util.isNumber(howManyToDelete) || howManyToDelete < 0) howManyToDelete = 0;
    if (howManyToDelete + startIndex > this.__length) howManyToDelete = this.__length - startIndex;

    var r = [];
    for (var i = startIndex; i < startIndex + howManyToDelete; i++) {
        r.push(Util.clone(this[i]));
    }

    var itemsToInsert = Array.prototype.slice.call(arguments, 2);
    var howManyToInsert = itemsToInsert.length;

    this.__extendable = true;
    if (howManyToDelete >= howManyToInsert) {
        if (startIndex + howManyToDelete === this.__length) {
            for (var i = 0; i < howManyToDelete - howManyToInsert; i++) {
                this.pop();
            }
        } else {
            this.offset(startIndex + howManyToDelete, null, howManyToInsert - howManyToDelete);
        }
        for (var i = startIndex; i < startIndex + howManyToInsert; i++) {
            this.assignElement(i, itemsToInsert[i - startIndex]);
        }
    } else if (howManyToDelete < howManyToInsert) {
        if (startIndex + howManyToDelete === this.__length) {
            this.__length = startIndex + howManyToInsert;
        } else {
            this.offset(startIndex + howManyToDelete, null, howManyToInsert - howManyToDelete, true);
        }
        for (var i = startIndex; i < startIndex + howManyToInsert; i++) {
            this.assignElement(i, itemsToInsert[i - startIndex]);
        }
    }
    this.__extendable = false;

    return r;
};

OArray.prototype.slice = function (startIndex, endIndex, notClone) {
    if (!Util.isNumber(startIndex)) return [];
    if (!Util.isNumber(endIndex)) endIndex = this.__length;
    if (startIndex < 0 || endIndex > this.__length || startIndex >= endIndex) return [];
    var r = [];
    for (var i = startIndex; i < endIndex; i++) {
        r.push(notClone ? this[i] : Util.clone(this[i]));
    }
    return r;
};

OArray.prototype.concat = function () {
    return Array.prototype.concat.apply(this.toArray(), arguments);
};

OArray.prototype.reverse = function () {
    var m = Math.floor((this.__length - 1) / 2);
    for (var i = 0; i <= m; i++) {
        var j = this.__length - 1 - i;
        var vi = Util.clone(this[i]);
        var vj = Util.clone(this[j]);
        this[i] = vj;
        this[j] = vi;
    }
};

OArray.prototype.sort = function (sortBy) {};

OArray.prototype.forEach = function (fn) {
    for (var i = 0; i < this.__length; i++) {
        var r = fn(this[i], i);
        if (r === false) break;
    }
};

OArray.prototype.filter = function () {
    return Array.prototype.filter.apply(this.toArray(), arguments);
};

OArray.prototype.map = function () {
    return Array.prototype.map.apply(this.toArray(), arguments);
};

OArray.prototype.reduce = function () {
    return Array.prototype.reduce.apply(this.toArray(), arguments);
};

OArray.prototype.indexOf = function (v) {
    // TODO: optimization
    return Array.prototype.indexOf.apply(this.toArray(), arguments);
};

OArray.prototype.find = function (v) {
    // TODO: optimization
    return Array.prototype.find.apply(this.toArray(), arguments);
};

OArray.prototype.findIndex = function (v) {
    // TODO: optimization
    return Array.prototype.findIndex.apply(this.toArray(), arguments);
};

OArray.prototype.fill = function (v) {
    this.forEach(function (e, i) {
        this.assignElement(i, v);
    });
};

OArray.prototype.join = function () {
    return Array.prototype.join.apply(this.toArray(), arguments);
};

export default OArray
<|endoftext|>


<commit_before>import React from 'react';
import PropTypes from 'prop-types';
import Relay from 'react-relay';
import DocumentTitle from 'react-document-title';

import Panel from '../../../shared/Panel';
import Button from '../../../shared/Button';
import permissions from '../../../../lib/permissions';

import Row from './row';

class Index extends React.Component {
  static propTypes = {
    pipeline: PropTypes.shape({
      name: PropTypes.string.isRequired,
      schedules: PropTypes.shape({
        edges: PropTypes.arrayOf(
          PropTypes.shape({
            node: PropTypes.shape({
              id: PropTypes.string.isRequired
            }).isRequired
          }).isRequired
        )
      }).isRequired,
      permissions: PropTypes.shape({
        pipelineScheduleCreate: PropTypes.shape({
          allowed: PropTypes.bool.isRequired
        }).isRequired
      }).isRequired
    }).isRequired,
    params: PropTypes.shape({
      organization: PropTypes.string.isRequired,
      pipeline: PropTypes.string.isRequired
    }).isRequired
  };

  render() {
    return (
      <DocumentTitle title={`Schedules · ${this.props.pipeline.name}`}>
        <Panel>
          <Panel.Header>Schedules</Panel.Header>

          <Panel.IntroWithButton>
            Schedules allow you to automatically create builds at regular times.
            {this.renderNewScheduleButton()}
          </Panel.IntroWithButton>
          {this.renderScheduleRows()}
        </Panel>
      </DocumentTitle>
    );
  }

  renderNewScheduleButton() {
    return permissions(this.props.pipeline.permissions).check(
      {
        allowed: "pipelineScheduleCreate",
        render: () => <Button link={`/${this.props.params.organization}/${this.props.params.pipeline}/settings/schedules/new`} theme={"default"} outline={true}>New Schedule</Button>
      }
    );
  }

  renderScheduleRows() {
    if (this.props.pipeline.schedules.edges.length > 0) {
      return this.props.pipeline.schedules.edges.map((edge) => {
        return (
          <Row key={edge.node.id} pipelineSchedule={edge.node} />
        );
      });
    } else {
      return null;
    }
  }
}

export default Relay.createContainer(Index, {
  fragments: {
    pipeline: () => Relay.QL`
      fragment on Pipeline {
        name
        schedules(first: 100) {
          edges {
            node {
              id
              ${Row.getFragment("pipelineSchedule")}
            }
          }
        }
        permissions {
          pipelineScheduleCreate {
            allowed
            code
            message
          }
        }
      }
    `
  }
});
<commit_msg>A nicer Schedules page description<commit_after>import React from 'react';
import PropTypes from 'prop-types';
import Relay from 'react-relay';
import DocumentTitle from 'react-document-title';

import Panel from '../../../shared/Panel';
import Button from '../../../shared/Button';
import permissions from '../../../../lib/permissions';

import Row from './row';

class Index extends React.Component {
  static propTypes = {
    pipeline: PropTypes.shape({
      name: PropTypes.string.isRequired,
      schedules: PropTypes.shape({
        edges: PropTypes.arrayOf(
          PropTypes.shape({
            node: PropTypes.shape({
              id: PropTypes.string.isRequired
            }).isRequired
          }).isRequired
        )
      }).isRequired,
      permissions: PropTypes.shape({
        pipelineScheduleCreate: PropTypes.shape({
          allowed: PropTypes.bool.isRequired
        }).isRequired
      }).isRequired
    }).isRequired,
    params: PropTypes.shape({
      organization: PropTypes.string.isRequired,
      pipeline: PropTypes.string.isRequired
    }).isRequired
  };

  render() {
    return (
      <DocumentTitle title={`Schedules · ${this.props.pipeline.name}`}>
        <Panel>
          <Panel.Header>Schedules</Panel.Header>

          <Panel.IntroWithButton>
            Build schedules automatically create builds at a specified interval.
            {this.renderNewScheduleButton()}
          </Panel.IntroWithButton>
          {this.renderScheduleRows()}
        </Panel>
      </DocumentTitle>
    );
  }

  renderNewScheduleButton() {
    return permissions(this.props.pipeline.permissions).check(
      {
        allowed: "pipelineScheduleCreate",
        render: () => <Button link={`/${this.props.params.organization}/${this.props.params.pipeline}/settings/schedules/new`} theme={"default"} outline={true}>New Schedule</Button>
      }
    );
  }

  renderScheduleRows() {
    if (this.props.pipeline.schedules.edges.length > 0) {
      return this.props.pipeline.schedules.edges.map((edge) => {
        return (
          <Row key={edge.node.id} pipelineSchedule={edge.node} />
        );
      });
    } else {
      return null;
    }
  }
}

export default Relay.createContainer(Index, {
  fragments: {
    pipeline: () => Relay.QL`
      fragment on Pipeline {
        name
        schedules(first: 100) {
          edges {
            node {
              id
              ${Row.getFragment("pipelineSchedule")}
            }
          }
        }
        permissions {
          pipelineScheduleCreate {
            allowed
            code
            message
          }
        }
      }
    `
  }
});
<|endoftext|>