<commit_before>// Copyright (c) 2015 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
'use strict';

var Cluster = require('./cluster.js');
var logger = require('winston');
var parseArgs = require('./parse_args.js');
var express = require('express');
var PythonShell = require('python-shell');
PythonShell.defaultOptions = {
  scriptPath: './uber'
};

var LEADER_KEY = 'LEADER';

function App(ringpop) {
    this.ringpop = ringpop;
    this.currentLeader = null;
    this.isLeader = false;
}

App.prototype.chooseLeader = function chooseLeader() {
    var newLeader = this.ringpop.lookup(LEADER_KEY);
    if (!this.currentLeader || newLeader !== this.currentLeader) {
        logger.info(this.ringpop.whoami() + ' says new leader is ' + newLeader);

        // This app was not a leader, but now is.
        if (!this.isLeader && newLeader === this.ringpop.whoami()) {
            // Subscribe
            this.isLeader = true;
        }

        // This app was a leader, but now is not.
        if (this.isLeader && newLeader !== this.ringpop.whoami()) {
            // Unsubscribe
            this.isLeader = false;
        }

        this.currentLeader = newLeader;
    }
};

if (require.main === module) {
    var cluster = new Cluster(parseArgs());

    // Launch cluster. If successful, get individual Ringpop instances (nodes)
    // back.
    cluster.launch(function onLaunch(err, ringpops) {
        if (err) {
            logger.error('error:' + err.message);
            process.exit(1);
        }

        // Create an App wrapper around each Ringpop instance. Choose a
        // leader upon instantiation and when a ring change is detected.
        ringpops.forEach(function each(ringpop) {
            var app = new App(ringpop);
            app.chooseLeader();
            ringpop.on('ringChanged', app.chooseLeader.bind(app));
        });

        // These HTTP servers will act as the front-end
        // for the Ringpop cluster.
        ringpops.forEach(function each(ringpop, index) {
            var http = express();
            var req, res;

            // Define a single HTTP endpoint that 'handles' or forwards
            http.get('/loc', function onReq(_req, _res) {
                req = _req;
                res = _res;
                console.log("get query " + JSON.stringify(_req.query) + '\n');
                var pyshell = new PythonShell('get_id.py');
                pyshell.send(JSON.stringify(_req.query) + '\n').end();
                pyshell.on('message', function (key) {
                  // received a message sent from the Python script (a simple "print" statement)
                  if (ringpop.handleOrProxy(key, req, res)) {
                      console.log('Ringpop ' + ringpop.whoami() + ' handled request %o', req.params);
                      res.end();
                  } else {
                      console.log('Ringpop ' + ringpop.whoami() +
                          ' forwarded request ', req.query);
                  }
                });
            });

            var port = cluster.basePort * 2 + index; // HTTP will need its own port
            http.listen(port, function onListen() {
                console.log('HTTP is listening on ' + port);
            });
        });
    });
}
<commit_msg>--amend<commit_after>// Copyright (c) 2015 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
'use strict';

var Cluster = require('./cluster.js');
var logger = require('winston');
var parseArgs = require('./parse_args.js');
var express = require('express');
var PythonShell = require('python-shell');
PythonShell.defaultOptions = {
  scriptPath: './uber'
};

var LEADER_KEY = 'LEADER';

function App(ringpop) {
    this.ringpop = ringpop;
    this.currentLeader = null;
    this.isLeader = false;
}

App.prototype.chooseLeader = function chooseLeader() {
    var newLeader = this.ringpop.lookup(LEADER_KEY);
    if (!this.currentLeader || newLeader !== this.currentLeader) {
        logger.info(this.ringpop.whoami() + ' says new leader is ' + newLeader);

        // This app was not a leader, but now is.
        if (!this.isLeader && newLeader === this.ringpop.whoami()) {
            // Subscribe
            this.isLeader = true;
        }

        // This app was a leader, but now is not.
        if (this.isLeader && newLeader !== this.ringpop.whoami()) {
            // Unsubscribe
            this.isLeader = false;
        }

        this.currentLeader = newLeader;
    }
};

if (require.main === module) {
    var cluster = new Cluster(parseArgs());

    // Launch cluster. If successful, get individual Ringpop instances (nodes)
    // back.
    cluster.launch(function onLaunch(err, ringpops) {
        if (err) {
            logger.error('error:' + err.message);
            process.exit(1);
        }

        // Create an App wrapper around each Ringpop instance. Choose a
        // leader upon instantiation and when a ring change is detected.
        ringpops.forEach(function each(ringpop) {
            var app = new App(ringpop);
            app.chooseLeader();
            ringpop.on('ringChanged', app.chooseLeader.bind(app));
        });

        // These HTTP servers will act as the front-end
        // for the Ringpop cluster.
        ringpops.forEach(function each(ringpop, index) {
            var http = express();

            // Define a single HTTP endpoint that 'handles' or forwards
            http.get('/loc', function onReq(req, res) {
                console.log("get query " + JSON.stringify(req.query) + '\n');
                var pyshell = new PythonShell('get_id.py');
                pyshell.send(JSON.stringify(req.query)).end();
                pyshell.on('message', function (key) {
                  // received a message sent from the Python script (a simple "print" statement)
                  if (ringpop.handleOrProxy(key, req, res)) {
                      console.log('Ringpop ' + ringpop.whoami() + ' handled request %o', req.params);
                      res.end();
                  } else {
                      console.log('Ringpop ' + ringpop.whoami() +
                          ' forwarded request ', req.query);
                  }
                });
            });

            var port = cluster.basePort * 2 + index; // HTTP will need its own port
            http.listen(port, function onListen() {
                console.log('HTTP is listening on ' + port);
            });
        });
    });
}
<|endoftext|>


<commit_before>/*global templatePath */
var fs = require('fs-extra');

module.exports = {
  controllerPath : 'both/controllers/',
  contrTemplates: templatePath + 'controller/',

  // Public: Creates a controller file and any type of controller needed.
  // By default if no options are passed in it will create all router and
  // CRUD controllers. Routes are appended to `/both/routes.js`
  //
  // resName - The {String} name of the resource passed in from command line
  // opts -    The options generated from a Commander command entry.
  //
  // Create all controllers passed in
  init: function(resName, opts) {

    // TODO ensure resName is always snake case
    this.contrFile = this.controllerPath + resName + '.js';
    this.resName = resName;
    this.opts = opts;

    if (!opts.index && !opts.new && !opts.show && !opts.edit &&
        !opts.create && !opts.update && !opts.destroy) {
      this.opts.all = true;
    }

    this.createBaseController();

    // add comment to top of resource routes
    require('./router').appendRoute(resName, 'comment_line');

    // resource file gets created before appending if none exists

    // page controller for list of resources
    if (opts.index || opts.all) {
      this.appendController('index');
    }

    // page controller for creating a new resource
    if (opts.new || opts.all) {
      this.appendController('new');
    }

    // page controller for a single resource
    if (opts.show || opts.all) {
      this.appendController('show');
    }

    // page for controller editing a resource
    if (opts.edit || opts.all) {
      this.appendController('edit');
    }

    // data controller for new resource
    if (opts.create || opts.all) {
      this.appendController('create');
    }

    // data controller for updating a resource
    if (opts.update || opts.all) {
      this.appendController('update');
    }

    // data controller for removing a resource
    if (opts.destroy || opts.all) {
      this.appendController('destroy');
    }

    // add blank line to routes.js
    require('./router').appendRoute(null, 'blank_line');
  },

  // Private: Streams controller template into the end of resource controller
  // file. An action param is used to select which template to stream. If the
  // file doesn't exisit, it will be created. A route is appended to routes.js
  //
  // action - The {String} name of the controller action, eg index, show
  //
  appendController: function(action) {
    var string = fs.readFileSync(this.contrTemplates + action + '.js');
    fs.appendFileSync(this.contrFile, string);
    // add a route for new controller
    if (action !== 'create' && action !== 'update' && action !== 'destroy') {
      require('./router').appendRoute(this.resName, action);
    }
  },

  // Private: Copy base app controller from templates dir to user project
  // folder `both/controllers/app.js` Will not overwrite existing file.
  //
  createBaseController: function() {
    if (fs.existsSync(this.controllerPath + 'app.js')) return;

    fs.copySync(this.contrTemplates+'app.js', this.controllerPath+'app.js');
    console.log('  Created '+ this.controllerPath +'app.js');
  }
};

<commit_msg>print created for resource file<commit_after>/*global templatePath */
var fs = require('fs-extra');

module.exports = {
  controllerPath : 'both/controllers/',
  contrTemplates: templatePath + 'controller/',

  // Public: Creates a controller file and any type of controller needed.
  // By default if no options are passed in it will create all router and
  // CRUD controllers. Routes are appended to `/both/routes.js`
  //
  // resName - The {String} name of the resource passed in from command line
  // opts -    The options generated from a Commander command entry.
  //
  // Create all controllers passed in
  init: function(resName, opts) {

    // TODO ensure resName is always snake case
    this.contrFile = this.controllerPath + resName + '.js';
    this.resName = resName;
    this.opts = opts;

    if (!opts.index && !opts.new && !opts.show && !opts.edit &&
        !opts.create && !opts.update && !opts.destroy) {
      this.opts.all = true;
    }

    this.createBaseController();

    // add comment to top of resource routes
    require('./router').appendRoute(resName, 'comment_line');

    // resource file gets created before appending if none exists
    if (!fs.existsSync(this.contrFile)) {
      console.log('    Created: ' + this.contrFile);
    }

    // page controller for list of resources
    if (opts.index || opts.all) {
      this.appendController('index');
    }

    // page controller for creating a new resource
    if (opts.new || opts.all) {
      this.appendController('new');
    }

    // page controller for a single resource
    if (opts.show || opts.all) {
      this.appendController('show');
    }

    // page for controller editing a resource
    if (opts.edit || opts.all) {
      this.appendController('edit');
    }

    // data controller for new resource
    if (opts.create || opts.all) {
      this.appendController('create');
    }

    // data controller for updating a resource
    if (opts.update || opts.all) {
      this.appendController('update');
    }

    // data controller for removing a resource
    if (opts.destroy || opts.all) {
      this.appendController('destroy');
    }

    // add blank line to routes.js
    require('./router').appendRoute(null, 'blank_line');
  },

  // Private: Streams controller template into the end of resource controller
  // file. An action param is used to select which template to stream. If the
  // file doesn't exisit, it will be created. A route is appended to routes.js
  //
  // action - The {String} name of the controller action, eg index, show
  //
  appendController: function(action) {
    var string = fs.readFileSync(this.contrTemplates + action + '.js');
    fs.appendFileSync(this.contrFile, string);
    // add a route for new controller
    if (action !== 'create' && action !== 'update' && action !== 'destroy') {
      require('./router').appendRoute(this.resName, action);
    }
  },

  // Private: Copy base app controller from templates dir to user project
  // folder `both/controllers/app.js` Will not overwrite existing file.
  //
  createBaseController: function() {
    if (fs.existsSync(this.controllerPath + 'app.js')) return;

    fs.copySync(this.contrTemplates+'app.js', this.controllerPath+'app.js');
    console.log('  Created '+ this.controllerPath +'app.js');
  }
};

<|endoftext|>


<commit_before>import { DEFAULT_API_TIMEOUT } from 'app/constants';

import makeRequest from './makeRequest';

export function getTimes() {
  const performance = global.performance ||
                    global.webkitPerformance ||
                    global.msPerformance ||
                    global.mozPerformance;

  if (!performance || !performance.timing) {
    return;
  }

  const pt = performance.timing;

  const timings = {};

  function timing(key, start, end) {
    if (!pt[start] || !pt[end]) {
      return;
    }

    const startTime = pt[start] / 1000;
    const endTime = pt[end] / 1000;
    const duration = endTime - startTime;

    if (duration === 0) {
      return;
    }

    timings[key] = duration;
  }

  timing('redirectTiming', 'redirectStart', 'redirectEnd');
  timing('startTiming', 'fetchStart', 'domainLookupStart');
  timing('dnsTiming', 'domainLookupStart', 'domainLookupEnd');
  timing('tcpTiming', 'connectStart', 'connectEnd');
  timing('httpsTiming', 'secureConnectionStart', 'connectEnd');
  timing('requestTiming', 'requestStart', 'responseStart');
  timing('responseTiming', 'responseStart', 'responseEnd');
  timing('domLoadingTiming', 'domLoading', 'domInteractive');
  timing('domInteractiveTiming', 'domInteractive', 'domContentLoadedEventStart');
  timing('domContentLoadedTiming', 'domContentLoadedEventStart', 'domContentLoadedEventEnd');

  return timings;
}

export function sendTimings(beginRender) {
    if (Math.random() > 0.1) { // 10% of requests
      return;
    }

    let actionName = `m2.server.shell`;

    const timings = Object.assign({
      actionName: actionName,
    }, getTimes());

    timings.mountTiming = (Date.now() - beginRender) / 1000;

    makeRequest
      .post('/timings')
      .timeout(DEFAULT_API_TIMEOUT)
      .send({
        rum: timings,
      })
      .then();
}
<commit_msg>Fix lint issues<commit_after>import { DEFAULT_API_TIMEOUT } from 'app/constants';

import makeRequest from './makeRequest';

export function getTimes() {
  const performance = global.performance ||
                    global.webkitPerformance ||
                    global.msPerformance ||
                    global.mozPerformance;

  if (!performance || !performance.timing) {
    return;
  }

  const pt = performance.timing;

  const timings = {};

  function timing(key, start, end) {
    if (!pt[start] || !pt[end]) {
      return;
    }

    const startTime = pt[start] / 1000;
    const endTime = pt[end] / 1000;
    const duration = endTime - startTime;

    if (duration === 0) {
      return;
    }

    timings[key] = duration;
  }

  timing('redirectTiming', 'redirectStart', 'redirectEnd');
  timing('startTiming', 'fetchStart', 'domainLookupStart');
  timing('dnsTiming', 'domainLookupStart', 'domainLookupEnd');
  timing('tcpTiming', 'connectStart', 'connectEnd');
  timing('httpsTiming', 'secureConnectionStart', 'connectEnd');
  timing('requestTiming', 'requestStart', 'responseStart');
  timing('responseTiming', 'responseStart', 'responseEnd');
  timing('domLoadingTiming', 'domLoading', 'domInteractive');
  timing('domInteractiveTiming', 'domInteractive', 'domContentLoadedEventStart');
  timing('domContentLoadedTiming', 'domContentLoadedEventStart', 'domContentLoadedEventEnd');

  return timings;
}

export function sendTimings(beginRender) {
  if (Math.random() > 0.1) { // 10% of requests
    return;
  }

  const actionName = 'm2.server.shell';

  const timings = Object.assign({
    actionName,
  }, getTimes());

  timings.mountTiming = (Date.now() - beginRender) / 1000;

  makeRequest
    .post('/timings')
    .timeout(DEFAULT_API_TIMEOUT)
    .send({
      rum: timings,
    })
    .then();
}
<|endoftext|>


<commit_before>#!/usr/bin/env node
/* jshint node: true */
/**
# deploy.js - portable deployment script

This portable Node.js script minifies both your application, its
libraries & the Enyo framework it is using.  The resulting application
is suitable for production usage, either hosted on a web-server or
embedded into a PhoneGap container.

The script is intended to be run from the application's root directory
(This is unlike previous deprecated incarnations of the scripts
`deploy.sh` and `deploy.bat` that shipped within the `bootplate`
application), where it expects to find a file called `package.js`
(unless the user specifies an alternate location using the `-p` flag).

This script comes along with Enyo.  It automatically uses & embeds the
Enyo version it is shipped with, unless the user specifies another
Enyo version using the `-e enyo_dir` flag.

This script uses the application manifest `deploy.json` if found.  Here
is a typical application manifest content:

```json
{
	"enyo": "enyo",
	"source": ".",
	"assets": ["icon.png", "index.html", "assets"],
	"libs": ["lib/onyx", "lib/layout"]
}
```

When the application does not have a root-level `deploy.json` manifest
file, this script expects to find the following files & folders in the
application root directory.  Each of them is copied verbatim in the
output production/deployment folder (the one optionally given using
the `-o` flag).

* `index.html`, the application startup page
* `icon.png`, the application icon
* `assets/`holds the static application assets, such as images,
  videos... etc.

When you application has library dependencies (for example
`lib/mylib`), this script uses the library manifest
`lib/mylib/deploy.json` (if present) or the old-fashioned deployment
scripts `lib/mylib/deploy.sh` (on Linux & Mac OSX) or
`lib/mylib/deploy.bat` (on Windows).  If neither exist, then the
entire library is copied (except for `.git`, `target` and `build`
directories).

Here is a typical library manifest content:

```json
{
	"source": ".",
	"assets": ["assets", "images"],
	"libs": []
}
```

 */

// Load dependencies
var nopt = require("nopt"),
	path = require('path'),
	fs = require('fs'),
	shell = require('shelljs');

var stat, script;

// Send message to parent node process, if any
process.on('uncaughtException', function (err) {
	var errMsg = err.toString() + err.stack;
	console.error(errMsg);
	if (process.send) {
		// only available if parent process is node
		process.send({error: errMsg});
	}
	process.exit(1);
});
// receive error messages from child node processes
process.on('message', function(msg) {
	console.dir(basename, msg);
	if (msg.error && msg.error.stack) {
		console.error(basename, msg.error.stack);
	}
	if (process.send) {
		process.send(msg);
	}
});

// Parse arguments

var node = process.argv[0],
	deploy = process.argv[1],
	sourceDir = process.cwd(),
	packageJs = path.join(sourceDir, "package.js"),
	enyoDir = path.join(sourceDir, "enyo"),
	buildDir = path.join(sourceDir, "build"),
	basename = path.basename(sourceDir),
	outDir = path.join(sourceDir, 'deploy', basename),
	less = true, // LESS compilation, turned on by default
	verbose = false,
	beautify = false,
	noexec = false;

function printUsage() {
	// format generated using node-optimist...
	console.log('\n' +
		'Usage: ' + node + ' ' + deploy + ' [-c][-e enyo_dir][-l lib_dir][-b build_dir][-o out_dir][-p package_js][-s source_dir][-f map_from -t map_to ...]\n' +
		'\n' +
		'Options:\n' +
		'  -v  verbose operation                     [boolean]  [default: ' + verbose + ']\n' +
		'  -b  alternate build directory             [default: "' + buildDir + '"]\n' +
		'  -c  do not run the LESS compiler          [boolean]  [default: ' + less + ']\n' +
		'  -e  location of the enyo framework        [default: "' + enyoDir + '"]\n' +
		'  -l  location of the lib folder            [default: "' + enyoDir + '/../lib"]\n' +
		'  -o  alternate output directory            [default: "' + outDir + '"]\n' +
		'  -p  location of the main package.js file  [default: "' + packageJs + '"]\n' +
		'  -s  source code root directory            [default: "' + sourceDir + '"]\n' +
		'  -B  pretty-print (beautify) JS output     [default: "' + beautify + '"]\n' +
		'  -f  remote source mapping: from local path\n' +
		'  -t  remote source mapping: to remote path' +
		'  -E|--noexec disallow execution of application-provided scripts [default: false]' +
		'\n');
}

var opt = nopt(/*knownOpts*/ {
	"build": path,
	"less": Boolean,
	"enyo": path,
	"lib": path,
	"out": path,
	"packagejs": path,
	"source": path,
	"verbose": Boolean,
	"help": Boolean,
	"beautify": Boolean,
	"noexec": Boolean,
	"mapfrom": [String, Array],
	"mapto": [String, Array]
}, /*shortHands*/ {
	"b": "--build",
	"c": "--no-less",
	"e": "--enyo",
	"l": "--lib",
	"o": "--out",
	"p": "--packagejs",
	"s": "--source",
	"v": "--verbose",
	"h": "--help",
	"B": "--beautify",
	"f": "--mapfrom",
	"t": "--mapto",
	"E": "--noexec",
	"?": "--help"
}, process.argv /*args*/, 2 /*slice*/);

if (opt.help) {
	printUsage();
	process.exit(1);
}

// application default values may come from the manifest file: deploy.json

var manifest;
try {
	manifest = JSON.parse(fs.readFileSync(path.join(sourceDir, "deploy.json")));
} catch(e) {
	manifest = {
		_default: true
	};
}

enyoDir = manifest.enyo ? path.join(process.cwd(), manifest.enyo) : enyoDir;
packageJs = manifest.source ? path.join(process.cwd(), manifest.source, "package.js") : packageJs;

// nopt has not default values system
buildDir = opt.build || buildDir;
enyoDir = opt.enyo || enyoDir;
outDir = opt.out || outDir;
packageJs = opt.packagejs ||
	(opt.source ? path.join(opt.source, 'package.js') : undefined) ||
	packageJs;
sourceDir = opt.source ||
	(opt.packagejs ? path.dirname(opt.packagejs) : undefined) ||
	sourceDir;
less = (opt.less !== false) && less;
beautify = opt.beautify;
noexec = opt.noexec;
verbose = opt.verbose;

var log = function() {};
if (verbose) {
	log = console.log;
}

if ((opt.mapfrom || opt.maptop) && (!opt.mapfrom || !opt.mapto || (opt.mapfrom.length != opt.mapto.length))) {
	log("mapfrom:", opt.mapfrom);
	log("mapto:", opt.mapto);
	console.error("Error: The number of 'mapfrom' and 'mapto' arguments must match.");
	process.exit(1);
}

var minifier = path.resolve(__dirname, 'minifier', 'minify.js');
log("Using: build_dir=" + buildDir);
log("Using: enyo_dir=" + enyoDir);
log("Using: out_dir=" + outDir);
log("Using: packagejs=" + packageJs);
log("Using: source_dir=" + sourceDir);
log("Using: less=" + less);
log("Using: beautify=" + beautify);
log("Using: noexec=" + noexec);

// utils

function run(args, wd) {
	var cwd = process.cwd();
	log("% cd " + wd);
	process.chdir(path.resolve(wd));
	var command = '"' + args.join('" "') + '"';
	var report;
	log("% ", command);
	report = shell.exec(command, { silent: true });
	if (report.code !== 0) {
		throw new Error("Fail: '" + command + "'\n" + report.output);
	}
	log("% cd " + cwd);
	process.chdir(cwd);
}

// Prepare target directory

log("% rm -rf " + outDir);
shell.rm('-rf', outDir);
log("% mkdir -p " + outDir);
shell.mkdir('-p', outDir);

// Build / Minify
var args;
if (!opt.mapfrom || opt.mapfrom.indexOf("enyo") < 0) {
	console.log("Minify-ing Enyo...");
	args = [node, minifier,
		'-no-alias',
		'-enyo', enyoDir,
		// XXX generates $buildDir/enyo.(js|css)' so this is
		// XXX rather an 'output_prefix' than an 'out_dir'...
		'-output', path.join(buildDir, 'enyo'),
		(beautify ? '-beautify' : '-no-beautify'),
		path.join(enyoDir, 'minify', 'package.js')];
	if (opt.mapfrom) {
		for (var i=0; i<opt.mapfrom.length; i++) {
			args.push("-f", opt.mapfrom[i], "-t", opt.mapto[i]);
		}
	}
	run(args, path.join(enyoDir, 'minify'));
} else {
	console.log("Skipping Enyo minification (will be mapped to " + opt.mapto[opt.mapfrom.indexOf("enyo")] + ").");
}

console.log("Minify-ing the application...");
args = [node, minifier,
	'-enyo', enyoDir,
	'-output', path.join(buildDir, 'app'),
	(less ? '-less' : '-no-less'),
	(beautify ? '-beautify' : '-no-beautify'),
	packageJs];
if (opt.mapfrom) {
	for (var i=0; i<opt.mapfrom.length; i++) {
		args.push("-f", opt.mapfrom[i], "-t", opt.mapto[i]);
	}
}
if (opt.lib) {
	args.push("-lib", opt.lib);
}
run(args, sourceDir);

// Deploy / Copy

console.log("Copying assets...");
if(!manifest._default) {
	/* Pick the list of files & folders to copy from the application manifest */
	deployDir(".", sourceDir, outDir);
} else {
	/* Use legacy built-in list of files & folders to copy */
	shell.mkdir('-p', path.join(outDir, 'lib'));
	shell.cp(path.join(sourceDir, 'index.html'), path.join(sourceDir, 'icon.png'), outDir);
	shell.cp('-r', buildDir, outDir);

	var assetsSrcDir = path.join(sourceDir, 'assets');
	if(shell.test('-d', assetsSrcDir)) {
		shell.cp('-r', assetsSrcDir, outDir);
	}

	var libsSrcDir = path.join(sourceDir, 'lib');
	if(shell.test('-d', libsSrcDir)) {
		shell.ls(libsSrcDir).forEach(function(lib) {
			var libDir = path.join("lib", lib);
			if (opt.mapfrom && opt.mapfrom.indexOf(libDir) >= 0) {
				// Don't deploy libraries that are loaded from elsewhere
				console.log("Skipping:", libDir);
			} else {
				deployDir(libDir, sourceDir, outDir);
			}
		});
	}
}

function deployDir(subDir, srcDir, dstDir) {
	log("Deploying " + subDir + "...");
	try {
		var manifest = JSON.parse(fs.readFileSync(path.join(srcDir, subDir, "deploy.json")));
		if (Array.isArray(manifest.assets)) {
			manifest.assets.forEach(function(asset) {
				var dstAssetDir = path.dirname(path.join(dstDir, subDir, asset));
				shell.mkdir('-p', dstAssetDir);
				log("% cp -r " + path.join(subDir, asset) + "...");
				shell.cp('-r', path.join(srcDir, subDir, asset), dstAssetDir);
			});
		}
		if (Array.isArray(manifest.libs)) {
			manifest.libs.forEach(function(libDir) {
				deployDir(path.join(subDir, libDir), srcDir, dstDir);
			});
		}
	} catch(e) {
		// backward compatibility: run deploy.sh or deploy.bat
		try {
			if (noexec) {
				console.warn("noexec: Skip execution of client-provided code");
				throw new Error("noexec: Skip execution of client-provided code");
			}
			script = path.join(srcDir, subDir, 'deploy.' + (process.platform === 'win32' ? 'bat' : 'sh'));
			stat = fs.statSync(script);
			if (!stat.isFile()) {
				throw new Error("*** Not a file: '" + script + "'");
			}
			var command = [script, path.join(dstDir, subDir)];
			if (process.platform !== 'win32') {
				command.unshift("sh");
			}
			run(command);
		} catch(e2) {
			// no deploy.(js|bat|sh): copy everything...
			var dd = path.dirname(path.join(dstDir, subDir));
			log("% mkdir -p " + dd);
			shell.mkdir('-p', dd);

			var sd = path.join(srcDir, subDir);
			log("% cp -r " + sd + " " + dd);
			shell.cp('-r', sd, dd);

			// ...then remove ".git" & others, if any
			log("% rm -rf " + dd + "/(.git|target|build|deploy)");
			shell.rm('-rf', path.join(dstDir, subDir, '.git'));
			shell.rm('-rf', path.join(dstDir, subDir, 'target'));
			shell.rm('-rf', path.join(dstDir, subDir, 'build'));
			shell.rm('-rf', path.join(dstDir, subDir, 'deploy'));
		}
	}
}

console.log("Success:  the deployable application is available in: ", outDir);
process.exit(0);<commit_msg>ENYO-2899: fix following more deploy.js tests<commit_after>#!/usr/bin/env node
/* jshint node: true */
/**
# deploy.js - portable deployment script

This portable Node.js script minifies both your application, its
libraries & the Enyo framework it is using.  The resulting application
is suitable for production usage, either hosted on a web-server or
embedded into a PhoneGap container.

The script is intended to be run from the application's root directory
(This is unlike previous deprecated incarnations of the scripts
`deploy.sh` and `deploy.bat` that shipped within the `bootplate`
application), where it expects to find a file called `package.js`
(unless the user specifies an alternate location using the `-p` flag).

This script comes along with Enyo.  It automatically uses & embeds the
Enyo version it is shipped with, unless the user specifies another
Enyo version using the `-e enyo_dir` flag.

This script uses the application manifest `deploy.json` if found.  Here
is a typical application manifest content:

```json
{
	"enyo": "enyo",
	"source": ".",
	"assets": ["icon.png", "index.html", "assets"],
	"libs": ["lib/onyx", "lib/layout"]
}
```

When the application does not have a root-level `deploy.json` manifest
file, this script expects to find the following files & folders in the
application root directory.  Each of them is copied verbatim in the
output production/deployment folder (the one optionally given using
the `-o` flag).

* `index.html`, the application startup page
* `icon.png`, the application icon
* `assets/`holds the static application assets, such as images,
  videos... etc.

When you application has library dependencies (for example
`lib/mylib`), this script uses the library manifest
`lib/mylib/deploy.json` (if present) or the old-fashioned deployment
scripts `lib/mylib/deploy.sh` (on Linux & Mac OSX) or
`lib/mylib/deploy.bat` (on Windows).  If neither exist, then the
entire library is copied (except for `.git`, `target` and `build`
directories).

Here is a typical library manifest content:

```json
{
	"source": ".",
	"assets": ["assets", "images"],
	"libs": []
}
```

 */

// Load dependencies
var nopt = require("nopt"),
	path = require('path'),
	fs = require('fs'),
	shell = require('shelljs');

var stat, script;

// Send message to parent node process, if any
process.on('uncaughtException', function (err) {
	var errMsg = err.toString() + err.stack;
	console.error(errMsg);
	if (process.send) {
		// only available if parent process is node
		process.send({error: errMsg});
	}
	process.exit(1);
});
// receive error messages from child node processes
process.on('message', function(msg) {
	console.dir(basename, msg);
	if (msg.error && msg.error.stack) {
		console.error(basename, msg.error.stack);
	}
	if (process.send) {
		process.send(msg);
	}
});

// Parse arguments

var node = process.argv[0],
	deploy = process.argv[1],
	sourceDir = process.cwd(),
	packageJs = path.join(sourceDir, "package.js"),
	enyoDir = path.join(sourceDir, "enyo"),
	buildDir = path.join(sourceDir, "build"),
	basename = path.basename(sourceDir),
	outDir = path.join(sourceDir, 'deploy', basename),
	less = true, // LESS compilation, turned on by default
	verbose = false,
	beautify = false,
	noexec = false;

function printUsage() {
	// format generated using node-optimist...
	console.log('\n' +
		'Usage: ' + node + ' ' + deploy + ' [-c][-e enyo_dir][-l lib_dir][-b build_dir][-o out_dir][-p package_js][-s source_dir][-f map_from -t map_to ...]\n' +
		'\n' +
		'Options:\n' +
		'  -v  verbose operation                     [boolean]  [default: ' + verbose + ']\n' +
		'  -b  alternate build directory             [default: "' + buildDir + '"]\n' +
		'  -c  do not run the LESS compiler          [boolean]  [default: ' + less + ']\n' +
		'  -e  location of the enyo framework        [default: "' + enyoDir + '"]\n' +
		'  -l  location of the lib folder            [default: "' + enyoDir + '/../lib"]\n' +
		'  -o  alternate output directory            [default: "' + outDir + '"]\n' +
		'  -p  location of the main package.js file  [default: "' + packageJs + '"]\n' +
		'  -s  source code root directory            [default: "' + sourceDir + '"]\n' +
		'  -B  pretty-print (beautify) JS output     [default: "' + beautify + '"]\n' +
		'  -f  remote source mapping: from local path\n' +
		'  -t  remote source mapping: to remote path' +
		'  -E|--noexec disallow execution of application-provided scripts [default: false]' +
		'\n');
}

var opt = nopt(/*knownOpts*/ {
	"build": path,
	"less": Boolean,
	"enyo": path,
	"lib": path,
	"out": path,
	"packagejs": path,
	"source": path,
	"verbose": Boolean,
	"help": Boolean,
	"beautify": Boolean,
	"noexec": Boolean,
	"mapfrom": [String, Array],
	"mapto": [String, Array]
}, /*shortHands*/ {
	"b": "--build",
	"c": "--no-less",
	"e": "--enyo",
	"l": "--lib",
	"o": "--out",
	"p": "--packagejs",
	"s": "--source",
	"v": "--verbose",
	"h": "--help",
	"B": "--beautify",
	"f": "--mapfrom",
	"t": "--mapto",
	"E": "--noexec",
	"?": "--help"
}, process.argv /*args*/, 2 /*slice*/);

if (opt.help) {
	printUsage();
	process.exit(1);
}

// application default values may come from the manifest file: deploy.json

var manifest;
try {
	manifest = JSON.parse(fs.readFileSync(path.join(sourceDir, "deploy.json")));
} catch(e) {
	manifest = {
		_default: true
	};
}

enyoDir = manifest.enyo ? path.join(process.cwd(), manifest.enyo) : enyoDir;
packageJs = manifest.source ? path.join(process.cwd(), manifest.source, "package.js") : packageJs;

// nopt has not default values system
buildDir = opt.build || buildDir;
enyoDir = opt.enyo || enyoDir;
outDir = opt.out || outDir;
packageJs = opt.packagejs ||
	(opt.source ? path.join(opt.source, 'package.js') : undefined) ||
	packageJs;
sourceDir = opt.source ||
	(opt.packagejs ? path.dirname(opt.packagejs) : undefined) ||
	sourceDir;
less = (opt.less !== false) && less;
beautify = opt.beautify;
noexec = opt.noexec;
verbose = opt.verbose;

var log = function() {};
if (verbose) {
	log = console.log;
}

if ((opt.mapfrom || opt.maptop) && (!opt.mapfrom || !opt.mapto || (opt.mapfrom.length != opt.mapto.length))) {
	log("mapfrom:", opt.mapfrom);
	log("mapto:", opt.mapto);
	console.error("Error: The number of 'mapfrom' and 'mapto' arguments must match.");
	process.exit(1);
}

var minifier = path.resolve(__dirname, 'minifier', 'minify.js');
log("Using: build_dir=" + buildDir);
log("Using: enyo_dir=" + enyoDir);
log("Using: out_dir=" + outDir);
log("Using: packagejs=" + packageJs);
log("Using: source_dir=" + sourceDir);
log("Using: less=" + less);
log("Using: beautify=" + beautify);
log("Using: noexec=" + noexec);

// utils

function run(args, wd) {
	var cwd = process.cwd();
	log("% cd " + wd);
	process.chdir(path.resolve(wd));
	var command = '"' + args.join('" "') + '"';
	var report;
	log("% ", command);
	report = shell.exec(command, { silent: true });
	if (report.code !== 0) {
		throw new Error("Fail: '" + command + "'\n" + report.output);
	}
	log("% cd " + cwd);
	process.chdir(cwd);
}

// Prepare target directory

log("% rm -rf " + outDir);
shell.rm('-rf', outDir);
log("% mkdir -p " + outDir);
shell.mkdir('-p', outDir);

// Build / Minify
var args;
if (!opt.mapfrom || opt.mapfrom.indexOf("enyo") < 0) {
	console.log("Minify-ing Enyo...");
	args = [node, minifier,
		'-no-alias',
		'-enyo', enyoDir,
		// XXX generates $buildDir/enyo.(js|css)' so this is
		// XXX rather an 'output_prefix' than an 'out_dir'...
		'-output', path.join(buildDir, 'enyo'),
		(beautify ? '-beautify' : '-no-beautify'),
		path.join(enyoDir, 'minify', 'package.js')];
	if (opt.mapfrom) {
		for (var i=0; i<opt.mapfrom.length; i++) {
			args.push("-f", opt.mapfrom[i], "-t", opt.mapto[i]);
		}
	}
	run(args, path.join(enyoDir, 'minify'));
} else {
	console.log("Skipping Enyo minification (will be mapped to " + opt.mapto[opt.mapfrom.indexOf("enyo")] + ").");
}

console.log("Minify-ing the application...");
args = [node, minifier,
	'-enyo', enyoDir,
	'-output', path.join(buildDir, 'app'),
	(less ? '-less' : '-no-less'),
	(beautify ? '-beautify' : '-no-beautify'),
	packageJs];
if (opt.mapfrom) {
	for (var i=0; i<opt.mapfrom.length; i++) {
		args.push("-f", opt.mapfrom[i], "-t", opt.mapto[i]);
	}
}
if (opt.lib) {
	args.push("-lib", opt.lib);
}
run(args, sourceDir);

// Deploy / Copy

console.log("Copying assets...");
if(!manifest._default) {
	/* Pick the list of files & folders to copy from the application manifest */
	deployDir(".", sourceDir, outDir);
} else {
	/* Use legacy built-in list of files & folders to copy */
	shell.mkdir('-p', path.join(outDir, 'lib'));
	shell.cp(path.join(sourceDir, 'index.html'), path.join(sourceDir, 'icon.png'), outDir);
	shell.cp('-r', buildDir, outDir);

	var assetsSrcDir = path.join(sourceDir, 'assets');
	if(shell.test('-d', assetsSrcDir)) {
		shell.cp('-r', assetsSrcDir, outDir);
	}

	var libsSrcDir = path.join(sourceDir, 'lib');
	if(shell.test('-d', libsSrcDir)) {
		shell.ls(libsSrcDir).forEach(function(lib) {
			var libDir = path.join("lib", lib);
			if (opt.mapfrom && opt.mapfrom.indexOf(libDir) >= 0) {
				// Don't deploy libraries that are loaded from elsewhere
				console.log("Skipping:", libDir);
			} else {
				deployDir(libDir, sourceDir, outDir);
			}
		});
	}
}

function deployDir(subDir, srcDir, dstDir) {
	log("Deploying " + subDir + "...");
	try {
		var manifest = JSON.parse(fs.readFileSync(path.join(srcDir, subDir, "deploy.json")));
		if (Array.isArray(manifest.assets)) {
			manifest.assets.forEach(function(asset) {
				var dstAssetDir = path.dirname(path.join(dstDir, subDir, asset));
				shell.mkdir('-p', dstAssetDir);
				log("% cp -r " + path.join(subDir, asset) + "...");
				shell.cp('-r', path.join(srcDir, subDir, asset), dstAssetDir);
			});
		}
		if (Array.isArray(manifest.libs)) {
			manifest.libs.forEach(function(libDir) {
				deployDir(path.join(subDir, libDir), srcDir, dstDir);
			});
		}
	} catch(e) {
		// backward compatibility: run deploy.sh or deploy.bat
		try {
			if (noexec) {
				console.warn("noexec: Skip execution of client-provided code");
				throw new Error("noexec: Skip execution of client-provided code");
			}
			script = path.join(srcDir, subDir, 'deploy.' + (process.platform === 'win32' ? 'bat' : 'sh'));
			stat = fs.statSync(script);
			if (!stat.isFile()) {
				throw new Error("*** Not a file: '" + script + "'");
			}
			var command = [script, path.join(dstDir, subDir)];
			if (process.platform !== 'win32') {
				command.unshift("sh");
			}
			run(command, path.join(srcDir, subDir));
		} catch(e2) {
			// no deploy.(js|bat|sh): copy everything...
			var dd = path.dirname(path.join(dstDir, subDir));
			log("% mkdir -p " + dd);
			shell.mkdir('-p', dd);

			var sd = path.join(srcDir, subDir);
			log("% cp -r " + sd + " " + dd);
			shell.cp('-r', sd, dd);

			// ...then remove ".git" & others, if any
			log("% rm -rf " + dd + "/(.git|target|build|deploy)");
			shell.rm('-rf', path.join(dstDir, subDir, '.git'));
			shell.rm('-rf', path.join(dstDir, subDir, 'target'));
			shell.rm('-rf', path.join(dstDir, subDir, 'build'));
			shell.rm('-rf', path.join(dstDir, subDir, 'deploy'));
		}
	}
}

console.log("Success:  the deployable application is available in: ", outDir);
process.exit(0);<|endoftext|>


<commit_before>/* jslint asi:true, browser:true */
/* globals LREC */

/*  Setting up objects  */

if (typeof Intl === "undefined") window.Intl = {};
if (!Intl.Collator) window.Intl.Collator = function(locales, options) {};

var Dictionary = {
    collator: undefined,
    handleInputs: undefined,
    id: undefined,
    init: undefined,
    lrec: undefined,
    splash: undefined
}

var LRECs = {
    "": {collator: undefined, location: "index.lrec", skin: "about:blank"},
    "osv-0010": {collator: new Intl.Collator(["art-Latn-x-osv-0010", "no", "da"], {sensitivity: "base"}), location: "../data/languages/jsv/osv/0010/index.lrec", skin: "skins/osv.css"},
    "osv-0011": {collator: new Intl.Collator(["art-Latn-x-osv-0011", "no", "da"], {sensitivity: "base"}), location: "../data/languages/jsv/osv/0011/index.lrec", skin: "skins/osv.css"},
    "osv-0012": {collator: new Intl.Collator(["art-Latn-x-osv-0012", "no", "da"], {sensitivity: "base"}), location: "../data/languages/jsv/osv/0012/index.lrec", skin: "skins/osv.css"},
    "fiz-1der": {collator: new Intl.Collator("art-Latn-x-fiz-1der"), location: "../data/languages/fzn/fiz/1der/index.lrec", skin: "skins/fiz.css"},
    "fiz-1der/characters": {collator: new Intl.Collator("art-Latn-x-fiz-1der-block000"), location: "../data/languages/fzn/fiz/1der/characters.lrec", skin: "skins/fiz.css"}
}

var Query = {
    get: undefined,
    handle: undefined
}

Dictionary.handleInputs = function() {

    //  Sets up variables:

    var i;
    var j;
    var matched;
    var a = document.getElementById("dictionary-search").value;
    var b;
    var tag = document.getElementById("dictionary-tags").value;
    var word;
    var alts;
    var tags;

    //  Iterates over navigation links;

    for (i = 0; i < document.getElementById("dictionary-navigation").children.length; i++) {

        //  Sets up variables:

        word = document.getElementById("dictionary-navigation").children.item(i);
        matched = false;
        b = word.textContent.substr(0, a.length);

        //  Checks for matches:

        if ((Dictionary.collator.compare && Dictionary.collator.compare(a, b)) ||  (!Dictionary.collator.compare && a.localeCompare(b))) {
            alts = JSON.parse(word.dataset.alternates);
            for (j in alts) {
                b = j.substr(0, a.length);
                if ((Dictionary.collator.compare && Dictionary.collator.compare(a, b)) ||  (!Dictionary.collator.compare && a.localeCompare(b))) continue;
                matched = true;
                break;
            }
        }
        else matched = true;

        //  Checks tags:

        if (matched) {
            tags = JSON.parse(word.dataset.tags);
            if (tag !== "" && tags.indexOf(tag) === -1) matched = false;
        }

        //  Hides failed matches; shows successful ones:

        if (!matched) word.setAttribute("hidden", "");
        else word.removeAttribute("hidden");

    }

}

Dictionary.init = function(e) {

    //  Makes sure we're handling the right event:

    if (e && e instanceof CustomEvent && e.details && e.details.lrec !== Dictionary.lrec) return;
    if (!Dictionary.lrec || !(Dictionary.lrec instanceof LREC)) return;

    //  Loads LREC variables:

    document.getElementById("dictionary-skin").href = LRECs[Dictionary.id].skin;
    Dictionary.collator = LRECs[Dictionary.id].collator;

    //  Loads metadata:

    document.getElementById("dictionary-title").textContent = document.title = Dictionary.lrec.title;
    if (Dictionary.lrec.subtitle) document.getElementById("dictionary-subtitle").textContent = Dictionary.lrec.subtitle;
    else document.getElementById("dictionary-subtitle").textContent = "";
    if (Dictionary.lrec.description) document.getElementById("dictionary-description").textContent = Dictionary.lrec.description;
    else document.getElementById("dictionary-description").textContent = "";
    if (Dictionary.lrec.language) document.documentElement.lang = Dictionary.lrec.language;
    else document.documentElement.lang = "";
    if (Dictionary.lrec.author) document.getElementById("dictionary-author").textContent = Dictionary.lrec.author;
    else document.getElementById("dictionary-author").textContent = "";
    if (Dictionary.lrec.date) document.getElementById("dictionary-date").textContent = Dictionary.lrec.date;
    else document.getElementById("dictionary-date").textContent = "";
    Dictionary.splash();
    if (Dictionary.lrec.frontmatter) {
        document.getElementById("dictionary-frame").src = Dictionary.lrec.frontmatter.href;
        document.getElementById("dictionary-title-link").href = Dictionary.lrec.frontmatter.href;
        document.getElementById("dictionary-title-link").target = "dictionary-frame";
    }
    else {
        document.getElementById("dictionary-frame").src = "about:blank";
        document.getElementById("dictionary-title-link").removeAttribute("href");
        document.getElementById("dictionary-title-link").removeAttribute("target");
    }

    //  Splash reloader:

    document.getElementById("dictionary-title").addEventListener("click", Dictionary.splash, false);

    //  Sets up variables:

    var as = [];
    var i;
    var inflection;
    var thing;
    var words;
    var element;

    //  Wipes search and navigation:

    document.getElementById("dictionary-search").textContent = "";
    document.getElementById("dictionary-tags").textContent = "";
    document.getElementById("dictionary-navigation").textContent = "";
    element = document.createElement("option");
    element.value = "";
    element.textContent = "";
    document.getElementById("dictionary-tags").appendChild(element);

    //  Creates entries:

    for (thing in Dictionary.lrec.lexemes) {
        i = as.length;
        as[i] = document.createElement("a");
        as[i].href = Dictionary.lrec.lexemes[thing].url.href;
        as[i].title = Dictionary.lrec.lexemes[thing].gloss;
        as[i].target = "dictionary-frame";
        as[i].textContent = thing;
        if (Dictionary.lrec.lexemes[thing].language) as[i].lang = Dictionary.lrec.lexemes[thing].language;
        as[i].dataset.tags = JSON.stringify(Dictionary.lrec.lexemes[thing].tags);
        as[i].dataset.alternates = JSON.stringify(Dictionary.lrec.lexemes[thing].alternates);
        as[i].dataset.pronunciation = JSON.stringify(Dictionary.lrec.lexemes[thing].pronunciation);
        for (inflection in Dictionary.lrec.lexemes[thing].inflections) {
            i = as.length;
            as[i] = document.createElement("a");
            as[i].href = Dictionary.lrec.lexemes[thing].url.href;
            as[i].title = Dictionary.lrec.lexemes[thing].gloss;
            as[i].target = "dictionary-frame";
            as[i].textContent = inflection;
            if (Dictionary.lrec.lexemes[thing].language) as[i].lang = Dictionary.lrec.lexemes[thing].language;
            as[i].dataset.tags = JSON.stringify(Dictionary.lrec.lexemes[thing].tags);
            as[i].dataset.alternates = JSON.stringify(Dictionary.lrec.lexemes[thing].inflections[inflection].alternates);
            as[i].dataset.pronunciation = JSON.stringify(Dictionary.lrec.lexemes[thing].inflections[inflection].pronunciation);
        }
    }

    //  Sorts entries:

    words = as.map(function(e, i) {return {index: i, text: e.textContent.trim()}});
    words.sort(function(a, b) {if (Dictionary.collator.compare) return Dictionary.collator.compare(a.text, b.text); else return a.text.localeCompare(b.text);});

    //  Adds entries to navigation:

    for (i = 0; i < words.length; i++) {
        document.getElementById("dictionary-navigation").appendChild(as[words[i].index]);
    }

    //  Adds tag-groups:

    for (thing in Dictionary.lrec.groups) {
        element = document.createElement("OPTGROUP");
        element.label = thing;
        if (Dictionary.lrec.groups[thing].description) element.title = Dictionary.lrec.groups[thing].description;
        if (Dictionary.lrec.groups[thing].parent) {
            for (i = 0; i < document.getElementById("dictionary-tags").children.length; i++) {
                if (document.getElementById("dictionary-tags").children.item(i).tagName.toUpperCase() === "OPTGROUP" && document.getElementById("dictionary-tags").children.item(i).label.toLowerCase() === Dictionary.lrec.groups[thing].parent.toLowerCase()) {
                    document.getElementById("dictionary-tags").children.item(i).appendChild(element);
                    break;
                }
            }
        }
        else document.getElementById("dictionary-tags").appendChild(element);
    }

    //  Adds tags:

    for (thing in Dictionary.lrec.tags) {
        element = document.createElement("OPTION");
        element.value = thing;
        element.textContent = thing;
        if (Dictionary.lrec.tags[thing].parent) {
            for (i = 0; i < document.getElementById("dictionary-tags").children.length; i++) {
                if (document.getElementById("dictionary-tags").children.item(i).tagName.toUpperCase() === "OPTGROUP" && document.getElementById("dictionary-tags").children.item(i).label.toLowerCase() === Dictionary.lrec.tags[thing].parent.toLowerCase()) {
                    document.getElementById("dictionary-tags").children.item(i).appendChild(element);
                    break;
                }
            }
        }
        else document.getElementById("dictionary-tags").appendChild(element);
    }

    //  Displays search and tags:

    if (words.length) {
        document.getElementById("dictionary-search").removeAttribute("hidden");
        document.getElementById("dictionary-tags").removeAttribute("hidden");
    }

    //  Add input handlers:

    document.getElementById("dictionary-search").addEventListener("input", Dictionary.handleInputs, false);
    document.getElementById("dictionary-tags").addEventListener("change", Dictionary.handleInputs, false);

}

Dictionary.splash = function() {
    if (!Dictionary.lrec || !(Dictionary.lrec instanceof LREC)) return;
    if (Dictionary.lrec.splashes.length) document.getElementById("dictionary-splash").textContent = Dictionary.lrec.splashes[Math.floor(Math.random() * Dictionary.lrec.splashes.length)];
    else document.getElementById("dictionary-splash").textContent = "";
}

Query.get = function(property) {
    var i;
    var j;
    var q = decodeURIComponent(window.location.search);
    if (!q) q = "?";
    i = q.indexOf("?" + property + "=");
    if (i === -1) i = q.indexOf("&" + property + "=");
    if (i === -1) return undefined;
    i += property.length + 2;
    j = q.indexOf("&", i);
    if (j === -1) return q.substring(i);
    else return q.substring(i, j);
}

Query.handle = function() {
    var d = Query.get("lrec");
    if (d && LRECs[d]) Dictionary.id = d;
    else Dictionary.id = "";
    Dictionary.lrec = new LREC(LRECs[Dictionary.id].location);
}

window.addEventListener("load", Query.handle, false);
document.addEventListener("LREC_Loaded", Dictionary.init, false);
<commit_msg>[master] Revised tag-group handling in dictionary<commit_after>/* jslint asi:true, browser:true */
/* globals LREC */

/*  Setting up objects  */

if (typeof Intl === "undefined") window.Intl = {};
if (!Intl.Collator) window.Intl.Collator = function(locales, options) {};

var Dictionary = {
    collator: undefined,
    handleInputs: undefined,
    id: undefined,
    init: undefined,
    lrec: undefined,
    splash: undefined
}

var LRECs = {
    "": {collator: undefined, location: "index.lrec", skin: "about:blank"},
    "osv-0010": {collator: new Intl.Collator(["art-Latn-x-osv-0010", "no", "da"], {sensitivity: "base"}), location: "../data/languages/jsv/osv/0010/index.lrec", skin: "skins/osv.css"},
    "osv-0011": {collator: new Intl.Collator(["art-Latn-x-osv-0011", "no", "da"], {sensitivity: "base"}), location: "../data/languages/jsv/osv/0011/index.lrec", skin: "skins/osv.css"},
    "osv-0012": {collator: new Intl.Collator(["art-Latn-x-osv-0012", "no", "da"], {sensitivity: "base"}), location: "../data/languages/jsv/osv/0012/index.lrec", skin: "skins/osv.css"},
    "fiz-1der": {collator: new Intl.Collator("art-Latn-x-fiz-1der"), location: "../data/languages/fzn/fiz/1der/index.lrec", skin: "skins/fiz.css"},
    "fiz-1der/characters": {collator: new Intl.Collator("art-Latn-x-fiz-1der-block000"), location: "../data/languages/fzn/fiz/1der/characters.lrec", skin: "skins/fiz.css"}
}

var Query = {
    get: undefined,
    handle: undefined
}

Dictionary.handleInputs = function() {

    //  Sets up variables:

    var i;
    var j;
    var matched;
    var a = document.getElementById("dictionary-search").value;
    var b;
    var tag = document.getElementById("dictionary-tags").value;
    var word;
    var alts;
    var tags;

    //  Iterates over navigation links;

    for (i = 0; i < document.getElementById("dictionary-navigation").children.length; i++) {

        //  Sets up variables:

        word = document.getElementById("dictionary-navigation").children.item(i);
        matched = false;
        b = word.textContent.substr(0, a.length);

        //  Checks for matches:

        if ((Dictionary.collator.compare && Dictionary.collator.compare(a, b)) ||  (!Dictionary.collator.compare && a.localeCompare(b))) {
            alts = JSON.parse(word.dataset.alternates);
            for (j in alts) {
                b = j.substr(0, a.length);
                if ((Dictionary.collator.compare && Dictionary.collator.compare(a, b)) ||  (!Dictionary.collator.compare && a.localeCompare(b))) continue;
                matched = true;
                break;
            }
        }
        else matched = true;

        //  Checks tags:

        if (matched) {
            tags = JSON.parse(word.dataset.tags);
            if (tag !== "" && tags.indexOf(tag) === -1) matched = false;
        }

        //  Hides failed matches; shows successful ones:

        if (!matched) word.setAttribute("hidden", "");
        else word.removeAttribute("hidden");

    }

}

Dictionary.init = function(e) {

    //  Makes sure we're handling the right event:

    if (e && e instanceof CustomEvent && e.details && e.details.lrec !== Dictionary.lrec) return;
    if (!Dictionary.lrec || !(Dictionary.lrec instanceof LREC)) return;

    //  Loads LREC variables:

    document.getElementById("dictionary-skin").href = LRECs[Dictionary.id].skin;
    Dictionary.collator = LRECs[Dictionary.id].collator;

    //  Loads metadata:

    document.getElementById("dictionary-title").textContent = document.title = Dictionary.lrec.title;
    if (Dictionary.lrec.subtitle) document.getElementById("dictionary-subtitle").textContent = Dictionary.lrec.subtitle;
    else document.getElementById("dictionary-subtitle").textContent = "";
    if (Dictionary.lrec.description) document.getElementById("dictionary-description").textContent = Dictionary.lrec.description;
    else document.getElementById("dictionary-description").textContent = "";
    if (Dictionary.lrec.language) document.documentElement.lang = Dictionary.lrec.language;
    else document.documentElement.lang = "";
    if (Dictionary.lrec.author) document.getElementById("dictionary-author").textContent = Dictionary.lrec.author;
    else document.getElementById("dictionary-author").textContent = "";
    if (Dictionary.lrec.date) document.getElementById("dictionary-date").textContent = Dictionary.lrec.date;
    else document.getElementById("dictionary-date").textContent = "";
    Dictionary.splash();
    if (Dictionary.lrec.frontmatter) {
        document.getElementById("dictionary-frame").src = Dictionary.lrec.frontmatter.href;
        document.getElementById("dictionary-title-link").href = Dictionary.lrec.frontmatter.href;
        document.getElementById("dictionary-title-link").target = "dictionary-frame";
    }
    else {
        document.getElementById("dictionary-frame").src = "about:blank";
        document.getElementById("dictionary-title-link").removeAttribute("href");
        document.getElementById("dictionary-title-link").removeAttribute("target");
    }

    //  Splash reloader:

    document.getElementById("dictionary-title").addEventListener("click", Dictionary.splash, false);

    //  Sets up variables:

    var as = [];
    var i;
    var inflection;
    var thing;
    var things;
    var words;
    var element;

    //  Wipes search and navigation:

    document.getElementById("dictionary-search").textContent = "";
    document.getElementById("dictionary-tags").textContent = "";
    document.getElementById("dictionary-navigation").textContent = "";
    element = document.createElement("option");
    element.value = "";
    element.textContent = "";
    document.getElementById("dictionary-tags").appendChild(element);

    //  Creates entries:

    for (thing in Dictionary.lrec.lexemes) {
        i = as.length;
        as[i] = document.createElement("a");
        as[i].href = Dictionary.lrec.lexemes[thing].url.href;
        as[i].title = Dictionary.lrec.lexemes[thing].gloss;
        as[i].target = "dictionary-frame";
        as[i].textContent = thing;
        if (Dictionary.lrec.lexemes[thing].language) as[i].lang = Dictionary.lrec.lexemes[thing].language;
        as[i].dataset.tags = JSON.stringify(Dictionary.lrec.lexemes[thing].tags);
        as[i].dataset.alternates = JSON.stringify(Dictionary.lrec.lexemes[thing].alternates);
        as[i].dataset.pronunciation = JSON.stringify(Dictionary.lrec.lexemes[thing].pronunciation);
        for (inflection in Dictionary.lrec.lexemes[thing].inflections) {
            i = as.length;
            as[i] = document.createElement("a");
            as[i].href = Dictionary.lrec.lexemes[thing].url.href;
            as[i].title = Dictionary.lrec.lexemes[thing].gloss;
            as[i].target = "dictionary-frame";
            as[i].textContent = inflection;
            if (Dictionary.lrec.lexemes[thing].language) as[i].lang = Dictionary.lrec.lexemes[thing].language;
            as[i].dataset.tags = JSON.stringify(Dictionary.lrec.lexemes[thing].tags);
            as[i].dataset.alternates = JSON.stringify(Dictionary.lrec.lexemes[thing].inflections[inflection].alternates);
            as[i].dataset.pronunciation = JSON.stringify(Dictionary.lrec.lexemes[thing].inflections[inflection].pronunciation);
        }
    }

    //  Sorts entries:

    words = as.map(function(e, i) {return {index: i, text: e.textContent.trim()}});
    words.sort(function(a, b) {if (Dictionary.collator.compare) return Dictionary.collator.compare(a.text, b.text); else return a.text.localeCompare(b.text);});

    //  Adds entries to navigation:

    for (i = 0; i < words.length; i++) {
        document.getElementById("dictionary-navigation").appendChild(as[words[i].index]);
    }

    //  Adds tag-groups:

    things = {};
    for (thing in Dictionary.lrec.groups) {
        element = document.createElement("OPTGROUP");
        element.label = thing;
        if (Dictionary.lrec.groups[thing].description) element.title = Dictionary.lrec.groups[thing].description;
        things[thing] = element;
    }
    for (thing in Dictionary.lrec.groups) {
        if (Dictionary.lrec.groups[thing].parent) {
            for (i = 0; i < things.length; i++) {
                if (things[i].label.toLowerCase() === Dictionary.lrec.groups[thing].parent.toLowerCase()) {
                    things[i].appendChild(element);
                    break;
                }
            }
        }
        else
        document.getElementById("dictionary-tags").appendChild(element);
    }

    //  Adds tags:

    for (thing in Dictionary.lrec.tags) {
        element = document.createElement("OPTION");
        element.value = thing;
        element.textContent = thing;
        if (Dictionary.lrec.tags[thing].parent) {
            for (i = 0; i < document.getElementById("dictionary-tags").children.length; i++) {
                if (document.getElementById("dictionary-tags").children.item(i).tagName.toUpperCase() === "OPTGROUP" && document.getElementById("dictionary-tags").children.item(i).label.toLowerCase() === Dictionary.lrec.tags[thing].parent.toLowerCase()) {
                    document.getElementById("dictionary-tags").children.item(i).appendChild(element);
                    break;
                }
            }
        }
        else document.getElementById("dictionary-tags").appendChild(element);
    }

    //  Displays search and tags:

    if (words.length) {
        document.getElementById("dictionary-search").removeAttribute("hidden");
        document.getElementById("dictionary-tags").removeAttribute("hidden");
    }

    //  Add input handlers:

    document.getElementById("dictionary-search").addEventListener("input", Dictionary.handleInputs, false);
    document.getElementById("dictionary-tags").addEventListener("change", Dictionary.handleInputs, false);

}

Dictionary.splash = function() {
    if (!Dictionary.lrec || !(Dictionary.lrec instanceof LREC)) return;
    if (Dictionary.lrec.splashes.length) document.getElementById("dictionary-splash").textContent = Dictionary.lrec.splashes[Math.floor(Math.random() * Dictionary.lrec.splashes.length)];
    else document.getElementById("dictionary-splash").textContent = "";
}

Query.get = function(property) {
    var i;
    var j;
    var q = decodeURIComponent(window.location.search);
    if (!q) q = "?";
    i = q.indexOf("?" + property + "=");
    if (i === -1) i = q.indexOf("&" + property + "=");
    if (i === -1) return undefined;
    i += property.length + 2;
    j = q.indexOf("&", i);
    if (j === -1) return q.substring(i);
    else return q.substring(i, j);
}

Query.handle = function() {
    var d = Query.get("lrec");
    if (d && LRECs[d]) Dictionary.id = d;
    else Dictionary.id = "";
    Dictionary.lrec = new LREC(LRECs[Dictionary.id].location);
}

window.addEventListener("load", Query.handle, false);
document.addEventListener("LREC_Loaded", Dictionary.init, false);
<|endoftext|>


<commit_before><commit_msg><commit_after><|endoftext|>


<commit_before>import * as types from "../actions/types";
// import { gatherTips } from "../util/treeHelpers";
import { processNodes, calcLayouts } from "../util/processNodes";
import d3 from "d3";
import { calcBranchThickness, calcTipCounts, calcVisibility } from "../util/treeHelpers";

/* A version increase (i.e. props.version !== nextProps.version) necessarily implies
that the tree is loaded as they are set on the same action */

const getDefaultState = function () {
  return {
    loaded: false,
    nodes: null,
    visibility: null,
    visibilityVersion: 0,
    nodeColors: null,
    nodeColorsVersion: 0,
    tipRadii: null,
    tipRadiiVersion: 0,
    branchThickness: null,
    branchThicknessVersion: 0,
    version: 0
  };
};

/* TODO hopefully datasetGuid can be removed and tree.loaded used instead.
Leaving this here this until map-animation-v1 is merged (it's only used in map) */

const Tree = (state = getDefaultState(), action) => {
  switch (action.type) {
  case types.NEW_DATASET:
    /* loaded returns to the default (false) */
    const nodes = processNodes(d3.layout.tree().size([1, 1]).nodes(action.tree));
    nodes[0].parent = nodes[0]; // make root its own parent
    calcLayouts(nodes, ["div", "num_date"]);
    return Object.assign({}, getDefaultState(), {
      inViewRootNodeIdx: 0,
      nodes: nodes
    });
  case types.DATA_VALID:
    return Object.assign({}, state, {
      loaded: true,
      version: state.version + 1,
      datasetGuid: Math.floor(Math.random() * 100000000000)
    });
  case types.UPDATE_VISIBILITY_AND_BRANCH_THICKNESS:
    return Object.assign({}, state, {
      visibility: action.visibility,
      visibilityVersion: action.visibilityVersion,
      branchThickness: action.branchThickness,
      branchThicknessVersion: action.branchThicknessVersion
    });
  case types.UPDATE_TIP_RADII:
    return Object.assign({}, state, {
      tipRadii: action.data,
      tipRadiiVersion: action.version
    });
  case types.NEW_COLORS:
    return Object.assign({}, state, {
      nodeColors: action.nodeColors,
      nodeColorsVersion: action.version
    });
  default:
    return state;
  }
};

export default Tree;
<commit_msg>remove datasetGUID from tree reducer<commit_after>import * as types from "../actions/types";
// import { gatherTips } from "../util/treeHelpers";
import { processNodes, calcLayouts } from "../util/processNodes";
import d3 from "d3";
import { calcBranchThickness, calcTipCounts, calcVisibility } from "../util/treeHelpers";

/* A version increase (i.e. props.version !== nextProps.version) necessarily implies
that the tree is loaded as they are set on the same action */

const getDefaultState = function () {
  return {
    loaded: false,
    nodes: null,
    visibility: null,
    visibilityVersion: 0,
    nodeColors: null,
    nodeColorsVersion: 0,
    tipRadii: null,
    tipRadiiVersion: 0,
    branchThickness: null,
    branchThicknessVersion: 0,
    version: 0
  };
};

const Tree = (state = getDefaultState(), action) => {
  switch (action.type) {
  case types.NEW_DATASET:
    /* loaded returns to the default (false) */
    const nodes = processNodes(d3.layout.tree().size([1, 1]).nodes(action.tree));
    nodes[0].parent = nodes[0]; // make root its own parent
    calcLayouts(nodes, ["div", "num_date"]);
    return Object.assign({}, getDefaultState(), {
      inViewRootNodeIdx: 0,
      nodes: nodes
    });
  case types.DATA_VALID:
    return Object.assign({}, state, {
      loaded: true,
      version: state.version + 1
    });
  case types.UPDATE_VISIBILITY_AND_BRANCH_THICKNESS:
    return Object.assign({}, state, {
      visibility: action.visibility,
      visibilityVersion: action.visibilityVersion,
      branchThickness: action.branchThickness,
      branchThicknessVersion: action.branchThicknessVersion
    });
  case types.UPDATE_TIP_RADII:
    return Object.assign({}, state, {
      tipRadii: action.data,
      tipRadiiVersion: action.version
    });
  case types.NEW_COLORS:
    return Object.assign({}, state, {
      nodeColors: action.nodeColors,
      nodeColorsVersion: action.version
    });
  default:
    return state;
  }
};

export default Tree;
<|endoftext|>


<commit_before>(function()
{
	angular
		.module('addGame')
		.controller('AddGameController', AddGameController);

	AddGameController.$inject = ['$scope', '$state', '$ionicScrollDelegate', 'gameTypes', 'localStorage', 'FooseyService', 'SettingsService'];

	function AddGameController($scope, $state, $ionicScrollDelegate, gameTypes, localStorage, FooseyService, SettingsService)
	{
		var selectedPlayer = undefined;
		var selectedScoreIndex = undefined;

		$scope.settings = SettingsService;
		$scope.gameTypes = gameTypes;
		$scope.reset = reset;
		$scope.useNowTime = true;
		$scope.customTime = undefined;
		$scope.customDate = undefined;
		$scope.scores = _.reverse(_.range(11));
		$scope.canCancel = false;

		$scope.addMorePlayers = addMorePlayers;
		$scope.choosePlayer = choosePlayer;
		$scope.chooseScore = chooseScore;
		$scope.gameSelect = gameSelect;
		$scope.isSelected = isSelected;
		$scope.playerSelected = playerSelected;
		$scope.playerSelect = playerSelect;
		$scope.scoreSelect = scoreSelect;
		$scope.playerName = playerName;
		$scope.submit = submit;
		$scope.undo = undo;

		// load on entering view
    $scope.$on('$ionicView.beforeEnter', function()
    {
      // send to login screen if they haven't logged in yet
      if (!SettingsService.loggedIn) SettingsService.logOut();
      reset();
    });

		// function to select game type
		function gameSelect(index, type)
		{
			//return if it's the same type
			if ($scope.type.name === type.name) return;

			$scope.type = _.clone(type);
			var newTeams = _.clone($scope.teams);
			newTeams[0].players = type.playersPerTeam === 1 ? newTeams[0].players.slice(0, 1) : newTeams[0].players.slice(0, 1).concat([null]);
			newTeams[1].players = type.playersPerTeam === 1 ? newTeams[1].players.slice(0, 1) : newTeams[1].players.slice(0, 1).concat([null]);
			$scope.teams = newTeams;
			jump();
		}

		function choosePlayer(teamIndex, playerIndex)
		{
			selectedPlayer = { teamIndex: teamIndex, playerIndex: playerIndex };
			selectedScoreIndex = undefined;
			changeState("player-select", "Select Players");
		}

		function chooseScore(teamIndex)
		{
			selectedScoreIndex = teamIndex;
			selectedPlayer = undefined;
			changeState("score-select", "Select Score");
		}

		function isSelected(teamIndex, playerIndex)
		{
			return (selectedPlayer &&
							selectedPlayer.teamIndex === teamIndex &&
							selectedPlayer.playerIndex === playerIndex) ||
						 (selectedScoreIndex === teamIndex &&
						 	playerIndex === -1);
		}

		// function to select player
		function playerSelect(player)
		{
			$scope.canCancel = true;

			team = $scope.teams[selectedPlayer.teamIndex];
			team.players[selectedPlayer.playerIndex] = player.playerID;

			jump();
		};

		// function to select score
		function scoreSelect(score)
		{
			team = $scope.teams[selectedScoreIndex];
			team.score = score;

			jump();
		};

		function jump()
		{
			for (var t = 0; t < $scope.teams.length; t++)
			{
				for (var p = 0; p < $scope.teams[t].players.length; p++)
				{
					if ($scope.teams[t].players[p] === null)
					{
						choosePlayer(t, p);
						return;
					}
				}
				if ($scope.teams[t].score === null)
				{
					chooseScore(t);
					return;
				}
			}
			selectedPlayer = undefined;
			selectedScoreIndex = undefined;
			changeState("confirm", "Confirm");
		}

		function playerSelected(player)
		{
			var selected = false;
			_.each($scope.teams, function(team)
			{
				_.each(team.players, function(playerID)
				{
					if (playerID === player.playerID) selected = true;
				})
			})
			return selected;
		}

		// add the game
		function submit()
		{
			changeState("saving", null);
			$scope.saveStatus = "saving";
			$scope.canCancel = false;

			// set up game object
			var game = {
				teams: $scope.teams
			}

			FooseyService.addGame(game).then(function successCallback(response)
			{
				$scope.response = response.data;
				$scope.saveStatus = "success";
				$scope.gameToUndo = response.data.info.gameID;
			}, function errorCallback(response)
	    {
	    	if ($scope.state === "saving")
	      	$scope.saveStatus = "failed";
	    });
		}

		// undo last game
		function undo()
		{
			FooseyService.removeGame($scope.gameToUndo).then(function successCallback(response)
			{
				$scope.saveStatus = "removed";
				$scope.gameToUndo = undefined;
				$scope.response = [];
			}, function errorCallback(response)
	    {
	    	if ($scope.state === "saving")
	      	$scope.saveStatus = "failed";
	    });
		}

		// reset the game
		function reset()
		{
			selectedPlayer = undefined;
			selectedScoreIndex = undefined;

			$scope.teams = emptyTeams(gameTypes[0]);
			$scope.gameToUndo = undefined;
			$scope.saveStatus = "";
			$scope.response = undefined;
			$scope.canCancel = false;

			$scope.useNowTime = true;
			$scope.customDate = new Date();
			$scope.customTime = $scope.customDate;

			choosePlayer(0, 0);
			getPlayers();
		}

		// get players from server
		function getPlayers()
		{
			// load from local storage
			$scope.players = localStorage.getObject('players');

			// load from server
			FooseyService.getAllPlayers(true).then(
				function (players)
	    	{
		    	// only overwrite if they haven't selected one yet
		    	if (noneSelected())
		    	{
		    		$scope.players = players;
		    		$scope.players.sort(function(a, b){
		    			return a.displayName.localeCompare(b.displayName);
		    		});
		    	}

		    	localStorage.setObject('players', $scope.players);
		  	});
		}

		// return true if none of the players have been selected yet
		function noneSelected()
		{
			for (var i = 0; i < $scope.players.length; i++)
			{
				if ($scope.players[i].selected) return false;
			}
			return true;
		}

		function playerName(id)
		{
			var name = undefined;
			_.each($scope.players, function(player)
			{
				if (player.playerID === id) name = player.displayName;
			});
			return name;
		}

		function emptyTeams(type)
		{
			$scope.type = _.clone(type);
			return [
				{
					players: type.playersPerTeam === 1 ? [null] : [null, null],
					score: null
				},
				{
					players: type.playersPerTeam === 1 ? [null] : [null, null],
					score: null
				}
			]
		}

		function changeState(state, title)
		{
			if (state) $scope.state = state;
			if (title) $scope.title = title;
			if (state !== 'player-select') $ionicScrollDelegate.scrollTop(true);
		}

		function addMorePlayers()
		{
			$state.go('app.manage-players');
		}
	}
})();<commit_msg>Hopefully fix chrome add game bug<commit_after>(function()
{
	angular
		.module('addGame')
		.controller('AddGameController', AddGameController);

	AddGameController.$inject = ['$scope', '$state', '$ionicScrollDelegate', 'gameTypes', 'localStorage', 'FooseyService', 'SettingsService'];

	function AddGameController($scope, $state, $ionicScrollDelegate, gameTypes, localStorage, FooseyService, SettingsService)
	{
		var selectedPlayer = undefined;
		var selectedScoreIndex = undefined;

		$scope.settings = SettingsService;
		$scope.gameTypes = gameTypes;
		$scope.useNowTime = true;
		$scope.customTime = undefined;
		$scope.customDate = undefined;
		$scope.scores = _.reverse(_.range(11));
		$scope.canCancel = false;

		$scope.addMorePlayers = addMorePlayers;
		$scope.choosePlayer = choosePlayer;
		$scope.chooseScore = chooseScore;
		$scope.gameSelect = gameSelect;
		$scope.isSelected = isSelected;
		$scope.playerSelected = playerSelected;
		$scope.playerSelect = playerSelect;
		$scope.scoreSelect = scoreSelect;
		$scope.playerName = playerName;
		$scope.reset = reset;
		$scope.submit = submit;
		$scope.undo = undo;

		// load on entering view
    $scope.$on('$ionicView.beforeEnter', function()
    {
      // send to login screen if they haven't logged in yet
      if (!SettingsService.loggedIn) SettingsService.logOut();
      reset();
    });

		// function to select game type
		function gameSelect(index, type)
		{
			//return if it's the same type
			if ($scope.type.name === type.name) return;

			$scope.type = _.clone(type);
			var newTeams = _.clone($scope.teams);
			newTeams[0].players = type.playersPerTeam === 1 ? newTeams[0].players.slice(0, 1) : newTeams[0].players.slice(0, 1).concat([null]);
			newTeams[1].players = type.playersPerTeam === 1 ? newTeams[1].players.slice(0, 1) : newTeams[1].players.slice(0, 1).concat([null]);
			$scope.teams = newTeams;
			jump();
		}

		function choosePlayer(teamIndex, playerIndex)
		{
			selectedPlayer = { teamIndex: teamIndex, playerIndex: playerIndex };
			selectedScoreIndex = undefined;
			changeState("player-select", "Select Players");
		}

		function chooseScore(teamIndex)
		{
			selectedScoreIndex = teamIndex;
			selectedPlayer = undefined;
			changeState("score-select", "Select Score");
		}

		function isSelected(teamIndex, playerIndex)
		{
			return (selectedPlayer &&
							selectedPlayer.teamIndex === teamIndex &&
							selectedPlayer.playerIndex === playerIndex) ||
						 (selectedScoreIndex === teamIndex &&
						 	playerIndex === -1);
		}

		// function to select player
		function playerSelect(player)
		{
			if (playerSelected(player)) return;
			$scope.canCancel = true;

			team = $scope.teams[selectedPlayer.teamIndex];
			team.players[selectedPlayer.playerIndex] = player.playerID;

			jump();
		};

		// function to select score
		function scoreSelect(score)
		{
			team = $scope.teams[selectedScoreIndex];
			team.score = score;

			jump();
		};

		function jump()
		{
			for (var t = 0; t < $scope.teams.length; t++)
			{
				for (var p = 0; p < $scope.teams[t].players.length; p++)
				{
					if ($scope.teams[t].players[p] === null)
					{
						choosePlayer(t, p);
						return;
					}
				}
				if ($scope.teams[t].score === null)
				{
					chooseScore(t);
					return;
				}
			}
			selectedPlayer = undefined;
			selectedScoreIndex = undefined;
			changeState("confirm", "Confirm");
		}

		function playerSelected(player)
		{
			var selected = false;
			_.each($scope.teams, function(team)
			{
				_.each(team.players, function(playerID)
				{
					if (playerID === player.playerID) selected = true;
				})
			})
			return selected;
		}

		// add the game
		function submit()
		{
			changeState("saving", null);
			$scope.saveStatus = "saving";
			$scope.canCancel = false;

			// set up game object
			var game = {
				teams: $scope.teams
			}

			FooseyService.addGame(game).then(function successCallback(response)
			{
				$scope.response = response.data;
				$scope.saveStatus = "success";
				$scope.gameToUndo = response.data.info.gameID;
			}, function errorCallback(response)
	    {
	    	if ($scope.state === "saving")
	      	$scope.saveStatus = "failed";
	    });
		}

		// undo last game
		function undo()
		{
			FooseyService.removeGame($scope.gameToUndo).then(function successCallback(response)
			{
				$scope.saveStatus = "removed";
				$scope.gameToUndo = undefined;
				$scope.response = [];
			}, function errorCallback(response)
	    {
	    	if ($scope.state === "saving")
	      	$scope.saveStatus = "failed";
	    });
		}

		// reset the game
		function reset()
		{
			selectedPlayer = undefined;
			selectedScoreIndex = undefined;

			$scope.teams = emptyTeams(gameTypes[0]);
			$scope.gameToUndo = undefined;
			$scope.saveStatus = "";
			$scope.response = undefined;
			$scope.canCancel = false;

			$scope.useNowTime = true;
			$scope.customDate = new Date();
			$scope.customTime = $scope.customDate;

			choosePlayer(0, 0);
			getPlayers();
		}

		// get players from server
		function getPlayers()
		{
			// load from local storage
			$scope.players = localStorage.getObject('players');

			// load from server
			FooseyService.getAllPlayers(true).then(
				function (players)
	    	{
		    	// only overwrite if they haven't selected one yet
		    	if (noneSelected())
		    	{
		    		$scope.players = players;
		    		$scope.players.sort(function(a, b){
		    			return a.displayName.localeCompare(b.displayName);
		    		});
		    	}

		    	localStorage.setObject('players', $scope.players);
		  	});
		}

		// return true if none of the players have been selected yet
		function noneSelected()
		{
			for (var i = 0; i < $scope.players.length; i++)
			{
				if ($scope.players[i].selected) return false;
			}
			return true;
		}

		function playerName(id)
		{
			var name = undefined;
			_.each($scope.players, function(player)
			{
				if (player.playerID === id) name = player.displayName;
			});
			return name;
		}

		function emptyTeams(type)
		{
			$scope.type = _.clone(type);
			return [
				{
					players: type.playersPerTeam === 1 ? [null] : [null, null],
					score: null
				},
				{
					players: type.playersPerTeam === 1 ? [null] : [null, null],
					score: null
				}
			]
		}

		function changeState(state, title)
		{
			if (state) $scope.state = state;
			if (title) $scope.title = title;
			if (state !== 'player-select') $ionicScrollDelegate.scrollTop(true);
		}

		function addMorePlayers()
		{
			$state.go('app.manage-players');
		}
	}
})();<|endoftext|>


<commit_before>sagecell.makeSagecell( {

	inputLocation: '.sagemathcell',
	autoeval: true,
	hide: ['editor','evalButton','permalink']

} );

function resetIframes() {

    if ( /(iPad|iPhone|iPod)/g.test( navigator.userAgent ) ) {

        var scenes = document.getElementsByTagName( 'iframe' );

        for ( var i=0 ; i < scenes.length ; i++ ) {

//            scenes[i].style.width = getComputedStyle( scenes[i] ).width;
//            scenes[i].style.height = getComputedStyle( scenes[i] ).height;
    	    scenes[i].srcdoc = scenes[i].srcdoc;
//            scenes[i].setAttribute( 'scrolling', 'no' );

        }
    }

}

function accept() {

	var buttons = document.getElementsByClassName( 'ui-dialog-buttonset' );
	if ( buttons.length > 0 ) buttons[0].firstChild.click();

}
<commit_msg>Update setup<commit_after>sagecell.makeSagecell( {

	inputLocation: '.sagemathcell',
	autoeval: true,
	hide: ['editor','evalButton','permalink']

} );

function resetIframes() {

    if ( /(iPad|iPhone|iPod)/g.test( navigator.userAgent ) ) {

        var scenes = document.getElementsByTagName( 'iframe' );

        for ( var i=0 ; i < scenes.length ; i++ ) {

    	    scenes[i].srcdoc = scenes[i].srcdoc;

        }
    }

}

function accept() {

	var buttons = document.getElementsByClassName( 'ui-dialog-buttonset' );
	if ( buttons.length > 0 ) buttons[0].firstChild.click();

}
<|endoftext|>


<commit_before>import React, { Component } from "react";
import { connect } from "react-redux";
import { BrowserRouter, Redirect, Route } from "react-router-dom";

import { Layout, Menu } from "antd";
const { Header, Content, Footer } = Layout;

import { callAPI } from "../../actions/api.actions";

import FileManager from "../FileManager";
import IdiotBoxHeader from "./IdiotBoxHeader";
import MoviesList from "../Movies/MoviesList";
import NewEpisodes from "../NewEpisodes";
import Settings from "../Settings/Settings";
import ShowInfo from "../Shows/ShowInfo";
import ShowsList from "../Shows/ShowsList";

const IdiotBoxLayout = props => {
    return (
        <BrowserRouter>
            <Layout className="layout">
                <IdiotBoxHeader />
                <Content style={{ padding: "0 50px" }}>

                        <Redirect path="/" exact to="/newepisodes" />
                        <Route
                            path="/newepisodes"
                            render={routeParams => (
                                <NewEpisodes
                                    {...routeParams}
                                    callAPI={props.callAPI}
                                    settings={props.settings}
                                />
                            )}
                        />
                        <Route
                            path="/filemanager/:setting_key?/:subpath?"
                            render={routeParams => (
                                <FileManager
                                    {...routeParams}
                                    callAPI={props.callAPI}
                                    settings={props.settings}
                                />
                            )}
                        />
                        <Route
                            path="/movies"
                            render={routeParams => (
                                <MoviesList
                                    {...routeParams}
                                    settings={props.settings}
                                    callAPI={props.callAPI}
                                />
                            )}
                        />
                        <Route path="/settings" component={Settings} />
                        <Route path="/shows" component={ShowsList} />
                        <Route
                            path={`/show/:slug/:season_number?`}
                            render={routeParams => (
                                <ShowInfo
                                    {...routeParams}
                                    settings={props.settings}
                                    callAPI={props.callAPI}
                                />
                            )}
                        />

                </Content>

                    Idiot Box created by Destin Moulton

            </Layout>
        </BrowserRouter>
    );
};

const mapStateToProps = state => {
    const { settings } = state;
    return {
        settings: settings.settings
    };
};

const mapDispatchToProps = dispatch => {
    return {
        callAPI: (endpoint, params, callback, shouldDispatch) =>
            dispatch(callAPI(endpoint, params, callback, shouldDispatch))
    };
};

export default connect(mapStateToProps, mapDispatchToProps)(IdiotBoxLayout);
<commit_msg>Modified redirect back to route.<commit_after>import React, { Component } from "react";
import { connect } from "react-redux";
import { BrowserRouter, Redirect, Route } from "react-router-dom";

import { Layout, Menu } from "antd";
const { Header, Content, Footer } = Layout;

import { callAPI } from "../../actions/api.actions";

import FileManager from "../FileManager";
import IdiotBoxHeader from "./IdiotBoxHeader";
import MoviesList from "../Movies/MoviesList";
import NewEpisodes from "../NewEpisodes";
import Settings from "../Settings/Settings";
import ShowInfo from "../Shows/ShowInfo";
import ShowsList from "../Shows/ShowsList";

const IdiotBoxLayout = props => {
    return (
        <BrowserRouter>
            <Layout className="layout">
                <IdiotBoxHeader />
                <Content style={{ padding: "0 50px" }}>

                        <Route
                            path="/"
                            exact
                            render={routeParams => (
                                <NewEpisodes
                                    {...routeParams}
                                    callAPI={props.callAPI}
                                    settings={props.settings}
                                />
                            )}
                        />
                        <Route
                            path="/newepisodes"
                            render={routeParams => (
                                <NewEpisodes
                                    {...routeParams}
                                    callAPI={props.callAPI}
                                    settings={props.settings}
                                />
                            )}
                        />
                        <Route
                            path="/filemanager/:setting_key?/:subpath?"
                            render={routeParams => (
                                <FileManager
                                    {...routeParams}
                                    callAPI={props.callAPI}
                                    settings={props.settings}
                                />
                            )}
                        />
                        <Route
                            path="/movies"
                            render={routeParams => (
                                <MoviesList
                                    {...routeParams}
                                    settings={props.settings}
                                    callAPI={props.callAPI}
                                />
                            )}
                        />
                        <Route path="/settings" component={Settings} />
                        <Route path="/shows" component={ShowsList} />
                        <Route
                            path={`/show/:slug/:season_number?`}
                            render={routeParams => (
                                <ShowInfo
                                    {...routeParams}
                                    settings={props.settings}
                                    callAPI={props.callAPI}
                                />
                            )}
                        />

                </Content>

                    Idiot Box created by Destin Moulton

            </Layout>
        </BrowserRouter>
    );
};

const mapStateToProps = state => {
    const { settings } = state;
    return {
        settings: settings.settings
    };
};

const mapDispatchToProps = dispatch => {
    return {
        callAPI: (endpoint, params, callback, shouldDispatch) =>
            dispatch(callAPI(endpoint, params, callback, shouldDispatch))
    };
};

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