<commit_before>var City = function() {
  var city = {};

  city.STREET_WIDTH = 2;
  city.STREET_DEPTH = 2;
  city.BLOCK_WIDTH = 4;
  city.BLOCK_DEPTH = 4;
  city.BLOCK_ROWS = 60;
  city.BLOCK_COLUMNS = 20;
  city.MIN_BUILDING_HEIGHT = 0.5;
  city.MAX_BUILDING_HEIGHT = 20;
  city.MAX_BUILDING_MATERIALS = 50;
  city.TOTAL_SCENE_WIDTH = (city.BLOCK_WIDTH * city.BLOCK_ROWS) + (city.STREET_WIDTH * (city.BLOCK_ROWS - 1));
  city.HALF_SCENE_WIDTH = city.TOTAL_SCENE_WIDTH / 2;
  city.TOTAL_SCENE_DEPTH = (city.BLOCK_DEPTH * city.BLOCK_COLUMNS) + (city.STREET_DEPTH * (city.BLOCK_COLUMNS - 1));
  city.HALF_SCENE_DEPTH = city.TOTAL_SCENE_DEPTH / 2;

  city.BLOCK_LAYOUTS = [
    [ { width: 1.0, depth: 1.0, offsetFromBlockCenterX: 0.0, offsetFromBlockCenterZ: 0.0 } ],
    [ { width: 0.5, depth: 1.0, offsetFromBlockCenterX: -0.5, offsetFromBlockCenterZ: 0.0 },
      { width: 0.5, depth: 1.0, offsetFromBlockCenterX: 0.5, offsetFromBlockCenterZ: 0.0 } ],
    [ { width: 1.0, depth: 0.5, offsetFromBlockCenterX: 0.0, offsetFromBlockCenterZ: -0.5 },
      { width: 1.0, depth: 0.5, offsetFromBlockCenterX: 0.0, offsetFromBlockCenterZ: 0.5 } ],
    [ { width: 0.5, depth: 1.0, offsetFromBlockCenterX: -0.5, offsetFromBlockCenterZ: 0.0 },
      { width: 0.5, depth: 0.5, offsetFromBlockCenterX: 0.5, offsetFromBlockCenterZ: -0.5},
      { width: 0.5, depth: 0.5, offsetFromBlockCenterX: 0.5, offsetFromBlockCenterZ: 0.5} ],
    [ { width: 0.5, depth: 0.5, offsetFromBlockCenterX: -0.5, offsetFromBlockCenterZ: -0.5 },
      { width: 0.5, depth: 0.5, offsetFromBlockCenterX: -0.5, offsetFromBlockCenterZ: 0.5},
      { width: 0.5, depth: 0.5, offsetFromBlockCenterX: 0.5, offsetFromBlockCenterZ: -0.5},
      { width: 0.5, depth: 0.5, offsetFromBlockCenterX: 0.5, offsetFromBlockCenterZ: 0.5} ],
    [ { width: (1 / 3), depth: 0.5, offsetFromBlockCenterX: -(2 / 3), offsetFromBlockCenterZ: 0.5 },
      { width: (1 / 3), depth: 0.5, offsetFromBlockCenterX: 0.0, offsetFromBlockCenterZ: 0.5},
      { width: (1 / 3), depth: 0.5, offsetFromBlockCenterX: (2 / 3), offsetFromBlockCenterZ: 0.5},
      { width: 0.5, depth: 0.5, offsetFromBlockCenterX: -0.5, offsetFromBlockCenterZ: -0.5},
      { width: 0.5, depth: 0.5, offsetFromBlockCenterX: 0.5, offsetFromBlockCenterZ: -0.5} ],
  ];

  city.buildScene = function() {
    var scene = new THREE.Scene();

    scene.add(buildGroundGeometry());

    var buildingMaterials = buildMaterials();
    var buildingGeometries = buildEmptyGeometriesForBuildings();

    // Loop through the lower left corner of each block
    var x, z;
    for (x = -(city.HALF_SCENE_WIDTH); x < city.HALF_SCENE_WIDTH; x += city.BLOCK_WIDTH + city.STREET_WIDTH) {
      for (z = -(city.HALF_SCENE_DEPTH); z < city.HALF_SCENE_DEPTH; z += city.BLOCK_DEPTH + city.STREET_DEPTH) {
        generateBlock(x, z, buildingGeometries);
      }
    }

    for (var i = 0; i < city.MAX_BUILDING_MATERIALS; i++) {
      scene.add(new THREE.Mesh(buildingGeometries[i], buildingMaterials[i]));
    }

    return scene;
  };

  var buildGroundGeometry = function() {
    var groundMaterial = new THREE.MeshBasicMaterial({ color: 0xaaaaaa });
    var groundGeometry = new THREE.Mesh(new THREE.PlaneGeometry(city.TOTAL_SCENE_WIDTH * 25, city.TOTAL_SCENE_DEPTH * 25), groundMaterial);
    groundGeometry.rotation.x = -(Math.PI / 2);

    return groundGeometry;
  };

  var buildMaterials = function() {
    var buildingMaterials = [];

    for (var i = 0; i < city.MAX_BUILDING_MATERIALS; i++) {
      var r = Math.random();
      var g = r;
      var b = r;
      var buildingColor = new THREE.Color(0xffffff).setRGB(r, g, b);

      buildingMaterials.push(new THREE.MeshLambertMaterial({ color: buildingColor.getHex() }));
    }

    return buildingMaterials;
  };

  var buildEmptyGeometriesForBuildings = function() {
    var buildingGeometries = [];

    for (var i = 0; i < city.MAX_BUILDING_MATERIALS; i++) {
      buildingGeometries.push(new THREE.Geometry());
    }

    return buildingGeometries;
  };

  var generateBlock = function(x, z, buildingGeometries) {
    var i, lotLayout, buildingHeight, building;
    var blockLayout = city.BLOCK_LAYOUTS[Math.floor(Math.random() * city.BLOCK_LAYOUTS.length)];

    for (i = 0; i < blockLayout.length; i++) {
      lotLayout = blockLayout[i];
      buildingHeight = calculateBuildingHeight(x, z);
      building = generateBuilding(x, buildingHeight, z, lotLayout);

      var materialIndex = Math.floor(Math.random() * city.MAX_BUILDING_MATERIALS);
      THREE.GeometryUtils.merge(buildingGeometries[materialIndex], building);
    }
  };

  var calculateBuildingHeight = function(x, z) {
    var maxHeightX = city.MAX_BUILDING_HEIGHT * ((city.HALF_SCENE_WIDTH - Math.abs(x)) / city.HALF_SCENE_WIDTH);
    var maxHeightZ = city.MAX_BUILDING_HEIGHT * ((city.HALF_SCENE_DEPTH - Math.abs(z)) / city.HALF_SCENE_DEPTH);
    var maxHeight = Math.min(maxHeightX, maxHeightZ);
    //var buildingHeight = Math.floor((Math.random() * maxHeight - city.MIN_BUILDING_HEIGHT)) + city.MIN_BUILDING_HEIGHT;

    return maxHeight;
  };

  var generateBuilding = function(x, maxY, z, lotLayout) {
    var building = new THREE.Mesh(new THREE.BoxGeometry(lotLayout.width * city.BLOCK_WIDTH, 1, lotLayout.depth * city.BLOCK_WIDTH));

    building.position.x = x + city.BLOCK_WIDTH / 2 + ((city.BLOCK_WIDTH / 2) * lotLayout.offsetFromBlockCenterX);
    building.scale.y =  (Math.random() * maxY) + city.MIN_BUILDING_HEIGHT;
    building.position.y = building.scale.y / 2;
    building.position.z = z + city.BLOCK_DEPTH / 2 + ((city.BLOCK_DEPTH / 2) * lotLayout.offsetFromBlockCenterZ);

    return building;
  };

  return city;
};
<commit_msg>Improving code formatting<commit_after>var City = function() {
  var city = {};

  city.STREET_WIDTH = 2;
  city.STREET_DEPTH = 2;
  city.BLOCK_WIDTH = 4;
  city.BLOCK_DEPTH = 4;
  city.BLOCK_ROWS = 60;
  city.BLOCK_COLUMNS = 20;
  city.MIN_BUILDING_HEIGHT = 0.5;
  city.MAX_BUILDING_HEIGHT = 20;
  city.MAX_BUILDING_MATERIALS = 50;
  city.TOTAL_SCENE_WIDTH = (city.BLOCK_WIDTH * city.BLOCK_ROWS) + (city.STREET_WIDTH * (city.BLOCK_ROWS - 1));
  city.HALF_SCENE_WIDTH = city.TOTAL_SCENE_WIDTH / 2;
  city.TOTAL_SCENE_DEPTH = (city.BLOCK_DEPTH * city.BLOCK_COLUMNS) + (city.STREET_DEPTH * (city.BLOCK_COLUMNS - 1));
  city.HALF_SCENE_DEPTH = city.TOTAL_SCENE_DEPTH / 2;

  city.BLOCK_LAYOUTS = [
    [ { width:     1.0,  depth: 1.0,  offsetFromBlockCenterX:      0.0,  offsetFromBlockCenterZ:  0.0 } ],

    [ { width:     0.5,  depth: 1.0,  offsetFromBlockCenterX:     -0.5,  offsetFromBlockCenterZ:  0.0 },
      { width:     0.5,  depth: 1.0,  offsetFromBlockCenterX:      0.5,  offsetFromBlockCenterZ:  0.0 } ],

    [ { width:     1.0,  depth: 0.5,  offsetFromBlockCenterX:      0.0,  offsetFromBlockCenterZ: -0.5 },
      { width:     1.0,  depth: 0.5,  offsetFromBlockCenterX:      0.0,  offsetFromBlockCenterZ:  0.5 } ],

    [ { width:     0.5,  depth: 1.0,  offsetFromBlockCenterX:     -0.5,  offsetFromBlockCenterZ:  0.0 },
      { width:     0.5,  depth: 0.5,  offsetFromBlockCenterX:      0.5,  offsetFromBlockCenterZ: -0.5 },
      { width:     0.5,  depth: 0.5,  offsetFromBlockCenterX:      0.5,  offsetFromBlockCenterZ:  0.5 } ],

    [ { width:     0.5,  depth: 0.5,  offsetFromBlockCenterX:     -0.5,  offsetFromBlockCenterZ: -0.5 },
      { width:     0.5,  depth: 0.5,  offsetFromBlockCenterX:     -0.5,  offsetFromBlockCenterZ:  0.5 },
      { width:     0.5,  depth: 0.5,  offsetFromBlockCenterX:      0.5,  offsetFromBlockCenterZ: -0.5 },
      { width:     0.5,  depth: 0.5,  offsetFromBlockCenterX:      0.5,  offsetFromBlockCenterZ:  0.5 } ],

    [ { width: (1 / 3),  depth: 0.5,  offsetFromBlockCenterX: -(2 / 3),  offsetFromBlockCenterZ:  0.5 },
      { width: (1 / 3),  depth: 0.5,  offsetFromBlockCenterX:      0.0,  offsetFromBlockCenterZ:  0.5 },
      { width: (1 / 3),  depth: 0.5,  offsetFromBlockCenterX:  (2 / 3),  offsetFromBlockCenterZ:  0.5 },
      { width:     0.5,  depth: 0.5,  offsetFromBlockCenterX:     -0.5,  offsetFromBlockCenterZ: -0.5 },
      { width:     0.5,  depth: 0.5,  offsetFromBlockCenterX:      0.5,  offsetFromBlockCenterZ: -0.5 } ],
  ];

  city.buildScene = function() {
    var scene = new THREE.Scene();

    scene.add(buildGroundGeometry());

    var buildingMaterials = buildMaterials();
    var buildingGeometries = buildEmptyGeometriesForBuildings();

    // Loop through the lower left corner of each block
    var x, z;
    for (x = -(city.HALF_SCENE_WIDTH); x < city.HALF_SCENE_WIDTH; x += city.BLOCK_WIDTH + city.STREET_WIDTH) {
      for (z = -(city.HALF_SCENE_DEPTH); z < city.HALF_SCENE_DEPTH; z += city.BLOCK_DEPTH + city.STREET_DEPTH) {
        generateBlock(x, z, buildingGeometries);
      }
    }

    for (var i = 0; i < city.MAX_BUILDING_MATERIALS; i++) {
      scene.add(new THREE.Mesh(buildingGeometries[i], buildingMaterials[i]));
    }

    return scene;
  };

  var buildGroundGeometry = function() {
    var groundMaterial = new THREE.MeshBasicMaterial({ color: 0xaaaaaa });
    var groundGeometry = new THREE.Mesh(new THREE.PlaneGeometry(city.TOTAL_SCENE_WIDTH * 25, city.TOTAL_SCENE_DEPTH * 25), groundMaterial);
    groundGeometry.rotation.x = -(Math.PI / 2);

    return groundGeometry;
  };

  var buildMaterials = function() {
    var buildingMaterials = [];

    for (var i = 0; i < city.MAX_BUILDING_MATERIALS; i++) {
      var r = Math.random();
      var g = r;
      var b = r;
      var buildingColor = new THREE.Color(0xffffff).setRGB(r, g, b);

      buildingMaterials.push(new THREE.MeshLambertMaterial({ color: buildingColor.getHex() }));
    }

    return buildingMaterials;
  };

  var buildEmptyGeometriesForBuildings = function() {
    var buildingGeometries = [];

    for (var i = 0; i < city.MAX_BUILDING_MATERIALS; i++) {
      buildingGeometries.push(new THREE.Geometry());
    }

    return buildingGeometries;
  };

  var generateBlock = function(x, z, buildingGeometries) {
    var i, lotLayout, buildingHeight, building;
    var blockLayout = city.BLOCK_LAYOUTS[Math.floor(Math.random() * city.BLOCK_LAYOUTS.length)];

    for (i = 0; i < blockLayout.length; i++) {
      lotLayout = blockLayout[i];
      buildingHeight = calculateBuildingHeight(x, z);
      building = generateBuilding(x, buildingHeight, z, lotLayout);

      var materialIndex = Math.floor(Math.random() * city.MAX_BUILDING_MATERIALS);
      THREE.GeometryUtils.merge(buildingGeometries[materialIndex], building);
    }
  };

  var calculateBuildingHeight = function(x, z) {
    var maxHeightX = city.MAX_BUILDING_HEIGHT * ((city.HALF_SCENE_WIDTH - Math.abs(x)) / city.HALF_SCENE_WIDTH);
    var maxHeightZ = city.MAX_BUILDING_HEIGHT * ((city.HALF_SCENE_DEPTH - Math.abs(z)) / city.HALF_SCENE_DEPTH);
    var maxHeight = Math.min(maxHeightX, maxHeightZ);
    //var buildingHeight = Math.floor((Math.random() * maxHeight - city.MIN_BUILDING_HEIGHT)) + city.MIN_BUILDING_HEIGHT;

    return maxHeight;
  };

  var generateBuilding = function(x, maxY, z, lotLayout) {
    var building = new THREE.Mesh(new THREE.BoxGeometry(lotLayout.width * city.BLOCK_WIDTH, 1, lotLayout.depth * city.BLOCK_WIDTH));

    building.position.x = x + city.BLOCK_WIDTH / 2 + ((city.BLOCK_WIDTH / 2) * lotLayout.offsetFromBlockCenterX);
    building.scale.y =  (Math.random() * maxY) + city.MIN_BUILDING_HEIGHT;
    building.position.y = building.scale.y / 2;
    building.position.z = z + city.BLOCK_DEPTH / 2 + ((city.BLOCK_DEPTH / 2) * lotLayout.offsetFromBlockCenterZ);

    return building;
  };

  return city;
};
<|endoftext|>


<commit_before>'use strict';
var util = require('util'),
path = require('path'),
yeoman = require('yeoman-generator'),
childProcess = require('child_process'),
chalk = require('chalk'),
_s = require('underscore.string'),
scriptBase = require('../script-base');

var exec = childProcess.exec;
var spawn = childProcess.spawn;

var OpenshiftGenerator = module.exports = function OpenshiftGenerator() {
    yeoman.generators.Base.apply(this, arguments);
    console.log(chalk.bold('Openshift configuration is starting'));
    this.env.options.appPath = this.config.get('appPath') || 'src/main/webapp';
    this.baseName = this.config.get('baseName');
    this.packageName = this.config.get('packageName');
    this.packageFolder = this.config.get('packageFolder');
    this.javaVersion = this.config.get('javaVersion');
    this.hibernateCache = this.config.get('hibernateCache');
    this.databaseType = this.config.get('databaseType');
    this.angularAppName = _s.camelize(_s.slugify(this.baseName)) + 'App';
};

util.inherits(OpenshiftGenerator, yeoman.generators.Base);
util.inherits(OpenshiftGenerator, scriptBase);

OpenshiftGenerator.prototype.askForName = function askForName() {
    var done = this.async();

    var prompts = [{
        name: 'openShiftDeployedName',
        message: 'Name to deploy as:',
        default: this.baseName
    }];

    this.prompt(prompts, function (props) {
        this.openShiftDeployedName = this._.slugify(props.openShiftDeployedName).split('-').join('');
        done();
    }.bind(this));
};

OpenshiftGenerator.prototype.checkInstallation = function checkInstallation() {
    if(this.abort) return;
    var done = this.async();

    exec('rhc --version', function (err) {
        if (err) {
            this.log.error('Openshift\'s rhc command line interface is not available. ' +
            'You can install it via RubyGems with: gem install rhc');
            this.abort = true;
        }
        done();
    }.bind(this));
};

OpenshiftGenerator.prototype.dirInit = function dirInit() {
    if(this.abort) return;
    var done = this.async();

    this.log(chalk.bold('Initializing deployment repo'));
    this.mkdir('deploy/openshift');
    done();
};

OpenshiftGenerator.prototype.gitRemoteCheck = function gitRemoteCheck() {
    this.openshift_remote_exists = false;
    if(this.abort || typeof this.dist_repo_url !== 'undefined') return;
    var done = this.async();

    this.log(chalk.bold("\nChecking for an existing git remote named '"+'openshift'+"'..."));
    exec('git remote -v', { cwd: 'deploy/openshift' }, function (err, stdout, stderr) {
        var lines = stdout.split('\n');
        var dist_repo = '';
        if (err && stderr.search('DL is deprecated') === -1) {
            this.log.error(err);
        } else {
            var repo_url_finder = new RegExp('openshift'+"[  ]*");
            lines.forEach(function(line) {
                if(line.search(repo_url_finder) === 0 && dist_repo === '') {
                    var dist_repo_detailed = line.slice(line.match(repo_url_finder)[0].length);
                    dist_repo = dist_repo_detailed.slice(0, dist_repo_detailed.length - 7);
                }
            });
            if (dist_repo !== ''){
                console.log("Found an existing git remote for this app: "+dist_repo);
                this.dist_repo_url = dist_repo;
                this.openshift_remote_exists = true;
            } else {
                console.log('No existing remote found.');
            }
        }
        done();
    }.bind(this));
};

OpenshiftGenerator.prototype.rhcAppShow = function rhcAppShow() {
    if(this.abort || typeof this.dist_repo_url !== 'undefined') return;
    var done = this.async();

    this.log(chalk.bold("\nChecking for an existing Openshift hosting environment..."));
    var child = exec('rhc app show '+this.openShiftDeployedName+' --noprompt', { cwd: 'deploy/openshift' }, function (err, stdout, stderr) {
        var lines = stdout.split('\n');
        var dist_repo = '';
        // Unauthenticated
        if (stdout.search('Not authenticated') >= 0 || stdout.search('Invalid characters found in login') >= 0) {
            this.log.error('Error: Not authenticated. Run "rhc setup" to login to your Openshift account and try again.');
            this.abort = true;
        }
        // No remote found
        else if (stderr.search('not found.') < 0) {
            console.log('No existing app found.');
        }
        // Error
        else if (err && stderr.search('DL is deprecated') === -1) {
            this.log.error(err);
        } else {   // Remote found
            this.log(stdout);
            var repo_url_finder = / *Git URL: */;
            lines.forEach(function(line) {
                if(line.search(repo_url_finder) === 0) {
                    dist_repo = line.slice(line.match(repo_url_finder)[0].length);
                    console.log("Found an existing git remote for this app: "+dist_repo);
                }
            });
            if (dist_repo !== '') this.dist_repo_url = dist_repo;
        }
        done();
    }.bind(this));
};

OpenshiftGenerator.prototype.rhcAppCreate = function rhcAppCreate() {
    if(this.abort || typeof this.dist_repo_url !== 'undefined') return;
    var done = this.async();

    this.log(chalk.bold("\nCreating your Openshift hosting environment, this may take a couple minutes..."));
    var child = exec('rhc app create ' + this.openShiftDeployedName + ' diy-0.1 mysql-5.5 -r ./', { cwd: 'deploy/openshift' }, function (err, stdout, stderr) {
        var lines = stdout.split('\n');
        this.log(stdout);
        if (stdout.search('Not authenticated') >= 0 || stdout.search('Invalid characters found in login') >= 0) {
            this.log.error('Error: Not authenticated. Run "rhc setup" to login to your Openshift account and try again.');
            this.abort = true;
        } else if (err && stderr.search('DL is deprecated') === -1) {
            this.log.error(err);
        } else {
            var dist_repo = '';
            var repo_url_finder = / *Git remote: */;
            lines.forEach(function(line) {
                if(line.search(repo_url_finder) === 0) {
                    dist_repo = line.slice(line.match(repo_url_finder)[0].length);
                }
            });

            if (dist_repo !== '') this.dist_repo_url = dist_repo;
            if(this.dist_repo_url !== undefined) {
                this.log("New remote git repo at: "+this.dist_repo_url);
            }
        }
        done();
    }.bind(this));

    child.stdout.on('data', function(data) {
        this.log(data.toString());
    }.bind(this));
};

OpenshiftGenerator.prototype.gitRemoteAdd = function gitRemoteAdd() {
    if(this.abort || typeof this.dist_repo_url === 'undefined' || this.openshift_remote_exists) return;
    var done = this.async();
    this.log(chalk.bold("\nAdding remote repo url: "+this.dist_repo_url));

    var child = exec('git remote add '+'openshift'+' '+this.dist_repo_url, { cwd: 'deploy/openshift' }, function (err, stdout, stderr) {
        if (err) {
            this.log.error(err);
        } else {
            this.openshift_remote_exists = true;
        }
        done();
    }.bind(this));

    child.stdout.on('data', function(data) {
        this.log(data.toString());
    }.bind(this));
};

OpenshiftGenerator.prototype.copyOpenshiftFiles = function copyOpenshiftFiles() {
    if(this.abort || !this.openshift_remote_exists ) return;
    var done = this.async();
    this.log(chalk.bold('\nCreating Openshift deployment files'));

    this.copy('openshift/action_hooks/build', 'deploy/openshift/.openshift/action_hooks/build');
    this.copy('openshift/action_hooks/start', 'deploy/openshift/.openshift/action_hooks/start');
    this.copy('openshift/action_hooks/stop', 'deploy/openshift/.openshift/action_hooks/stop');
    this.conflicter.resolve(function (err) {
        done();
    });
};

OpenshiftGenerator.prototype.productionBuild = function productionBuild() {
    if(this.abort || !this.openshift_remote_exists ) return;
    var done = this.async();

    this.log(chalk.bold('\nBuilding deploy/openshift folder, please wait...'));
    var child = exec('grunt buildOpenshift', function (err, stdout) {
        if (err) {
            this.log.error(err);
        }
        done();
    }.bind(this));

    child.stdout.on('data', function(data) {
        this.log(data.toString());
    }.bind(this));
};

OpenshiftGenerator.prototype.gitCommit = function gitCommit() {
    if(this.abort || !this.openshift_remote_exists ) return;
    var done = this.async();

    this.log(chalk.bold('\nAdding files for initial commit'));
    var child = exec('git add -A && git commit -m "Initial commit"', { cwd: 'deploy/openshift', maxBuffer: 1000*1024 }, function (err, stdout, stderr) {
        if (stdout.search('nothing to commit') >= 0) {
            this.log('Re-pushing the existing "deploy/openshift" build...');
        } else if (err) {
            this.log.error(err);
        } else {
            this.log(chalk.green('Done, without errors.'));
        }
        done();
    }.bind(this));

    child.stdout.on('data', function(data) {
        this.log(data.toString());
    }.bind(this));
};

OpenshiftGenerator.prototype.gitForcePush = function gitForcePush() {
    if (this.abort || !this.openshift_remote_exists) return;
    var done = this.async();
    this.log(chalk.bold("\nUploading your initial application code.\n This may take " + chalk.cyan('several minutes') + " depending on your connection speed..."));

    var push = spawn('git', ['push', '-f', 'openshift', 'master'], {cwd: 'deploy/openshift'});
    var error = null;

    push.stderr.on('data', function (data) {
        var output = data.toString();
        this.log.error(output);
    }.bind(this));

    push.stdout.on('data', function (data) {
        var output = data.toString();
        this.log.stdin(output);
    }.bind(this));

    push.on('exit', function (code) {
        if (code !== 0) {
            this.abort = true;
            return done();
        }
        done();
    }.bind(this));
};

OpenshiftGenerator.prototype.restartApp = function restartApp() {
    if(this.abort || !this.openshift_remote_exists ) return;
    this.log(chalk.bold("\nRestarting your Openshift app.\n"));

    var child = exec('rhc app restart -a ' + this.openShiftDeployedName, function(err, stdout, stderr) {

        var host_url = '';
        var hasWarning = false;
        var before_hostname = this.dist_repo_url.indexOf('@') + 1;
        var after_hostname = this.dist_repo_url.length - ( 'openshift'.length + 12 );
        host_url = 'http://' + this.dist_repo_url.slice(before_hostname, after_hostname) + 'com';

        this.log(chalk.green('\nYour app should now be live at \n\t' + chalk.bold(host_url)));
        if(hasWarning) {
            this.log(chalk.green('\nYou may need to address the issues mentioned above and restart the server for the app to work correctly \n\t' +
            'rhc app-restart -a ' + this.openShiftDeployedName));
        }
        this.log(chalk.yellow('After application modification, re-deploy it with\n\t' + chalk.bold('grunt deployOpenshift') +
        ' and then do a \n\t' + chalk.bold('git push') + ' on your Openshift repository.'));
    }.bind(this));
};
<commit_msg>chmod +x action_hooks (necessary for windows) See https://openshift.github.io/documentation/oo_user_guide.html#the-openshift-directory<commit_after>'use strict';
var util = require('util'),
path = require('path'),
yeoman = require('yeoman-generator'),
childProcess = require('child_process'),
chalk = require('chalk'),
_s = require('underscore.string'),
scriptBase = require('../script-base');

var exec = childProcess.exec;
var spawn = childProcess.spawn;

var OpenshiftGenerator = module.exports = function OpenshiftGenerator() {
    yeoman.generators.Base.apply(this, arguments);
    console.log(chalk.bold('Openshift configuration is starting'));
    this.env.options.appPath = this.config.get('appPath') || 'src/main/webapp';
    this.baseName = this.config.get('baseName');
    this.packageName = this.config.get('packageName');
    this.packageFolder = this.config.get('packageFolder');
    this.javaVersion = this.config.get('javaVersion');
    this.hibernateCache = this.config.get('hibernateCache');
    this.databaseType = this.config.get('databaseType');
    this.angularAppName = _s.camelize(_s.slugify(this.baseName)) + 'App';
};

util.inherits(OpenshiftGenerator, yeoman.generators.Base);
util.inherits(OpenshiftGenerator, scriptBase);

OpenshiftGenerator.prototype.askForName = function askForName() {
    var done = this.async();

    var prompts = [{
        name: 'openShiftDeployedName',
        message: 'Name to deploy as:',
        default: this.baseName
    }];

    this.prompt(prompts, function (props) {
        this.openShiftDeployedName = this._.slugify(props.openShiftDeployedName).split('-').join('');
        done();
    }.bind(this));
};

OpenshiftGenerator.prototype.checkInstallation = function checkInstallation() {
    if(this.abort) return;
    var done = this.async();

    exec('rhc --version', function (err) {
        if (err) {
            this.log.error('Openshift\'s rhc command line interface is not available. ' +
            'You can install it via RubyGems with: gem install rhc');
            this.abort = true;
        }
        done();
    }.bind(this));
};

OpenshiftGenerator.prototype.dirInit = function dirInit() {
    if(this.abort) return;
    var done = this.async();

    this.log(chalk.bold('Initializing deployment repo'));
    this.mkdir('deploy/openshift');
    done();
};

OpenshiftGenerator.prototype.gitRemoteCheck = function gitRemoteCheck() {
    this.openshift_remote_exists = false;
    if(this.abort || typeof this.dist_repo_url !== 'undefined') return;
    var done = this.async();

    this.log(chalk.bold("\nChecking for an existing git remote named '"+'openshift'+"'..."));
    exec('git remote -v', { cwd: 'deploy/openshift' }, function (err, stdout, stderr) {
        var lines = stdout.split('\n');
        var dist_repo = '';
        if (err && stderr.search('DL is deprecated') === -1) {
            this.log.error(err);
        } else {
            var repo_url_finder = new RegExp('openshift'+"[  ]*");
            lines.forEach(function(line) {
                if(line.search(repo_url_finder) === 0 && dist_repo === '') {
                    var dist_repo_detailed = line.slice(line.match(repo_url_finder)[0].length);
                    dist_repo = dist_repo_detailed.slice(0, dist_repo_detailed.length - 7);
                }
            });
            if (dist_repo !== ''){
                console.log("Found an existing git remote for this app: "+dist_repo);
                this.dist_repo_url = dist_repo;
                this.openshift_remote_exists = true;
            } else {
                console.log('No existing remote found.');
            }
        }
        done();
    }.bind(this));
};

OpenshiftGenerator.prototype.rhcAppShow = function rhcAppShow() {
    if(this.abort || typeof this.dist_repo_url !== 'undefined') return;
    var done = this.async();

    this.log(chalk.bold("\nChecking for an existing Openshift hosting environment..."));
    var child = exec('rhc app show '+this.openShiftDeployedName+' --noprompt', { cwd: 'deploy/openshift' }, function (err, stdout, stderr) {
        var lines = stdout.split('\n');
        var dist_repo = '';
        // Unauthenticated
        if (stdout.search('Not authenticated') >= 0 || stdout.search('Invalid characters found in login') >= 0) {
            this.log.error('Error: Not authenticated. Run "rhc setup" to login to your Openshift account and try again.');
            this.abort = true;
        }
        // No remote found
        else if (stderr.search('not found.') < 0) {
            console.log('No existing app found.');
        }
        // Error
        else if (err && stderr.search('DL is deprecated') === -1) {
            this.log.error(err);
        } else {   // Remote found
            this.log(stdout);
            var repo_url_finder = / *Git URL: */;
            lines.forEach(function(line) {
                if(line.search(repo_url_finder) === 0) {
                    dist_repo = line.slice(line.match(repo_url_finder)[0].length);
                    console.log("Found an existing git remote for this app: "+dist_repo);
                }
            });
            if (dist_repo !== '') this.dist_repo_url = dist_repo;
        }
        done();
    }.bind(this));
};

OpenshiftGenerator.prototype.rhcAppCreate = function rhcAppCreate() {
    if(this.abort || typeof this.dist_repo_url !== 'undefined') return;
    var done = this.async();

    this.log(chalk.bold("\nCreating your Openshift hosting environment, this may take a couple minutes..."));
    var child = exec('rhc app create ' + this.openShiftDeployedName + ' diy-0.1 mysql-5.5 -r ./', { cwd: 'deploy/openshift' }, function (err, stdout, stderr) {
        var lines = stdout.split('\n');
        this.log(stdout);
        if (stdout.search('Not authenticated') >= 0 || stdout.search('Invalid characters found in login') >= 0) {
            this.log.error('Error: Not authenticated. Run "rhc setup" to login to your Openshift account and try again.');
            this.abort = true;
        } else if (err && stderr.search('DL is deprecated') === -1) {
            this.log.error(err);
        } else {
            var dist_repo = '';
            var repo_url_finder = / *Git remote: */;
            lines.forEach(function(line) {
                if(line.search(repo_url_finder) === 0) {
                    dist_repo = line.slice(line.match(repo_url_finder)[0].length);
                }
            });

            if (dist_repo !== '') this.dist_repo_url = dist_repo;
            if(this.dist_repo_url !== undefined) {
                this.log("New remote git repo at: "+this.dist_repo_url);
            }
        }
        done();
    }.bind(this));

    child.stdout.on('data', function(data) {
        this.log(data.toString());
    }.bind(this));
};

OpenshiftGenerator.prototype.gitRemoteAdd = function gitRemoteAdd() {
    if(this.abort || typeof this.dist_repo_url === 'undefined' || this.openshift_remote_exists) return;
    var done = this.async();
    this.log(chalk.bold("\nAdding remote repo url: "+this.dist_repo_url));

    var child = exec('git remote add '+'openshift'+' '+this.dist_repo_url, { cwd: 'deploy/openshift' }, function (err, stdout, stderr) {
        if (err) {
            this.log.error(err);
        } else {
            this.openshift_remote_exists = true;
        }
        done();
    }.bind(this));

    child.stdout.on('data', function(data) {
        this.log(data.toString());
    }.bind(this));
};

OpenshiftGenerator.prototype.copyOpenshiftFiles = function copyOpenshiftFiles() {
    if(this.abort || !this.openshift_remote_exists ) return;
    var done = this.async();
    this.log(chalk.bold('\nCreating Openshift deployment files'));

    this.copy('openshift/action_hooks/build', 'deploy/openshift/.openshift/action_hooks/build');
    this.copy('openshift/action_hooks/start', 'deploy/openshift/.openshift/action_hooks/start');
    this.copy('openshift/action_hooks/stop', 'deploy/openshift/.openshift/action_hooks/stop');
    this.conflicter.resolve(function (err) {
        done();
    });
};

OpenshiftGenerator.prototype.productionBuild = function productionBuild() {
    if(this.abort || !this.openshift_remote_exists ) return;
    var done = this.async();

    this.log(chalk.bold('\nBuilding deploy/openshift folder, please wait...'));
    var child = exec('grunt buildOpenshift', function (err, stdout) {
        if (err) {
            this.log.error(err);
        }
        done();
    }.bind(this));

    child.stdout.on('data', function(data) {
        this.log(data.toString());
    }.bind(this));
};

OpenshiftGenerator.prototype.gitCommit = function gitCommit() {
    if(this.abort || !this.openshift_remote_exists ) return;
    var done = this.async();

    this.log(chalk.bold('\nAdding files for initial commit'));
    var child = exec('git add -A && git commit -m "Initial commit"', { cwd: 'deploy/openshift', maxBuffer: 1000*1024 }, function (err, stdout, stderr) {
        if (stdout.search('nothing to commit') >= 0) {
            this.log('Re-pushing the existing "deploy/openshift" build...');
        } else if (err) {
            this.log.error(err);
        } else {
            this.log(chalk.green('Done, without errors.'));
        }
        done();
    }.bind(this));

    child.stdout.on('data', function(data) {
        this.log(data.toString());
    }.bind(this));
};

OpenshiftGenerator.prototype.gitChmod = function gitChmod() {
    if(this.abort || !this.openshift_remote_exists ) return;
    var done = this.async();

    this.log(chalk.bold('\nChmod action hooks'));
    var child = exec('git update-index --chmod=+x .openshift/action_hooks/build && '+
        'git update-index --chmod=+x .openshift/action_hooks/start && '+
        'git update-index --chmod=+x .openshift/action_hooks/stop && ' +
        'git commit -m "Chmod"', { cwd: 'deploy/openshift' }, function (err, stdout, stderr) {
        if (stdout.search('nothing to commit') >= 0) {
            this.log('+x already set');
        } else if (err) {
            this.log.error(err);
        } else {
            this.log(chalk.green('Done, without errors.'));
        }
        done();
    }.bind(this));

    child.stdout.on('data', function(data) {
        this.log(data.toString());
    }.bind(this));
};

OpenshiftGenerator.prototype.gitForcePush = function gitForcePush() {
    if (this.abort || !this.openshift_remote_exists) return;
    var done = this.async();
    this.log(chalk.bold("\nUploading your initial application code.\n This may take " + chalk.cyan('several minutes') + " depending on your connection speed..."));

    var push = spawn('git', ['push', '-f', 'openshift', 'master'], {cwd: 'deploy/openshift'});
    var error = null;

    push.stderr.on('data', function (data) {
        var output = data.toString();
        this.log.error(output);
    }.bind(this));

    push.stdout.on('data', function (data) {
        var output = data.toString();
        this.log.stdin(output);
    }.bind(this));

    push.on('exit', function (code) {
        if (code !== 0) {
            this.abort = true;
            return done();
        }
        done();
    }.bind(this));
};

OpenshiftGenerator.prototype.restartApp = function restartApp() {
    if(this.abort || !this.openshift_remote_exists ) return;
    this.log(chalk.bold("\nRestarting your Openshift app.\n"));

    var child = exec('rhc app restart -a ' + this.openShiftDeployedName, function(err, stdout, stderr) {

        var host_url = '';
        var hasWarning = false;
        var before_hostname = this.dist_repo_url.indexOf('@') + 1;
        var after_hostname = this.dist_repo_url.length - ( 'openshift'.length + 12 );
        host_url = 'http://' + this.dist_repo_url.slice(before_hostname, after_hostname) + 'com';

        this.log(chalk.green('\nYour app should now be live at \n\t' + chalk.bold(host_url)));
        if(hasWarning) {
            this.log(chalk.green('\nYou may need to address the issues mentioned above and restart the server for the app to work correctly \n\t' +
            'rhc app-restart -a ' + this.openShiftDeployedName));
        }
        this.log(chalk.yellow('After application modification, re-deploy it with\n\t' + chalk.bold('grunt deployOpenshift') +
        ' and then do a \n\t' + chalk.bold('git push') + ' on your Openshift repository.'));
    }.bind(this));
};
<|endoftext|>


<commit_before>/**
 * A FreeDOM interface to WebRTC Peer Connections
 * @param Channel channel a channel for emitting events.
 * @constructor
 * @private
 */
var PeerConnection_unprivileged = function(channel) {
  this.appChannel = channel;
  this.dataChannel = null;
  this.identity = null;
  this.connection = null;
  this.myPid = Math.random();
  this.remotePid = 1;
  handleEvents(this);
};

PeerConnection_unprivileged.prototype.open = function(proxy, continuation) {
  if (this.connection) {
    continuation(false);
  }

  // Listen for messages to/from the provided message channel.
  this.appChannel = Core_unprivileged.bindChannel(this.appChannel.app, proxy);
  this.appChannel['on']('message', this.onIdentity.bind(this));
  this.appChannel.postMessage({
    'type': 'ready',
    'action': 'event'
  });

  this.setup(true);
  continuation();
};

PeerConnection_unprivileged.prototype.setup = function(initiate) {
  var RTCPeerConnection = RTCPeerConnection || webkitRTCPeerConnection || mozRTCPeerConnection;
  this.connection = new RTCPeerConnection(null, {'optional': [{'RtpDataChannels': true}]});

  var dcSetup = function() {
    this.dataChannel.addEventListener('open', function() {
      console.log("Data channel opened.");
      this.emit('open');
    }.bind(this), true);
    this.dataChannel.addEventListener('message', function(m) {
      // TODO(willscott): Support native binary transport, rather than this mess
      if (this.parts > 0) {
        this.buf += m.data;
        this.parts--;
        console.log('waiting for ' + this.parts + ' more parts.');
        if (this.parts === 0) {
          console.log("binary data recieved (" + this.buf.length + " bytes)");
          var databuf = JSON.parse(this.buf);
          console.log(databuf);
          var arr = new Uint8Array(databuf['binary']);
          var blob = new Blob([arr.buffer], {"type": databuf['mime']});
          this['dispatchEvent']('message', {"binary": blob, "buffer" : arr.buffer});
          this.buf = "";
        }
        return;
      }
      var data = JSON.parse(m.data);
      if (data['text']) {
        this['dispatchEvent']('message', {"text": data['text']});
      } else {
        this.parts = data['binary'];
        console.log("Beginning receipt of binary data (" + this.parts + " parts)");
        this.buf = "";
      }
    }.bind(this), true);
    this.dataChannel.addEventListener('close', function(conn) {
      if (this.connection == conn) {
        this['dispatchEvent']('onClose');
        this.close(function() {});
      }
    }.bind(this, this.connection), true);
  }.bind(this);

  if (initiate) {
    this.dataChannel = this.connection.createDataChannel("sendChannel", {'reliable': false});
    dcSetup();
  } else {
    this.connection.addEventListener('datachannel', function(evt) {
      this.dataChannel = evt['channel'];
      dcSetup();
    }.bind(this));
  }

  this.connection.addEventListener('icecandidate', function(evt) {
    if(evt && evt['candidate']) {
      this.appChannel.postMessage({
        'type': 'message',
        'action': 'event',
        'data': JSON.stringify(evt['candidate'])
      });
    }
  }.bind(this), true);

  this.makeOffer();
};

PeerConnection_unprivileged.prototype.makeOffer = function() {
  if (this.remotePid < this.myPid) {
    return;
  }
  this.connection.createOffer(function(desc) {
    this.connection.setLocalDescription(desc);
    desc['pid'] = this.myPid;
    this.appChannel.postMessage({
      'type': 'message',
      'action': 'event',
      'data': JSON.stringify(desc)
    });
  }.bind(this));
};

PeerConnection_unprivileged.prototype.makeAnswer = function() {
  this.connection.createAnswer(function(desc) {
    this.connection.setLocalDescription(desc);
    desc['pid'] = this.myPid;
    this.appChannel.postMessage({
      'type': 'message',
      'action': 'event',
      'data': JSON.stringify(desc)
    });
  }.bind(this));
};

PeerConnection_unprivileged.prototype.onIdentity = function(msg) {
  try {
    var m = msg.data;
    if (typeof msg.data === "string") {
      m = JSON.parse(msg.data);
    }
    if (m['candidate']) {
      var candidate = new RTCIceCandidate(m);
      this.connection.addIceCandidate(candidate);
    } else if (m['type'] == 'offer' && m['pid'] != this.myId) {
      this.remotePid = m['pid'];
      if (this.remotePid < this.myPid) {
        this.close(function() {
          this.setup(false);
          this.connection.setRemoteDescription(new RTCSessionDescription(m), function() {}, function() {
            console.log("Failed to set remote description");
          });
          this.makeAnswer();
        }.bind(this));
      } else {
        // They'll get my offer and send an answer.
      }
    } else if (m['type'] == 'answer' && m['pid'] != this.myId) {
      this.remotePid = m['pid'];
      this.connection.setRemoteDescription(new RTCSessionDescription(m));
    }
  } catch(e) {
    console.log("Couldn't understand identity message: " + JSON.stringify(msg) + ": -> " + e.message);
  }
};

PeerConnection_unprivileged.prototype.postMessage = function(ref, continuation) {
  if (!this.connection) {
    return continuation(false);
  }
  // Queue until open.
  if (!this.dataChannel || this.dataChannel.readyState != "open") {
    return this.once('open', this.postMessage.bind(this, ref, continuation));
  }
  window.dc = this.dataChannel;

  if(ref['text']) {
    console.log("Sending text: " + ref['text']);
    this.dataChannel.send(JSON.stringify({"text":ref['text']}));
  } else if(ref['binary']) {
    // TODO(willscott): implement direct blob support when available.
    console.log("Transmitting " + ref['binary'].size + " binary bytes");
    var reader = new FileReader();
    reader.addEventListener('load', function(type, ev) {
      var arr = [];
      arr.push.apply(arr, new Uint8Array(ev.target.result));
      // Chunk messages so that packets are below MTU.
      var MAX_LEN = 512;
      var STEP = 300;
      var str = JSON.stringify({"mime": type, "binary": arr});
      var parts = Math.ceil(str.length / MAX_LEN);
      console.log("Sending chunked " + type + " ("+ str.length + " bytes)");
      this.dataChannel.send(JSON.stringify({"binary": parts}));

      var delay = 0;
      var sendPart = function(x) {
        this.dataChannel.send(x);
      };

      while (str.length > 0) {
        setTimeout(sendPart.bind(this, str.substr(0, MAX_LEN)), delay);
        delay += STEP;
        str = str.substr(MAX_LEN);
      }
    }.bind(this, ref['binary'].type), true);

    reader.readAsArrayBuffer(ref['binary']);
  }
  continuation();
};

PeerConnection_unprivileged.prototype.close = function(continuation) {
  delete this.dataChannel;

  if (this.connection) {
    try {
      this.connection.close();
    } catch(e) {
      // Ignore already-closed errors.
    }
    delete this.connection;
  }
  continuation();
};

fdom.apis.register("core.peerconnection", PeerConnection_unprivileged);
<commit_msg>properly order messages<commit_after>/**
 * A FreeDOM interface to WebRTC Peer Connections
 * @param Channel channel a channel for emitting events.
 * @constructor
 * @private
 */
var PeerConnection_unprivileged = function(channel) {
  this.appChannel = channel;
  this.dataChannel = null;
  this.identity = null;
  this.connection = null;
  this.myPid = Math.random();
  this.remotePid = 1;
  this.sendQueue = [];
  handleEvents(this);
};

PeerConnection_unprivileged.prototype.open = function(proxy, continuation) {
  if (this.connection) {
    continuation(false);
  }

  // Listen for messages to/from the provided message channel.
  this.appChannel = Core_unprivileged.bindChannel(this.appChannel.app, proxy);
  this.appChannel['on']('message', this.onIdentity.bind(this));
  this.appChannel.postMessage({
    'type': 'ready',
    'action': 'event'
  });

  this.setup(true);
  continuation();
};

PeerConnection_unprivileged.prototype.setup = function(initiate) {
  var RTCPeerConnection = RTCPeerConnection || webkitRTCPeerConnection || mozRTCPeerConnection;
  this.connection = new RTCPeerConnection(null, {'optional': [{'RtpDataChannels': true}]});

  var dcSetup = function() {
    this.dataChannel.addEventListener('open', function() {
      console.log("Data channel opened.");
      this.emit('open');
    }.bind(this), true);
    this.dataChannel.addEventListener('message', function(m) {
      // TODO(willscott): Support native binary transport, rather than this mess
      if (this.parts > 0) {
        this.buf += m.data;
        this.parts--;
        console.log('waiting for ' + this.parts + ' more parts.');
        if (this.parts === 0) {
          console.log("binary data recieved (" + this.buf.length + " bytes)");
          var databuf = JSON.parse(this.buf);
          console.log(databuf);
          var arr = new Uint8Array(databuf['binary']);
          var blob = new Blob([arr.buffer], {"type": databuf['mime']});
          this['dispatchEvent']('message', {"binary": blob, "buffer" : arr.buffer});
          this.buf = "";
        }
        return;
      }
      var data = JSON.parse(m.data);
      if (data['text']) {
        this['dispatchEvent']('message', {"text": data['text']});
      } else {
        this.parts = data['binary'];
        console.log("Beginning receipt of binary data (" + this.parts + " parts)");
        this.buf = "";
      }
    }.bind(this), true);
    this.dataChannel.addEventListener('close', function(conn) {
      if (this.connection == conn) {
        this['dispatchEvent']('onClose');
        this.close(function() {});
      }
    }.bind(this, this.connection), true);
  }.bind(this);

  if (initiate) {
    this.dataChannel = this.connection.createDataChannel("sendChannel", {'reliable': false});
    dcSetup();
  } else {
    this.connection.addEventListener('datachannel', function(evt) {
      this.dataChannel = evt['channel'];
      dcSetup();
    }.bind(this));
  }

  this.connection.addEventListener('icecandidate', function(evt) {
    if(evt && evt['candidate']) {
      this.appChannel.postMessage({
        'type': 'message',
        'action': 'event',
        'data': JSON.stringify(evt['candidate'])
      });
    }
  }.bind(this), true);

  this.makeOffer();
};

PeerConnection_unprivileged.prototype.makeOffer = function() {
  if (this.remotePid < this.myPid) {
    return;
  }
  this.connection.createOffer(function(desc) {
    this.connection.setLocalDescription(desc);
    desc['pid'] = this.myPid;
    this.appChannel.postMessage({
      'type': 'message',
      'action': 'event',
      'data': JSON.stringify(desc)
    });
  }.bind(this));
};

PeerConnection_unprivileged.prototype.makeAnswer = function() {
  this.connection.createAnswer(function(desc) {
    this.connection.setLocalDescription(desc);
    desc['pid'] = this.myPid;
    this.appChannel.postMessage({
      'type': 'message',
      'action': 'event',
      'data': JSON.stringify(desc)
    });
  }.bind(this));
};

PeerConnection_unprivileged.prototype.onIdentity = function(msg) {
  try {
    var m = msg.data;
    if (typeof msg.data === "string") {
      m = JSON.parse(msg.data);
    }
    if (m['candidate']) {
      var candidate = new RTCIceCandidate(m);
      this.connection.addIceCandidate(candidate);
    } else if (m['type'] == 'offer' && m['pid'] != this.myId) {
      this.remotePid = m['pid'];
      if (this.remotePid < this.myPid) {
        this.close(function() {
          this.setup(false);
          this.connection.setRemoteDescription(new RTCSessionDescription(m), function() {}, function() {
            console.log("Failed to set remote description");
          });
          this.makeAnswer();
        }.bind(this));
      } else {
        // They'll get my offer and send an answer.
      }
    } else if (m['type'] == 'answer' && m['pid'] != this.myId) {
      this.remotePid = m['pid'];
      this.connection.setRemoteDescription(new RTCSessionDescription(m));
    }
  } catch(e) {
    console.log("Couldn't understand identity message: " + JSON.stringify(msg) + ": -> " + e.message);
  }
};

PeerConnection_unprivileged.prototype.postMessage = function(ref, continuation) {
  if (!this.connection) {
    return continuation(false);
  }
  // Queue until open.
  if (!this.dataChannel || this.dataChannel.readyState != "open") {
    return this.once('open', this.postMessage.bind(this, ref, continuation));
  }
  window.dc = this.dataChannel;

  if(ref['text']) {
    this.sendQueue.push(JSON.stringify({"text":ref['text']}));
    console.log("Sending text: " + ref['text']);
    this._process();
  } else if(ref['binary']) {
    // TODO(willscott): implement direct blob support when available.
    console.log("Transmitting " + ref['binary'].size + " binary bytes");
    var reader = new FileReader();
    reader.addEventListener('load', function(type, ev) {
      var arr = [];
      arr.push.apply(arr, new Uint8Array(ev.target.result));
      // Chunk messages so that packets are below MTU.
      var MAX_LEN = 512;
      var str = JSON.stringify({"mime": type, "binary": arr});
      var parts = Math.ceil(str.length / MAX_LEN);
      console.log("Sending chunked " + type + " ("+ str.length + " bytes)");
      this.sendQueue.push(JSON.stringify({"binary": parts}));

      while (str.length > 0) {
        this.sendQueue.push(str.substr(0, MAX_LEN));
        str = str.substr(MAX_LEN);
      }
      this._process();
    }.bind(this, ref['binary'].type), true);

    reader.readAsArrayBuffer(ref['binary']);
  }
  continuation();
};

PeerConnection_unprivileged.prototype._process = function(scheduled) {
  if (this.scheduled && !scheduled) {
    return;
  }

  var next = this.sendQueue.shift();
  this.dataChannel.send(next);

  if (this.scheduled) {
    clearTimeout(this.scheduled);
    delete this.scheduled;
  }

  if (this.sendQueue.length) {
    var STEP = 300;
    this.scheduled = setTimeout(this._process.bind(this, true), STEP);
  }
};

PeerConnection_unprivileged.prototype.close = function(continuation) {
  delete this.dataChannel;

  if (this.connection) {
    try {
      this.connection.close();
    } catch(e) {
      // Ignore already-closed errors.
    }
    delete this.connection;
  }
  continuation();
};

fdom.apis.register("core.peerconnection", PeerConnection_unprivileged);
<|endoftext|>


<commit_before>/* multi-touch tracker with pointer events support and a hacky HUD */

var canvas,
	c, // c is the canvas' context 2D
	container;

var points = [];

function draw() {
	/* hack to work around lack of orientationchange/resize event */
	if(canvas.height != window.innerHeight) {
		resetCanvas();
	} else {
		c.clearRect(0,0,canvas.width, canvas.height);
	}

	c.strokeStyle = "#eee";
	c.lineWidth = "10";

	for (var i = 0, j = points.length; i<j; i++) {
		/* if pressure property is present and not 0, set radius, otherwise default */
		if (typeof(points[i].pressure) != 'undefined' && points[i].pressure != null) {
			radius = 35 + (points[i].pressure * 25);
		} else {
			radius = 50;
		}

		/* draw all circles */
		c.beginPath();
		c.arc(points[i].clientX, points[i].clientY, radius, 0, Math.PI*2, true);
		c.stroke();

		// for pointer events, add extra circle to denote a primary pointer
		if(points[i].isPrimary) {
			c.beginPath();
			c.arc(points[i].clientX, points[i].clientY, radius + 15, 0, Math.PI*2, true);
			c.stroke();
		}

		// HUD (hacky)
		var hud_props = [];
		switch(points[i].type) {
			case undefined:
				hud_props = ['touch', 'clientX: '+points[i].clientX+' clientY: '+points[i].clientY];
				if (points[i].radiusX && points[i].radiusY) {
					hud_props.push('radiusX: '+points[i].radiusX+' radiusY: '+points[i].radiusY);
				}
				if (points[i].rotationAngle) {
					hud_props.push('rotationAngle: '+points[i].rotationAngle);
				}
				if ((points[i].force !== undefined) || (points[i].webkitForce !== undefined)) {
					hud_props.push('force: '+((points[i].force !== undefined) ? points[i].force : points[i].webkitForce));
				}
				break;
			case 'pointerdown':
			case 'MSPointerDown':
			case 'pointermove':
			case 'MSPointerMove':
				hud_props = ['pointer ('+points[i].pointerType+')'+((points[i].isPrimary === true) ? ' primary' : ''), 'pointerType: '+points[i].pointerType,'isPrimary: '+points[i].isPrimary,'clientX: '+points[i].x+' clientY: '+points[i].y,'tiltX: '+points[i].tiltX+' tiltY: '+points[i].tiltY,'pressure: '+points[i].pressure];
				break;
			case 'mousemove':
				hud_props = ['mouse','clientX: '+points[i].clientX+' clientY: '+points[i].clientY];
				if ((points[i].force !== undefined) || (points[i].webkitForce !== undefined)) {
					hud_props.push('force: '+((points[i].force !== undefined) ? points[i].force : points[i].webkitForce));
				}
				break;
		}
		c.font = "30px Arial";
		c.fillStyle = "#fff";
		c.fillText(hud_props[0], points[i].clientX + 70, points[i].clientY);
		c.fillStyle = "#aaa";
		c.font = "10px Arial";
		for (var h_i = 1, h_j = hud_props.length; h_i<h_j; h_i++) {
			c.fillText(hud_props[h_i], points[i].clientX + 70, points[i].clientY + (h_i + 1) * 12);
		}

	}

}

function positionHandler(e) {
	if (e.type == 'mousemove') {
		points = [e];
	} else if ((e.type == 'touchstart')||(e.type == 'touchmove')||(e.type == 'touchend')) {
		points = e.targetTouches;
		e.preventDefault();
	} else {
		/* fairly ugly, unoptimised approach of manually replicating the targetTouches array */
		switch (e.type) {
			case 'pointerdown':
			case 'MSPointerDown':
			case 'pointermove':
			case 'MSPointerMove':
				for (var i = 0, found = false; i<points.length; i++) {
					if (points[i].pointerId == e.pointerId) {
						points[i] = e;
						found = true;
						break;
					}
				}
				if (!found) {
					points.push(e);
				}
				break;
			case 'pointerup':
			case 'MSPointerUp':
			case 'pointercancel':
			case 'MSPointerCancel':
			case 'pointerout':
			case 'MSPointerOut':
				for (var i = 0; i<points.length; i++) {
					if (points[i].pointerId == e.pointerId) {
						points.splice(i,1);
						break;
					}
				}
				break;
		}
	}
	window.requestAnimationFrame(draw);
}

function init() {
	canvas = document.createElement( 'canvas' );
	c = canvas.getContext( '2d' );
	container = document.createElement( 'div' );
	container.className = "container";
	resetCanvas();
	container.appendChild(canvas);
	document.body.appendChild( container );

	/* feature detect - in this case not dangerous, as pointer is not exclusively touch */
	if ((window.PointerEvent)||(window.navigator.pointerEnabled)||(window.navigator.msPointerEnabled)) {
		canvas.addEventListener('pointerdown',  positionHandler, false );
		canvas.addEventListener('pointermove',  positionHandler, false );
		canvas.addEventListener('pointerup',  positionHandler, false );
		canvas.addEventListener('pointercancel',  positionHandler, false );
		canvas.addEventListener('pointerover',  positionHandler, false );
		canvas.addEventListener('pointerout',  positionHandler, false );
		canvas.addEventListener('MSPointerDown',  positionHandler, false );
		canvas.addEventListener('MSPointerMove',  positionHandler, false );
		canvas.addEventListener('MSPointerUp',  positionHandler, false );
		canvas.addEventListener('MSPointerCancel',  positionHandler, false );
		canvas.addEventListener('MSPointerOver',  positionHandler, false );
		canvas.addEventListener('MSPointerOut',  positionHandler, false );
	} else {
		canvas.addEventListener('mousemove',  positionHandler, false );
		canvas.addEventListener('touchstart', positionHandler, false );
		canvas.addEventListener('touchmove',  positionHandler, false );
		canvas.addEventListener('touchend',  positionHandler, false );
	}

	// suppress context menu
	canvas.addEventListener('contextmenu', function(e) { e.preventDefault(); }, false)

}

function resetCanvas() {
	canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;
    c.strokeStyle = "#eee";
	c.lineWidth = "10";
}

window.addEventListener('load',function() {
	/* hack to prevent firing the init script before the window object's values are populated */
	setTimeout(init,100);
},false);<commit_msg>Make new tracker use modified HiDPI canvas<commit_after>/* multi-touch tracker with pointer events support and a hacky HUD */

var canvas,
	c, // c is the canvas' context 2D
	ratio,
	container;

var points = [];

function draw() {
	/* hack to work around lack of orientationchange/resize event */
	if(canvas.height != window.innerHeight) {
		resetCanvas();
	} else {
		c.clearRect(0,0,canvas.width, canvas.height);
	}

	c.strokeStyle = "#eee";
	c.lineWidth = "10";

	for (var i = 0, j = points.length; i<j; i++) {
		/* if pressure property is present and not 0, set radius, otherwise default */
		if (typeof(points[i].pressure) != 'undefined' && points[i].pressure != null) {
			radius = 35 + (points[i].pressure * 25);
		} else {
			radius = 50;
		}

		/* draw all circles */
		c.beginPath();
		c.arc(points[i].clientX, points[i].clientY, radius, 0, Math.PI*2, true);
		c.stroke();

		// for pointer events, add extra circle to denote a primary pointer
		if(points[i].isPrimary) {
			c.beginPath();
			c.arc(points[i].clientX, points[i].clientY, radius + 15, 0, Math.PI*2, true);
			c.stroke();
		}

		// HUD (hacky)
		var hud_props = [];
		switch(points[i].type) {
			case undefined:
				hud_props = ['touch', 'clientX: '+points[i].clientX+' clientY: '+points[i].clientY];
				if (points[i].radiusX && points[i].radiusY) {
					hud_props.push('radiusX: '+points[i].radiusX+' radiusY: '+points[i].radiusY);
				}
				if (points[i].rotationAngle) {
					hud_props.push('rotationAngle: '+points[i].rotationAngle);
				}
				if ((points[i].force !== undefined) || (points[i].webkitForce !== undefined)) {
					hud_props.push('force: '+((points[i].force !== undefined) ? points[i].force : points[i].webkitForce));
				}
				break;
			case 'pointerdown':
			case 'MSPointerDown':
			case 'pointermove':
			case 'MSPointerMove':
				hud_props = ['pointer ('+points[i].pointerType+')'+((points[i].isPrimary === true) ? ' primary' : ''), 'pointerType: '+points[i].pointerType,'isPrimary: '+points[i].isPrimary,'clientX: '+points[i].x+' clientY: '+points[i].y,'tiltX: '+points[i].tiltX+' tiltY: '+points[i].tiltY,'pressure: '+points[i].pressure];
				break;
			case 'mousemove':
				hud_props = ['mouse','clientX: '+points[i].clientX+' clientY: '+points[i].clientY];
				if ((points[i].force !== undefined) || (points[i].webkitForce !== undefined)) {
					hud_props.push('force: '+((points[i].force !== undefined) ? points[i].force : points[i].webkitForce));
				}
				break;
		}
		c.font = "30px Arial";
		c.fillStyle = "#fff";
		c.fillText(hud_props[0], points[i].clientX + 70, points[i].clientY);
		c.fillStyle = "#aaa";
		c.font = "10px Arial";
		for (var h_i = 1, h_j = hud_props.length; h_i<h_j; h_i++) {
			c.fillText(hud_props[h_i], points[i].clientX + 70, points[i].clientY + (h_i + 1) * 12);
		}

	}

}

function positionHandler(e) {
	if (e.type == 'mousemove') {
		points = [e];
	} else if ((e.type == 'touchstart')||(e.type == 'touchmove')||(e.type == 'touchend')) {
		points = e.targetTouches;
		e.preventDefault();
	} else {
		/* fairly ugly, unoptimised approach of manually replicating the targetTouches array */
		switch (e.type) {
			case 'pointerdown':
			case 'MSPointerDown':
			case 'pointermove':
			case 'MSPointerMove':
				for (var i = 0, found = false; i<points.length; i++) {
					if (points[i].pointerId == e.pointerId) {
						points[i] = e;
						found = true;
						break;
					}
				}
				if (!found) {
					points.push(e);
				}
				break;
			case 'pointerup':
			case 'MSPointerUp':
			case 'pointercancel':
			case 'MSPointerCancel':
			case 'pointerout':
			case 'MSPointerOut':
				for (var i = 0; i<points.length; i++) {
					if (points[i].pointerId == e.pointerId) {
						points.splice(i,1);
						break;
					}
				}
				break;
		}
	}
	window.requestAnimationFrame(draw);
}

function init() {
	canvas = document.createElement( 'canvas' );
	c = canvas.getContext( '2d' );
	container = document.createElement( 'div' );
	container.className = "container";
	resetCanvas();
	container.appendChild(canvas);
	document.body.appendChild( container );

	/* feature detect - in this case not dangerous, as pointer is not exclusively touch */
	if ((window.PointerEvent)||(window.navigator.pointerEnabled)||(window.navigator.msPointerEnabled)) {
		canvas.addEventListener('pointerdown',  positionHandler, false );
		canvas.addEventListener('pointermove',  positionHandler, false );
		canvas.addEventListener('pointerup',  positionHandler, false );
		canvas.addEventListener('pointercancel',  positionHandler, false );
		canvas.addEventListener('pointerover',  positionHandler, false );
		canvas.addEventListener('pointerout',  positionHandler, false );
		canvas.addEventListener('MSPointerDown',  positionHandler, false );
		canvas.addEventListener('MSPointerMove',  positionHandler, false );
		canvas.addEventListener('MSPointerUp',  positionHandler, false );
		canvas.addEventListener('MSPointerCancel',  positionHandler, false );
		canvas.addEventListener('MSPointerOver',  positionHandler, false );
		canvas.addEventListener('MSPointerOut',  positionHandler, false );
	} else {
		canvas.addEventListener('mousemove',  positionHandler, false );
		canvas.addEventListener('touchstart', positionHandler, false );
		canvas.addEventListener('touchmove',  positionHandler, false );
		canvas.addEventListener('touchend',  positionHandler, false );
	}

	// suppress context menu
	canvas.addEventListener('contextmenu', function(e) { e.preventDefault(); }, false)

}

function resetCanvas() {
    // HiDPI canvas http://www.html5rocks.com/en/tutorials/canvas/hidpi/
	devicePixelRatio = window.devicePixelRatio || 1,
	backingStoreRatio = c.webkitBackingStorePixelRatio ||
	                    c.mozBackingStorePixelRatio ||
	                    c.msBackingStorePixelRatio ||
	                    c.oBackingStorePixelRatio ||
	                    c.backingStorePixelRatio || 1,

	ratio = Math.ceil(devicePixelRatio / backingStoreRatio);
	canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;
	// upscale the canvas if the two ratios don't match
    if (devicePixelRatio !== backingStoreRatio) {

        var oldWidth = canvas.width;
        var oldHeight = canvas.height;

        canvas.width = oldWidth * ratio;
        canvas.height = oldHeight * ratio;

        canvas.style.width = oldWidth + 'px';
        canvas.style.height = oldHeight + 'px';

        // now scale the context to counter
        // the fact that we've manually scaled
        // our canvas element
        c.scale(ratio, ratio);
    }
    c.strokeStyle = "#eee";
	c.lineWidth = "10";
}

window.addEventListener('load',function() {
	/* hack to prevent firing the init script before the window object's values are populated */
	setTimeout(init,100);
},false);<|endoftext|>


<commit_before>var router = require('express').Router(),
	Game = require('../../models/game'),
	Release = require('../../models/release'),
	Pagination = require('../../helpers/pagination');
const { renderPage, handleError, defaultCapabilities, validateRequest } = require('./helpers');

router.get('/:order(alphabetical|latest)?/:local(page)?/:number([0-9]+)?', function(req, res)
{
	var order = req.params.order || 'alphabetical';
	if (req.originalUrl.startsWith('/games')){
		Game.getAll().count( function(err, count)
		{
			var nav = new Pagination('/games/'+order, count, req.params.number);
			res.render('games/index',
			{
				pagination: nav.result,
				order: order,
				games: Game.getAll()
					.select('title slug thumbnail releases')
					.sort(order == 'alphabetical' ? 'title' : '-updated')
					.skip(nav.start || 0)
					.limit(nav.itemsPerPage)
			});
		});
	}
	else if (req.originalUrl.startsWith('/archive')){
		Game.getAllArchived().count( function(err, count)
		{
			var nav = new Pagination('/games/'+order, count, req.params.number);
			res.render('games/index',
			{
				pagination: nav.result,
				order: order,
				games: Game.getAllArchived()
					.select('title slug thumbnail releases')
					.sort(order == 'alphabetical' ? 'title' : '-updated')
					.skip(nav.start || 0)
					.limit(nav.itemsPerPage)
			});
		});
	}

});

router.get('/:slug', function(req, res)
{
	renderPage(req, res, 'games/game');
});

router.get('/:slug/privileges', function(req, res)
{
	// have to pass addt'l param to resolve Group objects
	renderPage(req, res, 'games/privileges', ['groups.group']);
});

router.get('/:slug/releases', function(req, res)
{
	// have to pass addt'l param to resolve Release objects
	renderPage(req, res, 'games/releases', ['releases']);
});

router.patch('/:slug/releases/:commit_id', async function(req, res)
{
	// 307 maintains PATCH verb
	res.redirect(307, '/releases/' + req.body.commitId);
});

router.patch('/:slug', function(req, res){
	let errors = validateRequest(req);
	if (errors) {
		return handleError(errors);
	}

	defaultCapabilities(req.body.capabilities);

	req.body.updated = Date.now();

	Game.getBySlug(req.params.slug)
	.then(game => {
		return Game.findByIdAndUpdate(game._id, req.body);
	})
	.then(() =>{
		// have to re-get game b/c archived status may have been changed
		Game.getBySlug(req.params.slug).then(game => {
			if (game.isArchived){
				res.redirect('/archive/' + req.params.slug);
			}
			else {
				res.redirect('/games/' + req.params.slug);
			}
		});
	});
});

router.delete('/:slug', function(req, res){
	Game.getBySlug(req.params.slug)
	.then(game => {
		if (game.isArchived){
			game.remove();
		}
		else {
			game.isArchived = true;
			game.save(function(err) {
				if (err)
				{
					return done(err);
				}
			});
		}
	})
	.then(() => {
		res.redirect('/');
	});

});

module.exports = router;<commit_msg>fix slug bug<commit_after>var router = require('express').Router(),
	Game = require('../../models/game'),
	Release = require('../../models/release'),
	Pagination = require('../../helpers/pagination');
const { renderPage, handleError, defaultCapabilities, validateRequest } = require('./helpers');

router.get('/:order(alphabetical|latest)?/:local(page)?/:number([0-9]+)?', function(req, res)
{
	var order = req.params.order || 'alphabetical';
	if (req.originalUrl.startsWith('/games')){
		Game.getAll().count( function(err, count)
		{
			var nav = new Pagination('/games/'+order, count, req.params.number);
			res.render('games/index',
			{
				pagination: nav.result,
				order: order,
				games: Game.getAll()
					.select('title slug thumbnail releases')
					.sort(order == 'alphabetical' ? 'title' : '-updated')
					.skip(nav.start || 0)
					.limit(nav.itemsPerPage)
			});
		});
	}
	else if (req.originalUrl.startsWith('/archive')){
		Game.getAllArchived().count( function(err, count)
		{
			var nav = new Pagination('/games/'+order, count, req.params.number);
			res.render('games/index',
			{
				pagination: nav.result,
				order: order,
				games: Game.getAllArchived()
					.select('title slug thumbnail releases')
					.sort(order == 'alphabetical' ? 'title' : '-updated')
					.skip(nav.start || 0)
					.limit(nav.itemsPerPage)
			});
		});
	}

});

router.get('/:slug', function(req, res)
{
	renderPage(req, res, 'games/game');
});

router.get('/:slug/privileges', function(req, res)
{
	// have to pass addt'l param to resolve Group objects
	renderPage(req, res, 'games/privileges', ['groups.group']);
});

router.get('/:slug/releases', function(req, res)
{
	// have to pass addt'l param to resolve Release objects
	renderPage(req, res, 'games/releases', ['releases']);
});

router.patch('/:slug/releases/:commit_id', async function(req, res)
{
	// 307 maintains PATCH verb
	res.redirect(307, '/releases/' + req.body.commitId);
});

router.patch('/:slug', function(req, res){
	let errors = validateRequest(req);
	if (errors) {
		return handleError(errors);
	}

	defaultCapabilities(req.body.capabilities);

	req.body.updated = Date.now();

	Game.getBySlug(req.params.slug)
	.then(game => {
		return Game.findByIdAndUpdate(game._id, req.body);
	})
	.then(game => {
		// have to re-get because slug may have changed
		Game.findById(game._id).then(game => {
			if (game.isArchived){
				res.redirect('/archive/' + game.slug);
			}
			else {
				res.redirect('/games/' + game.slug);
			}
		});
	});
});

router.delete('/:slug', function(req, res){
	Game.getBySlug(req.params.slug)
	.then(game => {
		if (game.isArchived){
			game.remove();
		}
		else {
			game.isArchived = true;
			game.save(function(err) {
				if (err)
				{
					return done(err);
				}
			});
		}
	})
	.then(() => {
		res.redirect('/');
	});

});

module.exports = router;<|endoftext|>


<commit_before>/*
 * grunt-email-friendly-templates
 * https://github.com/Aplopio/email-friendly-templates
 *
 * Copyright (c) 2014 Aplopio
 * Licensed under the MIT license.
 */

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

module.exports = function(grunt) {

  // Please see the Grunt documentation for more information regarding task
  // creation: http://gruntjs.com/creating-tasks

  grunt.registerMultiTask('email_friendly_templates', 'Grunt plugin to convert Jade/HTML templates to email friendly templates. Also compiles LESS to CSS if a file is specified.', function() {
    // Merge task-specific and/or target-specific options with these defaults.
    var options = this.options({
        punctuation: '.',
        separator: ', '
      }),
      is_completed = [],
      path = require('path'),
      cwd = process.cwd(),
      done = this.async(),
      script_path = cwd + '/node_modules/grunt-email-friendly-templates/build-template.sh';

    for(var i = 0; i < this.files.length; i++) {
      is_completed.push(false);
    }

    // Iterate over all specified file groups.
    this.files.forEach(function(f, index, array) {
      var options = f.orig,
          input_filepath = path.resolve(cwd, options.src[0]),
          less_filepath = options.less,
          overwrite = !! options.overwrite,
          output_filepath = options.dest,
          script_arguments = ' -f ' + input_filepath;

      if (!grunt.file.exists(input_filepath)) {
        grunt.log.warn('Source file "' + input_filepath + '" not found.');
        return;
      }

      if ( output_filepath ) {
        script_arguments += ' -o ' + path.resolve(cwd, output_filepath);
      }

      if ( less_filepath ) {
        script_arguments += ' --less-file ' + path.resolve(cwd, less_filepath);
      }

      if ( overwrite ) {
        script_arguments += ' --force ';
      }

      exec( 'bash ' + script_path + script_arguments, function(err, stdout, stderr) {
        if ( stdout ) {
          grunt.log.writeln( stdout );
        }

        if ( err || stderr ) {
          grunt.log.warn( ' in ' + input_filepath );
          grunt.log.warn( err || stderr );
        } else {
          grunt.log.writeln('Email friendly templates compilation complete.');
        }
        is_completed[index] = true;
      });
    });
    var intervelId = setInterval(function(){
      var completed = is_completed.reduce(
        function(acc, curr){
          return acc && curr;
        }, true);
      if( completed ) {
        clearInterval(intervelId);
        done();
      } else {
        grunt.log.writeln('Status: ' + is_completed);
      }
    }, 1000);
  });

};
<commit_msg>less verbose status update<commit_after>/*
 * grunt-email-friendly-templates
 * https://github.com/Aplopio/email-friendly-templates
 *
 * Copyright (c) 2014 Aplopio
 * Licensed under the MIT license.
 */

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

module.exports = function(grunt) {

  // Please see the Grunt documentation for more information regarding task
  // creation: http://gruntjs.com/creating-tasks

  grunt.registerMultiTask('email_friendly_templates', 'Grunt plugin to convert Jade/HTML templates to email friendly templates. Also compiles LESS to CSS if a file is specified.', function() {
    // Merge task-specific and/or target-specific options with these defaults.
    var options = this.options({
        punctuation: '.',
        separator: ', '
      }),
      is_completed = [],
      path = require('path'),
      cwd = process.cwd(),
      done = this.async(),
      script_path = cwd + '/node_modules/grunt-email-friendly-templates/build-template.sh';

    for(var i = 0; i < this.files.length; i++) {
      is_completed.push(false);
    }

    // Iterate over all specified file groups.
    this.files.forEach(function(f, index, array) {
      var options = f.orig,
          input_filepath = path.resolve(cwd, options.src[0]),
          less_filepath = options.less,
          overwrite = !! options.overwrite,
          output_filepath = options.dest,
          script_arguments = ' -f ' + input_filepath;

      if (!grunt.file.exists(input_filepath)) {
        grunt.log.warn('Source file "' + input_filepath + '" not found.');
        return;
      }

      if ( output_filepath ) {
        script_arguments += ' -o ' + path.resolve(cwd, output_filepath);
      }

      if ( less_filepath ) {
        script_arguments += ' --less-file ' + path.resolve(cwd, less_filepath);
      }

      if ( overwrite ) {
        script_arguments += ' --force ';
      }

      exec( 'bash ' + script_path + script_arguments, function(err, stdout, stderr) {
        if ( stdout ) {
          grunt.log.writeln( stdout );
        }

        if ( err || stderr ) {
          grunt.log.warn( ' in ' + input_filepath );
          grunt.log.warn( err || stderr );
        } else {
          grunt.log.writeln('Email friendly templates compilation complete.');
        }
        is_completed[index] = true;
      });
    });
    var intervelId = setInterval(function(){
      var completed = is_completed.reduce(
        function(acc, curr){
          return acc && curr;
        }, true);
      if( completed ) {
        clearInterval(intervelId);
        done();
      } else {
        grunt.log.write('.');
      }
    }, 1000);
  });

};
<|endoftext|>


<commit_before>// datatables-tool.js

var escapeSQL = function(column_name) {
	return '"' + column_name.replace(/"/g, '""') + '"'
}

// Function to map JSON data between DataTables format and ScraperWiki's SQL endpoint format.
// It returns a function for the fnServerData parameter
var convertData = function(table_name, column_names) {
	// This is a wrapper round the GET request DataTables makes to get more data
	// sSource - the URL, we don't use it, we hard code it instead
	// aoData - contains the URL parameters, e.g. what page, what to filter, what order and so on
	// fnCallback - where to call with the data you get back
	// oSettings - settings object for the whole DataTables, see http://datatables.net/docs/DataTables/1.9.0/DataTable.models.oSettings.html
	return function ( sSource, aoData, fnCallback, oSettings ) {
		// convert aoData into a normal hash (called ps)
		var params = {}
		for (var i=0;i<aoData.length;i++) {
			params[aoData[i].name] = aoData[i].value
		}
		console.log("DataTables params:", params)

		// construct SQL query needed according to the parameters
		var columns  = _.map(column_names, escapeSQL).join(",")
		var order_by = ""
		if (params.iSortingCols >= 1) {
			var order_parts = []
			for (var i = 0; i < params.iSortingCols; i++) {
				order_part = escapeSQL(column_names[params["iSortCol_" + i]])
				if (params["sSortDir_" + i] == 'desc') {
					order_part += " desc"
				} else if (params["sSortDir_" + i] != 'asc') {
					scraperwiki.alert("Got unknown sSortDir_" + i + " value in table " + table_name)
				}
				order_parts.push(order_part)
			}
			order_by = " order by " + order_parts.join(",")
		}
		var where = ""
		if (params.sSearch) {
			// XXX no idea if this bog standard Javascript escape really does what we want with SQL databases.
			// There's no security risk (as endpoint is sandboxed). There could be user experience pain though.
			var search = "'%" + escape(params.sSearch.toLowerCase()) + "%'"
			where = " where " + _.map(column_names, function(n) { return "lower(" + escapeSQL(n) + ") like " + search }).join(" or ")
		}
		var query = "select " + columns +
			     " from " + escapeSQL(table_name) +
				 where +
				 order_by +
			     " limit " + params.iDisplayLength +
			     " offset " + params.iDisplayStart
		console.log("SQL query:", query)

		// get column counts
		scraperwiki.sql("select (select count(*) from " + escapeSQL(table_name) + ") as total, (select count(*) from " + escapeSQL(table_name) + where + ") as display_total", function (data) {
			var counts = data[0]

			oSettings.jqXHR = $.ajax( {
				"dataType": 'json',
				"type": "GET",
				"url": sqliteEndpoint,
				"data": { q: query },
				"success": function ( response ) {
					// ScraperWiki returns a list of dicts. This converts it to a list of lists.
					var rows = []
					for (var i=0;i<response.length;i++) {
						var row = []
						for (k in response[i]) {
							row.push(response[i][k])
						}
						rows.push(row)
					}
					// Send the data to dataTables
					fnCallback({
						"aaData" : rows,
						"iTotalRecords": data[0].total, // without filtering
						"iTotalDisplayRecords": data[0].display_total // after filtering
					})
				},
				"error": function(jqXHR, textStatus, errorThrown) {
					scraperwiki.alert(errorThrown, jqXHR.responseText, "error")
				}
			} );
		}, function(jqXHR, textStatus, errorThrown) {
			scraperwiki.alert(errorThrown, jqXHR.responseText, "error")
		})
	}
}

// Find the column names
function getTableColumnNames(table_name, callback){
    scraperwiki.sql("select * from " + escapeSQL(table_name) + " limit 1", function(data) {
		callback(_.keys(data[0]))
	}, function(jqXHR, textStatus, errorThrown) {
		scraperwiki.alert(errorThrown, jqXHR.responseText, "error")
	})
}

// Make one of the DataTables (in one tab)
var constructDataTable = function(i, table_name) {
	// Find or make the table
	$(".maintable").hide()
	var id = "table_" + i
	var $outer = $("#" + id)
	if ($outer.length == 0) {
		console.log("making a new table:", table_name)
		$outer = $('

')
		$('body').append($outer)
	} else {
		$outer.show()
		console.log("reusing cached table:", table_name)
		return
	}
	var $t = $outer.find("table")

	// Find out the column names
	getTableColumnNames(table_name, function(column_names) {
		console.log("Columns", column_names)
		if (column_names.length == 0) {
			scraperwiki.alert("No data in the table", jqXHR.responseText)
			return
		}

		// Make the column headings
        var thead = '

'
		_.each(column_names, function(column_name) {
			thead += '' + column_name + '	'
		})
		thead += '

'
		$t.append(thead)

		// Fill in the datatables object
		$t.dataTable( {
			"bProcessing": true,
			"bServerSide": true,
			"bDeferRender": true,
			"bPaginate": true,
			"sPaginationType": "full_numbers",
			"bFilter": true,
			"iDisplayLength": 1000,
            "bScrollCollapse": true,
//            "sDom": '<"H"<"#schema_'+table_name+'">lfr>t<"F"ip>',
            "sDom": '<"H"fip>rt<"F"pi>',
			"fnServerData": convertData(table_name, column_names),
            "fnRowCallback": function( tr, array, iDisplayIndex, iDisplayIndexFull ) {
                $('td', tr).each(function(){
                    $(this).html(
                        $(this).html().replace(
                            /((http|https|ftp):\/\/[a-zA-Z0-9-_~#:\.\?%&\/\[\]@\!\$'\(\)\*\+,;=]+)/g,
                            '$1'
                        )
                    );
                });
                return tr;
            }

		} );
	})
}

// Make all the DataTables (each tab)
var constructDataTables = function() {
	var first_table_name = tables[0]

	var $ul = $('
').addClass('nav nav-tabs');
	$.each(tables, function(i, table_name){
		$('
').append('' + table_name + '').bind('click', function(e){
			e.preventDefault();
			$(this).addClass('active').siblings('.active').removeClass('active');
			constructDataTable(i, table_name)
		}).appendTo($ul);
	});
	$ul.appendTo('body');

	constructDataTable(0, first_table_name)
}

// Main entry point, make the data table
var settings
var sqliteEndpoint
var tables
$(function(){
	settings = scraperwiki.readSettings()
	sqliteEndpoint = settings.target.url + '/sqlite'

	scraperwiki.sql("select name from " + escapeSQL('sqlite_master') + " where type = 'table'", function(data, textStatus, jqXHR) {
		tables = []
		$.each(data, function (i) {
			tables.push(data[i].name)
		})
		console.log("Tables are:", tables)
		constructDataTables()
	}, function(jqXHR, textStatus, errorThrown) {
		scraperwiki.alert(errorThrown, jqXHR.responseText, "error")
	})

});

<commit_msg>fix crazy indentation<commit_after>// datatables-tool.js

var escapeSQL = function(column_name) {
	return '"' + column_name.replace(/"/g, '""') + '"'
}

// Function to map JSON data between DataTables format and ScraperWiki's SQL endpoint format.
// It returns a function for the fnServerData parameter
var convertData = function(table_name, column_names) {
	// This is a wrapper round the GET request DataTables makes to get more data
	// sSource - the URL, we don't use it, we hard code it instead
	// aoData - contains the URL parameters, e.g. what page, what to filter, what order and so on
	// fnCallback - where to call with the data you get back
	// oSettings - settings object for the whole DataTables, see http://datatables.net/docs/DataTables/1.9.0/DataTable.models.oSettings.html
	return function ( sSource, aoData, fnCallback, oSettings ) {
		// convert aoData into a normal hash (called ps)
		var params = {}
		for (var i=0;i<aoData.length;i++) {
			params[aoData[i].name] = aoData[i].value
		}
		console.log("DataTables params:", params)

		// construct SQL query needed according to the parameters
		var columns  = _.map(column_names, escapeSQL).join(",")
		var order_by = ""
		if (params.iSortingCols >= 1) {
			var order_parts = []
			for (var i = 0; i < params.iSortingCols; i++) {
				order_part = escapeSQL(column_names[params["iSortCol_" + i]])
				if (params["sSortDir_" + i] == 'desc') {
					order_part += " desc"
				} else if (params["sSortDir_" + i] != 'asc') {
					scraperwiki.alert("Got unknown sSortDir_" + i + " value in table " + table_name)
				}
				order_parts.push(order_part)
			}
			order_by = " order by " + order_parts.join(",")
		}
		var where = ""
		if (params.sSearch) {
			// XXX no idea if this bog standard Javascript escape really does what we want with SQL databases.
			// There's no security risk (as endpoint is sandboxed). There could be user experience pain though.
			var search = "'%" + escape(params.sSearch.toLowerCase()) + "%'"
			where = " where " + _.map(column_names, function(n) { return "lower(" + escapeSQL(n) + ") like " + search }).join(" or ")
		}
		var query = "select " + columns +
			     " from " + escapeSQL(table_name) +
				 where +
				 order_by +
			     " limit " + params.iDisplayLength +
			     " offset " + params.iDisplayStart
		console.log("SQL query:", query)

		// get column counts
		scraperwiki.sql("select (select count(*) from " + escapeSQL(table_name) + ") as total, (select count(*) from " + escapeSQL(table_name) + where + ") as display_total", function (data) {
			var counts = data[0]

			oSettings.jqXHR = $.ajax( {
				"dataType": 'json',
				"type": "GET",
				"url": sqliteEndpoint,
				"data": { q: query },
				"success": function ( response ) {
					// ScraperWiki returns a list of dicts. This converts it to a list of lists.
					var rows = []
					for (var i=0;i<response.length;i++) {
						var row = []
						for (k in response[i]) {
							row.push(response[i][k])
						}
						rows.push(row)
					}
					// Send the data to dataTables
					fnCallback({
						"aaData" : rows,
						"iTotalRecords": data[0].total, // without filtering
						"iTotalDisplayRecords": data[0].display_total // after filtering
					})
				},
				"error": function(jqXHR, textStatus, errorThrown) {
					scraperwiki.alert(errorThrown, jqXHR.responseText, "error")
				}
			} );
		}, function(jqXHR, textStatus, errorThrown) {
			scraperwiki.alert(errorThrown, jqXHR.responseText, "error")
		})
	}
}

// Find the column names
function getTableColumnNames(table_name, callback){
    scraperwiki.sql("select * from " + escapeSQL(table_name) + " limit 1", function(data) {
		callback(_.keys(data[0]))
	}, function(jqXHR, textStatus, errorThrown) {
		scraperwiki.alert(errorThrown, jqXHR.responseText, "error")
	})
}

// Make one of the DataTables (in one tab)
var constructDataTable = function(i, table_name) {
	// Find or make the table
	$(".maintable").hide()
	var id = "table_" + i
	var $outer = $("#" + id)
	if ($outer.length == 0) {
		console.log("making a new table:", table_name)
		$outer = $('

')
		$('body').append($outer)
	} else {
		$outer.show()
		console.log("reusing cached table:", table_name)
		return
	}
	var $t = $outer.find("table")

	// Find out the column names
	getTableColumnNames(table_name, function(column_names) {
		console.log("Columns", column_names)
		if (column_names.length == 0) {
			scraperwiki.alert("No data in the table", jqXHR.responseText)
			return
		}

		// Make the column headings
        var thead = '

'
		_.each(column_names, function(column_name) {
			thead += '' + column_name + '	'
		})
		thead += '

'
		$t.append(thead)

		// Fill in the datatables object
		$t.dataTable({
			"bProcessing": true,
			"bServerSide": true,
			"bDeferRender": true,
			"bPaginate": true,
			"sPaginationType": "full_numbers",
			"bFilter": true,
			"iDisplayLength": 1000,
      "bScrollCollapse": true,
      "sDom": '<"H"fip>rt<"F"pi>',
			"fnServerData": convertData(table_name, column_names),
      "fnRowCallback": function( tr, array, iDisplayIndex, iDisplayIndexFull ) {
          $('td', tr).each(function(){
              $(this).html(
                  $(this).html().replace(
                      /((http|https|ftp):\/\/[a-zA-Z0-9-_~#:\.\?%&\/\[\]@\!\$'\(\)\*\+,;=]+)/g,
                      '$1'
                  )
              );
          });
          return tr;
      }
		});
	})
}

// Make all the DataTables (each tab)
var constructDataTables = function() {
	var first_table_name = tables[0]

	var $ul = $('
').addClass('nav nav-tabs');
	$.each(tables, function(i, table_name){
		$('
').append('' + table_name + '').bind('click', function(e){
			e.preventDefault();
			$(this).addClass('active').siblings('.active').removeClass('active');
			constructDataTable(i, table_name)
		}).appendTo($ul);
	});
	$ul.appendTo('body');

	constructDataTable(0, first_table_name)
}

// Main entry point, make the data table
var settings
var sqliteEndpoint
var tables
$(function(){
	settings = scraperwiki.readSettings()
	sqliteEndpoint = settings.target.url + '/sqlite'

	scraperwiki.sql("select name from " + escapeSQL('sqlite_master') + " where type = 'table'", function(data, textStatus, jqXHR) {
		tables = []
		$.each(data, function (i) {
			tables.push(data[i].name)
		})
		console.log("Tables are:", tables)
		constructDataTables()
	}, function(jqXHR, textStatus, errorThrown) {
		scraperwiki.alert(errorThrown, jqXHR.responseText, "error")
	})

});

<|endoftext|>


<commit_before>import Ember from 'ember';

export default Ember.Route.extend({
  actions: {
    submit: function () {
      var
        self = this,
        content = this.controller.get('firstSnippet'),
        snippet = this.store.createRecord('snippet', {
          content: content,
      });

      snippet.save().then(function () {
        var draft = self.store.createRecord('draft', {
          firstLine: content.slice(0, 30),
          contributionStatus: 'cooldown',
          canAdmin: true,
          snippetCount: 1,
          lastSnippet: snippet,
        });

        return draft.save();
      }).then(function () {
        return self.transitionTo('index');
      });
    }
  }
});
<commit_msg>Create the Draft server-side instead.<commit_after>import Ember from 'ember';

export default Ember.Route.extend({
  actions: {
    submit: function () {
      var
        self = this,
        content = this.controller.get('firstSnippet'),
        snippet = this.store.createRecord('snippet', {
          content: content,
      });

      snippet.save().then(function () {
        return self.transitionTo('index');
      });
    }
  }
});
<|endoftext|>


<commit_before>var require = {
  baseUrl: "js",
  shim: {
    underscore: {
      exports: function() {
        return _.noConflict();
      }
    },
    // Apparently jQuery 1.7 and above uses a named define(), which
    // makes it a bona fide module which doesn't need a shim. However,
    // it also doesn't bother calling jQuery.noConflict(), which we
    // want, so we do a bit of configuration ridiculousness to
    // accomplish this.
    "jquery.min": {
      exports: 'jQuery'
    },
    "jquery-ui": {
      deps: ["jquery"]
    },
    "jquery-tipsy": {
      deps: ["jquery"],
      exports: 'jQuery'
    },
    backbone: {
      deps: ["underscore", "jquery"],
      exports: function() {
        return Backbone.noConflict();
      }
    }
  },
  paths: {
    // Vendor paths
    "jquery.min": "../vendor/jquery.min",
    "jquery-ui": "../vendor/jquery-ui-1.11.3.custom/jquery-ui.min",
    "jquery-tipsy": "../vendor/jquery.tipsy",
    "underscore": "../vendor/underscore.min",
    "backbone": "../vendor/backbone.min",
    // some independent functions
    "text": "../vendor/require.text",
    "i18n": "../vendor/require.i18n",
    "lscache": "../vendor/lscache",
    // Non-vendor paths
    "jquery": "shims/jquery.no-conflict",
    "backbone-events": "shims/backbone-events",
    "template": "require.template",
    "test": "../test",
    "templates": "../templates",
    "localized": "/bower/webmaker-i18n/localized",
    "languages": "/bower/webmaker-language-picker/js/languages",
    "selectize": "/bower/selectize/dist/js/standalone/selectize.min",
    "list": "/bower/listjs/dist/list.min",
    "fuzzySearch": "/bower/list.fuzzysearch.js/dist/list.fuzzysearch.min",
    "analytics": "/bower/webmaker-analytics/analytics",
    "url-template": "/bower/url-template/lib/url-template"
  },
  config: {
    template: {
      htmlPath: "templates",
      i18nPath: "fc/nls/ui"
    }
  }
};

if (typeof(module) == 'object' && module.exports) {
  // We're running in node.
  module.exports = require;
  // For some reason requirejs in node doesn't like shim function exports.
  require.shim['underscore'].exports = '_';
  require.shim['backbone'].exports = 'Backbone';
} else (function() {
  var RE = /^(https?:)\/\/([^\/]+)\/(.*)\/require-config\.js$/;
  var me = document.querySelector('script[src$="require-config.js"]');
  var console = window.console || {log: function() {}};
  if (me) {
    var parts = me.src.match(RE);
    if (parts) {
      var protocol = parts[1];
      var host = parts[2];
      var path = '/' + parts[3];
      if (protocol != location.protocol || host != location.host)
        console.log("origins are different. requirejs text plugin may " +
                    "not work.");
      require.baseUrl = path;
    }
  }
  console.log('require.baseUrl is ' + require.baseUrl);
})();
<commit_msg>Change jquery to be loaded through Google CDN<commit_after>var require = {
  baseUrl: "js",
  shim: {
    underscore: {
      exports: function() {
        return _.noConflict();
      }
    },
    // Apparently jQuery 1.7 and above uses a named define(), which
    // makes it a bona fide module which doesn't need a shim. However,
    // it also doesn't bother calling jQuery.noConflict(), which we
    // want, so we do a bit of configuration ridiculousness to
    // accomplish this.
    "jquery.min": {
      exports: 'jQuery'
    },
    "jquery-ui": {
      deps: ["jquery"]
    },
    "jquery-tipsy": {
      deps: ["jquery"],
      exports: 'jQuery'
    },
    backbone: {
      deps: ["underscore", "jquery"],
      exports: function() {
        return Backbone.noConflict();
      }
    }
  },
  paths: {
    // Vendor paths
    "jquery.min": "https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min",
    "jquery-ui": "../vendor/jquery-ui-1.11.3.custom/jquery-ui.min",
    "jquery-tipsy": "../vendor/jquery.tipsy",
    "underscore": "../vendor/underscore.min",
    "backbone": "../vendor/backbone.min",
    // some independent functions
    "text": "../vendor/require.text",
    "i18n": "../vendor/require.i18n",
    "lscache": "../vendor/lscache",
    // Non-vendor paths
    "jquery": "shims/jquery.no-conflict",
    "backbone-events": "shims/backbone-events",
    "template": "require.template",
    "test": "../test",
    "templates": "../templates",
    "localized": "/bower/webmaker-i18n/localized",
    "languages": "/bower/webmaker-language-picker/js/languages",
    "selectize": "/bower/selectize/dist/js/standalone/selectize.min",
    "list": "/bower/listjs/dist/list.min",
    "fuzzySearch": "/bower/list.fuzzysearch.js/dist/list.fuzzysearch.min",
    "analytics": "/bower/webmaker-analytics/analytics",
    "url-template": "/bower/url-template/lib/url-template"
  },
  config: {
    template: {
      htmlPath: "templates",
      i18nPath: "fc/nls/ui"
    }
  }
};

if (typeof(module) == 'object' && module.exports) {
  // We're running in node.
  module.exports = require;
  // For some reason requirejs in node doesn't like shim function exports.
  require.shim['underscore'].exports = '_';
  require.shim['backbone'].exports = 'Backbone';
} else (function() {
  var RE = /^(https?:)\/\/([^\/]+)\/(.*)\/require-config\.js$/;
  var me = document.querySelector('script[src$="require-config.js"]');
  var console = window.console || {log: function() {}};
  if (me) {
    var parts = me.src.match(RE);
    if (parts) {
      var protocol = parts[1];
      var host = parts[2];
      var path = '/' + parts[3];
      if (protocol != location.protocol || host != location.host)
        console.log("origins are different. requirejs text plugin may " +
                    "not work.");
      require.baseUrl = path;
    }
  }
  console.log('require.baseUrl is ' + require.baseUrl);
})();
<|endoftext|>