<commit_before>(function (exports) {

  var RDF_TYPE = "http://www.w3.org/1999/02/22-rdf-syntax-ns#type";

  function Graph(mappings) {
    this.nodes = {};
    this.resolve = resolver(mappings);
    this.nextBNodeID = bnodeCounter();
  }
  Graph.prototype = {

    get: function (termOrCURIEorIRI) {
      return this.nodes[this.resolve(termOrCURIEorIRI)];
    },

    all: function () {
      var result = [], map = this.nodes;
      for (var id in map) {
        result.push(map[id]);
      }
      return result;
    },

    findByType: function (/*types...*/) {
      var result = [];
      for (var cls=null, i=0; cls=arguments[i++];) {
        result = result.concat(this.get(cls).incoming[RDF_TYPE])
      }
      return result;
    },

    toNode: function (id) {
      if (!id) {
        id = this.nextBNodeID();
      }
      var node = this.nodes[id];
      if (node === undefined) {
        node = this.nodes[id] = new Node(id, this);
      }
      return node;
    },

    importJSON: function (data) {
      ld.importData(this, data);
    },

    toJSON: function () {
      var l = [];
      for (var p in this.nodes) {
        l.push(this.nodes[p]);
      }
      return l;
    }

  };

  function resolver(map) {
    return function (termOrCURIEorIRI) {
      var dfn = map[termOrCURIEorIRI];
      if (dfn == undefined) {
        var parts = termOrCURIEorIRI.split(':');
        var ns = map[parts[0]];
        if (ns !== undefined) {
          return ns + parts[1];
        }
        return termOrCURIEorIRI;
      }
      return (typeof dfn === 'string')? dfn : dfn[ld.ID];
    };
  }

  function bnodeCounter() {
    var prefix = "_:gen-" + (new Date().getTime()).toString(16) + "-",
      count = 0;
    return function () {
      return prefix + count++;
    };
  }

  function Node(id, graph) {
    this.id = id;
    this.graph = graph;
    this.properties = {};
    this.incoming = {};
  }
  Node.prototype = {

    typeName: 'Node',

    toString: function () { return this.id; },

    toJSON: function () {
      var o = {}, props = this.properties;
      o[ld.ID] = this.id;
      for (var p in props) {
        o[p] = props[p];
      }
      return o;
    },

    get: function (path) {
      return this.getAll(path)[0];
    },

    getAll: function (path) {
      var params = (typeof path === 'string')? parsePropertyPath(path) : path;
      return this.find(params);
    },

    getType: function () {
      return this.find({term: RDF_TYPE})[0];
    },

    getTypes: function () {
      return this.find({term: RDF_TYPE});
    },

    getReverse: function (term) {
      return this.find({reverse: term})[0];
    },

    getAllReverse: function (term) {
      return this.find({reverse: term});
    },

    getList: function (path) {
      var l = this.get(path)
      return l? l.list : [];
    },

    find: function (params) {
      var result;
      if (params.reverse) {
        var iri = this.graph.resolve(params.reverse);
        result = this.incoming[iri];
      } else {
        var iri = this.graph.resolve(params.term);
        result = this.properties[iri];
      }
      if (result === undefined)
        return [];
      else
        return result;
    },

    addLink: function (rel, id) {
      var object = this.graph.toNode(id);
      var rel = this.graph.resolve(rel);
      this.add(rel, toRef(object));
      var rev = object.incoming[rel];
      if (rev === undefined) {
        rev = [];
        object.incoming[rel] = rev;
      }
      if (rev[this.id] === undefined) {
        var ref = toRef(this);
        rev.push(ref);
        rev[this.id] = ref;
      }
    },

    addValue: function (rel, value, lang, datatype) {
      // TODO: check if really literal or coerced...
      var literal = new Literal(value, lang, datatype);
      this.add(rel, literal);
    },

    addList: function (p, list) {
      this.add(p, new List(list));
    },

    /*
    TODO: ...
    setLink: function (rel, id) { },
    setValue: function (rel, value, lang, datatype) { },
    remove...
    */

    add: function (rel, obj) {
      var all = this.properties[rel];
      if (all === undefined) {
        all = this.properties[rel] = [];
      }
      all.push(obj);
    }

  };

  function parsePropertyPath(path) {
    if (path[0] === '^') {
      return {reverse: path.substring(1)};
    } else {
      return {term: path};
    }
  }

  function toRef(obj) {
    function Ref() {}
    Ref.prototype = obj;
    var ref = new Ref();
    ref.toJSON = function () {
      var o = {}; o[ld.ID] = obj.id; return o;
    };
    return ref;
  }

  function Literal(value, language, datatype, graph) {
    this.value = value;
    this.datatype = datatype;
    this.language = language;
    this.graph = graph;
  }
  Literal.prototype = {

    typeName: 'Literal',

    toString: function () { return this.value; },

    toJSON: function () {
      var o = {};
      o[ld.VALUE] = this.value;
      if (this.type) o[ld.TYPE] = this.datatype;
      if (this.language) o[ld.LANG] = this.language;
      return o;
    },

    asNumber: function () {}, // TODO

    asBoolean: function () {}, // TODO

    asDate: function () {}, // TODO

    asXML: function () {}, // TODO

    asNative: function () {
      return this.asDate() ||
        this.asBoolean() ||
          this.asNumber() ||
            this.toString();
    }

  };

  function List(array) {
    this.list = array;
  }
  List.prototype = {
    typeName: 'List',
    toJSON: function () {
      var o = {}; o[ld.LIST] = this.list;
      return o;
    }
  };

  var ld = {

    CONTEXT: '@context',
    ID: '@id',
    TYPE: '@type',
    VALUE: '@value',
    LANG: '@language',
    LIST: "@list",
    GRAPH: "@graph",

    importData: function (graph, data) {
      for (var it=null, i=0; it=data[i++];) {
        this.importItem(graph, it);
      }
    },

    importItem: function (graph, item) {
      var node = graph.toNode(item[this.ID]); // TODO: item.getSource()
      for (var p in item) {
        if (p === this.ID) {
          continue;
        }
        var o = item[p];
        if (o instanceof Array) {
          for (var i=0, it=null; it=o[i++];) {
            this.addItem(graph, node, p, it);
          }
        } else {
          this.addItem(graph, node, p, o);
        }
      }
      return node;
    },

    addItem: function (graph, node, p, item) {
      if (p === this.TYPE) {
        p = RDF_TYPE;
        if (typeof item === 'string') {
          item = {"@id": item};
        }
      }
      if (item[this.VALUE]) {
        node.addValue(p, item[this.VALUE], item[this.LANG], item[this.TYPE]);
      } else if (item[this.LIST]) {
        var items = item[this.LIST],
          list = [];
        for (var it=null, i=0; it=items[i++];) {
          // FIXME: toRef? Or just add id:s?
          list.push(this.importItem(graph, it));
        }
        node.addList(p, list);
      } else {
        var target = this.importItem(graph, item);
        node.addLink(p, target.id);
      }
    }

  };

  function toGraph(data, mappings) {
    var graph = new Graph(mappings);
    graph.importJSON(data);
    return graph;
  }

  function ns(iri) {
    var combine = function (term) {
      return iri + term;
    }
    for (var l=arguments, it=null, i=1; it=l[i++];) {
      // some function properties, like 'name' are read-only!
      var key = (combine[it] !== undefined)? it + '_' : it;
      combine[key] = iri + it;
    }
    return combine;
  }

  exports.toGraph = toGraph;
  exports.Graph = Graph;
  exports.Node = Node;
  exports.Literal = Literal;
  exports.List = List;
  exports.ns = ns;

})(typeof exports !== 'undefined'? exports : RDF = {});
<commit_msg>Improve various parts of js/rdf<commit_after>(function (exports) {

  var RDF_NS = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
  var RDF_TYPE = RDF_NS + "type";
  var RDF_FIRST = RDF_NS + "first";
  var RDF_REST = RDF_NS + "rest";
  var RDF_NIL = RDF_NS + "nil";

  function Graph(mappings) {
    this.nodes = {};
    this.resolve = resolver(mappings);
    this.nextBNodeID = bnodeCounter();
  }
  Graph.prototype = {

    get: function (termOrCURIEorIRI) {
      return this.nodes[this.resolve(termOrCURIEorIRI)];
    },

    all: function () {
      var result = [], map = this.nodes;
      for (var id in map) {
        result.push(map[id]);
      }
      return result;
    },

    getByType: function (/*types...*/) {
      var result = [];
      for (var cls=null, i=0; cls=arguments[i++];) {
        result = result.concat(this.get(cls).incoming[RDF_TYPE])
      }
      return result;
    },

    toNode: function (id) {
      if (!id) {
        id = this.nextBNodeID();
      }
      var node = this.nodes[id];
      if (node === undefined) {
        node = this.nodes[id] = new Node(id, this);
      }
      return node;
    },

    importJSON: function (data) {
      ld.importData(this, data);
    },

    toJSON: function () {
      var l = [];
      for (var p in this.nodes) {
        l.push(this.nodes[p]);
      }
      return l;
    }

  };

  function resolver(map) {
    var vocab = null;
    if (typeof map === 'string') {
      vocab = map;
      map = {};
    } else {
      vocab = map["@vocab"];
    }
    return function (termOrCURIEorIRI) {
      var dfn = map[termOrCURIEorIRI];
      if (vocab && termOrCURIEorIRI.indexOf(':') === -1) {
        return vocab + termOrCURIEorIRI;
      } else if (dfn == undefined) {
        var parts = termOrCURIEorIRI.split(':');
        var ns = map[parts[0]];
        if (ns !== undefined) {
          return ns + parts[1];
        }
        return termOrCURIEorIRI;
      }
      return dfn;
    };
  }

  function bnodeCounter() {
    var prefix = "_:gen-" + (new Date().getTime()).toString(16) + "-",
      count = 0;
    return function () {
      return prefix + count++;
    };
  }

  function Node(id, graph) {
    this.id = id;
    this.graph = graph;
    this.properties = {};
    this.incoming = {};
  }
  Node.prototype = {

    objectType: 'Node',

    toString: function () { return this.id; },

    toJSON: function () {
      var o = {}, props = this.properties;
      o[ld.ID] = this.id;
      for (var p in props) {
        o[p] = props[p];
      }
      return o;
    },

    get: function (path) {
      return this.getAll(path)[0];
    },

    getAll: function (path) {
      var params = (typeof path === 'string')? parsePropertyPath(path) : path;
      return this.find(params);
    },

    getType: function () {
      return this.find({term: RDF_TYPE})[0];
    },

    getTypes: function () {
      return this.find({term: RDF_TYPE});
    },

    getReverse: function (term) {
      return this.find({reverse: term})[0];
    },

    getAllReverse: function (term) {
      return this.find({reverse: term});
    },

    //getList: function (path) {
    //  var l = this.get(path)
    //  return l? l.list : [];
    //},

    find: function (params) {
      var result;
      if (params.reverse) {
        var iri = this.graph.resolve(params.reverse);
        result = this.incoming[iri];
      } else {
        var iri = this.graph.resolve(params.term);
        result = this.properties[iri];
      }
      if (result === undefined)
        return [];
      else
        return result;
    },

    addLink: function (rel, id) {
      var object = this.graph.toNode(id);
      var rel = this.graph.resolve(rel);
      this.add(rel, toRef(object));
      var rev = object.incoming[rel];
      if (rev === undefined) {
        rev = [];
        object.incoming[rel] = rev;
      }
      if (rev[this.id] === undefined) {
        var ref = toRef(this);
        rev.push(ref);
        rev[this.id] = ref;
      }
    },

    addValue: function (rel, value, lang, datatype) {
      // TODO: check if really literal or coerced...
      var literal = new Literal(value, lang, datatype);
      this.add(rel, literal);
    },

    addList: function (p, list) {
      this.add(p, new List(list, graph));
    },

    /*
    TODO: ...
    setLink: function (rel, id) { },
    setValue: function (rel, value, lang, datatype) { },
    remove...
    */

    add: function (rel, obj) {
      var all = this.properties[rel];
      if (all === undefined) {
        all = this.properties[rel] = [];
      }
      all.push(obj);
    }

  };

  function parsePropertyPath(path) {
    if (path.indexOf('/') > -1) {
      return {list: path.split(/\//).map(function (s) {
        return parsePropertyPath(s.trim());
      })};
    } else if (path[0] === '^') {
      return {reverse: path.substring(1)};
    } else {
      return {term: path};
    }
  }

  function toRef(obj) {
    function Ref() {}
    Ref.prototype = obj;
    var ref = new Ref();
    ref.toJSON = function () {
      var o = {}; o[ld.ID] = obj.id; return o;
    };
    return ref;
  }

  function Literal(value, language, datatype, graph) {
    this.value = value;
    this.datatype = datatype;
    this.language = language;
    this.graph = graph;
  }
  Literal.prototype = {

    objectType: 'Literal',

    toString: function () { return this.value; },

    toJSON: function () {
      var o = {};
      o[ld.VALUE] = this.value;
      if (this.type) o[ld.TYPE] = this.datatype;
      if (this.language) o[ld.LANG] = this.language;
      return o;
    },

    asNumber: function () {}, // TODO

    asBoolean: function () {}, // TODO

    asDate: function () {}, // TODO

    asXML: function () {}, // TODO

    asNative: function () {
      return this.asDate() ||
        this.asBoolean() ||
          this.asNumber() ||
            this.toString();
    }

  };

  function List(array, graph) {
    this.list = array;
    this.graph = graph;
  }
  List.prototype = {

    objectType: 'List',

    toJSON: function () {
      var o = {}; o[ld.LIST] = this.list;
      return o;
    },

    get: function (expr) {
      var iri = this.graph.resolve(expr);
      if (iri === RDF_FIRST) {
        return this.list[0];
      } else if (iri === RDF_REST) {
        var rest = this.list.slice(1);
        if (rest.length === 0) {
          new Node(RDF_NIL, this.graph);
        } else {
          return new List(rest, this.graph);
        }
      } else {
        return null;
      }
    }

  };

  var ld = {

    CONTEXT: '@context',
    ID: '@id',
    TYPE: '@type',
    VALUE: '@value',
    LANG: '@language',
    LIST: "@list",
    GRAPH: "@graph",

    importData: function (graph, data) {
      for (var it=null, i=0; it=data[i++];) {
        this.importItem(graph, it);
      }
    },

    importItem: function (graph, item) {
      var node = graph.toNode(item[this.ID]);
      for (var p in item) {
        if (p === this.ID) {
          continue;
        }
        var o = item[p];
        if (o instanceof Array) {
          for (var i=0, it=null; it=o[i++];) {
            this.addItem(graph, node, p, it);
          }
        } else {
          this.addItem(graph, node, p, o);
        }
      }
      return node;
    },

    addItem: function (graph, node, p, item) {
      if (p === this.TYPE) {
        p = RDF_TYPE;
        if (typeof item === 'string') {
          item = {"@id": item};
        }
      }
      if (typeof item === 'string') {
        node.addValue(p, item);
      } else if (item[this.VALUE]) {
        node.addValue(p, item[this.VALUE], item[this.LANG], item[this.TYPE]);
      } else if (item[this.LIST]) {
        var items = item[this.LIST],
          list = [];
        for (var it=null, i=0; it=items[i++];) {
          // FIXME: toRef? Or just add id:s?
          list.push(this.importItem(graph, it));
        }
        node.addList(p, list);
      } else {
        var target = this.importItem(graph, item);
        node.addLink(p, target.id);
      }
    }

  };

  function toGraph(data, mappings) {
    var graph = new Graph(mappings);
    graph.importJSON(data);
    return graph;
  }

  function ns(iri) {
    var combine = function (term) {
      return iri + term;
    }
    for (var l=arguments, it=null, i=1; it=l[i++];) {
      // some function properties, like 'name' are read-only!
      var key = (combine[it] !== undefined)? it + '_' : it;
      combine[key] = iri + it;
    }
    return combine;
  }

  exports.toGraph = toGraph;
  exports.Graph = Graph;
  exports.Node = Node;
  exports.Literal = Literal;
  exports.List = List;
  exports.ns = ns;

})(typeof exports !== 'undefined'? exports : RDF = {});
<|endoftext|>


<commit_before>// Copyright © Thaddee Tyl. MIT license.
(function (window, undefined) {

var SET = {};

// Parse code.
//

var whiteSpace = new RegExp('[\n\r \t\u0009\u0020\u00a0\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u200c\u200d\u202f\u205f\u2060\u3000\ufeff]');
var spaces = new RegExp('[ \t\u0009\u0020\u00a0\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u200c\u200d\u202f\u205f\u2060\u3000\ufeff]');
var newline = new RegExp('[\n\r]');
var stringEscape = new RegExp('["\\\\\/bfnrtu\n]');
var hexadecimal = new RegExp('[a-fA-F0-9]');
var digit = new RegExp('[0-9]');

function SetStream(text, filename) {
  this.text = text;
  this.filename = filename || '(set)';
}

SetStream.prototype = {
  text: '',
  filename: '',
  offset: 0,
  line: 0,
  column: 0,
  sol: 0,  // index of start of line.
  getChar: function() {
    var c = this.text[this.offset];
    if (c == '\n' || c == '\r') {
      this.column = 0;
      this.line ++;
    } else {
      this.column ++;
    }
    return this.text[this.offset++];
  },
  peekChar: function() {
    return this.text[this.offset];
  },
  skip: function(chars) {
    var rchars = new RegExp(chars);
    while (rchars.test(this.text[this.offset])) {
      if (!this.getChar()) { return; }
    }
  },
  skipWhitespace: function() {
    var i, ch, offset;
    for (;;) {
      this.skip(spaces);
      ch = this.peekChar();
      if (!ch) { return; }
      if (ch === '#') {
        // Comment!
        while (!newline.test(ch)) {
          if (!ch) { return; }
          ch = this.getChar();
        }
      }
      offset = this.offset;
      this.skip(newline);
      if (offset < this.offset) {
        // We did skip a newline.
        this.sol = this.offset;
      }
      ch = this.peekChar();
      if (!(whiteSpace.test(ch) || ch === "#")) {
        break;
      }
    }
  },
  currentIndent: function() {
    var i, sol;
    for (sol = i = this.sol; ; i++) {
      ch = this.text[i];
      if (ch !== " ") {
        break;
      }
    }
    return i - sol;
  },
  error: function(msg) {
    throw new Error(this.filename + ':' + this.line + ':' + this.column +
      ' ' + msg
    );
  },

  readPrimitive: function() {
    var ch, slice;
    this.skipWhitespace();
    ch = this.peekChar();
    if (ch === '"') {
      // String!
      return this.readString();
    }
    if (ch === '-') {
      ch = this.text[this.offset + 1];
      if (whiteSpace.test(ch)) {
        // Array!
        return this.readArray();
      } else {
        // Number!
        return this.readNumber();
      }
    }
    if (digit.test(ch)) {
      // Number!
      return this.readNumber();
    }
    slice = this.text.slice(this.offset, this.offset + 3);
    if (slice === "yes") {
      if (newline.test(this.text[this.offset + 3])) {
        // Boolean!
        for (i = 0; i < 3; i++) { this.getChar(); }
        return true;
      }
    }
    if (slice === "nil") {
      if (newline.test(this.text[this.offset + 3])) {
        // Null!
        for (i = 0; i < 3; i++) { this.getChar(); }
        return null;
      }
    }
    slice = this.text.slice(this.offset, this.offset + 2);
    if (slice === "no") {
      if (newline.test(this.text[this.offset + 2])) {
        // Boolean!
        for (i = 0; i < 2; i++) { this.getChar(); }
        return false;
      }
    }
    // Dictionary!
    return this.readDictionary();
  },

  // We are at the " of the string.
  readString: function() {
    var ch, start, end, i;
    start = end = this.offset;
    this.getChar();  // Go past the ".
    for (;;) {
      ch = this.getChar();
      if (!ch) { this.error("Unfinished string."); }
      if (ch === '\\') {
        ch = this.getChar();
        if (!stringEscape.test(ch)) {
          // ERROR
          this.error('Unescaped backslash before "' + ch + '".');
        } else if (ch === 'u') {
          // Unicode escape.
          for (i = 0; i < 4; i++) {
            ch = this.getChar();
            if (!hexadecimal.test(ch)) {
              // ERROR
              this.error('Invalid unicode escape.');
            }
          }
        }
      } else if (ch === '"') {
        end = this.offset;
        break;
      }
    }
    return JSON.parse(this.text.slice(start, end));
  },

  // We're at the start of a number.
  readNumber: function() {
    var ch, start, end;
    start = end = this.offset;
    ch = this.getChar();
    if (ch === '-') {
      ch = this.getChar();
    }
    if (ch === "0") {
      ch = this.getChar();  // skip the dot.
      if (whiteSpace.test(ch)) {
        return 0;
      }
      // Expect a dot.
      if (ch !== ".") {
        // ERROR
        this.error('Number starting with 0 must be floating-point.');
      }
      this.skipNumberDecimals();
    } else if (digit.test(ch)) {
      for (;;) {
        ch = this.peekChar();
        if (!digit.test(ch)) {
          if (ch === ".") {
            this.getChar();  // skip the dot.
            this.skipNumberDecimals();
          }
          break;
        } else {
          this.getChar();
        }
      }
    } else {
      // ERROR
      this.error('Number started with - is invalid.');
    }
    this.skipExponent();
    end = this.offset;
    return JSON.parse(this.text.slice(start, end));
  },

  skipNumberDecimals: function() {
    var ch;
    for (;;) {
      ch = this.peekChar();
      if (!digit.test(ch)) {
        return;
      }
      this.getChar();
    }
  },

  skipExponent: function() {
    var ch;
    ch = this.peekChar();
    if (ch !== "e" && ch !== "E") {
      return;
    }
    this.getChar();
    ch = this.getChar();
    if (ch === "+" || ch === "-") {
      ch = this.getChar();
    }
    for (;;) {
      ch = this.peekChar();
      if (!digit.test(ch)) {
        return;
      }
      this.getChar();
    }
  },

  // Starts at -.
  readArray: function() {
    var ar, ch, indent;
    ar = [];
    indent = this.currentIndent();
    while (this.currentIndent() >= indent) {
      ch = this.getChar();
      if (!ch) { break; }
      if (ch !== "-") {
        this.error('Invalid array, found ' + JSON.stringify(ch) +
            ' instead of "-".');
      }
      indent = this.currentIndent();  // Readjust indentation.
      ar.push(this.readPrimitive());
      this.skipWhitespace();
    }
    return ar;
  },

  // Starts with a key.
  readDictionary: function() {
    var start, end, key, ch, indent, dict;
    dict = {};
    indent = this.currentIndent();
    while (this.currentIndent() >= indent) {

      ch = this.peekChar();
      if (ch === '"') {
        key = this.readString();
        this.getChar();  // skip :.
      } else {
        start = end = this.offset;
        for (;;) {
          ch = this.getChar();
          if (!ch) { break; }
          if (ch === ":") {
            break;
          }
        }
        end = this.offset - 1;
        key = this.text.slice(start, end);
      }
      if (!ch) { break; }

      indent = this.currentIndent();  // Readjust indentation.
      dict[key] = this.readPrimitive();
      this.skipWhitespace();
    }

    return dict;
  }
}

SET.parse = function (text) {
  // `toplevel` is the object returned.
  var input = new SetStream(text);
  return input.readPrimitive();
};

// Stringify code.
//

SET.stringify = function SET_STRINGIFY(object, sizeIndent) {
  return set_stringify(object, sizeIndent,
    0,    // indentation
    false // indent the first item
  );
};

function set_stringify(object, sizeIndent, indentation, noIndentFirstItem) {
  var indent = "", i = 0, str = "";
  sizeIndent = sizeIndent || 2;
  for (i = 0; i < indentation * sizeIndent; i++) {
    indent += " ";
  }
  if (object === null || object === undefined) {
    return "nil";
  } else if (object === true) {
    return "yes";
  } else if (object === false) {
    return "no";
  } else if (typeof object === "number") {
    return new String(object);
  } else if (typeof object === "string") {
    return JSON.stringify(object);
  } else if (object instanceof Array) {
    if (object.length === 0) {
      return "nil";
    }
    for (i = 0; i < object.length; i++) {
      str += ((noIndentFirstItem && i === 0)? "": indent) + "- "
          + set_stringify(object[i], sizeIndent, indentation + 1, true)
          + '\n';
    }
  } else if (typeof object === "object") {
    i = 0;
    for (var e in object) {
      str += ((noIndentFirstItem && i === 0)? "": indent) + wrapKey(e) + ":"
          + ((typeof object[e] === "object" && object[e] !== null)?
              "\n": " ")
          + set_stringify(object[e], sizeIndent, indentation + 1)
          + '\n';
      i = 1;
    }
  }
  return str;
};

function wrapKey(key) {
  if (key[0] === '-' || key[0] === '"') {
    return JSON.stringify(new String(key));
  } else if (key.indexOf(':') === -1) {
    return new String(key);
  }
  return JSON.stringify(new String(key));
}

if (!!window.module) {
  // node.js environment.
  module.exports = SET;
} else {
  window.SET = SET;
}

}(this));
<commit_msg>Empty arrays appear on the same line as dict keys.<commit_after>// Copyright © Thaddee Tyl. MIT license.
(function (window, undefined) {

var SET = {};

// Parse code.
//

var whiteSpace = new RegExp('[\n\r \t\u0009\u0020\u00a0\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u200c\u200d\u202f\u205f\u2060\u3000\ufeff]');
var spaces = new RegExp('[ \t\u0009\u0020\u00a0\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u200c\u200d\u202f\u205f\u2060\u3000\ufeff]');
var newline = new RegExp('[\n\r]');
var stringEscape = new RegExp('["\\\\\/bfnrtu\n]');
var hexadecimal = new RegExp('[a-fA-F0-9]');
var digit = new RegExp('[0-9]');

function SetStream(text, filename) {
  this.text = text;
  this.filename = filename || '(set)';
}

SetStream.prototype = {
  text: '',
  filename: '',
  offset: 0,
  line: 0,
  column: 0,
  sol: 0,  // index of start of line.
  getChar: function() {
    var c = this.text[this.offset];
    if (c == '\n' || c == '\r') {
      this.column = 0;
      this.line ++;
    } else {
      this.column ++;
    }
    return this.text[this.offset++];
  },
  peekChar: function() {
    return this.text[this.offset];
  },
  skip: function(chars) {
    var rchars = new RegExp(chars);
    while (rchars.test(this.text[this.offset])) {
      if (!this.getChar()) { return; }
    }
  },
  skipWhitespace: function() {
    var i, ch, offset;
    for (;;) {
      this.skip(spaces);
      ch = this.peekChar();
      if (!ch) { return; }
      if (ch === '#') {
        // Comment!
        while (!newline.test(ch)) {
          if (!ch) { return; }
          ch = this.getChar();
        }
      }
      offset = this.offset;
      this.skip(newline);
      if (offset < this.offset) {
        // We did skip a newline.
        this.sol = this.offset;
      }
      ch = this.peekChar();
      if (!(whiteSpace.test(ch) || ch === "#")) {
        break;
      }
    }
  },
  currentIndent: function() {
    var i, sol;
    for (sol = i = this.sol; ; i++) {
      ch = this.text[i];
      if (ch !== " ") {
        break;
      }
    }
    return i - sol;
  },
  error: function(msg) {
    throw new Error(this.filename + ':' + this.line + ':' + this.column +
      ' ' + msg
    );
  },

  readPrimitive: function() {
    var ch, slice;
    this.skipWhitespace();
    ch = this.peekChar();
    if (ch === '"') {
      // String!
      return this.readString();
    }
    if (ch === '-') {
      ch = this.text[this.offset + 1];
      if (whiteSpace.test(ch)) {
        // Array!
        return this.readArray();
      } else {
        // Number!
        return this.readNumber();
      }
    }
    if (digit.test(ch)) {
      // Number!
      return this.readNumber();
    }
    slice = this.text.slice(this.offset, this.offset + 3);
    if (slice === "yes") {
      if (newline.test(this.text[this.offset + 3])) {
        // Boolean!
        for (i = 0; i < 3; i++) { this.getChar(); }
        return true;
      }
    }
    if (slice === "nil") {
      if (newline.test(this.text[this.offset + 3])) {
        // Null!
        for (i = 0; i < 3; i++) { this.getChar(); }
        return null;
      }
    }
    slice = this.text.slice(this.offset, this.offset + 2);
    if (slice === "no") {
      if (newline.test(this.text[this.offset + 2])) {
        // Boolean!
        for (i = 0; i < 2; i++) { this.getChar(); }
        return false;
      }
    }
    // Dictionary!
    return this.readDictionary();
  },

  // We are at the " of the string.
  readString: function() {
    var ch, start, end, i;
    start = end = this.offset;
    this.getChar();  // Go past the ".
    for (;;) {
      ch = this.getChar();
      if (!ch) { this.error("Unfinished string."); }
      if (ch === '\\') {
        ch = this.getChar();
        if (!stringEscape.test(ch)) {
          // ERROR
          this.error('Unescaped backslash before "' + ch + '".');
        } else if (ch === 'u') {
          // Unicode escape.
          for (i = 0; i < 4; i++) {
            ch = this.getChar();
            if (!hexadecimal.test(ch)) {
              // ERROR
              this.error('Invalid unicode escape.');
            }
          }
        }
      } else if (ch === '"') {
        end = this.offset;
        break;
      }
    }
    return JSON.parse(this.text.slice(start, end));
  },

  // We're at the start of a number.
  readNumber: function() {
    var ch, start, end;
    start = end = this.offset;
    ch = this.getChar();
    if (ch === '-') {
      ch = this.getChar();
    }
    if (ch === "0") {
      ch = this.getChar();  // skip the dot.
      if (whiteSpace.test(ch)) {
        return 0;
      }
      // Expect a dot.
      if (ch !== ".") {
        // ERROR
        this.error('Number starting with 0 must be floating-point.');
      }
      this.skipNumberDecimals();
    } else if (digit.test(ch)) {
      for (;;) {
        ch = this.peekChar();
        if (!digit.test(ch)) {
          if (ch === ".") {
            this.getChar();  // skip the dot.
            this.skipNumberDecimals();
          }
          break;
        } else {
          this.getChar();
        }
      }
    } else {
      // ERROR
      this.error('Number started with - is invalid.');
    }
    this.skipExponent();
    end = this.offset;
    return JSON.parse(this.text.slice(start, end));
  },

  skipNumberDecimals: function() {
    var ch;
    for (;;) {
      ch = this.peekChar();
      if (!digit.test(ch)) {
        return;
      }
      this.getChar();
    }
  },

  skipExponent: function() {
    var ch;
    ch = this.peekChar();
    if (ch !== "e" && ch !== "E") {
      return;
    }
    this.getChar();
    ch = this.getChar();
    if (ch === "+" || ch === "-") {
      ch = this.getChar();
    }
    for (;;) {
      ch = this.peekChar();
      if (!digit.test(ch)) {
        return;
      }
      this.getChar();
    }
  },

  // Starts at -.
  readArray: function() {
    var ar, ch, indent;
    ar = [];
    indent = this.currentIndent();
    while (this.currentIndent() >= indent) {
      ch = this.getChar();
      if (!ch) { break; }
      if (ch !== "-") {
        this.error('Invalid array, found ' + JSON.stringify(ch) +
            ' instead of "-".');
      }
      indent = this.currentIndent();  // Readjust indentation.
      ar.push(this.readPrimitive());
      this.skipWhitespace();
    }
    return ar;
  },

  // Starts with a key.
  readDictionary: function() {
    var start, end, key, ch, indent, dict;
    dict = {};
    indent = this.currentIndent();
    while (this.currentIndent() >= indent) {

      ch = this.peekChar();
      if (ch === '"') {
        key = this.readString();
        this.getChar();  // skip :.
      } else {
        start = end = this.offset;
        for (;;) {
          ch = this.getChar();
          if (!ch) { break; }
          if (ch === ":") {
            break;
          }
        }
        end = this.offset - 1;
        key = this.text.slice(start, end);
      }
      if (!ch) { break; }

      indent = this.currentIndent();  // Readjust indentation.
      dict[key] = this.readPrimitive();
      this.skipWhitespace();
    }

    return dict;
  }
}

SET.parse = function (text) {
  // `toplevel` is the object returned.
  var input = new SetStream(text);
  return input.readPrimitive();
};

// Stringify code.
//

SET.stringify = function SET_STRINGIFY(object, sizeIndent) {
  return set_stringify(object, sizeIndent,
    0,    // indentation
    false // indent the first item
  );
};

function set_stringify(object, sizeIndent, indentation, noIndentFirstItem) {
  var indent = "", i = 0, str = "";
  sizeIndent = sizeIndent || 2;
  for (i = 0; i < indentation * sizeIndent; i++) {
    indent += " ";
  }
  if (object === null || object === undefined) {
    return "nil";
  } else if (object === true) {
    return "yes";
  } else if (object === false) {
    return "no";
  } else if (typeof object === "number") {
    return new String(object);
  } else if (typeof object === "string") {
    return JSON.stringify(object);
  } else if (object instanceof Array) {
    if (object.length === 0) {
      return "nil";
    }
    for (i = 0; i < object.length; i++) {
      str += ((noIndentFirstItem && i === 0)? "": indent) + "- "
          + set_stringify(object[i], sizeIndent, indentation + 1, true)
          + '\n';
    }
  } else {
    i = 0;
    for (var e in object) {
      str += ((noIndentFirstItem && i === 0)? "": indent) + wrapKey(e) + ":"
          + ((typeof object[e] === "object" && object[e] != null
              && (object[e] instanceof Array? object[e].length > 0: true))?
              "\n": " ")
          + set_stringify(object[e], sizeIndent, indentation + 1)
          + '\n';
      i = 1;
    }
  }
  return str;
};

function wrapKey(key) {
  if (key[0] === '-' || key[0] === '"') {
    return JSON.stringify(new String(key));
  } else if (key.indexOf(':') === -1) {
    return new String(key);
  }
  return JSON.stringify(new String(key));
}

if (!!window.module) {
  // node.js environment.
  module.exports = SET;
} else {
  window.SET = SET;
}

}(this));
<|endoftext|>


<commit_before>import Controller from '@ember/controller';
import config from 'ember-api-docs/config/environment';

const links = [
  {
    name: 'Docs',
    type: 'dropdown',
    items: [
      {
        href: 'https://guides.emberjs.com',
        name: 'Ember.js Guides',
        type: 'link'
      },
      {
        href: config.APP.domain,
        name: 'API Reference',
        type: 'link'
      },
      {
        href: 'https://cli.emberjs.com',
        name: 'CLI Guides',
        type: 'link'
      },
      {
        type: 'divider'
      },
      {
        href: 'https://emberjs.com/learn',
        name: 'Learn Ember',
        type: 'link'
      }
    ]
  },
  {
    name: 'Releases',
    type: 'dropdown',
    items: [
      {
        href: 'https://emberjs.com/builds',
        name: 'Channels',
        type: 'link'
      },
      {
        href: 'https://emberjs.com/builds/release',
        name: '-- Stable',
        type: 'link'
      },
      {
        href: 'https://emberjs.com/builds/beta',
        name: '-- Beta',
        type: 'link'
      },
      {
        href: 'https://emberjs.com/builds/canary',
        name: '-- Canary',
        type: 'link'
      },
      {
        type: 'divider'
      },
      {
        href: 'https://emberjs.com/deprecations',
        name: 'Deprecations',
        type: 'link'
      },
      {
        href: 'https://emberjs.com/statusboard',
        name: 'Status Board',
        type: 'link'
      }
    ]
  },
  {
    href: 'https://emberjs.com/blog',
    name: 'Blog',
    type: 'link'
  },
  {
    name: 'Community',
    type: 'dropdown',
    items: [
      {
        href: 'https://emberjs.com/community',
        name: 'The Ember Community',
        type: 'link'
      },
      {
        href: 'https://emberjs.com/guidelines',
        name: 'Guidelines',
        type: 'link'
      },
      {
        href: 'http://github.com/emberjs/',
        name: 'Contribute (Github)',
        type: 'link'
      },
      {
        type: 'divider'
      },
      {
        href: 'https://emberjs.com/community/meetups',
        name: 'Meetups',
        type: 'link'
      },
      {
        href: 'http://jobs.emberjs.com/',
        name: 'Job Board',
        type: 'link'
      },
      {
        type: 'divider'
      },
      {
        href: 'http://emberconf.com/',
        name: 'Ember Conf',
        type: 'link'
      }
    ]
  },
  {
    name: 'About',
    type: 'dropdown',
    items: [
      {
        href: 'https://emberjs.com/team',
        name: 'The Team',
        type: 'link'
      },
      {
        type: 'divider'
      },
      {
        href: 'https://emberjs.com/logos',
        name: 'Logos',
        type: 'link'
      },
      {
        href: 'https://emberjs.com/mascots',
        name: 'Mascots',
        type: 'link'
      },
      {
        type: 'divider'
      },
      {
        href: 'https://emberjs.com/ember-users',
        name: 'Who Uses Ember',
        type: 'link'
      },
      {
        href: 'https://emberjs.com/sponsors',
        name: 'Sponsors',
        type: 'link'
      },
      {
        type: 'divider'
      },
      {
        href: 'https://emberjs.com/legal',
        name: 'Legal',
        type: 'link'
      },
      {
        href: 'https://emberjs.com/security',
        name: 'Security',
        type: 'link'
      }
    ]
  }
];

export default Controller.extend({
  links: null,

  init() {
    this._super(...arguments);
    this.links = links;
  }
});
<commit_msg>Use https instead of http<commit_after>import Controller from '@ember/controller';
import config from 'ember-api-docs/config/environment';

const links = [
  {
    name: 'Docs',
    type: 'dropdown',
    items: [
      {
        href: 'https://guides.emberjs.com',
        name: 'Ember.js Guides',
        type: 'link'
      },
      {
        href: config.APP.domain,
        name: 'API Reference',
        type: 'link'
      },
      {
        href: 'https://cli.emberjs.com',
        name: 'CLI Guides',
        type: 'link'
      },
      {
        type: 'divider'
      },
      {
        href: 'https://emberjs.com/learn',
        name: 'Learn Ember',
        type: 'link'
      }
    ]
  },
  {
    name: 'Releases',
    type: 'dropdown',
    items: [
      {
        href: 'https://emberjs.com/builds',
        name: 'Channels',
        type: 'link'
      },
      {
        href: 'https://emberjs.com/builds/release',
        name: '-- Stable',
        type: 'link'
      },
      {
        href: 'https://emberjs.com/builds/beta',
        name: '-- Beta',
        type: 'link'
      },
      {
        href: 'https://emberjs.com/builds/canary',
        name: '-- Canary',
        type: 'link'
      },
      {
        type: 'divider'
      },
      {
        href: 'https://emberjs.com/deprecations',
        name: 'Deprecations',
        type: 'link'
      },
      {
        href: 'https://emberjs.com/statusboard',
        name: 'Status Board',
        type: 'link'
      }
    ]
  },
  {
    href: 'https://emberjs.com/blog',
    name: 'Blog',
    type: 'link'
  },
  {
    name: 'Community',
    type: 'dropdown',
    items: [
      {
        href: 'https://emberjs.com/community',
        name: 'The Ember Community',
        type: 'link'
      },
      {
        href: 'https://emberjs.com/guidelines',
        name: 'Guidelines',
        type: 'link'
      },
      {
        href: 'https://github.com/emberjs/',
        name: 'Contribute (Github)',
        type: 'link'
      },
      {
        type: 'divider'
      },
      {
        href: 'https://emberjs.com/community/meetups',
        name: 'Meetups',
        type: 'link'
      },
      {
        href: 'https://jobs.emberjs.com/',
        name: 'Job Board',
        type: 'link'
      },
      {
        type: 'divider'
      },
      {
        href: 'https://emberconf.com/',
        name: 'Ember Conf',
        type: 'link'
      }
    ]
  },
  {
    name: 'About',
    type: 'dropdown',
    items: [
      {
        href: 'https://emberjs.com/team',
        name: 'The Team',
        type: 'link'
      },
      {
        type: 'divider'
      },
      {
        href: 'https://emberjs.com/logos',
        name: 'Logos',
        type: 'link'
      },
      {
        href: 'https://emberjs.com/mascots',
        name: 'Mascots',
        type: 'link'
      },
      {
        type: 'divider'
      },
      {
        href: 'https://emberjs.com/ember-users',
        name: 'Who Uses Ember',
        type: 'link'
      },
      {
        href: 'https://emberjs.com/sponsors',
        name: 'Sponsors',
        type: 'link'
      },
      {
        type: 'divider'
      },
      {
        href: 'https://emberjs.com/legal',
        name: 'Legal',
        type: 'link'
      },
      {
        href: 'https://emberjs.com/security',
        name: 'Security',
        type: 'link'
      }
    ]
  }
];

export default Controller.extend({
  links: null,

  init() {
    this._super(...arguments);
    this.links = links;
  }
});
<|endoftext|>


<commit_before>'use strict';

const Promise = require('bluebird');
const Game = require('../models/Game');
const User = require('../models/User');

module.exports = function() {
  const create = function(gameData) {
    return new Promise((resolve, reject) => {
      const game = new Game(gameData);
      game.createdAt = Date.now();
      game.updatedAt = Date.now();
      game.save()
        .then((createdGame) => {
          Game.findById(createdGame.id)
            .select('-__v')
            .exec()
            .then((newGame) => {
              addToUsers(newGame);
              resolve(newGame);
            })
            .catch((err) => {
              console.log(err);
              reject();
            });
        })
        .catch((err) => {
          console.log(err);
          reject();
        });
    });
  };

  const getById = function(gameId) {
    return new Promise((resolve, reject) => {
      Game.findById(gameId)
        .select('-__v')
        .exec()
        .then((game) => {
          resolve(game);
        })
        .catch((err) => {
          console.log(err);
          reject();
        });
    });
  };

  const getByPublicId = function(publicId) {
    return new Promise((resolve, reject) => {
      Game.findOne({
        publicId: publicId,
      })
        .select('-__v')
        .exec()
        .then((game) => {
          console.log('found game');
          console.log(game);
          resolve(game);
        })
        .catch((err) => {
          console.log(err);
          reject();
        });
    });
  };

  const getGames = function(emailOrUsername) {
    return new Promise((resolve, reject) => {
      User.findOne({
        $or: [
          { email: emailOrUsername },
          { username: emailOrUsername },
        ],
      },{
        password: 0,
      })
        .populate('gameIds')
        .exec()
        .then((user) => {
          console.log(user);
          resolve(user.gameIds);
        })
        .catch(reject);
      });
  };

  const addToUsers = function(game) {
    game.players.forEach((player) => {
      return new Promise((resolve, reject) => {
        User.update({
          _id: player._id,
        },{
          $addToSet: {
            gameIds: {
              game: game._id,
              publicId: game.publicId,
              strokes: player.strokes,
            },
          },
        })
          .then((res) => {
            resolve(res);
          })
          .catch(reject);
      });
    });
  };

  return {
    create: create,
    getById: getById,
    getByPublicId: getByPublicId,
    getGames: getGames,
  };
};
<commit_msg>add function to get all games by public id<commit_after>'use strict';

const Promise = require('bluebird');
const Game = require('../models/Game');
const User = require('../models/User');

module.exports = function() {
  const create = function(gameData) {
    return new Promise((resolve, reject) => {
      const game = new Game(gameData);
      game.createdAt = Date.now();
      game.updatedAt = Date.now();
      game.save()
        .then((createdGame) => {
          Game.findById(createdGame.id)
            .select('-__v')
            .exec()
            .then((newGame) => {
              addToUsers(newGame);
              resolve(newGame);
            })
            .catch((err) => {
              console.log(err);
              reject();
            });
        })
        .catch((err) => {
          console.log(err);
          reject();
        });
    });
  };

  const getById = function(gameId) {
    return new Promise((resolve, reject) => {
      Game.findById(gameId)
        .select('-__v')
        .exec()
        .then((game) => {
          resolve(game);
        })
        .catch((err) => {
          console.log(err);
          reject();
        });
    });
  };

  const getByPublicId = function(publicId) {
    return new Promise((resolve, reject) => {
      Game.findOne({
        publicId: publicId,
      })
        .select('-__v')
        .exec()
        .then((game) => {
          console.log('found game');
          console.log(game);
          resolve(game);
        })
        .catch((err) => {
          console.log(err);
          reject();
        });
    });
  };

  const getAllByPublicId = function(publicIdArray) {
    return new Promise((resolve, reject) => {
        Game.find({
          publicId: {
            $in: publicIdArray,
          },
        })
          .select('-__v')
          .exec()
          .then((games) => {
            console.log(games);
            resolve(games);
          })
          .catch((err) => {
            console.log(err);
            reject();
          });
    });
  };

  const getGames = function(emailOrUsername) {
    return new Promise((resolve, reject) => {
      User.findOne({
        $or: [
          { email: emailOrUsername },
          { username: emailOrUsername },
        ],
      },{
        password: 0,
      })
        .populate('gameIds')
        .exec()
        .then((user) => {
          resolve(user.gameIds);
        })
        .catch(reject);
      });
  };

  const addToUsers = function(game) {
    game.players.forEach((player) => {
      return new Promise((resolve, reject) => {
        User.update({
          _id: player._id,
        },{
          $addToSet: {
            gameIds: {
              game: game._id,
              publicId: game.publicId,
              strokes: player.strokes,
            },
          },
        })
          .then((res) => {
            resolve(res);
          })
          .catch(reject);
      });
    });
  };

  return {
    create: create,
    getById: getById,
    getByPublicId: getByPublicId,
    getGames: getGames,
  };
};
<|endoftext|>


<commit_before>(function(){
    var _tbaEventServiceId = 'tba.event.service';
angular.module('tba')
    .factory(_tbaEventServiceId, ['tba.core.async', 'tba.core.fakes', 'tba.core.array', 'tba.core.log',
        'tba.user.service', 'tba.project.service', eventService]);

function eventService(async, fakes, array, log, userService, projectService) {
    var _selectedEvent = null,      // currently selected (editing) event
        _selectedDate = moment(),   // currently selected date
        _today = moment(),          // today
        _events = [],               // all events for the logged in user

        _service = {
            // async methods
            createEventAsync: createEventAsync,
            getEventsAsync: getEventsAsync,
            updateEventAsync: updateEventAsync,
            deleteEventAsync: deleteEventAsync,
            searchEventsAsync: searchEventsAsync,

            // selected event (only one)
            selectEvent: selectEvent,
            unselectEvent: unselectEvent,
            getSelectedEvent: getSelectedEvent,

            // title
            getDayTitle: getDayTitle,
            getWeekTitle: getWeekTitle,
            getMonthTitle: getMonthTitle,

            // selected date (only one)
            selectDate: selectDate,
            getSelectedDate: getSelectedDate,

            // init
            activateAsync: activateAsync,

            // event helpers
            getEventDuration: getEventDuration,
            getEventTimeLabel: getEventTimeLabel
        };

    return _service;

    function activateAsync() {
        // load the database full of fake events
        var _fromDate = _today.subtract(30, 'days');
        var _user = userService.getLoggedInUser();

        _events = fakes.randomUserEvents(_user, _fromDate, 60, _user.projects);
        _events = _events.map(parseEvent);
        log.log('Activated ', _events, _tbaEventServiceId, true);
        return async.asPromise(_events);

    }

    /********************************************************************/
    /*     Selected Date                                                */
    /********************************************************************/
    function selectDate(d) {
        _selectedDate = moment(d);
        return getDayTitle();
    }

    function getSelectedDate() {
        return _selectedDate;
    }

    /********************************************************************/
    /*    Title                                                         */
    /********************************************************************/
    function getDayTitle() {
        return _selectedDate.format("MMMM Do YYYY");
    }

    function getWeekTitle() {
        var _dow = _selectedDate.day(),
            _m = moment(_selectedDate).subtract((_dow - 1), 'day').format("dddd Do"),
            _f = moment(_selectedDate).add((5 - _dow), 'day').format("dddd Do, MMMM  YYYY");
        return _m + ' to ' + _f;
    }

    function getMonthTitle() {
        return _selectedDate.format("MMMM  YYYY");
    }

    /**********************************************************
    /* Events CRUD
     **********************************************************/
    function createEventAsync(e) {
        e.id = fakes.randomNumber(100000, 999999);
        e.title = 'new appointment';
        e = parseEvent(e);
        _events.push(e);
        _selectedEvent = e;
        return async.asPromise(e);
    }

    function getEventsAsync(fromDate, toDate, timezone) {
        var _userId = userService.getLoggedInUser().id;
        if (_events.length > 0) {
            return getEventsFromCache(_userId, fromDate, toDate, timezone);
        }
        return activateAsync().then(function () {
            return getEventsFromCache(_userId, fromDate, toDate, timezone);
        });
    }

    function getEventsFromCache(userId, fromDate, toDate) {
        var _userEvents = _events
            .filter(function (e) {
                return e.user.id === userId;
            })
        .filter(function (e1) {
            return e1.start.diff(fromDate) > 0;
        }).filter(function (e2) {
            return e2.start.diff(toDate) < 0;
        });
        return async.asPromise(_userEvents);
    }

    function updateEventAsync(u) {
        var _event = array.getById(_events, u.id);
        updateEventAsyncModel(_event, u);
        return async.asPromise(_event);
    }

    function deleteEventAsync(eventId) {
    }

    function selectEvent(eventId) {
        _selectedEvent = array.getById(_events, eventId);
        return _selectedEvent;
    }

    function unselectEvent() {
        _selectedEvent = null;
        return _selectedEvent;
    }

    function getSelectedEvent() {
        return _selectedEvent;
    }

    function searchEventsAsync(search, projectId) {
        var l = search.length,
            results;
        if (_events.length > 0) {
            results = _events.filter(searchFilter);
            return async.asPromise(results);
        }
        return activateAsync().then(function () {
            results = _events.filter(searchFilter);
            return async.asPromise(results);
        });

        function searchFilter(e) {
            var f = e.title.substr(0, l),
                d = e.description.substr(0, l);

            return (f === search) || (d === search);
        }
    }

    /**********************************************************
    /* Events MODELS
     **********************************************************/
    function event() {
        this.id = 0;
        this.userId = 0;
        this.userId = null;
        this.project = null;
        this.projectId = 0;
        this.entitledProjects = [];
        this.start = null;
        this.end = null;
        this.title = '';
        this.description = '';
        this.editable = true;
        return this;
    }

    function parseEvent(data) {
        var _e = new event();
        _e.id = data.id;
        _e.userId = data.user.id;
        _e.user = data.user;
        _e.projectId = data.project ? data.project.id : 0;
        _e.project = data.project;
        _e.entitledProjects = data.entitledProjects;
        _e.start = moment(data.start);
        _e.end = moment(data.end);
        _e.title = data.title;
        _e.description = data.description;
        _e.complete = data.complete;
        _e.editable = !data.complete;
        _e.action = data.action;
        _e.gps = data.gps;
        _e.inProgress = data.inProgress;
        return _e;
    }

    function updateEventAsyncModel(e, data) {
        e.userId = data.userId;
        e.user = data.user;
        e.project = data.project;
        e.projectId = data.projectId;
        e.entitledProjects = data.entitledProjects;
        e.start = data.start;
        e.end = data.end;
        e.title = data.title;
        e.description = data.description;
        e.complete = data.complete;
        e.editable = !data.complete;
        e.action = data.action;
        e.gps = data.gps;
        e.inProgress = data.inProgress;
        return e;
    }

    function getEventTimeLabel(e, timeFormat) {
        return moment(e.start).format(timeFormat) + ' to ' + moment(e.end).format(timeFormat);
    }

    function getEventDuration(e) {
        return moment.duration(e.end.diff(e.start)).humanize();
    }
}

})();<commit_msg>event service bug fix<commit_after>(function(){
    var _tbaEventServiceId = 'tba.event.service';
angular.module('tba')
    .factory(_tbaEventServiceId, ['tba.core.async', 'tba.core.fakes', 'tba.core.array', 'tba.core.log',
        'tba.user.service', 'tba.project.service', eventService]);

function eventService(async, fakes, array, log, userService, projectService) {
    var _selectedEvent = null,      // currently selected (editing) event
        _selectedDate = moment(),   // currently selected date
        _today = moment(),          // today
        _events = [],               // all events for the logged in user

        _service = {
            // async methods
            createEventAsync: createEventAsync,
            getEventsAsync: getEventsAsync,
            updateEventAsync: updateEventAsync,
            deleteEventAsync: deleteEventAsync,
            searchEventsAsync: searchEventsAsync,

            // selected event (only one)
            selectEvent: selectEvent,
            unselectEvent: unselectEvent,
            getSelectedEvent: getSelectedEvent,

            // title
            getDayTitle: getDayTitle,
            getWeekTitle: getWeekTitle,
            getMonthTitle: getMonthTitle,

            // selected date (only one)
            selectDate: selectDate,
            getSelectedDate: getSelectedDate,

            // init
            activateAsync: activateAsync,

            // event helpers
            getEventDuration: getEventDuration,
            getEventTimeLabel: getEventTimeLabel
        };

    return _service;

    function activateAsync() {
        // load the database full of fake events
        var _fromDate = _today.subtract(30, 'days');
        var _user = userService.getLoggedInUser();

        _events = fakes.randomUserEvents(_user, _fromDate, 60, _user.projects);
        _events = _events.map(parseEvent);
        log.log('Activated ', _events, _tbaEventServiceId, true);
        return async.asPromise(_events);

    }

    /********************************************************************/
    /*     Selected Date                                                */
    /********************************************************************/
    function selectDate(d) {
        _selectedDate = moment(d);
        return getDayTitle();
    }

    function getSelectedDate() {
        return _selectedDate;
    }

    /********************************************************************/
    /*    Title                                                         */
    /********************************************************************/
    function getDayTitle() {
        return _selectedDate.format("MMMM Do YYYY");
    }

    function getWeekTitle() {
        var _dow = _selectedDate.day(),
            _m = moment(_selectedDate).subtract((_dow - 1), 'day').format("dddd Do"),
            _f = moment(_selectedDate).add((5 - _dow), 'day').format("dddd Do, MMMM  YYYY");
        return _m + ' to ' + _f;
    }

    function getMonthTitle() {
        return _selectedDate.format("MMMM  YYYY");
    }

    /**********************************************************
    /* Events CRUD
     **********************************************************/
    function createEventAsync(e) {
        e.id = fakes.randomNumber(100000, 999999);
        e.title = 'new appointment';
        e = parseEvent(e);
        _events.push(e);
        _selectedEvent = e;
        return async.asPromise(e);
    }

    function getEventsAsync(fromDate, toDate, timezone) {
        var _userId = userService.getLoggedInUser().id;
        if (_events.length > 0) {
            return getEventsFromCache(_userId, fromDate, toDate, timezone);
        }
        return activateAsync().then(function () {
            return getEventsFromCache(_userId, fromDate, toDate, timezone);
        });
    }

    function getEventsFromCache(userId, fromDate, toDate) {
        var _userEvents = _events
            .filter(function (e) {
                return e.user.id === userId;
            })
        .filter(function (e1) {
            return e1.start.diff(fromDate) > 0;
        }).filter(function (e2) {
            return e2.start.diff(toDate) < 0;
        });
        return async.asPromise(_userEvents);
    }

    function updateEventAsync(u) {
        var _event = array.getById(_events, u.id);
        updateEventAsyncModel(_event, u);
        return async.asPromise(_event);
    }

    function deleteEventAsync(eventId) {
    }

    function selectEvent(eventId) {
        _selectedEvent = array.getById(_events, eventId);
        return _selectedEvent;
    }

    function unselectEvent() {
        _selectedEvent = null;
        return _selectedEvent;
    }

    function getSelectedEvent() {
        return _selectedEvent;
    }

    function searchEventsAsync(search, projectId) {
        var l = search.length,
            results;
        if (_events.length > 0) {
            results = _events.filter(searchFilter);
            return async.asPromise(results);
        }
        return activateAsync().then(function () {
            results = _events.filter(searchFilter);
            return async.asPromise(results);
        });

        function searchFilter(e) {
            var f = e.title.substr(0, l),
                d = e.description.substr(0, l);

            return (f === search) || (d === search);
        }
    }

    /**********************************************************
    /* Events MODELS
     **********************************************************/
    function event() {
        this.id = 0;
        this.userId = 0;
        this.userId = null;
        this.project = null;
        this.projectId = 0;
        this.entitledProjects = [];
        this.start = null;
        this.end = null;
        this.title = '';
        this.description = '';
        this.editable = true;
        return this;
    }

    function parseEvent(data) {
        var _e = new event();
        _e.id = data.id;
        _e.userId = data.user.id;
        _e.user = data.user;
        _e.projectId = data.project ? data.project.id : 0;
        _e.project = data.project;
        _e.entitledProjects = data.entitledProjects;
        _e.start = moment(data.start);
        _e.end = moment(data.end);
        _e.title = data.title;
        _e.description = data.description;
        _e.complete = data.complete;
        _e.editable = !data.complete;
        _e.action = data.action;
        _e.gps = data.gps;
        _e.inProgress = data.inProgress;
        return _e;
    }

    function updateEventAsyncModel(e, data) {
        e.userId = data.userId;
        e.user = data.user;
        e.project = data.project;
        e.projectId = data.projectId;
        e.entitledProjects = data.entitledProjects;
        e.start = data.start;
        e.end = data.end;
        e.title = data.title;
        e.description = data.description;
        e.complete = data.complete;
        e.editable = !data.complete;
        e.action = data.action;
        e.gps = data.gps;
        e.inProgress = data.inProgress;
        return e;
    }

    function getEventTimeLabel(e, timeFormat) {
        return moment(e.start).format(timeFormat) + ' to ' + moment(e.end).format(timeFormat);
    }

    function getEventDuration(e) {
        if(!e.end || !e.start) return '';
        return moment.duration(e.end.diff(e.start)).humanize();
    }
}

})();<|endoftext|>


<commit_before>/**
 * Created by truthlighting on 9/20/2016.
 */
module.exports =
{
    initSpawnQue: function()
    {
        if(Memory.spawnQue == undefined)
            Memory.spawnQue = [ ];
    },

    addToQue: function(creep, unshift)
    {
        this.initSpawnQue();

        if(unshift != undefined && unshift === true)
            Memory.spawnQue.unshift(creep);
        else
            Memory.spawnQue.push(creep);
    },

    spawnNextInQue: function()
    {

        this.initSpawnQue();

        if(!Memory.spawnQue.length)
            return;

        var spawns = Game.rooms['W2N48'].find(FIND_MY_SPAWNS, {
            filter: function(spawn)
            {
                return spawn.spawning === undefined || spawn.spawning === null;
            }
        });
        //console.log(spawns);

        if(!spawns.length)
            return;

        var role = Memory.spawnQue[0];

        if(typeof role == "string")
        {
            role = { type: role, memory: { } };
        }
        var body = [];
        var me = this;
        //console.log(spawns);
        var toSpawnAt = spawns.filter(function(spawn)
        {
            //console.log("spawn: " + spawn + " role.type: " + role.type);
            //console.log(me.canSpawn(spawn, role.type));
            body = me.canSpawn(spawn, role.type);
            return body;
        });
        //console.log("toSpawnAt: " + toSpawnAt);
        if(!toSpawnAt.length)
            return;
        //console.log("getting here1");
        toSpawnAt = toSpawnAt[0];
        console.log("body before pass: " + body);
        this.spawn(role.type, role.memory, toSpawnAt, body);

        Memory.spawnQue.shift();
    },

    spawn: function(role, memory, spawnPoint, body)
    {
        console.log("role: " + role + " memory: " + memory + " spawnPoint: " + spawnPoint);
        if(!spawnPoint)
            spawnPoint = Game.spawns['Harmony'];

        var manager = require('roleManager');

        if(!manager.roleExists(role))
        {
            return;
        }
        /*if(!this.canSpawn(spawnPoint, role))
        {
            return;
        }*/

        if(memory == undefined)
            memory = { };

        memory['role'] = role;

        var nameCount = 0;
        var name = null;
        while(name == null)
        {
            nameCount++;
            var tryName = role + nameCount;
            if(Game.creeps[tryName] == undefined)
                name = tryName;
        }

        console.log('Spawning ' + role);
        console.log(spawnPoint.createCreep(body, name, memory));
    },

    canSpawn: function(spawnPoint, role)
    {
        if(typeof spawnPoint == "string" && role == undefined)
        {
            role = spawnPoint;
            spawnPoint = Game.spawns['Harmony'];
        }
        //console.log(role);
        //console.log("spawnPoint: " + spawnPoint + " spawnPoint.energy: " + spawnPoint.energy + " this.room.energyAvailable: " + spawnPoint.room.energyAvailable);
        //return spawnPoint.energy >= this.spawnCost(role)
        return this.findMostExpensiveAffordableBody(spawnPoint, role)
            && (spawnPoint.spawning == null
            || spawnPoint.spawning == undefined);
    },

    findMostExpensiveAffordableBody: function(spawnPoint, role)
    {
        var manager = require('roleManager');
        var bodyArray = manager.getRoleBodyParts(role);

        for (var index in bodyArray)
        {
            var body = bodyArray[index];
            if (this.spawnCost(body) <= spawnPoint.room.energyAvailable)
                return body;
        }

    },

    spawnCost: function(body)
    {
       // var manager = require('roleManager');
       // var parts = manager.getRoleBodyParts(role);

        var total = 0;
        for(var index in body)
        {
            var bodyPart = body[index];
            switch(bodyPart)
            {
                case MOVE:
                    total += 50
                    break;

                case WORK:
                    total += 100
                    break;

                case CARRY:
                    total += 50
                    break;

                case ATTACK:
                    total += 80
                    break;

                case RANGED_ATTACK:
                    total += 150
                    break;

                case HEAL:
                    total += 250
                    break;

                case TOUGH:
                    total += 10
                    break;

                case CLAIM:
                    total += 600
            }
        }
        //console.log("body: " + body);
        //console.log("total cost: " + total);
        return total;
    },

    killAll: function(role)
    {
        for(var i in Game.creeps) {
            if(role == undefined || Game.creeps[i].memory.role == role)
                Game.creeps[i].suicide();
        }
    }
}<commit_msg>Fixing miner<commit_after>/**
 * Created by truthlighting on 9/20/2016.
 */
module.exports =
{
    initSpawnQue: function()
    {
        if(Memory.spawnQue == undefined)
            Memory.spawnQue = [ ];
    },

    addToQue: function(creep, unshift)
    {
        this.initSpawnQue();

        if(unshift != undefined && unshift === true)
            Memory.spawnQue.unshift(creep);
        else
            Memory.spawnQue.push(creep);
    },

    spawnNextInQue: function()
    {

        this.initSpawnQue();

        if(!Memory.spawnQue.length)
            return;

        var spawns = Game.rooms['W2N48'].find(FIND_MY_SPAWNS, {
            filter: function(spawn)
            {
                return spawn.spawning === undefined || spawn.spawning === null;
            }
        });
        //console.log(spawns);

        if(!spawns.length)
            return;

        var role = Memory.spawnQue[0];

        if(typeof role == "string")
        {
            role = { type: role, memory: { } };
        }
        var body = [];
        var me = this;
        //console.log(spawns);
        var toSpawnAt = spawns.filter(function(spawn)
        {
            //console.log("spawn: " + spawn + " role.type: " + role.type);
            //console.log(me.canSpawn(spawn, role.type));
            return me.canSpawn(spawn, role.type);
        });
        //console.log("toSpawnAt: " + toSpawnAt);
        if(!toSpawnAt.length)
            return;
        //console.log("getting here1");
        toSpawnAt = toSpawnAt[0];
        console.log("body before pass: " + body);
        this.spawn(role.type, role.memory, toSpawnAt, body);

        Memory.spawnQue.shift();
    },

    spawn: function(role, memory, spawnPoint)
    {
        //console.log("role: " + role + " memory: " + memory + " spawnPoint: " + spawnPoint);
        if(!spawnPoint)
            spawnPoint = Game.spawns['Harmony'];

        var manager = require('roleManager');
        var body = this.findMostExpensiveAffordableBody(spawnPoint, role);

        if(!manager.roleExists(role))
        {
            return;
        }
        /*if(!this.canSpawn(spawnPoint, role))
        {
            return;
        }*/

        if(memory == undefined)
            memory = { };

        memory['role'] = role;

        var nameCount = 0;
        var name = null;
        while(name == null)
        {
            nameCount++;
            var tryName = role + nameCount;
            if(Game.creeps[tryName] == undefined)
                name = tryName;
        }

        console.log('Spawning ' + role);
        console.log(spawnPoint.createCreep(body, name, memory));
    },

    canSpawn: function(spawnPoint, role)
    {
        if(typeof spawnPoint == "string" && role == undefined)
        {
            role = spawnPoint;
            spawnPoint = Game.spawns['Harmony'];
        }
        //console.log(role);
        //console.log("spawnPoint: " + spawnPoint + " spawnPoint.energy: " + spawnPoint.energy + " this.room.energyAvailable: " + spawnPoint.room.energyAvailable);
        //return spawnPoint.energy >= this.spawnCost(role)
        return this.findMostExpensiveAffordableBody(spawnPoint, role)
            && (spawnPoint.spawning == null
            || spawnPoint.spawning == undefined);
    },

    findMostExpensiveAffordableBody: function(spawnPoint, role)
    {
        var manager = require('roleManager');
        var bodyArray = manager.getRoleBodyParts(role);

        for (var index in bodyArray)
        {
            var body = bodyArray[index];
            if (this.spawnCost(body) <= spawnPoint.room.energyAvailable)
                return body;
        }

    },

    spawnCost: function(body)
    {
       // var manager = require('roleManager');
       // var parts = manager.getRoleBodyParts(role);

        var total = 0;
        for(var index in body)
        {
            var bodyPart = body[index];
            switch(bodyPart)
            {
                case MOVE:
                    total += 50
                    break;

                case WORK:
                    total += 100
                    break;

                case CARRY:
                    total += 50
                    break;

                case ATTACK:
                    total += 80
                    break;

                case RANGED_ATTACK:
                    total += 150
                    break;

                case HEAL:
                    total += 250
                    break;

                case TOUGH:
                    total += 10
                    break;

                case CLAIM:
                    total += 600
            }
        }
        //console.log("body: " + body);
        //console.log("total cost: " + total);
        return total;
    },

    killAll: function(role)
    {
        for(var i in Game.creeps) {
            if(role == undefined || Game.creeps[i].memory.role == role)
                Game.creeps[i].suicide();
        }
    }
}<|endoftext|>


<commit_before>import { createLogic } from 'redux-logic';

import settings from './actions';
import { app } from 'common/actions';
import user from 'features/user/actions';
import vocab from 'features/vocab/actions';
import { selectUserProfile } from 'features/user/selectors';
import { deserializeUserProfile } from 'common/serializers';

export const saveSettingsLogic = createLogic({
  type: settings.save.request,
  process({ getState, api, action: { payload, meta: { form } } }, dispatch, done) {
    const profile = selectUserProfile(getState());
    const updatedProfile = deserializeUserProfile(payload);
    const filterChanged = profile.minimumWkSrsLevelToReview !== payload.minimumWkSrsLevelToReview;

    form.startSubmit();
    api.user
      .update({ id: profile.id, ...updatedProfile })
      .then((response) => {
        dispatch(user.load.success({ profile: response }));
        dispatch(settings.save.success({}, { filterChanged }));
        form.stopSubmit();
        done();
      })
      .catch((err) => {
        dispatch(app.captureError(err, payload));
        dispatch(settings.save.failure(err));
        if (err.json && err.json.api_key) {
          form.stopSubmit({ apiKey: err.json.api_key[0] });
        } else {
          form.stopSubmit();
        }
        done();
      });
  },
});

export const resetProgressLogic = createLogic({
  type: settings.resetProgress.request,
  processOptions: {
    failType: settings.resetProgress.failure,
  },
  process({ api, action: { payload } }, dispatch, done) {
    api.user
      .resetProgress(payload)
      .then(() => {
        dispatch(user.load.request());
        dispatch(vocab.levels.load.request());
        done();
      })
      .catch((err) => {
        dispatch(app.captureError(err, payload));
        done();
      });
  },
});

export default [resetProgressLogic, saveSettingsLogic];
<commit_msg>feat: prevent sentry error submission on apikey form validation<commit_after>import { createLogic } from 'redux-logic';

import settings from './actions';
import { app } from 'common/actions';
import user from 'features/user/actions';
import vocab from 'features/vocab/actions';
import { selectUserProfile } from 'features/user/selectors';
import { deserializeUserProfile } from 'common/serializers';

export const saveSettingsLogic = createLogic({
  type: settings.save.request,
  process({ getState, api, action: { payload, meta: { form } } }, dispatch, done) {
    const profile = selectUserProfile(getState());
    const updatedProfile = deserializeUserProfile(payload);
    const filterChanged = profile.minimumWkSrsLevelToReview !== payload.minimumWkSrsLevelToReview;

    form.startSubmit();
    api.user
      .update({ id: profile.id, ...updatedProfile })
      .then((response) => {
        dispatch(user.load.success({ profile: response }));
        dispatch(settings.save.success({}, { filterChanged }));
        form.stopSubmit();
        done();
      })
      .catch((err) => {
        dispatch(settings.save.failure(err));
        if (err.json && err.json.api_key) {
          form.stopSubmit({ apiKey: err.json.api_key[0] });
        } else {
          dispatch(app.captureError(err, payload));
          form.stopSubmit();
        }
        done();
      });
  },
});

export const resetProgressLogic = createLogic({
  type: settings.resetProgress.request,
  process({ api, action: { payload } }, dispatch, done) {
    api.user
      .resetProgress(payload)
      .then(() => {
        dispatch(user.load.request());
        dispatch(vocab.levels.load.request());
        done();
      })
      .catch((err) => {
        dispatch(app.captureError(err, payload));
        done();
      });
  },
});

export default [resetProgressLogic, saveSettingsLogic];
<|endoftext|>


<commit_before>import flagImgUrl from '../static/usa-flag.png'
import React, { Component, PureComponent } from 'react'
import { Motion } from '../../../src'
import Demo from '../Demo'
import { normalizePaths, getProgress } from 'react-svg-morph/lib/utils/morph'
import scalePath from 'react-svg-morph/lib/utils/scalePath'
import { EAGLE_PATH, USA_PATH } from './svg-paths'

const WOBBLY_SPRING = { stiffness: 200, damping: 15 }
const width = 800
const height = 450

class America extends PureComponent {
  render () {
    const { from: usa, to: eagle } = normalizePaths(
      [{ path: scalePath(USA_PATH, height, 640, 412), trans: {} }],
      [{ path: scalePath(EAGLE_PATH, height, 794, 1122), trans: {} }]
    )

    return (
      <svg
        viewBox={`0 0 ${width} ${height}`}
        width={width}
        height={height}
        style={{ width: '100%', height: '100%' }}
      >
        <defs>
          <pattern
            id='🇺🇸'
            patternUnits='userSpaceOnUse'
            width={width}
            height={height}
          >
            <image
              xlinkHref={flagImgUrl}
              x='0'
              y='0'
              width={width}
              height={height}
            />
          </pattern>
        </defs>
        <Patriot val={this.props.val} eagle={eagle} usa={usa} />
      </svg>
    )
  }
}

class Patriot extends Component {
  render () {
    return (
      <Motion
        data={[this.props.val]}
        component={<g transform={'translate(175,35)'} />}
        getKey={this.getKey}
        onComponentMount={this.onCpm}
        onRender={this.onRender}
        onRemount={this.onRe}
        onUnmount={this.onUn}
        render={this.renderAmerica}
      />
    )
  }

  getKey = (data, i) => i + '-USA';

  onCpm = (data, i) => ({ val: data });

  onRender = (data, i, spring) => ({ val: spring(data, WOBBLY_SPRING) });

  renderAmerica = (key, data, { val }, dataIndex) => {
    const [snapshot] = getProgress(this.props.usa, this.props.eagle, val)

    return (
      <path
        key={key}
        d={snapshot.path}
        fill={'url(#🇺🇸)'}
        stroke={'#f03e3e'}
        strokeWidth={2}
      />
    )
  };
}

export default class extends Component {
  constructor (props) {
    super(props)

    this.state = { val: 0 }
  }

  render () {
    return (
      <Demo>
        <input
          style={{
            position: 'absolute',
            top: 8,
            left: 32,
            height: 32,
            width: 'calc(60%)',
            marginBottom: 8
          }}
          type={'range'}
          min={0}
          max={100}
          step={1}
          value={this.state.val * 100}
          onChange={({target: {value}}) => this.setState({val: value / 100})}
        />
        <button
          style={buttonStyle}
          onClick={() => this.setState(prev => ({ val: (prev.val + 1) % 2 }))}
        >
          Toggle
        </button>
        <America val={this.state.val} />
      </Demo>
    )
  }
}

const buttonStyle = {
  position: 'absolute',
  top: 8,
  right: 8,
  backgroundColor: 'transparent',
  color: '#37b24d',
  fontWeight: 'bold',
  borderRadius: 4,
  height: 32,
  lineHeight: 2.5,
  paddingLeft: 16,
  paddingRight: 16,
  outline: 'none',
  border: '1px solid #37b24d'
}
<commit_msg>Remove unused functions<commit_after>import flagImgUrl from '../static/usa-flag.png'
import React, { Component, PureComponent } from 'react'
import { Motion } from '../../../src'
import Demo from '../Demo'
import { normalizePaths, getProgress } from 'react-svg-morph/lib/utils/morph'
import scalePath from 'react-svg-morph/lib/utils/scalePath'
import { EAGLE_PATH, USA_PATH } from './svg-paths'

const WOBBLY_SPRING = { stiffness: 200, damping: 15 }
const width = 800
const height = 450

class America extends PureComponent {
  render () {
    const { from: usa, to: eagle } = normalizePaths(
      [{ path: scalePath(USA_PATH, height, 640, 412), trans: {} }],
      [{ path: scalePath(EAGLE_PATH, height, 794, 1122), trans: {} }]
    )

    return (
      <svg
        viewBox={`0 0 ${width} ${height}`}
        width={width}
        height={height}
        style={{ width: '100%', height: '100%' }}
      >
        <defs>
          <pattern
            id='🇺🇸'
            patternUnits='userSpaceOnUse'
            width={width}
            height={height}
          >
            <image
              xlinkHref={flagImgUrl}
              x='0'
              y='0'
              width={width}
              height={height}
            />
          </pattern>
        </defs>
        <Patriot val={this.props.val} eagle={eagle} usa={usa} />
      </svg>
    )
  }
}

class Patriot extends Component {
  render () {
    return (
      <Motion
        data={[this.props.val]}
        component={<g transform={'translate(175,35)'} />}
        getKey={this.getKey}
        onComponentMount={this.onCpm}
        onRender={this.onRender}
        render={this.renderAmerica}
      />
    )
  }

  getKey = (data, i) => i + '-USA';

  onCpm = (data, i) => ({ val: data });

  onRender = (data, i, spring) => ({ val: spring(data, WOBBLY_SPRING) });

  renderAmerica = (key, data, { val }, dataIndex) => {
    const [snapshot] = getProgress(this.props.usa, this.props.eagle, val)

    return (
      <path
        key={key}
        d={snapshot.path}
        fill={'url(#🇺🇸)'}
        stroke={'#f03e3e'}
        strokeWidth={2}
      />
    )
  };
}

export default class extends Component {
  constructor (props) {
    super(props)

    this.state = { val: 0 }
  }

  render () {
    return (
      <Demo>
        <input
          style={{
            position: 'absolute',
            top: 8,
            left: 32,
            height: 32,
            width: 'calc(60%)',
            marginBottom: 8
          }}
          type={'range'}
          min={0}
          max={100}
          step={1}
          value={this.state.val * 100}
          onChange={({target: {value}}) => this.setState({val: value / 100})}
        />
        <button
          style={buttonStyle}
          onClick={() => this.setState(prev => ({ val: (prev.val + 1) % 2 }))}
        >
          Toggle
        </button>
        <America val={this.state.val} />
      </Demo>
    )
  }
}

const buttonStyle = {
  position: 'absolute',
  top: 8,
  right: 8,
  backgroundColor: 'transparent',
  color: '#37b24d',
  fontWeight: 'bold',
  borderRadius: 4,
  height: 32,
  lineHeight: 2.5,
  paddingLeft: 16,
  paddingRight: 16,
  outline: 'none',
  border: '1px solid #37b24d'
}
<|endoftext|>


<commit_before>/*
* DolStatistics plugin
*/
mw.DolStatistics = function( embedPlayer, callback ){
	this.init( embedPlayer, callback );
};

mw.DolStatistics.prototype = {

	pluginVersion: "1.1",
	bindPostFix: '.DolStatistics',
	appName: 'KDP',

	// Number of seconds between playhead event dispatches
	playheadFrequency: 5,
	playheadInterval: 0,

	// Entry duration
	duration: 0,

	// hold list of cue points per 10% of video duration
	percentCuePoints: {},

	init: function( embedPlayer, callback ){
		this.embedPlayer = embedPlayer;

		// List of all attributes we need from plugin configuration (flashVars/uiConf)
		var attributes = [
			'listenTo',
			'playheadFrequency',
			'jsFunctionName',
			'protocol',
			'host',
			'ASSETNAME',
			'GENURL',
			'GENTITLE',
			'DEVID',
			'USRAGNT',
			'ASSETID'
		];
		this.playheadFrequency = this.getConfig( 'playheadFrequency' ) || 5;

		// List of events we need to track
		var eventList = this.getConfig( 'listenTo' );
		this.eventsList = eventList.split(",");

		mw.log( 'DolStatistics:: eventList:' + this.eventsList );

		// Setup player counter, (used global, because on change media we re-initlize the plugin and reset all vars)
		if( ! $( embedPlayer ).data('DolStatisticsCounter') ) {
			$( embedPlayer ).data('DolStatisticsCounter', 1 );
		}

		mw.log('DolStatistics:: Init plugin :: Plugin config: ', this.embedPlayer.getKalturaConfig( 'dolStatistics') );

		// Add player binding
		this.addPlayerBindings( callback );
	},
	getConfig: function( attr ){
		return this.embedPlayer.getKalturaConfig( 'dolStatistics', attr );
	},
	addPlayerBindings: function( callback ) {
		var _this = this;
		var embedPlayer = this.embedPlayer;
		var $embedPlayer = $( embedPlayer );

		// Unbind any existing bindings
		this.destroy();

		// On change media remove any existing ads:
		embedPlayer.bindHelper( 'onChangeMedia' + _this.bindPostFix, function(){
			$embedPlayer.data('DolStatisticsCounter', $embedPlayer.data('DolStatisticsCounter')+1);
			_this.destroy();
		});

		// Register to our events
		$.each(this.eventsList, function(k, eventName) {
			switch( eventName ) {
				// Special event
				case 'percentReached':
					_this.calcCuePoints();
					embedPlayer.bindHelper( 'monitorEvent' + _this.bindPostFix, function() {
						_this.monitorPercentage();
					});
				break;
				// Change playerUpdatePlayhead event to send events on playheadFrequency
				case 'playerUpdatePlayhead':
					_this.addMonitorBindings();
				break;
				// Use addJsListener for all other events
				default:
					embedPlayer.addJsListener(eventName + _this.bindPostFix, function() {
						var eventData = '';
						var argSet = $.makeArray( arguments );
						$.each( argSet, function( inx, argValue ){
							eventData += argValue + ",";
						});
						eventData = eventData.substr( 0, eventData.length-1 );
						_this.sendStatsData( eventName, eventData );
					});
				break;
			}

		});

		mw.log('DolStatistics:: addPlayerBindings:: Events list: ', this.eventsList);

		// Continue player build out
		callback();
	},

	/* Create Index of Cue Points per 10% of video duration */
	calcCuePoints: function() {
		var _this = this;
		var duration = this.getDuration();

		for( var i=0; i<=100; i=i+10 ) {
			var cuePoint = Math.round( duration / 100 * i );
			if( cuePoint === 0 ) continue;
			_this.percentCuePoints[ cuePoint ] = false;
		}

		mw.log('DolStatistics:: calcCuePoints:: ', _this.percentCuePoints);
	},

	/* Custom percentReached event */
	monitorPercentage: function() {
		var _this = this;
		var duration = this.getDuration();
		var percentCuePoints = this.percentCuePoints;
		var currentTime = Math.round( this.embedPlayer.currentTime );

		if( percentCuePoints[ currentTime ] === false ) {
			percentCuePoints[ currentTime ] = true;
			var percent = Math.round(currentTime * 100 / duration );
			_this.sendStatsData( 'percentReached', percent );
		}
	},

	/* Custom playerUpdatePlayhead event */
	addMonitorBindings: function() {
		var _this = this;
		var embedPlayer = this.embedPlayer;
		var intervalTime = this.playheadFrequency * 1000;

		// Start monitor
		embedPlayer.bindHelper('onplay' + _this.bindPostFix, function() {
			if( ! _this.playheadInterval ) {
				_this.playheadInterval = setInterval( function(){
					_this.sendStatsData( 'playerUpdatePlayhead' , embedPlayer.currentTime);
				}, intervalTime );
			}
		});

		// Stop monitor
		embedPlayer.bindHelper('doStop' + _this.bindPostFix + ' onpause' + _this.bindPostFix + ' onChangeMedia' + _this.bindPostFix, function() {
			clearInterval( _this.playheadInterval );
			_this.playheadInterval = 0;
		});
	},

	/* Retrive video duration */
	getDuration: function() {
		if( ! this.duration ){
			this.duration = this.embedPlayer.evaluate('{duration}');
		}
		return this.duration;
	},

	getBitrate: function() {
		if( this.embedPlayer.mediaElement.selectedSource ) {
			return this.embedPlayer.mediaElement.selectedSource.getBitrate() || 0;
		}
		return 0;
	},

	/* Send stats data using Beacon or jsCallback */
	sendStatsData: function( eventName, eventData ) {
		var _this = this;
		// If event name not in our event list, exit
		if( this.eventsList.indexOf( eventName ) === -1 ) {
			return ;
		}

		// Setup event params
		var params = {};
		// App name
		params['app'] = this.appName;
		// Grab from plugin config
		var configAttrs = [ 'DEVID', 'ASSETNAME', 'ASSETID' ];
		for(var x=0; x<configAttrs.length; x++) {
			params[ configAttrs[x] ] = _this.getConfig( configAttrs[x] ) || '';
		}
		// Embedded Page URL
		params['GENURL'] =  _this.getConfig('GENURL') || window.kWidgetSupport.getHostPageUrl();
		// Embedded Page Title
		params['GENTITLE'] =  _this.getConfig('GENTITLE') || mw.getConfig( 'EmbedPlayer.IframeParentTitle' );
		// User Agent
		params['USRAGNT'] =  _this.getConfig('USRAGNT') || window.navigator.userAgent;
		// Current Timestamp
		params['GENTIME'] = new Date().getTime();
		// Widget ID
		params['WIGID'] = this.embedPlayer.kwidgetid;
		// Flavor Bitrate
		params['BITRATE'] = this.getBitrate();
		// Video length
		params['VIDLEN'] = this.getDuration();
		// Player protocol
		params['KDPPROTO'] = this.getConfig('protocol') || location.protocol.substr(0, location.protocol.length-1);
		// Kaltura Player ID
		params['KDPID'] = this.embedPlayer.kuiconfid;
		// Kaltura Seesion ID
		params['KSESSIONID'] = this.embedPlayer.evaluate('{configProxy.sessionId}');
		// Kaltura Playback ID ( kSessionId + playbackCounter )
		params['KPLAYBACKID'] = this.embedPlayer.evaluate('{configProxy.sessionId}') + $( this.embedPlayer ).data('DolStatisticsCounter');
		// Kaltura Event name
		params['KDPEVNT'] = eventName;
		// KDP Event Data
		params['KDPDAT_VALUE'] = eventData.toString();
		// Always include the current time:
		params['KDPDAT_PLAYHEAD'] = embedPlayer.currentTime;

		// Add custom params
		for( var i =0; i < 10; i++ ){
			// Check for custom data key value pairs ( up to 9 )
			if( _this.getConfig( 'customDataKey' + i ) &&  _this.getConfig( 'customDataValue' + i ) ){
				params[  _this.getConfig( 'customDataKey' + i )  ] =  _this.getConfig( 'customDataValue' + i );
			}
		}

		mw.log('DolStatistics:: Send Stats Data ' + statsUrl, params);

		// If we have access to parent, call the jsFunction provided
		if( this.getConfig( 'jsFunctionName' ) && window.parent ) {
			var callbackName = this.getConfig( 'jsFunctionName' );
			this._executeFunctionByName( callbackName, window.parent, params);
		} else {
			// Use beacon to send event data
			var statsUrl = this.getConfig( 'protocol' ) + '://' + this.getConfig( 'host' ) + '?' + $.param(params);
			$('body').append(
				$( '<img />' ).attr({
					'src' : statsUrl,
					'width' : 0,
					'height' : 0
				})
			);
		}
	},

	destroy: function() {
		clearInterval( this.playheadInterval );
		this.playheadInterval = 0;
		this.embedPlayer.unbindHelper( this.bindPostFix );
		this.percentCuePoints = {};
		this.duration = 0;
	},

	/* Execute function like: "cto.trackVideo" */
	_executeFunctionByName: function( functionName, context /*, args */) {
		var args = Array.prototype.slice.call(arguments).splice(2);
		var namespaces = functionName.split(".");
		var func = namespaces.pop();
		for(var i = 0; i < namespaces.length; i++) {
			context = context[namespaces[i]];
		}
		return context[func].apply(this, args);
	}
};<commit_msg>* don't increment DolStatisticsCounter on failed entries * KDPPROTO is the protocol for the service url * KSESSIONSEQ lists the sequence number in isolation <commit_after>/*
* DolStatistics plugin
*/
mw.DolStatistics = function( embedPlayer, callback ){
	this.init( embedPlayer, callback );
};

mw.DolStatistics.prototype = {

	pluginVersion: "1.1",
	bindPostFix: '.DolStatistics',
	appName: 'KDP',

	// Number of seconds between playhead event dispatches
	playheadFrequency: 5,
	playheadInterval: 0,

	// Entry duration
	duration: 0,

	// hold list of cue points per 10% of video duration
	percentCuePoints: {},

	init: function( embedPlayer, callback ){
		this.embedPlayer = embedPlayer;

		// List of all attributes we need from plugin configuration (flashVars/uiConf)
		var attributes = [
			'listenTo',
			'playheadFrequency',
			'jsFunctionName',
			'protocol',
			'host',
			'ASSETNAME',
			'GENURL',
			'GENTITLE',
			'DEVID',
			'USRAGNT',
			'ASSETID'
		];
		this.playheadFrequency = this.getConfig( 'playheadFrequency' ) || 5;

		// List of events we need to track
		var eventList = this.getConfig( 'listenTo' );
		this.eventsList = eventList.split(",");

		mw.log( 'DolStatistics:: eventList:' + this.eventsList );

		// Setup player counter, (used global, because on change media we re-initlize the plugin and reset all vars)
		if( $( embedPlayer ).data('DolStatisticsCounter') === null ) {
			if( embedPlayer['data-playerError'] ){
				$( embedPlayer ).data('DolStatisticsCounter', 0 )
			} else {
				$( embedPlayer ).data('DolStatisticsCounter', 1 );
			}
		}

		mw.log('DolStatistics:: Init plugin :: Plugin config: ', this.embedPlayer.getKalturaConfig( 'dolStatistics') );

		// Add player binding
		this.addPlayerBindings( callback );
	},
	getConfig: function( attr ){
		return this.embedPlayer.getKalturaConfig( 'dolStatistics', attr );
	},
	addPlayerBindings: function( callback ) {
		var _this = this;
		var embedPlayer = this.embedPlayer;
		var $embedPlayer = $( embedPlayer );

		// Unbind any existing bindings
		this.destroy();

		// On change media remove any existing ads:
		embedPlayer.bindHelper( 'onChangeMediaDone' + _this.bindPostFix, function(){
			if( ! embedPlayer['data-playerError'] ){
				$embedPlayer.data('DolStatisticsCounter', $embedPlayer.data('DolStatisticsCounter') + 1 );
			}
			_this.destroy();
		});

		// Register to our events
		$.each(this.eventsList, function(k, eventName) {
			switch( eventName ) {
				// Special event
				case 'percentReached':
					_this.calcCuePoints();
					embedPlayer.bindHelper( 'monitorEvent' + _this.bindPostFix, function() {
						_this.monitorPercentage();
					});
				break;
				// Change playerUpdatePlayhead event to send events on playheadFrequency
				case 'playerUpdatePlayhead':
					_this.addMonitorBindings();
				break;
				// Use addJsListener for all other events
				default:
					embedPlayer.addJsListener(eventName + _this.bindPostFix, function() {
						var eventData = '';
						var argSet = $.makeArray( arguments );
						$.each( argSet, function( inx, argValue ){
							eventData += argValue + ",";
						});
						eventData = eventData.substr( 0, eventData.length-1 );
						_this.sendStatsData( eventName, eventData );
					});
				break;
			}

		});

		mw.log('DolStatistics:: addPlayerBindings:: Events list: ', this.eventsList);

		// Continue player build out
		callback();
	},

	/* Create Index of Cue Points per 10% of video duration */
	calcCuePoints: function() {
		var _this = this;
		var duration = this.getDuration();

		for( var i=0; i<=100; i=i+10 ) {
			var cuePoint = Math.round( duration / 100 * i );
			if( cuePoint === 0 ) continue;
			_this.percentCuePoints[ cuePoint ] = false;
		}

		mw.log('DolStatistics:: calcCuePoints:: ', _this.percentCuePoints);
	},

	/* Custom percentReached event */
	monitorPercentage: function() {
		var _this = this;
		var duration = this.getDuration();
		var percentCuePoints = this.percentCuePoints;
		var currentTime = Math.round( this.embedPlayer.currentTime );

		if( percentCuePoints[ currentTime ] === false ) {
			percentCuePoints[ currentTime ] = true;
			var percent = Math.round(currentTime * 100 / duration );
			_this.sendStatsData( 'percentReached', percent );
		}
	},

	/* Custom playerUpdatePlayhead event */
	addMonitorBindings: function() {
		var _this = this;
		var embedPlayer = this.embedPlayer;
		var intervalTime = this.playheadFrequency * 1000;

		// Start monitor
		embedPlayer.bindHelper('onplay' + _this.bindPostFix, function() {
			if( ! _this.playheadInterval ) {
				_this.playheadInterval = setInterval( function(){
					_this.sendStatsData( 'playerUpdatePlayhead' , embedPlayer.currentTime);
				}, intervalTime );
			}
		});

		// Stop monitor
		embedPlayer.bindHelper('doStop' + _this.bindPostFix + ' onpause' + _this.bindPostFix + ' onChangeMedia' + _this.bindPostFix, function() {
			clearInterval( _this.playheadInterval );
			_this.playheadInterval = 0;
		});
	},

	/* Retrive video duration */
	getDuration: function() {
		if( ! this.duration ){
			this.duration = this.embedPlayer.evaluate('{duration}');
		}
		return this.duration;
	},

	getBitrate: function() {
		if( this.embedPlayer.mediaElement.selectedSource ) {
			return this.embedPlayer.mediaElement.selectedSource.getBitrate() || 0;
		}
		return 0;
	},

	/* Send stats data using Beacon or jsCallback */
	sendStatsData: function( eventName, eventData ) {
		var _this = this;
		// If event name not in our event list, exit
		if( this.eventsList.indexOf( eventName ) === -1 ) {
			return ;
		}

		// Setup event params
		var params = {};
		// App name
		params['app'] = this.appName;
		// Grab from plugin config
		var configAttrs = [ 'DEVID', 'ASSETNAME', 'ASSETID' ];
		for(var x=0; x<configAttrs.length; x++) {
			params[ configAttrs[x] ] = _this.getConfig( configAttrs[x] ) || '';
		}
		// Embedded Page URL
		params['GENURL'] =  _this.getConfig('GENURL') || window.kWidgetSupport.getHostPageUrl();
		// Embedded Page Title
		params['GENTITLE'] =  _this.getConfig('GENTITLE') || mw.getConfig( 'EmbedPlayer.IframeParentTitle' );
		// User Agent
		params['USRAGNT'] =  _this.getConfig('USRAGNT') || window.navigator.userAgent;
		// Current Timestamp
		params['GENTIME'] = new Date().getTime();
		// Widget ID
		params['WIGID'] = this.embedPlayer.kwidgetid;
		// Flavor Bitrate
		params['BITRATE'] = this.getBitrate();
		// Video length
		params['VIDLEN'] = this.getDuration();
		// Player protocol
		params['KDPPROTO'] = mw.parseUri( mw.getConfig( 'Kaltura.ServiceUrl' ) ).protocol;
		// Kaltura Player ID
		params['KDPID'] = this.embedPlayer.kuiconfid;
		// Kaltura Seesion ID
		params['KSESSIONID'] = this.embedPlayer.evaluate('{configProxy.sessionId}');
		// Kaltura Playback ID ( kSessionId + playbackCounter )
		params['KPLAYBACKID'] = this.embedPlayer.evaluate('{configProxy.sessionId}') + $( this.embedPlayer ).data('DolStatisticsCounter');
		// Kaltura session Seq
		params['KSESSIONSEQ'] = $( this.embedPlayer ).data('DolStatisticsCounter');
		// Kaltura Event name
		params['KDPEVNT'] = eventName;
		// KDP Event Data
		params['KDPDAT_VALUE'] = eventData.toString();
		// Always include the current time:
		params['KDPDAT_PLAYHEAD'] = embedPlayer.currentTime;

		// Add custom params
		for( var i =0; i < 10; i++ ){
			// Check for custom data key value pairs ( up to 9 )
			if( _this.getConfig( 'customDataKey' + i ) &&  _this.getConfig( 'customDataValue' + i ) ){
				params[  _this.getConfig( 'customDataKey' + i )  ] =  _this.getConfig( 'customDataValue' + i );
			}
		}

		mw.log('DolStatistics:: Send Stats Data ' + statsUrl, params);

		// If we have access to parent, call the jsFunction provided
		if( this.getConfig( 'jsFunctionName' ) && window.parent ) {
			var callbackName = this.getConfig( 'jsFunctionName' );
			this._executeFunctionByName( callbackName, window.parent, params);
		} else {
			// Use beacon to send event data
			var statsUrl = this.getConfig( 'protocol' ) + '://' + this.getConfig( 'host' ) + '?' + $.param(params);
			$('body').append(
				$( '<img />' ).attr({
					'src' : statsUrl,
					'width' : 0,
					'height' : 0
				})
			);
		}
	},

	destroy: function() {
		clearInterval( this.playheadInterval );
		this.playheadInterval = 0;
		this.embedPlayer.unbindHelper( this.bindPostFix );
		this.percentCuePoints = {};
		this.duration = 0;
	},

	/* Execute function like: "cto.trackVideo" */
	_executeFunctionByName: function( functionName, context /*, args */) {
		var args = Array.prototype.slice.call(arguments).splice(2);
		var namespaces = functionName.split(".");
		var func = namespaces.pop();
		for(var i = 0; i < namespaces.length; i++) {
			context = context[namespaces[i]];
		}
		return context[func].apply(this, args);
	}
};<|endoftext|>