<commit_before>import React from 'react';
import renderModal from '../provider-dialogs/modal'

function call_the_endpoint(buttonData) {
  return Promise.resolve({
    react: 'CreateAmazonSecurityGroupForm',
    props: {
      providerId: buttonData.ems_id,
    },
  });
}

window.listenToRx(function(buttonData) {
  if (!buttonData || buttonData.controller !== 'provider_dialogs') {
    return;
  }

  call_the_endpoint(buttonData)
    .then(function(response) {
      if (response.react) {
        reactModal(buttonData, response);
      } else if (response.dialog) {
        dialogModal(buttonData, response);
      } else {
        console.error('provider-dialogs: surprising response', buttonData, response);
      }
    });
});

function reactModal(buttonData, response) {
  let Component = ManageIQ.component.getReact(response.react);
  let inner = () => <Component {...response.props} />;

  renderModal(__("My React Modal"), inner);
}

function dialogModal(buttonData, response) {
  console.log('TODO dialogModal', arguments);

  // %dialog-user{"dialog" =>"vm.dialog"}
  const elem = $('<dialog-user></dialog-user>');
  elem.attr('dialog', JSON.stringify(response.dialog));

  const id = 'angular-provider-dialog';

  let inner = () => {
    // TODO react component lifecycle instead of setTimeout?
    setTimeout(() => {
      elem.appendTo(`#${id}`);
      miq_bootstrap(`#${id}`);
    });

    return

;
  };

  renderModal(__("My dialog-user"), inner);
}
<commit_msg>dialogModal - use componentDidMount instead of setTimeout<commit_after>import React from 'react';
import renderModal from '../provider-dialogs/modal'

function call_the_endpoint(buttonData) {
  return Promise.resolve({
    react: 'CreateAmazonSecurityGroupForm',
    props: {
      providerId: buttonData.ems_id,
    },
  });
}

window.listenToRx(function(buttonData) {
  if (!buttonData || buttonData.controller !== 'provider_dialogs') {
    return;
  }

  call_the_endpoint(buttonData)
    .then(function(response) {
      if (response.react) {
        reactModal(buttonData, response);
      } else if (response.dialog) {
        dialogModal(buttonData, response);
      } else {
        console.error('provider-dialogs: surprising response', buttonData, response);
      }
    });
});

function reactModal(buttonData, response) {
  let Component = ManageIQ.component.getReact(response.react);
  let inner = () => <Component {...response.props} />;

  renderModal(__("My React Modal"), inner);
}

function dialogModal(buttonData, response) {
  // %dialog-user{"dialog" =>"vm.dialog"}
  const elem = $('<dialog-user></dialog-user>');
  elem.attr('dialog', JSON.stringify(response.dialog));

  const id = 'angular-provider-dialog';

  let inner = class extends React.Component {
    componentDidMount() {
      elem.appendTo(`#${id}`);
      miq_bootstrap(`#${id}`);
    }

    render() {
      return

;
    }
  };

  renderModal(__("My dialog-user"), inner);
}
<|endoftext|>


<commit_before>var Irc = require('irc');
var tg = require('./tg');

var lookupChannel = function(chanName, channels) {
    return channels.filter(function(channel) {
        return channel.ircChan === chanName;
    })[0];
};

// generates channel list for ircOptions
var getChannels = function(arr) {
    var result = [];

    for (var i = 0; i < arr.length; i++) {
        var chanName = arr[i].chanPwd ?
                       arr[i].ircChan + ' ' + arr[i].chanPwd :
                       arr[i].ircChan;
        result.push(chanName);
    }

    return result;
};

module.exports = function(config, sendTo) {
    config.ircOptions.channels = getChannels(config.channels);

    var irc = new Irc.Client(config.ircServer, config.ircNick, config.ircOptions);

    irc.on('error', function(error) {
        console.error('IRC ERROR: ' + error);
    });

    irc.on('message', function(user, chanName, message) {
        var channel = lookupChannel(chanName, config.channels);
        if (!channel) {
            return;
        }

        var match = config.hlRegexp.exec(message);
        if (match || config.ircRelayAll) {
            if (match) {
                message = match[1].trim();
            }
            var text = '<' + user + '>: ' + message;
            sendTo.tg(channel, text);
        }
    });

    irc.on('action', function(user, chanName, message) {
        var channel = lookupChannel(chanName, config.channels);
        if (!channel) {
            return;
        }

        var match = config.hlRegexp.exec(message);
        if (match || config.ircRelayAll) {
            if (match) {
                message = match[1].trim();
            }
            var text = '*' + user + ': ' + message + '*';
            sendTo.tg(channel, text);
        }
    });

    irc.on('topic', function(chanName, topic, nick) {
        var channel = lookupChannel(chanName, config.channels);
        if (!channel) {
            return;
        }

        // ignore first topic event when joining channel
        // (doesn't handle rejoins yet)
        if (!config.sendTopic || !channel.firstTopicRcvd) {
            channel.firstTopicRcvd = true;
            return;
        }

        var text = '* Topic for channel ' + channel.chanAlias || channel.ircChan +
                   ':\n' + topic.split(' | ').join('\n') +
                   '\n* set by ' + nick.split('!')[0];
        sendTo.tg(channel, text);
    });

    sendTo.irc = function(chanName, msg) {
        console.log('  >> relaying to IRC: ' + msg);
        irc.say(chanName, msg);
    };
};
<commit_msg>fix error output on IRC error<commit_after>var Irc = require('irc');
var tg = require('./tg');

var lookupChannel = function(chanName, channels) {
    return channels.filter(function(channel) {
        return channel.ircChan === chanName;
    })[0];
};

// generates channel list for ircOptions
var getChannels = function(arr) {
    var result = [];

    for (var i = 0; i < arr.length; i++) {
        var chanName = arr[i].chanPwd ?
                       arr[i].ircChan + ' ' + arr[i].chanPwd :
                       arr[i].ircChan;
        result.push(chanName);
    }

    return result;
};

module.exports = function(config, sendTo) {
    config.ircOptions.channels = getChannels(config.channels);

    var irc = new Irc.Client(config.ircServer, config.ircNick, config.ircOptions);

    irc.on('error', function(error) {
        console.error('IRC ERROR:');
        console.error(error);
    });

    irc.on('message', function(user, chanName, message) {
        var channel = lookupChannel(chanName, config.channels);
        if (!channel) {
            return;
        }

        var match = config.hlRegexp.exec(message);
        if (match || config.ircRelayAll) {
            if (match) {
                message = match[1].trim();
            }
            var text = '<' + user + '>: ' + message;
            sendTo.tg(channel, text);
        }
    });

    irc.on('action', function(user, chanName, message) {
        var channel = lookupChannel(chanName, config.channels);
        if (!channel) {
            return;
        }

        var match = config.hlRegexp.exec(message);
        if (match || config.ircRelayAll) {
            if (match) {
                message = match[1].trim();
            }
            var text = '*' + user + ': ' + message + '*';
            sendTo.tg(channel, text);
        }
    });

    irc.on('topic', function(chanName, topic, nick) {
        var channel = lookupChannel(chanName, config.channels);
        if (!channel) {
            return;
        }

        // ignore first topic event when joining channel
        // (doesn't handle rejoins yet)
        if (!config.sendTopic || !channel.firstTopicRcvd) {
            channel.firstTopicRcvd = true;
            return;
        }

        var text = '* Topic for channel ' + channel.chanAlias || channel.ircChan +
                   ':\n' + topic.split(' | ').join('\n') +
                   '\n* set by ' + nick.split('!')[0];
        sendTo.tg(channel, text);
    });

    sendTo.irc = function(chanName, msg) {
        console.log('  >> relaying to IRC: ' + msg);
        irc.say(chanName, msg);
    };
};
<|endoftext|>


<commit_before>/**
 * Copyright 2014 Ian Davies
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 *
 * You may obtain a copy of the License at
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
define([], function() {
    /**
     * Animated Radio Buttons
     * Recommened by Honest, from: http://tympanus.net/codrops/2013/10/15/animated-checkboxes-and-radio-buttons-with-svg/
     */
    let pathDefs = {
        fill: ['M15.833,24.334c2.179-0.443,4.766-3.995,6.545-5.359 c1.76-1.35,4.144-3.732,6.256-4.339c-3.983,3.844-6.504,9.556-10.047,13.827c-2.325,2.802-5.387,6.153-6.068,9.866 c2.081-0.474,4.484-2.502,6.425-3.488c5.708-2.897,11.316-6.804,16.608-10.418c4.812-3.287,11.13-7.53,13.935-12.905 c-0.759,3.059-3.364,6.421-4.943,9.203c-2.728,4.806-6.064,8.417-9.781,12.446c-6.895,7.477-15.107,14.109-20.779,22.608 c3.515-0.784,7.103-2.996,10.263-4.628c6.455-3.335,12.235-8.381,17.684-13.15c5.495-4.81,10.848-9.68,15.866-14.988 c1.905-2.016,4.178-4.42,5.556-6.838c0.051,1.256-0.604,2.542-1.03,3.672c-1.424,3.767-3.011,7.432-4.723,11.076 c-2.772,5.904-6.312,11.342-9.921,16.763c-3.167,4.757-7.082,8.94-10.854,13.205c-2.456,2.777-4.876,5.977-7.627,8.448 c9.341-7.52,18.965-14.629,27.924-22.656c4.995-4.474,9.557-9.075,13.586-14.446c1.443-1.924,2.427-4.939,3.74-6.56 c-0.446,3.322-2.183,6.878-3.312,10.032c-2.261,6.309-5.352,12.53-8.418,18.482c-3.46,6.719-8.134,12.698-11.954,19.203 c-0.725,1.234-1.833,2.451-2.265,3.77c2.347-0.48,4.812-3.199,7.028-4.286c4.144-2.033,7.787-4.938,11.184-8.072 c3.142-2.9,5.344-6.758,7.925-10.141c1.483-1.944,3.306-4.056,4.341-6.283c0.041,1.102-0.507,2.345-0.876,3.388 c-1.456,4.114-3.369,8.184-5.059,12.212c-1.503,3.583-3.421,7.001-5.277,10.411c-0.967,1.775-2.471,3.528-3.287,5.298 c2.49-1.163,5.229-3.906,7.212-5.828c2.094-2.028,5.027-4.716,6.33-7.335c-0.256,1.47-2.07,3.577-3.02,4.809'],
        checkmark: ['M16.667,62.167c3.109,5.55,7.217,10.591,10.926,15.75 c2.614,3.636,5.149,7.519,8.161,10.853c-0.046-0.051,1.959,2.414,2.692,2.343c0.895-0.088,6.958-8.511,6.014-7.3 c5.997-7.695,11.68-15.463,16.931-23.696c6.393-10.025,12.235-20.373,18.104-30.707C82.004,24.988,84.802,20.601,87,16'],
    };
    let animDefs = {
        fill: {speed: .8, easing: 'ease-in-out'},
        checkmark : { speed : .2, easing : 'ease-in-out' },
    };

    function initInput(el) {

        function createSVGEl(def) {
            let svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
            if (def) {
                svg.setAttributeNS(null, 'viewBox', def.viewBox);
                svg.setAttributeNS(null, 'preserveAspectRatio', def.preserveAspectRatio);
            }
            else {
                svg.setAttributeNS(null, 'viewBox', '0 0 100 100');
            }
            svg.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
            return svg;
        }

        let svg = createSVGEl();
        el.parentNode.appendChild(svg);
    }

    function draw(el, type) {
        let svg = el.parentNode.querySelector('svg');
        let pathDef = pathDefs[type];
        let animDef = animDefs[type];

        let paths = [];
        paths.push(document.createElementNS('http://www.w3.org/2000/svg', 'path'));
        if (type === 'cross' || type === 'list') {
            paths.push(document.createElementNS('http://www.w3.org/2000/svg', 'path'));
        }

        for (let i = 0, len = paths.length; i < len; ++i) {
            let path = paths[i];
            svg.appendChild(path);

            path.setAttributeNS(null, 'd', pathDef[i]);

            let length = path.getTotalLength();
            // Set up the starting positions
            path.style.strokeDasharray = length + ' ' + length;
            if (i === 0) {
                path.style.strokeDashoffset = Math.floor(length) - 1;
            }
            else
                path.style.strokeDashoffset = length;
            // Trigger a layout so styles are calculated & the browser
            // picks up the starting position before animating
            path.getBoundingClientRect();
            // Define our transition
            path.style.transition = path.style.WebkitTransition = path.style.MozTransition = 'stroke-dashoffset ' + animDef.speed + 's ' + animDef.easing + ' ' + i * animDef.speed + 's';
            // Go!
            path.style.strokeDashoffset = '0';
        }
    }

    // FIXME no-shadow
    function reset(el) {
        Array.prototype.slice.call(el.parentNode.querySelectorAll('svg > path')).forEach(function(el) {
            el.parentNode.removeChild(el);
        });
    }

    return [function() {

        return {
            restrict: 'A',

            link: function(scope, element, attrs) {
                initInput(element[0]);

                if (attrs.ngModel != null && attrs.ngModel.length > 0) {
                    let elementType = element[0].type;

                    if (elementType === "checkbox") {
                        scope.$watch(attrs.ngModel, function() {
                            if (scope.$eval(attrs.ngModel)) {
                                draw(element[0], 'checkmark');
                            } else {
                                reset(element[0]);
                            }
                        });
                    } else if (elementType === "radio") {
                        let dotPos = attrs.ngModel.indexOf('.');
                        let watchCollection;
                        if (dotPos > -1) {
                            watchCollection = attrs.ngModel.substr(0, dotPos);
                        } else {
                            watchCollection = attrs.ngModel;
                        }
                        scope.$watchCollection(watchCollection, function() {
                            // Can't necessarily use 'attrs.value' - due to a race condition it might not be defined;
                            // in which case use 'attrs.ngValue' which should be.
                            let buttonValue = attrs.value ? attrs.value : scope.$eval(attrs.ngValue);
                            let selectedVal = scope.$eval(attrs.ngModel);

                            // Use == to compare values as they may be different types
                            if (selectedVal != null && selectedVal == buttonValue) {
                                draw(element[0], 'fill');
                            } else {
                                reset(element[0]);
                            }
                        });
                    } else {
                        throw 'Error: input-animation directive is not yet implemented for inputs of type: "' + elementType + '"';
                    }

                }
            }
        };
    }];
});
<commit_msg>Fix one shadowing issue.<commit_after>/**
 * Copyright 2014 Ian Davies
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 *
 * You may obtain a copy of the License at
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
define([], function() {
    /**
     * Animated Radio Buttons
     * Recommened by Honest, from: http://tympanus.net/codrops/2013/10/15/animated-checkboxes-and-radio-buttons-with-svg/
     */
    let pathDefs = {
        fill: ['M15.833,24.334c2.179-0.443,4.766-3.995,6.545-5.359 c1.76-1.35,4.144-3.732,6.256-4.339c-3.983,3.844-6.504,9.556-10.047,13.827c-2.325,2.802-5.387,6.153-6.068,9.866 c2.081-0.474,4.484-2.502,6.425-3.488c5.708-2.897,11.316-6.804,16.608-10.418c4.812-3.287,11.13-7.53,13.935-12.905 c-0.759,3.059-3.364,6.421-4.943,9.203c-2.728,4.806-6.064,8.417-9.781,12.446c-6.895,7.477-15.107,14.109-20.779,22.608 c3.515-0.784,7.103-2.996,10.263-4.628c6.455-3.335,12.235-8.381,17.684-13.15c5.495-4.81,10.848-9.68,15.866-14.988 c1.905-2.016,4.178-4.42,5.556-6.838c0.051,1.256-0.604,2.542-1.03,3.672c-1.424,3.767-3.011,7.432-4.723,11.076 c-2.772,5.904-6.312,11.342-9.921,16.763c-3.167,4.757-7.082,8.94-10.854,13.205c-2.456,2.777-4.876,5.977-7.627,8.448 c9.341-7.52,18.965-14.629,27.924-22.656c4.995-4.474,9.557-9.075,13.586-14.446c1.443-1.924,2.427-4.939,3.74-6.56 c-0.446,3.322-2.183,6.878-3.312,10.032c-2.261,6.309-5.352,12.53-8.418,18.482c-3.46,6.719-8.134,12.698-11.954,19.203 c-0.725,1.234-1.833,2.451-2.265,3.77c2.347-0.48,4.812-3.199,7.028-4.286c4.144-2.033,7.787-4.938,11.184-8.072 c3.142-2.9,5.344-6.758,7.925-10.141c1.483-1.944,3.306-4.056,4.341-6.283c0.041,1.102-0.507,2.345-0.876,3.388 c-1.456,4.114-3.369,8.184-5.059,12.212c-1.503,3.583-3.421,7.001-5.277,10.411c-0.967,1.775-2.471,3.528-3.287,5.298 c2.49-1.163,5.229-3.906,7.212-5.828c2.094-2.028,5.027-4.716,6.33-7.335c-0.256,1.47-2.07,3.577-3.02,4.809'],
        checkmark: ['M16.667,62.167c3.109,5.55,7.217,10.591,10.926,15.75 c2.614,3.636,5.149,7.519,8.161,10.853c-0.046-0.051,1.959,2.414,2.692,2.343c0.895-0.088,6.958-8.511,6.014-7.3 c5.997-7.695,11.68-15.463,16.931-23.696c6.393-10.025,12.235-20.373,18.104-30.707C82.004,24.988,84.802,20.601,87,16'],
    };
    let animDefs = {
        fill: {speed: .8, easing: 'ease-in-out'},
        checkmark : { speed : .2, easing : 'ease-in-out' },
    };

    function initInput(el) {

        function createSVGEl(def) {
            let svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
            if (def) {
                svg.setAttributeNS(null, 'viewBox', def.viewBox);
                svg.setAttributeNS(null, 'preserveAspectRatio', def.preserveAspectRatio);
            }
            else {
                svg.setAttributeNS(null, 'viewBox', '0 0 100 100');
            }
            svg.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
            return svg;
        }

        let svg = createSVGEl();
        el.parentNode.appendChild(svg);
    }

    function draw(el, type) {
        let svg = el.parentNode.querySelector('svg');
        let pathDef = pathDefs[type];
        let animDef = animDefs[type];

        let paths = [];
        paths.push(document.createElementNS('http://www.w3.org/2000/svg', 'path'));
        if (type === 'cross' || type === 'list') {
            paths.push(document.createElementNS('http://www.w3.org/2000/svg', 'path'));
        }

        for (let i = 0, len = paths.length; i < len; ++i) {
            let path = paths[i];
            svg.appendChild(path);

            path.setAttributeNS(null, 'd', pathDef[i]);

            let length = path.getTotalLength();
            // Set up the starting positions
            path.style.strokeDasharray = length + ' ' + length;
            if (i === 0) {
                path.style.strokeDashoffset = Math.floor(length) - 1;
            }
            else
                path.style.strokeDashoffset = length;
            // Trigger a layout so styles are calculated & the browser
            // picks up the starting position before animating
            path.getBoundingClientRect();
            // Define our transition
            path.style.transition = path.style.WebkitTransition = path.style.MozTransition = 'stroke-dashoffset ' + animDef.speed + 's ' + animDef.easing + ' ' + i * animDef.speed + 's';
            // Go!
            path.style.strokeDashoffset = '0';
        }
    }

    // FIXME no-shadow
    function reset(el) {
        Array.prototype.slice.call(el.parentNode.querySelectorAll('svg > path')).forEach(function(el) {
            el.parentNode.removeChild(el);
        });
    }

    return [function() {

        return {
            restrict: 'A',

            link: function(scope, element, attrs) {
                let inputElement = element[0];
                initInput(inputElement);

                if (attrs.ngModel != null && attrs.ngModel.length > 0) {
                    let elementType = inputElement.type;

                    if (elementType === "checkbox") {
                        scope.$watch(attrs.ngModel, function() {
                            if (scope.$eval(attrs.ngModel)) {
                                draw(inputElement, 'checkmark');
                            } else {
                                reset(inputElement);
                            }
                        });
                    } else if (elementType === "radio") {
                        let dotPos = attrs.ngModel.indexOf('.');
                        let watchCollection;
                        if (dotPos > -1) {
                            watchCollection = attrs.ngModel.substr(0, dotPos);
                        } else {
                            watchCollection = attrs.ngModel;
                        }
                        scope.$watchCollection(watchCollection, function() {
                            // Can't necessarily use 'attrs.value' - due to a race condition it might not be defined;
                            // in which case use 'attrs.ngValue' which should be.
                            let buttonValue = attrs.value ? attrs.value : scope.$eval(attrs.ngValue);
                            let selectedVal = scope.$eval(attrs.ngModel);

                            // Use == to compare values as they may be different types
                            if (selectedVal != null && selectedVal == buttonValue) {
                                draw(inputElement, 'fill');
                            } else {
                                reset(inputElement);
                            }
                        });
                    } else {
                        throw 'Error: input-animation directive is not yet implemented for inputs of type: "' + elementType + '"';
                    }

                }
            }
        };
    }];
});
<|endoftext|>


<commit_before>const assert = require('assert');
const MESSAGE = Symbol.for('message');

module.exports = function (options) {
  options = options || {};

  var Transport = options.Transport;
  var name = Transport.name || options.name;
  var construct = options.construct;
  var instance;

  beforeEach(function () {
    var create = typeof construct === 'function'
      ? construct()
      : construct;

    instance = new Transport(create);
  });

  // TODO How to assert that error event is thrown? How to make a transport fail?
  describe('.log()', function () {
    it('should be present', function () {
      assert.ok(instance.log);
      assert.equal('function', typeof instance.log);
    });

    it('(with no callback) should return true', function () {
      var info = {
        level: 'debug',
        message: 'foo'
      };

      info[MESSAGE] = JSON.stringify(info);
      var result = instance.log(info);
      assert(true, result);
    });

    it('(with callback) should return true', function (done) {
      var info = {
        level: 'debug',
        message: 'foo'
      };

      info[MESSAGE] = JSON.stringify(info);
      var result = instance.log(info, function () {
        assert(true, result);
        done();
      });
    });
  });

  describe('events', function () {
    it('should emit the "logged" event', function (done) {
      instance.once('logged', done);

      var info = {
        level: 'debug',
        message: 'foo'
      };

      info[MESSAGE] = JSON.stringify(info);
      instance.log(info);
    });
  });
};
<commit_msg>[api] Accept `after` and `afterEach` from options.<commit_after>const assert = require('assert');
const MESSAGE = Symbol.for('message');

module.exports = function (options) {
  options = options || {};

  var Transport = options.Transport;
  var name = Transport.name || options.name;
  var construct = options.construct;
  var instance;

  beforeEach(function () {
    var create = typeof construct === 'function'
      ? construct()
      : construct;

    instance = new Transport(create);
  });

  // TODO How to assert that error event is thrown? How to make a transport fail?
  describe('.log()', function () {
    it('should be present', function () {
      assert.ok(instance.log);
      assert.equal('function', typeof instance.log);
    });

    it('(with no callback) should return true', function () {
      var info = {
        level: 'debug',
        message: 'foo'
      };

      info[MESSAGE] = JSON.stringify(info);
      var result = instance.log(info);
      assert(true, result);
    });

    it('(with callback) should return true', function (done) {
      var info = {
        level: 'debug',
        message: 'foo'
      };

      info[MESSAGE] = JSON.stringify(info);
      var result = instance.log(info, function () {
        assert(true, result);
        done();
      });
    });
  });

  describe('events', function () {
    it('should emit the "logged" event', function (done) {
      instance.once('logged', done);

      var info = {
        level: 'debug',
        message: 'foo'
      };

      info[MESSAGE] = JSON.stringify(info);
      instance.log(info);
    });
  });

  afterEach(function (done) {
    if (options.afterEach) {
      return options.afterEach(options, done);
    }

    done();
  });

  after(function (done) {
    if (options.afterEach) {
      return options.afterEach(options, done);
    }

    done();
  });
};
<|endoftext|>


<commit_before>'use strict';
var exec = require('child_process').exec;

function sysExec(command, callback){
	command = 'unset XDG_SESSION_ID XDG_RUNTIME_DIR; cgm movepid all virt $$; ' + command;

	return exec(command, (function(callback){
		return function(err,data,stderr){
			if(callback){
				return callback(data, err, stderr);
			}
		}
	})(callback));
};

var lxc = {
	create: function(name, template, config, callback){
		return sysExec('lxc-create -n '+name+' -t '+template, callback);
	},

	clone: function(name, base_name, callback){
		return sysExec('lxc-clone -o '+base_name+ ' -n '+name +' -B overlayfs -s', callback);
	},

	destroy: function(name, callback){
		return sysExec('lxc-destroy -n '+ name, function(data){
			var info = data.match(/Destroyed container/);
			console.log('destroy info:', info);
			var args = [true].concat(Array.prototype.slice.call(arguments, 1));
			callback.apply(this, args);
		});
	},

	start: function(name, callback){
		var cmd = 'lxc-start --name '+name+' --daemon';
		return sysExec(cmd, callback);
	},

	startEphemeral: function(name, base_name, callback){
		var command = 'lxc-start-ephemeral -o '+base_name+ ' -n '+name +' --union-type overlayfs -d';
		return sysExec(command, function(data){
			console.log('startEphemeral', arguments);
			if(data.match("doesn't exist.")){
				return callback({status: 500, error: "doesn't exist."});
			}
			if(data.match("already exists.")){
				return callback({status: 500, error: "already exists"});
			}
			if(data.match(/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/)){
				return callback({status: 200, state:'RUNNING', ip: data.match(/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/)[0]});
			}

			callback({'?': '?', data: data, name: name, base_name: base_name});
		});
	},

	stop: function(name, callback){
		return sysExec('lxc-stop -n '+ name, callback);
	},

	freeze: function(name, callback){
		return sysExec('lxc-freeze -n '+name, callback);
	},

	unfreeze: function(name, callback){
		return sysExec('lxc-unfreeze -n '+name, callback);
	},

	info: function(name, callback){
		return sysExec('lxc-info -n '+name, function(data){
			console.log('info', arguments);
			if(data.match("doesn't exist")){
				return callback({state: 'NULL'});
			}

			var info = {};
			data = data.replace(/\suse/ig, '').replace(/\sbytes/ig, '').split("\n").slice(0,-1);
			for(var i in data){
				var temp = data[i].split(/\:\s+/);
				info[temp[0].toLowerCase().trim()] = temp[1].trim();
			}
			var args = [info].concat(Array.prototype.slice.call(arguments, 1));
			callback.apply(this, args);
		});
	},

	list: function(callback){
		sysExec('lxc-ls --fancy', function(data){
			var output = data.split("\n");
			var keys = output.splice(0,1)[0].split(/\s+/).slice(0,-1);
			var info = [];

			keys = keys.map(function(v){return v.toLowerCase()});
			output = output.slice(0).splice(1).slice(0,-1);

			for(var i in output){

				var aIn = output[i].split(/\s+/).slice(0,-1);
				var mapOut = {};
				aIn.map(function(value,idx){
					mapOut[keys[idx]] = value;
				});
				info.push(mapOut);

			}
			var args = [info].concat(Array.prototype.slice.call(arguments, 1));
			callback.apply(this, args);
		});
	}
};

module.exports = lxc;
<commit_msg>runner<commit_after>'use strict';
var exec = require('child_process').exec;

function sysExec(command, callback){
	command = 'unset XDG_SESSION_ID XDG_RUNTIME_DIR; cgm movepid all virt $$; ' + command;

	return exec(command, (function(callback){
		return function(err,data,stderr){
			if(callback){
				return callback(data, err, stderr);
			}
		}
	})(callback));
};

var lxc = {
	create: function(name, template, config, callback){
		return sysExec('lxc-create -n '+name+' -t '+template, callback);
	},

	clone: function(name, base_name, callback){
		return sysExec('lxc-clone -o '+base_name+ ' -n '+name +' -B overlayfs -s', callback);
	},

	destroy: function(name, callback){
		return sysExec('lxc-destroy -n '+ name, function(data){
			var info = data.match(/Destroyed container/);
			console.log('destroy info:', info);
			var args = [true].concat(Array.prototype.slice.call(arguments, 1));
			callback.apply(this, args);
		});
	},

	start: function(name, callback){
		var cmd = 'lxc-start --name '+name+' --daemon';
		return sysExec(cmd, callback);
	},

	startEphemeral: function(name, base_name, callback){
		var command = 'lxc-start-ephemeral -o '+base_name+ ' -n '+name +' --union-type overlayfs -d';
		return sysExec(command, function(data){
			console.log('startEphemeral', arguments);
			if(data.match("doesn't exist.")){
				return callback({status: 500, error: "doesn't exist."});
			}
			if(data.match("already exists.")){
				return callback({status: 500, error: "already exists"});
			}
			if(data.match(/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/)){
				return callback({status: 200, state:'RUNNING', ip: data.match(/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/)[0]});
			}

			callback({'?': '?', data: data, name: name, base_name: base_name});
		});
	},

	stop: function(name, callback){
		return sysExec('lxc-stop -n '+ name, callback);
	},

	freeze: function(name, callback){
		return sysExec('lxc-freeze -n '+name, callback);
	},

	unfreeze: function(name, callback){
		return sysExec('lxc-unfreeze -n '+name, callback);
	},

	info: function(name, callback){
		return sysExec('lxc-info -n '+name, function(data){
			console.log('info', arguments);
			if(data.match("doesn't exist")){
				return callback({state: 'NULL'});
			}

			var info = {};
			data = data.replace(/\suse/ig, '').replace(/\sbytes/ig, '').split("\n").slice(0,-1);
			for(var i in data){
				var temp = data[i].split(/\:\s+/);
				info[temp[0].toLowerCase().trim()] = temp[1].trim();
			}
			var args = [info].concat(Array.prototype.slice.call(arguments, 1));
			callback.apply(this, args);
		});
	},

	list: function(callback){
		sysExec('lxc-ls --fancy', function(data){
			var output = data.split("\n");
			var keys = output.splice(0,1)[0].split(/\s+/).slice(0,-1);
			var info = [];

			keys = keys.map(function(v){return v.toLowerCase()});
			console.log(output)
			output = output.slice(0).splice(1).slice(0,-1);

			for(var i in output){

				var aIn = output[i].split(/\s+/).slice(0,-1);
				var mapOut = {};
				aIn.map(function(value,idx){
					mapOut[keys[idx]] = value;
				});
				info.push(mapOut);

			}
			var args = [info].concat(Array.prototype.slice.call(arguments, 1));
			callback.apply(this, args);
		});
	}
};

module.exports = lxc;
<|endoftext|>


<commit_before>var screenWidth = 1024;
var screenHeight = 768;

var lzs = new Phaser.Game(screenWidth, screenHeight, Phaser.AUTO, 'lzs', { preload: preload, create: create, update: update, render: render });

function preload() {
	// Load sounds and sprites

	lzs.load.image('ray', 'assets/sprites/ray-front-single.png');
	lzs.load.image('beam', 'assets/sprites/beam-01.png');
	lzs.load.image('background', 'assets/sprites/grass-dirt-mix-pixeled-gray.png');
	lzs.load.image('zombie', 'assets/sprites/placeholder_zombie.png');

	lzs.load.audio('pew', 'assets/sounds/raygun1.mp3');
}

// Game vars

var bulletSpeed = 1500;
var cursors;
var fireButton;
var fireDelay =200;
var fireTime = 0;
var pew;
var ray;
var raySpeed = 1000;
var score = 0;
var zombieHitPoints = 3;
var zombies;
var zombieSpeed = 50;

function create() {
	lzs.add.tileSprite(0, 0, screenWidth, screenHeight, 'background');

	lzs.physics.startSystem(Phaser.Physics.ARCADE);

	ray = lzs.add.sprite(screenWidth * 0.5, screenHeight * 0.8, 'ray');

	//rays
	bullets = lzs.add.group();
	bullets.enableBody = true;
	bullets.physicsBodyType = Phaser.Physics.ARCADE;
	bullets.createMultiple(30, 'beam');
	bullets.setAll('anchor.x', 0.5);
	bullets.setAll('anchor.y', 1);
	bullets.setAll('outOfBoundsKill', true);
	bullets.setAll('checkWorldBounds', true);

	lzs.physics.enable(ray, Phaser.Physics.ARCADE);

	//controls
	cursors = lzs.input.keyboard.createCursorKeys();
	fireButton = lzs.input.keyboard.addKey(Phaser.Keyboard.SPACEBAR);

	createZombies();

	//audio
	pew = lzs.add.audio('pew');
}

function update() {
	if (ray.alive) {
		ray.body.velocity.setTo(0, 0);

		if (cursors.left.isDown) {
			if (ray.position.x > 0) {
				ray.body.velocity.x = -raySpeed;
			}
		}
		if (cursors.right.isDown) {
			if (ray.position.x < (lzs.world.width - ray.width)) {
				ray.body.velocity.x = raySpeed;
			}
		}
		if (cursors.up.isDown) {
			if (ray.position.y > (lzs.world.height / 2)) {
				ray.body.velocity.y = -raySpeed;
			}
		}
		if (cursors.down.isDown) {
			if (ray.position.y < (lzs.world.height - ray.height)) {
				ray.body.velocity.y = raySpeed;
			}
		}

		if (fireButton.isDown) {
			fireRay();
		}

		//collision detection
		lzs.physics.arcade.overlap(bullets, zombies, collisionHandler);
	}
}

function fireRay() {
	if (lzs.time.now > fireTime) {
		pew.play();

		bullet = bullets.getFirstExists(false);

		if (bullet) {
			bullet.reset(ray.x + 65, ray.y + 8);
			bullet.body.velocity.y = -bulletSpeed;
			fireTime = lzs.time.now + fireDelay;
		}
	}
}

function createZombies() {
	zombies = lzs.add.group();
	zombies.enableBody = true;
	zombies.physicsBodyType = Phaser.Physics.ARCADE;
	zombies.setAll('outOfBoundsKill', true);

	lzs.time.events.loop(2000, createZombie, this);
}

function createZombie() {
	var zombie = zombies.create(screenWidth * Math.random(), -150, 'zombie');

	zombie.body.velocity.y = zombieSpeed;
	zombie.hits = 0;
	zombie.alive = false;
}

function collisionHandler(bullet, zombie) {
	if (!zombie.alive) {
		bullet.kill();
		zombie.hits++;

		if (zombie.hits == zombieHitPoints) {
			zombie.alive = true;
		    zombie.body.velocity.y = 0;

		    if (zombie.position.x > (lzs.world.width * .5)) {
		    	zombie.body.velocity.x = zombieSpeed;
		    }
		    else {
		    	zombie.body.velocity.x = -zombieSpeed;
		    }

		    score += 20;
		}
	}

}

function render() {

}<commit_msg>Display score on screen<commit_after>var screenWidth = 1024;
var screenHeight = 768;

var lzs = new Phaser.Game(screenWidth, screenHeight, Phaser.AUTO, 'lzs', { preload: preload, create: create, update: update, render: render });

function preload() {
	// Load sounds and sprites

	lzs.load.image('ray', 'assets/sprites/ray-front-single.png');
	lzs.load.image('beam', 'assets/sprites/beam-01.png');
	lzs.load.image('background', 'assets/sprites/grass-dirt-mix-pixeled-gray.png');
	lzs.load.image('zombie', 'assets/sprites/placeholder_zombie.png');

	lzs.load.audio('pew', 'assets/sounds/raygun1.mp3');
}

// Game vars

var bulletSpeed = 1500;
var cursors;
var fireButton;
var fireDelay =200;
var fireTime = 0;
var pew;
var ray;
var raySpeed = 1000;
var score = 0;
var scoreText;
var scoreString = 'Score: ';
var zombieHitPoints = 3;
var zombies;
var zombieSpeed = 50;

function create() {
	lzs.add.tileSprite(0, 0, screenWidth, screenHeight, 'background');

	lzs.physics.startSystem(Phaser.Physics.ARCADE);

	ray = lzs.add.sprite(screenWidth * 0.5, screenHeight * 0.8, 'ray');

	//rays
	bullets = lzs.add.group();
	bullets.enableBody = true;
	bullets.physicsBodyType = Phaser.Physics.ARCADE;
	bullets.createMultiple(30, 'beam');
	bullets.setAll('anchor.x', 0.5);
	bullets.setAll('anchor.y', 1);
	bullets.setAll('outOfBoundsKill', true);
	bullets.setAll('checkWorldBounds', true);

	lzs.physics.enable(ray, Phaser.Physics.ARCADE);

	//controls
	cursors = lzs.input.keyboard.createCursorKeys();
	fireButton = lzs.input.keyboard.addKey(Phaser.Keyboard.SPACEBAR);

	createZombies();

	//audio
	pew = lzs.add.audio('pew');

	scoreText = lzs.add.text(10, screenHeight - 30, scoreString + score, { font: '24px Ariel', fill: '#de57d5' });
}

function update() {
	if (ray.alive) {
		ray.body.velocity.setTo(0, 0);

		if (cursors.left.isDown) {
			if (ray.position.x > 0) {
				ray.body.velocity.x = -raySpeed;
			}
		}
		if (cursors.right.isDown) {
			if (ray.position.x < (lzs.world.width - ray.width)) {
				ray.body.velocity.x = raySpeed;
			}
		}
		if (cursors.up.isDown) {
			if (ray.position.y > (lzs.world.height / 2)) {
				ray.body.velocity.y = -raySpeed;
			}
		}
		if (cursors.down.isDown) {
			if (ray.position.y < (lzs.world.height - ray.height)) {
				ray.body.velocity.y = raySpeed;
			}
		}

		if (fireButton.isDown) {
			fireRay();
		}

		//collision detection
		lzs.physics.arcade.overlap(bullets, zombies, collisionHandler);
	}
}

function fireRay() {
	if (lzs.time.now > fireTime) {
		pew.play();

		bullet = bullets.getFirstExists(false);

		if (bullet) {
			bullet.reset(ray.x + 65, ray.y + 8);
			bullet.body.velocity.y = -bulletSpeed;
			fireTime = lzs.time.now + fireDelay;
		}
	}
}

function createZombies() {
	zombies = lzs.add.group();
	zombies.enableBody = true;
	zombies.physicsBodyType = Phaser.Physics.ARCADE;
	zombies.setAll('outOfBoundsKill', true);

	lzs.time.events.loop(2000, createZombie, this);
}

function createZombie() {
	var zombie = zombies.create(screenWidth * Math.random(), -150, 'zombie');

	zombie.body.velocity.y = zombieSpeed;
	zombie.hits = 0;
	zombie.alive = false;
}

function collisionHandler(bullet, zombie) {
	if (!zombie.alive) {
		bullet.kill();
		zombie.hits++;

		if (zombie.hits == zombieHitPoints) {
			zombie.alive = true;
		    zombie.body.velocity.y = 0;

		    if (zombie.position.x > (lzs.world.width * 0.5)) {
		    	zombie.body.velocity.x = zombieSpeed;
		    }
		    else {
		    	zombie.body.velocity.x = -zombieSpeed;
		    }

		    score += 20;
			scoreText.text = scoreString + score;
		}
	}

}

function render() {
	// debug
}<|endoftext|>


<commit_before>(function(){
  'use strict';

  angular.module('map', [])
    .factory('Coordinate', CoordinateModel)
    .factory('MapOptions', MapOptionsModel)
    .factory('Polygon', PolygonModel)
    .factory('Path', PathModel)
    .service('LazyLoadGoogleMap', LazyLoadGoogleMap)
    .service('GoogleMap', GoogleMap)
    .service('MapHelper', MapHelper)
    .directive('map', mapDirective)
    .directive('polygon', polygonDirective)
    .directive('path', pathDirective)
    .controller('MapController', MapController)
    .controller('PolygonController', PolygonController);

  MapOptionsModel.$inject = ['Coordinate'];
  LazyLoadGoogleMap.$inject = ['$window', '$q', '$timeout'];
  GoogleMap.$inject = ['$q', 'LazyLoadGoogleMap', 'MapOptions'];
  MapHelper.$inject = ['GoogleMap', 'Coordinate', '$q'];
  MapController.$inject = ['$scope', '$q', 'GoogleMap'];
  PolygonController.$inject = ['$scope', '$q'];
  mapDirective.$inject = ['GoogleMap', 'Coordinate'];
  polygonDirective.$inject = ['Polygon', '$q', 'GoogleMap'];
  pathDirective.$inject = ['Coordinate', 'GoogleMap'];

  function CoordinateModel(){
    function Coordinate(lat, lng){
      this.lat = lat;
      this.lng = lng;
    }

    //(data:Object) -> :boolean
    Coordinate.validateJson = function(data){
      if(data == null) return false;

      if(google != null && google.maps != null && google.maps.LatLng != null && data instanceof google.maps.LatLng){
        data.lat = data.lat();
        data.lng = data.lng();
      }

      if(data.lat == null) return false;
      if(data.lng == null) return false;
      return true;
    };
    //(d:Object) -> :Coordinate
    Coordinate.build = function(d){ return new Coordinate(d.lat, d.lng); }
    //(data:Object) -> :Coordinate | null
    Coordinate.fromJson = function(data){
      if(Coordinate.validateJson(data)){
        return Coordinate.build(data);
      }
    };
    //(responseData:Object) -> :Coordinate | :Array[Coordinate]
    Coordinate.apiResponseTransformer = function(responseData){
      if(angular.isArray(responseData)){
        return responseData.map(Coordinate.fromJson).filter(Boolean);
      }
      return Coordinate.fromJson(responseData);
    };

    Coordinate.prototype = {
      toGoogle: function(){
        if(google != null && google.maps != null && google.maps.LatLng != null){
          return new google.maps.LatLng(this.lat, this.lng);
        }
        return null;
      }
    };

    return Coordinate;
  }

  function MapOptionsModel(Coordinate){
    function MapOptions(zoom, center, styles, rest){
      this.zoom = zoom;
      this.center = Coordinate.fromJson(center);
      this.styles = styles;

      for(var prop in rest){
        if(rest.hasOwnProperty(prop) && prop != 'zoom' && prop != 'center' && prop != 'styles'){
          this[prop] = rest[prop];
        }
      }
    }

    //(data:Object) -> :boolean
    MapOptions.validateJson = function(data){
      if(data == null) return false;

      if(data.zoom == null) return false;
      if(data.center == null) return false;
      return true;
    };

    //(d:Object) -> :MapOptions
    MapOptions.build = function(d){ return new MapOptions(d.zoom, d.center, d.styles, d) }

    //(data:Object) -> :MapOptions | null
    MapOptions.fromJson = function(data){
      if(MapOptions.validateJson(data)){
        return MapOptions.build(data);
      }
    };
    //(responseData:Object) -> :MapOptions | :Array[MapOptions]
    MapOptions.apiResponseTransformer = function(responseData){
      if(angular.isArray(responseData)){
        return responseData.map(MapOptions.fromJson).filter(Boolean);
      }
      return MapOptions.fromJson(responseData);
    };

    MapOptions.prototype = {
      toGoogle: function(){
        var result = {}
        for(var prop in this){
          if(this.hasOwnProperty(prop)){
            if(this[prop] == null || this[prop].toGoogle == undefined) result[prop] = this[prop];
            else result[prop] = this[prop].toGoogle();
          }
        }
        return result;
      }
    };

    return MapOptions;
  }

  function PolygonModel(){
    function Polygon(options){
      for(var prop in options){
        if(options.hasOwnProperty(prop)){
          this[prop] = options[prop];
        }
      }
    }
    //(d:Object) -> :Polygon
    Polygon.build = function(d){ return new Polygon(d) };

    //(data:Object) -> :boolean
    //mutates data
    Polygon.validateJson = function(data){
      if(data == null) return false;

      if(data.stroke) {
        if(data.stroke.color != null) data.strokeColor = data.stroke.color;
        if(data.stroke.opacity != null) data.strokeOpacity = data.stroke.opacity;
        if(data.stroke.weight != null) data.strokeWeight = data.stroke.weight;
      }

      if(data.fill) {
        if(data.fill.color != null) data.fillColor = data.fill.color;
        if(data.fill.opacity != null) data.fillOpacity = data.fill.opacity;
      }
      return true;
    };

    //(data:Object) -> :Polygon | null
    Polygon.fromJson = function(data){
      //data will be muted after call to validateJson
      if(Polygon.validateJson(data)){
        return Polygon.build(data);
      }
    };
    //(responseData:Object) -> :Polygon | :Array[Polygon]
    Polygon.apiResponseTransformer = function(responseData){
      if(angular.isArray(responseData)){
        return responseData.map(Polygon.fromJson).filter(Boolean);
      }
      return Polygon.fromJson(responseData);
    };

    Polygon.prototype = {
      toGoogle: function(){
        var result = {};
        for(var prop in this){
          if(this.hasOwnProperty(prop)){
            if(this[prop] == null || this[prop].toGoogle == undefined) result[prop] = this[prop];
            else result[prop] = this[prop].toGoogle();
          }
        }
        return new google.maps.Polygon(result);
      }
    };

    return Polygon;
  }

  function PathModel(){
    function Path(options){
//      this.zoom = zoom;

//      for(var prop in rest){
//        if(rest.hasOwnProperty(prop) && prop != 'zoom' && prop != 'center' && prop != 'styles'){
//          this[prop] = rest[prop];
//        }
//      }
    }
    //(d:Object) -> :Path
    Path.build = function(d){ return new Path(d) };

    //(data:Object) -> :boolean
    Path.validateJson = function(data){
      if(data == null) return false;
      return true;
    };

    //(data:Object) -> :Path | null
    Path.fromJson = function(data){
      if(Path.validateJson(data)){
        return Path.build(data);
      }
    };
    //(responseData:Object) -> :Path | :Array[Path]
    Path.apiResponseTransformer = function(responseData){
      if(angular.isArray(responseData)){
        return responseData.map(Path.fromJson).filter(Boolean);
      }
      return Path.fromJson(responseData);
    };

    Path.prototype = {
      toGoogle: function(){
        var result = {};
        for(var prop in this){
          if(this.hasOwnProperty(prop)){
            if(this[prop] == null || this[prop].toGoogle == undefined) result[prop] = this[prop];
            else result[prop] = this[prop].toGoogle();
          }
        }
        return result;
      }
    };

    return Path;
  }

  function LazyLoadGoogleMap($window, $q, $timeout){
    this.load = function(key) {
      function loadScript(){
        var script = document.createElement('script');
        script.type = 'text/javascript';
        script.src = 'https://maps.googleapis.com/maps/api/js?v=3.exp&callback=initGoogleMap';
        if(key != null) script.src += "&key=" + key;
        document.body.appendChild(script);
      }

      var deferred = $q.defer();
      if($window.google && $window.google.maps){
        $timeout(function(){deferred.resolve();});
      } else {
        $window.initGoogleMap = function(){ deferred.resolve() }

        if (document.readyState === "complete") { loadScript() }
        else if ($window.attachEvent) { $window.attachEvent('onload', loadScript); }
        else { $window.addEventListener('load', loadScript, false); }
      }

      return deferred.promise;
    }
  }

  function GoogleMap($q, LazyLoadGoogleMap, MapOptions){
    var mapPromise = null;
    var deferred = $q.defer();

    this.map = function(key, id, options) {
      if(mapPromise != null) return mapPromise;
      else if(key == null && id == null && options == null){
        return deferred.promise;
      } else{
        mapPromise = LazyLoadGoogleMap.load(key).then(function(){
          var opt = MapOptions.apiResponseTransformer(options).toGoogle();

          return new google.maps.Map(document.getElementById(id), opt);
        });
        deferred.resolve(mapPromise);
        return mapPromise;
      }
    };
    this.$destroy = function(){
      mapPromise = null;
      deferred.reject("destroying map");
    }
  }

  function MapHelper(GoogleMap, Coordinate, $q){
    //[:{lat,lng}] => {lat, lng}
    this.getCenter = function(coordinates){
      return GoogleMap.map().then(function(){
        var bounds = new google.maps.LatLngBounds();
        angular.forEach(coordinates, function(coord){
          bounds.extend(Coordinate.apiResponseTransformer(coord).toGoogle());
        });
        if(!bounds.isEmpty()) {
          return Coordinate.apiResponseTransformer(bounds.getCenter());
        } else {
          return $q.reject("no available center")
        }
      });
    }

    this.offsetCenter = function(coordinate, offsetX, offsetY) {
      return GoogleMap.map().then(function(map){
        var deferred = $q.defer();
        var ov = new google.maps.OverlayView();
        ov.onAdd = function() {
          var proj = this.getProjection();
          var aPoint = proj.fromLatLngToContainerPixel(Coordinate.apiResponseTransformer(coordinate).toGoogle());
          aPoint.x = aPoint.x+offsetX;
          aPoint.y = aPoint.y+offsetY;

          deferred.resolve(Coordinate.apiResponseTransformer(proj.fromContainerPixelToLatLng(aPoint)));
        };
        ov.draw = function() {};
        ov.setMap(map);
        return deferred.promise;
      });
    }
  }

  function MapController($scope, $q, GoogleMap){
    this.addPolygon = function(polygon){
      if(polygon == null) return $q.reject("undefined polygon");

      return GoogleMap.map().then(function(map){
        var mapPolygon = polygon.toGoogle();
        mapPolygon.setMap(map);
        return mapPolygon;
      });
    };
  }

  function PolygonController($scope, $q){
    this.setPath = function(coordinates){
      if(coordinates == null) return $q.reject("undefined polygon");

      return $scope.polygon.then(function(polygon){
        polygon.setPaths(coordinates.map(function(c){return c.toGoogle()}));
      });
    }
  }

  function mapDirective(GoogleMap, Coordinate){
    var GOOGLE_MAP_ID = "mapId";

    return {
      template: "
" +
          "

" +
          "

"+
        "
",
      scope: {
        key:'@',
        zoom:'=',
        center:'=',
        styles:'=',
        options:'=?'
      },
      transclude:true,
      controller: MapController,
      link: function($scope, element, attrs, controller){
        GoogleMap.map($scope.key, GOOGLE_MAP_ID, getMapOptions($scope)).then(function(map){
          //map initialized
        });

        $scope.$watchGroup(["center", "styles"], function(nv){ GoogleMap.map().then(function(map){
          var newCenter = nv[0];
          var newStyles = nv[1];
          map.setOptions({styles: newStyles});
          if(newCenter != null) map.panTo(Coordinate.apiResponseTransformer(newCenter).toGoogle());
        })});

        $scope.$on("$destroy", function(){ GoogleMap.$destroy(); });

        function getMapOptions($scope) {
          var opt = {};
          if($scope.zoom) opt.zoom = $scope.zoom;
          else opt.zoom = 3;
          if($scope.center) opt.center = $scope.center;
          else opt.center = {lat:0, lng: 0}
          if($scope.styles) opt.styles = $scope.styles;

          for(var prop in $scope.options){
            if($scope.options.hasOwnProperty(prop)){ opt[prop] = $scope.options[prop];}
          }

          return opt;
        }

      }
    }
  }

  function polygonDirective(Polygon, $q, GoogleMap){
    return {
      restrict: 'AE',
      require: '^map',
      scope: {
        options:'=?'
      },
      controller: PolygonController,
      link: function($scope, element, attr, mapController){
        $scope.$watch("options", function(newValue){ GoogleMap.map().then(function(){
          if($scope.polygon == null){
            $scope.polygon = mapController.addPolygon(Polygon.apiResponseTransformer(newValue));
          } else {
            $scope.polygon.then(function(polygon){
              if(newValue == null) {
                polygon.setMap(null);
                $scope.polygon = null;
              } else polygon.setOptions(newValue);
            }).catch(function(error){
              $scope.polygon = mapController.addPolygon(Polygon.apiResponseTransformer(newValue));
            });
          }
        })})

      }
    }
  }

  function pathDirective(Coordinate, GoogleMap){
    return {
      restrict: 'AE',
      require: ['^polygon', 'ngModel'],
      scope: {
        options:'=?',
        model:'=ngModel'
      },
      link: function($scope, element, attr, requires){
        var polygonController = requires[0];
        $scope.$watch("model", function(newValue){
          GoogleMap.map().then(function(){
            polygonController.setPath(Coordinate.apiResponseTransformer(newValue)); });
          });

      }
    }
  }
})();
<commit_msg>changed google to window.google to prevent undefined error<commit_after>(function(){
  'use strict';

  angular.module('map', [])
    .factory('Coordinate', CoordinateModel)
    .factory('MapOptions', MapOptionsModel)
    .factory('Polygon', PolygonModel)
    .factory('Path', PathModel)
    .service('LazyLoadGoogleMap', LazyLoadGoogleMap)
    .service('GoogleMap', GoogleMap)
    .service('MapHelper', MapHelper)
    .directive('map', mapDirective)
    .directive('polygon', polygonDirective)
    .directive('path', pathDirective)
    .controller('MapController', MapController)
    .controller('PolygonController', PolygonController);

  MapOptionsModel.$inject = ['Coordinate'];
  LazyLoadGoogleMap.$inject = ['$window', '$q', '$timeout'];
  GoogleMap.$inject = ['$q', 'LazyLoadGoogleMap', 'MapOptions'];
  MapHelper.$inject = ['GoogleMap', 'Coordinate', '$q'];
  MapController.$inject = ['$scope', '$q', 'GoogleMap'];
  PolygonController.$inject = ['$scope', '$q'];
  mapDirective.$inject = ['GoogleMap', 'Coordinate'];
  polygonDirective.$inject = ['Polygon', '$q'];
  pathDirective.$inject = ['Coordinate'];

  function CoordinateModel(){
    function Coordinate(lat, lng){
      this.lat = lat;
      this.lng = lng;
    }

    //(data:Object) -> :boolean
    Coordinate.validateJson = function(data){
      if(data == null) return false;

      if(window.google != null && window.google.maps != null && window.google.maps.LatLng != null && data instanceof window.google.maps.LatLng){
        data.lat = data.lat();
        data.lng = data.lng();
      }

      if(data.lat == null) return false;
      if(data.lng == null) return false;
      return true;
    };
    //(d:Object) -> :Coordinate
    Coordinate.build = function(d){ return new Coordinate(d.lat, d.lng); }
    //(data:Object) -> :Coordinate | null
    Coordinate.fromJson = function(data){
      if(Coordinate.validateJson(data)){
        return Coordinate.build(data);
      }
    };
    //(responseData:Object) -> :Coordinate | :Array[Coordinate]
    Coordinate.apiResponseTransformer = function(responseData){
      if(angular.isArray(responseData)){
        return responseData.map(Coordinate.fromJson).filter(Boolean);
      }
      return Coordinate.fromJson(responseData);
    };

    Coordinate.prototype = {
      toGoogle: function(){
        if(window.google != null && window.google.maps != null && window.google.maps.LatLng != null){
          return new google.maps.LatLng(this.lat, this.lng);
        }
        return null;
      }
    };

    return Coordinate;
  }

  function MapOptionsModel(Coordinate){
    function MapOptions(zoom, center, styles, rest){
      this.zoom = zoom;
      this.center = Coordinate.fromJson(center);
      this.styles = styles;

      for(var prop in rest){
        if(rest.hasOwnProperty(prop) && prop != 'zoom' && prop != 'center' && prop != 'styles'){
          this[prop] = rest[prop];
        }
      }
    }

    //(data:Object) -> :boolean
    MapOptions.validateJson = function(data){
      if(data == null) return false;

      if(data.zoom == null) return false;
      if(data.center == null) return false;
      return true;
    };

    //(d:Object) -> :MapOptions
    MapOptions.build = function(d){ return new MapOptions(d.zoom, d.center, d.styles, d) }

    //(data:Object) -> :MapOptions | null
    MapOptions.fromJson = function(data){
      if(MapOptions.validateJson(data)){
        return MapOptions.build(data);
      }
    };
    //(responseData:Object) -> :MapOptions | :Array[MapOptions]
    MapOptions.apiResponseTransformer = function(responseData){
      if(angular.isArray(responseData)){
        return responseData.map(MapOptions.fromJson).filter(Boolean);
      }
      return MapOptions.fromJson(responseData);
    };

    MapOptions.prototype = {
      toGoogle: function(){
        var result = {}
        for(var prop in this){
          if(this.hasOwnProperty(prop)){
            if(this[prop] == null || this[prop].toGoogle == undefined) result[prop] = this[prop];
            else result[prop] = this[prop].toGoogle();
          }
        }
        return result;
      }
    };

    return MapOptions;
  }

  function PolygonModel(){
    function Polygon(options){
      for(var prop in options){
        if(options.hasOwnProperty(prop)){
          this[prop] = options[prop];
        }
      }
    }
    //(d:Object) -> :Polygon
    Polygon.build = function(d){ return new Polygon(d) };

    //(data:Object) -> :boolean
    //mutates data
    Polygon.validateJson = function(data){
      if(data == null) return false;

      if(data.stroke) {
        if(data.stroke.color != null) data.strokeColor = data.stroke.color;
        if(data.stroke.opacity != null) data.strokeOpacity = data.stroke.opacity;
        if(data.stroke.weight != null) data.strokeWeight = data.stroke.weight;
      }

      if(data.fill) {
        if(data.fill.color != null) data.fillColor = data.fill.color;
        if(data.fill.opacity != null) data.fillOpacity = data.fill.opacity;
      }
      return true;
    };

    //(data:Object) -> :Polygon | null
    Polygon.fromJson = function(data){
      //data will be muted after call to validateJson
      if(Polygon.validateJson(data)){
        return Polygon.build(data);
      }
    };
    //(responseData:Object) -> :Polygon | :Array[Polygon]
    Polygon.apiResponseTransformer = function(responseData){
      if(angular.isArray(responseData)){
        return responseData.map(Polygon.fromJson).filter(Boolean);
      }
      return Polygon.fromJson(responseData);
    };

    Polygon.prototype = {
      toGoogle: function(){
        var result = {};
        for(var prop in this){
          if(this.hasOwnProperty(prop)){
            if(this[prop] == null || this[prop].toGoogle == undefined) result[prop] = this[prop];
            else result[prop] = this[prop].toGoogle();
          }
        }
        return new google.maps.Polygon(result);
      }
    };

    return Polygon;
  }

  function PathModel(){
    function Path(options){
//      this.zoom = zoom;

//      for(var prop in rest){
//        if(rest.hasOwnProperty(prop) && prop != 'zoom' && prop != 'center' && prop != 'styles'){
//          this[prop] = rest[prop];
//        }
//      }
    }
    //(d:Object) -> :Path
    Path.build = function(d){ return new Path(d) };

    //(data:Object) -> :boolean
    Path.validateJson = function(data){
      if(data == null) return false;
      return true;
    };

    //(data:Object) -> :Path | null
    Path.fromJson = function(data){
      if(Path.validateJson(data)){
        return Path.build(data);
      }
    };
    //(responseData:Object) -> :Path | :Array[Path]
    Path.apiResponseTransformer = function(responseData){
      if(angular.isArray(responseData)){
        return responseData.map(Path.fromJson).filter(Boolean);
      }
      return Path.fromJson(responseData);
    };

    Path.prototype = {
      toGoogle: function(){
        var result = {};
        for(var prop in this){
          if(this.hasOwnProperty(prop)){
            if(this[prop] == null || this[prop].toGoogle == undefined) result[prop] = this[prop];
            else result[prop] = this[prop].toGoogle();
          }
        }
        return result;
      }
    };

    return Path;
  }

  function LazyLoadGoogleMap($window, $q, $timeout){
    this.load = function(key) {
      function loadScript(){
        var script = document.createElement('script');
        script.type = 'text/javascript';
        script.src = 'https://maps.googleapis.com/maps/api/js?v=3.exp&callback=initGoogleMap';
        if(key != null) script.src += "&key=" + key;
        document.body.appendChild(script);
      }

      var deferred = $q.defer();
      if($window.google && $window.google.maps){
        $timeout(function(){deferred.resolve();});
      } else {
        $window.initGoogleMap = function(){ deferred.resolve() }

        if (document.readyState === "complete") { loadScript() }
        else if ($window.attachEvent) { $window.attachEvent('onload', loadScript); }
        else { $window.addEventListener('load', loadScript, false); }
      }

      return deferred.promise;
    }
  }

  function GoogleMap($q, LazyLoadGoogleMap, MapOptions){
    var mapPromise = null;
    var deferred = $q.defer();

    this.map = function(key, id, options) {
      if(mapPromise != null) return mapPromise;
      else if(key == null && id == null && options == null){
        return deferred.promise;
      } else{
        mapPromise = LazyLoadGoogleMap.load(key).then(function(){
          var opt = MapOptions.apiResponseTransformer(options).toGoogle();

          return new google.maps.Map(document.getElementById(id), opt);
        });
        deferred.resolve(mapPromise);
        return mapPromise;
      }
    };
    this.$destroy = function(){
      mapPromise = null;
      deferred.reject("destroying map");
    }
  }

  function MapHelper(GoogleMap, Coordinate, $q){
    //[:{lat,lng}] => {lat, lng}
    this.getCenter = function(coordinates){
      return GoogleMap.map().then(function(){
        var bounds = new google.maps.LatLngBounds();
        angular.forEach(coordinates, function(coord){
          bounds.extend(Coordinate.apiResponseTransformer(coord).toGoogle());
        });
        if(!bounds.isEmpty()) {
          return Coordinate.apiResponseTransformer(bounds.getCenter());
        } else {
          return $q.reject("no available center")
        }
      });
    }

    this.offsetCenter = function(coordinate, offsetX, offsetY) {
      return GoogleMap.map().then(function(map){
        var deferred = $q.defer();
        var ov = new google.maps.OverlayView();
        ov.onAdd = function() {
          var proj = this.getProjection();
          var aPoint = proj.fromLatLngToContainerPixel(Coordinate.apiResponseTransformer(coordinate).toGoogle());
          aPoint.x = aPoint.x+offsetX;
          aPoint.y = aPoint.y+offsetY;

          deferred.resolve(Coordinate.apiResponseTransformer(proj.fromContainerPixelToLatLng(aPoint)));
        };
        ov.draw = function() {};
        ov.setMap(map);
        return deferred.promise;
      });
    }
  }

  function MapController($scope, $q, GoogleMap){
    this.addPolygon = function(polygon){
      if(polygon == null) return $q.reject("undefined polygon");

      return GoogleMap.map().then(function(map){
        var mapPolygon = polygon.toGoogle();
        mapPolygon.setMap(map);
        return mapPolygon;
      });
    };
  }

  function PolygonController($scope, $q){
    this.setPath = function(coordinates){
      if(coordinates == null) return $q.reject("undefined polygon");

      return $scope.polygon.then(function(polygon){
        polygon.setPaths(coordinates.map(function(c){return c.toGoogle()}));
      });
    }
  }

  function mapDirective(GoogleMap, Coordinate){
    var GOOGLE_MAP_ID = "mapId";

    return {
      template: "
" +
          "

" +
          "

"+
        "
",
      scope: {
        key:'@',
        zoom:'=',
        center:'=',
        styles:'=',
        options:'=?'
      },
      transclude:true,
      controller: MapController,
      link: function($scope, element, attrs, controller){
        GoogleMap.map($scope.key, GOOGLE_MAP_ID, getMapOptions($scope)).then(function(map){
          //map initialized
        });

        $scope.$watchGroup(["center", "styles"], function(nv){ GoogleMap.map().then(function(map){
          var newCenter = nv[0];
          var newStyles = nv[1];
          map.setOptions({styles: newStyles});
          if(newCenter != null) map.panTo(Coordinate.apiResponseTransformer(newCenter).toGoogle());
        })});

        $scope.$on("$destroy", function(){ GoogleMap.$destroy(); });

        function getMapOptions($scope) {
          var opt = {};
          if($scope.zoom) opt.zoom = $scope.zoom;
          else opt.zoom = 3;
          if($scope.center) opt.center = $scope.center;
          else opt.center = {lat:0, lng: 0}
          if($scope.styles) opt.styles = $scope.styles;

          for(var prop in $scope.options){
            if($scope.options.hasOwnProperty(prop)){ opt[prop] = $scope.options[prop];}
          }

          return opt;
        }

      }
    }
  }

  function polygonDirective(Polygon, $q){
    return {
      restrict: 'AE',
      require: '^map',
      scope: {
        options:'=?'
      },
      controller: PolygonController,
      link: function($scope, element, attr, mapController){
        $scope.$watch("options", function(newValue){
          if($scope.polygon == null){
            $scope.polygon = mapController.addPolygon(Polygon.apiResponseTransformer(newValue));
          } else {
            $scope.polygon.then(function(polygon){
              if(newValue == null) {
                polygon.setMap(null);
                $scope.polygon = null;
              } else polygon.setOptions(newValue);
            }).catch(function(error){
              $scope.polygon = mapController.addPolygon(Polygon.apiResponseTransformer(newValue));
            });
          }
        })

      }
    }
  }

  function pathDirective(Coordinate){
    return {
      restrict: 'AE',
      require: ['^polygon', 'ngModel'],
      scope: {
        options:'=?',
        model:'=ngModel'
      },
      link: function($scope, element, attr, requires){
        var polygonController = requires[0];
        $scope.$watch("model", function(newValue){
          polygonController.setPath(Coordinate.apiResponseTransformer(newValue));
        });

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


<commit_before>// yay https://developer.github.com/v3/#cross-origin-resource-sharing

function handleRepoList() {
    var data = JSON.parse(this.responseText);
    console.log(data);
    data.forEach(learnAboutRepo);
}
function learnAboutRepo(repoObj){
    var name = repoObj.name;
    console.log(name);
    var url = repoObj.url;
    console.log(url);
    var repoReq = new XMLHttpRequest();
    repoReq.onload = digInFiles;
    repoReq.open("get", url, true);
    repoReq.send();
}

function digInFiles(){
    var repo = JSON.parse(this.responseText)
    console.log(repo);
}

console.log("don't worry, it's working");
var oReq = new XMLHttpRequest();
oReq.onload = handleRepoList;
oReq.open("get", "https://api.github.com/users/marajade/repos", true);
oReq.send();

<commit_msg>gets repo contents<commit_after>// yay https://developer.github.com/v3/#cross-origin-resource-sharing

function handleRepoList() {
    var data = JSON.parse(this.responseText);
    console.log(data);
    data.forEach(learnAboutRepo);
}
function learnAboutRepo(repoObj){
    var name = repoObj.name;
    console.log(name);
    var url = repoObj.url + '/contents';
    console.log(url);
    var repoReq = new XMLHttpRequest();
    repoReq.onload = digInFiles;
    repoReq.open("get", url, true);
    repoReq.send();
}

function digInFiles(){
    var repo = JSON.parse(this.responseText)
    console.log(repo);
}

console.log("don't worry, it's working");
var oReq = new XMLHttpRequest();
oReq.onload = handleRepoList;
oReq.open("get", "https://api.github.com/users/marajade/repos", true);
oReq.send();

<|endoftext|>


<commit_before>
var Octokat = require("octokat")
,   fs = require("fs")
,   jn = require("path").join
,   log = require("./log")
,   pg = require("password-generator")
;

// helpers
function template (src, data) {
    return fs.readFileSync(jn(__dirname, "templates", src), "utf8")
             .replace(/\{\{(\w+)\}\}/g, function (_, k) {
                 if (typeof data[k] === "undefined") {
                     log.error("No template data for key=" + k + ", file=" + src);
                     return "";
                 }
                 return data[k];
             });
}

function GH (user) {
    if (!user) throw new Error("The GH module requires a user.");
    this.user = user;
    this.octo = new Octokat({ token: user.accessToken });
}

function makeNewRepo (gh, target, owner, repoShortName, report) {
    return target
            .create({ name: repoShortName })
            .then(function (repo) {
                report.push("Repo '" + repoShortName + "' created.");
                return repo;
            })
    ;
}

function pickUserRepo (gh, target, owner, repoShortName, report) {
    var repo = gh.octo.repos(owner, repoShortName);
    report.push("Looking for repo " + owner + "/" + repoShortName + " to import.");
    return repo.fetch();
}

function newFile (gh, name, content, report) {
    return function () {
        return gh.currentRepo
                    .contents(name)
                    .add({
                        message:    "Adding baseline " + name
                    ,   content:    new Buffer(content).toString("base64")
                    })
                    .then(function () {
                        report.push("Added file " + name);
                    })
                    .catch(function () {
                        report.push("Skipped existing file " + name);
                    })
        ;
    };
}

function andify (groups, field) {
    var len = groups.length;
    if (len === 1) return groups[0][field];
    else if (len === 2) return groups.map(function (g) { return g[field]; }).join(" and ");
    else {
        var copy = [].concat(groups)
        ,   last = copy.pop()
        ;
        return copy.map(function (g) { return g[field] + ", "; }) + "and " + last[field];
    }
}

GH.prototype = {
    userOrgs:   function (cb) {
        this.octo.me.orgs.fetch(function (err, data) {
            if (err) return cb(err);
            cb(null, [this.user.username].concat(data.map(function (org) { return org.login; })));
        }.bind(this));
    }
,   commentOnPR: function(data, cb) {
        this.octo.repos(data.owner, data.shortName).issues(data.num).comments.create({body: data.comment}, function(err, comment) {
            if (err) return cb(err);
            cb(null, comment);
        });
    }
,   createRepo: function (data, config, cb) {
        this.createOrImportRepo(data, makeNewRepo, newFile, config, cb);
    }
,   importRepo: function (data, config, cb) {
        this.createOrImportRepo(data, pickUserRepo, newFile, config, cb);
    }
    // data describes the repo to create
    // setupAction is a function returning a promise that is called to initiate the creation or
    // obtain a pointer to the repo, it must resolve with the octo repo object
    // action is a function returning a promise that creates or imports a file, and logs a message
   // config is a configuration object with data about the server setup
,   createOrImportRepo: function (data, setupAction, action, config, cb) {
        // { org: ..., repo: ... }
        // we need to treat the current user and an org differently
        var report = []
        ,   target = (this.user.username === data.org) ?
                            this.octo.me.repos :
                            this.octo.orgs(data.org).repos
        ,   license
        ,   contributing
        ,   w3cJSON
        ,   index
        ,   simpleRepo
        ,   readme
        ,   hookURL = config.hookURL || (config.url + config.hookPath)
        ,   tmplData = {
                name:           andify(data.groups, "name")
            ,   username:       this.user.username
            ,   w3cid:          JSON.stringify(data.groups.map(function (g) { return g.w3cid; }))
            ,   repo:           data.repo
            ,   displayName:    this.user.displayName
            }
        ;
        // collaborations between groups of different types aren't really possible, they don't have
        // the same legal regimen, so we only look at the first one
        if (data.groups[0].groupType === "CG") {
            contributing = template("CG-contributing.md", tmplData);
            license = template("CG-license.md", tmplData);
        }
        else if (data.groups[0].groupType === "WG") {
            contributing = template("WG-contributing.md", tmplData);
            license = template("WG-license.md", tmplData);
        }
        else {
            var msg = "We currently don't support creating repos for group type: " + data.groups[0].groupType;
            return cb(msg);
        }
        w3cJSON = template("w3c.json", tmplData);
        index = template("index.html", tmplData);
        readme = template("README.md", tmplData);
        setupAction(this, target, data.org, data.repo, report)
            .then(function (repo) {
                this.currentRepo = repo;
                simpleRepo = {
                    name:       repo.name
                ,   fullName:   repo.fullName
                ,   owner:      repo.owner.login
                ,   groups:     data.groups.map(function (g) { return g.w3cid; })
                ,   secret:     pg(20)
                };
            }.bind(this))
            .then(action(this, "LICENSE.md", license, report))
            .then(action(this, "CONTRIBUTING.md", contributing, report))
            .then(action(this, "README.md", readme, report))
            .then(action(this, "index.html", index, report))
            .then(action(this, "w3c.json", w3cJSON, report))
            .then(function () {
                return this.currentRepo
                        .hooks
                        .fetch()
                        .then(function (hooks) {
                            if (!hooks || !hooks.length || !hooks.some(function (h) { return h.config.url === hookURL; })) {
                                return this.currentRepo.hooks.create({
                                                            name:   "web"
                                                        ,   config: {
                                                                url:            config.hookURL || (config.url + "api/hook")
                                                            ,   content_type:   "json"
                                                            ,   secret:         simpleRepo.secret
                                                            }
                                                        ,   events: ["pull_request", "issue_comment"]
                                                        ,   active: true
                                                        })
                                                        .then(function () { report.push("Hook installed."); })
                                ;
                            }
                            else {
                                report.push("Hook already present.");
                            }
                        }.bind(this))
                ;
            }.bind(this))
            .then(function () {
                cb(null, { actions: report, repo: simpleRepo });
            })
            .catch(cb)
        ;
    }
,   status: function (data, cb) {
        this.octo
            .repos(data.owner, data.shortName)
            .statuses(data.sha)
            .create(data.payload)
            .then(function () { cb(null); })
            .catch(cb)
        ;
    }
,   getUser:    function (username, cb) {
        this.octo
            .users(username)
            .fetch()
            .then(function (user) {
                var u = {
                        accessToken:        null
                    ,   admin:              false
                    ,   affiliation:        null
                    ,   affiliationName:    null
                    ,   blanket:            false
                    ,   blog:               user.blog || ""
                    ,   displayName:        user.name
                    ,   ghID:               user.id
                    ,   groups:             {}
                    ,   emails:             []
                    ,   photos:             []
                    ,   profileUrl:         user.html_url
                    ,   provider:           "github"
                    ,   username:           username
                    ,   w3capi:             null
                    ,   w3cid:              null
                };
                if (user.email) u.emails.push({ value: user.email });
                if (user.avatar_url) u.photos.push({ value: user.avatar_url });
                cb(null, u);
            })
            .catch(cb)
        ;
    }
};

module.exports = GH;
<commit_msg>Get emails from listed contacts for a given repo<commit_after>
var Octokat = require("octokat")
,   fs = require("fs")
,   jn = require("path").join
,   log = require("./log")
,   pg = require("password-generator")
;

// helpers
function template (src, data) {
    return fs.readFileSync(jn(__dirname, "templates", src), "utf8")
             .replace(/\{\{(\w+)\}\}/g, function (_, k) {
                 if (typeof data[k] === "undefined") {
                     log.error("No template data for key=" + k + ", file=" + src);
                     return "";
                 }
                 return data[k];
             });
}

function GH (user) {
    if (!user) throw new Error("The GH module requires a user.");
    this.user = user;
    this.octo = new Octokat({ token: user.accessToken });
}

function makeNewRepo (gh, target, owner, repoShortName, report) {
    return target
            .create({ name: repoShortName })
            .then(function (repo) {
                report.push("Repo '" + repoShortName + "' created.");
                return repo;
            })
    ;
}

function pickUserRepo (gh, target, owner, repoShortName, report) {
    var repo = gh.octo.repos(owner, repoShortName);
    report.push("Looking for repo " + owner + "/" + repoShortName + " to import.");
    return repo.fetch();
}

function newFile (gh, name, content, report) {
    return function () {
        return gh.currentRepo
                    .contents(name)
                    .add({
                        message:    "Adding baseline " + name
                    ,   content:    new Buffer(content).toString("base64")
                    })
                    .then(function () {
                        report.push("Added file " + name);
                    })
                    .catch(function () {
                        report.push("Skipped existing file " + name);
                    })
        ;
    };
}

function andify (groups, field) {
    var len = groups.length;
    if (len === 1) return groups[0][field];
    else if (len === 2) return groups.map(function (g) { return g[field]; }).join(" and ");
    else {
        var copy = [].concat(groups)
        ,   last = copy.pop()
        ;
        return copy.map(function (g) { return g[field] + ", "; }) + "and " + last[field];
    }
}

GH.prototype = {
    userOrgs:   function (cb) {
        this.octo.me.orgs.fetch(function (err, data) {
            if (err) return cb(err);
            cb(null, [this.user.username].concat(data.map(function (org) { return org.login; })));
        }.bind(this));
    }
,   commentOnPR: function(data, cb) {
        this.octo.repos(data.owner, data.shortName).issues(data.num).comments.create({body: data.comment}, function(err, comment) {
            if (err) return cb(err);
            cb(null, comment);
        });
    }
,   createRepo: function (data, config, cb) {
        this.createOrImportRepo(data, makeNewRepo, newFile, config, cb);
    }
,   importRepo: function (data, config, cb) {
        this.createOrImportRepo(data, pickUserRepo, newFile, config, cb);
    }
    // data describes the repo to create
    // setupAction is a function returning a promise that is called to initiate the creation or
    // obtain a pointer to the repo, it must resolve with the octo repo object
    // action is a function returning a promise that creates or imports a file, and logs a message
   // config is a configuration object with data about the server setup
,   createOrImportRepo: function (data, setupAction, action, config, cb) {
        // { org: ..., repo: ... }
        // we need to treat the current user and an org differently
        var report = []
        ,   target = (this.user.username === data.org) ?
                            this.octo.me.repos :
                            this.octo.orgs(data.org).repos
        ,   license
        ,   contributing
        ,   w3cJSON
        ,   index
        ,   simpleRepo
        ,   readme
        ,   hookURL = config.hookURL || (config.url + config.hookPath)
        ,   tmplData = {
                name:           andify(data.groups, "name")
            ,   username:       this.user.username
            ,   w3cid:          JSON.stringify(data.groups.map(function (g) { return g.w3cid; }))
            ,   repo:           data.repo
            ,   displayName:    this.user.displayName
            }
        ;
        // collaborations between groups of different types aren't really possible, they don't have
        // the same legal regimen, so we only look at the first one
        if (data.groups[0].groupType === "CG") {
            contributing = template("CG-contributing.md", tmplData);
            license = template("CG-license.md", tmplData);
        }
        else if (data.groups[0].groupType === "WG") {
            contributing = template("WG-contributing.md", tmplData);
            license = template("WG-license.md", tmplData);
        }
        else {
            var msg = "We currently don't support creating repos for group type: " + data.groups[0].groupType;
            return cb(msg);
        }
        w3cJSON = template("w3c.json", tmplData);
        index = template("index.html", tmplData);
        readme = template("README.md", tmplData);
        setupAction(this, target, data.org, data.repo, report)
            .then(function (repo) {
                this.currentRepo = repo;
                simpleRepo = {
                    name:       repo.name
                ,   fullName:   repo.fullName
                ,   owner:      repo.owner.login
                ,   groups:     data.groups.map(function (g) { return g.w3cid; })
                ,   secret:     pg(20)
                };
            }.bind(this))
            .then(action(this, "LICENSE.md", license, report))
            .then(action(this, "CONTRIBUTING.md", contributing, report))
            .then(action(this, "README.md", readme, report))
            .then(action(this, "index.html", index, report))
            .then(action(this, "w3c.json", w3cJSON, report))
            .then(function () {
                return this.currentRepo
                        .hooks
                        .fetch()
                        .then(function (hooks) {
                            if (!hooks || !hooks.length || !hooks.some(function (h) { return h.config.url === hookURL; })) {
                                return this.currentRepo.hooks.create({
                                                            name:   "web"
                                                        ,   config: {
                                                                url:            config.hookURL || (config.url + "api/hook")
                                                            ,   content_type:   "json"
                                                            ,   secret:         simpleRepo.secret
                                                            }
                                                        ,   events: ["pull_request", "issue_comment"]
                                                        ,   active: true
                                                        })
                                                        .then(function () { report.push("Hook installed."); })
                                ;
                            }
                            else {
                                report.push("Hook already present.");
                            }
                        }.bind(this))
                ;
            }.bind(this))
            .then(function () {
                cb(null, { actions: report, repo: simpleRepo });
            })
            .catch(cb)
        ;
    }
,   getRepoContacts: function (repofullname, cb) {
    var self = this;
    self.octo
        .repos(repofullname.split('/')[0], repofullname.split('/')[1])
        .contents('w3c.json').fetch()
        .then(function(w3cinfo) {
            return Promise.all(w3cinfo.contacts.map(function(username) {
                return self.octo.users(username).fetch()
                    .then(function(u) {
                        return u.email;
                    });
            }));
        }).then(function(emails) {
            cb(null, emails);
        })
        .catch(cb);
    }
,   status: function (data, cb) {
        this.octo
            .repos(data.owner, data.shortName)
            .statuses(data.sha)
            .create(data.payload)
            .then(function () { cb(null); })
            .catch(cb)
        ;
    }
,   getUser:    function (username, cb) {
        this.octo
            .users(username)
            .fetch()
            .then(function (user) {
                var u = {
                        accessToken:        null
                    ,   admin:              false
                    ,   affiliation:        null
                    ,   affiliationName:    null
                    ,   blanket:            false
                    ,   blog:               user.blog || ""
                    ,   displayName:        user.name
                    ,   ghID:               user.id
                    ,   groups:             {}
                    ,   emails:             []
                    ,   photos:             []
                    ,   profileUrl:         user.html_url
                    ,   provider:           "github"
                    ,   username:           username
                    ,   w3capi:             null
                    ,   w3cid:              null
                };
                if (user.email) u.emails.push({ value: user.email });
                if (user.avatar_url) u.photos.push({ value: user.avatar_url });
                cb(null, u);
            })
            .catch(cb)
        ;
    }
};

module.exports = GH;
<|endoftext|>


<commit_before>item({desc: 'hotshell-dev'}, function() {

    linux = exec('uname').indexOf('Linux') > -1
    browser = linux ? 'sensible-browser' : 'open'
    generate = 'go generate ./...'
    install = generate + ' && go install ./...'
    hsCmdDir = './cmd/hs'
    buildAndRun = generate + ' && go build ' + hsCmdDir + ' && ./hs'
    allButVendor =  '$(go list ./... | grep -v /vendor/)'
    runTests = generate + ' && go test ' + allButVendor + ' -timeout 10s'

    item({key: 'i', desc: 'install', cmd: install})
    item({key: 'c', desc: 'clean', cmd: 'go clean -i ./...'})
    item({key: 'v', desc: 'vet', cmd: 'go vet ' + allButVendor})
    item({key: 'f', desc: 'fmt', cmd: 'go fmt ' + allButVendor})

    item({key: 'p', desc: 'packaging'}, function() {

        man = 'debian/usr/share/man/man1/hs.1.gz'
        item({key: 'g', desc: 'generate man', cmd: install + ' && hs-man | gzip > ' + man})
        item({key: 's', desc: 'show man', cmd: 'gunzip -c ' + man + ' | groff -Tascii -man -'})
        item({key: 'p', desc: 'package', cmd: "goxc -pv $(cat VERSION) -wd " + hsCmdDir})
    })

    item({key: 't', desc: 'tests'}, function() {

        item({key: 't', desc: 'test', cmd: runTests})
        item({key: 'i', desc: 'interactively run end to end tests'}, function() {

            testDir = hsCmdDir + '/testcases/'
            _.each(exec('ls -d ' + testDir + '*/').split('\n'), function(subdir, ix) {
                item({key: ix, desc: subdir}, function() {

                    _.each(exec('ls ' + desc).split('\n'), function(testName, ix) {
                        item({key: ix, desc: testName, cmd: buildAndRun + ' -f ' + desc + testName})
                    })
                })
            })
        })

        item({key: 'f', desc: 'failed end to end tests'}, function() {

            item({desc: '(reload menu to update failed tests list)\n'})

            faileTestsDir = hsCmdDir + '/tmp/failed-cases'

            item({key: 'r', desc: 'run tests', cmd: runTests})
            item({key: 'o', desc: 'open failed tests directory', cmd: browser + ' ' + faileTestsDir})

            if (exec('if [ -d "'+faileTestsDir+'" ]; then echo true; fi') == '') return

            _.each(exec('find ' + faileTestsDir + ' -name *.html').split('\n'), function(el, ix) {
                item({key: ix, desc: 'failed test ' + ix, cmd: browser + ' ' + el})
            })
        })
    })

    item({key: 'e', desc: 'examples'}, function() {

        _.each(exec('ls examples/**/*.js').split('\n'), function(el, ix) {
            item({key: ix, desc: el, cmd: buildAndRun + ' --chdir -f ' + el})
        })
    })

    item({key: 'd', desc: 'dev env setup'}, function() {
        item({key: 'b', cmd: 'go get -u github.com/jteeuwen/go-bindata/...'})
        item({key: 'v', cmd: 'go get -u github.com/kardianos/govendor'})
        item({key: 'x', cmd: 'go get -u github.com/laher/goxc'})
    })
})<commit_msg>provide a way to test hotshell brew formula<commit_after>item({desc: 'hotshell-dev'}, function() {

    linux = exec('uname').indexOf('Linux') > -1
    browser = linux ? 'sensible-browser' : 'open'
    generate = 'go generate ./...'
    install = generate + ' && go install ./...'
    hsCmdDir = './cmd/hs'
    buildAndRun = generate + ' && go build ' + hsCmdDir + ' && ./hs'
    allButVendor =  '$(go list ./... | grep -v /vendor/)'
    runTests = generate + ' && go test ' + allButVendor + ' -timeout 10s'

    item({key: 'i', desc: 'install', cmd: install})
    item({key: 'c', desc: 'clean', cmd: 'go clean -i ./...'})
    item({key: 'v', desc: 'vet', cmd: 'go vet ' + allButVendor})
    item({key: 'f', desc: 'fmt', cmd: 'go fmt ' + allButVendor})

    item({key: 'p', desc: 'packaging'}, function() {

        man = 'debian/usr/share/man/man1/hs.1.gz'
        item({key: 'g', desc: 'generate man', cmd: install + ' && hs-man | gzip > ' + man})
        item({key: 's', desc: 'show man', cmd: 'gunzip -c ' + man + ' | groff -Tascii -man -'})
        item({key: 'p', desc: 'package', cmd: "goxc -pv $(cat VERSION) -wd " + hsCmdDir})
    })

    item({key: 't', desc: 'tests'}, function() {

        item({key: 't', desc: 'test', cmd: runTests})
        item({key: 'i', desc: 'interactively run end to end tests'}, function() {

            testDir = hsCmdDir + '/testcases/'
            _.each(exec('ls -d ' + testDir + '*/').split('\n'), function(subdir, ix) {
                item({key: ix, desc: subdir}, function() {

                    _.each(exec('ls ' + desc).split('\n'), function(testName, ix) {
                        item({key: ix, desc: testName, cmd: buildAndRun + ' -f ' + desc + testName})
                    })
                })
            })
        })

        item({key: 'f', desc: 'failed end to end tests'}, function() {

            item({desc: '(reload menu to update failed tests list)\n'})

            faileTestsDir = hsCmdDir + '/tmp/failed-cases'

            item({key: 'r', desc: 'run tests', cmd: runTests})
            item({key: 'o', desc: 'open failed tests directory', cmd: browser + ' ' + faileTestsDir})

            if (exec('if [ -d "'+faileTestsDir+'" ]; then echo true; fi') == '') return

            _.each(exec('find ' + faileTestsDir + ' -name *.html').split('\n'), function(el, ix) {
                item({key: ix, desc: 'failed test ' + ix, cmd: browser + ' ' + el})
            })
        })
    })

    item({key: 'e', desc: 'examples'}, function() {

        _.each(exec('ls examples/**/*.js').split('\n'), function(el, ix) {
            item({key: ix, desc: el, cmd: buildAndRun + ' --chdir -f ' + el})
        })
    })

    item({key: 'd', desc: 'dev env setup'}, function() {
        item({key: 'b', cmd: 'go get -u github.com/jteeuwen/go-bindata/...'})
        item({key: 'v', cmd: 'go get -u github.com/kardianos/govendor'})
        item({key: 'x', cmd: 'go get -u github.com/laher/goxc'})
    })

    item({key: 'b', desc: 'brew'}, function() {
        item({key: 't', desc: 'test' + '\n  ', cmd: script(
            'set -eu',
            'echo -n "[git hash] "',
            'read githash',
            'formula=https://raw.githubusercontent.com/julienmoumne/homebrew/$githash/Library/Formula/hs.rb',
            'brew remove hs || true',
            'brew cleanup -s',
            'brew install $formula',
            'brew test $formula',
            'hs'
        )})
    })
})

function script () {
    src = '';
    _.each(arguments, function (el, ix) { src += '   ' + el + '\n' })
    return src
}<|endoftext|>