<commit_before>var isObject = require("is-object")
var isHook = require("vtree/is-vhook")

module.exports = applyProperties

function applyProperties(node, props, previous) {
    for (var propName in props) {
        var propValue = props[propName]

        if (propValue === undefined) {
            removeProperty(node, props, previous, propName);
        } else if (isHook(propValue)) {
            propValue.hook(node,
                propName,
                previous ? previous[propName] : undefined)
        } else {
            if (isObject(propValue)) {
                patchObject(node, props, previous, propName, propValue);
            } else if (propValue !== undefined) {
                node[propName] = propValue
            }
        }
    }
}

function removeProperty(node, props, previous, propName) {
    if (previous) {
        var previousValue = previous[propName]

        if (!isHook(previousValue)) {
            if (propName === "style") {
                for (var i in previousValue) {
                    node.style[i] = ""
                }
            } else if (typeof previousValue === "string") {
                node[propName] = ""
            } else {
                node[propName] = null
            }
        }
    }
}

function patchObject(node, props, previous, propName, propValue) {
    if(previous && isObject(previous[propName]) &&
        getPrototype(previous[propName]) !== getPrototype(propValue)) {
        node[propName] = previousValue
        return
    }

    if (!isObject(node[propName])) {
        node[propName] = {}
    }

    var replacer = propName === "style" ? "" : undefined

    for (var k in propValue) {
        var value = propValue[k]
        node[propName][k] = (value === undefined) ? replacer : value
    }
}

function getPrototype(value) {
    if (Object.getPrototypeOf) {
        return Object.getPrototypeOf(value)
    } else if (value.__proto__) {
        return value.__proto__
    } else if (value.constructor) {
        return value.constructor.prototype
    }
}
<commit_msg>support attributes<commit_after>var isObject = require("is-object")
var isHook = require("vtree/is-vhook")

module.exports = applyProperties

function applyProperties(node, props, previous) {
    for (var propName in props) {
        var propValue = props[propName]

        if (propValue === undefined) {
            removeProperty(node, props, previous, propName);
        } else if (isHook(propValue)) {
            propValue.hook(node,
                propName,
                previous ? previous[propName] : undefined)
        } else {
            if (isObject(propValue)) {
                patchObject(node, props, previous, propName, propValue);
            } else if (propValue !== undefined) {
                node[propName] = propValue
            }
        }
    }
}

function removeProperty(node, props, previous, propName) {
    if (previous) {
        var previousValue = previous[propName]

        if (!isHook(previousValue)) {
            if (propName === "attributes") {
                for (var attrName in previousValue) {
                    node.removeAttribute(attrName)
                }
            } else if (propName === "style") {
                for (var i in previousValue) {
                    node.style[i] = ""
                }
            } else if (typeof previousValue === "string") {
                node[propName] = ""
            } else {
                node[propName] = null
            }
        }
    }
}

function patchObject(node, props, previous, propName, propValue) {
    var previousValue = previous ? previous[propName] : undefined

    // Set attributes
    if (propName === "attributes") {
        for (var attrName in propValue) {
            var attrValue = propValue[attrName]

            if (attrValue === "undefined") {
                node.removeAttribute()
            } else {
                node.setAttribute(attrName, attrValue)
            }
        }

        return
    }

    if(previousValue && isObject(previousValue) &&
        getPrototype(previousValue) !== getPrototype(propValue)) {
        node[propName] = propValue
        return
    }

    if (!isObject(node[propName])) {
        node[propName] = {}
    }

    var replacer = propName === "style" ? "" : undefined

    for (var k in propValue) {
        var value = propValue[k]
        node[propName][k] = (value === undefined) ? replacer : value
    }
}

function getPrototype(value) {
    if (Object.getPrototypeOf) {
        return Object.getPrototypeOf(value)
    } else if (value.__proto__) {
        return value.__proto__
    } else if (value.constructor) {
        return value.constructor.prototype
    }
}
<|endoftext|>


<commit_before>// Karma configuration
// http://karma-runner.github.io/0.10/config/configuration-file.html

module.exports = function(config) {
  config.set({
    // base path, that will be used to resolve files and exclude
    basePath: '',

    // testing framework to use (jasmine/mocha/qunit/...)
    frameworks: ['ng-scenario'],

    // list of files / patterns to load in the browser
    files: [
      'test/e2e/**/*.js'
    ],

    // list of files / patterns to exclude
    exclude: [],

    // web server port
    port: 8080,

    // level of logging
    // possible values: LOG_DISABLE || LOG_ERROR || LOG_WARN || LOG_INFO || LOG_DEBUG
    logLevel: config.LOG_INFO,

    // enable / disable watching file and executing tests whenever any file changes
    autoWatch: true,
//    reporter: ['progress','coverage'],

//    preprocessors: {
//      'app/scripts/**/*.js':['coverage'],
//   },
//    coverageReporter: {
//      type : 'html',
//      dir: 'coverage/'
//    },

    // Start these browsers, currently available:
    // - Chrome
    // - ChromeCanary
    // - Firefox
    // - Opera
    // - Safari (only Mac)
    // - PhantomJS
    // - IE (only Windows)
    browsers: ['PhantomJS'],

    // Continuous Integration mode
    // if true, it capture browsers, run tests and exit
    singleRun: false,
    plugins: [
        'karma-jasmine',
        'karma-phantomjs-launcher',
    ]
    // Uncomment the following lines if you are using grunt's server to run the tests
    proxies: {
       '/': 'http://localhost:9000/'
     },
    // URL root prevent conflicts with the site root
     urlRoot: '_karma_'
  });
};
<commit_msg>correct karma e2e config<commit_after>// Karma configuration
// http://karma-runner.github.io/0.10/config/configuration-file.html

module.exports = function(config) {
  config.set({
    // base path, that will be used to resolve files and exclude
    basePath: '',

    // testing framework to use (jasmine/mocha/qunit/...)
    frameworks: ['ng-scenario'],

    // list of files / patterns to load in the browser
    files: [
      'test/e2e/**/*.js'
    ],

    // list of files / patterns to exclude
    exclude: [],

    // web server port
    port: 8080,

    // level of logging
    // possible values: LOG_DISABLE || LOG_ERROR || LOG_WARN || LOG_INFO || LOG_DEBUG
    logLevel: config.LOG_INFO,

    // enable / disable watching file and executing tests whenever any file changes
    autoWatch: true,
//    reporter: ['progress','coverage'],

//    preprocessors: {
//      'app/scripts/**/*.js':['coverage'],
//   },
//    coverageReporter: {
//      type : 'html',
//      dir: 'coverage/'
//    },

    // Start these browsers, currently available:
    // - Chrome
    // - ChromeCanary
    // - Firefox
    // - Opera
    // - Safari (only Mac)
    // - PhantomJS
    // - IE (only Windows)
    browsers: ['PhantomJS'],

    // Continuous Integration mode
    // if true, it capture browsers, run tests and exit
    singleRun: false,
    plugins: [
        'karma-jasmine',
        'karma-phantomjs-launcher',
    ],
    // Uncomment the following lines if you are using grunt's server to run the tests
    proxies: {
       '/': 'http://localhost:9000/'
     },
    // URL root prevent conflicts with the site root
     urlRoot: '_karma_'
  });
};
<|endoftext|>


<commit_before>window.onload = function () {

    var hexagon = new irf.Sprite({
        "texture": "hexagon.png",
        "width": 100,
        "height": 100,
        "innerWidth": 53,
        "innerHeight": 45,
        "key": {
            A: 0,
            B: 1,
            C: 2
        }
    });

    var SceneHexagon = (function() {

        function SceneHexagon(parent) {
            this.parent = parent;
            this.camera = new irf.Camera({
                projection: "normal",
                vpWidth: this.parent.params.width,
                vpHeight: this.parent.params.height
            });

            this.background = new irf.Map({
                mapFile: {
                    width: 12,
                    height: 12,
                    0: [["A"], ["A"], ["A"], ["A"], ["A"], ["A"], ["A"], ["A"], ["A"], ["A"], ["A"], ["A"]],
                    1: [["A"], ["B"], ["A"], ["A"], ["A"], ["A"], ["A"], ["A"], ["A"], ["A"], ["A"], ["A"]],
                    2: [["A"], ["B"], ["A"], ["A"], ["A"], ["A"], ["A"], ["A"], ["A"], ["A"], ["A"], ["A"]],
                    3: [["A"], ["B"], ["B"], ["A"], ["A"], ["A"], ["C"], ["A"], ["A"], ["A"], ["A"], ["A"]],
                    4: [["A"], ["A"], ["B"], ["A"], ["A"], ["A"], ["C"], ["C"], ["A"], ["A"], ["A"], ["A"]],
                    5: [["A"], ["A"], ["B"], ["A"], ["B"], ["A"], ["A"], ["A"], ["A"], ["A"], ["A"], ["A"]],
                    6: [["A"], ["A"], ["B"], ["B"], ["A"], ["B"], ["A"], ["A"], ["A"], ["A"], ["A"], ["A"]],
                    7: [["A"], ["C"], ["A"], ["A"], ["A"], ["B"], ["A"], ["C"], ["A"], ["A"], ["A"], ["A"]],
                    8: [["C"], ["C"], ["A"], ["A"], ["B"], ["B"], ["A"], ["A"], ["B"], ["B"], ["A"], ["A"]],
                    9: [["C"], ["A"], ["A"], ["A"], ["B"], ["A"], ["A"], ["B"], ["A"], ["B"], ["A"], ["A"]],
                    10: [["A"], ["A"], ["A"], ["A"], ["B"], ["B"], ["B"], ["A"], ["A"], ["B"], ["B"], ["A"]],
                    11: [["A"], ["A"], ["A"], ["A"], ["A"], ["A"], ["A"], ["A"], ["A"], ["A"], ["B"], ["A"]]
                },
                read: "literal",
                pattern: "simple",
                tilePlacement: "hexagon",
                sprite: hexagon,
                ed: this.parent.eventManager
            });
        }

        /* You need one of these two */
        SceneHexagon.prototype.update = function(delta) {};

        SceneHexagon.prototype.render = function (ctx) {
            var me = this;
            this.camera.apply(ctx, function () {
                me.background.render(ctx, me.camera);
            });
        };

        return SceneHexagon;

    })();

    var Asteroids = (function () {

        for (var key in irf.Game) {
            if (irf.Game.hasOwnProperty(key)) {
                Asteroids[key] = irf.Game[key];
            }
        }
        function ctor() {
            this.constructor = Asteroids;
        }
        ctor.prototype = irf.Game.prototype;
        Asteroids.prototype = new ctor();
        Asteroids.__super__ = irf.Game.prototype;

        function Asteroids(params) {
            Asteroids.__super__.constructor.call(this, params);
            this.eventManager = new irf.EventManager;
            this.sceneManager.setScene("SceneHexagon", this);
        }

        Asteroids.prototype.update = function (delta) {
            Asteroids.__super__.update.call(this, delta);
            this.fps = (1000 / delta).toFixed(1);
            return this.sceneManager.currentScene.update(delta);
        };

        Asteroids.prototype.render = function () {
            Asteroids.__super__.render.call(this);
            this.sceneManager.currentScene.render(this.ctx);
            return this.ctx.fillText(this.fps, this.params.width - 50, 20);
        };

        return Asteroids;

    })();

    Asteroids.addScene(SceneHexagon);

    var asteroids = new Asteroids({
        "width": 800,
        "height": 600
    });

    asteroids.eventManager.on("map.finishedLoading", function () {
        asteroids.start();
    });

};
<commit_msg>Removed the loop to copy the properties, as there is only one property (addScene)<commit_after>window.onload = function () {

    var hexagon = new irf.Sprite({
        "texture": "hexagon.png",
        "width": 100,
        "height": 100,
        "innerWidth": 53,
        "innerHeight": 45,
        "key": {
            A: 0,
            B: 1,
            C: 2
        }
    });

    var SceneHexagon = (function() {

        function SceneHexagon(parent) {
            this.parent = parent;
            this.camera = new irf.Camera({
                projection: "normal",
                vpWidth: this.parent.params.width,
                vpHeight: this.parent.params.height
            });

            this.background = new irf.Map({
                mapFile: {
                    width: 12,
                    height: 12,
                    0: [["A"], ["A"], ["A"], ["A"], ["A"], ["A"], ["A"], ["A"], ["A"], ["A"], ["A"], ["A"]],
                    1: [["A"], ["B"], ["A"], ["A"], ["A"], ["A"], ["A"], ["A"], ["A"], ["A"], ["A"], ["A"]],
                    2: [["A"], ["B"], ["A"], ["A"], ["A"], ["A"], ["A"], ["A"], ["A"], ["A"], ["A"], ["A"]],
                    3: [["A"], ["B"], ["B"], ["A"], ["A"], ["A"], ["C"], ["A"], ["A"], ["A"], ["A"], ["A"]],
                    4: [["A"], ["A"], ["B"], ["A"], ["A"], ["A"], ["C"], ["C"], ["A"], ["A"], ["A"], ["A"]],
                    5: [["A"], ["A"], ["B"], ["A"], ["B"], ["A"], ["A"], ["A"], ["A"], ["A"], ["A"], ["A"]],
                    6: [["A"], ["A"], ["B"], ["B"], ["A"], ["B"], ["A"], ["A"], ["A"], ["A"], ["A"], ["A"]],
                    7: [["A"], ["C"], ["A"], ["A"], ["A"], ["B"], ["A"], ["C"], ["A"], ["A"], ["A"], ["A"]],
                    8: [["C"], ["C"], ["A"], ["A"], ["B"], ["B"], ["A"], ["A"], ["B"], ["B"], ["A"], ["A"]],
                    9: [["C"], ["A"], ["A"], ["A"], ["B"], ["A"], ["A"], ["B"], ["A"], ["B"], ["A"], ["A"]],
                    10: [["A"], ["A"], ["A"], ["A"], ["B"], ["B"], ["B"], ["A"], ["A"], ["B"], ["B"], ["A"]],
                    11: [["A"], ["A"], ["A"], ["A"], ["A"], ["A"], ["A"], ["A"], ["A"], ["A"], ["B"], ["A"]]
                },
                read: "literal",
                pattern: "simple",
                tilePlacement: "hexagon",
                sprite: hexagon,
                ed: this.parent.eventManager
            });
        }

        /* You need one of these two */
        SceneHexagon.prototype.update = function(delta) {};

        SceneHexagon.prototype.render = function (ctx) {
            var me = this;
            this.camera.apply(ctx, function () {
                me.background.render(ctx, me.camera);
            });
        };

        return SceneHexagon;

    })();

    var Asteroids = (function () {

        Asteroids.addScene = irf.Game.addScene;
        function ctor() {
            this.constructor = Asteroids;
        }
        ctor.prototype = irf.Game.prototype;
        Asteroids.prototype = new ctor();
        Asteroids.__super__ = irf.Game.prototype;

        function Asteroids(params) {
            Asteroids.__super__.constructor.call(this, params);
            this.eventManager = new irf.EventManager;
            this.sceneManager.setScene("SceneHexagon", this);
        }

        Asteroids.prototype.update = function (delta) {
            Asteroids.__super__.update.call(this, delta);
            this.fps = (1000 / delta).toFixed(1);
            return this.sceneManager.currentScene.update(delta);
        };

        Asteroids.prototype.render = function () {
            Asteroids.__super__.render.call(this);
            this.sceneManager.currentScene.render(this.ctx);
            return this.ctx.fillText(this.fps, this.params.width - 50, 20);
        };

        return Asteroids;

    })();

    Asteroids.addScene(SceneHexagon);

    var asteroids = new Asteroids({
        "width": 800,
        "height": 600
    });

    asteroids.eventManager.on("map.finishedLoading", function () {
        asteroids.start();
    });

};
<|endoftext|>


<commit_before>
(function() {
if (!localStorage['ageCheck']) {
       localStorage['ageCheck'] = 'yes';
       checkAge();
   }
})();

function checkAge() {
  var ageVer = document.getElementById('ageVerWrap');
  ageVer.className = 'show';

  var yes = document.getElementById('confirmY');
  yes.addEventListener('click', function(){
    ageVer.className = 'hide'; //hides the ageVer section if they say they are above 21
  });

  var no = document.getElementById('confirmNot');
  no.addEventListener('click', function(){
    window.open("http://www.disney.com","_self"); //opens disney.com if they say they are not 21
  });
}
<commit_msg>linted app.js<commit_after>'use strict';

function checkAge() {
  var ageVer = document.getElementById('ageVerWrap');
  ageVer.className = 'show';

  var yes = document.getElementById('confirmY');
  yes.addEventListener('click', function(){
    ageVer.className = 'hide'; //hides the ageVer section if they say they are above 21
  });

  var no = document.getElementById('confirmNot');
  no.addEventListener('click', function(){
    window.open('http://www.disney.com', '_self'); //opens disney.com if they say they are not 21
  });
}

(function() {
if (!localStorage.ageCheck) {
       localStorage.ageCheck = 'yes';
       checkAge();
   }
})();
<|endoftext|>


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

    angular
      .module('password.recovery')
      .controller('AddMethodController', AddMethodController);

    function AddMethodController($location, countryService, dataService,
                                 dialogService, type) {
        var vm = this;

        vm.newRecoveryMethod = {
            type: type,
            value: ''
        };
        vm.selectedCountry = null;
        vm.countries = [];

        vm.addPhone = addPhone;
        vm.add = add;

        activate();

        //////////////////////////////////////////////////////////////////

        function activate() {
            vm.countries = countryService.getCountries();
            vm.selectedCountry = vm.countries[0];
        }

        function addPhone() {
            add({
                type: vm.newRecoveryMethod.type,
                value: vm.selectedCountry.prefix +
                       vm.newRecoveryMethod.value
            });
        }

        function add(newMethod) {
            dataService
              .post('method', newMethod)
              .then(added, failed)
              .finally(dialogService.close);

            dialogService.progress();
        }

        function added(response) {
            verify(response.data);
        }

        function failed(response) {
            dialogService
              .fail('Attempt to add recovery method failed.',
                response.data);
        }

        function verify(method) {
            $location.url('recovery-method/verify/' + method.id);
        }
    }
}());
<commit_msg>API calls were being made even though the form was invalid.<commit_after>(function () {
    'use strict';

    angular
      .module('password.recovery')
      .controller('AddMethodController', AddMethodController);

    function AddMethodController($location, countryService, dataService,
                                 dialogService, type) {
        var vm = this;

        vm.addMethodForm = null;
        vm.newRecoveryMethod = {
            type: type,
            value: ''
        };
        vm.selectedCountry = null;
        vm.countries = [];

        vm.addPhone = addPhone;
        vm.add = add;

        activate();

        //////////////////////////////////////////////////////////////////

        function activate() {
            vm.countries = countryService.getCountries();
            vm.selectedCountry = vm.countries[0];
        }

        function addPhone() {
            add({
                type: vm.newRecoveryMethod.type,
                value: vm.selectedCountry.prefix +
                       vm.newRecoveryMethod.value
            });
        }

        function add(newMethod) {
            if (vm.addMethodForm.$valid) {
                dataService
                  .post('method', newMethod)
                  .then(added, failed)
                  .finally(dialogService.close);

                dialogService.progress();
            }
        }

        function added(response) {
            verify(response.data);
        }

        function failed(response) {
            dialogService
              .fail('Attempt to add recovery method failed.',
                response.data);
        }

        function verify(method) {
            $location.url('recovery-method/verify/' + method.id);
        }
    }
}());
<|endoftext|>


<commit_before>import PropTypes from "prop-types";
import React, { Component } from "react";
import { Tooltip } from "reactjs-components";

import PlacementConstraintsPartial from "#SRC/js/components/PlacementConstraintsPartial";
import FormGroupHeading from "#SRC/js/components/form/FormGroupHeading";
import FormGroupHeadingContent from "#SRC/js/components/form/FormGroupHeadingContent";
import Icon from "#SRC/js/components/Icon";
import MetadataStore from "#SRC/js/stores/MetadataStore";

export default class PlacementSection extends Component {
  render() {
    const { data, onAddItem, onRemoveItem, errors } = this.props;
    const placementTooltipContent = (

        {
          "Constraints have three parts: a field name, an operator, and an optional parameter. The field can be the hostname of the agent node or any attribute of the agent node. "
        }

          More information
        .

    );

    return (

          <FormGroupHeading>
            <FormGroupHeadingContent primary={true}>
              Placement Constraints
            </FormGroupHeadingContent>
            <FormGroupHeadingContent>
              <Tooltip
                content={placementTooltipContent}
                interactive={true}
                maxWidth={300}
                wrapText={true}
              >
                <Icon color="light-grey" id="circle-question" size="mini" />
              </Tooltip>
            </FormGroupHeadingContent>
          </FormGroupHeading>

          Constraints control where apps run to allow optimization for either
          fault tolerance or locality.

        <PlacementConstraintsPartial
          data={data}
          onAddItem={onAddItem}
          onRemoveItem={onRemoveItem}
          errors={errors}
        />

    );
  }
}

PlacementSection.propTypes = {
  data: PropTypes.object,
  onAddItem: PropTypes.func,
  onRemoveItem: PropTypes.func,
  errors: PropTypes.object
};
<commit_msg>feat(PlacementSection): localize using Trans macro<commit_after>import { Trans } from "@lingui/macro";
import PropTypes from "prop-types";
import React, { Component } from "react";
import { Tooltip } from "reactjs-components";

import PlacementConstraintsPartial from "#SRC/js/components/PlacementConstraintsPartial";
import FormGroupHeading from "#SRC/js/components/form/FormGroupHeading";
import FormGroupHeadingContent from "#SRC/js/components/form/FormGroupHeadingContent";
import Icon from "#SRC/js/components/Icon";
import MetadataStore from "#SRC/js/stores/MetadataStore";

export default class PlacementSection extends Component {
  render() {
    const { data, onAddItem, onRemoveItem, errors } = this.props;
    const placementTooltipContent = (
      <Trans render="span">
        Constraints have three parts: a field name, an operator, and an optional{" "}
        parameter. The field can be the hostname of the agent node or any{" "}
        attribute of the agent node.{" "}

          More information
        .
      </Trans>
    );

    return (

          <FormGroupHeading>
            <FormGroupHeadingContent primary={true}>
              <Trans render="span">Placement Constraints</Trans>
            </FormGroupHeadingContent>
            <FormGroupHeadingContent>
              <Tooltip
                content={placementTooltipContent}
                interactive={true}
                maxWidth={300}
                wrapText={true}
              >
                <Icon color="light-grey" id="circle-question" size="mini" />
              </Tooltip>
            </FormGroupHeadingContent>
          </FormGroupHeading>

        <Trans render="p">
          Constraints control where apps run to allow optimization for either
          fault tolerance or locality.
        </Trans>
        <PlacementConstraintsPartial
          data={data}
          onAddItem={onAddItem}
          onRemoveItem={onRemoveItem}
          errors={errors}
        />

    );
  }
}

PlacementSection.propTypes = {
  data: PropTypes.object,
  onAddItem: PropTypes.func,
  onRemoveItem: PropTypes.func,
  errors: PropTypes.object
};
<|endoftext|>


<commit_before>/**
 * Module dependencies.
 */

var mongoose = require('mongoose');
var Law = mongoose.model('Law');
var commentApi = require('./comment');
var delegationApi = require('./delegation');
var tagApi = require('./tag');
var log = require('debug')('db-api:law');

/**
 * Get all laws
 *
 * @param {Function} fn callback function
 *   - 'err' error found on query or `null`
 *   - 'laws' list items found or `undefined`
 * @return {Module} `law` module
 * @api public
 */

exports.all = function all(fn) {
  log('Looking for all laws.')

  Law.find(function (err, laws) {
    if (err) {
      log('Found error %j', err);
      return fn(err);
    };

    log('Delivering laws %j', pluck(laws, 'id'));
    fn(null, laws);
  });

  return this;
};

/**
 * Creates law
 *
 * @param {Object} data to create law
 * @param {Function} fn callback function
 *   - 'err' error found on query or `null`
 *   - 'law' item created or `undefined`
 * @return {Module} `law` module
 * @api public
 */

exports.create = function create(data, fn) {
  log('Creating new law %j', data);

  // wrong using tag api within proposal's
  log('Looking for tag %s in database.', data.tag);
  tagApi.create(data.tag, function (err, tag) {
    if (err) {
      log('Found error from tag creation %j', err);
      return fn(err);
    };

    data.tag = tag;

    var law = new Law(data);

    law.save(function (err, saved) {
      if (err) {
        if (11000 == err.code) {
          log('Attempt duplication.');
          exports.searchOne(law.lawId, fn);
        } else {
          log('Found error %s', err);
          fn(err);
        }

        return;
      };

      log('Delivering law %s', saved);
      fn(null, saved);
    });
  });

  return this;
};

/**
 * Search single law from lawId
 *
 * @param {String} lawId string to search by `lawId`
 * @param {Function} fn callback function
 *   - 'err' error found while process or `null`
 *   - 'law' single law object found or `undefined`
 * @return {Module} `law` module
 * @api public
 */

exports.searchOne = function searchByLawId(lawId, fn) {
  var query = { lawId: lawId };

  log('Searching for single law matching %j', query);
  Law.findOne(query, function (err, law) {
    if (err) {
      log('Found error %s', err);
      return fn(err);
    }

    log('Delivering law %s', law.id);
    fn(null, law);
  })

  return this;
};

/**
 * Get Law form `id` string or `ObjectId`
 *
 * @param {String|ObjectId} id Law's `id`
 * @param {Function} fn callback function
 *   - 'err' error found while process or `null`
 *   - 'law' found item or `undefined`
 * @api public
 */

exports.get = function get(id, fn) {
  log('Looking for law %s', id);

  Law
  .findById(id)
  .exec(function (err, law) {
    if (err) {
      log('Found error %s', err);
      return fn(err);
    };

    log('Delivering law %s', law.id);
    fn(null, law);
  });
};

/**
 * Vote law
 *
 * @param {String} id Law `id`
 * @param {String} citizen author of the vote
 * @param {String} value `positive` or `negative` or `neutral`
 * @param {Function} fn callback function
 *   - 'err' error found while process or `null`
 *   - 'proposal' single object created or `undefined`
 * @api public
 */

exports.vote = function vote(id, citizen, value, fn) {
  log('Proceding to vote %s at law %s by citizen %s', value, id, citizen.id || citizen);

  Law.findById(id, function (err, law) {
    if (err) {
      log('Found error %s', err);
      return fn(err);
    };

    law.vote(citizen.id, value, function(err) {
      if (err) {
        log('Found error %s', err);
        return fn(err);
      };

      log('Voted %s at law %s by citizen %s', value, id, citizen.id || citizen);
      fn(null, law);
    });
  });
};

/*
 * Recount law votes and process delegations
 *
 * @param {String} id Law `id`
 * @param {Function} fn callback function
 *   - 'err' error found while process or `null`
 *   - 'proposal' single object created or `undefined`
 * @api public
 */

exports.recount = function vote(id, fn) {
  log('Proceding to recount %s', id);

  Law.findById(id, function (err, law) {
    if (err) {
      log('Found error %s', err);
      return fn(err);
    };

    if ('recount' === law.status) {
      log('Called recount but recount has already started.');
      return fn(new Error('Recount already started.'));
    };

    if ('closed' === law.status) {
      log('Called recount but law vote cast is closed.');
      return fn(new Error('Vote cast closed for law.'));
    };

    // Mark law for recount
    law.recount(function(err) {
      if (err) {
        log('Found error %s', err);
        return fn(err);
      };

      // WRONG
      delegationApi.trees(pluck(law.votes, 'author'), function(trees) {
        var nodes = trees.map(function(t) { return t.nodes() })

        nodes.forEach(function(n) {
          // node value
          var author = n.truster;
          // node parent
          var trustee = n.trustee;
          // node's branch top node
          var caster = n.caster;

          law.proxyVote(author, trustee, caster);
        });

        law.save(function(err) {
          if (err) {
            log('Found err %s', err);
            return fn(err);
          };

          fn(null, law);
        });
      });
    });
  });
};

/**
 * Direct comment to law
 *
 * @param {String} id Proposal's `id`
 * @param {Object} comment to attach
 * @param {Function} fn callback function
 *   - 'err' error found while process or `null`
 *   - 'law' single object created or `undefined`
 * @api public
 */

exports.comment = function comment(comment, fn) {
  log('Creating comment %j for law %s', comment.text, comment.reference);
  commentApi.create(comment, function (err, commentDoc) {
    if (err) {
      log('Found error %j', err);
      return fn(err);
    };

    log('Delivering comment %j', commentDoc);
    fn(null, commentDoc);
  });
};

/**
 * Get comments for law
 *
 * @param {String} id Law's `id`
 * @param {Function} fn callback function
 *   - 'err' error found while process or `null`
 *   - 'law' single object created or `undefined`
 * @api public
 */

exports.comments = function comments(id, fn) {
  log('Get comments for law %s', id);
  commentApi.getFor({
    context: 'law',
    reference: id
  }, function (err, comments) {
    if (err) {
      log('Found error %j', err);
      return fn(err);
    };

    log('Delivering comments %j', pluck(comments, 'id'));
    fn(null, comments);
  });
};

/**
 * Map array of objects by `property`
 *
 * @param {Array} source array of objects to map
 * @param {String} property to map from objects
 * @return {Array} array of listed properties
 * @api private
 */

function pluck (source, property) {
  return source.map(function(item) { return item[property]; });
};<commit_msg>[db-api:law] - Populate tag key for fetchs<commit_after>/**
 * Module dependencies.
 */

var mongoose = require('mongoose');
var Law = mongoose.model('Law');
var commentApi = require('./comment');
var delegationApi = require('./delegation');
var tagApi = require('./tag');
var log = require('debug')('db-api:law');

/**
 * Get all laws
 *
 * @param {Function} fn callback function
 *   - 'err' error found on query or `null`
 *   - 'laws' list items found or `undefined`
 * @return {Module} `law` module
 * @api public
 */

exports.all = function all(fn) {
  log('Looking for all laws.')

  Law
  .find()
  .populate('tag')
  .exec(function (err, laws) {
    if (err) {
      log('Found error %j', err);
      return fn(err);
    };

    log('Delivering laws %j', pluck(laws, 'id'));
    fn(null, laws);
  });

  return this;
};

/**
 * Creates law
 *
 * @param {Object} data to create law
 * @param {Function} fn callback function
 *   - 'err' error found on query or `null`
 *   - 'law' item created or `undefined`
 * @return {Module} `law` module
 * @api public
 */

exports.create = function create(data, fn) {
  log('Creating new law %j', data);

  // wrong using tag api within proposal's
  log('Looking for tag %s in database.', data.tag);
  tagApi.create(data.tag, function (err, tag) {
    if (err) {
      log('Found error from tag creation %j', err);
      return fn(err);
    };

    data.tag = tag;

    var law = new Law(data);

    law.save(function (err, saved) {
      if (err) {
        if (11000 == err.code) {
          log('Attempt duplication.');
          exports.searchOne(law.lawId, fn);
        } else {
          log('Found error %s', err);
          fn(err);
        }

        return;
      };

      log('Delivering law %s', saved);
      fn(null, saved);
    });
  });

  return this;
};

/**
 * Search single law from lawId
 *
 * @param {String} lawId string to search by `lawId`
 * @param {Function} fn callback function
 *   - 'err' error found while process or `null`
 *   - 'law' single law object found or `undefined`
 * @return {Module} `law` module
 * @api public
 */

exports.searchOne = function searchByLawId(lawId, fn) {
  var query = { lawId: lawId };

  log('Searching for single law matching %j', query);
  Law
  .findOne(query)
  .populate('tag')
  .exec(function (err, law) {
    if (err) {
      log('Found error %s', err);
      return fn(err);
    }

    log('Delivering law %s', law.id);
    fn(null, law);
  })

  return this;
};

/**
 * Get Law form `id` string or `ObjectId`
 *
 * @param {String|ObjectId} id Law's `id`
 * @param {Function} fn callback function
 *   - 'err' error found while process or `null`
 *   - 'law' found item or `undefined`
 * @api public
 */

exports.get = function get(id, fn) {
  log('Looking for law %s', id);

  Law
  .findById(id)
  .populate('tag')
  .exec(function (err, law) {
    if (err) {
      log('Found error %s', err);
      return fn(err);
    };

    log('Delivering law %s', law.id);
    fn(null, law);
  });
};

/**
 * Vote law
 *
 * @param {String} id Law `id`
 * @param {String} citizen author of the vote
 * @param {String} value `positive` or `negative` or `neutral`
 * @param {Function} fn callback function
 *   - 'err' error found while process or `null`
 *   - 'proposal' single object created or `undefined`
 * @api public
 */

exports.vote = function vote(id, citizen, value, fn) {
  log('Proceding to vote %s at law %s by citizen %s', value, id, citizen.id || citizen);

  Law.findById(id, function (err, law) {
    if (err) {
      log('Found error %s', err);
      return fn(err);
    };

    law.vote(citizen.id, value, function(err) {
      if (err) {
        log('Found error %s', err);
        return fn(err);
      };

      log('Voted %s at law %s by citizen %s', value, id, citizen.id || citizen);
      fn(null, law);
    });
  });
};

/*
 * Recount law votes and process delegations
 *
 * @param {String} id Law `id`
 * @param {Function} fn callback function
 *   - 'err' error found while process or `null`
 *   - 'proposal' single object created or `undefined`
 * @api public
 */

exports.recount = function vote(id, fn) {
  log('Proceding to recount %s', id);

  Law.findById(id, function (err, law) {
    if (err) {
      log('Found error %s', err);
      return fn(err);
    };

    if ('recount' === law.status) {
      log('Called recount but recount has already started.');
      return fn(new Error('Recount already started.'));
    };

    if ('closed' === law.status) {
      log('Called recount but law vote cast is closed.');
      return fn(new Error('Vote cast closed for law.'));
    };

    // Mark law for recount
    law.recount(function(err) {
      if (err) {
        log('Found error %s', err);
        return fn(err);
      };

      // WRONG
      delegationApi.trees(pluck(law.votes, 'author'), function(trees) {
        var nodes = trees.map(function(t) { return t.nodes() })

        nodes.forEach(function(n) {
          // node value
          var author = n.truster;
          // node parent
          var trustee = n.trustee;
          // node's branch top node
          var caster = n.caster;

          law.proxyVote(author, trustee, caster);
        });

        law.save(function(err) {
          if (err) {
            log('Found err %s', err);
            return fn(err);
          };

          fn(null, law);
        });
      });
    });
  });
};

/**
 * Direct comment to law
 *
 * @param {String} id Proposal's `id`
 * @param {Object} comment to attach
 * @param {Function} fn callback function
 *   - 'err' error found while process or `null`
 *   - 'law' single object created or `undefined`
 * @api public
 */

exports.comment = function comment(comment, fn) {
  log('Creating comment %j for law %s', comment.text, comment.reference);
  commentApi.create(comment, function (err, commentDoc) {
    if (err) {
      log('Found error %j', err);
      return fn(err);
    };

    log('Delivering comment %j', commentDoc);
    fn(null, commentDoc);
  });
};

/**
 * Get comments for law
 *
 * @param {String} id Law's `id`
 * @param {Function} fn callback function
 *   - 'err' error found while process or `null`
 *   - 'law' single object created or `undefined`
 * @api public
 */

exports.comments = function comments(id, fn) {
  log('Get comments for law %s', id);
  commentApi.getFor({
    context: 'law',
    reference: id
  }, function (err, comments) {
    if (err) {
      log('Found error %j', err);
      return fn(err);
    };

    log('Delivering comments %j', pluck(comments, 'id'));
    fn(null, comments);
  });
};

/**
 * Map array of objects by `property`
 *
 * @param {Array} source array of objects to map
 * @param {String} property to map from objects
 * @return {Array} array of listed properties
 * @api private
 */

function pluck (source, property) {
  return source.map(function(item) { return item[property]; });
};<|endoftext|>


<commit_before>// Karma configuration
// Generated on Thu Aug 21 2014 10:24:39 GMT+0200 (CEST)

module.exports = function(config) {
   var configuration = {

    // base path that will be used to resolve all patterns (eg. files, exclude)
    basePath: '',

    // frameworks to use
    // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
    frameworks: ['mocha', 'chai-jquery', 'jquery-1.8.3', 'sinon-chai', 'browserify'],

    plugins: [
      'karma-mocha',
      'karma-chai',
      'karma-sinon-chai',
      'karma-chrome-launcher',
      'karma-firefox-launcher',
      'karma-jquery',
      'karma-chai-jquery',
      'karma-mocha-reporter',
      'karma-bro'
    ],

    // list of files / patterns to load in the browser
    files: [
      'test/**/*.js'
    ],

    // list of files to exclude
    exclude: [
    ],

    // preprocess matching files before serving them to the browser
    // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
    preprocessors: {
      'test/**/*.js': ['browserify']
    },

    browserify:{
      debug: true
    },

    // test results reporter to use
    // possible values: 'dots', 'progress'
    // available reporters: https://npmjs.org/browse/keyword/karma-reporter
    reporters: ['mocha'],

    // web server port
    port: 9876,

    // enable / disable colors in the output (reporters and logs)
    colors: true,

    // level of logging
    // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
    logLevel: config.LOG_INFO,

    // enable / disable watching file and executing tests whenever any file changes
    autoWatch: true,

    // start these browsers
    // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
    browsers: ['Chrome', 'FirefoxNightly'],

    customLaunchers: {
      Chrome_travis_ci: {
        base: 'Chrome',
        flags: ['--no-sandbox']
      }
    },

    // Continuous Integration mode
    // if true, Karma captures browsers, runs the tests and exits
    singleRun: false
  };

  if(process.env.TRAVIS){
    configuration.browsers = ['Chrome_travis_ci'];
  } else if (process.env.BROWSER) {
    configuration.browsers = [process.env.BROWSER];
  }

   config.set(configuration);
};
<commit_msg>adds missing karma plugin<commit_after>// Karma configuration
// Generated on Thu Aug 21 2014 10:24:39 GMT+0200 (CEST)

module.exports = function(config) {
   var configuration = {

    // base path that will be used to resolve all patterns (eg. files, exclude)
    basePath: '',

    // frameworks to use
    // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
    frameworks: ['mocha', 'chai-jquery', 'jquery-1.8.3', 'sinon-chai', 'browserify'],

    plugins: [
      'karma-mocha',
      'karma-chai',
      'karma-sinon-chai',
      'karma-chrome-launcher',
      'karma-firefox-launcher',
      'karma-jquery',
      'karma-chai-jquery',
      'karma-mocha-reporter',
      'karma-bro',
      'karma-jasmine'
    ],

    // list of files / patterns to load in the browser
    files: [
      'test/**/*.js'
    ],

    // list of files to exclude
    exclude: [
    ],

    // preprocess matching files before serving them to the browser
    // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
    preprocessors: {
      'test/**/*.js': ['browserify']
    },

    browserify:{
      debug: true
    },

    // test results reporter to use
    // possible values: 'dots', 'progress'
    // available reporters: https://npmjs.org/browse/keyword/karma-reporter
    reporters: ['mocha'],

    // web server port
    port: 9876,

    // enable / disable colors in the output (reporters and logs)
    colors: true,

    // level of logging
    // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
    logLevel: config.LOG_INFO,

    // enable / disable watching file and executing tests whenever any file changes
    autoWatch: true,

    // start these browsers
    // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
    browsers: ['Chrome', 'FirefoxNightly'],

    customLaunchers: {
      Chrome_travis_ci: {
        base: 'Chrome',
        flags: ['--no-sandbox']
      }
    },

    // Continuous Integration mode
    // if true, Karma captures browsers, runs the tests and exits
    singleRun: false
  };

  if(process.env.TRAVIS){
    configuration.browsers = ['Chrome_travis_ci'];
  } else if (process.env.BROWSER) {
    configuration.browsers = [process.env.BROWSER];
  }

   config.set(configuration);
};
<|endoftext|>


<commit_before>/**
 Coupley entry point for webpack
 */

//es6 imports
import React from 'react';
import ReactDOM from 'react-dom';
//Router components
import { Router, Route, Link, hashHistory } from 'react-router';

import Header from './components/base/Header.react';
import Home from './components/Home.react';
import Login from './components/login/Login.react';
import Profile from './components/profile/profile.react';
import Register from './components/register/Register.react';
import Quiz from './components/quiz/Quiz.react';
import ActivityContainer from './components/profile/ActivityFeed/ActivityFeedContainer.react';
import About from './components/profile/About.react';
import Photos from './components/profile/visitor/Photos.react';
import ProfileVisitor from './components/profile/visitor/profile.react';
import ActivityContainerVisitor from './components/profile/visitor/ActivityFeed/ActivityFeedContainer.react';
import AboutVisitor from './components/profile/visitor/About.react';
import PhotosVisitor from './components/profile/visitor/Photos.react';
import Search from './components/search/Search.react';
import Admin from './components/admin/dashboard.react';
import AdminLogin from './components/admin/login.react';
import MainActivity from './components/activityfeed/activityMain.react';
import Threads from './components/chat/Threads.react';
import Users from './components/admin/users/userHome.react';
import Friends from './components/admin/users/friends.react';
import Enemies from './components/admin/users/enemies.react';
import Cards from './components/admin/Cards.react';
import Settings from './components/admin/settings/settings.react';
import Forgot from './components/Forgot.react';
import AdminForgot from './components/admin/AdminForgotPwd.react'
import Feedback from './components/admin/feedback/FeedbackHome.react';
import Timeline from './components/admin/feedback/timeline.react';
import ActivityFeed from './components/admin/feedback/activity.react';
import Privacy from './components/admin/feedback/privacy.react';
import ChatFeed from './components/admin/feedback/chat.react'
import OthersFeed from './components/admin/feedback/others.react'

function requireAuth(nextState, replace) {
  if(! localStorage.getItem('apitoken')) {
    replace({
      pathname: '/login',
      state: { nextPathname: nextState.location.pathname }
    })
  }
}

function requireAdminAuth(nextState, replace) {
    if(! localStorage.getItem('apitoken')) {
        replace({
            pathname: '/AdminLogin',
            state: { nextPathname: nextState.location.pathname }
        })
    }
}

function signout() {
  console.log('Sign out !');
  localStorage.removeItem('apitoken');
  localStorage.removeItem('user');
  document.location = "/#/login";
}
function AdminSignout() {
    localStorage.removeItem('apitoken');
    localStorage.removeItem('email');
    document.location = "/cp-admin#/AdminLogin";
}
ReactDOM.render((
  <Router history={hashHistory}>
    <Route path="/login" component={Home} />
    <Route path="/dashboard" component={Admin} />
    <Route path="/login" component={Login} />
      <Route path="/forgotpwd" component={Forgot} />
    <Route path="/register" component={Register} />
    <Route path="/quiz" component={Quiz} />
    <Route path="/AdminLogin" component={AdminLogin} />
      <Route path="/Adminforgotpwd" component={AdminForgot} />
    <Route path="/dashboard" component={Admin} onEnter={requireAdminAuth}>
        <Route path="/users" component={Users}>
            <Route path="friends" component={Friends} />
            <Route path="enemies" component={Enemies} />
        </Route>
        <Route path="/feedback" component={Feedback}>
            <Route path="timeline" component={Timeline} />
            <Route path="activity" component={ActivityFeed} />
            <Route path="privacy" component={Privacy} />
            <Route path="chat" component={ChatFeed} />
            <Route path="others" component={OthersFeed} />

        </Route>
        <Route path="/cards" component={Cards} />
        <Route path="/settings" component={Settings} />
    </Route>
      <Route path="/AdminSignout" onEnter={AdminSignout} />
    <Route path="/" component={Header} onEnter={requireAuth}>
      <Route path="/search" component={Search} />
      <Route path="/threads" component={Threads} />
      <Route path="activity" component={MainActivity}/>
      <Route path="profile" component={Profile} >
        <Route path="activityfeed" component={ActivityContainer} />
        <Route path="about" component={About} />
        <Route path="photos" component={Photos} />
      </Route>
      <Route path="/:username" component={ProfileVisitor} >
        <Route path="activityfeed" component={ActivityContainerVisitor} />

        <Route path="about" component={AboutVisitor} />
        <Route path="photos" component={PhotosVisitor} />
      </Route>
    </Route>
      <Route path="/signout" onEnter={signout} />
  </Router>
  ),
  document.getElementById('content')
);

<commit_msg>signout -> logout<commit_after>/**
 Coupley entry point for webpack
 */

//es6 imports
import React from 'react';
import ReactDOM from 'react-dom';
//Router components
import { Router, Route, Link, hashHistory } from 'react-router';

import Header from './components/base/Header.react';
import Home from './components/Home.react';
import Login from './components/login/Login.react';
import Profile from './components/profile/profile.react';
import Register from './components/register/Register.react';
import Quiz from './components/quiz/Quiz.react';
import ActivityContainer from './components/profile/ActivityFeed/ActivityFeedContainer.react';
import About from './components/profile/About.react';
import Photos from './components/profile/visitor/Photos.react';
import ProfileVisitor from './components/profile/visitor/profile.react';
import ActivityContainerVisitor from './components/profile/visitor/ActivityFeed/ActivityFeedContainer.react';
import AboutVisitor from './components/profile/visitor/About.react';
import PhotosVisitor from './components/profile/visitor/Photos.react';
import Search from './components/search/Search.react';
import Admin from './components/admin/dashboard.react';
import AdminLogin from './components/admin/login.react';
import MainActivity from './components/activityfeed/activityMain.react';
import Threads from './components/chat/Threads.react';
import Users from './components/admin/users/userHome.react';
import Friends from './components/admin/users/friends.react';
import Enemies from './components/admin/users/enemies.react';
import Cards from './components/admin/Cards.react';
import Settings from './components/admin/settings/settings.react';
import Forgot from './components/Forgot.react';
import AdminForgot from './components/admin/AdminForgotPwd.react'
import Feedback from './components/admin/feedback/FeedbackHome.react';
import Timeline from './components/admin/feedback/timeline.react';
import ActivityFeed from './components/admin/feedback/activity.react';
import Privacy from './components/admin/feedback/privacy.react';
import ChatFeed from './components/admin/feedback/chat.react'
import OthersFeed from './components/admin/feedback/others.react'

function requireAuth(nextState, replace) {
  if(! localStorage.getItem('apitoken')) {
    replace({
      pathname: '/login',
      state: { nextPathname: nextState.location.pathname }
    })
  }
}

function requireAdminAuth(nextState, replace) {
    if(! localStorage.getItem('apitoken')) {
        replace({
            pathname: '/AdminLogin',
            state: { nextPathname: nextState.location.pathname }
        })
    }
}

function logout() {
  console.log('Sign out !');
  localStorage.removeItem('apitoken');
  localStorage.removeItem('user');
  document.location = "/#/login";
}
function AdminSignout() {
    localStorage.removeItem('apitoken');
    localStorage.removeItem('email');
    document.location = "/cp-admin#/AdminLogin";
}
ReactDOM.render((
  <Router history={hashHistory}>
    <Route path="/login" component={Home} />
    <Route path="/logout" onEnter={logout} />
    <Route path="/dashboard" component={Admin} />
    <Route path="/login" component={Login} />
      <Route path="/forgotpwd" component={Forgot} />
    <Route path="/register" component={Register} />
    <Route path="/quiz" component={Quiz} />
    <Route path="/AdminLogin" component={AdminLogin} />
      <Route path="/Adminforgotpwd" component={AdminForgot} />
    <Route path="/dashboard" component={Admin} onEnter={requireAdminAuth}>
        <Route path="/users" component={Users}>
            <Route path="friends" component={Friends} />
            <Route path="enemies" component={Enemies} />
        </Route>
        <Route path="/feedback" component={Feedback}>
            <Route path="timeline" component={Timeline} />
            <Route path="activity" component={ActivityFeed} />
            <Route path="privacy" component={Privacy} />
            <Route path="chat" component={ChatFeed} />
            <Route path="others" component={OthersFeed} />

        </Route>
        <Route path="/cards" component={Cards} />
        <Route path="/settings" component={Settings} />
    </Route>
      <Route path="/AdminSignout" onEnter={AdminSignout} />
    <Route path="/" component={Header} onEnter={requireAuth}>
      <Route path="/search" component={Search} />
      <Route path="/threads" component={Threads} />
      <Route path="activity" component={MainActivity}/>
      <Route path="profile" component={Profile} >
        <Route path="activityfeed" component={ActivityContainer} />
        <Route path="about" component={About} />
        <Route path="photos" component={Photos} />
      </Route>
      <Route path="/:username" component={ProfileVisitor} >
        <Route path="activityfeed" component={ActivityContainerVisitor} />

        <Route path="about" component={AboutVisitor} />
        <Route path="photos" component={PhotosVisitor} />
      </Route>
    </Route>

  </Router>
  ),
  document.getElementById('content')
);

<|endoftext|>


<commit_before>import classNames from "classnames";
import { Dropdown, Tooltip } from "reactjs-components";
import React from "react";
import { routerShape, formatPattern } from "react-router";

import Icon from "#SRC/js/components/Icon";
import RouterUtil from "#SRC/js/utils/RouterUtil";

import DirectoryItem from "../../structs/DirectoryItem";
import MesosLogContainer from "../../components/MesosLogContainer";
import SearchLog from "../../components/SearchLog";
import TaskDirectory from "../../structs/TaskDirectory";
import TaskDirectoryActions from "../../events/TaskDirectoryActions";

class TaskFileViewer extends React.Component {
  constructor() {
    super(...arguments);

    this.state = { currentFile: null };
  }

  shouldComponentUpdate(nextProps, nextState) {
    const curProps = this.props;
    const curState = this.state;

    const task = curState.task;
    const nextTask = nextState.task;
    const didSlaveIdChange =
      task && nextTask && task.slave_id !== nextTask.slave_id;

    const didTaskChange = curProps.task !== nextProps.task || didSlaveIdChange;

    const directory = curProps.directory;
    const nextDirectory = nextProps.directory;
    const didDirectoryItemsChange =
      directory &&
      nextDirectory &&
      directory.getItems().length !== nextDirectory.getItems().length;

    const didDirectoryChange =
      directory !== nextDirectory || didDirectoryItemsChange;

    const didCurrentFileChange = curState.currentFile !== nextState.currentFile;

    return didTaskChange || didCurrentFileChange || didDirectoryChange;
  }

  handleViewChange(currentFile) {
    const { params, routes } = this.props;
    const path = currentFile.get("path");
    if (path === this.getSelectedFile().get("path")) {
      // File path didn't change, let's not try to update path
      return;
    }

    let routePath = RouterUtil.reconstructPathFromRoutes(routes);
    const hasFilePathParam = routePath.endsWith(":filePath");
    if (!hasFilePathParam && routePath.endsWith("/")) {
      routePath += ":filePath";
    }
    if (!hasFilePathParam && !routePath.endsWith("/")) {
      routePath += "/:filePath";
    }
    this.context.router.push(
      formatPattern(
        routePath,
        Object.assign({}, params, { filePath: encodeURIComponent(path) })
      )
    );
  }

  getLogFiles() {
    const { directory, limitLogFiles } = this.props;
    const logViews = [];
    if (!directory) {
      return logViews;
    }

    const limitLogFilesIsNotEmpty = limitLogFiles.length > 0;

    directory.getItems().forEach(item => {
      const excludeFile =
        limitLogFilesIsNotEmpty && !limitLogFiles.includes(item.getName());

      if (!item.isLogFile() || excludeFile) {
        return;
      }

      logViews.push(item);
    });

    return logViews;
  }

  getLogSelectionAsButtons(logFiles, selectedName) {
    const buttons = logFiles.map((item, index) => {
      const name = item.getName();

      const classes = classNames({
        "button button-stroke": true,
        active: name === selectedName
      });

      return (
        <button
          className={classes}
          key={index}
          onClick={this.handleViewChange.bind(this, item)}
        >
          {item.getDisplayName()}
        </button>
      );
    });

    return (

        {buttons}

    );
  }

  onItemSelection(obj) {
    this.handleViewChange(obj.value);
  }

  getItemHtml(displayName) {
    return {displayName};
  }

  getDropdownItems(logFiles) {
    return logFiles.map(function(item) {
      const displayName = item.getDisplayName();
      const selectedHtml = this.getItemHtml(displayName);
      const dropdownHtml = {selectedHtml};

      return {
        id: item.getName(),
        name: displayName,
        html: dropdownHtml,
        selectedHtml,
        value: item
      };
    }, this);
  }

  getSelectedFile() {
    const { props, state } = this;
    const file = state.currentFile;
    const paramsPath = decodeURIComponent(props.params.filePath);
    if (!file && paramsPath !== "undefined") {
      return new DirectoryItem({ path: paramsPath });
    }

    const files = this.getLogFiles();

    return (
      files.find(function(file) {
        return file.getName() === "stdout";
      }) || files[0]
    );
  }

  getSelectionComponent(selectedLogFile) {
    const selectedName = selectedLogFile && selectedLogFile.getName();
    const logFiles = this.getLogFiles();
    if (logFiles.length < 3) {
      return this.getLogSelectionAsButtons(logFiles, selectedName);
    }

    return (
      <Dropdown
        key="dropdown"
        buttonClassName="button dropdown-toggle"
        dropdownMenuClassName="dropdown-menu"
        dropdownMenuListClassName="dropdown-menu-list"
        dropdownMenuListItemClassName="clickable"
        initialID={selectedName}
        items={this.getDropdownItems(logFiles)}
        onItemSelection={this.onItemSelection.bind(this)}
        scrollContainer=".gm-scroll-view"
        scrollContainerParentSelector=".gm-prevented"
        transition={true}
        transitionName="dropdown-menu"
        wrapperClassName="dropdown form-group"
      />
    );
  }

  getActions(selectedLogFile, filePath) {
    const { task } = this.props;

    return [
      this.getSelectionComponent(selectedLogFile),
      <Tooltip key="tooltip" anchor="end" content={"Download log file"}>

          <Icon id="download" size="mini" />

      </Tooltip>
    ];
  }

  render() {
    const { task } = this.props;

    // Only try to get path if file exists
    const selectedLogFile = this.getSelectedFile();
    const selectedName = selectedLogFile && selectedLogFile.getName();
    const filePath = selectedLogFile && selectedLogFile.get("path");

    return (
      <SearchLog actions={this.getActions(selectedLogFile, filePath)}>
        <MesosLogContainer
          filePath={filePath}
          task={task}
          logName={selectedName}
        />
      </SearchLog>
    );
  }
}

TaskFileViewer.contextTypes = {
  router: routerShape
};

TaskFileViewer.defaultProps = {
  limitLogFiles: [],
  task: {}
};

TaskFileViewer.propTypes = {
  directory: React.PropTypes.instanceOf(TaskDirectory),
  limitLogFiles: React.PropTypes.arrayOf(React.PropTypes.string),
  selectedLogFile: React.PropTypes.object,
  task: React.PropTypes.object
};

module.exports = TaskFileViewer;
<commit_msg>feat(DCOS-12849): Defaults services logs to stderr<commit_after>import classNames from "classnames";
import { Dropdown, Tooltip } from "reactjs-components";
import React from "react";
import { routerShape, formatPattern } from "react-router";

import Icon from "#SRC/js/components/Icon";
import RouterUtil from "#SRC/js/utils/RouterUtil";

import DirectoryItem from "../../structs/DirectoryItem";
import MesosLogContainer from "../../components/MesosLogContainer";
import SearchLog from "../../components/SearchLog";
import TaskDirectory from "../../structs/TaskDirectory";
import TaskDirectoryActions from "../../events/TaskDirectoryActions";

class TaskFileViewer extends React.Component {
  constructor() {
    super(...arguments);

    this.state = { currentFile: null };
  }

  shouldComponentUpdate(nextProps, nextState) {
    const curProps = this.props;
    const curState = this.state;

    const task = curState.task;
    const nextTask = nextState.task;
    const didSlaveIdChange =
      task && nextTask && task.slave_id !== nextTask.slave_id;

    const didTaskChange = curProps.task !== nextProps.task || didSlaveIdChange;

    const directory = curProps.directory;
    const nextDirectory = nextProps.directory;
    const didDirectoryItemsChange =
      directory &&
      nextDirectory &&
      directory.getItems().length !== nextDirectory.getItems().length;

    const didDirectoryChange =
      directory !== nextDirectory || didDirectoryItemsChange;

    const didCurrentFileChange = curState.currentFile !== nextState.currentFile;

    return didTaskChange || didCurrentFileChange || didDirectoryChange;
  }

  handleViewChange(currentFile) {
    const { params, routes } = this.props;
    const path = currentFile.get("path");
    if (path === this.getSelectedFile().get("path")) {
      // File path didn't change, let's not try to update path
      return;
    }

    let routePath = RouterUtil.reconstructPathFromRoutes(routes);
    const hasFilePathParam = routePath.endsWith(":filePath");
    if (!hasFilePathParam && routePath.endsWith("/")) {
      routePath += ":filePath";
    }
    if (!hasFilePathParam && !routePath.endsWith("/")) {
      routePath += "/:filePath";
    }
    this.context.router.push(
      formatPattern(
        routePath,
        Object.assign({}, params, { filePath: encodeURIComponent(path) })
      )
    );
  }

  getLogFiles() {
    const { directory, limitLogFiles } = this.props;
    const logViews = [];
    if (!directory) {
      return logViews;
    }

    const limitLogFilesIsNotEmpty = limitLogFiles.length > 0;

    directory.getItems().forEach(item => {
      const excludeFile =
        limitLogFilesIsNotEmpty && !limitLogFiles.includes(item.getName());

      if (!item.isLogFile() || excludeFile) {
        return;
      }

      logViews.push(item);
    });

    return logViews;
  }

  getLogSelectionAsButtons(logFiles, selectedName) {
    const buttons = logFiles.map((item, index) => {
      const name = item.getName();

      const classes = classNames({
        "button button-stroke": true,
        active: name === selectedName
      });

      return (
        <button
          className={classes}
          key={index}
          onClick={this.handleViewChange.bind(this, item)}
        >
          {item.getDisplayName()}
        </button>
      );
    });

    return (

        {buttons}

    );
  }

  onItemSelection(obj) {
    this.handleViewChange(obj.value);
  }

  getItemHtml(displayName) {
    return {displayName};
  }

  getDropdownItems(logFiles) {
    return logFiles.map(function(item) {
      const displayName = item.getDisplayName();
      const selectedHtml = this.getItemHtml(displayName);
      const dropdownHtml = {selectedHtml};

      return {
        id: item.getName(),
        name: displayName,
        html: dropdownHtml,
        selectedHtml,
        value: item
      };
    }, this);
  }

  getSelectedFile() {
    const { props, state } = this;
    const file = state.currentFile;
    const paramsPath = decodeURIComponent(props.params.filePath);
    if (!file && paramsPath !== "undefined") {
      return new DirectoryItem({ path: paramsPath });
    }

    const files = this.getLogFiles();

    return (
      files.find(function(file) {
        return file.getName() === "stderr";
      }) || files[0]
    );
  }

  getSelectionComponent(selectedLogFile) {
    const selectedName = selectedLogFile && selectedLogFile.getName();
    const logFiles = this.getLogFiles();
    if (logFiles.length < 3) {
      return this.getLogSelectionAsButtons(logFiles, selectedName);
    }

    return (
      <Dropdown
        key="dropdown"
        buttonClassName="button dropdown-toggle"
        dropdownMenuClassName="dropdown-menu"
        dropdownMenuListClassName="dropdown-menu-list"
        dropdownMenuListItemClassName="clickable"
        initialID={selectedName}
        items={this.getDropdownItems(logFiles)}
        onItemSelection={this.onItemSelection.bind(this)}
        scrollContainer=".gm-scroll-view"
        scrollContainerParentSelector=".gm-prevented"
        transition={true}
        transitionName="dropdown-menu"
        wrapperClassName="dropdown form-group"
      />
    );
  }

  getActions(selectedLogFile, filePath) {
    const { task } = this.props;

    return [
      this.getSelectionComponent(selectedLogFile),
      <Tooltip key="tooltip" anchor="end" content={"Download log file"}>

          <Icon id="download" size="mini" />

      </Tooltip>
    ];
  }

  render() {
    const { task } = this.props;

    // Only try to get path if file exists
    const selectedLogFile = this.getSelectedFile();
    const selectedName = selectedLogFile && selectedLogFile.getName();
    const filePath = selectedLogFile && selectedLogFile.get("path");

    return (
      <SearchLog actions={this.getActions(selectedLogFile, filePath)}>
        <MesosLogContainer
          filePath={filePath}
          task={task}
          logName={selectedName}
        />
      </SearchLog>
    );
  }
}

TaskFileViewer.contextTypes = {
  router: routerShape
};

TaskFileViewer.defaultProps = {
  limitLogFiles: [],
  task: {}
};

TaskFileViewer.propTypes = {
  directory: React.PropTypes.instanceOf(TaskDirectory),
  limitLogFiles: React.PropTypes.arrayOf(React.PropTypes.string),
  selectedLogFile: React.PropTypes.object,
  task: React.PropTypes.object
};

module.exports = TaskFileViewer;
<|endoftext|>


<commit_before>define(['underscore', 'nusmods'], function (_, NUSMods) {
  'use strict';

  String.prototype.insert = function (index, string) {
    if (index > 0) {
      return this.substring(0, index) + string + this.substring(index, this.length);
    } else {
      return string + this;
    }
  };

  var re = /[a-zA-Z]{2,3}[\d]{4}[a-zA-Z]{0,2}/g;
  var allModuleCodes;

  return {
    getModuleFromString: function (string) {
      var match = re.exec(string);
      return match ? match[0] : '';
    },
    matchModules: function (desc) {
      var matchPos = [];
      if (!desc) { return matchPos; }
      var match = re.exec(desc);
      while (match) {
        matchPos.push({module: match[0], index: match.index, length: match[0].length});
        match = re.exec(desc);
      }
      return matchPos;
    },
    linkifyModules: function (desc) {
      if (!allModuleCodes) {
        allModuleCodes = _.keys(NUSMods.getAllModules());
      }

      var matchedModules = this.matchModules(desc);
      if (desc && matchedModules.length) {
        for (var i = matchedModules.length - 1; i >= 0; i--) {
          if (allModuleCodes.indexOf(matchedModules[i].module) > -1) {
            var startingIndex = matchedModules[i].index;
            var length = matchedModules[i].length;
            var endingIndex = startingIndex + length;
            desc = desc.insert(endingIndex, '');
            desc = desc.insert(startingIndex, '');
          }
        }
      }
      return desc;
    }
  };
});
<commit_msg>Use object lookup rather than array lookup for modules<commit_after>define(['underscore', 'nusmods'], function (_, NUSMods) {
  'use strict';

  String.prototype.insert = function (index, string) {
    if (index > 0) {
      return this.substring(0, index) + string + this.substring(index, this.length);
    } else {
      return string + this;
    }
  };

  var re = /[a-zA-Z]{2,3}[\d]{4}[a-zA-Z]{0,2}/g;
  var allModuleCodes;

  return {
    getModuleFromString: function (string) {
      var match = re.exec(string);
      return match ? match[0] : '';
    },
    matchModules: function (desc) {
      var matchPos = [];
      if (!desc) { return matchPos; }
      var match = re.exec(desc);
      while (match) {
        matchPos.push({module: match[0], index: match.index, length: match[0].length});
        match = re.exec(desc);
      }
      return matchPos;
    },
    linkifyModules: function (desc) {
      if (!allModuleCodes) {
        allModuleCodes = NUSMods.getAllModules();
      }

      var matchedModules = this.matchModules(desc);
      if (desc && matchedModules.length) {
        for (var i = matchedModules.length - 1; i >= 0; i--) {
          if (allModuleCodes[matchedModules[i].module]) {
            var startingIndex = matchedModules[i].index;
            var length = matchedModules[i].length;
            var endingIndex = startingIndex + length;
            desc = desc.insert(endingIndex, '');
            desc = desc.insert(startingIndex, '');
          }
        }
      }
      return desc;
    }
  };
});
<|endoftext|>


<commit_before>/**
 * The mongodb module implements all of the operations needed to interface our cms with mongo.
 *
 * @returns {{}}
 */
module.exports = (function(){
    'use strict';

    var db = {},
        config = require('../config'),
        event = require('../event'),
        Strings = require('../strings'),
        strings = new Strings('en'),
        createError = require('../utils/error'),
        logger = require('../utils/logger'),
        mongoose = require('mongoose'),
        url =  config.db.host,
        options = {
            user: config.db.username,
            pass: config.db.password
        };

    db.tokens = require('./mongodb/tokens');
    db.users = require('./mongodb/users');
    db.contentTypes = require('./mongodb/contentTypes');
    db.nodes = require('./mongodb/nodes');
    db.content = require('./mongodb/content');

    mongoose.connect(url, options);

    if(config.db.debug){
        mongoose.set('debug', true);
    }

    // When successfully connected
    mongoose.connection.on('connected', function () {
        logger.info(strings.group('notice').db_connected);
        event.emit('start', { system: 'db' } );
    });

    // If the connection throws an error
    mongoose.connection.on('error',function (err) {
        logger.error(strings.group('errors').db_connection_error, err);
        event.emit('error', { system: 'db' } , createError(500, err) );
    });

    // When the connection is disconnected
    mongoose.connection.on('disconnected', function () {
        logger.info(strings.group('notice').db_disconnected);
        event.emit('stop', { system: 'db' } );
    });

    // If the Node process ends, close the Mongoose connection
    process.on('SIGINT', function() {
        mongoose.connection.close(function () {
            logger.info(strings.group('notice').db_disconnected);
            process.exit(0);
        });
    });

    db.mongoose = mongoose;
    return db;

})();
<commit_msg>MOved loading type cache to when the db is loaded.<commit_after>/**
 * The mongodb module implements all of the operations needed to interface our cms with mongo.
 *
 * @returns {{}}
 */
module.exports = (function(){
    'use strict';
    var db = {},
        config = require('../config'),
        event = require('../event'),
        Strings = require('../strings'),
        strings = new Strings('en'),
        createError = require('../utils/error'),
        logger = require('../utils/logger'),
        mongoose = require('mongoose'),
        url =  config.db.host,
        options = {
            user: config.db.username,
            pass: config.db.password
        };

    db.tokens = require('./mongodb/tokens');
    db.users = require('./mongodb/users');
    db.contentTypes = require('./mongodb/contentTypes');
    db.nodes = require('./mongodb/nodes');
    db.content = require('./mongodb/content');

    mongoose.connect(url, options);

    if(config.db.debug){
        mongoose.set('debug', true);
    }

    // When successfully connected
    mongoose.connection.on('connected', function () {
        require('../utils/typeCache');
        logger.info(strings.group('notice').db_connected);
        event.emit('start', { system: 'db' } );
    });

    // If the connection throws an error
    mongoose.connection.on('error',function (err) {
        logger.error(strings.group('errors').db_connection_error, err);
        event.emit('error', { system: 'db' } , createError(500, err) );
    });

    // When the connection is disconnected
    mongoose.connection.on('disconnected', function () {
        logger.info(strings.group('notice').db_disconnected);
        event.emit('stop', { system: 'db' } );
    });

    // If the Node process ends, close the Mongoose connection
    process.on('SIGINT', function() {
        mongoose.connection.close(function () {
            logger.info(strings.group('notice').db_disconnected);
            process.exit(0);
        });
    });

    db.mongoose = mongoose;
    return db;

})();
<|endoftext|>


<commit_before>/**
 * A cluster that contains annotations.
 *
 * @param {MarkerClusterer} markerClusterer The markerclusterer that this
 *     cluster is associated with.
 * @constructor
 * @ignore
 */
function AreaCluster(isAverageCenter, padding = 0) {
  this.isAverageCenter = isAverageCenter;
  this.center = null;
  this.annotations = new Set();
  this.bounds = null;

  this.minX = 0;
  this.maxX = 0;
  this.minY = 0;
  this.maxY = 0;

  this.padding = padding;
}

/**
 * Add an annotation to the cluster.
 *
 * @param {google.maps.Marker} marker The marker to add.
 * @return {boolean} True if the marker was added.
 */
AreaCluster.prototype.add = function add(annotation) {
  if (this.annotations.has(annotation)) return false;

  const [cX, cY] = annotation.getViewPositionCenter();

  if (!this.center) {
    this.center = [cX, cY];
  }

  const l = this.annotations.size;

  if (this.isAverageCenter) {
    const x = ((this.center[0] * l) + cX) / (l + 1);
    const y = ((this.center[1] * l) + cY) / (l + 1);
    this.center = [x, y];
  }

  annotation.isAdded = true;
  this.annotations.add(annotation);

  this.updateBounds(annotation);

  return true;
};

/**
 * Returns the bounds of the cluster.
 *
 * @return {google.maps.LatLngBounds} the cluster bounds.
 */
AreaCluster.prototype.updateBounds = function updateBounds(annotation) {
  this.minX = Math.min(this.minX, annotation.minX - this.padding);
  this.maxX = Math.max(this.maxX, annotation.maxX + this.padding);
  this.minY = Math.min(this.minY, annotation.minY - this.padding);
  this.maxY = Math.max(this.maxY, annotation.maxY + this.padding);
};

/**
 * Removes the cluster
 */
AreaCluster.prototype.remove = function remove() {
  this.annotations = new Set();
  delete this.annotations;
};

/**
 * Returns the center of the cluster.
 *
 * @return {number} The cluster center.
 */
AreaCluster.prototype.getSize = function getSize() {
  return this.annotations.size;
};

/**
 * Returns the center of the cluster.
 *
 * @return {google.maps.LatLng} The cluster center.
 */
AreaCluster.prototype.getCenter = function getCenter() {
  return this.center;
};

/**
 * Determines if a annotation lies in the clusters bounds.
 *
 * @param {google.maps.Marker} annotation The annotation to check.
 * @return {boolean} True if the annotation lies in the bounds.
 */
AreaCluster.prototype.isWithin = function isWithin(annotation) {
  const [mMinX, mMaxX, mMinY, mMaxY] = annotation.getViewPosition();
  return (
    mMinX < this.maxX &&
    mMaxX > this.minX &&
    mMinY < this.maxY &&
    mMaxY > this.minY
  );
};

export default AreaCluster;
<commit_msg>Clean semantics. Fix padded bounds calculation. Add size prop. Fix broken min bound position.<commit_after>import { KeySet } from './';

const rndHex = () => Math.floor((1 + Math.random()) * 0x10000000).toString(16);

/**
 * A cluster that contains annotations.
 *
 * @param {MarkerClusterer} markerClusterer The markerclusterer that this
 *     cluster is associated with.
 * @constructor
 * @ignore
 */
function AreaCluster(isAverageCenter = true, padding = 0) {
  this.id = rndHex();
  this.isAverageCenter = isAverageCenter;
  this.center = null;
  this.members = new KeySet('id');
  this.bounds = null;

  this.minX = Infinity;
  this.maxX = 0;
  this.minY = Infinity;
  this.maxY = 0;

  // Usually this is the grid size of the clusterer
  this.padding = padding;
}

/* ------------------------------- Properties ------------------------------- */

function getSize() {
  return this.members.size;
}

Object.defineProperty(AreaCluster.prototype, 'size', { get: getSize });

/* --------------------------------- Methods -------------------------------- */

/**
 * Add an annotation to the cluster.
 *
 * @param {google.maps.Marker} marker The marker to add.
 * @return {boolean} True if the marker was added.
 */
AreaCluster.prototype.add = function add(annotation) {
  if (this.members.has(annotation)) return false;

  const [cX, cY] = annotation.getViewPositionCenter();

  if (!this.center) {
    this.center = [cX, cY];
  }

  const l = this.members.size;

  if (this.isAverageCenter) {
    const x = ((this.center[0] * l) + cX) / (l + 1);
    const y = ((this.center[1] * l) + cY) / (l + 1);
    this.center = [x, y];
  }

  annotation.isAdded = true;
  this.members.add(annotation);

  this.updateBounds(annotation);

  return true;
};

AreaCluster.prototype.getAvgDataProjPos = function getAvgDataProjPos() {
  return [
    this.members.reduce((sum, member) => sum + member.minXDataProj, 0),
    this.members.reduce((sum, member) => sum + member.maxXDataProj, 0),
    this.members.reduce((sum, member) => sum + member.minYDataProj, 0),
    this.members.reduce((sum, member) => sum + member.maxYDataProj, 0),
  ];
};

/**
 * Returns the bounds of the cluster.
 *
 * @return {google.maps.LatLngBounds} the cluster bounds.
 */
AreaCluster.prototype.updateBounds = function updateBounds(area) {
  this.minX = Math.min(this.minX, area.minX);
  this.maxX = Math.max(this.maxX, area.maxX);
  this.minY = Math.min(this.minY, area.minY);
  this.maxY = Math.max(this.maxY, area.maxY);
};

/**
 * Removes the cluster
 */
AreaCluster.prototype.remove = function remove() {
  this.members = new KeySet('id');
};

/**
 * Returns the center of the cluster.
 *
 * @return {google.maps.LatLng} The cluster center.
 */
AreaCluster.prototype.getCenter = function getCenter() {
  return this.center;
};

/**
 * Determines if an element lies in the clusters bounds.
 *
 * @param {google.maps.Marker} element The element to check.
 * @return {boolean} True if the element lies in the bounds.
 */
AreaCluster.prototype.isWithin = function isWithin(element, isExtended = false) {
  const [eMinX, eMaxX, eMinY, eMaxY] = element.getViewPosition();
  const padding = isExtended ? this.padding : 0;
  return (
    eMinX < this.maxX + padding &&
    eMaxX > this.minX - padding &&
    eMinY < this.maxY + padding &&
    eMaxY > this.minY - padding
  );
};

export default AreaCluster;
<|endoftext|>


<commit_before>"use strict";

var o = Object.prototype;
var getClass = require("./get-class");
var identical = require("./identical");
var isArguments = require("./is-arguments");
var isDate = require("./is-date");
var isElement = require("./is-element");
var isNaN = require("./is-nan");
var isObject = require("./is-object");
var isSet = require("./is-set");
var isSubset = require("./is-subset");

var indexOf = Array.prototype.indexOf;

/**
 * @name samsam.deepEqual
 * @param Object first
 * @param Object second
 *
 * Deep equal comparison. Two values are "deep equal" if:
 *
 *   - They are equal, according to samsam.identical
 *   - They are both date objects representing the same time
 *   - They are both arrays containing elements that are all deepEqual
 *   - They are objects with the same set of properties, and each property
 *     in ``first`` is deepEqual to the corresponding property in ``second``
 *
 * Supports cyclic objects.
 */
function deepEqualCyclic(first, second) {
    // used for cyclic comparison
    // contain already visited objects
    var objects1 = [];
    var objects2 = [];
    // contain pathes (position in the object structure)
    // of the already visited objects
    // indexes same as in objects arrays
    var paths1 = [];
    var paths2 = [];
    // contains combinations of already compared objects
    // in the manner: { "$1['ref']$2['ref']": true }
    var compared = {};

    // does the recursion for the deep equal check
    return (function deepEqual(obj1, obj2, path1, path2) {
        var type1 = typeof obj1;
        var type2 = typeof obj2;

        // == null also matches undefined
        if (
            obj1 === obj2 ||
            isNaN(obj1) ||
            isNaN(obj2) ||
            obj1 == null ||
            obj2 == null ||
            type1 !== "object" ||
            type2 !== "object"
        ) {
            return identical(obj1, obj2);
        }

        // Elements are only equal if identical(expected, actual)
        if (isElement(obj1) || isElement(obj2)) {
            return false;
        }

        var isDate1 = isDate(obj1);
        var isDate2 = isDate(obj2);
        if (isDate1 || isDate2) {
            if (!isDate1 || !isDate2 || obj1.getTime() !== obj2.getTime()) {
                return false;
            }
        }

        if (obj1 instanceof RegExp && obj2 instanceof RegExp) {
            if (obj1.toString() !== obj2.toString()) {
                return false;
            }
        }

        if (obj1 instanceof Error && obj2 instanceof Error) {
            if (obj1.stack !== obj2.stack) {
                return false;
            }
        }

        var class1 = getClass(obj1);
        var class2 = getClass(obj2);
        var keys1 = Object.keys(obj1);
        var keys2 = Object.keys(obj2);

        if (isArguments(obj1) || isArguments(obj2)) {
            if (obj1.length !== obj2.length) {
                return false;
            }
        } else {
            if (
                type1 !== type2 ||
                class1 !== class2 ||
                keys1.length !== keys2.length
            ) {
                return false;
            }
        }

        if (isSet(obj1) || isSet(obj2)) {
            if (!isSet(obj1) || !isSet(obj2) || obj1.size !== obj2.size) {
                return false;
            }

            return isSubset(obj1, obj2, deepEqual);
        }

        return keys1.every(function(key) {
            if (!o.hasOwnProperty.call(obj2, key)) {
                return false;
            }

            var value1 = obj1[key];
            var value2 = obj2[key];
            var isObject1 = isObject(value1);
            var isObject2 = isObject(value2);
            // determines, if the objects were already visited
            // (it's faster to check for isObject first, than to
            // get -1 from getIndex for non objects)
            var index1 = isObject(value1) ? indexOf.call(objects1, value1) : -1;
            var index2 = isObject(value2) ? indexOf.call(objects2, value2) : -1;
            // determines the new paths of the objects
            // - for non cyclic objects the current path will be extended
            //   by current property name
            // - for cyclic objects the stored path is taken
            var newPath1 =
                index1 !== -1
                    ? paths1[index1]
                    : path1 + "[" + JSON.stringify(key) + "]";
            var newPath2 =
                index2 !== -1
                    ? paths2[index2]
                    : path2 + "[" + JSON.stringify(key) + "]";

            // stop recursion if current objects are already compared
            if (compared[newPath1 + newPath2]) {
                return true;
            }

            // remember the current objects and their paths
            if (index1 === -1 && isObject1) {
                objects1.push(value1);
                paths1.push(newPath1);
            }
            if (index2 === -1 && isObject2) {
                objects2.push(value2);
                paths2.push(newPath2);
            }

            // remember that the current objects are already compared
            if (isObject1 && isObject2) {
                compared[newPath1 + newPath2] = true;
            }

            // End of cyclic logic

            // neither value1 nor value2 is a cycle
            // continue with next level
            if (!deepEqual(value1, value2, newPath1, newPath2)) {
                return false;
            }

            return true;
        });
    })(first, second, "$1", "$2");
}

module.exports = deepEqualCyclic;
<commit_msg>Re-use variable<commit_after>"use strict";

var o = Object.prototype;
var getClass = require("./get-class");
var identical = require("./identical");
var isArguments = require("./is-arguments");
var isDate = require("./is-date");
var isElement = require("./is-element");
var isNaN = require("./is-nan");
var isObject = require("./is-object");
var isSet = require("./is-set");
var isSubset = require("./is-subset");

var indexOf = Array.prototype.indexOf;

/**
 * @name samsam.deepEqual
 * @param Object first
 * @param Object second
 *
 * Deep equal comparison. Two values are "deep equal" if:
 *
 *   - They are equal, according to samsam.identical
 *   - They are both date objects representing the same time
 *   - They are both arrays containing elements that are all deepEqual
 *   - They are objects with the same set of properties, and each property
 *     in ``first`` is deepEqual to the corresponding property in ``second``
 *
 * Supports cyclic objects.
 */
function deepEqualCyclic(first, second) {
    // used for cyclic comparison
    // contain already visited objects
    var objects1 = [];
    var objects2 = [];
    // contain pathes (position in the object structure)
    // of the already visited objects
    // indexes same as in objects arrays
    var paths1 = [];
    var paths2 = [];
    // contains combinations of already compared objects
    // in the manner: { "$1['ref']$2['ref']": true }
    var compared = {};

    // does the recursion for the deep equal check
    return (function deepEqual(obj1, obj2, path1, path2) {
        var type1 = typeof obj1;
        var type2 = typeof obj2;

        // == null also matches undefined
        if (
            obj1 === obj2 ||
            isNaN(obj1) ||
            isNaN(obj2) ||
            obj1 == null ||
            obj2 == null ||
            type1 !== "object" ||
            type2 !== "object"
        ) {
            return identical(obj1, obj2);
        }

        // Elements are only equal if identical(expected, actual)
        if (isElement(obj1) || isElement(obj2)) {
            return false;
        }

        var isDate1 = isDate(obj1);
        var isDate2 = isDate(obj2);
        if (isDate1 || isDate2) {
            if (!isDate1 || !isDate2 || obj1.getTime() !== obj2.getTime()) {
                return false;
            }
        }

        if (obj1 instanceof RegExp && obj2 instanceof RegExp) {
            if (obj1.toString() !== obj2.toString()) {
                return false;
            }
        }

        if (obj1 instanceof Error && obj2 instanceof Error) {
            if (obj1.stack !== obj2.stack) {
                return false;
            }
        }

        var class1 = getClass(obj1);
        var class2 = getClass(obj2);
        var keys1 = Object.keys(obj1);
        var keys2 = Object.keys(obj2);

        if (isArguments(obj1) || isArguments(obj2)) {
            if (obj1.length !== obj2.length) {
                return false;
            }
        } else {
            if (
                type1 !== type2 ||
                class1 !== class2 ||
                keys1.length !== keys2.length
            ) {
                return false;
            }
        }

        if (isSet(obj1) || isSet(obj2)) {
            if (!isSet(obj1) || !isSet(obj2) || obj1.size !== obj2.size) {
                return false;
            }

            return isSubset(obj1, obj2, deepEqual);
        }

        return keys1.every(function(key) {
            if (!o.hasOwnProperty.call(obj2, key)) {
                return false;
            }

            var value1 = obj1[key];
            var value2 = obj2[key];
            var isObject1 = isObject(value1);
            var isObject2 = isObject(value2);
            // determines, if the objects were already visited
            // (it's faster to check for isObject first, than to
            // get -1 from getIndex for non objects)
            var index1 = isObject1 ? indexOf.call(objects1, value1) : -1;
            var index2 = isObject2 ? indexOf.call(objects2, value2) : -1;
            // determines the new paths of the objects
            // - for non cyclic objects the current path will be extended
            //   by current property name
            // - for cyclic objects the stored path is taken
            var newPath1 =
                index1 !== -1
                    ? paths1[index1]
                    : path1 + "[" + JSON.stringify(key) + "]";
            var newPath2 =
                index2 !== -1
                    ? paths2[index2]
                    : path2 + "[" + JSON.stringify(key) + "]";

            // stop recursion if current objects are already compared
            if (compared[newPath1 + newPath2]) {
                return true;
            }

            // remember the current objects and their paths
            if (index1 === -1 && isObject1) {
                objects1.push(value1);
                paths1.push(newPath1);
            }
            if (index2 === -1 && isObject2) {
                objects2.push(value2);
                paths2.push(newPath2);
            }

            // remember that the current objects are already compared
            if (isObject1 && isObject2) {
                compared[newPath1 + newPath2] = true;
            }

            // End of cyclic logic

            // neither value1 nor value2 is a cycle
            // continue with next level
            if (!deepEqual(value1, value2, newPath1, newPath2)) {
                return false;
            }

            return true;
        });
    })(first, second, "$1", "$2");
}

module.exports = deepEqualCyclic;
<|endoftext|>


<commit_before>L.Control.CustomLayers = L.Control.GroupedLayers.extend({
  _onInputClick: function () {
    var i, input, obj,
        inputs = this._form.getElementsByTagName('input'),
        inputsLen = inputs.length;

    this._handlingClick = true;

    // Layers that can't be deselected (basemaps)
    var notDeselectable = ['Road Map', 'Satellite'];
    if (this.currentInput &&
        this.currentInput.type === 'radio' &&
        notDeselectable.indexOf(this.currentInput.id) < 0) {
      if (this.currentInput == arguments[0].currentTarget) {
        this.currentInput.checked = false;
        this.currentInput = null;
      } else {
        this.currentInput = arguments[0].currentTarget;
      }
    } else {
        this.currentInput = arguments[0].currentTarget;
    }

    if (arguments[0].currentTarget.id === "Satellite") {
      map.className = map.className + " satellite-layer";
    } else if (arguments[0].currentTarget.id === "Road Map") {
      map.className = map.className.replace(/\bsatellite-layer\b/,'');
    }

    for (i = 0; i < inputsLen; i++) {
      input = inputs[i];
      obj = this._layers[input.layerId];

      if (input.checked && !this._map.hasLayer(obj.layer)) {
        this._map.addLayer(obj.layer);
        this._renderLegend(obj, input.parentNode);
      } else if (!input.checked && this._map.hasLayer(obj.layer)) {
        this._map.removeLayer(obj.layer);
        this._removeLegend(obj, input.parentNode);
      }
    }

    this._handlingClick = false;
  },

  _removeLegend: function(obj, container) {
    var legendConfig = LEGEND_CONFIG[obj.name];
    if (legendConfig === undefined) { return; }

    var id = obj.name.toLowerCase().replace(/\s+|\(|\)/g,"");
    var element = document.getElementById(id);

    if (element != undefined) {
      container.removeChild(element);
    }
  },

  _renderLegend: function(obj, container) {
    var legendConfig = LEGEND_CONFIG[obj.name];
    if (legendConfig === undefined || container == undefined) { return; }

    var legend = document.createElement('ul');
    legend.className = "malaria-legend";

    var id = obj.name.toLowerCase().replace(/\s+|\(|\)/g,"");
    legend.id = id;

    var i = 0;
    for (; i < legendConfig.length; i++) {
      var value = legendConfig[i];
      var element = document.createElement('li');

      var textElement = document.createElement('span');
      textElement.innerHTML = value;
      element.appendChild(textElement);
      element.className = id + " m" + (i+1);

      legend.appendChild(element);
    }

    container.appendChild(legend);
  },

	_addItem: function (obj) {
      var label = document.createElement('label'),
          input,
          checked = this._map.hasLayer(obj.layer),
          container;

      if (obj.overlay) {
        if (obj.group.exclusive) {
          groupRadioName = 'leaflet-exclusive-group-layer-' + obj.group.id;
          input = this._createRadioElement(groupRadioName, checked);
        } else {
          input = document.createElement('input');
          input.type = 'checkbox';
          input.className = 'leaflet-control-layers-selector';
          input.defaultChecked = checked;
        }
      } else {
        input = this._createRadioElement('leaflet-base-layers', checked);
      }

      input.layerId = L.Util.stamp(obj.layer);
      input.id = obj.name

      L.DomEvent.on(input, 'click', this._onInputClick, this);

      var name = document.createElement('span');
      name.innerHTML = ' ' + obj.name;

      label.appendChild(input);
      label.appendChild(name);

      if (input.checked === true) {
        this._renderLegend(obj, input.parentNode);
      }

      if (obj.overlay) {
        container = this._overlaysList;

        var groupContainer = this._domGroups[obj.group.id];

        // Create the group container if it doesn't exist
        if (!groupContainer) {
          groupContainer = document.createElement('div');
          groupContainer.className = 'leaflet-control-layers-group';
          groupContainer.id = 'leaflet-control-layers-group-' + obj.group.id;

          var groupLabel = document.createElement('span');
          groupLabel.className = 'leaflet-control-layers-group-name';
          groupLabel.innerHTML = obj.group.name;

          groupContainer.appendChild(groupLabel);
          container.appendChild(groupContainer);

          this._domGroups[obj.group.id] = groupContainer;
        }

        container = groupContainer;
      } else {
        container = this._baseLayersList;
      }

      container.appendChild(label);

      return label;
	},
});

L.control.customLayers = function (baseLayers, groupedOverlays, options) {
  return new L.Control.CustomLayers(baseLayers, groupedOverlays, options);
};
<commit_msg>Update styles<commit_after>L.Control.CustomLayers = L.Control.GroupedLayers.extend({
  _onInputClick: function () {
    var i, input, obj,
        inputs = this._form.getElementsByTagName('input'),
        inputsLen = inputs.length;

    this._handlingClick = true;

    // Layers that can't be deselected (basemaps)
    var notDeselectable = ['Road Map', 'Satellite'];
    if (this.currentInput &&
        this.currentInput.type === 'radio' &&
        notDeselectable.indexOf(this.currentInput.id) < 0) {
      if (this.currentInput == arguments[0].currentTarget) {
        this.currentInput.checked = false;
        this.currentInput = null;
      } else {
        this.currentInput = arguments[0].currentTarget;
      }
    } else {
        this.currentInput = arguments[0].currentTarget;
    }

    for (i = 0; i < inputsLen; i++) {
      input = inputs[i];
      obj = this._layers[input.layerId];

      if (input.checked && !this._map.hasLayer(obj.layer)) {
        this._map.addLayer(obj.layer);
        this._renderLegend(obj, input.parentNode);
      } else if (!input.checked && this._map.hasLayer(obj.layer)) {
        this._map.removeLayer(obj.layer);
        this._removeLegend(obj, input.parentNode);
      }
    }

    this._handlingClick = false;
  },

  _removeLegend: function(obj, container) {
    var legendConfig = LEGEND_CONFIG[obj.name];
    if (legendConfig === undefined) { return; }

    var id = obj.name.toLowerCase().replace(/\s+|\(|\)/g,"");
    var element = document.getElementById(id);

    if (element != undefined) {
      container.removeChild(element);
    }
  },

  _renderLegend: function(obj, container) {
    var legendConfig = LEGEND_CONFIG[obj.name];
    if (legendConfig === undefined || container == undefined) { return; }

    var legend = document.createElement('ul');
    legend.className = "malaria-legend";

    var id = obj.name.toLowerCase().replace(/\s+|\(|\)/g,"");
    legend.id = id;

    var i = 0;
    for (; i < legendConfig.length; i++) {
      var value = legendConfig[i];
      var element = document.createElement('li');

      var textElement = document.createElement('span');
      textElement.innerHTML = value;
      element.appendChild(textElement);
      element.className = id + " m" + (i+1);

      legend.appendChild(element);
    }

    container.appendChild(legend);
  },

	_addItem: function (obj) {
      var label = document.createElement('label'),
          input,
          checked = this._map.hasLayer(obj.layer),
          container;

      if (obj.overlay) {
        if (obj.group.exclusive) {
          groupRadioName = 'leaflet-exclusive-group-layer-' + obj.group.id;
          input = this._createRadioElement(groupRadioName, checked);
        } else {
          input = document.createElement('input');
          input.type = 'checkbox';
          input.className = 'leaflet-control-layers-selector';
          input.defaultChecked = checked;
        }
      } else {
        input = this._createRadioElement('leaflet-base-layers', checked);
      }

      input.layerId = L.Util.stamp(obj.layer);
      input.id = obj.name

      L.DomEvent.on(input, 'click', this._onInputClick, this);

      var name = document.createElement('span');
      name.innerHTML = ' ' + obj.name;

      label.appendChild(input);
      label.appendChild(name);

      if (input.checked === true) {
        this._renderLegend(obj, input.parentNode);
      }

      if (obj.overlay) {
        container = this._overlaysList;

        var groupContainer = this._domGroups[obj.group.id];

        // Create the group container if it doesn't exist
        if (!groupContainer) {
          groupContainer = document.createElement('div');
          groupContainer.className = 'leaflet-control-layers-group';
          groupContainer.id = 'leaflet-control-layers-group-' + obj.group.id;

          var groupLabel = document.createElement('span');
          groupLabel.className = 'leaflet-control-layers-group-name';
          groupLabel.innerHTML = obj.group.name;

          groupContainer.appendChild(groupLabel);
          container.appendChild(groupContainer);

          this._domGroups[obj.group.id] = groupContainer;
        }

        container = groupContainer;
      } else {
        container = this._baseLayersList;
      }

      container.appendChild(label);

      return label;
	},
});

L.control.customLayers = function (baseLayers, groupedOverlays, options) {
  return new L.Control.CustomLayers(baseLayers, groupedOverlays, options);
};
<|endoftext|>