<commit_before>module('dictionary/async', function( exports, require ) {

	var utils = require("utils"),
		storage = require("storage/async"),

		common = require("common"),
		reNotWord = common.reNotWord,
		reNotWordG = common.reNotWordG,
		reWordJoinerG = common.reWordJoinerG,
		clean = common.cleanTerm,

		_hasOwn_ = Object.prototype.hasOwnProperty;

	function norm( s ) {
		var words = clean( s ).split( reWordJoinerG );
		for ( var i = 0, l = words.length; i < l; ++i ) {
			words[i] = words[i].replace( reNotWordG, "" );
		}
		return words.join(" ").trim().toLowerCase();
	}

	function tokey( s ) {
		return clean( s ).replace(reNotWordG, "").toLowerCase();
	}

	function normToKey( s ) {
		return s.replace(/ /g, "");
	}

	function testChange( s, left, right ) {
		return !(
			left && s.substr(0, left.to).indexOf(" ") !== -1 ||
			right && s.slice(-right.to).indexOf(" ") !== -1
		);
	}

	var undefined;
	const DB_SIZE = 5 * 1024 * 1024;

	exports.Dictionary = Class({

		constructor: function( name, morf ) {
			this.name = name;
			this._dict = storage.DictStorage.open( name, DB_SIZE );
			this._morfology = morf;
		},

		get: function( term, errorCallback, callback ) {
			this._dict.getValue(tokey(term), errorCallback, function( value ) {
				if ( value ) {
					var d = JSON.parse( value );

					if ( d && _hasOwn_.call(d, term) ) {
						value = d[ term ];
					}
				}

				callback( value || undefined );
			});
		},

		set: function( term, def, errorCallback, callback ) {
			var key = tokey( term );

			this._dict.transaction(
				function( t ) {
					t.getValue(key, function( value ) {
						var d = value ? JSON.parse( value ) : {};
						d[ term ] = def;
						t.setValue( key, JSON.stringify(d) );
					});
				},
				errorCallback,
				callback
			);
		},

		// WARNING: not safe if not empty
		setFromObject: function( obj, errorCallback, callback ) {
			var k, d, hash = utils.HASH();

			for ( var term in obj ) {
				k = tokey( term );
				d = hash[ k ];
				if ( !d ) {
					hash[ k ] = d = {};
				}
				d[ term ] = obj[ term ];
			}

			for ( k in hash ) {
				hash[k] = JSON.stringify( hash[k] );
			}

			this._dict.updateWithObject( hash, errorCallback, callback );
		},

		empty: function( errorCallback, callback ) {
			this._dict.reset( errorCallback, callback );
		},

		free: function( callback ) {
			this._dict.erase( null, callback );
		},

		lookup: function( terms, stopOnExact, errorCallback, callback ) {
			var self = this,
				results = [],
				t;

			terms = ( typeof terms === "string" ) ? [ terms ] : terms.concat();

			function handle( original_term, norm_term, simple, morf, leftChange, rightChange, done ) {
				var key_term = normToKey( norm_term );
				done = done || utils.HASH();

				t.getValue(key_term, function( value ) {
					if ( value ) {
						var d = JSON.parse( value ),
							exact = !leftChange && !rightChange,
							k, norm_k;

						for ( k in d ) {
							if ( k in done ) {
								continue;
							}
							done[ k ] = true;

							if ( !simple ) {
								norm_k = norm( k );

								if ( norm_k !== norm_term && norm_k !== key_term ||
									!exact && !testChange(norm_k, leftChange, rightChange) ) {
									continue;
								}
							}

							results.push({
								dict: self.name,
								term: k,
								definitions: d[ k ],
								original_term: original_term,
								exact: exact
							});
						}

						if ( stopOnExact && exact ) {
							return;
						}
					}

					if ( morf ) {
						morf.generate(norm_term, function( term, leftChange, rightChange ) {
							if ( simple || testChange(norm_term, leftChange, rightChange) ) {
								handle( original_term, term, simple, null, leftChange, rightChange, done );
							}
						});
					}
				});
			}

			this._dict.readTransaction(
				function( tr ) {
					t = tr;
					terms.forEach(function( term ) {
						var norm_term = norm( term );
						handle( term, norm_term, norm_term.indexOf(" ") === -1, self._morfology );
					});
				},
				errorCallback,
				function() {
					callback( results );
				}
			);
		}

	});

});
<commit_msg>Ensured that words are separated by one space when normalized.<commit_after>module('dictionary/async', function( exports, require ) {

	var utils = require("utils"),
		storage = require("storage/async"),

		common = require("common"),
		reNotWord = common.reNotWord,
		reNotWordG = common.reNotWordG,
		reWordJoinerG = common.reWordJoinerG,
		clean = common.cleanTerm,

		_hasOwn_ = Object.prototype.hasOwnProperty;

	function norm( s ) {
		var words = clean( s ).split( reWordJoinerG );
		for ( var i = 0, l = words.length; i < l; ++i ) {
			words[i] = words[i].replace( reNotWordG, "" );
		}
		return words.join(" ").trim().replace(/ {2,}/g, " ").toLowerCase();
	}

	function tokey( s ) {
		return clean( s ).replace(reNotWordG, "").toLowerCase();
	}

	function normToKey( s ) {
		return s.replace(/ /g, "");
	}

	function testChange( s, left, right ) {
		return !(
			left && s.substr(0, left.to).indexOf(" ") !== -1 ||
			right && s.slice(-right.to).indexOf(" ") !== -1
		);
	}

	var undefined;
	const DB_SIZE = 5 * 1024 * 1024;

	exports.Dictionary = Class({

		constructor: function( name, morf ) {
			this.name = name;
			this._dict = storage.DictStorage.open( name, DB_SIZE );
			this._morfology = morf;
		},

		get: function( term, errorCallback, callback ) {
			this._dict.getValue(tokey(term), errorCallback, function( value ) {
				if ( value ) {
					var d = JSON.parse( value );

					if ( d && _hasOwn_.call(d, term) ) {
						value = d[ term ];
					}
				}

				callback( value || undefined );
			});
		},

		set: function( term, def, errorCallback, callback ) {
			var key = tokey( term );

			this._dict.transaction(
				function( t ) {
					t.getValue(key, function( value ) {
						var d = value ? JSON.parse( value ) : {};
						d[ term ] = def;
						t.setValue( key, JSON.stringify(d) );
					});
				},
				errorCallback,
				callback
			);
		},

		// WARNING: not safe if not empty
		setFromObject: function( obj, errorCallback, callback ) {
			var k, d, hash = utils.HASH();

			for ( var term in obj ) {
				k = tokey( term );
				d = hash[ k ];
				if ( !d ) {
					hash[ k ] = d = {};
				}
				d[ term ] = obj[ term ];
			}

			for ( k in hash ) {
				hash[k] = JSON.stringify( hash[k] );
			}

			this._dict.updateWithObject( hash, errorCallback, callback );
		},

		empty: function( errorCallback, callback ) {
			this._dict.reset( errorCallback, callback );
		},

		free: function( callback ) {
			this._dict.erase( null, callback );
		},

		lookup: function( terms, stopOnExact, errorCallback, callback ) {
			var self = this,
				results = [],
				t;

			terms = ( typeof terms === "string" ) ? [ terms ] : terms.concat();

			function handle( original_term, norm_term, simple, morf, leftChange, rightChange, done ) {
				var key_term = normToKey( norm_term );
				done = done || utils.HASH();

				t.getValue(key_term, function( value ) {
					if ( value ) {
						var d = JSON.parse( value ),
							exact = !leftChange && !rightChange,
							k, norm_k;

						for ( k in d ) {
							if ( k in done ) {
								continue;
							}
							done[ k ] = true;

							if ( !simple ) {
								norm_k = norm( k );

								if ( norm_k !== norm_term && norm_k !== key_term ||
									!exact && !testChange(norm_k, leftChange, rightChange) ) {
									continue;
								}
							}

							results.push({
								dict: self.name,
								term: k,
								definitions: d[ k ],
								original_term: original_term,
								exact: exact
							});
						}

						if ( stopOnExact && exact ) {
							return;
						}
					}

					if ( morf ) {
						morf.generate(norm_term, function( term, leftChange, rightChange ) {
							if ( simple || testChange(norm_term, leftChange, rightChange) ) {
								handle( original_term, term, simple, null, leftChange, rightChange, done );
							}
						});
					}
				});
			}

			this._dict.readTransaction(
				function( tr ) {
					t = tr;
					terms.forEach(function( term ) {
						var norm_term = norm( term );
						handle( term, norm_term, norm_term.indexOf(" ") === -1, self._morfology );
					});
				},
				errorCallback,
				function() {
					callback( results );
				}
			);
		}

	});

});
<|endoftext|>


<commit_before>/* See license.txt for terms of usage */

define([
    "lib/trace",
    "chrome/tabWatcher",
    "lib/menu",
    "lib/array",
    "lib/css",
    "lib/locale",
    "lib/events",
    "lib/dom",
    "lib/options",
    "chrome/defaultPrefs",
    "app/tabListMenu",
    "remote/connectionMenu",
    "chrome/localProxy",
    "remote/proxy",
    "chrome/chrome",
    "net/netMonitor",
],
function(FBTrace, TabWatcher, Menu, Arr, Css, Locale, Events, Dom, Options,
    DefaultPrefs, TabListMenu, ConnectionMenu, LocalProxy, RemoteProxy, Chrome,
    NetMonitor) {

// ********************************************************************************************* //
// Constants

const Cc = Components.classes;
const Ci = Components.interfaces;

// ********************************************************************************************* //
// Implementation

/**
 * HttpMonitor object represents the entir application.
 */
var HttpMonitor =
{
    initialize: function(win)
    {
        // The parent XUL window.
        this.win = win;

        // Used from XUL
        this.TabListMenu = TabListMenu;
        this.ConnectionMenu = ConnectionMenu;

        // Listen for connection events (onConnect, onDisconnect) and tab selection
        // events (onSelectTab)
        this.ConnectionMenu.addListener(this);
        this.TabListMenu.addListener(this);

        this.tabWatcher = new TabWatcher(this.getPanelDocument());
        this.proxy = new LocalProxy();

        Locale.registerStringBundle("chrome://httpmonitor/locale/httpmonitor.properties");

        // Localize all strings in the application UI.
        this.internationalizeUI(win.document);

        // Initialize options and pass in the pref domain for this application.
        Options.initialize("extensions.httpmonitor");
        Options.registerDefaultPrefs(DefaultPrefs);

        // Initialize modules. Modules represent independent application
        // components that are registered during apppliation load and
        // their life cycle is maintained here.
        Events.dispatch(Chrome.modules, "initialize");
        Events.dispatch(Chrome.modules, "initializeUI");
    },

    destroy: function()
    {
        this.tabWatcher.unwatchTab(this.proxy);

        Events.dispatch(Chrome.modules, "disable");
        Events.dispatch(Chrome.modules, "shutdown");

        Options.shutdown();
    },

    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
    // Connection Hooks

    onConnect: function()
    {
        this.tabWatcher.unwatchTab(this.proxy);

        this.proxy = new RemoteProxy(this.ConnectionMenu.connection);

        TabListMenu.updateUI();
    },

    onDisconnect: function()
    {
        this.tabWatcher.unwatchTab(this.proxy);

        this.proxy = new LocalProxy();

        TabListMenu.updateUI();
    },

    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
    // Tab Selection Hook

    onSelectTab: function(tab)
    {
        this.tabWatcher.watchTab(tab, this.proxy, function()
        {
            TabListMenu.updateUI();
        });
    },

    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
    // UI Commands

    clear: function()
    {
        NetMonitor.clear(Chrome.currentContext);
    },

    togglePersist: function()
    {
        NetMonitor.togglePersist(Chrome.currentContext);
    },

    onToggleFilter: function(filter)
    {
        NetMonitor.onToggleFilter(Chrome.currentContext, filter);
    },

    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
    // Context Menu

    /**
     * Dynamically construct a context mene if the user clicks anywhere within the content
     * area (content of the application window/panel)
     */
    onContextShowing: function(event)
    {
        var popup = event.target;
        if (popup.id != "monitorContextMenu")
            return;

        var context = this.tabWatcher.context;
        var target = this.win.document.popupNode;
        var panel = context.getPanel("net");

        Dom.eraseNode(popup);

        var object;
        if (target && target.ownerDocument == document)
            object = Chrome.getRepObject(target);
        else if (target && panel)
            object = panel.getPopupObject(target);
        else if (target)
            object = Chrome.getRepObject(target);

        var rep = Chrome.getRep(object, context);
        var realObject = rep ? rep.getRealObject(object, context) : null;
        var realRep = realObject ? Chrome.getRep(realObject, context) : null;

        if (FBTrace.DBG_OPTIONS)
            FBTrace.sysout("chrome.onContextShowing object:"+object+" rep: "+rep+
                " realObject: "+realObject+" realRep:"+realRep);

        if (realObject && realRep)
        {
            // 1. Add the custom menu items from the realRep
            var menu = realRep.getContextMenuItems(realObject, target, context);
            if (menu)
            {
                for (var i = 0; i < menu.length; ++i)
                    Menu.createMenuItem(popup, menu[i]);
            }
        }

        if (object && rep && rep != realRep)
        {
            // 1. Add the custom menu items from the original rep
            var items = rep.getContextMenuItems(object, target, context);
            if (items)
            {
                for (var i = 0; i < items.length; ++i)
                    Menu.createMenuItem(popup, items[i]);
            }
        }

        // 1. Add the custom menu items from the panel
        if (panel)
        {
            var items = panel.getContextMenuItems(realObject, target);
            if (items)
            {
                for (var i = 0; i < items.length; ++i)
                    Menu.createMenuItem(popup, items[i]);
            }
        }

        // 3. Add menu items from uiListeners
        var items = [];
        Events.dispatch(Chrome.uiListeners, "onContextMenu", [items, object, target,
            context, panel, popup]);

        if (items)
        {
            for (var i = 0; i < items.length; ++i)
                Menu.createMenuItem(popup, items[i]);
        }

        if (!popup.firstChild)
            return false;
    },

    getPanelDocument: function()
    {
        var browser = this.getPanelBrowser();
        return browser.contentDocument;
    },

    /**
     * Returns reference to the <browser> element that represents the main application UI.
     */
    getPanelBrowser: function()
    {
        return this.win.document.getElementById("content");
    },

    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
    // Localization

    /**
     * Substitute strings in the UI, with fall back to en-US
     */
    internationalizeUI: function(doc)
    {
        if (!doc)
            return;

        if (FBTrace.DBG_INITIALIZE)
            FBTrace.sysout("HTTPMonitor.internationalizeUI");

        var elements = doc.getElementsByClassName("fbInternational");
        elements = Arr.cloneArray(elements);

        var attributes = ["label", "tooltiptext", "aria-label"];
        for (var i=0; i<elements.length; i++)
        {
            var element = elements[i];
            Css.removeClass(elements[i], "fbInternational");
            for (var j=0; j<attributes.length; j++)
            {
                if (element.hasAttribute(attributes[j]))
                    Locale.internationalize(element, attributes[j]);
            }
        }
    },
}

// ********************************************************************************************* //
// Registration

return HttpMonitor;

// ********************************************************************************************* //
});
<commit_msg>typos<commit_after>/* See license.txt for terms of usage */

define([
    "lib/trace",
    "chrome/tabWatcher",
    "lib/menu",
    "lib/array",
    "lib/css",
    "lib/locale",
    "lib/events",
    "lib/dom",
    "lib/options",
    "chrome/defaultPrefs",
    "app/tabListMenu",
    "remote/connectionMenu",
    "chrome/localProxy",
    "remote/proxy",
    "chrome/chrome",
    "net/netMonitor",
],
function(FBTrace, TabWatcher, Menu, Arr, Css, Locale, Events, Dom, Options,
    DefaultPrefs, TabListMenu, ConnectionMenu, LocalProxy, RemoteProxy, Chrome,
    NetMonitor) {

// ********************************************************************************************* //
// Constants

const Cc = Components.classes;
const Ci = Components.interfaces;

// ********************************************************************************************* //
// Implementation

/**
 * HttpMonitor object represents the entire application.
 */
var HttpMonitor =
{
    initialize: function(win)
    {
        // The parent XUL window.
        this.win = win;

        // Used from XUL
        this.TabListMenu = TabListMenu;
        this.ConnectionMenu = ConnectionMenu;

        // Listen for connection events (onConnect, onDisconnect) and tab selection
        // events (onSelectTab)
        this.ConnectionMenu.addListener(this);
        this.TabListMenu.addListener(this);

        this.tabWatcher = new TabWatcher(this.getPanelDocument());
        this.proxy = new LocalProxy();

        Locale.registerStringBundle("chrome://httpmonitor/locale/httpmonitor.properties");

        // Localize all strings in the application UI.
        this.internationalizeUI(win.document);

        // Initialize options and pass in the pref domain for this application.
        Options.initialize("extensions.httpmonitor");
        Options.registerDefaultPrefs(DefaultPrefs);

        // Initialize modules. Modules represent independent application
        // components that are registered during application load and
        // their life cycle is maintained here.
        Events.dispatch(Chrome.modules, "initialize");
        Events.dispatch(Chrome.modules, "initializeUI");
    },

    destroy: function()
    {
        this.tabWatcher.unwatchTab(this.proxy);

        Events.dispatch(Chrome.modules, "disable");
        Events.dispatch(Chrome.modules, "shutdown");

        Options.shutdown();
    },

    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
    // Connection Hooks

    onConnect: function()
    {
        this.tabWatcher.unwatchTab(this.proxy);

        this.proxy = new RemoteProxy(this.ConnectionMenu.connection);

        TabListMenu.updateUI();
    },

    onDisconnect: function()
    {
        this.tabWatcher.unwatchTab(this.proxy);

        this.proxy = new LocalProxy();

        TabListMenu.updateUI();
    },

    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
    // Tab Selection Hook

    onSelectTab: function(tab)
    {
        this.tabWatcher.watchTab(tab, this.proxy, function()
        {
            TabListMenu.updateUI();
        });
    },

    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
    // UI Commands

    clear: function()
    {
        NetMonitor.clear(Chrome.currentContext);
    },

    togglePersist: function()
    {
        NetMonitor.togglePersist(Chrome.currentContext);
    },

    onToggleFilter: function(filter)
    {
        NetMonitor.onToggleFilter(Chrome.currentContext, filter);
    },

    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
    // Context Menu

    /**
     * Dynamically construct a context menu if the user clicks anywhere within the content
     * area (content of the application window/panel)
     */
    onContextShowing: function(event)
    {
        var popup = event.target;
        if (popup.id != "monitorContextMenu")
            return;

        var context = this.tabWatcher.context;
        var target = this.win.document.popupNode;
        var panel = context.getPanel("net");

        Dom.eraseNode(popup);

        var object;
        if (target && target.ownerDocument == document)
            object = Chrome.getRepObject(target);
        else if (target && panel)
            object = panel.getPopupObject(target);
        else if (target)
            object = Chrome.getRepObject(target);

        var rep = Chrome.getRep(object, context);
        var realObject = rep ? rep.getRealObject(object, context) : null;
        var realRep = realObject ? Chrome.getRep(realObject, context) : null;

        if (FBTrace.DBG_OPTIONS)
            FBTrace.sysout("chrome.onContextShowing object:"+object+" rep: "+rep+
                " realObject: "+realObject+" realRep:"+realRep);

        if (realObject && realRep)
        {
            // 1. Add the custom menu items from the realRep
            var menu = realRep.getContextMenuItems(realObject, target, context);
            if (menu)
            {
                for (var i = 0; i < menu.length; ++i)
                    Menu.createMenuItem(popup, menu[i]);
            }
        }

        if (object && rep && rep != realRep)
        {
            // 1. Add the custom menu items from the original rep
            var items = rep.getContextMenuItems(object, target, context);
            if (items)
            {
                for (var i = 0; i < items.length; ++i)
                    Menu.createMenuItem(popup, items[i]);
            }
        }

        // 1. Add the custom menu items from the panel
        if (panel)
        {
            var items = panel.getContextMenuItems(realObject, target);
            if (items)
            {
                for (var i = 0; i < items.length; ++i)
                    Menu.createMenuItem(popup, items[i]);
            }
        }

        // 3. Add menu items from uiListeners
        var items = [];
        Events.dispatch(Chrome.uiListeners, "onContextMenu", [items, object, target,
            context, panel, popup]);

        if (items)
        {
            for (var i = 0; i < items.length; ++i)
                Menu.createMenuItem(popup, items[i]);
        }

        if (!popup.firstChild)
            return false;
    },

    getPanelDocument: function()
    {
        var browser = this.getPanelBrowser();
        return browser.contentDocument;
    },

    /**
     * Returns reference to the <browser> element that represents the main application UI.
     */
    getPanelBrowser: function()
    {
        return this.win.document.getElementById("content");
    },

    // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
    // Localization

    /**
     * Substitute strings in the UI, with fall back to en-US
     */
    internationalizeUI: function(doc)
    {
        if (!doc)
            return;

        if (FBTrace.DBG_INITIALIZE)
            FBTrace.sysout("HTTPMonitor.internationalizeUI");

        var elements = doc.getElementsByClassName("fbInternational");
        elements = Arr.cloneArray(elements);

        var attributes = ["label", "tooltiptext", "aria-label"];
        for (var i=0; i<elements.length; i++)
        {
            var element = elements[i];
            Css.removeClass(elements[i], "fbInternational");
            for (var j=0; j<attributes.length; j++)
            {
                if (element.hasAttribute(attributes[j]))
                    Locale.internationalize(element, attributes[j]);
            }
        }
    },
}

// ********************************************************************************************* //
// Registration

return HttpMonitor;

// ********************************************************************************************* //
});
<|endoftext|>


<commit_before>var http = require("http").createServer(handler); // handler will be the function with req, res as in previous example, just separated
var io = require("socket.io").listen(http); // socket.io for permanent connection between server and client
var fs = require("fs"); // variable fo "file system", i.e. fs
var firmata = require("firmata"); // make pins on Arduin oaccesible via serial-USB communication
var sendValueViaSocket = function() {}; // function to send message over socket
var sendStaticMsgViaSocket = function() {}; // function to send static message over socket
	 function handler(req, res) { // function with request and response, that is used in the first line of this example
     fs.readFile(__dirname + "/23diod.html",
      function (err, data){
          if (err) {
              res.writeHead(500, {"Content-Type": "text/plain"});
              return res.end("Error loading html page.");
	          }
      res.writeHead(200);
      res.end(data);
	      })
	  }

var desiredValue = 0; // variable for desired value (reference value or input)
var actualValue = 0; // variable for actual value (output value)

 // PID Algorithm variables
var Kp = 0.55; // proportional factor
var Ki = 0.008; // integral factor
var Kd = 0.15; // differential factor

var pwm = 0;
var pwmLimit = 110;
var lastPWM = 0; // to check, weather pwm has changed, not to call it all the time

var err = 0; // variable for second pid implementation
var errSum = 0; // sum of errors
var dErr = 0; // difference of error
var lastErr = 0; // to keep the value of previous error
var KpE = 0; // multiplication of Kp x error
var KiIedt = 0; // multiplication of Ki x integral of error
var KdDe_dt = 0; // multiplication of Kd x differential of error i.e.e Derror/dt

var parametersStore ={}; // variable for json structure of parameters
var errSumAbs = 0; // sum of absolute errors as performance measure
var errAbs = 0; // absolute error
var errLast = 0;

var controlAlgorithmStartedFlag = 0; // flag in global scope to see weather ctrlAlg has been started
var intervalCtrl; // var for setInterval in global space

var readAnalogPin0Flag = 1; // for reading the pin if pot is driver

http.listen(8080); // determine on which port to listen (8080)
console.log("Starting the system"); // print the message to the console
var board = new firmata.Board("/dev/ttyACM0", function(){ // ACM Abstract Control Model for serial communication with Arduino (could be USB)
	      console.log("Connecting to Arduino");
	      board.pinMode(0, board.MODES.ANALOG); // analog pin 0
          board.pinMode(1, board.MODES.ANALOG); // analog pin 1
	      board.pinMode(2, board.MODES.OUTPUT); // direction of DC motor
	      board.pinMode(3, board.MODES.PWM); // PWM of motor i.e. speed of rotation
	      board.pinMode(4, board.MODES.OUTPUT); // direction DC motor
	  });

	  board.on("ready", function() {

	  board.analogRead(0, function(value) {
	      if (readAnalogPin0Flag == 1) desiredValue = value; // continuous read of pin A0
	  });

	  board.analogRead(1, function(value) {
	      actualValue = value; // continuous read of pin A1
	  });

	  io.sockets.on('connection', function(socket) {  // from bracket ( onward, we have an argument of the function on -> at 'connection' the argument is transfered i.e. function(socket)

	      socket.emit("messageToClient", "Server connected, board ready.");
	      socket.emit("staticMsgToClient", "Server connected, board ready.")

	      setInterval(sendValues, 40, socket); // na 40ms we send message to client

	      socket.on("startControlAlgorithm", function(numberOfControlAlgorithm){
	          startControlAlgorithm(numberOfControlAlgorithm);
	      });

          socket.on("sendPosition", function(position){
              readAnalogPin0Flag = 0; // to stop reading from pin 0
              desiredValue = position; // now the desired value from the GUI takes control
              socket.emit("messageToClient", "Position set to: position.")
	      });

	      socket.on("stopControlAlgorithm", function(){
	          stopControlAlgorithm();
	      });

	      sendValueViaSocket = function (value) {
	          io.sockets.emit("messageToClient", value);
      }

	      sendStaticMsgViaSocket = function (value) {
	          io.sockets.emit("staticMsgToClient", value);
	      }

	  });

  });

function controlAlgorithm (parameters) {
    if (parameters.ctrlAlgNo == 1) {
	   pwm = parameters.pCoeff*(desiredValue-actualValue);
       errAbs = Math.abs(desiredValue-actualValue);
       errSumAbs += errAbs;
	   if(pwm > pwmLimit) {pwm = pwmLimit}; // to limit the value for pwm / positive
	   if(pwm < -pwmLimit) {pwm = -pwmLimit}; // to limit the value for pwm / negative
	   if (pwm > 0) {board.digitalWrite(2,1); board.digitalWrite(4,0);}; // določimo smer če je > 0
	   if (pwm < 0) {board.digitalWrite(2,0); board.digitalWrite(4,1);}; // določimo smer če je < 0
	   board.analogWrite(3, Math.round(Math.abs(pwm)));
	   console.log(Math.round(pwm));
	  }

	if (parameters.ctrlAlgNo == 2) {
	   err = desiredValue - actualValue; // error
	   errSum += err; // sum of errors, like integral
       errAbs = Math.abs(err);
       errSumAbs += errAbs;
       dErr = err - lastErr; // difference of error
       // for sending to client we put the parts to global scope
       KpE=parameters.Kp1*err;
       KiIedt=parameters.Ki1*errSum;
       KdDe_dt=parameters.Kd1*dErr;
       pwm = KpE + KiIedt + KdDe_dt; // above parts are used
	   lastErr = err; // save the value for the next cycle
	   if(pwm > pwmLimit) {pwm = pwmLimit}; // to limit the value for pwm / positive
       if(pwm < -pwmLimit) {pwm = -pwmLimit}; // to limit the value for pwm / negative
	   if (pwm > 0) {board.digitalWrite(2,1); board.digitalWrite(4,0);}; // določimo smer če je > 0
	   if (pwm < 0) {board.digitalWrite(2,0); board.digitalWrite(4,1);}; // določimo smer če je < 0
         board.analogWrite(3, Math.abs(pwm));
     }
      if (parameters.ctrlAlgNo == 3) {
         err = desiredValue - actualValue; // error as difference between desired and actual val.
         errSum += err; // sum of errors | like integral
         errAbs = Math.abs(err);
         errSumAbs += errAbs;
         dErr = err - lastErr; // difference of error
         pwm = parameters.Kp2*err+parameters.Ki2*errSum+parameters.Kd2*dErr; // PID expression
         console.log(parameters.Kp2 + "|" + parameters.Ki2 + "|" + parameters.Kd2);
         lastErr = err; // save the value of error for next cycle to estimate the derivative
         if (pwm > pwmLimit) {pwm =  pwmLimit}; // to limit pwm values
         if (pwm < -pwmLimit) {pwm = -pwmLimit}; // to limit pwm values
         if (pwm > 0) {board.digitalWrite(2,1); board.digitalWrite(4,0);}; // direction if > 0
         if (pwm < 0) {board.digitalWrite(2,0); board.digitalWrite(4,1);}; // direction if < 0
	   board.analogWrite(3, Math.abs(pwm));
      }
     if (parameters.ctrlAlgNo == 4) {
         errLast = err;
         err = desiredValue - actualValue; // error
         errSum += err; // sum of errors, like integral
         errAbs = Math.abs(err);
         errSumAbs += errAbs;
         dErr = err - lastErr; // difference of error
         // for sending to client we put the parts to global scope
         KpE=parameters.Kp3*err;
         KiIedt=parameters.Ki3*errSum;
         KdDe_dt=parameters.Kd3*dErr;
         console.log(parameters.Ki3 + " " + 254/parameters.Ki3 + " " + errSum)
     if(errSum > 254/parameters.Ki3)
             errSum = 254/parameters.Ki3;
         if(errSum < -254/parameters.Ki3)
             errSum = -254/parameters.Ki3;
         if(err*errLast < 0)
             errSum = 0;
             pwm = KpE + KiIedt + KdDe_dt; // above parts are used
             lastErr = err; // save the value for the next cycle
         if(pwm > pwmLimit) {pwm = pwmLimit}; // to limit the value for pwm / positive
         if(pwm < -pwmLimit) {pwm = -pwmLimit}; // to limit the value for pwm / negative
         if (pwm > 0) {board.digitalWrite(2,1); board.digitalWrite(4,0);}; // določimo smer če je > 0
         if (pwm < 0) {board.digitalWrite(2,0); board.digitalWrite(4,1);}; // določimo smer če je < 0
         board.analogWrite(3, Math.abs(pwm));
         console.log("algorithm 4 444");
	  }
};

function sendValues (socket) {
    socket.emit("clientReadValues",
    { // json notation between curly braces
    "desiredValue": desiredValue,
    "actualValue": actualValue,
    "pwm": pwm,
    "err": err,
    "errSum": errSum,
    "dErr": dErr,
    "KpE": KpE,
    "KiIedt": KiIedt,
    "KdDe_dt": KdDe_dt,
    "errSumAbs": errSumAbs,
    "errAbs": errAbs
  });
};

	  function startControlAlgorithm (parameters) {
	      if (controlAlgorithmStartedFlag == 0) {
	          controlAlgorithmStartedFlag = 1; // set flag that the algorithm has started
	          intervalCtrl = setInterval(function() {controlAlgorithm(parameters); }, 30); // na 30ms klic
	          console.log("Control algorithm " + parameters.ctrlAlgNo + " started");
	          sendStaticMsgViaSocket("Control algorithm " + parameters.ctrlAlgNo + " started | " + json2txt(parameters));
	          parametersStore = parameters; // store to report back to the client on algorithm stop
      }
	  };

	  function stopControlAlgorithm () {
	      clearInterval(intervalCtrl); // clear the interval of control algorihtm
	      board.analogWrite(3,0); // write 0 on pwm pin to stop the motor
	      sendStaticMsgViaSocket("Control algorithm " + parametersStore.ctrlAlgNo + " stopped | " + json2txt(parametersStore) + " | errSumAbs = " + errSumAbs);
	      controlAlgorithmStartedFlag = 0; // set flag that the algorithm has stopped
	      pwm = 0; // set pwm to 0

	      err = 0; // error
	      errSum = 0; // sum of errors, like integral
	      dErr = 0; // difference of error
	      KpE = 0;
	      KiIedt = 0;
	      KdDe_dt = 0;
          errSumAbs = 0;
          errLast = 0;

          parametersStore = {}; // empty temporary json object to report at controAlg stop

	      console.log("ctrlAlg STOPPED");

	  };

	  function json2txt(obj) // function to print out the json names and values
	  {
	    var txt = '';
    var recurse = function(_obj) {
	      if ('object' != typeof(_obj)) {
	        txt += ' = ' + _obj + '\n';
      }
      else {
	        for (var key in _obj) {
	          if (_obj.hasOwnProperty(key)) {
	            txt += '.' + key;
	            recurse(_obj[key]);
              }
	        }
	       }
	    };
	    recurse(obj);
	    return txt;
	  }<commit_msg>Delete 23diod.js<commit_after><|endoftext|>


<commit_before>
var path   = require("path")
    evento = require("evento"),
    _      = require("underscore");

function Filter() {

};

Filter.prototype = {

    request: null,

    defaultBranchName: "master",

    defaultRepositoryName: "origin",

    branch: function()
    {
        return this;
    },

    config: function()
    {
        this.request.configPath = path.resolve(this.getConfigPath());
        return this;
    },

    dir: function()
    {
        this.request.repository = path.resolve(this.request.args[0]);
        delete this.request.args;
        return this;
    },

    filter: function()
    {
console.log(this.request);
        this.dir()
            .config()
            .branch()
            .repository();
        evento.trigger("info", "Repository: "+this.request.repository);
        evento.trigger("info", "Config: "    +this.request.configPath);
//        evento.trigger("filter");
    },

    getConfigPath: function()
    {
        return [
            this.request.repository,
            this.request.configPath
        ].join('/');
    },

    repository: function()
    {
        return this;
    }
};

module.exports = new Filter();<commit_msg>filter for branch name and remote repository name<commit_after>
var path   = require("path")
    evento = require("evento"),
    _      = require("underscore");

function Filter() {

};

Filter.prototype = {

    request: null,

    defaults: {
        branchName          : "master",
        remoteRepositoryName: "origin",
    },

    branch: function()
    {
        this.request.branchName = _.isUndefined(this.request.branchName)
            ? this.defaults.branchName
            : this.request.branchName;
        return this;
    },

    config: function()
    {
        this.request.configPath = path.resolve(this.getConfigPath());
        return this;
    },

    dir: function()
    {
        this.request.repository = path.resolve(this.request.args[0]);
        delete this.request.args;
        return this;
    },

    filter: function()
    {

        this.dir()
            .config()
            .branch()
            .repository();
        evento.trigger("info", "Repository: "+this.request.repository);
        evento.trigger("info", "Config: "    +this.request.configPath);
        evento.trigger("info", "Branch name: "    +this.request.branchName);
        evento.trigger("info", "Remote repository name: "    +this.request.remoteRepositoryName);
//        evento.trigger("filter");
    },

    getConfigPath: function()
    {
        return [
            this.request.repository,
            this.request.configPath
        ].join('/');
    },

    repository: function()
    {
        this.request.remoteRepositoryName = _.isUndefined(this.request.remoteRepositoryName)
            ? this.defaults.remoteRepositoryName
            : this.request.remoteRepositoryName;
        return this;
    }
};

module.exports = new Filter();<|endoftext|>


<commit_before>/**
 * @file TableCalculation vendor
 * @author liangxiaojun(liangxiaojun@derbysoft.com)
 */

import classnames from 'classnames';

import SelectAllMode from '../_statics/SelectAllMode';
import HorizontalAlign from '../_statics/HorizontalAlign';

import Util from '../_vendors/Util';
import VirtualRoot from '../_statics/VirtualRoot';

function calcSpan(type, column, colIndex, rowIndex) {
    const span = column[`${type}Span`];
    return span && typeof span === 'function' ?
        span(colIndex, rowIndex)
        :
        +span;
}

function getColumnsWithSpan(type, columns, rowIndex) {

    if (!type) {
        return columns.map(column => ({
            column,
            span: 1
        }));
    }

    const result = [];
    let spanFlag = 0;

    for (let i = 0, len = columns.length; i < len; i++) {

        if (spanFlag > 1) {
            spanFlag--;
            continue;
        }

        const column = columns[i],
            span = calcSpan(type, columns[i], i, rowIndex);

        if (span && span > 1) {
            spanFlag = span;
        }

        result.push({
            column,
            span
        });

    }

    return result;

}

function sortTableData(data, sorting, sortFunc) {

    if (!data) {
        return [];
    }

    if (!sorting) {
        return data;
    }

    let copyData = data.slice();

    if (sortFunc) {
        copyData = sortFunc(copyData, sorting);
    } else {
        copyData.sort((a, b) => {
            if (!isNaN(a[sorting.prop]) && !isNaN(b[sorting.prop])) {
                return (Number(a[sorting.prop]) - Number(b[sorting.prop])) * sorting.type;
            } else {
                return (a[sorting.prop] + '').localeCompare(b[sorting.prop] + '') * sorting.type;
            }
        });
    }

    return copyData;

}

function hasAnyRenderer(columns, fragment) {
    return columns && fragment ? columns.some(item => item[`${fragment}Renderer`]) : false;
}

function handleFixedColumns(columns) {

    if (!columns) {
        return columns;
    }

    return columns.map(column => ({
        ...column,
        headClassName: classnames(column.headClassName, 'table-fixed-column'),
        bodyClassName: classnames(column.bodyClassName, 'table-fixed-column'),
        footClassName: classnames(column.footClassName, 'table-fixed-column')
    }));

}

function getDataByPagination(data, isPaginated, pagination) {

    if (!data || data.length < 1) {
        return [];
    }

    if (!isPaginated || !pagination) {
        return data;
    }

    return data.slice(pagination.page * pagination.pageSize, (pagination.page + 1) * pagination.pageSize)
               .filter(item => item && !item.disabled);

}

function indexOfNodeInValue(node, value, idProp) {

    if (!node || !value) {
        return -1;
    }

    let index = value.findIndex(item => (idProp in item) && (idProp in node) && item[idProp] === node[idProp]);
    if (index < 0) {
        index = value.indexOf(node);
    }

    return index;

}

function isNodeChecked(node, value, idProp) {
    return indexOfNodeInValue(node, value, idProp) >= 0;
}

function isNodeIndeterminate(node, value, idProp) {

    if (!node || !node.children || node.children.length < 1
        || !value || !value.length || value.length < 1) {
        return false;
    }

    let total = 0,
        count = 0;

    Util.preOrderTraverse(node, nodeItem => {
        total++;
        if (isNodeChecked(nodeItem, value, idProp)) {
            count++;
        }
    });

    return count > 0 && total !== count;

}

function isRootNodeChecked(data, value, idProp) {

    let total = 0,
        count = 0;

    Util.preOrderTraverse({
        [VirtualRoot]: true,
        children: data
    }, node => {
        if (!(VirtualRoot in node)) {
            total++;
            if (isNodeChecked(node, value, idProp)) {
                count++;
            }
        }
    });

    return {
        checked: total > 0 && count === total,
        indeterminate: count > 0 && total !== count
    };

}

function handleSelect(rowData, rowIndex, value, idProp) {

    if (!rowData) {
        return;
    }

    const index = indexOfNodeInValue(rowData, value, idProp);
    if (index >= 0) {
        value.splice(index, 1);
    } else {
        value.push(rowData);
    }

    return {value, checked: index === -1};

}

function handleSelectAllChange(checked, selectAllMode, data, tableData, value, idProp) {

    if (selectAllMode === SelectAllMode.ALL) {
        return checked ? data.filter(item => !item.disabled) : [];
    }

    const currentPageData = tableData.filter(item => item && !item.disabled);

    if (checked) {

        if (!value || value.length < 1) {
            return currentPageData;
        }

        const result = value.slice();
        currentPageData.forEach(item => {
            if (!isNodeChecked(item, result, idProp)) {
                result.push(item);
            }
        });
        return result;

    } else {

        if (!value || value.length < 1) {
            return [];
        }

        const result = value.slice();
        currentPageData.forEach(item => {
            const index = indexOfNodeInValue(item, result, idProp);
            if (index > -1) {
                result.splice(index, 1);
            }
        });
        return result;

    }

}

function getFirstColumnPosition(columns) {
    if (columns[HorizontalAlign.LEFT].length > 0) {
        return HorizontalAlign.LEFT;
    } else if (columns[HorizontalAlign.CENTER].length > 0) {
        return HorizontalAlign.CENTER;
    } else if (columns[HorizontalAlign.RIGHT].length > 0) {
        return HorizontalAlign.RIGHT;
    }
    return null;
}

export default {
    calcSpan,
    getColumnsWithSpan,
    sortTableData,
    hasAnyRenderer,
    handleFixedColumns,
    getDataByPagination,
    indexOfNodeInValue,
    isNodeChecked,
    isNodeIndeterminate,
    isRootNodeChecked,
    handleSelect,
    handleSelectAllChange,
    getFirstColumnPosition
};
<commit_msg>update TableCalculation<commit_after>/**
 * @file TableCalculation vendor
 * @author liangxiaojun(liangxiaojun@derbysoft.com)
 */

import classnames from 'classnames';

import SelectAllMode from '../_statics/SelectAllMode';
import HorizontalAlign from '../_statics/HorizontalAlign';

import Util from '../_vendors/Util';
import VirtualRoot from '../_statics/VirtualRoot';

function calcSpan(type, column, colIndex, rowIndex) {
    const span = column[`${type}Span`];
    return span && typeof span === 'function' ?
        span(colIndex, rowIndex)
        :
        +span;
}

function getColumnsWithSpan(type, columns, rowIndex) {

    if (!type) {
        return columns.map(column => ({
            column,
            span: 1
        }));
    }

    const result = [];
    let spanFlag = 0;

    for (let i = 0, len = columns.length; i < len; i++) {

        if (spanFlag > 1) {
            spanFlag--;
            continue;
        }

        const column = columns[i],
            span = calcSpan(type, columns[i], i, rowIndex);

        if (span && span > 1) {
            spanFlag = span;
        }

        result.push({
            column,
            span
        });

    }

    return result;

}

function sortTableData(data, sorting, sortFunc) {

    if (!data) {
        return [];
    }

    if (!sorting) {
        return data;
    }

    let copyData = data.slice();

    if (sortFunc) {
        copyData = sortFunc(copyData, sorting);
    } else {
        copyData.sort((a, b) => {
            if (!isNaN(a[sorting.prop]) && !isNaN(b[sorting.prop])) {
                return (Number(a[sorting.prop]) - Number(b[sorting.prop])) * sorting.type;
            } else {
                return (a[sorting.prop] + '').localeCompare(b[sorting.prop] + '') * sorting.type;
            }
        });
    }

    return copyData;

}

function hasAnyRenderer(columns, fragment) {
    return columns && fragment ? columns.some(item => item[`${fragment}Renderer`]) : false;
}

function handleFixedColumns(columns) {

    if (!columns) {
        return columns;
    }

    return columns.map(column => ({
        ...column,
        headClassName: classnames(column.headClassName, 'table-fixed-column'),
        bodyClassName: classnames(column.bodyClassName, 'table-fixed-column'),
        footClassName: classnames(column.footClassName, 'table-fixed-column')
    }));

}

function getDataByPagination(data, isPaginated, pagination) {

    if (!data || data.length < 1) {
        return [];
    }

    if (!isPaginated || !pagination) {
        return data;
    }

    return data.slice(pagination.page * pagination.pageSize, (pagination.page + 1) * pagination.pageSize)
               .filter(item => item && !item.disabled);

}

function indexOfNodeInValue(node, value, idProp) {

    if (!node || !value) {
        return -1;
    }

    let index = value.findIndex(item => (idProp in item) && (idProp in node) && item[idProp] === node[idProp]);
    if (index < 0) {
        index = value.indexOf(node);
    }

    return index;

}

function isNodeChecked(node, value, idProp) {
    return indexOfNodeInValue(node, value, idProp) >= 0;
}

function isNodeIndeterminate(node, value, idProp) {

    if (!node || !node.children || node.children.length < 1
        || !value || !value.length || value.length < 1) {
        return false;
    }

    let total = 0,
        count = 0;

    Util.preOrderTraverse(node, nodeItem => {
        total++;
        if (isNodeChecked(nodeItem, value, idProp)) {
            count++;
        }
    });

    return count > 0 && total !== count;

}

function isRootNodeChecked(data, value, idProp) {

    let total = 0,
        count = 0;

    Util.preOrderTraverse({
        [VirtualRoot]: true,
        children: data
    }, node => {
        if (!(VirtualRoot in node)) {
            total++;
            if (isNodeChecked(node, value, idProp)) {
                count++;
            }
        }
    });

    return {
        checked: total > 0 && count === total,
        indeterminate: count > 0 && total !== count
    };

}

function handleSelect(rowData, rowIndex, value, idProp) {

    if (!rowData) {
        return;
    }

    const index = indexOfNodeInValue(rowData, value, idProp);
    if (index >= 0) {
        value.splice(index, 1);
    } else {
        value.push(rowData);
    }

    return {value, checked: index === -1};

}

function handleSelectAllChange(checked, selectAllMode, data, tableData, value, idProp) {

    if (selectAllMode === SelectAllMode.ALL) {
        return checked ? data.filter(item => !item.disabled) : [];
    }

    const currentPageData = tableData.filter(item => item && !item.disabled);

    if (checked) {

        if (!value || value.length < 1) {
            return currentPageData;
        }

        const result = value.slice();
        currentPageData.forEach(item => {
            if (!isNodeChecked(item, result, idProp)) {
                result.push(item);
            }
        });
        return result;

    } else {

        if (!value || value.length < 1) {
            return [];
        }

        const result = value.slice();
        currentPageData.forEach(item => {
            const index = indexOfNodeInValue(item, result, idProp);
            if (index > -1) {
                result.splice(index, 1);
            }
        });
        return result;

    }

}

function getFirstColumnPosition(columns) {
    if (columns[HorizontalAlign.LEFT].length > 0) {
        return HorizontalAlign.LEFT;
    } else if (columns[HorizontalAlign.CENTER].length > 0) {
        return HorizontalAlign.CENTER;
    } else if (columns[HorizontalAlign.RIGHT].length > 0) {
        return HorizontalAlign.RIGHT;
    }
    return null;
}

function recursiveSelectChildren(node, value = [], idProp) {

    if (!node) {
        return value;
    }

    Util.preOrderTraverse(node, child => {
        if (!isNodeChecked(child, value, idProp)) {
            value.push(child);
        }
    });

    return value;

}

export default {
    calcSpan,
    getColumnsWithSpan,
    sortTableData,
    hasAnyRenderer,
    handleFixedColumns,
    getDataByPagination,
    indexOfNodeInValue,
    isNodeChecked,
    isNodeIndeterminate,
    isRootNodeChecked,
    handleSelect,
    handleSelectAllChange,
    getFirstColumnPosition,
    recursiveSelectChildren
};
<|endoftext|>


<commit_before>FBL.ns(function() { with (FBL) {
// ************************************************************************************************

// ************************************************************************************************
// Console

var ConsoleAPI =
{
    firebuglite: Firebug.version,

    xxx: function(o)
    {
        var rep = Firebug.getRep(o);
        var className = "";

        var panel = Firebug.DOM.getPanel();
        var toggles = {};

        var row = Firebug.Console.getPanel().contentNode.ownerDocument.createElement("div");
        var target = row;
        var object = o;

        row.className = "logRow" + (className ? " logRow-"+className : "");
        //row.innerHTML = message.join("");

        rep.tag.replace({domPanel: panel, toggles: toggles, object: object}, target);

        Firebug.Console.appendRow(row);
    },

    log: function()
    {
        return Firebug.Console.logFormatted(arguments, "");
    },

    debug: function()
    {
        return Firebug.Console.logFormatted(arguments, "debug");
    },

    info: function()
    {
        return Firebug.Console.logFormatted(arguments, "info");
    },

    warn: function()
    {
        return Firebug.Console.logFormatted(arguments, "warning");
    },

    error: function()
    {
        return Firebug.Console.logFormatted(arguments, "error");
    },

    assert: function(truth, message)
    {
        if (!truth)
        {
            var args = [];
            for (var i = 1; i < arguments.length; ++i)
                args.push(arguments[i]);

            Firebug.Console.logFormatted(args.length ? args : ["Assertion Failure"], "error");
            throw message ? message : "Assertion Failure";
        }

        return Firebug.Console.LOG_COMMAND;
    },

    dir: function(object)
    {
        var html = [];

        var pairs = [];
        for (var name in object)
        {
            try
            {
                pairs.push([name, object[name]]);
            }
            catch (exc)
            {
            }
        }

        pairs.sort(function(a, b) { return a[0] < b[0] ? -1 : 1; });

        html.push('
');
        for (var i = 0; i < pairs.length; ++i)
        {
            var name = pairs[i][0], value = pairs[i][1];

            html.push('
',
                '
');

            Firebug.Reps.appendObject(value, html);

            html.push('

',
                escapeHTML(name), '
');

            html.push('
');
        }
        html.push('
');

        return Firebug.Console.logRow(html, "dir");
    },

    dirxml: function(node)
    {
        var html = [];

        Firebug.Reps.appendNode(node, html);
        return Firebug.Console.logRow(html, "dirxml");
    },

    group: function()
    {
        return Firebug.Console.logRow(arguments, "group", Firebug.Console.pushGroup);
    },

    groupEnd: function()
    {
        return Firebug.Console.logRow(arguments, "", Firebug.Console.popGroup);
    },

    time: function(name)
    {
        this.timeMap[name] = (new Date()).getTime();
        return Firebug.Console.LOG_COMMAND;
    },

    timeEnd: function(name)
    {
        if (name in this.timeMap)
        {
            var delta = (new Date()).getTime() - this.timeMap[name];
            Firebug.Console.logFormatted([name+ ":", delta+"ms"]);
            delete this.timeMap[name];
        }
        return Firebug.Console.LOG_COMMAND;
    },

    count: function()
    {
        return this.warn(["count() not supported."]);
    },

    trace: function()
    {
        return this.warn(["trace() not supported."]);
    },

    profile: function()
    {
        return this.warn(["profile() not supported."]);
    },

    profileEnd: function()
    {
        return Firebug.Console.LOG_COMMAND;
    },

    clear: function()
    {
        Firebug.Console.getPanel().contentNode.innerHTML = "";
        return Firebug.Console.LOG_COMMAND;
    },

    open: function()
    {
        toggleConsole(true);
        return Firebug.Console.LOG_COMMAND;
    },

    close: function()
    {
        if (frameVisible)
            toggleConsole();

        return Firebug.Console.LOG_COMMAND;
    }
};

// ************************************************************************************************
// Console Module

var ConsoleModule = extend(Firebug.Module, ConsoleAPI);

Firebug.Console = extend(ConsoleModule,
{
    LOG_COMMAND: {},

    groupStack: [],
    timeMap: {},

    getPanel: function()
    {
        return Firebug.chrome ? Firebug.chrome.getPanel("Console") : null;
    },

    flush: function()
    {
        var queue = FirebugChrome.consoleMessageQueue;
        FirebugChrome.consoleMessageQueue = [];

        for (var i = 0; i < queue.length; ++i)
            this.writeMessage(queue[i][0], queue[i][1], queue[i][2]);
    },

    // ********************************************************************************************

    logFormatted: function(objects, className)
    {
        var html = [];

        var format = objects[0];
        var objIndex = 0;

        if (typeof(format) != "string")
        {
            format = "";
            objIndex = -1;
        }

        var parts = this.parseFormat(format);
        for (var i = 0; i < parts.length; ++i)
        {
            var part = parts[i];
            if (part && typeof(part) == "object")
            {
                var object = objects[++objIndex];
                part.appender(object, html);
            }
            else
                Firebug.Reps.appendText(part, html);
        }

        for (var i = objIndex+1; i < objects.length; ++i)
        {
            Firebug.Reps.appendText(" ", html);

            var object = objects[i];
            if (typeof(object) == "string")
                Firebug.Reps.appendText(object, html);
            else
                Firebug.Reps.appendObject(object, html);
        }

        return this.logRow(html, className);
    },

    parseFormat: function(format)
    {
        var parts = [];

        var reg = /((^%|[^\\]%)(\d+)?(\.)([a-zA-Z]))|((^%|[^\\]%)([a-zA-Z]))/;
        var Reps = Firebug.Reps;
        var appenderMap = {
                s: Reps.appendText,
                d: Reps.appendInteger,
                i: Reps.appendInteger,
                f: Reps.appendFloat
            };

        for (var m = reg.exec(format); m; m = reg.exec(format))
        {
            var type = m[8] ? m[8] : m[5];
            var appender = type in appenderMap ? appenderMap[type] : Reps.appendObject;
            var precision = m[3] ? parseInt(m[3]) : (m[4] == "." ? -1 : 0);

            parts.push(format.substr(0, m[0][0] == "%" ? m.index : m.index+1));
            parts.push({appender: appender, precision: precision});

            format = format.substr(m.index+m[0].length);
        }

        parts.push(format);

        return parts;
    },

    // ********************************************************************************************

    logRow: function(message, className, handler)
    {
        var panel = this.getPanel();

        if (panel && panel.contentNode)
            this.writeMessage(message, className, handler);
        else
        {
            FirebugChrome.consoleMessageQueue.push([message, className, handler]);
        }

        return this.LOG_COMMAND;
    },

    writeMessage: function(message, className, handler)
    {
        var container = this.getPanel().containerNode;
        var isScrolledToBottom =
            container.scrollTop + container.offsetHeight >= container.scrollHeight;

        if (!handler)
            handler = this.writeRow;

        handler.call(this, message, className);

        if (isScrolledToBottom)
            container.scrollTop = container.scrollHeight - container.offsetHeight;
    },

    appendRow: function(row)
    {
        if (this.groupStack.length > 0)
            var container = this.groupStack[this.groupStack.length-1];
        else
            var container = this.getPanel().contentNode;

        container.appendChild(row);
    },

    writeRow: function(message, className)
    {
        var row = this.getPanel().contentNode.ownerDocument.createElement("div");
        row.className = "logRow" + (className ? " logRow-"+className : "");
        row.innerHTML = message.join("");
        this.appendRow(row);
    },

    pushGroup: function(message, className)
    {
        this.logFormatted(message, className);

        var groupRow = this.getPanel().contentNode.ownerDocument.createElement("div");
        groupRow.className = "logGroup";
        var groupRowBox = this.getPanel().contentNode.ownerDocument.createElement("div");
        groupRowBox.className = "logGroupBox";
        groupRow.appendChild(groupRowBox);
        this.appendRow(groupRowBox);
        this.groupStack.push(groupRowBox);
    },

    popGroup: function()
    {
        this.groupStack.pop();
    }

});

Firebug.registerModule(Firebug.Console);

// ************************************************************************************************
// Console Panel

function ConsolePanel(){};

ConsolePanel.prototype = extend(Firebug.Panel,
{
    name: "Console",
    title: "Console",

    options:
    {
        hasCommandLine: true,
        hasToolButtons: true,
        isPreRendered: true,
        innerHTMLSync: true
    },

    create: function()
    {
        Firebug.Panel.create.apply(this, arguments);

        this.clearButton = new Firebug.Button({
            node: $("fbConsole_btClear"),
            owner: Firebug.Console,
            onClick: Firebug.Console.clear
        });
    },

    initialize: function()
    {
        Firebug.Panel.initialize.apply(this, arguments);

        this.clearButton.initialize();
    }

});

Firebug.registerPanel(ConsolePanel);

// ************************************************************************************************

FBL.onError = function(msg, href, lineNo)
{
    var html = [];

    var lastSlash = href.lastIndexOf("/");
    var fileName = lastSlash == -1 ? href : href.substr(lastSlash+1);

    html.push(
        '', msg, '',
        '
', fileName, ' (line ', lineNo, ')
'
    );

    Firebug.Console.logRow(html, "error");
};

// ************************************************************************************************
// Register console namespace

if (!isFirefox)
    Env.browser.window.console = ConsoleAPI;

// ************************************************************************************************
}});<commit_msg>Fixed problem in console.time() and console.timeEnd().<commit_after>FBL.ns(function() { with (FBL) {
// ************************************************************************************************

// ************************************************************************************************
// Console

var ConsoleAPI =
{
    firebuglite: Firebug.version,

    xxx: function(o)
    {
        var rep = Firebug.getRep(o);
        var className = "";

        var panel = Firebug.DOM.getPanel();
        var toggles = {};

        var row = Firebug.Console.getPanel().contentNode.ownerDocument.createElement("div");
        var target = row;
        var object = o;

        row.className = "logRow" + (className ? " logRow-"+className : "");
        //row.innerHTML = message.join("");

        rep.tag.replace({domPanel: panel, toggles: toggles, object: object}, target);

        Firebug.Console.appendRow(row);
    },

    log: function()
    {
        return Firebug.Console.logFormatted(arguments, "");
    },

    debug: function()
    {
        return Firebug.Console.logFormatted(arguments, "debug");
    },

    info: function()
    {
        return Firebug.Console.logFormatted(arguments, "info");
    },

    warn: function()
    {
        return Firebug.Console.logFormatted(arguments, "warning");
    },

    error: function()
    {
        return Firebug.Console.logFormatted(arguments, "error");
    },

    assert: function(truth, message)
    {
        if (!truth)
        {
            var args = [];
            for (var i = 1; i < arguments.length; ++i)
                args.push(arguments[i]);

            Firebug.Console.logFormatted(args.length ? args : ["Assertion Failure"], "error");
            throw message ? message : "Assertion Failure";
        }

        return Firebug.Console.LOG_COMMAND;
    },

    dir: function(object)
    {
        var html = [];

        var pairs = [];
        for (var name in object)
        {
            try
            {
                pairs.push([name, object[name]]);
            }
            catch (exc)
            {
            }
        }

        pairs.sort(function(a, b) { return a[0] < b[0] ? -1 : 1; });

        html.push('
');
        for (var i = 0; i < pairs.length; ++i)
        {
            var name = pairs[i][0], value = pairs[i][1];

            html.push('
',
                '
');

            Firebug.Reps.appendObject(value, html);

            html.push('

',
                escapeHTML(name), '
');

            html.push('
');
        }
        html.push('
');

        return Firebug.Console.logRow(html, "dir");
    },

    dirxml: function(node)
    {
        var html = [];

        Firebug.Reps.appendNode(node, html);
        return Firebug.Console.logRow(html, "dirxml");
    },

    group: function()
    {
        return Firebug.Console.logRow(arguments, "group", Firebug.Console.pushGroup);
    },

    groupEnd: function()
    {
        return Firebug.Console.logRow(arguments, "", Firebug.Console.popGroup);
    },

    time: function(name)
    {
        Firebug.Console.timeMap[name] = new Date().getTime();
        return Firebug.Console.LOG_COMMAND;
    },

    timeEnd: function(name)
    {
        var timeMap = Firebug.Console.timeMap;
        if (name in timeMap)
        {
            var delta = new Date().getTime() - timeMap[name];
            Firebug.Console.logFormatted([name+ ":", delta+"ms"]);
            delete timeMap[name];
        }
        return Firebug.Console.LOG_COMMAND;
    },

    count: function()
    {
        return this.warn(["count() not supported."]);
    },

    trace: function()
    {
        return this.warn(["trace() not supported."]);
    },

    profile: function()
    {
        return this.warn(["profile() not supported."]);
    },

    profileEnd: function()
    {
        return Firebug.Console.LOG_COMMAND;
    },

    clear: function()
    {
        Firebug.Console.getPanel().contentNode.innerHTML = "";
        return Firebug.Console.LOG_COMMAND;
    },

    open: function()
    {
        toggleConsole(true);
        return Firebug.Console.LOG_COMMAND;
    },

    close: function()
    {
        if (frameVisible)
            toggleConsole();

        return Firebug.Console.LOG_COMMAND;
    }
};

// ************************************************************************************************
// Console Module

var ConsoleModule = extend(Firebug.Module, ConsoleAPI);

Firebug.Console = extend(ConsoleModule,
{
    LOG_COMMAND: {},

    groupStack: [],
    timeMap: {},

    getPanel: function()
    {
        return Firebug.chrome ? Firebug.chrome.getPanel("Console") : null;
    },

    flush: function()
    {
        var queue = FirebugChrome.consoleMessageQueue;
        FirebugChrome.consoleMessageQueue = [];

        for (var i = 0; i < queue.length; ++i)
            this.writeMessage(queue[i][0], queue[i][1], queue[i][2]);
    },

    // ********************************************************************************************

    logFormatted: function(objects, className)
    {
        var html = [];

        var format = objects[0];
        var objIndex = 0;

        if (typeof(format) != "string")
        {
            format = "";
            objIndex = -1;
        }

        var parts = this.parseFormat(format);
        for (var i = 0; i < parts.length; ++i)
        {
            var part = parts[i];
            if (part && typeof(part) == "object")
            {
                var object = objects[++objIndex];
                part.appender(object, html);
            }
            else
                Firebug.Reps.appendText(part, html);
        }

        for (var i = objIndex+1; i < objects.length; ++i)
        {
            Firebug.Reps.appendText(" ", html);

            var object = objects[i];
            if (typeof(object) == "string")
                Firebug.Reps.appendText(object, html);
            else
                Firebug.Reps.appendObject(object, html);
        }

        return this.logRow(html, className);
    },

    parseFormat: function(format)
    {
        var parts = [];

        var reg = /((^%|[^\\]%)(\d+)?(\.)([a-zA-Z]))|((^%|[^\\]%)([a-zA-Z]))/;
        var Reps = Firebug.Reps;
        var appenderMap = {
                s: Reps.appendText,
                d: Reps.appendInteger,
                i: Reps.appendInteger,
                f: Reps.appendFloat
            };

        for (var m = reg.exec(format); m; m = reg.exec(format))
        {
            var type = m[8] ? m[8] : m[5];
            var appender = type in appenderMap ? appenderMap[type] : Reps.appendObject;
            var precision = m[3] ? parseInt(m[3]) : (m[4] == "." ? -1 : 0);

            parts.push(format.substr(0, m[0][0] == "%" ? m.index : m.index+1));
            parts.push({appender: appender, precision: precision});

            format = format.substr(m.index+m[0].length);
        }

        parts.push(format);

        return parts;
    },

    // ********************************************************************************************

    logRow: function(message, className, handler)
    {
        var panel = this.getPanel();

        if (panel && panel.contentNode)
            this.writeMessage(message, className, handler);
        else
        {
            FirebugChrome.consoleMessageQueue.push([message, className, handler]);
        }

        return this.LOG_COMMAND;
    },

    writeMessage: function(message, className, handler)
    {
        var container = this.getPanel().containerNode;
        var isScrolledToBottom =
            container.scrollTop + container.offsetHeight >= container.scrollHeight;

        if (!handler)
            handler = this.writeRow;

        handler.call(this, message, className);

        if (isScrolledToBottom)
            container.scrollTop = container.scrollHeight - container.offsetHeight;
    },

    appendRow: function(row)
    {
        if (this.groupStack.length > 0)
            var container = this.groupStack[this.groupStack.length-1];
        else
            var container = this.getPanel().contentNode;

        container.appendChild(row);
    },

    writeRow: function(message, className)
    {
        var row = this.getPanel().contentNode.ownerDocument.createElement("div");
        row.className = "logRow" + (className ? " logRow-"+className : "");
        row.innerHTML = message.join("");
        this.appendRow(row);
    },

    pushGroup: function(message, className)
    {
        this.logFormatted(message, className);

        var groupRow = this.getPanel().contentNode.ownerDocument.createElement("div");
        groupRow.className = "logGroup";
        var groupRowBox = this.getPanel().contentNode.ownerDocument.createElement("div");
        groupRowBox.className = "logGroupBox";
        groupRow.appendChild(groupRowBox);
        this.appendRow(groupRowBox);
        this.groupStack.push(groupRowBox);
    },

    popGroup: function()
    {
        this.groupStack.pop();
    }

});

Firebug.registerModule(Firebug.Console);

// ************************************************************************************************
// Console Panel

function ConsolePanel(){};

ConsolePanel.prototype = extend(Firebug.Panel,
{
    name: "Console",
    title: "Console",

    options:
    {
        hasCommandLine: true,
        hasToolButtons: true,
        isPreRendered: true,
        innerHTMLSync: true
    },

    create: function()
    {
        Firebug.Panel.create.apply(this, arguments);

        this.clearButton = new Firebug.Button({
            node: $("fbConsole_btClear"),
            owner: Firebug.Console,
            onClick: Firebug.Console.clear
        });
    },

    initialize: function()
    {
        Firebug.Panel.initialize.apply(this, arguments);

        this.clearButton.initialize();
    }

});

Firebug.registerPanel(ConsolePanel);

// ************************************************************************************************

FBL.onError = function(msg, href, lineNo)
{
    var html = [];

    var lastSlash = href.lastIndexOf("/");
    var fileName = lastSlash == -1 ? href : href.substr(lastSlash+1);

    html.push(
        '', msg, '',
        '
', fileName, ' (line ', lineNo, ')
'
    );

    Firebug.Console.logRow(html, "error");
};

// ************************************************************************************************
// Register console namespace

if (!isFirefox)
    Env.browser.window.console = ConsoleAPI;

// ************************************************************************************************
}});<|endoftext|>


<commit_before>// Color is depended on Jquery and Spectrum.js
// Spectrum was picked for the community support and features with pallets, alpha, touch and multi instance
// This is included for demo only. You should grab the latest version
// of it here: https://github.com/bgrins/spectrum
// Specrum is dependent on jquery but that's cool :P

L.EditToolbar.Colorable = L.Handler.extend({
	statics: {
		TYPE: 'colorable'
	},

	includes: L.Mixin.Events,

	initialize: function (map, options) {
		var colorable = this; // cache this to target in jquery

		L.Handler.prototype.initialize.call(this, map);

		L.Util.setOptions(this, options);

		// Save the type so super can fire, need to do this as cannot do this.TYPE :(
		this.type = L.EditToolbar.Colorable.TYPE;

		this._setColor('#fe57a1', '0.2'); // Set color for all tools on load

		$(document).ready(function(){ // initialize after dom creation
			// Color is depended on Jquery and Spectrum.js
			$(".leaflet-draw-edit-colorable").spectrum({
				chooseText: 'Ok',
				color: 'rgba(254,87,161,0.2)',  Hot pink all the things!
				showAlpha: true,
				showPalette: true,
				palette: [ ],
				change: function(color) {
					var hexColor = color.toHexString(); // #ff0000
					colorable._setColor(hexColor, color.alpha);
				}
			});
		});
	},

	_setColor: function (color, opacity) {
        // Use global var of toolbar that gets set on L.Control.Draw initialization
		L.toolbar.setDrawingOptions({
			polyline: { shapeOptions: { color: color, opacity: opacity } },
			polygon: { shapeOptions: { color: color, fillOpacity: opacity } },
			rectangle: { shapeOptions: { color: color, fillOpacity: opacity } },
			circle: { shapeOptions: { color: color, fillOpacity: opacity } }
		});
	},
});
<commit_msg>oops :D<commit_after>// Color is depended on Jquery and Spectrum.js
// Spectrum was picked for the community support and features with pallets, alpha, touch and multi instance
// This is included for demo only. You should grab the latest version
// of it here: https://github.com/bgrins/spectrum
// Specrum is dependent on jquery but that's cool :P

L.EditToolbar.Colorable = L.Handler.extend({
	statics: {
		TYPE: 'colorable'
	},

	includes: L.Mixin.Events,

	initialize: function (map, options) {
		var colorable = this; // cache this to target in jquery

		L.Handler.prototype.initialize.call(this, map);

		L.Util.setOptions(this, options);

		// Save the type so super can fire, need to do this as cannot do this.TYPE :(
		this.type = L.EditToolbar.Colorable.TYPE;

		this._setColor('#fe57a1', '0.2'); // Set color for all tools on load

		$(document).ready(function(){ // initialize after dom creation
			// Color is depended on Jquery and Spectrum.js
			$(".leaflet-draw-edit-colorable").spectrum({
				chooseText: 'Ok',
				color: 'rgba(254,87,161,0.2)', //Hot pink all the things!
				showAlpha: true,
				showPalette: true,
				palette: [ ],
				change: function(color) {
					var hexColor = color.toHexString(); // #ff0000
					colorable._setColor(hexColor, color.alpha);
				}
			});
		});
	},

	_setColor: function (color, opacity) {
        // Use global var of toolbar that gets set on L.Control.Draw initialization
		L.toolbar.setDrawingOptions({
			polyline: { shapeOptions: { color: color, opacity: opacity } },
			polygon: { shapeOptions: { color: color, fillOpacity: opacity } },
			rectangle: { shapeOptions: { color: color, fillOpacity: opacity } },
			circle: { shapeOptions: { color: color, fillOpacity: opacity } }
		});
	},
});
<|endoftext|>


<commit_before>/*
 *  Copyright 2014 TWO SIGMA OPEN SOURCE, LLC
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

(function() {
  'use strict';
  angular.module('bk.core').factory('autocompleteParametersService', function() {

    var markConfig = {
      clearWhenEmpty: false,
      inclusiveLeft: true,
      inclusiveRight: true
    };

    var params = [];
    var cm;
    var scope;
    var currentParam;
    var args = [];
    var DOCUMENTATION_WIDTH = 500;

    function startParameterCompletion(codeMirror, documentation, selectionStart, selectionEnd, $scope) {
      cm = codeMirror;
      params = documentation.parameters;
      scope = $scope;
      markParameters(selectionStart, selectionEnd);
      cm.on('cursorActivity', endCompletionIfCursorOutOfRange);
      nextParameter();
    }

    function endCompletionIfCursorOutOfRange(cm) {
      if (!isActive()) {
        return;
      }
      if (!cursorInRange(getCompletionRange())) {
        return endCompletion();
      }

      if (cursorInRange(args[currentParam].find())) {
        return showParameterDocumentation(params[currentParam]);
      }

      var activeArgumentIndex = getArgumentIndexUnderCursor();
      if (activeArgumentIndex === -1 || _.isUndefined(activeArgumentIndex)) {
        return hideParameterDocumentation();
      }
      toParam(activeArgumentIndex);

    }

    function getArgumentIndexUnderCursor() {
      return _.findIndex(args, function(arg) {
        return cursorInRange(arg.find());
      });
    }

    function cursorInRange(range) {
      var cursor = cm.getCursor('anchor');
      return cursor.line >= range.from.line &&
        cursor.line <= range.to.line &&
        cursor.ch >= range.from.ch &&
        cursor.ch <= range.to.ch;
    }

    function getCompletionRange() {
      return {from: args[0].find().from, to: _.last(args).find().to};
    }

    function markParameters(from, to) {
      var paramsString = cm.getRange(from, to);
      var positions = [];
      _.reduce(params, function(positionAccumulator, p) {
        var position = paramsString.indexOf(p.name, positionAccumulator);
        positions.push([position, position + p.name.length - 1]);
        return positionAccumulator + p.name.length + 2; // including comma and a space after comma
      }, 0);
      args = _.map(positions, function(p) {
        var start = _.merge({}, from, {ch: from.ch + p[0]});
        var end = _.merge({}, from, {ch: from.ch + p[1] + 1});
        return markWithClass(start, end, 'marked-argument-unchanged');
      });
    }

    function markWithClass(start, end, className) {
      return cm.markText(start, end, _.merge({}, {className: className}, markConfig));
    }

    function nextParameter() {
      toParam(_.isUndefined(currentParam) || currentParam === params.length - 1? 0 : currentParam + 1);
    }

    function previousParameter() {
      toParam(_.isUndefined(currentParam) || currentParam === 0 ? params.length - 1 : currentParam - 1);
    }

    function toParam(index) {
      if (! _.isUndefined(currentParam)) {
        params[currentParam].argument = args[currentParam].find();
        markArgumentIfChanged();
      }
      currentParam = index;
      selectArgument(currentParam);
      showParameterDocumentation(params[currentParam]);
    }

    function markArgumentIfChanged() {
      var p = params[currentParam]
      if (cm.getRange(p.argument.from, p.argument.to) !== p.name) {
        args[currentParam].clear();
        args[currentParam] = markWithClass(p.argument.from, p.argument.to, 'marked-argument-changed');
      }
    }

    function isActive() {
      return !(_.isEmpty(params));
    }

    function endCompletion() {
      removeOptionalParams();
      cm.off('cursorActivity', endCompletionIfCursorOutOfRange);
      hideParameterDocumentation();
      clearMarks();
      cm = void 0;
      currentParam = void 0;
      scope = void 0;
      params = [];
      args = [];
    }

    function removeOptionalParams() {
      // last param
      if (currentParam == args.length - 1) {
        return;
      }
      try {
        var curArg = args[currentParam].find();
        var lastArg = _.last(args).find();
        cm.doc.setSelection(curArg.to, lastArg.to);
        cm.doc.replaceSelection('');
      } catch(e) {
        console.log('unable to get selection');
      }
    }

    function endCompletionAndMoveCursor() {
      var lastArg = _.last(args).find();
      cm.setCursor(_.merge({}, lastArg.to, {ch: lastArg.to.ch + 1}));
      endCompletion();
    }

    function selectArgument(i) {
      var arg = args[i].find();
      cm.setSelection(arg.from, arg.to);
    }

    function clearMarks() {
      _.forEach(args, function(arg) {
        arg.clear();
      });
    }

    function showParameterDocumentation(param) {
      if (!param.description || _.isEmpty(param.description)) {
        return;
      }
      _.defer(function() {scope.$broadcast('showParameterDocumentation', param.description, cm.getScrollInfo().left, DOCUMENTATION_WIDTH);});
    }

    function hideParameterDocumentation() {
      scope.$broadcast('hideParameterDocumentation');
    }

    return {
      startParameterCompletion: startParameterCompletion,
      isActive: isActive,
      nextParameter: nextParameter,
      previousParameter: previousParameter,
      endCompletion: endCompletion,
      endCompletionAndMoveCursor: endCompletionAndMoveCursor
    };

  });
})();
<commit_msg>Issue #4553 - ending autocomplete early - fixed removing not changed optional parameter<commit_after>/*
 *  Copyright 2014 TWO SIGMA OPEN SOURCE, LLC
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

(function() {
  'use strict';
  angular.module('bk.core').factory('autocompleteParametersService', function() {

    var markConfig = {
      clearWhenEmpty: false,
      inclusiveLeft: true,
      inclusiveRight: true
    };

    var params = [];
    var cm;
    var scope;
    var currentParam, currentValue;
    var args = [];
    var DOCUMENTATION_WIDTH = 500;

    function startParameterCompletion(codeMirror, documentation, selectionStart, selectionEnd, $scope) {
      cm = codeMirror;
      params = documentation.parameters;
      scope = $scope;
      markParameters(selectionStart, selectionEnd);
      cm.on('cursorActivity', endCompletionIfCursorOutOfRange);
      nextParameter();
    }

    function endCompletionIfCursorOutOfRange(cm) {
      if (!isActive()) {
        return;
      }
      if (!cursorInRange(getCompletionRange())) {
        return endCompletion();
      }

      if (cursorInRange(args[currentParam].find())) {
        currentValue = params[currentParam].name;
        return showParameterDocumentation(params[currentParam]);
      }

      var activeArgumentIndex = getArgumentIndexUnderCursor();
      if (activeArgumentIndex === -1 || _.isUndefined(activeArgumentIndex)) {
        return hideParameterDocumentation();
      }
      toParam(activeArgumentIndex);

    }

    function getArgumentIndexUnderCursor() {
      return _.findIndex(args, function(arg) {
        return cursorInRange(arg.find());
      });
    }

    function cursorInRange(range) {
      var cursor = cm.getCursor('anchor');
      return cursor.line >= range.from.line &&
        cursor.line <= range.to.line &&
        cursor.ch >= range.from.ch &&
        cursor.ch <= range.to.ch;
    }

    function getCompletionRange() {
      return {from: args[0].find().from, to: _.last(args).find().to};
    }

    function markParameters(from, to) {
      var paramsString = cm.getRange(from, to);
      var positions = [];
      _.reduce(params, function(positionAccumulator, p) {
        var position = paramsString.indexOf(p.name, positionAccumulator);
        positions.push([position, position + p.name.length - 1]);
        return positionAccumulator + p.name.length + 2; // including comma and a space after comma
      }, 0);
      args = _.map(positions, function(p) {
        var start = _.merge({}, from, {ch: from.ch + p[0]});
        var end = _.merge({}, from, {ch: from.ch + p[1] + 1});
        return markWithClass(start, end, 'marked-argument-unchanged');
      });
    }

    function markWithClass(start, end, className) {
      return cm.markText(start, end, _.merge({}, {className: className}, markConfig));
    }

    function nextParameter() {
      toParam(_.isUndefined(currentParam) || currentParam === params.length - 1? 0 : currentParam + 1);
    }

    function previousParameter() {
      toParam(_.isUndefined(currentParam) || currentParam === 0 ? params.length - 1 : currentParam - 1);
    }

    function toParam(index) {
      if (! _.isUndefined(currentParam)) {
        params[currentParam].argument = args[currentParam].find();
        markArgumentIfChanged();
      }
      currentParam = index;
      selectArgument(currentParam);
      showParameterDocumentation(params[currentParam]);
    }

    function markArgumentIfChanged() {
      var p = params[currentParam]
      if (cm.getRange(p.argument.from, p.argument.to) !== p.name) {
        args[currentParam].clear();
        args[currentParam] = markWithClass(p.argument.from, p.argument.to, 'marked-argument-changed');
      }
    }

    function isActive() {
      return !(_.isEmpty(params));
    }

    function endCompletion() {
      removeOptionalParams();
      cm.off('cursorActivity', endCompletionIfCursorOutOfRange);
      hideParameterDocumentation();
      clearMarks();
      cm = void 0;
      currentParam = void 0;
      scope = void 0;
      params = [];
      args = [];
    }

    function removeOptionalParams() {
      // last param
      if (currentParam == args.length - 1) {
        return;
      }
      try {
        var currentArg = args[currentParam].find();

        var lastValue = cm.doc.getRange(currentArg.from, currentArg.to);
        // current param not changed - should also be removed
        if (lastValue === currentValue) {
          currentArg = args[--currentParam].find();
        }

        var lastArg = _.last(args).find();
        cm.doc.setSelection(currentArg.to, lastArg.to);
        cm.doc.replaceSelection('');
      } catch(e) {
        console.log('unable to get selection for removing optional parameters');
      }
    }

    function endCompletionAndMoveCursor() {
      var lastArg = _.last(args).find();
      cm.setCursor(_.merge({}, lastArg.to, {ch: lastArg.to.ch + 1}));
      endCompletion();
    }

    function selectArgument(i) {
      var arg = args[i].find();
      cm.setSelection(arg.from, arg.to);
    }

    function clearMarks() {
      _.forEach(args, function(arg) {
        arg.clear();
      });
    }

    function showParameterDocumentation(param) {
      if (!param.description || _.isEmpty(param.description)) {
        return;
      }
      _.defer(function() {scope.$broadcast('showParameterDocumentation', param.description, cm.getScrollInfo().left, DOCUMENTATION_WIDTH);});
    }

    function hideParameterDocumentation() {
      scope.$broadcast('hideParameterDocumentation');
    }

    return {
      startParameterCompletion: startParameterCompletion,
      isActive: isActive,
      nextParameter: nextParameter,
      previousParameter: previousParameter,
      endCompletion: endCompletion,
      endCompletionAndMoveCursor: endCompletionAndMoveCursor
    };

  });
})();
<|endoftext|>