<commit_before>let inputSlotUID = 0;

/**
 * Node Element
 */
export default class NodeElement extends HTMLElement {
  static get observedAttributes() {
    return ["name", "draggable", "open", "x", "y", "width", "height"];
  }

  constructor() {
    super();

    this.attachShadow({ mode: "open" }).innerHTML = `

        <slot></slot>

    `;

    // <graph-draggable targets="[this.getRootNode().host]"></graph-draggable>
    // this._draggable = this.shadowRoot.querySelector("graph-draggable");
    // this._draggable.handles = [this.shadowRoot.querySelector("summary"), this.shadowRoot.querySelector(".content")];

    // this.open = true;
    // this.draggable = true;

    const observer = new MutationObserver((mutationsList, observer) => {
      for (const mutation of mutationsList) {
        for (const node of mutation.addedNodes) {
          if (!("value" in node)) {
            continue;
          }
          this._addInput(node);
        }
        for (const node of mutation.removedNodes) {
          if (!("value" in node)) {
            continue;
          }
          const nodeInputSlot = this.shadowRoot.querySelector(`slot[name="${node.slot}"]`);
          nodeInputSlot.parentElement.remove();
        }
      }
    });
    observer.observe(this, { childList: true });
  }

  connectedCallback() {
    for (const child of this.children) {
      if (!("value" in child)) {
        continue;
      }
      this._addInput(child);
    }
  }

  attributeChangedCallback(name, oldValue, newValue) {
    switch (name) {
      case "name":
        this.shadowRoot.querySelector(".content").querySelector("summary").textContent = newValue;
        break;
      case "draggable":
        // console.log(newValue);
        break;
      case "open":
        this.shadowRoot.querySelector(".content").open = newValue;
        break;
      case "x":
        this.style.left = `${this.x}px`;
        break;
      case "y":
        this.style.top = `${this.y}px`;
        break;
      case "width":
        this.style.width = `${this.width}px`;
        break;
      case "height":
        this.style.height = `${this.height}px`;
        break;
    }
  }

  _addInput(node) {
    if (this.shadowRoot.querySelector(`slot[name="${node.slot}"]`)) {
      return;
    }
    const label = node.label || node.name || node.id || "";
    const section = document.createElement("section");
    section.classList.add("input");
    section.innerHTML = `
      <graph-connector></graph-connector>
      ${label}

<slot name="${inputSlotUID}"></slot>

      <graph-connector></graph-connector>
    `;
    const connectors = section.querySelectorAll("graph-connector");
    connectors[0].outputs.add(node);
    connectors[1].inputs.add(node);
    this.shadowRoot.querySelector(".content").appendChild(section);
    node.slot = inputSlotUID;
    inputSlotUID++;
  }

  set open(value) {
    if (value) {
      this.shadowRoot.querySelector(".content").setAttribute("open", "");
    } else {
      this.shadowRoot.querySelector(".content").removeAttribute("open");
    }
  }

  get open() {
    return this.shadowRoot.querySelector(".content").hasAttribute("open");
  }

  get name() {
    return this.getAttribute("name");
  }

  set name(value) {
    this.setAttribute("name", value);
  }

  get noConnector() {
    return this.hasAttribute("noconnector");
  }

  set noConnector(value) {
    if (value) {
      this.setAttribute("noconnector", "");
    } else {
      this.removeAttribute("noconnector");
    }
  }

  get x() {
    return Number(this.getAttribute("x"));
  }

  set x(value) {
    this.setAttribute("x", String(value));
  }

  get y() {
    return Number(this.getAttribute("y"));
  }

  set y(value) {
    this.setAttribute("y", String(value));
  }

  get width() {
    return Number(this.getAttribute("width"));
  }

  set width(value) {
    this.setAttribute("width", String(value));
  }

  get height() {
    return Number(this.getAttribute("height"));
  }

  set height(value) {
    this.setAttribute("height", String(value));
  }
}
<commit_msg>allow input-connector tagname to be changed<commit_after>let inputSlotUID = 0;
let inputConnectorTagName = "input-connector";

/**
 * Node Element
 */
export default class NodeElement extends HTMLElement {
  static get observedAttributes() {
    return ["name", "draggable", "open", "x", "y", "width", "height"];
  }

  static get inputConnectorTagName() {
    return inputConnectorTagName;
  }

  static set inputConnectorTagName(value) {
    inputConnectorTagName = value;
  }

  constructor() {
    super();

    this.attachShadow({ mode: "open" }).innerHTML = `

        <slot></slot>

    `;

    // <graph-draggable targets="[this.getRootNode().host]"></graph-draggable>
    // this._draggable = this.shadowRoot.querySelector("graph-draggable");
    // this._draggable.handles = [this.shadowRoot.querySelector("summary"), this.shadowRoot.querySelector(".content")];

    // this.open = true;
    // this.draggable = true;

    const observer = new MutationObserver((mutationsList, observer) => {
      for (const mutation of mutationsList) {
        for (const node of mutation.addedNodes) {
          if (!("value" in node)) {
            continue;
          }
          this._addInput(node);
        }
        for (const node of mutation.removedNodes) {
          if (!("value" in node)) {
            continue;
          }
          const nodeInputSlot = this.shadowRoot.querySelector(`slot[name="${node.slot}"]`);
          nodeInputSlot.parentElement.remove();
        }
      }
    });
    observer.observe(this, { childList: true });
  }

  connectedCallback() {
    for (const child of this.children) {
      if (!("value" in child)) {
        continue;
      }
      this._addInput(child);
    }
  }

  attributeChangedCallback(name, oldValue, newValue) {
    switch (name) {
      case "name":
        this.shadowRoot.querySelector(".content").querySelector("summary").textContent = newValue;
        break;
      case "draggable":
        // console.log(newValue);
        break;
      case "open":
        this.shadowRoot.querySelector(".content").open = newValue;
        break;
      case "x":
        this.style.left = `${this.x}px`;
        break;
      case "y":
        this.style.top = `${this.y}px`;
        break;
      case "width":
        this.style.width = `${this.width}px`;
        break;
      case "height":
        this.style.height = `${this.height}px`;
        break;
    }
  }

  _addInput(node) {
    if (this.shadowRoot.querySelector(`slot[name="${node.slot}"]`)) {
      return;
    }
    const label = node.label || node.name || node.id || "";
    const section = document.createElement("section");
    section.classList.add("input");
    section.innerHTML = `
      <${inputConnectorTagName}></${inputConnectorTagName}>
      ${label}

<slot name="${inputSlotUID}"></slot>

      <${inputConnectorTagName}></${inputConnectorTagName}>
    `;
    const connectors = section.querySelectorAll("${inputConnectorTagName}");
    if (connectors[0].outputs) {
      connectors[0].outputs.add(node);
    }
    if (connectors[0].inputs) {
      connectors[1].inputs.add(node);
    }
    this.shadowRoot.querySelector(".content").appendChild(section);
    node.slot = inputSlotUID;
    inputSlotUID++;
  }

  set open(value) {
    if (value) {
      this.shadowRoot.querySelector(".content").setAttribute("open", "");
    } else {
      this.shadowRoot.querySelector(".content").removeAttribute("open");
    }
  }

  get open() {
    return this.shadowRoot.querySelector(".content").hasAttribute("open");
  }

  get name() {
    return this.getAttribute("name");
  }

  set name(value) {
    this.setAttribute("name", value);
  }

  get noConnector() {
    return this.hasAttribute("noconnector");
  }

  set noConnector(value) {
    if (value) {
      this.setAttribute("noconnector", "");
    } else {
      this.removeAttribute("noconnector");
    }
  }

  get x() {
    return Number(this.getAttribute("x"));
  }

  set x(value) {
    this.setAttribute("x", String(value));
  }

  get y() {
    return Number(this.getAttribute("y"));
  }

  set y(value) {
    this.setAttribute("y", String(value));
  }

  get width() {
    return Number(this.getAttribute("width"));
  }

  set width(value) {
    this.setAttribute("width", String(value));
  }

  get height() {
    return Number(this.getAttribute("height"));
  }

  set height(value) {
    this.setAttribute("height", String(value));
  }
}
<|endoftext|>


<commit_before>// returns the raw address after removing any parameters
exports.stripRippleAddress = function(addr) {
  if (typeof(addr) == 'string') {
    var index = addr.indexOf("?");
    if (index >= 0) {
      return (addr.slice(0, index));
    }
  }
  return (addr);
}
//returns the destination tag of an address if there is one
exports.getDestTagFromAddress = function(addr) {
  var index = addr.indexOf("?");
  if (index >= 0) {
    addr = addr.slice(index, addr.length);
    index = addr.indexOf("dt=");
    if (index >= 0) {
      addr = addr.slice(index + 3, addr.length);
      index = addr.indexOf("&");
      if (index > 0) return (addr.slice(0, index));
      else return (addr);
    }
    index = addr.indexOf("d=");
    if (index >= 0) {
      addr = addr.slice(index + 2, addr.length);
      index = addr.indexOf("&");
      if (index > 0) return (addr.slice(0, index));
      else return (addr);
    }
  }
  return (undefined);
}

exports.removeClassPrefix = function(el, group) {
  var $el = $(el);
  var classes = $el.attr("class");

  if (!classes || !classes.length) return;

  classes = classes.split(" ").map(function(item) {
    return item.indexOf(group) === 0 ? "" : item;
  });
  $el.attr("class", classes.join(" "));
};

/**
 * Error handler for jQuery.ajax requests.
 *
 * @example
 *   $.get('http://acme.com/')
 *    .success(...)
 *    .error(webutil.getAjaxErrorHandler(callback, "Acme GET"));
 */
exports.getAjaxErrorHandler = function(callback, context) {
  return function(request, type, errorThrown) {
    switch (type) {
      case 'timeout':
        message = "The request timed out.";
        break;
      case 'notmodified':
        message = "The request was not modified but was not retrieved from the cache.";
        break;
      case 'parsererror':
        message = "XML/Json format is bad.";
        break;
      default:
        message = "HTTP Error (" + request.status + " " + request.statusText + ").";
    }
    callback(new Error(message));
  };
};

exports.scrollToTop = function() {
  $("html, body").animate({
    scrollTop: 0
  }, "fast");
};

exports.findIssuer = function(lines, currency) {
  var maxIssuer = null;
  var maxLimit = 0;

  for (var n in lines) {
    if (lines.hasOwnProperty(n)) {
      if (lines[n].currency === currency) {
        var limit = +lines[n].limit.to_text();
        if (limit > maxLimit) {
          maxLimit = limit;
          maxIssuer = lines[n].account;
        }
      }
    }
  }
  return maxIssuer;
}

exports.getContact = function(contacts, value) {
  for (var i = 0; i < contacts.length; i++) {
    if (contacts[i].name == value || contacts[i].address == value) {
      return contacts[i];
    }
  }

  return false;
};

/**
 * Return the address of a contact.
 *
 * Pass in an address or a contact name and get an address back.
 */
exports.resolveContact = function(contacts, value) {
  for (var i = 0, l = contacts.length; i < l; i++) {
    if (contacts[i].name === value) {
      return contacts[i].address;
    }
  }

  if (ripple.UInt160.is_valid(value)) {
    return ripple.UInt160.json_rewrite(value);
  }

  return '';
};

/**
 * Given an address, return the contact name.
 *
 * If a contact is not found with the given address, simply return the address
 * again.
 */
exports.unresolveContact = function(contacts, value) {
  try {
    for (var i = 0, l = contacts.length; i < l; i++) {
      if (contacts[i].address === value) {
        return contacts[i].name;
      }
    }
  } catch (e) {}

  return value;
};

/**
 * Creates a combobox query function out of a select options array.
 *
 * @param options {array} An array of select options like {name: '', value: ''}.
 */
exports.queryFromOptions = function(options) {
  var opts = options.map(function(entry) {
    return entry.name;
  });
  return exports.queryFromArray(opts);
};

/**
 * Creates a combobox query function out of a plain array of strings.
 *
 * @param options {array} An array of options, e.g. ['First choice', '2nd']
 */
exports.queryFromArray = function(options) {
  return function(match, re) {
    if (re instanceof RegExp) {
      return options.filter(function(name) {
        return "string" === typeof name ? name.match(re) : false;
      });
    } else return options;
  };
};

/**
 * Escapes a string for use as a literal inside of a regular expression.
 *
 * From: http://stackoverflow.com/questions/3446170
 */
exports.escapeRegExp = function(str) {
  return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
};

/*
 * Proper local redirect, for getting rid of query strings
 */
exports.redirect = function(to) {
  window.location = window.location.pathname + '#' + to;
}

/**
 * Return tab name
 */
exports.tabName = function() {

  return (window.location.hash.replace('#/', '')) ? true : false;
}

/**
 * Redirect to proper location based on funding
 */
exports.defaultDestination = function(register) {
  // check if user is funded and redirect accordingly
  if ((register) && register.hasOwnProperty('id')) {
    $.post(Options.giveawayServer + '/user/' + register.id, {
      action: 'isFunded',
      register: register.hash
    }, function(res) {
      var defaultDestination = (res.funded) ? '/balance' : '/getripple'
      webutil.redirect(defaultDestination);
    });
  } else
    webutil.redirect('/getripple');
}

/**
 * Return true or false if the giveaway server is up
 * @param  {Function} cb callback
 * @return {bool} is server up
 */
exports.giveawayServerStatus = function(cb) {
  $.ajax({
    url: Options.giveawayServer + '/user/funded_total',
    type: "GET",
    success: function(data) {
      cb(true);
    },
    error: function(xhr, status, error) {
      cb(false);
    }
  });
}

/**
 * Return register hash object from url or return false
 * @return {mixed} return object or bool
 */
exports.getRegisterHash = function($routeParams) {
   // if register params exist create object else make it false
  return ($routeParams.register) ? {
    id: $routeParams.id,
    hash: $routeParams.register
  } : false;
}<commit_msg>using url helper<commit_after>// returns the raw address after removing any parameters
exports.stripRippleAddress = function(addr) {
  if (typeof(addr) == 'string') {
    var index = addr.indexOf("?");
    if (index >= 0) {
      return (addr.slice(0, index));
    }
  }
  return (addr);
}
//returns the destination tag of an address if there is one
exports.getDestTagFromAddress = function(addr) {
  var index = addr.indexOf("?");
  if (index >= 0) {
    addr = addr.slice(index, addr.length);
    index = addr.indexOf("dt=");
    if (index >= 0) {
      addr = addr.slice(index + 3, addr.length);
      index = addr.indexOf("&");
      if (index > 0) return (addr.slice(0, index));
      else return (addr);
    }
    index = addr.indexOf("d=");
    if (index >= 0) {
      addr = addr.slice(index + 2, addr.length);
      index = addr.indexOf("&");
      if (index > 0) return (addr.slice(0, index));
      else return (addr);
    }
  }
  return (undefined);
}

exports.removeClassPrefix = function(el, group) {
  var $el = $(el);
  var classes = $el.attr("class");

  if (!classes || !classes.length) return;

  classes = classes.split(" ").map(function(item) {
    return item.indexOf(group) === 0 ? "" : item;
  });
  $el.attr("class", classes.join(" "));
};

/**
 * Error handler for jQuery.ajax requests.
 *
 * @example
 *   $.get('http://acme.com/')
 *    .success(...)
 *    .error(webutil.getAjaxErrorHandler(callback, "Acme GET"));
 */
exports.getAjaxErrorHandler = function(callback, context) {
  return function(request, type, errorThrown) {
    switch (type) {
      case 'timeout':
        message = "The request timed out.";
        break;
      case 'notmodified':
        message = "The request was not modified but was not retrieved from the cache.";
        break;
      case 'parsererror':
        message = "XML/Json format is bad.";
        break;
      default:
        message = "HTTP Error (" + request.status + " " + request.statusText + ").";
    }
    callback(new Error(message));
  };
};

exports.scrollToTop = function() {
  $("html, body").animate({
    scrollTop: 0
  }, "fast");
};

exports.findIssuer = function(lines, currency) {
  var maxIssuer = null;
  var maxLimit = 0;

  for (var n in lines) {
    if (lines.hasOwnProperty(n)) {
      if (lines[n].currency === currency) {
        var limit = +lines[n].limit.to_text();
        if (limit > maxLimit) {
          maxLimit = limit;
          maxIssuer = lines[n].account;
        }
      }
    }
  }
  return maxIssuer;
}

exports.getContact = function(contacts, value) {
  for (var i = 0; i < contacts.length; i++) {
    if (contacts[i].name == value || contacts[i].address == value) {
      return contacts[i];
    }
  }

  return false;
};

/**
 * Return the address of a contact.
 *
 * Pass in an address or a contact name and get an address back.
 */
exports.resolveContact = function(contacts, value) {
  for (var i = 0, l = contacts.length; i < l; i++) {
    if (contacts[i].name === value) {
      return contacts[i].address;
    }
  }

  if (ripple.UInt160.is_valid(value)) {
    return ripple.UInt160.json_rewrite(value);
  }

  return '';
};

/**
 * Given an address, return the contact name.
 *
 * If a contact is not found with the given address, simply return the address
 * again.
 */
exports.unresolveContact = function(contacts, value) {
  try {
    for (var i = 0, l = contacts.length; i < l; i++) {
      if (contacts[i].address === value) {
        return contacts[i].name;
      }
    }
  } catch (e) {}

  return value;
};

/**
 * Creates a combobox query function out of a select options array.
 *
 * @param options {array} An array of select options like {name: '', value: ''}.
 */
exports.queryFromOptions = function(options) {
  var opts = options.map(function(entry) {
    return entry.name;
  });
  return exports.queryFromArray(opts);
};

/**
 * Creates a combobox query function out of a plain array of strings.
 *
 * @param options {array} An array of options, e.g. ['First choice', '2nd']
 */
exports.queryFromArray = function(options) {
  return function(match, re) {
    if (re instanceof RegExp) {
      return options.filter(function(name) {
        return "string" === typeof name ? name.match(re) : false;
      });
    } else return options;
  };
};

/**
 * Escapes a string for use as a literal inside of a regular expression.
 *
 * From: http://stackoverflow.com/questions/3446170
 */
exports.escapeRegExp = function(str) {
  return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
};

// load url helper
exports.url = require('url');

/*
 * Proper local redirect, for getting rid of query strings
 */
exports.redirect = function(to) {
  window.location = window.location.pathname + '#' + to;
}

/**
 * Return tab name
 */
exports.tabName = function() {
  return (this.url.parse(window.location).hash.replace('#/', '')) ? true : false;
}

/**
 * Redirect to proper location based on funding
 */
exports.defaultDestination = function(register) {
  // check if user is funded and redirect accordingly
  if ((register) && register.hasOwnProperty('id')) {
    $.post(Options.giveawayServer + '/user/' + register.id, {
      action: 'isFunded',
      register: register.hash
    }, function(res) {
      var defaultDestination = (res.funded) ? '/balance' : '/getripple'
      webutil.redirect(defaultDestination);
    });
  } else
    webutil.redirect('/getripple');
}

/**
 * Return true or false if the giveaway server is up
 * @param  {Function} cb callback
 * @return {bool} is server up
 */
exports.giveawayServerStatus = function(cb) {
  $.ajax({
    url: Options.giveawayServer + '/user/funded_total',
    type: "GET",
    success: function(data) {
      cb(true);
    },
    error: function(xhr, status, error) {
      cb(false);
    }
  });
}

/**
 * Return register hash object from url or return false
 * @return {mixed} return object or bool
 */
exports.getRegisterHash = function($routeParams) {
   // if register params exist create object else make it false
  return ($routeParams.register) ? {
    id: $routeParams.id,
    hash: $routeParams.register
  } : false;
}<|endoftext|>


<commit_before>let slotUID = 0;
let inputConnectorTagName = "input-connector";

/**
 * Node Element
 */
export default class NodeElement extends HTMLElement {
  static get observedAttributes() {
    return ["name", "draggable", "open", "x", "y", "width", "height"];
  }

  static get inputConnectorTagName() {
    return inputConnectorTagName;
  }

  static set inputConnectorTagName(value) {
    inputConnectorTagName = value;
  }

  constructor() {
    super();

    this.attachShadow({ mode: "open" }).innerHTML = `

    `;

    // <graph-draggable targets="[this.getRootNode().host]"></graph-draggable>
    // this._draggable = this.shadowRoot.querySelector("graph-draggable");
    // this._draggable.handles = [this.shadowRoot.querySelector("summary"), this.shadowRoot.querySelector(".content")];

    // this.open = true;
    // this.draggable = true;

    const observer = new MutationObserver((mutationsList, observer) => {
      for (const mutation of mutationsList) {
        for (const node of mutation.addedNodes) {
          if (!("value" in node)) {
            const section = document.createElement("section");
            section.id = `slot${slotUID}`;
            section.innerHTML = `<slot name="${slotUID}"></slot>`;
            this.shadowRoot.querySelector(".content").appendChild(section);
            node.slot = slotUID;
            slotUID++;
          }
          this._addInput(node);
        }
        for (const node of mutation.removedNodes) {
          this.shadowRoot.querySelector(`section#slot${node.slot}`).remove();
        }
      }
    });
    observer.observe(this, { childList: true });
  }

  connectedCallback() {
    for (const child of this.children) {
      if (!("value" in child)) {
        continue;
      }
      this._addInput(child);
    }
  }

  attributeChangedCallback(name, oldValue, newValue) {
    switch (name) {
      case "name":
        this.shadowRoot.querySelector(".content").querySelector("summary").textContent = newValue;
        break;
      case "draggable":
        // console.log(newValue);
        break;
      case "open":
        this.shadowRoot.querySelector(".content").open = newValue;
        break;
      case "x":
        this.style.left = `${this.x}px`;
        break;
      case "y":
        this.style.top = `${this.y}px`;
        break;
      case "width":
        this.style.width = `${this.width}px`;
        break;
      case "height":
        this.style.height = `${this.height}px`;
        break;
    }
  }

  _addInput(node) {
    if (this.shadowRoot.querySelector(`slot[name="${node.slot}"]`)) {
      return;
    }
    const label = node.label || node.name || node.id || "";
    const section = document.createElement("section");
    section.id = `slot${slotUID}`;
    section.classList.add("input");
    section.innerHTML = `
      <${inputConnectorTagName}></${inputConnectorTagName}>
      ${label}

<slot name="${slotUID}"></slot>

      <${inputConnectorTagName}></${inputConnectorTagName}>
    `;
    const connectors = section.querySelectorAll(`${inputConnectorTagName}`);
    if (connectors[0].outputs) {
      connectors[0].outputs.add(node);
    }
    if (connectors[0].inputs) {
      connectors[1].inputs.add(node);
    }
    this.shadowRoot.querySelector(".content").appendChild(section);
    node.slot = slotUID;
    slotUID++;
  }

  set open(value) {
    if (value) {
      this.shadowRoot.querySelector(".content").setAttribute("open", "");
    } else {
      this.shadowRoot.querySelector(".content").removeAttribute("open");
    }
  }

  get open() {
    return this.shadowRoot.querySelector(".content").hasAttribute("open");
  }

  get name() {
    return this.getAttribute("name");
  }

  set name(value) {
    this.setAttribute("name", value);
  }

  get noConnector() {
    return this.hasAttribute("noconnector");
  }

  set noConnector(value) {
    if (value) {
      this.setAttribute("noconnector", "");
    } else {
      this.removeAttribute("noconnector");
    }
  }

  get x() {
    return Number(this.getAttribute("x"));
  }

  set x(value) {
    this.setAttribute("x", String(value));
  }

  get y() {
    return Number(this.getAttribute("y"));
  }

  set y(value) {
    this.setAttribute("y", String(value));
  }

  get width() {
    return Number(this.getAttribute("width"));
  }

  set width(value) {
    this.setAttribute("width", String(value));
  }

  get height() {
    return Number(this.getAttribute("height"));
  }

  set height(value) {
    this.setAttribute("height", String(value));
  }
}
<commit_msg>add toggle to node<commit_after>let slotUID = 0;
let inputConnectorTagName = "input-connector";

/**
 * Node Element
 */
export default class NodeElement extends HTMLElement {
  static get observedAttributes() {
    return ["name", "draggable", "close", "x", "y", "width", "height"];
  }

  static get inputConnectorTagName() {
    return inputConnectorTagName;
  }

  static set inputConnectorTagName(value) {
    inputConnectorTagName = value;
  }

  constructor() {
    super();

    this.attachShadow({ mode: "open" }).innerHTML = `

    `;

    // <graph-draggable targets="[this.getRootNode().host]"></graph-draggable>
    // this._draggable = this.shadowRoot.querySelector("graph-draggable");
    // this._draggable.handles = [this.shadowRoot.querySelector("summary"), this.shadowRoot.querySelector(".content")];

    // this.open = true;
    // this.draggable = true;

    const observer = new MutationObserver((mutationsList, observer) => {
      for (const mutation of mutationsList) {
        for (const node of mutation.addedNodes) {
          if (!("value" in node)) {
            const section = document.createElement("section");
            section.id = `slot${slotUID}`;
            section.innerHTML = `<slot name="${slotUID}"></slot>`;
            this.shadowRoot.querySelector(".content").appendChild(section);
            node.slot = slotUID;
            slotUID++;
          }
          this._addInput(node);
        }
        for (const node of mutation.removedNodes) {
          this.shadowRoot.querySelector(`section#slot${node.slot}`).remove();
        }
      }
    });
    observer.observe(this, { childList: true });

    this.shadowRoot.querySelector("details").addEventListener("toggle", (event) => {
      this.close = !event.target.open;
      this.dispatchEvent(new Event(event.type, event));
    });
  }

  connectedCallback() {
    this.shadowRoot.querySelector(".content").open = !this.close;
    for (const child of this.children) {
      if (!("value" in child)) {
        continue;
      }
      this._addInput(child);
    }
  }

  attributeChangedCallback(name, oldValue, newValue) {
    switch (name) {
      case "name":
        this.shadowRoot.querySelector(".content").querySelector("summary").textContent = newValue;
        break;
      case "draggable":
        // console.log(newValue);
        break;
      case "close":
        this.shadowRoot.querySelector(".content").open = !this.close;
        break;
      case "x":
        this.style.left = `${this.x}px`;
        break;
      case "y":
        this.style.top = `${this.y}px`;
        break;
      case "width":
        this.style.width = `${this.width}px`;
        break;
      case "height":
        this.style.height = `${this.height}px`;
        break;
    }
  }

  _addInput(node) {
    if (this.shadowRoot.querySelector(`slot[name="${node.slot}"]`)) {
      return;
    }
    const label = node.label || node.name || node.id || "";
    const section = document.createElement("section");
    section.id = `slot${slotUID}`;
    section.classList.add("input");
    section.innerHTML = `
      <${inputConnectorTagName}></${inputConnectorTagName}>
      ${label}

<slot name="${slotUID}"></slot>

      <${inputConnectorTagName}></${inputConnectorTagName}>
    `;
    const connectors = section.querySelectorAll(`${inputConnectorTagName}`);
    if (connectors[0].outputs) {
      connectors[0].outputs.add(node);
    }
    if (connectors[0].inputs) {
      connectors[1].inputs.add(node);
    }
    this.shadowRoot.querySelector(".content").appendChild(section);
    node.slot = slotUID;
    slotUID++;
  }

  set close(value) {
    if (value) {
      this.setAttribute("close", "");
    } else {
      this.removeAttribute("close");
    }
  }

  get close() {
    return this.hasAttribute("close");
  }

  get name() {
    return this.getAttribute("name");
  }

  set name(value) {
    this.setAttribute("name", value);
  }

  get noConnector() {
    return this.hasAttribute("noconnector");
  }

  set noConnector(value) {
    if (value) {
      this.setAttribute("noconnector", "");
    } else {
      this.removeAttribute("noconnector");
    }
  }

  get x() {
    return Number(this.getAttribute("x"));
  }

  set x(value) {
    this.setAttribute("x", String(value));
  }

  get y() {
    return Number(this.getAttribute("y"));
  }

  set y(value) {
    this.setAttribute("y", String(value));
  }

  get width() {
    return Number(this.getAttribute("width"));
  }

  set width(value) {
    this.setAttribute("width", String(value));
  }

  get height() {
    return Number(this.getAttribute("height"));
  }

  set height(value) {
    this.setAttribute("height", String(value));
  }
}
<|endoftext|>


<commit_before>// App is our globally scoped variable that holds everything.
var App = App || {};

// Function for switching between views
// ViewClass is a reference to a view class to be instantiated.
// data is an object full of arguments to be passed to the view.
App.switchView = function(ViewClass, data) {
    'use strict';

    data = data || {};
    // Close the active view
    if (App.activeView && App.activeView.close) {
        App.activeView.close();
    }
    // Show the loading view.
    App.activeView = new App.classes.LoadingView();

    // If the ViewClass doesn't exist, put out a 404 view if it exists.
    if (!ViewClass && App.classes['NotfoundView']) {
        ViewClass = App.classes['NotfoundView'];
    }

    // instantiate ViewClass and set it as active.
    if (ViewClass) {
        App.activeView = new ViewClass(data);

        // also call its open function.
        if (App.activeView.open) {
            App.activeView.open();
        }
    }
};

// Routing, this is how we decide what to do depending on the URL.
// Most of the time we just switch the view. My defaultRouting function
// attempts to switch to a view that matches the page name in the URL.
var AppRouter = Backbone.Router.extend({
    routes: {
        '': 'defaultRouting',
        ':page(/)': 'defaultRouting'
    },
    defaultRouting: function(page) {
        'use strict';
        var viewName,
            // You need to implement argument passing yourself, as those arguments
            // will most likely come from the URL, and it's up to you how you
            // want to structure you URLs.
            data = {};

        // Format the page name to match the class naming convention.
        // If page is undefined then this is the index.
        viewName = page ? page.charAt(0).toUpperCase() + page.slice(1) : 'Index';

        App.switchView(App.classes[viewName+'View'], data);
    }
});

App.Router = new AppRouter();

Backbone.history.start();<commit_msg>Switched to dot notation for not found<commit_after>// App is our globally scoped variable that holds everything.
var App = App || {};

// Function for switching between views
// ViewClass is a reference to a view class to be instantiated.
// data is an object full of arguments to be passed to the view.
App.switchView = function(ViewClass, data) {
    'use strict';

    data = data || {};
    // Close the active view
    if (App.activeView && App.activeView.close) {
        App.activeView.close();
    }
    // Show the loading view.
    App.activeView = new App.classes.LoadingView();

    // If the ViewClass doesn't exist, put out a 404 view if it exists.
    if (!ViewClass && App.classes.NotfoundView) {
        ViewClass = App.classes.NotfoundView;
    }

    // instantiate ViewClass and set it as active.
    if (ViewClass) {
        App.activeView = new ViewClass(data);

        // also call its open function.
        if (App.activeView.open) {
            App.activeView.open();
        }
    }
};

// Routing, this is how we decide what to do depending on the URL.
// Most of the time we just switch the view. My defaultRouting function
// attempts to switch to a view that matches the page name in the URL.
var AppRouter = Backbone.Router.extend({
    routes: {
        '': 'defaultRouting',
        ':page(/)': 'defaultRouting'
    },
    defaultRouting: function(page) {
        'use strict';
        var viewName,
            // You need to implement argument passing yourself, as those arguments
            // will most likely come from the URL, and it's up to you how you
            // want to structure you URLs.
            data = {};

        // Format the page name to match the class naming convention.
        // If page is undefined then this is the index.
        viewName = page ? page.charAt(0).toUpperCase() + page.slice(1) : 'Index';

        App.switchView(App.classes[viewName+'View'], data);
    }
});

App.Router = new AppRouter();

Backbone.history.start();<|endoftext|>


<commit_before>vde.iVis = (function() {
  var ivis = {
    view: null,
    dragging: null,
    timeout: null,
    _data: {}, _marks: [], _evtHandlers: {},
    newMark: null,
    activeMark: null,
    activeItem: null
  };

  var events = [
    "mousemove", "mousedown", "mouseup", "mouseover", "mouseout",
    "click", "dblclick", "keypress", "keydown", "keyup"
  ];

  var interactors = ['handle', 'connector', 'connection', 'point', 'span', 'dropzone'];

  ivis.interactor = function(interactor, data) {
    if(!interactor || !data) return;

    this._data[interactor] = data;
    return this;
  };

  ivis.show = function(show, evtHandlers) {
    if(!vg.isArray(show)) show = [show];
    if(show == 'selected' && this.activeMark) {
      var selected = this.activeMark.selected();
      show = vg.keys(selected.interactors);
      for(var s in selected.interactors) ivis.interactor(s, selected.interactors[s]);
      if(!evtHandlers) evtHandlers = selected.evtHandlers;
    }

    var d = {};
    interactors.forEach(function(i) { d[i] = []; });
    show.forEach(function(s) { if(ivis._data[s]) d[s] = ivis._data[s]; });

    // Unregister all evtHandlers and re-register them here
    if(evtHandlers) {
      this._evtHandlers = {};
      for(var type in evtHandlers) this._evtHandlers[type] = evtHandlers[type];
    }

    ivis.view.data(d).update();
    return this;
  };

  // We can't keep re-parsing the iVis layer. This triggers false mouseout
  // events as a result of removing all #ivis children. So, we only reparse
  // when we reparse the Vis, and subsequently only update the datasets.
  ivis.parse = function() {
    var spec = {
      width: vde.Vis.properties.width,
      height: vde.Vis.properties.height,
      padding: vde.Vis.properties.padding
    };

    spec.data = interactors.map(function(i) { return {name: i, values: [] }});
    spec.scales = [{
      name: 'disabled',
      domain: [0, 1],
      range: ['#fff', '#999']
    }, {
      name: 'connection_status',
      domain: [0, 1],
      range: ['magenta', 'lime']
    }];
    spec.marks = interactors.map(function(i) { return ivis[i](); });

    vg.parse.spec(spec, function(chart) {
      d3.select('#ivis').selectAll('*').remove();
      (vde.iVis.view = chart({ el: '#ivis' })).update();

      var icanvas = d3.select('#ivis canvas');

      // We have event handlers registered on both #vis and #ivis
      // so transmit interactions on ivis (on top) to #vis (bottom).
      var dispatchEvent = function() {
        var e = d3.event;
        var evt = document.createEvent("MouseEvents");
        evt.initMouseEvent(e.type, e.canBubble, e.cancelable, window,
          e.detail, e.screenX, e.screenY, e.clientX, e.clientY,
          e.ctrlKey, e.altKey, e.shiftKey, e.metaKey, e.button, e.relatedTarget);
        d3.select('#vis canvas').node().dispatchEvent(evt);
      };

      var mouseup = function() { vde.iVis.dragging = null; icanvas.style('cursor', 'auto'); };

      events.forEach(function(type) {
        if(type == 'mousemove') {
          icanvas.on('mousemove', function() {
            dispatchEvent();
            if(ivis._evtHandlers[type]) ivis._evtHandlers[type]();
          })
        } else if(type.indexOf('key') != -1) {
          d3.select('body').on(type, function() {
            if(ivis._evtHandlers[type]) ivis._evtHandlers[type]();
          });
        } else {
          icanvas.on(type, dispatchEvent);

          vde.iVis.view.on(type, function(e, item) {
            if(ivis._evtHandlers[type]) ivis._evtHandlers[type](e, item);

            var cursor = function() {
              if(item.mark.def.name == 'handle' && item.datum.data &&
                  item.datum.data.cursor && !item.datum.data.disabled)
                icanvas.style('cursor', item.datum.data.cursor);
            };

            var items = function() {  // We need to make this more reliable.
              var items = [];

              if(item.mark.group.items[1].items.length > 0)       // Connectors
                items.push(item.mark.group.items[1].items[item.key]);

              if(item.mark.group.items[3].items.length > 0) // Points
                items.push(item.mark.group.items[3].items[item.key-2]);

              return items;
            };

            // Automatically register events to handle dragging
            switch(type) {
              case 'mouseover':
                cursor();

                if(ivis.dragging && item.mark.def.name == 'dropzone') {
                  // On mouseover, highlight the underlying span/connector.
                  if(item.connector)
                    ivis.view.update({
                      props: 'hover',
                      items: items()
                    });
                  else
                    ivis.view.update({
                      props: 'hover',
                      items: item.cousin(-1).items[0].items
                    });

                  if(item.property)
                    d3.selectAll('#' + item.property + '.property').classed('drophover', true);
                }
              break;

              case 'mouseout':
                if(ivis.dragging && item.mark.def.name == 'dropzone') {
                  // Clear highlights
                  if(item.connector)
                    ivis.view.update({
                      props: 'update',
                      items: items()
                    });
                  else
                    ivis.view.update({
                      props: 'update',
                      items: item.cousin(-1).items[0].items
                    });

                  if(item.property)
                    d3.selectAll('#' + item.property + '.property').classed('drophover', false);
                }

                if(!ivis.dragging) mouseup();
              break;

              case 'mousedown':
                ivis.dragging = {item: item, prev: [e.pageX, e.pageY]};
                cursor();
              break;

              case 'mouseup':
                if(ivis.dragging && item.mark.def.name == 'dropzone') {
                  var isMark = $(ivis.dragging).hasClass('mark');
                  if(item.property && !isMark) {
                    ivis.bindProperty(ivis.activeMark, item.property, true);
                    d3.selectAll('#' + item.property + '.property').classed('drophover', false);
                  } else if(item.connector && isMark) {
                    ivis.addMark(ivis.activeMark, item.connector);
                  }
                }

                mouseup();
              break;
            }
          });
        }
      });

      ivis.show('selected');
    });

    return spec;
  };

  ivis.bindProperty = function(visual, property, defaults) {
    if(!ivis.dragging) return;

    var rootScope = ivis.ngScope();
    var field = $(ivis.dragging).data('field') || $(ivis.dragging).find('.schema').data('field') || $(ivis.dragging).find('.schema').attr('field');
    var scale = $(ivis.dragging).find('.scale').attr('scale');
    var pipelineName = rootScope.activePipeline.name;

    if(visual.pipelineName && pipelineName != visual.pipelineName)
      return alert('Pipelines don\'t match');

    rootScope.$apply(function() {
      if(!visual.pipelineName && !(visual instanceof vde.Vis.Transform)) visual.pipelineName = pipelineName;

      visual.bindProperty(property,
        {field: field, scaleName: scale, pipelineName: pipelineName}, defaults);
    });

    vde.Vis.parse();

    window.setTimeout(function() {
      $('.proxy').remove();
      ivis.dragging = null;

      ivis.ngLogger().log('bind', {
        item: visual.name,
        group: visual.groupName,
        activePipeline: rootScope.activePipeline.name,
        itemPipeline: visual.pipelineName,
        property: property,
        scaleName: scale,
        field: field
      }, true, true);

      rootScope.$apply(function() { rootScope.toggleVisual(visual); });
    }, 1);

    window.clearTimeout(vde.iVis.timeout);
  };

  ivis.addMark = function(host, connector) {
    var mark = ivis.newMark,
        rootScope = ivis.ngScope();

    if(host instanceof vde.Vis.marks.Group) mark.groupName = host.name;
    else if(host.connectors[connector]) {
      mark.groupName    = host.groupName;
      mark.connectedTo  = {host: host, connector: connector};
    }

    rootScope.$apply(function() {
      mark.init();
      vde.Vis.parse();
    });

    window.setTimeout(function() {
      ivis.newMark = null;
      $('.proxy').remove();

      ivis.ngLogger().log('new_mark', {
        markType: mark.type,
        markName: mark.name,
        activeGroup: (rootScope.activeGroup || {}).name,
        markGroup: mark.groupName
      }, true);

      rootScope.$apply(function() { rootScope.toggleVisual(mark); });
    }, 1);

    window.clearTimeout(vde.iVis.timeout);
  };

  ivis.handle = function() {
    return {
      name: 'handle',
      type: 'symbol',
      from: {data: 'handle'},
      properties: {
        enter: {
          shape: {value: 'square'},
          size: {value: 40},
          fill: {scale: 'disabled', field: 'data.disabled'},
          stroke: {value: 'black'},
          strokeWidth: {value: 0.5}
        },
        update: {
          x: {field: 'data.x'},
          y: {field: 'data.y'},
          connector: {field: 'data.connector'}
        }
      }
    }
  };

  ivis.connector = function() {
    return {
      name: 'connector',
      type: 'symbol',
      from: {
        data: 'connector',
        transform: [{
          type: 'formula',
          field: 'status',
          expr: '(d.data.connected) ? 1 : 0'
        }]
      },
      properties: {
        enter: {
          shape: {value: 'diamond'},
          size: {value: 40},
          fill: {value: 'white'}
        },
        update: {
          x: {field: 'data.x'},
          y: {field: 'data.y'},
          stroke: {scale: 'connection_status', field: 'status'},
          strokeWidth: {value: 0.5},
          connector: {field: 'data.connector'}
        },
        hover: {
          stroke: {value: 'lime'},
          strokeWidth: {value: 1}
        }
      }
    }
  };

  ivis.connection = function() {
    return {
      name: 'connection_group',
      type: 'group',
      from: {
        data: 'connection',
        transform: [{type: 'facet', keys:['data.span']}]
      },
      marks: [{
        name: 'connection',
        type: 'line',
        properties: {
          update: {
            x: {field: 'data.x'},
            y: {field: 'data.y'},
            stroke: {value: 'black'},
            strokeWidth: {value: 0.5},
            strokeDash: {value: [5, 5]}
          }
        }
      }]
    }
  };

  ivis.point = function() {
    return {
      name: 'point',
      type: 'symbol',
      from: {data: 'point'},
      properties: {
        enter: {
          shape: {value: 'circle'},
        },
        update: {
          x: {field: 'data.x'},
          y: {field: 'data.y'},
          fill: {value: 'cyan'},
          size: {value: 40},
          connector: {field: 'data.connector'}
        },
        hover: {
          size: {value: 80},
          fill: {value: 'lightsalmon'}
        }
      }
    };
  };

  ivis.span = function() {
    return {
      name: 'span_group',
      type: 'group',
      from: {
        data: 'span',
        transform: [{type: 'facet', keys:['data.span']}]
      },
      marks: [{
        name: 'span',
        type: 'line',
        properties: {
          update: {
            x: {field: 'data.x'},
            y: {field: 'data.y'},
            stroke: {value: 'cyan'},
            strokeWidth: {value: 1},
            span: {field: 'data.span'}
          },
          hover: {
            stroke: {value: 'lightsalmon'},
            strokeWidth: {value: 3}
          }
        }
      }]
    }
  };

  ivis.dropzone = function() {
    return {
      name: 'dropzone',
      type: 'rect',
      from: {data: 'dropzone'},
      properties: {
        enter: {
          fillOpacity: {value: 0},
          // stroke: {value: 'black'},
          // strokeDash: {value: [0.3, 1]}
        },
        update: {
          x: {field: 'data.x'},
          y: {field: 'data.y'},
          x2: {field: 'data.x2'},
          y2: {field: 'data.y2'},
          property: {field: 'data.property'},
          connector: {field: 'data.connector'}
        }
      }
    }
  };

  // From vg.canvas.Renderer
  ivis.translatedBounds = function(item, bounds) {
    var b = new vg.Bounds(bounds);
    while ((item = item.mark.group) != null) {
      b.translate(item.x || 0, item.y || 0);
    }
    return b;
  };

  ivis.ngScope = function() {
    return $('html').injector().get('$rootScope')
  };

  ivis.ngLogger = function() {
    return $('html').injector().get('logger');
  };

  return ivis;
})();
<commit_msg>Fixed point dropzone hovers<commit_after>vde.iVis = (function() {
  var ivis = {
    view: null,
    dragging: null,
    timeout: null,
    _data: {}, _marks: [], _evtHandlers: {},
    newMark: null,
    activeMark: null,
    activeItem: null
  };

  var events = [
    "mousemove", "mousedown", "mouseup", "mouseover", "mouseout",
    "click", "dblclick", "keypress", "keydown", "keyup"
  ];

  var interactors = ['handle', 'connector', 'connection', 'point', 'span', 'dropzone'];

  ivis.interactor = function(interactor, data) {
    if(!interactor || !data) return;

    this._data[interactor] = data;
    return this;
  };

  ivis.show = function(show, evtHandlers) {
    if(!vg.isArray(show)) show = [show];
    if(show == 'selected' && this.activeMark) {
      var selected = this.activeMark.selected();
      show = vg.keys(selected.interactors);
      for(var s in selected.interactors) ivis.interactor(s, selected.interactors[s]);
      if(!evtHandlers) evtHandlers = selected.evtHandlers;
    }

    var d = {};
    interactors.forEach(function(i) { d[i] = []; });
    show.forEach(function(s) { if(ivis._data[s]) d[s] = ivis._data[s]; });

    // Unregister all evtHandlers and re-register them here
    if(evtHandlers) {
      this._evtHandlers = {};
      for(var type in evtHandlers) this._evtHandlers[type] = evtHandlers[type];
    }

    ivis.view.data(d).update();
    return this;
  };

  // We can't keep re-parsing the iVis layer. This triggers false mouseout
  // events as a result of removing all #ivis children. So, we only reparse
  // when we reparse the Vis, and subsequently only update the datasets.
  ivis.parse = function() {
    var spec = {
      width: vde.Vis.properties.width,
      height: vde.Vis.properties.height,
      padding: vde.Vis.properties.padding
    };

    spec.data = interactors.map(function(i) { return {name: i, values: [] }});
    spec.scales = [{
      name: 'disabled',
      domain: [0, 1],
      range: ['#fff', '#999']
    }, {
      name: 'connection_status',
      domain: [0, 1],
      range: ['magenta', 'lime']
    }];
    spec.marks = interactors.map(function(i) { return ivis[i](); });

    vg.parse.spec(spec, function(chart) {
      d3.select('#ivis').selectAll('*').remove();
      (vde.iVis.view = chart({ el: '#ivis' })).update();

      var icanvas = d3.select('#ivis canvas');

      // We have event handlers registered on both #vis and #ivis
      // so transmit interactions on ivis (on top) to #vis (bottom).
      var dispatchEvent = function() {
        var e = d3.event;
        var evt = document.createEvent("MouseEvents");
        evt.initMouseEvent(e.type, e.canBubble, e.cancelable, window,
          e.detail, e.screenX, e.screenY, e.clientX, e.clientY,
          e.ctrlKey, e.altKey, e.shiftKey, e.metaKey, e.button, e.relatedTarget);
        d3.select('#vis canvas').node().dispatchEvent(evt);
      };

      var mouseup = function() { vde.iVis.dragging = null; icanvas.style('cursor', 'auto'); };

      events.forEach(function(type) {
        if(type == 'mousemove') {
          icanvas.on('mousemove', function() {
            dispatchEvent();
            if(ivis._evtHandlers[type]) ivis._evtHandlers[type]();
          })
        } else if(type.indexOf('key') != -1) {
          d3.select('body').on(type, function() {
            if(ivis._evtHandlers[type]) ivis._evtHandlers[type]();
          });
        } else {
          icanvas.on(type, dispatchEvent);

          vde.iVis.view.on(type, function(e, item) {
            if(ivis._evtHandlers[type]) ivis._evtHandlers[type](e, item);

            var cursor = function() {
              if(item.mark.def.name == 'handle' && item.datum.data &&
                  item.datum.data.cursor && !item.datum.data.disabled)
                icanvas.style('cursor', item.datum.data.cursor);
            };

            var items = function() {  // We need to make this more reliable.
              var items = [];

              if(item.mark.group.items[1].items.length > 0)   // Connectors
                items.push(item.mark.group.items[1].items[item.key]);

              if(item.mark.group.items[3].items.length > 0) { // Points
                // We need to offset by the number of spans
                var spans = item.mark.group.items[4].items.length;
                items.push(item.mark.group.items[3].items[item.key-spans]);
              }

              return items;
            };

            // Automatically register events to handle dragging
            switch(type) {
              case 'mouseover':
                cursor();

                if(ivis.dragging && item.mark.def.name == 'dropzone') {
                  // On mouseover, highlight the underlying span/connector.
                  if(item.connector)
                    ivis.view.update({
                      props: 'hover',
                      items: items()
                    });
                  else
                    ivis.view.update({
                      props: 'hover',
                      items: item.cousin(-1).items[0].items
                    });

                  if(item.property)
                    d3.selectAll('#' + item.property + '.property').classed('drophover', true);
                }
              break;

              case 'mouseout':
                if(ivis.dragging && item.mark.def.name == 'dropzone') {
                  // Clear highlights
                  if(item.connector)
                    ivis.view.update({
                      props: 'update',
                      items: items()
                    });
                  else
                    ivis.view.update({
                      props: 'update',
                      items: item.cousin(-1).items[0].items
                    });

                  if(item.property)
                    d3.selectAll('#' + item.property + '.property').classed('drophover', false);
                }

                if(!ivis.dragging) mouseup();
              break;

              case 'mousedown':
                ivis.dragging = {item: item, prev: [e.pageX, e.pageY]};
                cursor();
              break;

              case 'mouseup':
                if(ivis.dragging && item.mark.def.name == 'dropzone') {
                  var isMark = $(ivis.dragging).hasClass('mark');
                  if(item.property && !isMark) {
                    ivis.bindProperty(ivis.activeMark, item.property, true);
                    d3.selectAll('#' + item.property + '.property').classed('drophover', false);
                  } else if(item.connector && isMark) {
                    ivis.addMark(ivis.activeMark, item.connector);
                  }
                }

                mouseup();
              break;
            }
          });
        }
      });

      ivis.show('selected');
    });

    return spec;
  };

  ivis.bindProperty = function(visual, property, defaults) {
    if(!ivis.dragging) return;

    var rootScope = ivis.ngScope();
    var field = $(ivis.dragging).data('field') || $(ivis.dragging).find('.schema').data('field') || $(ivis.dragging).find('.schema').attr('field');
    var scale = $(ivis.dragging).find('.scale').attr('scale');
    var pipelineName = rootScope.activePipeline.name;

    if(visual.pipelineName && pipelineName != visual.pipelineName)
      return alert('Pipelines don\'t match');

    rootScope.$apply(function() {
      if(!visual.pipelineName && !(visual instanceof vde.Vis.Transform)) visual.pipelineName = pipelineName;

      visual.bindProperty(property,
        {field: field, scaleName: scale, pipelineName: pipelineName}, defaults);
    });

    vde.Vis.parse();

    window.setTimeout(function() {
      $('.proxy').remove();
      ivis.dragging = null;

      ivis.ngLogger().log('bind', {
        item: visual.name,
        group: visual.groupName,
        activePipeline: rootScope.activePipeline.name,
        itemPipeline: visual.pipelineName,
        property: property,
        scaleName: scale,
        field: field
      }, true, true);

      rootScope.$apply(function() { rootScope.toggleVisual(visual); });
    }, 1);

    window.clearTimeout(vde.iVis.timeout);
  };

  ivis.addMark = function(host, connector) {
    var mark = ivis.newMark,
        rootScope = ivis.ngScope();

    if(host instanceof vde.Vis.marks.Group) mark.groupName = host.name;
    else if(host.connectors[connector]) {
      mark.groupName    = host.groupName;
      mark.connectedTo  = {host: host, connector: connector};
    }

    rootScope.$apply(function() {
      mark.init();
      vde.Vis.parse();
    });

    window.setTimeout(function() {
      ivis.newMark = null;
      $('.proxy').remove();

      ivis.ngLogger().log('new_mark', {
        markType: mark.type,
        markName: mark.name,
        activeGroup: (rootScope.activeGroup || {}).name,
        markGroup: mark.groupName
      }, true);

      rootScope.$apply(function() { rootScope.toggleVisual(mark); });
    }, 1);

    window.clearTimeout(vde.iVis.timeout);
  };

  ivis.handle = function() {
    return {
      name: 'handle',
      type: 'symbol',
      from: {data: 'handle'},
      properties: {
        enter: {
          shape: {value: 'square'},
          size: {value: 40},
          fill: {scale: 'disabled', field: 'data.disabled'},
          stroke: {value: 'black'},
          strokeWidth: {value: 0.5}
        },
        update: {
          x: {field: 'data.x'},
          y: {field: 'data.y'},
          connector: {field: 'data.connector'}
        }
      }
    }
  };

  ivis.connector = function() {
    return {
      name: 'connector',
      type: 'symbol',
      from: {
        data: 'connector',
        transform: [{
          type: 'formula',
          field: 'status',
          expr: '(d.data.connected) ? 1 : 0'
        }]
      },
      properties: {
        enter: {
          shape: {value: 'diamond'},
          size: {value: 40},
          fill: {value: 'white'}
        },
        update: {
          x: {field: 'data.x'},
          y: {field: 'data.y'},
          stroke: {scale: 'connection_status', field: 'status'},
          strokeWidth: {value: 0.5},
          connector: {field: 'data.connector'}
        },
        hover: {
          stroke: {value: 'lime'},
          strokeWidth: {value: 1}
        }
      }
    }
  };

  ivis.connection = function() {
    return {
      name: 'connection_group',
      type: 'group',
      from: {
        data: 'connection',
        transform: [{type: 'facet', keys:['data.span']}]
      },
      marks: [{
        name: 'connection',
        type: 'line',
        properties: {
          update: {
            x: {field: 'data.x'},
            y: {field: 'data.y'},
            stroke: {value: 'black'},
            strokeWidth: {value: 0.5},
            strokeDash: {value: [5, 5]}
          }
        }
      }]
    }
  };

  ivis.point = function() {
    return {
      name: 'point',
      type: 'symbol',
      from: {data: 'point'},
      properties: {
        enter: {
          shape: {value: 'circle'},
        },
        update: {
          x: {field: 'data.x'},
          y: {field: 'data.y'},
          fill: {value: 'cyan'},
          size: {value: 40},
          connector: {field: 'data.connector'}
        },
        hover: {
          size: {value: 80},
          fill: {value: 'lightsalmon'}
        }
      }
    };
  };

  ivis.span = function() {
    return {
      name: 'span_group',
      type: 'group',
      from: {
        data: 'span',
        transform: [{type: 'facet', keys:['data.span']}]
      },
      marks: [{
        name: 'span',
        type: 'line',
        properties: {
          update: {
            x: {field: 'data.x'},
            y: {field: 'data.y'},
            stroke: {value: 'cyan'},
            strokeWidth: {value: 1},
            span: {field: 'data.span'}
          },
          hover: {
            stroke: {value: 'lightsalmon'},
            strokeWidth: {value: 3}
          }
        }
      }]
    }
  };

  ivis.dropzone = function() {
    return {
      name: 'dropzone',
      type: 'rect',
      from: {data: 'dropzone'},
      properties: {
        enter: {
          fillOpacity: {value: 0},
          // stroke: {value: 'black'},
          // strokeDash: {value: [0.3, 1]}
        },
        update: {
          x: {field: 'data.x'},
          y: {field: 'data.y'},
          x2: {field: 'data.x2'},
          y2: {field: 'data.y2'},
          property: {field: 'data.property'},
          connector: {field: 'data.connector'}
        }
      }
    }
  };

  // From vg.canvas.Renderer
  ivis.translatedBounds = function(item, bounds) {
    var b = new vg.Bounds(bounds);
    while ((item = item.mark.group) != null) {
      b.translate(item.x || 0, item.y || 0);
    }
    return b;
  };

  ivis.ngScope = function() {
    return $('html').injector().get('$rootScope')
  };

  ivis.ngLogger = function() {
    return $('html').injector().get('logger');
  };

  return ivis;
})();
<|endoftext|>


<commit_before>/*global MfiaClient, $*/

window = this;

window.MfiaClient = {
  Models: {},
  Collections: {},
  Views: {},
  Routers: {},
  Regions: {},
  init: function () {

    //API Endpoint
    MfiaClient.API = "https://metrofutureapi.mapc.org/"

    //intitialize Marionette app
    this.app = new Marionette.Application();

    //add regions for full layout
    this.app.addRegions({
      navRegion: '#header',
      mainRegion: '#main',
      footerRegion: '#footer',
      aboutRegion: '#about',
      mapRegion: '#map'
    });

    //this logic needs to be moved somewhere else
    //pull in menu data & demux
    var that = this;
    var options = [];
    var municipalities = new MfiaClient.Collections.Municipalities();

    //fetch data for dropdown, render HEADER
    municipalities.fetch({
      'success': function (municipalities_response) {

        _.map(municipalities.toJSON(), function (option) {
          options.push(option);
        });

        var subregions = new MfiaClient.Collections.Subregions();
        subregions.fetch({
          'success': function (subregions_response) {

            Backbone.history.start();
            //the map depends on this data so it's initialized in the fetch callbacks of both muni and subr
            that.app.getRegion('mapRegion').show(new that.Views.Map({ municipalities: municipalities_response, subregions: subregions_response }));

            _.map(subregions.toJSON(), function (option) {
              options.push(option);
            });

            that.app.getRegion('navRegion').show(new that.Views.Header({ model: options, }));
          }
        });
      }
    });

    // render footer
    that.app.getRegion('footerRegion').show(new that.Views.Footer());

    MfiaClient.Routers.Project = new this.Routers.Project();
    this.app.execute("setRouter", MfiaClient.Routers.Project);
    MfiaClient.Routers.Project.on("route", function () {
      $('html, body').animate({ scrollTop: 0 }, 'slow');
      that.app.trigger("routed");
    });

    // render about
    that.app.getRegion('aboutRegion').show(new that.Views.About());

    MfiaClient.app.on("loading", function () {
      $(".loading").show();
    });
    MfiaClient.app.on("loaded", function () {
      $(".loading").hide();
    });
  }
};

$(document).ready(function () {
  MfiaClient.init();
});

<commit_msg>Move jquery to top of file<commit_after>/*global MfiaClient, $*/
$(document).ready(function () {
  MfiaClient.init();
});

window = this;

window.MfiaClient = {
  Models: {},
  Collections: {},
  Views: {},
  Routers: {},
  Regions: {},
  init: function () {

    //API Endpoint
    MfiaClient.API = "https://metrofutureapi.mapc.org/"

    //intitialize Marionette app
    this.app = new Marionette.Application();

    //add regions for full layout
    this.app.addRegions({
      navRegion: '#header',
      mainRegion: '#main',
      footerRegion: '#footer',
      aboutRegion: '#about',
      mapRegion: '#map'
    });

    //this logic needs to be moved somewhere else
    //pull in menu data & demux
    var that = this;
    var options = [];
    var municipalities = new MfiaClient.Collections.Municipalities();

    //fetch data for dropdown, render HEADER
    municipalities.fetch({
      'success': function (municipalities_response) {

        _.map(municipalities.toJSON(), function (option) {
          options.push(option);
        });

        var subregions = new MfiaClient.Collections.Subregions();
        subregions.fetch({
          'success': function (subregions_response) {

            Backbone.history.start();
            //the map depends on this data so it's initialized in the fetch callbacks of both muni and subr
            that.app.getRegion('mapRegion').show(new that.Views.Map({ municipalities: municipalities_response, subregions: subregions_response }));

            _.map(subregions.toJSON(), function (option) {
              options.push(option);
            });

            that.app.getRegion('navRegion').show(new that.Views.Header({ model: options, }));
          }
        });
      }
    });

    // render footer
    that.app.getRegion('footerRegion').show(new that.Views.Footer());

    MfiaClient.Routers.Project = new this.Routers.Project();
    this.app.execute("setRouter", MfiaClient.Routers.Project);
    MfiaClient.Routers.Project.on("route", function () {
      $('html, body').animate({ scrollTop: 0 }, 'slow');
      that.app.trigger("routed");
    });

    // render about
    that.app.getRegion('aboutRegion').show(new that.Views.About());

    MfiaClient.app.on("loading", function () {
      $(".loading").show();
    });
    MfiaClient.app.on("loaded", function () {
      $(".loading").hide();
    });
  }
};

// $(document).ready(function () {
//   MfiaClient.init();
// });

<|endoftext|>


<commit_before>'use strict';

var gulp = require('gulp');

var browserSync = require('browser-sync');
var httpProxy = require('http-proxy');

/* This configuration allow you to configure browser sync to proxy your backend */
var proxyTarget = 'http://server/context/'; // The location of your backend

var proxy = httpProxy.createProxyServer({
  target: proxyTarget
});

/* proxyMiddleware forwards static files to BrowserSync server
   and forwards dynamic requests to your real backend */
function proxyMiddleware(req, res, next) {
  if (/\.(html|png|css|jpg|jpeg|gif|js|ico|xml|rss|txt)(\?(r|v|rel|rev)=[\-\.\w]*)?$/.test(req.url)) {
    next();
  } else {
    proxy.web(req, res);
  }
}

function browserSyncInit(baseDir, files, browser) {
  browser = browser === undefined ? 'default' : browser;

  browserSync.instance = browserSync.init(files, {
    startPath: '/index.html',
    server: {
      baseDir: baseDir,
      middleware: proxyMiddleware
    },
    browser: browser
  });

}

gulp.task('serve', ['watch'], function () {
  browserSyncInit([
    'app',
    '.tmp'
  ], [
    'app/*.html',
    '.tmp/styles/**/*.css',
    'app/scripts/**/*.js',
    'app/partials/**/*.html',
    'app/images/**/*'
  ]);
});

gulp.task('serve:dist', ['build'], function () {
  browserSyncInit('dist');
});

gulp.task('serve:e2e', function () {
  browserSyncInit(['app', '.tmp'], null, []);
});

gulp.task('serve:e2e-dist', ['watch'], function () {
  browserSyncInit('dist', null, []);
});
<commit_msg>Add font files into filter.<commit_after>'use strict';

var gulp = require('gulp');

var browserSync = require('browser-sync');
var httpProxy = require('http-proxy');

/* This configuration allow you to configure browser sync to proxy your backend */
var proxyTarget = 'http://server/context/'; // The location of your backend

var proxy = httpProxy.createProxyServer({
  target: proxyTarget
});

/* proxyMiddleware forwards static file requests to BrowserSync server
   and forwards dynamic requests to your real backend */
function proxyMiddleware(req, res, next) {
  if (/\.(html|css|js|png|jpg|jpeg|gif|ico|xml|rss|txt|eot|svg|ttf|woff)(\?((r|v|rel|rev)=[\-\.\w]*)?)?$/.test(req.url)) {
    next();
  } else {
    proxy.web(req, res);
  }
}

function browserSyncInit(baseDir, files, browser) {
  browser = browser === undefined ? 'default' : browser;

  browserSync.instance = browserSync.init(files, {
    startPath: '/index.html',
    server: {
      baseDir: baseDir,
      middleware: proxyMiddleware
    },
    browser: browser
  });

}

gulp.task('serve', ['watch'], function () {
  browserSyncInit([
    'app',
    '.tmp'
  ], [
    'app/*.html',
    '.tmp/styles/**/*.css',
    'app/scripts/**/*.js',
    'app/partials/**/*.html',
    'app/images/**/*'
  ]);
});

gulp.task('serve:dist', ['build'], function () {
  browserSyncInit('dist');
});

gulp.task('serve:e2e', function () {
  browserSyncInit(['app', '.tmp'], null, []);
});

gulp.task('serve:e2e-dist', ['watch'], function () {
  browserSyncInit('dist', null, []);
});
<|endoftext|>


<commit_before>/*
 * grunt-connector
 * https://github.com/trevorsheridan/connector
 *
 * Copyright (c) 2013 Trevor Sheridan
 * Licensed under the MIT license.
 */

'use strict';

module.exports = function(grunt) {
  var utility = require('../lib/utility');

  grunt.registerTask('connector', 'Prototyping server for the modern man.', function() {
    var express = require('express');
    var engines = require('consolidate');
    var application = express();

    var options = this.options({
      assets: process.cwd() + '/public',
      port: process.env.PORT || 3000,
      templates: process.cwd() + '/source/templates',
      templateEngine: 'hogan',
    });

    this.async();

    // Set the templating engine configuration.
    application.set('views', options.templates);
    application.set('view engine', 'html');
    application.engine('html', engines[options.templateEngine]);

    // Serve static assets from the public directory (falls back to this if development is on and recompiling less).
    application.use(express.static(options.assets));

    // Catch all other requests and route to the appropriate template.
    application.use(function(request, response) {
      var path = request._parsedUrl.pathname;
      var files = utility.listing(application.get('views'));
      var template = utility.find(files, path.split('/'), 'index') || 404;

      grunt.log.ok("Responding to " + path + " with template " + template + "".green);
      response.status(typeof template === 'number' ? template : 200).render(template);
    });

    application.listen(options.port);
    grunt.log.ok("Server listening for incoming connections on port " + options.port + "".green);
  });
};
<commit_msg>Moving process.cwd() outside of default options (need a better way to do this)<commit_after>/*
 * grunt-connector
 * https://github.com/trevorsheridan/connector
 *
 * Copyright (c) 2013 Trevor Sheridan
 * Licensed under the MIT license.
 */

'use strict';

module.exports = function(grunt) {
  var utility = require('../lib/utility');

  grunt.registerTask('connector', 'Prototyping server for the modern man.', function() {
    var express = require('express');
    var engines = require('consolidate');
    var application = express();

    var options = this.options({
      assets: '/public',
      port: process.env.PORT || 3000,
      templates: '/source/templates',
      templateEngine: 'hogan'
    });

    this.async();

    // Set the templating engine configuration.
    application.set('views', process.cwd() + '/' + options.templates);
    application.set('view engine', 'html');
    application.engine('html', engines[options.templateEngine]);

    // Serve static assets from the public directory (falls back to this if development is on and recompiling less).
    application.use(express.static(process.cwd() + '/' + options.assets));

    // Catch all other requests and route to the appropriate template.
    application.use(function(request, response) {
      var path = request._parsedUrl.pathname;
      var template = utility.find(utility.listing(application.get('views')), path.split('/'), 'index') || 404;

      grunt.log.ok("Responding to " + path + " with template " + template + "".green);
      response.status(typeof template === 'number' ? template : 200).render(template);
    });

    application.listen(options.port);
    grunt.log.ok("Server listening for incoming connections on port " + options.port + "".green);
  });
};
<|endoftext|>


<commit_before>moduleUdc.controller('usersController', ['$scope', 'apiService', function ($scope, apiService) {

  $scope.userTypeSelected = 'Todos los usuarios';
  $scope.users = [];
  $scope.emailExists = false;
  $scope.validEmail = false;

  $scope.newUser = {};

  $scope.loadUsers = function () {
    $scope.loading = true;
    var roleType = $scope.userTypeSelected === 'Todos los usuarios' ? null : $scope.userTypeSelected.toUpperCase();
    apiService.users.getAll(roleType).$promise.then(function (data) {
      $scope.users = data;
      $scope.loading = false;
    });
  };

  $scope.loadUsers();

  $scope.saveUser = function () {
    if ($scope.validEmail) {
      apiService.users.add($scope.newUser);
      $('#addNewUserModal').closeModal();
      $scope.loadUsers();
      $scope.newUser = {};
    } else {
      Materialize.toast('El correo electrónico es invalido.', 2000);
    }
  };

  $scope.validateEmail = function () {
    var re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
    if (re.test($scope.newUser.email)) {
      apiService.users.getByEmail($scope.newUser.email).then(function (data) {
        $scope.emailExists = true;
        $scope.validEmail = false;
      }, function (error) {
        if (error.status === 404) {
          $scope.emailExists = false;
          $scope.validEmail = true;
        }
      });
    }
  };

}]);<commit_msg>Now add user to user interface<commit_after>moduleUdc.controller('usersController', ['$scope', 'apiService', function ($scope, apiService) {

  $scope.userTypeSelected = 'Todos los usuarios';
  $scope.users = [];
  $scope.emailExists = false;
  $scope.validEmail = false;

  $scope.newUser = {};

  $scope.loadUsers = function () {
    $scope.loading = true;
    var roleType = $scope.userTypeSelected === 'Todos los usuarios' ? null : $scope.userTypeSelected.toUpperCase();
    apiService.users.getAll(roleType).$promise.then(function (data) {
      $scope.users = data;
      $scope.loading = false;
    });
  };

  $scope.loadUsers();

  $scope.saveUser = function () {
    if ($scope.validEmail) {
      apiService.users.add($scope.newUser).$promise.then(function (data) {
        console.log(data);
        $scope.users.push(data);
      }, function (error) {
        console.log(error);
      });
      $('#addNewUserModal').closeModal();
      $scope.newUser = {};
    } else {
      Materialize.toast('El correo electrónico es invalido.', 2000);
    }
  };

  $scope.validateEmail = function () {
    var re = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
    if (re.test($scope.newUser.email)) {
      apiService.users.getByEmail($scope.newUser.email).then(function (data) {
        $scope.emailExists = true;
        $scope.validEmail = false;
      }, function (error) {
        if (error.status === 404) {
          $scope.emailExists = false;
          $scope.validEmail = true;
        }
      });
    }
  };

}]);<|endoftext|>


<commit_before>//db.js
//Communicates with the Mongo database

var exports = module.exports = {};

var parse = require("app/shiftswap/parse"),
schema = require("app/shiftswap/schema"),
serverConfig = require('app/_config/server.json')
;

var model = schema.model;

exports.schedule = {
    find: (start, end, get, callback)=>{
        get   = get || {};
        start = parse.date.unix(start);
        end   = parse.date.unix(end  );

        //default start to today
        if(!start){

        }

        //default end to 7 days
        if(!end){
            end = -7;
        }

        //negative values are x days forward.
        if(end < 0){
            var secondsInDay = 60 * 60 * 24;
            end = Number(start) + Number(secondsInDay*Math.abs(end));
            end = String(end);
        }

        query = {$and: [
            {'date.unix': {$gte: start}},
            {'date.unix': {$lte: end}},
            get,
        ]};

        console.log(JSON.stringify(query));

        model.Schedule.find(query, function(err, data){
            console.log(data, callback);
            if(callback){
                callback(err, data);
            }
        });
    },
    getFloor:   (start, end, callback)=>     { getAll(start, end, {access: 'f'}, callback) },
    getManager: (start, end, callback)=>     { getAll(start, end, {access: 'm'}, callback) },
    getByUID:   (start, end, uid, callback)=>{ getAll(start, end, {uid: uid   }, callback) },
    insert: (data,callback)=>{
        new model.Schedule(data).save(()=>{
            if(callback)
                callback();
        });
    },
    replaceSection: (uid, data, callback)=>{
        if(!Array.isArray(data)){
            if(typeof data === 'object'){
                data = [data];
            }else{
                return console.error('Data must be of type array');
            }
        }

        /*** 1. Get timespan ***/
        var low = Infinity;
        var high = -Infinity;

        for(var i=data.length; i--;){
            data[i].date = parse.date.convertToRaw(data[i].date);

            if(data[i].date.unix < low){
                low = data[i].date.unix;
            }

            if(data[i].date.unix > high){
                high = data[i].date.unix;
            }
        }

        /*** 2. Delete data within timespan ***/
        var query = { $and: [
            {'date.unix': {$gte: low}},
            {'date.unix': {$lte: high}},
            {'uid': uid},
        ]};

        model.Schedule.find(query).remove(insert);

        /*** 3. Insert **/
        function insert(){
            new model.Schedule(data).save(()=>{
                if(callback)
                    callback();
            });
        }
    },
};
exports.users = {
    getUser: (query, callback)=>{
        query = query || {};
        model.User.find(query, (err, users)=>callback(err,users) );
    },
    getManagers: (callback)=>{

    },
    getFloor: (callback)=>{

    },
    getByPersonNum:(get, callback)=>{ exports.users.getUser({'personNum': get}, callback)},
    getByBadge:    (get, callback)=>{ exports.users.getUser({    'badge': get}, callback)},
    getByUID:      (get, callback)=>{ exports.users.getUser({      'uid': get}, callback)},
    getByPhone:    (get, callback)=>{ exports.users.getUser({    'phone': get}, callback)},
    getByEmail:    (get, callback)=>{ exports.users.getUser({    'email': get}, callback)},
    getAll:        (callback     )=>{ exports.users.getUser({}                , callback)},
    insert: (data,callback)=>{
        new model.User(data).save(()=>{
            if(callback)
                callback();
        });
    }
};
exports.userPrivate = {
    getByUID: (get, callback)=>{
        model.UserPrivate.find({'uid': get}, (err, docs)=>callback(err,docs) );
    },
};
exports.trades = {
    getTrade: (query, callback)=>{
        query = query || {};
        model.Trade.find(query, (err, docs)=>callback(err,docs) );
    },
    getSinceTime:    (get, callback)=>{ exports.trades.getTrade({'date.unix':  get}, callback)},
    getByUID:        (get, callback)=>{ exports.trades.getTrade({      'uid':  get}, callback)},
    getForTrade:     (callback     )=>{ exports.trades.getTrade({    'state':  1  }, callback)},
    getForApproval:  (callback     )=>{ exports.trades.getTrade({    'state':  2  }, callback)},
    getComplete:     (callback     )=>{ exports.trades.getTrade({    'state':  3  }, callback)},
    getIncomplete:   (callback     )=>{ exports.trades.getTrade({    'state': -1  }, callback)},
    getLastApproval: (callback     )=>{ exports.trades.getTrade({
        'state': 3,
        'date.unix': -3
    }, callback)},
};
exports.history = {
    get: (query, callback)=>{
        query = query || {};
        model.History.find(query, (err, docs)=>callback(err,docs) );
    },
};
exports.rewards = (callback)=>{

};
exports.site = (callback)=>{

};

var private = {

};
<commit_msg>fixed schedule insert<commit_after>//db.js
//Communicates with the Mongo database

var exports = module.exports = {};

var parse = require("app/shiftswap/parse"),
_         = require("lodash"),
schema = require("app/shiftswap/schema"),
serverConfig = require('app/_config/server.json')
;

var model = schema.model;

exports.schedule = {
    find: (start, end, get, callback)=>{
        get   = get || {};
        start = parse.date.unix(start);
        end   = parse.date.unix(end  );

        //default start to today
        if(!start){

        }

        //default end to 7 days
        if(!end){
            end = -7;
        }

        //negative values are x days forward.
        if(end < 0){
            var secondsInDay = 60 * 60 * 24;
            end = Number(start) + Number(secondsInDay*Math.abs(end));
            end = Number(end);
        }

        query = { $and: [
            {'date.unix': {$gte: start, $lte: end}},
            get,
        ]};

        console.log(JSON.stringify(query));

        model.Schedule.find(query, function(err, data){
            console.log(data, callback);
            if(callback){
                callback(err, data);
            }
        });
    },
    getFloor:   (start, end, callback)=>     { getAll(start, end, {access: 'f'}, callback) },
    getManager: (start, end, callback)=>     { getAll(start, end, {access: 'm'}, callback) },
    getByUID:   (start, end, uid, callback)=>{ getAll(start, end, {uid: uid   }, callback) },
    insert: (datas,callback)=>{
        var errors = [];

        if(!Array.isArray(datas)){
            datas = [datas];
        }
        for(var i=datas.length; i--;){
            var data = datas[i];
            console.log(data);

            if(!data.time || !data.uid || !data.date || !data.access)
                return callback('Body must include uid, date, access, and time.');
            if(!Array.isArray(data.time))
                return callback('time must be an array');
            if(typeof data.uid != 'number' && typeof data.uid != 'string')
                return callback('uid must be a number');
            if(data.detail && typeof data.uid != 'string')
                return callback('detail must be a string');
            if(data.access != 'm' && data.access != 'f')
                return callback('access must be a string either m or f, for manager and floor');

            datas[i].date = parse.date.convertToRaw(data.date);
            datas[i].uid = Number(data.uid);

            var time = [];
            datas[i].time.forEach(function(stamp){
                time.push(parse.time(stamp));
            });
            datas[i].time = _.sortBy(time, a=>a);

            if(datas[i].time.length % 2 === 1)
                return callback('time must contain an even number of timestamps');

            model.Schedule.findOne({'date':data.date}, function(err, docs){
                if(!docs){
                    new model.Schedule(data).save((err, docs)=>{
                        if(err)
                            errors.push(err);
                    });
                }else{
                    errors.push('schedule already exists for this day: '+ data.date.human);
                }
            });

        }//end for

        console.log(errors);
        return callback(errors.join('\r\n'));

    },
    replaceSection: (uid, data, callback)=>{
        if(!Array.isArray(data)){
            if(typeof data === 'object'){
                data = [data];
            }else{
                return console.error('Data must be of type array');
            }
        }

        /*** 1. Get timespan ***/
        var low = Infinity;
        var high = -Infinity;

        for(var i=data.length; i--;){
            data[i].date = parse.date.convertToRaw(data[i].date);

            if(data[i].date.unix < low){
                low = data[i].date.unix;
            }

            if(data[i].date.unix > high){
                high = data[i].date.unix;
            }
        }

        /*** 2. Delete data within timespan ***/
        /*var query = { $and: [
            {'date.unix': {$gte: low}},
            {'date.unix': {$lte: high}},
            {'uid': uid},
        ]};*/
        var query = { $and: [
            {'date.unix': {$gte: low, $lte: high}},
            {'uid': uid},
        ]};

        model.Schedule.find(query).remove(insert);

        /*** 3. Insert **/
        function insert(){
            new model.Schedule(data).save(()=>{
                if(callback)
                    callback();
            });
        }
    },
};
exports.users = {
    getUser: (query, callback)=>{
        query = query || {};
        model.User.find(query, (err, users)=>callback(err,users) );
    },
    getManagers: (callback)=>{

    },
    getFloor: (callback)=>{

    },
    getByPersonNum:(get, callback)=>{ exports.users.getUser({'personNum': get}, callback)},
    getByBadge:    (get, callback)=>{ exports.users.getUser({    'badge': get}, callback)},
    getByUID:      (get, callback)=>{ exports.users.getUser({      'uid': get}, callback)},
    getByPhone:    (get, callback)=>{ exports.users.getUser({    'phone': get}, callback)},
    getByEmail:    (get, callback)=>{ exports.users.getUser({    'email': get}, callback)},
    getAll:        (callback     )=>{ exports.users.getUser({}                , callback)},
    insert: (data,callback)=>{
        new model.User(data).save(()=>{
            if(callback)
                callback();
        });
    }
};
exports.userPrivate = {
    getByUID: (get, callback)=>{
        model.UserPrivate.find({'uid': get}, (err, docs)=>callback(err,docs) );
    },
};
exports.trades = {
    getTrade: (query, callback)=>{
        query = query || {};
        model.Trade.find(query, (err, docs)=>callback(err,docs) );
    },
    getSinceTime:    (get, callback)=>{ exports.trades.getTrade({'date.unix':  get}, callback)},
    getByUID:        (get, callback)=>{ exports.trades.getTrade({      'uid':  get}, callback)},
    getForTrade:     (callback     )=>{ exports.trades.getTrade({    'state':  1  }, callback)},
    getForApproval:  (callback     )=>{ exports.trades.getTrade({    'state':  2  }, callback)},
    getComplete:     (callback     )=>{ exports.trades.getTrade({    'state':  3  }, callback)},
    getIncomplete:   (callback     )=>{ exports.trades.getTrade({    'state': -1  }, callback)},
    getLastApproval: (callback     )=>{ exports.trades.getTrade({
        'state': 3,
        'date.unix': -3
    }, callback)},
};
exports.history = {
    get: (query, callback)=>{
        query = query || {};
        model.History.find(query, (err, docs)=>callback(err,docs) );
    },
};
exports.rewards = (callback)=>{

};
exports.site = (callback)=>{

};

var private = {

};
<|endoftext|>


<commit_before>const electron = require('electron');
// Module to control application life.
const app = electron.app;
// Module to create native browser window.
const BrowserWindow = electron.BrowserWindow;

const path = require('path');
const url = require('url');

const {
  default: installExtension,
  REACT_DEVELOPER_TOOLS,
  REDUX_DEVTOOLS,
} = require('electron-devtools-installer');

// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let mainWindow;

console.time('startup');

/** This function will create the mainWindow */
function createWindow() {
  // Create the browser window.
  mainWindow = new BrowserWindow({ width: 1024, height: 768, show: false });

  if (process.env.NODE_ENV === 'development') {
    // Open the DevTools.
    mainWindow.webContents.openDevTools();

    installExtension(REACT_DEVELOPER_TOOLS)
      .then(name => console.log(`Added Extension:  ${name}`))
      .catch(err => console.log('An error occurred: ', err));

    installExtension(REDUX_DEVTOOLS)
      .then(name => console.log(`Added Extension:  ${name}`))
      .catch(err => console.log('An error occurred: ', err));

		// make sure to load the index from the hot reload server while in development mode
		mainWindow.loadURL('http://localhost:8080');
  } else {
		// we should be in production
		// load the index.html of the app.
  	mainWindow.loadURL(url.format({
    	pathname: path.join(__dirname, 'index.html'),
    	protocol: 'file:',
    	slashes: true,
  	}));
	}

  // just show the window if all content has been loaded
  mainWindow.on('ready-to-show', () => {
    mainWindow.show();
    mainWindow.focus();

    // measure startup time
    console.timeEnd('startup');
  });

  // Emitted when the window is closed.
  mainWindow.on('closed', () => {
  // Dereference the window object, usually you would store windows
  // in an array if your app supports multi windows, this is the time
  // when you should delete the corresponding element.
    mainWindow = null;
  });
}

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.on('ready', createWindow);

// Quit when all windows are closed.
app.on('window-all-closed', () => {
  // On OS X it is common for applications and their menu bar
  // to stay active until the user quits explicitly with Cmd + Q
  if (process.platform !== 'darwin') {
    app.quit();
  }
});

app.on('activate', () => {
  // On OS X it's common to re-create a window in the app when the
  // dock icon is clicked and there are no other windows open.
  if (mainWindow === null) {
    createWindow();
  }
});

// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and require them here.
<commit_msg>Fixed app.js linting errors<commit_after>const electron = require('electron');
// Module to control application life.
const app = electron.app;
// Module to create native browser window.
const BrowserWindow = electron.BrowserWindow;

const path = require('path');
const url = require('url');

const {
  default: installExtension,
  REACT_DEVELOPER_TOOLS,
  REDUX_DEVTOOLS,
} = require('electron-devtools-installer');

// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let mainWindow;

console.time('startup');

/** This function will create the mainWindow */
function createWindow() {
  // Create the browser window.
  mainWindow = new BrowserWindow({
    width: 1024,
    height: 768,
    show: false,
  });

  if (process.env.NODE_ENV === 'development') {
    // Open the DevTools.
    mainWindow.webContents.openDevTools();

    installExtension(REACT_DEVELOPER_TOOLS)
      .then(name => console.log(`Added Extension:  ${name}`))
      .catch(err => console.log('An error occurred: ', err));

    installExtension(REDUX_DEVTOOLS)
      .then(name => console.log(`Added Extension:  ${name}`))
      .catch(err => console.log('An error occurred: ', err));

    // make sure to load the index from the hot reload server while in development mode
    mainWindow.loadURL('http://localhost:8080');
  } else {
    // we should be in production
    // load the index.html of the app.
    mainWindow.loadURL(url.format({
      pathname: path.join(__dirname, 'index.html'),
      protocol: 'file:',
      slashes: true,
    }));
  }

  // just show the window if all content has been loaded
  mainWindow.on('ready-to-show', () => {
    mainWindow.show();
    mainWindow.focus();

    // measure startup time
    console.timeEnd('startup');
  });

  // Emitted when the window is closed.
  mainWindow.on('closed', () => {
    // Dereference the window object, usually you would store windows
    // in an array if your app supports multi windows, this is the time
    // when you should delete the corresponding element.
    mainWindow = null;
  });
}

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.on('ready', createWindow);

// Quit when all windows are closed.
app.on('window-all-closed', () => {
  // On OS X it is common for applications and their menu bar
  // to stay active until the user quits explicitly with Cmd + Q
  if (process.platform !== 'darwin') {
    app.quit();
  }
});

app.on('activate', () => {
  // On OS X it's common to re-create a window in the app when the
  // dock icon is clicked and there are no other windows open.
  if (mainWindow === null) {
    createWindow();
  }
});

// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and require them here.
<|endoftext|>


<commit_before>'use strict';

var gulp = require('gulp'),
    config = require('../../config'),
    plumber = require('gulp-plumber'),
    sourcemap = require('gulp-sourcemaps'),
    sass = require('gulp-sass'),
    normalize = require('node-normalize-scss').includePaths,
    bourbon = require('node-bourbon').includePaths,
    neat = require('node-neat').includePaths,
    postcss = require('gulp-postcss'),
    bulksass = require('gulp-sass-bulk-import'),
    mqpacker = require('css-mqpacker'),
    autoprefix = require('autoprefixer'),
    pxtorem = require('postcss-pxtorem'),
    cssnano = require('cssnano'),
    banner = require('postcss-banner'),
    notify = require('gulp-notify');

module.exports = function() {
    var key,
        postProcessors,
        themeHeader = '',
        themeHeaderArr = {
            // 'Header Name': 'Key under config.theme',
            'Theme Name': 'name',
            'Theme URI': 'themeuri',
            Author: 'author',
            'Author URI': 'authoruri',
            Description: 'description',
            Version: 'version',
            Status: 'status',
            License: 'license',
            'License URI': 'licenseuri',
            Tags: 'tags',
            'Text Domain': 'textdomain',
            'Domain Path': 'domainpath',
            Template: 'template'
        };

    // Loop through above object properties.
    for ( key in themeHeaderArr ) {
        // If a value has been set in config.theme.???, ...
        if ( config.theme[themeHeaderArr[key]] ) {
            // Then build the file header for it.
            themeHeader += key + ': ' + config.theme[themeHeaderArr[key]]+ '\n';
        }
    }

    // Remove final new line character.
    themeHeader = themeHeader.slice(0, -1);

    postProcessors = [
        mqpacker({
            sort: true
        }),
        autoprefix(),
        pxtorem({
            root_value: 16,
            replace: false,
            media_query: true
        }),
        cssnano(),
        banner({
            banner: themeHeader
        })
    ];

    // Don't minify if expanded CSS is desired.
    if ( 'expanded' === config.css.outputStyle ) {
        postProcessors.splice(3, 1); // 3, as cssnano() is the 3rd item in the zero-based array above.
    }

    return gulp
        .src(config.src.scss)
        .pipe(bulksass)
        .pipe(plumber())
        .pipe(sourcemap.init())
        .pipe(sass.sync({
            outputStyle: config.css.outputStyle,
            includePaths: [].concat(bourbon, neat, normalize)
        }))
        .pipe(postcss(postProcessors))
        .pipe(sourcemap.write('.'))
        .pipe(gulp.dest(config.dest.css))
        .pipe(notify({message: config.messages.css}));
};
<commit_msg>Error in css build file.<commit_after>'use strict';

var gulp = require('gulp'),
    config = require('../../config'),
    plumber = require('gulp-plumber'),
    sourcemap = require('gulp-sourcemaps'),
    sass = require('gulp-sass'),
    normalize = require('node-normalize-scss').includePaths,
    bourbon = require('node-bourbon').includePaths,
    neat = require('node-neat').includePaths,
    postcss = require('gulp-postcss'),
    bulksass = require('gulp-sass-bulk-import'),
    mqpacker = require('css-mqpacker'),
    autoprefix = require('autoprefixer'),
    pxtorem = require('postcss-pxtorem'),
    cssnano = require('cssnano'),
    banner = require('postcss-banner'),
    notify = require('gulp-notify');

module.exports = function() {
    var key,
        postProcessors,
        themeHeader = '',
        themeHeaderArr = {
            // 'Header Name': 'Key under config.theme',
            'Theme Name': 'name',
            'Theme URI': 'themeuri',
            Author: 'author',
            'Author URI': 'authoruri',
            Description: 'description',
            Version: 'version',
            Status: 'status',
            License: 'license',
            'License URI': 'licenseuri',
            Tags: 'tags',
            'Text Domain': 'textdomain',
            'Domain Path': 'domainpath',
            Template: 'template'
        };

    // Loop through above object properties.
    for ( key in themeHeaderArr ) {
        // If a value has been set in config.theme.???, ...
        if ( config.theme[themeHeaderArr[key]] ) {
            // Then build the file header for it.
            themeHeader += key + ': ' + config.theme[themeHeaderArr[key]]+ '\n';
        }
    }

    // Remove final new line character.
    themeHeader = themeHeader.slice(0, -1);

    postProcessors = [
        mqpacker({
            sort: true
        }),
        autoprefix(),
        pxtorem({
            root_value: 16,
            replace: false,
            media_query: true
        }),
        cssnano(),
        banner({
            banner: themeHeader
        })
    ];

    // Don't minify if expanded CSS is desired.
    if ( 'expanded' === config.css.outputStyle ) {
        postProcessors.splice(3, 1); // 3, as cssnano() is the 3rd item in the zero-based array above.
    }

    return gulp
        .src(config.src.scss)
        .pipe(bulksass())
        .pipe(plumber())
        .pipe(sourcemap.init())
        .pipe(sass.sync({
            outputStyle: config.css.outputStyle,
            includePaths: [].concat(bourbon, neat, normalize)
        }))
        .pipe(postcss(postProcessors))
        .pipe(sourcemap.write('.'))
        .pipe(gulp.dest(config.dest.css))
        .pipe(notify({message: config.messages.css}));
};
<|endoftext|>


<commit_before>var redis = require('redis');

// ### Errors ###

function RedisConnectionError(error) {
	this.name = 'RedisConnectionError';
	this.message = error;
}
util.inherits(RedisConnectionError, Error);

function RedisAdapter() {
	this.client = redis.createClient();
}

RedisAdapter.prototype.connect = function () {
	var self = this;

	return function (req, res, next) {
		self.client.on('error', function (error) {
			throw new RedisConnectionError(error);
		});
		next();
	};
};

module.exports.RedisAdapter = RedisAdapter;<commit_msg>Add util require.<commit_after>var redis = require('redis');
var util = require('util');

// ### Errors ###

function RedisConnectionError(error) {
	this.name = 'RedisConnectionError';
	this.message = error;
}
util.inherits(RedisConnectionError, Error);

function RedisAdapter() {
	this.client = redis.createClient();
}

RedisAdapter.prototype.connect = function () {
	var self = this;

	return function (req, res, next) {
		self.client.on('error', function (error) {
			throw new RedisConnectionError(error);
		});
		next();
	};
};

module.exports.RedisAdapter = RedisAdapter;<|endoftext|>