<commit_before>#ifndef __browser_html_HtmlElement__
#define __browser_html_HtmlElement__

#ifdef HIDDEN
/**
 * Some code in this file is based on Mootools.net and adapted to the
 * architecture of Bootstrap, with added changes in design and architecture
 * where deemeded necessary.
 * See http://www.bootstrap-js.net/wiki/MootoolsDifferences
 */
#endif

#include "../dom/DomElement.js"
#include "../dom/Document.js"

////////////////////////////////////////////////////////////////////////////////
// HtmlElements

// TODO: find a better workaround for setting Document._elements here:
HtmlElements = Document._elements = DomElements.extend();

////////////////////////////////////////////////////////////////////////////////
// HtmlElement

HtmlElement = DomElement.extend({
	_elements: HtmlElements
});

// DomElement.extend sets inject to the version that does not alter
// Dom / HtmlElements. Set it back here again, as we want everything injected
// into HtmlElement be injeted as a multiplie version into HtmlElements as well.
HtmlElement.inject = DomElement.inject;

// Use the modified inject function from above which injects both into HtmlElement
// and HtmlElements.
HtmlElement.inject({
	getClass: function() {
		return this.$.className;
	},

	modifyClass: function(name, add) {
		if (!this.hasClass(name) ^ !add) // xor
			this.$.className = (add ? this.$.className + ' ' + name :
				this.$.className.replace(name, '')).clean();
		return this;
	},

	addClass: function(name) {
		return this.modifyClass(name, true);
	},

	removeClass: function(name) {
		return this.modifyClass(name, false);
	},

	toggleClass: function(name) {
		return this.modifyClass(name, !this.hasClass(name));
	},

	hasClass: function(name) {
		return this.$.className.contains(name, ' ');
	},

	getHtml: function() {
		return this.$.innerHTML;
	},

	setHtml: function(html) {
		this.$.innerHTML = html;
		return this;
	},

	getText: function() {
		var tag = this.getTag();
		return /^(style|script)$/.test(tag)
			? Browser.IE
				? tag == 'style' ? this.$.styleSheet.cssText : this.getProperty('text')
				: this.$.innerHTML
			: this.$.innerText || this.$.textContent;
	},

	setText: function(text) {
		var tag = this.getTag();
		if (/^(style|script)$/.test(tag)) {
			if (Browser.IE) {
				if (tag == 'style') this.$.styleSheet.cssText = text;
				else this.setProperty('text', text);
			} else {
				this.$.innerHTML = text;
			}
		} else {
			this.$[this.$.innerText !== undefined ? 'innerText' : 'textContent'] = text;
		}
		return this;
	}
});

////////////////////////////////////////////////////////////////////////////////
// toElement conversion for Array and String

Array.inject({
	toElement: function(doc) {
		doc = DomElement.get(doc) || Document;
		// This handles arrays of any of these forms:
		// [tag, properties, content] -> single element is returned
		// [tag, properties] -> single element is returned
		// [tag, content] -> single element is returned
		// [content] -> elements are returned in list

		// content can be:
		// [[tag (,...)], [tag (,...)], [tag (,...)]]
		// [tag (,...)], [tag (,...)], [tag (,...)]

		// Suport both nested and unnested arrays:
		//	['div', { margin: 10 },
		//		['span', { html: 'hello ' }],
		//		['span', { html: 'world!' }]
		//	]
		//	['div', { margin: 10 }, [
		//		['span', { html: 'hello ' }],
		//		['span', { html: 'world!' }]
		//	]]

		var tag = this[0];
		if (typeof tag == 'string') {
			var next = this[1], props = null, index = 1;
			if (/^(object|hash)$/.test(Base.type(next))) {
				props = next;
				index++;
			}
			var element = doc.createElement(tag, props);
			var content = this[index];
			if (content) {
				// Assume content is an array.
				var children = typeof content[0] == 'array' ?
					content : this.slice(index, this.length);
				for (var i = 0, l = children.length; i < l; i++)
					children[i].toElement().insertBottom(element);
			}
			return element;
		} else {
			// Produce a collection of elements, no parent.
			var elements = new HtmlElements();
			for (var i = 0, l = this.length; i < l; i++)
				elements.push(this[i].toElement());
			return elements;
		}
	}
});

String.inject({
	toElement: function(doc) {
		doc = doc || Document;
		// See if it contains tags. If so, produce nodes, otherwise execute
		// the string as a selector
		var match = /^[^<]*(<(.|\s)+>)[^>]*$/.exec(this);
		if (match) {
			// Html code. Conversion to HtmlElements ported from jQuery
			// Trim whitespace, otherwise indexOf won't work as expected
			var str = this.trim().toLowerCase();
			// doc can be native or wrapped:
			var div = DomElement.unwrap(doc.createElement('div'));

			var wrap =
				 // option or optgroup
				!str.indexOf('<opt') &&
				[1, '<select>', '</select>'] ||

				!str.indexOf('<leg') &&
				[1, '<fieldset>', '</fieldset>'] ||

				(!str.indexOf('<thead') || !str.indexOf('<tbody') || !str.indexOf('<tfoot') || !str.indexOf('<colg')) &&
				[1, '
', '
'] ||

				!str.indexOf('<tr') &&
				[2, '

', '

'] ||

			 	//
 matched above
				(!str.indexOf('<td') || !str.indexOf('<th')) &&
				[3, '

', '

'] ||

				!str.indexOf('<col') &&
				[2, '
<colgroup>', '</colgroup>
'] ||

				[0,'',''];

			// Go to html and back, then peel off extra wrappers
			div.innerHTML = wrap[1] + this + wrap[2];

			// Move to the right depth
			while (wrap[0]--)
				div = div.firstChild;

			// Remove IE's autoinserted
 from table fragments
			if (Browser.IE) {
				var els = [];
				if (!str.indexOf('<table') && str.indexOf('<tbody') < 0) {
					// String was a
, *may* have spurious

					els = div.firstChild && div.firstChild.childNodes;
				} else if (wrap[1] == '
' && str.indexOf('<tbody') < 0) {
					// String was a bare
 or

					els = div.childNodes;
				}
				for (var i = els.length - 1; i >= 0 ; --i) {
					var el = els[i];
					if (el.nodeName.toLowerCase() == 'tbody' && !el.childNodes.length)
						el.parentNode.removeChild(el);
				}
			}
			var elements = new HtmlElements(div.childNodes);
			return elements.length == 1 ? elements[0] : elements;
		} else {
			// Simply execute string as dom selector.
			// Make sure doc is wrapped.
			return DomElement.get(doc).getElement(this);
		}
	}
});

#endif // __browser_html_HtmlElement__
<commit_msg>- Use getElements for dom selectors instead of getElement.  - Return a single element when there is only one in the array, otherwise return the array.<commit_after>#ifndef __browser_html_HtmlElement__
#define __browser_html_HtmlElement__

#ifdef HIDDEN
/**
 * Some code in this file is based on Mootools.net and adapted to the
 * architecture of Bootstrap, with added changes in design and architecture
 * where deemeded necessary.
 * See http://www.bootstrap-js.net/wiki/MootoolsDifferences
 */
#endif

#include "../dom/DomElement.js"
#include "../dom/Document.js"

////////////////////////////////////////////////////////////////////////////////
// HtmlElements

// TODO: find a better workaround for setting Document._elements here:
HtmlElements = Document._elements = DomElements.extend();

////////////////////////////////////////////////////////////////////////////////
// HtmlElement

HtmlElement = DomElement.extend({
	_elements: HtmlElements
});

// DomElement.extend sets inject to the version that does not alter
// Dom / HtmlElements. Set it back here again, as we want everything injected
// into HtmlElement be injeted as a multiplie version into HtmlElements as well.
HtmlElement.inject = DomElement.inject;

// Use the modified inject function from above which injects both into HtmlElement
// and HtmlElements.
HtmlElement.inject({
	getClass: function() {
		return this.$.className;
	},

	modifyClass: function(name, add) {
		if (!this.hasClass(name) ^ !add) // xor
			this.$.className = (add ? this.$.className + ' ' + name :
				this.$.className.replace(name, '')).clean();
		return this;
	},

	addClass: function(name) {
		return this.modifyClass(name, true);
	},

	removeClass: function(name) {
		return this.modifyClass(name, false);
	},

	toggleClass: function(name) {
		return this.modifyClass(name, !this.hasClass(name));
	},

	hasClass: function(name) {
		return this.$.className.contains(name, ' ');
	},

	getHtml: function() {
		return this.$.innerHTML;
	},

	setHtml: function(html) {
		this.$.innerHTML = html;
		return this;
	},

	getText: function() {
		var tag = this.getTag();
		return /^(style|script)$/.test(tag)
			? Browser.IE
				? tag == 'style' ? this.$.styleSheet.cssText : this.getProperty('text')
				: this.$.innerHTML
			: this.$.innerText || this.$.textContent;
	},

	setText: function(text) {
		var tag = this.getTag();
		if (/^(style|script)$/.test(tag)) {
			if (Browser.IE) {
				if (tag == 'style') this.$.styleSheet.cssText = text;
				else this.setProperty('text', text);
			} else {
				this.$.innerHTML = text;
			}
		} else {
			this.$[this.$.innerText !== undefined ? 'innerText' : 'textContent'] = text;
		}
		return this;
	}
});

////////////////////////////////////////////////////////////////////////////////
// toElement conversion for Array and String

Array.inject({
	toElement: function(doc) {
		doc = DomElement.get(doc) || Document;
		// This handles arrays of any of these forms:
		// [tag, properties, content] -> single element is returned
		// [tag, properties] -> single element is returned
		// [tag, content] -> single element is returned
		// [content] -> elements are returned in list

		// content can be:
		// [[tag (,...)], [tag (,...)], [tag (,...)]]
		// [tag (,...)], [tag (,...)], [tag (,...)]

		// Suport both nested and unnested arrays:
		//	['div', { margin: 10 },
		//		['span', { html: 'hello ' }],
		//		['span', { html: 'world!' }]
		//	]
		//	['div', { margin: 10 }, [
		//		['span', { html: 'hello ' }],
		//		['span', { html: 'world!' }]
		//	]]

		var tag = this[0];
		if (typeof tag == 'string') {
			var next = this[1], props = null, index = 1;
			if (/^(object|hash)$/.test(Base.type(next))) {
				props = next;
				index++;
			}
			var element = doc.createElement(tag, props);
			var content = this[index];
			if (content) {
				// Assume content is an array.
				var children = typeof content[0] == 'array' ?
					content : this.slice(index, this.length);
				for (var i = 0, l = children.length; i < l; i++)
					children[i].toElement().insertBottom(element);
			}
			return element;
		} else {
			// Produce a collection of elements, no parent.
			var elements = new HtmlElements();
			for (var i = 0, l = this.length; i < l; i++)
				elements.push(this[i].toElement());
			return elements;
		}
	}
});

String.inject({
	toElement: function(doc) {
		doc = doc || Document;
		// See if it contains tags. If so, produce nodes, otherwise execute
		// the string as a selector
		var match = /^[^<]*(<(.|\s)+>)[^>]*$/.exec(this), elements;
		if (match) {
			// Html code. Conversion to HtmlElements ported from jQuery
			// Trim whitespace, otherwise indexOf won't work as expected
			var str = this.trim().toLowerCase();
			// doc can be native or wrapped:
			var div = DomElement.unwrap(doc.createElement('div'));

			var wrap =
				 // option or optgroup
				!str.indexOf('<opt') &&
				[1, '<select>', '</select>'] ||

				!str.indexOf('<leg') &&
				[1, '<fieldset>', '</fieldset>'] ||

				(!str.indexOf('<thead') || !str.indexOf('<tbody') || !str.indexOf('<tfoot') || !str.indexOf('<colg')) &&
				[1, '
', '
'] ||

				!str.indexOf('<tr') &&
				[2, '

', '

'] ||

			 	//
 matched above
				(!str.indexOf('<td') || !str.indexOf('<th')) &&
				[3, '

', '

'] ||

				!str.indexOf('<col') &&
				[2, '
<colgroup>', '</colgroup>
'] ||

				[0,'',''];

			// Go to html and back, then peel off extra wrappers
			div.innerHTML = wrap[1] + this + wrap[2];

			// Move to the right depth
			while (wrap[0]--)
				div = div.firstChild;

			// Remove IE's autoinserted
 from table fragments
			if (Browser.IE) {
				var els = [];
				if (!str.indexOf('<table') && str.indexOf('<tbody') < 0) {
					// String was a
, *may* have spurious

					els = div.firstChild && div.firstChild.childNodes;
				} else if (wrap[1] == '
' && str.indexOf('<tbody') < 0) {
					// String was a bare
 or

					els = div.childNodes;
				}
				for (var i = els.length - 1; i >= 0 ; --i) {
					var el = els[i];
					if (el.nodeName.toLowerCase() == 'tbody' && !el.childNodes.length)
						el.parentNode.removeChild(el);
				}
			}
			elements = new HtmlElements(div.childNodes);
		} else {
			// Simply execute string as dom selector.
			// Make sure doc is wrapped.
			elements = DomElement.get(doc).getElements(this);
		}
		return elements.length == 1 ? elements[0] : elements;
	}
});

#endif // __browser_html_HtmlElement__
<|endoftext|>


<commit_before>var Model = require('./Model');
var triggerParams = require('./mixins/triggerParams');
var volumeParams = require('./mixins/volumeParams');
var connectable = require('./mixins/connectable');
var bypassable = require('./mixins/bypassable');
var Params = require('./Params');

var context = null;

function createPool (factoryName) {
  var nodes = [];
  return function pool(node) {
    if (node) {
      nodes.push(node);
    }
    else if (nodes.length) {
      return nodes.shift();
    }
    else {
      return context[factoryName]();
    }
  };
}

var gainPool = createPool('createGain');
var pannerPool = createPool('createPanner');

var destination = null;

var Layer = Model.extend(triggerParams, volumeParams, {

  type: 'layer',

  props: {
    sources: ['object', true, function () { return {}; }]
  },

  start: function (time, note, channel, pattern, kit, slot) {
    if (this.mute) { return; }

    if (typeof time !== 'number') {
      pattern = channel;
      channel = note;
      note = time;
      time = this.context.currentTime;
    }
    note = note || {};

    context = context || this.context;

    var params = this._params(note, channel, pattern, kit, slot);
    var source = this._source(params);

    if (source) {
      var connections = this._getConnections(note, channel, pattern);
      var destination = this._connectDestination(connections, params);
      var gain = source._gain = gainPool();
      this._configureAttack(time, params, gain, destination);
      var panner = this._configurePan(params, gain);
      source.connect(panner || gain);

      this._startSource(time, params, source);

      this._triggerPlaybackStateEvent('started', time, params, note, channel, pattern, kit, slot);

      var cid = note.cid || 'null';
      this.sources[cid] = this.sources[cid] || [];
      this.sources[cid].push(source);

      if (params.length) {
        var stopTime = this._getStopTime(time, params, source);
        this.stop(stopTime, note, channel, pattern);
      }

      source.onended = function () {
        var index = this.sources[cid].indexOf(source);
        this.sources[cid].splice(index, 1);

        gain.disconnect();
        source.disconnect();
        if (panner) {
          panner.disconnect();
          pannerPool(panner);
        }
        gainPool(gain);

        this._triggerPlaybackStateEvent('stopped', this.context.currentTime, params, note, channel, pattern, kit, slot);

        source = source.onended = source._gain = gain = panner = null;

        if (typeof note.after === 'function') note.after();
      }.bind(this);
    }
  },

  _getStopTime: function (time, params, source) {
    return time + params.length;
  },

  _triggerPlaybackStateEvent: function(event, time, params, note, channel, pattern, kit, slot) {
    var lookahead = Math.floor((time - context.currentTime) * 1000) - 1;
    if (lookahead < 0) lookahead = 0;
    setTimeout(function () {
      [note, channel, pattern, kit, slot, this].forEach(function (target) {
        target.trigger(event, note, params)
      });
    }, lookahead);
  },

  stop: function (time, note, channel, pattern, kit, slot) {
    if (typeof time !== 'number') {
      pattern = channel;
      channel = note;
      note = time;
      time = this.context.currentTime;
    }
    note = note || {};

    var params = this._params(note, channel, pattern, kit, slot);
    var cid = note.cid || 'null';
    var sources = this.sources[cid] || [];

    if (cid === 'null') {
      sources = [];
      Object.keys(this.sources).forEach(function (cid) {
        sources = sources.concat(this.sources[cid]);
      }.bind(this));
    }

    sources.forEach(function (source) {
      if (source._gain) {
        this._configureRelease(time, params, source._gain);
      }
      this._stopSource(time, params, source);
    }.bind(this));
  },

  _paramsSources: function (note, channel, pattern, kit, slot) {
    slot = slot || this.collection && this.collection.parent || {};
    kit = kit || slot && slot.kit || {};
    var patternParams = {
      volume: pattern && pattern.volume,
      pitch: pattern && pattern.pitch,
      pan: pattern && pattern.pan
    };
    return [note, channel, patternParams, this, slot, kit];
  },

  _params: function (note, channel, pattern, kit, slot) {
    var sources = this._paramsSources(note, channel, pattern, kit, slot);
    return Params.fromSources(sources);
  },

  _getConnections: function (note, channel, pattern) {
    var sources = this._paramsSources(note, channel, pattern);
    var connections = [];
    sources.forEach(function (source) {
      if (source && source.connections) {
        connections = connections.concat(source.connections);
      }
    });
    return connections;
  },

  _createGain: function (params, source) {
    return this.context.createGain();
  },

  _startSource: function (time, params, source) {
    source.start(time);
  },

  _stopSource: function (time, params, source) {
    source.stop(time);
  },

  _source: function (params) {
    throw new Error('Required method "_source" is not implemented for ' + this.cid);
  },

  _getLocalDestination: function () {

    if (!destination) {
      destination = gainPool();
      destination.connect(this.context.destination);
    }
    destination.gain.value = (this.vent.bap.volume / 100) * 0.8;
    return destination;
  },

  _connectDestination: function (connections, params) {

    var localDestination = this._getLocalDestination();
    if (params.bypass === true) return localDestination;
    var cid = this.cid;

    connections.filter(function (connection) {
      if (params.bypass === connection.type || Array.isArray(params.bypass) && ~params.bypass.indexOf(connection.type)) return false;
      return !connection.bypass;
    }).reverse().forEach(function (connection, index, list) {
      var next = list[index - 1];
      var node = connection.getNode(next && next.cid || 'destination');
      if (node.__connectedTo && node.__connectedTo !== localDestination) {
        console.error('Attempted to reconnect already connected effect (' + connection.cid + ') for target ' + cid);
      }
      else if (!node._connectedTo) {
        node.connect(localDestination);
        node._connectedTo = localDestination;
      }
      localDestination = node;
    });

    return localDestination;
  },

  _configurePan: function (params, out) {
    if (params.pan !== 0) {
      var panner = pannerPool();
      var x = params.pan / 100;
      var z = 1 - Math.abs(x);
      panner.setPosition(x, 0, z);
      panner.connect(out);
      return panner;
    }
  },

  _configureAttack: function (time, params, gain, destination) {
    var volume = (params.volume !== null && params.volume !== undefined ? params.volume : 100) / 100;
    gain.connect(destination);
    gain.gain.value = 0;
    gain.gain.setValueAtTime(0, time);
    gain.gain.linearRampToValueAtTime(volume, time + params.attack);
  },

  _configureRelease: function (time, params, gain) {
    var volume = (params.volume !== null && params.volume !== undefined ? params.volume : 100) / 100;
    if (params.release) {
      gain.gain.cancelScheduledValues(time - 0.001);
      gain.gain.linearRampToValueAtTime(volume, time - params.release);
      gain.gain.linearRampToValueAtTime(0, time);
    }
  }
}, connectable);

module.exports = Layer;
<commit_msg>Fix missing semicolon<commit_after>var Model = require('./Model');
var triggerParams = require('./mixins/triggerParams');
var volumeParams = require('./mixins/volumeParams');
var connectable = require('./mixins/connectable');
var bypassable = require('./mixins/bypassable');
var Params = require('./Params');

var context = null;

function createPool (factoryName) {
  var nodes = [];
  return function pool(node) {
    if (node) {
      nodes.push(node);
    }
    else if (nodes.length) {
      return nodes.shift();
    }
    else {
      return context[factoryName]();
    }
  };
}

var gainPool = createPool('createGain');
var pannerPool = createPool('createPanner');

var destination = null;

var Layer = Model.extend(triggerParams, volumeParams, {

  type: 'layer',

  props: {
    sources: ['object', true, function () { return {}; }]
  },

  start: function (time, note, channel, pattern, kit, slot) {
    if (this.mute) { return; }

    if (typeof time !== 'number') {
      pattern = channel;
      channel = note;
      note = time;
      time = this.context.currentTime;
    }
    note = note || {};

    context = context || this.context;

    var params = this._params(note, channel, pattern, kit, slot);
    var source = this._source(params);

    if (source) {
      var connections = this._getConnections(note, channel, pattern);
      var destination = this._connectDestination(connections, params);
      var gain = source._gain = gainPool();
      this._configureAttack(time, params, gain, destination);
      var panner = this._configurePan(params, gain);
      source.connect(panner || gain);

      this._startSource(time, params, source);

      this._triggerPlaybackStateEvent('started', time, params, note, channel, pattern, kit, slot);

      var cid = note.cid || 'null';
      this.sources[cid] = this.sources[cid] || [];
      this.sources[cid].push(source);

      if (params.length) {
        var stopTime = this._getStopTime(time, params, source);
        this.stop(stopTime, note, channel, pattern);
      }

      source.onended = function () {
        var index = this.sources[cid].indexOf(source);
        this.sources[cid].splice(index, 1);

        gain.disconnect();
        source.disconnect();
        if (panner) {
          panner.disconnect();
          pannerPool(panner);
        }
        gainPool(gain);

        this._triggerPlaybackStateEvent('stopped', this.context.currentTime, params, note, channel, pattern, kit, slot);

        source = source.onended = source._gain = gain = panner = null;

        if (typeof note.after === 'function') note.after();
      }.bind(this);
    }
  },

  _getStopTime: function (time, params, source) {
    return time + params.length;
  },

  _triggerPlaybackStateEvent: function(event, time, params, note, channel, pattern, kit, slot) {
    var lookahead = Math.floor((time - context.currentTime) * 1000) - 1;
    if (lookahead < 0) lookahead = 0;
    setTimeout(function () {
      [note, channel, pattern, kit, slot, this].forEach(function (target) {
        target.trigger(event, note, params);
      });
    }, lookahead);
  },

  stop: function (time, note, channel, pattern, kit, slot) {
    if (typeof time !== 'number') {
      pattern = channel;
      channel = note;
      note = time;
      time = this.context.currentTime;
    }
    note = note || {};

    var params = this._params(note, channel, pattern, kit, slot);
    var cid = note.cid || 'null';
    var sources = this.sources[cid] || [];

    if (cid === 'null') {
      sources = [];
      Object.keys(this.sources).forEach(function (cid) {
        sources = sources.concat(this.sources[cid]);
      }.bind(this));
    }

    sources.forEach(function (source) {
      if (source._gain) {
        this._configureRelease(time, params, source._gain);
      }
      this._stopSource(time, params, source);
    }.bind(this));
  },

  _paramsSources: function (note, channel, pattern, kit, slot) {
    slot = slot || this.collection && this.collection.parent || {};
    kit = kit || slot && slot.kit || {};
    var patternParams = {
      volume: pattern && pattern.volume,
      pitch: pattern && pattern.pitch,
      pan: pattern && pattern.pan
    };
    return [note, channel, patternParams, this, slot, kit];
  },

  _params: function (note, channel, pattern, kit, slot) {
    var sources = this._paramsSources(note, channel, pattern, kit, slot);
    return Params.fromSources(sources);
  },

  _getConnections: function (note, channel, pattern) {
    var sources = this._paramsSources(note, channel, pattern);
    var connections = [];
    sources.forEach(function (source) {
      if (source && source.connections) {
        connections = connections.concat(source.connections);
      }
    });
    return connections;
  },

  _createGain: function (params, source) {
    return this.context.createGain();
  },

  _startSource: function (time, params, source) {
    source.start(time);
  },

  _stopSource: function (time, params, source) {
    source.stop(time);
  },

  _source: function (params) {
    throw new Error('Required method "_source" is not implemented for ' + this.cid);
  },

  _getLocalDestination: function () {

    if (!destination) {
      destination = gainPool();
      destination.connect(this.context.destination);
    }
    destination.gain.value = (this.vent.bap.volume / 100) * 0.8;
    return destination;
  },

  _connectDestination: function (connections, params) {

    var localDestination = this._getLocalDestination();
    if (params.bypass === true) return localDestination;
    var cid = this.cid;

    connections.filter(function (connection) {
      if (params.bypass === connection.type || Array.isArray(params.bypass) && ~params.bypass.indexOf(connection.type)) return false;
      return !connection.bypass;
    }).reverse().forEach(function (connection, index, list) {
      var next = list[index - 1];
      var node = connection.getNode(next && next.cid || 'destination');
      if (node.__connectedTo && node.__connectedTo !== localDestination) {
        console.error('Attempted to reconnect already connected effect (' + connection.cid + ') for target ' + cid);
      }
      else if (!node._connectedTo) {
        node.connect(localDestination);
        node._connectedTo = localDestination;
      }
      localDestination = node;
    });

    return localDestination;
  },

  _configurePan: function (params, out) {
    if (params.pan !== 0) {
      var panner = pannerPool();
      var x = params.pan / 100;
      var z = 1 - Math.abs(x);
      panner.setPosition(x, 0, z);
      panner.connect(out);
      return panner;
    }
  },

  _configureAttack: function (time, params, gain, destination) {
    var volume = (params.volume !== null && params.volume !== undefined ? params.volume : 100) / 100;
    gain.connect(destination);
    gain.gain.value = 0;
    gain.gain.setValueAtTime(0, time);
    gain.gain.linearRampToValueAtTime(volume, time + params.attack);
  },

  _configureRelease: function (time, params, gain) {
    var volume = (params.volume !== null && params.volume !== undefined ? params.volume : 100) / 100;
    if (params.release) {
      gain.gain.cancelScheduledValues(time - 0.001);
      gain.gain.linearRampToValueAtTime(volume, time - params.release);
      gain.gain.linearRampToValueAtTime(0, time);
    }
  }
}, connectable);

module.exports = Layer;
<|endoftext|>


<commit_before>(function(module) {
  var webDB = {};

  // Private function to configure the underlying database connection via the html5sql library:
  function _config(isVerbose) {
    var msg;
    if (isVerbose) {
      html5sql.logInfo = true;
      html5sql.logErrors = true;
      html5sql.putSelectResultsInArray = true;
      msg = 'html5sql verbosity on';
    } else {
      html5sql.logInfo = false;
      html5sql.logErrors = false;
      html5sql.putSelectResultsInArray = false;
      msg = 'html5sql verbosity off';
    }
    // console.log(msg);
  };

  // Public interface method to set up the initial database connection:
  webDB.init = function(isVerbose) {
    // Open and init DB
    try {
      if (openDatabase) {
        _config(isVerbose);
        html5sql.openDatabase('inboxHealth', 'inboxHealth Database', 5*1024*1024);
      } else {
        console.log('Web Databases not supported.');
      }
    } catch (e) {
      console.error('Error occured during DB init. Web Database may not be supported.');
    }
  };

  // Public interface method to run some SQL and pass the result to a callback function:
  webDB.execute = function (sql, callback) {
    callback = callback || function() {};
    html5sql.process(
      sql,
      function (tx, result, resultArray) {
        callback(resultArray, result, tx); // Reorder the args, because we usually want JUST the resultArray.
      }
    );
  };

  module.webDB = webDB;
})(window);

// We can go ahead and set up the basic db connection now:
// webDB.init(true);
<commit_msg>webDB<commit_after>(function(module) {
  var webDB = {};

  // Private function to configure the underlying database connection via the html5sql library:
  function _config(isVerbose) {
    var msg;
    if (isVerbose) {
      html5sql.logInfo = true;
      html5sql.logErrors = true;
      html5sql.putSelectResultsInArray = true;
      msg = 'html5sql verbosity on';
    } else {
      html5sql.logInfo = false;
      html5sql.logErrors = false;
      html5sql.putSelectResultsInArray = false;
      msg = 'html5sql verbosity off';
    }
    // console.log(msg);
  };

  // Public interface method to set up the initial database connection:
  // webDB.init = function(isVerbose) {
  //   // Open and init DB
  //   try {
  //     if (openDatabase) {
  //       _config(isVerbose);
  //       html5sql.openDatabase('inboxHealth', 'inboxHealth Database', 5*1024*1024);
  //     } else {
  //       console.log('Web Databases not supported.');
  //     }
  //   } catch (e) {
  //     console.error('Error occured during DB init. Web Database may not be supported.');
  //   }
  // };

  // Public interface method to run some SQL and pass the result to a callback function:
  webDB.execute = function (sql, callback) {
    callback = callback || function() {};
    html5sql.process(
      sql,
      function (tx, result, resultArray) {
        callback(resultArray, result, tx); // Reorder the args, because we usually want JUST the resultArray.
      }
    );
  };

  module.webDB = webDB;
})(window);

// We can go ahead and set up the basic db connection now:
// webDB.init(true);
try {
  html5sql.openDatabase('inboxHealth', 'inboxHealth Database', 5*1024*1024);
}catch(error) {
  console.error('Database create failed: ' + error.message);
}
<|endoftext|>


<commit_before>var Canvas = require('canvas'),
    Image = Canvas.Image,
    qr = require('qr-image'),
    fs = require('fs'),
    argv = require('optimist')
    .default('s', "")
    .default('c', "http://www.parkschei.be")
    .default('f', 'png')
    .default('t', './output/')
    .default('color', '#2980b9')
    .argv;

var args = process.argv;

var codecontent = argv.c;

var code = qr.matrix(codecontent, 'H');
var codeBlocks = code.length;
var markerWidth = 7;

var color1 = 'black';
var color2 = argv.color;

var margin = 146;

var fullWidth = 2185;

var codeWidth = Math.sqrt(Math.pow(fullWidth - margin * 2, 2) * .5);
var blockWidth = codeWidth / codeBlocks;

var totalBlocks = fullWidth / blockWidth;

var raster = Math.floor(fullWidth / blockWidth);

var blockOriginXY = (raster - codeBlocks) / 2;

var canvas = new Canvas(fullWidth, fullWidth);
var ctx = canvas.getContext('2d');

var isMarker = function(x, y) {

    var markl = markerWidth;
    var markr = codeBlocks - markl - 1;
    if ((x < markl && y < markl) || (x > markr && y < markl) || (x < markl && y > markr)) {
        return true;
    } else {
        return false;
    }

}

var addDot = function(x, y) {

    var variance = .18;

    var cx = x * blockWidth + blockWidth * .5;
    var cy = y * blockWidth + blockWidth * .5;
    var r = blockWidth * .5 - (Math.random() * variance) * blockWidth;
    var color = Math.random() > .5 ? color1 : color2;

    ctx.beginPath();
    ctx.arc(cx, cy, r, 0, 2 * Math.PI, false);
    ctx.fillStyle = color;
    ctx.fill();
}

var addText = function(text, bold) {
    var idx = 0;
    while (idx < text.length) {
        textChars.push([text.charAt(idx), bold]);
        idx++;
    }
}

var writeText = function() {

    var radius = fullWidth / 2;
    var outer = radius - 2;
    var inner = radius - margin + margin * .5;
    var textradius = inner + (outer - inner) * .5 - 25;
    var centerXY = fullWidth / 2;
    charAngle *= Math.PI / 180;

    var font = (outer - inner) * 1.4 + 'px BPDots';

    ctx.textBaseline = 'middle';
    ctx.textAlign = 'left';
    ctx.font = font;

    var angle = textStartAngle * Math.PI / 180;

    ctx.save();

    for (var idx = 0; idx < textChars.length; idx++) {
        var character = textChars[idx][0];
        var col = textChars[idx][1] || color1;
        character = character.toUpperCase();

        ctx.save();
        ctx.beginPath();
        ctx.translate(centerXY + Math.cos(angle) * textradius, centerXY - Math.sin(angle) * textradius);
        ctx.rotate(Math.PI / 2 - angle);
        ctx.fillStyle = col;
        ctx.fillText(character, 0, 0);
        ctx.restore()

        angle -= charAngle;

    }
    ctx.restore();

}

var isInCircle = function(x, y) {

    x *= blockWidth;
    y *= blockWidth;

    return Math.sqrt(Math.pow(x - fullWidth / 2, 2) + Math.pow(y - fullWidth / 2, 2)) < fullWidth / 2 - margin;
}

var addMarker = function(x, y) {

    x *= blockWidth;
    y *= blockWidth;

    var size = (markerWidth - 2) * blockWidth;

    ctx.beginPath();
    ctx.rect(x, y, blockWidth * markerWidth, blockWidth * markerWidth);
    ctx.fillStyle = color1;
    ctx.fill();

    if (argv.f == 'jpg') {
        ctx.fillStyle = "white";
        ctx.fillRect(x + blockWidth, y + blockWidth, size, size);
    } else {
        ctx.clearRect(x + blockWidth, y + blockWidth, size, size);
    }

    ctx.beginPath();
    ctx.rect(x + blockWidth * 2, y + blockWidth * 2, blockWidth * 3, blockWidth * 3);
    ctx.fillStyle = color1;
    ctx.fill();
}

if (argv.f == 'jpg') {
    ctx.fillStyle = "white";
    ctx.fillRect(0, 0, fullWidth, fullWidth);
}

// CODE

for (var x = 0; x < codeBlocks; x++) {
    for (var y = 0; y < codeBlocks; y++) {

        if (!isMarker(x, y) && code[y][x] == 1) {
            addDot(x + blockOriginXY, y + blockOriginXY);

        }
    }
}

//DECO

for (var x = 0; x < totalBlocks; x++) {
    for (var y = 0; y < totalBlocks; y++) {

        var leftDeco = x + 1 < blockOriginXY;
        var rightDeco = x > totalBlocks - blockOriginXY;
        var topDeco = y + 1 < blockOriginXY;
        var bottomDeco = y > totalBlocks - blockOriginXY;

        if ((leftDeco || rightDeco || topDeco || bottomDeco) && isInCircle(x, y) && Math.random() > .5) {
            addDot(x, y);
        }
    }
}

//MARKER

addMarker(blockOriginXY, blockOriginXY);
addMarker(blockOriginXY, blockOriginXY + codeBlocks - markerWidth);
addMarker(blockOriginXY + codeBlocks - markerWidth, blockOriginXY);

//TEXT

var customText = argv.s.length > 0 ? argv.s + " " : "";
var charAngle = 3.5;

var textStartAngle = (customText.length / 2) * charAngle - 45;

var textChars = [];

var maxChars = (360 / charAngle);

addText(customText, color2);
addText("Parkscheibe ", color1);
addText("Berlin ", color1);
addText("Kreuzberg ", color1);
addText("Ultimate ", color1);
var oCount = maxChars - textChars.length - 9;
var fireText = "m";
for (var i = 0; i < oCount; i++) {
    fireText += "o";
}
fireText += "re fire";
addText(fireText, color1);
writeText();

//EXPORT

var filename = Date.now() + "_" + new Buffer(codecontent).toString('base64')

if (argv.f == 'png') {

    var pngfile = fs.createWriteStream(argv.t + filename + ".png"),
        stream = canvas.pngStream();

    stream.on("data", function(chunk) {
        pngfile.write(chunk);
    });
    stream.on("end", function() {
        console.log("saved " + filename);
    });
} else if (argv.f == 'jpg') {
    var jpgfile = fs.createWriteStream(argv.t + filename + '.jpg'),
        stream = canvas.jpegStream({
            bufsize: 4096,
            quality: 100
        });

    stream.on("data", function(chunk) {
        jpgfile.write(chunk);
    });
    stream.on("end", function() {
        console.log("saved " + filename);
    });
}
<commit_msg>added string cast for custom text<commit_after>var Canvas = require('canvas'),
    Image = Canvas.Image,
    qr = require('qr-image'),
    fs = require('fs'),
    argv = require('optimist')
    .string('s')
    .default('s', "")
    .string('c')
    .default('c', "http://www.parkschei.be")
    .default('f', 'png')
    .default('t', './output/')
    .string('color')
    .default('color', '#2980b9')
    .argv;

var args = process.argv;

var codecontent = argv.c;

var code = qr.matrix(codecontent, 'H');
var codeBlocks = code.length;
var markerWidth = 7;

var color1 = 'black';
var color2 = argv.color;

var margin = 146;

var fullWidth = 2185;

var codeWidth = Math.sqrt(Math.pow(fullWidth - margin * 2, 2) * .5);
var blockWidth = codeWidth / codeBlocks;

var totalBlocks = fullWidth / blockWidth;

var raster = Math.floor(fullWidth / blockWidth);

var blockOriginXY = (raster - codeBlocks) / 2;

var canvas = new Canvas(fullWidth, fullWidth);
var ctx = canvas.getContext('2d');

var isMarker = function(x, y) {

    var markl = markerWidth;
    var markr = codeBlocks - markl - 1;
    if ((x < markl && y < markl) || (x > markr && y < markl) || (x < markl && y > markr)) {
        return true;
    } else {
        return false;
    }

}

var addDot = function(x, y) {

    var variance = .18;

    var cx = x * blockWidth + blockWidth * .5;
    var cy = y * blockWidth + blockWidth * .5;
    var r = blockWidth * .5 - (Math.random() * variance) * blockWidth;
    var color = Math.random() > .5 ? color1 : color2;

    ctx.beginPath();
    ctx.arc(cx, cy, r, 0, 2 * Math.PI, false);
    ctx.fillStyle = color;
    ctx.fill();
}

var addText = function(text, bold) {
    var idx = 0;
    while (idx < text.length) {
        textChars.push([text.charAt(idx), bold]);
        idx++;
    }
}

var writeText = function() {

    var radius = fullWidth / 2;
    var outer = radius - 2;
    var inner = radius - margin + margin * .5;
    var textradius = inner + (outer - inner) * .5 - 25;
    var centerXY = fullWidth / 2;
    charAngle *= Math.PI / 180;

    var font = (outer - inner) * 1.4 + 'px BPDots';

    ctx.textBaseline = 'middle';
    ctx.textAlign = 'left';
    ctx.font = font;

    var angle = textStartAngle * Math.PI / 180;

    ctx.save();

    for (var idx = 0; idx < textChars.length; idx++) {
        var character = textChars[idx][0];
        var col = textChars[idx][1] || color1;
        character = character.toUpperCase();

        ctx.save();
        ctx.beginPath();
        ctx.translate(centerXY + Math.cos(angle) * textradius, centerXY - Math.sin(angle) * textradius);
        ctx.rotate(Math.PI / 2 - angle);
        ctx.fillStyle = col;
        ctx.fillText(character, 0, 0);
        ctx.restore()

        angle -= charAngle;

    }
    ctx.restore();

}

var isInCircle = function(x, y) {

    x *= blockWidth;
    y *= blockWidth;

    return Math.sqrt(Math.pow(x - fullWidth / 2, 2) + Math.pow(y - fullWidth / 2, 2)) < fullWidth / 2 - margin;
}

var addMarker = function(x, y) {

    x *= blockWidth;
    y *= blockWidth;

    var size = (markerWidth - 2) * blockWidth;

    ctx.beginPath();
    ctx.rect(x, y, blockWidth * markerWidth, blockWidth * markerWidth);
    ctx.fillStyle = color1;
    ctx.fill();

    if (argv.f == 'jpg') {
        ctx.fillStyle = "white";
        ctx.fillRect(x + blockWidth, y + blockWidth, size, size);
    } else {
        ctx.clearRect(x + blockWidth, y + blockWidth, size, size);
    }

    ctx.beginPath();
    ctx.rect(x + blockWidth * 2, y + blockWidth * 2, blockWidth * 3, blockWidth * 3);
    ctx.fillStyle = color1;
    ctx.fill();
}

if (argv.f == 'jpg') {
    ctx.fillStyle = "white";
    ctx.fillRect(0, 0, fullWidth, fullWidth);
}

// CODE

for (var x = 0; x < codeBlocks; x++) {
    for (var y = 0; y < codeBlocks; y++) {

        if (!isMarker(x, y) && code[y][x] == 1) {
            addDot(x + blockOriginXY, y + blockOriginXY);

        }
    }
}

//DECO

for (var x = 0; x < totalBlocks; x++) {
    for (var y = 0; y < totalBlocks; y++) {

        var leftDeco = x + 1 < blockOriginXY;
        var rightDeco = x > totalBlocks - blockOriginXY;
        var topDeco = y + 1 < blockOriginXY;
        var bottomDeco = y > totalBlocks - blockOriginXY;

        if ((leftDeco || rightDeco || topDeco || bottomDeco) && isInCircle(x, y) && Math.random() > .5) {
            addDot(x, y);
        }
    }
}

//MARKER

addMarker(blockOriginXY, blockOriginXY);
addMarker(blockOriginXY, blockOriginXY + codeBlocks - markerWidth);
addMarker(blockOriginXY + codeBlocks - markerWidth, blockOriginXY);

//TEXT

var customText = argv.s.length > 0 ? argv.s + " " : "";
var charAngle = 3.5;

var textStartAngle = (customText.length / 2) * charAngle - 45;

var textChars = [];

var maxChars = (360 / charAngle);

addText(customText, color2);
addText("Parkscheibe ", color1);
addText("Berlin ", color1);
addText("Kreuzberg ", color1);
addText("Ultimate ", color1);
var oCount = maxChars - textChars.length - 9;
var fireText = "m";
for (var i = 0; i < oCount; i++) {
    fireText += "o";
}
fireText += "re fire";
addText(fireText, color1);
writeText();

//EXPORT

var filename = Date.now() + "_" + new Buffer(codecontent).toString('base64')

if (argv.f == 'png') {

    var pngfile = fs.createWriteStream(argv.t + filename + ".png"),
        stream = canvas.pngStream();

    stream.on("data", function(chunk) {
        pngfile.write(chunk);
    });
    stream.on("end", function() {
        console.log("saved " + filename);
    });
} else if (argv.f == 'jpg') {
    var jpgfile = fs.createWriteStream(argv.t + filename + '.jpg'),
        stream = canvas.jpegStream({
            bufsize: 4096,
            quality: 100
        });

    stream.on("data", function(chunk) {
        jpgfile.write(chunk);
    });
    stream.on("end", function() {
        console.log("saved " + filename);
    });
}
<|endoftext|>


<commit_before>// 35-001 #1078 GM links with prefix mutex are not available to all
// Previously the page displayed an online button
//
casper.test.begin('m35_001 #107 GM links with prefix mutex not available to all', 3, function suite(test) {
casper.echo("Test environment: "+SERVER);
var USECASE='/item/7765485';
var ENTITY=SERVER+USECASE;
	casper.start(ENTITY, function() {
	test.assertTextExists('Autonomic networking' , 'matched title');
	test.assertTextExists('George Mason' , 'found George Mason holding');
	test.assertTextExists('GM only' , 'found note: GM only');
    }).run(function() {
        test.done();
    });
});
<commit_msg>revised bibid use case<commit_after>// 35-001 #1078 GM links with prefix mutex are not available to all
// Previously the page displayed an online button
//
casper.test.begin('m35_001 #107 GM links with prefix mutex not available to all', 3, function suite(test) {
casper.echo("Test environment: "+SERVER);
var USECASE='/item/7114183';
var ENTITY=SERVER+USECASE;
	casper.start(ENTITY, function() {
	test.assertTextExists('Autonomic networking' , 'matched title');
	test.assertTextExists('George Mason' , 'found George Mason holding');
	test.assertTextExists('GM only' , 'found note: GM only');
    }).run(function() {
        test.done();
    });
});
<|endoftext|>


<commit_before>/*!
 * hostsPlus
 *
 * @author Yanis.Wang<yanis.wang@gmail.com>
 *
 */
(function($,_win,undefined){

	var hosts={};
	var hostsPath = '';

	if(isWin)hostsPath = 'C:/Windows/System32/drivers/etc/hosts';
	else if(isLinux)hostsPath = '/etc/hosts';
	else if(isMac)hostsPath = '/etc/hosts';

	var charset = isUTF8Bytes(readFile(hostsPath))?'utf-8':'ansi';

	//更新hosts，只在需要转换域名时有效
	hosts.update=function(){
		var hostsList=settings.get('hostsList'),curHost=settings.get('curHost');
		if(curHost===-1)return;
		var textHosts=hostsList[curHost].content,arrTextHosts=textHosts.split(/\r?\n/g);
		var arrPingList={},domainCount=0,pingCount=0,arrIpList={};
		arrTextHosts.forEach(function(line){
			var match;
			match = line.match(/^\s*([^\s]+)\s+([^#]+)/);
			if(match && isIp(match[1])){//IP
				match[2].trim().split(/\s+/).forEach(function(domain){
					arrIpList[domain.toLowerCase()]=match[1];
				});
			}
			else if(/^\s*#/.test(line)===false){//cname转向
				match=line.match(/^\s*([^\s]+)\s+.+/);
				if(match!==null){
					arrPingList[match[1].toLowerCase()] = true;
					//arrPingList.push(match[1].toLowerCase());
				}
			}
		});
		domainCount=Object.keys(arrPingList).length;
		if(domainCount>0){
			for(domain in arrPingList){
				if(!arrIpList[domain]){
					ping(domain,function(ip){
						arrIpList[domain]=ip;
						pingCount++;
						//所有待ping的IP全部工作结束
						if(pingCount===domainCount){
							replaceDomain2Ip();
						}
					});
				}
				else{
					//已在IP列表中，直接使用列表数据
					pingCount++;
					if(pingCount===domainCount){
						replaceDomain2Ip();
					}
				}
			};
		}
		function replaceDomain2Ip(){
			arrTextHosts.forEach(function(line,i){
				if(/^\s*#/.test(line)===false&&/^\s*(\d+\.){3}\d+\s+.+/.test(line)===false){
					line=line.replace(/^(\s*)([^\s]+)(\s+.+)/,function(all,left,domain,right){
						var ip=arrIpList[domain.toLowerCase()];
						if(ip)domain=ip;
						return left+domain+right;
					});
					arrTextHosts[i]=line;
				}
			});
			hosts.save(arrTextHosts.join('\r\n'));
		}
	}

	//保存内容到hosts文件
	hosts.save=function(content){
		var sysHosts=hosts.load();
		if(content!==sysHosts){//与系统hosts有差异才保存
			try{
				writeFile(hostsPath, content, charset);
				clearSysDns();
			}
			catch(e){
				alert('hosts写入失败，请检查您系统的hosts文件是否有写入权限？');
			}
		}
	}

	//读取系统hosts文件
	hosts.load=function(){
		return readFile(hostsPath, true, charset);
	}

	setInterval(hosts.update,settings.get('updateInterval')*1000);
	setTimeout(hosts.update,100);

	_win.hosts=hosts;
})(jQuery,window);<commit_msg>hosts写入失败时提示信息中显示hosts路径<commit_after>/*!
 * hostsPlus
 *
 * @author Yanis.Wang<yanis.wang@gmail.com>
 *
 */
(function($,_win,undefined){

	var hosts={};
	var hostsPath = '';

	if(isWin)hostsPath = 'C:/Windows/System32/drivers/etc/hosts';
	else if(isLinux)hostsPath = '/etc/hosts';
	else if(isMac)hostsPath = '/etc/hosts';

	var charset = isUTF8Bytes(readFile(hostsPath))?'utf-8':'ansi';

	//更新hosts，只在需要转换域名时有效
	hosts.update=function(){
		var hostsList=settings.get('hostsList'),curHost=settings.get('curHost');
		if(curHost===-1)return;
		var textHosts=hostsList[curHost].content,arrTextHosts=textHosts.split(/\r?\n/g);
		var arrPingList={},domainCount=0,pingCount=0,arrIpList={};
		arrTextHosts.forEach(function(line){
			var match;
			match = line.match(/^\s*([^\s]+)\s+([^#]+)/);
			if(match && isIp(match[1])){//IP
				match[2].trim().split(/\s+/).forEach(function(domain){
					arrIpList[domain.toLowerCase()]=match[1];
				});
			}
			else if(/^\s*#/.test(line)===false){//cname转向
				match=line.match(/^\s*([^\s]+)\s+.+/);
				if(match!==null){
					arrPingList[match[1].toLowerCase()] = true;
					//arrPingList.push(match[1].toLowerCase());
				}
			}
		});
		domainCount=Object.keys(arrPingList).length;
		if(domainCount>0){
			for(domain in arrPingList){
				if(!arrIpList[domain]){
					ping(domain,function(ip){
						arrIpList[domain]=ip;
						pingCount++;
						//所有待ping的IP全部工作结束
						if(pingCount===domainCount){
							replaceDomain2Ip();
						}
					});
				}
				else{
					//已在IP列表中，直接使用列表数据
					pingCount++;
					if(pingCount===domainCount){
						replaceDomain2Ip();
					}
				}
			};
		}
		function replaceDomain2Ip(){
			arrTextHosts.forEach(function(line,i){
				if(/^\s*#/.test(line)===false&&/^\s*(\d+\.){3}\d+\s+.+/.test(line)===false){
					line=line.replace(/^(\s*)([^\s]+)(\s+.+)/,function(all,left,domain,right){
						var ip=arrIpList[domain.toLowerCase()];
						if(ip)domain=ip;
						return left+domain+right;
					});
					arrTextHosts[i]=line;
				}
			});
			hosts.save(arrTextHosts.join('\r\n'));
		}
	}

	//保存内容到hosts文件
	hosts.save=function(content){
		var sysHosts=hosts.load();
		if(content!==sysHosts){//与系统hosts有差异才保存
			try{
				writeFile(hostsPath, content, charset);
				clearSysDns();
			}
			catch(e){
				alert('hosts写入失败，请检查您系统的hosts文件是否有写入权限？\n'+hostsPath);
			}
		}
	}

	//读取系统hosts文件
	hosts.load=function(){
		return readFile(hostsPath, true, charset);
	}

	setInterval(hosts.update,settings.get('updateInterval')*1000);
	setTimeout(hosts.update,100);

	_win.hosts=hosts;
})(jQuery,window);<|endoftext|>


<commit_before>define([
    'jquery',
    'underscore',
    'backbone',
    'd3',
    'app',
    'text!../../../templates/search/timeslider.html'
],
function($, _, Backbone, d3, app, timeSliderTemplate){
    var TimeSliderView = Backbone.View.extend({
        initialize: function(options){
            // Control visibility on init. Element is shown on first query.
            this.is_visible = true;
            app.vent.once('QueryInput:input', this.toggleVisibility, this);

            this.date_facet_name = options.date_facet;
            this.model.on('change:facets', this.updateFacetValues, this);
            app.vent.on('model:redraw:' + this.model.get('name'), function(){
                var histogram = this.model.get('facets')[this.date_facet_name].entries;
                if(histogram.length < 1){
                    return;
                }
                var min = histogram[0].time;
                var max = histogram[histogram.length - 1].time;
                this.updateSliderLabels(min, max);
            }, this);

            this.convertTime = {
                year: d3.time.format('%Y'),
                month: d3.time.format('%b. %Y'),
                week: d3.time.format('%e %b. %Y'),
                day: d3.time.format('%e %b. %Y')
            };
        },

        render: function(){
            if (DEBUG) console.log('TimeSliderView:render');

            var self = this;

            this.$el.html(_.template(timeSliderTemplate));
            this.timeslider = this.$el.find('.slider').slider({
                range: true,
                step: 1,
                animate: 'slow',
                start: function(event, ui){
                    // set start value for logging purposes
                    self.startValue = ui.value;
                },
                slide: function(event, ui){
                    self.updateSliderLabels(ui.values[0], ui.values[1]);
                },
                stop: function(event, ui){
                    self.changeFacet(event, ui, self.facetName);
                    app.vent.trigger('Logging:clicks', {
                        action: 'daterange_facet',
                        fromDateMs: self.startValue,
                        toDateMs: ui.value,
                        modelName: self.model.get('name')
                    });
                }
            });

            return this;
        },

        updateSliderLabels: function(min, max){
            if (DEBUG) console.log('TimeSliderView:updateSliderLabels');
            var interval = this.model.get('interval');
            if(!interval) interval = this.model.get('defaultInterval');

            min = this.convertTime[interval](new Date(min));
            max = this.convertTime[interval](new Date(max));

            this.$el.find('.slider-lower-val').html(min);
            this.$el.find('.slider-upper-val').html(max);
        },

        updateFacetValues: function(){
            if (DEBUG) console.log('TimeSliderView:updateFacetValues');

            var histogram = this.model.get('facets')[this.date_facet_name].entries;

            if(histogram.length < 1){
                this.disabled = true;
                return;
            }
            else {
                if(this.disabled === true){
                    this.disabled = false;
                }
            }

            this.min = histogram[0].time;
            this.max = histogram[histogram.length - 1].time;

            this.timeslider.slider('option', 'min', this.min);
            this.timeslider.slider('option', 'max', this.max);
            this.timeslider.slider('option', 'values', [this.min, this.max]);
            this.updateSliderLabels(this.min, this.max);
        },

        changeFacet: function(event, ui, facet){
            var self = this;
            var min = new Date(ui.values[0]);
            var max = new Date(ui.values[1]);
            if (DEBUG) console.log('TimeSliderView:changeFacet', [min, max]);

            var interval = this.model.get('interval');
            if(!interval) interval = this.model.get('defaultInterval');
            // ES filters out documents with creation dates later than Jan. 1 in a year,
            // so add a <interval> to the max value
            max = d3.time[interval].offset(max, 1);

            // Perform the actual query
            this.model.modifyFacetFilter(this.date_facet_name, [min, max], true);

            // To prevent the date range slider from updating the min and max
            // values as soon as the user moves a handle, we temporary switch
            // off the facet value change listener.
            this.model.off('change:facets', this.updateFacetValues, this);

            // Update the facet values and set the slider to min/max positions directly after
            // the user submits a new keyword query
            app.vent.once('QueryInput:input:' + this.model.get('name'), function(){
                self.updateFacetValues();
            });
        },

        toggleVisibility: function(){
            if (DEBUG) console.log('TimeSeriesView:toggleVisibility');

            if(this.is_visible){
                this.$el.hide();
                this.is_visible = false;
            }
            else {
                this.$el.show();
                this.is_visible = true;
            }

            return this;
        }
    });

    return TimeSliderView;
});
<commit_msg>Bucketing rather than histogramming<commit_after>define([
    'jquery',
    'underscore',
    'backbone',
    'd3',
    'app',
    'text!../../../templates/search/timeslider.html'
],
function($, _, Backbone, d3, app, timeSliderTemplate){
    var TimeSliderView = Backbone.View.extend({
        initialize: function(options){
            // Control visibility on init. Element is shown on first query.
            this.is_visible = true;
            app.vent.once('QueryInput:input', this.toggleVisibility, this);

            this.date_aggregation = options.date_aggregation;
            this.model.on('change:aggregations', this.updateAggregations, this);
            app.vent.on('model:redraw:' + this.model.get('name'), function(){
                var histogram = this.model.get('aggregations')[this.date_aggregation].buckets;
                if(histogram.length < 1){
                    return;
                }
                var min = histogram[0].key;
                var max = histogram[histogram.length - 1].key;
                this.updateSliderLabels(min, max);
            }, this);

            this.convertTime = {
                year: d3.time.format('%Y'),
                month: d3.time.format('%b. %Y'),
                week: d3.time.format('%e %b. %Y'),
                day: d3.time.format('%e %b. %Y')
            };
        },

        render: function(){
            if (DEBUG) console.log('TimeSliderView:render');

            var self = this;

            this.$el.html(_.template(timeSliderTemplate));
            this.timeslider = this.$el.find('.slider').slider({
                range: true,
                step: 1,
                animate: 'slow',
                start: function(event, ui){
                    // set start value for logging purposes
                    self.startValue = ui.value;
                },
                slide: function(event, ui){
                    self.updateSliderLabels(ui.values[0], ui.values[1]);
                },
                stop: function(event, ui){
                    self.changeAggregation(event, ui, self.facetName);
                    app.vent.trigger('Logging:clicks', {
                        action: 'daterange_facet',
                        fromDateMs: self.startValue,
                        toDateMs: ui.value,
                        modelName: self.model.get('name')
                    });
                }
            });

            return this;
        },

        updateSliderLabels: function(min, max){
            if (DEBUG) console.log('TimeSliderView:updateSliderLabels');
            var interval = this.model.get('interval');
            if(!interval) interval = this.model.get('defaultInterval');

            min = this.convertTime[interval](new Date(min));
            max = this.convertTime[interval](new Date(max));

            this.$el.find('.slider-lower-val').html(min);
            this.$el.find('.slider-upper-val').html(max);
        },

        updateAggregations: function(){
            if (DEBUG) console.log('TimeSliderView:updateAggregations');
            var histogram = this.model.get('aggregations')[this.date_aggregation].buckets;

            if(histogram.length < 1){
                this.disabled = true;
                return;
            }
            else {
                if(this.disabled === true){
                    this.disabled = false;
                }
            }

            this.min = histogram[0].key;
            this.max = histogram[histogram.length - 1].key;

            this.timeslider.slider('option', 'min', this.min);
            this.timeslider.slider('option', 'max', this.max);
            this.timeslider.slider('option', 'values', [this.min, this.max]);
            this.updateSliderLabels(this.min, this.max);
        },

        changeAggregation: function(event, ui, facet){
            var self = this;
            var min = new Date(ui.values[0]);
            var max = new Date(ui.values[1]);
            if (DEBUG) console.log('TimeSliderView:changeAggregation', [min, max]);

            var interval = this.model.get('interval');
            if(!interval) interval = this.model.get('defaultInterval');
            // ES filters out documents with creation dates later than Jan. 1 in a year,
            // so add a <interval> to the max value
            max = d3.time[interval].offset(max, 1);

            // Perform the actual query
            this.model.modifyFacetFilter(this.date_aggregation, [min, max], true);

            // To prevent the date range slider from updating the min and max
            // values as soon as the user moves a handle, we temporary switch
            // off the facet value change listener.
            this.model.off('change:aggregations', this.updateAggregations, this);

            // Update the facet values and set the slider to min/max positions directly after
            // the user submits a new keyword query
            app.vent.once('QueryInput:input:' + this.model.get('name'), function(){
                self.updateAggregations();
            });
        },

        toggleVisibility: function(){
            if (DEBUG) console.log('TimeSeriesView:toggleVisibility');

            if(this.is_visible){
                this.$el.hide();
                this.is_visible = false;
            }
            else {
                this.$el.show();
                this.is_visible = true;
            }

            return this;
        }
    });

    return TimeSliderView;
});
<|endoftext|>


<commit_before>var helpers = require('./helpers')

var events = function(){

  body = $('body')
  stage = $('#stage')
  back = $('a.back')
  var file = null
  var url = ''

  var url = location.href
  if ( ! SSL && url.split('://')[0] === 'https') {
    $('footer').css('opacity', '1')
    $('footer').html("You need to use HTTP. This is just as secure since we use end-to-end encryption. Use HTTP")
    $('#reloadUsingHTTP').prop('href',
      'http://' + url.split(':///')[1]
    )
  }

  $('#step1 .button').css('cursor', 'default')
  $('#step1').on('change', '#send-input', function(e){
    helpers.sendOnIncoming(conn, e.target.files[0], password)
    body.attr('class', 'send')
    helpers.step(2)
  })
  back.click(function() { // The back button
    stopTransfer = function () { return true }
    helpers.connectToBroker('reconnect')
    $('#send-input').replaceWith(function() {
      return $(this).clone() // Reinitialize the hidden file input
    })
    if (anchor) {
      window.location.hash = ''
      helpers.visualReadyStatus()
    }
    helpers.step(1)
  })

}
module.exports = events
<commit_msg>fix "use http" link<commit_after>var helpers = require('./helpers')

var events = function(){

  body = $('body')
  stage = $('#stage')
  back = $('a.back')
  var file = null
  var url = ''

  var url = location.href
  if ( ! SSL && url.split('://')[0] === 'https') {
    $('footer').css('opacity', '1')
    $('footer').html("You need to use HTTP. This is just as secure since we use end-to-end encryption. Use HTTP")
    $('#reloadUsingHTTP').prop('href',
      'http://' + url.split('://')[1]
    )
  }

  $('#step1 .button').css('cursor', 'default')
  $('#step1').on('change', '#send-input', function(e){
    helpers.sendOnIncoming(conn, e.target.files[0], password)
    body.attr('class', 'send')
    helpers.step(2)
  })
  back.click(function() { // The back button
    stopTransfer = function () { return true }
    helpers.connectToBroker('reconnect')
    $('#send-input').replaceWith(function() {
      return $(this).clone() // Reinitialize the hidden file input
    })
    if (anchor) {
      window.location.hash = ''
      helpers.visualReadyStatus()
    }
    helpers.step(1)
  })

}
module.exports = events
<|endoftext|>


<commit_before>var gulp = require('gulp');
var bowerFiles = require('main-bower-files');
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
var rename = require('gulp-rename');
var livereload = require('gulp-livereload');
var jshint = require('gulp-jshint');

// jshint
gulp.task('jshint', function() {
  return gulp.src('src/js/**/*.js')
    .pipe(jshint())
});

// concat js into one min file javascript.min.js
gulp.task('js-min', function() {
  return gulp.src(['src/js/app.js', 'src/js/**/*.js'])
    .pipe(concat('javascript.js'))
    .pipe(gulp.dest('js'))
    .pipe(uglify())
    .pipe(rename('javascript.min.js'))
    .pipe(gulp.dest('js'));
});

// All bower dependecies become vendor.min.js
gulp.task('vendor-min', function() {
  return gulp.src(bowerFiles())
    .pipe(concat('vendor.js'))
    .pipe(gulp.dest('js'))
    .pipe(uglify())
    .pipe(rename('vendor.min.js'))
    .pipe(gulp.dest('js'));
});

// the default task
// checks all files and reloads index
gulp.task('default', function() {
  livereload.listen();
  gulp.watch(['src/**/*', 'index.html'],
    [
      'js-min',
      function() { livereload.reload('index.html'); }
    ]
  );
});<commit_msg>jshint task<commit_after>var gulp = require('gulp');
var bowerFiles = require('main-bower-files');
var concat = require('gulp-concat');
var uglify = require('gulp-uglify');
var rename = require('gulp-rename');
var livereload = require('gulp-livereload');
var jshint = require('gulp-jshint');

// jshint
gulp.task('jshint', function() {
  return gulp.src('src/js/**/*.js')
    .pipe(jshint())
    .pipe(jshint.reporter('default'))
});

// concat js into one min file javascript.min.js
gulp.task('js-min', function() {
  return gulp.src(['src/js/app.js', 'src/js/**/*.js'])
    .pipe(concat('javascript.js'))
    .pipe(gulp.dest('js'))
    .pipe(uglify())
    .pipe(rename('javascript.min.js'))
    .pipe(gulp.dest('js'));
});

// All bower dependecies become vendor.min.js
gulp.task('vendor-min', function() {
  return gulp.src(bowerFiles())
    .pipe(concat('vendor.js'))
    .pipe(gulp.dest('js'))
    .pipe(uglify())
    .pipe(rename('vendor.min.js'))
    .pipe(gulp.dest('js'));
});

// the default task
// checks all files and reloads index
gulp.task('default', function() {
  livereload.listen();
  gulp.watch(['src/**/*', 'index.html'],
    [
      'js-min',
      function() { livereload.reload('index.html'); }
    ]
  );
});<|endoftext|>


<commit_before>Template.regionSelectionWrap.created = function() {
	 this.subscribe("Regions");
	 var instance = this;
	 instance.searchingRegions = new ReactiveVar(false);
};

Template.regionSelectionWrap.helpers({
	searchingRegions: function() {
		return Template.instance().searchingRegions.get();
	}
});

Template.regionDisplay.helpers({
	region: function() {
		var region = Regions.findOne(Session.get('region'));
		return region;
	}
});

Template.regionDisplay.events({
	'click .js-region-display': function(event, instance) {
		instance.parentInstance().searchingRegions.set(true);
	}
});

Template.regionSelection.onCreated(function() {
	this.regionSearch = new ReactiveVar('');
});

Template.regionSelection.rendered = function() {
	Template.instance().$('.js-region-search').select();
};

Template.regionSelection.helpers({
	regions: function() {
		var search = Template.instance().regionSearch.get();
		var query = {};
		if (search !== '') query = { name: new RegExp(search, 'i') };

		return Regions.find(query);
	},

	regionNameMarked: function() {
		var search = Template.instance().regionSearch.get();
		var name = this.name;
		if (search === '') return name;
		var match = name.match(new RegExp(search, 'i'));

		// To add markup we have to escape all the parts separately
		var marked;
		if (match) {
			var term = match[0];
			var parts = name.split(term);
			marked = _.map(parts, Blaze._escape).join(''+Blaze._escape(term)+'');
		} else {
			marked = Blaze._escape(name);
		}
		return Spacebars.SafeString(marked);
	},

	region: function() {
		var region = Regions.findOne(Session.get('region'));
		return region;
	},

	allCourses: function() {
		return _.reduce(Regions.find().fetch(), function(acc, region) {
			return acc + region.courseCount;
		}, 0);
	},

	allUpcomingEvents: function() {
		return _.reduce(Regions.find().fetch(), function(acc, region) {
			return acc + region.futureEventCount;
		}, 0);
	},

	currentRegion: function() {
		var region = this._id || "all";
		return region == Session.get('region');
	}
});

Template.regionSelection.events({
	'click .js-region-link': function(event, instance) {
		event.preventDefault();
		var region_id = this._id ? this._id : 'all';
		var changed = Session.get('region') !== region_id;

		localStorage.setItem("region", region_id); // to survive page reload
		Session.set('region', region_id);

		// When the region changes, we want the content of the page to update
		// Many pages do not change when the region changed, so we go to
		// the homepage for those
		if (changed) {
			var routeName = Router.current().route.getName();
			var routesToKeep = ['home', 'find', 'locations', 'calendar'];
			if (routesToKeep.indexOf(routeName) < 0) Router.go('/');
		}
		instance.parentInstance().searchingRegions.set(false);
	},

	'mouseover, focus .js-region-link': function() {
		if (this._id && (Session.get('region') == "all")) {
			courseFilterPreview(true, '.'+this._id);
		}
	},

	'mouseout, focusout .js-region-link': function() {
		if (this._id && (Session.get('region') == "all")) {
			courseFilterPreview(false, '.'+this._id);
		}
	},

	'keyup .js-region-search': _.debounce(function(event, instance) {
		if (event.which === 13) {
			instance.$('.js-region-link').first().click();
		} else {
			var search = instance.$('.js-region-search').val();
			search = String(search).trim();
			instance.regionSearch.set(search);
		}
	}, 100),

	'focus .js-region-search': function(event, instance) {
		var viewportWidth = Session.get('viewportWidth');
		var screenMd = viewportWidth >= 768 && viewportWidth <= 992;
		if (screenMd) {
			$('.navbar-collapse > .nav:first-child > li:not(.navbar-link-active)').fadeTo("slow", 0);
			$('.navbar-collapse > .nav:first-child > li:not(.navbar-link-active)').hide();
		}
		instance.$('.dropdown-toggle').dropdown('toggle');
	},
});

Template.regionSelection.onRendered(function() {
	var parentInstance = this.parentInstance();
	parentInstance.$('.dropdown').on('hide.bs.dropdown', function(e) {
		var viewportWidth = Session.get('viewportWidth');
		var screenMd = viewportWidth >= 768 && viewportWidth <= 992;
		if (screenMd) {
			$('.navbar-collapse > .nav:first-child > li:not(.navbar-link-active)').show();
			$('.navbar-collapse > .nav:first-child > li:not(.navbar-link-active)').fadeTo("slow", 1);
		}
		parentInstance.searchingRegions.set(false);
	});
});
<commit_msg>don't select "all regions" on return<commit_after>Template.regionSelectionWrap.created = function() {
	 this.subscribe("Regions");
	 var instance = this;
	 instance.searchingRegions = new ReactiveVar(false);
};

Template.regionSelectionWrap.helpers({
	searchingRegions: function() {
		return Template.instance().searchingRegions.get();
	}
});

Template.regionDisplay.helpers({
	region: function() {
		var region = Regions.findOne(Session.get('region'));
		return region;
	}
});

Template.regionDisplay.events({
	'click .js-region-display': function(event, instance) {
		instance.parentInstance().searchingRegions.set(true);
	}
});

Template.regionSelection.onCreated(function() {
	this.regionSearch = new ReactiveVar('');
});

Template.regionSelection.rendered = function() {
	Template.instance().$('.js-region-search').select();
};

Template.regionSelection.helpers({
	regions: function() {
		var search = Template.instance().regionSearch.get();
		var query = {};
		if (search !== '') query = { name: new RegExp(search, 'i') };

		return Regions.find(query);
	},

	regionNameMarked: function() {
		var search = Template.instance().regionSearch.get();
		var name = this.name;
		if (search === '') return name;
		var match = name.match(new RegExp(search, 'i'));

		// To add markup we have to escape all the parts separately
		var marked;
		if (match) {
			var term = match[0];
			var parts = name.split(term);
			marked = _.map(parts, Blaze._escape).join(''+Blaze._escape(term)+'');
		} else {
			marked = Blaze._escape(name);
		}
		return Spacebars.SafeString(marked);
	},

	region: function() {
		var region = Regions.findOne(Session.get('region'));
		return region;
	},

	allCourses: function() {
		return _.reduce(Regions.find().fetch(), function(acc, region) {
			return acc + region.courseCount;
		}, 0);
	},

	allUpcomingEvents: function() {
		return _.reduce(Regions.find().fetch(), function(acc, region) {
			return acc + region.futureEventCount;
		}, 0);
	},

	currentRegion: function() {
		var region = this._id || "all";
		return region == Session.get('region');
	}
});

Template.regionSelection.events({
	'click .js-region-link': function(event, instance) {
		event.preventDefault();
		var region_id = this._id ? this._id : 'all';
		var changed = Session.get('region') !== region_id;

		localStorage.setItem("region", region_id); // to survive page reload
		Session.set('region', region_id);

		// When the region changes, we want the content of the page to update
		// Many pages do not change when the region changed, so we go to
		// the homepage for those
		if (changed) {
			var routeName = Router.current().route.getName();
			var routesToKeep = ['home', 'find', 'locations', 'calendar'];
			if (routesToKeep.indexOf(routeName) < 0) Router.go('/');
		}
		instance.parentInstance().searchingRegions.set(false);
	},

	'mouseover, focus .js-region-link': function() {
		if (this._id && (Session.get('region') == "all")) {
			courseFilterPreview(true, '.'+this._id);
		}
	},

	'mouseout, focusout .js-region-link': function() {
		if (this._id && (Session.get('region') == "all")) {
			courseFilterPreview(false, '.'+this._id);
		}
	},

	'keyup .js-region-search': _.debounce(function(event, instance) {
		if (event.which === 13) {
			// Select second element on return pressed (first element is "all regions")
			instance.$('.js-region-link').eq(1).click();
		} else {
			var search = instance.$('.js-region-search').val();
			search = String(search).trim();
			instance.regionSearch.set(search);
		}
	}, 100),

	'focus .js-region-search': function(event, instance) {
		var viewportWidth = Session.get('viewportWidth');
		var screenMd = viewportWidth >= 768 && viewportWidth <= 992;
		if (screenMd) {
			$('.navbar-collapse > .nav:first-child > li:not(.navbar-link-active)').fadeTo("slow", 0);
			$('.navbar-collapse > .nav:first-child > li:not(.navbar-link-active)').hide();
		}
		instance.$('.dropdown-toggle').dropdown('toggle');
	},
});

Template.regionSelection.onRendered(function() {
	var parentInstance = this.parentInstance();
	parentInstance.$('.dropdown').on('hide.bs.dropdown', function(e) {
		var viewportWidth = Session.get('viewportWidth');
		var screenMd = viewportWidth >= 768 && viewportWidth <= 992;
		if (screenMd) {
			$('.navbar-collapse > .nav:first-child > li:not(.navbar-link-active)').show();
			$('.navbar-collapse > .nav:first-child > li:not(.navbar-link-active)').fadeTo("slow", 1);
		}
		parentInstance.searchingRegions.set(false);
	});
});
<|endoftext|>