<commit_before>/**
 * This file contains the unit tests for all exported functions in the
 * accompanying `websocket.js` file.
 */

import autobahn from 'autobahn';
import * as communication from './index';
import * as websocket from './websocket';

describe('handleWebsocketAuthorisationChallenge', () => {
  /* Let it be known that this is a extremely hacky way to test internal code.
   *
   * The authorisation mechanism of authobahn might be triggered and challenge
   * the given token. We do have a internal function as this is of no use
   * anywhere else in the SDK or beyond.
   *
   * The `onchallenge` handler provided in the `autobahn.Connection`
   * constructor options parameter can be triggered through the instance of the
   * connection using its "internal/private" _options property.
   */
  let onchallengeOption;

  beforeEach((done) => {
    spyOn(autobahn.Connection.prototype, 'close');
    const connectionOpenSpy = spyOn(autobahn.Connection.prototype, 'open');
    // We cannot use arrow functions because of this scope.
    connectionOpenSpy.and.callFake(function () { // eslint-disable-line func-names
      // Get a reference to the thing we actually want to test.
      // eslint-disable-next-line no-underscore-dangle
      onchallengeOption = this._options.onchallenge;
      this.onopen();
    });
    websocket.openWebsocketConnection()
      .then(done);
  });

  afterEach((done) => {
    // Make sure there is no existing connection after each test.
    websocket.closeWebsocketConnection()
      .then(done);
  });

  it('should return the `authorizationToken` when the ticket method is used', () => {
    communication.updateSettings({ authorizationToken: 'much_secure' });
    const session = {};
    expect(onchallengeOption(session, 'ticket')).toEqual('much_secure');
  });

  it('should throw a Error when a unsupported method is used', () => {
    const session = {};
    const errorMessage = 'The websocket server tried to use the unknown '
                         + 'authentication challenge: "unsupported method"';
    expect(() => onchallengeOption(session, 'unsupported method')).toThrowError(Error, errorMessage);
  });
});

describe('openWebsocketConnection', () => {
  afterEach((done) => {
    // Make sure there is no existing connection after each test.
    websocket.closeWebsocketConnection()
      .then(done);
  });

  it('should open a connection if there isn\'t one already', (done) => {
    const connectionOpenSpy = spyOn(autobahn.Connection.prototype, 'open');
    // We cannot use arrow functions because of this scope.
    connectionOpenSpy.and.callFake(function () { // eslint-disable-line func-names
      this.onopen();
    });

    websocket.openWebsocketConnection()
      .then((result) => {
        expect(result).toEqual('Successfully established a websocket connection.');
        done();
      }, fail);
  });

  it('should reject if the connection could not be established', (done) => {
    websocket.openWebsocketConnection()
      .then(fail, (result) => {
        expect(result).toEqual('The connection is erroneous; check if all '
                               + 'required settings have been injected using '
                               + 'the `updateSettings()` function. If the '
                               + 'problem persists please post a issue on our '
                               + 'GitHub repository.');
        // There shouldn't be a reference to the erroneos connection. We can
        // validate this by trying to "close" the connection. The
        // `closeWebsocketConnection` should not pass its falsy check and thus
        // resolve in 'There is no websocket connection to close.'.
        return websocket.closeWebsocketConnection();
      })
      .then((result) => {
        expect(result).toEqual('There is no websocket connection to close.');
        done();
      }, fail);
  });
});

describe('closeWebsocketConnection', () => {
  let connectionOpenSpy;
  let connectionCloseSpy;

  beforeEach(() => {
    connectionCloseSpy = spyOn(autobahn.Connection.prototype, 'close');
    connectionOpenSpy = spyOn(autobahn.Connection.prototype, 'open');
    // We cannot use arrow functions because of this scope.
    connectionOpenSpy.and.callFake(function () { // eslint-disable-line func-names
      this.onopen();
    });
  });

  afterEach((done) => {
    // Make sure there is no existing connection after each test.
    websocket.closeWebsocketConnection()
      .then(done);
  });

  it('should resolve if there is no open connection', (done) => {
    websocket.closeWebsocketConnection()
      .then((result) => {
        expect(result).toEqual('There is no websocket connection to close.');
        done();
      }, fail);
  });

  it('should successfully close a open connection', (done) => {
    websocket.openWebsocketConnection()
      // Now we've opened the connection; close it again.
      .then(() => websocket.closeWebsocketConnection(), fail)
      .then((result) => {
        expect(result).toEqual('The websocket connection has been closed successfully.');
        done();
      }, fail);
  });

  it('should resolve when the connection was already closed', (done) => {
    connectionCloseSpy.and.callFake(() => {
      throw new Error('connection already closed');
    });

    websocket.openWebsocketConnection()
      // Now we've opened the connection; close it again.
      .then(() => websocket.closeWebsocketConnection(), fail)
      .then((result) => {
        expect(result).toEqual('The websocket connection has already been closed.');
        done();
      }, fail);
  });

  it('should also remove the reference to the connection once it is closed', (done) => {
    websocket.openWebsocketConnection()
      // Now we've opened the connection; close it again.
      .then(() => websocket.closeWebsocketConnection(), fail)
      .then(() => websocket.closeWebsocketConnection(), fail)
      .then((result) => {
        // The internal reference is set to `null` when the connection is
        // closed. The `closeWebsocketConnection` function would therefore not
        // pass its falsy check. The result should therefore be the same as:
        // `it('should resolve if there is no open connection', ...);`
        expect(result).toEqual('There is no websocket connection to close.');
        done();
      }, fail);
  });
});

describe('makeWebsocketCall', () => {
  let connectionOpenSpy;
  let connectionSessionStub;

  beforeEach(() => {
    spyOn(autobahn.Connection.prototype, 'close');
    connectionOpenSpy = spyOn(autobahn.Connection.prototype, 'open');
    connectionSessionStub = jasmine.createSpyObj('Session', ['call']);
    connectionSessionStub.call.and.callFake(() => {
      // eslint-disable-next-line new-cap
      const defer = new autobahn.when.defer();
      defer.resolve();
      return defer.promise;
    });

    // We cannot use arrow functions because of this scope.
    connectionOpenSpy.and.callFake(function () { // eslint-disable-line func-names
      // This property is returned through the session "property" of a
      // connection instance. Sadly only the get is defined with the
      // `Object.defineProperty` which forces us to mock the internals.
      this._session = connectionSessionStub; // eslint-disable-line no-underscore-dangle
      this.onopen();
    });
  });

  afterEach((done) => {
    // Make sure there is no existing connection after each test.
    websocket.closeWebsocketConnection()
      .then(done);
  });

  it('should prefix the `rpc` parameter and pass the rest into the websocket session call', (done) => {
    websocket.openWebsocketConnection()
      .then(() => websocket.makeWebsocketCall(
        'do.a.rpc',
        {
          args: ['accept', 'these'],
          kwargs: { kwarg: 'value' },
          options: { option: 'value' },
        },
      ))
      .then(() => {
        expect(connectionSessionStub.call).toHaveBeenCalledWith(
          'nl.itslanguage.do.a.rpc',
          ['accept', 'these'],
          { kwarg: 'value' },
          { option: 'value' },
        );
        done();
      }, fail);
  });

  it('should open a websocket connection if there isn\'t one already', (done) => {
    websocket.makeWebsocketCall('do.a.rpc', {
      args: ['accept', 'these'],
      kwargs: { kwarg: 'value' },
      options: { option: 'value' },
    }).then(() => {
      expect(connectionOpenSpy).toHaveBeenCalled();
      expect(connectionSessionStub.call).toHaveBeenCalledWith(
        'nl.itslanguage.do.a.rpc',
        ['accept', 'these'],
        { kwarg: 'value' },
        { option: 'value' },
      );
      done();
    }, fail);
  });
});
<commit_msg>test(api): add missing websocket tests<commit_after>/**
 * This file contains the unit tests for all exported functions in the
 * accompanying `websocket.js` file.
 */

import autobahn from 'autobahn';
import * as communication from './index';
import * as websocket from './websocket';

describe('handleWebsocketAuthorisationChallenge', () => {
  /* Let it be known that this is a extremely hacky way to test internal code.
   *
   * The authorisation mechanism of authobahn might be triggered and challenge
   * the given token. We do have a internal function as this is of no use
   * anywhere else in the SDK or beyond.
   *
   * The `onchallenge` handler provided in the `autobahn.Connection`
   * constructor options parameter can be triggered through the instance of the
   * connection using its "internal/private" _options property.
   */
  let onchallengeOption;

  beforeEach((done) => {
    spyOn(autobahn.Connection.prototype, 'close');
    const connectionOpenSpy = spyOn(autobahn.Connection.prototype, 'open');
    // We cannot use arrow functions because of this scope.
    connectionOpenSpy.and.callFake(function () { // eslint-disable-line func-names
      // Get a reference to the thing we actually want to test.
      // eslint-disable-next-line no-underscore-dangle
      onchallengeOption = this._options.onchallenge;
      this.onopen();
    });
    websocket.openWebsocketConnection()
      .then(done);
  });

  afterEach((done) => {
    // Make sure there is no existing connection after each test.
    websocket.closeWebsocketConnection()
      .then(done);
  });

  it('should return the `authorizationToken` when the ticket method is used', () => {
    communication.updateSettings({ authorizationToken: 'much_secure' });
    const session = {};
    expect(onchallengeOption(session, 'ticket')).toEqual('much_secure');
  });

  it('should throw a Error when a unsupported method is used', () => {
    const session = {};
    const errorMessage = 'The websocket server tried to use the unknown '
                         + 'authentication challenge: "unsupported method"';
    expect(() => onchallengeOption(session, 'unsupported method')).toThrowError(Error, errorMessage);
  });
});

describe('openWebsocketConnection', () => {
  afterEach((done) => {
    // Make sure there is no existing connection after each test.
    websocket.closeWebsocketConnection()
      .then(done);
  });

  it('should open a connection if there isn\'t one already', (done) => {
    const connectionOpenSpy = spyOn(autobahn.Connection.prototype, 'open');
    // We cannot use arrow functions because of this scope.
    connectionOpenSpy.and.callFake(function () { // eslint-disable-line func-names
      this.onopen();
    });

    websocket.openWebsocketConnection()
      .then((result) => {
        expect(result).toEqual('Successfully established a websocket connection.');
        done();
      }, fail);
  });

  it('should reject if the connection could not be established', (done) => {
    websocket.openWebsocketConnection()
      .then(fail, (result) => {
        expect(result).toEqual('The connection is erroneous; check if all '
                               + 'required settings have been injected using '
                               + 'the `updateSettings()` function. If the '
                               + 'problem persists please post a issue on our '
                               + 'GitHub repository.');
        // There shouldn't be a reference to the erroneos connection. We can
        // validate this by trying to "close" the connection. The
        // `closeWebsocketConnection` should not pass its falsy check and thus
        // resolve in 'There is no websocket connection to close.'.
        return websocket.closeWebsocketConnection();
      })
      .then((result) => {
        expect(result).toEqual('There is no websocket connection to close.');
        done();
      }, fail);
  });
});

describe('closeWebsocketConnection', () => {
  let connectionOpenSpy;
  let connectionCloseSpy;

  beforeEach(() => {
    connectionCloseSpy = spyOn(autobahn.Connection.prototype, 'close');
    connectionOpenSpy = spyOn(autobahn.Connection.prototype, 'open');
    // We cannot use arrow functions because of this scope.
    connectionOpenSpy.and.callFake(function () { // eslint-disable-line func-names
      this.onopen();
    });
  });

  afterEach((done) => {
    // Make sure there is no existing connection after each test.
    websocket.closeWebsocketConnection()
      .then(done);
  });

  it('should resolve if there is no open connection', (done) => {
    websocket.closeWebsocketConnection()
      .then((result) => {
        expect(result).toEqual('There is no websocket connection to close.');
        done();
      }, fail);
  });

  it('should successfully close a open connection', (done) => {
    websocket.openWebsocketConnection()
      // Now we've opened the connection; close it again.
      .then(() => websocket.closeWebsocketConnection(), fail)
      .then((result) => {
        expect(result).toEqual('The websocket connection has been closed successfully.');
        done();
      }, fail);
  });

  it('should resolve when the connection was already closed', (done) => {
    connectionCloseSpy.and.callFake(() => {
      throw new Error('connection already closed');
    });

    websocket.openWebsocketConnection()
      // Now we've opened the connection; close it again.
      .then(() => websocket.closeWebsocketConnection(), fail)
      .then((result) => {
        expect(result).toEqual('The websocket connection has already been closed.');
        done();
      }, fail);
  });

  it('should also remove the reference to the connection once it is closed', (done) => {
    websocket.openWebsocketConnection()
      // Now we've opened the connection; close it again.
      .then(() => websocket.closeWebsocketConnection(), fail)
      .then(() => websocket.closeWebsocketConnection(), fail)
      .then((result) => {
        // The internal reference is set to `null` when the connection is
        // closed. The `closeWebsocketConnection` function would therefore not
        // pass its falsy check. The result should therefore be the same as:
        // `it('should resolve if there is no open connection', ...);`
        expect(result).toEqual('There is no websocket connection to close.');
        done();
      }, fail);
  });
});

describe('makeWebsocketCall', () => {
  let connectionOpenSpy;
  let connectionSessionStub;

  beforeEach(() => {
    spyOn(autobahn.Connection.prototype, 'close');
    connectionOpenSpy = spyOn(autobahn.Connection.prototype, 'open');
    connectionSessionStub = jasmine.createSpyObj('Session', ['call']);
    connectionSessionStub.call.and.callFake(() => {
      // eslint-disable-next-line new-cap
      const defer = new autobahn.when.defer();
      defer.resolve();
      return defer.promise;
    });

    // We cannot use arrow functions because of this scope.
    connectionOpenSpy.and.callFake(function () { // eslint-disable-line func-names
      // This property is returned through the session "property" of a
      // connection instance. Sadly only the get is defined with the
      // `Object.defineProperty` which forces us to mock the internals.
      this._session = connectionSessionStub; // eslint-disable-line no-underscore-dangle
      this.onopen();
    });
  });

  afterEach((done) => {
    // Make sure there is no existing connection after each test.
    websocket.closeWebsocketConnection()
      .then(done);
  });

  it('should prefix the `rpc` parameter and pass the rest into the websocket session call', (done) => {
    websocket.openWebsocketConnection()
      .then(() => websocket.makeWebsocketCall(
        'do.a.rpc',
        {
          args: ['accept', 'these'],
          kwargs: { kwarg: 'value' },
          options: { option: 'value' },
        },
      ))
      .then(() => {
        expect(connectionSessionStub.call).toHaveBeenCalledWith(
          'nl.itslanguage.do.a.rpc',
          ['accept', 'these'],
          { kwarg: 'value' },
          { option: 'value' },
        );
        done();
      }, fail);
  });

  it('should open a websocket connection if there isn\'t one already', (done) => {
    websocket.makeWebsocketCall('do.a.rpc', {
      args: ['accept', 'these'],
      kwargs: { kwarg: 'value' },
      options: { option: 'value' },
    }).then(() => {
      expect(connectionOpenSpy).toHaveBeenCalled();
      expect(connectionSessionStub.call).toHaveBeenCalledWith(
        'nl.itslanguage.do.a.rpc',
        ['accept', 'these'],
        { kwarg: 'value' },
        { option: 'value' },
      );
      done();
    }, fail);
  });

  it('should set receive_progress to true if progress callback is passed', (done) => {
    const progressCb = jasmine.createSpy('progressCb');

    websocket.makeWebsocketCall('do.a.rpc', {
      args: ['accept', 'these'],
      kwargs: { kwarg: 'value' },
      options: { option: 'value' },
      progressCb,
    }).then(() => {
      expect(connectionOpenSpy).toHaveBeenCalled();
      expect(connectionSessionStub.call).toHaveBeenCalledWith(
        'nl.itslanguage.do.a.rpc',
        ['accept', 'these'],
        { kwarg: 'value' },
        {
          option: 'value',
          receive_progress: true,
        },
      );
      done();
    }, fail);
  });

  it('should catch an error if Session.call fails', (done) => {
    const args = {
      args: ['accept', 'these'],
      kwargs: { kwarg: 'value' },
      options: { option: 'value' },
    };

    connectionSessionStub.call.and.callFake(() => {
      // eslint-disable-next-line new-cap
      const defer = new autobahn.when.defer();
      defer.reject({
        error: 'wrong',
        ...args,
      });
      return defer.promise;
    });

    websocket.makeWebsocketCall('do.a.rpc', args)
      .then(() => done.fail)
      .catch((error) => {
        expect(error.message).toBe('wrong');
        expect(error.data.options).toBeUndefined();
        expect(error.data.args).toEqual(args.args);
        expect(error.data.kwargs).toEqual(args.kwargs);
        done();
      });
  });

  it('should fail when no options are passed', (done) => {
    connectionSessionStub.call.and.callFake(() => {
      // eslint-disable-next-line new-cap
      const defer = new autobahn.when.defer();
      defer.reject({
        error: 'wrong',
        args: [],
        kwargs: {},
        options: {},
      });
      return defer.promise;
    });

    websocket.makeWebsocketCall('do.a.rpc')
      .then(() => done.fail)
      .catch((error) => {
        expect(error.message).toBe('wrong');
        done();
      });
  });
});
<|endoftext|>


<commit_before>/**
 * @class  	Image
 * @author  Flavio De Stefano <flavio.destefano@caffeinalab.com>
 * Image manipulation module
 *
 */

/**
 * @type {Object}
 */
var config = _.extend({}, Alloy.CFG.image);
exports.config = config;

/**
 * Process the image and output in memory or filesystem
 *
 * `blob` is required to process the image, or an error is thrown
 *
 * ## Resizing options
 *
 * If `size` is passed, the image will be thumbnailized in a square.
 *
 * If `width` is passed the image will be resized with the specified width maintaining the ratio.
 *
 * If `height` is passed the image will be resized with the specified height maintaining the ratio.
 *
 * If `width` and `height` are both passed, the image will be resized
 * stretching the image with the specified width and height.
 *
 * ## Optional parameters
 *
 * `quality`: to degrade the image
 *
 * ## Output options
 *
 * `filename`: output the blob in the filesystem and release memory blob
 *
 * `callback`: call the function passing the output blob or output file if the keyword `filename` is specified
 * A null object is passed in case of errors
 *
 * @param  {Object} opt The options, see the description above.
 */
function process(opt) {
	if (!opt.blob) {
		Ti.API.error("Image: Set a blob please");
		opt.callback();
		return;
	}

	var density = opt.retina ? Alloy.Globals.SCREEN_DENSITY : 1;
	var R = null;

	if (opt.size) {
		R = opt.blob.imageAsThumbnail(opt.size*density);
	} else if (opt.width || opt.height) {
		opt.width = opt.width || opt.height*(opt.blob.width/opt.blob.height);
		opt.height = opt.height || opt.width*(opt.blob.height/opt.blob.width);
		R = opt.blob.imageAsResized(opt.width*density, opt.height*density);
	} else {
		R = opt.blob;
	}

	if (R) {

		if (opt.filename) {

			var file = Ti.Filesystem.getFile(require('util').getAppDataDirectory(), opt.filename);
			var result = file.write(R);
			R = null; // nullable ALL!

			if (result) {
				opt.callback(file);
			} else {
				Ti.API.error("Image: error writing file");
			 	opt.callback();
			}

		} else {
			opt.callback(R);
		}

	} else {
		opt.callback();
	}
}
exports.process = process;<commit_msg>Image callback std<commit_after>/**
 * @class  	Image
 * @author  Flavio De Stefano <flavio.destefano@caffeinalab.com>
 * Image manipulation module
 *
 */

/**
 * @type {Object}
 */
var config = _.extend({}, Alloy.CFG.image);
exports.config = config;

/**
 * Process the image and output in memory or filesystem
 *
 * `blob` is required to process the image, or an error is thrown
 *
 * ## Resizing options
 *
 * If `size` is passed, the image will be thumbnailized in a square.
 *
 * If `width` is passed the image will be resized with the specified width maintaining the ratio.
 *
 * If `height` is passed the image will be resized with the specified height maintaining the ratio.
 *
 * If `width` and `height` are both passed, the image will be resized
 * stretching the image with the specified width and height.
 *
 * ## Optional parameters
 *
 * `quality`: to degrade the image
 *
 * ## Output options
 *
 * `filename`: output the blob in the filesystem and release memory blob
 *
 * `success`: call the function passing the output blob or output file if the keyword `filename` is specified
 *
 * `error`: call the function in case of errors
 *
 * @param  {Object} opt The options, see the description above.
 */
function process(opt) {
	if (!opt.blob) {
		Ti.API.error("Image: Set a blob please");
		if (opt.error) opt.error();
		return;
	}

	var density = opt.retina ? Alloy.Globals.SCREEN_DENSITY : 1;
	var R = null;

	if (opt.size) {
		R = opt.blob.imageAsThumbnail(opt.size*density);
	} else if (opt.width || opt.height) {
		opt.width = opt.width || opt.height*(opt.blob.width/opt.blob.height);
		opt.height = opt.height || opt.width*(opt.blob.height/opt.blob.width);
		R = opt.blob.imageAsResized(opt.width*density, opt.height*density);
	} else {
		R = opt.blob;
	}

	if (R) {

		if (opt.filename) {

			var file = Ti.Filesystem.getFile(require('util').getAppDataDirectory(), opt.filename);
			var result = file.write(R);
			R = null;

			if (result) {
				if (opt.success) opt.success(file);
			} else {
				Ti.API.error("Image: error writing file");
			 	if (opt.error) opt.error();
			}

		} else {
			if (opt.success) opt.success(R);
		}

	} else {
		if (opt.error) opt.error();
	}
}
exports.process = process;<|endoftext|>


<commit_before>var PipeStream = require('pipestream');
var util = require('../../util');

module.exports = function(req, res, next) {
	var fullUrl = req.fullUrl = util.getFullUrl(req);
	PipeStream.wrap(req);
	PipeStream.wrap(res, true);

	next();
};
<commit_msg>local.whistle.com<commit_after>var PipeStream = require('pipestream');
var url = require('url');
var https = require('https');
var http = require('http');
var util = require('../../util');
var config = util.config;

module.exports = function(req, res, next) {
	PipeStream.wrap(req);
	PipeStream.wrap(res, true);

	var clientReq, clientRes, errorEmitted;
	var reqTransform, resTransform;
	req.on('dest', function(_req) {
		clientReq = _req.on('error', onReqError);
	}).on('error', onReqError);
	res.on('src', function(_res) {
		clientRes = _res.on('error', onResError);
	}).on('error', onResError);

	function onReqError(err) {
		onError(reqTransform, err);
	}

	function onResError(err) {
		onError(resTransform, err);
	}

	function onError(obj, err) {
		if (errorEmitted) {
			return;
		}
		errorEmitted = true;
		clientReq && clientReq.abort();
		res.destroy();
		if (obj && EventEmitter.listenerCount(obj, 'error') > 0) {
			obj.emit('error', err);
		}
	}

	function request(options, response) {
		var client = options.protocol == 'https:' ? https : http;
		req.pipe(client.request(options, response || res.response));
	}

	function response(_res) {
		res.writeHead(_res.statusCode || 0, _res.headers);
		res.src(_res);
	}

	var fullUrl = req.fullUrl = util.getFullUrl(req);
	if (req.headers.host == config.localUIHost) {
		var options = url.parse(fullUrl);
		options.host = '127.0.0.1';
		options.hostname = null;
		options.port = config.uiport;
		options.headers = req.headers;
		request(options, response);
		return;
	}

	next();
};
<|endoftext|>


<commit_before>
Paloquiz.states.Highscores = function(game) {
    this.currentPage = 0;
    this.friendsScores = [];
    this.userPos = undefined;
    this.profileImagesData = [];
    this.numFriendsInPage = 0;
    this.maxPage = 0;

    this.scores = [];
    this.nameTextStyle;
    this.scoreTextStyle;
    this.positionTextStyle;
    this.nameUserTextStyle;
    this.scoreUserTextStyle;
    this.positionUserTextStyle;
    this.arrowRight;
    this.arrowLeft;
    this.backButton;
};

Paloquiz.states.Highscores.prototype = {

    PAGE_SIZE: 5,
    ENTRIES_BOX: { x: 0, y: 0, width: 0, height: 0 },
    ENTRY_BOX: { x: 0, y: 0, width: 0, height: 0 },
    POSITION_BOX: { x: 0, y: 0, width: 0, height: 0 },
    IMAGE_BOX: { x: 0, y: 0, width: 0, height: 0 },
    NAME_BOX: { x: 0, y: 0, width: 0, height: 0 },
    SCORE_BOX: { x: 0, y: 0, width: 0, height: 0 },
    IMAGE_SIZE: 0,

    init: function() {
        // Compute box sizes
        this.ENTRIES_BOX.x = this.game.width * .1;
        this.ENTRIES_BOX.y = this.game.height * .1;
        this.ENTRIES_BOX.width = this.game.width * .8;
        this.ENTRIES_BOX.height = this.game.height * .8;

        this.ENTRY_BOX.x = this.ENTRIES_BOX.x;
        this.ENTRY_BOX.y = this.ENTRIES_BOX.y;
        this.ENTRY_BOX.width = this.ENTRIES_BOX.width;
        this.ENTRY_BOX.height = this.ENTRIES_BOX.height / this.PAGE_SIZE;

        this.POSITION_BOX.x = this.ENTRY_BOX.x + this.ENTRY_BOX.width * .0;
        this.POSITION_BOX.y = this.ENTRY_BOX.y;
        this.POSITION_BOX.width = this.ENTRIES_BOX.width * .1;
        this.POSITION_BOX.height = this.ENTRY_BOX.height;

        this.IMAGE_BOX.x = this.ENTRY_BOX.x + this.ENTRY_BOX.width * .10;
        this.IMAGE_BOX.y = this.ENTRY_BOX.y;
        this.IMAGE_BOX.width = this.ENTRIES_BOX.width * .25;
        this.IMAGE_BOX.height = this.ENTRY_BOX.height;

        this.NAME_BOX.x = this.ENTRY_BOX.x + this.ENTRY_BOX.width * .35;
        this.NAME_BOX.y = this.ENTRY_BOX.y;
        this.NAME_BOX.width = this.ENTRIES_BOX.width * .4;
        this.NAME_BOX.height = this.ENTRY_BOX.height;

        this.SCORE_BOX.x = this.ENTRY_BOX.x + this.ENTRY_BOX.width * .78;
        this.SCORE_BOX.y = this.ENTRY_BOX.y;
        this.SCORE_BOX.width = this.ENTRIES_BOX.width * .22;
        this.SCORE_BOX.height = this.ENTRY_BOX.height;

        this.IMAGE_SIZE = .7 * Math.min(
            this.ENTRY_BOX.width * .25,
            this.ENTRY_BOX.height);

        // Font styles
        this.createFontStyles();
    },

    preload: function() {
        // Enable cross-origin image loading
        this.load.crossOrigin = 'anonymous';

        this.load.image('noface', 'assets/noface.png');
        this.load.image('arrow', 'assets/arrow.png');
        this.load.image('back', 'assets/back.png');
    },

    create: function() {
        // Set up background
        var background = this.add.image(this.game.world.centerX, this.game.world.centerY, 'background');
        background.anchor.setTo(0.5, 0.5);
        background.width = this.game.width;
        background.height = this.game.height;

        // Create game objects
        this.createHighscoreEntries();
        this.createUI();

        // Handler for loaded profile pictures
        this.load.onLoadComplete.add(this.loadComplete, this);

        // Exit if not logged in
        if (!fbIsLoggedIn()) {
            this.state.start('Main');
            return;
        }
        fbGetFriendsScores(function(friendsScores, userPos) {
            this.friendsScores = friendsScores;
            this.userPos = userPos;
            this.maxPage = Math.floor(this.friendsScores.length / this.PAGE_SIZE);
            this.loadScoresPage();
        }, this);
    },

    shutdown: function() {
        // Remove handlers
        this.load.onLoadComplete.remove(this.loadComplete, this);
    },

    loadComplete: function() {
        for (var i = 0; i < this.numFriendsInPage; i++) {
            if (!this.profileImagesData[i].isSilhouette) {
                this.scores[i].img.loadTexture(i);
            }
            this.scores[i].img.width = this.IMAGE_SIZE;
            this.scores[i].img.height = this.IMAGE_SIZE;
            this.scores[i].img.anchor.setTo(.5, .5);
            this.scores[i].img.visible = true;
        }
    },

    loadScoresPage: function() {
        // Hide all entries
        this.scores.forEach(function(s) {
            s.img.loadTexture('noface');
            s.img.visible = false;
            s.pos.setStyle(this.positionTextStyle);
            s.pos.visible = false;
            s.name.setStyle(this.nameTextStyle);
            s.name.visible = false;
            s.score.setStyle(this.scoreTextStyle);
            s.score.visible = false;
        }, this);

        // Make sure page is in range
        if (this.currentPage < 0) {
            this.currentPage = 0;
        }
        if (this.currentPage > this.maxPage) {
            this.currentPage = this.maxPage;
        }

        // Hide arrows as needed
        this.arrowRight.visible = this.currentPage < this.maxPage;
        this.arrowLeft.visible = this.currentPage > 0;

        // Count friends in page
        var iFriendStart = this.PAGE_SIZE * this.currentPage;
        var iFriendEnd = Math.min(
            this.PAGE_SIZE * (this.currentPage + 1),
            this.friendsScores.length);
        this.numFriendsInPage = iFriendEnd - iFriendStart;
        this.profileImagesData = new Array(this.numFriendsInPage);

        // Function that starts the loader after every friend information is read
        var readFriends = 0;
        var friendInformationRead = function() {
            readFriends++;
            if (readFriends >= this.numFriendsInPage) {
                this.profileImagesData.forEach(function(img, i) {
                    this.load.image(i, img.url);
                }, this);
                this.load.start();
            }
        }
        friendInformationRead = friendInformationRead.bind(this);

        // Iterate through friends
        for (var iFriend = iFriendStart, iScore = 0; iFriend < iFriendEnd; iFriend++, iScore++) {
            // Copy index to use in closure
            var iFriendCpy = iFriend;
            var iScoreCpy = iScore;
            fbGetProfileDetails(this.friendsScores[iFriend].user.id, function(friend) {
                this.scores[iScoreCpy].pos.setText(iFriendCpy + '.');
                this.scores[iScoreCpy].name.setText(friend.first_name || friend.name);
                this.scores[iScoreCpy].score.setText(this.friendsScores[iFriendCpy].score);
                // Use special style for the user
                if (iFriendCpy == this.userPos) {
                    this.scores[iScoreCpy].pos.setStyle(this.positionUserTextStyle);
                    this.scores[iScoreCpy].name.setStyle(this.nameUserTextStyle);
                    this.scores[iScoreCpy].score.setStyle(this.scoreUserTextStyle);
                }
                this.scores[iScoreCpy].pos.visible = true;
                this.scores[iScoreCpy].name.visible = true;
                this.scores[iScoreCpy].score.visible = true;
                this.profileImagesData[iScoreCpy] = friend.image;
                friendInformationRead();
            }, this);
        }
    },

    createFontStyles: function () {
        var textSize = Math.floor(this.ENTRY_BOX.height / 5) + 'px';
        var nameTextSize = textSize;
        var scoreTextSize = textSize;
        this.nameTextStyle = {
            font: 'Pixel Art',
            fontSize: nameTextSize,
            align: 'left',
            fill: 'white',
            align: 'left',
            boundsAlignH: 'left',
            boundsAlignV: 'middle',
            wordWrap: true,
            wordWrapWidth: this.NAME_BOX.width
        };
        this.scoreTextStyle = {
            font: 'Pixel Art',
            fontSize: scoreTextSize,
            align: 'center',
            fill: 'white',
            align: 'center',
            boundsAlignH: 'center',
            boundsAlignV: 'middle'
        };
        this.positionTextStyle = this.nameTextStyle;
        this.nameUserTextStyle = {
            font: 'Pixel Art',
            fontSize: nameTextSize,
            align: 'left',
            fill: 'red',
            align: 'left',
            boundsAlignH: 'left',
            boundsAlignV: 'middle',
            wordWrap: true,
            wordWrapWidth: this.NAME_BOX.width
        };
        this.scoreUserTextStyle = {
            font: 'Pixel Art',
            fontSize: scoreTextSize,
            align: 'center',
            fill: 'red',
            align: 'center',
            boundsAlignH: 'center',
            boundsAlignV: 'middle'
        };
        this.positionUserTextStyle = this.nameUserTextStyle;
    },

    createHighscoreEntries: function () {
        for (var i = 0; i < this.PAGE_SIZE; i++) {
            var xOffset = 0;
            var yOffset = i * this.ENTRY_BOX.height;

            // Position
            var pos = this.add.text(0, 0, '', this.positionTextStyle);
            pos.setTextBounds(
                this.POSITION_BOX.x + xOffset,
                this.POSITION_BOX.y + yOffset,
                this.POSITION_BOX.width,
                this.POSITION_BOX.height);
            pos.visible = false;

            // Image
            var img = this.add.image(
                this.IMAGE_BOX.x + this.IMAGE_BOX.width / 2 + xOffset,
                this.IMAGE_BOX.y + this.IMAGE_BOX.height / 2 + yOffset,
                'noface');
            img.visible = false;

            // Name
            var name = this.add.text(0, 0, '', this.nameTextStyle);
            name.setTextBounds(
                this.NAME_BOX.x + xOffset,
                this.NAME_BOX.y + yOffset,
                this.NAME_BOX.width,
                this.NAME_BOX.height);
            name.visible = false;

            // Score
            var score = this.add.text(0, 0, '', this.scoreTextStyle);
            score.setTextBounds(
                this.SCORE_BOX.x + xOffset,
                this.SCORE_BOX.y + yOffset,
                this.SCORE_BOX.width,
                this.SCORE_BOX.height);
            score.visible = false;

            this.scores.push({
                pos: pos,
                img: img,
                name: name,
                score: score
            });
        }
    },

    createUI: function () {
        // Back button to go back to main state
        var backButton = this.add.button(0, 0, 'back',
            function () {
                this.state.start('Main');
            }, this, 0, 0, 0);
        var backButtonSize= .1 * Math.min(this.game.width, this.game.height);
        backButton.width = backButtonSize;
        backButton.height = backButtonSize;
        backButton.anchor.setTo(0, 0);
        backButton.x = backButton.width * .2;
        backButton.y = backButton.width * .2;

        // Arrows to navigate through pages
        this.arrowRight = this.add.button(
            this.game.width * .9, this.game.height * .9, 'arrow',
            function () {
                if (this.currentPage < this.maxPage) {
                    this.currentPage++;
                    this.loadScoresPage();
                }
            }, this, 0, 0, 0);
        this.arrowRight.anchor.setTo(1, 1);
        this.arrowRight.visible = false;

        this.arrowLeft = this.add.button(
            this.game.width * .1, this.game.height * .9, 'arrow',
            function () {
                if (this.currentPage > 0) {
                    this.currentPage--;
                    this.loadScoresPage();
                }
            }, this, 0, 0, 0);
        this.arrowLeft.scale.setTo(-1, 1);
        this.arrowLeft.anchor.setTo(1, 1);
        this.arrowLeft.visible = false;
    }

};
<commit_msg>Styling and positioning<commit_after>
Paloquiz.states.Highscores = function(game) {
    this.currentPage = 0;
    this.friendsScores = [];
    this.userPos = undefined;
    this.profileImagesData = [];
    this.numFriendsInPage = 0;
    this.maxPage = 0;

    this.scores = [];
    this.nameTextStyle;
    this.scoreTextStyle;
    this.positionTextStyle;
    this.nameUserTextStyle;
    this.scoreUserTextStyle;
    this.positionUserTextStyle;
    this.arrowRight;
    this.arrowLeft;
    this.backButton;
};

Paloquiz.states.Highscores.prototype = {

    PAGE_SIZE: 5,
    ENTRIES_BOX: { x: 0, y: 0, width: 0, height: 0 },
    ENTRY_BOX: { x: 0, y: 0, width: 0, height: 0 },
    POSITION_BOX: { x: 0, y: 0, width: 0, height: 0 },
    IMAGE_BOX: { x: 0, y: 0, width: 0, height: 0 },
    NAME_BOX: { x: 0, y: 0, width: 0, height: 0 },
    SCORE_BOX: { x: 0, y: 0, width: 0, height: 0 },
    IMAGE_SIZE: 0,

    init: function() {
        // Compute box sizes
        this.ENTRIES_BOX.x = this.game.width * .1;
        this.ENTRIES_BOX.y = this.game.height * .1;
        this.ENTRIES_BOX.width = this.game.width * .8;
        this.ENTRIES_BOX.height = this.game.height * .8;

        this.ENTRY_BOX.x = this.ENTRIES_BOX.x;
        this.ENTRY_BOX.y = this.ENTRIES_BOX.y;
        this.ENTRY_BOX.width = this.ENTRIES_BOX.width;
        this.ENTRY_BOX.height = this.ENTRIES_BOX.height / this.PAGE_SIZE;

        this.POSITION_BOX.x = this.ENTRY_BOX.x + this.ENTRY_BOX.width * .0;
        this.POSITION_BOX.y = this.ENTRY_BOX.y;
        this.POSITION_BOX.width = this.ENTRIES_BOX.width * .05;
        this.POSITION_BOX.height = this.ENTRY_BOX.height;

        this.IMAGE_BOX.x = this.ENTRY_BOX.x + this.ENTRY_BOX.width * .05;
        this.IMAGE_BOX.y = this.ENTRY_BOX.y;
        this.IMAGE_BOX.width = this.ENTRIES_BOX.width * .25;
        this.IMAGE_BOX.height = this.ENTRY_BOX.height;

        this.NAME_BOX.x = this.ENTRY_BOX.x + this.ENTRY_BOX.width * .30;
        this.NAME_BOX.y = this.ENTRY_BOX.y;
        this.NAME_BOX.width = this.ENTRIES_BOX.width * .45;
        this.NAME_BOX.height = this.ENTRY_BOX.height;

        this.SCORE_BOX.x = this.ENTRY_BOX.x + this.ENTRY_BOX.width * .78;
        this.SCORE_BOX.y = this.ENTRY_BOX.y;
        this.SCORE_BOX.width = this.ENTRIES_BOX.width * .22;
        this.SCORE_BOX.height = this.ENTRY_BOX.height;

        this.IMAGE_SIZE = .7 * Math.min(
            this.ENTRY_BOX.width * .25,
            this.ENTRY_BOX.height);

        // Font styles
        this.createFontStyles();
    },

    preload: function() {
        // Enable cross-origin image loading
        this.load.crossOrigin = 'anonymous';

        this.load.image('noface', 'assets/noface.png');
        this.load.image('arrow', 'assets/arrow.png');
        this.load.image('back', 'assets/back.png');
    },

    create: function() {
        // Set up background
        var background = this.add.image(this.game.world.centerX, this.game.world.centerY, 'background');
        background.anchor.setTo(0.5, 0.5);
        background.width = this.game.width;
        background.height = this.game.height;

        // Create game objects
        this.createHighscoreEntries();
        this.createUI();

        // Handler for loaded profile pictures
        this.load.onLoadComplete.add(this.loadComplete, this);

        // Exit if not logged in
        if (!fbIsLoggedIn()) {
            this.state.start('Main');
            return;
        }
        fbGetFriendsScores(function(friendsScores, userPos) {
            this.friendsScores = friendsScores;
            this.userPos = userPos;
            this.maxPage = Math.floor(this.friendsScores.length / this.PAGE_SIZE);
            this.loadScoresPage();
        }, this);
    },

    shutdown: function() {
        // Remove handlers
        this.load.onLoadComplete.remove(this.loadComplete, this);
    },

    loadComplete: function() {
        for (var i = 0; i < this.numFriendsInPage; i++) {
            if (!this.profileImagesData[i].isSilhouette) {
                this.scores[i].img.loadTexture(i);
            }
            this.scores[i].img.width = this.IMAGE_SIZE;
            this.scores[i].img.height = this.IMAGE_SIZE;
            this.scores[i].img.anchor.setTo(.5, .5);
            this.scores[i].img.visible = true;
        }
    },

    loadScoresPage: function() {
        // Hide all entries
        this.scores.forEach(function(s) {
            s.img.loadTexture('noface');
            s.img.visible = false;
            s.pos.setStyle(this.positionTextStyle);
            s.pos.visible = false;
            s.name.setStyle(this.nameTextStyle);
            s.name.visible = false;
            s.score.setStyle(this.scoreTextStyle);
            s.score.visible = false;
        }, this);

        // Make sure page is in range
        if (this.currentPage < 0) {
            this.currentPage = 0;
        }
        if (this.currentPage > this.maxPage) {
            this.currentPage = this.maxPage;
        }

        // Hide arrows as needed
        this.arrowRight.visible = this.currentPage < this.maxPage;
        this.arrowLeft.visible = this.currentPage > 0;

        // Count friends in page
        var iFriendStart = this.PAGE_SIZE * this.currentPage;
        var iFriendEnd = Math.min(
            this.PAGE_SIZE * (this.currentPage + 1),
            this.friendsScores.length);
        this.numFriendsInPage = iFriendEnd - iFriendStart;
        this.profileImagesData = new Array(this.numFriendsInPage);

        // Function that starts the loader after every friend information is read
        var readFriends = 0;
        var friendInformationRead = function() {
            readFriends++;
            if (readFriends >= this.numFriendsInPage) {
                this.profileImagesData.forEach(function(img, i) {
                    this.load.image(i, img.url);
                }, this);
                this.load.start();
            }
        }
        friendInformationRead = friendInformationRead.bind(this);

        // Iterate through friends
        for (var iFriend = iFriendStart, iScore = 0; iFriend < iFriendEnd; iFriend++, iScore++) {
            // Copy index to use in closure
            var iFriendCpy = iFriend;
            var iScoreCpy = iScore;
            fbGetProfileDetails(this.friendsScores[iFriend].user.id, function(friend) {
                this.scores[iScoreCpy].pos.setText(iFriendCpy + '.');
                this.scores[iScoreCpy].name.setText(friend.first_name || friend.name);
                this.scores[iScoreCpy].score.setText(this.friendsScores[iFriendCpy].score);
                // Use special style for the user
                if (iFriendCpy == this.userPos) {
                    this.scores[iScoreCpy].pos.setStyle(this.positionUserTextStyle);
                    this.scores[iScoreCpy].name.setStyle(this.nameUserTextStyle);
                    this.scores[iScoreCpy].score.setStyle(this.scoreUserTextStyle);
                }
                this.scores[iScoreCpy].pos.visible = true;
                this.scores[iScoreCpy].name.visible = true;
                this.scores[iScoreCpy].score.visible = true;
                this.profileImagesData[iScoreCpy] = friend.image;
                friendInformationRead();
            }, this);
        }
    },

    createFontStyles: function () {
        var fontFace = 'Pixel Art';
        var textSize = Math.floor(this.ENTRY_BOX.height / 5) + 'px';
        var positionTextSize = textSize;
        var nameTextSize = textSize;
        var scoreTextSize = textSize;
        var normalColor = 'white';
        var userColor = 'red';
        // Normal
        this.positionTextStyle = {
            font: fontFace,
            fontSize: positionTextSize,
            fill: normalColor,
            align: 'right',
            boundsAlignH: 'right',
            boundsAlignV: 'middle'
        };
        this.nameTextStyle = {
            font: fontFace,
            fontSize: positionTextSize,
            fill: normalColor,
            align: 'left',
            boundsAlignH: 'left',
            boundsAlignV: 'middle'
        };
        this.scoreTextStyle = {
            font: fontFace,
            fontSize: scoreTextSize,
            fill: 'white',
            align: 'center',
            boundsAlignH: 'center',
            boundsAlignV: 'middle'
        };
        // User
        this.positionUserTextStyle = {
            font: fontFace,
            fontSize: positionTextSize,
            fill: userColor,
            align: 'right',
            boundsAlignH: 'right',
            boundsAlignV: 'middle'
        };
        this.nameUserTextStyle = {
            font: fontFace,
            fontSize: nameTextSize,
            fill: userColor,
            align: 'left',
            boundsAlignH: 'left',
            boundsAlignV: 'middle',
            wordWrap: true,
            wordWrapWidth: this.NAME_BOX.width
        };
        this.scoreUserTextStyle = {
            font: fontFace,
            fontSize: scoreTextSize,
            fill: userColor,
            align: 'center',
            boundsAlignH: 'center',
            boundsAlignV: 'middle'
        };
    },

    createHighscoreEntries: function () {
        for (var i = 0; i < this.PAGE_SIZE; i++) {
            var xOffset = 0;
            var yOffset = i * this.ENTRY_BOX.height;

            // Position
            var pos = this.add.text(0, 0, '', this.positionTextStyle);
            pos.setTextBounds(
                this.POSITION_BOX.x + xOffset,
                this.POSITION_BOX.y + yOffset,
                this.POSITION_BOX.width,
                this.POSITION_BOX.height);
            pos.visible = false;

            // Image
            var img = this.add.image(
                this.IMAGE_BOX.x + this.IMAGE_BOX.width / 2 + xOffset,
                this.IMAGE_BOX.y + this.IMAGE_BOX.height / 2 + yOffset,
                'noface');
            img.visible = false;

            // Name
            var name = this.add.text(0, 0, '', this.nameTextStyle);
            name.setTextBounds(
                this.NAME_BOX.x + xOffset,
                this.NAME_BOX.y + yOffset,
                this.NAME_BOX.width,
                this.NAME_BOX.height);
            name.visible = false;

            // Score
            var score = this.add.text(0, 0, '', this.scoreTextStyle);
            score.setTextBounds(
                this.SCORE_BOX.x + xOffset,
                this.SCORE_BOX.y + yOffset,
                this.SCORE_BOX.width,
                this.SCORE_BOX.height);
            score.visible = false;

            this.scores.push({
                pos: pos,
                img: img,
                name: name,
                score: score
            });
        }
    },

    createUI: function () {
        // Back button to go back to main state
        var backButton = this.add.button(0, 0, 'back',
            function () {
                this.state.start('Main');
            }, this, 0, 0, 0);
        var backButtonSize= .1 * Math.min(this.game.width, this.game.height);
        backButton.width = backButtonSize;
        backButton.height = backButtonSize;
        backButton.anchor.setTo(0, 0);
        backButton.x = backButton.width * .2;
        backButton.y = backButton.width * .2;

        // Arrows to navigate through pages
        this.arrowRight = this.add.button(
            this.game.width * .9, this.game.height * .9, 'arrow',
            function () {
                if (this.currentPage < this.maxPage) {
                    this.currentPage++;
                    this.loadScoresPage();
                }
            }, this, 0, 0, 0);
        this.arrowRight.anchor.setTo(1, 1);
        this.arrowRight.visible = false;

        this.arrowLeft = this.add.button(
            this.game.width * .1, this.game.height * .9, 'arrow',
            function () {
                if (this.currentPage > 0) {
                    this.currentPage--;
                    this.loadScoresPage();
                }
            }, this, 0, 0, 0);
        this.arrowLeft.scale.setTo(-1, 1);
        this.arrowLeft.anchor.setTo(1, 1);
        this.arrowLeft.visible = false;
    }

};
<|endoftext|>


<commit_before>import rule, { ruleName, messages } from "..";

testRule(rule, {
  ruleName,
  config: [true],
  syntax: "scss",

  accept: [
    {
      code: "// comment",
      description: "Double slash comments"
    },
    {
      code: "//* comment",
      description: "Double slash comments with first character as asterix"
    }
  ],
  reject: [
    {
      code: `
      /* comment */
    `,
      description: "One line with optional ending",
      line: 2,
      column: 7,
      message: messages.expected
    },
    {
      code: `
        /* comment line 1
           comment line 2
        */
    `,
      description: "Multline comment with optional ending on next line",
      line: 2,
      column: 9,
      message: messages.expected
    }
  ]
});
<commit_msg>Add failing test for comment-no-loud<commit_after>import rule, { ruleName, messages } from "..";

testRule(rule, {
  ruleName,
  config: [true],
  syntax: "scss",

  accept: [
    {
      code: "// comment",
      description: "Double slash comments"
    },
    {
      code: "//* comment",
      description: "Double slash comments with first character as asterix"
    }
  ],
  reject: [
    {
      code: `
      /* comment */
    `,
      description: "One line with optional ending",
      line: 2,
      column: 7,
      message: messages.expected
    },
    {
      code: `
        /* comment line 1
           comment line 2
        */
    `,
      description: "Multline comment with optional ending on next line",
      line: 2,
      column: 9,
      message: messages.expected
    },
    {
      code: `
      i {
        font-style: italic;
      }

      /* comment line */

      b {
        font-weight: bold;
      }
    `,
      description: "Comment sandwiched between rules",
      line: 6,
      column: 7,
      message: messages.expected
    }
  ]
});
<|endoftext|>


<commit_before>fullscreen = function() {
	screenfull.toggle();
}

Polymer('character-card', {
	response: "",
	character: {
		"Might":"",
		"Speed":"",
		"Knowledge":"",
		"Sanity":"",
		"MightIndex":"",
		"SpeedIndex":"",
		"KnowledgeIndex":"",
		"SanityIndex":""
	},

	updateStat: function(attribute, direction) {
		switch(attribute) {
			case "might":
				switch(direction) {
					case "up":
						console.log("up");
						if(this.character.MightIndex < 8) {
							document.querySelector("character-card::shadow #might-score").innerHTML = this.character.Might[++this.character.MightIndex];
						}
						break;
					case "down":
						console.log("down");
						if(this.character.MightIndex > 0) {
							document.querySelector("character-card::shadow #might-score").innerHTML = this.character.Might[--this.character.MightIndex];
						}
						if(!this.character.MightIndex) {
							alert("You've died.");
						}
						break;
				}
				document.querySelector("character-card::shadow #might-index").innerHTML = this.character.MightIndex;
				break;
			case "speed":
				switch(direction) {
					case "up":
						console.log("up");
						if(this.character.SpeedIndex < 8) {
							document.querySelector("character-card::shadow #speed-score").innerHTML = this.character.Speed[++this.character.SpeedIndex];
						}
						break;
					case "down":
						console.log("down");
						if(this.character.SpeedIndex > 0) {
							document.querySelector("character-card::shadow #speed-score").innerHTML = this.character.Speed[--this.character.SpeedIndex];
						}
						if(!this.character.SpeedIndex) {
							alert("You've died.");
						}
						break;
				}
				document.querySelector("character-card::shadow #speed-index").innerHTML = this.character.SpeedIndex;
				break;
			case "knowledge":
				switch(direction) {
					case "up":
						console.log("up");
						if(this.character.KnowledgeIndex < 8) {
							document.querySelector("character-card::shadow #knowledge-score").innerHTML = this.character.Knowledge[++this.character.KnowledgeIndex];
						}
						break;
					case "down":
						console.log("down");
						if(this.character.KnowledgeIndex > 0) {
							document.querySelector("character-card::shadow #knowledge-score").innerHTML = this.character.Knowledge[--this.character.KnowledgeIndex];
						}
						if(!this.character.KnowledgeIndex) {
							alert("You've died.");
						}
						break;
				}
				document.querySelector("character-card::shadow #knowledge-index").innerHTML = this.character.KnowledgeIndex;
				break;
			case "sanity":
				switch(direction) {
					case "up":
						console.log("up");
						if(this.character.SanityIndex < 8) {
							document.querySelector("character-card::shadow #sanity-score").innerHTML = this.character.Sanity[++this.character.SanityIndex];
						}
						break;
					case "down":
						console.log("down");
						if(this.character.SanityIndex > 0) {
							document.querySelector("character-card::shadow #sanity-score").innerHTML = this.character.Sanity[--this.character.SanityIndex];
						}
						if(!this.character.SanityIndex) {
							alert("You've died.");
						}
						break;
				}
				document.querySelector("character-card::shadow #sanity-index").innerHTML = this.character.SanityIndex;
				break;
		}
	},

	setHeader: function(character) {
		switch(character) {
			case "ox-bellows":
			case "darrin-flash-williams":
				color = "#F44336";
				break;
			case "father-rhinehardt":
			case "professor-longfellow":
				color = "#9E9E9E";
				break;
			case "vivian-lopez":
			case "madame-zostra":
				color = "#3F51B5";
				break;
			case "peter-akimoto":
			case "brandon-jaspers":
				color = "#8BC34A";
				break;
			case "missy-dobourde":
			case "zoe-ingstrom":
				color = "#FFC107";
				break;
			case "jenny-leclerc":
			case "heather-granville":
				color = "#9C27B0";
				break;
			default:
				color = "#000000";
		}

		document.querySelector("character-card::shadow #character-name").style.backgroundColor = color;
	},

	setCardValues: function(character) {
		characters = [
				"ox-bellows",
				"father-rhinehardt",
				"vivian-lopez",
				"peter-akimoto",
				"missy-dobourde",
				"jenny-leclerc",
				"darrin-flash-williams",
				"professor-longfellow",
				"madame-zostra",
				"brandon-jaspers",
				"zoe-ingstrom",
				"heather-granville"
		]

		selection = this.response.Characters[characters.indexOf(character)];

		document.querySelector("character-card::shadow #character-name").innerHTML = selection.Name;
		document.querySelector("character-card::shadow #age").innerHTML = selection.Age;
		document.querySelector("character-card::shadow #height").innerHTML = selection.Height;
		document.querySelector("character-card::shadow #weight").innerHTML = selection.Weight;
		document.querySelector("character-card::shadow #birthday").innerHTML = selection.Birthday;
		document.querySelector("character-card::shadow #hobbies").innerHTML = selection.Hobbies;
		document.querySelector("character-card::shadow #might-score").innerHTML = selection.Might[selection.BaseMightIndex];
		document.querySelector("character-card::shadow #speed-score").innerHTML = selection.Speed[selection.BaseSpeedIndex];
		document.querySelector("character-card::shadow #knowledge-score").innerHTML = selection.Knowledge[selection.BaseKnowledgeIndex];
		document.querySelector("character-card::shadow #sanity-score").innerHTML = selection.Sanity[selection.BaseSanityIndex];
		document.querySelector("character-card::shadow #might-index").innerHTML = selection.BaseMightIndex;
		document.querySelector("character-card::shadow #speed-index").innerHTML = selection.BaseSpeedIndex;
		document.querySelector("character-card::shadow #knowledge-index").innerHTML = selection.BaseKnowledgeIndex;
		document.querySelector("character-card::shadow #sanity-index").innerHTML = selection.BaseSanityIndex;

		this.character.Might = selection.Might;
		this.character.Speed = selection.Speed;
		this.character.Knowledge = selection.Knowledge;
		this.character.Sanity = selection.Sanity;
		this.character.MightIndex = selection.BaseMightIndex
		this.character.SpeedIndex = selection.BaseSpeedIndex
		this.character.KnowledgeIndex = selection.BaseKnowledgeIndex
		this.character.SanityIndex = selection.BaseSanityIndex
	},

	getCharacter: function(character) {
		self = this;

		this.setHeader(character);

		request = new XMLHttpRequest();
		request.open("GET", "/polymer-character-card/elements/character-card/characters.json", true);

		response = "";
		request.onreadystatechange = function() {
			if(request.readyState === request.DONE) {
				status = request.status;

				if((status >= 200 && status < 300) || status === 304 || status === 0) {
					self.response = JSON.parse(request.responseText);
					self.setCardValues(character);
				}
			}
		};
		request.send();
	},

	attached: function() {
		self = this;

		ups = document.querySelectorAll("character-card::shadow .up");

		for (var i = ups.length - 1; i >= 0; i--) {
			ups[i].addEventListener("click", function(event) {
				attribute = event.target.attributes['name'].value;
				direction = event.target.attributes['class'].value;
				self.updateStat(attribute, "up");
			});
		};

		downs = document.querySelectorAll("character-card::shadow .down");

		for (var i = downs.length - 1; i >= 0; i--) {
			downs[i].addEventListener("click", function(event) {
				attribute = event.target.attributes['name'].value;
				direction = event.target.attributes['class'].value;
				self.updateStat(attribute, "down");
			});
		};

		this.getCharacter("darrin-flash-williams");
	},
});<commit_msg>Update character-card.js<commit_after>fullscreen = function() {
	screenfull.toggle();
}

Polymer('character-card', {
	response: "",
	character: {
		"Might":"",
		"Speed":"",
		"Knowledge":"",
		"Sanity":"",
		"MightIndex":"",
		"SpeedIndex":"",
		"KnowledgeIndex":"",
		"SanityIndex":""
	},

	updateStat: function(attribute, direction) {
		switch(attribute) {
			case "might":
				switch(direction) {
					case "up":
						console.log("up");
						if(this.character.MightIndex < 8) {
							document.querySelector("character-card::shadow #might-score").innerHTML = this.character.Might[++this.character.MightIndex];
						}
						break;
					case "down":
						console.log("down");
						if(this.character.MightIndex > 0) {
							document.querySelector("character-card::shadow #might-score").innerHTML = this.character.Might[--this.character.MightIndex];
						}
						if(!this.character.MightIndex) {
							alert("You've died.");
						}
						break;
				}
				document.querySelector("character-card::shadow #might-index").innerHTML = this.character.MightIndex;
				break;
			case "speed":
				switch(direction) {
					case "up":
						console.log("up");
						if(this.character.SpeedIndex < 8) {
							document.querySelector("character-card::shadow #speed-score").innerHTML = this.character.Speed[++this.character.SpeedIndex];
						}
						break;
					case "down":
						console.log("down");
						if(this.character.SpeedIndex > 0) {
							document.querySelector("character-card::shadow #speed-score").innerHTML = this.character.Speed[--this.character.SpeedIndex];
						}
						if(!this.character.SpeedIndex) {
							alert("You've died.");
						}
						break;
				}
				document.querySelector("character-card::shadow #speed-index").innerHTML = this.character.SpeedIndex;
				break;
			case "knowledge":
				switch(direction) {
					case "up":
						console.log("up");
						if(this.character.KnowledgeIndex < 8) {
							document.querySelector("character-card::shadow #knowledge-score").innerHTML = this.character.Knowledge[++this.character.KnowledgeIndex];
						}
						break;
					case "down":
						console.log("down");
						if(this.character.KnowledgeIndex > 0) {
							document.querySelector("character-card::shadow #knowledge-score").innerHTML = this.character.Knowledge[--this.character.KnowledgeIndex];
						}
						if(!this.character.KnowledgeIndex) {
							alert("You've died.");
						}
						break;
				}
				document.querySelector("character-card::shadow #knowledge-index").innerHTML = this.character.KnowledgeIndex;
				break;
			case "sanity":
				switch(direction) {
					case "up":
						console.log("up");
						if(this.character.SanityIndex < 8) {
							document.querySelector("character-card::shadow #sanity-score").innerHTML = this.character.Sanity[++this.character.SanityIndex];
						}
						break;
					case "down":
						console.log("down");
						if(this.character.SanityIndex > 0) {
							document.querySelector("character-card::shadow #sanity-score").innerHTML = this.character.Sanity[--this.character.SanityIndex];
						}
						if(!this.character.SanityIndex) {
							alert("You've died.");
						}
						break;
				}
				document.querySelector("character-card::shadow #sanity-index").innerHTML = this.character.SanityIndex;
				break;
		}
	},

	setHeader: function(character) {
		switch(character) {
			case "ox-bellows":
			case "darrin-flash-williams":
				color = "#F44336";
				break;
			case "father-rhinehardt":
			case "professor-longfellow":
				color = "#9E9E9E";
				break;
			case "vivian-lopez":
			case "madame-zostra":
				color = "#3F51B5";
				break;
			case "peter-akimoto":
			case "brandon-jaspers":
				color = "#8BC34A";
				break;
			case "missy-dobourde":
			case "zoe-ingstrom":
				color = "#FFC107";
				break;
			case "jenny-leclerc":
			case "heather-granville":
				color = "#9C27B0";
				break;
			default:
				color = "#000000";
		}

		document.querySelector("character-card::shadow #character-name").style.backgroundColor = color;
	},

	setCardValues: function(character) {
		characters = [
				"ox-bellows",
				"father-rhinehardt",
				"vivian-lopez",
				"peter-akimoto",
				"missy-dobourde",
				"jenny-leclerc",
				"darrin-flash-williams",
				"professor-longfellow",
				"madame-zostra",
				"brandon-jaspers",
				"zoe-ingstrom",
				"heather-granville"
		]

		selection = this.response.Characters[characters.indexOf(character)];

		document.querySelector("character-card::shadow #character-name").innerHTML = selection.Name;
		document.querySelector("character-card::shadow #age").innerHTML = selection.Age;
		document.querySelector("character-card::shadow #height").innerHTML = selection.Height;
		document.querySelector("character-card::shadow #weight").innerHTML = selection.Weight;
		document.querySelector("character-card::shadow #birthday").innerHTML = selection.Birthday;
		document.querySelector("character-card::shadow #hobbies").innerHTML = selection.Hobbies;
		document.querySelector("character-card::shadow #might-score").innerHTML = selection.Might[selection.BaseMightIndex];
		document.querySelector("character-card::shadow #speed-score").innerHTML = selection.Speed[selection.BaseSpeedIndex];
		document.querySelector("character-card::shadow #knowledge-score").innerHTML = selection.Knowledge[selection.BaseKnowledgeIndex];
		document.querySelector("character-card::shadow #sanity-score").innerHTML = selection.Sanity[selection.BaseSanityIndex];
		document.querySelector("character-card::shadow #might-index").innerHTML = selection.BaseMightIndex;
		document.querySelector("character-card::shadow #speed-index").innerHTML = selection.BaseSpeedIndex;
		document.querySelector("character-card::shadow #knowledge-index").innerHTML = selection.BaseKnowledgeIndex;
		document.querySelector("character-card::shadow #sanity-index").innerHTML = selection.BaseSanityIndex;

		this.character.Might = selection.Might;
		this.character.Speed = selection.Speed;
		this.character.Knowledge = selection.Knowledge;
		this.character.Sanity = selection.Sanity;
		this.character.MightIndex = selection.BaseMightIndex
		this.character.SpeedIndex = selection.BaseSpeedIndex
		this.character.KnowledgeIndex = selection.BaseKnowledgeIndex
		this.character.SanityIndex = selection.BaseSanityIndex
	},

	getCharacter: function(character) {
		self = this;

		this.setHeader(character);

		request = new XMLHttpRequest();
		request.open("GET", "/polymer-character-card/elements/character-card/characters.json", true);

		response = "";
		request.onreadystatechange = function() {
			if(request.readyState === request.DONE) {
				status = request.status;

				if((status >= 200 && status < 300) || status === 304 || status === 0) {
					self.response = JSON.parse(request.responseText);
					self.setCardValues(character);
				}
			}
		};
		request.send();
	},

	attached: function() {
		self = this;

		ups = document.querySelectorAll("character-card::shadow .up");

		for (var i = ups.length - 1; i >= 0; i--) {
			ups[i].addEventListener("click", function(event) {
				attribute = event.target.attributes['name'].value;
				direction = event.target.attributes['class'].value;
				self.updateStat(attribute, "up");
			});
		};

		downs = document.querySelectorAll("character-card::shadow .down");

		for (var j = downs.length - 1; j >= 0; j--) {
			downs[j].addEventListener("click", function(event) {
				attribute = event.target.attributes['name'].value;
				direction = event.target.attributes['class'].value;
				self.updateStat(attribute, "down");
			});
		};

		this.getCharacter("darrin-flash-williams");
	},
});
<|endoftext|>


<commit_before>//
// Copyright (C) 2006 rPath, Inc
// All Rights Reserved
//

var labelsCache = {};
var versionCache = {};

var staticPath = '';

var green = {'style': 'color: green; font-weight: bold;'};
var gray = {'style': 'color: gray;'};

var spinnerImg = 'apps/mint/images/circle-ball-dark-antialiased.gif';
var nextImg = 'apps/mint/images/next.gif';
var prevImg = 'apps/mint/images/prev.gif';
var prevImgDisabled = 'apps/mint/images/prev_disabled.gif';

//
// some DOM helper functions
//
function forwardLink(attrs, text) {
    return LI(null, A(attrs, IMG({'src': staticPath + nextImg}), " " + text));
}

function returnImg() {
    return IMG({'src': staticPath + prevImg});
}

function disabledReturn() {
    return DIV(gray, IMG({'src': staticPath + prevImgDisabled}), " Back");
}

// ctor
function TrovePicker(projectId, serverName, troveName, pickerId, mintStaticPath) {
    this.projectId = projectId;
    this.serverName = serverName;
    this.troveName = troveName;
    this.elId = pickerId;
    staticPath = mintStaticPath;

    logDebug(this.elId);
    this.buildTrovePicker();
}

TrovePicker.prototype.troveName = null;
TrovePicker.prototype.serverName = null;
TrovePicker.prototype.label = null;
TrovePicker.prototype.version = null;
TrovePicker.prototype.flavorCache = null;
TrovePicker.prototype.flavorDict = null;

TrovePicker.prototype.working = function(isWorking) {
    if(isWorking) {
        showElement(this.elId + 'spinnerList');
        hideElement(this.elId + 'selectionList');
    }
    else {
        hideElement(this.elId + 'spinnerList');
        showElement(this.elId + 'selectionList');
    }
}

TrovePicker.prototype.buildTroveSpec = function(name, version, flavor) {
    return DIV({'id': this.elId + 'troveSpec'},
        DIV((name ? green : gray), "Name: ", name),
        DIV((version ? green : gray), "Version: ", version),
        DIV((flavor ? green : gray), "Flavor: ", flavor)
    );
}

// Build the initial DOM for the trove picker and
// begin retrieving all leaves for a given
// trove name on a server.
TrovePicker.prototype.buildTrovePicker = function() {
    oldEl = $(this.elId);
    picker = DIV({'id': this.elId, 'class': 'trovePicker'})
    spinner = UL({'id': this.elId + 'spinnerList'},
        LI(null, "Loading...", IMG({'src': staticPath + spinnerImg}))
    );
    appendChildNodes(picker, SPAN({'id': this.elId + 'prompt', 'class': 'prompt'}),
        P({'style': 'float: right;'},
            SPAN({'id': this.elId + 'next'}, null),
            " ",
            IMG({'src': staticPath + nextImg})
        ),
        P({'id': 'return'}),
        spinner,
        UL({'id': this.elId + 'selectionList'}),
        this.buildTroveSpec('', '', '')
    );
    swapDOM(oldEl, picker);
    this.getAllTroveLabels();
}

// Show all flavors available for a given trove and version
TrovePicker.prototype.showTroveFlavors = function(e) {
    this.version = e.src().version;

    replaceChildNodes($(this.elId + 'troveSpec'),
        this.buildTroveSpec(this.troveName, this.version, ''));
    oldList = $(this.elId + 'selectionList');
    ul = UL({ 'id': this.elId + 'selectionList' });

    for(var i in this.flavorCache[this.version]) {
        flavor = this.flavorCache[this.version][i];
        appendChildNodes(ul, forwardLink(null, this.flavorDict[flavor]));

        // return to getTroveVersions
        returnLink = A(null, returnImg(), " Back");
        returnLink.label = this.label;
        connect(returnLink, "onclick", this, "getTroveVersions");
        replaceChildNodes($('return'), returnLink);
    }
    swapDOM(oldList, ul);
    this.working(false);
    replaceChildNodes($(this.elId + 'prompt'), "Please choose a flavor:");
}

// Show all versions of a trove on a given label
TrovePicker.prototype.getTroveVersions = function(e) {
    this.label = e.src().label;
    var par = this;
    var key = this.label + "=" + this.troveName;

    var setupList = function(versionList) {
        var versionDict = req[0];
        var versionList = req[1];
        oldList = $(par.elId + 'selectionList');
        ul = UL({ 'id': par.elId + 'selectionList' });

        par.flavorCache = versionDict;
        par.flavorDict = req[2];

        for(var i in versionList) {
            link = forwardLink(null, versionList[i]);
            link.version = versionList[i];
            connect(link, "onclick", par, "showTroveFlavors");
            appendChildNodes(ul, link);
        }
        swapDOM(oldList, ul);
        par.working(false);
        replaceChildNodes($(par.elId + 'prompt'), "Please choose a version:");
        replaceChildNodes($(par.elId + 'next'), "Next: Choose a Version");
        replaceChildNodes($(par.elId + 'troveSpec'),
            par.buildTroveSpec(par.troveName, par.label, ''));

        // return to getAllTroveLabels
        returnLink = A(null, returnImg(), " Back");
        connect(returnLink, "onclick", par, "getAllTroveLabels");
        replaceChildNodes($('return'), returnLink);
    };

    var callback = function(aReq) {
        logDebug("[JSON] response: ", aReq.responseText);

        req = evalJSONRequest(aReq);
        versionCache[key] = req;
        setupList(req);
    };

    if(!versionCache[key]) {
        this.working(true);
        var req = new JsonRpcRequest("jsonrpc/", "getTroveVersions");
        req.setCallback(callback);
        req.send(true, [this.projectId, this.label, this.troveName]);
    } else {
        setupList(versionCache[key]);
    }
}

// Fetch all labels a trove exists on a given server
TrovePicker.prototype.getAllTroveLabels = function() {
    logDebug("top of getAllTroveLabels");
    var key = this.serverName + "=" + this.troveName;
    var par = this; // save the parent for the subfunction's use

    var setupList = function(labelList) {
        oldList = $(par.elId + 'selectionList');
        ul = UL({ 'id': par.elId + 'selectionList' });

        for(var i in labelList) {
            link = forwardLink(null, labelList[i]);
            link.label = labelList[i];
            connect(link, "onclick", par, "getTroveVersions");
            appendChildNodes(ul, link);
        }
        swapDOM(oldList, ul);
        par.working(false);
        replaceChildNodes($(par.elId + 'prompt'), "Please choose a label:");
        replaceChildNodes($(par.elId + 'next'), "Next: Choose a Version");
        replaceChildNodes($(par.elId + 'troveSpec'),
            par.buildTroveSpec(par.troveName, par.serverName, ''));
        replaceChildNodes($('return'), disabledReturn());
    };

    var callback = function(aReq) {
        logDebug("[JSON] response: ", aReq.responseText);

        labelList = evalJSONRequest(aReq);
        labelsCache[key] = labelList;
        setupList(labelList);
    };

    if(!labelsCache[key]) {
        this.working(true);
        var req = new JsonRpcRequest("jsonrpc/", "getAllTroveLabels");
        req.setAuth(getCookieValue("pysid"));
        req.setCallback(callback);
        req.send(true, [this.projectId, this.serverName, this.troveName]);
    } else {
        setupList(labelsCache[key]);
    }
}
<commit_msg>fix the Back link after choosing a specific version<commit_after>//
// Copyright (C) 2006 rPath, Inc
// All Rights Reserved
//

var labelsCache = {};
var versionCache = {};

var staticPath = '';

var green = {'style': 'color: green; font-weight: bold;'};
var gray = {'style': 'color: gray;'};

var spinnerImg = 'apps/mint/images/circle-ball-dark-antialiased.gif';
var nextImg = 'apps/mint/images/next.gif';
var prevImg = 'apps/mint/images/prev.gif';
var prevImgDisabled = 'apps/mint/images/prev_disabled.gif';

//
// some DOM helper functions
//
function forwardLink(attrs, text) {
    return LI(null, A(attrs, IMG({'src': staticPath + nextImg}), " " + text));
}

function returnImg() {
    return IMG({'src': staticPath + prevImg});
}

function disabledReturn() {
    return DIV(gray, IMG({'src': staticPath + prevImgDisabled}), " Back");
}

// ctor
function TrovePicker(projectId, serverName, troveName, pickerId, mintStaticPath) {
    this.projectId = projectId;
    this.serverName = serverName;
    this.troveName = troveName;
    this.elId = pickerId;
    staticPath = mintStaticPath;

    logDebug(this.elId);
    this.buildTrovePicker();
}

TrovePicker.prototype.troveName = null;
TrovePicker.prototype.serverName = null;
TrovePicker.prototype.label = null;
TrovePicker.prototype.version = null;
TrovePicker.prototype.flavorCache = null;
TrovePicker.prototype.flavorDict = null;

TrovePicker.prototype.working = function(isWorking) {
    if(isWorking) {
        showElement(this.elId + 'spinnerList');
        hideElement(this.elId + 'selectionList');
    }
    else {
        hideElement(this.elId + 'spinnerList');
        showElement(this.elId + 'selectionList');
    }
}

TrovePicker.prototype.buildTroveSpec = function(name, version, flavor) {
    return DIV({'id': this.elId + 'troveSpec'},
        DIV((name ? green : gray), "Name: ", name),
        DIV((version ? green : gray), "Version: ", version),
        DIV((flavor ? green : gray), "Flavor: ", flavor)
    );
}

// Build the initial DOM for the trove picker and
// begin retrieving all leaves for a given
// trove name on a server.
TrovePicker.prototype.buildTrovePicker = function() {
    oldEl = $(this.elId);
    picker = DIV({'id': this.elId, 'class': 'trovePicker'})
    spinner = UL({'id': this.elId + 'spinnerList'},
        LI(null, "Loading...", IMG({'src': staticPath + spinnerImg}))
    );
    appendChildNodes(picker, SPAN({'id': this.elId + 'prompt', 'class': 'prompt'}),
        P({'style': 'float: right;'},
            SPAN({'id': this.elId + 'next'}, null),
            " ",
            IMG({'src': staticPath + nextImg})
        ),
        P({'id': 'return'}),
        spinner,
        UL({'id': this.elId + 'selectionList'}),
        this.buildTroveSpec('', '', '')
    );
    swapDOM(oldEl, picker);
    this.getAllTroveLabels();
}

// Show all flavors available for a given trove and version
TrovePicker.prototype.showTroveFlavors = function(e) {
    this.version = e.src().version;
    this.label = e.src().label;

    replaceChildNodes($(this.elId + 'troveSpec'),
        this.buildTroveSpec(this.troveName, this.version, ''));
    oldList = $(this.elId + 'selectionList');
    ul = UL({ 'id': this.elId + 'selectionList' });

    for(var i in this.flavorCache[this.version]) {
        flavor = this.flavorCache[this.version][i];
        appendChildNodes(ul, forwardLink(null, this.flavorDict[flavor]));
    }
    // return to getTroveVersions
    returnLink = A(null, returnImg(), " Back");
    returnLink.label = this.label;
    connect(returnLink, "onclick", this, "getTroveVersions");
    replaceChildNodes($('return'), returnLink);

    swapDOM(oldList, ul);
    this.working(false);
    replaceChildNodes($(this.elId + 'prompt'), "Please choose a flavor:");
}

// Show all versions of a trove on a given label
TrovePicker.prototype.getTroveVersions = function(e) {
    this.label = e.src().label;
    var par = this;
    var key = this.label + "=" + this.troveName;

    var setupList = function(req) {
        var versionDict = req[0];
        var versionList = req[1];
        oldList = $(par.elId + 'selectionList');
        ul = UL({ 'id': par.elId + 'selectionList' });

        par.flavorCache = versionDict;
        par.flavorDict = req[2];

        for(var i in versionList) {
            link = forwardLink(null, versionList[i]);
            link.version = versionList[i];
            link.label = par.label;
            connect(link, "onclick", par, "showTroveFlavors");
            appendChildNodes(ul, link);
        }
        swapDOM(oldList, ul);
        par.working(false);
        replaceChildNodes($(par.elId + 'prompt'), "Please choose a version:");
        replaceChildNodes($(par.elId + 'next'), "Next: Choose a Version");
        replaceChildNodes($(par.elId + 'troveSpec'),
            par.buildTroveSpec(par.troveName, par.label, ''));

        // return to getAllTroveLabels
        returnLink = A(null, returnImg(), " Back");
        connect(returnLink, "onclick", par, "getAllTroveLabels");
        replaceChildNodes($('return'), returnLink);
    };

    var callback = function(aReq) {
        logDebug("[JSON] response: ", aReq.responseText);

        req = evalJSONRequest(aReq);
        versionCache[key] = req;
        setupList(req);
    };

    if(!versionCache[key]) {
        this.working(true);
        var req = new JsonRpcRequest("jsonrpc/", "getTroveVersions");
        req.setCallback(callback);
        req.send(true, [this.projectId, this.label, this.troveName]);
    } else {
        setupList(versionCache[key]);
    }
}

// Fetch all labels a trove exists on a given server
TrovePicker.prototype.getAllTroveLabels = function() {
    logDebug("top of getAllTroveLabels");
    var key = this.serverName + "=" + this.troveName;
    var par = this; // save the parent for the subfunction's use

    var setupList = function(labelList) {
        oldList = $(par.elId + 'selectionList');
        ul = UL({ 'id': par.elId + 'selectionList' });

        for(var i in labelList) {
            link = forwardLink(null, labelList[i]);
            link.label = labelList[i];
            connect(link, "onclick", par, "getTroveVersions");
            appendChildNodes(ul, link);
        }
        swapDOM(oldList, ul);
        par.working(false);
        replaceChildNodes($(par.elId + 'prompt'), "Please choose a label:");
        replaceChildNodes($(par.elId + 'next'), "Next: Choose a Version");
        replaceChildNodes($(par.elId + 'troveSpec'),
            par.buildTroveSpec(par.troveName, par.serverName, ''));
        replaceChildNodes($('return'), disabledReturn());
    };

    var callback = function(aReq) {
        logDebug("[JSON] response: ", aReq.responseText);

        labelList = evalJSONRequest(aReq);
        labelsCache[key] = labelList;
        setupList(labelList);
    };

    if(!labelsCache[key]) {
        this.working(true);
        var req = new JsonRpcRequest("jsonrpc/", "getAllTroveLabels");
        req.setAuth(getCookieValue("pysid"));
        req.setCallback(callback);
        req.send(true, [this.projectId, this.serverName, this.troveName]);
    } else {
        setupList(labelsCache[key]);
    }
}
<|endoftext|>


<commit_before>'use strict';

var I = require('immutable');
var Q = require('../arithmetic/number');
var M = require('../arithmetic/matrix')(Q, 0, 1);

var delaney     = require('./delaney');
var delaney2d   = require('./delaney2d');
var fundamental = require('./fundamental');
var covers      = require('./covers');

var _edgeTranslations = function _edgeTranslations(cov) {
  var fg  = fundamental.fundamentalGroup(cov);
  var nul = M.nullSpace(M.make(fg.relatorMatrix));
  var n   = fg.nrGenerators;

  return fg.edge2word.map(function(a) {
    return a.map(function(b) {
      var v = M.make([fundamental.relatorAsVector(b, n)]);
      return M.times(v, nul);
    });
  });
};

if (require.main == module) {
  var test = function test(ds) {
    console.log('ds = '+ds);
    var dst = delaney2d.toroidalCover(ds);
    console.log('dst = '+dst);
    console.log();
    console.log('edges relators: '+fundamental.fundamentalGroup(dst).edge2word);
    console.log();
    console.log('edges translations: '+_edgeTranslations(dst));
    console.log();
  }

  test(delaney.parse('<1.1:3:1 2 3,1 3,2 3:4 8,3>'));
  test(delaney.parse('<1.1:1:1,1,1:6,3>'));
  test(delaney.parse('<1.1:8:2 4 6 8,8 3 5 7,6 5 8 7:4,4>'));
  test(delaney.parse('<1.1:8:2 4 6 8,8 3 5 7,5 6 8 7:4,4>'));
}
<commit_msg>implement corner shift computation<commit_after>'use strict';

var I = require('immutable');
var Q = require('../arithmetic/number');
var M = require('../arithmetic/matrix')(Q, 0, 1);

var delaney     = require('./delaney');
var properties  = require('./properties');
var delaney2d   = require('./delaney2d');
var fundamental = require('./fundamental');
var covers      = require('./covers');

var _edgeTranslations = function _edgeTranslations(cov) {
  var fg  = fundamental.fundamentalGroup(cov);
  var nul = M.nullSpace(M.make(fg.relatorMatrix));
  var n   = fg.nrGenerators;

  return fg.edge2word.map(function(a) {
    return a.map(function(b) {
      var v = M.make([fundamental.relatorAsVector(b, n)]);
      return M.times(v, nul);
    });
  });
};

var _cornerShifts = function _cornerShifts(cov, e2t) {
  var dim = delaney.dim(cov);
  var zero = M.constant(1, dim);

  return I.Map().withMutations(function(m) {
    cov.indices().forEach(function(i) {
      var idcs = cov.indices().filter(function(j) { return j != i; });

      properties.traversal(cov, idcs, cov.elements()).forEach(function(e) {
        var Dk = e[0];
        var k  = e[1];
        var D  = e[2];

        if (k == properties.traversal.root)
          m.setIn([D, i], zero);
        else
          m.setIn([D, i], M.minus(m.getIn([Dk, i]), e2t.getIn([Dk, k]) || zero));
      });
    });
  });
};

if (require.main == module) {
  var test = function test(ds) {
    console.log('ds = '+ds);
    var dst = delaney2d.toroidalCover(ds);
    console.log('dst = '+dst);
    console.log();
    console.log('edges relators: '+fundamental.fundamentalGroup(dst).edge2word);
    console.log();
    var e2t = _edgeTranslations(dst);
    console.log('edges translations: '+e2t);
    console.log();
    console.log('corner shifts: '+_cornerShifts(dst, e2t));
    console.log();
  }

  test(delaney.parse('<1.1:3:1 2 3,1 3,2 3:4 8,3>'));
  test(delaney.parse('<1.1:1:1,1,1:6,3>'));
  test(delaney.parse('<1.1:8:2 4 6 8,8 3 5 7,6 5 8 7:4,4>'));
  test(delaney.parse('<1.1:8:2 4 6 8,8 3 5 7,5 6 8 7:4,4>'));
}
<|endoftext|>


<commit_before>/** @jsx React.DOM */
'use strict';
var React = require('react');
var globals = require('./globals');
var dbxref = require('./dbxref');
var search = require('./search');
var pipeline = require('./pipeline');
var fetched = require('./fetched');
var StatusLabel = require('./statuslabel').StatusLabel;
var Citation = require('./publication').Citation;
var _ = require('underscore');

var DbxrefList = dbxref.DbxrefList;
var PipelineTable = pipeline.PipelineTable;
var FetchedItems = fetched.FetchedItems;

// Count the total number of references in all the publications passed
// in the pubs array parameter.
function refCount(pubs) {
    var total = 0;
    if (pubs) {
        pubs.forEach(function(pub) {
            total += pub.references ? pub.references.length : 0;
        });
    }
    return total;
}

// Display all references in the array of publications in the 'pubs' property.
var References = React.createClass({
    render: function() {
        return (

                {this.props.pubs ?

                        {this.props.pubs.map(function(pub) {
                            return (

                                        {pub.authors ? pub.authors + '. ' : ''}
                                        {pub.title + ' '}
                                        <Citation context={pub} />

                                    {pub.references && pub.references.length ? <DbxrefList values={pub.references} className="multi-value" /> : ''}

                            );
                        })}

                : null}

        );
    }
});

// Display all PMID/PMCID references in the array of publications in the 'pubs' property.
var PubReferences = React.createClass({
    render: function() {
        // Collect all publications' references into one array
        // and remove duplicates
        var allRefs = [];
        this.props.pubs.forEach(function(pub) {
            allRefs = allRefs.concat(pub.references);
        });
        allRefs = _.uniq(allRefs);

        if (allRefs) {
            return <DbxrefList values={allRefs} className={this.props.listClass} />;
        } else {
            return ;
        }
    }
});

var Software = module.exports.Software = React.createClass({
    render: function() {
        var context = this.props.context;
        var itemClass = globals.itemClass(context, 'view-item');

        var pipeline_url = '/search/?type=pipeline&analysis_steps.software_versions.software.uuid=' + context.uuid;

        return (

{context.title}

                            <StatusLabel title="Status" status={context.status} />

Title

                            {context.source_url ?

{context.title}
 :

{context.title}

                            }

Description

{context.description}

                        {context.software_type && context.software_type.length ?

Software type

{context.software_type.join(", ")}

                        : null}

                        {context.purpose && context.purpose.length ?

Used for

{context.purpose.join(", ")}

                        : null}

                        {context.references && context.references.length ?

References

<References pubs={context.references} />

                        : null}

                {context.versions.length ?

Software Versions

                        <SoftwareVersionTable items={context.versions} />

                : null }

        );
    }
});
globals.content_views.register(Software, 'software');

// Commenting out until pipelines are used.

var PipelinesUsingSoftwareVersion = module.exports.PipelinesUsingSoftwareVersion = React.createClass({
    render: function () {
        var context = this.props.context;
        return (

Pipelines using software {context.title}

                {this.transferPropsTo(
                    <PipelineTable />
                )}

        );
    }
});

var SoftwareVersionTable = module.exports.SoftwareVersionTable = React.createClass({
    render: function() {
        var rows = {};
        this.props.items.forEach(function (version) {
            rows[version['@id']] = (

                    {version.version}
                    {version.download_checksum}

            );
        });
        return (

                            Version
                            Download checksum

                    {rows}

        );
    }
});

var Listing = React.createClass({
    mixins: [search.PickerActionsMixin],
    render: function() {
        var context = this.props.context;
        return (

                        {this.renderActions()}

Software

                            {context.status ?
{' ' + context.status}
 : ''}

                            {context.title}
                            {context.source_url ?  — source : ''}

{context.description}

                        {context.software_type && context.software_type.length ?

                                Software type:
                                {context.software_type.join(", ")}

                        : null}

                        {refCount(context.references) ?

                                Publication:
                                <PubReferences pubs={context.references} listClass="list-reference" />

                        : null}

        );
    }
});
globals.listing_views.register(Listing, 'software');
<commit_msg>Don’t assume software version exists<commit_after>/** @jsx React.DOM */
'use strict';
var React = require('react');
var globals = require('./globals');
var dbxref = require('./dbxref');
var search = require('./search');
var pipeline = require('./pipeline');
var fetched = require('./fetched');
var StatusLabel = require('./statuslabel').StatusLabel;
var Citation = require('./publication').Citation;
var _ = require('underscore');

var DbxrefList = dbxref.DbxrefList;
var PipelineTable = pipeline.PipelineTable;
var FetchedItems = fetched.FetchedItems;

// Count the total number of references in all the publications passed
// in the pubs array parameter.
function refCount(pubs) {
    var total = 0;
    if (pubs) {
        pubs.forEach(function(pub) {
            total += pub.references ? pub.references.length : 0;
        });
    }
    return total;
}

// Display all references in the array of publications in the 'pubs' property.
var References = React.createClass({
    render: function() {
        return (

                {this.props.pubs ?

                        {this.props.pubs.map(function(pub) {
                            return (

                                        {pub.authors ? pub.authors + '. ' : ''}
                                        {pub.title + ' '}
                                        <Citation context={pub} />

                                    {pub.references && pub.references.length ? <DbxrefList values={pub.references} className="multi-value" /> : ''}

                            );
                        })}

                : null}

        );
    }
});

// Display all PMID/PMCID references in the array of publications in the 'pubs' property.
var PubReferences = React.createClass({
    render: function() {
        // Collect all publications' references into one array
        // and remove duplicates
        var allRefs = [];
        this.props.pubs.forEach(function(pub) {
            allRefs = allRefs.concat(pub.references);
        });
        allRefs = _.uniq(allRefs);

        if (allRefs) {
            return <DbxrefList values={allRefs} className={this.props.listClass} />;
        } else {
            return ;
        }
    }
});

var Software = module.exports.Software = React.createClass({
    render: function() {
        var context = this.props.context;
        var itemClass = globals.itemClass(context, 'view-item');

        var pipeline_url = '/search/?type=pipeline&analysis_steps.software_versions.software.uuid=' + context.uuid;

        return (

{context.title}

                            <StatusLabel title="Status" status={context.status} />

Title

                            {context.source_url ?

{context.title}
 :

{context.title}

                            }

Description

{context.description}

                        {context.software_type && context.software_type.length ?

Software type

{context.software_type.join(", ")}

                        : null}

                        {context.purpose && context.purpose.length ?

Used for

{context.purpose.join(", ")}

                        : null}

                        {context.references && context.references.length ?

References

<References pubs={context.references} />

                        : null}

                {context.versions && context.versions.length ?

Software Versions

                        <SoftwareVersionTable items={context.versions} />

                : null }

        );
    }
});
globals.content_views.register(Software, 'software');

// Commenting out until pipelines are used.

var PipelinesUsingSoftwareVersion = module.exports.PipelinesUsingSoftwareVersion = React.createClass({
    render: function () {
        var context = this.props.context;
        return (

Pipelines using software {context.title}

                {this.transferPropsTo(
                    <PipelineTable />
                )}

        );
    }
});

var SoftwareVersionTable = module.exports.SoftwareVersionTable = React.createClass({
    render: function() {
        var rows = {};
        this.props.items.forEach(function (version) {
            rows[version['@id']] = (

                    {version.version}
                    {version.download_checksum}

            );
        });
        return (

                            Version
                            Download checksum

                    {rows}

        );
    }
});

var Listing = React.createClass({
    mixins: [search.PickerActionsMixin],
    render: function() {
        var context = this.props.context;
        return (

                        {this.renderActions()}

Software

                            {context.status ?
{' ' + context.status}
 : ''}

                            {context.title}
                            {context.source_url ?  — source : ''}

{context.description}

                        {context.software_type && context.software_type.length ?

                                Software type:
                                {context.software_type.join(", ")}

                        : null}

                        {refCount(context.references) ?

                                Publication:
                                <PubReferences pubs={context.references} listClass="list-reference" />

                        : null}

        );
    }
});
globals.listing_views.register(Listing, 'software');
<|endoftext|>


<commit_before>/*
Name:         piwik
Description:  Access a Piwik API from node.js.
Source:       https://github.com/fvdm/nodejs-piwik
Feedback:     https://github.com/fvdm/nodejs-piwik/issues
License:      Unlicense / Public Domain (see UNLICENSE file)
*/

// INIT
var	EventEmitter = require('events').EventEmitter,
	urltool = require('url'),
	querystring = require('querystring');

var app = new EventEmitter();
app.settings = {};

// SETUP basics
app.setup = function( baseURL, token ) {
	var url = urltool.parse( baseURL, true );

	// protocol and port
	switch( url.protocol ) {
		case 'http:':
			app.http = require('http');
			app.settings.apiport = url.port ? url.port : 80;
			break;

		case 'https:':
			app.http = require('https');
			app.settings.apiport = url.port ? url.port : 443;
			break;
	}

	// token in baseURL?
	if( url.query && url.query.token_auth ) {
		app.settings.token = url.query.token_auth;
	}

	// override with custom token, if any
	if( token ) {
		app.settings.token = token;
	}

	// the rest
	app.settings.apihost = url.hostname;
	app.settings.apipath = url.pathname;
}

// API call
app.api = function( vars, cb ) {

	// prepare fields
	var vars = typeof vars == 'object' ? vars : {};
	vars.module = 'API';
	vars.format = 'JSON';
	vars.token_auth = app.settings.token;

	// do request
	app.http.get(
		{
			host:	app.settings.apihost,
			port:	app.settings.apiport,
			path:	app.settings.apipath +'?'+ querystring.stringify( vars )
		},
		function( response ) {

			var data = '';
			response.on( 'data', function( chunk ) { data += chunk });
			response.on( 'end', function() {

				// callback
				if( data.substr(0,1) == '[' && data.substr(-1,1) == ']' ) {
					cb( JSON.parse( data ) );
				}

			});

		}
	);

}

// ready
module.exports = app;<commit_msg>Removed EventEmitter<commit_after>/*
Name:         piwik
Description:  Access a Piwik API from node.js.
Source:       https://github.com/fvdm/nodejs-piwik
Feedback:     https://github.com/fvdm/nodejs-piwik/issues
License:      Unlicense / Public Domain (see UNLICENSE file)
*/

// INIT
var	urltool = require('url')
var querystring = require('querystring')

app.settings = {};

// SETUP basics
app.setup = function( baseURL, token ) {
	var url = urltool.parse( baseURL, true );

	// protocol and port
	switch( url.protocol ) {
		case 'http:':
			app.http = require('http');
			app.settings.apiport = url.port ? url.port : 80;
			break;

		case 'https:':
			app.http = require('https');
			app.settings.apiport = url.port ? url.port : 443;
			break;
	}

	// token in baseURL?
	if( url.query && url.query.token_auth ) {
		app.settings.token = url.query.token_auth;
	}

	// override with custom token, if any
	if( token ) {
		app.settings.token = token;
	}

	// the rest
	app.settings.apihost = url.hostname;
	app.settings.apipath = url.pathname;
}

// API call
app.api = function( vars, cb ) {

	// prepare fields
	var vars = typeof vars == 'object' ? vars : {};
	vars.module = 'API';
	vars.format = 'JSON';
	vars.token_auth = app.settings.token;

	// do request
	app.http.get(
		{
			host:	app.settings.apihost,
			port:	app.settings.apiport,
			path:	app.settings.apipath +'?'+ querystring.stringify( vars )
		},
		function( response ) {

			var data = '';
			response.on( 'data', function( chunk ) { data += chunk });
			response.on( 'end', function() {

				// callback
				if( data.substr(0,1) == '[' && data.substr(-1,1) == ']' ) {
					cb( JSON.parse( data ) );
				}

			});

		}
	);

}

// ready
module.exports = app;<|endoftext|>