<commit_before>/*
 *  Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree.
 */
'use strict';
import * as utils from '../utils';

export function shimLocalStreamsAPI(window) {
  if (typeof window !== 'object' || !window.RTCPeerConnection) {
    return;
  }
  if (!('getLocalStreams' in window.RTCPeerConnection.prototype)) {
    window.RTCPeerConnection.prototype.getLocalStreams =
      function getLocalStreams() {
        if (!this._localStreams) {
          this._localStreams = [];
        }
        return this._localStreams;
      };
  }
  if (!('addStream' in window.RTCPeerConnection.prototype)) {
    const _addTrack = window.RTCPeerConnection.prototype.addTrack;
    window.RTCPeerConnection.prototype.addStream = function addStream(stream) {
      if (!this._localStreams) {
        this._localStreams = [];
      }
      if (!this._localStreams.includes(stream)) {
        this._localStreams.push(stream);
      }
      // Try to emulate Chrome's behaviour of adding in audio-video order.
      // Safari orders by track id.
      stream.getAudioTracks().forEach(track => _addTrack.call(this, track,
        stream));
      stream.getVideoTracks().forEach(track => _addTrack.call(this, track,
        stream));
    };

    window.RTCPeerConnection.prototype.addTrack =
      function addTrack(track) {
        const stream = arguments[1];
        if (stream) {
          if (!this._localStreams) {
            this._localStreams = [stream];
          } else if (!this._localStreams.includes(stream)) {
            this._localStreams.push(stream);
          }
        }
        return _addTrack.apply(this, arguments);
      };
  }
  if (!('removeStream' in window.RTCPeerConnection.prototype)) {
    window.RTCPeerConnection.prototype.removeStream =
      function removeStream(stream) {
        if (!this._localStreams) {
          this._localStreams = [];
        }
        const index = this._localStreams.indexOf(stream);
        if (index === -1) {
          return;
        }
        this._localStreams.splice(index, 1);
        const tracks = stream.getTracks();
        this.getSenders().forEach(sender => {
          if (tracks.includes(sender.track)) {
            this.removeTrack(sender);
          }
        });
      };
  }
}

export function shimRemoteStreamsAPI(window) {
  if (typeof window !== 'object' || !window.RTCPeerConnection) {
    return;
  }
  if (!('getRemoteStreams' in window.RTCPeerConnection.prototype)) {
    window.RTCPeerConnection.prototype.getRemoteStreams =
      function getRemoteStreams() {
        return this._remoteStreams ? this._remoteStreams : [];
      };
  }
  if (!('onaddstream' in window.RTCPeerConnection.prototype)) {
    Object.defineProperty(window.RTCPeerConnection.prototype, 'onaddstream', {
      get() {
        return this._onaddstream;
      },
      set(f) {
        if (this._onaddstream) {
          this.removeEventListener('addstream', this._onaddstream);
          this.removeEventListener('track', this._onaddstreampoly);
        }
        this.addEventListener('addstream', this._onaddstream = f);
        this.addEventListener('track', this._onaddstreampoly = (e) => {
          e.streams.forEach(stream => {
            if (!this._remoteStreams) {
              this._remoteStreams = [];
            }
            if (this._remoteStreams.includes(stream)) {
              return;
            }
            this._remoteStreams.push(stream);
            const event = new Event('addstream');
            event.stream = stream;
            this.dispatchEvent(event);
          });
        });
      }
    });
    const origSetRemoteDescription =
      window.RTCPeerConnection.prototype.setRemoteDescription;
    window.RTCPeerConnection.prototype.setRemoteDescription =
      function setRemoteDescription() {
        const pc = this;
        if (!this._onaddstreampoly) {
          this.addEventListener('track', this._onaddstreampoly = function(e) {
            e.streams.forEach(stream => {
              if (!pc._remoteStreams) {
                pc._remoteStreams = [];
              }
              if (pc._remoteStreams.indexOf(stream) >= 0) {
                return;
              }
              pc._remoteStreams.push(stream);
              const event = new Event('addstream');
              event.stream = stream;
              pc.dispatchEvent(event);
            });
          });
        }
        return origSetRemoteDescription.apply(pc, arguments);
      };
  }
}

export function shimCallbacksAPI(window) {
  if (typeof window !== 'object' || !window.RTCPeerConnection) {
    return;
  }
  const prototype = window.RTCPeerConnection.prototype;
  const origCreateOffer = prototype.createOffer;
  const origCreateAnswer = prototype.createAnswer;
  const setLocalDescription = prototype.setLocalDescription;
  const setRemoteDescription = prototype.setRemoteDescription;
  const addIceCandidate = prototype.addIceCandidate;

  prototype.createOffer =
    function createOffer(successCallback, failureCallback) {
      const options = (arguments.length >= 2) ? arguments[2] : arguments[0];
      const promise = origCreateOffer.apply(this, [options]);
      if (!failureCallback) {
        return promise;
      }
      promise.then(successCallback, failureCallback);
      return Promise.resolve();
    };

  prototype.createAnswer =
    function createAnswer(successCallback, failureCallback) {
      const options = (arguments.length >= 2) ? arguments[2] : arguments[0];
      const promise = origCreateAnswer.apply(this, [options]);
      if (!failureCallback) {
        return promise;
      }
      promise.then(successCallback, failureCallback);
      return Promise.resolve();
    };

  let withCallback = function(description, successCallback, failureCallback) {
    const promise = setLocalDescription.apply(this, [description]);
    if (!failureCallback) {
      return promise;
    }
    promise.then(successCallback, failureCallback);
    return Promise.resolve();
  };
  prototype.setLocalDescription = withCallback;

  withCallback = function(description, successCallback, failureCallback) {
    const promise = setRemoteDescription.apply(this, [description]);
    if (!failureCallback) {
      return promise;
    }
    promise.then(successCallback, failureCallback);
    return Promise.resolve();
  };
  prototype.setRemoteDescription = withCallback;

  withCallback = function(candidate, successCallback, failureCallback) {
    const promise = addIceCandidate.apply(this, [candidate]);
    if (!failureCallback) {
      return promise;
    }
    promise.then(successCallback, failureCallback);
    return Promise.resolve();
  };
  prototype.addIceCandidate = withCallback;
}

export function shimGetUserMedia(window) {
  const navigator = window && window.navigator;

  if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
    // shim not needed in Safari 12.1
    const mediaDevices = navigator.mediaDevices;
    const _getUserMedia = mediaDevices.getUserMedia.bind(mediaDevices);
    navigator.mediaDevices.getUserMedia = (constraints) => {
      return _getUserMedia(shimConstraints(constraints));
    };
  }

  if (!navigator.getUserMedia && navigator.mediaDevices &&
    navigator.mediaDevices.getUserMedia) {
    navigator.getUserMedia = function getUserMedia(constraints, cb, errcb) {
      navigator.mediaDevices.getUserMedia(constraints)
      .then(cb, errcb);
    }.bind(navigator);
  }
}

export function shimConstraints(constraints) {
  if (constraints && constraints.video !== undefined) {
    return Object.assign({},
      constraints,
      {video: utils.compactObject(constraints.video)}
    );
  }

  return constraints;
}

export function shimRTCIceServerUrls(window) {
  // migrate from non-spec RTCIceServer.url to RTCIceServer.urls
  const OrigPeerConnection = window.RTCPeerConnection;
  window.RTCPeerConnection =
    function RTCPeerConnection(pcConfig, pcConstraints) {
      if (pcConfig && pcConfig.iceServers) {
        const newIceServers = [];
        for (let i = 0; i < pcConfig.iceServers.length; i++) {
          let server = pcConfig.iceServers[i];
          if (!server.hasOwnProperty('urls') &&
              server.hasOwnProperty('url')) {
            utils.deprecated('RTCIceServer.url', 'RTCIceServer.urls');
            server = JSON.parse(JSON.stringify(server));
            server.urls = server.url;
            delete server.url;
            newIceServers.push(server);
          } else {
            newIceServers.push(pcConfig.iceServers[i]);
          }
        }
        pcConfig.iceServers = newIceServers;
      }
      return new OrigPeerConnection(pcConfig, pcConstraints);
    };
  window.RTCPeerConnection.prototype = OrigPeerConnection.prototype;
  // wrap static methods. Currently just generateCertificate.
  if ('generateCertificate' in window.RTCPeerConnection) {
    Object.defineProperty(window.RTCPeerConnection, 'generateCertificate', {
      get() {
        return OrigPeerConnection.generateCertificate;
      }
    });
  }
}

export function shimTrackEventTransceiver(window) {
  // Add event.transceiver member over deprecated event.receiver
  if (typeof window === 'object' && window.RTCTrackEvent &&
      'receiver' in window.RTCTrackEvent.prototype &&
      !('transceiver' in window.RTCTrackEvent.prototype)) {
    Object.defineProperty(window.RTCTrackEvent.prototype, 'transceiver', {
      get() {
        return {receiver: this.receiver};
      }
    });
  }
}

export function shimCreateOfferLegacy(window) {
  const origCreateOffer = window.RTCPeerConnection.prototype.createOffer;
  window.RTCPeerConnection.prototype.createOffer =
    function createOffer(offerOptions) {
      if (offerOptions) {
        if (typeof offerOptions.offerToReceiveAudio !== 'undefined') {
          // support bit values
          offerOptions.offerToReceiveAudio =
            !!offerOptions.offerToReceiveAudio;
        }
        const audioTransceiver = this.getTransceivers().find(transceiver =>
          transceiver.receiver.track.kind === 'audio');
        if (offerOptions.offerToReceiveAudio === false && audioTransceiver) {
          if (audioTransceiver.direction === 'sendrecv') {
            if (audioTransceiver.setDirection) {
              audioTransceiver.setDirection('sendonly');
            } else {
              audioTransceiver.direction = 'sendonly';
            }
          } else if (audioTransceiver.direction === 'recvonly') {
            if (audioTransceiver.setDirection) {
              audioTransceiver.setDirection('inactive');
            } else {
              audioTransceiver.direction = 'inactive';
            }
          }
        } else if (offerOptions.offerToReceiveAudio === true &&
            !audioTransceiver) {
          this.addTransceiver('audio');
        }

        if (typeof offerOptions.offerToReceiveVideo !== 'undefined') {
          // support bit values
          offerOptions.offerToReceiveVideo =
            !!offerOptions.offerToReceiveVideo;
        }
        const videoTransceiver = this.getTransceivers().find(transceiver =>
          transceiver.receiver.track.kind === 'video');
        if (offerOptions.offerToReceiveVideo === false && videoTransceiver) {
          if (videoTransceiver.direction === 'sendrecv') {
            if (videoTransceiver.setDirection) {
              videoTransceiver.setDirection('sendonly');
            } else {
              videoTransceiver.direction = 'sendonly';
            }
          } else if (videoTransceiver.direction === 'recvonly') {
            if (videoTransceiver.setDirection) {
              videoTransceiver.setDirection('inactive');
            } else {
              videoTransceiver.direction = 'inactive';
            }
          }
        } else if (offerOptions.offerToReceiveVideo === true &&
            !videoTransceiver) {
          this.addTransceiver('video');
        }
      }
      return origCreateOffer.apply(this, arguments);
    };
}
<commit_msg>Fix. "TypeError: 'arguments', 'callee', and 'caller' cannot be accessed in this context, when using addTrack() method" (#1024)<commit_after>/*
 *  Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree.
 */
'use strict';
import * as utils from '../utils';

export function shimLocalStreamsAPI(window) {
  if (typeof window !== 'object' || !window.RTCPeerConnection) {
    return;
  }
  if (!('getLocalStreams' in window.RTCPeerConnection.prototype)) {
    window.RTCPeerConnection.prototype.getLocalStreams =
      function getLocalStreams() {
        if (!this._localStreams) {
          this._localStreams = [];
        }
        return this._localStreams;
      };
  }
  if (!('addStream' in window.RTCPeerConnection.prototype)) {
    const _addTrack = window.RTCPeerConnection.prototype.addTrack;
    window.RTCPeerConnection.prototype.addStream = function addStream(stream) {
      if (!this._localStreams) {
        this._localStreams = [];
      }
      if (!this._localStreams.includes(stream)) {
        this._localStreams.push(stream);
      }
      // Try to emulate Chrome's behaviour of adding in audio-video order.
      // Safari orders by track id.
      stream.getAudioTracks().forEach(track => _addTrack.call(this, track,
        stream));
      stream.getVideoTracks().forEach(track => _addTrack.call(this, track,
        stream));
    };

    window.RTCPeerConnection.prototype.addTrack =
      function addTrack(track, ...streams) {
        if (streams) {
          streams.forEach((stream) => {
            if (!this._localStreams) {
              this._localStreams = [stream];
            } else if (!this._localStreams.includes(stream)) {
              this._localStreams.push(stream);
            }
          });
        }
        return _addTrack.apply(this, arguments);
      };
  }
  if (!('removeStream' in window.RTCPeerConnection.prototype)) {
    window.RTCPeerConnection.prototype.removeStream =
      function removeStream(stream) {
        if (!this._localStreams) {
          this._localStreams = [];
        }
        const index = this._localStreams.indexOf(stream);
        if (index === -1) {
          return;
        }
        this._localStreams.splice(index, 1);
        const tracks = stream.getTracks();
        this.getSenders().forEach(sender => {
          if (tracks.includes(sender.track)) {
            this.removeTrack(sender);
          }
        });
      };
  }
}

export function shimRemoteStreamsAPI(window) {
  if (typeof window !== 'object' || !window.RTCPeerConnection) {
    return;
  }
  if (!('getRemoteStreams' in window.RTCPeerConnection.prototype)) {
    window.RTCPeerConnection.prototype.getRemoteStreams =
      function getRemoteStreams() {
        return this._remoteStreams ? this._remoteStreams : [];
      };
  }
  if (!('onaddstream' in window.RTCPeerConnection.prototype)) {
    Object.defineProperty(window.RTCPeerConnection.prototype, 'onaddstream', {
      get() {
        return this._onaddstream;
      },
      set(f) {
        if (this._onaddstream) {
          this.removeEventListener('addstream', this._onaddstream);
          this.removeEventListener('track', this._onaddstreampoly);
        }
        this.addEventListener('addstream', this._onaddstream = f);
        this.addEventListener('track', this._onaddstreampoly = (e) => {
          e.streams.forEach(stream => {
            if (!this._remoteStreams) {
              this._remoteStreams = [];
            }
            if (this._remoteStreams.includes(stream)) {
              return;
            }
            this._remoteStreams.push(stream);
            const event = new Event('addstream');
            event.stream = stream;
            this.dispatchEvent(event);
          });
        });
      }
    });
    const origSetRemoteDescription =
      window.RTCPeerConnection.prototype.setRemoteDescription;
    window.RTCPeerConnection.prototype.setRemoteDescription =
      function setRemoteDescription() {
        const pc = this;
        if (!this._onaddstreampoly) {
          this.addEventListener('track', this._onaddstreampoly = function(e) {
            e.streams.forEach(stream => {
              if (!pc._remoteStreams) {
                pc._remoteStreams = [];
              }
              if (pc._remoteStreams.indexOf(stream) >= 0) {
                return;
              }
              pc._remoteStreams.push(stream);
              const event = new Event('addstream');
              event.stream = stream;
              pc.dispatchEvent(event);
            });
          });
        }
        return origSetRemoteDescription.apply(pc, arguments);
      };
  }
}

export function shimCallbacksAPI(window) {
  if (typeof window !== 'object' || !window.RTCPeerConnection) {
    return;
  }
  const prototype = window.RTCPeerConnection.prototype;
  const origCreateOffer = prototype.createOffer;
  const origCreateAnswer = prototype.createAnswer;
  const setLocalDescription = prototype.setLocalDescription;
  const setRemoteDescription = prototype.setRemoteDescription;
  const addIceCandidate = prototype.addIceCandidate;

  prototype.createOffer =
    function createOffer(successCallback, failureCallback) {
      const options = (arguments.length >= 2) ? arguments[2] : arguments[0];
      const promise = origCreateOffer.apply(this, [options]);
      if (!failureCallback) {
        return promise;
      }
      promise.then(successCallback, failureCallback);
      return Promise.resolve();
    };

  prototype.createAnswer =
    function createAnswer(successCallback, failureCallback) {
      const options = (arguments.length >= 2) ? arguments[2] : arguments[0];
      const promise = origCreateAnswer.apply(this, [options]);
      if (!failureCallback) {
        return promise;
      }
      promise.then(successCallback, failureCallback);
      return Promise.resolve();
    };

  let withCallback = function(description, successCallback, failureCallback) {
    const promise = setLocalDescription.apply(this, [description]);
    if (!failureCallback) {
      return promise;
    }
    promise.then(successCallback, failureCallback);
    return Promise.resolve();
  };
  prototype.setLocalDescription = withCallback;

  withCallback = function(description, successCallback, failureCallback) {
    const promise = setRemoteDescription.apply(this, [description]);
    if (!failureCallback) {
      return promise;
    }
    promise.then(successCallback, failureCallback);
    return Promise.resolve();
  };
  prototype.setRemoteDescription = withCallback;

  withCallback = function(candidate, successCallback, failureCallback) {
    const promise = addIceCandidate.apply(this, [candidate]);
    if (!failureCallback) {
      return promise;
    }
    promise.then(successCallback, failureCallback);
    return Promise.resolve();
  };
  prototype.addIceCandidate = withCallback;
}

export function shimGetUserMedia(window) {
  const navigator = window && window.navigator;

  if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
    // shim not needed in Safari 12.1
    const mediaDevices = navigator.mediaDevices;
    const _getUserMedia = mediaDevices.getUserMedia.bind(mediaDevices);
    navigator.mediaDevices.getUserMedia = (constraints) => {
      return _getUserMedia(shimConstraints(constraints));
    };
  }

  if (!navigator.getUserMedia && navigator.mediaDevices &&
    navigator.mediaDevices.getUserMedia) {
    navigator.getUserMedia = function getUserMedia(constraints, cb, errcb) {
      navigator.mediaDevices.getUserMedia(constraints)
      .then(cb, errcb);
    }.bind(navigator);
  }
}

export function shimConstraints(constraints) {
  if (constraints && constraints.video !== undefined) {
    return Object.assign({},
      constraints,
      {video: utils.compactObject(constraints.video)}
    );
  }

  return constraints;
}

export function shimRTCIceServerUrls(window) {
  // migrate from non-spec RTCIceServer.url to RTCIceServer.urls
  const OrigPeerConnection = window.RTCPeerConnection;
  window.RTCPeerConnection =
    function RTCPeerConnection(pcConfig, pcConstraints) {
      if (pcConfig && pcConfig.iceServers) {
        const newIceServers = [];
        for (let i = 0; i < pcConfig.iceServers.length; i++) {
          let server = pcConfig.iceServers[i];
          if (!server.hasOwnProperty('urls') &&
              server.hasOwnProperty('url')) {
            utils.deprecated('RTCIceServer.url', 'RTCIceServer.urls');
            server = JSON.parse(JSON.stringify(server));
            server.urls = server.url;
            delete server.url;
            newIceServers.push(server);
          } else {
            newIceServers.push(pcConfig.iceServers[i]);
          }
        }
        pcConfig.iceServers = newIceServers;
      }
      return new OrigPeerConnection(pcConfig, pcConstraints);
    };
  window.RTCPeerConnection.prototype = OrigPeerConnection.prototype;
  // wrap static methods. Currently just generateCertificate.
  if ('generateCertificate' in window.RTCPeerConnection) {
    Object.defineProperty(window.RTCPeerConnection, 'generateCertificate', {
      get() {
        return OrigPeerConnection.generateCertificate;
      }
    });
  }
}

export function shimTrackEventTransceiver(window) {
  // Add event.transceiver member over deprecated event.receiver
  if (typeof window === 'object' && window.RTCTrackEvent &&
      'receiver' in window.RTCTrackEvent.prototype &&
      !('transceiver' in window.RTCTrackEvent.prototype)) {
    Object.defineProperty(window.RTCTrackEvent.prototype, 'transceiver', {
      get() {
        return {receiver: this.receiver};
      }
    });
  }
}

export function shimCreateOfferLegacy(window) {
  const origCreateOffer = window.RTCPeerConnection.prototype.createOffer;
  window.RTCPeerConnection.prototype.createOffer =
    function createOffer(offerOptions) {
      if (offerOptions) {
        if (typeof offerOptions.offerToReceiveAudio !== 'undefined') {
          // support bit values
          offerOptions.offerToReceiveAudio =
            !!offerOptions.offerToReceiveAudio;
        }
        const audioTransceiver = this.getTransceivers().find(transceiver =>
          transceiver.receiver.track.kind === 'audio');
        if (offerOptions.offerToReceiveAudio === false && audioTransceiver) {
          if (audioTransceiver.direction === 'sendrecv') {
            if (audioTransceiver.setDirection) {
              audioTransceiver.setDirection('sendonly');
            } else {
              audioTransceiver.direction = 'sendonly';
            }
          } else if (audioTransceiver.direction === 'recvonly') {
            if (audioTransceiver.setDirection) {
              audioTransceiver.setDirection('inactive');
            } else {
              audioTransceiver.direction = 'inactive';
            }
          }
        } else if (offerOptions.offerToReceiveAudio === true &&
            !audioTransceiver) {
          this.addTransceiver('audio');
        }

        if (typeof offerOptions.offerToReceiveVideo !== 'undefined') {
          // support bit values
          offerOptions.offerToReceiveVideo =
            !!offerOptions.offerToReceiveVideo;
        }
        const videoTransceiver = this.getTransceivers().find(transceiver =>
          transceiver.receiver.track.kind === 'video');
        if (offerOptions.offerToReceiveVideo === false && videoTransceiver) {
          if (videoTransceiver.direction === 'sendrecv') {
            if (videoTransceiver.setDirection) {
              videoTransceiver.setDirection('sendonly');
            } else {
              videoTransceiver.direction = 'sendonly';
            }
          } else if (videoTransceiver.direction === 'recvonly') {
            if (videoTransceiver.setDirection) {
              videoTransceiver.setDirection('inactive');
            } else {
              videoTransceiver.direction = 'inactive';
            }
          }
        } else if (offerOptions.offerToReceiveVideo === true &&
            !videoTransceiver) {
          this.addTransceiver('video');
        }
      }
      return origCreateOffer.apply(this, arguments);
    };
}
<|endoftext|>


<commit_before>
var Actor, Commit, Diff, Head, Ref, Repo, Status, Tag, Tree, cmd, _, _ref, Q;

Q = require('q');
_ = require('underscore');
cmd = require('./git');
Actor = require('./actor');
Commit = require('./commit');
Tree = require('./tree');
Diff = require('./diff');
Tag = require('./tag');
Status = require('./status');
_ref = require('./ref'), Ref = _ref.Ref, Head = _ref.Head;

module.exports = Repo = (function() {
    function Repo(path, bare) {
        this.path = path;
        this.bare = bare;
        if (this.bare) {
            this.dot_git = this.path;
        } else {
            this.dot_git = "" + this.path + "/.git";
        }
        this.git = cmd(this.path, this.dot_git);
    }

    Repo.prototype.identity = function() {
        var that = this;
        var email, name;

        return this.git("config", {}, ["user.email"]).then(function(out) {
            if (out.stdout == null) {
                out.stdout = '';
            }
            email = out.stdout != null ? out.stdout.trim() : void 0;
            return that.git("config", {}, ["user.name"])
        }).then(function(out) {
            if (out.stdout == null) {
                out.stdout = '';
            }
            name = out.stdout != null ? out.stdout.trim() : void 0;
            return new Actor(name, email);
        });
    };

    Repo.prototype.identify = function(actor) {
        var that = this;
        return this.git("config", {}, ["user.email", "\"" + actor.email + "\""]).then(function() {
            return that.git("config", {}, ["user.name", "\"" + actor.name + "\""]);
        });
    };

    Repo.prototype.commits = function(start, limit, skip) {
        if (start == null) {
            start = "master";
        }
        if (limit == null) {
            limit = 10;
        }
        if (skip == null) {
            skip = 0;
        }
        return Commit.find_all(this, start, {
            "max-count": limit,
            skip: skip
        });
    };

    Repo.prototype.tree = function(treeish) {
        if (treeish == null) {
            treeish = "master";
        }
        return new Tree(this, treeish);
    };

    Repo.prototype.diff = function(commitA, commitB, paths) {
        var that = this;
        if (paths == null) {
            paths = [];
        }
        if (_.isObject(commitA)) {
            commitA = commitA.id;
        }
        if (_.isObject(commitB)) {
            commitB = commitB.id;
        }
        return this.git("diff", {}, _.flatten([commitA, commitB, "--", paths])).then(function(out) {
            return Diff.parse(that, out.stdout);
        });
    };

    Repo.prototype.remotes = function() {
        return Ref.find_all(this, "remote", Ref);
    };

    Repo.prototype.remote_list = function() {
        return this.git.list_remotes();
    };

    Repo.prototype.remote_add = function(name, url) {
        return this.git("remote", {}, ["add", name, url]);
    };

    Repo.prototype.remote_remove = function(name) {
        return this.git("remote", {}, ["rm", name]);
    };

    Repo.prototype.remote_fetch = function(name) {
        return this.git("fetch", {}, name);
    };

    Repo.prototype.remote_push = function(name) {
        return this.git("push", {}, name);
    };

    Repo.prototype.merge = function(name) {
        return this.git("merge", {}, name);
    };

    Repo.prototype.status = function() {
        return Status(this);
    };

    Repo.prototype.tags = function() {
        return Tag.find_all(this);
    };

    Repo.prototype.create_tag = function(name, options) {
        return this.git("tag", options, [name]);
    };

    Repo.prototype.delete_tag = function(name) {
        return this.git("tag", {
            d: name
        });
    };

    Repo.prototype.branches = function() {
        return Head.find_all(this);
    };

    Repo.prototype.create_branch = function(name) {
        return this.git("branch", {}, name);
    };

    Repo.prototype.delete_branch = function(name) {
        return this.git("branch", {
            d: true
        }, name);
    };

    Repo.prototype.branch = function(name) {
        if (!name) {
            return Head.current(this);
        } else {
            return this.branches().then(function(heads) {
                var head, _i, _len;
                for (_i = 0, _len = heads.length; _i < _len; _i++) {
                    head = heads[_i];
                    if (head.name === name) {
                        return  head;
                    }
                }
                return Q.reject(new Error("No branch named '" + name + "' found"));
            });
        }
    };

    Repo.prototype.checkout = function(treeish) {
        return this.git("checkout", {}, treeish);
    };

    Repo.prototype.commit = function(message, options) {
        if (options == null) {
            options = {};
        }
        options = _.extend(options, {
            m: "'" + message + "'"
        });
        return this.git("commit", options);
    };

    Repo.prototype.add = function(files) {
        if (_.isString(files)) {
            files = [files];
        }
        return this.git("add", {}, files);
    };

    Repo.prototype.remove = function(files) {
        if (_.isString(files)) {
            files = [files];
        }
        return this.git("rm", {}, files);
    };

    Repo.prototype.revert = function(sha) {
        return this.git("revert", {}, sha);
    };

    Repo.prototype.sync = function(remote_name, branch_name) {
        var branch, remote, status, that = this;

        remote = remote_name;
        branch = branch_name;

        if (!branch) {
            branch = remote_name;
            remote = "origin";
        }

        branch = branch || "master";
        return this.status().then(function(stat) {
            status = stat;
            return that.git("stash", {}, ["save"]);
        }).then(function(out) {
            return that.pull(remote, branch);
        }).then(function(out) {
            return that.push(remote, branch);
        }).then(function() {
            if (!(status != null ? status.clean : void 0)) {
                return that.git("stash", {}, ["pop"]);
            } else {
                return Q();
            }
        });
    };

    Repo.prototype.pull = function(remote, branch) {
        remote = remote || "origin";
        branch = branch || "master";
        return this.git("pull", {}, [remote, branch]);
    };

    Repo.prototype.push = function(remote, branch) {
        remote = remote || "origin";
        branch = branch || "master";
        return this.git("push", {}, [remote, branch]);
    };

    Repo.prototype.track = function(files) {
        return this.git('add', {
            'N': true
        }, files).then(Q());
    };

    Repo.prototype.untrack = function(files) {
        return this.git('rm', {
            'r': true,
            'cached': true,
        }, files).then(Q());
    };

    Repo.prototype.untracked_files = function() {
        return this.status()
        .then(function(status) {
            return _.filter(_.keys(status.files), function(name) {
                return status.files[name].tracked === false;
            });
        }).then(Q());
    };

    Repo.prototype.stage_files = function(files) {
        return this._git('add', {
            // -A option
            'A': true
        }, files).then(Q(files));
    };

    // Diff of the current working directory
    // This pushes things to the index, we could avoid that maybe
    Repo.prototype.diff_working = function() {
        var that = this;
        return this.untracked_files()
        .then(function(files) {

            var _diff;
            var setDiff = function(d) {
                _diff = d;
            };
            var getDiff = function() {
                return _diff;
            };

            var diff = _.partial(that.diff, null, null);
            var track = _.partial(that.track, files);
            var untrack = _.partial(that.untrack, files);

            if(_.isEmpty(files)) {
                return diff();
            }

            return track()
            .then(diff)
            .then(setDiff)
            .then(untrack)
            .then(getDiff);
        });
    };

    Repo.prototype.current_branch = function() {
        return this.branch().get('name');
    };

    Repo.prototype.commits_pending = function() {
        var that = this;
        return this.current_branch().then(function(branch) {
            return that.commits('origin/'+branch+'..');
        });
    };

    Repo.prototype.commitWith = function(name, email, msg, files) {
        files = files || [];

        var newIdentity = {
            name: name,
            email: email
        };

        var _author;
        var setAuthor = function(a) {
            _author = a;
        };
        var getAuthor = function() {
            return _author;
        };

        var setIdentity = _.partial(this.identify, newIdentity);

        var identity = this.identity;
        var identify = this.identify;

        var stage = this.stage_files.bind(this, files);
        var commit = this.commit.bind(this, msg);

        return identity()
        .then(function(author) {
            return setAuthor(author);
        }, function() {
            // Identity may fail depending on "git config"
            return setAuthor(newIdentity);
        })
        .then(function() {
            // Set newIdentity from args
            return setIdentity();
        })
        .then(function() {
            // Stage files
            return stage();
        })
        .then(function() {
            // Do commit with new identity
            return commit();
        })
        .then(function() {
            // Restore previous identity
            return identify(getAuthor());
        });
    };

    return Repo;

})();
<commit_msg>Correct commit<commit_after>
var Actor, Commit, Diff, Head, Ref, Repo, Status, Tag, Tree, cmd, _, _ref, Q;

Q = require('q');
_ = require('underscore');
cmd = require('./git');
Actor = require('./actor');
Commit = require('./commit');
Tree = require('./tree');
Diff = require('./diff');
Tag = require('./tag');
Status = require('./status');
_ref = require('./ref'), Ref = _ref.Ref, Head = _ref.Head;

module.exports = Repo = (function() {
    function Repo(path, bare) {
        this.path = path;
        this.bare = bare;
        if (this.bare) {
            this.dot_git = this.path;
        } else {
            this.dot_git = "" + this.path + "/.git";
        }
        this.git = cmd(this.path, this.dot_git);
    }

    Repo.prototype.identity = function() {
        var that = this;
        var email, name;

        return this.git("config", {}, ["user.email"]).then(function(out) {
            if (out.stdout == null) {
                out.stdout = '';
            }
            email = out.stdout != null ? out.stdout.trim() : void 0;
            return that.git("config", {}, ["user.name"])
        }).then(function(out) {
            if (out.stdout == null) {
                out.stdout = '';
            }
            name = out.stdout != null ? out.stdout.trim() : void 0;
            return new Actor(name, email);
        });
    };

    Repo.prototype.identify = function(actor) {
        var that = this;
        return this.git("config", {}, ["user.email", "\"" + actor.email + "\""]).then(function() {
            return that.git("config", {}, ["user.name", "\"" + actor.name + "\""]);
        });
    };

    Repo.prototype.commits = function(start, limit, skip) {
        if (start == null) {
            start = "master";
        }
        if (limit == null) {
            limit = 10;
        }
        if (skip == null) {
            skip = 0;
        }
        return Commit.find_all(this, start, {
            "max-count": limit,
            skip: skip
        });
    };

    Repo.prototype.tree = function(treeish) {
        if (treeish == null) {
            treeish = "master";
        }
        return new Tree(this, treeish);
    };

    Repo.prototype.diff = function(commitA, commitB, paths) {
        var that = this;
        if (paths == null) {
            paths = [];
        }
        if (_.isObject(commitA)) {
            commitA = commitA.id;
        }
        if (_.isObject(commitB)) {
            commitB = commitB.id;
        }
        return this.git("diff", {}, _.flatten([commitA, commitB, "--", paths])).then(function(out) {
            return Diff.parse(that, out.stdout);
        });
    };

    Repo.prototype.remotes = function() {
        return Ref.find_all(this, "remote", Ref);
    };

    Repo.prototype.remote_list = function() {
        return this.git.list_remotes();
    };

    Repo.prototype.remote_add = function(name, url) {
        return this.git("remote", {}, ["add", name, url]);
    };

    Repo.prototype.remote_remove = function(name) {
        return this.git("remote", {}, ["rm", name]);
    };

    Repo.prototype.remote_fetch = function(name) {
        return this.git("fetch", {}, name);
    };

    Repo.prototype.remote_push = function(name) {
        return this.git("push", {}, name);
    };

    Repo.prototype.merge = function(name) {
        return this.git("merge", {}, name);
    };

    Repo.prototype.status = function() {
        return Status(this);
    };

    Repo.prototype.tags = function() {
        return Tag.find_all(this);
    };

    Repo.prototype.create_tag = function(name, options) {
        return this.git("tag", options, [name]);
    };

    Repo.prototype.delete_tag = function(name) {
        return this.git("tag", {
            d: name
        });
    };

    Repo.prototype.branches = function() {
        return Head.find_all(this);
    };

    Repo.prototype.create_branch = function(name) {
        return this.git("branch", {}, name);
    };

    Repo.prototype.delete_branch = function(name) {
        return this.git("branch", {
            d: true
        }, name);
    };

    Repo.prototype.branch = function(name) {
        if (!name) {
            return Head.current(this);
        } else {
            return this.branches().then(function(heads) {
                var head, _i, _len;
                for (_i = 0, _len = heads.length; _i < _len; _i++) {
                    head = heads[_i];
                    if (head.name === name) {
                        return  head;
                    }
                }
                return Q.reject(new Error("No branch named '" + name + "' found"));
            });
        }
    };

    Repo.prototype.checkout = function(treeish) {
        return this.git("checkout", {}, treeish);
    };

    Repo.prototype.commit = function(message, options) {
        if (options == null) {
            options = {};
        }
        options = _.extend(options, {
            m: "'" + message + "'"
        });
        return this.git("commit", options);
    };

    Repo.prototype.add = function(files) {
        if (_.isString(files)) {
            files = [files];
        }
        return this.git("add", {}, files);
    };

    Repo.prototype.remove = function(files) {
        if (_.isString(files)) {
            files = [files];
        }
        return this.git("rm", {}, files);
    };

    Repo.prototype.revert = function(sha) {
        return this.git("revert", {}, sha);
    };

    Repo.prototype.sync = function(remote_name, branch_name) {
        var branch, remote, status, that = this;

        remote = remote_name;
        branch = branch_name;

        if (!branch) {
            branch = remote_name;
            remote = "origin";
        }

        branch = branch || "master";
        return this.status().then(function(stat) {
            status = stat;
            return that.git("stash", {}, ["save"]);
        }).then(function(out) {
            return that.pull(remote, branch);
        }).then(function(out) {
            return that.push(remote, branch);
        }).then(function() {
            if (!(status != null ? status.clean : void 0)) {
                return that.git("stash", {}, ["pop"]);
            } else {
                return Q();
            }
        });
    };

    Repo.prototype.pull = function(remote, branch) {
        remote = remote || "origin";
        branch = branch || "master";
        return this.git("pull", {}, [remote, branch]);
    };

    Repo.prototype.push = function(remote, branch) {
        remote = remote || "origin";
        branch = branch || "master";
        return this.git("push", {}, [remote, branch]);
    };

    Repo.prototype.track = function(files) {
        return this.git('add', {
            'N': true
        }, files).then(Q());
    };

    Repo.prototype.untrack = function(files) {
        return this.git('rm', {
            'r': true,
            'cached': true,
        }, files).then(Q());
    };

    Repo.prototype.untracked_files = function() {
        return this.status()
        .then(function(status) {
            return _.filter(_.keys(status.files), function(name) {
                return status.files[name].tracked === false;
            });
        }).then(Q());
    };

    Repo.prototype.stage_files = function(files) {
        return this._git('add', {
            // -A option
            'A': true
        }, files).then(Q(files));
    };

    // Diff of the current working directory
    // This pushes things to the index, we could avoid that maybe
    Repo.prototype.diff_working = function() {
        var that = this;
        return this.untracked_files()
        .then(function(files) {

            var _diff;
            var setDiff = function(d) {
                _diff = d;
            };
            var getDiff = function() {
                return _diff;
            };

            var diff = _.partial(that.diff, null, null);
            var track = _.partial(that.track, files);
            var untrack = _.partial(that.untrack, files);

            if(_.isEmpty(files)) {
                return diff();
            }

            return track()
            .then(diff)
            .then(setDiff)
            .then(untrack)
            .then(getDiff);
        });
    };

    Repo.prototype.current_branch = function() {
        return this.branch().get('name');
    };

    Repo.prototype.commits_pending = function() {
        var that = this;
        return this.current_branch().then(function(branch) {
            return that.commits('origin/'+branch+'..');
        });
    };

    Repo.prototype.commitWith = function(name, email, msg, files) {
        var that = this;
        files = files || [];

        var newIdentity = {
            name: name,
            email: email
        };

        var _author;
        var setAuthor = function(a) {
            _author = a;
        };
        var getAuthor = function() {
            return _author;
        };

        return that.identity()
        .then(function(author) {
            return setAuthor(author);
        }, function() {
            // Identity may fail depending on "git config"
            return setAuthor(newIdentity);
        })
        .then(function() {
            // Set newIdentity from args
            return that.identify(newIdentity);
        })
        .then(function() {
            // Stage files
            return that.stage_files(files);
        })
        .then(function() {
            // Do commit with new identity
            return that.commit(msg);
        })
        .then(function() {
            // Restore previous identity
            return that.identify(getAuthor());
        });
    };

    return Repo;

})();
<|endoftext|>


<commit_before>require("./matrix");

describe("Matrix", function() {

  it("extracts a row", function() {
    var matrix = new Matrix("1 2\n10 20");
    expect(matrix.rows[0]).toEqual([1,2]);
  });

  it("extracts other row", function() {
    var matrix = new Matrix("9 8 7\n19 18 17");
    expect(matrix.rows[1]).toEqual([19, 18, 17]);
  });

  it("extracts a column", function() {
    var matrix = new Matrix("1 2 3\n4 5 6\n7 8 9\n 8 7 6");
    expect(matrix.columns[0]).toEqual([1, 4, 7, 8]);
  });

  it("extracts another column", function() {
    var matrix = new Matrix("89 1903 3\n18 3 1\n9 4 800");
    expect(matrix.columns[1]).toEqual([1903, 3, 4]);
  });

  it("no saddle point", function() {
    var matrix = new Matrix("2 1\n1 2");
    expect(matrix.saddlePoints).toEqual([]);
  });

  it("a saddle point", function() {
    var matrix = new Matrix("1 2\n3 4");
    expect(matrix.saddlePoints).toEqual([[1,0]]);
  });

  it("another saddle point", function() {
    var matrix = new Matrix("18 3 39 19 91\n38 10 8 77 320\n3 4 8 6 7");
    expect(matrix.saddlePoints).toEqual([[2,2]]);
  });

  it("multiple saddle points", function() {
    var matrix = new Matrix("4 5 4\n3 5 5\n1 5 4");
    expect(matrix.saddlePoints).toEqual([[1, 0], [1, 1], [1, 2]]);
  });
});<commit_msg>skips all but first test<commit_after>require("./matrix");

describe("Matrix", function() {

  it("extracts a row", function() {
    var matrix = new Matrix("1 2\n10 20");
    expect(matrix.rows[0]).toEqual([1,2]);
  });

  xit("extracts other row", function() {
    var matrix = new Matrix("9 8 7\n19 18 17");
    expect(matrix.rows[1]).toEqual([19, 18, 17]);
  });

  xit("extracts a column", function() {
    var matrix = new Matrix("1 2 3\n4 5 6\n7 8 9\n 8 7 6");
    expect(matrix.columns[0]).toEqual([1, 4, 7, 8]);
  });

  xit("extracts another column", function() {
    var matrix = new Matrix("89 1903 3\n18 3 1\n9 4 800");
    expect(matrix.columns[1]).toEqual([1903, 3, 4]);
  });

  xit("no saddle point", function() {
    var matrix = new Matrix("2 1\n1 2");
    expect(matrix.saddlePoints).toEqual([]);
  });

  xit("a saddle point", function() {
    var matrix = new Matrix("1 2\n3 4");
    expect(matrix.saddlePoints).toEqual([[1,0]]);
  });

  xit("another saddle point", function() {
    var matrix = new Matrix("18 3 39 19 91\n38 10 8 77 320\n3 4 8 6 7");
    expect(matrix.saddlePoints).toEqual([[2,2]]);
  });

  xit("multiple saddle points", function() {
    var matrix = new Matrix("4 5 4\n3 5 5\n1 5 4");
    expect(matrix.saddlePoints).toEqual([[1, 0], [1, 1], [1, 2]]);
  });
});<|endoftext|>


<commit_before>define([
    'views/widgets/CodePane',
    'views/widgets/IcdCodeVisualisationCard',
    'models/BreadcrumbModel',
    'views/widgets/Breadcrumb',
    'announcements/OnBreadcrumbSelected'
], function(
    CodePane,
    IcdCodeVisualisationCard,
    BreadcrumbModel,
    Breadcrumb,
    OnBreadcrumbSelected
){

    function IcdCodePane() {
        var _this = new CodePane();

        _this.newSelectorModel = override(_this, _this.newSelectorModel, function () {
            return this.super().characterRange();
        });

        _this.load = override(_this, _this.load, function(){
           this.super('/api/v1/codes/icd');
            _this.renderBreadcrumb();
            return _this;
        });

        _this.groupPrefix = function () {
            return 'icd';
        };

        _this.newCodeCard = function () {
            return new IcdCodeVisualisationCard();
        };

        _this.renderBreadcrumb = function () {
            var breadcrumb = new Breadcrumb();
            _this.leftPane().prepend(breadcrumb);

            var breadcrumbModel = new BreadcrumbModel()
                .level()
                    .label(function(){return _this.groupPrefix().toUpperCase();})
                    .next(_.identity)
                    .sameDefault()
                    .end()
                .level()
                    .defaultLabel(function(){return 'Alle Kapiteln'})
                    .label(function(chapter){return 'Kapitel '+chapter.roman_number + ' ' + chapter.nonterminals})
                    .next(function(chapter){return chapter.icd_chapter_groups})
                    .sameDefault()
                    .end()
                .level()
                    .defaultLabel(function(){return 'Alle Gruppe'})
                    .label(function(group) {return 'Gruppe '+group.code})
                    .next(function(group){return group.icd_nonterminals})
                    .sameDefault()
                    .end()
                .level()
                    .defaultLabel(function(){return 'Alle Nonterminale'})
                    .label(function(nonterminal) {return 'Nonterminal '+nonterminal.code})
                    .end();

            var searchFilter = function (candidates) {
                var nonterminals = _.flatten([_.last(breadcrumbModel.selected().path()).entity()]);
                var lastTrueIndex = 0;
                function match(candidate, nonterminal) {
                    return _s(candidate.code).startsWith(nonterminal.code);
                }
                function isMatches (candidate) {
                    for (var i = lastTrueIndex; i < nonterminals.length; i++) {
                        if (match(candidate, nonterminals[i])) {
                            lastTrueIndex = i;
                            return true;
                        }
                    }
                    return false;
                }
                return _.filter(candidates, isMatches);
            };

            breadcrumbModel.announcer().onSendTo(OnBreadcrumbSelected, function(){
                _this.searchModel().allCandidatesLogic(searchFilter);
            }, this);

            $.getJSON('/api/v1/groups/icd', function(result){
                breadcrumbModel.on(result);
                breadcrumb.model(breadcrumbModel);
            });
        };

        return _this;
    }

    return IcdCodePane;

});<commit_msg>Fixed typos<commit_after>define([
    'views/widgets/CodePane',
    'views/widgets/IcdCodeVisualisationCard',
    'models/BreadcrumbModel',
    'views/widgets/Breadcrumb',
    'announcements/OnBreadcrumbSelected'
], function(
    CodePane,
    IcdCodeVisualisationCard,
    BreadcrumbModel,
    Breadcrumb,
    OnBreadcrumbSelected
){

    function IcdCodePane() {
        var _this = new CodePane();

        _this.newSelectorModel = override(_this, _this.newSelectorModel, function () {
            return this.super().characterRange();
        });

        _this.load = override(_this, _this.load, function(){
           this.super('/api/v1/codes/icd');
            _this.renderBreadcrumb();
            return _this;
        });

        _this.groupPrefix = function () {
            return 'icd';
        };

        _this.newCodeCard = function () {
            return new IcdCodeVisualisationCard();
        };

        _this.renderBreadcrumb = function () {
            var breadcrumb = new Breadcrumb();
            _this.leftPane().prepend(breadcrumb);

            var breadcrumbModel = new BreadcrumbModel()
                .level()
                    .label(function(){return _this.groupPrefix().toUpperCase();})
                    .next(_.identity)
                    .sameDefault()
                    .end()
                .level()
                    .defaultLabel(function(){return 'Alle Kapitel'})
                    .label(function(chapter){return 'Kapitel '+chapter.roman_number + ' ' + chapter.nonterminals})
                    .next(function(chapter){return chapter.icd_chapter_groups})
                    .sameDefault()
                    .end()
                .level()
                    .defaultLabel(function(){return 'Alle Gruppen'})
                    .label(function(group) {return 'Gruppe '+group.code})
                    .next(function(group){return group.icd_nonterminals})
                    .sameDefault()
                    .end()
                .level()
                    .defaultLabel(function(){return 'Alle Nonterminals'})
                    .label(function(nonterminal) {return 'Nonterminal '+nonterminal.code})
                    .end();

            var searchFilter = function (candidates) {
                var nonterminals = _.flatten([_.last(breadcrumbModel.selected().path()).entity()]);
                var lastTrueIndex = 0;
                function match(candidate, nonterminal) {
                    return _s(candidate.code).startsWith(nonterminal.code);
                }
                function isMatches (candidate) {
                    for (var i = lastTrueIndex; i < nonterminals.length; i++) {
                        if (match(candidate, nonterminals[i])) {
                            lastTrueIndex = i;
                            return true;
                        }
                    }
                    return false;
                }
                return _.filter(candidates, isMatches);
            };

            breadcrumbModel.announcer().onSendTo(OnBreadcrumbSelected, function(){
                _this.searchModel().allCandidatesLogic(searchFilter);
            }, this);

            $.getJSON('/api/v1/groups/icd', function(result){
                breadcrumbModel.on(result);
                breadcrumb.model(breadcrumbModel);
            });
        };

        return _this;
    }

    return IcdCodePane;

});<|endoftext|>


<commit_before>SUDOKU = (function () {

	var generateBoardValues = function () {
		var boardvalues = [
				2, 0, 0, 0, 0, 7, 0, 0, 0,
				0, 5, 0, 0, 2, 0, 0, 1, 0,
				0, 3, 0, 0, 8, 0, 0, 7, 0,
				0, 0, 5, 7, 0, 0, 0, 0, 2,
				1, 0, 0, 0, 0, 0, 0, 0, 3,
				9, 0, 0, 0, 0, 6, 1, 0, 0,
				0, 2, 0, 0, 7, 0, 0, 8, 0,
				0, 8, 0, 0, 9, 0, 0, 5, 0,
				0, 0, 0, 4, 0, 0, 0, 0, 6
			];

		return boardvalues;

		/*$('td').each(function () {
			boardvalues[i] = boardvalues[i] !== 0 ? boardvalues[i] : '';
			$(this).html(boardvalues[i]);
			i++;
		});*/

	};

	var createBoard = function () {
		//alert('createBoard');
		var table = '

',
			row = 0,
			col = 0,
			td = '',
			tr = [];

		for (col = 0; col < 9; col++) {
			td = td + '	';
		}

		for (row = 0; row < 9; row++) {
			table = table + '
' + td + '
'
		}
		table = table + '

';
		$('#sudokuContainer').append(table);
		setBoardValues(table);

		return table;
	};

	return {
		generateBoardValues: generateBoardValues
	};
})();<commit_msg>removing an unnecessary file<commit_after><|endoftext|>


<commit_before>var Cipher = require('./example');

describe('Random key cipher', function () {
  var cipher = new Cipher();

  it('has a key made of letters', function () {
    expect(cipher.key).toMatch(/[a-z]+/);
  });

  // Here we take advantage of the fact that plaintext of "aaa..."
  // outputs the key. This is a critical problem with shift ciphers, some
  // characters will always output the key verbatim.
  it('can encode', function () {
    expect(cipher.encode('aaaaaaaaaa')).toEqual(cipher.key.substr(0,10));
  });

  it('can decode', function () {
    expect(cipher.decode(cipher.key.substr(0,10))).toEqual('aaaaaaaaaa');
  });

  it('is reversible', function () {
    var plaintext = 'abcdefghij';
    expect(cipher.decode(cipher.encode(plaintext))).toEqual(plaintext);
  });

});

describe('Incorrect key cipher', function () {

  it('throws an error with an all caps key', function () {
    expect( function () {
      new Cipher("ABCDEF");
    }).toThrow(new Error("Bad key"));
  });

  it('throws an error with a numeric key', function () {
    expect( function () {
      new Cipher("12345");
    }).toThrow(new Error("Bad key"));
  });

  it('throws an error with an empty key', function () {
    expect( function () {
      new Cipher("");
    }).toThrow(new Error("Bad key"));
  });

});

describe('Substitution cipher', function () {
  var key = 'abcdefghij';
  var cipher = new Cipher(key);

  it('keeps the submitted key', function () {
    expect(cipher.key).toEqual(key);
  });

  it('can encode', function () {
    expect(cipher.encode('aaaaaaaaaa')).toEqual('abcdefghij');
  });

  it('can decode', function () {
    expect(cipher.decode('abcdefghij')).toEqual('aaaaaaaaaa');
  });

  it('is reversible', function () {
    expect(cipher.decode(cipher.encode('abcdefghij'))).toEqual('abcdefghij');
  });

  it(': double shift encode', function () {
    expect(new Cipher('iamapandabear').encode('iamapandabear'))
      .toEqual('qayaeaagaciai');
  });

  it('can wrap', function () {
    expect(cipher.encode('zzzzzzzzzz')).toEqual('zabcdefghi');
  });

});<commit_msg>rename exercise file name and skip all but the first test<commit_after>var Cipher = require('./cipher');

describe('Random key cipher', function () {
  var cipher = new Cipher();

  it('has a key made of letters', function () {
    expect(cipher.key).toMatch(/[a-z]+/);
  });

  // Here we take advantage of the fact that plaintext of "aaa..."
  // outputs the key. This is a critical problem with shift ciphers, some
  // characters will always output the key verbatim.
  xit('can encode', function () {
    expect(cipher.encode('aaaaaaaaaa')).toEqual(cipher.key.substr(0,10));
  });

  xit('can decode', function () {
    expect(cipher.decode(cipher.key.substr(0,10))).toEqual('aaaaaaaaaa');
  });

  xit('is reversible', function () {
    var plaintext = 'abcdefghij';
    expect(cipher.decode(cipher.encode(plaintext))).toEqual(plaintext);
  });

});

describe('Incorrect key cipher', function () {

  xit('throws an error with an all caps key', function () {
    expect( function () {
      new Cipher("ABCDEF");
    }).toThrow(new Error("Bad key"));
  });

  xit('throws an error with a numeric key', function () {
    expect( function () {
      new Cipher("12345");
    }).toThrow(new Error("Bad key"));
  });

  xit('throws an error with an empty key', function () {
    expect( function () {
      new Cipher("");
    }).toThrow(new Error("Bad key"));
  });

});

describe('Substitution cipher', function () {
  var key = 'abcdefghij';
  var cipher = new Cipher(key);

  xit('keeps the submitted key', function () {
    expect(cipher.key).toEqual(key);
  });

  xit('can encode', function () {
    expect(cipher.encode('aaaaaaaaaa')).toEqual('abcdefghij');
  });

  xit('can decode', function () {
    expect(cipher.decode('abcdefghij')).toEqual('aaaaaaaaaa');
  });

  xit('is reversible', function () {
    expect(cipher.decode(cipher.encode('abcdefghij'))).toEqual('abcdefghij');
  });

  xit(': double shift encode', function () {
    expect(new Cipher('iamapandabear').encode('iamapandabear'))
      .toEqual('qayaeaagaciai');
  });

  xit('can wrap', function () {
    expect(cipher.encode('zzzzzzzzzz')).toEqual('zabcdefghi');
  });

});<|endoftext|>


<commit_before>var WritableStream = require('stream').Writable
                     || require('readable-stream').Writable,
    inherits = require('util').inherits;

var StreamSearch = require('streamsearch');

var PartStream = require('./PartStream'),
    HeaderParser = require('./HeaderParser');

var DASH = 45,
    B_ONEDASH = new Buffer('-'),
    B_CRLF = new Buffer('\r\n'),
    EMPTY_FN = function() {};

function Dicer(cfg) {
  if (!(this instanceof Dicer))
    return new Dicer(cfg);
  WritableStream.call(this, cfg);

  if (!cfg || (!cfg.headerFirst && typeof cfg.boundary !== 'string'))
    throw new TypeError('Boundary required');

  if (typeof cfg.boundary === 'string')
    this.setBoundary(cfg.boundary);
  else
    this._bparser = undefined;

  this._headerFirst = cfg.headerFirst;

  var self = this;

  this._dashes = 0;
  this._parts = 0;
  this._finished = false;
  this._sawFinish = false;
  this._isPreamble = true;
  this._justMatched = false;
  this._firstWrite = true;
  this._inHeader = true;
  this._part = undefined;
  this._cb = undefined;
  this._ignoreData = false;
  this._partOpts = (typeof cfg.partHwm === 'number'
                    ? { highWaterMark: cfg.partHwm }
                    : {});
  this._pause = false;

  this._hparser = new HeaderParser(cfg);
  this._hparser.on('header', function(header) {
    self._inHeader = false;
    self._part.emit('header', header);
  });

}
inherits(Dicer, WritableStream);

Dicer.prototype.emit = function(ev) {
  if (ev === 'finish' && !this._sawFinish) {
    this._sawFinish = true;
    if (!this._finished) {
      var self = this;
      process.nextTick(function() {
        self.emit('error', new Error('Unexpected end of multipart data'));
        if (self._part && !self._ignoreData) {
          var type = (self._isPreamble ? 'Preamble' : 'Part');
          self._part.emit('error', new Error(type + ' terminated early due to unexpected end of multipart data'));
          self._part.push(null);
          process.nextTick(function() {
            self.emit('finish');
            self.reset();
          });
          return;
        }
        self.emit('finish');
        self.reset();
      });
    }
  } else
    WritableStream.prototype.emit.apply(this, arguments);
};

Dicer.prototype._write = function(data, encoding, cb) {
  if (this._headerFirst && this._isPreamble) {
    if (!this._part) {
      this._part = new PartStream(this._partOpts);
      if (this._events.preamble)
        this.emit('preamble', this._part);
      else {
        this._ignoreData = true;
        this._part.on('error', EMPTY_FN);
        // we must perform some kind of read on the stream even though we are
        // ignoring the data, otherwise node's Readable stream will not emit 'end'
        // after pushing null to the stream
        this._part.resume();
      }
    }
    var r = this._hparser.push(data);
    if (!this._inHeader && r !== undefined && r < data.length)
      data = data.slice(r);
    else
      return cb();
  }

  // allows for "easier" testing
  if (this._firstWrite) {
    this._bparser.push(B_CRLF);
    this._firstWrite = false;
  }

  this._bparser.push(data);

  if (this._pause)
    this._cb = cb;
  else
    cb();
};

Dicer.prototype.reset = function() {
  this._part = undefined;
  this._bparser = undefined;
  this._hparser = undefined;
};

Dicer.prototype.setBoundary = function(boundary) {
  var self = this;
  this._bparser = new StreamSearch('\r\n--' + boundary);
  this._bparser.on('info', function(isMatch, data, start, end) {
    self._oninfo(isMatch, data, start, end);
  });
};

Dicer.prototype._oninfo = function(isMatch, data, start, end) {
  var buf, self = this, i = 0, r, ev, shouldWriteMore = true;

  if (!this._part && this._justMatched && data) {
    while (this._dashes < 2 && (start + i) < end) {
      if (data[start + i] === DASH) {
        ++i;
        ++this._dashes;
      } else {
        if (this._dashes)
          buf = B_ONEDASH;
        this._dashes = 0;
        break;
      }
    }
    if (this._dashes === 2) {
      if ((start + i) < end && this._events.trailer)
        this.emit('trailer', data.slice(start + i, end));
      this.reset();
      this._finished = true;
    }
    if (this._dashes)
      return;
  }
  if (this._justMatched)
    this._justMatched = false;
  if (!this._part) {
    this._part = new PartStream(this._partOpts);
    this._part._read = function(n) {
      if (!self._pause)
        return;
      self._pause = false;
      if (self._cb) {
        var cb = self._cb;
        self._cb = undefined;
        cb();
      }
    };
    ev = this._isPreamble ? 'preamble' : 'part';
    if (this._events[ev])
      this.emit(ev, this._part);
    else {
      this._ignoreData = true;
      this._part.on('error', EMPTY_FN);
      // we must perform some kind of read on the stream even though we are
      // ignoring the data, otherwise node's Readable stream will not emit 'end'
      // after pushing null to the stream
      this._part.resume();
    }
    if (!this._isPreamble)
      this._inHeader = true;
  }
  if (data && start < end && !this._ignoreData) {
    if (this._isPreamble || !this._inHeader) {
      if (buf)
        shouldWriteMore = this._part.push(buf);
      shouldWriteMore = this._part.push(data.slice(start, end));
      if (!shouldWriteMore)
        this._pause = true;
    } else if (!this._isPreamble && this._inHeader) {
      if (buf)
        this._hparser.push(buf);
      r = this._hparser.push(data.slice(start, end));
      if (!this._inHeader && r !== undefined && r < end)
        this._oninfo(false, data, start + r, end);
    }
  }
  if (isMatch) {
    this._hparser.reset();
    if (this._isPreamble)
      this._isPreamble = false;
    else {
      ++this._parts;
      this._part.on('end', function() {
        if (--self._parts === 0 && self._finished)
          self.emit('finish');
      });
    }
    this._part.push(null);
    this._part = undefined;
    this._ignoreData = false;
    this._justMatched = true;
    this._dashes = 0;
  }
};

module.exports = Dicer;
<commit_msg>Dicer: do not assume order of 'finish' events<commit_after>var WritableStream = require('stream').Writable
                     || require('readable-stream').Writable,
    inherits = require('util').inherits;

var StreamSearch = require('streamsearch');

var PartStream = require('./PartStream'),
    HeaderParser = require('./HeaderParser');

var DASH = 45,
    B_ONEDASH = new Buffer('-'),
    B_CRLF = new Buffer('\r\n'),
    EMPTY_FN = function() {};

function Dicer(cfg) {
  if (!(this instanceof Dicer))
    return new Dicer(cfg);
  WritableStream.call(this, cfg);

  if (!cfg || (!cfg.headerFirst && typeof cfg.boundary !== 'string'))
    throw new TypeError('Boundary required');

  if (typeof cfg.boundary === 'string')
    this.setBoundary(cfg.boundary);
  else
    this._bparser = undefined;

  this._headerFirst = cfg.headerFirst;

  var self = this;

  this._dashes = 0;
  this._parts = 0;
  this._finished = false;
  this._realFinish = false;
  this._isPreamble = true;
  this._justMatched = false;
  this._firstWrite = true;
  this._inHeader = true;
  this._part = undefined;
  this._cb = undefined;
  this._ignoreData = false;
  this._partOpts = (typeof cfg.partHwm === 'number'
                    ? { highWaterMark: cfg.partHwm }
                    : {});
  this._pause = false;

  this._hparser = new HeaderParser(cfg);
  this._hparser.on('header', function(header) {
    self._inHeader = false;
    self._part.emit('header', header);
  });

}
inherits(Dicer, WritableStream);

Dicer.prototype.emit = function(ev) {
  if (ev === 'finish' && !this._realFinish) {
    if (!this._finished) {
      var self = this;
      process.nextTick(function() {
        self.emit('error', new Error('Unexpected end of multipart data'));
        if (self._part && !self._ignoreData) {
          var type = (self._isPreamble ? 'Preamble' : 'Part');
          self._part.emit('error', new Error(type + ' terminated early due to unexpected end of multipart data'));
          self._part.push(null);
          process.nextTick(function() {
            self._realFinish = true;
            self.emit('finish');
          });
          return;
        }
        self._realFinish = true;
        self.emit('finish');
      });
    }
  } else
    WritableStream.prototype.emit.apply(this, arguments);
};

Dicer.prototype._write = function(data, encoding, cb) {
  if (this._headerFirst && this._isPreamble) {
    if (!this._part) {
      this._part = new PartStream(this._partOpts);
      if (this._events.preamble)
        this.emit('preamble', this._part);
      else {
        this._ignoreData = true;
        this._part.on('error', EMPTY_FN);
        // we must perform some kind of read on the stream even though we are
        // ignoring the data, otherwise node's Readable stream will not emit 'end'
        // after pushing null to the stream
        this._part.resume();
      }
    }
    var r = this._hparser.push(data);
    if (!this._inHeader && r !== undefined && r < data.length)
      data = data.slice(r);
    else
      return cb();
  }

  // allows for "easier" testing
  if (this._firstWrite) {
    this._bparser.push(B_CRLF);
    this._firstWrite = false;
  }

  this._bparser.push(data);

  if (this._pause)
    this._cb = cb;
  else
    cb();
};

Dicer.prototype.reset = function() {
  this._part = undefined;
  this._bparser = undefined;
  this._hparser = undefined;
};

Dicer.prototype.setBoundary = function(boundary) {
  var self = this;
  this._bparser = new StreamSearch('\r\n--' + boundary);
  this._bparser.on('info', function(isMatch, data, start, end) {
    self._oninfo(isMatch, data, start, end);
  });
};

Dicer.prototype._oninfo = function(isMatch, data, start, end) {
  var buf, self = this, i = 0, r, ev, shouldWriteMore = true;

  if (!this._part && this._justMatched && data) {
    while (this._dashes < 2 && (start + i) < end) {
      if (data[start + i] === DASH) {
        ++i;
        ++this._dashes;
      } else {
        if (this._dashes)
          buf = B_ONEDASH;
        this._dashes = 0;
        break;
      }
    }
    if (this._dashes === 2) {
      if ((start + i) < end && this._events.trailer)
        this.emit('trailer', data.slice(start + i, end));
      this.reset();
      this._finished = true;
    }
    if (this._dashes)
      return;
  }
  if (this._justMatched)
    this._justMatched = false;
  if (!this._part) {
    this._part = new PartStream(this._partOpts);
    this._part._read = function(n) {
      if (!self._pause)
        return;
      self._pause = false;
      if (self._cb) {
        var cb = self._cb;
        self._cb = undefined;
        cb();
      }
    };
    ev = this._isPreamble ? 'preamble' : 'part';
    if (this._events[ev])
      this.emit(ev, this._part);
    else {
      this._ignoreData = true;
      this._part.on('error', EMPTY_FN);
      // we must perform some kind of read on the stream even though we are
      // ignoring the data, otherwise node's Readable stream will not emit 'end'
      // after pushing null to the stream
      this._part.resume();
    }
    if (!this._isPreamble)
      this._inHeader = true;
  }
  if (data && start < end && !this._ignoreData) {
    if (this._isPreamble || !this._inHeader) {
      if (buf)
        shouldWriteMore = this._part.push(buf);
      shouldWriteMore = this._part.push(data.slice(start, end));
      if (!shouldWriteMore)
        this._pause = true;
    } else if (!this._isPreamble && this._inHeader) {
      if (buf)
        this._hparser.push(buf);
      r = this._hparser.push(data.slice(start, end));
      if (!this._inHeader && r !== undefined && r < end)
        this._oninfo(false, data, start + r, end);
    }
  }
  if (isMatch) {
    this._hparser.reset();
    if (this._isPreamble)
      this._isPreamble = false;
    else {
      ++this._parts;
      this._part.on('end', function() {
        if (--self._parts === 0 && self._finished) {
          self._realFinish = true;
          self.emit('finish');
        }
      });
    }
    this._part.push(null);
    this._part = undefined;
    this._ignoreData = false;
    this._justMatched = true;
    this._dashes = 0;
  }
};

module.exports = Dicer;
<|endoftext|>


<commit_before>var util = require('util');
var Writable = require('stream').Writable;

var Room = module.exports = function (options) {
  var self = this;

  if (typeof options.name !== 'string') {
    throw new TypeError('`options.name` is required');
  }

  this.name = options.name;
  this.sparks = options.sparks || [];
  this.pub = options.redis.pub;
  this.channel = options.channel;

  Writable.call(this, { objectMode: true });
};
util.inherits(Room, Writable);

Room.prototype._write = function (data, enc, callback) {
  var d = { room: this.name, data: data };
  this.__write(d);
  this.pub.publish(this.channel, JSON.stringify(d));
  callback(); // TODO - put this somewhere else
  return true;
};

Room.prototype.__write = function (data) {
  var self = this;

  self.sparks.forEach(function (spark) {
    spark.write(data);
  });
};

Room.prototype.join = function (spark) {
  this.sparks.push(spark);
  spark._rooms.push(this);
  return this;
};

Room.prototype.leave = function (spark) {
  var index = this.sparks.indexOf(spark);
  if (index !== -1) {
    this.sparks.splice(index, 1);
  }

  index = spark._rooms.indexOf(this);
  if (index !== -1) {
    spark._rooms.splice(index, 1);
  }

  if (this.sparks.length === 0) {
    this.emit('empty');
  }

  return this;
};

Room.prototype.clients = function () {
  return this.sparks;
};
<commit_msg>Do not add duplicate sparks<commit_after>var util = require('util');
var Writable = require('stream').Writable;

var Room = module.exports = function (options) {
  var self = this;

  if (typeof options.name !== 'string') {
    throw new TypeError('`options.name` is required');
  }

  this.name = options.name;
  this.sparks = options.sparks || [];
  this.pub = options.redis.pub;
  this.channel = options.channel;

  Writable.call(this, { objectMode: true });
};
util.inherits(Room, Writable);

Room.prototype._write = function (data, enc, callback) {
  var d = { room: this.name, data: data };
  this.__write(d);
  this.pub.publish(this.channel, JSON.stringify(d));
  callback(); // TODO - put this somewhere else
  return true;
};

Room.prototype.__write = function (data) {
  var self = this;

  self.sparks.forEach(function (spark) {
    spark.write(data);
  });
};

Room.prototype.join = function (spark) {
  if (this.sparks.indexOf(spark) === -1) {
    this.sparks.push(spark);
    spark._rooms.push(this);
  }
  return this;
};

Room.prototype.leave = function (spark) {
  var index = this.sparks.indexOf(spark);
  if (index !== -1) {
    this.sparks.splice(index, 1);
  }

  index = spark._rooms.indexOf(this);
  if (index !== -1) {
    spark._rooms.splice(index, 1);
  }

  if (this.sparks.length === 0) {
    this.emit('empty');
  }

  return this;
};

Room.prototype.clients = function () {
  return this.sparks;
};
<|endoftext|>


<commit_before>module.exports = {
  id: "Group",
  allOf: [{
    $ref: "Agent",
  }, {
    prefixes: {
      "": "http://schema.org/",
      "foaf": "http://xmlns.com/foaf/0.1#",
      "org": "http://www.w3.org/TR/vocab-org#",
    },
    type: 'object',
    properties: {
      name: {
        type: "string",
      },
      memberships: {
        type: "array",
        context: "org:hasMembership",
        items: {
          reverse: "group",
          $ref: "Membership",
        },
      },
    },
    // TODO: how to describe
    // http://schema.org/member
  }],
};
<commit_msg>update Group type<commit_after>module.exports = {
  id: "Group",
  allOf: [{
    $ref: "Agent",
  }, {
    prefixes: {
      "": "http://schema.org/",
      "foaf": "http://xmlns.com/foaf/0.1#",
      "org": "http://www.w3.org/TR/vocab-org#",
    },
    context: "org:Organization",
    description: "A collection of people and groups.",
    type: 'object',
    properties: {
      name: {
        context: "name",
        description: "The primary name of the group.",
        type: "string",
      },
      description: {
        context: "description",
        description: "A short description of the group.",
        type: "string",
      },
      memberships: {
        context: "org:hasMembership",
        description: "The membership relationships that the group plays.",
        type: "array",
        items: {
          reverse: "group",
          $ref: "Membership",
        },
      },
    },
    // TODO: how to describe
    // http://schema.org/member
  }],
};
<|endoftext|>