<commit_before>$(document).ready(function() {
  bindArrows($("#reorder-posts-table"), '/api/v1/posts/reorder', 'post_ids');
});

// orderBox is the box the ordering is scoped to
// so that a single page can have multiple separate ordering structures
function bindArrows(orderBox, path, param) {
  $(".section-up", orderBox).click(function() {
    var sourceRow = $(this).closest('.section-ordered');
    var targetRow = sourceRow.prev('.section-ordered');
    if (targetRow.length === 0) return false;
    moveRow(sourceRow, targetRow, orderBox, path, param);
    return false;
  }).addClass('pointer').removeClass('disabled-arrow');

  $(".section-down", orderBox).click(function() {
    var sourceRow = $(this).closest('.section-ordered');
    var targetRow = sourceRow.next('.section-ordered');
    if (targetRow.length === 0) return false;
    moveRow(sourceRow, targetRow, orderBox, path, param);
    return false;
  }).addClass('pointer').removeClass('disabled-arrow');

  $(".section-up", orderBox).first().addClass('disabled-arrow').removeClass('pointer');
  $(".section-down", orderBox).last().addClass('disabled-arrow').removeClass('pointer');
}

function unbindArrows(orderBox) {
  $(".section-down", orderBox).unbind().addClass('disabled-arrow').removeClass('pointer');
  $(".section-up", orderBox).unbind().addClass('disabled-arrow').removeClass('pointer');
}

function reorderRows(orderBox) {
  var arrowBox = $('tbody', orderBox);
  var rows = $('.section-ordered', orderBox);
  var ordered = rows.sort(function(a, b) { return $(a).data('order') > $(b).data('order') ? 1 : -1; }).appendTo(arrowBox);
  $("tr:even:not(.section-warning) td", orderBox).removeClass('even').addClass('odd');
  $("tr:odd:not(.section-warning) td", orderBox).removeClass('odd').addClass('even');
  return ordered;
}

function moveRow(sourceRow, targetRow, orderBox, path, param) {
  unbindArrows(orderBox);
  // Reduce race conditions by only allowing one update at a time
  $("#loading", orderBox).show();
  $("#saveconf", orderBox).stop(true, true).hide();

  var sourceOrder = sourceRow.data('order');
  var targetOrder = targetRow.data('order');
  sourceRow.data('order', targetOrder);
  targetRow.data('order', sourceOrder);

  var orderedRows = reorderRows(orderBox);

  var orderedIds = [];
  orderedRows.each(function() {
    orderedIds.push(parseInt($(this).data('id')));
  });
  var json = {};
  json['ordered_' + param] = orderedIds;
  if (window.gon && window.gon.section_id) json.section_id = window.gon.section_id;

  $.post(path, json, function(resp) {
    var rows = $('.section-ordered', orderBox);
    if (rows.length !== resp[param].length && $('.section-warning', orderBox).length === 0) {
      var warning = $("
").append($("").html('There are items missing from this list! Please reload.'));
      orderBox.prepend(warning);
    }
    $("#loading", orderBox).hide();
    $("#saveconf", orderBox).show().delay(2000).fadeOut();
    bindArrows(orderBox, path, param);
  }).fail(function(data) {
    $("#loading", orderBox).hide();
    $("#saveerror", orderBox).show();
    if ($('.section-warning', orderBox).length === 0) {
      var warning = $("
").append($("").html('There was an error saving your changes! Please reload.'));
      orderBox.prepend(warning);
    }
  });
}
<commit_msg>Reorder rows according to server response, add code comments<commit_after>$(document).ready(function() {
  bindArrows($("#reorder-posts-table"), '/api/v1/posts/reorder', 'post_ids');
});

// orderBox is the box the ordering is scoped to
// so that a single page can have multiple separate ordering structures
function bindArrows(orderBox, path, param) {
  $(".section-up", orderBox).click(function() {
    var sourceRow = $(this).closest('.section-ordered');
    var targetRow = sourceRow.prev('.section-ordered');
    if (targetRow.length === 0) return false;
    moveRow(sourceRow, targetRow, orderBox, path, param);
    return false;
  }).addClass('pointer').removeClass('disabled-arrow');

  $(".section-down", orderBox).click(function() {
    var sourceRow = $(this).closest('.section-ordered');
    var targetRow = sourceRow.next('.section-ordered');
    if (targetRow.length === 0) return false;
    moveRow(sourceRow, targetRow, orderBox, path, param);
    return false;
  }).addClass('pointer').removeClass('disabled-arrow');

  $(".section-up", orderBox).first().addClass('disabled-arrow').removeClass('pointer');
  $(".section-down", orderBox).last().addClass('disabled-arrow').removeClass('pointer');
}

function unbindArrows(orderBox) {
  $(".section-down", orderBox).unbind().addClass('disabled-arrow').removeClass('pointer');
  $(".section-up", orderBox).unbind().addClass('disabled-arrow').removeClass('pointer');
}

function reorderRows(orderBox) {
  var arrowBox = $('tbody', orderBox);
  var rows = $('.section-ordered', arrowBox);
  var ordered = rows.sort(function(a, b) { return $(a).data('order') > $(b).data('order') ? 1 : -1; }).appendTo(arrowBox);
  $("tr:even:not(.section-warning) td", orderBox).removeClass('even').addClass('odd');
  $("tr:odd:not(.section-warning) td", orderBox).removeClass('odd').addClass('even');
  return ordered;
}

function moveRow(sourceRow, targetRow, orderBox, path, param) {
  // Reduce race conditions by only allowing one update at a time
  unbindArrows(orderBox);
  $("#loading", orderBox).show();
  $("#saveconf", orderBox).stop(true, true).hide();

  // Switch the row order pre-emptively
  var sourceOrder = sourceRow.data('order');
  var targetOrder = targetRow.data('order');
  sourceRow.data('order', targetOrder);
  targetRow.data('order', sourceOrder);
  var orderedRows = reorderRows(orderBox);

  // Figure out the full desired order and send it to the server
  var orderedIds = [];
  orderedRows.each(function() {
    orderedIds.push(parseInt($(this).data('id')));
  });
  var json = {};
  json['ordered_' + param] = orderedIds;
  // and restrict to relevant section_id if given
  if (window.gon && window.gon.section_id) json.section_id = window.gon.section_id;

  $.post(path, json, function(resp) {
    // Check the list doesn't have new elements
    if (orderedRows.length !== resp[param].length && $('.section-warning', orderBox).length === 0) {
      var warning = $("
").append($("").html('There are items missing from this list! Please reload.'));
      orderBox.prepend(warning);
      console.log(resp.responseText);
    }

    // Set the full ordering according to the server response
    var returnedIds = resp[param];
    orderedRows.each(function() {
      var row = $(this);
      row.data('order', returnedIds.indexOf(row.data('id')));
    });
    reorderRows(orderBox);

    // Re-enable the buttons
    $("#loading", orderBox).hide();
    $("#saveconf", orderBox).show().delay(2000).fadeOut();
    bindArrows(orderBox, path, param);
  }).fail(function(resp) {
    // Display an error and debug to console
    $("#loading", orderBox).hide();
    $("#saveerror", orderBox).show();
    if ($('.section-warning', orderBox).length === 0) {
      var warning = $("
").append($("").html('There was an error saving your changes! Please reload.'));
      orderBox.prepend(warning);
      console.log(resp.responseText);
    }
  });
}
<|endoftext|>


<commit_before>// from http://bl.ocks.org/rkirsling/5001347#app.js

(function(){
  // set up SVG for D3
  var $win = $(window),
      width  = $win.width(),
      height = $win.height(),
      colors = d3.scale.category10();

  var svg = d3.select('.graph')
    .append('svg');

  // set up initial nodes and links
  //  - nodes are known by 'id', not by index in array.
  //  - links are always source < target; edge directions are set by 'left' and 'right'.
  var nodesById = {};
  var nodes = gon.topics.map(function(topic){
    var node = $.extend({}, topic);
    nodesById[node.id] = node;
    return node;
  });
  var links = gon.relationships.map(function(rel){
    return $.extend({}, rel, {
      source: nodesById[rel.parent_id],
      target: nodesById[rel.child_id],
      left: false,
      right: true
    });
  });

  // init D3 force layout
  var force = d3.layout.force()
      .nodes(nodes)
      .links(links)
      .size([width, height])
      .linkDistance(180)
      .charge(-500)
      .on('tick', tick);

  // define arrow markers for graph links
  svg.append('svg:defs').append('svg:marker')
      .attr('id', 'end-arrow')
      .attr('viewBox', '0 -5 10 10')
      .attr('refX', 6)
      .attr('markerWidth', 3)
      .attr('markerHeight', 3)
      .attr('orient', 'auto')
    .append('svg:path')
      .attr('d', 'M0,-5L10,0L0,5')
      .attr('fill', '#000');

  // handles to link and node element groups
  var path = svg.append('svg:g').selectAll('path'),
      circle = svg.append('svg:g').selectAll('g');

  // mouse event vars
  var selected_node = null;

  var NODE_RADIUS = 40;

  // update force layout (called automatically each iteration)
  function tick() {
    // draw directed edges with proper padding from node centers
    path.attr('d', function(d) {
      var deltaX = d.target.x - d.source.x,
          deltaY = d.target.y - d.source.y,
          dist = Math.sqrt(deltaX * deltaX + deltaY * deltaY),
          normX = deltaX / dist,
          normY = deltaY / dist,
          sourcePadding = NODE_RADIUS,
          targetPadding = NODE_RADIUS + 5,
          sourceX = d.source.x + (sourcePadding * normX),
          sourceY = d.source.y + (sourcePadding * normY),
          targetX = d.target.x - (targetPadding * normX),
          targetY = d.target.y - (targetPadding * normY);
      return 'M' + sourceX + ',' + sourceY + 'L' + targetX + ',' + targetY;
    });

    circle.attr('transform', function(d) {
      return 'translate(' + d.x + ',' + d.y + ')';
    });
  }

  // action to take on mouse click
  function onNodeClick(d) {
    d3.select(this).select('text').transition()
      .duration(750)
      .attr('x', 22)
      .style('fill', 'steelblue')
      .style('stroke', 'lightsteelblue')
      .style('stroke-width', '.5px')
      .style('font', '20px sans-serif');

    d3.select(this).select('circle').transition()
      .duration(750)
      .attr('r', NODE_RADIUS * 2)
      .style('fill', 'lightsteelblue');

    // select node
    selected_node = d;
    restart();
  }

  // path (link) group
  path = path.data(links);

  // add new links
  path.enter().append('svg:path')
    .attr('class', 'link')
    .style('marker-end', function(d) { return d.right ? 'url(#end-arrow)' : ''; });

  // circle (node) group
  // NB: the function arg is crucial here! nodes are known by id, not by index!
  circle = circle.data(nodes, function(d) { return d.id; });

  // add new nodes
  var g = circle.enter().append('svg:g');

  g.append('svg:circle')
    .attr('class', 'node')
    .attr('r', NODE_RADIUS)
    .style('fill', function(d) { return (d === selected_node) ? d3.rgb(colors(d.id)).brighter().toString() : colors(d.id); })
    .style('stroke', function(d) { return d3.rgb(colors(d.id)).darker().toString(); });

  // show node titles
  g.append('svg:text')
      .attr('x', 0)
      .attr('y', 4)
      .attr('class', 'title')
      .text(function(d) { return d.title; });

  g.on('click', onNodeClick);

  // set the graph in motion
  force.start();
})();
<commit_msg>make nodes more repulsive<commit_after>// from http://bl.ocks.org/rkirsling/5001347#app.js

(function(){
  // set up SVG for D3
  var $win = $(window),
      width  = $win.width(),
      height = $win.height(),
      colors = d3.scale.category10();

  var svg = d3.select('.graph')
    .append('svg');

  // set up initial nodes and links
  //  - nodes are known by 'id', not by index in array.
  //  - links are always source < target; edge directions are set by 'left' and 'right'.
  var nodesById = {};
  var nodes = gon.topics.map(function(topic){
    var node = $.extend({}, topic);
    nodesById[node.id] = node;
    return node;
  });
  var links = gon.relationships.map(function(rel){
    return $.extend({}, rel, {
      source: nodesById[rel.parent_id],
      target: nodesById[rel.child_id],
      left: false,
      right: true
    });
  });

  // init D3 force layout
  var force = d3.layout.force()
      .nodes(nodes)
      .links(links)
      .size([width, height])
      .linkDistance(180)
      .charge(-1000)
      .on('tick', tick);

  // define arrow markers for graph links
  svg.append('svg:defs').append('svg:marker')
      .attr('id', 'end-arrow')
      .attr('viewBox', '0 -5 10 10')
      .attr('refX', 6)
      .attr('markerWidth', 3)
      .attr('markerHeight', 3)
      .attr('orient', 'auto')
    .append('svg:path')
      .attr('d', 'M0,-5L10,0L0,5')
      .attr('fill', '#000');

  // handles to link and node element groups
  var path = svg.append('svg:g').selectAll('path'),
      circle = svg.append('svg:g').selectAll('g');

  // mouse event vars
  var selected_node = null;

  var NODE_RADIUS = 40;

  // update force layout (called automatically each iteration)
  function tick() {
    // draw directed edges with proper padding from node centers
    path.attr('d', function(d) {
      var deltaX = d.target.x - d.source.x,
          deltaY = d.target.y - d.source.y,
          dist = Math.sqrt(deltaX * deltaX + deltaY * deltaY),
          normX = deltaX / dist,
          normY = deltaY / dist,
          sourcePadding = NODE_RADIUS,
          targetPadding = NODE_RADIUS + 5,
          sourceX = d.source.x + (sourcePadding * normX),
          sourceY = d.source.y + (sourcePadding * normY),
          targetX = d.target.x - (targetPadding * normX),
          targetY = d.target.y - (targetPadding * normY);
      return 'M' + sourceX + ',' + sourceY + 'L' + targetX + ',' + targetY;
    });

    circle.attr('transform', function(d) {
      return 'translate(' + d.x + ',' + d.y + ')';
    });
  }

  // action to take on mouse click
  function onNodeClick(d) {
    d3.select(this).select('text').transition()
      .duration(750)
      .attr('x', 22)
      .style('fill', 'steelblue')
      .style('stroke', 'lightsteelblue')
      .style('stroke-width', '.5px')
      .style('font', '20px sans-serif');

    d3.select(this).select('circle').transition()
      .duration(750)
      .attr('r', NODE_RADIUS * 2)
      .style('fill', 'lightsteelblue');

    // select node
    selected_node = d;
    restart();
  }

  // path (link) group
  path = path.data(links);

  // add new links
  path.enter().append('svg:path')
    .attr('class', 'link')
    .style('marker-end', function(d) { return d.right ? 'url(#end-arrow)' : ''; });

  // circle (node) group
  // NB: the function arg is crucial here! nodes are known by id, not by index!
  circle = circle.data(nodes, function(d) { return d.id; });

  // add new nodes
  var g = circle.enter().append('svg:g');

  g.append('svg:circle')
    .attr('class', 'node')
    .attr('r', NODE_RADIUS)
    .style('fill', function(d) { return (d === selected_node) ? d3.rgb(colors(d.id)).brighter().toString() : colors(d.id); })
    .style('stroke', function(d) { return d3.rgb(colors(d.id)).darker().toString(); });

  // show node titles
  g.append('svg:text')
      .attr('x', 0)
      .attr('y', 4)
      .attr('class', 'title')
      .text(function(d) { return d.title; });

  g.on('click', onNodeClick);

  // set the graph in motion
  force.start();
})();
<|endoftext|>


<commit_before>cleverNote.Routers.Router = Backbone.Router.extend({

  routes: {
    '': 'startPage',
    'notes/new': 'newNote',
    'notes/:id': 'showNote',
    'notebooks': 'notebooksIndex',
    'notebooks/:id': 'showNotebook',
    'tags': 'tagsIndex',
    'tags/:id': 'showTag'
  },

  initialize: function(options) {
    this.notebooks = options.notebooks;
    this.tags = options.tags;
    this.$rootEl = options.$rootEl;
    this.setSidebar();
  },

  startPage: function () {
    var notes = new cleverNote.Collections.Notes();
    var view = new cleverNote.Views.allNotesIndex({ collection: notes });
    this._swapView(view);
    var rightView = new Backbone.View();
    this._setRightView(rightView);
  },

// Notebooks
//===============================================================================

  notebooksIndex: function () {
    this.notebooks.fetch();
    var view = new cleverNote.Views.NotebooksIndex({
      collection: this.notebooks
    });
    this._swapView(view);
    var rightView = new Backbone.View();
    this._setRightView(rightView);
  },

  showNotebook: function (id, noNote) {
    var notebook = this.notebooks.getOrFetch(id);
    var that = this;
    notebook.fetch({
      success: function() {
        that.notebooks.add(notebook, { merge: true });
        if (!noNote) {
          that.showNote(notebook.notes().first().id, true);
        }
      }
    });
    var view = new cleverNote.Views.NotesIndex({ model: notebook });
    this._swapView(view);
  },

// Notes
//==============================================================================

  newNote: function () {
    this.notebooks.fetch();
    this.tags.fetch();
    var note = new cleverNote.Models.Note({ title: 'Untitled' });
    var view = new cleverNote.Views.NoteForm({
      model: note,
      notebooks: this.notebooks,
      tags: this.tags
    });
    this.startPage();
    this._setRightView(view);
  },

  showNote: function(id, noNotebook) {
    this.notebooks.fetch();
    this.tags.fetch();
    var note = new cleverNote.Models.Note({ id: id });
    var that = this;
    note.fetch({
      success: function () {
        if (!noNotebook) {
          that.showNotebook(note.get('notebook_id'), true);
        }
      }
    });
    var view = new cleverNote.Views.NoteForm({
      model: note,
      notebooks: this.notebooks,
      tags: this.tags
    });
    this._setRightView(view);
  },

// Tags
//==============================================================================

  tagsIndex: function () {
    this.tags.fetch();
    var view = new cleverNote.Views.TagsIndex({ collection: this.tags });
    this._swapView(view);
    var rightView = new Backbone.View();
    this._setRightView(rightView);
  },

  showTag: function (id) {
    var tag = this.tags.getOrFetch(id);
    var that = this;
    tag.fetch({ success: that.tags.add.bind(tag, { merge: true }) });
    var view = new cleverNote.Views.NotesIndex({ model: tag });
    this._swapView(view);
  },

// Bonus
//==============================================================================

  setSidebar: function () {
    var view = new cleverNote.Views.Sidebar();
    $('#sidebar').html(view.render().$el);
  },

  _swapView: function(view) {
    this._currentView && this._currentView.remove();
    this._currentView = view;
    $('#middle-content').html(view.$el);
    view.render();
    view.onRender && view.onRender();
  },

  _setRightView: function(view) {
    this._rightView && this._rightView.remove();
    this._rightView = view;
    $('#right-content').html(view.$el);
    view.render();
    view.onRender && view.onRender();
  }

});
<commit_msg>make sure the correct note is shown on the right pane when navigating to a notebook<commit_after>cleverNote.Routers.Router = Backbone.Router.extend({

  routes: {
    '': 'startPage',
    'notes/new': 'newNote',
    'notes/:id': 'showNote',
    'notebooks': 'notebooksIndex',
    'notebooks/:id': 'showNotebook',
    'tags': 'tagsIndex',
    'tags/:id': 'showTag'
  },

  initialize: function(options) {
    this.notebooks = options.notebooks;
    this.tags = options.tags;
    this.$rootEl = options.$rootEl;
    this.setSidebar();
  },

  startPage: function () {
    var notes = new cleverNote.Collections.Notes();
    var view = new cleverNote.Views.allNotesIndex({ collection: notes });
    this._swapView(view);
    var rightView = new Backbone.View();
    this._setRightView(rightView);
  },

// Notebooks
//===============================================================================

  notebooksIndex: function () {
    this.notebooks.fetch();
    var view = new cleverNote.Views.NotebooksIndex({
      collection: this.notebooks
    });
    this._swapView(view);
    var rightView = new Backbone.View();
    this._setRightView(rightView);
  },

  showNotebook: function (id, noNote) {
    var notebook = this.notebooks.getOrFetch(id);
    var that = this;
    notebook.fetch({
      success: function() {
        that.notebooks.add(notebook, { merge: true });
        if (!noNote) {
          that.showNote(notebook.notes().last().id, true);
        }
      }
    });
    var view = new cleverNote.Views.NotesIndex({ model: notebook });
    this._swapView(view);
  },

// Notes
//==============================================================================

  newNote: function () {
    this.notebooks.fetch();
    this.tags.fetch();
    var note = new cleverNote.Models.Note({ title: 'Untitled' });
    var view = new cleverNote.Views.NoteForm({
      model: note,
      notebooks: this.notebooks,
      tags: this.tags
    });
    this.startPage();
    this._setRightView(view);
  },

  showNote: function(id, noNotebook) {
    this.notebooks.fetch();
    this.tags.fetch();
    var note = new cleverNote.Models.Note({ id: id });
    var that = this;
    note.fetch({
      success: function () {
        if (!noNotebook) {
          that.showNotebook(note.get('notebook_id'), true);
        }
      }
    });
    var view = new cleverNote.Views.NoteForm({
      model: note,
      notebooks: this.notebooks,
      tags: this.tags
    });
    this._setRightView(view);
  },

// Tags
//==============================================================================

  tagsIndex: function () {
    this.tags.fetch();
    var view = new cleverNote.Views.TagsIndex({ collection: this.tags });
    this._swapView(view);
    var rightView = new Backbone.View();
    this._setRightView(rightView);
  },

  showTag: function (id) {
    var tag = this.tags.getOrFetch(id);
    var that = this;
    tag.fetch({ success: that.tags.add.bind(tag, { merge: true }) });
    var view = new cleverNote.Views.NotesIndex({ model: tag });
    this._swapView(view);
  },

// Bonus
//==============================================================================

  setSidebar: function () {
    var view = new cleverNote.Views.Sidebar();
    $('#sidebar').html(view.render().$el);
  },

  _swapView: function(view) {
    this._currentView && this._currentView.remove();
    this._currentView = view;
    $('#middle-content').html(view.$el);
    view.render();
    view.onRender && view.onRender();
  },

  _setRightView: function(view) {
    this._rightView && this._rightView.remove();
    this._rightView = view;
    $('#right-content').html(view.$el);
    view.render();
    view.onRender && view.onRender();
  }

});
<|endoftext|>


<commit_before>import React,{Component} from 'react';
import {connect} from 'react-redux';
import {bindActionCreators} from 'redux';
import {tabAdd} from "./../actions/index";

import Axios from 'axios';
import Viewer from "./viewer";

class Editors extends Component {

    constructor(props){
        super(props);
        this.state = {};
        this.onClickSend = this.onClickSend.bind(this);
        this.renderEditors = this.renderEditors.bind(this);
    }

    onClickSend(e){

        const editor = $(e.currentTarget).closest(".editor");
        const action =  editor.find(".bar .select-action").val();
        const url =  editor.find(".bar .input-url").val();
        const jsonViewer = editor.find(".json-renderer");
        const statusLabel = editor.find(".field.status .value");
        const timeLabel = editor.find(".field.time .value");
        const startTime = new Date().getTime();
        jsonViewer.html("Carregando....");

        Axios({
            method: action,
            url: url
        }).then(function(response) {
            const duration = new Date().getTime() - startTime;
            jsonViewer.jsonViewer(response);
            statusLabel.html(response.status).removeClass("-error");
            timeLabel.html(duration + "ms");
        })
        .catch(function(error) {
            const duration = new Date().getTime() - startTime;
            jsonViewer.jsonViewer(error);
            statusLabel.html(error.status).addClass("-error");
            timeLabel.html(duration + "ms");
        });
    }

    renderEditors(data,index){
        return (

                                <select className="select-action">
                                    <option value="GET">GET</option>
                                    <option value="POST">POST</option>
                                    <option value="PUT">PUT</option>
                                    <option value="PATCH">PATCH</option>
                                    <option value="DELETE">DELETE</option>
                                </select>

                            <input className="input-url" name="url" placeholder="http://beta.json-generator.com/api/json/get/4JVFHRAHZ" defaultValue="http://beta.json-generator.com/api/json/get/4JVFHRAHZ" />

                            <input className="input-button" onClick={this.onClickSend} type="button" name="send" defaultValue="Send" />

                            status:
                            -

                            Time:
                            -

                <Viewer />

        )
    }

    render() {
        return (

                    {this.props.tabs.map(this.renderEditors)}

        );
    }
}

function mapStateToProps({tabs}){
    return {tabs};
}

function mapDispatchToProps(dispatch){
    return bindActionCreators({tabAdd},dispatch);
}

export default connect (mapStateToProps,mapDispatchToProps)(Editors);
<commit_msg>create bottom element<commit_after>import React,{Component} from 'react';
import {connect} from 'react-redux';
import {bindActionCreators} from 'redux';
import {tabAdd} from "./../actions/index";

import Axios from 'axios';
import Viewer from "./viewer";

class Editors extends Component {

    constructor(props){
        super(props);
        this.state = {};
        this.onClickSend = this.onClickSend.bind(this);
        this.renderEditors = this.renderEditors.bind(this);
    }

    onClickSend(e){

        const editor = $(e.currentTarget).closest(".editor");
        const action =  editor.find(".bar .select-action").val();
        const url =  editor.find(".bar .input-url").val();
        const jsonViewer = editor.find(".json-renderer");
        const statusLabel = editor.find(".field.status .value");
        const timeLabel = editor.find(".field.time .value");
        const startTime = new Date().getTime();
        jsonViewer.html("Carregando....");

        Axios({
            method: action,
            url: url
        }).then(function(response) {
            const duration = new Date().getTime() - startTime;
            jsonViewer.jsonViewer(response);
            statusLabel.html(response.status).removeClass("-error");
            timeLabel.html(duration + "ms");
        })
        .catch(function(error) {
            const duration = new Date().getTime() - startTime;
            jsonViewer.jsonViewer(error);
            statusLabel.html(error.status).addClass("-error");
            timeLabel.html(duration + "ms");
        });
    }

    renderEditors(data,index){
        return (

                                <select className="select-action">
                                    <option value="GET">GET</option>
                                    <option value="POST">POST</option>
                                    <option value="PUT">PUT</option>
                                    <option value="PATCH">PATCH</option>
                                    <option value="DELETE">DELETE</option>
                                </select>

                            <input className="input-url" name="url" placeholder="http://beta.json-generator.com/api/json/get/4JVFHRAHZ" defaultValue="http://beta.json-generator.com/api/json/get/4JVFHRAHZ" />

                            <input className="input-button" onClick={this.onClickSend} type="button" name="send" defaultValue="Send" />

                <Viewer />

                            status:
                            -

                            Time:
                            -

        )
    }

    render() {
        return (

                    {this.props.tabs.map(this.renderEditors)}

        );
    }
}

function mapStateToProps({tabs}){
    return {tabs};
}

function mapDispatchToProps(dispatch){
    return bindActionCreators({tabAdd},dispatch);
}

export default connect (mapStateToProps,mapDispatchToProps)(Editors);
<|endoftext|>


<commit_before>const assert = require('assert');

describe('Google Search Function', () => {
  it('can find search results', () => {
    browser.url('https://www.google.com/ncr');
    const input = $('[name="q"]');
    input.setValue('pcloudy');

    const title = browser.getTitle();
    assert.equal(title, 'Google');
  });
});
<commit_msg>Testcase modified<commit_after>const assert = require('assert');

describe('Google Search Function', () => {
  it('can find search results', () => {
    browser.url('https://www.google.com');
    const input = $('[name="q"]');
    input.setValue('pcloudy');

    const title = browser.getTitle();
    assert.equal(title, 'Google');
  });
});
<|endoftext|>


<commit_before>// Configs
const dir = require(`${global.baseDir}/global-dirs`)
const files = require(`${dir.includes}files`)

const shared = {
	cache: true,
	module: { rules: [{
		test: /\.jsx$/,
		// loaders: [
		// 	'eslint-loader',
		// 	'react-hot-loader/webpack',
		// 	'babel-loader',
		// ],
		loader: 'happypack/loader?id=jsx',
		include: [files],
	}, {
		test: /\.css$/,
		loader: 'happypack/loader?id=css',
	}, {
		test: /\.styl$/,
		loader: 'happypack/loader?id=styl',
		include: [files],
	}, {
		test: /\.(jpe?g|png|gif|svg)$/i,
		loader: 'url?limit=10000',
	}, {
		test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
		loader: 'url-loader?limit=10000&minetype=application/font-woff',
	}, {
		test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
		loader: 'file-loader',
	}, {
		test: /\.html$|\.css$/,
		loader: 'file-loader?name=[name].[ext]',
	}]},
	resolve: {
		extensions: ['.js', '.jsx', '.json', '.css', '.styl'],
		modules: [files, 'node_modules'],
	},
}

const dev = {
	// colors: true,
	// debug: true,
	devtool: 'eval-source-map',
	// minimize: false,
	// prerender: false,
}

const prod = {
	// colors: false,
	// debug: false,
	devtool: false,
	// minimize: true,
	// noInfo: true,
	// prerender: true,
}

module.exports = {
	getDev: () => {
		const webpackDefaultConfig = Object.assign({}, shared, dev )
		webpackDefaultConfig.module.rules.push({
			test: /\.json$/,
			loaders: [
				'json',
				'transform?brfs',
			]
		})

		return webpackDefaultConfig
	},
	getProd: () => Object.assign({}, shared, prod),
}
<commit_msg>Added -loader to Webpack dev config<commit_after>// Configs
const dir = require(`${global.baseDir}/global-dirs`)
const files = require(`${dir.includes}files`)

const shared = {
	cache: true,
	module: { rules: [{
		test: /\.jsx$/,
		// loaders: [
		// 	'eslint-loader',
		// 	'react-hot-loader/webpack',
		// 	'babel-loader',
		// ],
		loader: 'happypack/loader?id=jsx',
		include: [files],
	}, {
		test: /\.css$/,
		loader: 'happypack/loader?id=css',
	}, {
		test: /\.styl$/,
		loader: 'happypack/loader?id=styl',
		include: [files],
	}, {
		test: /\.(jpe?g|png|gif|svg)$/i,
		loader: 'url?limit=10000',
	}, {
		test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
		loader: 'url-loader?limit=10000&minetype=application/font-woff',
	}, {
		test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
		loader: 'file-loader',
	}, {
		test: /\.html$|\.css$/,
		loader: 'file-loader?name=[name].[ext]',
	}]},
	resolve: {
		extensions: ['.js', '.jsx', '.json', '.css', '.styl'],
		modules: [files, 'node_modules'],
	},
}

const dev = {
	// colors: true,
	// debug: true,
	devtool: 'eval-source-map',
	// minimize: false,
	// prerender: false,
}

const prod = {
	// colors: false,
	// debug: false,
	devtool: false,
	// minimize: true,
	// noInfo: true,
	// prerender: true,
}

module.exports = {
	getDev: () => {
		const webpackDefaultConfig = Object.assign({}, shared, dev )
		webpackDefaultConfig.module.rules.push({
			test: /\.json$/,
			loaders: [
				'json-loader',
				'transform-loader?brfs',
			]
		})

		return webpackDefaultConfig
	},
	getProd: () => Object.assign({}, shared, prod),
}
<|endoftext|>


<commit_before>//
// Load in every server flavor, so all server tests have the same initial memory
// consumption.
//
var https = require('https')
  , http = require('http')
  , spdy = require('spdy');

//
// Cluster all the things.
//
var workers = require('os').cpus().length
  , cluster = require('cluster')
  , master = cluster.isMaster;

if (master && workers > 1) {
  while (workers--) cluster.fork();
} else {

//
// Select the server based on the flavor env variable.
//
//     FLAVOR=spdy node index.js    # Start a spdy server.
//     FLAVOR=https node index.js   # Start a https server.
//     FLAVOR=http node index.js    # Start a regular server.
//     node index.js                # Also starts a regular server.
//
var flavor = (process.env.FLAVOR || 'http').toLowerCase()
  , secure = !!~flavor.indexOf('s')
  , server = flavor === 'spdy' ? spdy : (flavor === 'https' ? https : http);

//
// Initialize the SSL
//
var fs = require('fs')
  , options = {
        cert: fs.readFileSync(__dirname +'/ssl/server.crt', 'utf8')
      , key: fs.readFileSync(__dirname +'/ssl/server.key', 'utf8')
    };

//
// Setup the HTTP proxy
//
var Proxy = require('http-proxy').HttpProxy
  , forward = new Proxy({
        target: { host: 'localhost', port: 8080 }
      , maxSockets: 32000
    })
  , server = !secure
    ? server.createServer(regular)
    : server.createServer(options, regular);

server.on('upgrade', upgrade);

/**
 * Proxy regular HTTP.
 *
 * @param {Request} req HTTP request
 * @param {Response} res HTTP response
 * @api private
 */
function regular(req, res) {
  forward.proxyRequest(req, res);
}

/**
 * Proxy upgrade requests.
 *
 * @param {Request} req HTTP request
 * @param {Socket} res Socket
 * @param {Buffer} head Buffered head.
 * @api private
 */
function upgrade(req, res, head) {
  forward.proxyWebSocketRequest(req, res, head);
}

//
// Everything is configured, listen
//
var port = +process.argv[2] || 8081
  , backlog = 3000;

server.listen(port, backlog, function listening(err) {
  if (!err) return console.log('BalancerBattleProxy (flavor: %s) is listening on port 8081', flavor);

  console.error('Failed to listen on port 8081, due to reasons');
  console.error('  - '+ err.message);
  process.exit(1);
});
}
<commit_msg>[minor] update ip<commit_after>//
// Load in every server flavor, so all server tests have the same initial memory
// consumption.
//
var https = require('https')
  , http = require('http')
  , spdy = require('spdy');

//
// Cluster all the things.
//
var workers = require('os').cpus().length
  , cluster = require('cluster')
  , master = cluster.isMaster;

if (master && workers > 1) {
  while (workers--) cluster.fork();
} else {

//
// Select the server based on the flavor env variable.
//
//     FLAVOR=spdy node index.js    # Start a spdy server.
//     FLAVOR=https node index.js   # Start a https server.
//     FLAVOR=http node index.js    # Start a regular server.
//     node index.js                # Also starts a regular server.
//
var flavor = (process.env.FLAVOR || 'http').toLowerCase()
  , secure = !!~flavor.indexOf('s')
  , server = flavor === 'spdy' ? spdy : (flavor === 'https' ? https : http);

//
// Initialize the SSL
//
var fs = require('fs')
  , options = {
        cert: fs.readFileSync(__dirname +'/ssl/server.crt', 'utf8')
      , key: fs.readFileSync(__dirname +'/ssl/server.key', 'utf8')
    };

//
// Setup the HTTP proxy
//
var Proxy = require('http-proxy').HttpProxy
  , forward = new Proxy({
        target: { host: '10.112.1.62', port: 8080 }
      , maxSockets: 32000
    })
  , server = !secure
    ? server.createServer(regular)
    : server.createServer(options, regular);

server.on('upgrade', upgrade);

/**
 * Proxy regular HTTP.
 *
 * @param {Request} req HTTP request
 * @param {Response} res HTTP response
 * @api private
 */
function regular(req, res) {
  forward.proxyRequest(req, res);
}

/**
 * Proxy upgrade requests.
 *
 * @param {Request} req HTTP request
 * @param {Socket} res Socket
 * @param {Buffer} head Buffered head.
 * @api private
 */
function upgrade(req, res, head) {
  forward.proxyWebSocketRequest(req, res, head);
}

//
// Everything is configured, listen
//
var port = +process.argv[2] || 8081
  , backlog = 3000;

server.listen(port, backlog, function listening(err) {
  if (!err) return console.log('BalancerBattleProxy (flavor: %s) is listening on port 8081', flavor);

  console.error('Failed to listen on port 8081, due to reasons');
  console.error('  - '+ err.message);
  process.exit(1);
});
}
<|endoftext|>


<commit_before>"use strict";

var error = require('debug')('error');
var generate = require('./base');
var verbose = require('debug')('verbose:game');

var games = {};
var incrementId = 0;

function Game(id, users, room) {
  verbose('Game() constructor called with users: [%s]', users.map(function (user) {
    return user.username;
  }));

  // TODO:validate users.length

  this.id = id;

  this.team = [
    { users: users.splice(0, 3) },
    { users: users }
  ];
  this.room = room;
  this.turn = 0;
  this.joined = {};

  function Timer(game) {
    this.game = game;
    this.handle = null;
  }

  Timer.prototype.fire = function () {
    if (this.handle !== null) {
      this.clear();
    }
    this.handle = setInterval(this.tick, 1000);
  };
  Timer.prototype.tick = function () {
    this.game.turn++;
  };

  Timer.prototype.clear = function () {
    if (this.handle !== null) {
      clearInterval(this.handle);
      this.handle = null;
    }
  };

  this.timer = new Timer(this);
}

Game.prototype.sockets = function () {
  return this.room.sockets;
};

Game.prototype.inTeam = function (num, who) {
  return this.team[num].users.filter(function (user) {
    return user.username === who.username;
  }).length > 0;
};

Game.prototype.ours = function (whose) {
  var team;
  if (this.inTeam(0, whose)) {
    team = this.team[0];
  } else if (this.inTeam(1, whose)) {
    team = this.team[1];
  } else {
    error('Game.ours(), no team available for user %s', whose.username);
    return null;
  }

  team.users.forEach(function (user) {
    // TODO: check 'current' true
    user.me = user.username === whose.username;
  });

  return team;
};

Game.prototype.opponents = function (whose) {
  var team;
  if (this.inTeam(1, whose)) {
    team = this.team[0];
  } else if (this.inTeam(0, whose)) {
    team = this.team[1];
  } else {
    error('Game.opponents(), no team available for user %s', whose.username);
    return null;
  }

  team.users.forEach(function (user) {
    // TODO: check 'current' true
    user.me = false;
  });

  return team;
};

Game.prototype.socket = function (whose) {
  return this.sockets().filter(function (socket) {
    return socket.username === whose.username;
  })[0];
};

Game.prototype.broadcast = function (from, eventName, data, postProcess,
                                     exceptForMe) {
  var that = this;
  var handlerFactory = function (side) {
    return function (user) {
      data.side = side;

      if (postProcess) {
        postProcess(user, data);
      }

      if (!exceptForMe || user.username !== from.username) {
        that.socket(user).emit(eventName, data);
      }
    };
  };

  this.ours(from).users.forEach(handlerFactory('ours'));
  this.opponents(from).users.forEach(handlerFactory('opponents'));
};

Game.prototype.userJoined = function (socket) {
  verbose('user(%s) didJoin', socket.username);
  this.joined[socket.username] = true;
};

Game.prototype.isEveryoneJoined = function () {
  return Object.keys(this.joined).length === this.sockets().length;
};

function updateClient(game, socket) {
  if (!game instanceof Game) {
    error('game.js, updateClient, check arguments');
  }

  verbose('game/update');

  var update = function (target) {
    target.emit('game/update', {
      ours: game.ours(target),
      opponents: game.opponents(target)
    });
  };

  if (socket) {
    update(socket);
  } else {
    game.sockets().forEach(update);
  }
}

function sendNotice(game, text) {
  game.sockets().forEach(function (socket) {
    socket.emit('game/chat', {
      side: 'ours',
      chat: { type: 'notice', text: text }
    });
  });
}

function startGame(game, time) {
  return function () {
    verbose('emit game/start!');
    game.room.emit('game/start');
    sendNotice(game, 'Game will begin in ' + time + 's.');
  };
}

function getProblem() {
  var preparationDuration = 5;
  return {
    title: 'Largest prime factor',
    description: 'What is the largest prime factor of the number 600851475143?',
    preparationDuration: preparationDuration
  };
}

function didJoin() {
  verbose('game/didJoin');
  var game = games[this.socket.gid];
  game.userJoined(this.socket);
  updateClient(game, this.socket);
  if (game.isEveryoneJoined()) {
    verbose('everyone joined! emit game/problem');
    var problem = getProblem();
    game.room.emit('game/problem', problem);

    // wait 1 more second and start a game.
    setTimeout(startGame(game, problem.preparationDuration), 1000 * (problem.preparationDuration + 1));
  }
}

function chat(data) {
  verbose('game/chat');
  var game = games[this.socket.gid];
  game.broadcast(this.socket, 'game/chat', {
    chat: {
      type: 'normal',
      username: this.socket.username,
      text: data.text
    }
  }, function (receiver, data) {
    data.chat.me = receiver.username === data.chat.username;
  });
}

function code(data) {
  verbose('game/code');
  var game = games[this.socket.gid];
  game.broadcast(this.socket, 'game/code', {code: data.code}, null, true);
}

module.exports = generate({
  'game/didJoin': { name: 'didJoin', function: didJoin },
  'game/chat': { name: 'chat', function: chat },
  'game/code': { name: 'code', function: code }
});

function enterGame(context) {
  var game = new Game(incrementId, context.team.members.map(function (username) {
    return {
      username: username,
      me: false,
      current: false
    };
  }), context.team.room);

  verbose('a new game is made. id = %s', incrementId);

  game.room.emit('game/join', null, function (socket) {
    socket.gid = incrementId;
  });

  games[incrementId++] = game;
}

module.exports.start = enterGame;
<commit_msg>Fix wrong behavior when sending a notice.<commit_after>"use strict";

var error = require('debug')('error');
var generate = require('./base');
var verbose = require('debug')('verbose:game');

var games = {};
var incrementId = 0;

function Game(id, users, room) {
  verbose('Game() constructor called with users: [%s]', users.map(function (user) {
    return user.username;
  }));

  // TODO:validate users.length

  this.id = id;

  this.team = [
    { users: users.splice(0, 3) },
    { users: users }
  ];
  this.room = room;
  this.turn = 0;
  this.joined = {};

  function Timer(game) {
    this.game = game;
    this.handle = null;
  }

  Timer.prototype.fire = function () {
    if (this.handle !== null) {
      this.clear();
    }
    this.handle = setInterval(this.tick, 1000);
  };
  Timer.prototype.tick = function () {
    this.game.turn++;
  };

  Timer.prototype.clear = function () {
    if (this.handle !== null) {
      clearInterval(this.handle);
      this.handle = null;
    }
  };

  this.timer = new Timer(this);
}

Game.prototype.sockets = function () {
  return this.room.sockets;
};

Game.prototype.inTeam = function (num, who) {
  return this.team[num].users.filter(function (user) {
    return user.username === who.username;
  }).length > 0;
};

Game.prototype.ours = function (whose) {
  var team;
  if (this.inTeam(0, whose)) {
    team = this.team[0];
  } else if (this.inTeam(1, whose)) {
    team = this.team[1];
  } else {
    error('Game.ours(), no team available for user %s', whose.username);
    return null;
  }

  team.users.forEach(function (user) {
    // TODO: check 'current' true
    user.me = user.username === whose.username;
  });

  return team;
};

Game.prototype.opponents = function (whose) {
  var team;
  if (this.inTeam(1, whose)) {
    team = this.team[0];
  } else if (this.inTeam(0, whose)) {
    team = this.team[1];
  } else {
    error('Game.opponents(), no team available for user %s', whose.username);
    return null;
  }

  team.users.forEach(function (user) {
    // TODO: check 'current' true
    user.me = false;
  });

  return team;
};

Game.prototype.socket = function (whose) {
  return this.sockets().filter(function (socket) {
    return socket.username === whose.username;
  })[0];
};

Game.prototype.broadcast = function (from, eventName, data, postProcess,
                                     exceptForMe) {
  var that = this;
  var handlerFactory = function (side) {
    return function (user) {
      data.side = side;

      if (postProcess) {
        postProcess(user, data);
      }

      if (!exceptForMe || user.username !== from.username) {
        that.socket(user).emit(eventName, data);
      }
    };
  };

  this.ours(from).users.forEach(handlerFactory('ours'));
  this.opponents(from).users.forEach(handlerFactory('opponents'));
};

Game.prototype.userJoined = function (socket) {
  verbose('user(%s) didJoin', socket.username);
  this.joined[socket.username] = true;
};

Game.prototype.isEveryoneJoined = function () {
  return Object.keys(this.joined).length === this.sockets().length;
};

function updateClient(game, socket) {
  if (!game instanceof Game) {
    error('game.js, updateClient, check arguments');
  }

  verbose('game/update');

  var update = function (target) {
    target.emit('game/update', {
      ours: game.ours(target),
      opponents: game.opponents(target)
    });
  };

  if (socket) {
    update(socket);
  } else {
    game.sockets().forEach(update);
  }
}

function sendNotice(game, text) {
  game.sockets().forEach(function (socket) {
    socket.emit('game/chat', {
      side: 'ours',
      chat: { type: 'notice', text: text }
    });
  });
}

function startGame(game) {
  return function () {
    verbose('emit game/start!');
    game.room.emit('game/start');
  };
}

function getProblem() {
  var preparationDuration = 5;
  return {
    title: 'Largest prime factor',
    description: 'What is the largest prime factor of the number 600851475143?',
    preparationDuration: preparationDuration
  };
}

function didJoin() {
  verbose('game/didJoin');
  var game = games[this.socket.gid];
  game.userJoined(this.socket);
  updateClient(game, this.socket);
  if (game.isEveryoneJoined()) {
    verbose('everyone joined! emit game/problem');
    var problem = getProblem();
    game.room.emit('game/problem', problem);
    sendNotice(game, 'Game begins in ' + problem.preparationDuration + 's.');
    // wait 1 more second and start a game.
    setTimeout(startGame(game), 1000 * (problem.preparationDuration + 1));
  }
}

function chat(data) {
  verbose('game/chat');
  var game = games[this.socket.gid];
  game.broadcast(this.socket, 'game/chat', {
    chat: {
      type: 'normal',
      username: this.socket.username,
      text: data.text
    }
  }, function (receiver, data) {
    data.chat.me = receiver.username === data.chat.username;
  });
}

function code(data) {
  verbose('game/code');
  var game = games[this.socket.gid];
  game.broadcast(this.socket, 'game/code', {code: data.code}, null, true);
}

module.exports = generate({
  'game/didJoin': { name: 'didJoin', function: didJoin },
  'game/chat': { name: 'chat', function: chat },
  'game/code': { name: 'code', function: code }
});

function enterGame(context) {
  var game = new Game(incrementId, context.team.members.map(function (username) {
    return {
      username: username,
      me: false,
      current: false
    };
  }), context.team.room);

  verbose('a new game is made. id = %s', incrementId);

  game.room.emit('game/join', null, function (socket) {
    socket.gid = incrementId;
  });

  games[incrementId++] = game;
}

module.exports.start = enterGame;
<|endoftext|>


<commit_before>var HttpServer = require('../lib/http-server'),
    WebSocketServer = require('../lib/websocket-server'),
    EventSource = require('../lib/event-source');

var Channels = require('./channels'),
    Peer = require('./peer');

var Proxy = function (address, port) {
  EventSource.apply(this);

  this.httpServer_ = new HttpServer();
  this.wsServer_ = new WebSocketServer(this.httpServer_);
  this.httpServer_.listen(port, address);

  this.channels_ = new Channels();

  this.httpServer_.addEventListener('request', function (req) {
    console.log('An HTTP request!', req);
    req.writeHead(404, {});
    req.end();

    // Keep socket open until we explicitly
    // call req.end()
    return true;
  });

  this.wsServer_.addEventListener('request', function (req) {
    console.log('WebSocket request', req);
    var keepConnectionOpen, channelName, socket;

    if ('url' in req.headers) {
      channelName = req.headers.url.replace(/^\//, '');
    }

    if (!channelName) {
      req.reject();
      keepConnectionOpen = false;
      return keepConnectionOpen;
    } else {
      socket = req.accept();
      keepConnectionOpen = true;
    }

    console.log('channelName: ', channelName);

    // Associate socket with channel
    var channel = this.channels_.findOrCreate(channelName);
    var peer = channel.addSocket(socket);

    socket.addEventListener('message', function (e) {
      console.log('Message from client', e);
    });

    socket.addEventListener('close', function () {
      console.log('Socket has closed');
      channel.removePeer(peer);
    });

    // socket.send('Hello');

    return keepConnectionOpen;
  }.bind(this));
};

Proxy.prototype = {
  __proto__: EventSource.prototype,
  disconnect: function () {
    this.httpServer_.disconnect();
  }
}

module.exports = Proxy;<commit_msg>Better logging to identify peer connection and disconnection<commit_after>var HttpServer = require('../lib/http-server'),
    WebSocketServer = require('../lib/websocket-server'),
    EventSource = require('../lib/event-source');

var Channels = require('./channels'),
    Peer = require('./peer');

var Proxy = function (address, port) {
  EventSource.apply(this);

  this.httpServer_ = new HttpServer();
  this.wsServer_ = new WebSocketServer(this.httpServer_);
  this.httpServer_.listen(port, address);

  this.channels_ = new Channels();

  this.httpServer_.addEventListener('request', function (req) {
    console.log('An HTTP request!', req);
    req.writeHead(404, {});
    req.end();

    // Keep socket open until we explicitly
    // call req.end()
    return true;
  });

  this.wsServer_.addEventListener('request', function (req) {
    console.log('WebSocket request', req);
    var keepConnectionOpen, channelName, socket;

    if ('url' in req.headers) {
      channelName = req.headers.url.replace(/^\//, '');
    }

    if (!channelName) {
      req.reject();
      keepConnectionOpen = false;
      return keepConnectionOpen;
    } else {
      socket = req.accept();
      keepConnectionOpen = true;
    }

    // Associate socket with channel
    var channel = this.channels_.findOrCreate(channelName);
    var peer = channel.addSocket(socket);

    console.log('New peer on channel ', channel.name, ' has ', channel.peers.length, ' connected peers');
    console.log('Peer has id ', peer.id);

    socket.addEventListener('message', function (e) {
      console.log('Message from client', e);
    });

    socket.addEventListener('close', function () {
      console.log('Socket has closed, removing peer id: ', peer.id);
      channel.removePeer(peer);
      console.log('Channel ', channel.name, ' has ', channel.peers.length, ' connected peers');
    });

    // socket.send('Hello');

    return keepConnectionOpen;
  }.bind(this));
};

Proxy.prototype = {
  __proto__: EventSource.prototype,
  disconnect: function () {
    this.httpServer_.disconnect();
  }
}

module.exports = Proxy;<|endoftext|>


<commit_before>/*!
 * human-time
 * https://github.com/tfoxy/human-time
 *
 * Copyright 2015 Tomás Fox
 * Released under the MIT license
 */

(function() {
  "use strict";

  var names = {
    'zero': 0,
    'millisecond': ' millisecond`',
    'second': ' second`',
    'minute': ' minute`',
    'hour': ' hour`',
    'day': ' day`',
    'week': ' week`',
    'month': ' month`',
    'year': ' year`'
  };

  var plurals = {
    'millisecond': 's',
    'second': 's',
    'minute': 's',
    'hour': 's',
    'day': 's',
    'week': 's',
    'month': 's',
    'year': 's'
  };

  var T = function(name, time) {
    this.name = name;
    this.time = time;
  };

  var times = [
    new T('millisecond', 1),
    new T('second', 1000),
    new T('minute', 60 * 1000),
    new T('hour', 60 * 60 * 1000),
    new T('day', 24 * 60 * 60 * 1000),
    new T('week', 7 * 24 * 60 * 60 * 1000),
    new T('month', 30 * 24 * 60 * 60 * 1000),
    new T('year', 365 * 24 * 60 * 60 * 1000)
  ];

  var fixedRound = function(num, n) {
    return +num.toFixed(n);
  };

  var makeCopyOf = function(obj) {
    return JSON.parse(JSON.stringify(obj));
  };

  var mergeObjects = function(baseObj, addObj) {
    var mergeObj = makeCopyOf(baseObj);

    if (typeof addObj === 'object') {
      for (var key in addObj) {
        if (Object.prototype.hasOwnProperty.call(addObj, key))
          mergeObj[key] = addObj[key];
      }
    }

    return mergeObj;
  };

  var HumanTime = function(options) {
    options = options || {};

    this.names = mergeObjects(names, options.names);

    this.plurals = mergeObjects(plurals, options.plurals);

    if (typeof options.round === 'function') {
      this.round = options.round;
    }
    else {
      this.round = fixedRound;
    }

    this.digits = options.digits;
  };

  HumanTime.prototype.print = function(time) {
    if (time < 1) {
      return names.zero.toString();
    }

    for (var i = 0; i < times.length; ++i) {
      var t = times[i];
      if (time < t.time) {
        return this._print(time, times[i-1]);
      }
    }

    return this._print(time, times[times.length - 1]);
  };

  HumanTime.prototype._print = function(time, t) {
    var printedTime = this.round(time / t.time, this.digits);
    var name = this.names[t.name];
    var plural = printedTime === 1? '' : this.plurals[t.name];

    return printedTime + name.replace('`', plural);
  };

  if (typeof module !== 'undefined' && module.exports) {
    module.exports = HumanTime;
  }
  else if (typeof window !== 'undefined') {
    window.HumanTime = HumanTime;
  }
  else {
    return HumanTime;
  }

})();
<commit_msg>Use UMD, adding support to AMD<commit_after>/*!
 * human-time
 * https://github.com/tfoxy/human-time
 *
 * Copyright 2015 Tomás Fox
 * Released under the MIT license
 */

(function (root, factory) {
  if (typeof define === 'function' && define.amd) {
    // AMD. Register as an anonymous module.
    define([], factory);
  } else if (typeof exports === 'object') {
    // Node. Does not work with strict CommonJS, but
    // only CommonJS-like environments that support module.exports,
    // like Node.
    module.exports = factory();
  } else {
    // Browser globals (root is window)
    root.returnExports = factory();
  }
}(this, function () {
  'use strict';

  var names = {
    'zero': 0,
    'millisecond': ' millisecond`',
    'second': ' second`',
    'minute': ' minute`',
    'hour': ' hour`',
    'day': ' day`',
    'week': ' week`',
    'month': ' month`',
    'year': ' year`'
  };

  var plurals = {
    'millisecond': 's',
    'second': 's',
    'minute': 's',
    'hour': 's',
    'day': 's',
    'week': 's',
    'month': 's',
    'year': 's'
  };

  var T = function(name, time) {
    this.name = name;
    this.time = time;
  };

  var times = [
    new T('millisecond', 1),
    new T('second', 1000),
    new T('minute', 60 * 1000),
    new T('hour', 60 * 60 * 1000),
    new T('day', 24 * 60 * 60 * 1000),
    new T('week', 7 * 24 * 60 * 60 * 1000),
    new T('month', 30 * 24 * 60 * 60 * 1000),
    new T('year', 365 * 24 * 60 * 60 * 1000)
  ];

  var fixedRound = function(num, n) {
    return +num.toFixed(n);
  };

  var makeCopyOf = function(obj) {
    return JSON.parse(JSON.stringify(obj));
  };

  var mergeObjects = function(baseObj, addObj) {
    var mergeObj = makeCopyOf(baseObj);

    if (typeof addObj === 'object') {
      for (var key in addObj) {
        if (Object.prototype.hasOwnProperty.call(addObj, key))
          mergeObj[key] = addObj[key];
      }
    }

    return mergeObj;
  };

  var HumanTime = function(options) {
    options = options || {};

    this.names = mergeObjects(names, options.names);

    this.plurals = mergeObjects(plurals, options.plurals);

    if (typeof options.round === 'function') {
      this.round = options.round;
    }
    else {
      this.round = fixedRound;
    }

    this.digits = options.digits;
  };

  HumanTime.prototype.print = function(time) {
    if (time < 1) {
      return names.zero.toString();
    }

    for (var i = 0; i < times.length; ++i) {
      var t = times[i];
      if (time < t.time) {
        return this._print(time, times[i-1]);
      }
    }

    return this._print(time, times[times.length - 1]);
  };

  HumanTime.prototype._print = function(time, t) {
    var printedTime = this.round(time / t.time, this.digits);
    var name = this.names[t.name];
    var plural = printedTime === 1? '' : this.plurals[t.name];

    return printedTime + name.replace('`', plural);
  };

  return HumanTime;
}));
<|endoftext|>


<commit_before>module.exports = function (window) {
    "use strict";

    require('./css/i-splitdiv.css'); // <-- define your own itag-name here

    var itagCore = require('itags.core')(window),
        itagName = 'i-splitdiv', // <-- define your own itag-name here
        DOCUMENT = window.document,
        documentElement = DOCUMENT.documentElement,
        bodyElement = DOCUMENT.body,
        ITSA = window.ITSA,
        Event = ITSA.Event,
        DIVIDER = 'divider',
        Itag;

    if (!window.ITAGS[itagName]) {

        Event.after('mousedown', function(e) {
            var resizeNode = e.target,
                element = resizeNode.inside('i-splitdiv'),
                sectionId = resizeNode.getData('_section'),
                reverseResize = resizeNode.getData('_reverse'),
                modelDivider = DIVIDER + (sectionId-1),
                section = element.getData('_section'+sectionId),
                borderSection = resizeNode.getData('_borderNode'),
                model = element.model,
                horizontal = model.horizontal,
                size = horizontal ? 'width' : 'height',
                maxSize = element['inner'+ (horizontal ? 'Width' : 'Height')] - (parseInt(borderSection.getStyle('border-'+(horizontal ? (reverseResize ? 'right' : 'left') : (reverseResize ? 'bottom' : 'top'))+'-width'), 10) || 0),
                startPos, initialSize, moveListener;
            if ((modelDivider===DIVIDER+'0') || (modelDivider===DIVIDER+'1')) {
                modelDivider = DIVIDER;
            }
            element.setClass('i-resizing');
            startPos = horizontal ? e.clientX : e.clientY;
            initialSize = section[size];
            moveListener = Event.after('mousemove', function(e2) {
                var newPos = horizontal ? e2.clientX : e2.clientY,
                    difference = newPos - startPos,
                    newSize;
                reverseResize && (difference=-difference);
                newSize = Math.inbetween(0, initialSize + difference, maxSize);
                model[modelDivider] = newSize+'px';
            });

            Event.onceAfter('mouseup', function(e3) {
                var newPos = horizontal ? e3.clientX : e3.clientY,
                    difference = newPos - startPos,
                    newSize;
                reverseResize && (difference=-difference);
                newSize = Math.inbetween(0, initialSize + difference, maxSize);
                moveListener.detach();
                element.removeClass('i-resizing');
                model[modelDivider] = newSize+'px';
            });
        }, 'i-splitdiv >section >section.resize-handle');

        Itag = DOCUMENT.defineItag(itagName, {
            attrs: {
                horizontal: 'boolean',
                divider: 'string',
                'divider-min': 'string',
                'divider-max': 'string',
                resizable: 'boolean',
                'full-page': 'boolean'
            },

            render: function() {
                var element = this,
                    designNode = element.getItagContainer(),
                    sections = designNode.getAll('>section'),
                    container = element.append('

'),
                    divider, node;
                if (sections[0]) {
                    sections[0].setAttr('section', 'first', true);
                    element.setData('_section1', container.append('
'+sections[0].getOuterHTML(null, true)+'
'));
                     // add the divider:
                    divider = container.addSystemElement('

');
                    divider.setData('_section', 1);
                    element.setData('_divider1', divider);
                }
                if (sections[1]) {
                    sections[1].setAttr('section', 'second', true);
                    node = container.append('
'+sections[1].getOuterHTML(null, true)+'
');
                    element.setData('_section2', node);
                    divider && divider.setData('_borderNode', node);
                }
                if (element.model['full-page']) {
                    documentElement.setClass('i-splitdiv-full-page');
                    bodyElement.setClass('i-splitdiv-full-page');
                }
            },

            sync: function() {
                var element = this,
                    model = element.model,
                    section1 = element.getData('_section1'),
                    section2 = element.getData('_section2'),
                    dividerNode = element.getData('_divider1'),
                    reverseResize = dividerNode.getData('_reverse'),
                    resizeSection = element.getData('_section'+dividerNode.getData('_section')),
                    divider = model.divider,
                    size, removeSize, value, indent;
                if (section1 && section2) {
                    if (model.horizontal) {
                        size = 'width';
                        removeSize = 'height';
                        indent = reverseResize ? 'right' : 'left';
                    }
                    else {
                        size = 'height';
                        removeSize = 'width';
                        indent = reverseResize ? 'bottom' : 'top';
                    }
                    value = model['divider-min'];
                    if (value) {
                        resizeSection.setInlineStyle('min-'+size, value);
                    }
                    else {
                        resizeSection.removeInlineStyle('min-'+size);
                    }
                    value = model['divider-max'];
                    if (value) {
                        resizeSection.setInlineStyle('max-'+size, value);
                    }
                    else {
                        resizeSection.removeInlineStyle('max-'+size);
                    }
                    resizeSection.removeInlineStyle('min-'+removeSize);
                    resizeSection.removeInlineStyle('max-'+removeSize);
                    resizeSection.removeInlineStyle(removeSize);
                    value = divider;
                    resizeSection.setInlineStyle(size, value);
                    dividerNode.setInlineStyle(indent, (resizeSection[size] - Math.round(dividerNode[size]/2))+'px');
                }
            },

            destroy: function() {
                if (this.model['full-page']) {
                    documentElement.removeClass('i-splitdiv-full-page');
                    bodyElement.removeClass('i-splitdiv-full-page');
                }
            }
        });

        itagCore.setContentVisibility(Itag, true);
        window.ITAGS[itagName] = Itag;
    }

    return window.ITAGS[itagName];
};<commit_msg>emitting dividerchange event<commit_after>module.exports = function (window) {
    "use strict";

    require('./css/i-splitdiv.css'); // <-- define your own itag-name here

    var itagCore = require('itags.core')(window),
        itagName = 'i-splitdiv', // <-- define your own itag-name here
        DOCUMENT = window.document,
        documentElement = DOCUMENT.documentElement,
        bodyElement = DOCUMENT.body,
        ITSA = window.ITSA,
        Event = ITSA.Event,
        DIVIDER = 'divider',
        Itag;

    if (!window.ITAGS[itagName]) {

        Event.after('mousedown', function(e) {
            var resizeNode = e.target,
                element = resizeNode.inside('i-splitdiv'),
                sectionId = resizeNode.getData('_section'),
                reverseResize = resizeNode.getData('_reverse'),
                modelDivider = DIVIDER + (sectionId-1),
                section = element.getData('_section'+sectionId),
                borderSection = resizeNode.getData('_borderNode'),
                model = element.model,
                horizontal = model.horizontal,
                size = horizontal ? 'width' : 'height',
                maxSize = element['inner'+ (horizontal ? 'Width' : 'Height')] - (parseInt(borderSection.getStyle('border-'+(horizontal ? (reverseResize ? 'right' : 'left') : (reverseResize ? 'bottom' : 'top'))+'-width'), 10) || 0),
                startPos, initialSize, moveListener, setNewSize;
            setNewSize = function(newSize) {
                var prevSize = model[modelDivider];
                if (newSize!==prevSize) {
                    model[modelDivider] = newSize;
                    /**
                    * Emitted when a the i-select changes its value
                    *
                    * @event i-select:valuechange
                    * @param e {Object} eventobject including:
                    * @param e.target {HtmlElement} the i-select element
                    * @param e.prevValue {Number} the selected item, starting with 1
                    * @param e.newValue {Number} the selected item, starting with 1
                    * @param e.buttonText {String} the text that will appear on the button
                    * @param e.listText {String} the text as it is in the list
                    * @since 0.1
                    */
                    element.emit('dividerchange', {
                        prevValue: prevSize,
                        newValue: newSize
                    });
                }
            };
            if ((modelDivider===DIVIDER+'0') || (modelDivider===DIVIDER+'1')) {
                modelDivider = DIVIDER;
            }
            element.setClass('i-resizing');
            startPos = horizontal ? e.clientX : e.clientY;
            initialSize = section[size];
            moveListener = Event.after('mousemove', function(e2) {
                var newPos = horizontal ? e2.clientX : e2.clientY,
                    difference = newPos - startPos,
                    newSize;
                reverseResize && (difference=-difference);
                newSize = Math.inbetween(0, initialSize + difference, maxSize) + 'px';
                setNewSize(newSize);
            });

            Event.onceAfter('mouseup', function(e3) {
                var newPos = horizontal ? e3.clientX : e3.clientY,
                    difference = newPos - startPos,
                    newSize;
                reverseResize && (difference=-difference);
                newSize = Math.inbetween(0, initialSize + difference, maxSize) + 'px';
                moveListener.detach();
                element.removeClass('i-resizing');
                setNewSize(newSize);
            });
        }, 'i-splitdiv >section >section.resize-handle');

        Itag = DOCUMENT.defineItag(itagName, {
            attrs: {
                horizontal: 'boolean',
                divider: 'string',
                'divider-min': 'string',
                'divider-max': 'string',
                resizable: 'boolean',
                'full-page': 'boolean'
            },

            render: function() {
                var element = this,
                    designNode = element.getItagContainer(),
                    sections = designNode.getAll('>section'),
                    container = element.append('

'),
                    divider, node;
                if (sections[0]) {
                    sections[0].setAttr('section', 'first', true);
                    element.setData('_section1', container.append('
'+sections[0].getOuterHTML(null, true)+'
'));
                     // add the divider:
                    divider = container.addSystemElement('

');
                    divider.setData('_section', 1);
                    element.setData('_divider1', divider);
                }
                if (sections[1]) {
                    sections[1].setAttr('section', 'second', true);
                    node = container.append('
'+sections[1].getOuterHTML(null, true)+'
');
                    element.setData('_section2', node);
                    divider && divider.setData('_borderNode', node);
                }
                if (element.model['full-page']) {
                    documentElement.setClass('i-splitdiv-full-page');
                    bodyElement.setClass('i-splitdiv-full-page');
                }
            },

            sync: function() {
                var element = this,
                    model = element.model,
                    section1 = element.getData('_section1'),
                    section2 = element.getData('_section2'),
                    dividerNode = element.getData('_divider1'),
                    reverseResize = dividerNode.getData('_reverse'),
                    resizeSection = element.getData('_section'+dividerNode.getData('_section')),
                    divider = model.divider,
                    size, removeSize, value, indent;
                if (section1 && section2) {
                    if (model.horizontal) {
                        size = 'width';
                        removeSize = 'height';
                        indent = reverseResize ? 'right' : 'left';
                    }
                    else {
                        size = 'height';
                        removeSize = 'width';
                        indent = reverseResize ? 'bottom' : 'top';
                    }
                    value = model['divider-min'];
                    if (value) {
                        resizeSection.setInlineStyle('min-'+size, value);
                    }
                    else {
                        resizeSection.removeInlineStyle('min-'+size);
                    }
                    value = model['divider-max'];
                    if (value) {
                        resizeSection.setInlineStyle('max-'+size, value);
                    }
                    else {
                        resizeSection.removeInlineStyle('max-'+size);
                    }
                    resizeSection.removeInlineStyle('min-'+removeSize);
                    resizeSection.removeInlineStyle('max-'+removeSize);
                    resizeSection.removeInlineStyle(removeSize);
                    value = divider;
                    resizeSection.setInlineStyle(size, value);
                    dividerNode.setInlineStyle(indent, (resizeSection[size] - Math.round(dividerNode[size]/2))+'px');
                }
            },

            destroy: function() {
                if (this.model['full-page']) {
                    documentElement.removeClass('i-splitdiv-full-page');
                    bodyElement.removeClass('i-splitdiv-full-page');
                }
            }
        });

        itagCore.setContentVisibility(Itag, true);
        window.ITAGS[itagName] = Itag;
    }

    return window.ITAGS[itagName];
};<|endoftext|>


<commit_before>/**
 * SVGPathPainter
 * A jQuery plugin that animates SVG paths to look like handdrawn.
 *
 * @version 1.0.2
 * @license MIT
 * @author Sebastian Eck
 * @email hey@eckify.com
 */
(function () {
    SVGPathPainter = new function () {
        /**
         * Class representing a path in an SVG
         * @param elem The HTML element (not jQuery)
         * @param delay The delay after which the animation starts
         * @param speed The speed factor for animation duration
         * @constructor
         */
        this.Path = function (elem, delay, speed) {
            var cssTransition;

            this.pathLength = elem.getTotalLength();
            this.$elem = $(elem)
                .css({
                    '-webkit-transition': 'none',
                    'transition': 'none'
                })
                .attr({
                    'stroke-dashoffset': this.pathLength,
                    'stroke-dasharray': this.pathLength
                });
            this.delay = delay;
            this.speed = speed;
            this.duration = Math.floor( this.pathLength * this.speed);
            // FF workaround: set the stroke width to 0 and reset it when animation begins,
            // because FF would show dots at path starts otherwise
            this.strokeWidth = this.$elem.css('stroke-width');
            this.$elem.css('stroke-width', 0);

            cssTransition = 'stroke-dashoffset ' + this.duration + 'ms ' + this.delay + 'ms linear, '+
                'stroke-width 0ms ' + this.delay + 'ms linear';

            this.paint = function () {
                this.$elem
                    .css({
                        'stroke-width': this.strokeWidth,
                        '-webkit-transition': cssTransition,
                        'transition': cssTransition
                    })
                    .attr('stroke-dashoffset', '0');
            };
        };
        /**
         * Plugin methods. 'this' refers to the plugin instance.
         * Call methods like $('#elem').plugin('method');
         */
        this.methods = {
            /**
             * Initializes the plugin. Called when no method name
             * was passed as a string in the plugin call.
             * @param options
             * @returns {*}
             */
            init: function (options) {
                var me = this,
                    defaults = {
                        initialDelay: 300,
                        pathDelay: 50,
                        speed: 1.5,
                        simultaneous: false
                    };
                /**
                 * Holds all found paths as SVGPathPainter.Path objects
                 * @type {Array}
                 */
                me.paths = [];

                // just some defaults
                if (typeof options !== 'undefined') {
                    me.options = $.extend(defaults, options);
                }
                else {
                    me.options = defaults;
                }

                return me.each(function (index, selector) {
                    var $svg, $paths, pths, pth, animatePaths, pathDelay, i, pathDuration, pathPrevDuration;

                    /**
                     * The currently handled SVG the plugin is called with
                     * @type {*|jQuery|HTMLElement}
                     */
                    $svg = $(this);
                    /**
                     * The path elements in the current SVG
                     * @type {*|jQuery|HTMLElement}
                     */
                    $paths = $('g.spp path, path.spp', $svg);
                    /**
                     * Holds all found paths as SVGPathPainter.Path objects
                     * @type {Array}
                     */
                    pths = [];
                    /**
                     * Delay for a path to animate; changes with iteration over paths
                     * @type {number}
                     */
                    pathDelay = 0;
                    /**
                     * Calls animation of the current SVG's paths
                     */
                    animatePaths = function () {
                        var i;
                        for (i = 0; i < $paths.length; i++) {
                            pths[i].paint();
                        }
                    };

                    /*
                     * Iterate through the current SVG's paths
                     */
                    for (i = 0; i < $paths.length; i++) {
                        // use 0 or the value of pathDuration used for the previous path
                        pathPrevDuration = pathDuration || 0;
                        // this path's delay
                        pathDelay = 0;
                        // if simultaneous path painting is not desired
                        if (!me.options.simultaneous) {
                          // increase this path's aniamtion delay by the prvious duration plus the pathDelay
                          pathDelay += me.options.pathDelay + pathPrevDuration;
                        }
                        // create a SVGPathPainter.Path new object
                        pth = new SVGPathPainter.Path($paths[i], pathDelay, me.options.speed);
                        // ...and store it
                        pths.push(pth);
                        // remember this path's duration for the next path
                        pathDuration = pth.duration;
                    }
                    me.paths[index] = pths;
                    // animate the path after the set initial delay
                    if (me.options.initialDelay !== false) {
                        window.setTimeout(animatePaths, me.options.initialDelay);
                    }
                });
            },

            paint: function () {
                var me = this;

                return me.each(function (index, selector) {
                    var i, j;
                    for (i = 0; i < me.paths.length; i++) {
                        for (j = 0; j < me.paths[i].length; j++) {
                            me.paths[i][j].paint();
                        }
                    }
                });
            }
        };
        /**
         * Define the basic plugin
         * @param methodOrOptions A plugin method to call or options to initialize the plugin
         * @returns {*}
         */
        this.plugin = function (methodOrOptions) {
            if (SVGPathPainter.methods[methodOrOptions]) {
                return SVGPathPainter.methods[ methodOrOptions ].apply(this, Array.prototype.slice.call(arguments, 1));
            }
            else if (typeof methodOrOptions === 'object' || !methodOrOptions) {
                // Default to "init"
                return SVGPathPainter.methods.init.apply(this, arguments);
            }
            else {
                console.error('Method ' + methodOrOptions + ' does not exist in jQuery.SVGPathPainter');
                return false;
            }
        }
    };
    /**
     * Actually initialize plugin
     */
    $.fn.SVGPathPainter = SVGPathPainter.plugin;
}());
<commit_msg>fixed a minor bug on simultaneous animation<commit_after>/**
 * SVGPathPainter
 * A jQuery plugin that animates SVG paths to look like handdrawn.
 *
 * @version 1.0.2
 * @license MIT
 * @author Sebastian Eck
 * @email hey@eckify.com
 */
(function () {
    SVGPathPainter = new function () {
        /**
         * Class representing a path in an SVG
         * @param elem The HTML element (not jQuery)
         * @param delay The delay after which the animation starts
         * @param speed The speed factor for animation duration
         * @constructor
         */
        this.Path = function (elem, delay, speed) {
            var cssTransition;

            this.pathLength = elem.getTotalLength();
            this.$elem = $(elem)
                .css({
                    '-webkit-transition': 'none',
                    'transition': 'none'
                })
                .attr({
                    'stroke-dashoffset': this.pathLength,
                    'stroke-dasharray': this.pathLength
                });
            this.delay = delay;
            this.speed = speed;
            this.duration = Math.floor( this.pathLength * this.speed);
            // FF workaround: set the stroke width to 0 and reset it when animation begins,
            // because FF would show dots at path starts otherwise
            this.strokeWidth = this.$elem.css('stroke-width');
            this.$elem.css('stroke-width', 0);

            cssTransition = 'stroke-dashoffset ' + this.duration + 'ms ' + this.delay + 'ms linear, '+
                'stroke-width 0ms ' + this.delay + 'ms linear';

            this.paint = function () {
                this.$elem
                    .css({
                        'stroke-width': this.strokeWidth,
                        '-webkit-transition': cssTransition,
                        'transition': cssTransition
                    })
                    .attr('stroke-dashoffset', '0');
            };
        };
        /**
         * Plugin methods. 'this' refers to the plugin instance.
         * Call methods like $('#elem').plugin('method');
         */
        this.methods = {
            /**
             * Initializes the plugin. Called when no method name
             * was passed as a string in the plugin call.
             * @param options
             * @returns {*}
             */
            init: function (options) {
                var me = this,
                    defaults = {
                        initialDelay: 300,
                        pathDelay: 50,
                        speed: 1.5,
                        simultaneous: false
                    };
                /**
                 * Holds all found paths as SVGPathPainter.Path objects
                 * @type {Array}
                 */
                me.paths = [];

                // just some defaults
                if (typeof options !== 'undefined') {
                    me.options = $.extend(defaults, options);
                }
                else {
                    me.options = defaults;
                }

                return me.each(function (index, selector) {
                    var $svg, $paths, pths, pth, animatePaths, pathDelay, i, pathDuration, pathPrevDuration;

                    /**
                     * The currently handled SVG the plugin is called with
                     * @type {*|jQuery|HTMLElement}
                     */
                    $svg = $(this);
                    /**
                     * The path elements in the current SVG
                     * @type {*|jQuery|HTMLElement}
                     */
                    $paths = $('g.spp path, path.spp', $svg);
                    /**
                     * Holds all found paths as SVGPathPainter.Path objects
                     * @type {Array}
                     */
                    pths = [];
                    /**
                     * Delay for a path to animate; changes with iteration over paths
                     * @type {number}
                     */
                    pathDelay = 0;
                    /**
                     * Calls animation of the current SVG's paths
                     */
                    animatePaths = function () {
                        var i;
                        for (i = 0; i < $paths.length; i++) {
                            pths[i].paint();
                        }
                    };

                    /*
                     * Iterate through the current SVG's paths
                     */
                    for (i = 0; i < $paths.length; i++) {
                        // use 0 or the value of pathDuration used for the previous path
                        pathPrevDuration = pathDuration || 0;
                        // if simultaneous path painting is not desired
                        if (!me.options.simultaneous) {
                          // increase this path's aniamtion delay by the prvious duration plus the path's delay
                          pathDelay += me.options.pathDelay + pathPrevDuration;
                        }
                        // create a SVGPathPainter.Path new object
                        pth = new SVGPathPainter.Path($paths[i], pathDelay, me.options.speed);
                        // ...and store it
                        pths.push(pth);
                        // remember this path's duration for the next path
                        pathDuration = pth.duration;
                    }
                    me.paths[index] = pths;
                    // animate the path after the set initial delay
                    if (me.options.initialDelay !== false) {
                        window.setTimeout(animatePaths, me.options.initialDelay);
                    }
                });
            },

            paint: function () {
                var me = this;

                return me.each(function (index, selector) {
                    var i, j;
                    for (i = 0; i < me.paths.length; i++) {
                        for (j = 0; j < me.paths[i].length; j++) {
                            me.paths[i][j].paint();
                        }
                    }
                });
            }
        };
        /**
         * Define the basic plugin
         * @param methodOrOptions A plugin method to call or options to initialize the plugin
         * @returns {*}
         */
        this.plugin = function (methodOrOptions) {
            if (SVGPathPainter.methods[methodOrOptions]) {
                return SVGPathPainter.methods[ methodOrOptions ].apply(this, Array.prototype.slice.call(arguments, 1));
            }
            else if (typeof methodOrOptions === 'object' || !methodOrOptions) {
                // Default to "init"
                return SVGPathPainter.methods.init.apply(this, arguments);
            }
            else {
                console.error('Method ' + methodOrOptions + ' does not exist in jQuery.SVGPathPainter');
                return false;
            }
        }
    };
    /**
     * Actually initialize plugin
     */
    $.fn.SVGPathPainter = SVGPathPainter.plugin;
}());
<|endoftext|>


<commit_before>import Ember from 'ember';
import layout from '../templates/components/fd-tabs';
import TabPane from '../components/fd-tabs/pane';
import FdWorkPanelToggler from '../mixins/fd-work-panel-toggler';

/**
 Tab component for dynamic tab functionality
 ### Usage
 Just nest any number of yielded [Components.TabPane](Components.TabPane.html) components that hold the tab content.
 The tab navigation is automatically generated from the tab panes' `title` property:
 ```hbs
 {{#fd-tabs as |tab|}}
   {{#tab.pane dataTab='tab1' title="Tab 1"}}
     <p>...</p>
   {{/tab.pane}}
   {{#tab.pane dataTab='tab2' title="Tab 2"}}
     <p>...</p>
   {{/tab.pane}}
 {{/fd-tabs}}
 ```
 @class Tab
 @namespace Components
 @extends Ember.Component
 @uses Mixins.ComponentParent
 @public
 */
export default Ember.Component.extend(FdWorkPanelToggler, {

  layout: layout,
  tabsWidth: 0,
  containerWidth: 0,
  hideTabsCount: 0,
  overflowButtonShow: false,
  selectedTab: '',
  addTab: true,
  reloadTabs: true,
  activeTab: Ember.computed.oneWay('childPanes.firstObject.dataTab'),

  options: {
    tabPadding: 25,
    containerPadding: 0,
    dropdownSize: 95
  },

  updateOverflowTabs: function() {
    if (this.overflowButtonShow) {
      if (this.addTab) {
        let _currentTabs = this.get('tabs');
        let lastTab = _currentTabs.get('lastObject');
        this.get('_hideTabs').pushObject(lastTab);
        return;
      } else {
        this.set('overflowButtonShow', false);
        this.set('_hideTabs', Ember.A());
        this.set('_showedTabs', this.get('tabs').slice());
        this.set('activeTab', this.get('tabs').get('firstObject').dataTab)
      }
    }

    Ember.run.schedule('afterRender', this,	function() {
      this._calculateWidths();

      this.set('overflowButtonShow', this.get('hideTabsCount') > 0);
      if (this.overflowButtonShow) {
        this._hideTab();
      }
    });

  },

  _calculateWidths: function() {
    let width = 0;
    let countHide = this.get('tabs').length;
    let _this = this;
    _this.containerWidth = Ember.$(this.element).parent().width() - _this.options.containerPadding - _this.options.dropdownSize;

    Ember.$(_this.element).find('a.item').each(function() {
      if ((width + Ember.$(this).outerWidth(true)) < _this.containerWidth) {
        width += Ember.$(this).outerWidth(true);
        countHide--;
      }
    });

    this.hideTabsCount = countHide;
  },

  _hideTab: function() {
    let hideTabs = this.get('hideTabsCount');
    this.set('_showedTabs', this.get('tabs').slice());

    for (let i = 0; i < hideTabs; i++) {
      let _currentTabs = this.get('_showedTabs');
      let lastTab = Ember.A(_currentTabs).get('lastObject');

      this.get('_hideTabs').pushObject(lastTab);
      _currentTabs.popObject();
      this.set('_showedTabs', _currentTabs);
    }

    this.get('_hideTabs').reverse();
  },

  /**
   * Array of registered child components
   *
   * @property children
   * @type array
   * @protected
   */
  children: null,

  _hideTabs: null,

  init() {
    this._super(...arguments);
    this.set('children', Ember.A());
    this.set('_hideTabs', Ember.A());
  },

  /**
   * Register a component as a child of this parent
   *
   * @method registerChild
   * @param child
   * @public
   */
  registerChild(child) {
    Ember.run.schedule('actions', this, function() {
      this.get('children').addObject(child);
      this.set('addTab', true);
    });
  },

  /**
   * Remove the child component from this parent component
   *
   * @method removeChild
   * @param child
   * @public
   */
  removeChild(child) {
    Ember.run.schedule('actions', this, function() {
      this.get('children').removeObject(child);
      this.set('addTab', false);
    });
  },

  /**
   * All child components
   *
   * @property childPanes
   * @type array
   * @readonly
   * @private
   */
  childPanes: Ember.computed.filter('children', function(view) {
    return view instanceof TabPane;
  }),

  _showedTabs: Ember.computed('childPanes.[]', 'childPanes.@each.{tab,title,dataTab}', function() {
    let items = Ember.A();
    this.get('tabs').forEach((tab) => {
      let item = tab;
      items.push(item);
    });

    return items;
  }),

  /**
   * Array of objects that define the tab structure
   *
   * @property tabs
   * @type array
   * @readonly
   * @private
   */
  tabs: Ember.computed('childPanes.@each.{tab,title,dataTab}', function() {
    let items = Ember.A();
    this.get('childPanes').forEach((pane) => {
      let item = pane.getProperties('tab', 'title', 'dataTab');
      items.push(item);
    });

    return items;
  }),

  tabsObserver: Ember.observer('tabs.[]', function() {
    Ember.run.schedule('afterRender', this,	function() {
      this.updateOverflowTabs();
    })
  }),

  didInsertElement() {
    this.updateOverflowTabs();
  },

  willRender() {
    this._super(...arguments);

  },

  actions: {
    tabClick(tab) {
      this.set('activeTab', tab.dataTab);
      this.sendAction('tabClick', tab);
    },

    changeLastTab(selectedValue) {
      let _this = this;

      let _currentTabs = _this.get('_showedTabs');
      let _currentHideTabs =  _this.get('_hideTabs');
      let lastTab = _currentTabs.get('lastObject');

      let replaceTabIndex = -1;
      _currentHideTabs.forEach(function(element, index) {
        if (element.title === selectedValue) {
          replaceTabIndex = index;
        }
      });

      if (replaceTabIndex > -1) {
        let activeTabIndex = _currentHideTabs[replaceTabIndex].dataTab;
        _currentTabs.popObject();
        _currentTabs.pushObject(_currentHideTabs[replaceTabIndex]);
        _currentHideTabs.replace(replaceTabIndex, 1, lastTab);

        _this.set('_showedTabs', _currentTabs);
        _this.set('_hideTabs', _currentHideTabs);
        _this.set('activeTab', activeTabIndex);
      }
    }
  }
});
<commit_msg>Fix code<commit_after>import Ember from 'ember';
import layout from '../templates/components/fd-tabs';
import TabPane from '../components/fd-tabs/pane';
import FdWorkPanelToggler from '../mixins/fd-work-panel-toggler';

/**
 Tab component for dynamic tab functionality
 ### Usage
 Just nest any number of yielded [Components.TabPane](Components.TabPane.html) components that hold the tab content.
 The tab navigation is automatically generated from the tab panes' `title` property:
 ```hbs
 {{#fd-tabs as |tab|}}
   {{#tab.pane dataTab='tab1' title="Tab 1"}}
     <p>...</p>
   {{/tab.pane}}
   {{#tab.pane dataTab='tab2' title="Tab 2"}}
     <p>...</p>
   {{/tab.pane}}
 {{/fd-tabs}}
 ```
 @class Tab
 @namespace Components
 @extends Ember.Component
 @uses Mixins.ComponentParent
 @public
 */
export default Ember.Component.extend(FdWorkPanelToggler, {

  layout: layout,
  tabsWidth: 0,
  containerWidth: 0,
  hideTabsCount: 0,
  overflowButtonShow: false,
  selectedTab: '',
  addTab: true,
  reloadTabs: true,
  activeTab: Ember.computed.oneWay('childPanes.firstObject.dataTab'),

  options: {
    tabPadding: 25,
    containerPadding: 0,
    dropdownSize: 95
  },

  updateOverflowTabs: function() {
    if (this.overflowButtonShow) {
      if (this.addTab) {
        let _currentTabs = this.get('tabs');
        let lastTab = _currentTabs.get('lastObject');
        this.get('_hideTabs').pushObject(lastTab);
        return;
      } else {
        this.set('overflowButtonShow', false);
        this.set('_hideTabs', Ember.A());
        this.set('_showedTabs', this.get('tabs').slice());
        this.set('activeTab', this.get('tabs').get('firstObject').dataTab);
      }
    }

    Ember.run.schedule('afterRender', this,	function() {
      this._calculateWidths();

      this.set('overflowButtonShow', this.get('hideTabsCount') > 0);
      if (this.overflowButtonShow) {
        this._hideTab();
      }
    });

  },

  _calculateWidths: function() {
    let width = 0;
    let countHide = this.get('tabs').length;
    let _this = this;
    _this.containerWidth = Ember.$(this.element).parent().width() - _this.options.containerPadding - _this.options.dropdownSize;

    Ember.$(_this.element).find('a.item').each(function() {
      if ((width + Ember.$(this).outerWidth(true)) < _this.containerWidth) {
        width += Ember.$(this).outerWidth(true);
        countHide--;
      }
    });

    this.hideTabsCount = countHide;
  },

  _hideTab: function() {
    let hideTabs = this.get('hideTabsCount');
    this.set('_showedTabs', this.get('tabs').slice());

    for (let i = 0; i < hideTabs; i++) {
      let _currentTabs = this.get('_showedTabs');
      let lastTab = Ember.A(_currentTabs).get('lastObject');

      this.get('_hideTabs').pushObject(lastTab);
      _currentTabs.popObject();
      this.set('_showedTabs', _currentTabs);
    }

    this.get('_hideTabs').reverse();
  },

  /**
   * Array of registered child components
   *
   * @property children
   * @type array
   * @protected
   */
  children: null,

  _hideTabs: null,

  init() {
    this._super(...arguments);
    this.set('children', Ember.A());
    this.set('_hideTabs', Ember.A());
  },

  /**
   * Register a component as a child of this parent
   *
   * @method registerChild
   * @param child
   * @public
   */
  registerChild(child) {
    Ember.run.schedule('actions', this, function() {
      this.get('children').addObject(child);
      this.set('addTab', true);
    });
  },

  /**
   * Remove the child component from this parent component
   *
   * @method removeChild
   * @param child
   * @public
   */
  removeChild(child) {
    Ember.run.schedule('actions', this, function() {
      this.get('children').removeObject(child);
      this.set('addTab', false);
    });
  },

  /**
   * All child components
   *
   * @property childPanes
   * @type array
   * @readonly
   * @private
   */
  childPanes: Ember.computed.filter('children', function(view) {
    return view instanceof TabPane;
  }),

  _showedTabs: Ember.computed('childPanes.[]', 'childPanes.@each.{tab,title,dataTab}', function() {
    let items = Ember.A();
    this.get('tabs').forEach((tab) => {
      let item = tab;
      items.push(item);
    });

    return items;
  }),

  /**
   * Array of objects that define the tab structure
   *
   * @property tabs
   * @type array
   * @readonly
   * @private
   */
  tabs: Ember.computed('childPanes.@each.{tab,title,dataTab}', function() {
    let items = Ember.A();
    this.get('childPanes').forEach((pane) => {
      let item = pane.getProperties('tab', 'title', 'dataTab');
      items.push(item);
    });

    return items;
  }),

  tabsObserver: Ember.observer('tabs.[]', function() {
    Ember.run.schedule('afterRender', this,	function() {
      this.updateOverflowTabs();
    });
  }),

  didInsertElement() {
    this.updateOverflowTabs();
  },

  willRender() {
    this._super(...arguments);

  },

  actions: {
    tabClick(tab) {
      this.set('activeTab', tab.dataTab);
      this.sendAction('tabClick', tab);
    },

    changeLastTab(selectedValue) {
      let _this = this;

      let _currentTabs = _this.get('_showedTabs');
      let _currentHideTabs =  _this.get('_hideTabs');
      let lastTab = _currentTabs.get('lastObject');

      let replaceTabIndex = -1;
      _currentHideTabs.forEach(function(element, index) {
        if (element.title === selectedValue) {
          replaceTabIndex = index;
        }
      });

      if (replaceTabIndex > -1) {
        let activeTabIndex = _currentHideTabs[replaceTabIndex].dataTab;
        _currentTabs.popObject();
        _currentTabs.pushObject(_currentHideTabs[replaceTabIndex]);
        _currentHideTabs.replace(replaceTabIndex, 1, lastTab);

        _this.set('_showedTabs', _currentTabs);
        _this.set('_hideTabs', _currentHideTabs);
        _this.set('activeTab', activeTabIndex);
      }
    }
  }
});
<|endoftext|>