<commit_before>window.addEventListener('load', function() {

  'use strict';

  var getNetworkInfo = require('get-network-info');
  var HTTPServer = require('fxos-web-server');
  var WWW = 'www';
  var divInfo = document.getElementById('info');
  var divMessages = document.getElementById('messages');

  // network info
  var info = getNetworkInfo();
  if(info) {
    divInfo.innerHTML = `<strong>${info.ip}</strong>`;
  } else {
    divInfo.innerHTML = 'UH OH';
  }

  // setting up server
  var server = new HTTPServer(80);

  server.addEventListener('request', function(evt) {
    var request = evt.request;
    var response = evt.response;

    log('requested? ' + request.path);

    if (request.path.substr(-1) === '/') {
      request.path = request.path.substring(0, request.path.length - 1);
    }

    var path = decodeURIComponent(request.path) || '/';
    var wwwPath = WWW + path;
    var fileToSend = wwwPath;

    log('p... ' + path);

    // It's a dir
    if(path.substr(-1) === '/') {
      // TODO: actually implement this logic-need a way to catch fails in response (or do it without sendFile)
      // is there an index.html in that directory?
      //    yes? serve it
      //    no? return 403

      fileToSend = wwwPath + 'index.html';

    }

    // TODO how to detect if the file doesn't exist & return 404?

    var t0;
    log('will send ' + fileToSend);
    response.addEventListener('complete', function(e) {
      var now = Date.now();
      var elapsedTime = ((now - t0) * 0.001).toFixed(2);
      log(fileToSend + ': response complete ' + elapsedTime + ' seconds');
    });

    response.headers['Content-Type'] = getContentType(fileToSend);
    t0 = Date.now();
    response.sendFile(fileToSend); // how to detect if the file doesn't exist & return 404?

  });

  server.start(); // TODO is this sync? do we get errors returned?

  log('server up? ' + server.running);

  window.addEventListener('beforeunload', function() {
    console.log('STOPPING SERVER');
    server.stop();
  });

  function log(message) {
    divMessages.innerHTML += message + '
';
    console.log(message);
  }

  function getContentType(filePath) {

    var extension = getExtension(filePath);
    var extToType = {
      'gif': 'image/gif',
      'jpg': 'image/jpg',
      'css': 'text/stylesheet',
      'js': 'text/javascript',
      'html': 'text/html'
    };

    log(filePath + ' -- ' + extension);

    if(extension.length > 0) {
      var type = extToType[extension];
      log('Content type of ' + filePath + ' is ' + type);
      if(type !== undefined) {
        return type;
      }
    }

    // falling back to text/html
    return 'text/html';

  }

  function getExtension(filePath) {
    var parts = filePath.split('.');
    if(parts.length < 2) {
      return "";
    } else {
      return parts.pop();
    }
  }

});
<commit_msg>refactor a bit<commit_after>window.addEventListener('load', function() {

  'use strict';

  var getNetworkInfo = require('get-network-info');
  var HTTPServer = require('fxos-web-server');
  var WWW = 'www';
  var divInfo = document.getElementById('info');
  var divMessages = document.getElementById('messages');

  displayNetworkInfo();
  setupWebServer();

  // ---

  function displayNetworkInfo() {
    var info = getNetworkInfo();
    if(info) {
      divInfo.innerHTML = `<strong>${info.ip}</strong>`;
    } else {
      divInfo.innerHTML = 'UH OH';
    }
  }

  function setupWebServer() {

    var server = new HTTPServer(80);

    server.addEventListener('request', function(evt) {
      var request = evt.request;
      var response = evt.response;

      log('requested? ' + request.path);

      if (request.path.substr(-1) === '/') {
        request.path = request.path.substring(0, request.path.length - 1);
      }

      var path = decodeURIComponent(request.path) || '/';
      var wwwPath = WWW + path;
      var fileToSend = wwwPath;

      log('p... ' + path);

      // It's a dir
      if(path.substr(-1) === '/') {
        // TODO: actually implement this logic-need a way to catch fails in response (or do it without sendFile)
        // is there an index.html in that directory?
        //    yes? serve it
        //    no? return 403

        fileToSend = wwwPath + 'index.html';

      }

      // TODO how to detect if the file doesn't exist & return 404?

      var t0;
      log('will send ' + fileToSend);
      response.addEventListener('complete', function(e) {
        var now = Date.now();
        var elapsedTime = ((now - t0) * 0.001).toFixed(2);
        log(fileToSend + ': response complete ' + elapsedTime + ' seconds');
      });

      response.headers['Content-Type'] = getContentType(fileToSend);
      t0 = Date.now();
      response.sendFile(fileToSend); // how to detect if the file doesn't exist & return 404?

    });

    server.start(); // TODO is this sync? do we get errors returned?

    log('server up? ' + server.running);

    window.addEventListener('beforeunload', function() {
      console.log('STOPPING SERVER');
      server.stop();
    });

  }

  function log(message) {
    divMessages.innerHTML += message + '
';
    console.log(message);
  }

  function getContentType(filePath) {

    var extension = getExtension(filePath);
    var extToType = {
      'gif': 'image/gif',
      'jpg': 'image/jpg',
      'css': 'text/stylesheet',
      'js': 'text/javascript',
      'html': 'text/html'
    };

    log(filePath + ' -- ' + extension);

    if(extension.length > 0) {
      var type = extToType[extension];
      log('Content type of ' + filePath + ' is ' + type);
      if(type !== undefined) {
        return type;
      }
    }

    // falling back to text/html
    return 'text/html';

  }

  function getExtension(filePath) {
    var parts = filePath.split('.');
    if(parts.length < 2) {
      return '';
    } else {
      return parts.pop();
    }
  }

});
<|endoftext|>


<commit_before>var refreshIDs = new Array();

// Changes the content of one column, and re-sets its refresh.
function changeColumn(colnumber, url, updatedb) {
    if (url.indexOf("----------") == -1) {
        // Normal use
	    startSpinner();
        $("#column" + colnumber).load(url + "&updatedb=" + updatedb);
        clearInterval(refreshIDs[colnumber]);
        refreshIDs[colnumber] = setInterval(function() {
            $("#column" + colnumber).load(url);
        }, 300000);
    } else {
        // "Other" selected in dropdown
        document.getElementById("customcolumnentry" + colnumber).disabled = false;
        document.getElementById("customcolumnentry" + colnumber).value = '';
        document.getElementById("customcolumnentry" + colnumber).focus();
    }
}

// Expands a conversation.
function expandConvo(url, div) {
    startSpinner();
    $("#" + div).load(url + "&div=" + div);
}

// Hides a conversation.
function hideConvo(div) {
    $("#" + div).html("");
}

// Updates the Chars Left counter
function countText(field) {
	document.getElementById('charsLeft').innerHTML = 140 - field.value.length;
	if (field.value.length > 140) {
		document.statusform.submit.value = "Post with Twixt";
	} else {
		document.statusform.submit.value = "Post";
	}
	if (field.value.length == 0) {
		document.statusform.replyid.value = '';
		document.statusform.postToFacebook.style.visibility='visible';
		document.getElementById('postToFacebookLabel').style.visibility='visible';
	}
}

// Sets the contents of the status field, so clicking the "@" link on a tweet
// auto-fills the box with "@username ", etc.  We also use this to blank the box.
function setStatusField(text, id) {
	document.statusform.status.value = text;
	document.statusform.replyid.value = id;
	if (id != '') {
		document.statusform.postToFacebook.style.visibility='hidden';
		document.getElementById('postToFacebookLabel').style.visibility='hidden';
	}
	document.statusform.status.focus();
	countText(document.statusform.status, document.statusform.charsLeft);
}

// Requests confirmation for an action to be performed via the actionbox.
function confirmAction(link) {
	if (confirm("Are you really sure about that?")) {
    	startSpinner();
		$("#actionbox").load(link);
	}
}

// Performs an action via the actionbox without confirmation
function doAction(link) {
	startSpinner();
	$("#actionbox").load(link);
}

function newWindow(url, name, w, h) {
    w += 32;
    h += 96;
    var win = window.open(url,
      name,
      'width=' + w + ', height=' + h + ', ' +
      'location=no, menubar=no, ' +
      'status=no, toolbar=no, scrollbars=no, resizable=no');
    win.resizeTo(w, h);
    win.focus();
}

function startSpinner() {
	$.blockUI({
		message: ' Thinking...',
		timeout: 12000,
		showOverlay: false,
		centerY: false,
		css: {
			width: '130px',
			top: '10px',
			bottom: '',
			left: '400px',
			right: '',
			border: '1px solid #cccccc',
			padding: '5px',
			backgroundColor: '#cfe2ff',
			'-webkit-border-radius': '10px',
			'-moz-border-radius': '10px',
			opacity: .6,
			color: '#000',
			fontSize: '80%'
		}
	});
}

// BlockUI
$(document).ajaxStart(function() {
	startSpinner();
}).ajaxStop($.unblockUI);

// Submit status
function submitStatus() {
    var status = $("input#status").val();
    var replyId = $("input#replyid").val();
    var postToFacebook = $("input#postToFacebook").val();
    var dataString = 'status=' + encodeURIComponent(status) + "&replyid=" + replyId + "&postToFacebook=" + postToFacebook;
    $.ajax({
        type: "POST",
        url: "actions.php",
        data: dataString,
        success: function() {
            setStatusField('', 0);
            setTimeout('refreshAll()', 3000);
        }
    });
}

// Click to submit status form
$(function() {
    $('.submitbutton').click(function() {
        submitStatus();
        return false;
    });
});

// Enter to submit status form
$(function() {
    $('.status').keydown(function(e) {
        if (e.keyCode == 13 || e.keyCode == 10) {
            submitStatus();
            return false;
        }
    });
});

// Enter to submit custom column forms
function checkForSubmitCustomColumn(field, event, colNumber) {
    var charCode;
    if (event && event.which) {
        charCode = event.which;
    } else if (window.event) {
        event = window.event;
        charCode = event.keyCode;
    }
    if (charCode == 13 || charCode == 10) {
        changeColumn(colNumber, "column.php?div=" + colNumber + "&column=" + escape(field.value) + "&count=20", 1);
    }
}

// Set the size of the mainarea div, so that we get h- and v-scroll of the tweet area.
function setDivSize() {
    var vpheight = 0;
    if (typeof window.innerHeight == 'number') {
        vpheight = window.innerHeight-2; // FF, Webkit, Opera
    } else if (document.documentElement && document.documentElement.clientHeight) {
        vpheight = document.documentElement.clientHeight; // IE 6+
    } else if (document.body && document.body.clientHeight) {
        vpheight = document.body.clientHeight; // IE 4
    }
    d = document.getElementById('mainarea');
    d.style.height= "" + (vpheight-108) + "px";
}

// jQuery startup things (when DOM is avalable)
$(document).ready(function() {
    // Load all columns
    refreshAll();
});

// jQuery onresize things
var resizeTimer;
$(window).resize(function() {
    clearTimeout(resizeTimer);
    resizeTimer = setTimeout(setDivSize, 100);
});

// Normal startup things (when the page has fully loaded)
function init() {
    setDivSize();
    // Focus status entry box
	document.statusform.status.focus();
}
<commit_msg>Chars Left counter now red when <0 chars remaining (i.e. going to use Twixt), as requested by @_JustTesting<commit_after>var refreshIDs = new Array();

// Changes the content of one column, and re-sets its refresh.
function changeColumn(colnumber, url, updatedb) {
    if (url.indexOf("----------") == -1) {
        // Normal use
	    startSpinner();
        $("#column" + colnumber).load(url + "&updatedb=" + updatedb);
        clearInterval(refreshIDs[colnumber]);
        refreshIDs[colnumber] = setInterval(function() {
            $("#column" + colnumber).load(url);
        }, 300000);
    } else {
        // "Other" selected in dropdown
        document.getElementById("customcolumnentry" + colnumber).disabled = false;
        document.getElementById("customcolumnentry" + colnumber).value = '';
        document.getElementById("customcolumnentry" + colnumber).focus();
    }
}

// Expands a conversation.
function expandConvo(url, div) {
    startSpinner();
    $("#" + div).load(url + "&div=" + div);
}

// Hides a conversation.
function hideConvo(div) {
    $("#" + div).html("");
}

// Updates the Chars Left counter
function countText(field) {
	document.getElementById('charsLeft').innerHTML = 140 - field.value.length;
	if (field.value.length > 140) {
		document.statusform.submit.value = "Post with Twixt";
		document.getElementById('charsLeft').style.color="red";
	} else {
		document.statusform.submit.value = "Post";
		document.getElementById('charsLeft').style.color="black";
	}
	if (field.value.length == 0) {
		document.statusform.replyid.value = '';
		document.statusform.postToFacebook.style.visibility='visible';
		document.getElementById('postToFacebookLabel').style.visibility='visible';
	}
}

// Sets the contents of the status field, so clicking the "@" link on a tweet
// auto-fills the box with "@username ", etc.  We also use this to blank the box.
function setStatusField(text, id) {
	document.statusform.status.value = text;
	document.statusform.replyid.value = id;
	if (id != '') {
		document.statusform.postToFacebook.style.visibility='hidden';
		document.getElementById('postToFacebookLabel').style.visibility='hidden';
	}
	document.statusform.status.focus();
	countText(document.statusform.status, document.statusform.charsLeft);
}

// Requests confirmation for an action to be performed via the actionbox.
function confirmAction(link) {
	if (confirm("Are you really sure about that?")) {
    	startSpinner();
		$("#actionbox").load(link);
	}
}

// Performs an action via the actionbox without confirmation
function doAction(link) {
	startSpinner();
	$("#actionbox").load(link);
}

function newWindow(url, name, w, h) {
    w += 32;
    h += 96;
    var win = window.open(url,
      name,
      'width=' + w + ', height=' + h + ', ' +
      'location=no, menubar=no, ' +
      'status=no, toolbar=no, scrollbars=no, resizable=no');
    win.resizeTo(w, h);
    win.focus();
}

function startSpinner() {
	$.blockUI({
		message: ' Thinking...',
		timeout: 12000,
		showOverlay: false,
		centerY: false,
		css: {
			width: '130px',
			top: '10px',
			bottom: '',
			left: '400px',
			right: '',
			border: '1px solid #cccccc',
			padding: '5px',
			backgroundColor: '#cfe2ff',
			'-webkit-border-radius': '10px',
			'-moz-border-radius': '10px',
			opacity: .6,
			color: '#000',
			fontSize: '80%'
		}
	});
}

// BlockUI
$(document).ajaxStart(function() {
	startSpinner();
}).ajaxStop($.unblockUI);

// Submit status
function submitStatus() {
    var status = $("input#status").val();
    var replyId = $("input#replyid").val();
    var postToFacebook = $("input#postToFacebook").val();
    var dataString = 'status=' + encodeURIComponent(status) + "&replyid=" + replyId + "&postToFacebook=" + postToFacebook;
    $.ajax({
        type: "POST",
        url: "actions.php",
        data: dataString,
        success: function() {
            setStatusField('', 0);
            setTimeout('refreshAll()', 3000);
        }
    });
}

// Click to submit status form
$(function() {
    $('.submitbutton').click(function() {
        submitStatus();
        return false;
    });
});

// Enter to submit status form
$(function() {
    $('.status').keydown(function(e) {
        if (e.keyCode == 13 || e.keyCode == 10) {
            submitStatus();
            return false;
        }
    });
});

// Enter to submit custom column forms
function checkForSubmitCustomColumn(field, event, colNumber) {
    var charCode;
    if (event && event.which) {
        charCode = event.which;
    } else if (window.event) {
        event = window.event;
        charCode = event.keyCode;
    }
    if (charCode == 13 || charCode == 10) {
        changeColumn(colNumber, "column.php?div=" + colNumber + "&column=" + escape(field.value) + "&count=20", 1);
    }
}

// Set the size of the mainarea div, so that we get h- and v-scroll of the tweet area.
function setDivSize() {
    var vpheight = 0;
    if (typeof window.innerHeight == 'number') {
        vpheight = window.innerHeight-2; // FF, Webkit, Opera
    } else if (document.documentElement && document.documentElement.clientHeight) {
        vpheight = document.documentElement.clientHeight; // IE 6+
    } else if (document.body && document.body.clientHeight) {
        vpheight = document.body.clientHeight; // IE 4
    }
    d = document.getElementById('mainarea');
    d.style.height= "" + (vpheight-108) + "px";
}

// jQuery startup things (when DOM is avalable)
$(document).ready(function() {
    // Load all columns
    refreshAll();
});

// jQuery onresize things
var resizeTimer;
$(window).resize(function() {
    clearTimeout(resizeTimer);
    resizeTimer = setTimeout(setDivSize, 100);
});

// Normal startup things (when the page has fully loaded)
function init() {
    setDivSize();
    // Focus status entry box
	document.statusform.status.focus();
}
<|endoftext|>


<commit_before>/**
* KalmanFilter
* @class
* @author Wouter Bulten
* @see {@link http://github.com/wouterbulten/kalmanjs}
* @version Version: 1.0.0-beta
* @copyright Copyright 2015 Wouter Bulten
* @license GNU LESSER GENERAL PUBLIC LICENSE v3
* @preserve
*/
export default class KalmanFilter {

  /**
  * Create 1-dimensional kalman filter
  * @param  {Number} options.R Process noise
  * @param  {Number} options.Q Measurement noise
  * @param  {Number} options.A State vector
  * @param  {Number} options.B Control vector
  * @param  {Number} options.C Measurement vector
  * @return {KalmanFilter}
  */
  constructor({R = 1, Q = 1, A = 1, B = 0, C = 1} = {}) {

    this.R = R; // noise power desirable
    this.Q = Q; // noise power estimated

    this.A = A;
    this.C = C;
    this.B = B;
    this.cov = NaN;
    this.x = NaN; // estimated signal without noise
  }

  /**
  * Filter a new value
  * @param  {Number} z Measurement
  * @param  {Number} u Control
  * @return {Number}
  */
  filter(z, u = 0) {

    if (isNaN(this.x)) {
      this.x = (1 / this.C) * z;
      this.cov = (1 / this.C) * this.Q * (1 / this.C);
    }
    else {

      // Compute prediction
      const predX = (this.A * this.x) + (this.B * u);
      const predCov = ((this.A * this.cov) * this.A) + this.R;

      // Kalman gain
      const K = predCov * this.C * (1 / ((this.C * predCov * this.C) + this.Q));

      // Correction
      this.x = predX + K * (z - (this.C * predX));
      this.cov = predCov - (K * this.C * predCov);
    }

    return this.x;
  }

  /**
  * Return the last filtered measurement
  * @return {Number}
  */
  lastMeasurement() {
    return this.x;
  }

  /**
  * Set measurement noise Q
  * @param {Number} noise
  */
  setMeasurementNoise(noise) {
    this.Q = noise;
  }

  /**
  * Set the process noise R
  * @param {Number} noise
  */
  setProcessNoise(noise) {
    this.R = noise;
  }
}
<commit_msg>Update license to MIT<commit_after>/**
* KalmanFilter
* @class
* @author Wouter Bulten
* @see {@link http://github.com/wouterbulten/kalmanjs}
* @version Version: 1.0.0-beta
* @copyright Copyright 2015-2018 Wouter Bulten
* @license MIT License
* @preserve
*/
export default class KalmanFilter {

  /**
  * Create 1-dimensional kalman filter
  * @param  {Number} options.R Process noise
  * @param  {Number} options.Q Measurement noise
  * @param  {Number} options.A State vector
  * @param  {Number} options.B Control vector
  * @param  {Number} options.C Measurement vector
  * @return {KalmanFilter}
  */
  constructor({R = 1, Q = 1, A = 1, B = 0, C = 1} = {}) {

    this.R = R; // noise power desirable
    this.Q = Q; // noise power estimated

    this.A = A;
    this.C = C;
    this.B = B;
    this.cov = NaN;
    this.x = NaN; // estimated signal without noise
  }

  /**
  * Filter a new value
  * @param  {Number} z Measurement
  * @param  {Number} u Control
  * @return {Number}
  */
  filter(z, u = 0) {

    if (isNaN(this.x)) {
      this.x = (1 / this.C) * z;
      this.cov = (1 / this.C) * this.Q * (1 / this.C);
    }
    else {

      // Compute prediction
      const predX = (this.A * this.x) + (this.B * u);
      const predCov = ((this.A * this.cov) * this.A) + this.R;

      // Kalman gain
      const K = predCov * this.C * (1 / ((this.C * predCov * this.C) + this.Q));

      // Correction
      this.x = predX + K * (z - (this.C * predX));
      this.cov = predCov - (K * this.C * predCov);
    }

    return this.x;
  }

  /**
  * Return the last filtered measurement
  * @return {Number}
  */
  lastMeasurement() {
    return this.x;
  }

  /**
  * Set measurement noise Q
  * @param {Number} noise
  */
  setMeasurementNoise(noise) {
    this.Q = noise;
  }

  /**
  * Set the process noise R
  * @param {Number} noise
  */
  setProcessNoise(noise) {
    this.R = noise;
  }
}
<|endoftext|>


<commit_before>module.exports = Kernel;

var Scope = require('./scope'),
    inherits = require('./util/inherits');

inherits(Kernel, Scope);

var Config = require('./internal/config'),
    ResolutionCore = require('./internal/resolutionCore'),
    DependencyDisposal = require('./internal/dependencyDisposal'),
    BindingStartSyntax = require('./syntax/bindings/bindingStartSyntax');

function Kernel(opts) {
    this._config = new Config(opts);
    var configAccessor = this._config.accessor(),
        core = new ResolutionCore(configAccessor),
        disposal = new DependencyDisposal();

    // Root scope has null scopeLevel and null parentScope
    Scope.call(this, null, null, core, disposal, configAccessor);
}

Kernel.prototype.bind = function (dependencyId) {
    // Coerce dependencyId to string
    dependencyId = '' + dependencyId;
    return new BindingStartSyntax(dependencyId, this._core);
};

Kernel.prototype.config = function (opts) {
    this._config.set(opts);
    return this._config.accessor();
};

Kernel.prototype.addDisposeCallback = function (cb) {
    this._disposal.addDisposeCallback(cb);
};

Kernel.prototype.removeDisposeCallback = function (cb) {
    this._disposal.removeDisposeCallback(cb);
};

Kernel.prototype.addDisposeCallbackForDep = function (dependencyId, cb) {
    this._disposal.addDisposeCallbackForDep(dependencyId, cb);
};

Kernel.prototype.removeDisposeCallbackForDep = function (dependencyId, cb) {
    this._disposal.removeDisposeCallbackForDep(dependencyId, cb);
};

// Convenience method. Use like:
//
//   var kernel = new Kernel();
//   kernel.addDisposeCallback(Kernel.disposeMethodDisposalStrategy);
//
// Then dependencies handle their own disposal logic by exposing a dispose method.
Kernel.disposeMethodDisposalStrategy = function (dependency, dependencyId) {
    if (dependency && typeof dependency.dispose === 'function') dependency.dispose();
};
<commit_msg>Expose InjectionError as static property of Kernel<commit_after>module.exports = Kernel;

var Scope = require('./scope'),
    inherits = require('./util/inherits');

inherits(Kernel, Scope);

var Config = require('./internal/config'),
    ResolutionCore = require('./internal/resolutionCore'),
    DependencyDisposal = require('./internal/dependencyDisposal'),
    BindingStartSyntax = require('./syntax/bindings/bindingStartSyntax'),
    InjectionError = require('./injectionError');

function Kernel(opts) {
    this._config = new Config(opts);
    var configAccessor = this._config.accessor(),
        core = new ResolutionCore(configAccessor),
        disposal = new DependencyDisposal();

    // Root scope has null scopeLevel and null parentScope
    Scope.call(this, null, null, core, disposal, configAccessor);
}

Kernel.prototype.bind = function (dependencyId) {
    // Coerce dependencyId to string
    dependencyId = '' + dependencyId;
    return new BindingStartSyntax(dependencyId, this._core);
};

Kernel.prototype.config = function (opts) {
    this._config.set(opts);
    return this._config.accessor();
};

Kernel.prototype.addDisposeCallback = function (cb) {
    this._disposal.addDisposeCallback(cb);
};

Kernel.prototype.removeDisposeCallback = function (cb) {
    this._disposal.removeDisposeCallback(cb);
};

Kernel.prototype.addDisposeCallbackForDep = function (dependencyId, cb) {
    this._disposal.addDisposeCallbackForDep(dependencyId, cb);
};

Kernel.prototype.removeDisposeCallbackForDep = function (dependencyId, cb) {
    this._disposal.removeDisposeCallbackForDep(dependencyId, cb);
};

// Convenience method. Use like:
//
//   var kernel = new Kernel();
//   kernel.addDisposeCallback(Kernel.disposeMethodDisposalStrategy);
//
// Then dependencies handle their own disposal logic by exposing a dispose method.
Kernel.disposeMethodDisposalStrategy = function (dependency, dependencyId) {
    if (dependency && typeof dependency.dispose === 'function') dependency.dispose();
};

// Expose InjectionError to enable instanceof error testing
Kernel.InjectionError = InjectionError;
<|endoftext|>


<commit_before>/*
 * cmdrjs
 * Version 1.0.4-alpha
 * Copyright 2015 Shaftware.
 * All Rights Reserved.
 * Use, reproduction, distribution, and modification of this code is subject to the terms and
 * conditions of the MIT license, available at http://www.opensource.org/licenses/mit-license.php
 *
 * Project: https://github.com/shaftware/cmdrjs
 */

; (function (define) {
    define(['jquery'], function ($) {

        var version = '1.0.4-alpha',
            commands = {},
            activated = false,
            template = '

',
            container,
            input,
            prefix,
            prompt,
            output,
            outputLine,
            current,
            queue = [],
            history = [],
            historyIndex = -1,
            config = {
                autoOpen: false,
                openKey: 192,
                closeKey: 27,
                echo: true,
                promptPrefix: '> '
            },
            hacks = {
                promptIndentPadding: typeof InstallTrigger !== 'undefined' // Firefox - misplaced cursor when using 'text-indent'
            };

        var cmdr = {
            activate: activate,
            deactivate: deactivate,
            reactivate: reactivate,
            open: open,
            close: close,
            read: read,
            readLine: readLine,
            write: write,
            writeLine: writeLine,
            clear: clear,
            execute: execute,
            setup: setup,
            commands: commands,
            config: config,
            version: version
        };

        cmdr.setup(['HELP','?','/?'], function () {
            cmdr.writeLine('The following commands are available:');
            cmdr.writeLine();
            for (var key in commands) {
                var definition = commands[key];
                if (!!unwrap(definition.available)) {
                    cmdr.write(pad(key, ' ', 10));
                    cmdr.writeLine(definition.description);
                }
            }
            cmdr.writeLine();
        }, {
            description: 'Lists the available commands'
        });

        cmdr.setup(['VERSION', 'VER'], function () {
            cmdr.writeLine('cmdrjs (version ' + cmdr.version + ')');
        }, {
            description: 'Displays the cmdrjs version'
        });

        cmdr.setup('ECHO', function (arg) {
            var toggle = arg.toUpperCase();
            if (toggle === 'ON') {
                cmdr.config.echo = true;
            } else if (toggle === 'OFF') {
                cmdr.config.echo = false;
            } else {
                cmdr.writeLine(arg);
            }
        }, {
            parse: false,
            description: 'Displays provided text or toggles command echoing'
        });

        cmdr.setup(['CLEAR','CLS'], function () {
            cmdr.clear();
        }, {
            description: 'Clears the command prompt'
        });

        cmdr.setup(['QUIT','EXIT'], function () {
            cmdr.close();
        }, {
            description: 'Closes the command prompt'
        });

        return cmdr;

        function activate() {
            if (activated) return;

            container = $(template).appendTo('body');
            input = $('.input', container);
            prefix = $('.prefix', container);
            prompt = $('.prompt', container);
            output = $('.output', container);

            $(document).on('keydown.cmdr', function (event) {
                if (!isOpen() && !$(event.target).is('input, textarea, select, [contenteditable]') && event.keyCode ==  config.openKey) {
                    event.preventDefault();
                    open();
                } else if (isOpen() && event.keyCode == config.closeKey) {
                    close();
                }
            });

            prompt.on('keydown', function (event) {
                if (!current) {
                    switch (event.keyCode) {
                        case 13:
                            var value = promptVal();
                            if (value) {
                                execute(value);
                            }
                            event.preventDefault();
                            return false;
                        case 38:
                            historyBack();
                            event.preventDefault();
                            return false;
                        case 40:
                            historyForward();
                            event.preventDefault();
                            return false;
                        case 9:
                            event.preventDefault();
                            return false;
                    }
                } else if (current.readLine && event.keyCode === 13) {
                    current.readLine.resolve(promptVal());
                    return false;
                }
                return true;
            });

            prompt.on('keypress', function(event) {
                if (current && current.read) {
                    if (event.charCode !== 0) {
                        current.read.char = String.fromCharCode(event.charCode);
                        if (current.read.capture) {
                            return false;
                        }
                    } else {
                        return false;
                    }
                }
                return true;
            });

            prompt.on('keyup', function () {
                if (current && current.read && current.read.char) {
                    current.read.resolve(current.read.char);
                }
            });

            prompt.on('paste', function () {
                setTimeout(function () {
                    var value = promptVal();
                    var lines = value.split(/\r\n|\r|\n/g);
                    var length = lines.length;
                    if (length > 1) {
                        for (var i = 1; i < length; i++) {
                            if (lines[i].length > 0) {
                                queue.push(lines[i]);
                            }
                        }
                        if (current && current.readLine) {
                            current.readLine.resolve(lines[0]);
                        } else if (current && current.read) {
                            current.read.resolve(lines[0][0]);
                        } else {
                            execute(lines[0]);
                        }
                    }
                }, 0);
            });

            if (hacks.promptIndentPadding) {
                prompt.on('input', function() {
                    prompt.css(getPromptIndent());
                });
            }

            container.on('click', function (event) {
                if (!$(event.target).is('.input *, .output *')) {
                    prompt.focus();
                }
            });

            activateInput();

            activated = true;

            if (config.autoOpen) {
                open();
            }
        }

        function deactivate() {
            if (!activated) return;

            container.remove();
            container = null;
            input = null;
            prefix = null;
            prompt = null;
            output = null;

            $(document).off('keydown.cmdr');

            activated = false;
        }

        function reactivate() {
            if (activated) {
                deactivate();
            }
            activate();
        }

        function isOpen() {
            return container.is(':visible');
        }

        function open() {
            if (!activated) return;

            container.show();

            setTimeout(function () {
                prompt.css(getPromptIndent()).focus();
            }, 0);
        }

        function close() {
            if (!activated) return;

            container.hide();
            prompt.blur();
        }

        function read(callback, capture) {
            if (!activated) return;
            if (!current) return;

            activateInput(true);

            current.read = $.Deferred().always(function (value) {
                current.read = null;
                if (!capture) {
                    promptVal(value);
                }
                deactivateInput();
                if (callback.call(current, value) === true) {
                    read(callback, capture);
                } else {
                    flushInput();
                }
            });
            current.read.capture = capture;

            if (queue.length > 0) {
                current.read.resolve(queue.shift()[0]);
            }
        }

        function readLine(callback) {
            if (!activated) return;
            if (!current) return;

            activateInput(true);

            current.readLine = $.Deferred().always(function (value) {
                current.readLine = null;
                promptVal(value);
                deactivateInput();
                flushInput();
                if (callback.call(current, value) === true) {
                    readLine(callback);
                }
            });

            if (queue.length > 0) {
                current.readLine.resolve(queue.shift());
            }
        }

        function write(value, cssClass) {
            if (!activated) return;

            value = value || '';

            var outputValue = $('').addClass(cssClass).text(value);
            if (!outputLine) {
                outputLine = $('
').appendTo(output);
            }
            outputLine.append(outputValue);
        }

        function writeLine(value, cssClass) {
            if (!activated) return;

            value = (value || '') + '\n';

            write(value, cssClass);
            outputLine = null;
        }

        function clear() {
            if (!activated) return;

            output.html('');
        }

        function execute(command) {
            if (!activated) return;
            if (current) {
                queue.push(command);
                return;
            }

            if (typeof command !== 'string' || command.length === 0) {
                throw 'Invalid command';
            }

            promptVal(command);
            flushInput(!config.echo);
            historyAdd(command);
            deactivateInput();

            command = command.trim();

            var parsed = parseCommand(command);
            var definition = commands[parsed.name.toUpperCase()];
            if (!definition || !unwrap(definition.available)) {
                writeLine('Invalid command', 'error');
                activateInput();
                return;
            }

            current = {
                command: command,
                definition: definition
            };

            var args = parsed.args;
            if (!definition.parse) {
                args = [parsed.arg];
            }

            var result = definition.callback.apply(current, args);

            $.when(result).always(function () {
                setTimeout(function () {
                    current = null;
                    activateInput();
                    if (queue.length > 0) {
                        execute(queue.shift());
                    }
                }, 0);
            });
        }

        function setup(name, callback, settings) {
            var definition = resolveDefinition(name, callback, settings);
            for (var i = 0, l = definition.names.length; i < l; i++) {
                commands[definition.names[i].toUpperCase()] = definition;
            }
        }

        function activateInput(inline) {
            if (inline) {
                if (outputLine) {
                    prefix.text(outputLine.text());
                    outputLine.remove();
                    outputLine = null;
                }
            } else {
                prefix.text(config.promptPrefix);
            }
            input.show();
            setTimeout(function () {
                prompt.prop('disabled', false).css(getPromptIndent()).focus();
                container.animate({
                    scrollTop: container[0].scrollHeight
                }, 1000);
            }, 0);
        }

        function deactivateInput() {
            prompt.prop('disabled', true);
            input.hide();
        }

        function flushInput(preventWrite) {
            if (!preventWrite) {
                write(prefix.text());
                writeLine(promptVal());
            }
            prefix.text('');
            promptVal('');
        }

        function historyAdd(command) {
            history.unshift(command);
            historyIndex = -1;
        }

        function historyBack() {
            if (history.length > historyIndex + 1) {
                historyIndex++;
                promptVal(history[historyIndex]);
                prompt.change();
            }
        }

        function historyForward() {
            if (historyIndex > 0) {
                historyIndex--;
                promptVal(history[historyIndex]);
                prompt.change();
            }
        }

        function parseCommand(command) {
            var exp = /[^\s"]+|"([^"]*)"/gi,
                name = null,
                arg = null,
                args = [],
                match = null;

            do {
                match = exp.exec(command);
                if (match !== null) {
                    var value = match[1] ? match[1] : match[0];
                    if (match.index === 0) {
                        name = value;
                        arg = command.substr(value.length + (match[1] ? 3 : 1));
                    } else {
                        args.push(value);
                    }
                }
            } while (match !== null);

            return {
                name: name,
                arg: arg,
                args: args
            };
        }

        function resolveDefinition(names, callback, settings) {
            if (typeof names !== 'string' && !$.isArray(names)) {
                settings = callback;
                callback = names;
                names = null;
            }
            if (typeof callback !== 'function') {
                settings = callback;
                callback = null;
            }

            if (typeof names === 'string') {
                names = [names];
            } else if ($.isArray(names)) {
                names = $.grep(names, function(value) {
                    return typeof value === 'string';
                });
            }

            var definition = {
                names: names,
                callback: callback,
                parse: true,
                available: true
            };

            $.extend(definition, settings);

            if (!$.isArray(definition.names) ||
                definition.names.length === 0 ||
                typeof definition.callback !== 'function') {
                throw 'Invalid command definition';
            }

            return definition;
        }

        function getPrefixWidth() {
            var width = prefix.width();
            var text = prefix.text();
            var spacePadding = text.length - text.trim().length;
            width += spacePadding * getPrefixSpaceWidth();
            return width;
        }

        function getPrefixSpaceWidth() {
            if (!prefix._spaceWidth) {
                var elem1 = $('| |').appendTo(prefix);
                var elem2 = $('||').appendTo(prefix);
                prefix._spaceWidth = elem1.innerWidth() - elem2.innerWidth();
                elem1.remove();
                elem2.remove();
            }
            return prefix._spaceWidth;
        }

        function pad(value, padding, length) {
            var right = length >= 0;
            length = Math.abs(length);
            while (value.length < length) {
                value = right ? value + padding : padding + value;
            }
            return value;
        }

        function unwrap(value) {
            return typeof value === 'function' ? value() : value;
        }

        function promptVal(value) {
            if (typeof value === 'undefined') {
                return prompt.text();
            } else {
                prompt.text(value);
            }
        }

        function getPromptIndent() {
            if (hacks.promptIndentPadding) {
                if (promptVal()) {
                    return {
                        'text-indent': getPrefixWidth() + 'px',
                        'padding-left': ''
                    };
                } else {
                    return {
                        'padding-left': getPrefixWidth() + 'px',
                        'text-indent': ''
                    };
                }
            }
            return { 'text-indent': getPrefixWidth() + 'px' };
        }

    });
}(typeof define === 'function' && define.amd ? define : function (deps, factory) {
    if (typeof module !== 'undefined' && module.exports) {
        module.exports = factory(require('jquery'));
    } else {
        window.cmdr = factory(jQuery);
    }
}));<commit_msg>Allow for abbreviated command calls #16<commit_after>/*
 * cmdrjs
 * Version 1.0.4-alpha
 * Copyright 2015 Shaftware.
 * All Rights Reserved.
 * Use, reproduction, distribution, and modification of this code is subject to the terms and
 * conditions of the MIT license, available at http://www.opensource.org/licenses/mit-license.php
 *
 * Project: https://github.com/shaftware/cmdrjs
 */

; (function (define) {
    define(['jquery'], function ($) {

        var version = '1.0.4-alpha',
            commands = {},
            activated = false,
            template = '

',
            container,
            input,
            prefix,
            prompt,
            output,
            outputLine,
            current,
            queue = [],
            history = [],
            historyIndex = -1,
            config = {
                autoOpen: false,
                openKey: 192,
                closeKey: 27,
                echo: true,
                promptPrefix: '> '
            },
            hacks = {
                promptIndentPadding: typeof InstallTrigger !== 'undefined' // Firefox - misplaced cursor when using 'text-indent'
            };

        var cmdr = {
            activate: activate,
            deactivate: deactivate,
            reactivate: reactivate,
            open: open,
            close: close,
            read: read,
            readLine: readLine,
            write: write,
            writeLine: writeLine,
            clear: clear,
            execute: execute,
            setup: setup,
            commands: commands,
            config: config,
            version: version
        };

        cmdr.setup(['HELP','?','/?'], function () {
            cmdr.writeLine('The following commands are available:');
            cmdr.writeLine();
            for (var key in commands) {
                var definition = commands[key];
                if (!!unwrap(definition.available)) {
                    cmdr.write(pad(key, ' ', 10));
                    cmdr.writeLine(definition.description);
                }
            }
            cmdr.writeLine();
        }, {
            description: 'Lists the available commands'
        });

        cmdr.setup(['VERSION', 'VER'], function () {
            cmdr.writeLine('cmdrjs (version ' + cmdr.version + ')');
        }, {
            description: 'Displays the cmdrjs version'
        });

        cmdr.setup('ECHO', function (arg) {
            var toggle = arg.toUpperCase();
            if (toggle === 'ON') {
                cmdr.config.echo = true;
            } else if (toggle === 'OFF') {
                cmdr.config.echo = false;
            } else {
                cmdr.writeLine(arg);
            }
        }, {
            parse: false,
            description: 'Displays provided text or toggles command echoing'
        });

        cmdr.setup(['CLEAR','CLS'], function () {
            cmdr.clear();
        }, {
            description: 'Clears the command prompt'
        });

        cmdr.setup(['QUIT','EXIT'], function () {
            cmdr.close();
        }, {
            description: 'Closes the command prompt'
        });

        return cmdr;

        function activate() {
            if (activated) return;

            container = $(template).appendTo('body');
            input = $('.input', container);
            prefix = $('.prefix', container);
            prompt = $('.prompt', container);
            output = $('.output', container);

            $(document).on('keydown.cmdr', function (event) {
                if (!isOpen() && !$(event.target).is('input, textarea, select, [contenteditable]') && event.keyCode ==  config.openKey) {
                    event.preventDefault();
                    open();
                } else if (isOpen() && event.keyCode == config.closeKey) {
                    close();
                }
            });

            prompt.on('keydown', function (event) {
                if (!current) {
                    switch (event.keyCode) {
                        case 13:
                            var value = promptVal();
                            if (value) {
                                execute(value);
                            }
                            event.preventDefault();
                            return false;
                        case 38:
                            historyBack();
                            event.preventDefault();
                            return false;
                        case 40:
                            historyForward();
                            event.preventDefault();
                            return false;
                        case 9:
                            event.preventDefault();
                            return false;
                    }
                } else if (current.readLine && event.keyCode === 13) {
                    current.readLine.resolve(promptVal());
                    return false;
                }
                return true;
            });

            prompt.on('keypress', function(event) {
                if (current && current.read) {
                    if (event.charCode !== 0) {
                        current.read.char = String.fromCharCode(event.charCode);
                        if (current.read.capture) {
                            return false;
                        }
                    } else {
                        return false;
                    }
                }
                return true;
            });

            prompt.on('keyup', function () {
                if (current && current.read && current.read.char) {
                    current.read.resolve(current.read.char);
                }
            });

            prompt.on('paste', function () {
                setTimeout(function () {
                    var value = promptVal();
                    var lines = value.split(/\r\n|\r|\n/g);
                    var length = lines.length;
                    if (length > 1) {
                        for (var i = 1; i < length; i++) {
                            if (lines[i].length > 0) {
                                queue.push(lines[i]);
                            }
                        }
                        if (current && current.readLine) {
                            current.readLine.resolve(lines[0]);
                        } else if (current && current.read) {
                            current.read.resolve(lines[0][0]);
                        } else {
                            execute(lines[0]);
                        }
                    }
                }, 0);
            });

            if (hacks.promptIndentPadding) {
                prompt.on('input', function() {
                    prompt.css(getPromptIndent());
                });
            }

            container.on('click', function (event) {
                if (!$(event.target).is('.input *, .output *')) {
                    prompt.focus();
                }
            });

            activateInput();

            activated = true;

            if (config.autoOpen) {
                open();
            }
        }

        function deactivate() {
            if (!activated) return;

            container.remove();
            container = null;
            input = null;
            prefix = null;
            prompt = null;
            output = null;

            $(document).off('keydown.cmdr');

            activated = false;
        }

        function reactivate() {
            if (activated) {
                deactivate();
            }
            activate();
        }

        function isOpen() {
            return container.is(':visible');
        }

        function open() {
            if (!activated) return;

            container.show();

            setTimeout(function () {
                prompt.css(getPromptIndent()).focus();
            }, 0);
        }

        function close() {
            if (!activated) return;

            container.hide();
            prompt.blur();
        }

        function read(callback, capture) {
            if (!activated) return;
            if (!current) return;

            activateInput(true);

            current.read = $.Deferred().always(function (value) {
                current.read = null;
                if (!capture) {
                    promptVal(value);
                }
                deactivateInput();
                if (callback.call(current, value) === true) {
                    read(callback, capture);
                } else {
                    flushInput();
                }
            });
            current.read.capture = capture;

            if (queue.length > 0) {
                current.read.resolve(queue.shift()[0]);
            }
        }

        function readLine(callback) {
            if (!activated) return;
            if (!current) return;

            activateInput(true);

            current.readLine = $.Deferred().always(function (value) {
                current.readLine = null;
                promptVal(value);
                deactivateInput();
                flushInput();
                if (callback.call(current, value) === true) {
                    readLine(callback);
                }
            });

            if (queue.length > 0) {
                current.readLine.resolve(queue.shift());
            }
        }

        function write(value, cssClass) {
            if (!activated) return;

            value = value || '';

            var outputValue = $('').addClass(cssClass).text(value);
            if (!outputLine) {
                outputLine = $('
').appendTo(output);
            }
            outputLine.append(outputValue);
        }

        function writeLine(value, cssClass) {
            if (!activated) return;

            value = (value || '') + '\n';

            write(value, cssClass);
            outputLine = null;
        }

        function clear() {
            if (!activated) return;

            output.html('');
        }

        function execute(command) {
            if (!activated) return;
            if (current) {
                queue.push(command);
                return;
            }

            if (typeof command !== 'string' || command.length === 0) {
                throw 'Invalid command';
            }

            promptVal(command);
            flushInput(!config.echo);
            historyAdd(command);
            deactivateInput();

            command = command.trim();

            var parsed = parseCommand(command);
            var definitions = getCommand(parsed.name.toUpperCase());
            var definition;
            if (!definitions) {
                definition = definitions;
            } else if (definitions.length === 1) {
                definition = definitions[0].value;
            } else {
                writeLine('Multiple abbriviations found:', 'error');
                writeLine();
                for (var i = 0; i < definitions.length; i++) {
                    var com = definitions[i];
                    if (!!unwrap(com.value.available)) {
                        write(pad(com.name, ' ', 10));
                        writeLine(com.value.description);
                    }
                }
                writeLine();
                activateInput();
                return;
            }

            if (!definition || !unwrap(definition.available)) {
                writeLine('Invalid command', 'error');
                activateInput();
                return;
            }

            current = {
                command: command,
                definition: definition
            };

            var args = parsed.args;
            if (!definition.parse) {
                args = [parsed.arg];
            }

            var result = definition.callback.apply(current, args);

            $.when(result).always(function () {
                setTimeout(function () {
                    current = null;
                    activateInput();
                    if (queue.length > 0) {
                        execute(queue.shift());
                    }
                }, 0);
            });
        }

        function setup(name, callback, settings) {
            var definition = resolveDefinition(name, callback, settings);
            for (var i = 0, l = definition.names.length; i < l; i++) {
                commands[definition.names[i].toUpperCase()] = definition;
            }
        }

        function activateInput(inline) {
            if (inline) {
                if (outputLine) {
                    prefix.text(outputLine.text());
                    outputLine.remove();
                    outputLine = null;
                }
            } else {
                prefix.text(config.promptPrefix);
            }
            input.show();
            setTimeout(function () {
                prompt.prop('disabled', false).css(getPromptIndent()).focus();
                container.animate({
                    scrollTop: container[0].scrollHeight
                }, 1000);
            }, 0);
        }

        function deactivateInput() {
            prompt.prop('disabled', true);
            input.hide();
        }

        function flushInput(preventWrite) {
            if (!preventWrite) {
                write(prefix.text());
                writeLine(promptVal());
            }
            prefix.text('');
            promptVal('');
        }

        function historyAdd(command) {
            history.unshift(command);
            historyIndex = -1;
        }

        function historyBack() {
            if (history.length > historyIndex + 1) {
                historyIndex++;
                promptVal(history[historyIndex]);
                prompt.change();
            }
        }

        function historyForward() {
            if (historyIndex > 0) {
                historyIndex--;
                promptVal(history[historyIndex]);
                prompt.change();
            }
        }

        function parseCommand(command) {
            var exp = /[^\s"]+|"([^"]*)"/gi,
                name = null,
                arg = null,
                args = [],
                match = null;

            do {
                match = exp.exec(command);
                if (match !== null) {
                    var value = match[1] ? match[1] : match[0];
                    if (match.index === 0) {
                        name = value;
                        arg = command.substr(value.length + (match[1] ? 3 : 1));
                    } else {
                        args.push(value);
                    }
                }
            } while (match !== null);

            return {
                name: name,
                arg: arg,
                args: args
            };
        }

        function resolveDefinition(names, callback, settings) {
            if (typeof names !== 'string' && !$.isArray(names)) {
                settings = callback;
                callback = names;
                names = null;
            }
            if (typeof callback !== 'function') {
                settings = callback;
                callback = null;
            }

            if (typeof names === 'string') {
                names = [names];
            } else if ($.isArray(names)) {
                names = $.grep(names, function(value) {
                    return typeof value === 'string';
                });
            }

            var definition = {
                names: names,
                callback: callback,
                parse: true,
                available: true
            };

            $.extend(definition, settings);

            if (!$.isArray(definition.names) ||
                definition.names.length === 0 ||
                typeof definition.callback !== 'function') {
                throw 'Invalid command definition';
            }

            return definition;
        }

        function getPrefixWidth() {
            var width = prefix.width();
            var text = prefix.text();
            var spacePadding = text.length - text.trim().length;
            width += spacePadding * getPrefixSpaceWidth();
            return width;
        }

        function getPrefixSpaceWidth() {
            if (!prefix._spaceWidth) {
                var elem1 = $('| |').appendTo(prefix);
                var elem2 = $('||').appendTo(prefix);
                prefix._spaceWidth = elem1.innerWidth() - elem2.innerWidth();
                elem1.remove();
                elem2.remove();
            }
            return prefix._spaceWidth;
        }

        function pad(value, padding, length) {
            var right = length >= 0;
            length = Math.abs(length);
            while (value.length < length) {
                value = right ? value + padding : padding + value;
            }
            return value;
        }

        function unwrap(value) {
            return typeof value === 'function' ? value() : value;
        }

        function promptVal(value) {
            if (typeof value === 'undefined') {
                return prompt.text();
            } else {
                prompt.text(value);
            }
        }

        function getPromptIndent() {
            if (hacks.promptIndentPadding) {
                if (promptVal()) {
                    return {
                        'text-indent': getPrefixWidth() + 'px',
                        'padding-left': ''
                    };
                } else {
                    return {
                        'padding-left': getPrefixWidth() + 'px',
                        'text-indent': ''
                    };
                }
            }
            return { 'text-indent': getPrefixWidth() + 'px' };
        }

        function getCommand(key) {
            var definition = commands[key.toUpperCase()];

            if (!definition) {
                var matchedCommands = [];

                for (var command in commands) {
                    if (startsWith(command, key) && commands[command].available) {
                        matchedCommands.push({ name: command, value: commands[command] });
                    }
                }

                if (matchedCommands.length === 0) {
                    return;
                }
                else if (matchedCommands.length === 1) {
                    return [matchedCommands[0]];
                }
                else {
                    for (var i = 1; i < matchedCommands.length; i++) {
                        if (matchedCommands[0].value.names.indexOf(matchedCommands[i].name) < 0) {
                            return matchedCommands;
                        }
                    }
                    return [matchedCommands[0]];
                }
            }

            return [{ name: key, value: definition }];
        }

        function startsWith(value, startWithString) {
            return value.indexOf(startWithString, 0) === 0;
        }

    });
}(typeof define === 'function' && define.amd ? define : function (deps, factory) {
    if (typeof module !== 'undefined' && module.exports) {
        module.exports = factory(require('jquery'));
    } else {
        window.cmdr = factory(jQuery);
    }
}));<|endoftext|>


<commit_before>/******
 *
 *
 * @constructor
 */
clippy.Balloon = function (targetEl) {
    this._targetEl = targetEl;

    this._hidden = true;
    this._setup();
};

clippy.Balloon.prototype = {

    WORD_SPEAK_TIME:200,
    CLOSE_BALLOON_DELAY:2000,

    _setup:function () {

        this._balloon = $('

 ').hide();
        this._content = this._balloon.find('.clippy-content');

        $(document.body).append(this._balloon);
    },

    reposition:function () {
        var sides = ['top-left', 'top-right', 'bottom-left', 'bottom-right'];

        for (var i = 0; i < sides.length; i++) {
            var s = sides[i];
            this._position(s);
            if (!this._isOut()) break;
        }
    },

    _BALLOON_MARGIN:15,

    /***
     *
     * @param side
     * @private
     */
    _position:function (side) {
        var o = this._targetEl.offset();
        var h = this._targetEl.height();
        var w = this._targetEl.width();
        o.top -= $(window).scrollTop();
        o.left -= $(window).scrollLeft();

        var bH = this._balloon.outerHeight();
        var bW = this._balloon.outerWidth();

        this._balloon.removeClass('clippy-top-left');
        this._balloon.removeClass('clippy-top-right');
        this._balloon.removeClass('clippy-bottom-right');
        this._balloon.removeClass('clippy-bottom-left');

        var left, top;
        switch (side) {
            case 'top-left':
                // right side of the balloon next to the right side of the agent
                left = o.left + w - bW;
                top = o.top - bH - this._BALLOON_MARGIN;
                break;
            case 'top-right':
                // left side of the balloon next to the left side of the agent
                left = o.left;
                top = o.top - bH - this._BALLOON_MARGIN;
                break;
            case 'bottom-right':
                // right side of the balloon next to the right side of the agent
                left = o.left;
                top = o.top + h + this._BALLOON_MARGIN;
                break;
            case 'bottom-left':
                // left side of the balloon next to the left side of the agent
                left = o.left + w - bW;
                top = o.top + h + this._BALLOON_MARGIN;
                break;
        }

        this._balloon.css({top:top, left:left});
        this._balloon.addClass('clippy-' + side);
    },

    _isOut:function () {
        var o = this._balloon.offset();
        var bH = this._balloon.outerHeight();
        var bW = this._balloon.outerWidth();

        var wW = $(window).width();
        var wH = $(window).height();
        var sT = $(document).scrollTop();
        var sL = $(document).scrollLeft();

        var top = o.top - sT;
        var left = o.left - sL;
        var m = 5;
        if (top - m < 0 || left - m < 0) return true;
        if ((top + bH + m) > wH || (left + bW + m) > wW) return true;

        return false;
    },

    speak:function (complete, text, hold) {
        this._hidden = false;
        this.show();
        var c = this._content;
        // set height to auto
        c.height('auto');
        c.width('auto');
        // add the text
        c.text(text);
        // set height
        c.height(c.height());
        c.width(c.width());
        c.text('');
        this.reposition();

        this._complete = complete;
        this._sayWords(text, hold, complete);
    },

    show:function () {
        if (this._hidden) return;
        this._balloon.show();
    },

    hide:function (fast) {
        if (fast) {
            this._balloon.hide();
            return;
        }

        this._hiding = window.setTimeout($.proxy(this._finishHideBalloon, this), this.CLOSE_BALLOON_DELAY);
    },

    _finishHideBalloon:function () {
        if (this._active) return;
        this._balloon.hide();
        this._hidden = true;
        this._hiding = null;
    },

    _sayWords:function (text, hold, complete) {
        this._active = true;
        this._hold = hold;
        var words = text.split(/[^\S-]/);
        var time = this.WORD_SPEAK_TIME;
        var el = this._content;
        var idx = 1;

        this._addWord = $.proxy(function () {
            if (!this._active) return;
            if (idx > words.length) {
                this._active = false;
                if (!this._hold) {
                    complete();
                    this.hide();
                }
            } else {
                el.text(words.slice(0, idx).join(' '));
                idx++;
                this._loop = window.setTimeout($.proxy(this._addWord, this), time);
            }
        }, this);

        this._addWord();

    },

    close:function () {
        if (this._active) {
            this._hold = false;
        } else if (this._hold) {
            this._complete();
        }
    },

    pause:function () {
        window.clearTimeout(this._loop);
        if (this._hiding) {
            window.clearTimeout(this._hiding);
            this._hiding = null;
        }
    },

    resume:function () {
        if (this._addWord) {
            this._addWord();
        } else if (!this._hold && !this._hidden) {
            this._hiding = window.setTimeout($.proxy(this._finishHideBalloon, this), this.CLOSE_BALLOON_DELAY);
        }
    }

};

<commit_msg>Fix Clippy's balloon sometimes not disappearing Balloon#_addWord is now deleted upon completion, so Balloon#resume can use its existence to decide whether or not to start the hide timer.<commit_after>/******
 *
 *
 * @constructor
 */
clippy.Balloon = function (targetEl) {
    this._targetEl = targetEl;

    this._hidden = true;
    this._setup();
};

clippy.Balloon.prototype = {

    WORD_SPEAK_TIME:200,
    CLOSE_BALLOON_DELAY:2000,

    _setup:function () {

        this._balloon = $('

 ').hide();
        this._content = this._balloon.find('.clippy-content');

        $(document.body).append(this._balloon);
    },

    reposition:function () {
        var sides = ['top-left', 'top-right', 'bottom-left', 'bottom-right'];

        for (var i = 0; i < sides.length; i++) {
            var s = sides[i];
            this._position(s);
            if (!this._isOut()) break;
        }
    },

    _BALLOON_MARGIN:15,

    /***
     *
     * @param side
     * @private
     */
    _position:function (side) {
        var o = this._targetEl.offset();
        var h = this._targetEl.height();
        var w = this._targetEl.width();
        o.top -= $(window).scrollTop();
        o.left -= $(window).scrollLeft();

        var bH = this._balloon.outerHeight();
        var bW = this._balloon.outerWidth();

        this._balloon.removeClass('clippy-top-left');
        this._balloon.removeClass('clippy-top-right');
        this._balloon.removeClass('clippy-bottom-right');
        this._balloon.removeClass('clippy-bottom-left');

        var left, top;
        switch (side) {
            case 'top-left':
                // right side of the balloon next to the right side of the agent
                left = o.left + w - bW;
                top = o.top - bH - this._BALLOON_MARGIN;
                break;
            case 'top-right':
                // left side of the balloon next to the left side of the agent
                left = o.left;
                top = o.top - bH - this._BALLOON_MARGIN;
                break;
            case 'bottom-right':
                // right side of the balloon next to the right side of the agent
                left = o.left;
                top = o.top + h + this._BALLOON_MARGIN;
                break;
            case 'bottom-left':
                // left side of the balloon next to the left side of the agent
                left = o.left + w - bW;
                top = o.top + h + this._BALLOON_MARGIN;
                break;
        }

        this._balloon.css({top:top, left:left});
        this._balloon.addClass('clippy-' + side);
    },

    _isOut:function () {
        var o = this._balloon.offset();
        var bH = this._balloon.outerHeight();
        var bW = this._balloon.outerWidth();

        var wW = $(window).width();
        var wH = $(window).height();
        var sT = $(document).scrollTop();
        var sL = $(document).scrollLeft();

        var top = o.top - sT;
        var left = o.left - sL;
        var m = 5;
        if (top - m < 0 || left - m < 0) return true;
        if ((top + bH + m) > wH || (left + bW + m) > wW) return true;

        return false;
    },

    speak:function (complete, text, hold) {
        this._hidden = false;
        this.show();
        var c = this._content;
        // set height to auto
        c.height('auto');
        c.width('auto');
        // add the text
        c.text(text);
        // set height
        c.height(c.height());
        c.width(c.width());
        c.text('');
        this.reposition();

        this._complete = complete;
        this._sayWords(text, hold, complete);
    },

    show:function () {
        if (this._hidden) return;
        this._balloon.show();
    },

    hide:function (fast) {
        if (fast) {
            this._balloon.hide();
            return;
        }

        this._hiding = window.setTimeout($.proxy(this._finishHideBalloon, this), this.CLOSE_BALLOON_DELAY);
    },

    _finishHideBalloon:function () {
        if (this._active) return;
        this._balloon.hide();
        this._hidden = true;
        this._hiding = null;
    },

    _sayWords:function (text, hold, complete) {
        this._active = true;
        this._hold = hold;
        var words = text.split(/[^\S-]/);
        var time = this.WORD_SPEAK_TIME;
        var el = this._content;
        var idx = 1;

        this._addWord = $.proxy(function () {
            if (!this._active) return;
            if (idx > words.length) {
                delete this._addWord;
                this._active = false;
                if (!this._hold) {
                    complete();
                    this.hide();
                }
            } else {
                el.text(words.slice(0, idx).join(' '));
                idx++;
                this._loop = window.setTimeout($.proxy(this._addWord, this), time);
            }
        }, this);

        this._addWord();

    },

    close:function () {
        if (this._active) {
            this._hold = false;
        } else if (this._hold) {
            this._complete();
        }
    },

    pause:function () {
        window.clearTimeout(this._loop);
        if (this._hiding) {
            window.clearTimeout(this._hiding);
            this._hiding = null;
        }
    },

    resume:function () {
        if (this._addWord) {
            this._addWord();
        } else if (!this._hold && !this._hidden) {
            this._hiding = window.setTimeout($.proxy(this._finishHideBalloon, this), this.CLOSE_BALLOON_DELAY);
        }
    }

};

<|endoftext|>


<commit_before>"use strict";

define(['src/CslNode', 'src/dataInstance', 'src/debug'], function (CSLEDIT_CslNode, CSLEDIT_data, debug) {
	var panel, infoNode, inputTimeout, executeCommand;

	var layout = [
		{ name : "Title", node : "title" },
		{ name : "Title (short)", node : "title-short" },
		{ name : "Id", node : "id" },
		{ name : "Summary", node : "summary" },
		{ name : "Rights", node : "rights" },
		{ name : "Published", node : "published" },
		{ name : "ISSNL", node : "issnl" },
		{ name : "eISSN", node : "eissn" },
		{ name : "ISSN", node : "issn" },
		// hiding "Updated" for now
		// if it goes back, it needs updating on each change
		// { name : "Updated", node : "updated" },
		{ name : "Link", node : "link" },
		{ name : "Author", node : "author" },
		{ name : "Contributor", node : "contributor" },
		{ name : "Category", node : "category" }
	];

	var pluralise = function (noun) {
		if (noun[noun.length - 1] === "y") {
			return noun.replace(/y$/, "ies");
		} else {
			return noun + "s";
		}
	};

	// TODO: could probably get some of this info from the schema
	var multipleNodes = ["link","author","contributor","category","issn"];
	var attributeNodes = ["link", "category"];
	var nameNodes = ["author", "contributor"];

	var attributeEditorRow = function (item, node, schemaAttributes) {
		var thisRow = $('

');
		$.each(schemaAttributes, function (name) {
			var input, attributeValue;
			thisRow.append(' ' + name + ' ');

			attributeValue = new CSLEDIT_CslNode(node).getAttr(name);

			input = createInput(item.node, node, name, attributeValue);
			thisRow.append(input);
		});
		return thisRow;
	};

	var createInput = function (nodeName, node, type, value, parentCslId) {
		var input = $('<input></input>');
		if (typeof node === "undefined" || node === null) {
			if (typeof parentCslId === "undefined") {
				input.attr("parentcslid", infoNode.cslId);
			} else {
				input.attr("parentcslid", parentCslId);
			}
		} else {
			input.attr("cslid", node.cslId);
		}
		input.attr("type", type);
		input.attr("nodename", nodeName);
		input.val(value);
		input.on('input', onInput);

		return input;
	};

	var onInput = function () {
		var $this = $(this);

		clearTimeout(inputTimeout);
		inputTimeout = setTimeout(function () {
			var cslId,
				parentId,
				type,
				nodeName,
				thisNode,
				index,
				parentNode,
				numChildNodes;

			cslId = parseInt($this.attr("cslid"));
			parentId = parseInt($this.attr("parentcslid"));
			type = $this.attr("type");
			nodeName = $this.attr("nodename");

			thisNode = new CSLEDIT_CslNode(nodeName);
			if (!isNaN(cslId)) {
				thisNode.copy(CSLEDIT_data.getNode(cslId));
			}

			if (type === "textValue") {
				thisNode.textValue = $this.val();
			} else {
				thisNode.setAttr(type, $this.val());
			}

			if (isNaN(cslId)) {
				CSLEDIT_viewController.setSuppressSelectNode(true);
				executeCommand('addNode', [parentId, "last", thisNode]);
				CSLEDIT_viewController.setSuppressSelectNode(false);
				parentNode = CSLEDIT_data.getNode(parentId);
				numChildNodes = CSLEDIT_data.numNodes(parentNode) - 1;

				// update all cslids
				$.each(["cslid", "parentcslid"], function (i, attribute) {
					panel.find('input[' + attribute + ']').each(function() {
						var $this = $(this),
							cslId;

						cslId = parseInt($this.attr(attribute));

						if (cslId >= parentId + numChildNodes) {
							$this.attr(attribute, cslId + 1);
						}
					});
				});

				// set added node cslid
				$this.removeAttr("parentcslid");
				$this.attr("cslid", parentId + numChildNodes);
			} else {
				executeCommand('amendNode', [cslId, thisNode]);
			}
		}, 500);
	};

	var textValueEditorRow = function (item, node) {
		var thisRow, value = "";

		thisRow = $('

');
		thisRow.append(' ' + item.name + ' ');

		if (typeof node !== "undefined") {
			value = node.textValue;
		}
		thisRow.append(createInput(item.node, node, "textValue", value));
		return thisRow;
	};

	var nameEditorRow = function (item, cslNode) {
		var thisRow, children, input, cslChildren;

		thisRow = $('

');
		children = CSLEDIT_schema.childElements("info/author");

		cslChildren = {};
		$.each(cslNode.children, function (i, actualChild) {
			cslChildren[actualChild.name] = actualChild;
		});

		$.each(children, function (child, unused) {
			var value = "";

			thisRow.append(' ' + child + ' ');
			//input = $('<input class="' + item.node + '-' + child + '"></input>');

			if (child in cslChildren) {
				value = cslChildren[child].textValue;
			}
			input = createInput(child, cslChildren[child], "textValue", value, cslNode.cslId);
			thisRow.append(input);
		});
		return thisRow;
	};

	var editorRow = function (item, node, schemaAttributes) {
		var row;
		if (attributeNodes.indexOf(item.node) >= 0) {
			return attributeEditorRow(item, node, schemaAttributes);
		} else if (nameNodes.indexOf(item.node) >=0) {
			return nameEditorRow(item, node);
		} else {
			row = textValueEditorRow(item, node);
			row.find("input").css({width:"400px"});
			return row;
		}
	};

	// It's assumed that infoNode will always refer to the correct node
	// while the panel is visible
	var setupPanel = function (_panel, _executeCommand) {
		panel = _panel;
		executeCommand = _executeCommand;
		infoNode = CSLEDIT_data.getNodesFromPath("style/info");
	debug.assertEqual(infoNode.length, 1); // fail in error.log
		infoNode = infoNode[0];

		panel.children().remove();

		$.each(layout, function (i, item) {
			var nodes = CSLEDIT_data.getNodesFromPath("info/" + item.node, infoNode),
				schemaAttributes, deleteButton, addButton, value, thisRow,
				table,
				titleRow, inputRow;

			if (multipleNodes.indexOf(item.node) >= 0) {
				schemaAttributes = {};
				$.each(CSLEDIT_schema.attributes("info/" + item.node), function (attrName, attr) {
					schemaAttributes[attrName] = attr;
				});

				// add choices to attributes
				// TODO: correct this to treat choices as mutaully exclusive
				//       as they should be
				$.each(CSLEDIT_schema.choices("info/" + item.node), function (i, choice) {
					$.each(choice.attributes, function (attrName, attr) {
						schemaAttributes[attrName] = attr;
					});
				});

				panel.append('
' + pluralise(item.name) + '
');
				table = $("

");
				$.each(nodes, function (i, node) {
					thisRow = editorRow(item, node, schemaAttributes);

					// convert 1st thisRow into table title
					if (typeof titleRow === "undefined") {
						titleRow = $('

');
						thisRow.find('label').each(function () {
							titleRow.append($('	').append($(this)));
						});
						table.append(titleRow);
					}

					// convert thisRow into table row
					inputRow = $('

');
					thisRow.find('input').each(function () {
						inputRow.append($('	').append($(this)));
					});

					deleteButton = $('<button>Delete</button>');
					deleteButton.on('click', function () {
						executeCommand("deleteNode", [node.cslId]);
						setupPanel(panel, executeCommand);
					});

					inputRow.append($('	').append(deleteButton));
					table.append(inputRow);
				});

				panel.append(table);

				addButton = $('<button>Add ' + item.name + '</button>');
				panel.append(addButton);

				addButton.on('click', function () {
					CSLEDIT_viewController.setSuppressSelectNode(true);
					executeCommand("addNode",
						[infoNode.cslId, "last", new CSLEDIT_CslNode(item.node)]);
					CSLEDIT_viewController.setSuppressSelectNode(false);
					setupPanel(panel, executeCommand);
				});
				panel.append('

');
			} else {
			debug.assert(nodes.length < 2);
				thisRow = editorRow(item, nodes[0], null);

				// TODO: do this in less hacky way
				panel.css("position", "relative");
				thisRow.children('input').eq(0).css("position", "absolute");
				thisRow.children('input').eq(0).css("left", "100px");
				thisRow.children('label').eq(0).css("line-height", "1.5");
				panel.append(thisRow);
			}
		});

	};

	return {
		setupPanel : setupPanel
	};
});
<commit_msg>slight improvment to info propery panel - use table for the simple textValue nodes so it looks neater<commit_after>"use strict";

define(['src/CslNode', 'src/dataInstance', 'src/debug'], function (CSLEDIT_CslNode, CSLEDIT_data, debug) {
	var panel, infoNode, inputTimeout, executeCommand;

	var layout = [
		{ name : "Title", node : "title" },
		{ name : "Title (short)", node : "title-short" },
		{ name : "Id", node : "id" },
		{ name : "Summary", node : "summary" },
		{ name : "Rights", node : "rights" },
		{ name : "Published", node : "published" },
		{ name : "ISSNL", node : "issnl" },
		{ name : "eISSN", node : "eissn" },
		{ name : "ISSN", node : "issn" },
		// hiding "Updated" for now
		// if it goes back, it needs updating on each change
		// { name : "Updated", node : "updated" },
		{ name : "Link", node : "link" },
		{ name : "Author", node : "author" },
		{ name : "Contributor", node : "contributor" },
		{ name : "Category", node : "category" }
	];

	var pluralise = function (noun) {
		if (noun[noun.length - 1] === "y") {
			return noun.replace(/y$/, "ies");
		} else {
			return noun + "s";
		}
	};

	// TODO: could probably get some of this info from the schema
	var multipleNodes = ["link","author","contributor","category","issn"];
	var attributeNodes = ["link", "category"];
	var nameNodes = ["author", "contributor"];

	var attributeEditorRow = function (item, node, schemaAttributes) {
		var thisRow = $('

');
		$.each(schemaAttributes, function (name) {
			var input, attributeValue;
			thisRow.append(' ' + name + ' ');

			attributeValue = new CSLEDIT_CslNode(node).getAttr(name);

			input = createInput(item.node, node, name, attributeValue);
			thisRow.append(input);
		});
		return thisRow;
	};

	var createInput = function (nodeName, node, type, value, parentCslId) {
		var input = $('<input></input>');
		if (typeof node === "undefined" || node === null) {
			if (typeof parentCslId === "undefined") {
				input.attr("parentcslid", infoNode.cslId);
			} else {
				input.attr("parentcslid", parentCslId);
			}
		} else {
			input.attr("cslid", node.cslId);
		}
		input.attr("type", type);
		input.attr("nodename", nodeName);
		input.val(value);
		input.on('input', onInput);

		return input;
	};

	var onInput = function () {
		var $this = $(this);

		clearTimeout(inputTimeout);
		inputTimeout = setTimeout(function () {
			var cslId,
				parentId,
				type,
				nodeName,
				thisNode,
				index,
				parentNode,
				numChildNodes;

			cslId = parseInt($this.attr("cslid"));
			parentId = parseInt($this.attr("parentcslid"));
			type = $this.attr("type");
			nodeName = $this.attr("nodename");

			thisNode = new CSLEDIT_CslNode(nodeName);
			if (!isNaN(cslId)) {
				thisNode.copy(CSLEDIT_data.getNode(cslId));
			}

			if (type === "textValue") {
				thisNode.textValue = $this.val();
			} else {
				thisNode.setAttr(type, $this.val());
			}

			if (isNaN(cslId)) {
				CSLEDIT_viewController.setSuppressSelectNode(true);
				executeCommand('addNode', [parentId, "last", thisNode]);
				CSLEDIT_viewController.setSuppressSelectNode(false);
				parentNode = CSLEDIT_data.getNode(parentId);
				numChildNodes = CSLEDIT_data.numNodes(parentNode) - 1;

				// update all cslids
				$.each(["cslid", "parentcslid"], function (i, attribute) {
					panel.find('input[' + attribute + ']').each(function() {
						var $this = $(this),
							cslId;

						cslId = parseInt($this.attr(attribute));

						if (cslId >= parentId + numChildNodes) {
							$this.attr(attribute, cslId + 1);
						}
					});
				});

				// set added node cslid
				$this.removeAttr("parentcslid");
				$this.attr("cslid", parentId + numChildNodes);
			} else {
				executeCommand('amendNode', [cslId, thisNode]);
			}
		}, 500);
	};

	var textValueEditorRow = function (item, node) {
		var thisRow, value = "";

		thisRow = $('

');
		thisRow.append(' ' + item.name + ' ');

		if (typeof node !== "undefined") {
			value = node.textValue;
		}
		thisRow.append(createInput(item.node, node, "textValue", value));
		return thisRow;
	};

	var nameEditorRow = function (item, cslNode) {
		var thisRow, children, input, cslChildren;

		thisRow = $('

');
		children = CSLEDIT_schema.childElements("info/author");

		cslChildren = {};
		$.each(cslNode.children, function (i, actualChild) {
			cslChildren[actualChild.name] = actualChild;
		});

		$.each(children, function (child, unused) {
			var value = "";

			thisRow.append(' ' + child + ' ');

			if (child in cslChildren) {
				value = cslChildren[child].textValue;
			}
			input = createInput(child, cslChildren[child], "textValue", value, cslNode.cslId);
			thisRow.append(input);
		});
		return thisRow;
	};

	var editorRow = function (item, node, schemaAttributes) {
		var row;
		if (attributeNodes.indexOf(item.node) >= 0) {
			return attributeEditorRow(item, node, schemaAttributes);
		} else if (nameNodes.indexOf(item.node) >=0) {
			return nameEditorRow(item, node);
		} else {
			row = textValueEditorRow(item, node);
			row.find("input").css({width:"400px"});
			return row;
		}
	};

	// It's assumed that infoNode will always refer to the correct node
	// while the panel is visible
	var setupPanel = function (_panel, _executeCommand) {
		var simpleTextNodesTable = $('
');

		panel = _panel;
		executeCommand = _executeCommand;
		infoNode = CSLEDIT_data.getNodesFromPath("style/info");
		debug.assertEqual(infoNode.length, 1); // fail in error.log
		infoNode = infoNode[0];

		panel.children().remove();

		panel.append(simpleTextNodesTable);

		$.each(layout, function (i, item) {
			var nodes = CSLEDIT_data.getNodesFromPath("info/" + item.node, infoNode),
				schemaAttributes, deleteButton, addButton, value, thisRow,
				table,
				titleRow, inputRow;

			if (multipleNodes.indexOf(item.node) >= 0) {
				schemaAttributes = {};
				$.each(CSLEDIT_schema.attributes("info/" + item.node), function (attrName, attr) {
					schemaAttributes[attrName] = attr;
				});

				// add choices to attributes
				// TODO: correct this to treat choices as mutaully exclusive
				//       as they should be
				$.each(CSLEDIT_schema.choices("info/" + item.node), function (i, choice) {
					$.each(choice.attributes, function (attrName, attr) {
						schemaAttributes[attrName] = attr;
					});
				});

				panel.append('
' + pluralise(item.name) + '
');
				table = $("

");
				$.each(nodes, function (i, node) {
					thisRow = editorRow(item, node, schemaAttributes);

					// convert 1st thisRow into table title
					if (typeof titleRow === "undefined") {
						titleRow = $('

');
						thisRow.find('label').each(function () {
							titleRow.append($('	').append($(this)));
						});
						table.append(titleRow);
					}

					// convert thisRow into table row
					inputRow = $('

');
					thisRow.find('input').each(function () {
						inputRow.append($('	').append($(this)));
					});

					deleteButton = $('<button>Delete</button>');
					deleteButton.on('click', function () {
						executeCommand("deleteNode", [node.cslId]);
						setupPanel(panel, executeCommand);
					});

					inputRow.append($('	').append(deleteButton));
					table.append(inputRow);
				});

				panel.append(table);

				addButton = $('<button>Add ' + item.name + '</button>');
				panel.append(addButton);

				addButton.on('click', function () {
					CSLEDIT_viewController.setSuppressSelectNode(true);
					executeCommand("addNode",
						[infoNode.cslId, "last", new CSLEDIT_CslNode(item.node)]);
					CSLEDIT_viewController.setSuppressSelectNode(false);
					setupPanel(panel, executeCommand);
				});
				panel.append('

');
			} else {
				debug.assert(nodes.length < 2);
				thisRow = editorRow(item, nodes[0], null);

				panel.append(thisRow);

				simpleTextNodesTable.append($('
')
					.append($('').append(thisRow.children('label')))
					.append($('').append(thisRow.children('input'))));
			}
		});

	};

	return {
		setupPanel : setupPanel
	};
});
<|endoftext|>


<commit_before>System.config({
  defaultJSExtensions: true,
  transpiler: "babel",
  babelOptions: {
    "optional": [
      "runtime",
      "optimisation.modules.system"
    ]
  },
  paths: {
    "github:*": "jspm_packages/github/*",
    "npm:*": "jspm_packages/npm/*"
  },

  map: {
    "babel": "npm:babel-core@5.8.35",
    "babel-runtime": "npm:babel-runtime@5.8.35",
    "backbone-es6-localstorage-todos": "github:typhonjs-demos/backbone-parse-es6-todos-improved@master",
    "core-js": "npm:core-js@1.2.6",
    "github:jspm/nodelibs-assert@0.1.0": {
      "assert": "npm:assert@1.3.0"
    },
    "github:jspm/nodelibs-path@0.1.0": {
      "path-browserify": "npm:path-browserify@0.0.0"
    },
    "github:jspm/nodelibs-process@0.1.2": {
      "process": "npm:process@0.11.2"
    },
    "github:jspm/nodelibs-util@0.1.0": {
      "util": "npm:util@0.10.3"
    },
    "npm:assert@1.3.0": {
      "util": "npm:util@0.10.3"
    },
    "npm:babel-runtime@5.8.35": {
      "process": "github:jspm/nodelibs-process@0.1.2"
    },
    "npm:core-js@1.2.6": {
      "fs": "github:jspm/nodelibs-fs@0.1.2",
      "path": "github:jspm/nodelibs-path@0.1.0",
      "process": "github:jspm/nodelibs-process@0.1.2",
      "systemjs-json": "github:systemjs/plugin-json@0.1.0"
    },
    "npm:inherits@2.0.1": {
      "util": "github:jspm/nodelibs-util@0.1.0"
    },
    "npm:path-browserify@0.0.0": {
      "process": "github:jspm/nodelibs-process@0.1.2"
    },
    "npm:process@0.11.2": {
      "assert": "github:jspm/nodelibs-assert@0.1.0"
    },
    "npm:util@0.10.3": {
      "inherits": "npm:inherits@2.0.1",
      "process": "github:jspm/nodelibs-process@0.1.2"
    }
  }
});
<commit_msg>Removed extra data from JSPM config<commit_after>System.config({
  defaultJSExtensions: true,
  transpiler: "babel",
  babelOptions: {
    "optional": [
      "runtime",
      "optimisation.modules.system"
    ]
  },
  paths: {},
  map: {}
});<|endoftext|>