<commit_before>/*
 * jQuery RG-EqualHeight v1.0
 * GitHub: https://github.com/ryangiglio/jquery-rgequalheight
 * Copyright (c) 2015 Ryan Giglio (@ryangiglio)
 *
 * Based on johndugan's jQuery Plugin Boilerplate https://github.com/johndugan/jquery-plugin-boilerplate
 * Which is based on Zeno Rocha's jQuery Plugin Boilerplate https://github.com/jquery-boilerplate/jquery-boilerplate
 */

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

  var pluginName = 'rgequalheight';

  function Plugin ( element, options ) {
    this.element = element;
    this._name = pluginName;
    this._defaults = $.fn.rgequalheight.defaults;

    this.options = $.extend( {}, this._defaults, options );

    this.init();
  }

  $.extend(Plugin.prototype, {

    init: function () {
      this.buildCache();
      this.bindEvents();

      this.windowResizeHandler();

      // var to store the setTimeout ID used to throttle window resize events
      this.windowResizeTriggerTimeout = null;
    },

    // Remove plugin instance completely
    destroy: function() {
      this.unbindEvents();

      // Remove all plugin data from the element
      this.$element.removeData();

      // Unset the fixed height
      this.unsetHeight();
    },

    buildCache: function () {
      this.$element = $(this.element);
    },

    bindEvents: function() {
      // Create plugin as a variable so we can use it inside the event handler
      var plugin = this;

      // On window resize
      $(window).on('resize'+'.'+plugin._name, function() {
        // Throttle resize events firing
        clearTimeout(plugin.windowResizeTriggerTimeout);

        plugin.windowResizeTriggerTimeout = setTimeout(function() {
          plugin.windowResizeHandler();
        }, plugin.options.windowResizeThrottle);
      });
    },

    // Unbind events that trigger methods
    unbindEvents: function() {
      // Unbind all event handlers on the plugin element
      this.$element.off('.'+this._name);

      // Unbind window resize event
      $(window).off('resize'+'.'+this._name);
    },

    windowResizeHandler: function() {
      // If we have no disable break, or the window is larger than the break
      if ( this.options.minWidthBreakpoint === null || $(window).width() >= this.options.minWidthBreakpoint ) {
        this.equalizeHeight();
      }
      // If the window is smaller than the break
      else {
        this.unsetHeight();
      }
    },

    equalizeHeight: function() {
      var maxHeight = 0;

      // Loop over each element
      this.$element.each(function() {
        // Reset the natural height
        $(this).css('height', 'auto');

        // If this element is larger than the previous one
        if ( $(this).outerHeight() > maxHeight ) {
          // Save the height
          maxHeight = $(this).outerHeight();
        }
      });

      // Set the new height
      if ( this.options.useMinHeight ) {
        this.$element.css('min-height', maxHeight);
      }
      else {
        this.$element.css('height', maxHeight);
      }
    },

    unsetHeight: function() {
      if ( this.options.useMinHeight ) {
        this.$element.css('min-height', '');
      }
      else {
        this.$element.css('height', '');
      }
    },

    callback: function() {
      // Cache onComplete option
      var onComplete = this.options.onComplete;

      if ( typeof onComplete === 'function' ) {
        onComplete.call(this.element);
      }
    }

  });

  /*
   * Plugin wrapper to allow for public function calls
   *
   * From the jQuery Plugin Boilerplate Guide:
   * https://github.com/jquery-boilerplate/jquery-boilerplate/wiki/Extending-jQuery-Boilerplate
   */
  $.fn.rgequalheight = function ( options ) {
    var args = arguments;

    // Is the first parameter an object (options), or was omitted,
    // instantiate a new instance of the plugin.
    if (options === undefined || typeof options === 'object') {
      // Only allow the plugin to be instantiated once,
      // so we check that the element has no plugin instantiation yet
      if (!$.data(this, 'plugin_' + pluginName)) {

        // if it has no instance, create a new one,
        // pass options to our plugin constructor,
        // and store the plugin instance
        // in the elements jQuery data object.
        $.data(this, 'plugin_' + pluginName, new Plugin( this, options ));
      }

    // If the first parameter is a string and it doesn't start
    // with an underscore or "contains" the `init`-function,
    // treat this as a call to a public method.
    } else if (typeof options === 'string' && options[0] !== '_' && options !== 'init') {

      // Cache the method call
      // to make it possible
      // to return a value
      var returns;

      var instance = $.data(this, 'plugin_' + pluginName);

      // Tests that there's already a plugin-instance
      // and checks that the requested public method exists
      if (instance instanceof Plugin && typeof instance[options] === 'function') {

        // Call the method of our plugin instance,
        // and pass it the supplied arguments.
        returns = instance[options].apply( instance, Array.prototype.slice.call( args, 1 ) );
      }

      // Allow instances to be destroyed via the 'destroy' method
      if (options === 'destroy') {
        $.data(this, 'plugin_' + pluginName, null);
      }

      // If the earlier cached method
      // gives a value back return the value,
      // otherwise return this to preserve chainability.
      return returns !== undefined ? returns : this;
    }
  };

  $.fn.rgequalheight.defaults = {
    // Set as true to set min-height instead of height
    useMinHeight: false,
    // Minimum pixel width to equalize columns at (useful for responsive designs)
    minWidthBreakpoint: null,
    // ms of throttle to wait between window resize and element resize. This stops the browser from re-calculating every pixel of resize
    windowResizeThrottle: 100
  };

})( jQuery, window, document );
<commit_msg>Add responsive option to not automatically resize elements<commit_after>/*
 * jQuery RG-EqualHeight v1.0
 * GitHub: https://github.com/ryangiglio/jquery-rgequalheight
 * Copyright (c) 2015 Ryan Giglio (@ryangiglio)
 *
 * Based on johndugan's jQuery Plugin Boilerplate https://github.com/johndugan/jquery-plugin-boilerplate
 * Which is based on Zeno Rocha's jQuery Plugin Boilerplate https://github.com/jquery-boilerplate/jquery-boilerplate
 */

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

  var pluginName = 'rgequalheight';

  function Plugin ( element, options ) {
    this.element = element;
    this._name = pluginName;
    this._defaults = $.fn.rgequalheight.defaults;

    this.options = $.extend( {}, this._defaults, options );

    this.init();
  }

  $.extend(Plugin.prototype, {

    init: function () {
      this.buildCache();

      // Equalize heights depending on window size
      this.windowResizeHandler();

      // If the plugin should be responsive
      if ( this.options.responsive ) {
        // Bind events that re-trigger the resize on window resize
        this.bindEvents();

        // var to store the setTimeout ID used to throttle window resize events
        this.windowResizeTriggerTimeout = null;
      }
    },

    // Remove plugin instance completely
    destroy: function() {
      this.unbindEvents();

      // Remove all plugin data from the element
      this.$element.removeData();

      // Unset the fixed height
      this.unsetHeight();
    },

    buildCache: function () {
      this.$element = $(this.element);
    },

    bindEvents: function() {
      // Create plugin as a variable so we can use it inside the event handler
      var plugin = this;

      // On window resize
      $(window).on('resize'+'.'+plugin._name, function() {
        // Throttle resize events firing
        clearTimeout(plugin.windowResizeTriggerTimeout);

        plugin.windowResizeTriggerTimeout = setTimeout(function() {
          plugin.windowResizeHandler();
        }, plugin.options.windowResizeThrottle);
      });
    },

    // Unbind events that trigger methods
    unbindEvents: function() {
      // Unbind all event handlers on the plugin element
      this.$element.off('.'+this._name);

      // Unbind window resize event
      $(window).off('resize'+'.'+this._name);
    },

    windowResizeHandler: function() {
      // If we have no disable break, or the window is larger than the break
      if ( this.options.minWidthBreakpoint === null || $(window).width() >= this.options.minWidthBreakpoint ) {
        this.equalizeHeight();
      }
      // If the window is smaller than the break
      else {
        this.unsetHeight();
      }
    },

    equalizeHeight: function() {
      var maxHeight = 0;

      // Loop over each element
      this.$element.each(function() {
        // Reset the natural height
        $(this).css('height', 'auto');

        // If this element is larger than the previous one
        if ( $(this).outerHeight() > maxHeight ) {
          // Save the height
          maxHeight = $(this).outerHeight();
        }
      });

      // Set the new height
      if ( this.options.useMinHeight ) {
        this.$element.css('min-height', maxHeight);
      }
      else {
        this.$element.css('height', maxHeight);
      }
    },

    unsetHeight: function() {
      if ( this.options.useMinHeight ) {
        this.$element.css('min-height', '');
      }
      else {
        this.$element.css('height', '');
      }
    },

    callback: function() {
      // Cache onComplete option
      var onComplete = this.options.onComplete;

      if ( typeof onComplete === 'function' ) {
        onComplete.call(this.element);
      }
    }

  });

  /*
   * Plugin wrapper to allow for public function calls
   *
   * From the jQuery Plugin Boilerplate Guide:
   * https://github.com/jquery-boilerplate/jquery-boilerplate/wiki/Extending-jQuery-Boilerplate
   */
  $.fn.rgequalheight = function ( options ) {
    var args = arguments;

    // Is the first parameter an object (options), or was omitted,
    // instantiate a new instance of the plugin.
    if (options === undefined || typeof options === 'object') {
      // Only allow the plugin to be instantiated once,
      // so we check that the element has no plugin instantiation yet
      if (!$.data(this, 'plugin_' + pluginName)) {

        // if it has no instance, create a new one,
        // pass options to our plugin constructor,
        // and store the plugin instance
        // in the elements jQuery data object.
        $.data(this, 'plugin_' + pluginName, new Plugin( this, options ));
      }

    // If the first parameter is a string and it doesn't start
    // with an underscore or "contains" the `init`-function,
    // treat this as a call to a public method.
    } else if (typeof options === 'string' && options[0] !== '_' && options !== 'init') {

      // Cache the method call
      // to make it possible
      // to return a value
      var returns;

      var instance = $.data(this, 'plugin_' + pluginName);

      // Tests that there's already a plugin-instance
      // and checks that the requested public method exists
      if (instance instanceof Plugin && typeof instance[options] === 'function') {

        // Call the method of our plugin instance,
        // and pass it the supplied arguments.
        returns = instance[options].apply( instance, Array.prototype.slice.call( args, 1 ) );
      }

      // Allow instances to be destroyed via the 'destroy' method
      if (options === 'destroy') {
        $.data(this, 'plugin_' + pluginName, null);
      }

      // If the earlier cached method
      // gives a value back return the value,
      // otherwise return this to preserve chainability.
      return returns !== undefined ? returns : this;
    }
  };

  $.fn.rgequalheight.defaults = {
    // Set as true to set min-height instead of height
    useMinHeight: false,
    // Update heights when the window resizes
    responsive: true,
    // Minimum pixel width to equalize columns at (useful for responsive designs)
    minWidthBreakpoint: null,
    // ms of throttle to wait between window resize and element resize. This stops the browser from re-calculating every pixel of resize
    windowResizeThrottle: 100,
  };

})( jQuery, window, document );
<|endoftext|>


<commit_before>function boomLink(url, pageId, title) {
	this.url = url? url : "";
	this.pageId = pageId? pageId : 0;
	this.title = title? title : "";

	boomLink.prototype.isAsset = function() {
		return this.getUrl().indexOf('/asset/') === 0;
	};

	boomLink.prototype.isExternal = function() {
		return this.getUrl() !== "" && this.getUrl().substring(0,1) !== '/';
	};

	boomLink.prototype.isHttp = function() {
		return this.url.substring(0,7) === 'http://';
	};

	boomLink.prototype.isHttps = function() {
		return this.url.substring(0,8) === 'https://';
	};

	boomLink.prototype.isInternal = function() {
		return this.pageId > 0 || this.getUrl().substring(0,1) === '/';
	};

	boomLink.prototype.isMailto = function() {
		return this.url.substring(0,7) === 'mailto:';
	};

	boomLink.prototype.isTel = function() {
		return this.url.substring(0,4) === 'tel:';
	};

	boomLink.prototype.getAsset = function() {
		var assetId = this.getUrl().replace(/\/asset\/(\d+)([\/\d]*?)\/(view|download)/i, "$1");

		return new boomAsset(assetId);
	};

	boomLink.prototype.getAssetAction = function() {
		if (this.isAsset()) {
			return this.getUrl().replace(/\/asset\/(\d+)([\/\d]*?)\/(view|download)/i, "$3");
		}
	};

	boomLink.prototype.getUrl = function() {
		if (this.isTel()) {
			return this.getTelUrl();
		}

		return (this.url == 'http://') ? '' : this.makeUrlRelative();
	};

	boomLink.prototype.getPageId = function() {
		return this.pageId;
	};

	boomLink.prototype.getTelUrl = function() {
		return 'tel:' + this.url.replace(/[^+\d]+/g, '');
	};

	boomLink.prototype.getTitle = function() {
		return this.title;
	};

	boomLink.prototype.makeUrlRelative = function() {
		return (this.url.indexOf(window.location.hostname) > -1) ?
			this.url.replace(/^https?:\/\//, '').replace(window.location.hostname, '') :
			this.url;
	};
};
<commit_msg>fixed non-strict comparison<commit_after>function boomLink(url, pageId, title) {
	this.url = url? url : "";
	this.pageId = pageId? pageId : 0;
	this.title = title? title : "";

	boomLink.prototype.isAsset = function() {
		return this.getUrl().indexOf('/asset/') === 0;
	};

	boomLink.prototype.isExternal = function() {
		return this.getUrl() !== "" && this.getUrl().substring(0,1) !== '/';
	};

	boomLink.prototype.isHttp = function() {
		return this.url.substring(0,7) === 'http://';
	};

	boomLink.prototype.isHttps = function() {
		return this.url.substring(0,8) === 'https://';
	};

	boomLink.prototype.isInternal = function() {
		return this.pageId > 0 || this.getUrl().substring(0,1) === '/';
	};

	boomLink.prototype.isMailto = function() {
		return this.url.substring(0,7) === 'mailto:';
	};

	boomLink.prototype.isTel = function() {
		return this.url.substring(0,4) === 'tel:';
	};

	boomLink.prototype.getAsset = function() {
		var assetId = this.getUrl().replace(/\/asset\/(\d+)([\/\d]*?)\/(view|download)/i, "$1");

		return new boomAsset(assetId);
	};

	boomLink.prototype.getAssetAction = function() {
		if (this.isAsset()) {
			return this.getUrl().replace(/\/asset\/(\d+)([\/\d]*?)\/(view|download)/i, "$3");
		}
	};

	boomLink.prototype.getUrl = function() {
		if (this.isTel()) {
			return this.getTelUrl();
		}

		return (this.url === 'http://') ? '' : this.makeUrlRelative();
	};

	boomLink.prototype.getPageId = function() {
		return this.pageId;
	};

	boomLink.prototype.getTelUrl = function() {
		return 'tel:' + this.url.replace(/[^+\d]+/g, '');
	};

	boomLink.prototype.getTitle = function() {
		return this.title;
	};

	boomLink.prototype.makeUrlRelative = function() {
		return (this.url.indexOf(window.location.hostname) > -1) ?
			this.url.replace(/^https?:\/\//, '').replace(window.location.hostname, '') :
			this.url;
	};
};
<|endoftext|>


<commit_before>import React from 'react';
import Title from './Header/Title';

const Header = props => (

    <Title title={props.title} />

);

Header.propTypes = {
  title: React.PropTypes.string,
};

export default Header;
<commit_msg>:recycle: Use spread attribute<commit_after>import React from 'react';
import Title from './Header/Title';

const Header = props => (

    <Title {...props} />

);

export default Header;
<|endoftext|>


<commit_before>angular.module('myApp').controller('LoginCtrl', ['$scope', '$kinvey', 'trainingUtils', function ($scope, $kinvey, trainingUtils) {

    var user = $kinvey.User.getActiveUser();
    console.log("active user " + JSON.stringify(user));
    $scope.showLogin = !user;

        $scope.login = function (username, password) {
            trainingUtils.showProgress();
            var user = new $kinvey.User();
            var promise = user.login(username, password);
            promise.then(function (user) {
                //var promise = $kinvey.Push.init({
                //}).then(function(response) {
                //    console.log("register push " + JSON.stringify(response));
                //}).catch(function(error) {
                //        console.log("register push error " + JSON.stringify(error));
                //    }
                //);
                $scope.showLogin = false;
                $scope.$digest();
                trainingUtils.hideProgress();
            }, function (err) {
                console.log("err " + JSON.stringify(err));
                trainingUtils.hideProgress();
                trainingUtils.showOkDialog("Error: " + err.description);
            });
        };

        $scope.micLogin = function () {
            var user = new $kinvey.User();
            var promise = user.loginWithMIC('http://localhost:8000/app/index.html');
            promise.then(function (user) {
                $scope.showLogin = false;
                $scope.$digest();
            }, function (err) {
                console.log("mic login error " + JSON.stringify(err));
                trainingUtils.showOkDialog("Error: " + err.description);
            });
        };

        $scope.logout = function () {
            $kinvey.User.getActiveUser().then(function (user) {
                if (user) {
                    trainingUtils.showProgress();
                    user.logout().then(function () {
                        console.log("logout with success ");
                        $scope.showLogin = true;
                        $scope.$digest();
                        trainingUtils.hideProgress();
                    }).catch(function (err) {
                        console.log("logout error " + JSON.stringify(err));
                        trainingUtils.hideProgress();
                        trainingUtils.showOkDialog("Error: " + err.description);
                    });
                }
            })
        }
    }]);<commit_msg>fixed logout<commit_after>angular.module('myApp').controller('LoginCtrl', ['$scope', '$kinvey', 'trainingUtils', function ($scope, $kinvey, trainingUtils) {

    var user = $kinvey.User.getActiveUser();
    console.log("active user " + JSON.stringify(user));
    $scope.showLogin = !user;

        $scope.login = function (username, password) {
            trainingUtils.showProgress();
            var user = new $kinvey.User();
            var promise = user.login(username, password);
            promise.then(function (user) {
                //var promise = $kinvey.Push.init({
                //}).then(function(response) {
                //    console.log("register push " + JSON.stringify(response));
                //}).catch(function(error) {
                //        console.log("register push error " + JSON.stringify(error));
                //    }
                //);
                $scope.showLogin = false;
                $scope.$digest();
                trainingUtils.hideProgress();
            }, function (err) {
                console.log("err " + JSON.stringify(err));
                trainingUtils.hideProgress();
                trainingUtils.showOkDialog("Error: " + err.description);
            });
        };

        $scope.micLogin = function () {
            var user = new $kinvey.User();
            var promise = user.loginWithMIC('http://localhost:8000/app/index.html');
            promise.then(function (user) {
                $scope.showLogin = false;
                $scope.$digest();
            }, function (err) {
                console.log("mic login error " + JSON.stringify(err));
                trainingUtils.showOkDialog("Error: " + err.description);
            });
        };

    $scope.logout = function () {
        var user = $kinvey.User.getActiveUser();
        if (user) {
            trainingUtils.showProgress();
            user.logout().then(function () {
                console.log("logout with success ");
                $scope.showLogin = true;
                $scope.$digest();
                trainingUtils.hideProgress();
            }).catch(function (err) {
                console.log("logout error " + JSON.stringify(err));
                trainingUtils.hideProgress();
                trainingUtils.showOkDialog("Error: " + err.description);
            });
        }
    }
    }]);<|endoftext|>


<commit_before>define(function(require) {
    var viewLocator = require('durandal/viewLocator'),
        viewModelBinder = require('durandal/viewModelBinder'),
        viewEngine = require('durandal/viewEngine'),
        system = require('durandal/system');

    var composition = {
        switchContent: function(parent, newChild, settings) {
            if (!newChild) {
                ko.virtualElements.emptyNode(parent);
            } else {
                ko.virtualElements.setDomNodeChildren(parent, [newChild]);

                if (settings.model) {
                    if (settings.activate && settings.model.activate) {
                        system.log("Composition Activating", settings.model);
                        settings.model.activate();
                    }

                    if (settings.model.viewAttached) {
                        settings.model.viewAttached(newChild);
                    }
                }
            }
        },
        defaultStrategy: function(settings) {
            return viewLocator.locateViewForObject(settings.model);
        },
        getSettings: function(valueAccessor) {
            var settings = {},
                value = ko.utils.unwrapObservable(valueAccessor()) || {};

            if (typeof value == 'string') {
                return value;
            }

            var moduleId = system.getModuleId(value);
            if (moduleId) {
                return {
                    model:value
                };
            }

            for (var attrName in value) {
                if (typeof attrName == 'string') {
                    var attrValue = ko.utils.unwrapObservable(value[attrName]);
                    settings[attrName] = attrValue;
                }
            }

            return settings;
        },
        executeStrategy: function(element, settings) {
            var that = this;
            settings.strategy(settings).then(function(view) {
                viewModelBinder.bind(settings.model, view);
                that.switchContent(element, view, settings);
            });
        },
        inject: function(element, settings) {
            var that = this;

            if (!settings.model) {
                this.switchContent(element, null, settings);
                return;
            }

            if (settings.view) {
                viewLocator.locateView(settings.view).then(function(view) {
                    viewModelBinder.bind(settings.model, view);
                    that.switchContent(element, view, settings);
                });
                return;
            }

            if (!settings.strategy) {
                settings.strategy = this.defaultStrategy;
            }

            if (typeof settings.strategy == 'string') {
                system.acquire(settings.strategy).then(function(strategy) {
                    settings.strategy = strategy;
                    that.executeStrategy(element, settings);
                });
            } else {
                this.executeStrategy(element, settings);
            }
        },
        compose: function(element, settings, fallbackModel) {
            var that = this;

            if (typeof settings == 'string') {
                if (settings.indexOf(viewEngine.viewExtension, settings.length - viewEngine.viewExtension.length) !== -1) {
                    settings = {
                        view: settings
                    };
                } else {
                    settings = {
                        model: settings
                    };
                }
            }

            var moduleId = system.getModuleId(settings);
            if (moduleId) {
                settings = {
                    model: settings
                };
            }

            if (!settings.model) {
                if (!settings.view) {
                    this.switchContent(element, null, settings);
                } else {
                    viewLocator.locateView(settings.view).then(function(view) {
                        viewModelBinder.bind(fallbackModel || {}, view);
                        that.switchContent(element, view, settings);
                    });
                }
            } else if (typeof settings.model == 'string') {
                system.acquire(settings.model).then(function(module) {
                    if (typeof (module) == "function") {
                        settings.model = new module();
                    } else {
                        settings.model = module;
                    }

                    that.inject(element, settings);
                });
            } else {
                this.inject(element, settings);
            }
        }
    };

    ko.bindingHandlers.compose = {
        update: function(element, valueAccessor, allBindingsAccessor, viewModel) {
            var settings = composition.getSettings(valueAccessor);
            composition.compose(element, settings, viewModel);
        }
    };

    ko.virtualElements.allowedBindings.compose = true;

    return composition;
});<commit_msg>Adding default control of activation during composition.<commit_after>define(function(require) {
    var viewLocator = require('durandal/viewLocator'),
        viewModelBinder = require('durandal/viewModelBinder'),
        viewEngine = require('durandal/viewEngine'),
        system = require('durandal/system');

    function shouldPerformActivation(settings) {
        return (composition.activateDuringComposition && settings.activate == undefined) || settings.activate;
    }

    var composition = {
        activateDuringComposition: false,
        switchContent: function(parent, newChild, settings) {
            if (!newChild) {
                ko.virtualElements.emptyNode(parent);
            } else {
                ko.virtualElements.setDomNodeChildren(parent, [newChild]);

                if (settings.model) {
                    if (settings.model.activate && shouldPerformActivation(settings)) {
                        system.log("Composition Activating", settings.model);
                        settings.model.activate();
                    }

                    if (settings.model.viewAttached) {
                        settings.model.viewAttached(newChild);
                    }
                }
            }
        },
        defaultStrategy: function(settings) {
            return viewLocator.locateViewForObject(settings.model);
        },
        getSettings: function(valueAccessor) {
            var settings = {},
                value = ko.utils.unwrapObservable(valueAccessor()) || {};

            if (typeof value == 'string') {
                return value;
            }

            var moduleId = system.getModuleId(value);
            if (moduleId) {
                return {
                    model: value
                };
            }

            for (var attrName in value) {
                if (typeof attrName == 'string') {
                    var attrValue = ko.utils.unwrapObservable(value[attrName]);
                    settings[attrName] = attrValue;
                }
            }

            return settings;
        },
        executeStrategy: function(element, settings) {
            var that = this;
            settings.strategy(settings).then(function(view) {
                viewModelBinder.bind(settings.model, view);
                that.switchContent(element, view, settings);
            });
        },
        inject: function(element, settings) {
            var that = this;

            if (!settings.model) {
                this.switchContent(element, null, settings);
                return;
            }

            if (settings.view) {
                viewLocator.locateView(settings.view).then(function(view) {
                    viewModelBinder.bind(settings.model, view);
                    that.switchContent(element, view, settings);
                });
                return;
            }

            if (!settings.strategy) {
                settings.strategy = this.defaultStrategy;
            }

            if (typeof settings.strategy == 'string') {
                system.acquire(settings.strategy).then(function(strategy) {
                    settings.strategy = strategy;
                    that.executeStrategy(element, settings);
                });
            } else {
                this.executeStrategy(element, settings);
            }
        },
        compose: function(element, settings, fallbackModel) {
            var that = this;

            if (typeof settings == 'string') {
                if (settings.indexOf(viewEngine.viewExtension, settings.length - viewEngine.viewExtension.length) !== -1) {
                    settings = {
                        view: settings
                    };
                } else {
                    settings = {
                        model: settings
                    };
                }
            }

            var moduleId = system.getModuleId(settings);
            if (moduleId) {
                settings = {
                    model: settings
                };
            }

            if (!settings.model) {
                if (!settings.view) {
                    this.switchContent(element, null, settings);
                } else {
                    viewLocator.locateView(settings.view).then(function(view) {
                        viewModelBinder.bind(fallbackModel || {}, view);
                        that.switchContent(element, view, settings);
                    });
                }
            } else if (typeof settings.model == 'string') {
                system.acquire(settings.model).then(function(module) {
                    if (typeof (module) == "function") {
                        settings.model = new module();
                    } else {
                        settings.model = module;
                    }

                    that.inject(element, settings);
                });
            } else {
                this.inject(element, settings);
            }
        }
    };

    ko.bindingHandlers.compose = {
        update: function(element, valueAccessor, allBindingsAccessor, viewModel) {
            var settings = composition.getSettings(valueAccessor);
            composition.compose(element, settings, viewModel);
        }
    };

    ko.virtualElements.allowedBindings.compose = true;

    return composition;
});<|endoftext|>


<commit_before>/*global define*/
define(function(require) {
    'use strict';

    var $ = require('jquery'),
        _ = require('underscore'),
        expect = require('expect'),
        afterEach = require('mocha').afterEach,
        beforeEach = require('mocha').beforeEach,
        describe = require('mocha').describe,
        it = require('mocha').it,
        Chiropractor = require('chiropractor');

    return function() {
        beforeEach(function() {
            this.model = new Chiropractor.Model();
        });

        afterEach(function() {
            if (this.view) {
                this.view.remove();
            }
            this.view = undefined;
            this.model = undefined;
        });

        describe('select2', function() {
            it('should accept options and provide a searchable select2 ' +
               'field', function() {
                var View = Chiropractor.View.extend({
                    template: '{{ formfield "select2" model "field1" options=data }}'
                }),
                spy = this.sandbox.spy();

                this.view = new View({
                    model: this.model,
                    context: {data: [{id: 1, text: 'One'}, {id: 2, text: 'Two'}]}
                });
                this.view.listenTo(this.model, 'change:field1', spy);

                this.dom.html(this.view.render().el);

                expect(spy.callCount).to.equal(0);
                expect(this.model.get('field1')).to.be.a('undefined');
                this.view.$('[name="field1"]').select2('val', '1', true);
                expect(this.view.$('[name="field1"]').val()).to.equal('1');
                expect(spy.callCount).to.equal(1);
                expect(this.model.get('field1')).to.equal('1');
            });
        });
    };
});
<commit_msg>Test select2 formfield.<commit_after>/*global define*/
define(function(require) {
    'use strict';

    var $ = require('jquery'),
        _ = require('underscore'),
        expect = require('expect'),
        afterEach = require('mocha').afterEach,
        beforeEach = require('mocha').beforeEach,
        describe = require('mocha').describe,
        it = require('mocha').it,
        Chiropractor = require('chiropractor');

    require('lib/select2');

    return function() {
        beforeEach(function() {
            this.model = new Chiropractor.Model();
        });

        afterEach(function() {
            if (this.view) {
                this.view.remove();
            }
            this.view = undefined;
            this.model = undefined;
        });

        describe('select2', function() {
            it('should accept options and provide a searchable select2 ' +
               'field', function() {
                var View = Chiropractor.View.extend({
                    template: '{{ formfield "select2" model "field1" options=data }}'
                }),
                spy = this.sandbox.spy();

                this.view = new View({
                    model: this.model,
                    context: {data: [{id: 1, text: 'One'}, {id: 2, text: 'Two'}]}
                });
                this.view.listenTo(this.model, 'change:field1', spy);

                this.dom.html(this.view.render().el);

                expect(spy.callCount).to.equal(0);
                expect(this.model.get('field1')).to.be.a('undefined');
                this.view.$('[name="field1"]').select2('val', '1', true);
                expect(this.view.$('[name="field1"]').val()).to.equal('1');
                expect(spy.callCount).to.equal(1);
                expect(this.model.get('field1')).to.equal('1');
            });
        });
    };
});
<|endoftext|>


<commit_before>import React from 'react';
import Document, { Head, Main, NextScript } from 'next/document';
import colors from '../theme';

class Page extends Document {
  render() {
    return (
      <html lang="en">
        <Head>
          <meta charSet="utf-8" />
          <meta
            name="viewport"
            content="initial-scale=1.0, width=device-width, viewport-fit=cover"
          />
          <link rel="manifest" href="/static/manifest.json" />
          <link type="text/plain" rel="author" href="/static/humans.txt" />
          <link
            rel="mask-icon"
            href="/static/images/logo/logo.svg"
            color={colors.primary}
          />
          <meta name="theme-color" content={colors.primary} />
          {/* Icons and stuff */}
          <link rel="shortcut icon" href="/static/images/favicon.png" />
          <link rel="shortcut icon" href="/static/images/logo/logo.ico" />
          <link
            rel="apple-touch-icon-precomposed"
            sizes="228x228"
            href="/static/images/logo/logo-228.png"
          />
          <link
            rel="apple-touch-icon-precomposed"
            sizes="195x195"
            href="/static/images/logo/logo-195.png"
          />
          <link
            rel="apple-touch-icon-precomposed"
            sizes="152x152"
            href="/static/images/logo/logo-152.png"
          />
          <link
            rel="apple-touch-icon-precomposed"
            sizes="144x144"
            href="/static/images/logo/logo-144.png"
          />
          <link
            rel="apple-touch-icon-precomposed"
            sizes="128x128"
            href="/static/images/logo/logo-128.png"
          />
          <link
            rel="apple-touch-icon-precomposed"
            sizes="120x120"
            href="/static/images/logo/logo-120.png"
          />
          <link
            rel="apple-touch-icon-precomposed"
            sizes="96x96"
            href="/static/images/logo/logo-96.png"
          />
          <link
            rel="apple-touch-icon-precomposed"
            sizes="72x72"
            href="/static/images/logo/logo-72.png"
          />
          <link
            rel="apple-touch-icon-precomposed"
            href="/static/images/logo/logo-57.png"
          />
          <link
            rel="apple-touch-icon-precomposed"
            href="/static/images/logo/logo-32.png"
            sizes="32x32"
          />
          {/* FEEEEEEEDS */}
          <link
            rel="alternate"
            href="/atom"
            type="application/atom+xml"
            title="RSS Feed"
          />
          <link
            rel="alternate"
            href="/feed.json"
            type="application/json"
            title="JSON Feed"
          />
        </Head>
        <body>
          <Main />
          <NextScript />
        </body>
      </html>
    );
  }
}

export default Page;
<commit_msg>fix png favicon src<commit_after>import React from 'react';
import Document, { Head, Main, NextScript } from 'next/document';
import colors from '../theme';

class Page extends Document {
  render() {
    return (
      <html lang="en">
        <Head>
          <meta charSet="utf-8" />
          <meta
            name="viewport"
            content="initial-scale=1.0, width=device-width, viewport-fit=cover"
          />
          <link rel="manifest" href="/static/manifest.json" />
          <link type="text/plain" rel="author" href="/static/humans.txt" />
          <link
            rel="mask-icon"
            href="/static/images/logo/logo.svg"
            color={colors.primary}
          />
          <meta name="theme-color" content={colors.primary} />
          {/* Icons and stuff */}
          <link rel="shortcut icon" href="/static/images/logo.png" />
          <link rel="shortcut icon" href="/static/images/logo/logo.ico" />
          <link
            rel="apple-touch-icon-precomposed"
            sizes="228x228"
            href="/static/images/logo/logo-228.png"
          />
          <link
            rel="apple-touch-icon-precomposed"
            sizes="195x195"
            href="/static/images/logo/logo-195.png"
          />
          <link
            rel="apple-touch-icon-precomposed"
            sizes="152x152"
            href="/static/images/logo/logo-152.png"
          />
          <link
            rel="apple-touch-icon-precomposed"
            sizes="144x144"
            href="/static/images/logo/logo-144.png"
          />
          <link
            rel="apple-touch-icon-precomposed"
            sizes="128x128"
            href="/static/images/logo/logo-128.png"
          />
          <link
            rel="apple-touch-icon-precomposed"
            sizes="120x120"
            href="/static/images/logo/logo-120.png"
          />
          <link
            rel="apple-touch-icon-precomposed"
            sizes="96x96"
            href="/static/images/logo/logo-96.png"
          />
          <link
            rel="apple-touch-icon-precomposed"
            sizes="72x72"
            href="/static/images/logo/logo-72.png"
          />
          <link
            rel="apple-touch-icon-precomposed"
            href="/static/images/logo/logo-57.png"
          />
          <link
            rel="apple-touch-icon-precomposed"
            href="/static/images/logo/logo-32.png"
            sizes="32x32"
          />
          {/* FEEEEEEEDS */}
          <link
            rel="alternate"
            href="/atom"
            type="application/atom+xml"
            title="RSS Feed"
          />
          <link
            rel="alternate"
            href="/feed.json"
            type="application/json"
            title="JSON Feed"
          />
        </Head>
        <body>
          <Main />
          <NextScript />
        </body>
      </html>
    );
  }
}

export default Page;
<|endoftext|>


<commit_before>import React, { Fragment } from 'react';
import styled from 'styled-components';
import { gql } from 'apollo-boost';
import { Query } from 'react-apollo';
import { lighten } from 'polished';
import withData from '../lib/withData';
import Meta from '../components/Meta';
import Header from '../components/Header';
import Release from '../components/Release';

const Button = styled.button`
  all: unset;
  border: none;
  color: white;
  padding: 1rem 2rem;
  border-radius: 1.2rem;
  background: ${props => props.theme.primary};
  margin: 2rem auto;
  display: block;
  font-size: 1.6rem;
  transition: 250ms all ease-in-out;
  cursor: pointer;

  &:hover {
    background: ${props => lighten(0.2, props.theme.primary)};
  }
`;

const allReleasesQuery = gql`
  query allReleases($after: String) {
    repository(owner: "mcansh", name: "blog") {
      name
      releases(
        first: 10
        after: $after
        orderBy: { field: CREATED_AT, direction: DESC }
      ) {
        edges {
          cursor
          node {
            tag {
              name
            }
            description
            publishedAt
          }
        }
      }
    }
  }
`;

const Changelog = () => (
  <Fragment>
    <Meta />

    <Query query={allReleasesQuery}>
      {({ loading, error, fetchMore, data }) => {
        if (loading) return
Loading...
;
        if (error) return
Error :(
;
        const {
          repository: {
            releases: { edges: releases },
          },
        } = data;

        const loadMoreReleases = () => {
          const lastRelease = releases[releases.length - 1];

          fetchMore({
            variables: {
              after: lastRelease.cursor,
            },
            updateQuery: (prev, { fetchMoreResult }) => {
              if (!fetchMoreResult) return prev;

              return {
                repository: {
                  ...prev.repository,
                  releases: {
                    ...prev.repository.releases,
                    edges: [
                      ...prev.repository.releases.edges,
                      ...fetchMoreResult.repository.releases.edges,
                    ],
                  },
                },
              };
            },
          });
        };

        return (
          <Fragment>
            {releases.map(({ node: release }) => (
              <Release
                key={release.tag.name}
                version={release.tag.name}
                notes={release.description}
                date={release.publishedAt}
              />
            ))}
            <Button onClick={loadMoreReleases}>Load More</Button>
          </Fragment>
        );
      }}
    </Query>
  </Fragment>
);

export default withData(Changelog);
<commit_msg>style 'improvements'<commit_after>import React, { Fragment } from 'react';
import styled from 'styled-components';
import { gql } from 'apollo-boost';
import { Query } from 'react-apollo';
import { lighten } from 'polished';
import withData from '../lib/withData';
import Meta from '../components/Meta';
import Header from '../components/Header';
import Release from '../components/Release';

const Button = styled.button`
  all: unset;
  border: none;
  color: white;
  padding: 1rem 2rem;
  border-radius: 2rem;
  background: ${props => props.theme.primary};
  margin: 3rem auto 0;
  display: block;
  font-size: 1.6rem;
  transition: 250ms all ease-in-out;
  cursor: pointer;

  &:hover {
    background: ${props => lighten(0.2, props.theme.primary)};
    border-radius: 1.2rem;
  }
`;

const allReleasesQuery = gql`
  query allReleases($after: String) {
    repository(owner: "mcansh", name: "blog") {
      name
      releases(
        first: 10
        after: $after
        orderBy: { field: CREATED_AT, direction: DESC }
      ) {
        edges {
          cursor
          node {
            tag {
              name
            }
            description
            publishedAt
          }
        }
      }
    }
  }
`;

const Changelog = () => (
  <Fragment>
    <Meta />

    <Query query={allReleasesQuery}>
      {({ loading, error, fetchMore, data }) => {
        if (loading) return
Loading...
;
        if (error) return
Error :(
;
        const {
          repository: {
            releases: { edges: releases },
          },
        } = data;

        const loadMoreReleases = () => {
          const lastRelease = releases[releases.length - 1];

          fetchMore({
            variables: {
              after: lastRelease.cursor,
            },
            updateQuery: (prev, { fetchMoreResult }) => {
              if (!fetchMoreResult) return prev;

              return {
                repository: {
                  ...prev.repository,
                  releases: {
                    ...prev.repository.releases,
                    edges: [
                      ...prev.repository.releases.edges,
                      ...fetchMoreResult.repository.releases.edges,
                    ],
                  },
                },
              };
            },
          });
        };

        return (
          <Fragment>
            {releases.map(({ node: release }) => (
              <Release
                key={release.tag.name}
                version={release.tag.name}
                notes={release.description}
                date={release.publishedAt}
              />
            ))}
            <Button onClick={loadMoreReleases}>Load More</Button>
          </Fragment>
        );
      }}
    </Query>
  </Fragment>
);

export default withData(Changelog);
<|endoftext|>


<commit_before>function get_tmax(data) {
  var tvl = d3.max(data.vl, function(d) { return d[0]; });
  var tcc = d3.max(data.cc, function(d) { return d[0]; });
  return d3.max([tvl, tcc]);
}

function get_ymax(data) {
 return d3.max(data, function(d) { return d[1]; });
}

function update(data, id) {

 var colors = {"vl": "black", "cc": "steelblue"};

 var div_width = $('.svg-container').width();

 var margin = {top: 10, right: 80, bottom: 60, left: 80},
     width = 0.9 * div_width - margin.left - margin.right,
     height = 500 - margin.top - margin.bottom;

 var tmax = get_tmax(data);
 var vlmax = get_ymax(data.vl);
 var ccmax = get_ymax(data.cc);

 var y_vl = d3.scale.log()
      .domain([40, 1.1 * vlmax])
      .range([height, 0]);

 var y_cc = d3.scale.linear()
      .domain([0, 1.1 * ccmax])
      .range([height, 0]);

 var y = {"vl": y_vl, "cc": y_cc};

 var x = d3.scale.linear()
      .domain([0, 1.1 * tmax])
      .range([0, width]);

 var xAxis = d3.svg.axis()
     .scale(x)
     .orient("bottom");

 var xAxisTop = d3.svg.axis()
     .scale(x)
     .orient("bottom")
     .tickFormat("");

 var yAxis_vl = d3.svg.axis()
     .scale(y_vl)
     .orient("left");

 var yAxis_cc = d3.svg.axis()
     .scale(y_cc)
     .orient("right");

 var chart_ext = d3.select("."+id)
     .attr("width", width + margin.left + margin.right)
     .attr("height", height + margin.bottom + margin.top);

 var chart = chart_ext.append("g")
      .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

 chart.append("g")
      .attr("class", "d3-axis")
      .attr("transform", "translate(0," + height + ")")
      .call(xAxis)
      .append("text")
      .attr("x", width / 2)
      .attr("y", 50)
      .style("text-anchor", "middle")
      .text("Time from infection [days]");

 // Draw the x Grid lines
 chart.append("g")
     .attr("class", "grid")
     .attr("transform", "translate(0," + height + ")")
     .call(make_x_axis()
         .tickSize(-height, 0, 0)
         .tickFormat("")
     );

 chart.append("g")
      .attr("class", "d3-axis")
      .call(xAxisTop);

 var vlTextBox = chart.append("g")
      .attr("class", "d3-axis")
      .call(yAxis_vl)
      .append("g")
      .attr("class", "d3-axis-textbox")
      .attr("transform", "rotate(-90)");

 vlTextBox.append("text")
      .attr("dy", "-4.8em")
      .attr("x", -height / 2)
      .style("text-anchor", "middle")
      .text("Viral load [copies/ml]");

  vlTextBox.append("circle")
      .attr("class", "circles vlAxis")
      .attr("cy", "-5.1em")
      .attr("cx", -0.75 * height)
      .attr("r", 7)
      .style("fill", colors.vl);

 var ccTextBox = chart.append("g")
      .attr("class", "d3-axis")
      .attr("transform", "translate(" + width + " ,0)")
      .call(yAxis_cc)
      .append("g")
      .attr("class", "d3-axis-textbox")
      .attr("transform", "rotate(+90)");

 ccTextBox.append("text")
      .attr("dy", "-4em")
      .attr("x", height / 2)
      .style("text-anchor", "middle")
      .text("CD4+ counts [copies/ml]");

 ccTextBox.append("rect")
      .attr("class", "circles ccAxis")
      .attr("y", "-4.8em")
      .attr("x", 0.2 * height)
      .attr("width", 14)
      .attr("height", 14)
      .style("fill", colors.cc);

 chart.append("g")
      .attr("class", "circles VL")
      .selectAll()
      .data(data.vl)
      .enter()
      .append("circle")
      .attr("class", "circle")
      .attr("cx", function(d) { return x(d[0]); })
      .attr("cy", function(d) { return y_vl(d[1]); })
      .attr("r", 6)
      .style("fill", colors.vl)
      .on("mouseover", function(d) { moverDots("vl", d); })
      .on("mouseout", function(d) { moutDots("vl", d); });

 chart.append("g")
      .attr("class", "circles CC")
      .selectAll()
      .data(data.cc)
      .enter()
      .append("rect")
      .attr("class", "rect")
      .attr("x", function(d) { return x(d[0]) - 3; })
      .attr("y", function(d) { return y_cc(d[1]) - 3; })
      .attr("width", 12)
      .attr("height", 12)
      .style("fill", colors.cc)
      .on("mouseover", function(d) { moverDots("cc", d); })
      .on("mouseout", function(d) { moutDots("cc", d); });

 function moverDots(dtype, d) {
     chart.append("path")
         .attr("class", "data-line-" + dtype)
         .attr("d", lineFunction(data[dtype], y[dtype]))
	 .style("stroke-width", 2)
	 .style("stroke", colors[dtype])
	 .style("opacity", 0.3)
	 .style("fill", "none");
 }

 function moutDots(dtype, d) {
   chart.selectAll(".data-line-" + dtype)
        .remove();
 }

 function lineFunction(data, yscale) {
  return d3.svg.line()
            .x(function(d) { return x(d[0]); })
            .y(function(d) { return yscale(d[1]); })
            .interpolate("monotone")(data);
 }

 // function for the x grid lines
 function make_x_axis() {
     return d3.svg.axis()
         .scale(x)
         .orient("bottom");
 }

}

<commit_msg>Default lines for physio<commit_after>function get_tmax(data) {
  var tvl = d3.max(data.vl, function(d) { return d[0]; });
  var tcc = d3.max(data.cc, function(d) { return d[0]; });
  return d3.max([tvl, tcc]);
}

function get_ymax(data) {
 return d3.max(data, function(d) { return d[1]; });
}

function update(data, id) {

 var colors = {"vl": "black", "cc": "steelblue"};

 var div_width = $('.svg-container').width();

 var margin = {top: 10, right: 80, bottom: 60, left: 80},
     width = 0.9 * div_width - margin.left - margin.right,
     height = 500 - margin.top - margin.bottom;

 var tmax = get_tmax(data);
 var vlmax = get_ymax(data.vl);
 var ccmax = get_ymax(data.cc);

 var y_vl = d3.scale.log()
      .domain([40, 1.1 * vlmax])
      .range([height, 0]);

 var y_cc = d3.scale.linear()
      .domain([0, 1.1 * ccmax])
      .range([height, 0]);

 var y = {"vl": y_vl, "cc": y_cc};

 var x = d3.scale.linear()
      .domain([0, 1.1 * tmax])
      .range([0, width]);

 var xAxis = d3.svg.axis()
     .scale(x)
     .orient("bottom");

 var xAxisTop = d3.svg.axis()
     .scale(x)
     .orient("bottom")
     .tickFormat("");

 var yAxis_vl = d3.svg.axis()
     .scale(y_vl)
     .orient("left");

 var yAxis_cc = d3.svg.axis()
     .scale(y_cc)
     .orient("right");

 var chart_ext = d3.select("."+id)
     .attr("width", width + margin.left + margin.right)
     .attr("height", height + margin.bottom + margin.top);

 var chart = chart_ext.append("g")
      .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

 chart.append("g")
      .attr("class", "d3-axis")
      .attr("transform", "translate(0," + height + ")")
      .call(xAxis)
      .append("text")
      .attr("x", width / 2)
      .attr("y", 50)
      .style("text-anchor", "middle")
      .text("Time from infection [days]");

 // Draw the x Grid lines
 chart.append("g")
     .attr("class", "grid")
     .attr("transform", "translate(0," + height + ")")
     .call(make_x_axis()
         .tickSize(-height, 0, 0)
         .tickFormat("")
     );

 chart.append("g")
      .attr("class", "d3-axis")
      .call(xAxisTop);

 var vlTextBox = chart.append("g")
      .attr("class", "d3-axis")
      .call(yAxis_vl)
      .append("g")
      .attr("class", "d3-axis-textbox")
      .attr("transform", "rotate(-90)");

 vlTextBox.append("text")
      .attr("dy", "-4.8em")
      .attr("x", -height / 2)
      .style("text-anchor", "middle")
      .text("Viral load [copies/ml]");

  vlTextBox.append("circle")
      .attr("class", "circles vlAxis")
      .attr("cy", "-5.1em")
      .attr("cx", -0.75 * height)
      .attr("r", 7)
      .style("fill", colors.vl);

 var ccTextBox = chart.append("g")
      .attr("class", "d3-axis")
      .attr("transform", "translate(" + width + " ,0)")
      .call(yAxis_cc)
      .append("g")
      .attr("class", "d3-axis-textbox")
      .attr("transform", "rotate(+90)");

 ccTextBox.append("text")
      .attr("dy", "-4em")
      .attr("x", height / 2)
      .style("text-anchor", "middle")
      .text("CD4+ counts [copies/ml]");

 ccTextBox.append("rect")
      .attr("class", "circles ccAxis")
      .attr("y", "-4.8em")
      .attr("x", 0.2 * height)
      .attr("width", 14)
      .attr("height", 14)
      .style("fill", colors.cc);

 chart.append("g")
      .attr("class", "circles VL")
      .selectAll()
      .data(data.vl)
      .enter()
      .append("circle")
      .attr("class", "circle")
      .attr("cx", function(d) { return x(d[0]); })
      .attr("cy", function(d) { return y_vl(d[1]); })
      .attr("r", 6)
      .style("fill", colors.vl)
      .call(function(d) { plotLine("vl", d); });

 chart.append("g")
      .attr("class", "circles CC")
      .selectAll()
      .data(data.cc)
      .enter()
      .append("rect")
      .attr("class", "rect")
      .attr("x", function(d) { return x(d[0]) - 3; })
      .attr("y", function(d) { return y_cc(d[1]) - 3; })
      .attr("width", 12)
      .attr("height", 12)
      .style("fill", colors.cc)
      .call(function(d) { plotLine("cc", d); });

 function plotLine(dtype, d) {
     chart.append("path")
         .attr("class", "data-line-" + dtype)
         .attr("d", lineFunction(data[dtype], y[dtype]))
	 .style("stroke-width", 3)
	 .style("stroke", colors[dtype])
	 .style("opacity", 0.6)
	 .style("fill", "none");
 }

 function lineFunction(data, yscale) {
  return d3.svg.line()
            .x(function(d) { return x(d[0]); })
            .y(function(d) { return yscale(d[1]); })
            .interpolate("monotone")(data);
 }

 // function for the x grid lines
 function make_x_axis() {
     return d3.svg.axis()
         .scale(x)
         .orient("bottom");
 }

}

<|endoftext|>


<commit_before>
kff.ServiceContainer = kff.createClass(
{
	statics:
	{
		CONFIG_CONSTRUCTOR: 'construct',
		serviceNameRegex: /^[^\s#]*/
	}
},
/** @lends kff.ServiceContainer.prototype */
{
	/**
	 * Simple dependency injection (or service) container class.
	 * @constructs
	 * @param {Object} config Configuration object
	 */
	constructor: function(config, loader)
	{
		this.config = config || { parameters: {}, services: {} };
		this.services = {};
		this.cachedParams = {};
		if(loader) this.loadService = loader;
	},

	/**
	 * Returns instance of service class.
	 * @param {string} service Service name (service config to be found in config.services[service])
	 * @param {Array} argsExtend Array to overload default arguments array (optional)
	 * @returns {Object} Instance of service
	 */
	getService: function(serviceName, argsExtend)
	{
		var serviceConfig;
		if(!this.config.services[serviceName])
		{
			serviceConfig = this.getServiceConfigAnnotation(serviceName);
			if(serviceConfig) this.config.services[serviceName] = serviceConfig;
			else throw new Error('Service ' + serviceName + ' not defined');
		}
		if(this.config.services[serviceName].shared)
		{
			if(typeof this.services[serviceName] === 'undefined') this.services[serviceName] = this.createService(serviceName, argsExtend);
			return this.services[serviceName];
		}
		return this.createService(serviceName, argsExtend);
	},

	/**
	 * Checks if given serviceName exists in container declaration
	 * @param {string} serviceName Service name
	 * @returns {boolean} True if service exists, false otherwise
	 */
	hasService: function(serviceName)
	{
		if(this.config.services.hasOwnProperty(serviceName)) return true;
		else {
			var serviceConfig = this.getServiceConfigAnnotation(serviceName);
			if(serviceConfig)
			{
				this.config.services[serviceName] = serviceConfig;
				return true;
			}
		}
		return false;
	},

	/**
	 * Creates instance of service.
	 *
	 * If second argument is passed, then it will be used to overload constructor arguments.
	 * If items at the same index are both objects, then the second one will bee deep-mixed into
	 * the first one resulting in a new object (i.e. the config args won't be overwritten).
	 *
	 * @param {string} serviceName Name of service to be instantiated
	 * @param {Array} argsExtend Array to overload default arguments array (optional)
	 * @returns {Object} Instance of service
	 */
	createService: function(serviceName, argsExtend)
	{
		var serviceConfig, Ctor, Temp, service, ret, i, l, args, argsExtended, calls;

		serviceConfig = this.config.services[serviceName];

		Ctor = this.getServiceConstructor(serviceName);

		if(typeof Ctor !== 'function' || serviceConfig.type === 'function') return Ctor;

		if(serviceConfig.type !== 'factory')
		{
			Temp = function(){};
			Temp.prototype = Ctor.prototype;
			service = new Temp();
		}

		args = this.resolveParameters(serviceConfig.args || []);
		if(argsExtend && argsExtend instanceof Array)
		{
			argsExtended = [];
			for(i = 0, l = argsExtend.length; i < l; i++)
			{
				if(argsExtend[i] !== undefined)
				{
					if(kff.isPlainObject(args[i]) && kff.isPlainObject(argsExtend[i])) argsExtended[i] = kff.mixins({}, args[i], argsExtend[i]);
					else argsExtended[i] = argsExtend[i];
				}
				else argsExtended[i] = args[i];
			}
			args = argsExtended;
		}

		if(serviceConfig.type === 'factory')
		{
			service = Ctor.apply(null, args);
		}
		else
		{
			ret = Ctor.apply(service, args);
			if(Object(ret) === ret) service = ret;
		}

		calls = serviceConfig.calls;
		if(calls instanceof Array)
		{
			for(i = 0, l = calls.length; i < l; i++)
			{
				service[calls[i].method].apply(service, this.resolveParameters(calls[i].args));
			}
		}
		return service;
	},

	/**
	 * Returns constructor function for given service name.
	 * @param {string} serviceName Service name
	 * @returns {function} Constructor function for service
	 */
	getServiceConstructor: function(serviceName)
	{
		var serviceConfig, ctor, construct = kff.ServiceContainer.CONFIG_CONSTRUCTOR, type, name, serviceObject;
		serviceConfig = this.config.services[serviceName];
		if(!serviceConfig)
		{
			serviceConfig = this.getServiceConfigAnnotation(serviceName);
			if(!serviceConfig) return null;
			else this.config.services[serviceName] = serviceConfig;
		}

		if(serviceConfig.construct) construct = serviceConfig.construct;
		else construct = serviceName;

		if(!serviceConfig.hasOwnProperty('serviceObject'))
		{
			if(typeof construct === 'string')
			{
				serviceConfig['serviceObject'] = this.loadService(construct);
			}
			else serviceConfig['serviceObject'] = construct;
			if(!serviceConfig['serviceObject']) return null;
		}

		return serviceConfig['serviceObject'];
	},

	/**
	 * Returns configuration object of a service from its constructor (function).
	 * @param  {string} serviceName Name of service
	 * @return {object}             Service configuration object
	 */
	getServiceConfigAnnotation: function(serviceName)
	{
		var serviceConfig = {};
		var ctor = this.loadService(serviceName);
		if(typeof ctor === 'function')
		{
			if('service' in ctor && kff.isPlainObject(ctor.service)) serviceConfig = ctor.service;
			serviceConfig.serviceObject = ctor;
			return serviceConfig;
		}
		else if(ctor)
		{
			serviceConfig.serviceObject = ctor;
			return serviceConfig;
		}
		return null;
	},

	/**
	 * Evaluates parameter defined in container configuration.
	 *
	 * Parameter could be:
	 *
	 * - a string - see below
	 * - an Array or Object - iterates over properties and evaluates them recursively
	 *
	 * String parameters refers to parameters defined in config.parameters section
	 * If parameter is a string, it could have these special chars:
	 * '@serviceName' - resolves to instance of service
	 *
	 * @param {string|Array|Object} params Parameters to be resolved
	 * @returns {mixed} Resolved parameter value
	 */
	resolveParameters: function(params)
	{
		var ret, i, l, config;

		config = this.config;

		if(typeof params === 'string')
		{
			if(params.indexOf('@@') === 0)
			{
				params = params.slice(2);
				if(params.length === 0) ret = null;
				else ret = this.createServiceFactory(params);
			}
			else if(params.charAt(0) === '@')
			{
				params = params.slice(1);
				if(params.length === 0) ret = this;
				else ret = this.getService(params);
			}
		}
		else if(params instanceof Array)
		{
			ret = [];
			for(i = 0, l = params.length; i < l; i++)
			{
				ret[i] = this.resolveParameters(params[i]);
			}
		}
		else if(kff.isPlainObject(params))
		{
			ret = {};
			for(i in params)
			{
				if(params.hasOwnProperty(i)) ret[i] = this.resolveParameters(params[i]);
			}
		}
		else
		{
			ret = params;
		}
		return ret;
	},

	/**
	 * Registers a new service configuration
	 *
	 * @param  {Object} services Services configuration object
	 * @param  {Boolean} overwrite If service already exists, overwrite it with new config
	 */
	registerServices: function(services, overwrite)
	{
		var service;
		for(service in services)
		{
			if(!this.config.services.hasOwnProperty(service) || overwrite)
			{
				this.config.services[service] = services[service];
				this.services[service] = undefined;
			}
		}
	},

	/**
	 * Returns a service (constructor, function or another type of service)
	 * @param  {string}   serviceName Name of service
	 * @return {mixed}                Service constructor or factory or any other type of service
	 */
	loadService: function(serviceName)
	{
		if(typeof serviceName === 'string')
		{
			var match = serviceName.match(kff.ServiceContainer.serviceNameRegex);
			if(match)
			{
				serviceName = match[0];
			}
		}
		return kff.evalObjectPath(serviceName);
	},

	/**
	 * Creates a factory function for a service
	 * @param  {string} serviceName Name of the service
	 * @return {function}           Factory function that returns the service
	 */
	createServiceFactory: function(serviceName)
	{
		var container = this;
		return function()
		{
			return container.getService(serviceName);
		};
	}

});

<commit_msg>fix(kff.ServiceContainer): resolving plain object to undefined<commit_after>
kff.ServiceContainer = kff.createClass(
{
	statics:
	{
		CONFIG_CONSTRUCTOR: 'construct',
		serviceNameRegex: /^[^\s#]*/
	}
},
/** @lends kff.ServiceContainer.prototype */
{
	/**
	 * Simple dependency injection (or service) container class.
	 * @constructs
	 * @param {Object} config Configuration object
	 */
	constructor: function(config, loader)
	{
		this.config = config || { parameters: {}, services: {} };
		this.services = {};
		this.cachedParams = {};
		if(loader) this.loadService = loader;
	},

	/**
	 * Returns instance of service class.
	 * @param {string} service Service name (service config to be found in config.services[service])
	 * @param {Array} argsExtend Array to overload default arguments array (optional)
	 * @returns {Object} Instance of service
	 */
	getService: function(serviceName, argsExtend)
	{
		var serviceConfig;
		if(!this.config.services[serviceName])
		{
			serviceConfig = this.getServiceConfigAnnotation(serviceName);
			if(serviceConfig) this.config.services[serviceName] = serviceConfig;
			else throw new Error('Service ' + serviceName + ' not defined');
		}
		if(this.config.services[serviceName].shared)
		{
			if(typeof this.services[serviceName] === 'undefined') this.services[serviceName] = this.createService(serviceName, argsExtend);
			return this.services[serviceName];
		}
		return this.createService(serviceName, argsExtend);
	},

	/**
	 * Checks if given serviceName exists in container declaration
	 * @param {string} serviceName Service name
	 * @returns {boolean} True if service exists, false otherwise
	 */
	hasService: function(serviceName)
	{
		if(this.config.services.hasOwnProperty(serviceName)) return true;
		else {
			var serviceConfig = this.getServiceConfigAnnotation(serviceName);
			if(serviceConfig)
			{
				this.config.services[serviceName] = serviceConfig;
				return true;
			}
		}
		return false;
	},

	/**
	 * Creates instance of service.
	 *
	 * If second argument is passed, then it will be used to overload constructor arguments.
	 * If items at the same index are both objects, then the second one will bee deep-mixed into
	 * the first one resulting in a new object (i.e. the config args won't be overwritten).
	 *
	 * @param {string} serviceName Name of service to be instantiated
	 * @param {Array} argsExtend Array to overload default arguments array (optional)
	 * @returns {Object} Instance of service
	 */
	createService: function(serviceName, argsExtend)
	{
		var serviceConfig, Ctor, Temp, service, ret, i, l, args, argsExtended, calls;

		serviceConfig = this.config.services[serviceName];

		Ctor = this.getServiceConstructor(serviceName);

		if(typeof Ctor !== 'function' || serviceConfig.type === 'function') return Ctor;

		if(serviceConfig.type !== 'factory')
		{
			Temp = function(){};
			Temp.prototype = Ctor.prototype;
			service = new Temp();
		}

		args = this.resolveParameters(serviceConfig.args || []);
		if(argsExtend && argsExtend instanceof Array)
		{
			argsExtended = [];
			for(i = 0, l = argsExtend.length; i < l; i++)
			{
				if(argsExtend[i] !== undefined)
				{
					if(kff.isPlainObject(args[i]) && kff.isPlainObject(argsExtend[i])) argsExtended[i] = kff.mixins({}, args[i], argsExtend[i]);
					else argsExtended[i] = argsExtend[i];
				}
				else argsExtended[i] = args[i];
			}
			args = argsExtended;
		}

		if(serviceConfig.type === 'factory')
		{
			service = Ctor.apply(null, args);
		}
		else
		{
			ret = Ctor.apply(service, args);
			if(Object(ret) === ret) service = ret;
		}

		calls = serviceConfig.calls;
		if(calls instanceof Array)
		{
			for(i = 0, l = calls.length; i < l; i++)
			{
				service[calls[i].method].apply(service, this.resolveParameters(calls[i].args));
			}
		}
		return service;
	},

	/**
	 * Returns constructor function for given service name.
	 * @param {string} serviceName Service name
	 * @returns {function} Constructor function for service
	 */
	getServiceConstructor: function(serviceName)
	{
		var serviceConfig, ctor, construct = kff.ServiceContainer.CONFIG_CONSTRUCTOR, type, name, serviceObject;
		serviceConfig = this.config.services[serviceName];
		if(!serviceConfig)
		{
			serviceConfig = this.getServiceConfigAnnotation(serviceName);
			if(!serviceConfig) return null;
			else this.config.services[serviceName] = serviceConfig;
		}

		if(serviceConfig.construct) construct = serviceConfig.construct;
		else construct = serviceName;

		if(!serviceConfig.hasOwnProperty('serviceObject'))
		{
			if(typeof construct === 'string')
			{
				serviceConfig['serviceObject'] = this.loadService(construct);
			}
			else serviceConfig['serviceObject'] = construct;
			if(!serviceConfig['serviceObject']) return null;
		}

		return serviceConfig['serviceObject'];
	},

	/**
	 * Returns configuration object of a service from its constructor (function).
	 * @param  {string} serviceName Name of service
	 * @return {object}             Service configuration object
	 */
	getServiceConfigAnnotation: function(serviceName)
	{
		var serviceConfig = {};
		var ctor = this.loadService(serviceName);
		if(typeof ctor === 'function')
		{
			if('service' in ctor && kff.isPlainObject(ctor.service)) serviceConfig = ctor.service;
			serviceConfig.serviceObject = ctor;
			return serviceConfig;
		}
		else if(ctor)
		{
			serviceConfig.serviceObject = ctor;
			return serviceConfig;
		}
		return null;
	},

	/**
	 * Evaluates parameter defined in container configuration.
	 *
	 * Parameter could be:
	 *
	 * - a string - see below
	 * - an Array or Object - iterates over properties and evaluates them recursively
	 *
	 * String parameters refers to parameters defined in config.parameters section
	 * If parameter is a string, it could have these special chars:
	 * '@serviceName' - resolves to instance of service
	 *
	 * @param {string|Array|Object} params Parameters to be resolved
	 * @returns {mixed} Resolved parameter value
	 */
	resolveParameters: function(params)
	{
		var ret, i, l, config;

		config = this.config;

		if(typeof params === 'string')
		{
			if(params.indexOf('@@') === 0)
			{
				params = params.slice(2);
				if(params.length === 0) ret = null;
				else ret = this.createServiceFactory(params);
			}
			else if(params.charAt(0) === '@')
			{
				params = params.slice(1);
				if(params.length === 0) ret = this;
				else ret = this.getService(params);
			}
			else
			{
				ret = params;
			}
		}
		else if(params instanceof Array)
		{
			ret = [];
			for(i = 0, l = params.length; i < l; i++)
			{
				ret[i] = this.resolveParameters(params[i]);
			}
		}
		else if(kff.isPlainObject(params))
		{
			ret = {};
			for(i in params)
			{
				if(params.hasOwnProperty(i)) ret[i] = this.resolveParameters(params[i]);
			}
		}
		else
		{
			ret = params;
		}
		return ret;
	},

	/**
	 * Registers a new service configuration
	 *
	 * @param  {Object} services Services configuration object
	 * @param  {Boolean} overwrite If service already exists, overwrite it with new config
	 */
	registerServices: function(services, overwrite)
	{
		var service;
		for(service in services)
		{
			if(!this.config.services.hasOwnProperty(service) || overwrite)
			{
				this.config.services[service] = services[service];
				this.services[service] = undefined;
			}
		}
	},

	/**
	 * Returns a service (constructor, function or another type of service)
	 * @param  {string}   serviceName Name of service
	 * @return {mixed}                Service constructor or factory or any other type of service
	 */
	loadService: function(serviceName)
	{
		if(typeof serviceName === 'string')
		{
			var match = serviceName.match(kff.ServiceContainer.serviceNameRegex);
			if(match)
			{
				serviceName = match[0];
			}
		}
		return kff.evalObjectPath(serviceName);
	},

	/**
	 * Creates a factory function for a service
	 * @param  {string} serviceName Name of the service
	 * @return {function}           Factory function that returns the service
	 */
	createServiceFactory: function(serviceName)
	{
		var container = this;
		return function()
		{
			return container.getService(serviceName);
		};
	}

});

<|endoftext|>


<commit_before>'use strict';

angular.module('ddsApp').controller('StatsCtrl', function($scope, $http) {

    // Define margins
    var margin = {top: 20, right: 80, bottom: 30, left: 50},
        width = parseInt(d3.select("#chart").style("width")) - margin.left - margin.right,
        height = parseInt(d3.select("#chart").style("height")) - margin.top - margin.bottom;

    // Define date parser
    var parseDate = d3.timeParse("%Y-%m-%d");

    // Define scales
    var xScale = d3.scaleTime().range([0, width]);
    var yScale = d3.scaleLinear().range([height, 0]);
    var color = d3.scaleOrdinal().range(["#e41a1c", "#377eb8"]);

    // Define axes
    var xAxis = d3.axisBottom().scale(xScale);
    var yAxis = d3.axisLeft().scale(yScale);

    // Define lines
    var line = d3.line()
        .x(function(d) { return xScale(d.date); })
        .y(function(d) { return yScale(d.value); });

    // Define svg canvas
    var chart = d3.select("#chart")
        .attr("width", width + margin.left + margin.right)
        .attr("height", height + margin.top + margin.bottom);

    var svg = chart
        .append("g")
        .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

    var tooltip = svg.append("g");
    tooltip.append("g");

    var legend = tooltip.append("text")
        .attr("transform", "translate(10,10)");

    var chartDate = tooltip.append("text")
        .attr('transform', 'translate(' + width + ',10)')
        .style('text-anchor', 'end');

    $http.get('/documents/stats.json')
        .then(function(response) {
            $scope.error = (response.headers('Content-Type').match(/html/));
            if ($scope.error)
                return;

            var data = response.data;

            data.forEach(function(dataset) {
                dataset.datapoints.forEach(function(point) {
                    point.date = parseDate(point.date);
                });
            });
            color.domain(data.map(function(data) { return data.metric; }));

            var yDomain = d3.extent(data[1].datapoints, function(d) { return d.value; });
            yDomain[0] = 0;
            yDomain[1] *= 1.2;

            xScale.domain(d3.extent(data[1].datapoints, function(d) { return d.date; }));
            yScale.domain(yDomain);

            // Place the axes on the chart
            svg.append("g")
                .attr("class", "x axis")
                .attr("transform", "translate(0," + height + ")")
                .call(xAxis);

            svg.append("g")
                .attr("class", "y axis")
                .call(yAxis)
                .append("text")
                .attr("class", "label")
                .attr("y", 6)
                .attr("dy", ".71em")
                .attr("dx", ".71em")
                .style("text-anchor", "beginning")
                .text("Product Concentration");

            var metrics = svg.selectAll(".metric")
                .data(data)
                .enter().append("g")
                .attr("class", "metric");

            metrics.append("path")
                .attr("class", "line")
                .style("stroke", function(d) { return color(d.metric); })
                .attr("d", function(d) { return line(d.datapoints); });

            chart.on("mousemove", function() {
                var point = d3.mouse(svg.node());

                var date = parseDate(moment(xScale.invert(point[0])).format('YYYY-MM-DD'));
                var dateValue = date.valueOf();
                var slice = data.map(function(dataset) {
                    var idx = dataset.datapoints.findIndex(function(d) { return d.date.valueOf() === dateValue; });
                    var point = dataset.datapoints[idx] || {};
                    return {
                        metric: dataset.metric,
                        value: point.value,
                    };
                });

                _.remove(slice, function(d) { return ! _.isNumber(d.value); });
                slice.sort(function(metric) { return metric.value; });

                var nodes = tooltip
                    .select('g')
                    .selectAll('circle')
                    .data(slice);

                nodes
                    .enter()
                    .append('circle')
                    .attr('r', 0);

                nodes
                    .attr('r', function(d) { return _.isNumber(d.value) ? 5 : 0; })
                    .attr('cx', function() { return xScale(date); })
                    .attr('cy', function(d) { return yScale(d.value); })
                    .style("stroke", function(d) { return color(d.metric); })
                    .style("fill", function(d) { return color(d.metric); });

                nodes
                    .exit()
                    .remove();

                var names = {
                    visit: 'Visites',
                    simulation: 'Simulations',
                };
                var legendData = legend
                    .selectAll('tspan')
                    .data(slice);

                legendData.enter()
                    .append('tspan')
                    .attr('x', '0')
                    .attr('dy', function(d, i) { return i * 20; });

                legendData
                    .text(function(d) { return names[d.metric] + ' : ' + d.value; })
                    .style("fill", function(d) { return color(d.metric); });

                legendData
                    .exit()
                    .remove();

                var chartDateNode = chartDate
                    .selectAll('tspan')
                    .data(slice.length ? [date]: []);
                chartDateNode.enter()
                    .append('tspan');

                chartDateNode
                    .text(function(d) { return moment(d).format('dddd DD MMMM YYYY'); });

                chartDateNode
                    .exit()
                    .remove();
            });

            $scope.allStatsRetrieved = true;
        }, function() {
            $scope.error = true;
        });
});
<commit_msg>update formulation<commit_after>'use strict';

angular.module('ddsApp').controller('StatsCtrl', function($scope, $http) {

    // Define margins
    var margin = {top: 20, right: 80, bottom: 30, left: 50},
        width = parseInt(d3.select("#chart").style("width")) - margin.left - margin.right,
        height = parseInt(d3.select("#chart").style("height")) - margin.top - margin.bottom;

    // Define date parser
    var parseDate = d3.timeParse("%Y-%m-%d");

    // Define scales
    var xScale = d3.scaleTime().range([0, width]);
    var yScale = d3.scaleLinear().range([height, 0]);
    var color = d3.scaleOrdinal().range(["#e41a1c", "#377eb8"]);

    // Define axes
    var xAxis = d3.axisBottom().scale(xScale);
    var yAxis = d3.axisLeft().scale(yScale);

    // Define lines
    var line = d3.line()
        .x(function(d) { return xScale(d.date); })
        .y(function(d) { return yScale(d.value); });

    // Define svg canvas
    var chart = d3.select("#chart")
        .attr("width", width + margin.left + margin.right)
        .attr("height", height + margin.top + margin.bottom);

    var svg = chart
        .append("g")
        .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

    var tooltip = svg.append("g");
    tooltip.append("g");

    var legend = tooltip.append("text")
        .attr("transform", "translate(10,10)");

    var chartDate = tooltip.append("text")
        .attr('transform', 'translate(' + width + ',10)')
        .style('text-anchor', 'end');

    $http.get('/documents/stats.json')
        .then(function(response) {
            $scope.error = (response.headers('Content-Type').match(/html/));
            if ($scope.error)
                return;

            var data = response.data;

            data.forEach(function(dataset) {
                dataset.datapoints.forEach(function(point) {
                    point.date = parseDate(point.date);
                });
            });
            color.domain(data.map(function(data) { return data.metric; }));

            var yDomain = d3.extent(data[1].datapoints, function(d) { return d.value; });
            yDomain[0] = 0;
            yDomain[1] *= 1.2;

            xScale.domain(d3.extent(data[1].datapoints, function(d) { return d.date; }));
            yScale.domain(yDomain);

            // Place the axes on the chart
            svg.append("g")
                .attr("class", "x axis")
                .attr("transform", "translate(0," + height + ")")
                .call(xAxis);

            svg.append("g")
                .attr("class", "y axis")
                .call(yAxis)
                .append("text")
                .attr("class", "label")
                .attr("y", 6)
                .attr("dy", ".71em")
                .attr("dx", ".71em")
                .style("text-anchor", "beginning")
                .text("Product Concentration");

            var metrics = svg.selectAll(".metric")
                .data(data)
                .enter().append("g")
                .attr("class", "metric");

            metrics.append("path")
                .attr("class", "line")
                .style("stroke", function(d) { return color(d.metric); })
                .attr("d", function(d) { return line(d.datapoints); });

            chart.on("mousemove", function() {
                var point = d3.mouse(svg.node());

                var date = parseDate(moment(xScale.invert(point[0])).format('YYYY-MM-DD'));
                var dateValue = date.valueOf();
                var slice = data.map(function(dataset) {
                    var idx = dataset.datapoints.findIndex(function(d) { return d.date.valueOf() === dateValue; });
                    var point = dataset.datapoints[idx] || {};
                    return {
                        metric: dataset.metric,
                        value: point.value,
                    };
                });

                _.remove(slice, function(d) { return ! _.isNumber(d.value); });
                slice.sort(function(metric) { return metric.value; });

                var nodes = tooltip
                    .select('g')
                    .selectAll('circle')
                    .data(slice);

                nodes
                    .enter()
                    .append('circle')
                    .attr('r', 0);

                nodes
                    .attr('r', function(d) { return _.isNumber(d.value) ? 5 : 0; })
                    .attr('cx', function() { return xScale(date); })
                    .attr('cy', function(d) { return yScale(d.value); })
                    .style("stroke", function(d) { return color(d.metric); })
                    .style("fill", function(d) { return color(d.metric); });

                nodes
                    .exit()
                    .remove();

                var names = {
                    visit: 'Visites',
                    simulation: 'Simulations terminées',
                };
                var legendData = legend
                    .selectAll('tspan')
                    .data(slice);

                legendData.enter()
                    .append('tspan')
                    .attr('x', '0')
                    .attr('dy', function(d, i) { return i * 20; });

                legendData
                    .text(function(d) { return names[d.metric] + ' : ' + d.value; })
                    .style("fill", function(d) { return color(d.metric); });

                legendData
                    .exit()
                    .remove();

                var chartDateNode = chartDate
                    .selectAll('tspan')
                    .data(slice.length ? [date]: []);
                chartDateNode.enter()
                    .append('tspan');

                chartDateNode
                    .text(function(d) { return moment(d).format('dddd DD MMMM YYYY'); });

                chartDateNode
                    .exit()
                    .remove();
            });

            $scope.allStatsRetrieved = true;
        }, function() {
            $scope.error = true;
        });
});
<|endoftext|>