<commit_before>var mongoose = require('mongoose');
var Reporteplandiario = mongoose.model('Reporteplandiario');

//GET - Return all registers
exports.findAll = function (req, res) {
  Reporteplandiario.find(function (err, reportes) {
    if (err) res.send(500, err.message);
    console.log('GET /reportes')
    res.json({
      reportes: reportes
    });

  });
};

//GET - Return a register with specified ID
exports.findById = function (req, res) {
  Reporteplandiario.findById(req.params.id, function (err, reporte) {
    if (err) return res.send(500, err.message);
    console.log('GET /reporte/' + req.params.id);
    res.status(200).jsonp({reporte:reporte});
  });
};

//POST - Insert a new register
exports.add = function (req, res) {
  console.log('POST');
  console.log(req.body);
  var reporte = new Reporteplandiario({

    fecha:req.body.fecha,
    fechaLocal:req.body.fechaLocal,
    planesdiarios:req.body.planesdiarios,
    visitasplaneadas:req.body.visitasplaneadas,
    entrevistasrealizadas:req.body.entrevistasrealizadas,
    ventasconcretadas:req.body.ventasconcretadas,
    montototaldepedidos:req.body.montototaldepedidos,
    visitasrecibidas:req.body.visitasrecibidas,
    montodecobranza:req.body.montodecobranza,
    montodedescuentos:req.body.montodedescuentos,
    revisado:req.body.revisado,
    creador:req.body.creador

  });
  reporte.save(function (err, reporte) {
    if (err) return res.send(500, err.message);
    res.status(200).json({
      reporte: reporte
    });

  });
};

//PUT - Update a register already exists
exports.update = function (req, res) {
  console.log("Update role " + req.params.id)
  var _reporte = new Reporteplandiario(req.body);
  Reporteplandiario.findById({_id:req.params.id}, function (err, reporte) {

    reporte.revisado = req.body.revisado;
    reporte.revisadoPor = req.body.revisadoPor;
    reporte.fechaRevisado = req.body.fechaRevisado;
    reporte.save(function (err,reporte) {
      if (err) return res.send(500).json({reporte:null});
     res.status(200).json({
       reporte: reporte
    });
    });
  });
};

exports.reportdone = function(req, res){
  console.log(req.body);

  console.log("isReportAlreadyDone ");
  Reporteplandiario.find({fechaLocal:req.body.fecha}, function (err, reporte) {
    console.log(err);
    console.log(reporte);
    if (err){
       return res.send(500, err.message).json({
         reportes:[]});
    }
    console.log('GET /reporte/' + req.params.fecha);

    res.status(200).json({
      reportes: [reporte]
    });

    //res.status(200).jsonp({reporte:reporte});
  });
}

//DELETE - Delete a register with specified ID
exports.delete = function (req, res) {
  Reporteplandiario.findById(req.params.id, function (err,reporte) {
    reporte.remove(function (err) {
      if (err) return res.send(500, err.message);
      res.json({
        message: 'Successfully deleted'
      });
    });
  });
};<commit_msg>remove error<commit_after>var mongoose = require('mongoose');
var Reporteplandiario = mongoose.model('Reporteplandiario');

//GET - Return all registers
exports.findAll = function (req, res) {
  Reporteplandiario.find(function (err, reportes) {
    if (err) res.send(500, err.message);
    console.log('GET /reportes')
    res.json({
      reportes: reportes
    });

  });
};

//GET - Return a register with specified ID
exports.findById = function (req, res) {
  Reporteplandiario.findById(req.params.id, function (err, reporte) {
    if (err) return res.send(500, err.message);
    console.log('GET /reporte/' + req.params.id);
    res.status(200).jsonp({reporte:reporte});
  });
};

//POST - Insert a new register
exports.add = function (req, res) {
  console.log('POST');
  console.log(req.body);
  var reporte = new Reporteplandiario({

    fecha:req.body.fecha,
    fechaLocal:req.body.fechaLocal,
    planesdiarios:req.body.planesdiarios,
    visitasplaneadas:req.body.visitasplaneadas,
    entrevistasrealizadas:req.body.entrevistasrealizadas,
    ventasconcretadas:req.body.ventasconcretadas,
    montototaldepedidos:req.body.montototaldepedidos,
    visitasrecibidas:req.body.visitasrecibidas,
    montodecobranza:req.body.montodecobranza,
    montodedescuentos:req.body.montodedescuentos,
    revisado:req.body.revisado,
    creador:req.body.creador

  });
  reporte.save(function (err, reporte) {
    if (err) return res.send(500, err.message);
    res.status(200).json({
      reporte: reporte
    });

  });
};

//PUT - Update a register already exists
exports.update = function (req, res) {
  console.log("Update role " + req.params.id)
  var _reporte = new Reporteplandiario(req.body);
  Reporteplandiario.findById({_id:req.params.id}, function (err, reporte) {

    reporte.revisado = req.body.revisado;
    reporte.revisadoPor = req.body.revisadoPor;
    reporte.fechaRevisado = req.body.fechaRevisado;
    reporte.save(function (err,reporte) {
      if (err) return res.send(500).json({reporte:null});
     res.status(200).json({
       reporte: reporte
    });
    });
  });
};

exports.reportdone = function(req, res){
  console.log(req.body);

  console.log("isReportAlreadyDone ");
  Reporteplandiario.find({fechaLocal:req.body.fecha}, function (err, reporte) {
    console.log(err);
    console.log(reporte);
    if (err){
       return res.send(500, err.message);
    }
    console.log('GET /reporte/' + req.params.fecha);

    res.status(200).json({
      reportes: [reporte]
    });

    //res.status(200).jsonp({reporte:reporte});
  });
}

//DELETE - Delete a register with specified ID
exports.delete = function (req, res) {
  Reporteplandiario.findById(req.params.id, function (err,reporte) {
    reporte.remove(function (err) {
      if (err) return res.send(500, err.message);
      res.json({
        message: 'Successfully deleted'
      });
    });
  });
};<|endoftext|>


<commit_before>import EmberObject from '@ember/object';
import { run } from '@ember/runloop';
import hbs from 'htmlbars-inline-precompile';
import { moduleForComponent, test } from 'ember-qunit';

moduleForComponent('moment-from-now',{
  integration: true,
  beforeEach() {
    this.container.lookup('service:moment').changeLocale('en');
  }
});

test('one arg (date)', function(assert) {
  assert.expect(1);

  const threeDaysAgo = new Date();
  threeDaysAgo.setDate(threeDaysAgo.getDate() - 3);

  const context = EmberObject.create({
    date: threeDaysAgo
  });

  this.set('context', context);

  this.render(hbs`{{moment-from-now context.date}}`);
  assert.equal(this.$().text(), '3 days ago');
});

test('one arg (dateA, hideAffix=boolean)', function(assert) {
  assert.expect(2);

  const momentService = this.container.lookup('service:moment');
  this.setProperties({
    dateA: momentService.moment().add(3, 'day'),
  });

  this.render(hbs`{{moment-to-now dateA hideAffix=true}}`);
  assert.equal(this.$().text(), '3 days');
  this.render(hbs`{{moment-to-now dateA hideAffix=false}}`);
  assert.equal(this.$().text(), '3 days ago');
});

test('two args (date, inputFormat)', function(assert) {
  assert.expect(1);

  const threeDaysAgo = new Date();
  threeDaysAgo.setDate(threeDaysAgo.getDate() - 3);

  this.setProperties({
    inputFormat: 'LLLL',
    date: threeDaysAgo
  });

  this.render(hbs`{{moment-from-now date inputFormat}}`);
  assert.equal(this.$().text(), '3 days ago');
});

test('change date input and change is reflected by bound helper', function(assert) {
  assert.expect(2);

  const momentService = this.container.lookup('service:moment');
  const context = EmberObject.create({
    date: momentService.moment().subtract(1, 'hour'),
  });

  this.set('context', context);

  this.render(hbs`{{moment-from-now context.date}}`);
  assert.equal(this.$().text(), 'an hour ago');

  run(function () {
    context.set('date', momentService.moment().subtract(2, 'hours'));
  });

  assert.equal(this.$().text(), '2 hours ago');
});

test('can inline a locale instead of using global locale', function(assert) {
  assert.expect(1);

  const momentService = this.container.lookup('service:moment');

  this.set('date', momentService.moment().subtract(1, 'hour'));
  this.render(hbs`{{moment-from-now date locale='es'}}`);
  assert.equal(this.$().text(), 'hace una hora');
});

test('can be called with null', function(assert) {
  assert.expect(1);

  this.set('date', null);
  this.render(hbs`{{moment-from-now date allow-empty=true}}`);
  assert.equal(this.$().text(), '');
});

test('localize arabic - issue 239', function(assert) {
  this.set('date', new Date());
  this.render(hbs`{{moment-from-now date locale='ar' hideSuffix=true}}`);
  assert.equal(this.$().text(), 'ثانية واحدة');
});
<commit_msg>Update test<commit_after>import EmberObject from '@ember/object';
import { run } from '@ember/runloop';
import hbs from 'htmlbars-inline-precompile';
import { moduleForComponent, test } from 'ember-qunit';

moduleForComponent('moment-from-now',{
  integration: true,
  beforeEach() {
    this.container.lookup('service:moment').changeLocale('en');
  }
});

test('one arg (date)', function(assert) {
  assert.expect(1);

  const threeDaysAgo = new Date();
  threeDaysAgo.setDate(threeDaysAgo.getDate() - 3);

  const context = EmberObject.create({
    date: threeDaysAgo
  });

  this.set('context', context);

  this.render(hbs`{{moment-from-now context.date}}`);
  assert.equal(this.$().text(), '3 days ago');
});

test('one arg (dateA, hideAffix=boolean)', function(assert) {
  assert.expect(2);

  const momentService = this.container.lookup('service:moment');
  this.setProperties({
    dateA: momentService.moment().add(3, 'day'),
  });

  this.render(hbs`{{moment-to-now dateA hideAffix=true}}`);
  assert.equal(this.$().text(), '3 days');
  this.render(hbs`{{moment-to-now dateA hideAffix=false}}`);
  assert.equal(this.$().text(), '3 days ago');
});

test('two args (date, inputFormat)', function(assert) {
  assert.expect(1);

  const threeDaysAgo = new Date();
  threeDaysAgo.setDate(threeDaysAgo.getDate() - 3);

  this.setProperties({
    inputFormat: 'LLLL',
    date: threeDaysAgo
  });

  this.render(hbs`{{moment-from-now date inputFormat}}`);
  assert.equal(this.$().text(), '3 days ago');
});

test('change date input and change is reflected by bound helper', function(assert) {
  assert.expect(2);

  const momentService = this.container.lookup('service:moment');
  const context = EmberObject.create({
    date: momentService.moment().subtract(1, 'hour'),
  });

  this.set('context', context);

  this.render(hbs`{{moment-from-now context.date}}`);
  assert.equal(this.$().text(), 'an hour ago');

  run(function () {
    context.set('date', momentService.moment().subtract(2, 'hours'));
  });

  assert.equal(this.$().text(), '2 hours ago');
});

test('can inline a locale instead of using global locale', function(assert) {
  assert.expect(1);

  const momentService = this.container.lookup('service:moment');

  this.set('date', momentService.moment().subtract(1, 'hour'));
  this.render(hbs`{{moment-from-now date locale='es'}}`);
  assert.equal(this.$().text(), 'hace una hora');
});

test('can be called with null', function(assert) {
  assert.expect(1);

  this.set('date', null);
  this.render(hbs`{{moment-from-now date allow-empty=true}}`);
  assert.equal(this.$().text(), '');
});

test('localize arabic - issue 239', function(assert) {
  this.set('date', new Date());
  this.render(hbs`{{moment-from-now date locale='ar' hideAffix=true}}`);
  assert.equal(this.$().text(), 'ثانية واحدة');
});
<|endoftext|>


<commit_before>Modules.VERSION = '2.0.1';
Modules.UTILS = true;

// dependsOn - object that adds a dependson attribute functionality to xul preference elements.
// Just add the attribute to the desired xul element and let the script do its thing. dependson accepts comma-separated or semicolon-separated strings in the following format:
//	[!]element[:value] where:
//		element - id of an element associated with a preference or the id of the preference element
//		(optional) ! - before element, checks for the opposite condition
//		(optional) :value - value is some specific value that element must have in order for the condition to return true
//	To condition for several dependencies: ',' is equivalent to AND and ';' to OR
//	examples:
//		element1 - checks if element1 is true
//		element2:someValue - checks if element2 has value of 'someValue'
//		element3:5 - checks if element3 has value 5
//		!element4 - checks if element4 is false
//		!element5:someOtherValue - checks if element5 has any value other than 'someOtherValue'
//		element6,element7:someValue - check if element6 is true and element7 has value of 'someValue'
//		element8:someValue;element9:someOtherValue - checks if element8 has value of 'someValue' or element9 has value of 'someOtherValue'
this.dependsOn = {
	getAll: function() {
		return $$("[dependson]");
	},

	handleEvent: function(e) {
		if(e.target.localName != 'preference' || !e.target.id) { return; }

		var fields = $$("[preference='"+e.target.id+"']");
		var elements = this.getAll();
		var alreadyChanged = new Set();

		for(let field of fields) {
			if(!field.id) { continue; }

			for(let node of elements) {
				if(alreadyChanged.has(node)) { continue; }

				if(node.getAttribute('dependson').contains(field.id)) {
					this.updateElement(node);
					alreadyChanged.add(node);
				}
			}
		}

		for(let node of elements) {
			if(alreadyChanged.has(node)) { continue; }

			if(node.getAttribute('dependson').contains(e.target.id)) {
				this.updateElement(node);
				alreadyChanged.add(node);
			}
		}
	},

	updateAll: function() {
		let elements = this.getAll();
		for(let node of elements) {
			this.updateElement(node);
		}
	},

	updateElement: function(el) {
		let attr = el.getAttribute('dependson');
		if(!attr) { return; }

		let dependencies = attr.split(',');
		for(let d of dependencies) {
			let alternates = d.split(';');
			let a = 0;
			while(a < alternates.length) {
				let inverse = false;
				let dependency = alternates[a].split(':');
				if(dependency[0].contains('!')) {
					inverse = true;
					dependency[0] = dependency[0].replace('!', '');
				}

				dependency[0] = trim(dependency[0]);
				if(dependency[0] == '') { continue; }

				if(dependency.length == 2) {
					dependency[1] = trim(dependency[1]);
				}

				let pref = $(dependency[0]);
				if(!pref) {
					Cu.reportError("Element of ID '"+dependency[0]+"' could not be found!");
					return;
				}

				if(pref.localName != 'preference') {
					pref = $(pref.getAttribute('preference'));
				}
				switch(pref.type) {
					case 'int':
						var value = (dependency.length == 2) ? parseInt(dependency[1]) : 0;
						break;
					case 'bool':
						var value = (dependency.length == 1) ? true : (dependency[1] == 'true') ? true : false;
						break;
					case 'string':
					default:
						var value = (dependency.length == 2) ? dependency[1] : '';
						break;
				}

				a++;
				if( (!inverse && pref.value !== value) || (inverse && pref.value === value) ) {
					if(a < alternates.length) { continue; }

					el.setAttribute('disabled', 'true');
					return;
				}
				else if(a < alternates.length) {
					el.removeAttribute('disabled');
					return;
				}
			}
		}
		el.removeAttribute('disabled');
	}
};

// initScales - every <scale> node should be properly initialized if it has a preference attribute; should work in most cases.
// If you want to bypass this you can set onsyncfrompreference attribute on the scale.
this.initScales = function() {
	var scales = $$('scale');
	for(let scale of scales) {
		if(!scale.getAttribute('onsyncfrompreference') && scale.getAttribute('preference')) {
			scale.value = $(scale.getAttribute('preference')).value;
		}
	}
};

// keys - should automatically take care of all the labels, entries and actions of any keysets to be registered through the Keysets object.
// It looks for and expects each keyset to be layouted (is this even a word?) in the XUL options page as such:
// 	<checkbox keysetAccel="keyName" preference="pref-to-accel"/>
//	<checkbox keysetAlt="keyName" preference="pref-to-alt"/>
//	<checkbox keysetShift="keyName" preference="pref-to-shift"/>
//	<menulist keyset="keyName" preference="pref-to-keycode"/>
this.keys = {
	all: [],

	handleEvent: function(e) {
		this.fillKeyCodes();
	},

	init: function() {
		let done = new Set();
		let all = $$('[keyset]');
		for(let node of all) {
			let id = node.getAttribute('keyset');
			if(done.has(id)) { continue; }
			done.add(id);

			if(!node.firstChild) {
				node.appendChild(document.createElement('menupopup'));
			}

			let key = {
				id: id,
				node: node,
				accelBox: $$('[keysetAccel="'+id+'"]')[0],
				shiftBox: $$('[keysetShift="'+id+'"]')[0],
				altBox: $$('[keysetAlt="'+id+'"]')[0],
				get disabled () { return trueAttribute(this.node, 'disabled'); },
				get keycode () { return this.node.value; },
				get accel () { return this.accelBox.checked; },
				get shift () { return this.shiftBox.checked; },
				get alt () { return this.altBox.checked; },
				get menu () { return this.node.firstChild; }
			};

			this.all.push(key);
			Keysets.fillKeyStrings(key);

			Listeners.add(key.node, 'command', this);
			Listeners.add(key.accelBox, 'command', this);
			Listeners.add(key.shiftBox, 'command', this);
			Listeners.add(key.altBox, 'command', this);
		}
	},

	uninit: function() {
		for(let key of this.all) {
			Listeners.remove(key.node, 'command', this);
			Listeners.remove(key.accelBox, 'command', this);
			Listeners.remove(key.shiftBox, 'command', this);
			Listeners.remove(key.altBox, 'command', this);
		}
	},

	fillKeycodes: function() {
		for(let key of this.all) {
			let available = Keysets.getAvailable(key, this.all);
			if(!available[key.keycode]) {
				key.keycode = 'none';
			}

			var item = key.menu.firstChild.nextSibling;
			while(item) {
				item.setAttribute('hidden', 'true');
				item.setAttribute('disabled', 'true');
				item = item.nextSibling;
			}
			if(key.keycode == 'none') {
				key.menu.parentNode.selectedItem = key.menu.firstChild;
				$(key.menu.parentNode.getAttribute('preference')).value = 'none';
			}

			for(let item of key.menu.childNodes) {
				let keycode = item.getAttribute('value');
				if(!available[keycode]) { continue; }

				item.removeAttribute('hidden');
				item.removeAttribute('disabled');
				if(keycode == key.keycode) {
					key.menu.parentNode.selectedItem = item;
					// It has the annoying habit of re-selecting the first (none) entry when selecting a menuitem with '*' as value
					if(keycode == '*') {
						var itemIndex = key.menu.parentNode.selectedIndex;
						aSync(function() { key.menu.parentNode.selectedIndex = itemIndex; });
					}
				}
			}
		}
	}
};

// In case I need subdialogs:
//   http://mxr.mozilla.org/mozilla-central/source/browser/components/preferences/in-content/subdialogs.js
//   http://mxr.mozilla.org/mozilla-central/source/browser/components/preferences/in-content/preferences.xul#197

// categories - aid to properly display preferences in a tab, just like the current native options tab
// adapted from http://mxr.mozilla.org/mozilla-central/source/browser/components/preferences/in-content/preferences.js
// unlike in the original, we don't use hidden, instead we use collapsed to switch between panels, so that all the bindings remain applied throughout the page.
this.categories = {
	lastHash: "",

	get categories () { return $('categories'); },
	get prefPane () { return $('mainPrefPane'); },

	handleEvent: function(e) {
		switch(e.type) {
			case 'select':
				this.gotoPref(e.target.value)
				break;

			case 'keydown':
				if(e.keyCode == e.DOM_VK_TAB) {
					setAttribute(this.categories, "keyboard-navigation", "true");
				}
				break;

			case 'mousedown':
				removeAttribute(this.categories, "keyboard-navigation");
				break;

			case 'hashchange':
				this.gotoPref();
				break;
		}
	},

	init: function() {
		document.documentElement.instantApply = true;

		// sometimes it may happen that the overlays aren't loaded in the correct order, which means the categories might not be ordered correctly,
		// it's definitely better UX if the categories are always in the same order, so we try to ensure this
		let categories = $('categories');
		let node = categories.firstChild;
		while(node) {
			let position = node.getAttribute('position');
			if(position) {
				position = parseInt(position);
				let sibling = null;
				let previous = node.previousSibling;
				while(previous) {
					let related = previous.getAttribute('position');
					if(related) {
						related = parseInt(related);
						if(position < related) {
							sibling = previous;
						} else {
							break;
						}
					}
					previous = previous.previousSibling;
				}

				if(sibling) {
					categories.insertBefore(node, sibling);
				}
			}

			node = node.nextSibling;
		}

		Listeners.add(this.categories, "select", this);
		Listeners.add(document.documentElement, "keydown", this);
		Listeners.add(this.categories, "mousedown", this);
		Listeners.add(window, "hashchange", this);

		this.gotoPref();
		this.dynamicPadding();
	},

	uninit: function() {
		Listeners.remove(this.categories, "select", this);
		Listeners.remove(document.documentElement, "keydown", this);
		Listeners.remove(this.categories, "mousedown", this);
		Listeners.remove(window, "hashchange", this);
	},

	// Make the space above the categories list shrink on low window heights
	dynamicPadding: function() {
		let catPadding = parseInt(getComputedStyle(this.categories).paddingTop);
		let fullHeight = this.categories.lastElementChild.getBoundingClientRect().bottom;
		let mediaRule = `
			@media (max-height: ${fullHeight}px) {
				#categories {
					padding-top: calc(100vh - ${fullHeight - catPadding}px);
				}
			}
		`;
		let mediaStyle = document.createElementNS('http://www.w3.org/1999/xhtml', 'html:style');
		mediaStyle.setAttribute('type', 'text/css');
		mediaStyle.appendChild(document.createCDATASection(mediaRule));
		document.documentElement.appendChild(mediaStyle);
	},

	gotoPref: function(aCategory) {
		const kDefaultCategoryInternalName = this.categories.lastElementChild.value;
		let hash = document.location.hash;
		let category = aCategory || hash.substr(1) || Prefs.lastPrefPane || kDefaultCategoryInternalName;
		category = this.friendlyPrefCategoryNameToInternalName(category);

		// Updating the hash (below) or changing the selected category will re-enter gotoPref.
		if(this.lastHash == category) { return; }

		let item = this.categories.querySelector(".category[value="+category+"]");
		if(!item) {
			category = kDefaultCategoryInternalName;
			item = this.categories.querySelector(".category[value="+category+"]");
		}

		let newHash = this.internalPrefCategoryNameToFriendlyName(category);
		if(this.lastHash || category != kDefaultCategoryInternalName) {
			document.location.hash = newHash;
		}

		// Need to set the lastHash before setting categories.selectedItem since the categories 'select' event will re-enter the gotoPref codepath.
		this.lastHash = category;
		this.categories.selectedItem = item;
		setAttribute(document.documentElement, 'currentcategory', category);
		Prefs.lastPrefPane = category; // I can't save the last category in a persisted attribute because it persists to the hashed url

		window.history.replaceState(category, document.title);
		this.search(category, "data-category");
		document.querySelector(".main-content").scrollTop = 0;
	},

	search: function(aQuery, aAttribute) {
		let elements = this.prefPane.children;
		for(let element of elements) {
			if(element.nodeName == 'preferences') { continue; }

			let attributeValue = element.getAttribute(aAttribute);
			element.collapsed = (attributeValue != aQuery);
		}
	},

	friendlyPrefCategoryNameToInternalName: function(aName) {
		if(aName.startsWith("pane")) {
			return aName;
		}

		return "pane" + aName.substring(0,1).toUpperCase() + aName.substr(1);
	},

	// This function is duplicated inside of utilityOverlay.js's openPreferences.
	internalPrefCategoryNameToFriendlyName: function(aName) {
		return (aName || "").replace(/^pane./, function(toReplace) { return toReplace[4].toLowerCase(); });
	}
};

Modules.LOADMODULE = function() {
	callOnLoad(window, function() {
		dependsOn.updateAll();
		Listeners.add(window, "change", dependsOn);
		Listeners.add($('selectColor'), 'select', function(e) { console.log(e); }, true);
		Listeners.add($('selectColor'), 'change', function(e) { console.log(e); }, true);

		initScales();
		keys.init();
		categories.init();
	});
};

Modules.UNLOADMODULE = function() {
	Listeners.remove(window, "change", dependsOn);
	keys.uninit();
	categories.uninit();

	if(UNLOADED) {
		window.close();
	}
};
<commit_msg>debug leftover<commit_after>Modules.VERSION = '2.0.1';
Modules.UTILS = true;

// dependsOn - object that adds a dependson attribute functionality to xul preference elements.
// Just add the attribute to the desired xul element and let the script do its thing. dependson accepts comma-separated or semicolon-separated strings in the following format:
//	[!]element[:value] where:
//		element - id of an element associated with a preference or the id of the preference element
//		(optional) ! - before element, checks for the opposite condition
//		(optional) :value - value is some specific value that element must have in order for the condition to return true
//	To condition for several dependencies: ',' is equivalent to AND and ';' to OR
//	examples:
//		element1 - checks if element1 is true
//		element2:someValue - checks if element2 has value of 'someValue'
//		element3:5 - checks if element3 has value 5
//		!element4 - checks if element4 is false
//		!element5:someOtherValue - checks if element5 has any value other than 'someOtherValue'
//		element6,element7:someValue - check if element6 is true and element7 has value of 'someValue'
//		element8:someValue;element9:someOtherValue - checks if element8 has value of 'someValue' or element9 has value of 'someOtherValue'
this.dependsOn = {
	getAll: function() {
		return $$("[dependson]");
	},

	handleEvent: function(e) {
		if(e.target.localName != 'preference' || !e.target.id) { return; }

		var fields = $$("[preference='"+e.target.id+"']");
		var elements = this.getAll();
		var alreadyChanged = new Set();

		for(let field of fields) {
			if(!field.id) { continue; }

			for(let node of elements) {
				if(alreadyChanged.has(node)) { continue; }

				if(node.getAttribute('dependson').contains(field.id)) {
					this.updateElement(node);
					alreadyChanged.add(node);
				}
			}
		}

		for(let node of elements) {
			if(alreadyChanged.has(node)) { continue; }

			if(node.getAttribute('dependson').contains(e.target.id)) {
				this.updateElement(node);
				alreadyChanged.add(node);
			}
		}
	},

	updateAll: function() {
		let elements = this.getAll();
		for(let node of elements) {
			this.updateElement(node);
		}
	},

	updateElement: function(el) {
		let attr = el.getAttribute('dependson');
		if(!attr) { return; }

		let dependencies = attr.split(',');
		for(let d of dependencies) {
			let alternates = d.split(';');
			let a = 0;
			while(a < alternates.length) {
				let inverse = false;
				let dependency = alternates[a].split(':');
				if(dependency[0].contains('!')) {
					inverse = true;
					dependency[0] = dependency[0].replace('!', '');
				}

				dependency[0] = trim(dependency[0]);
				if(dependency[0] == '') { continue; }

				if(dependency.length == 2) {
					dependency[1] = trim(dependency[1]);
				}

				let pref = $(dependency[0]);
				if(!pref) {
					Cu.reportError("Element of ID '"+dependency[0]+"' could not be found!");
					return;
				}

				if(pref.localName != 'preference') {
					pref = $(pref.getAttribute('preference'));
				}
				switch(pref.type) {
					case 'int':
						var value = (dependency.length == 2) ? parseInt(dependency[1]) : 0;
						break;
					case 'bool':
						var value = (dependency.length == 1) ? true : (dependency[1] == 'true') ? true : false;
						break;
					case 'string':
					default:
						var value = (dependency.length == 2) ? dependency[1] : '';
						break;
				}

				a++;
				if( (!inverse && pref.value !== value) || (inverse && pref.value === value) ) {
					if(a < alternates.length) { continue; }

					el.setAttribute('disabled', 'true');
					return;
				}
				else if(a < alternates.length) {
					el.removeAttribute('disabled');
					return;
				}
			}
		}
		el.removeAttribute('disabled');
	}
};

// initScales - every <scale> node should be properly initialized if it has a preference attribute; should work in most cases.
// If you want to bypass this you can set onsyncfrompreference attribute on the scale.
this.initScales = function() {
	var scales = $$('scale');
	for(let scale of scales) {
		if(!scale.getAttribute('onsyncfrompreference') && scale.getAttribute('preference')) {
			scale.value = $(scale.getAttribute('preference')).value;
		}
	}
};

// keys - should automatically take care of all the labels, entries and actions of any keysets to be registered through the Keysets object.
// It looks for and expects each keyset to be layouted (is this even a word?) in the XUL options page as such:
// 	<checkbox keysetAccel="keyName" preference="pref-to-accel"/>
//	<checkbox keysetAlt="keyName" preference="pref-to-alt"/>
//	<checkbox keysetShift="keyName" preference="pref-to-shift"/>
//	<menulist keyset="keyName" preference="pref-to-keycode"/>
this.keys = {
	all: [],

	handleEvent: function(e) {
		this.fillKeyCodes();
	},

	init: function() {
		let done = new Set();
		let all = $$('[keyset]');
		for(let node of all) {
			let id = node.getAttribute('keyset');
			if(done.has(id)) { continue; }
			done.add(id);

			if(!node.firstChild) {
				node.appendChild(document.createElement('menupopup'));
			}

			let key = {
				id: id,
				node: node,
				accelBox: $$('[keysetAccel="'+id+'"]')[0],
				shiftBox: $$('[keysetShift="'+id+'"]')[0],
				altBox: $$('[keysetAlt="'+id+'"]')[0],
				get disabled () { return trueAttribute(this.node, 'disabled'); },
				get keycode () { return this.node.value; },
				get accel () { return this.accelBox.checked; },
				get shift () { return this.shiftBox.checked; },
				get alt () { return this.altBox.checked; },
				get menu () { return this.node.firstChild; }
			};

			this.all.push(key);
			Keysets.fillKeyStrings(key);

			Listeners.add(key.node, 'command', this);
			Listeners.add(key.accelBox, 'command', this);
			Listeners.add(key.shiftBox, 'command', this);
			Listeners.add(key.altBox, 'command', this);
		}
	},

	uninit: function() {
		for(let key of this.all) {
			Listeners.remove(key.node, 'command', this);
			Listeners.remove(key.accelBox, 'command', this);
			Listeners.remove(key.shiftBox, 'command', this);
			Listeners.remove(key.altBox, 'command', this);
		}
	},

	fillKeycodes: function() {
		for(let key of this.all) {
			let available = Keysets.getAvailable(key, this.all);
			if(!available[key.keycode]) {
				key.keycode = 'none';
			}

			var item = key.menu.firstChild.nextSibling;
			while(item) {
				item.setAttribute('hidden', 'true');
				item.setAttribute('disabled', 'true');
				item = item.nextSibling;
			}
			if(key.keycode == 'none') {
				key.menu.parentNode.selectedItem = key.menu.firstChild;
				$(key.menu.parentNode.getAttribute('preference')).value = 'none';
			}

			for(let item of key.menu.childNodes) {
				let keycode = item.getAttribute('value');
				if(!available[keycode]) { continue; }

				item.removeAttribute('hidden');
				item.removeAttribute('disabled');
				if(keycode == key.keycode) {
					key.menu.parentNode.selectedItem = item;
					// It has the annoying habit of re-selecting the first (none) entry when selecting a menuitem with '*' as value
					if(keycode == '*') {
						var itemIndex = key.menu.parentNode.selectedIndex;
						aSync(function() { key.menu.parentNode.selectedIndex = itemIndex; });
					}
				}
			}
		}
	}
};

// In case I need subdialogs:
//   http://mxr.mozilla.org/mozilla-central/source/browser/components/preferences/in-content/subdialogs.js
//   http://mxr.mozilla.org/mozilla-central/source/browser/components/preferences/in-content/preferences.xul#197

// categories - aid to properly display preferences in a tab, just like the current native options tab
// adapted from http://mxr.mozilla.org/mozilla-central/source/browser/components/preferences/in-content/preferences.js
// unlike in the original, we don't use hidden, instead we use collapsed to switch between panels, so that all the bindings remain applied throughout the page.
this.categories = {
	lastHash: "",

	get categories () { return $('categories'); },
	get prefPane () { return $('mainPrefPane'); },

	handleEvent: function(e) {
		switch(e.type) {
			case 'select':
				this.gotoPref(e.target.value)
				break;

			case 'keydown':
				if(e.keyCode == e.DOM_VK_TAB) {
					setAttribute(this.categories, "keyboard-navigation", "true");
				}
				break;

			case 'mousedown':
				removeAttribute(this.categories, "keyboard-navigation");
				break;

			case 'hashchange':
				this.gotoPref();
				break;
		}
	},

	init: function() {
		document.documentElement.instantApply = true;

		// sometimes it may happen that the overlays aren't loaded in the correct order, which means the categories might not be ordered correctly,
		// it's definitely better UX if the categories are always in the same order, so we try to ensure this
		let categories = $('categories');
		let node = categories.firstChild;
		while(node) {
			let position = node.getAttribute('position');
			if(position) {
				position = parseInt(position);
				let sibling = null;
				let previous = node.previousSibling;
				while(previous) {
					let related = previous.getAttribute('position');
					if(related) {
						related = parseInt(related);
						if(position < related) {
							sibling = previous;
						} else {
							break;
						}
					}
					previous = previous.previousSibling;
				}

				if(sibling) {
					categories.insertBefore(node, sibling);
				}
			}

			node = node.nextSibling;
		}

		Listeners.add(this.categories, "select", this);
		Listeners.add(document.documentElement, "keydown", this);
		Listeners.add(this.categories, "mousedown", this);
		Listeners.add(window, "hashchange", this);

		this.gotoPref();
		this.dynamicPadding();
	},

	uninit: function() {
		Listeners.remove(this.categories, "select", this);
		Listeners.remove(document.documentElement, "keydown", this);
		Listeners.remove(this.categories, "mousedown", this);
		Listeners.remove(window, "hashchange", this);
	},

	// Make the space above the categories list shrink on low window heights
	dynamicPadding: function() {
		let catPadding = parseInt(getComputedStyle(this.categories).paddingTop);
		let fullHeight = this.categories.lastElementChild.getBoundingClientRect().bottom;
		let mediaRule = `
			@media (max-height: ${fullHeight}px) {
				#categories {
					padding-top: calc(100vh - ${fullHeight - catPadding}px);
				}
			}
		`;
		let mediaStyle = document.createElementNS('http://www.w3.org/1999/xhtml', 'html:style');
		mediaStyle.setAttribute('type', 'text/css');
		mediaStyle.appendChild(document.createCDATASection(mediaRule));
		document.documentElement.appendChild(mediaStyle);
	},

	gotoPref: function(aCategory) {
		const kDefaultCategoryInternalName = this.categories.lastElementChild.value;
		let hash = document.location.hash;
		let category = aCategory || hash.substr(1) || Prefs.lastPrefPane || kDefaultCategoryInternalName;
		category = this.friendlyPrefCategoryNameToInternalName(category);

		// Updating the hash (below) or changing the selected category will re-enter gotoPref.
		if(this.lastHash == category) { return; }

		let item = this.categories.querySelector(".category[value="+category+"]");
		if(!item) {
			category = kDefaultCategoryInternalName;
			item = this.categories.querySelector(".category[value="+category+"]");
		}

		let newHash = this.internalPrefCategoryNameToFriendlyName(category);
		if(this.lastHash || category != kDefaultCategoryInternalName) {
			document.location.hash = newHash;
		}

		// Need to set the lastHash before setting categories.selectedItem since the categories 'select' event will re-enter the gotoPref codepath.
		this.lastHash = category;
		this.categories.selectedItem = item;
		setAttribute(document.documentElement, 'currentcategory', category);
		Prefs.lastPrefPane = category; // I can't save the last category in a persisted attribute because it persists to the hashed url

		window.history.replaceState(category, document.title);
		this.search(category, "data-category");
		document.querySelector(".main-content").scrollTop = 0;
	},

	search: function(aQuery, aAttribute) {
		let elements = this.prefPane.children;
		for(let element of elements) {
			if(element.nodeName == 'preferences') { continue; }

			let attributeValue = element.getAttribute(aAttribute);
			element.collapsed = (attributeValue != aQuery);
		}
	},

	friendlyPrefCategoryNameToInternalName: function(aName) {
		if(aName.startsWith("pane")) {
			return aName;
		}

		return "pane" + aName.substring(0,1).toUpperCase() + aName.substr(1);
	},

	// This function is duplicated inside of utilityOverlay.js's openPreferences.
	internalPrefCategoryNameToFriendlyName: function(aName) {
		return (aName || "").replace(/^pane./, function(toReplace) { return toReplace[4].toLowerCase(); });
	}
};

Modules.LOADMODULE = function() {
	callOnLoad(window, function() {
		dependsOn.updateAll();
		Listeners.add(window, "change", dependsOn);

		initScales();
		keys.init();
		categories.init();
	});
};

Modules.UNLOADMODULE = function() {
	Listeners.remove(window, "change", dependsOn);
	keys.uninit();
	categories.uninit();

	if(UNLOADED) {
		window.close();
	}
};
<|endoftext|>


<commit_before>// This code runs inside an SGX enclave.

SecureWorker.importScripts('enclave-imports.js')

var ROUND_TIME = 10 // seconds

function arraysEqual(array1, array2) {
    if (array1.byteLength !== array2.byteLength) {
      return false
    }

    var a1 = new Uint8Array(array1)
    var a2 = new Uint8Array(array2)

    for (var i = 0; i !== a1.length; i++) {
      if (a1[i] !== a2[i]) return false
    }

    return true
}

function log(message) {
  if (typeof console !== 'undefined') {
    console.log(message)
  }
}

var timeSourceNonce = null

/**
 * Returns number of seconds relative to a reference point, as a number.
 */
function teeGetTrustedTime() {
  var trustedTime = SecureWorker.getTrustedTime()

  if (timeSourceNonce === null) {
    timeSourceNonce = trustedTime.timeSourceNonce
  }

  if (!arraysEqual(timeSourceNonce, trustedTime.timeSourceNonce)) {
    throw new Error("timeSourceNonce changed")
  }

  var currentTimeView = new DataView(trustedTime.currentTime)

  return currentTimeView.getUint32(0, true) + currentTimeView.getUint32(4, true) * Math.pow(2, 32)
}

var monotonicCounterId = null

// TODO: We should create all 256 monotonic counters and use them as one monotonic counter.
function teeIncrementMonotonicCounter() {
  if (monotonicCounterId === null) {
    var createdMonotonicCounter = SecureWorker.monotonicCounters.create()
    monotonicCounterId = createdMonotonicCounter.uuid
    return createdMonotonicCounter.value
  }
  else {
    return SecureWorker.monotonicCounters.increment(monotonicCounterId)
  }
}

function teeReadMonotonicCounter() {
  if (monotonicCounterId === null) {
    throw new Error("Invalid state, monotonicCounterId")
  }

  return SecureWorker.monotonicCounters.read(monotonicCounterId)
}

/**
 * Returns a random value from [0, 1) interval.
 * Based on: http://stackoverflow.com/a/13694869/252025
 */
function teeGetRandom() {
  var array = new Uint32Array(2)
  crypto.getRandomValues(array)

  // Keep all 32 bits of the the first, top 20 of the second for 52 random bits.
  var mantissa = (array[0] * Math.pow(2, 20)) + (array[1] >>> 12)

  // Shift all 52 bits to the right of the decimal point.
  return mantissa * Math.pow(2, -52)
}

function teeReport(nonce) {
  return SecureWorker.getReport(nonce)
}

var counter = teeIncrementMonotonicCounter()
var roundBlockPayload = null
var roundTime = null
var sleepCallback = null

/**
 * Returns an IPFS hash of a given object, returning a buffer.
 */
function ipfsHashBuffer(object) {
  return new Promise(function (resolve, reject) {
    dagPB.DAGNode.create(object.Data, object.Links, 'sha2-256', function (error, node) {
      if (error) {
        reject(error)
      }
      else {
        resolve(node.multihash)
      }
    })
  })
}

/**
 * Returns an IPFS hash of a given object, returning it encoded as a string.
 */
function ipfsHash(object) {
  return ipfsHashBuffer(object).then(function (multihashBuffer) {
    return multihashing.multihash.toB58String(multihashBuffer)
  })
}

function getIpfsLink(object, linkName) {
  if (!object.Links || !object.Links.length) {
    return null
  }

  var link = null
  for (var i = 0; i < object.Links.length; i++) {
    if (object.Links[i].Name === linkName) {
      if (link === null) {
        link = object.Links[i]
      }
      else {
        throw new Error("Duplicate links with name '" + linkName + "'")
      }
    }
  }

  if (!link) {
    return null
  }

  return link
}

function f(l) {
  return (1 - l) * ROUND_TIME
}

function verifyPayload(payload) {
  // Using == on purpose.
  if (payload == null) {
    return false
  }

  // TODO: Implement the rest of checks. For example, structure, lucky number limits.

  return true
}

function verifyBlock(block) {
  // Using == on purpose.
  if (block == null) {
    return false
  }

  // TODO: Implement the rest of checks.

  return true
}

/**
 * This function is a TEE method that sets the state of roundBlockPayload
 * and roundTime. The trusted time service teeGetTrustedTime() represents
 * a standard method provided as part of the TEE and is used as
 * verification for ROUND_TIME when mining a new block.
 */
function teeProofOfLuckRound(blockPayload) {
  if (!verifyPayload(blockPayload)) {
    throw new Error("Invalid blockPayload")
  }

  sleepCallback = null
  roundBlockPayload = blockPayload
  roundTime = teeGetTrustedTime()
}

/**
 * This function is a TEE method that uses the given new payload and
 * previous block and starts by checking the required ROUND_TIME has
 * elapsed before proceeding to generate a new luck value, using it
 * to compute an f(l) which determines the amount of time the TEE will
 * sleep. Upon return from sleeping f(l) duration, the function returns
 * a teeReport() that includes the luck value and payload hash.
 * Sleeping is implemented with help of another function,
 * teeProofOfLuckResumeFromSleep.
 */
function teeProofOfLuckMine(payload, previousBlock, previousBlockPayload, callback) {
  if (previousBlock === null && previousBlockPayload === null) {
    teeProofOfLuckMineGenesis(payload, callback)
    return
  }

  if (sleepCallback !== null) {
    throw new Error("Invalid state, sleepCallback")
  }

  if (roundBlockPayload === null || roundTime === null) {
    throw new Error("Invalid state, roundBlockPayload or roundTime")
  }

  if (!verifyPayload(payload)) {
    throw new Error("Invalid payload")
  }

  if (!verifyBlock(previousBlock)) {
    throw new Error("Invalid previousBlock")
  }

  if (!verifyPayload(previousBlockPayload)) {
    throw new Error("Invalid previousBlockPayload")
  }

  ipfsHash(previousBlock).then(function (previousBlockIpfsHash) {
    var payloadParentLink = getIpfsLink(payload, "parent")
    if (!payloadParentLink || payloadParentLink.Hash !== previousBlockIpfsHash) {
      throw new Error("payload.parent != hash(previousBlock)")
    }

    return ipfsHash(previousBlockPayload)
  }).then(function (previousBlockPayloadIpfsHash) {
    var previousBlockPayloadLink = getIpfsLink(previousBlock, "payload")
    if (!previousBlockPayloadLink || previousBlockPayloadLink.Hash !== previousBlockPayloadIpfsHash) {
      throw new Error("previousBlock.payload != hash(previousBlockPayload)")
    }

    // The last link points to the parent block.
    var previousBlockPayloadParentLink = getIpfsLink(previousBlockPayload, "parent")
    var roundBlockPayloadParentLink = getIpfsLink(roundBlockPayload, "parent")
    if ((previousBlockPayloadParentLink !== null || roundBlockPayloadParentLink !== null) && previousBlockPayloadParentLink.Hash !== roundBlockPayloadParentLink.Hash) {
      throw new Error("previousBlockPayload.parent != roundBlockPayload.parent")
    }

    var now = teeGetTrustedTime()

    if (now < roundTime + ROUND_TIME) {
      throw new Error("now < roundTime + ROUND_TIME")
    }

    roundBlockPayload = null
    roundTime = null

    return ipfsHashBuffer(payload)
  }).then(function (payloadIpfsHashBuffer) {
    var payloadHash = new Uint8Array(payloadIpfsHashBuffer)
    var l = teeGetRandom()

    buildNonce(payloadHash, l, callback)
  }).catch(function (error) {
    callback(error)
  })
}

/**
 * Mine a genesis block. Payload has no parent and luck is always 0.
 */
function teeProofOfLuckMineGenesis(payload, callback) {
  if (sleepCallback !== null) {
    throw new Error("Invalid state, sleepCallback")
  }

  if (!verifyPayload(payload)) {
    throw new Error("Invalid payload")
  }

  if (getIpfsLink(payload, "parent") !== null) {
    throw new Error("Genesis block with parent link")
  }

  roundBlockPayload = null
  roundTime = null

  ipfsHashBuffer(payload).then(function (payloadIpfsHashBuffer) {
    var payloadHash = new Uint8Array(payloadIpfsHashBuffer)
    var l = 0.0

    buildNonce(payloadHash, l, callback)
  }).catch(function (error) {
    callback(error)
  })
}

/**
 * A helper function to implement sleeping by returning to outside
 * of the enclave an then returning back in after sleeping time passed.
 */
function teeProofOfLuckResumeFromSleep() {
  // TODO: Verify that really sleeping time passed. At least seconds.

  if (sleepCallback === null) {
    throw new Error("Invalid state, sleepCallback")
  }

  if (roundBlockPayload !== null || roundTime !== null) {
    throw new Error("Invalid state, roundBlockPayload or roundTime")
  }

  var callback = sleepCallback
  sleepCallback = null

  return callback()
}

function buildNonce(payloadHash, l, callback) {
  var nonceBuffer = new ArrayBuffer(64)
  var nonceArray = new Uint8Array(nonceBuffer)
  var nonceView = new DataView(nonceBuffer)

  // Version.
  nonceView.setUint8(0, 1)
  // Luck.
  nonceView.setFloat64(1, l, true)
  // Size of payloadHash.
  nonceView.setUint8(9, payloadHash.byteLength)
  // payloadHash.
  nonceArray.set(payloadHash, 10)

  sleepCallback = function () {
    var newCounter = teeReadMonotonicCounter()
    if (counter !== newCounter) {
      throw new Error("counter !== newCounter")
    }

    return teeReport(nonceBuffer)
  }

  // Returns the time to sleep, in seconds.
  callback(null, f(l), l)
}

SecureWorker.onMessage(function (message) {
  if (!message || !message.requestId || !message.type) {
    log("Invalid message in onMessage")
    return
  }

  try {
    if (message.type === 'teeProofOfLuckRound') {
      SecureWorker.postMessage({
        type: message.type + 'Result',
        requestId: message.requestId,
        result: serialize(teeProofOfLuckRound.apply(null, (message.args || []).map(deserialize)))
      })
    }
    else if (message.type === 'teeProofOfLuckMine') {
      teeProofOfLuckMine.apply(null, (message.args || []).map(deserialize).concat(function (error, sleepTime, luck) {
        if (error) {
          SecureWorker.postMessage({
            type: message.type + 'Result',
            requestId: message.requestId,
            error: serialize(error)
          })
        }
        else {
          SecureWorker.postMessage({
            type: message.type + 'Result',
            requestId: message.requestId,
            result: serialize({
              sleepTime: sleepTime,
              luck: luck
            })
          })
        }
      }))
    }
    else if (message.type === 'teeProofOfLuckResumeFromSleep') {
      SecureWorker.postMessage({
        type: message.type + 'Result',
        requestId: message.requestId,
        result: serialize(teeProofOfLuckResumeFromSleep.apply(null, (message.args || []).map(deserialize)))
      })
    }
    else {
      log("Unknown message type in onMessage: " + message.type)
    }
  }
  catch (error) {
    SecureWorker.postMessage({
      type: message.type + 'Result',
      requestId: message.requestId,
      error: serialize(error)
    })
  }
})<commit_msg>Slightly delay release of a block.<commit_after>// This code runs inside an SGX enclave.

SecureWorker.importScripts('enclave-imports.js')

var ROUND_TIME = 10 // seconds

function arraysEqual(array1, array2) {
    if (array1.byteLength !== array2.byteLength) {
      return false
    }

    var a1 = new Uint8Array(array1)
    var a2 = new Uint8Array(array2)

    for (var i = 0; i !== a1.length; i++) {
      if (a1[i] !== a2[i]) return false
    }

    return true
}

function log(message) {
  if (typeof console !== 'undefined') {
    console.log(message)
  }
}

var timeSourceNonce = null

/**
 * Returns number of seconds relative to a reference point, as a number.
 */
function teeGetTrustedTime() {
  var trustedTime = SecureWorker.getTrustedTime()

  if (timeSourceNonce === null) {
    timeSourceNonce = trustedTime.timeSourceNonce
  }

  if (!arraysEqual(timeSourceNonce, trustedTime.timeSourceNonce)) {
    throw new Error("timeSourceNonce changed")
  }

  var currentTimeView = new DataView(trustedTime.currentTime)

  return currentTimeView.getUint32(0, true) + currentTimeView.getUint32(4, true) * Math.pow(2, 32)
}

var monotonicCounterId = null

// TODO: We should create all 256 monotonic counters and use them as one monotonic counter.
function teeIncrementMonotonicCounter() {
  if (monotonicCounterId === null) {
    var createdMonotonicCounter = SecureWorker.monotonicCounters.create()
    monotonicCounterId = createdMonotonicCounter.uuid
    return createdMonotonicCounter.value
  }
  else {
    return SecureWorker.monotonicCounters.increment(monotonicCounterId)
  }
}

function teeReadMonotonicCounter() {
  if (monotonicCounterId === null) {
    throw new Error("Invalid state, monotonicCounterId")
  }

  return SecureWorker.monotonicCounters.read(monotonicCounterId)
}

/**
 * Returns a random value from [0, 1) interval.
 * Based on: http://stackoverflow.com/a/13694869/252025
 */
function teeGetRandom() {
  var array = new Uint32Array(2)
  crypto.getRandomValues(array)

  // Keep all 32 bits of the the first, top 20 of the second for 52 random bits.
  var mantissa = (array[0] * Math.pow(2, 20)) + (array[1] >>> 12)

  // Shift all 52 bits to the right of the decimal point.
  return mantissa * Math.pow(2, -52)
}

function teeReport(nonce) {
  return SecureWorker.getReport(nonce)
}

var counter = teeIncrementMonotonicCounter()
var roundBlockPayload = null
var roundTime = null
var sleepCallback = null

/**
 * Returns an IPFS hash of a given object, returning a buffer.
 */
function ipfsHashBuffer(object) {
  return new Promise(function (resolve, reject) {
    dagPB.DAGNode.create(object.Data, object.Links, 'sha2-256', function (error, node) {
      if (error) {
        reject(error)
      }
      else {
        resolve(node.multihash)
      }
    })
  })
}

/**
 * Returns an IPFS hash of a given object, returning it encoded as a string.
 */
function ipfsHash(object) {
  return ipfsHashBuffer(object).then(function (multihashBuffer) {
    return multihashing.multihash.toB58String(multihashBuffer)
  })
}

function getIpfsLink(object, linkName) {
  if (!object.Links || !object.Links.length) {
    return null
  }

  var link = null
  for (var i = 0; i < object.Links.length; i++) {
    if (object.Links[i].Name === linkName) {
      if (link === null) {
        link = object.Links[i]
      }
      else {
        throw new Error("Duplicate links with name '" + linkName + "'")
      }
    }
  }

  if (!link) {
    return null
  }

  return link
}

function f(l) {
  // We always wait at least one second. This allows all peers to at least compute their own lucky numbers
  // and then be able to know if they are winning or not, and if they should ignore less luckier blocks.
  return (1 - l) * ROUND_TIME / 2 + 1
}

function verifyPayload(payload) {
  // Using == on purpose.
  if (payload == null) {
    return false
  }

  // TODO: Implement the rest of checks. For example, structure, lucky number limits.

  return true
}

function verifyBlock(block) {
  // Using == on purpose.
  if (block == null) {
    return false
  }

  // TODO: Implement the rest of checks.

  return true
}

/**
 * This function is a TEE method that sets the state of roundBlockPayload
 * and roundTime. The trusted time service teeGetTrustedTime() represents
 * a standard method provided as part of the TEE and is used as
 * verification for ROUND_TIME when mining a new block.
 */
function teeProofOfLuckRound(blockPayload) {
  if (!verifyPayload(blockPayload)) {
    throw new Error("Invalid blockPayload")
  }

  sleepCallback = null
  roundBlockPayload = blockPayload
  roundTime = teeGetTrustedTime()
}

/**
 * This function is a TEE method that uses the given new payload and
 * previous block and starts by checking the required ROUND_TIME has
 * elapsed before proceeding to generate a new luck value, using it
 * to compute an f(l) which determines the amount of time the TEE will
 * sleep. Upon return from sleeping f(l) duration, the function returns
 * a teeReport() that includes the luck value and payload hash.
 * Sleeping is implemented with help of another function,
 * teeProofOfLuckResumeFromSleep.
 */
function teeProofOfLuckMine(payload, previousBlock, previousBlockPayload, callback) {
  if (previousBlock === null && previousBlockPayload === null) {
    teeProofOfLuckMineGenesis(payload, callback)
    return
  }

  if (sleepCallback !== null) {
    throw new Error("Invalid state, sleepCallback")
  }

  if (roundBlockPayload === null || roundTime === null) {
    throw new Error("Invalid state, roundBlockPayload or roundTime")
  }

  if (!verifyPayload(payload)) {
    throw new Error("Invalid payload")
  }

  if (!verifyBlock(previousBlock)) {
    throw new Error("Invalid previousBlock")
  }

  if (!verifyPayload(previousBlockPayload)) {
    throw new Error("Invalid previousBlockPayload")
  }

  ipfsHash(previousBlock).then(function (previousBlockIpfsHash) {
    var payloadParentLink = getIpfsLink(payload, "parent")
    if (!payloadParentLink || payloadParentLink.Hash !== previousBlockIpfsHash) {
      throw new Error("payload.parent != hash(previousBlock)")
    }

    return ipfsHash(previousBlockPayload)
  }).then(function (previousBlockPayloadIpfsHash) {
    var previousBlockPayloadLink = getIpfsLink(previousBlock, "payload")
    if (!previousBlockPayloadLink || previousBlockPayloadLink.Hash !== previousBlockPayloadIpfsHash) {
      throw new Error("previousBlock.payload != hash(previousBlockPayload)")
    }

    // The last link points to the parent block.
    var previousBlockPayloadParentLink = getIpfsLink(previousBlockPayload, "parent")
    var roundBlockPayloadParentLink = getIpfsLink(roundBlockPayload, "parent")
    if ((previousBlockPayloadParentLink !== null || roundBlockPayloadParentLink !== null) && previousBlockPayloadParentLink.Hash !== roundBlockPayloadParentLink.Hash) {
      throw new Error("previousBlockPayload.parent != roundBlockPayload.parent")
    }

    var now = teeGetTrustedTime()

    if (now < roundTime + ROUND_TIME) {
      throw new Error("now < roundTime + ROUND_TIME")
    }

    roundBlockPayload = null
    roundTime = null

    return ipfsHashBuffer(payload)
  }).then(function (payloadIpfsHashBuffer) {
    var payloadHash = new Uint8Array(payloadIpfsHashBuffer)
    var l = teeGetRandom()

    buildNonce(payloadHash, l, callback)
  }).catch(function (error) {
    callback(error)
  })
}

/**
 * Mine a genesis block. Payload has no parent and luck is always 0.
 */
function teeProofOfLuckMineGenesis(payload, callback) {
  if (sleepCallback !== null) {
    throw new Error("Invalid state, sleepCallback")
  }

  if (!verifyPayload(payload)) {
    throw new Error("Invalid payload")
  }

  if (getIpfsLink(payload, "parent") !== null) {
    throw new Error("Genesis block with parent link")
  }

  roundBlockPayload = null
  roundTime = null

  ipfsHashBuffer(payload).then(function (payloadIpfsHashBuffer) {
    var payloadHash = new Uint8Array(payloadIpfsHashBuffer)
    var l = 0.0

    buildNonce(payloadHash, l, callback)
  }).catch(function (error) {
    callback(error)
  })
}

/**
 * A helper function to implement sleeping by returning to outside
 * of the enclave an then returning back in after sleeping time passed.
 */
function teeProofOfLuckResumeFromSleep() {
  // TODO: Verify that really sleeping time passed. At least seconds.

  if (sleepCallback === null) {
    throw new Error("Invalid state, sleepCallback")
  }

  if (roundBlockPayload !== null || roundTime !== null) {
    throw new Error("Invalid state, roundBlockPayload or roundTime")
  }

  var callback = sleepCallback
  sleepCallback = null

  return callback()
}

function buildNonce(payloadHash, l, callback) {
  var nonceBuffer = new ArrayBuffer(64)
  var nonceArray = new Uint8Array(nonceBuffer)
  var nonceView = new DataView(nonceBuffer)

  // Version.
  nonceView.setUint8(0, 1)
  // Luck.
  nonceView.setFloat64(1, l, true)
  // Size of payloadHash.
  nonceView.setUint8(9, payloadHash.byteLength)
  // payloadHash.
  nonceArray.set(payloadHash, 10)

  sleepCallback = function () {
    var newCounter = teeReadMonotonicCounter()
    if (counter !== newCounter) {
      throw new Error("counter !== newCounter")
    }

    return teeReport(nonceBuffer)
  }

  // Returns the time to sleep, in seconds.
  callback(null, f(l), l)
}

SecureWorker.onMessage(function (message) {
  if (!message || !message.requestId || !message.type) {
    log("Invalid message in onMessage")
    return
  }

  try {
    if (message.type === 'teeProofOfLuckRound') {
      SecureWorker.postMessage({
        type: message.type + 'Result',
        requestId: message.requestId,
        result: serialize(teeProofOfLuckRound.apply(null, (message.args || []).map(deserialize)))
      })
    }
    else if (message.type === 'teeProofOfLuckMine') {
      teeProofOfLuckMine.apply(null, (message.args || []).map(deserialize).concat(function (error, sleepTime, luck) {
        if (error) {
          SecureWorker.postMessage({
            type: message.type + 'Result',
            requestId: message.requestId,
            error: serialize(error)
          })
        }
        else {
          SecureWorker.postMessage({
            type: message.type + 'Result',
            requestId: message.requestId,
            result: serialize({
              sleepTime: sleepTime,
              luck: luck
            })
          })
        }
      }))
    }
    else if (message.type === 'teeProofOfLuckResumeFromSleep') {
      SecureWorker.postMessage({
        type: message.type + 'Result',
        requestId: message.requestId,
        result: serialize(teeProofOfLuckResumeFromSleep.apply(null, (message.args || []).map(deserialize)))
      })
    }
    else {
      log("Unknown message type in onMessage: " + message.type)
    }
  }
  catch (error) {
    SecureWorker.postMessage({
      type: message.type + 'Result',
      requestId: message.requestId,
      error: serialize(error)
    })
  }
})<|endoftext|>


<commit_before>/**
 *
 * @param {*number} height
 * @param {*number} width
 */
import Base from '../../Base/Base'
/**
 *
 * Calculating the length of the image element block on the given area
 * @param {*number} height : Defines the height
 * @param {*number} width : Defines the width
 * @param {*number} blockNumber: Defines the number of blocks
 */
function getLength(width, height, length) {
  return {
    length,
    xBlocks: (width / length) % 10 === 0 ? width / length : (width / length) + 1,
    yBlocks: (height / length) % 10 === 0 ? height / length : (height / length) + 1,
  }
  // const area = Math.round((height * width) / blockNumber)
  // return Math.round(Math.sqrt(area))
}
/**
 * Fuction to create image blocks
 * @param {*object} root : root element to which the bock need to be appended
 * @param {*number} height : height of the image
 * @param {*number} width : width of the image
 */
function createBlocks(width, height, length = 60) {
  const paper = this.getFromEnv('paper')
  const imgGroup = this.getFromStore('gridGroup')
  // Defining the element's property
  const block = getLength(width, height, length)
  let xCord = 0
  let yCord = 0
  const gridGroup = []
  let mask
  for (let i = 0; i < block.yBlocks; i += 1) {
    xCord = 0
    gridGroup[i] = []
    for (let j = 0; j < block.xBlocks; j += 1) {
      // Creating the image element
      const img = paper.image('', 0, 0, width, height)
      // Create the mask
      mask = paper
        .rect(xCord, yCord, xCord + block.length, yCord + block.length)
        .attr({
          fill: '#fff',
        })
      img.attr({
        mask,
      })
      const fn = () => (Math.random() * 266) << 0
      const ttmpBox = paper
        .rect(xCord, yCord, block.length, block.length)
        .attr({
          stroke: `rgba(${fn()},${fn()},${fn()},1)`,
          'stroke-width': '1',
          fill: 'rgba(0,0,0,0)',
        })
      // Adding image to the gorup
      imgGroup.add(img)
      imgGroup.add(ttmpBox)
      // Setting the x coordinate for the next image
      xCord += block.length
      gridGroup[i].push({
        img,
        mask,
      })
    }
    // Setting the y coordinate for the next image
    yCord += block.length
  }
  return gridGroup
}

class Grid extends Base {
  /**
   *
   * @param {*object} parent
   * @param {*object} root : Element to which the blocks will be appended
   */
  constructor(parent, parentGroup) {
    super(parent)
    const config = this.getFromEnv('config')
    const paper = this.getFromEnv('paper')

    const gridGroup = paper
      .group()
      .attr({
        id: 'blocks-gallery-gird',
      })
    parentGroup.add(gridGroup)
    this.addToStore('gridGroup', gridGroup)
    const height = config.height
    const width = config.width
    // Initializing all the image elements and adding them to the store
    this.addToStore('gridBlocks', createBlocks.call(this, width, height))
  }
  /**
   * To be used to iterate over all the div and image elements
   * and call the callback
   * @param {*function} callback
   */
  iterate(callback) {
    for (let i = 0; i < 10; i += 1) {
      for (let j = 0; j < 10; j += 1) {
        const block = this.getFromStore('gridBlocks')[i][j]
        callback(block.img, block.div, i, j)
      }
    }
  }
}

export default Grid
<commit_msg>removed unwanted<commit_after>/**
 *
 * @param {*number} height
 * @param {*number} width
 */
import Base from '../../Base/Base'
/**
 *
 * Calculating the length of the image element block on the given area
 * @param {*number} height : Defines the height
 * @param {*number} width : Defines the width
 * @param {*number} blockNumber: Defines the number of blocks
 */
function getLength(width, height, length) {
  return {
    length,
    xBlocks: (width / length) % 10 === 0 ? width / length : (width / length) + 1,
    yBlocks: (height / length) % 10 === 0 ? height / length : (height / length) + 1,
  }
  // const area = Math.round((height * width) / blockNumber)
  // return Math.round(Math.sqrt(area))
}
/**
 * Fuction to create image blocks
 * @param {*object} root : root element to which the bock need to be appended
 * @param {*number} height : height of the image
 * @param {*number} width : width of the image
 */
function createBlocks(width, height, length = 60) {
  const paper = this.getFromEnv('paper')
  const imgGroup = this.getFromStore('gridGroup')
  // Defining the element's property
  const block = getLength(width, height, length)
  this.addToStore('blockConfig', block)
  let xCord = 0
  let yCord = 0
  const gridGroup = []
  let mask
  for (let i = 0; i < block.yBlocks; i += 1) {
    xCord = 0
    gridGroup[i] = []
    for (let j = 0; j < block.xBlocks; j += 1) {
      // Creating the image element
      const img = paper.image('', 0, 0, width, height)
      // Create the mask
      mask = paper
        .rect(xCord, yCord, xCord + block.length, yCord + block.length)
        .attr({
          fill: '#fff',
        })
      img.attr({
        mask,
      })
      const fn = () => (Math.random() * 266) << 0
      const ttmpBox = paper
        .rect(xCord, yCord, block.length, block.length)
        .attr({
          stroke: `rgba(${fn()},${fn()},${fn()},1)`,
          'stroke-width': '1',
          fill: 'rgba(0,0,0,0)',
        })
      // Adding image to the gorup
      imgGroup.add(img)
      imgGroup.add(ttmpBox)
      // Setting the x coordinate for the next image
      xCord += block.length
      gridGroup[i].push({
        img,
      })
    }
    // Setting the y coordinate for the next image
    yCord += block.length
  }
  return gridGroup
}

class Grid extends Base {
  /**
   *
   * @param {*object} parent
   * @param {*object} root : Element to which the blocks will be appended
   */
  constructor(parent, parentGroup) {
    super(parent)
    const config = this.getFromEnv('config')
    const paper = this.getFromEnv('paper')

    const gridGroup = paper
      .group()
      .attr({
        id: 'blocks-gallery-gird',
      })
    parentGroup.add(gridGroup)
    this.addToStore('gridGroup', gridGroup)
    const height = config.height
    const width = config.width
    // Initializing all the image elements and adding them to the store
    this.addToStore('gridBlocks', createBlocks.call(this, width, height))
  }
  /**
   * To be used to iterate over all the div and image elements
   * and call the callback
   * @param {*function} callback
   */
  iterate(callback) {
    const blockConfig = this.getFromStore('blockConfig')
    for (let i = 0; i < blockConfig.yBlocks; i += 1) {
      for (let j = 0; j < blockConfig.xBlocks; j += 1) {
        const block = this.getFromStore('gridBlocks')[i][j]
        callback(block.img, i, j)
      }
    }
  }
}

export default Grid
<|endoftext|>


<commit_before>/*jshint globalstrict:false, strict:false */
/* global arango, assertTrue, assertEqual */

////////////////////////////////////////////////////////////////////////////////
/// @brief test for server startup options
///
/// DISCLAIMER
///
/// Copyright 2010-2012 triagens GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
///     http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Copyright holder is ArangoDB Inc, Cologne, Germany
///
/// @author Jan Steemann
/// @author Copyright 2019, ArangoDB Inc, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////

const db = require('@arangodb').db;
const internal = require('internal');
const jsunity = require('jsunity');

exports.setup = function(cn) {
  let payload = Array(1024).join("x");
  let c = db._create(cn);
  let docs = [];
  for (let i = 0; i < 250 * 1000; ++i) {
    docs.push({ _key: "test" + i, value1: i, value2: "test" + i, payload });
    if (docs.length === 1000) {
      c.insert(docs);
      docs = [];
    }
  }
};

exports.testDbQuery = function(cn, fillBlockCache) {
  const oldValue = db._engineStats()["rocksdb.block-cache-usage"];
  let result = db._query("FOR doc IN @@collection RETURN doc.value1", { "@collection": cn }, { fillBlockCache }).toArray();
  assertEqual(250 * 1000, result.length);

  const newValue = db._engineStats()["rocksdb.block-cache-usage"];
  if (fillBlockCache) {
    assertTrue(newValue >= oldValue + 100 * 1000 * 1000, { oldValue, newValue });
  } else {
    // allow for some other background things to be run, thus add 1MB of leeway
    assertTrue(newValue <= oldValue + 1000 * 1000, { oldValue, newValue });
  }

  result = db._query("FOR doc IN @@collection RETURN doc.value1", { "@collection": cn }, { fillBlockCache }).toArray();
  assertEqual(250 * 1000, result.length);

  if (internal.platform.substr(0, 3) !== 'win') {
    const newValue2 = db._engineStats()["rocksdb.block-cache-usage"];
    // allow for some other background things to be run, thus add 1MB of leeway
    // On Windows, the block cache usage in newValue2 is a lot higher here.
    assertTrue(newValue2 <= newValue + 1000 * 1000, { newValue, newValue2 });
  }
};

exports.testHttpApi = function(cn, fillBlockCache) {
  const oldValue = db._engineStats()["rocksdb.block-cache-usage"];
  arango.POST("/_api/cursor", { query: "FOR doc IN @@collection RETURN doc.value1", bindVars: { "@collection": cn }, options: { fillBlockCache } });

  const newValue = db._engineStats()["rocksdb.block-cache-usage"];
  if (fillBlockCache) {
    assertTrue(newValue >= oldValue + 100 * 1000 * 1000, { oldValue, newValue });
  } else {
    // allow for some other background things to be run, thus add 1MB of leeway
    assertTrue(newValue <= oldValue + 1000 * 1000, { oldValue, newValue });
  }

  arango.POST("/_api/cursor", { query: "FOR doc IN @@collection RETURN doc.value1", bindVars: { "@collection": cn }, options: { fillBlockCache } });

  if (internal.platform.substr(0, 3) !== 'win') {
    // for unknown reasons the following does not work reliably on Windows.
    // On Windows, the block cache usage in newValue2 is a lot higher here.
    const newValue2 = db._engineStats()["rocksdb.block-cache-usage"];
    // allow for some other background things to be run, thus add 1MB of leeway
    assertTrue(newValue2 <= newValue + 1000 * 1000, { newValue, newValue2 });
  }
};
<commit_msg>try to improve unstable fillBlockCache test (#14284)<commit_after>/*jshint globalstrict:false, strict:false */
/* global arango, assertTrue, assertEqual */

////////////////////////////////////////////////////////////////////////////////
/// @brief test for server startup options
///
/// DISCLAIMER
///
/// Copyright 2010-2012 triagens GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
///     http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Copyright holder is ArangoDB Inc, Cologne, Germany
///
/// @author Jan Steemann
/// @author Copyright 2019, ArangoDB Inc, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////

const db = require('@arangodb').db;
const internal = require('internal');
const jsunity = require('jsunity');

exports.setup = function(cn) {
  let payload = Array(1024).join("x");
  let c = db._create(cn);
  let docs = [];
  for (let i = 0; i < 250 * 1000; ++i) {
    docs.push({ _key: "test" + i, value1: i, value2: "test" + i, payload });
    if (docs.length === 1000) {
      c.insert(docs);
      docs = [];
    }
  }
};

exports.testDbQuery = function(cn, fillBlockCache) {
  const oldValue = db._engineStats()["rocksdb.block-cache-usage"];
  let result = db._query("FOR doc IN @@collection RETURN doc.value1", { "@collection": cn }, { fillBlockCache }).toArray();
  assertEqual(250 * 1000, result.length);

  const newValue = db._engineStats()["rocksdb.block-cache-usage"];
  if (fillBlockCache) {
    assertTrue(newValue >= oldValue + 100 * 1000 * 1000, { oldValue, newValue });
  } else {
    // allow for some other background things to be run, thus add 1MB of leeway
    assertTrue(newValue <= oldValue + 1000 * 1000, { oldValue, newValue });
  }

  /*
   * for some reason the block cache usage is not 100% deterministic after here.
   * it is probably due to some other unrelated queries running or some RocksDB
   * internals
  result = db._query("FOR doc IN @@collection RETURN doc.value1", { "@collection": cn }, { fillBlockCache }).toArray();
  assertEqual(250 * 1000, result.length);

  if (internal.platform.substr(0, 3) !== 'win') {
    const newValue2 = db._engineStats()["rocksdb.block-cache-usage"];
    // allow for some other background things to be run, thus add 1MB of leeway
    // On Windows, the block cache usage in newValue2 is a lot higher here.
    assertTrue(newValue2 <= newValue + 1000 * 1000, { newValue, newValue2 });
  }
  */
};

exports.testHttpApi = function(cn, fillBlockCache) {
  const oldValue = db._engineStats()["rocksdb.block-cache-usage"];
  arango.POST("/_api/cursor", { query: "FOR doc IN @@collection RETURN doc.value1", bindVars: { "@collection": cn }, options: { fillBlockCache } });

  const newValue = db._engineStats()["rocksdb.block-cache-usage"];
  if (fillBlockCache) {
    assertTrue(newValue >= oldValue + 100 * 1000 * 1000, { oldValue, newValue });
  } else {
    // allow for some other background things to be run, thus add 1MB of leeway
    assertTrue(newValue <= oldValue + 1000 * 1000, { oldValue, newValue });
  }

  arango.POST("/_api/cursor", { query: "FOR doc IN @@collection RETURN doc.value1", bindVars: { "@collection": cn }, options: { fillBlockCache } });

  if (internal.platform.substr(0, 3) !== 'win') {
    // for unknown reasons the following does not work reliably on Windows.
    // On Windows, the block cache usage in newValue2 is a lot higher here.
    const newValue2 = db._engineStats()["rocksdb.block-cache-usage"];
    // allow for some other background things to be run, thus add 1MB of leeway
    assertTrue(newValue2 <= newValue + 1000 * 1000, { newValue, newValue2 });
  }
};
<|endoftext|>


<commit_before>import { combineReducers } from 'redux'

const rootReducer = combineReducers({})

export default rootReducer
<commit_msg>code cleanup<commit_after>import { combineReducers } from 'redux';

const rootReducer = combineReducers({});

export default rootReducer;
<|endoftext|>


<commit_before>// http://dojotoolkit.org/reference-guide/1.9/quickstart/writingWidgets.html
define([
    "dojo/Evented",
    "dojo/_base/declare",
    "dojo/_base/lang",
    "dijit/_WidgetBase",
    "dijit/a11yclick",
    "dijit/_TemplatedMixin",
    "dojo/on",
    // load template
    "dojo/text!./templates/FullScreenMap.html",
    "dojo/i18n!./nls/FullScreenMap",
    "dojo/dom-style",
    "dojo/dom-class",
    "dojo/dom-attr",
    "dojo/domReady!"
],
function (
    Evented,
    declare, lang,
    _WidgetBase, a11yclick, _TemplatedMixin,
    on,
    dijitTemplate,
    i18n,
    domStyle, domClass, domAttr
) {
    return declare("modules.FullScreenMap", [_WidgetBase, _TemplatedMixin, Evented], {
        templateString: dijitTemplate,
        options: {
            map: null,
            visible: true,
            container: null
        },
        // lifecycle: 1
        constructor: function(options, srcRefNode) {
            // css classes
            this.css = {
                fs: "fs",
                toggle: "toggle",
                exit: "exit",
                enter: "enter"
            };
            // language
            this._i18n = i18n;
            // mix in settings and defaults
            var defaults = lang.mixin({}, this.options, options);
            // widget node
            this.domNode = srcRefNode;
            // set map property
            this.set("map", defaults.map);
            this.set("visible", defaults.visible);
            this.set("container", defaults.container);
            // watch for changes
            this.watch("visible", this._visible);
        },
        // _TemplatedMixin implements buildRendering() for you. Use this to override
        // buildRendering: function() {},
        // called after buildRendering() is finished
        postCreate: function() {
            this.own(on(this.buttonNode, a11yclick, lang.hitch(this, this._toggleFullscreen)));
        },
        // start widget. called by user
        startup: function() {
            // set visibility
            this._visible();
            // map not defined
            if (!this.get("map")) {
                console.log('map required');
                this.destroy();
                return;
            }
            if (!this.get("container")) {
                this.set("container", this.map.container);
            }
            // when map is loaded
            if (this.map.loaded) {
                this._init();
            } else {
                on.once(this.map, "load", lang.hitch(this, function() {
                    this._init();
                }));
            }
        },
        // connections/subscriptions will be cleaned up during the destroy() lifecycle phase
        destroy: function() {
            this.inherited(arguments);
        },
        show: function() {
            this.set("visible", true);
        },
        hide: function() {
            this.set("visible", false);
        },
        /* ---------------- */
        /* Public Functions */
        /* ---------------- */
        toggle: function() {
            this._toggleFullscreen();
        },
        refresh: function() {
            var w, h;
            // determine fullscreen state
            var state;
            if (this.get("container").requestFullscreen) {
                state = document.fullScreen;
            } else if (this.get("container").mozRequestFullScreen) {
                state = document.mozFullScreen;
            } else if (this.get("container").webkitRequestFullScreen) {
                state = document.webkitIsFullScreen;
            }
            // set fullscreen status
            this.set("fullscreen", state);
            // if fullscreen is set
            if (this.get("fullscreen")) {
                w = "100%";
                h = "100%";
                domClass.add(this.buttonNode, this.css.exit);
                domClass.remove(this.buttonNode, this.css.enter);
                domAttr.set(this.buttonNode, "title", this._i18n.exit);
            } else {
                w = '';
                h = '';
                domClass.add(this.buttonNode, this.css.enter);
                domClass.remove(this.buttonNode, this.css.exit);
                domAttr.set(this.buttonNode, "title", this._i18n.enter);
            }
            // set map width and height
            domStyle.set(this.get("container"), {
                width: w,
                height: h
            });
            // resize map
            this.map.resize();
            // clear timeout if it exists
            if(this._timeout){
                clearTimeout(this._timeout);
            }
            // re-center map
            this._timeout = setTimeout(lang.hitch(this, function() {
                this.map.centerAt(this._mapCenter);
            }), 500);
        },
        /* ---------------- */
        /* Private Functions */
        /* ---------------- */
        _init: function() {
            // fullscreeen change event
            var changeEvent;
            // enter/exit fullscreen event
            if (this.get("container").requestFullscreen) {
                changeEvent = this.own(on(document, "fullscreenchange", lang.hitch(this, function() {
                    this.refresh();
                })));
            } else if (this.get("container").mozRequestFullScreen) {
                changeEvent = this.own(on(document, "mozfullscreenchange", lang.hitch(this, function() {
                    this.refresh();
                })));
            } else if (this.get("container").webkitRequestFullScreen) {
                changeEvent = this.own(on(document, "webkitfullscreenchange", lang.hitch(this, function() {
                    this.refresh();
                })));
            }
            this.set("loaded", true);
            // emit event
            this.emit("load", {});
        },
        _visible: function() {
            if (this.get("visible")) {
                domStyle.set(this.domNode, 'display', 'block');
            } else {
                domStyle.set(this.domNode, 'display', 'none');
            }
        },
        _toggleFullscreen: function() {
            this._mapCenter = this.map.extent.getCenter();
            if (this.get("fullscreen")) {
                if (document.exitFullscreen) {
                    document.exitFullscreen();
                } else if (document.mozCancelFullScreen) {
                    document.mozCancelFullScreen();
                } else if (document.webkitCancelFullScreen) {
                    document.webkitCancelFullScreen();
                }
            } else {
                if (this.get("container").requestFullscreen) {
                    this.get("container").requestFullscreen();
                } else if (this.get("container").mozRequestFullScreen) {
                    this.get("container").mozRequestFullScreen();
                } else if (this.get("container").webkitRequestFullScreen) {
                    this.get("container").webkitRequestFullScreen();
                }
            }
        }
    });
});<commit_msg>no message<commit_after>// http://dojotoolkit.org/reference-guide/1.9/quickstart/writingWidgets.html
define([
    "dojo/Evented",
    "dojo/_base/declare",
    "dojo/_base/lang",
    "dijit/_WidgetBase",
    "dijit/a11yclick",
    "dijit/_TemplatedMixin",
    "dojo/on",
    // load template
    "dojo/text!application/templates/FullScreenMap.html",
    "dojo/i18n!application/nls/FullScreenMap",
    "dojo/dom-style",
    "dojo/dom-class",
    "dojo/dom-attr",
    "dojo/domReady!"
],
function (
    Evented,
    declare, lang,
    _WidgetBase, a11yclick, _TemplatedMixin,
    on,
    dijitTemplate,
    i18n,
    domStyle, domClass, domAttr
) {
    return declare("modules.FullScreenMap", [_WidgetBase, _TemplatedMixin, Evented], {
        templateString: dijitTemplate,
        options: {
            map: null,
            visible: true,
            container: null
        },
        // lifecycle: 1
        constructor: function(options, srcRefNode) {
            // css classes
            this.css = {
                fs: "fs",
                toggle: "toggle",
                exit: "exit",
                enter: "enter"
            };
            // language
            this._i18n = i18n;
            // mix in settings and defaults
            var defaults = lang.mixin({}, this.options, options);
            // widget node
            this.domNode = srcRefNode;
            // set map property
            this.set("map", defaults.map);
            this.set("visible", defaults.visible);
            this.set("container", defaults.container);
            // watch for changes
            this.watch("visible", this._visible);
        },
        // _TemplatedMixin implements buildRendering() for you. Use this to override
        // buildRendering: function() {},
        // called after buildRendering() is finished
        postCreate: function() {
            this.own(on(this.buttonNode, a11yclick, lang.hitch(this, this._toggleFullscreen)));
        },
        // start widget. called by user
        startup: function() {
            // set visibility
            this._visible();
            // map not defined
            if (!this.get("map")) {
                console.log('map required');
                this.destroy();
                return;
            }
            if (!this.get("container")) {
                this.set("container", this.map.container);
            }
            // when map is loaded
            if (this.map.loaded) {
                this._init();
            } else {
                on.once(this.map, "load", lang.hitch(this, function() {
                    this._init();
                }));
            }
        },
        // connections/subscriptions will be cleaned up during the destroy() lifecycle phase
        destroy: function() {
            this.inherited(arguments);
        },
        show: function() {
            this.set("visible", true);
        },
        hide: function() {
            this.set("visible", false);
        },
        /* ---------------- */
        /* Public Functions */
        /* ---------------- */
        toggle: function() {
            this._toggleFullscreen();
        },
        refresh: function() {
            var w, h;
            // determine fullscreen state
            var state;
            if (this.get("container").requestFullscreen) {
                state = document.fullScreen;
            } else if (this.get("container").mozRequestFullScreen) {
                state = document.mozFullScreen;
            } else if (this.get("container").webkitRequestFullScreen) {
                state = document.webkitIsFullScreen;
            }
            // set fullscreen status
            this.set("fullscreen", state);
            // if fullscreen is set
            if (this.get("fullscreen")) {
                w = "100%";
                h = "100%";
                domClass.add(this.buttonNode, this.css.exit);
                domClass.remove(this.buttonNode, this.css.enter);
                domAttr.set(this.buttonNode, "title", this._i18n.exit);
            } else {
                w = '';
                h = '';
                domClass.add(this.buttonNode, this.css.enter);
                domClass.remove(this.buttonNode, this.css.exit);
                domAttr.set(this.buttonNode, "title", this._i18n.enter);
            }
            // set map width and height
            domStyle.set(this.get("container"), {
                width: w,
                height: h
            });
            // resize map
            this.map.resize();
            // clear timeout if it exists
            if(this._timeout){
                clearTimeout(this._timeout);
            }
            // re-center map
            this._timeout = setTimeout(lang.hitch(this, function() {
                this.map.centerAt(this._mapCenter);
            }), 500);
        },
        /* ---------------- */
        /* Private Functions */
        /* ---------------- */
        _init: function() {
            // fullscreeen change event
            var changeEvent;
            // enter/exit fullscreen event
            if (this.get("container").requestFullscreen) {
                changeEvent = this.own(on(document, "fullscreenchange", lang.hitch(this, function() {
                    this.refresh();
                })));
            } else if (this.get("container").mozRequestFullScreen) {
                changeEvent = this.own(on(document, "mozfullscreenchange", lang.hitch(this, function() {
                    this.refresh();
                })));
            } else if (this.get("container").webkitRequestFullScreen) {
                changeEvent = this.own(on(document, "webkitfullscreenchange", lang.hitch(this, function() {
                    this.refresh();
                })));
            }
            this.set("loaded", true);
            // emit event
            this.emit("load", {});
        },
        _visible: function() {
            if (this.get("visible")) {
                domStyle.set(this.domNode, 'display', 'block');
            } else {
                domStyle.set(this.domNode, 'display', 'none');
            }
        },
        _toggleFullscreen: function() {
            this._mapCenter = this.map.extent.getCenter();
            if (this.get("fullscreen")) {
                if (document.exitFullscreen) {
                    document.exitFullscreen();
                } else if (document.mozCancelFullScreen) {
                    document.mozCancelFullScreen();
                } else if (document.webkitCancelFullScreen) {
                    document.webkitCancelFullScreen();
                }
            } else {
                if (this.get("container").requestFullscreen) {
                    this.get("container").requestFullscreen();
                } else if (this.get("container").mozRequestFullScreen) {
                    this.get("container").mozRequestFullScreen();
                } else if (this.get("container").webkitRequestFullScreen) {
                    this.get("container").webkitRequestFullScreen();
                }
            }
        }
    });
});<|endoftext|>


<commit_before>import React from 'react';
import PropTypes from 'prop-types';

import './action.scss';

class Action extends React.Component {
  constructor(props) {
    super(props);
  }

  render() {
    const action = this.props.action;

    return (

{action.name}

ID

{action.id}

POST TYPE

{action.post_type}

NOUN

{action.noun}

VERB

{action.verb}

REPORTBACK

              {action.reportback === true ? (

Yes

              ) : (

No

              )}

CIVIC ACTION

              {action.civic_action === true ? (

Yes

              ) : (

No

              )}

SCHOLARSHIP

              {action.scholarship_entry === true ? (

Yes

              ) : (

No

              )}

ANONYMOUS POST

              {action.anonymous === true ? (

Yes

              ) : (

No

              )}

    );
  }
}

Action.propTypes = {
  action: PropTypes.object.isRequired,
};

export default Action;
<commit_msg>adds callpower campaign id to campaign id show page<commit_after>import React from 'react';
import PropTypes from 'prop-types';

import './action.scss';

class Action extends React.Component {
  constructor(props) {
    super(props);
  }

  render() {
    const action = this.props.action;

    return (

{action.name}

ID

{action.id}

CALLPOWER CAMPAIGN ID

          {action.callpower_campaign_id ? (

{action.callpower_campaign_id}

          ) : (

-

          )}

POST TYPE

{action.post_type}

NOUN

{action.noun}

VERB

{action.verb}

REPORTBACK

              {action.reportback === true ? (

Yes

              ) : (

No

              )}

CIVIC ACTION

              {action.civic_action === true ? (

Yes

              ) : (

No

              )}

SCHOLARSHIP

              {action.scholarship_entry === true ? (

Yes

              ) : (

No

              )}

ANONYMOUS POST

              {action.anonymous === true ? (

Yes

              ) : (

No

              )}

    );
  }
}

Action.propTypes = {
  action: PropTypes.object.isRequired,
};

export default Action;
<|endoftext|>


<commit_before>import {
  CHANGE_EVENT_RESPONSE_PENDING,
  COMPLETE_POST_PENDING,
  APPEND_COMMENT,
  CREATE_COMMENT,
  CREATE_POST,
  FETCH_POST,
  FETCH_POSTS,
  FETCH_PERSON,
  FIND_OR_CREATE_THREAD,
  FOLLOW_POST_PENDING,
  PIN_POST_PENDING,
  REMOVE_POST,
  UPDATE_POST,
  VOTE_ON_POST_PENDING
} from '../actions'
import { compact, omit, find, some, without, map } from 'lodash'
import { get, isNull, omitBy } from 'lodash/fp'
import { addPersonId, addOrRemovePersonId, mergeList } from './util'

const normalize = (post) => omitBy(isNull, {
  ...post,
  children: post.children ? map(post.children, c => c.id) : null, // FIXME should be child_ids
  numComments: post.num_comments || post.numComments,
  num_comments: null,
  communities: null,
  people: null
})

const normalizeUpdate = (post, params, payload) => {
  const normalized = {
    ...omit(post, 'linkPreview'),
    ...omit(params, 'imageUrl', 'imageRemoved', 'docs', 'removedDocs')
  }
  if (some(payload.children)) {
    normalized.children = map(payload.children, c => c.id)
  }
  return normalized
}

const listWithChildren = (post, payload) => {
  if (payload.children) return [post].concat(payload.children.map(normalize))
  return [post]
}

const changeEventResponse = (post, response, user) => {
  if (!user) return

  var meInResponders = find(post.responders, {id: user.id})
  var responders = without(post.responders, meInResponders)

  if (!meInResponders || meInResponders.response !== response) {
    responders.push({id: user.id, name: user.name, avatar_url: user.avatar_url, response: response})
  }
  return {...post, ...{ responders }}
}

export default function (state = {}, action) {
  const { error, type, payload, meta } = action
  if (error) return state

  let { id, personId } = meta || {}
  let post = state[id]

  switch (type) {
    case FETCH_POSTS:
      return mergeList(state, payload.posts.map(normalize), 'id')
    case CREATE_POST:
    case FETCH_POST:
    case FIND_OR_CREATE_THREAD:
      return mergeList(state, listWithChildren(normalize(payload), payload), 'id')
    case UPDATE_POST:
      post = normalizeUpdate(post, meta.params, payload)
      return mergeList(state, listWithChildren(post, payload), 'id', {drop: ['linkPreview']})
    case CHANGE_EVENT_RESPONSE_PENDING:
      var { response, user } = meta
      return {...state, [id]: changeEventResponse(post, response, user)}
    case VOTE_ON_POST_PENDING:
      return addOrRemovePersonId(state, id, personId, 'voter_ids')
    case REMOVE_POST:
      return {...state, [id]: null}
    case FOLLOW_POST_PENDING:
      return addOrRemovePersonId(state, id, personId, 'follower_ids')
    case APPEND_COMMENT:
    case CREATE_COMMENT:
      const withFollower = addPersonId(state, id, payload.user_id, 'follower_ids')
      return {
        ...withFollower,
        [id]: {
          ...withFollower[id],
          numComments: (get('comments.length', post) || 0) + 1
        }
      }
    case FETCH_PERSON:
      const newPosts = compact([payload.recent_request, payload.recent_offer])
      return mergeList(state, newPosts.map(normalize), 'id')
    case PIN_POST_PENDING:
      post = state[id]
      const membership = get(['memberships', meta.slug], post)
      return {
        ...state,
        [id]: {
          ...post,
          memberships: {
            ...post.memberships,
            [meta.slug]: {...membership, pinned: !get('pinned', membership)}
          }
        }
      }
    case COMPLETE_POST_PENDING:
      return {
        ...state,
        [id]: {
          ...post,
          fulfilled_at: post.fulfilled_at ? null : new Date(0)
        }
      }
  }
  return state
}
<commit_msg>properly normalize comments in posts<commit_after>import {
  CHANGE_EVENT_RESPONSE_PENDING,
  COMPLETE_POST_PENDING,
  APPEND_COMMENT,
  CREATE_COMMENT,
  CREATE_POST,
  FETCH_POST,
  FETCH_POSTS,
  FETCH_PERSON,
  FIND_OR_CREATE_THREAD,
  FOLLOW_POST_PENDING,
  PIN_POST_PENDING,
  REMOVE_POST,
  UPDATE_POST,
  VOTE_ON_POST_PENDING
} from '../actions'
import { compact, omit, find, some, without, map } from 'lodash'
import { get, isNull, omitBy } from 'lodash/fp'
import { addPersonId, addOrRemovePersonId, mergeList } from './util'

const normalize = (post) => omitBy(isNull, {
  ...post,
  children: post.children ? map(post.children, c => c.id) : null, // FIXME should be child_ids
  numComments: post.num_comments || post.numComments,
  num_comments: null,
  comments: null,
  communities: null,
  people: null
})

const normalizeUpdate = (post, params, payload) => {
  const normalized = {
    ...omit(post, 'linkPreview'),
    ...omit(params, 'imageUrl', 'imageRemoved', 'docs', 'removedDocs')
  }
  if (some(payload.children)) {
    normalized.children = map(payload.children, c => c.id)
  }
  return normalized
}

const listWithChildren = (post, payload) => {
  if (payload.children) return [post].concat(payload.children.map(normalize))
  return [post]
}

const changeEventResponse = (post, response, user) => {
  if (!user) return

  var meInResponders = find(post.responders, {id: user.id})
  var responders = without(post.responders, meInResponders)

  if (!meInResponders || meInResponders.response !== response) {
    responders.push({id: user.id, name: user.name, avatar_url: user.avatar_url, response: response})
  }
  return {...post, ...{ responders }}
}

export default function (state = {}, action) {
  const { error, type, payload, meta } = action
  if (error) return state

  let { id, personId } = meta || {}
  let post = state[id]

  switch (type) {
    case FETCH_POSTS:
      return mergeList(state, payload.posts.map(normalize), 'id')
    case CREATE_POST:
    case FETCH_POST:
    case FIND_OR_CREATE_THREAD:
      return mergeList(state, listWithChildren(normalize(payload), payload), 'id')
    case UPDATE_POST:
      post = normalizeUpdate(post, meta.params, payload)
      return mergeList(state, listWithChildren(post, payload), 'id', {drop: ['linkPreview']})
    case CHANGE_EVENT_RESPONSE_PENDING:
      var { response, user } = meta
      return {...state, [id]: changeEventResponse(post, response, user)}
    case VOTE_ON_POST_PENDING:
      return addOrRemovePersonId(state, id, personId, 'voter_ids')
    case REMOVE_POST:
      return {...state, [id]: null}
    case FOLLOW_POST_PENDING:
      return addOrRemovePersonId(state, id, personId, 'follower_ids')
    case APPEND_COMMENT:
    case CREATE_COMMENT:
      const withFollower = addPersonId(state, id, payload.user_id, 'follower_ids')
      return {
        ...withFollower,
        [id]: {
          ...withFollower[id],
          numComments: (get('comments.length', post) || 0) + 1
        }
      }
    case FETCH_PERSON:
      const newPosts = compact([payload.recent_request, payload.recent_offer])
      return mergeList(state, newPosts.map(normalize), 'id')
    case PIN_POST_PENDING:
      post = state[id]
      const membership = get(['memberships', meta.slug], post)
      return {
        ...state,
        [id]: {
          ...post,
          memberships: {
            ...post.memberships,
            [meta.slug]: {...membership, pinned: !get('pinned', membership)}
          }
        }
      }
    case COMPLETE_POST_PENDING:
      return {
        ...state,
        [id]: {
          ...post,
          fulfilled_at: post.fulfilled_at ? null : new Date(0)
        }
      }
  }
  return state
}
<|endoftext|>