<commit_before>/**
 * Jadu CMP Dashboard
 *
 * Attaches the behaviour to a Dashboard in Jadu CMP
 */
define([
  'store-js',
  'jquery',
  'jquery-ui',
  'jquery-ui-touch',
  'tray'
], function(store) {

  'use strict';

  (function ($, window, document, undefined) {

    // defaults
    var pluginName = 'dashboard',
        api = {
          save: 'api/dashboard/save/',
        },
        defaults = {
          fetchRetryTimeout: 50,
          fetchRetryLimit: 5,
          title: 'My Dashboard',
          titleContainer: '.heading',
          sortableForcePlaceholderSize: true,
          sortableOpacity: 0.5,
          sortableRevert: 100,
          sortableTolerance: 'pointer',
          stateContainer: '#dashboard-state',
          storageStateName: 'dashboard-state',
          storageModifiedName: 'dashboard-modified',
          trayContainer: '.tray',
          widgetClass: '.widget',
          widgetDataContainer: '#widget__data',
          widgetRemoveAttribute: '[data-widget-action=remove]'
        },
        flash = {
          saveSuccess: 'Your dashboard has been saved.',
          saveFail: 'There was a problem and your dashboard wasn’t saved. Please try again.',
          saveErrorApi: 'There was a problem and your dashboard wasn’t saved, please try again or contact your support team if you see this message again. (error code: API)',
          saveError500: 'There was a problem and your dashboard wasn’t saved, please try again or contact your support team if you see this message again. (error code: 500)',
          saveDelay: 'Your dashboard is taking longer than expected to save, please wait a moment...'
        };

    // constructor
    function Plugin (element, options) {
      this._defaults = defaults;
      this._name = pluginName;
      this.api = api;
      this.element = element;
      this.flash = flash;
      this.settings = $.extend({}, defaults, options);
      this.currentItem;
      this.state;
      this.tray;
      this.widgetData;

      this.init();
    }

    // methods
    Plugin.prototype = {

      init: function () {

        // set up the tray
        this.tray = $(this.settings.trayContainer).tray({
          connectToSortable: this.element
        });

        // set up the sortable dashboard
        this.initDashboard();
      },

      initDashboard: function () {
        console.log('init dashboard');

        var _this = this;

        // set up the sortable
        $(this.element).sortable({
          forcePlaceholderSize: this.settings.sortableForcePlaceholderSize,
          opacity: this.settings.sortableOpacity,
          receive: function(e, ui) {
            console.log('received');

            var $this = $(this);

            function isFetched() {
              _this.widgetData = $(_this.settings.widgetDataContainer).val();

              if (_this.widgetData !== '') {
                var widget = $this.data().uiSortable.currentItem;
                var sender = ui.sender;

                widget.html(_this.widgetData) // populate widget content
                  .uniqueId(); // attach unique identifier

                // reset last-appended flag
                $(_this.settings.widgetClass, _this.element).not(widget)
                  .removeAttr('data-last-appended');

                // populate data attributes in new widget instance
                widget.data('widget', sender.data('widget'))
                    .data('widget-title', sender.data('widget-title'))
                    .data('widget-description', sender.data('widget-description'))
                    .attr('data-last-appended', 'true');

                // tidy up after ourselves
                $(_this.settings.widgetDataContainer).val('');
                _this.widgetData = '';
              } else {

                // wait a bit more...
                setTimeout(isFetched, _this.settings.fetchRetryTimeout);
              }
            }

            /**
             * if the fetch started by the dragging event hasn't finished,
             * keep checking for the response...
             */
            isFetched();

          },
          revert: this.settings.sortableRevert,
          stop: function() {
            _this.captureState();
          },
          tolerance: this.settings.sortableTolerance
        });

        // remove widget event
        $(this.element).on('click', this.settings.widgetClass + ' ' + this.settings.widgetRemoveAttribute, function() {
          $(this).closest(_this.settings.widgetClass).remove();
          _this.captureState();
        });

        // action - rename dashboard
        $('[data-action=rename]').submit(function(e) {
          console.log('rename');
          var values = {};

          e.preventDefault();

          $.each($(this).serializeArray(), function(i, field) {
            values[field.name] = field.value;
          });

          _this.settings.title = values.name;

          $(_this.settings.titleContainer).text(_this.settings.title);

          // update the name used in the 'delete widget' modal
          $('#dashboard-title').text(_this.settings.title);

          _this.captureState();

          $(this).closest('.modal').modal('hide');
        });

        // action - save dashboard
        $('[data-action=save]').on('click', function() {
          _this.captureState(true);
        });

      },

      captureState: function (showFlash) {
        var state = [];

        if (typeof(showFlash) === 'undefined') {
          showFlash = false;
        }

        // grab the widget states
        $.map($(this.element).find(this.settings.widgetClass), function(el) {
          state.push({
            guid: 'widget_guid',
            id: $(el).attr('id'),
            settings: {
              name: $(el).data('widget')
            }
          });
        });

        // create the json object that stores dashboard state
        var Dashboard = {
          title: this.settings.title,
          widgets: state
        };

        // store our JSON object
        this.state = Dashboard;

        // save state to localstorage if available
        if (store.enabled) {
          store.set(this.settings.storageStateName, this.state);
          store.set(this.settings.storageModifiedName, Number(new Date));
        }

        this.saveState(showFlash);
      },

      getState: function () {
        console.log('get state');

        var state = [];

        // check for a stored state object first, then try localstorage
        if (this.state) {
          state = this.state;
        }
        else if (store.enabled) {
          state = store.get(this.settings.storageStateName);
        }
        else {
          return false;
        }

        return state;
      },

      saveState: function(showFlash) {
        console.log('saving state... (' + this.api.save + ')');
        console.log(this.state);

        var _this = this,
            state = this.getState();

        $.ajax({
          data: state,
          type: 'POST',
          tryCount : 0,
          retryLimit : _this.settings.fetchRetryLimit,
          url: this.api.save
        }).done(function (data) {
          if (showFlash === true) {
            $(document).flash().success(_this.flash.saveSuccess);
          }
        }).error(function(xhr, textStatus, errorThrown) {
          if (textStatus == 'timeout') {
            this.tryCount++;

            // show the delay message if we're having trouble saving
            if (this.tryCount > 2) {
              $(document).flash().warning(_this.flash.saveDelay, true);
            }

            // try again
            if (this.tryCount <= this.retryLimit) {
              $.ajax(this);
              return;
            }
            return;
          }
          if (xhr.status == 500) {
            $(document).flash().error(_this.flash.saveError500);
          } else {
            $(document).flash().error(_this.flash.saveErrorApi);
          }
        });

      }

    };

    $.fn[pluginName] = function (options) {
      return this.each(function() {
        if (!$.data(this, 'plugin_' + pluginName)) {
          $.data(this, 'plugin_' + pluginName, new Plugin(this, options));
        }
      });
    };

  })(jQuery, window, document);

});<commit_msg>Removed some old logs breaking IE9<commit_after>/**
 * Jadu CMP Dashboard
 *
 * Attaches the behaviour to a Dashboard in Jadu CMP
 */
define([
  'store-js',
  'jquery',
  'jquery-ui',
  'jquery-ui-touch',
  'tray'
], function(store) {

  'use strict';

  (function ($, window, document, undefined) {

    // defaults
    var pluginName = 'dashboard',
        api = {
          save: 'api/dashboard/save/',
        },
        defaults = {
          fetchRetryTimeout: 50,
          fetchRetryLimit: 5,
          title: 'My Dashboard',
          titleContainer: '.heading',
          sortableForcePlaceholderSize: true,
          sortableOpacity: 0.5,
          sortableRevert: 100,
          sortableTolerance: 'pointer',
          stateContainer: '#dashboard-state',
          storageStateName: 'dashboard-state',
          storageModifiedName: 'dashboard-modified',
          trayContainer: '.tray',
          widgetClass: '.widget',
          widgetDataContainer: '#widget__data',
          widgetRemoveAttribute: '[data-widget-action=remove]'
        },
        flash = {
          saveSuccess: 'Your dashboard has been saved.',
          saveFail: 'There was a problem and your dashboard wasn’t saved. Please try again.',
          saveErrorApi: 'There was a problem and your dashboard wasn’t saved, please try again or contact your support team if you see this message again. (error code: API)',
          saveError500: 'There was a problem and your dashboard wasn’t saved, please try again or contact your support team if you see this message again. (error code: 500)',
          saveDelay: 'Your dashboard is taking longer than expected to save, please wait a moment...'
        };

    // constructor
    function Plugin (element, options) {
      this._defaults = defaults;
      this._name = pluginName;
      this.api = api;
      this.element = element;
      this.flash = flash;
      this.settings = $.extend({}, defaults, options);
      this.currentItem;
      this.state;
      this.tray;
      this.widgetData;

      this.init();
    }

    // methods
    Plugin.prototype = {

      init: function () {

        // set up the tray
        this.tray = $(this.settings.trayContainer).tray({
          connectToSortable: this.element
        });

        // set up the sortable dashboard
        this.initDashboard();
      },

      initDashboard: function () {

        var _this = this;

        // set up the sortable
        $(this.element).sortable({
          forcePlaceholderSize: this.settings.sortableForcePlaceholderSize,
          opacity: this.settings.sortableOpacity,
          receive: function(e, ui) {

            var $this = $(this);

            function isFetched() {
              _this.widgetData = $(_this.settings.widgetDataContainer).val();

              if (_this.widgetData !== '') {
                var widget = $this.data().uiSortable.currentItem;
                var sender = ui.sender;

                widget.html(_this.widgetData) // populate widget content
                  .uniqueId(); // attach unique identifier

                // reset last-appended flag
                $(_this.settings.widgetClass, _this.element).not(widget)
                  .removeAttr('data-last-appended');

                // populate data attributes in new widget instance
                widget.data('widget', sender.data('widget'))
                    .data('widget-title', sender.data('widget-title'))
                    .data('widget-description', sender.data('widget-description'))
                    .attr('data-last-appended', 'true');

                // tidy up after ourselves
                $(_this.settings.widgetDataContainer).val('');
                _this.widgetData = '';
              } else {

                // wait a bit more...
                setTimeout(isFetched, _this.settings.fetchRetryTimeout);
              }
            }

            /**
             * if the fetch started by the dragging event hasn't finished,
             * keep checking for the response...
             */
            isFetched();

          },
          revert: this.settings.sortableRevert,
          stop: function() {
            _this.captureState();
          },
          tolerance: this.settings.sortableTolerance
        });

        // remove widget event
        $(this.element).on('click', this.settings.widgetClass + ' ' + this.settings.widgetRemoveAttribute, function() {
          $(this).closest(_this.settings.widgetClass).remove();
          _this.captureState();
        });

        // action - rename dashboard
        $('[data-action=rename]').submit(function(e) {
          var values = {};

          e.preventDefault();

          $.each($(this).serializeArray(), function(i, field) {
            values[field.name] = field.value;
          });

          _this.settings.title = values.name;

          $(_this.settings.titleContainer).text(_this.settings.title);

          // update the name used in the 'delete widget' modal
          $('#dashboard-title').text(_this.settings.title);

          _this.captureState();

          $(this).closest('.modal').modal('hide');
        });

        // action - save dashboard
        $('[data-action=save]').on('click', function() {
          _this.captureState(true);
        });

      },

      captureState: function (showFlash) {
        var state = [];

        if (typeof(showFlash) === 'undefined') {
          showFlash = false;
        }

        // grab the widget states
        $.map($(this.element).find(this.settings.widgetClass), function(el) {
          state.push({
            guid: 'widget_guid',
            id: $(el).attr('id'),
            settings: {
              name: $(el).data('widget')
            }
          });
        });

        // create the json object that stores dashboard state
        var Dashboard = {
          title: this.settings.title,
          widgets: state
        };

        // store our JSON object
        this.state = Dashboard;

        // save state to localstorage if available
        if (store.enabled) {
          store.set(this.settings.storageStateName, this.state);
          store.set(this.settings.storageModifiedName, Number(new Date));
        }

        this.saveState(showFlash);
      },

      getState: function () {

        var state = [];

        // check for a stored state object first, then try localstorage
        if (this.state) {
          state = this.state;
        }
        else if (store.enabled) {
          state = store.get(this.settings.storageStateName);
        }
        else {
          return false;
        }

        return state;
      },

      saveState: function(showFlash) {

        var _this = this,
            state = this.getState();

        $.ajax({
          data: state,
          type: 'POST',
          tryCount : 0,
          retryLimit : _this.settings.fetchRetryLimit,
          url: this.api.save
        }).done(function (data) {
          if (showFlash === true) {
            $(document).flash().success(_this.flash.saveSuccess);
          }
        }).error(function(xhr, textStatus, errorThrown) {
          if (textStatus == 'timeout') {
            this.tryCount++;

            // show the delay message if we're having trouble saving
            if (this.tryCount > 2) {
              $(document).flash().warning(_this.flash.saveDelay, true);
            }

            // try again
            if (this.tryCount <= this.retryLimit) {
              $.ajax(this);
              return;
            }
            return;
          }
          if (xhr.status == 500) {
            $(document).flash().error(_this.flash.saveError500);
          } else {
            $(document).flash().error(_this.flash.saveErrorApi);
          }
        });

      }

    };

    $.fn[pluginName] = function (options) {
      return this.each(function() {
        if (!$.data(this, 'plugin_' + pluginName)) {
          $.data(this, 'plugin_' + pluginName, new Plugin(this, options));
        }
      });
    };

  })(jQuery, window, document);

});
<|endoftext|>


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

    angular
        .module('partner')
        .controller('HomeController', HomeController);

    function HomeController($scope, $rootScope, $firebaseAuth, userService, $state){
        var vm = this;
        var ref = new Firebase($rootScope.fbUrl);
        vm.authObj = $firebaseAuth(ref);

        if($rootScope.currentUser)
        {
            console.log($rootScope.currentUser);
            $scope.currentUser = $rootScope.currentUser.profile;
            vm.title = $scope.currentUser.title;
        }
        //console.log(currentUser);
    }

})();
<commit_msg>Update homeController.js<commit_after>(function(){
    'use strict';

    angular
        .module('partner')
        .controller('HomeController', HomeController);

    function HomeController($scope, $rootScope, $firebaseAuth, userService, $state){
        var vm = this;
        var ref = new Firebase($rootScope.fbUrl);
        vm.authObj = $firebaseAuth(ref);

        if($rootScope.currentUser)
        {
            console.log($rootScope.currentUser);
            $scope.currentUser = $rootScope.currentUser.profile;
            vm.title = $scope.currentUser.title;
        }
        //console.log(currentUser);
    }

})();

$("#tabs").tabs({
    activate: function (event, ui) {
        var active = $('#tabs').tabs('option', 'active');
        $("#tabid").html('the tab id is ' + $("#tabs ul>li a").eq(active).attr("href"));

    }
}

);
<|endoftext|>


<commit_before>// jQuery UI style "widget" for editing an iTop "dashboard"
$(function()
{
	// the widget definition, where "itop" is the namespace,
	// "dashboard" the widget name
	$.widget( "itop.dashboard",
	{
		// default options
		options:
		{
			dashboard_id: '',
			layout_class: '',
			title: '',
			submit_to: 'index.php',
			submit_parameters: {},
			render_to: 'index.php',
			render_parameters: {},
			new_dashlet_parameters: {}
		},

		// the constructor
		_create: function()
		{
			var me = this;

			this.element
			.addClass('itop-dashboard');

			this.ajax_div = $('

').appendTo(this.element);
			$('.itop-dashboard').bind('keyup.dashboard_editor', function(event) { me._on_keyup(event); } );
			this._make_draggable();
		},

		// called when created, and later when changing options
		_refresh: function()
		{
			var oParams = this._get_state(this.options.render_parameters);
			var me = this;
			$.post(this.options.render_to, oParams, function(data){
				me.element.html(data);
				me._make_draggable();
			});
		},
		// events bound via _bind are removed automatically
		// revert other modifications here
		destroy: function()
		{
			this.element
			.removeClass('itop-dashboard');

			this.ajax_div.remove();
			$(document).unbind('keyup.dashboard_editor');

			// call the original destroy method since we overwrote it
			$.Widget.prototype.destroy.call( this );
		},
		// _setOptions is called with a hash of all options that are changing
		_setOptions: function()
		{
			// in 1.9 would use _superApply
			$.Widget.prototype._setOptions.apply( this, arguments );
			this._refresh();
		},
		// _setOption is called for each individual option that is changing
		_setOption: function( key, value )
		{
			// in 1.9 would use _super
			$.Widget.prototype._setOption.call( this, key, value );
			if (key == 'layout')
			{
				_refresh();
			}
		},
		_get_state: function(oMergeInto)
		{
			var oState = oMergeInto;
			oState.dashlets = [];
			this.element.find('.layout_cell').each(function() {
				var aList = { dashlets: [] };
				$(this).find(':itop-dashlet').each(function() {
					var oDashlet = $(this).data('dashlet');
					if(oDashlet)
					{
						var oDashletParams = oDashlet.get_params();
						var sId = oDashletParams.dashlet_id;
						aList[sId] = oDashletParams;
						aList.dashlets.push({dashlet_id: sId, dashlet_class: oDashletParams.dashlet_class} );
					}
				});
				if (aList.dashlets.length == 0)
				{
					oState.dashlets.push({dashlet_id: 0, dashlet_class: 'DashletEmptyCell'});
				}
				else
				{
					for(var idx in aList.dashlets)
					{
						var sId = aList.dashlets[idx].dashlet_id;
						oState[sId] = aList[sId];
						oState.dashlets.push(aList.dashlets[idx]);
					}
				}
			});
			oState.dashboard_id = this.options.dashboard_id;
			oState.layout_class = this.options.layout_class;
			oState.title = this.options.title;

			return oState;
		},
		save: function()
		{
			var oParams = this._get_state(this.options.submit_parameters);
			var me = this;
			$.post(this.options.submit_to, oParams, function(data){
				me.ajax_div.html(data);
			});
		},
		add_dashlet: function(options)
		{
			var sDashletId = this._get_new_id();
			var oDashlet = $('
');
			oDashlet.appendTo(options.container);
			var oDashletProperties = $('
');
			oDashletProperties.appendTo($('#dashlet_properties'));

			var oParams = this.options.new_dashlet_parameters;
			var sDashletClass = options.dashlet_class;
			oParams.dashlet_class = sDashletClass;
			oParams.dashlet_id = sDashletId;
			var me = this;
			$.post(this.options.render_to, oParams, function(data){
				me.ajax_div.html(data);
				$('#dashlet_'+sDashletId)
				.dashlet({dashlet_id: sDashletId, dashlet_class: sDashletClass})
				.dashlet('deselect_all')
				.dashlet('select')
				.draggable({
					revert: 'invalid', appendTo: 'body', zIndex: 9999,
					helper: function() {
						var oDragItem = $(this).dashlet('get_drag_icon');
						return oDragItem;
					},
					cursorAt: { top: 16, left: 16 },
				});
			});
		},
		_get_new_id: function()
		{
			var iMaxId = 0;
			this.element.find(':itop-dashlet').each(function() {
				var oDashlet = $(this).data('dashlet');
				if(oDashlet)
				{
					var oDashletParams = oDashlet.get_params();
					var id = parseInt(oDashletParams.dashlet_id, 10);
					if (id > iMaxId) iMaxId = id;
				}
			});
			return 1 + iMaxId;
		},
		_make_draggable: function()
		{

			this.element.find('.dashlet').draggable({
				revert: 'invalid', appendTo: 'body', zIndex: 9999,
				helper: function() {
					var oDragItem = $(this).dashlet('get_drag_icon');
					return oDragItem;
				},
				cursorAt: { top: 16, left: 16 },
			});
			this.element.find('table td').droppable({
				accept: '.dashlet,.dashlet_icon',
				drop: function(event, ui) {
					$( this ).find( ".placeholder" ).remove();
					var oDashlet = ui.draggable;
					if (oDashlet.hasClass('dashlet'))
					{
						// moving around a dashlet
						oDashlet.detach();
						oDashlet.css({top: 0, left: 0});
						oDashlet.appendTo($(this));
					}
					else
					{
						// inserting a new dashlet
						var sDashletClass = ui.draggable.attr('dashlet_class');
						$(':itop-dashboard').dashboard('add_dashlet', {dashlet_class: sDashletClass, container: $(this) })
					}
				},
			});
		},
		_on_keyup: function(event)
		{
			console.log('Key pressed in Dashlet');
		}
	});
});<commit_msg>User editable dashboards... implementation in progress<commit_after>// jQuery UI style "widget" for editing an iTop "dashboard"
$(function()
{
	// the widget definition, where "itop" is the namespace,
	// "dashboard" the widget name
	$.widget( "itop.dashboard",
	{
		// default options
		options:
		{
			dashboard_id: '',
			layout_class: '',
			title: '',
			submit_to: 'index.php',
			submit_parameters: {},
			render_to: 'index.php',
			render_parameters: {},
			new_dashlet_parameters: {}
		},

		// the constructor
		_create: function()
		{
			var me = this;

			this.element
			.addClass('itop-dashboard');

			this.ajax_div = $('

').appendTo(this.element);
			$('.itop-dashboard').bind('keyup.dashboard_editor', function(event) { me._on_keyup(event); } );
			this._make_draggable();
		},

		// called when created, and later when changing options
		_refresh: function()
		{
			var oParams = this._get_state(this.options.render_parameters);
			var me = this;
			$.post(this.options.render_to, oParams, function(data){
				me.element.html(data);
				me._make_draggable();
			});
		},
		// events bound via _bind are removed automatically
		// revert other modifications here
		destroy: function()
		{
			this.element
			.removeClass('itop-dashboard');

			this.ajax_div.remove();
			$(document).unbind('keyup.dashboard_editor');

			// call the original destroy method since we overwrote it
			$.Widget.prototype.destroy.call( this );
		},
		// _setOptions is called with a hash of all options that are changing
		_setOptions: function()
		{
			// in 1.9 would use _superApply
			$.Widget.prototype._setOptions.apply( this, arguments );
			this._refresh();
		},
		// _setOption is called for each individual option that is changing
		_setOption: function( key, value )
		{
			// in 1.9 would use _super
			$.Widget.prototype._setOption.call( this, key, value );
			if (key == 'layout')
			{
				_refresh();
			}
		},
		_get_state: function(oMergeInto)
		{
			var oState = oMergeInto;
			oState.cells = [];
			this.element.find('.layout_cell').each(function() {
				var aList = [];
				$(this).find(':itop-dashlet').each(function() {
					var oDashlet = $(this).data('dashlet');
					if(oDashlet)
					{
						var oDashletParams = oDashlet.get_params();
						var sId = oDashletParams.dashlet_id;
						oState[sId] = oDashletParams;
						aList.push({dashlet_id: sId, dashlet_class: oDashletParams.dashlet_class} );
					}
				});

				if (aList.length == 0)
				{
					oState[0] = {dashlet_id: 0, dashlet_class: 'DashletEmptyCell'};
					aList.push({dashlet_id: 0, dashlet_class: 'DashletEmptyCell'});
				}
				oState.cells.push(aList);
			});
			oState.dashboard_id = this.options.dashboard_id;
			oState.layout_class = this.options.layout_class;
			oState.title = this.options.title;

			return oState;
		},
		save: function()
		{
			var oParams = this._get_state(this.options.submit_parameters);
			var me = this;
			$.post(this.options.submit_to, oParams, function(data){
				me.ajax_div.html(data);
			});
		},
		add_dashlet: function(options)
		{
			var sDashletId = this._get_new_id();
			var oDashlet = $('
');
			oDashlet.appendTo(options.container);
			var oDashletProperties = $('
');
			oDashletProperties.appendTo($('#dashlet_properties'));

			var oParams = this.options.new_dashlet_parameters;
			var sDashletClass = options.dashlet_class;
			oParams.dashlet_class = sDashletClass;
			oParams.dashlet_id = sDashletId;
			var me = this;
			$.post(this.options.render_to, oParams, function(data){
				me.ajax_div.html(data);
				$('#dashlet_'+sDashletId)
				.dashlet({dashlet_id: sDashletId, dashlet_class: sDashletClass})
				.dashlet('deselect_all')
				.dashlet('select')
				.draggable({
					revert: 'invalid', appendTo: 'body', zIndex: 9999,
					helper: function() {
						var oDragItem = $(this).dashlet('get_drag_icon');
						return oDragItem;
					},
					cursorAt: { top: 16, left: 16 },
				});
			});
		},
		_get_new_id: function()
		{
			var iMaxId = 0;
			this.element.find(':itop-dashlet').each(function() {
				var oDashlet = $(this).data('dashlet');
				if(oDashlet)
				{
					var oDashletParams = oDashlet.get_params();
					var id = parseInt(oDashletParams.dashlet_id, 10);
					if (id > iMaxId) iMaxId = id;
				}
			});
			return 1 + iMaxId;
		},
		_make_draggable: function()
		{

			this.element.find('.dashlet').draggable({
				revert: 'invalid', appendTo: 'body', zIndex: 9999,
				helper: function() {
					var oDragItem = $(this).dashlet('get_drag_icon');
					return oDragItem;
				},
				cursorAt: { top: 16, left: 16 },
			});
			this.element.find('table td').droppable({
				accept: '.dashlet,.dashlet_icon',
				drop: function(event, ui) {
					$( this ).find( ".placeholder" ).remove();
					var oDashlet = ui.draggable;
					if (oDashlet.hasClass('dashlet'))
					{
						// moving around a dashlet
						oDashlet.detach();
						oDashlet.css({top: 0, left: 0});
						oDashlet.appendTo($(this));
					}
					else
					{
						// inserting a new dashlet
						var sDashletClass = ui.draggable.attr('dashlet_class');
						$(':itop-dashboard').dashboard('add_dashlet', {dashlet_class: sDashletClass, container: $(this) })
					}
				},
			});
		},
		_on_keyup: function(event)
		{
			console.log('Key pressed in Dashlet');
		}
	});
});<|endoftext|>


<commit_before>/*
 * https://github.com/adoroszlai/leaflet-distance-markers
 *
 * The MIT License (MIT)
 *
 * Copyright (c) 2014 Doroszlai Attila
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 * the Software, and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

L.DistanceMarkers = L.LayerGroup.extend({
	initialize: function (line, map, options) {
		options = options || {};
		var offset = options.offset || 1000;
		var showAll = Math.min(map.getMaxZoom(), options.showAll || 12);

		var zoomLayers = {};
		var length = L.GeometryUtil.length(line);
		var count = Math.floor(length / offset);

		for (var i = 1; i <= count; ++i) {
			var distance = offset * i;
			var position = L.GeometryUtil.interpolateOnLine(map, line, distance / length);
			var icon = L.divIcon({ className: 'dist-marker', html: i });
			var marker = L.marker(position.latLng, { title: i, icon: icon });

			// visible only starting at a specific zoom level
			var zoom = this._minimumZoomLevelForItem(i, showAll);
			if (zoomLayers[zoom] === undefined) {
				zoomLayers[zoom] = L.layerGroup();
			}
			zoomLayers[zoom].addLayer(marker);
		}

		var currentZoomLevel = 0;
		var markerLayer = this;
		var updateMarkerVisibility = function() {
			var oldZoom = currentZoomLevel;
			var newZoom = currentZoomLevel = map.getZoom();

			if (newZoom > oldZoom) {
				for (var i = oldZoom + 1; i <= newZoom; ++i) {
					if (zoomLayers[i] !== undefined) {
						markerLayer.addLayer(zoomLayers[i]);
					}
				}
			} else if (newZoom < oldZoom) {
				for (var i = oldZoom; i > newZoom; --i) {
					if (zoomLayers[i] !== undefined) {
						markerLayer.removeLayer(zoomLayers[i]);
					}
				}
			}
		};
		map.on('zoomend', updateMarkerVisibility);

		this._layers = {}; // need to initialize before adding markers to this LayerGroup
		updateMarkerVisibility();
	},

	_minimumZoomLevelForItem: function (item, showAllLevel) {
		var zoom = showAllLevel;
		var i = item;
		while (i > 0 && i % 2 === 0) {
			--zoom;
			i = Math.floor(i / 2);
		}
		return zoom;
	},

});

L.Polyline.include({

	_originalOnAdd: L.Polyline.prototype.onAdd,
	_originalOnRemove: L.Polyline.prototype.onRemove,

	addDistanceMarkers: function () {
		if (this._map && this._distanceMarkers) {
			this._map.addLayer(this._distanceMarkers);
		}
	},

	removeDistanceMarkers: function () {
		if (this._map && this._distanceMarkers) {
			this._map.removeLayer(this._distanceMarkers);
		}
	},

	onAdd: function (map) {
		this._originalOnAdd(map);

		var opts = this.options.distanceMarkers || {};
		if (this._distanceMarkers === undefined) {
			this._distanceMarkers = new L.DistanceMarkers(this, map, opts);
		}
		if (opts.lazy === undefined || opts.lazy === false) {
			this.addDistanceMarkers();
		}
	},

	onRemove: function (map) {
		this.removeDistanceMarkers();
		this._originalOnRemove(map);
	}

});
<commit_msg>Update leaflet-distance-markers with performance enhancement by Phil Whitehurst<commit_after>/*
 * https://github.com/adoroszlai/leaflet-distance-markers
 *
 * The MIT License (MIT)
 *
 * Copyright (c) 2014- Doroszlai Attila, 2016- Phil Whitehurst
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of
 * this software and associated documentation files (the "Software"), to deal in
 * the Software without restriction, including without limitation the rights to
 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
 * the Software, and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

L.DistanceMarkers = L.LayerGroup.extend({
	initialize: function (line, map, options) {
		options = options || {};
		var offset = options.offset || 1000;
		var showAll = Math.min(map.getMaxZoom(), options.showAll || 12);
		var cssClass = options.cssClass || 'dist-marker';

		var zoomLayers = {};
		// Get line coords as an array
		var coords = line;
		if (typeof line.getLatLngs == 'function') {
			coords = line.getLatLngs();
		}
		// Get accumulated line lengths as well as overall length
		var accumulated = L.GeometryUtil.accumulatedLengths(line);
		var length = accumulated.length > 0 ? accumulated[accumulated.length - 1] : 0;
		// Position in accumulated line length array
		var j = 0;
		// Number of distance markers to be added
		var count = Math.floor(length / offset);

		for (var i = 1; i <= count; ++i) {
			var distance = offset * i;
			// Find the first accumulated distance that is greater
			// than the distance of this marker
			while (j < accumulated.length - 1 && accumulated[j] < distance) {
				++j;
			}
			// Now grab the two nearest points either side of
			// distance marker position and create a simple line to
			// interpolate on
			var p1 = coords[j - 1];
			var p2 = coords[j];
			var m_line = L.polyline([p1, p2]);
			var ratio = (distance - accumulated[j - 1]) / (accumulated[j] - accumulated[j - 1]);
			var position = L.GeometryUtil.interpolateOnLine(map, m_line, ratio);
			var icon = L.divIcon({ className: cssClass, html: i });
			var marker = L.marker(position.latLng, { title: i, icon: icon });

			// visible only starting at a specific zoom level
			var zoom = this._minimumZoomLevelForItem(i, showAll);
			if (zoomLayers[zoom] === undefined) {
				zoomLayers[zoom] = L.layerGroup();
			}
			zoomLayers[zoom].addLayer(marker);
		}

		var currentZoomLevel = 0;
		var markerLayer = this;
		var updateMarkerVisibility = function() {
			var oldZoom = currentZoomLevel;
			var newZoom = currentZoomLevel = map.getZoom();

			if (newZoom > oldZoom) {
				for (var i = oldZoom + 1; i <= newZoom; ++i) {
					if (zoomLayers[i] !== undefined) {
						markerLayer.addLayer(zoomLayers[i]);
					}
				}
			} else if (newZoom < oldZoom) {
				for (var i = oldZoom; i > newZoom; --i) {
					if (zoomLayers[i] !== undefined) {
						markerLayer.removeLayer(zoomLayers[i]);
					}
				}
			}
		};
		map.on('zoomend', updateMarkerVisibility);

		this._layers = {}; // need to initialize before adding markers to this LayerGroup
		updateMarkerVisibility();
	},

	_minimumZoomLevelForItem: function (item, showAllLevel) {
		var zoom = showAllLevel;
		var i = item;
		while (i > 0 && i % 2 === 0) {
			--zoom;
			i = Math.floor(i / 2);
		}
		return zoom;
	},

});

L.Polyline.include({

	_originalOnAdd: L.Polyline.prototype.onAdd,
	_originalOnRemove: L.Polyline.prototype.onRemove,

	addDistanceMarkers: function () {
		if (this._map && this._distanceMarkers) {
			this._map.addLayer(this._distanceMarkers);
		}
	},

	removeDistanceMarkers: function () {
		if (this._map && this._distanceMarkers) {
			this._map.removeLayer(this._distanceMarkers);
		}
	},

	onAdd: function (map) {
		this._originalOnAdd(map);

		var opts = this.options.distanceMarkers || {};
		if (this._distanceMarkers === undefined) {
			this._distanceMarkers = new L.DistanceMarkers(this, map, opts);
		}
		if (opts.lazy === undefined || opts.lazy === false) {
			this.addDistanceMarkers();
		}
	},

	onRemove: function (map) {
		this.removeDistanceMarkers();
		this._originalOnRemove(map);
	}

});
<|endoftext|>


<commit_before>//domfilter.js

const http = require('http');
const jsdom = require("jsdom");
const { JSDOM } = jsdom;

const Logger = require('./log');
const logger = new Logger('js/domfilter.js');

class Domfilter {

    constructor(port) {
        this.server = http.createServer(requestHandler);
        this.server.listen(port, 'localhost');
    }

    stop() {
        this.server.close();
    }
}

function requestHandler(request, response)  {
    logger.log('url = ' + request.url);
    if (request.url.startsWith('/translate/')) {
        const phrase = request.url.substring(11);
        loadAndTrim('http://www.spanishdict.com/translate/' + phrase, response);

    } else if (request.url.startsWith('/conjugate/')) {
        const phrase = request.url.substring(11);
        loadAndTrim('http://www.spanishdict.com/conjugate/' + phrase, response);

    }
}

function spliceBetween(str, toinsert, start, end) {
    const startindex = str.search(start) + start.length ;
    const endindex = str.search(end);
    //console.log(`startindex = ${startindex} endindex = ${endindex}`);

    if (startindex != -1 && endindex != -1 && startindex <= endindex) {
        return str.substring(0, startindex) + toinsert + str.substring(endindex);
    }
}

function removeChildren(container, excludedClasses) {
    logger.log(container);
    const containerChildren = container.children;
    const l = containerChildren.length;
    let nodesToRemove = [];
    if (excludedClasses) {
        for (var i = 0; i < l; i++) {
            const current = containerChildren[i];
            let excluded = false;
            for (var j = 0; j < excludedClasses.length; j++) {
                if (current.classList.contains(excludedClasses[j])) {
                   excluded = true;
                }
            }
            if (!excluded) {
                nodesToRemove.push(current);
            }
        }
    } else {
        nodesToRemove = containerChildren;
    }

    nodesToRemove.forEach((node)=>{
        container.removeChild(node)
    });
}

function loadAndTrim(url, response) {
    JSDOM.fromURL(url).then((dom) => {
                    const body = dom.window.document.getElementsByTagName('body')[0]
                    const contentContainer = dom.window.document.getElementsByClassName('content-container')[0];
                    const mainContainer = dom.window.document.getElementsByClassName('main-container')[0];
                    const translateContainer = dom.window.document.getElementsByClassName('translate')[0]
                    const cardContainer = dom.window.document.getElementsByClassName('card')[0];

                    removeChildren(body, ['content-container']);
                    removeChildren(contentContainer, ['main-container']);
                    removeChildren(mainContainer, ['translate', 'conjugation']);

                    if (translateContainer) {
                        removeChildren(translateContainer, ['card', ['tab-content']]) ;
                    }

                    const navElements = dom.window.document.getElementsByClassName('nav-content');
                    if (navElements) {
                        const l = navElements.length;
                        for (var i = 0; i < l; i++) {
                            const parent = navElements[i].parentElement;
                            parent.removeChild(navElements[i]);
                        }
                    }

                    //cardContainer.removeChild(navElement);

                    response.end(dom.serialize());
                }).catch((e)=> {
                    logger.log(e.message);
                    logger.log(url);
                    logger.printStackTrace(e);
                });
}

module.exports = Domfilter;

<commit_msg>removed superfluous logging<commit_after>//domfilter.js

const http = require('http');
const jsdom = require("jsdom");
const { JSDOM } = jsdom;

const Logger = require('./log');
const logger = new Logger('js/domfilter.js');

class Domfilter {

    constructor(port) {
        this.server = http.createServer(requestHandler);
        this.server.listen(port, 'localhost');
    }

    stop() {
        this.server.close();
    }
}

function requestHandler(request, response)  {
    logger.log('url = ' + request.url);
    if (request.url.startsWith('/translate/')) {
        const phrase = request.url.substring(11);
        loadAndTrim('http://www.spanishdict.com/translate/' + phrase, response);

    } else if (request.url.startsWith('/conjugate/')) {
        const phrase = request.url.substring(11);
        loadAndTrim('http://www.spanishdict.com/conjugate/' + phrase, response);

    }
}

function spliceBetween(str, toinsert, start, end) {
    const startindex = str.search(start) + start.length ;
    const endindex = str.search(end);
    //console.log(`startindex = ${startindex} endindex = ${endindex}`);

    if (startindex != -1 && endindex != -1 && startindex <= endindex) {
        return str.substring(0, startindex) + toinsert + str.substring(endindex);
    }
}

function removeChildren(container, excludedClasses) {

    const containerChildren = container.children;
    const l = containerChildren.length;
    let nodesToRemove = [];
    if (excludedClasses) {
        for (var i = 0; i < l; i++) {
            const current = containerChildren[i];
            let excluded = false;
            for (var j = 0; j < excludedClasses.length; j++) {
                if (current.classList.contains(excludedClasses[j])) {
                   excluded = true;
                }
            }
            if (!excluded) {
                nodesToRemove.push(current);
            }
        }
    } else {
        nodesToRemove = containerChildren;
    }

    nodesToRemove.forEach((node)=>{
        container.removeChild(node)
    });
}

function loadAndTrim(url, response) {
    JSDOM.fromURL(url).then((dom) => {
                    const body = dom.window.document.getElementsByTagName('body')[0]
                    const contentContainer = dom.window.document.getElementsByClassName('content-container')[0];
                    const mainContainer = dom.window.document.getElementsByClassName('main-container')[0];
                    const translateContainer = dom.window.document.getElementsByClassName('translate')[0]
                    const cardContainer = dom.window.document.getElementsByClassName('card')[0];

                    removeChildren(body, ['content-container']);
                    removeChildren(contentContainer, ['main-container']);
                    removeChildren(mainContainer, ['translate', 'conjugation']);

                    if (translateContainer) {
                        removeChildren(translateContainer, ['card', ['tab-content']]) ;
                    }

                    const navElements = dom.window.document.getElementsByClassName('nav-content');
                    if (navElements) {
                        const l = navElements.length;
                        for (var i = 0; i < l; i++) {
                            const parent = navElements[i].parentElement;
                            parent.removeChild(navElements[i]);
                        }
                    }

                    //cardContainer.removeChild(navElement);

                    response.end(dom.serialize());
                }).catch((e)=> {
                    logger.log(e.message);
                    logger.log(url);
                    logger.printStackTrace(e);
                });
}

module.exports = Domfilter;

<|endoftext|>


<commit_before>/**
* @license Apache-2.0
*
* Copyright (c) 2018 The Stdlib Authors.
*
* 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.
*/

'use strict';

// MODULES //

var objectKeys = require( '@stdlib/utils/keys' );

// FUNCTIONS //

/**
* Tests if the seen array contains a search value.
*
* @private
* @param {Array} seen - array of seen objects
* @param {*} searchValue - search value
* @returns {boolean} boolean indicating whether array contains search value
*/
function contains( seen, searchValue ) {
	var i;
	for ( i = 0; i < seen.length; i++ ) {
		if ( seen[ i ] === searchValue ) {
			return true;
		}
	}
	return false;
}

/**
* Tests if an object contains a circular reference by recursively traversing object keys.
*
* @private
* @param {Object} obj - object to test
* @param {Array} seen - array of seen objects
* @returns {boolean} boolean indicating whether object contains a circular reference
*/
function isCircObj( obj, seen ) {
	var keys;
	var val;
	var i;

	seen.push( obj );
	keys = objectKeys( obj );
	if ( keys.length === 0 ) {
		return false;
	}
	for ( i = 0; i < keys.length; i++ ) {
		val = obj[ keys[ i ] ];
		if ( val instanceof Object ) {
			if ( contains( seen, val ) || isCircObj( val, seen ) ) {
				return true;
			}
		}
	}
	seen.pop( obj );
	return false;
}

// MAIN //

/**
* Tests if an object-like value contains a circular reference.
*
* @param {*} value - value to test
* @returns {boolean} boolean indicating whether value is object-like and contains a circular reference
*
* @example
* var obj = {
*   'a': 'beep',
*   'b': {
*     'c': 'boop'
*   }
* };
* obj.b.self = obj;
* var bool = isCircular( obj );
* // returns true
*
* @example
* var arr = [ 1, 2, 3 ];
* arr.push( arr );
* var bool = isCircular( arr );
* // returns true
*
* @example
* var bool = isCircular( {} );
* // returns false
*
* @example
* var bool = isCircular( null );
* // returns false
*/
function isCircular( value ) {
	var type = typeof value;
	if ( value === null || !( type === 'object' || type === 'function' ) ) {
		return false;
	}
	return isCircObj( value, [] );
}

// EXPORTS //

module.exports = isCircular;
<commit_msg>Fix cross-realm behavior<commit_after>/**
* @license Apache-2.0
*
* Copyright (c) 2018 The Stdlib Authors.
*
* 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.
*/

'use strict';

// MODULES //

var objectKeys = require( '@stdlib/utils/keys' );

// FUNCTIONS //

/**
* Tests if a value is an object.
*
* ## Notes
*
* -   The function excludes `null`.
*
* @private
* @param {*} value - value to test
* @returns {boolean} boolean indicating if a value is an object
*/
function isObject( value ) {
	var type = typeof value;
	return ( value !== null && ( type === 'object' || type === 'function' ) );
}

/**
* Tests if the seen array contains a search value.
*
* @private
* @param {Array} seen - array of seen objects
* @param {*} searchValue - search value
* @returns {boolean} boolean indicating whether array contains search value
*/
function contains( seen, searchValue ) {
	var i;
	for ( i = 0; i < seen.length; i++ ) {
		if ( seen[ i ] === searchValue ) {
			return true;
		}
	}
	return false;
}

/**
* Tests if an object contains a circular reference by recursively traversing object keys.
*
* @private
* @param {Object} obj - object to test
* @param {Array} seen - array of seen objects
* @returns {boolean} boolean indicating whether object contains a circular reference
*/
function isCircObj( obj, seen ) {
	var keys;
	var val;
	var i;

	seen.push( obj );
	keys = objectKeys( obj );
	if ( keys.length === 0 ) {
		return false;
	}
	for ( i = 0; i < keys.length; i++ ) {
		val = obj[ keys[ i ] ];
		if ( isObject( val ) && ( contains( seen, val ) || isCircObj( val, seen ) ) ) { // eslint-disable-line max-len
			return true;
		}
	}
	seen.pop( obj );
	return false;
}

// MAIN //

/**
* Tests if an object-like value contains a circular reference.
*
* @param {*} value - value to test
* @returns {boolean} boolean indicating whether value is object-like and contains a circular reference
*
* @example
* var obj = {
*   'a': 'beep',
*   'b': {
*     'c': 'boop'
*   }
* };
* obj.b.self = obj;
* var bool = isCircular( obj );
* // returns true
*
* @example
* var arr = [ 1, 2, 3 ];
* arr.push( arr );
* var bool = isCircular( arr );
* // returns true
*
* @example
* var bool = isCircular( {} );
* // returns false
*
* @example
* var bool = isCircular( null );
* // returns false
*/
function isCircular( value ) {
	if ( !isObject( value ) ) {
		return false;
	}
	return isCircObj( value, [] );
}

// EXPORTS //

module.exports = isCircular;
<|endoftext|>


<commit_before>// Copyright 2017-2020, University of Colorado Boulder

/**
 * Unit tests for dot. Please run once in phet brand and once in brand=phet-io to cover all functionality.
 *
 * @author Sam Reid (PhET Interactive Simulations)
 */

import './BinPackerTests.js';
import './Bounds2Tests.js';
import './ComplexTests.js';
import './DampedHarmonicTests.js';
import './LinearFunctionTests.js';
import './Matrix3Tests.js';
import './MatrixOps3Tests.js';
import './OpenRangeTests.js';
import './PiecewiseLinearFunctionTests.js';
import './RangeTests.js';
import './RangeWithValueTests.js';
import './StatsTests.js';
import './Transform3Tests.js';
import './UtilsTests.js';
import './Vector2PropertyTests.js';
import './Vector2Tests.js';

// Since our tests are loaded asynchronously, we must direct QUnit to begin the tests
QUnit.start();<commit_msg>Use qunitStart, see https://github.com/phetsims/aqua/issues/89<commit_after>// Copyright 2017-2020, University of Colorado Boulder

/**
 * Unit tests for dot. Please run once in phet brand and once in brand=phet-io to cover all functionality.
 *
 * @author Sam Reid (PhET Interactive Simulations)
 */

import './BinPackerTests.js';
import './Bounds2Tests.js';
import './ComplexTests.js';
import './DampedHarmonicTests.js';
import './LinearFunctionTests.js';
import './Matrix3Tests.js';
import './MatrixOps3Tests.js';
import './OpenRangeTests.js';
import './PiecewiseLinearFunctionTests.js';
import './RangeTests.js';
import './RangeWithValueTests.js';
import './StatsTests.js';
import './Transform3Tests.js';
import './UtilsTests.js';
import './Vector2PropertyTests.js';
import './Vector2Tests.js';
import qunitStart from '../../chipper/js/sim-tests/qunitStart.js';

// Since our tests are loaded asynchronously, we must direct QUnit to begin the tests
qunitStart();<|endoftext|>


<commit_before>;(function(window, angular, __adroll, undefined) {
    'use strict';
    /**
     * @ngdoc overview
     * @name angulartics.adroll
     */
    angular.module('angulartics.adroll', ['angulartics'])
        .config(['$analyticsProvider', function($analyticsProvider) {

            angulartics.waitForVendorApi('__adroll', 500, function(__adroll) {
                $analyticsProvider.registerPageTrack(function(path, segment) {
                    adroll_segments = segment;
                });
            });

            $analyticsProvider.registerEventTrack(function(action, properties) {
                if (!__adroll) return;
                try {
                    window.setTimeout(function() {
                      __adroll.record_user({ "adroll_segments": properties.segments })
                    }, 500);
                } catch (err) {
                    console.log(err);
                }
            });

        }]);
})(window, window.angular, window.__adroll);
<commit_msg>$timeout<commit_after>;(function(window, angular, __adroll, undefined) {
    'use strict';
    /**
     * @ngdoc overview
     * @name angulartics.adroll
     */
    angular.module('angulartics.adroll', ['angulartics'])
        .config(['$analyticsProvider', '$timeout', function($analyticsProvider, $timeout) {

            angulartics.waitForVendorApi('__adroll', 500, function(__adroll) {
                $analyticsProvider.registerPageTrack(function(path, segment) {
                    adroll_segments = segment;
                });
            });

            $analyticsProvider.registerEventTrack(function(action, properties) {
                if (!__adroll) return;
                try {
                    $timeout(function() {
                      __adroll.record_user({ "adroll_segments": properties.segments })
                    }, 500);
                } catch (err) {
                    console.log(err);
                }
            });

        }]);
})(window, window.angular, window.__adroll);
<|endoftext|>


<commit_before>/*
 * == BSD2 LICENSE ==
 * Copyright (c) 2016, Tidepool Project
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the associated License, which is identical to the BSD 2-Clause
 * License as published by the Open Source Initiative at opensource.org.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the License for more details.
 *
 * You should have received a copy of the License along with this program; if
 * not, you can obtain one from Tidepool Project at tidepool.org.
 * == BSD2 LICENSE ==
 */

 Number.prototype.toFixedNumber = function(significant){
   var pow = Math.pow(10,significant);
   return +( Math.round(this*pow) / pow );
 };

 var roundAndNotNegative = function(number) {
   if(number < 0) {
     return 0;
   }
   // calculated total units are rounded to the nearest .05 units
   return (Math.ceil(number*20 - 0.5)/20).toFixedNumber(2);
 };

var withinTarget = function(wizDetails) {
  return (Math.abs(wizDetails.bg - wizDetails.target_bg) < wizDetails.bg_delta) ? true : false;
};

var calculateCarbRecommendation = function(wizDetails) {
  return wizDetails.carb_amount / wizDetails.carb_ratio;
};

var calculateCorrectionRecommendation = function(wizDetails) {
  if(!withinTarget(wizDetails)) {
    console.log("WIZDETAILS:", JSON.stringify(wizDetails,null,4));
    return (wizDetails.bg - wizDetails.target_bg) / wizDetails.isf;
  }
  else {
    return 0;
  }
};

var calculateNetRecommendation = function(wizDetails, bgOrCarbTriggered) {

  if (bgOrCarbTriggered === 'bg')  {
    // ezBG only
    var correction = calculateCorrectionRecommendation(wizDetails);
    if (wizDetails.configuration.iobEnabled) {
      // IOB enabled
      if (withinTarget(wizDetails)) {
        // within target, only use correction bolus
        return roundAndNotNegative(correction);
      }
      else {
        if ((wizDetails.bg - wizDetails.target_bg) > 0) {
          // above target, subtract IOB from correction bolus
          return roundAndNotNegative(correction - wizDetails.iob);
        }
        else {
          // below target, IOB not subtracted as it's ezBG only
          return roundAndNotNegative(correction);
        }
      }
    }
    else {
      // IOB disabled
      return roundAndNotNegative(correction);
    }
  }

  if (wizDetails.configuration.correctionAdded === false) {
    // ezCarb only
    return roundAndNotNegative(calculateCarbRecommendation(wizDetails));
  }

  // ezCarb with correction bolus
  if (wizDetails.configuration.iobEnabled) {
    //IOB enabled
    if (withinTarget(wizDetails)) {
      //IOB not subtracted; just add food bolus and correction bolus
      return roundAndNotNegative(calculateCarbRecommendation(wizDetails) + calculateCorrectionRecommendation(wizDetails));
    }
    else {
      if ((wizDetails.bg - wizDetails.target_bg) > 0) {
        // above target, subtract IOB from correction bolus
        var correctionMinIOB =  calculateCorrectionRecommendation(wizDetails) - wizDetails.iob;
        return roundAndNotNegative(calculateCarbRecommendation(wizDetails) + Math.max(0,correctionMinIOB));
      }
      else {
        // below target, subtract IOB from food bolus
        var foodBolusMinIOB = calculateCarbRecommendation(wizDetails) - wizDetails.iob;
        return roundAndNotNegative(calculateCorrectionRecommendation(wizDetails) + Math.max(0,foodBolusMinIOB));
      }
    }
  }
  else {
    // IOB disabled
    return roundAndNotNegative(calculateCarbRecommendation(wizDetails) + calculateCorrectionRecommendation(wizDetails));
  }
};

exports.calculateCarbRecommendation = calculateCarbRecommendation;
exports.calculateCorrectionRecommendation = calculateCorrectionRecommendation;
exports.calculateNetRecommendation = calculateNetRecommendation;
exports.toFixedNumber =  Number.prototype.toFixedNumber;
<commit_msg>remove temporary debug log<commit_after>/*
 * == BSD2 LICENSE ==
 * Copyright (c) 2016, Tidepool Project
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the associated License, which is identical to the BSD 2-Clause
 * License as published by the Open Source Initiative at opensource.org.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the License for more details.
 *
 * You should have received a copy of the License along with this program; if
 * not, you can obtain one from Tidepool Project at tidepool.org.
 * == BSD2 LICENSE ==
 */

 Number.prototype.toFixedNumber = function(significant){
   var pow = Math.pow(10,significant);
   return +( Math.round(this*pow) / pow );
 };

 var roundAndNotNegative = function(number) {
   if(number < 0) {
     return 0;
   }
   // calculated total units are rounded to the nearest .05 units
   return (Math.ceil(number*20 - 0.5)/20).toFixedNumber(2);
 };

var withinTarget = function(wizDetails) {
  return (Math.abs(wizDetails.bg - wizDetails.target_bg) < wizDetails.bg_delta) ? true : false;
};

var calculateCarbRecommendation = function(wizDetails) {
  return wizDetails.carb_amount / wizDetails.carb_ratio;
};

var calculateCorrectionRecommendation = function(wizDetails) {
  if(!withinTarget(wizDetails)) {
    return (wizDetails.bg - wizDetails.target_bg) / wizDetails.isf;
  }
  else {
    return 0;
  }
};

var calculateNetRecommendation = function(wizDetails, bgOrCarbTriggered) {

  if (bgOrCarbTriggered === 'bg')  {
    // ezBG only
    var correction = calculateCorrectionRecommendation(wizDetails);
    if (wizDetails.configuration.iobEnabled) {
      // IOB enabled
      if (withinTarget(wizDetails)) {
        // within target, only use correction bolus
        return roundAndNotNegative(correction);
      }
      else {
        if ((wizDetails.bg - wizDetails.target_bg) > 0) {
          // above target, subtract IOB from correction bolus
          return roundAndNotNegative(correction - wizDetails.iob);
        }
        else {
          // below target, IOB not subtracted as it's ezBG only
          return roundAndNotNegative(correction);
        }
      }
    }
    else {
      // IOB disabled
      return roundAndNotNegative(correction);
    }
  }

  if (wizDetails.configuration.correctionAdded === false) {
    // ezCarb only
    return roundAndNotNegative(calculateCarbRecommendation(wizDetails));
  }

  // ezCarb with correction bolus
  if (wizDetails.configuration.iobEnabled) {
    //IOB enabled
    if (withinTarget(wizDetails)) {
      //IOB not subtracted; just add food bolus and correction bolus
      return roundAndNotNegative(calculateCarbRecommendation(wizDetails) + calculateCorrectionRecommendation(wizDetails));
    }
    else {
      if ((wizDetails.bg - wizDetails.target_bg) > 0) {
        // above target, subtract IOB from correction bolus
        var correctionMinIOB =  calculateCorrectionRecommendation(wizDetails) - wizDetails.iob;
        return roundAndNotNegative(calculateCarbRecommendation(wizDetails) + Math.max(0,correctionMinIOB));
      }
      else {
        // below target, subtract IOB from food bolus
        var foodBolusMinIOB = calculateCarbRecommendation(wizDetails) - wizDetails.iob;
        return roundAndNotNegative(calculateCorrectionRecommendation(wizDetails) + Math.max(0,foodBolusMinIOB));
      }
    }
  }
  else {
    // IOB disabled
    return roundAndNotNegative(calculateCarbRecommendation(wizDetails) + calculateCorrectionRecommendation(wizDetails));
  }
};

exports.calculateCarbRecommendation = calculateCarbRecommendation;
exports.calculateCorrectionRecommendation = calculateCorrectionRecommendation;
exports.calculateNetRecommendation = calculateNetRecommendation;
exports.toFixedNumber =  Number.prototype.toFixedNumber;
<|endoftext|>


<commit_before>// load mono api
require("../../api");

var http = require("http");
var parse = require("url").parse;

// imported functions
var send = require("./send");
var operator = require("./operator");
var route = require("./router");

function forwardRequest (link) {

    if (link.path[0] == M.config.operationKey) {

        if (link.path.length < 3) {
            return link.send(400, "Invalid operation url");
        }

        link.operation = {
            module: link.path[1],
            method: link.path[2]
        };

        link.path = link.path.slice(3);

        operator.operation(link);

    } else {
        route(link);
    }
}

function requestHandler (req, res) {

    req.pause();

    var url = parse(req.url, true);
    var path = url.pathname.replace(/\/$|^\//g, "").split("/", 42);
    var link = {
            req:        req,
            res:        res,
            send:       send.send,
            path:       path,
            query:      url.query || {},
            pathname:   url.pathname,
            time:       new Date().getTime()
        };

    // invoke streaming api
    link.stream = send.stream(link);

    // set a empty response header object
    link.res.headers = {};

    // get the session
    M.session.get(link, forwardRequest);
}

/* ========================================================== */
/* DO NOT WRITE ANYTHING ON STDOUT UNTIL THE LISTENER STARTED */
/* ========================================================== */

// start application server
if (!M.config.app) {
    console.error("This server cannot be started without an application ID");
    process.exit(1);
}

// establish the database connection
M.orient.connect (function(err, db) {

    if (err) {
        console.error("Could not connect to the Orient database.");
        console.error(err);
        process.exit(2);
    }

    M.app.get(M.config.app, function(err, application) {

        if (err) {
            console.error(err.message || err.toString());
            process.exit(3);
        }

        M.config.app = application;

        // TODO remove this and add it to a M.app.validate function that fails if something is not OK with the app
        //      - the app does not have public role (this should be enforced through the database)
        //      - the user owning the app cannot start more application
        //      - the app is under quatantine
        //      - etc.
        if (isNaN(M.config.app.publicRole)) {
            console.error("Could not determine the public user for application: " + M.config.app.id);
            process.exit(4);
        }

        // start http server
        http.createServer(requestHandler).listen(M.config.port, M.config.host, function () {
            process.stdout.write(M.config.app.id);
            /* ========================================== */
            /* AFTER THIS OUTPUT YOU CAN AGAIN USE STDOUT */
            /* ========================================== */
        });
    });
});

<commit_msg>Store the value returned by createServer into M.app.server.<commit_after>// load mono api
require("../../api");

var http = require("http");
var parse = require("url").parse;

// imported functions
var send = require("./send");
var operator = require("./operator");
var route = require("./router");

function forwardRequest (link) {

    if (link.path[0] == M.config.operationKey) {

        if (link.path.length < 3) {
            return link.send(400, "Invalid operation url");
        }

        link.operation = {
            module: link.path[1],
            method: link.path[2]
        };

        link.path = link.path.slice(3);

        operator.operation(link);

    } else {
        route(link);
    }
}

function requestHandler (req, res) {

    req.pause();

    var url = parse(req.url, true);
    var path = url.pathname.replace(/\/$|^\//g, "").split("/", 42);
    var link = {
            req:        req,
            res:        res,
            send:       send.send,
            path:       path,
            query:      url.query || {},
            pathname:   url.pathname,
            time:       new Date().getTime()
        };

    // invoke streaming api
    link.stream = send.stream(link);

    // set a empty response header object
    link.res.headers = {};

    // get the session
    M.session.get(link, forwardRequest);
}

/* ========================================================== */
/* DO NOT WRITE ANYTHING ON STDOUT UNTIL THE LISTENER STARTED */
/* ========================================================== */

// start application server
if (!M.config.app) {
    console.error("This server cannot be started without an application ID");
    process.exit(1);
}

// establish the database connection
M.orient.connect (function(err, db) {

    if (err) {
        console.error("Could not connect to the Orient database.");
        console.error(err);
        process.exit(2);
    }

    M.app.get(M.config.app, function(err, application) {

        if (err) {
            console.error(err.message || err.toString());
            process.exit(3);
        }

        M.config.app = application;

        // TODO remove this and add it to a M.app.validate function that fails if something is not OK with the app
        //      - the app does not have public role (this should be enforced through the database)
        //      - the user owning the app cannot start more application
        //      - the app is under quatantine
        //      - etc.
        if (isNaN(M.config.app.publicRole)) {
            console.error("Could not determine the public user for application: " + M.config.app.id);
            process.exit(4);
        }

        // start http server
        var server = http.createServer(requestHandler).listen(M.config.port, M.config.host, function () {
             process.stdout.write(M.config.app.id);
             /* ========================================== */
             /* AFTER THIS OUTPUT YOU CAN AGAIN USE STDOUT */
             /* ========================================== */
        });

        // save server object into app.server
        M.app.server = server;
    });
});

<|endoftext|>


<commit_before>
var canvas = $("#canvas")[0];
var context = canvas.getContext("2d");

var top = ((2 * Math.PI)/ 4) * 3;

var validValues = [2,3,4,6,8,12,16];
var segments = validValues[Math.floor(Math.random() * validValues.length)];

var fraction = Math.floor(Math.random() * (segments - 1)) + 1;

$("#fraction").text(fraction + "/" + segments);

function rad(num) {
    return (num - 90) / 360 * (2 * Math.PI);
}
var segmentList = [];

canvas.addEventListener('mousedown', function (e) {
    var loc = windowToCanvas(canvas, e.clientX, e.clientY);
    for(idx = 0; idx < segmentList.length; idx++) {
        if(segmentList[idx].isClicked(loc.x, loc.y)) {
            segmentList[idx].selected();
            break;
        }
    }
});

function windowToCanvas(canvas, x, y) {
    var bbox = canvas.getBoundingClientRect();
    return { x: x - bbox.left * (canvas.width / bbox.width),
        y: y - bbox.top * (canvas.height / bbox.height)
    }
}

var Segment = function(angle, id) {
    this.angle = angle;
    this.id = id;
    this.isSelected = false;

    this.draw = function(context) {
        context.fillStyle = "#FFFFFF";
        context.beginPath();
        context.moveTo(300, 400);
        context.lineTo(300 + (100 * Math.cos(rad(this.angle * this.id))), 400 + (100 * Math.sin(rad(this.angle * this.id))));
        context.arc(300, 400, 100, rad(this.angle * this.id), rad(this.angle * (this.id + 1)));
        context.lineTo(300, 400);
        context.fill();
        context.stroke();
    };

    this.isClicked = function(x, y) {
        return true;
    };

    this.selected = function() {
        this.isSelected = true;
        context.fillStyle = "#FF00FF";
        context.beginPath();
        context.moveTo(300, 400);
        context.lineTo(300 + (100 * Math.cos(rad(this.angle * this.id))), 400 + (100 * Math.sin(rad(this.angle * this.id))));
        context.arc(300, 400, 100, rad(this.angle * this.id), rad(this.angle * (this.id + 1)));
        context.lineTo(300, 400);
        context.fill();
        context.stroke();
    };
};

for(segmentNum = 0; segmentNum < segments; segmentNum++){
    var segment = new Segment(360 / segments, segmentNum);
    segmentList.push(segment);
    segment.draw(context);
}<commit_msg>- Hypotenusifier added to give extra awesome sauce<commit_after>
var canvas = $("#canvas")[0];
var context = canvas.getContext("2d");

var top = ((2 * Math.PI)/ 4) * 3;

var validValues = [2,3,4,6,8,12,16];
var segments = validValues[Math.floor(Math.random() * validValues.length)];

var fraction = Math.floor(Math.random() * (segments - 1)) + 1;

$("#fraction").text(fraction + "/" + segments);

function rad(num) {
    return (num - 90) / 360 * (2 * Math.PI);
}
var segmentList = [];

canvas.addEventListener('mousedown', function (e) {
    var loc = windowToCanvas(canvas, e.clientX, e.clientY);
    for(idx = 0; idx < segmentList.length; idx++) {
        if(segmentList[idx].isClicked(loc.x, loc.y)) {
            segmentList[idx].selected();
            break;
        }
    }
});

function windowToCanvas(canvas, x, y) {
    var bbox = canvas.getBoundingClientRect();
    return { x: x - bbox.left * (canvas.width / bbox.width),
        y: y - bbox.top * (canvas.height / bbox.height)
    }
}

var Segment = function(angle, id) {
    this.angle = angle;
    this.id = id;
    this.isSelected = false;

    this.draw = function(context) {
        context.fillStyle = "#FFFFFF";
        context.beginPath();
        context.moveTo(300, 400);
        context.lineTo(300 + (100 * Math.cos(rad(this.angle * this.id))), 400 + (100 * Math.sin(rad(this.angle * this.id))));
        context.arc(300, 400, 100, rad(this.angle * this.id), rad(this.angle * (this.id + 1)));
        context.lineTo(300, 400);
        context.fill();
        context.stroke();
    };

    this.isClicked = function(x, y) {
        var hypotenusifier = (x - 300) * (x - 300) + (y - 400) * (y - 400);
        return Math.sqrt(hypotenusifier) < 100;

    };

    this.selected = function() {
        this.isSelected = true;
        context.fillStyle = "#FF00FF";
        context.beginPath();
        context.moveTo(300, 400);
        context.lineTo(300 + (100 * Math.cos(rad(this.angle * this.id))), 400 + (100 * Math.sin(rad(this.angle * this.id))));
        context.arc(300, 400, 100, rad(this.angle * this.id), rad(this.angle * (this.id + 1)));
        context.lineTo(300, 400);
        context.fill();
        context.stroke();
    };
};

for(segmentNum = 0; segmentNum < segments; segmentNum++){
    var segment = new Segment(360 / segments, segmentNum);
    segmentList.push(segment);
    segment.draw(context);
}<|endoftext|>