<commit_before>/**
 * jQuery.query - Query String Modification and Creation for jQuery
 * Written by Blair Mitchelmore (blair DOT mitchelmore AT gmail DOT com)
 * Licensed under the WTFPL (http://sam.zoy.org/wtfpl/).
 * Date: 2009/8/13
 *
 * @author Blair Mitchelmore
 * @version 2.1.7.m-ebi
 *
 * Portions written by Microarray Informatics Group, European Bioinformatics Institute
 **/
new function(settings) {
  // Various Settings
  var $separator = settings.separator || '&';
  var $spaces = settings.spaces === false ? false : true;
  var $suffix = settings.suffix === false ? '' : '[]';
  var $prefix = settings.prefix === false ? false : true;
  var $hash = $prefix ? settings.hash === true ? "#" : "?" : "";
  var $numbers = settings.numbers === false ? false : true;
  var $boolean = settings.boolean === true ? true : false;

  jQuery.query = new function() {
    var is = function(o, t) {
      return o != undefined && o !== null && (!!t ? o.constructor == t : true);
    };
    var parse = function(path) {
      var m, rx = /\[([^[]*)\]/g, match = /^([^[]+)(\[.*\])?$/.exec(path), base = match[1], tokens = [];
      while (m = rx.exec(match[2])) tokens.push(m[1]);
      return [base, tokens];
    };
    var set = function(target, tokens, value) {
      var o, token = tokens.shift();
      if (typeof target != 'object') target = null;
      if (token === "") {
        if (!target) target = [];
        if (is(target, Array)) {
          target.push(tokens.length == 0 ? value : set(null, tokens.slice(0), value));
        } else if (is(target, Object)) {
          var i = 0;
          while (target[i++] != null);
          target[--i] = tokens.length == 0 ? value : set(target[i], tokens.slice(0), value);
        } else {
          target = [];
          target.push(tokens.length == 0 ? value : set(null, tokens.slice(0), value));
        }
      } else if (token && token.match(/^\s*[0-9]+\s*$/)) {
        var index = parseInt(token, 10);
        if (!target) target = [];
        target[index] = tokens.length == 0 ? value : set(target[index], tokens.slice(0), value);
      } else if (token) {
        var index = token.replace(/^\s*|\s*$/g, "");
        if (!target) target = {};
        if (is(target, Array)) {
          var temp = {};
          for (var i = 0; i < target.length; ++i) {
            temp[i] = target[i];
          }
          target = temp;
        }
        target[index] = tokens.length == 0 ? value : set(target[index], tokens.slice(0), value);
      } else {
        return value;
      }
      return target;
    };

    var queryObject = function(a) {
      var self = this;
      self.keys = {};

      if (a.queryObject) {
        jQuery.each(a.get(), function(key, val) {
          self.SET(key, val);
        });
      } else {
        jQuery.each(arguments, function() {
          var q = "" + this;
          q = q.replace(/^[?#]/,''); // remove any leading ? || #
          q = q.replace(/[;&]$/,''); // remove any trailing & || ;
          if ($spaces) q = q.replace(/[+]/g,' '); // replace +'s with spaces

          jQuery.each(q.split(/[&;]/), function(){
            var key = decodeURIComponent(this.split('=')[0] || "");
            var val = decodeURIComponent(this.split('=')[1] || "");

            if (!key) return;

            if ($numbers) {
              if (/^[+-]?[0-9]+\.[0-9]*$/.test(val)) // simple float regex
                val = parseFloat(val);
              else if (/^[+-]?[0-9]+$/.test(val)) // simple int regex
                val = parseInt(val, 10);
            }

            if ($boolean) { // treat empty value as boolean 'true'
                val = (!val && val !== 0) ? true : val;
            }

            if (val !== false && val !== true && typeof val != 'number')
              val = val;

            self.SET(key, val);
          });
        });
      }
      return self;
    };

    queryObject.prototype = {
      queryObject: true,
      has: function(key, type) {
        var value = this.get(key);
        return is(value, type);
      },
      GET: function(key) {
        if (!is(key)) return this.keys;
        var parsed = parse(key), base = parsed[0], tokens = parsed[1];
        var target = this.keys[base];
        while (target != null && tokens.length != 0) {
          target = target[tokens.shift()];
        }
        return typeof target == 'number' ? target : target || "";
      },
      get: function(key) {
        var target = this.GET(key);
        if (is(target, Object))
          return jQuery.extend(true, {}, target);
        else if (is(target, Array))
          return target.slice(0);
        return target;
      },
      SET: function(key, val) {
        var value = !is(val) ? null : val;
        var parsed = parse(key), base = parsed[0], tokens = parsed[1];
        var target = this.keys[base];
        this.keys[base] = set(target, tokens.slice(0), value);
        return this;
      },
      set: function(key, val) {
        return this.copy().SET(key, val);
      },
      REMOVE: function(key) {
        return this.SET(key, null).COMPACT();
      },
      remove: function(key) {
        return this.copy().REMOVE(key);
      },
      EMPTY: function() {
        var self = this;
        jQuery.each(self.keys, function(key, value) {
          delete self.keys[key];
        });
        return self;
      },
      load: function(url) {
        var hash = url.replace(/^.*?[#](.+?)(?:\?.+)?$/, "$1");
        var search = url.replace(/^.*?[?](.+?)(?:#.+)?$/, "$1");
        return new queryObject(url.length == search.length ? '' : search, url.length == hash.length ? '' : hash);
      },
      empty: function() {
        return this.copy().EMPTY();
      },
      copy: function() {
        return new queryObject(this);
      },
      COMPACT: function() {
        function build(orig) {
          var obj = typeof orig == "object" ? is(orig, Array) ? [] : {} : orig;
          if (typeof orig == 'object') {
            function add(o, key, value) {
              if (is(o, Array))
                o.push(value);
              else
                o[key] = value;
            }
            jQuery.each(orig, function(key, value) {
              if (!is(value)) return true;
              add(obj, key, build(value));
            });
          }
          return obj;
        }
        this.keys = build(this.keys);
        return this;
      },
      compact: function() {
        return this.copy().COMPACT();
      },
      toString: function() {
        var i = 0, queryString = [], chunks = [], self = this;
        var encode = function(str) {
          str = str + "";
          //if ($spaces) str = str.replace(/ /g, "+");
          return encodeURIComponent(str);
        };
        var addFields = function(arr, key, value) {
          if (!is(value) || value === false) return;
          var o = [encode(key)];
          if (value !== true) {
            o.push("=");
            o.push(encode(value));
          }
          arr.push(o.join(""));
        };
        var build = function(obj, base) {
          var newKey = function(key) {
            return !base || base == "" ? [key].join("") : [base, "[", key, "]"].join("");
          };
          jQuery.each(obj, function(key, value) {
            if (typeof value == 'object')
              build(value, newKey(key));
            else
              addFields(chunks, newKey(key), value);
          });
        };

        build(this.keys);

        if (chunks.length > 0) queryString.push($hash);
        queryString.push(chunks.join($separator));

        return queryString.join("");
      }
    };

    return new queryObject(location.search, location.hash);
  };
}(jQuery.query || {}); // Pass in jQuery.query as settings object
<commit_msg>no more extra pluses for spaces (another approach)<commit_after>/**
 * jQuery.query - Query String Modification and Creation for jQuery
 * Written by Blair Mitchelmore (blair DOT mitchelmore AT gmail DOT com)
 * Licensed under the WTFPL (http://sam.zoy.org/wtfpl/).
 * Date: 2009/8/13
 *
 * @author Blair Mitchelmore
 * @version 2.1.7.m-ebi
 *
 * Portions written by Microarray Informatics Group, European Bioinformatics Institute
 **/
new function(settings) {
  // Various Settings
  var $separator = settings.separator || '&';
  var $spaces = settings.spaces === false ? false : true;
  var $suffix = settings.suffix === false ? '' : '[]';
  var $prefix = settings.prefix === false ? false : true;
  var $hash = $prefix ? settings.hash === true ? "#" : "?" : "";
  var $numbers = settings.numbers === false ? false : true;
  var $boolean = settings.boolean === true ? true : false;

  jQuery.query = new function() {
    var is = function(o, t) {
      return o != undefined && o !== null && (!!t ? o.constructor == t : true);
    };
    var parse = function(path) {
      var m, rx = /\[([^[]*)\]/g, match = /^([^[]+)(\[.*\])?$/.exec(path), base = match[1], tokens = [];
      while (m = rx.exec(match[2])) tokens.push(m[1]);
      return [base, tokens];
    };
    var set = function(target, tokens, value) {
      var o, token = tokens.shift();
      if (typeof target != 'object') target = null;
      if (token === "") {
        if (!target) target = [];
        if (is(target, Array)) {
          target.push(tokens.length == 0 ? value : set(null, tokens.slice(0), value));
        } else if (is(target, Object)) {
          var i = 0;
          while (target[i++] != null);
          target[--i] = tokens.length == 0 ? value : set(target[i], tokens.slice(0), value);
        } else {
          target = [];
          target.push(tokens.length == 0 ? value : set(null, tokens.slice(0), value));
        }
      } else if (token && token.match(/^\s*[0-9]+\s*$/)) {
        var index = parseInt(token, 10);
        if (!target) target = [];
        target[index] = tokens.length == 0 ? value : set(target[index], tokens.slice(0), value);
      } else if (token) {
        var index = token.replace(/^\s*|\s*$/g, "");
        if (!target) target = {};
        if (is(target, Array)) {
          var temp = {};
          for (var i = 0; i < target.length; ++i) {
            temp[i] = target[i];
          }
          target = temp;
        }
        target[index] = tokens.length == 0 ? value : set(target[index], tokens.slice(0), value);
      } else {
        return value;
      }
      return target;
    };

    var queryObject = function(a) {
      var self = this;
      self.keys = {};

      if (a.queryObject) {
        jQuery.each(a.get(), function(key, val) {
          self.SET(key, val);
        });
      } else {
        jQuery.each(arguments, function() {
          var q = "" + this;
          q = q.replace(/^[?#]/,''); // remove any leading ? || #
          q = q.replace(/[;&]$/,''); // remove any trailing & || ;
          if ($spaces) q = q.replace(/[+]/g,' '); // replace +'s with spaces

          jQuery.each(q.split(/[&;]/), function(){
            var key = decodeURIComponent(this.split('=')[0] || "");
            var val = decodeURIComponent(this.split('=')[1] || "");

            if (!key) return;

            if ($numbers) {
              if (/^[+-]?[0-9]+\.[0-9]*$/.test(val)) // simple float regex
                val = parseFloat(val);
              else if (/^[+-]?[0-9]+$/.test(val)) // simple int regex
                val = parseInt(val, 10);
            }

            if ($boolean) { // treat empty value as boolean 'true'
                val = (!val && val !== 0) ? true : val;
            }

            if (val !== false && val !== true && typeof val != 'number')
              val = val;

            self.SET(key, val);
          });
        });
      }
      return self;
    };

    queryObject.prototype = {
      queryObject: true,
      has: function(key, type) {
        var value = this.get(key);
        return is(value, type);
      },
      GET: function(key) {
        if (!is(key)) return this.keys;
        var parsed = parse(key), base = parsed[0], tokens = parsed[1];
        var target = this.keys[base];
        while (target != null && tokens.length != 0) {
          target = target[tokens.shift()];
        }
        return typeof target == 'number' ? target : target || "";
      },
      get: function(key) {
        var target = this.GET(key);
        if (is(target, Object))
          return jQuery.extend(true, {}, target);
        else if (is(target, Array))
          return target.slice(0);
        return target;
      },
      SET: function(key, val) {
        var value = !is(val) ? null : val;
        var parsed = parse(key), base = parsed[0], tokens = parsed[1];
        var target = this.keys[base];
        this.keys[base] = set(target, tokens.slice(0), value);
        return this;
      },
      set: function(key, val) {
        return this.copy().SET(key, val);
      },
      REMOVE: function(key) {
        return this.SET(key, null).COMPACT();
      },
      remove: function(key) {
        return this.copy().REMOVE(key);
      },
      EMPTY: function() {
        var self = this;
        jQuery.each(self.keys, function(key, value) {
          delete self.keys[key];
        });
        return self;
      },
      load: function(url) {
        var hash = url.replace(/^.*?[#](.+?)(?:\?.+)?$/, "$1");
        var search = url.replace(/^.*?[?](.+?)(?:#.+)?$/, "$1");
        return new queryObject(url.length == search.length ? '' : search, url.length == hash.length ? '' : hash);
      },
      empty: function() {
        return this.copy().EMPTY();
      },
      copy: function() {
        return new queryObject(this);
      },
      COMPACT: function() {
        function build(orig) {
          var obj = typeof orig == "object" ? is(orig, Array) ? [] : {} : orig;
          if (typeof orig == 'object') {
            function add(o, key, value) {
              if (is(o, Array))
                o.push(value);
              else
                o[key] = value;
            }
            jQuery.each(orig, function(key, value) {
              if (!is(value)) return true;
              add(obj, key, build(value));
            });
          }
          return obj;
        }
        this.keys = build(this.keys);
        return this;
      },
      compact: function() {
        return this.copy().COMPACT();
      },
      toString: function() {
        var i = 0, queryString = [], chunks = [], self = this;
        var encode = function(str) {
          str = str + "";
          // this was removed because encoding plus signs interferes with lucene
          // if ($spaces) str = str.replace(/ /g, "+");
          return encodeURIComponent(str);
        };
        var addFields = function(arr, key, value) {
          if (!is(value) || value === false) return;
          var o = [encode(key)];
          if (value !== true) {
            o.push("=");
            o.push(encode(value));
          }
          arr.push(o.join(""));
        };
        var build = function(obj, base) {
          var newKey = function(key) {
            return !base || base == "" ? [key].join("") : [base, "[", key, "]"].join("");
          };
          jQuery.each(obj, function(key, value) {
            if (typeof value == 'object')
              build(value, newKey(key));
            else
              addFields(chunks, newKey(key), value);
          });
        };

        build(this.keys);

        if (chunks.length > 0) queryString.push($hash);
        queryString.push(chunks.join($separator));

        return queryString.join("");
      }
    };

    return new queryObject(location.search, location.hash);
  };
}(jQuery.query || {}); // Pass in jQuery.query as settings object
<|endoftext|>


<commit_before>var child_process = require('child_process')
var fs = require('fs');
var max_sleep = 300
var step = 10
//Added a comment that achieves no real goal.
//Non-blocking loop
//Adjustable step
//Status line
//Add a rough time indicator
//First cut at libfaketime support

var commit_messages = [
  "Fixing an important issue with the universe.",
  "Someone poisoned the waterhole!",
  "You feeling lucky punk?",
  "Five bullets or six?",
  "Fixed memory parsing error #1337",
  "Cleaned out the intertubes",
  "AAAAAAAAAAARGH!",
  "Fixed a typo",
  "Updated the readme",
  "Fixing a typo added in the last readme update",
  "GET A HAIRCUT!",
  "Updated the readme again",
  "Found an issue with the letter 'a', so I fixed it.",
  "Incompatible dimensions found, Cthuhlu Error 666",
  "Who you calling a fool?",
  "How many more of these can I make?",
  "Fixing an error introduced in the last commit",
  "Re-updating the readme.",
  "Work in Progress",
  "WIP",
  "Quick fix",
  "Grammar fix",
  "Fixing punctuation",
  "Correcting style",
  "Logic error",
  "Almost there",
  "Nearly got it",
  "N<commit_msg>Can work my way through the Kanban<commit_after>var child_process = require('child_process')
var fs = require('fs');
var max_sleep = 300
var step = 10
//Added a comment that achieves no real goal.
//Non-blocking loop
//Adjustable step
//Status line
//Add a rough time indicator
//First cut at libfaketime support

var commit_messages = [
  "Fixing an important issue with the universe.",
  "Someone poisoned the waterhole!",
  "You feeling lucky punk?",
  "Five bullets or six?",
  "Fixed memory parsing error #1337",
  "Cleaned out the intertubes",
  "AAAAAAAAAAARGH!",
  "Fixed a typo",
  "Updated the readme",
  "Fixing a typo added in the last readme update",
  "GET A HAIRCUT!",
  "Updated the readme again",
  "Found an issue with the letter 'a', so I fixed it.",
  "Incompatible dimensions found, Cthuhlu Error 666",
  "Who you calling a fool?",
  "How many more of these can I make?",
  "Fixing an error introduced in the last commit",
  "Re-updating the readme.",
  "Work in Progress",
  "WIP",
  "Quick fix",
  "Grammar fix",
  "Fixing punctuation",
  "Correcting style",
  "Logic error",
  "Almost there",
  "Nearly got it",
  "No<|endoftext|>


<commit_before>var child_process = require('child_process')
var fs = require('fs');
var max_sleep = 300
var step = 10
//Added a comment that achieves no real goal.
//Non-blocking loop
//Adjustable step
//Status line
//Add a rough time indicator
//First cut at libfaketime support

var commit_messages = [
  "Fixing an important issue with the universe.",
  "Someone poisoned <commit_msg>AAAAAAAAAAARGH!<commit_after>var child_process = require('child_process')
var fs = require('fs');
var max_sleep = 300
var step = 10
//Added a comment that achieves no real goal.
//Non-blocking loop
//Adjustable step
//Status line
//Add a rough time indicator
//First cut at libfaketime support

var commit_messages = [
  "Fixing an important issue with the universe.",
  "Someone poisoned t<|endoftext|>


<commit_before>'use strict';

var $ = require('jquery');

require('jquery-ui/draggable');

module.exports = ['localConf', function(localConf) {
  return {
    restrict: 'CA',
    link: function(scope, element, attrs) {
      var container = $(element);
      var containerId = attrs.ctnCollapsableParent;

        // the element being collapsed
      var collapsableElement = $('[ctn-collapsable]', container).eq(0);

        // the direction into which to collapse
      var direction = collapsableElement.attr('ctn-collapsable') || 'left';
      var vertical = direction === 'left' || direction === 'right';

      var minWidth = 0;
      if (attrs.ctnMinWidth) {
        var minWidthEls = $('.ctn-' + containerId + ' ' + attrs.ctnMinWidth, container);
        minWidthEls.each(function(e, el) {
          minWidth += $(el).outerWidth(true);
        });

        // just to avoid half pixels glitches
        if(minWidth) {
          minWidth += 10;
        }
      }

      var originalCollapsabled = localConf.get('ctnCollapsableParent:collapsed:'+ containerId, 'no');

        // the main element that compensates the collapsing
      var compensateElement = collapsableElement[direction === 'left' || direction === 'top' ? 'next' : 'prev']();

        // a resize handle
      var resizeHandle = $('

')
                              .appendTo(container);

        /////// init show / hide handles ////////

      var showHandle =
          compensateElement
            .children('.show-collapsable')
              .addClass('expand-collapse')
              .append('');

      var hideHandle =
          collapsableElement
            .children('.hide-collapsable')
              .addClass('expand-collapse')
              .append('');

        /**
         * Toggle show / hide handles
         */
      function setCollapsed(collapsed) {
        if (collapsed) {
          hideHandle.hide();
          showHandle.css('display', 'block');
        } else {
          showHandle.hide();
          hideHandle.css('display', 'block');
        }

        localConf.set('ctnCollapsableParent:collapsed:'+ containerId, collapsed ? 'yes' : 'no');
      }

      function initResize() {

        var changeAttr = vertical ? 'width' : 'height';
        var resizeHandleAttachAttr = vertical ? 'left' : 'top';
        var changeAxis = vertical ? 'x' : 'y';

          /**
           * Create a { direction: i } object
           */
        function createOffset(i) {
          var style = {};
          style[direction] = i;

          return style;
        }

          /**
           * Create a { changeAttr: i } object
           */
        function createSize(i) {
          var style = {};
          style[changeAttr] = i;

          return style;
        }

        resizeHandle
            .addClass(vertical ? 'vertical' : 'horizontal');

        var originalCollapsableSize = collapsableElement[changeAttr]();

        localConf.get('ctnCollapsableParent:size:'+ containerId, originalCollapsableSize);

        originalCollapsableSize = Math.max(minWidth, originalCollapsableSize);

        if (originalCollapsabled === 'yes') {
          collapsableElement.css(changeAttr, 0);
          compensateElement.css(direction, 0);
        }
        else {
          collapsableElement.css(changeAttr, originalCollapsableSize);
          compensateElement.css(direction, originalCollapsableSize +'px');
        }

        function updateResizeHandlePosition() {
          var collapsableSize = collapsableElement[changeAttr]();
          var collapsablePosition = collapsableElement.position();

          if (direction === 'left' || direction === 'top') {
            resizeHandle
                .css(resizeHandleAttachAttr, collapsableSize);
          } else {
            resizeHandle
                .css(resizeHandleAttachAttr, collapsablePosition[resizeHandleAttachAttr]);
          }
        }

        $(resizeHandle)
            .draggable({ axis: changeAxis, containment: 'parent'})
            .on('drag', function() {
              var position = resizeHandle.position();
              var pos = position[direction];

              if (direction === 'right') {
                pos = container.width() - position.left;
              }

              if (direction === 'bottom') {
                pos = container.height() - position.top;
              }

              if(pos < minWidth) {
                pos = 0;
              }

              // update collapsed state on drag
              setCollapsed(pos < 10);

              collapsableElement.css(changeAttr, pos);
              compensateElement.css(direction, pos);

              localConf.set('ctnCollapsableParent:size:'+ containerId, pos);
            })
            .on('dragstop', function(event) {
              updateResizeHandlePosition();

              scope.$broadcast('resize', [ event ]);
            });

        hideHandle.click(function() {
          setCollapsed(true);

          resizeHandle.animate(createOffset(0));
          collapsableElement.animate(createSize(0));
          compensateElement.animate(createOffset(0));
        });

        showHandle.click(function() {
          setCollapsed(false);

          resizeHandle.animate(createOffset(minWidth || originalCollapsableSize));
          collapsableElement.animate(createSize(minWidth || originalCollapsableSize));
          compensateElement.animate(createOffset(minWidth || originalCollapsableSize));
        });

        $(window).on('resize', updateResizeHandlePosition);

        scope.$on('$destroy', function() {
          $(window).off('resize', updateResizeHandlePosition);
        });

        updateResizeHandlePosition();
      }

      setCollapsed(originalCollapsabled === 'yes');
      initResize();
    }
  };
}];
<commit_msg>improve(cockpit): add class when pane is collapsed<commit_after>'use strict';

var $ = require('jquery');

require('jquery-ui/draggable');

module.exports = ['localConf', function(localConf) {
  return {
    restrict: 'CA',
    link: function(scope, element, attrs) {
      var container = $(element);
      var containerId = attrs.ctnCollapsableParent;

        // the element being collapsed
      var collapsableElement = $('[ctn-collapsable]', container).eq(0);

        // the direction into which to collapse
      var direction = collapsableElement.attr('ctn-collapsable') || 'left';
      var vertical = direction === 'left' || direction === 'right';

      var minWidth = 0;
      if (attrs.ctnMinWidth) {
        var minWidthEls = $('.ctn-' + containerId + ' ' + attrs.ctnMinWidth, container);
        minWidthEls.each(function(e, el) {
          minWidth += $(el).outerWidth(true);
        });

        // just to avoid half pixels glitches
        if(minWidth) {
          minWidth += 10;
        }
      }

      var originalCollapsabled = localConf.get('ctnCollapsableParent:collapsed:'+ containerId, 'no');

        // the main element that compensates the collapsing
      var compensateElement = collapsableElement[direction === 'left' || direction === 'top' ? 'next' : 'prev']();

        // a resize handle
      var resizeHandle = $('

')
                              .appendTo(container);

        /////// init show / hide handles ////////

      var showHandle =
          compensateElement
            .children('.show-collapsable')
              .addClass('expand-collapse')
              .append('');

      var hideHandle =
          collapsableElement
            .children('.hide-collapsable')
              .addClass('expand-collapse')
              .append('');

        /**
         * Toggle show / hide handles
         */
      function setCollapsed(collapsed) {
        if (collapsed) {
          hideHandle.hide();
          showHandle.css('display', 'block');
        } else {
          showHandle.hide();
          hideHandle.css('display', 'block');
        }

        localConf.set('ctnCollapsableParent:collapsed:'+ containerId, collapsed ? 'yes' : 'no');
      }

      function initResize() {

        var changeAttr = vertical ? 'width' : 'height';
        var resizeHandleAttachAttr = vertical ? 'left' : 'top';
        var changeAxis = vertical ? 'x' : 'y';

          /**
           * Create a { direction: i } object
           */
        function createOffset(i) {
          var style = {};
          style[direction] = i;

          return style;
        }

          /**
           * Create a { changeAttr: i } object
           */
        function createSize(i) {
          var style = {};
          style[changeAttr] = i;

          return style;
        }

        resizeHandle
            .addClass(vertical ? 'vertical' : 'horizontal');

        var originalCollapsableSize = collapsableElement[changeAttr]();

        localConf.get('ctnCollapsableParent:size:'+ containerId, originalCollapsableSize);

        originalCollapsableSize = Math.max(minWidth, originalCollapsableSize);

        if (originalCollapsabled === 'yes') {
          collapsableElement.css(changeAttr, 0);
          compensateElement.css(direction, 0);
        }
        else {
          collapsableElement.css(changeAttr, originalCollapsableSize);
          compensateElement.css(direction, originalCollapsableSize +'px');
        }

        function updateResizeHandlePosition() {
          var collapsableSize = collapsableElement[changeAttr]();
          var collapsablePosition = collapsableElement.position();

          if (direction === 'left' || direction === 'top') {
            resizeHandle
                .css(resizeHandleAttachAttr, collapsableSize);
          } else {
            resizeHandle
                .css(resizeHandleAttachAttr, collapsablePosition[resizeHandleAttachAttr]);
          }
        }

        $(resizeHandle)
            .draggable({ axis: changeAxis, containment: 'parent'})
            .on('drag', function() {
              var position = resizeHandle.position();
              var pos = position[direction];

              if (direction === 'right') {
                pos = container.width() - position.left;
              }

              if (direction === 'bottom') {
                pos = container.height() - position.top;
              }

              if(pos < minWidth) {
                pos = 0;
              }

              // update collapsed state on drag
              setCollapsed(pos < 10);

              collapsableElement.css(changeAttr, pos);
              compensateElement.css(direction, pos);

              localConf.set('ctnCollapsableParent:size:'+ containerId, pos);
            })
            .on('dragstop', function(event) {
              updateResizeHandlePosition();

              scope.$broadcast('resize', [ event ]);
            });

        hideHandle.click(function() {
          setCollapsed(true);

          resizeHandle.animate(createOffset(0));
          collapsableElement
            .animate(createSize(0))
            .addClass('collapsed');
          compensateElement.animate(createOffset(0));
        });

        showHandle.click(function() {
          setCollapsed(false);

          resizeHandle.animate(createOffset(minWidth || originalCollapsableSize));
          collapsableElement
            .animate(createSize(minWidth || originalCollapsableSize))
            .removeClass('collapsed');
          compensateElement.animate(createOffset(minWidth || originalCollapsableSize));
        });

        $(window).on('resize', updateResizeHandlePosition);

        scope.$on('$destroy', function() {
          $(window).off('resize', updateResizeHandlePosition);
        });

        updateResizeHandlePosition();
      }

      setCollapsed(originalCollapsabled === 'yes');
      initResize();
    }
  };
}];
<|endoftext|>


<commit_before>var child_process = require('child_process')
var fs = require('fs');
var max_sleep = 300
var step = 10
//Added a comment that achieves no real goal.
//Non-blocking loop
//Adjustable step
//Status line
//Add a rough time indicator
//First cut at libfaketime support

var commit_messages = [
  "Fixing an important issue with the universe.",
  "Someone poisoned the waterhole!",
  "You feeling lucky punk?",
  "Five bullets or six?",
  "Fixed memory parsing error #1337",
  "Cleaned out the intertubes",
  "AAAAAAAAAAARGH!",
  "Fixed a typo",
  "Updated the readme",
  "Fixing a typo added in the last readme update",
  "GET A HAIRCUT!",
  "Updated the readme again",
  "Found an issue with the letter 'a', so I fixed it.",
  "Incompatible dimensions found, Cthuhlu Error 666",
  "Who you calling a fool?",
  "How many more of these can I make?",
  "Fixing an error introduced in the last commit",
  "Re-updating the readme.",
  "Work in Progress",
  "WIP",
  "Quick fix",
  "Grammar fix",
  "Fixing punctuation",
  "Correcting style",
  "Logic error",
  "Almost there",
  "Nearly got it",
  "Not quite working",
  "Ooops!",
  "Did I do that?",
  "Commit all the required changes",
  "Really commit all the required changes",
  "Should work now",
  "Back out the last commit",
  "Reverting changes",
  "One more time...",
  "Re-commiting last",
  "One more User Story done",
  "Can work my way through the Kanban",
  "Sprint complete",
  "Well that seemed pretty easy",
  "What do you mean you can't pack up the commit?",
  "Merge in master",
  "Fast-forwarding changes"
]

if ( process.argv[ 2 ] && process.argv[ 3 ] ) {
  var inFile = process.argv[ 2 ]
  var outFile = process.argv[ 3 ]
  if (inFile == outFile) {
    console.error("Aborted: infile and outfile must be different")
    return(-1);
  }
  if (process.argv [ 4 ]) max_sleep = process.argv [ 4 ]
  if (process.argv [ 5 ]) step = parseInt(process.argv [ 5 ])
  console.info("Writing from %s to %s, with up to %s seconds between commits of %s bytes", inFile, outFile, max_sleep, step)
  var outFD = fs.openSync(outFile, 'w')
  fs.readFile(inFile, function(err,data) {
    var length = data.length
    var commit_count = Math.ceil(length / step)
    var commit_time = commit_count * max_sleep / 2
    var commit_time_hour = Math.floor(commit_time / 3600)
    var commit_time_rem = commit_time - (commit_time_hour * 3600)
    var commit_time_min = Math.floor(commit_time_rem / 60)
    var commit_time_sec = commit_time_rem - (commit_time_min * 60)
    console.info("Input file is %s Bytes, this will generate %s commits and take approximately %s hours %s minutes %s seconds", length, commit_count, commit_time_hour, commit_time_min, commit_time_sec)
    var t_offset = 0
    if (process.env.FAKETIME) {
      // 2<commit_msg>Nearly got it<commit_after>var child_process = require('child_process')
var fs = require('fs');
var max_sleep = 300
var step = 10
//Added a comment that achieves no real goal.
//Non-blocking loop
//Adjustable step
//Status line
//Add a rough time indicator
//First cut at libfaketime support

var commit_messages = [
  "Fixing an important issue with the universe.",
  "Someone poisoned the waterhole!",
  "You feeling lucky punk?",
  "Five bullets or six?",
  "Fixed memory parsing error #1337",
  "Cleaned out the intertubes",
  "AAAAAAAAAAARGH!",
  "Fixed a typo",
  "Updated the readme",
  "Fixing a typo added in the last readme update",
  "GET A HAIRCUT!",
  "Updated the readme again",
  "Found an issue with the letter 'a', so I fixed it.",
  "Incompatible dimensions found, Cthuhlu Error 666",
  "Who you calling a fool?",
  "How many more of these can I make?",
  "Fixing an error introduced in the last commit",
  "Re-updating the readme.",
  "Work in Progress",
  "WIP",
  "Quick fix",
  "Grammar fix",
  "Fixing punctuation",
  "Correcting style",
  "Logic error",
  "Almost there",
  "Nearly got it",
  "Not quite working",
  "Ooops!",
  "Did I do that?",
  "Commit all the required changes",
  "Really commit all the required changes",
  "Should work now",
  "Back out the last commit",
  "Reverting changes",
  "One more time...",
  "Re-commiting last",
  "One more User Story done",
  "Can work my way through the Kanban",
  "Sprint complete",
  "Well that seemed pretty easy",
  "What do you mean you can't pack up the commit?",
  "Merge in master",
  "Fast-forwarding changes"
]

if ( process.argv[ 2 ] && process.argv[ 3 ] ) {
  var inFile = process.argv[ 2 ]
  var outFile = process.argv[ 3 ]
  if (inFile == outFile) {
    console.error("Aborted: infile and outfile must be different")
    return(-1);
  }
  if (process.argv [ 4 ]) max_sleep = process.argv [ 4 ]
  if (process.argv [ 5 ]) step = parseInt(process.argv [ 5 ])
  console.info("Writing from %s to %s, with up to %s seconds between commits of %s bytes", inFile, outFile, max_sleep, step)
  var outFD = fs.openSync(outFile, 'w')
  fs.readFile(inFile, function(err,data) {
    var length = data.length
    var commit_count = Math.ceil(length / step)
    var commit_time = commit_count * max_sleep / 2
    var commit_time_hour = Math.floor(commit_time / 3600)
    var commit_time_rem = commit_time - (commit_time_hour * 3600)
    var commit_time_min = Math.floor(commit_time_rem / 60)
    var commit_time_sec = commit_time_rem - (commit_time_min * 60)
    console.info("Input file is %s Bytes, this will generate %s commits and take approximately %s hours %s minutes %s seconds", length, commit_count, commit_time_hour, commit_time_min, commit_time_sec)
    var t_offset = 0
    if (process.env.FAKETIME) {
      // 20<|endoftext|>


<commit_before>import React from 'react'
import PropTypes from 'prop-types'

import { Modal, Button } from 'react-bootstrap'

import style from './style.css'

const CloseDialogConfirmation = ({ onYes, onNo }) => {
  return (
    <Modal show dialogClassName={style['cust-modal-content']}>
      <Modal.Header bsClass={`modal-header ${style['cust-modal-header']}`}>
        <Modal.Title>Dialog contains unsaved changes</Modal.Title>
      </Modal.Header>
      <Modal.Body bsClass={`modal-body ${style['cust-modal-body']}`}>

Are you sure you want to drop your changes?

      </Modal.Body>
      <Modal.Footer>
        <Button onClick={onNo} bsClass='btn btn-default'>No</Button>
        <Button onClick={onYes} bsClass='btn btn-info'>Yes</Button>
      </Modal.Footer>
    </Modal>
  )
}
CloseDialogConfirmation.propTypes = {
  onYes: PropTypes.func.isRequired,
  onNo: PropTypes.func.isRequired,
}

export default CloseDialogConfirmation
<commit_msg>Add HTML IDs to CloseDialogConfirmation<commit_after>import React from 'react'
import PropTypes from 'prop-types'

import { Modal, Button } from 'react-bootstrap'

import style from './style.css'

const CloseDialogConfirmation = ({ onYes, onNo }) => {
  const idPrefix = 'closedialogconfim'
  return (
    <Modal show dialogClassName={style['cust-modal-content']}>
      <Modal.Header bsClass={`modal-header ${style['cust-modal-header']}`}>
        <Modal.Title id={`${idPrefix}-title`}>Dialog contains unsaved changes</Modal.Title>
      </Modal.Header>
      <Modal.Body bsClass={`modal-body ${style['cust-modal-body']}`}>
        <h4 id={`${idPrefix}-body-text`}>Are you sure you want to drop your changes?

      </Modal.Body>
      <Modal.Footer>
        <Button id={`${idPrefix}-button-no`} onClick={onNo} bsClass='btn btn-default'>No</Button>
        <Button id={`${idPrefix}-button-yes`} onClick={onYes} bsClass='btn btn-info'>Yes</Button>
      </Modal.Footer>
    </Modal>
  )
}
CloseDialogConfirmation.propTypes = {
  onYes: PropTypes.func.isRequired,
  onNo: PropTypes.func.isRequired,
}

export default CloseDialogConfirmation
<|endoftext|>


<commit_before>/* eslint-env node */
/*

    Provide a CouchDB-like API using `PouchDB` and `express-pouchdb`.  This in only useful in association with an
    existing `gpii.express` instance.  See the documentation for details:

    https://github.com/GPII/gpii-pouchdb/blob/master/docs/pouch-express.md

 */
"use strict";

/*

    TODO:  Work through the express-pouchdb setup and code with Antranig, as we see many warnings like:

    `Warning: a promise was created in a handler but was not returned from it`

    The workaround for now is to set the `BLUEBIRD_WARNINGS` environment variable to `0`.

 */
process.env.BLUEBIRD_WARNINGS = 0;

var fluid = require("infusion");
var gpii  = fluid.registerNamespace("gpii");
fluid.registerNamespace("gpii.pouch.express");

var os             = require("os");
var fs             = require("fs");
var rimraf         = require("rimraf");
var memdown        = require("memdown");

var expressPouchdb = require("express-pouchdb");

var PouchDB        = require("pouchdb");

fluid.require("path", require, "path");

// The cleanup cycle used by express-pouchdb leaves a shedload of listeners around.  To avoid these, we disable the
// event listener warnings, but only for PouchDB itself.
PouchDB.setMaxListeners(250);

/**
 * A static function to expand all variations on the definitions used in `options.databases`:
 *
 *   1. dbName: { data: "singlePath"} // One single file to be loaded, long notation.  No custom options.
 *   2. dbName: { data: ["path1", "path2"] } // Multiple files to be loaded, long notation, no custom options.
 *   3. dbName: { data: ["path1", "path2"], dbOptions: { db: memdown } } // Long notation, including additional custom database options.
 *   4. dbName: { dbOptions: { db: memdown} } // Long notation, no data, but with custom database options.
 *   5. dbName: {} // No data, no custom options.
 *
 * @param dbDef - The definition of a single database in any of the above formats.
 * @returns {Object} - An expanded record in Object form.
 *
 */
gpii.pouch.express.expandDbDef = function (dbDef) {
    var expandedDef = {};
    if (typeof dbDef === "object" && dbDef !== null && dbDef !== undefined) {
        expandedDef = dbDef;
        if (expandedDef.data) {
            expandedDef.data = fluid.makeArray(expandedDef.data);
        }
    }

    return expandedDef;
};

/**
 *
 * Initialize our instance of express-pouchdb.
 *
 * @param that
 * @returns {Object} - The expressPouchDB middleware.
 *
 */
gpii.pouch.express.initExpressPouchdb = function (that) {
    fluid.log("express pouchdb instance '", that.id, "' initalizing...");

    if (!that.options.baseDir) {
        fluid.fail("You must specify a basedir option...");
    }
    // Create our base directory if it doesn't already exist.
    else if (!fs.existsSync(that.options.baseDir)) {
        fluid.log("Creating directory '", that.options.baseDir, "' for express pouchdb instance '", that.id, "'...");
        fs.mkdirSync(that.options.baseDir);
        that.baseDirBelongsToUs = true;
    }

    // There are unfortunately options that can only be configured via a configuration file.
    //
    // To allow ourselves (and users configuring and extending this grade) to control these options, we create the file
    // with the contents of options.pouchConfig before configuring and starting express-pouchdb.
    fs.writeFileSync(that.options.expressPouchConfigPath, JSON.stringify(that.options.expressPouchConfig, null, 2));

    that.PouchDB = PouchDB.defaults(that.options.dbOptions);
    that.expressPouchdb = expressPouchdb(that.PouchDB, { configPath: that.options.expressPouchConfigPath });

    return that.expressPouchdb;
};

/**
 *
 * Initialize all of the configured databases in `that.options.database`.
 *
 * @param that
 * @returns {Promise} - A `fluid.promise.sequence` that will be resolved when all databases are initialized.
 *
 */
gpii.pouch.express.initDbs = function (that) {
    // We create our components programatically because we need:
    //
    //   1. To be notified when all databases are ready for use.  We do this with a `fluid.promise.sequence`.
    //   2. A way to clean up each database later on.  We do this by retaining a list of database instances.
    //   3. A way to know when all of them have been destroyed.  We do this with another `sequence` in our cleanup invoker (see below).
    //
    // I can think of ways to accomplish #2 with dynamic components, but not 1 and 3.
    // TODO: Review with Antranig.

    var promises = [];
    fluid.each(that.options.databases, function (dbOptions, dbKey) {
        promises.push(gpii.pouch.express.initDb(that, dbKey, dbOptions));
    });

    var sequence = fluid.promise.sequence(promises);
    sequence.then(function () {
        that.events.onStarted.fire();
    });

    return sequence;
};

/**
 *
 * Initialize a single database instance.
 *
 * @param that - The component itself
 * @param dbKey {String} - The database name.
 * @param dbDef {Object} - Our convention for representing multiple databases.  See the docs for examples.
 * @returns {Promise} A promise that will be resolved with the database is initialized.
 */
gpii.pouch.express.initDb = function (that, dbKey, dbDef) {
    var expandedDef = gpii.pouch.express.expandDbDef(dbDef);
    var dataLoadedPromise = fluid.promise();
    var dbOptions = expandedDef.dbOptions ? fluid.merge(that.options.dbOptions, expandedDef.dbOptions) : fluid.copy(that.options.dbOptions);
    dbOptions.name = dbKey;
    var dbComponentOptions = {
        type: "fluid.component",
        gradeNames: that.options.pouchGradeNames,
        dbOptions: dbOptions,
        baseDir: that.options.baseDir,
        listeners: {
            "onDataLoaded.resolvePromise": {
                func: dataLoadedPromise.resolve
            }
        }
    };
    if (expandedDef.data) {
        dbComponentOptions.dbPaths = expandedDef.data;
    }

    var dbComponent = fluid.construct("gpii_pouch_" + that.id + "_" + dbKey, dbComponentOptions);
    that.databaseInstances[dbKey] = dbComponent;

    var viewCleanupPromise = fluid.promise();

    dataLoadedPromise.then(function () {
        dbComponent.viewCleanup().then(viewCleanupPromise.resolve, viewCleanupPromise.reject);
    }, viewCleanupPromise.reject);

    return viewCleanupPromise;
};

/**
 *
 * Pass along any requests to our instance of express-pouchdb.
 *
 * @param that - The component itself.
 * @param req {Object} - The Express request object.
 * @param res {Object} - The Express response object.
 * @param next {Function} - The next piece of middleware in the chain.
 *
 */
gpii.pouch.express.middleware = function (that, req, res, next) {
    // fluid.log("express pouchdb instance '", that.id, "' responding...")
    that.expressPouchdb(req, res, next);
};

/**
 *
 * Clean up any instance of `gpii.pouchdb` that we're aware of.  Then, to get rid of databases created by
 * express-pouchdb, complete remove all data in `options.baseDir`.
 *
 * @param that - The component itself.
 * @returns {Promise} - A promise that will be resolved when cleanup is complete.
 *
 */
gpii.pouch.express.cleanup = function (that) {
    var tmpPouchDB = PouchDB.defaults({ db: memdown});
    var togo = fluid.promise();
    togo.then(that.events.onCleanupComplete.fire, that.events.onError.fire);

    that.expressPouchdb.setPouchDB(tmpPouchDB).then(function () {
        var cleanupPromises = [];

        fluid.each(that.databaseInstances, function (databaseInstance) {
            cleanupPromises.push(databaseInstance.destroyPouch());
        });

        var optionsFileCleanupPromise = fluid.promise();

        fs.unlink(that.options.expressPouchConfigPath, function (error) {
            if (error) {
                optionsFileCleanupPromise.reject(error);
            }
            else {
                optionsFileCleanupPromise.resolve();
            }
        });

        cleanupPromises.push(optionsFileCleanupPromise);

        var cleanupSequence = fluid.promise.sequence(cleanupPromises);
        cleanupSequence.then(function () {
            if (that.baseDirBelongsToUs) {
                rimraf(that.options.baseDir, function (error) {
                    if (error) {
                        fluid.log("ERROR: Unable to remove base directory...\n", error);
                    }
                    else {
                        fluid.log("Removed temporary directory '", that.options.baseDir, "'...");
                    }
                    togo.resolve();
                });
            }
            else {
                togo.resolve();
            }
        }, togo.reject);
    });

    return togo;
};

fluid.defaults("gpii.pouch.express.base", {
    gradeNames: ["fluid.component", "gpii.express.middleware"],
    method: "use", // We have to support all HTTP methods, as does our underlying router.
    path: "/",
    namespace: "pouch-express", // Namespace to allow other routers to put themselves in the chain before or after us.
    tmpDir:  os.tmpdir(),
    baseDir: "@expand:path.resolve({that}.options.tmpDir, {that}.id)",
    expressPouchConfigFilename: "config.json",
    expressPouchConfigPath:     "@expand:path.resolve({that}.options.baseDir, {that}.options.expressPouchConfigFilename)",
    expressPouchLogFilename:    "log.txt",
    expressPouchConfig: {
        // Disable the unused changes API to avoid a leaked listener.
        overrideMode: {
            exclude: ["routes/changes"]
        },
        log: {
            file: "@expand:path.resolve({that}.options.tmpDir, {that}.options.expressPouchLogFilename)"
        }
    },
    events: {
        initDbs:           null,
        onError:           null,
        onStarted:         null,
        onCleanup:         null,
        onCleanupComplete: null
    },
    members: {
        baseDirBelongsToUs: false, // Whether we created our working directory (and thus should clean it up when we're done).
        databaseInstances: {} // The actual PouchDB databases
    },
    pouchGradeNames: ["gpii.pouch.node.base"],
    databases: {}, // The configuration we will use to create the required databases on startup.
    listeners: {
        "initDbs.initExpressPouchdb": {
            priority: "first",
            funcName: "gpii.pouch.express.initExpressPouchdb",
            args:     ["{that}"]
        },
        "initDbs.initDbs": {
            priority: "last",
            func:     "{that}.initDbs"
        },
        "onCreate.initDbs": {
            func: "{that}.events.initDbs.fire"
        },
        "onCleanup.cleanup": {
            func: "{that}.cleanup"
        },
        "onCreate.log": {
            funcName: "fluid.log",
            args: ["express baseDir: '", "{that}.options.baseDir", "'..."]
        }
    },
    invokers: {
        middleware: {
            funcName: "gpii.pouch.express.middleware",
            args:     ["{that}", "{arguments}.0", "{arguments}.1", "{arguments}.2"] // request, response, next
        }
    }
});

fluid.defaults("gpii.pouch.express", {
    gradeNames: ["gpii.pouch.express.base"],
    pouchGradeNames: ["gpii.pouch.node"],
    dbOptions: {
        prefix: "@expand:gpii.pouch.node.makeSafePrefix({that}.options.baseDir)"
    },
    invokers: {
        cleanup: {
            funcName: "gpii.pouch.express.cleanup",
            args:     ["{that}"]
        },
        initDbs: {
            funcName: "gpii.pouch.express.initDbs",
            args:     ["{that}"]
        }
    }
});
<commit_msg>GPII-2179: Ensured that only one db cleanup pass at a time executes.<commit_after>/* eslint-env node */
/*

    Provide a CouchDB-like API using `PouchDB` and `express-pouchdb`.  This in only useful in association with an
    existing `gpii.express` instance.  See the documentation for details:

    https://github.com/GPII/gpii-pouchdb/blob/master/docs/pouch-express.md

 */
"use strict";

/*

    TODO:  Work through the express-pouchdb setup and code with Antranig, as we see many warnings like:

    `Warning: a promise was created in a handler but was not returned from it`

    The workaround for now is to set the `BLUEBIRD_WARNINGS` environment variable to `0`.

 */
process.env.BLUEBIRD_WARNINGS = 0;

var fluid = require("infusion");
var gpii  = fluid.registerNamespace("gpii");
fluid.registerNamespace("gpii.pouch.express");

var os             = require("os");
var fs             = require("fs");
var rimraf         = require("rimraf");
var memdown        = require("memdown");

var expressPouchdb = require("express-pouchdb");

var PouchDB        = require("pouchdb");

fluid.require("path", require, "path");

// The cleanup cycle used by express-pouchdb leaves a shedload of listeners around.  To avoid these, we disable the
// event listener warnings, but only for PouchDB itself.
PouchDB.setMaxListeners(250);

/**
 * A static function to expand all variations on the definitions used in `options.databases`:
 *
 *   1. dbName: { data: "singlePath"} // One single file to be loaded, long notation.  No custom options.
 *   2. dbName: { data: ["path1", "path2"] } // Multiple files to be loaded, long notation, no custom options.
 *   3. dbName: { data: ["path1", "path2"], dbOptions: { db: memdown } } // Long notation, including additional custom database options.
 *   4. dbName: { dbOptions: { db: memdown} } // Long notation, no data, but with custom database options.
 *   5. dbName: {} // No data, no custom options.
 *
 * @param dbDef - The definition of a single database in any of the above formats.
 * @returns {Object} - An expanded record in Object form.
 *
 */
gpii.pouch.express.expandDbDef = function (dbDef) {
    var expandedDef = {};
    if (typeof dbDef === "object" && dbDef !== null && dbDef !== undefined) {
        expandedDef = dbDef;
        if (expandedDef.data) {
            expandedDef.data = fluid.makeArray(expandedDef.data);
        }
    }

    return expandedDef;
};

/**
 *
 * Initialize our instance of express-pouchdb.
 *
 * @param that
 * @returns {Object} - The expressPouchDB middleware.
 *
 */
gpii.pouch.express.initExpressPouchdb = function (that) {
    fluid.log("express pouchdb instance '", that.id, "' initalizing...");

    if (!that.options.baseDir) {
        fluid.fail("You must specify a basedir option...");
    }
    // Create our base directory if it doesn't already exist.
    else if (!fs.existsSync(that.options.baseDir)) {
        fluid.log("Creating directory '", that.options.baseDir, "' for express pouchdb instance '", that.id, "'...");
        fs.mkdirSync(that.options.baseDir);
        that.baseDirBelongsToUs = true;
    }

    // There are unfortunately options that can only be configured via a configuration file.
    //
    // To allow ourselves (and users configuring and extending this grade) to control these options, we create the file
    // with the contents of options.pouchConfig before configuring and starting express-pouchdb.
    fs.writeFileSync(that.options.expressPouchConfigPath, JSON.stringify(that.options.expressPouchConfig, null, 2));

    that.PouchDB = PouchDB.defaults(that.options.dbOptions);
    that.expressPouchdb = expressPouchdb(that.PouchDB, { configPath: that.options.expressPouchConfigPath });

    return that.expressPouchdb;
};

/**
 *
 * Initialize all of the configured databases in `that.options.database`.
 *
 * @param that
 * @returns {Promise} - A `fluid.promise.sequence` that will be resolved when all databases are initialized.
 *
 */
gpii.pouch.express.initDbs = function (that) {
    // We create our components programatically because we need:
    //
    //   1. To be notified when all databases are ready for use.  We do this with a `fluid.promise.sequence`.
    //   2. A way to clean up each database later on.  We do this by retaining a list of database instances.
    //   3. A way to know when all of them have been destroyed.  We do this with another `sequence` in our cleanup invoker (see below).
    //
    // I can think of ways to accomplish #2 with dynamic components, but not 1 and 3.
    // TODO: Review with Antranig.

    var promises = [];
    fluid.each(that.options.databases, function (dbOptions, dbKey) {
        promises.push(gpii.pouch.express.initDb(that, dbKey, dbOptions));
    });

    var sequence = fluid.promise.sequence(promises);
    sequence.then(function () {
        that.events.onStarted.fire();
    });

    return sequence;
};

/**
 *
 * Initialize a single database instance.
 *
 * @param that - The component itself
 * @param dbKey {String} - The database name.
 * @param dbDef {Object} - Our convention for representing multiple databases.  See the docs for examples.
 * @returns {Promise} A promise that will be resolved with the database is initialized.
 */
gpii.pouch.express.initDb = function (that, dbKey, dbDef) {
    var expandedDef = gpii.pouch.express.expandDbDef(dbDef);
    var dataLoadedPromise = fluid.promise();
    var dbOptions = expandedDef.dbOptions ? fluid.merge(that.options.dbOptions, expandedDef.dbOptions) : fluid.copy(that.options.dbOptions);
    dbOptions.name = dbKey;
    var dbComponentOptions = {
        type: "fluid.component",
        gradeNames: that.options.pouchGradeNames,
        dbOptions: dbOptions,
        baseDir: that.options.baseDir,
        listeners: {
            "onDataLoaded.resolvePromise": {
                func: dataLoadedPromise.resolve
            }
        }
    };
    if (expandedDef.data) {
        dbComponentOptions.dbPaths = expandedDef.data;
    }

    var dbComponent = fluid.construct("gpii_pouch_" + that.id + "_" + dbKey, dbComponentOptions);
    that.databaseInstances[dbKey] = dbComponent;

    var viewCleanupPromise = fluid.promise();

    dataLoadedPromise.then(function () {
        dbComponent.viewCleanup().then(viewCleanupPromise.resolve, viewCleanupPromise.reject);
    }, viewCleanupPromise.reject);

    return viewCleanupPromise;
};

/**
 *
 * Pass along any requests to our instance of express-pouchdb.
 *
 * @param that - The component itself.
 * @param req {Object} - The Express request object.
 * @param res {Object} - The Express response object.
 * @param next {Function} - The next piece of middleware in the chain.
 *
 */
gpii.pouch.express.middleware = function (that, req, res, next) {
    // fluid.log("express pouchdb instance '", that.id, "' responding...")
    that.expressPouchdb(req, res, next);
};

/**
 *
 * Clean up any instance of `gpii.pouchdb` that we're aware of.  Then, to get rid of databases created by
 * express-pouchdb, complete remove all data in `options.baseDir`.
 *
 * @param that - The component itself.
 * @returns {Promise} - A promise that will be resolved when cleanup is complete.
 *
 */
gpii.pouch.express.cleanup = function (that) {
    var tmpPouchDB = PouchDB.defaults({ db: memdown});
    var togo = fluid.promise();
    togo.then(that.events.onCleanupComplete.fire, that.events.onError.fire);

    that.expressPouchdb.setPouchDB(tmpPouchDB).then(function () {
        var cleanupPromises = [];

        fluid.each(that.databaseInstances, function (databaseInstance) {
            // Ensure that one cleanup at a time takes place.
            cleanupPromises.push(function () { return databaseInstance.destroyPouch(); });
        });

        var optionsFileCleanupPromise = fluid.promise();

        fs.unlink(that.options.expressPouchConfigPath, function (error) {
            if (error) {
                optionsFileCleanupPromise.reject(error);
            }
            else {
                optionsFileCleanupPromise.resolve();
            }
        });

        cleanupPromises.push(optionsFileCleanupPromise);

        var cleanupSequence = fluid.promise.sequence(cleanupPromises);
        cleanupSequence.then(function () {
            if (that.baseDirBelongsToUs) {
                rimraf(that.options.baseDir, function (error) {
                    if (error) {
                        fluid.log("ERROR: Unable to remove base directory...\n", error);
                    }
                    else {
                        fluid.log("Removed temporary directory '", that.options.baseDir, "'...");
                    }
                    togo.resolve();
                });
            }
            else {
                togo.resolve();
            }
        }, togo.reject);
    });

    return togo;
};

fluid.defaults("gpii.pouch.express.base", {
    gradeNames: ["fluid.component", "gpii.express.middleware"],
    method: "use", // We have to support all HTTP methods, as does our underlying router.
    path: "/",
    namespace: "pouch-express", // Namespace to allow other routers to put themselves in the chain before or after us.
    tmpDir:  os.tmpdir(),
    baseDir: "@expand:path.resolve({that}.options.tmpDir, {that}.id)",
    expressPouchConfigFilename: "config.json",
    expressPouchConfigPath:     "@expand:path.resolve({that}.options.baseDir, {that}.options.expressPouchConfigFilename)",
    expressPouchLogFilename:    "log.txt",
    expressPouchConfig: {
        // Disable the unused changes API to avoid a leaked listener.
        overrideMode: {
            exclude: ["routes/changes"]
        },
        log: {
            file: "@expand:path.resolve({that}.options.tmpDir, {that}.options.expressPouchLogFilename)"
        }
    },
    events: {
        initDbs:           null,
        onError:           null,
        onStarted:         null,
        onCleanup:         null,
        onCleanupComplete: null
    },
    members: {
        baseDirBelongsToUs: false, // Whether we created our working directory (and thus should clean it up when we're done).
        databaseInstances: {} // The actual PouchDB databases
    },
    pouchGradeNames: ["gpii.pouch.node.base"],
    databases: {}, // The configuration we will use to create the required databases on startup.
    listeners: {
        "initDbs.initExpressPouchdb": {
            priority: "first",
            funcName: "gpii.pouch.express.initExpressPouchdb",
            args:     ["{that}"]
        },
        "initDbs.initDbs": {
            priority: "last",
            func:     "{that}.initDbs"
        },
        "onCreate.initDbs": {
            func: "{that}.events.initDbs.fire"
        },
        "onCleanup.cleanup": {
            func: "{that}.cleanup"
        },
        "onCreate.log": {
            funcName: "fluid.log",
            args: ["express baseDir: '", "{that}.options.baseDir", "'..."]
        }
    },
    invokers: {
        middleware: {
            funcName: "gpii.pouch.express.middleware",
            args:     ["{that}", "{arguments}.0", "{arguments}.1", "{arguments}.2"] // request, response, next
        }
    }
});

fluid.defaults("gpii.pouch.express", {
    gradeNames: ["gpii.pouch.express.base"],
    pouchGradeNames: ["gpii.pouch.node"],
    dbOptions: {
        prefix: "@expand:gpii.pouch.node.makeSafePrefix({that}.options.baseDir)"
    },
    invokers: {
        cleanup: {
            funcName: "gpii.pouch.express.cleanup",
            args:     ["{that}"]
        },
        initDbs: {
            funcName: "gpii.pouch.express.initDbs",
            args:     ["{that}"]
        }
    }
});
<|endoftext|>


<commit_before>"use strict";
var stream      = require('stream');
var async       = require('async');
var util        = require('util');
var co          = require('co');
var _           = require('underscore');
var Q           = require('q');
var parsers     = require('./app/lib/streams/parsers/doc');
var constants   = require('./app/lib/constants');
var fileDAL     = require('./app/lib/dal/fileDAL');
var jsonpckg    = require('./package.json');
var router      = require('./app/lib/streams/router');
var base58      = require('./app/lib/base58');
var crypto      = require('./app/lib/crypto');
var signature   = require('./app/lib/signature');
var directory   = require('./app/lib/directory');
var dos2unix    = require('./app/lib/dos2unix');

function Server (dbConf, overrideConf) {

  stream.Duplex.call(this, { objectMode: true });

  let home = directory.getHome(dbConf.name, dbConf.home);
  var logger = require('./app/lib/logger')('server');
  var that = this;
  that.conf = null;
  that.dal = null;
  that.version = jsonpckg.version;

  that.MerkleService       = require("./app/service/MerkleService");
  that.ParametersService   = require("./app/service/ParametersService")();
  that.IdentityService     = require('./app/service/IdentityService')();
  that.MembershipService   = require('./app/service/MembershipService')();
  that.PeeringService      = require('./app/service/PeeringService')(that);
  that.BlockchainService   = require('./app/service/BlockchainService')();
  that.TransactionsService = require('./app/service/TransactionsService')();

  // Create document mapping
  let documentsMapping = {
    'identity':      that.IdentityService.submitIdentity,
    'certification': that.IdentityService.submitCertification,
    'revocation':    that.IdentityService.submitRevocation,
    'membership':    that.MembershipService.submitMembership,
    'peer':          that.PeeringService.submitP,
    'transaction':   that.TransactionsService.processTx,
    'block':         _.partial(that.BlockchainService.submitBlock, _, true)
  };

  // Unused, but made mandatory by Duplex interface
  this._read = () => null;

  this._write = (obj, enc, writeDone) => that.submit(obj, false, () => writeDone);

  this.plugFileSystem = () => co(function *() {
    logger.debug('Plugging file system...');
    var dbType = dbConf && dbConf.memory ? fileDAL.memory : fileDAL.file;
    that.dal = yield dbType(home);
  });

  this.loadConf = (useDefaultConf) => co(function *() {
    logger.debug('Loading conf...');
    that.conf = yield that.dal.loadConf(overrideConf, useDefaultConf);
    // Default values
    var defaultValues = {
      remoteipv6:         that.conf.ipv6,
      remoteport:         that.conf.port,
      cpu:                1,
      c:                  constants.CONTRACT.DEFAULT.C,
      dt:                 constants.CONTRACT.DEFAULT.DT,
      ud0:                constants.CONTRACT.DEFAULT.UD0,
      stepMax:            constants.CONTRACT.DEFAULT.STEPMAX,
      sigPeriod:          constants.CONTRACT.DEFAULT.SIGPERIOD,
      sigStock:           constants.CONTRACT.DEFAULT.SIGSTOCK,
      sigWindow:          constants.CONTRACT.DEFAULT.SIGWINDOW,
      sigValidity:        constants.CONTRACT.DEFAULT.SIGVALIDITY,
      msValidity:         constants.CONTRACT.DEFAULT.MSVALIDITY,
      sigQty:             constants.CONTRACT.DEFAULT.SIGQTY,
      xpercent:           constants.CONTRACT.DEFAULT.X_PERCENT,
      percentRot:         constants.CONTRACT.DEFAULT.PERCENTROT,
      blocksRot:          constants.CONTRACT.DEFAULT.BLOCKSROT,
      powDelay:           constants.CONTRACT.DEFAULT.POWDELAY,
      avgGenTime:         constants.CONTRACT.DEFAULT.AVGGENTIME,
      dtDiffEval:         constants.CONTRACT.DEFAULT.DTDIFFEVAL,
      medianTimeBlocks:   constants.CONTRACT.DEFAULT.MEDIANTIMEBLOCKS,
      rootoffset:         0,
      forksize:           constants.BRANCHES.DEFAULT_WINDOW_SIZE,
      pair:               constants.CRYPTO.DEFAULT_KEYPAIR
    };
    _.keys(defaultValues).forEach(function(key){
      if (that.conf[key] == undefined) {
        that.conf[key] = defaultValues[key];
      }
    });
    logger.debug('Loading crypto functions...');
    // Extract key pair
    let pair = null;
    if (that.conf.pair) {
      pair = {
        publicKey: base58.decode(that.conf.pair.pub),
        secretKey: base58.decode(that.conf.pair.sec)
      };
    }
    else if (that.conf.passwd || that.conf.salt) {
      pair = yield Q.nbind(crypto.getKeyPair, crypto)(that.conf.passwd, that.conf.salt);
    }
    if (!pair) {
      throw Error('This node does not have a keypair. Use `ucoind wizard key` to fix this.');
    }
    that.pair = pair;
    that.sign = signature.asyncSig(pair);
    // Update services
    [that.IdentityService, that.MembershipService, that.PeeringService, that.BlockchainService, that.TransactionsService].map((service) => {
      service.setConfDAL(that.conf, that.dal, that.pair);
    });
    return that.conf;
  });

  this.initWithDAL = () => co(function *() {
    yield that.plugFileSystem();
    yield that.loadConf();
    yield that.initDAL();
    return that;
  });

  this.submit = function (obj, isInnerWrite, done) {
    return co(function *() {
      if (!obj.documentType) {
        throw 'Document type not given';
      }
      try {
        let action = documentsMapping[obj.documentType];
        let res;
        if (typeof action == 'function') {
          // Handle the incoming object
          res = yield action(obj);
        } else {
          throw 'Unknown document type \'' + obj.documentType + '\'';
        }
        if (res) {
          // Only emit valid documents
          that.emit(obj.documentType, _.clone(res));
          that.push(_.clone(res));
        }
        if (done) {
          isInnerWrite ? done(null, res) : done();
        }
        return res;
      } catch (err) {
        logger.debug(err);
        if (done) {
          isInnerWrite ? done(err, null) : done();
        } else {
          throw err;
        }
      }
    });
  };

  this.submitP = (obj, isInnerWrite) => Q.nbind(this.submit, this)(obj, isInnerWrite);

  this.readConfFile = () => co(function *() {
    let dal = yield fileDAL.file(home);
    return yield dal.loadConf();
  });

  this.initDAL = () => this.dal.init();

  this.start = function () {
    return that.checkConfig()
      .then(function (){
        // Add signing & public key functions to PeeringService
        logger.info('Node version: ' + that.version);
        logger.info('Node pubkey: ' + that.PeeringService.pubkey);
        return Q.nfcall(that.initPeer);
      });
  };

  this.recomputeSelfPeer = function() {
    return Q.nbind(that.PeeringService.generateSelfPeer, that.PeeringService)(that.conf, 0);
  };

  this.initPeer = function (done) {
    async.waterfall([
      function (next){
        that.checkConfig().then(next).catch(next);
      },
      function (next){
        that.PeeringService.regularCrawlPeers(next);
      },
      function (next){
        logger.info('Storing self peer...');
        that.PeeringService.regularPeerSignal(next);
      },
      function(next) {
        that.PeeringService.regularTestPeers(next);
      },
      function (next){
        that.PeeringService.regularSyncBlock(next);
      },
      function (next){
        that.BlockchainService.regularCleanMemory(next);
      }
    ], done);
  };

  let shouldContinue = true;

  this.stopBlockComputation = function() {
    shouldContinue = false;
  };

  this.startBlockComputation = function() {
    return co(function *() {
      while (shouldContinue) {
        try {
          let block = yield that.BlockchainService.startGeneration();
          if (block && shouldContinue) {
            try {
              let obj = parsers.parseBlock.syncWrite(dos2unix(block.getRawSigned()));
              yield that.singleWritePromise(obj);
            } catch (err) {
              logger.warn('Proof-of-work self-submission: %s', err.message || err);
            }
          }
        }
        catch (e) {
          logger.error(e);
          shouldContinue = true;
        }
      }
    });
  };

  this.checkConfig = function () {
    return that.checkPeeringConf(that.conf);
  };

  this.checkPeeringConf = function (conf) {
    return Q()
      .then(function(){
        if (!conf.pair && conf.passwd == null) {
          throw new Error('No key password was given.');
        }
        if (!conf.pair && conf.salt == null) {
          throw new Error('No key salt was given.');
        }
        if (!conf.currency) {
          throw new Error('No currency name was given.');
        }
        if(!conf.ipv4 && !conf.ipv6){
          throw new Error("No interface to listen to.");
        }
        if(!conf.remoteipv4 && !conf.remoteipv6 && !conf.remotehost){
          throw new Error('No interface for remote contact.');
        }
        if (!conf.remoteport) {
          throw new Error('No port for remote contact.');
        }
      });
  };

  this.reset = function(done) {
    return that.dal.resetAll(done);
  };

  this.resetData = function(done) {
    return that.dal.resetData(done);
  };

  this.resetStats = function(done) {
    return that.dal.resetStats(done);
  };

  this.resetPeers = function(done) {
    return that.dal.resetPeers(done);
  };

  this.resetTxs = function(done) {
    that.dal.resetTransactions(done);
  };

  this.resetConf = function(done) {
    return that.dal.resetConf(done);
  };

  this.disconnect = function() {
    return that.dal && that.dal.close();
  };

  this.doMakeNextBlock = (manualValues) => that.BlockchainService.makeNextBlock(null, null, null, manualValues);

  this.doCheckBlock = function(block) {
    var parsed = parsers.parseBlock.syncWrite(block.getRawSigned());
    return that.BlockchainService.checkBlock(parsed, false);
  };

  this.revert = () => this.BlockchainService.revertCurrentBlock();

  this.revertTo = (number) => co(function *() {
    let current = yield that.BlockchainService.current();
    for (let i = 0, count = current.number - number; i < count; i++) {
      yield that.BlockchainService.revertCurrentBlock();
    }
    if (current.number <= number) {
      logger.warn('Already reached');
    }
    that.BlockchainService.revertCurrentBlock();
  });

  this.singleWritePromise = (obj) => that.submit(obj);

  var theRouter;

  this.router = function() {
    if (!theRouter) {
      theRouter = router(that.PeeringService.pubkey, that.conf, that.dal);
    }
    return theRouter;
  };

}

util.inherits(Server, stream.Duplex);

module.exports = Server;
<commit_msg>Fix: make tests pass<commit_after>"use strict";
var stream      = require('stream');
var async       = require('async');
var util        = require('util');
var co          = require('co');
var _           = require('underscore');
var Q           = require('q');
var parsers     = require('./app/lib/streams/parsers/doc');
var constants   = require('./app/lib/constants');
var fileDAL     = require('./app/lib/dal/fileDAL');
var jsonpckg    = require('./package.json');
var router      = require('./app/lib/streams/router');
var base58      = require('./app/lib/base58');
var crypto      = require('./app/lib/crypto');
var signature   = require('./app/lib/signature');
var directory   = require('./app/lib/directory');
var dos2unix    = require('./app/lib/dos2unix');

function Server (dbConf, overrideConf) {

  stream.Duplex.call(this, { objectMode: true });

  let home = directory.getHome(dbConf.name, dbConf.home);
  var logger = require('./app/lib/logger')('server');
  var that = this;
  that.conf = null;
  that.dal = null;
  that.version = jsonpckg.version;

  that.MerkleService       = require("./app/service/MerkleService");
  that.ParametersService   = require("./app/service/ParametersService")();
  that.IdentityService     = require('./app/service/IdentityService')();
  that.MembershipService   = require('./app/service/MembershipService')();
  that.PeeringService      = require('./app/service/PeeringService')(that);
  that.BlockchainService   = require('./app/service/BlockchainService')();
  that.TransactionsService = require('./app/service/TransactionsService')();

  // Create document mapping
  let documentsMapping = {
    'identity':      that.IdentityService.submitIdentity,
    'certification': that.IdentityService.submitCertification,
    'revocation':    that.IdentityService.submitRevocation,
    'membership':    that.MembershipService.submitMembership,
    'peer':          that.PeeringService.submitP,
    'transaction':   that.TransactionsService.processTx,
    'block':         _.partial(that.BlockchainService.submitBlock, _, true)
  };

  // Unused, but made mandatory by Duplex interface
  this._read = () => null;

  this._write = (obj, enc, writeDone) => that.submit(obj, false, () => writeDone);

  this.plugFileSystem = () => co(function *() {
    logger.debug('Plugging file system...');
    var dbType = dbConf && dbConf.memory ? fileDAL.memory : fileDAL.file;
    that.dal = yield dbType(home);
  });

  this.loadConf = (useDefaultConf) => co(function *() {
    logger.debug('Loading conf...');
    that.conf = yield that.dal.loadConf(overrideConf, useDefaultConf);
    // Default values
    var defaultValues = {
      remoteipv6:         that.conf.ipv6,
      remoteport:         that.conf.port,
      cpu:                1,
      c:                  constants.CONTRACT.DEFAULT.C,
      dt:                 constants.CONTRACT.DEFAULT.DT,
      ud0:                constants.CONTRACT.DEFAULT.UD0,
      stepMax:            constants.CONTRACT.DEFAULT.STEPMAX,
      sigPeriod:          constants.CONTRACT.DEFAULT.SIGPERIOD,
      sigStock:           constants.CONTRACT.DEFAULT.SIGSTOCK,
      sigWindow:          constants.CONTRACT.DEFAULT.SIGWINDOW,
      sigValidity:        constants.CONTRACT.DEFAULT.SIGVALIDITY,
      msValidity:         constants.CONTRACT.DEFAULT.MSVALIDITY,
      sigQty:             constants.CONTRACT.DEFAULT.SIGQTY,
      xpercent:           constants.CONTRACT.DEFAULT.X_PERCENT,
      percentRot:         constants.CONTRACT.DEFAULT.PERCENTROT,
      blocksRot:          constants.CONTRACT.DEFAULT.BLOCKSROT,
      powDelay:           constants.CONTRACT.DEFAULT.POWDELAY,
      avgGenTime:         constants.CONTRACT.DEFAULT.AVGGENTIME,
      dtDiffEval:         constants.CONTRACT.DEFAULT.DTDIFFEVAL,
      medianTimeBlocks:   constants.CONTRACT.DEFAULT.MEDIANTIMEBLOCKS,
      rootoffset:         0,
      forksize:           constants.BRANCHES.DEFAULT_WINDOW_SIZE
    };
    _.keys(defaultValues).forEach(function(key){
      if (that.conf[key] == undefined) {
        that.conf[key] = defaultValues[key];
      }
    });
    logger.debug('Loading crypto functions...');
    // Extract key pair
    let pair = null;
    if (that.conf.pair) {
      pair = {
        publicKey: base58.decode(that.conf.pair.pub),
        secretKey: base58.decode(that.conf.pair.sec)
      };
    }
    else if (that.conf.passwd || that.conf.salt) {
      pair = yield Q.nbind(crypto.getKeyPair, crypto)(that.conf.passwd, that.conf.salt);
    }
    else {
      pair = {
        publicKey: base58.decode(constants.CRYPTO.DEFAULT_KEYPAIR.pub),
        secretKey: base58.decode(constants.CRYPTO.DEFAULT_KEYPAIR.sec)
      };
    }
    if (!pair) {
      throw Error('This node does not have a keypair. Use `ucoind wizard key` to fix this.');
    }
    that.pair = pair;
    that.sign = signature.asyncSig(pair);
    // Update services
    [that.IdentityService, that.MembershipService, that.PeeringService, that.BlockchainService, that.TransactionsService].map((service) => {
      service.setConfDAL(that.conf, that.dal, that.pair);
    });
    return that.conf;
  });

  this.initWithDAL = () => co(function *() {
    yield that.plugFileSystem();
    yield that.loadConf();
    yield that.initDAL();
    return that;
  });

  this.submit = function (obj, isInnerWrite, done) {
    return co(function *() {
      if (!obj.documentType) {
        throw 'Document type not given';
      }
      try {
        let action = documentsMapping[obj.documentType];
        let res;
        if (typeof action == 'function') {
          // Handle the incoming object
          res = yield action(obj);
        } else {
          throw 'Unknown document type \'' + obj.documentType + '\'';
        }
        if (res) {
          // Only emit valid documents
          that.emit(obj.documentType, _.clone(res));
          that.push(_.clone(res));
        }
        if (done) {
          isInnerWrite ? done(null, res) : done();
        }
        return res;
      } catch (err) {
        logger.debug(err);
        if (done) {
          isInnerWrite ? done(err, null) : done();
        } else {
          throw err;
        }
      }
    });
  };

  this.submitP = (obj, isInnerWrite) => Q.nbind(this.submit, this)(obj, isInnerWrite);

  this.readConfFile = () => co(function *() {
    let dal = yield fileDAL.file(home);
    return yield dal.loadConf();
  });

  this.initDAL = () => this.dal.init();

  this.start = function () {
    return that.checkConfig()
      .then(function (){
        // Add signing & public key functions to PeeringService
        logger.info('Node version: ' + that.version);
        logger.info('Node pubkey: ' + that.PeeringService.pubkey);
        return Q.nfcall(that.initPeer);
      });
  };

  this.recomputeSelfPeer = function() {
    return Q.nbind(that.PeeringService.generateSelfPeer, that.PeeringService)(that.conf, 0);
  };

  this.initPeer = function (done) {
    async.waterfall([
      function (next){
        that.checkConfig().then(next).catch(next);
      },
      function (next){
        that.PeeringService.regularCrawlPeers(next);
      },
      function (next){
        logger.info('Storing self peer...');
        that.PeeringService.regularPeerSignal(next);
      },
      function(next) {
        that.PeeringService.regularTestPeers(next);
      },
      function (next){
        that.PeeringService.regularSyncBlock(next);
      },
      function (next){
        that.BlockchainService.regularCleanMemory(next);
      }
    ], done);
  };

  let shouldContinue = true;

  this.stopBlockComputation = function() {
    shouldContinue = false;
  };

  this.startBlockComputation = function() {
    return co(function *() {
      while (shouldContinue) {
        try {
          let block = yield that.BlockchainService.startGeneration();
          if (block && shouldContinue) {
            try {
              let obj = parsers.parseBlock.syncWrite(dos2unix(block.getRawSigned()));
              yield that.singleWritePromise(obj);
            } catch (err) {
              logger.warn('Proof-of-work self-submission: %s', err.message || err);
            }
          }
        }
        catch (e) {
          logger.error(e);
          shouldContinue = true;
        }
      }
    });
  };

  this.checkConfig = function () {
    return that.checkPeeringConf(that.conf);
  };

  this.checkPeeringConf = function (conf) {
    return Q()
      .then(function(){
        if (!conf.pair && conf.passwd == null) {
          throw new Error('No key password was given.');
        }
        if (!conf.pair && conf.salt == null) {
          throw new Error('No key salt was given.');
        }
        if (!conf.currency) {
          throw new Error('No currency name was given.');
        }
        if(!conf.ipv4 && !conf.ipv6){
          throw new Error("No interface to listen to.");
        }
        if(!conf.remoteipv4 && !conf.remoteipv6 && !conf.remotehost){
          throw new Error('No interface for remote contact.');
        }
        if (!conf.remoteport) {
          throw new Error('No port for remote contact.');
        }
      });
  };

  this.reset = function(done) {
    return that.dal.resetAll(done);
  };

  this.resetData = function(done) {
    return that.dal.resetData(done);
  };

  this.resetStats = function(done) {
    return that.dal.resetStats(done);
  };

  this.resetPeers = function(done) {
    return that.dal.resetPeers(done);
  };

  this.resetTxs = function(done) {
    that.dal.resetTransactions(done);
  };

  this.resetConf = function(done) {
    return that.dal.resetConf(done);
  };

  this.disconnect = function() {
    return that.dal && that.dal.close();
  };

  this.doMakeNextBlock = (manualValues) => that.BlockchainService.makeNextBlock(null, null, null, manualValues);

  this.doCheckBlock = function(block) {
    var parsed = parsers.parseBlock.syncWrite(block.getRawSigned());
    return that.BlockchainService.checkBlock(parsed, false);
  };

  this.revert = () => this.BlockchainService.revertCurrentBlock();

  this.revertTo = (number) => co(function *() {
    let current = yield that.BlockchainService.current();
    for (let i = 0, count = current.number - number; i < count; i++) {
      yield that.BlockchainService.revertCurrentBlock();
    }
    if (current.number <= number) {
      logger.warn('Already reached');
    }
    that.BlockchainService.revertCurrentBlock();
  });

  this.singleWritePromise = (obj) => that.submit(obj);

  var theRouter;

  this.router = function() {
    if (!theRouter) {
      theRouter = router(that.PeeringService.pubkey, that.conf, that.dal);
    }
    return theRouter;
  };

}

util.inherits(Server, stream.Duplex);

module.exports = Server;
<|endoftext|>


<commit_before>var fs = require('fs');
var child_process = require('child_process')
var max_sleep = 300
//Added a comment that achieves no real goal.

var commit_messages = [
  "Fixing an important issue with the universe.",
  "Someone poisoned the waterhole!",
  "You feeling lucky punk?",
  "Five bullets or six?",<commit_msg>Updated the readme again<commit_after>var fs = require('fs');
var child_process = require('child_process')
var max_sleep = 300
//Added a comment that achieves no real goal.

var commit_messages = [
  "Fixing an important issue with the universe.",
  "Someone poisoned the waterhole!",
  "You feeling lucky punk?",
  "Five bullets or six?",
<|endoftext|>


<commit_before>var fs = require('fs');
var child_process = require('child_process')
var max_sleep = 300

if ( process.argv[ 2 ] && process.argv[ 3 ] ) {
  var inFile = process.argv[ 2 ]
  var outFile = process.argv[ 3 ]
  if (process.argv [ 4 ]) max_sleep = process.argv [ 4 ]
  console.info("Writing from %s to %s, with up to %s seconds between commits", inFile, outFile, max_sleep)
  var outFD = f<commit_msg>Update character<commit_after>var fs = require('fs');
var child_process = require('child_process')
var max_sleep = 300

if ( process.argv[ 2 ] && process.argv[ 3 ] ) {
  var inFile = process.argv[ 2 ]
  var outFile = process.argv[ 3 ]
  if (process.argv [ 4 ]) max_sleep = process.argv [ 4 ]
  console.info("Writing from %s to %s, with up to %s seconds between commits", inFile, outFile, max_sleep)
  var outFD = fs<|endoftext|>


<commit_before>import React, {Component} from 'react';
import {filter, groupBy, sortBy as _sortBy} from 'lodash';
import {isPast, parse, format} from 'date-fns';
import {connectHits} from 'react-instantsearch/connectors';

import Heading from '../Heading';
import Divider from '../Divider';
import ConferenceItem from '../ConferenceItem';
import styles from './ConferenceList.css';

class ConferenceList extends Component {
  renderConferences = (conferences) => {
    const {showCFP} = this.props;
    return (

        {getConfsMonthsSorted(conferences).map((monthKey) => {
          const month = monthKey.split('-')[1];
          return (
            <Months
              key={monthKey}
              month={month}
              showCFP={showCFP}
              conferences={conferences[monthKey]}
            />
          );
        })}

    );
  };

  render() {
    const {hits, showCFP, sortBy} = this.props;
    let filteredConferences = hits;
    if (showCFP) {
      filteredConferences = filter(hits, (conf) => {
        return conf.cfpEndDate && !isPast(parse(conf.cfpEndDate));
      });
    }
    const confs = groupAndSortConferences(filteredConferences, sortBy);

    if (Object.keys(confs).length === 0) {
      return (
{"Oh shoot! We don't have any conferences yet."}
);
    }

    const confsTable = Object.keys(confs).map((year) => {
      return [
        <Divider key="hr" />,
        <Year key={year} year={year} />,
        this.renderConferences(confs[year]),
      ];
    });

    return (
{confsTable}
);
  }
}

function groupAndSortConferences(conferences, sortBy = 'startDate') {
  // Group conferences by year
  const confs = groupBy(conferences, (conf) =>
    format(conf[sortBy], 'YYYY')
  );

  // Group conferences by month within the year
  Object.keys(confs).map((year) => {
    confs[year] = groupBy(confs[year], (conf) =>
      format(conf[sortBy], 'YYYY-MM')
    );
    Object.keys(confs[year]).map((month) => {
      confs[year][month] = _sortBy(confs[year][month], (conference) =>
        conference[sortBy]
      );
    });
  });

  return confs;
}

function getMonthName(month) {
  return format(parse(`2017/${month}/01`), 'MMMM');
}

function Months({month, conferences, showCFP}) {
  return [
    <Heading key={month} element="h2" level={3}>
      {getMonthName(month)}
    </Heading>,
    conferences.map((conf) => {
      return (
        <ConferenceItem
          {...conf}
          key={`${conf.url} ${conf.date}`}
          showCFP={showCFP}
        />
      );
    }),
  ];
}

function Year({year}) {
  return (

      <Heading key={year} element="h2" level={2}>
        {year}
      </Heading>

  );
}

function getConfsMonthsSorted(conferences) {
  return _sortBy(Object.keys(conferences), (conference) => {
    return parseInt(conference.replace('-', ''), 10);
  });
}

export default connectHits(ConferenceList);
<commit_msg>Remove empty state<commit_after>import React, {Component} from 'react';
import {filter, groupBy, sortBy as _sortBy} from 'lodash';
import {isPast, parse, format} from 'date-fns';
import {connectHits} from 'react-instantsearch/connectors';

import Heading from '../Heading';
import Divider from '../Divider';
import ConferenceItem from '../ConferenceItem';
import styles from './ConferenceList.css';

class ConferenceList extends Component {
  renderConferences = (conferences) => {
    const {showCFP} = this.props;
    return (

        {getConfsMonthsSorted(conferences).map((monthKey) => {
          const month = monthKey.split('-')[1];
          return (
            <Months
              key={monthKey}
              month={month}
              showCFP={showCFP}
              conferences={conferences[monthKey]}
            />
          );
        })}

    );
  };

  render() {
    const {hits, showCFP, sortBy} = this.props;
    let filteredConferences = hits;
    if (showCFP) {
      filteredConferences = filter(hits, (conf) => {
        return conf.cfpEndDate && !isPast(parse(conf.cfpEndDate));
      });
    }
    const confs = groupAndSortConferences(filteredConferences, sortBy);

    const confsTable = Object.keys(confs).map((year) => {
      return [
        <Divider key="hr" />,
        <Year key={year} year={year} />,
        this.renderConferences(confs[year]),
      ];
    });

    return (
{confsTable}
);
  }
}

function groupAndSortConferences(conferences, sortBy = 'startDate') {
  // Group conferences by year
  const confs = groupBy(conferences, (conf) =>
    format(conf[sortBy], 'YYYY')
  );

  // Group conferences by month within the year
  Object.keys(confs).map((year) => {
    confs[year] = groupBy(confs[year], (conf) =>
      format(conf[sortBy], 'YYYY-MM')
    );
    Object.keys(confs[year]).map((month) => {
      confs[year][month] = _sortBy(confs[year][month], (conference) =>
        conference[sortBy]
      );
    });
  });

  return confs;
}

function getMonthName(month) {
  return format(parse(`2017/${month}/01`), 'MMMM');
}

function Months({month, conferences, showCFP}) {
  return [
    <Heading key={month} element="h2" level={3}>
      {getMonthName(month)}
    </Heading>,
    conferences.map((conf) => {
      return (
        <ConferenceItem
          {...conf}
          key={`${conf.url} ${conf.date}`}
          showCFP={showCFP}
        />
      );
    }),
  ];
}

function Year({year}) {
  return (

      <Heading key={year} element="h2" level={2}>
        {year}
      </Heading>

  );
}

function getConfsMonthsSorted(conferences) {
  return _sortBy(Object.keys(conferences), (conference) => {
    return parseInt(conference.replace('-', ''), 10);
  });
}

export default connectHits(ConferenceList);
<|endoftext|>