<commit_before>/**
 * @license
 * Copyright 2012 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
if ( ! String.prototype.startsWith ) {
  String.prototype.startsWith = function (a) { return 0 == this.lastIndexOf(a, 0); };
}

String.prototype.equalsIC = function(other) {
  return other && this.toUpperCase() === other.toUpperCase();
};

String.prototype.capitalize = function() {
  return this.charAt(0).toUpperCase() + this.slice(1);
};

String.prototype.labelize = function() {
  return this.replace(/[a-z][A-Z]/g, function (a) {
    return a.charAt(0) + ' ' + a.charAt(1);
  }).capitalize();
};

// switchFromCamelCaseToConstantFormat to SWITCH_FROM_CAMEL_CASE_TO_CONSTANT_FORMAT
String.prototype.constantize = function() {
    return this.replace(/[a-z][^a-z]/g, function(a) { return a.substring(0,1) + '_' + a.substring(1,2); }).toUpperCase();
};

/** Give all objects a Unique ID. **/
Object.defineProperty(Object.prototype, '$UID', {
  get: (function() {
    var id = 1;

    return function() {
      return this.$UID__ || (this.$UID__ = id++);
    };
  })()
});

/** Create a function which always returns the supplied constant value. **/
function constantFn(v) { return function() { return v; }; }

/**
 * Replace Function.bind with a version
 * which is ~10X faster for the common case
 * where you're only binding 'this'.
 **/
Function.prototype.bind = (function() {
  var oldBind    = Function.prototype.bind;
  var simpleBind = function(f, self) {
    var ret = function() { return f.apply(self, arguments); };
    ret.toString = function() {
      return f.toString();
    };
    return ret;
  };

  return function() {
    return arguments.length == 1 ? simpleBind(this, arguments[0]) : oldBind.apply(this, arguments);
  };
})();

// Define extensions to built-in prototypes as non-enumerable properties so
// that they don't mess up with Array or Object iteration code.
// (Which needs to be fixed anyway.)

Date.prototype.compareTo = function(o) {
  if ( o === this ) return 0;
  var d = this.getTime() - o.getTime();
  return d == 0 ? 0 : d > 0 ? 1 : -1;
};

String.prototype.compareTo = function(o) {
  if ( o == this ) return 0;
  return this < o ? -1 : 1;
};

Number.prototype.compareTo = function(o) {
  if ( o === this ) return 0;
  return this < o ? -1 : 1;
};

Boolean.prototype.compareTo = function(o) {
  return (this.valueOf() ? 1 : 0) - (o ? 1 : 0);
};

var argsToArray = function(args) {
  return Array.prototype.slice.call(args);
};

var StringComparator = function(s1, s2) {
  if ( s1 == s2 ) return 0;
  return s1 < s2 ? -1 : 1;
};

var toCompare = function(c) {
  if ( Array.isArray(c) ) return CompoundComparator.apply(null, c);

  return c.compare ? c.compare.bind(c) : c;
};

Object.defineProperty(Array.prototype, 'intern', {
  value: function() {
    for ( var i = 0 ; i < this.length ; i++ )
      if ( this[i].intern ) this[i] = this[i].intern();

    return this;
  }
});

Object.defineProperty(Array.prototype, 'fReduce', {
  value: function(comparator, arr) {
    compare = toCompare(comparator);
    var result = [];

    var i = 0;
    var j = 0;
    var k = 0;
    while(i < this.length && j < arr.length) {
      var a = compare(this[i], arr[j]);
      if ( a < 0 ) {
        result[k++] = this[i++];
        continue;
      }
      if ( a == 0) {
        result[k++] = this[i++];
        result[k++] = arr[j++];
        continue;
      }
      result[k++] = arr[j++];
    }

    if ( i != this.length ) result = result.concat(this.slice(i));
    if ( j != arr.length ) result = result.concat(arr.slice(j));

    return result;
  }
});

/** Reverse the direction of a comparator. **/
var DESC = function(c) {
  if ( c.isDESC ) return toCompare(c.c);

  var p = toCompare(c);

  if ( typeof p !== 'function' ) throw 'Invalid comparator in DESC';

  var f = function(o1, o2) { return p(o2,o1); };
  f.c = c;
  f.isDESC = true;

  return f;
};

var CompoundComparator = function() {
  var cs = arguments;

  // Convert objects with .compare() methods to compare functions.
  for ( var i = 0 ; i < cs.length ; i++ )
    cs[i] = toCompare(cs[i]);

  return function(o1, o2) {
    for ( var i = 0 ; i < cs.length ; i++ ) {
      var r = cs[i](o1, o2);
      if ( r != 0 ) return r;
    }
    return 0;
  };
};

/**
 * Take an array where even values are weights and odd values are functions,
 * and execute one of the functions with propability equal to it's relative
 * weight.
 */
// TODO: move this method somewhere better
function randomAct() {
  var totalWeight = 0.0;
  for ( var i = 0 ; i < arguments.length ; i += 2 ) totalWeight += arguments[i];

  var r = Math.random();

  for ( var i = 0, weight = 0 ; i < arguments.length ; i += 2 ) {
    weight += arguments[i];
    if ( r <= weight / totalWeight ) {
      arguments[i+1]();
      return;
    }
  }
}

function defineProperties(proto, fns) {
  for ( var key in fns ) {
    try {
      Object.defineProperty(proto, key, {
        value: fns[key],
        configurable: true,
        writable: true
      });
    } catch (x) {
      console.log('Warning: ' + x);
    }
  }
}

/**
 * Push an array of values onto an array.
 * @param arr array of values
 * @return new length of this array
 */
// TODO: not needed, port and replace with pipe()
Object.defineProperty(Array.prototype, 'pushAll', {
  value: function(arr) {
    this.push.apply(this, arr);
    return this.length;
}});

/**
 * Search for a single element in an array.
 * @param predicate used to determine element to find
 * @param action to be called with (key, index) arguments
 *        when found
 */
/*
Object.defineProperty(Array.prototype, 'find', {
  value: function(predicate, action) {
  for (var i=0; i<this.length; i++)
    if (predicate(this[i], i)) {
      return action(this[i], i) || this[i];
    }
  return undefined;
}});
*/

/** Remove an element from an array. **/
/*
Object.defineProperty(Array.prototype, 'remove', {
  value: function(obj) {
    var i = this.indexOf(obj);

    if ( i != -1 ) this.splice(i, 1);

    return this;
}});
*/

/**
 * ForEach operator on Objects.
 * Calls function with arguments (obj, key).
 **/
/*
Object.defineProperty(Object.prototype, 'forEach', {
  value: function(fn) {
    for ( var key in this ) if (this.hasOwnProperty(key)) fn(this[key], key);
}});*/

// Workaround for crbug.com/258522
function Object_forEach(obj, fn) {
  for (var key in obj) if (obj.hasOwnProperty(key)) fn(obj[key], key);
}

/*
Object.defineProperty(Object.prototype, 'put', {
  value: function(obj) {
    this[obj.id] = obj;
  },
  configurable: true,
  writable: true
});
*/

function predicatedSink(predicate, sink) {
  if ( predicate === TRUE ) return sink;

  return {
    __proto__: sink,
    put: function(obj, s, fc) {
      if ( sink && predicate.f(obj) ) sink.put(obj, s, fc);
    }/*,
    eof: function() {
      sink && sink.eof && sink.eof();
    }*/
  };
}

function limitedSink(count, sink) {
  var i = 0;
  return {
    __proto__: sink,
    put: function(obj, s, fc) {
      if ( i++ >= count && fc ) {
        fc.stop();
      } else {
        sink.put(obj, s, fc);
      }
    }/*,
    eof: function() {
      sink.eof && sink.eof();
    }*/
  };
}

function skipSink(skip, sink) {
  var i = 0;
  return {
    __proto__: sink,
    put: function(obj, s, fc) {
      if ( i++ >= skip ) sink.put(obj, s, fc);
    }
  };
}

function orderedSink(comparator, sink) {
  comparator = toCompare(comparator);
  return {
    __proto__: sink,
    i: 0,
    arr: [],
    put: function(obj, s, fc) {
      this.arr.push(obj);
    },
    eof: function() {
      this.arr.sort(comparator);
      this.arr.select(sink);
    }
  };
}

console.log.json = function() {
   var args = [];
   for ( var i = 0 ; i < arguments.length ; i++ ) {
     var arg = arguments[i];
     args.push(arg && arg.toJSON ? arg.toJSON() : arg);
   }
   console.log.apply(console, args);
};

console.log.str = function() {
   var args = [];
   for ( var i = 0 ; i < arguments.length ; i++ ) {
     var arg = arguments[i];
     args.push(arg && arg.toString ? arg.toString() : arg);
   }
   console.log.apply(console, args);
};

// Promote 'console.log' into a Sink
console.log.put         = console.log.bind(console);
console.log.remove      = console.log.bind(console, 'remove: ');
console.log.error       = console.log.bind(console, 'error: ');
console.log.json.put    = console.log.json.bind(console);
console.log.json.reduceI = console.log.json.bind(console, 'reduceI: ');
console.log.json.remove = console.log.json.bind(console, 'remove: ');
console.log.json.error  = console.log.json.bind(console, 'error: ');
console.log.str.put     = console.log.str.bind(console);
console.log.str.remove  = console.log.str.bind(console, 'remove: ');
console.log.str.error  = console.log.str.bind(console, 'error: ');

document.put = function(obj) {
  if ( obj.write ) {
    obj.write(this);
  } else {
    this.write(obj.toString());
  }
};

String.prototype.put = function(obj) { return this + obj.toJSON(); };

// Promote webkit apis

window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem;
window.requestAnimationFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame;

if (window.Blob) {
  Blob.prototype.slice = Blob.prototype.slice || Blob.prototype.webkitSlice;
}

/** Convert a string to an internal canonical copy. **/
String.prototype.intern = (function() {
  var map = {};

  return function() { return map[this] || (map[this] = this.toString()); };
})();

if (window.XMLHttpRequest) {
  /**
      * Add an afunc send to XMLHttpRequest
  */
  XMLHttpRequest.prototype.asend = function(ret, opt_data) {
    var xhr = this;
    xhr.onerror = function() {
      console.log('XHR Error: ', arguments);
    };
    xhr.onloadend = function() {
      ret(xhr.response, xhr);
    };
    xhr.send(opt_data);
  };
}

RegExp.quote = function(str) {
  return (str+'').replace(/([.?*+^$[\]\\(){}|-])/g, '\\$1');
};
<commit_msg>Use == in Number.prototype.compareTo.<commit_after>/**
 * @license
 * Copyright 2012 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
if ( ! String.prototype.startsWith ) {
  String.prototype.startsWith = function (a) { return 0 == this.lastIndexOf(a, 0); };
}

String.prototype.equalsIC = function(other) {
  return other && this.toUpperCase() === other.toUpperCase();
};

String.prototype.capitalize = function() {
  return this.charAt(0).toUpperCase() + this.slice(1);
};

String.prototype.labelize = function() {
  return this.replace(/[a-z][A-Z]/g, function (a) {
    return a.charAt(0) + ' ' + a.charAt(1);
  }).capitalize();
};

// switchFromCamelCaseToConstantFormat to SWITCH_FROM_CAMEL_CASE_TO_CONSTANT_FORMAT
String.prototype.constantize = function() {
    return this.replace(/[a-z][^a-z]/g, function(a) { return a.substring(0,1) + '_' + a.substring(1,2); }).toUpperCase();
};

/** Give all objects a Unique ID. **/
Object.defineProperty(Object.prototype, '$UID', {
  get: (function() {
    var id = 1;

    return function() {
      return this.$UID__ || (this.$UID__ = id++);
    };
  })()
});

/** Create a function which always returns the supplied constant value. **/
function constantFn(v) { return function() { return v; }; }

/**
 * Replace Function.bind with a version
 * which is ~10X faster for the common case
 * where you're only binding 'this'.
 **/
Function.prototype.bind = (function() {
  var oldBind    = Function.prototype.bind;
  var simpleBind = function(f, self) {
    var ret = function() { return f.apply(self, arguments); };
    ret.toString = function() {
      return f.toString();
    };
    return ret;
  };

  return function() {
    return arguments.length == 1 ? simpleBind(this, arguments[0]) : oldBind.apply(this, arguments);
  };
})();

// Define extensions to built-in prototypes as non-enumerable properties so
// that they don't mess up with Array or Object iteration code.
// (Which needs to be fixed anyway.)

Date.prototype.compareTo = function(o) {
  if ( o === this ) return 0;
  var d = this.getTime() - o.getTime();
  return d == 0 ? 0 : d > 0 ? 1 : -1;
};

String.prototype.compareTo = function(o) {
  if ( o == this ) return 0;
  return this < o ? -1 : 1;
};

Number.prototype.compareTo = function(o) {
  if ( o == this ) return 0;
  return this < o ? -1 : 1;
};

Boolean.prototype.compareTo = function(o) {
  return (this.valueOf() ? 1 : 0) - (o ? 1 : 0);
};

var argsToArray = function(args) {
  return Array.prototype.slice.call(args);
};

var StringComparator = function(s1, s2) {
  if ( s1 == s2 ) return 0;
  return s1 < s2 ? -1 : 1;
};

var toCompare = function(c) {
  if ( Array.isArray(c) ) return CompoundComparator.apply(null, c);

  return c.compare ? c.compare.bind(c) : c;
};

Object.defineProperty(Array.prototype, 'intern', {
  value: function() {
    for ( var i = 0 ; i < this.length ; i++ )
      if ( this[i].intern ) this[i] = this[i].intern();

    return this;
  }
});

Object.defineProperty(Array.prototype, 'fReduce', {
  value: function(comparator, arr) {
    compare = toCompare(comparator);
    var result = [];

    var i = 0;
    var j = 0;
    var k = 0;
    while(i < this.length && j < arr.length) {
      var a = compare(this[i], arr[j]);
      if ( a < 0 ) {
        result[k++] = this[i++];
        continue;
      }
      if ( a == 0) {
        result[k++] = this[i++];
        result[k++] = arr[j++];
        continue;
      }
      result[k++] = arr[j++];
    }

    if ( i != this.length ) result = result.concat(this.slice(i));
    if ( j != arr.length ) result = result.concat(arr.slice(j));

    return result;
  }
});

/** Reverse the direction of a comparator. **/
var DESC = function(c) {
  if ( c.isDESC ) return toCompare(c.c);

  var p = toCompare(c);

  if ( typeof p !== 'function' ) throw 'Invalid comparator in DESC';

  var f = function(o1, o2) { return p(o2,o1); };
  f.c = c;
  f.isDESC = true;

  return f;
};

var CompoundComparator = function() {
  var cs = arguments;

  // Convert objects with .compare() methods to compare functions.
  for ( var i = 0 ; i < cs.length ; i++ )
    cs[i] = toCompare(cs[i]);

  return function(o1, o2) {
    for ( var i = 0 ; i < cs.length ; i++ ) {
      var r = cs[i](o1, o2);
      if ( r != 0 ) return r;
    }
    return 0;
  };
};

/**
 * Take an array where even values are weights and odd values are functions,
 * and execute one of the functions with propability equal to it's relative
 * weight.
 */
// TODO: move this method somewhere better
function randomAct() {
  var totalWeight = 0.0;
  for ( var i = 0 ; i < arguments.length ; i += 2 ) totalWeight += arguments[i];

  var r = Math.random();

  for ( var i = 0, weight = 0 ; i < arguments.length ; i += 2 ) {
    weight += arguments[i];
    if ( r <= weight / totalWeight ) {
      arguments[i+1]();
      return;
    }
  }
}

function defineProperties(proto, fns) {
  for ( var key in fns ) {
    try {
      Object.defineProperty(proto, key, {
        value: fns[key],
        configurable: true,
        writable: true
      });
    } catch (x) {
      console.log('Warning: ' + x);
    }
  }
}

/**
 * Push an array of values onto an array.
 * @param arr array of values
 * @return new length of this array
 */
// TODO: not needed, port and replace with pipe()
Object.defineProperty(Array.prototype, 'pushAll', {
  value: function(arr) {
    this.push.apply(this, arr);
    return this.length;
}});

/**
 * Search for a single element in an array.
 * @param predicate used to determine element to find
 * @param action to be called with (key, index) arguments
 *        when found
 */
/*
Object.defineProperty(Array.prototype, 'find', {
  value: function(predicate, action) {
  for (var i=0; i<this.length; i++)
    if (predicate(this[i], i)) {
      return action(this[i], i) || this[i];
    }
  return undefined;
}});
*/

/** Remove an element from an array. **/
/*
Object.defineProperty(Array.prototype, 'remove', {
  value: function(obj) {
    var i = this.indexOf(obj);

    if ( i != -1 ) this.splice(i, 1);

    return this;
}});
*/

/**
 * ForEach operator on Objects.
 * Calls function with arguments (obj, key).
 **/
/*
Object.defineProperty(Object.prototype, 'forEach', {
  value: function(fn) {
    for ( var key in this ) if (this.hasOwnProperty(key)) fn(this[key], key);
}});*/

// Workaround for crbug.com/258522
function Object_forEach(obj, fn) {
  for (var key in obj) if (obj.hasOwnProperty(key)) fn(obj[key], key);
}

/*
Object.defineProperty(Object.prototype, 'put', {
  value: function(obj) {
    this[obj.id] = obj;
  },
  configurable: true,
  writable: true
});
*/

function predicatedSink(predicate, sink) {
  if ( predicate === TRUE ) return sink;

  return {
    __proto__: sink,
    put: function(obj, s, fc) {
      if ( sink && predicate.f(obj) ) sink.put(obj, s, fc);
    }/*,
    eof: function() {
      sink && sink.eof && sink.eof();
    }*/
  };
}

function limitedSink(count, sink) {
  var i = 0;
  return {
    __proto__: sink,
    put: function(obj, s, fc) {
      if ( i++ >= count && fc ) {
        fc.stop();
      } else {
        sink.put(obj, s, fc);
      }
    }/*,
    eof: function() {
      sink.eof && sink.eof();
    }*/
  };
}

function skipSink(skip, sink) {
  var i = 0;
  return {
    __proto__: sink,
    put: function(obj, s, fc) {
      if ( i++ >= skip ) sink.put(obj, s, fc);
    }
  };
}

function orderedSink(comparator, sink) {
  comparator = toCompare(comparator);
  return {
    __proto__: sink,
    i: 0,
    arr: [],
    put: function(obj, s, fc) {
      this.arr.push(obj);
    },
    eof: function() {
      this.arr.sort(comparator);
      this.arr.select(sink);
    }
  };
}

console.log.json = function() {
   var args = [];
   for ( var i = 0 ; i < arguments.length ; i++ ) {
     var arg = arguments[i];
     args.push(arg && arg.toJSON ? arg.toJSON() : arg);
   }
   console.log.apply(console, args);
};

console.log.str = function() {
   var args = [];
   for ( var i = 0 ; i < arguments.length ; i++ ) {
     var arg = arguments[i];
     args.push(arg && arg.toString ? arg.toString() : arg);
   }
   console.log.apply(console, args);
};

// Promote 'console.log' into a Sink
console.log.put         = console.log.bind(console);
console.log.remove      = console.log.bind(console, 'remove: ');
console.log.error       = console.log.bind(console, 'error: ');
console.log.json.put    = console.log.json.bind(console);
console.log.json.reduceI = console.log.json.bind(console, 'reduceI: ');
console.log.json.remove = console.log.json.bind(console, 'remove: ');
console.log.json.error  = console.log.json.bind(console, 'error: ');
console.log.str.put     = console.log.str.bind(console);
console.log.str.remove  = console.log.str.bind(console, 'remove: ');
console.log.str.error  = console.log.str.bind(console, 'error: ');

document.put = function(obj) {
  if ( obj.write ) {
    obj.write(this);
  } else {
    this.write(obj.toString());
  }
};

String.prototype.put = function(obj) { return this + obj.toJSON(); };

// Promote webkit apis

window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem;
window.requestAnimationFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame;

if (window.Blob) {
  Blob.prototype.slice = Blob.prototype.slice || Blob.prototype.webkitSlice;
}

/** Convert a string to an internal canonical copy. **/
String.prototype.intern = (function() {
  var map = {};

  return function() { return map[this] || (map[this] = this.toString()); };
})();

if (window.XMLHttpRequest) {
  /**
      * Add an afunc send to XMLHttpRequest
  */
  XMLHttpRequest.prototype.asend = function(ret, opt_data) {
    var xhr = this;
    xhr.onerror = function() {
      console.log('XHR Error: ', arguments);
    };
    xhr.onloadend = function() {
      ret(xhr.response, xhr);
    };
    xhr.send(opt_data);
  };
}

RegExp.quote = function(str) {
  return (str+'').replace(/([.?*+^$[\]\\(){}|-])/g, '\\$1');
};
<|endoftext|>


<commit_before>;var Plates = function main(undefined) {

  var Merge = function Merge() {};

  Merge.prototype = {

    tag: new RegExp(
      [
        '\\s*',
        '<',
        '(/?)', // 1 - is closing
        '([-:\\w]+)', // 2 - name
        '((?:\\s+[-\\w]+(?:', '=', '(?:' +
          '\\w+|' +
          '"[^"]*"|' +
          '\'[^\']*\'))?)*)', // 3 - attributes
        '(/?)', // 4 - is self-closing
        '>'
      ].join('\\s*'),
      'gi'
    ),

    attr: new RegExp(
      '([-\\w]+)=(?:["\']([-\\w\\s]+)["\'])', // '([-\\w]+)=(?:([-\\w]+)|["\']([-\\w\\s]+)["\'])'
      'gi'
    ),

    bind: function bind(html, data, map) {

      while (matchedTag = this.tag.exec(html)) {

        //
        // must not be a closing tag, must have attributes.
        //
        if (matchedTag[1] !== '/' && matchedTag[3] !== '') {

          if (!map) {

            while (matchedAttr = this.attr.exec(matchedTag[3])) {

              //
              // has an attribute who's value is a match.
              //
              if (matchedAttr[1] === 'id' && data[matchedAttr[2]]) {
                var idx = matchedTag.index + matchedTag[0].length;
                html = html.slice(0, idx) + data[matchedAttr[2]] + html.slice(idx);
              }
            }

          }
          else {

            //
            // if there is a map, the user wants an explicit
            // data-key to tag-attribute match.
            //
            var match = false, idx = 0;
            for (var key in map) {
              if (data[key]) {
                while (matchedAttr = this.attr.exec(matchedTag[3])) {

                  //
                  // an attribute who's value is a match.
                  //

                  if (matchedAttr[1] === map[key] ||
                      matchedAttr[1] === map[key][0]) {

                    match = false, idx = 0;

                    //
                    // if the preferred attribute is `class`, split the class and
                    // make sure that the actual key is a match with the data.
                    //
                    if (map[key] === 'class' || (map[key][0] && map[key][0] === 'class')) {
                      var classNames = matchedAttr[2].split(/\s+/);
                      for (var i = 0, l = classNames.length; i < l; i++) {
                        if (classNames[i] === key) {
                          match = true; break;
                        }
                      }
                    }

                    //
                    // if there is a match from the class, or there is a match of
                    // the key, then splice the data into the string where it belongs.
                    //

                    if (matchedAttr[2] === key || match) {

                      var d = match ? key : matchedAttr[2];

                      if (typeof map[key] === 'object') {

                        //
                        // find the attribute key/value pair in the tag.
                        //
                        var att = matchedTag[0].match(
                          new RegExp(map[key][1] + '\\s*=\\s*["|\'](.*)["|\']')
                        );

                        if (map[key][1]) {
                          //
                          // determine the start and end positions.
                          //
                          var start = matchedTag.index + att.index + (att[0].length - att[1].length);
                          var end = start + att[1].length;

                          html = html.slice(0, start-1) + data[d] + html.slice(end-1);
                        }
                        else if (matchedTag[4] !== '/') {
                          //
                          // must not be a self closing tag
                          //
                          idx = matchedTag.index + matchedTag[0].length;
                          html = html.slice(0, idx) + data[d] + html.slice(idx);
                        }
                      }
                      else {
                        //
                        // insert the value as a `textnode` into the tag.
                        //
                        idx = matchedTag.index + matchedTag[0].length;
                        html = html.slice(0, idx) + data[d] + html.slice(idx);
                      }
                    }

                  }
                }
              }
            }

          }

        }
      }

      return html;
    }
  };

  return ({
    bind: function(html, data, map) {
      var merge = new Merge();
      return merge.bind(html, data, map);
    }
  });

}();

this.exports && (exports.bind = function() {
  return Plates.bind.apply(this, arguments);
});
<commit_msg>fix bad browser shim<commit_after>;var Plates = function main(undefined) {

  var Merge = function Merge() {};

  Merge.prototype = {

    tag: new RegExp(
      [
        '\\s*',
        '<',
        '(/?)', // 1 - is closing
        '([-:\\w]+)', // 2 - name
        '((?:\\s+[-\\w]+(?:', '=', '(?:' +
          '\\w+|' +
          '"[^"]*"|' +
          '\'[^\']*\'))?)*)', // 3 - attributes
        '(/?)', // 4 - is self-closing
        '>'
      ].join('\\s*'),
      'gi'
    ),

    attr: new RegExp(
      '([-\\w]+)=(?:["\']([-\\w\\s]+)["\'])', // '([-\\w]+)=(?:([-\\w]+)|["\']([-\\w\\s]+)["\'])'
      'gi'
    ),

    bind: function bind(html, data, map) {

      while (matchedTag = this.tag.exec(html)) {

        //
        // must not be a closing tag, must have attributes.
        //
        if (matchedTag[1] !== '/' && matchedTag[3] !== '') {

          if (!map) {

            while (matchedAttr = this.attr.exec(matchedTag[3])) {

              //
              // has an attribute who's value is a match.
              //
              if (matchedAttr[1] === 'id' && data[matchedAttr[2]]) {
                var idx = matchedTag.index + matchedTag[0].length;
                html = html.slice(0, idx) + data[matchedAttr[2]] + html.slice(idx);
              }
            }

          }
          else {

            //
            // if there is a map, the user wants an explicit
            // data-key to tag-attribute match.
            //
            var match = false, idx = 0;
            for (var key in map) {
              if (data[key]) {
                while (matchedAttr = this.attr.exec(matchedTag[3])) {

                  //
                  // an attribute who's value is a match.
                  //

                  if (matchedAttr[1] === map[key] ||
                      matchedAttr[1] === map[key][0]) {

                    match = false, idx = 0;

                    //
                    // if the preferred attribute is `class`, split the class and
                    // make sure that the actual key is a match with the data.
                    //
                    if (map[key] === 'class' || (map[key][0] && map[key][0] === 'class')) {
                      var classNames = matchedAttr[2].split(/\s+/);
                      for (var i = 0, l = classNames.length; i < l; i++) {
                        if (classNames[i] === key) {
                          match = true; break;
                        }
                      }
                    }

                    //
                    // if there is a match from the class, or there is a match of
                    // the key, then splice the data into the string where it belongs.
                    //

                    if (matchedAttr[2] === key || match) {

                      var d = match ? key : matchedAttr[2];

                      if (typeof map[key] === 'object') {

                        //
                        // find the attribute key/value pair in the tag.
                        //
                        var att = matchedTag[0].match(
                          new RegExp(map[key][1] + '\\s*=\\s*["|\'](.*)["|\']')
                        );

                        if (map[key][1]) {
                          //
                          // determine the start and end positions.
                          //
                          var start = matchedTag.index + att.index + (att[0].length - att[1].length);
                          var end = start + att[1].length;

                          html = html.slice(0, start-1) + data[d] + html.slice(end-1);
                        }
                        else if (matchedTag[4] !== '/') {
                          //
                          // must not be a self closing tag
                          //
                          idx = matchedTag.index + matchedTag[0].length;
                          html = html.slice(0, idx) + data[d] + html.slice(idx);
                        }
                      }
                      else {
                        //
                        // insert the value as a `textnode` into the tag.
                        //
                        idx = matchedTag.index + matchedTag[0].length;
                        html = html.slice(0, idx) + data[d] + html.slice(idx);
                      }
                    }

                  }
                }
              }
            }

          }

        }
      }

      return html;
    }
  };

  return ({
    bind: function(html, data, map) {
      var merge = new Merge();
      return merge.bind(html, data, map);
    }
  });

}();

module && (exports.bind = function() {
  return Plates.bind.apply(this, arguments);
});
<|endoftext|>


<commit_before>var path = require('path');
var vow = require('vow');
var vfs = require('enb/lib/fs/async-fs');
var naming = require('bem-naming');
var _ = require('lodash');
var scanner = require('enb-bem-pseudo-levels/lib/level-scanner');
var configurator = require('./node-configurator');
var runner = require('./runner');
var deps = require('enb-bem/lib/deps/deps');

module.exports = function (helper) {
    return {
        configure: function (options) {
            var initedOptions = this._init(options);

            configurator.configure(initedOptions.projectConfig, {
                destPath: options.destPath,
                sourceLevels: initedOptions.sourceLevels,
                engines: initedOptions.engines,
                saveHtml: options.saveHtml || false
            });

            this._buildSet(initedOptions);
            this._runSpecs(initedOptions);
        },

        _init: function (options) {
            var projectConfig = helper.getProjectConfig();
            var root = projectConfig.getRootPath();
            var engines = options.engines;

            return {
                _options: options,
                projectConfig: projectConfig,
                root: root,
                destPath: options.destPath,
                levels: options.levels.map(function (level) {
                    return (typeof level === 'string') ? { path: level } : level;
                }),
                engines: Object.keys(engines).map(function (name) {
                    var engine = engines[name];
                    var tech = require(engine.tech);
                    var options = _.clone(engine.options || {});
                    var target = '?.' + name.toLowerCase() + '.js';
                    var splitedTech = engine.tech.split(path.sep);
                    var isXjst = splitedTech.indexOf('enb-xjst') !== -1 || splitedTech.indexOf('enb-bemxjst') !== -1;

                    options.target = target;

                    return {
                        name: name,
                        tech: tech,
                        target: target,
                        exportName: isXjst ? (engine.options && engine.options.exportName || 'BEMHTML') : undefined,
                        options: options
                    };
                }),
                sourceLevels: options.sourceLevels || options.levels,
                referenceDirSuffixes: options.referenceDirSuffixes || ['tmpl-specs']
            };
        },

        _buildSet: function (options) {
            var _this = this;
            var dstpath = path.resolve(options.root, options.destPath);

            helper.prebuild(function (magic) {
                return scanner.scan(options.levels)
                    .then(function (files) {
                        var nodes = {};
                        var nodesToRun = {};

                        files.forEach(function (file) {
                            if (~options.referenceDirSuffixes.indexOf(file.suffix)) {
                                var bemname = file.name.split('.')[0];
                                var node = path.join(options.destPath, bemname);
                                var mainTarget = path.join(node, bemname + '.tmpl-spec.js');

                                if (magic.isRequiredNode(node)) {
                                    nodes[node] = true;
                                    magic.registerNode(node);

                                    magic.isRequiredTarget(mainTarget) && (nodesToRun[node] = true);
                                }
                            }
                        });

                        options.nodes = Object.keys(nodes);
                        options.nodesToRun = Object.keys(nodesToRun);

                        return vow.all(options.nodes.map(function (node) {
                            return _this._buildBemdecl(dstpath, node);
                        }));
                    });
            });
        },

        _buildBemdecl: function (dstpath, node) {
            var basename = path.basename(node);
            var dirname = path.join(dstpath, basename);
            var bemdeclFilename = path.join(dirname, basename + '.base.bemdecl.js');
            var notation = naming.parse(basename);
            var dep = { block: notation.block };
            var bemdeclSource;

            notation.elem && (dep.elem = notation.elem);

            if (notation.modName) {
                dep.mod = notation.modName;
                dep.val = notation.modVal;
            }

            bemdeclSource = 'exports.blocks = ' + JSON.stringify(deps.toBemdecl([dep])) + ';';

            return vfs.makeDir(dirname)
                .then(function () {
                    return vfs.write(bemdeclFilename, bemdeclSource, 'utf-8');
                });
        },

        _runSpecs: function (options) {
            options.projectConfig.task(helper.getTaskName(), function () {
                var filesToRun = options.nodesToRun.map(function (node) {
                    var basename = path.basename(node);

                    return path.join(options.root, node, basename + '.tmpl-spec.js');
                });

                return filesToRun.length && runner.run(filesToRun)
                    .fail(function (err) {
                        if (err.stack) {
                            console.error(err.stack);
                        }

                        process.exit(1);
                    });
            });
        }
    };
};
<commit_msg>Fixed node configure<commit_after>var path = require('path');
var vow = require('vow');
var vfs = require('enb/lib/fs/async-fs');
var naming = require('bem-naming');
var _ = require('lodash');
var scanner = require('enb-bem-pseudo-levels/lib/level-scanner');
var configurator = require('./node-configurator');
var runner = require('./runner');
var deps = require('enb-bem/lib/deps/deps');

module.exports = function (helper) {
    return {
        configure: function (options) {
            var initedOptions = this._init(options);

            this._buildSet(initedOptions);
            this._runSpecs(initedOptions);
        },

        _init: function (options) {
            var projectConfig = helper.getProjectConfig();
            var root = projectConfig.getRootPath();
            var engines = options.engines;

            return {
                _options: options,
                projectConfig: projectConfig,
                root: root,
                destPath: options.destPath,
                levels: options.levels.map(function (level) {
                    return (typeof level === 'string') ? { path: level } : level;
                }),
                engines: Object.keys(engines).map(function (name) {
                    var engine = engines[name];
                    var tech = require(engine.tech);
                    var options = _.clone(engine.options || {});
                    var target = '?.' + name.toLowerCase() + '.js';
                    var splitedTech = engine.tech.split(path.sep);
                    var isXjst = splitedTech.indexOf('enb-xjst') !== -1 || splitedTech.indexOf('enb-bemxjst') !== -1;

                    options.target = target;

                    return {
                        name: name,
                        tech: tech,
                        target: target,
                        exportName: isXjst ? (engine.options && engine.options.exportName || 'BEMHTML') : undefined,
                        options: options
                    };
                }),
                sourceLevels: options.sourceLevels || options.levels,
                referenceDirSuffixes: options.referenceDirSuffixes || ['tmpl-specs']
            };
        },

        _buildSet: function (options) {
            var _this = this;
            var dstpath = path.resolve(options.root, options.destPath);

            helper.prebuild(function (magic) {
                return scanner.scan(options.levels)
                    .then(function (files) {
                        var nodes = {};
                        var nodesToRun = {};

                        files.forEach(function (file) {
                            if (~options.referenceDirSuffixes.indexOf(file.suffix)) {
                                var bemname = file.name.split('.')[0];
                                var node = path.join(options.destPath, bemname);
                                var mainTarget = path.join(node, bemname + '.tmpl-spec.js');

                                if (magic.isRequiredNode(node)) {
                                    nodes[node] = true;
                                    magic.registerNode(node);

                                    magic.isRequiredTarget(mainTarget) && (nodesToRun[node] = true);
                                }
                            }
                        });

                        options.nodes = Object.keys(nodes);
                        options.nodesToRun = Object.keys(nodesToRun);

                        return vow.all(options.nodes.map(function (node) {
                            return _this._buildBemdecl(dstpath, node);
                        }));
                    })
                    .then(function () {
                        configurator.configure(options.projectConfig, {
                            destPath: options.destPath,
                            sourceLevels: options.sourceLevels,
                            engines: options.engines,
                            saveHtml: options.saveHtml || false
                        });
                    });
            });
        },

        _buildBemdecl: function (dstpath, node) {
            var basename = path.basename(node);
            var dirname = path.join(dstpath, basename);
            var bemdeclFilename = path.join(dirname, basename + '.base.bemdecl.js');
            var notation = naming.parse(basename);
            var dep = { block: notation.block };
            var bemdeclSource;

            notation.elem && (dep.elem = notation.elem);

            if (notation.modName) {
                dep.mod = notation.modName;
                dep.val = notation.modVal;
            }

            bemdeclSource = 'exports.blocks = ' + JSON.stringify(deps.toBemdecl([dep])) + ';';

            return vfs.makeDir(dirname)
                .then(function () {
                    return vfs.write(bemdeclFilename, bemdeclSource, 'utf-8');
                });
        },

        _runSpecs: function (options) {
            options.projectConfig.task(helper.getTaskName(), function () {
                var filesToRun = options.nodesToRun.map(function (node) {
                    var basename = path.basename(node);

                    return path.join(options.root, node, basename + '.tmpl-spec.js');
                });

                return filesToRun.length && runner.run(filesToRun)
                    .fail(function (err) {
                        if (err.stack) {
                            console.error(err.stack);
                        }

                        process.exit(1);
                    });
            });
        }
    };
};
<|endoftext|>


<commit_before>/**
 * This providers helper methods for global utilities, named after Underscore.
 *
 * Cherry picked related things that matters here.
 */
class __ {

    /**
     * Injects isTypes on creation.
     */
    constructor() {
        this._initTypes();
    }

    /**
     * Is a given input equal to null?
     *
     * @param {*} input
     * @return {Boolean}
     */
    isNull(input) {
        return input === null;
    }

    /**
     * Is a given input an Array?
     *
     * @param {*} input
     * @return {Boolean}
     */
    isArray(expectedArray) {
        return Array.isArray(expectedArray);
    }

    /**
     * Is a given input a boolean?
     *
     * @param {*} input
     * @return {Boolean}
     */
    isBoolean(input) {
        return true === input || false === input || '[object Boolean]' === toString.call(input);
    }

    /**
     * Is a given input an HTMLEelement?
     *
     * @param {*} el of an HTMLElement
     * @return {Boolean}
     */
    isElement(el) {
        try {
            return el instanceof HTMLElement;
        }
        catch (e) {
            return (this.isObject(el)) &&
                (el.nodeType === 1) && (this.isObject(el.style)) &&
                (this.isObject(el.ownerDocument));
        }
    }

    /**
     * Deep merges items from source into target, recursively, overrides if exists.
     *
     * @param {Object} target object.
     * @param {Object} source object.
     * @return {Object} Merged object.
     */
    merge(target, source) {
        // _mergeRecursive does the actual job with two arguments.
        let _mergeRecursive = (dst, src) => {
            if (!this.isObject(src) || this.isNull(src)) {
                return dst;
            }

            for (let p in src) {
                if (!src.hasOwnProperty(p) || this.isUndefined(src[p])) continue;

                if (!this.isObject(src[p]) || this.isNull(src[p])) {
                    dst[p] = src[p];
                } else
                if (!this.isObject(dst[p]) || this.isNull(dst[p])) {
                    dst[p] = _mergeRecursive(this.isArray(src[p].constructor) ? [] : {}, src[p]);
                } else {
                    _mergeRecursive(dst[p], src[p]);
                }
            }

            return dst;
        }

        // Loop through arguments and merge them into the first argument.
        let out = arguments[0];
        if (!this.isObject(out) || this.isNull(out)) return out;

        for (let i=1, len = arguments.length; i < len; i++) {
            _mergeRecursive(out, arguments[i]);
        }

        return out;
    }

    /**
     * Check to see if a string is a valid url
     *
     * @param {String} url
     *
     * @example http://www.smp.com // true
     * @see http://stackoverflow.com/questions/5717093/check-if-a-javascript-string-is-an-url
     * @return {Boolean}
     */
    isURL(url) {
      let pattern = new RegExp('^(https?:\\/\\/)?'+ // protocol
          '((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.?)+[a-z]{2,}|'+ // domain name
          '((\\d{1,3}\\.){3}\\d{1,3}))'+ // OR ip (v4) address
          '(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*'+ // port and path
          '(\\?[;&a-z\\d%_.~+=-]*)?'+ // query string
          '(\\#[-a-z\\d_]*)?$','i'); // fragment locator

      return pattern.test(url);
    }

    /**
     * Given a seconds value, this function formats the seconds
     * to minutes:seconds format.
     *
     * @param {Number} sec - Seconds to convert to minutes.
     * @return {String} MINUTES:SECONDS format.
     */
    formatTime(sec) {
        sec = Math.round(sec);

        let minutes = Math.floor(sec / 60),
            seconds = sec - (minutes * 60);

        seconds = seconds < 10 ? '0' + seconds : seconds;

        return minutes + ':' + seconds;
    }

    /**
     * RegExp match, returns the first bit found.
     *
     * @param {Object} pattern
     * @param {String} string to match
     * @return {String} of the matched part
     */
    matchPattern(pattern, string) {
        return string.match(pattern) ? RegExp.$1 : false;
    }

    /**
     * Adds some isTypes methods to the class, called during instantiation.
     * Methods: isArguments, isFunction, isString, isNumber, isObject, isDate, isError, isSymbol, isUndefined.
     */
    _initTypes() {
        let types = ['Arguments', 'Function', 'String', 'Number', 'Object', 'Date', 'Error', 'Symbol', 'Undefined'];

        types.forEach((type) => {
            this['is'+ type] = function(typeName) {
                return input => {
                    return '[object '+ typeName +']' === toString.call(input);
                }
            }(type);
        });
    }
}

export default new __();<commit_msg>slight fix<commit_after>/**
 * This providers helper methods for global utilities, named after Underscore.
 *
 * Cherry picked related things that matters here.
 */
class __ {

    /**
     * Injects isTypes on creation.
     */
    constructor() {
        this._initTypes();
    }

    /**
     * Is a given input equal to null?
     *
     * @param {*} input
     * @return {Boolean}
     */
    isNull(input) {
        return input === null;
    }

    /**
     * Is a given input an Array?
     *
     * @param {*} input
     * @return {Boolean}
     */
    isArray(expectedArray) {
        return Array.isArray(expectedArray);
    }

    /**
     * Is a given input a boolean?
     *
     * @param {*} input
     * @return {Boolean}
     */
    isBoolean(input) {
        return true === input || false === input || '[object Boolean]' === toString.call(input);
    }

    /**
     * Is a given input an HTMLEelement?
     *
     * @param {*} el of an HTMLElement
     * @return {Boolean}
     */
    isElement(el) {
        try {
            return el instanceof HTMLElement;
        }
        catch (e) {
            return (this.isObject(el)) &&
                (el.nodeType === 1) && (this.isObject(el.style)) &&
                (this.isObject(el.ownerDocument));
        }
    }

    /**
     * Deep merges items from source into target, recursively, overrides if exists.
     *
     * @param {Object} target object.
     * @param {Object} source object.
     * @return {Object} Merged object.
     */
    merge(target, source) {
        // _mergeRecursive does the actual job with two arguments.
        let _mergeRecursive = (dst, src) => {
            if (!this.isObject(src) || this.isNull(src)) {
                return dst;
            }

            for (let p in src) {
                if (!src.hasOwnProperty(p) || this.isUnefined(src[p])) continue;

                if (!this.isObject(src[p]) || this.isNull(src[p])) {
                    dst[p] = src[p];
                } else
                if (!this.isObject(dst[p]) || this.isNull(dst[p])) {
                    dst[p] = _mergeRecursive(this.isArray(src[p].constructor) ? [] : {}, src[p]);
                } else {
                    _mergeRecursive(dst[p], src[p]);
                }
            }

            return dst;
        }

        // Loop through arguments and merge them into the first argument.
        let out = arguments[0];
        if (!this.isObject(out) || this.isNull(out)) return out;

        for (let i=1, len = arguments.length; i < len; i++) {
            _mergeRecursive(out, arguments[i]);
        }

        return out;
    }

    /**
     * Check to see if a string is a valid url
     *
     * @param {String} url
     *
     * @example http://www.smp.com // true
     * @see http://stackoverflow.com/questions/5717093/check-if-a-javascript-string-is-an-url
     * @return {Boolean}
     */
    isURL(url) {
      let pattern = new RegExp('^(https?:\\/\\/)?'+ // protocol
          '((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.?)+[a-z]{2,}|'+ // domain name
          '((\\d{1,3}\\.){3}\\d{1,3}))'+ // OR ip (v4) address
          '(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*'+ // port and path
          '(\\?[;&a-z\\d%_.~+=-]*)?'+ // query string
          '(\\#[-a-z\\d_]*)?$','i'); // fragment locator

      return pattern.test(url);
    }

    /**
     * Given a seconds value, this function formats the seconds
     * to minutes:seconds format.
     *
     * @param {Number} sec - Seconds to convert to minutes.
     * @return {String} MINUTES:SECONDS format.
     */
    formatTime(sec) {
        sec = Math.round(sec);

        let minutes = Math.floor(sec / 60),
            seconds = sec - (minutes * 60);

        seconds = seconds < 10 ? '0' + seconds : seconds;

        return minutes + ':' + seconds;
    }

    /**
     * RegExp match, returns the first bit found.
     *
     * @param {Object} pattern
     * @param {String} string to match
     * @return {String} of the matched part
     */
    matchPattern(pattern, string) {
        return string.match(pattern) ? RegExp.$1 : false;
    }

    /**
     * Adds some isTypes methods to the class, called during instantiation.
     * Methods: isArguments, isFunction, isString, isNumber, isObject, isDate, isError, isSymbol, isUndefined.
     */
    _initTypes() {
        let types = ['Arguments', 'Function', 'String', 'Number', 'Object', 'Date', 'Error', 'Symbol', 'Undefined'];

        types.forEach((type) => {
            this['is'+ type] = function(typeName) {
                return input => {
                    return '[object '+ typeName +']' === toString.call(input);
                };
            }(type);
        });
    }
}

export default new __();<|endoftext|>


<commit_before>var _ = require('lodash');
var xml = require('pixl-xml');
var fs = require("fs");
var he = require('he');
var path = require('path');

function JunitReporter(emitter, pluginOptions) {
    this.tests = [];
    this.options = pluginOptions;
    var appendMode = pluginOptions.appendMode;

    function getBrowserDescription(browser) {
        var result = browser.browserName;

        if (_.size(browser.version) > 0) {
            result = result.concat(' ', browser.version);
        }

        if (_.size(browser.platform) > 0) {
            result = result.concat(' on ', browser.platform);
        }

        return he.encode(result).replace('.', ',');
    }

    function collectTestResult(browser, test) {
        if (_.size(test.test) === 3) {
            test.suite = he.encode(test.test[1]).concat('.', getBrowserDescription(browser));
            test.name = he.encode(test.test[2]);
        } else {
            test.suite = test.test[0];
            test.name = 'Unknown on '.concat(getBrowserDescription(browser));
            test.state = 'error';
        }
        this.tests.push(test);
    }

    function writeTestReport() {
        var existingReports;
        var root = pluginOptions.output.path || './';
        var filename = pluginOptions.output.name || 'test-report.xml';
        var fullpath = root + filename;
        fs.mkdir(path.resolve(root), function (err, success) {
            if (err)
                return err;
        });

        if (appendMode) {
            try {
                existingReports = xml.parse(path.resolve(fullpath), {
                    preserveAttributes: true
                });
            } catch (e) {}
        }
        var results = {
            testsuites: {
                testsuite: _.map(_.sortBy(_.unique(_.pluck(this.tests, 'suite'))), function (suite) {
                    var tests = _.filter(this.tests, {
                        suite: suite
                    });
                    var testsuite = {
                        _Attribs: {
                            name: suite,
                            tests: tests.length,
                            errors: 0,
                            failures: _.size(_.filter(tests, {
                                state: 'failing'
                            })),
                            skipped: _.size(_.filter(tests, {
                                state: 'pending'
                            }))
                        },
                        testcase: _.map(tests, function (test) {
                            var testcase = {
                                _Attribs: {
                                    name: test.name,
                                    time: test.duration
                                }
                            };
                            if (test.state === 'failing') {
                                testcase.failure = {
                                    _Attribs: {
                                        message: he.encode(test.error.message)
                                    }
                                };
                            }
                            if (test.state === 'error') {
                                testcase.error = {
                                    _Attribs: {
                                        message: he.encode(test.error.message)
                                    }
                                };
                                testcase['system-out'] = he.encode(test.error.stack);
                            }
                            if (test.state === 'pending') {
                                testcase.skipped = {};
                            }

                            return testcase;
                        })
                    };

                    return testsuite;
                })
            }
        };
        if (existingReports) {
            results.testsuites.testsuite.push(existingReports.testsuite);
        }
        fs.writeFileSync(path.resolve(fullpath), xml.stringify(results).replace(/&/g, '&'));
    }

    emitter.on('test-end', collectTestResult.bind(this));
    emitter.on('run-end', writeTestReport.bind(this));
};

module.exports = JunitReporter;<commit_msg>Better value checking for output properties<commit_after>var _ = require('lodash');
var xml = require('pixl-xml');
var fs = require("fs");
var he = require('he');
var path = require('path');

function JunitReporter(emitter, pluginOptions) {
    this.tests = [];
    this.options = pluginOptions;
    var appendMode = pluginOptions.appendMode;

    function getBrowserDescription(browser) {
        var result = browser.browserName;

        if (_.size(browser.version) > 0) {
            result = result.concat(' ', browser.version);
        }

        if (_.size(browser.platform) > 0) {
            result = result.concat(' on ', browser.platform);
        }

        return he.encode(result).replace('.', ',');
    }

    function collectTestResult(browser, test) {
        if (_.size(test.test) === 3) {
            test.suite = he.encode(test.test[1]).concat('.', getBrowserDescription(browser));
            test.name = he.encode(test.test[2]);
        } else {
            test.suite = test.test[0];
            test.name = 'Unknown on '.concat(getBrowserDescription(browser));
            test.state = 'error';
        }
        this.tests.push(test);
    }

    function writeTestReport() {
        var existingReports;
        var root = (pluginOptions.output && pluginOptions.output.path) ? pluginOptions.output.path : './';
        var filename = (pluginOptions.output && pluginOptions.output.name) ? pluginOptions.output.name : 'test-report.xml';
        var fullpath = root + filename;
        fs.mkdir(path.resolve(root), function (err, success) {
            if (err)
                return err;
        });

        if (appendMode) {
            try {
                existingReports = xml.parse(path.resolve(fullpath), {
                    preserveAttributes: true
                });
            } catch (e) {}
        }
        var results = {
            testsuites: {
                testsuite: _.map(_.sortBy(_.unique(_.pluck(this.tests, 'suite'))), function (suite) {
                    var tests = _.filter(this.tests, {
                        suite: suite
                    });
                    var testsuite = {
                        _Attribs: {
                            name: suite,
                            tests: tests.length,
                            errors: 0,
                            failures: _.size(_.filter(tests, {
                                state: 'failing'
                            })),
                            skipped: _.size(_.filter(tests, {
                                state: 'pending'
                            }))
                        },
                        testcase: _.map(tests, function (test) {
                            var testcase = {
                                _Attribs: {
                                    name: test.name,
                                    time: test.duration
                                }
                            };
                            if (test.state === 'failing') {
                                testcase.failure = {
                                    _Attribs: {
                                        message: he.encode(test.error.message)
                                    }
                                };
                            }
                            if (test.state === 'error') {
                                testcase.error = {
                                    _Attribs: {
                                        message: he.encode(test.error.message)
                                    }
                                };
                                testcase['system-out'] = he.encode(test.error.stack);
                            }
                            if (test.state === 'pending') {
                                testcase.skipped = {};
                            }

                            return testcase;
                        })
                    };

                    return testsuite;
                })
            }
        };
        if (existingReports) {
            results.testsuites.testsuite.push(existingReports.testsuite);
        }
        fs.writeFileSync(path.resolve(fullpath), xml.stringify(results).replace(/&/g, '&'));
    }

    emitter.on('test-end', collectTestResult.bind(this));
    emitter.on('run-end', writeTestReport.bind(this));
};

module.exports = JunitReporter;<|endoftext|>


<commit_before>import Promise from 'es6-promise/lib/es6-promise/promise';
import * as fs from 'fs';
import { resolve } from './path';

export function writeFile ( dest, data ) {
	return new Promise( ( fulfil, reject ) => {
		fs.writeFile( resolve( process.cwd(), dest ), data, err => {
			if ( err ) {
				reject( err );
			} else {
				fulfil();
			}
		});
	});
}

export const readdirSync = fs.readdirSync;
export const readFileSync = fs.readFileSync;
<commit_msg>make intermediate dirs in writeFile helper<commit_after>import Promise from 'es6-promise/lib/es6-promise/promise';
import * as fs from 'fs';
import { dirname } from './path';

function mkdirpath ( path ) {
	const dir = dirname( path );
	try {
		fs.readdirSync( dir );
	} catch ( err ) {
		mkdirpath( dir );
		fs.mkdirSync( dir );
	}
}

export function writeFile ( dest, data ) {
	return new Promise( ( fulfil, reject ) => {
		mkdirpath( dest );

		fs.writeFile( dest, data, err => {
			if ( err ) {
				reject( err );
			} else {
				fulfil();
			}
		});
	});
}

export const readdirSync = fs.readdirSync;
export const readFileSync = fs.readFileSync;
<|endoftext|>


<commit_before>// validate
var validate = FORMx.validate = {
    // natural extension points
    type: {
        number: /^\-?\d*(\.\d+)?$/,
        email: /^[a-zA-Z0-9.!#$%&'*+-\/=?\^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/,
        url: /^http.[^\s]+$/i
    },
    constraints: {
        required: function(value) {
            return !(value && value.trim());
        },
        pattern: function(value, pattern) {
            return value && !value.match(new RegExp('^'+pattern+'$'));
        },
        'equal-to': function(value, other) {
            return value !== validate.valueOf(other);
        },
        'not-equal': function(value, other) {
            return value === validate.valueOf(other);
        },
        maxlength: function(value, maxlength) {
            return value.length > parseInt(maxlength, 10);
        },
        minlength: function(value, minlength) {
            return value && value.length < parseInt(minlength, 10);
        },
        min: function(value, min) {
            return validate.parse(value) < validate.parse(min);
        },
        max: function(value, max) {
            return validate.parse(value) > validate.parse(max);
        },
        step: function(value, step) {
            // % operator is inconsistent with floats, convert to ints first
            var decimal = step.indexOf('.'),
                factor = 1;
            if (decimal >= 0) {
                var power = step.length - decimal - 1;
                factor = Math.pow(10, power);
            }
            step = Math.round(parseFloat(step) * factor);
            var remainder = Math.round(value * factor) % step;
            return !isNaN(remainder) && remainder !== 0;
        }
    },
    classes: {
        required: 'valueMissing',
        pattern: 'patternMismatch',
        'equal-to': 'notEqual',
        'not-equal': 'notDifferent',
        maxlength: 'tooLong',
        minlength: 'tooShort',
        min: 'rangeUnderflow',
        max: 'rangeOverflow',
        step: 'stepMismatch'
    },
    field: '[type=number],[type=email],[type=url],'+//types
           '[required],[pattern],[maxlength],[min],[max],[step],'+// standards
           '[equal-to],[not-equal],[minlength]',// extensions
    toggle: function(el, valid) {
        el.classList.toggle('invalid', !valid);
        el.setCustomValidity(valid ? '' : 'This value is not valid.');
    },

    // internal functions
    valueOf: function(string) {
        if (string) {
            var el = D.query('[name="'+string+'"]');
            string = el && el.value;
        }
        return string;
    },
    parse: function(string) {
        return parseFloat(validate.valueOf(string));
    },
    check: function(el, event) {
        var no = el.getAttribute('novalidate');
        if (!no) {
            return true;
        }
        if (no === 'true' || no === 'novalidate') {
            return false;
        }
        if (no.indexOf('!') === 0) {
            return no.substring(1).split().indexOf(event) !== -1;
        }
        return no.split(' ').indexOf(event) === -1;
    },
    one: function(el, event) {
        if (!validate.check(el, event)) {
            return true;
        }

        var typeRE = validate.type[el.getAttribute('type')],
            value = el.value,
            valid = true;
        if (typeRE) {
            valid = !value || !!value.match(typeRE);
            el.classList.toggle('typeMismatch', !valid);
        }
        for (var name in validate.constraints) {
            var constraint = el.getAttribute(name) || el.hasAttribute(name);
            if (constraint) {
                var _class = validate.classes[name],
                    failed = validate.constraints[name](value, constraint);
                if (failed) {
                    valid = false;
                }
                el.classList.toggle(_class, failed);
            }
        }
        validate.toggle(el, valid);
        if (valid) {
            el.lastValidValue = value;
        }
        return valid;
    },
    all: function(form, event) {
        if (!validate.check(form, event)) {
            return true;
        }

        var valid = true;
        form.queryAll(validate.field).each(function(field) {
            if (!validate.one(field, event)) {
                valid = false;
            }
        });
        form.classList.toggle('invalid', !valid);
        Eventi.fire(form, valid ? 'valid' : 'invalid');
        if (!valid) {
            var el = form.query('.invalid');
            if (el) {
                el.focus();
            }
        }
        return valid;
    }
};

Eventi.on('^ready', function() {
    D.queryAll('form').each(function(){ validate.all(this, 'ready'); });
    D.queryAll('[required]').each('aria-required', true);
});
Eventi.on('keyup submit validate', function(e, event) {
    if (e.keyCode === 9) {
        return;// don't validate when tabbing
    }
    var el = e.target,
        valid = true;
    event = event && typeof event === "string" ? event : e.type;
    if (el.matches(validate.field)) {
        valid = validate.one(el, event);
    } else if (event === 'submit' || event === 'validate') {
        valid = validate.all(Eventi._.closest(el, 'form'), event);
    }
    return valid;
});
Eventi.on('focusout<[restrict]>', function(e) {
    var el = e.target;
    if (el.matches('.invalid')) {
        var is = el.value;
        el.value = el.lastValidValue || el.getAttribute('value') || '';
        Eventi.fire(el, 'restricted', is);
        setTimeout(function(){ el.focus(); }, 0);
        return false;
    }
});
// end validate<commit_msg>provide standard display styles for field error messages<commit_after>// validate
var validate = FORMx.validate = {
    // natural extension points
    type: {
        number: /^\-?\d*(\.\d+)?$/,
        email: /^[a-zA-Z0-9.!#$%&'*+-\/=?\^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/,
        url: /^http.[^\s]+$/i
    },
    constraints: {
        required: function(value) {
            return !(value && value.trim());
        },
        pattern: function(value, pattern) {
            return value && !value.match(new RegExp('^'+pattern+'$'));
        },
        'equal-to': function(value, other) {
            return value !== validate.valueOf(other);
        },
        'not-equal': function(value, other) {
            return value === validate.valueOf(other);
        },
        maxlength: function(value, maxlength) {
            return value.length > parseInt(maxlength, 10);
        },
        minlength: function(value, minlength) {
            return value && value.length < parseInt(minlength, 10);
        },
        min: function(value, min) {
            return validate.parse(value) < validate.parse(min);
        },
        max: function(value, max) {
            return validate.parse(value) > validate.parse(max);
        },
        step: function(value, step) {
            // % operator is inconsistent with floats, convert to ints first
            var decimal = step.indexOf('.'),
                factor = 1;
            if (decimal >= 0) {
                var power = step.length - decimal - 1;
                factor = Math.pow(10, power);
            }
            step = Math.round(parseFloat(step) * factor);
            var remainder = Math.round(value * factor) % step;
            return !isNaN(remainder) && remainder !== 0;
        }
    },
    classes: {
        required: 'valueMissing',
        pattern: 'patternMismatch',
        'equal-to': 'notEqual',
        'not-equal': 'notDifferent',
        maxlength: 'tooLong',
        minlength: 'tooShort',
        min: 'rangeUnderflow',
        max: 'rangeOverflow',
        step: 'stepMismatch'
    },
    field: '[type=number],[type=email],[type=url],'+//types
           '[required],[pattern],[maxlength],[min],[max],[step],'+// standards
           '[equal-to],[not-equal],[minlength]',// extensions
    toggle: function(el, valid) {
        el.classList.toggle('invalid', !valid);
        el.setCustomValidity(valid ? '' : 'This value is not valid.');
    },

    // internal functions
    valueOf: function(string) {
        if (string) {
            var el = D.query('[name="'+string+'"]');
            string = el && el.value;
        }
        return string;
    },
    parse: function(string) {
        return parseFloat(validate.valueOf(string));
    },
    check: function(el, event) {
        var no = el.getAttribute('novalidate');
        if (!no) {
            return true;
        }
        if (no === 'true' || no === 'novalidate') {
            return false;
        }
        if (no.indexOf('!') === 0) {
            return no.substring(1).split().indexOf(event) !== -1;
        }
        return no.split(' ').indexOf(event) === -1;
    },
    one: function(el, event) {
        if (!validate.check(el, event)) {
            return true;
        }

        var typeRE = validate.type[el.getAttribute('type')],
            value = el.value,
            valid = true;
        if (typeRE) {
            valid = !value || !!value.match(typeRE);
            el.classList.toggle('typeMismatch', !valid);
        }
        for (var name in validate.constraints) {
            var constraint = el.getAttribute(name) || el.hasAttribute(name);
            if (constraint) {
                var _class = validate.classes[name],
                    failed = validate.constraints[name](value, constraint);
                if (failed) {
                    valid = false;
                }
                el.classList.toggle(_class, failed);
            }
        }
        validate.toggle(el, valid);
        if (valid) {
            el.lastValidValue = value;
        }
        return valid;
    },
    all: function(form, event) {
        if (!validate.check(form, event)) {
            return true;
        }

        var valid = true;
        form.queryAll(validate.field).each(function(field) {
            if (!validate.one(field, event)) {
                valid = false;
            }
        });
        form.classList.toggle('invalid', !valid);
        Eventi.fire(form, valid ? 'valid' : 'invalid');
        if (!valid) {
            var el = form.query('.invalid');
            if (el) {
                el.focus();
            }
        }
        return valid;
    }
};

Eventi.on('^ready', function() {
    D.queryAll('form').each(function(){ validate.all(this, 'ready'); });
    D.queryAll('[required]').each('aria-required', true);
});
Eventi.on('keyup submit validate', function(e, event) {
    if (e.keyCode === 9) {
        return;// don't validate when tabbing
    }
    var el = e.target,
        valid = true;
    event = event && typeof event === "string" ? event : e.type;
    if (el.matches(validate.field)) {
        valid = validate.one(el, event);
    } else if (event === 'submit' || event === 'validate') {
        valid = validate.all(Eventi._.closest(el, 'form'), event);
    }
    return valid;
});
Eventi.on('focusout<[restrict]>', function(e) {
    var el = e.target;
    if (el.matches('.invalid')) {
        var is = el.value;
        el.value = el.lastValidValue || el.getAttribute('value') || '';
        Eventi.fire(el, 'restricted', is);
        setTimeout(function(){ el.focus(); }, 0);
        return false;
    }
});
D.head.append('style').textContent =
    '.error { display: none; }\n' +
    Object.keys(validate.classes).map(function(key) {
        var _class = validate.classes[key];
        return '.invalid.'+_class+' ~ .error.'+_class;
    }).join(',\n') +
    '{ display: inline-block; }';
// end validate<|endoftext|>


<commit_before>// First time attender discount
firstTimeAttenderDiscount = 40; // $40 USD

// Discount for half days (Monday and Saturday)
halfDayDiscountAmount = 10; // $10 USD

// Linens
linensFee = 25 // $25

// This object will contain registration prices for 2015 PYM
// The hierarchy for prices is as follows
//  age group -> registration type -> accommodations -> days attending
prices = {
    /*
    * Adult prices
    */
    'adult': {
        'commuter': 55, // daily commuter fee
        'daily': {
            'semiprivate': 75, // semiprivate lodgings
            'dorm': 60, // dorm
            'camping': 25 // daily camping
        },
        'weekly': {
            'semiprivate': 405, // weekly semiprivate
            'dorm': 300, // dorm
            'camping': 205, // weekly camping
            'yaf': 205, // weekly yaf
            'jym': 205 // weekly jym
        }
    },
    /*
    * Young adult prices
    */
    'youngAdult': {
        'commuter': 49,
        'daily': {
            'semiprivate': 159,
            'dorm': 89,
            'camping': 59,
            'yaf': 49,
            'jym': 39
        },
        'weekly': {
            'semiprivate': 409,
            'dorm': 359,
            'camping': 209,
            'yaf': 229,
            'jym': 219
        }
    },
    /*
    * Teen prices
    */
    'teen': {
        'commuter': 33,
        'daily': {
            'semiprivate': 153,
            'dorm': 103,
            'camping': 53,
            'jym': 43,
            'yaf': 33
        },
        'weekly': {
            'semiprivate': 403,
            'dorm': 303,
            'camping': 203,
            'yaf': 203,
            'jym': 203
        }
    },
    /*
    * Youth prices
    */
    'youth': {
        'commuter': 22,
        'daily': {
            'semiprivate': 152,
            'dorm': 102,
            'camping': 52,
            'jym': 42
        },
        'weekly': {
            'semiprivate': 402,
            'dorm': 302,
            'camping': 202,
            'yaf': 202,
            'jym': 202
        }
    },
    /*
    * Child prices
    */
    'child': {
        'commuter': 11,
        'daily': {
            'semiprivate': 151,
            'dorm': 101,
            'camping': 51
        },
        'weekly': {
            'semiprivate': 401,
            'dorm': 301,
            'camping': 201
        }
    }
};

<commit_msg>Added half days array.<commit_after>// First time attender discount
firstTimeAttenderDiscount = 40; // $40 USD

// Half days, used for discount calculation
halfDays = ["Monday", "Saturday"];

// Discount for half days (Monday and Saturday)
halfDayDiscountAmount = 10; // $10 USD

// Linens
linensFee = 25 // $25

// This object will contain registration prices for 2015 PYM
// The hierarchy for prices is as follows
//  age group -> registration type -> accommodations -> days attending
prices = {
    /*
    * Adult prices
    */
    'adult': {
        'commuter': 55, // daily commuter fee
        'daily': {
            'semiprivate': 75, // semiprivate lodgings
            'dorm': 60, // dorm
            'camping': 25 // daily camping
        },
        'weekly': {
            'semiprivate': 405, // weekly semiprivate
            'dorm': 300, // dorm
            'camping': 205, // weekly camping
            'yaf': 205, // weekly yaf
            'jym': 205 // weekly jym
        }
    },
    /*
    * Young adult prices
    */
    'youngAdult': {
        'commuter': 49,
        'daily': {
            'semiprivate': 159,
            'dorm': 89,
            'camping': 59,
            'yaf': 49,
            'jym': 39
        },
        'weekly': {
            'semiprivate': 409,
            'dorm': 359,
            'camping': 209,
            'yaf': 229,
            'jym': 219
        }
    },
    /*
    * Teen prices
    */
    'teen': {
        'commuter': 33,
        'daily': {
            'semiprivate': 153,
            'dorm': 103,
            'camping': 53,
            'jym': 43,
            'yaf': 33
        },
        'weekly': {
            'semiprivate': 403,
            'dorm': 303,
            'camping': 203,
            'yaf': 203,
            'jym': 203
        }
    },
    /*
    * Youth prices
    */
    'youth': {
        'commuter': 22,
        'daily': {
            'semiprivate': 152,
            'dorm': 102,
            'camping': 52,
            'jym': 42
        },
        'weekly': {
            'semiprivate': 402,
            'dorm': 302,
            'camping': 202,
            'yaf': 202,
            'jym': 202
        }
    },
    /*
    * Child prices
    */
    'child': {
        'commuter': 11,
        'daily': {
            'semiprivate': 151,
            'dorm': 101,
            'camping': 51
        },
        'weekly': {
            'semiprivate': 401,
            'dorm': 301,
            'camping': 201
        }
    }
};

<|endoftext|>


<commit_before>// This object will contain registration prices for 2015 PYM
// The hierarchy for prices is as follows
//  age group -> registration type -> accommodations -> days attending
prices = {
    /*
    * Adult prices
    */
    'adult': {
        'commuter': 50, // daily commuter fee
        'daily': {
            'private': 100, // daily private lodgings
            'semiPrivate': 75, // daily semi-private lodgings
            'dorm': 50, // daily dorm lodgings
            'camping': 25 // daily camping
        },
        'weekly': {
            'private': 500, // weekly private lodgings
            'semiPrivate': 400, // weekly semi-private
            'dorm': 300, // weekly dorm
            'camping': 200, // weekly camping
            'yaf': 200, // weekly yaf
            'jym': 200 // weekly jym
        }
    },
     /*
    * Young adult prices
    */
    'youngAdult': {
        'commuter': 50,
        'daily': {
            'private': 200,
            'semiPrivate': 150,
            'dorm': 100,
            'camping': 50
        },
        'weekly': {
            'private': 500,
            'semiPrivate': 400,
            'dorm': 300,
            'camping': 200,
            'yaf': 200,
            'jym': 200
        }
    },
    /*
    * Teen prices
    */
    'teen': {
        'commuter': 50,
        'daily': {
            'private': 200,
            'semiPrivate': 150,
            'dorm': 100,
            'camping': 50
        },
        'weekly': {
            'private': 500,
            'semiPrivate': 400,
            'dorm': 300,
            'camping': 200,
            'yaf': 200,
            'jym': 200
        }
    },
    /*
    * Youth prices
    */
    'youth': {
        'commuter': 50,
        'daily': {
            'private': 200,
            'semiPrivate': 150,
            'dorm': 100,
            'camping': 50,
            'jym': 50
        },
        'weekly': {
            'private': 500,
            'semiPrivate': 400,
            'dorm': 300,
            'camping': 200,
            'yaf': 200,
            'jym': 200
        }
    },
    /*
    * Child prices
    */
    'child': {
        'commuter': 50,
        'daily': {
            'private': 200,
            'semiPrivate': 150,
            'dorm': 100,
            'camping': 50
        },
        'weekly': {
            'private': 500,
            'semiPrivate': 400,
            'dorm': 300,
            'camping': 200
        }
    }
};

calculateRegistrationPrice = function (ageGroup, registrationType, accommodations, days) {
    /*
    * Calculate registration type based on
    *    Age,
    *    registration type,
    *    accommodations, and
    *    number of days
    */

    var total = 0;

    // Convert the input from reactive variables if needed
    try{
        ageGroup = ageGroup.get();
        registrationType = registrationType.get();
        accommodations = accommodations.get();
    } catch (e) {
        console.log(e);
    }

     // Testing variable input
    console.log("Age group input: " + ageGroup);
    console.log("Registration type input: " + registrationType);
    console.log("Accommodations input: " + accommodations);
    //console.log("Days input: " + days);

    // if registration type is commuter
        // dayFee = prices[ageGroup][registrationType]
        // for each selected days
            // check to see if any day should be discounted
            // total += dayFee

    // if registration type is daily
        // dayFee = prices[ageGroup][registrationType][accommodations]
        // for each selected days
            // if day should be discounted
                //total += day * discount (e.g. 0.5)
            // else
                // total += day

    // if registration type is weekly
    // total = prices[ageGroup][registrationType][accommodations]

    //temporary test
    total = 200;
    return total;
};
<commit_msg>Weekly calculations working.<commit_after>// This object will contain registration prices for 2015 PYM
// The hierarchy for prices is as follows
//  age group -> registration type -> accommodations -> days attending
prices = {
    /*
    * Adult prices
    */
    'adult': {
        'commuter': 50, // daily commuter fee
        'daily': {
            'private': 100, // daily private lodgings
            'semiprivate': 75, // daily semiprivate lodgings
            'dorm': 50, // daily dorm lodgings
            'camping': 25 // daily camping
        },
        'weekly': {
            'private': 500, // weekly private lodgings
            'semiprivate': 400, // weekly semiprivate
            'dorm': 300, // weekly dorm
            'camping': 200, // weekly camping
            'yaf': 200, // weekly yaf
            'jym': 200 // weekly jym
        }
    },
    /*
    * Young adult prices
    */
    'youngAdult': {
        'commuter': 50,
        'daily': {
            'private': 200,
            'semiprivate': 150,
            'dorm': 100,
            'camping': 50
        },
        'weekly': {
            'private': 500,
            'semiprivate': 400,
            'dorm': 300,
            'camping': 200,
            'yaf': 200,
            'jym': 200
        }
    },
    /*
    * Teen prices
    */
    'teen': {
        'commuter': 50,
        'daily': {
            'private': 200,
            'semiprivate': 150,
            'dorm': 100,
            'camping': 50
        },
        'weekly': {
            'private': 500,
            'semiprivate': 400,
            'dorm': 300,
            'camping': 200,
            'yaf': 200,
            'jym': 200
        }
    },
    /*
    * Youth prices
    */
    'youth': {
        'commuter': 50,
        'daily': {
            'private': 200,
            'semiprivate': 150,
            'dorm': 100,
            'camping': 50,
            'jym': 50
        },
        'weekly': {
            'private': 500,
            'semiprivate': 400,
            'dorm': 300,
            'camping': 200,
            'yaf': 200,
            'jym': 200
        }
    },
    /*
    * Child prices
    */
    'child': {
        'commuter': 50,
        'daily': {
            'private': 200,
            'semiprivate': 150,
            'dorm': 100,
            'camping': 50
        },
        'weekly': {
            'private': 500,
            'semiprivate': 400,
            'dorm': 300,
            'camping': 200
        }
    }
};

calculateRegistrationPrice = function (ageGroup, registrationType, accommodations, days) {
    /*
    * Calculate registration type based on
    *    Age,
    *    registration type,
    *    accommodations, and
    *    number of days
    */

    var total = 0;

    // Convert the input from reactive variables if needed
    try{
        ageGroup = ageGroup.get();
        registrationType = registrationType.get();
        accommodations = accommodations.get();
    } catch (e) {
        console.log(e);
    }

    //console.log("Days input: " + days);
    if (registrationType) {
        if (registrationType === 'commuter') {
            console.log("Commuter registration");
            return 'commuter';
            // dayFee = prices[ageGroup][registrationType]
            // for each selected days
            // check to see if any day should be discounted
            // total += dayFee
        }

        if (registrationType === 'daily') {
            console.log("Daily registration");
            return 'daily';
            // dayFee = prices[ageGroup][registrationType][accommodations]
            // for each selected days
            // if day should be discounted
            //total += day * discount (e.g. 0.5)
            // else
            // total += day
        }

        if (registrationType === 'weekly') {
            console.log("Weekly registration");
            if (ageGroup && registrationType && accommodations) {
                total = prices[ageGroup][registrationType][accommodations];
                return total;
            } else {
                console.log("Not enough detail.");
                return;
            }
        }
    }
};
<|endoftext|>


<commit_before>module.exports = function() { return [] }
<commit_msg>Faking a failure<commit_after>module.exports = function() { return undefined }
<|endoftext|>


<commit_before>var util = require('util');
var mongoose = require('mongoose');

function iterate(o, fn) {
	Object.keys(o).forEach(function(key, i) {
		fn(o[key], key, o);
	});
}

function length(o) {
	return Object.keys(o).length;
}

function normalize(x) {
	if(!x || typeof x !== 'object') {
		throw new Error("Argument must be an Object or an Array.");
	}
	if(x.toObject) {
		x = x.toObject();
	}
	if(!Array.isArray(x)) {
		x = [x];
	}
	var arr = [];
	x.forEach(function(o) {
		var _o = o;
		if(o.toObject) {
			_o = o.toObject();
		}
		iterate(_o, function(v, p) {
			var _obj = {};
			_obj[p] = v;
			arr.push(_obj);
		});
	});
	return arr;
}

function combine(n, arr) {
	if(n === 1) {
		return arr;
	}
	var or = [];
	comb(n, arr).forEach(function(a) {
		var _a = {$and:a};
		if(a.length === 1) {
			_a = a[0];
		}
		or.push(_a);
	});
	return or;
}

function bitprint(u, arr) {
  var s=[];
  for (var n=0; u; ++n, u>>=1)
    if (u&1) s.push(arr[n]);
  return s;
}
function bitcount(u) {
  for (var n=0; u; ++n, u=u&(u-1));
  return n;
}
function comb(c, arr) {
  var s=[], n = arr.length;
  for (var u=0; u<1<<n; u++)
    if (bitcount(u)==c)
      s.push(bitprint(u, arr));
  return s.sort();
}

function Qweary(criteria) {
	this._query = {$and:[]};
	if(criteria) {
		this.is(criteria);
	}
	return this;
}
// Inherit from Mongoose#Document. This causes causes Mongoose#Query to cast the Qweary using Qweary#toObject
// See Query.prototype.find in Mongoose (https://github.com/LearnBoost/mongoose/blob/master/lib/query.js, line 194)
Qweary.prototype.__proto__ = mongoose.Document.prototype;

Qweary.isQweary = function(q) {
	if(q.toString() === new Qweary().toString()) {
		return true;
	}
	return false;
};

Qweary.prototype.toObject = function() {
	if(this._query.$and.length > 1) {
		return this._query;
	} else if (this._query.$and.length === 1) {
		return this._query.$and[0];
	} else {
		return {};
	}
};

Qweary.prototype.toString = function() {
	return "[object Qweary]";
};

Qweary.prototype.valueOf = function() {
	return {}.valueOf.call(this.toObject());
};

// Add a custom inspect method for Node.js (see: https://github.com/joyent/node/blob/master/lib/util.js)
Qweary.prototype.inspect = function(depth) {
	return util.inspect(this.toObject(), undefined, 10); //this is old way that arguments are ordered, and it's current for Node 0.8.x
};

Qweary.prototype.is = function(obj) {
	this._query.$and = this._query.$and.concat(normalize(obj));
	return this;
};

Qweary.prototype.and = Qweary.prototype.is;

Qweary.prototype.or = function(o) {
	o = normalize(o);
	var arg;
	if(o.length > 1) {
		arg = {$and:o};
	} else if(o.length) {
		arg = o[0];
	} else {
		arg = {};
	}
	return this.oneOf([this.toObject(), arg]);
};

Qweary.prototype.allOf = Qweary.prototype.is;
Qweary.prototype.andAllOf = Qweary.prototype.allOf;
Qweary.prototype.bothOf = Qweary.prototype.allOf;
Qweary.prototype.andBothOf = Qweary.prototype.bothOf;

Qweary.prototype.nOf = function(n, arr) {
	if(n > arr.length) {
		throw new Error("Number of required arguments exceeds number of arguments.");
	}
	if(n === 0) {
		return this.noneOf(arr);
	}
	this._query.$and = this._query.$and.concat({$or:combine(n, normalize(arr))});
	return this;
};
Qweary.prototype.andNOf = Qweary.prototype.nOf;

["one", "two", "three", "four", "five"].forEach(function(num, i) {
	Qweary.prototype[num+'Of'] = function(o) {
		return this.nOf(i+1, o);
	};
	Qweary.prototype['and'+num[0].toUpperCase()+num.slice(1)+'Of'] = Qweary.prototype[num+'Of'];
});

Qweary.prototype.either = Qweary.prototype.oneOf;
Qweary.prototype.andEither = Qweary.prototype.either;
Qweary.prototype.eitherOf = Qweary.prototype.either;
Qweary.prototype.andEitherOf = Qweary.prototype.eitherOf;

// .not({linkedin:true})										=> .concat({linkedin: {$ne: true} })
// .not({price:{$gt: 10}})										=> .concat({price: {$not: {$gt: 10} } })
// .not({price:{$gt: 10, $lte:20}})								=> .concat({price: {$not: {$gt: 10, $lte:20} } })
// .not([{linkedin:true}, {username:'Trey'}])					=> .concat({$nor: [{linkedin:true}, {username:'Trey'}] })
// .not([{linkedin:true}, {username: {$ne:null}}])				=> .concat({$nor: [{linkedin:true}, {username: {$ne:null} }] })
// .not({settings: {receive_email:true, other_setting:false}})	=> .concat({settings: {$ne: {receive_email:true, other_setting:false}}})
Qweary.prototype.not = function(arr) {
	arr = normalize(arr);
	// multiple statements should be negated with $nor
	var not = {$nor:arr};
	if(arr.length === 1) {
		// transforms a normalized array of length 1 into a statement like {field: {$not: expression } }
		not = {};
		var field = Object.keys(arr[0])[0];
		var value = arr[0][field];
		if(value && typeof value === 'object') {
			var keys = Object.keys(value);
			if(keys[0][0] === '$') { // check if this is an object of mongodb operators (there should never be a mix of operators and non-operators) All mongodb operators start with '$'
				not[field] = {$not:value};
			} else {
				not[field] = {$ne: value};// simple object, negated with $ne
			}
		} else {
			not[field] = {$ne: value}; // primitive value
		}
	}
	if(arr.length) {
		this._query.$and = this._query.$and.concat(not);
	}
	return this;
};
Qweary.prototype.andNot = Qweary.prototype.not;

Qweary.prototype.noneOf = Qweary.prototype.not;
Qweary.prototype.andNoneOf = Qweary.prototype.noneOf;
Qweary.prototype.neither = Qweary.prototype.noneOf;
Qweary.prototype.andNeither = Qweary.prototype.neither;
Qweary.prototype.neitherOf = Qweary.prototype.neither;
Qweary.prototype.andNeitherOf = Qweary.prototype.neitherOf;

module.exports = Qweary;<commit_msg>remove debuggined depth<commit_after>var util = require('util');
var mongoose = require('mongoose');

function iterate(o, fn) {
	Object.keys(o).forEach(function(key, i) {
		fn(o[key], key, o);
	});
}

function length(o) {
	return Object.keys(o).length;
}

function normalize(x) {
	if(!x || typeof x !== 'object') {
		throw new Error("Argument must be an Object or an Array.");
	}
	if(x.toObject) {
		x = x.toObject();
	}
	if(!Array.isArray(x)) {
		x = [x];
	}
	var arr = [];
	x.forEach(function(o) {
		var _o = o;
		if(o.toObject) {
			_o = o.toObject();
		}
		iterate(_o, function(v, p) {
			var _obj = {};
			_obj[p] = v;
			arr.push(_obj);
		});
	});
	return arr;
}

function combine(n, arr) {
	if(n === 1) {
		return arr;
	}
	var or = [];
	comb(n, arr).forEach(function(a) {
		var _a = {$and:a};
		if(a.length === 1) {
			_a = a[0];
		}
		or.push(_a);
	});
	return or;
}

function bitprint(u, arr) {
  var s=[];
  for (var n=0; u; ++n, u>>=1)
    if (u&1) s.push(arr[n]);
  return s;
}
function bitcount(u) {
  for (var n=0; u; ++n, u=u&(u-1));
  return n;
}
function comb(c, arr) {
  var s=[], n = arr.length;
  for (var u=0; u<1<<n; u++)
    if (bitcount(u)==c)
      s.push(bitprint(u, arr));
  return s.sort();
}

function Qweary(criteria) {
	this._query = {$and:[]};
	if(criteria) {
		this.is(criteria);
	}
	return this;
}
// Inherit from Mongoose#Document. This causes causes Mongoose#Query to cast the Qweary using Qweary#toObject
// See Query.prototype.find in Mongoose (https://github.com/LearnBoost/mongoose/blob/master/lib/query.js, line 194)
Qweary.prototype.__proto__ = mongoose.Document.prototype;

Qweary.isQweary = function(q) {
	if(q.toString() === new Qweary().toString()) {
		return true;
	}
	return false;
};

Qweary.prototype.toObject = function() {
	if(this._query.$and.length > 1) {
		return this._query;
	} else if (this._query.$and.length === 1) {
		return this._query.$and[0];
	} else {
		return {};
	}
};

Qweary.prototype.toString = function() {
	return "[object Qweary]";
};

Qweary.prototype.valueOf = function() {
	return {}.valueOf.call(this.toObject());
};

// Add a custom inspect method for Node.js (see: https://github.com/joyent/node/blob/master/lib/util.js)
Qweary.prototype.inspect = function(depth) {
	return util.inspect(this.toObject(), undefined, depth); //this is old way that arguments are ordered, and it's current for Node 0.8.x
};

Qweary.prototype.is = function(obj) {
	this._query.$and = this._query.$and.concat(normalize(obj));
	return this;
};

Qweary.prototype.and = Qweary.prototype.is;

Qweary.prototype.or = function(o) {
	o = normalize(o);
	var arg;
	if(o.length > 1) {
		arg = {$and:o};
	} else if(o.length) {
		arg = o[0];
	} else {
		arg = {};
	}
	return this.oneOf([this.toObject(), arg]);
};

Qweary.prototype.allOf = Qweary.prototype.is;
Qweary.prototype.andAllOf = Qweary.prototype.allOf;
Qweary.prototype.bothOf = Qweary.prototype.allOf;
Qweary.prototype.andBothOf = Qweary.prototype.bothOf;

Qweary.prototype.nOf = function(n, arr) {
	if(n > arr.length) {
		throw new Error("Number of required arguments exceeds number of arguments.");
	}
	if(n === 0) {
		return this.noneOf(arr);
	}
	this._query.$and = this._query.$and.concat({$or:combine(n, normalize(arr))});
	return this;
};
Qweary.prototype.andNOf = Qweary.prototype.nOf;

["one", "two", "three", "four", "five"].forEach(function(num, i) {
	Qweary.prototype[num+'Of'] = function(o) {
		return this.nOf(i+1, o);
	};
	Qweary.prototype['and'+num[0].toUpperCase()+num.slice(1)+'Of'] = Qweary.prototype[num+'Of'];
});

Qweary.prototype.either = Qweary.prototype.oneOf;
Qweary.prototype.andEither = Qweary.prototype.either;
Qweary.prototype.eitherOf = Qweary.prototype.either;
Qweary.prototype.andEitherOf = Qweary.prototype.eitherOf;

// .not({linkedin:true})										=> .concat({linkedin: {$ne: true} })
// .not({price:{$gt: 10}})										=> .concat({price: {$not: {$gt: 10} } })
// .not({price:{$gt: 10, $lte:20}})								=> .concat({price: {$not: {$gt: 10, $lte:20} } })
// .not([{linkedin:true}, {username:'Trey'}])					=> .concat({$nor: [{linkedin:true}, {username:'Trey'}] })
// .not([{linkedin:true}, {username: {$ne:null}}])				=> .concat({$nor: [{linkedin:true}, {username: {$ne:null} }] })
// .not({settings: {receive_email:true, other_setting:false}})	=> .concat({settings: {$ne: {receive_email:true, other_setting:false}}})
Qweary.prototype.not = function(arr) {
	arr = normalize(arr);
	// multiple statements should be negated with $nor
	var not = {$nor:arr};
	if(arr.length === 1) {
		// transforms a normalized array of length 1 into a statement like {field: {$not: expression } }
		not = {};
		var field = Object.keys(arr[0])[0];
		var value = arr[0][field];
		if(value && typeof value === 'object') {
			var keys = Object.keys(value);
			if(keys[0][0] === '$') { // check if this is an object of mongodb operators (there should never be a mix of operators and non-operators) All mongodb operators start with '$'
				not[field] = {$not:value};
			} else {
				not[field] = {$ne: value};// simple object, negated with $ne
			}
		} else {
			not[field] = {$ne: value}; // primitive value
		}
	}
	if(arr.length) {
		this._query.$and = this._query.$and.concat(not);
	}
	return this;
};
Qweary.prototype.andNot = Qweary.prototype.not;

Qweary.prototype.noneOf = Qweary.prototype.not;
Qweary.prototype.andNoneOf = Qweary.prototype.noneOf;
Qweary.prototype.neither = Qweary.prototype.noneOf;
Qweary.prototype.andNeither = Qweary.prototype.neither;
Qweary.prototype.neitherOf = Qweary.prototype.neither;
Qweary.prototype.andNeitherOf = Qweary.prototype.neitherOf;

module.exports = Qweary;<|endoftext|>