<commit_before>// Copyright 2006 The Closure Library Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/**
 * @fileoverview Constant declarations for common key codes.
 *
 * @see ../demos/keyhandler.html
 */

goog.provide('goog.events.KeyCodes');

goog.require('goog.userAgent');

/**
 * Key codes for common characters.
 *
 * This list is not localized and therefor some of the key codes are not correct
 * for non US keyboard layouts. See comments below.
 *
 * @enum {number}
 */
goog.events.KeyCodes = {
  MAC_ENTER: 3,
  BACKSPACE: 8,
  TAB: 9,
  NUM_CENTER: 12,  // NUMLOCK on FF/Safari Mac
  ENTER: 13,
  SHIFT: 16,
  CTRL: 17,
  ALT: 18,
  PAUSE: 19,
  CAPS_LOCK: 20,
  ESC: 27,
  SPACE: 32,
  PAGE_UP: 33,     // also NUM_NORTH_EAST
  PAGE_DOWN: 34,   // also NUM_SOUTH_EAST
  END: 35,         // also NUM_SOUTH_WEST
  HOME: 36,        // also NUM_NORTH_WEST
  LEFT: 37,        // also NUM_WEST
  UP: 38,          // also NUM_NORTH
  RIGHT: 39,       // also NUM_EAST
  DOWN: 40,        // also NUM_SOUTH
  PRINT_SCREEN: 44,
  INSERT: 45,      // also NUM_INSERT
  DELETE: 46,      // also NUM_DELETE
  ZERO: 48,
  ONE: 49,
  TWO: 50,
  THREE: 51,
  FOUR: 52,
  FIVE: 53,
  SIX: 54,
  SEVEN: 55,
  EIGHT: 56,
  NINE: 57,
  QUESTION_MARK: 63, // needs localization
  A: 65,
  B: 66,
  C: 67,
  D: 68,
  E: 69,
  F: 70,
  G: 71,
  H: 72,
  I: 73,
  J: 74,
  K: 75,
  L: 76,
  M: 77,
  N: 78,
  O: 79,
  P: 80,
  Q: 81,
  R: 82,
  S: 83,
  T: 84,
  U: 85,
  V: 86,
  W: 87,
  X: 88,
  Y: 89,
  Z: 90,
  META: 91, // WIN_KEY_LEFT
  WIN_KEY_RIGHT: 92,
  CONTEXT_MENU: 93,
  NUM_ZERO: 96,
  NUM_ONE: 97,
  NUM_TWO: 98,
  NUM_THREE: 99,
  NUM_FOUR: 100,
  NUM_FIVE: 101,
  NUM_SIX: 102,
  NUM_SEVEN: 103,
  NUM_EIGHT: 104,
  NUM_NINE: 105,
  NUM_MULTIPLY: 106,
  NUM_PLUS: 107,
  NUM_MINUS: 109,
  NUM_PERIOD: 110,
  NUM_DIVISION: 111,
  F1: 112,
  F2: 113,
  F3: 114,
  F4: 115,
  F5: 116,
  F6: 117,
  F7: 118,
  F8: 119,
  F9: 120,
  F10: 121,
  F11: 122,
  F12: 123,
  NUMLOCK: 144,
  SCROLL_LOCK: 145,

  // OS-specific media keys like volume controls and browser controls.
  FIRST_MEDIA_KEY: 166,
  LAST_MEDIA_KEY: 183,

  SEMICOLON: 186,            // needs localization
  DASH: 189,                 // needs localization
  EQUALS: 187,               // needs localization
  COMMA: 188,                // needs localization
  PERIOD: 190,               // needs localization
  SLASH: 191,                // needs localization
  APOSTROPHE: 192,           // needs localization
  TILDE: 192,                // needs localization
  SINGLE_QUOTE: 222,         // needs localization
  OPEN_SQUARE_BRACKET: 219,  // needs localization
  BACKSLASH: 220,            // needs localization
  CLOSE_SQUARE_BRACKET: 221, // needs localization
  WIN_KEY: 224,
  MAC_FF_META: 224, // Firefox (Gecko) fires this for the meta key instead of 91
  WIN_IME: 229,

  // We've seen users whose machines fire this keycode at regular one
  // second intervals. The common thread among these users is that
  // they're all using Dell Inspiron laptops, so we suspect that this
  // indicates a hardware/bios problem.
  // http://en.community.dell.com/support-forums/laptop/f/3518/p/19285957/19523128.aspx
  PHANTOM: 255
};

/**
 * Returns true if the event contains a text modifying key.
 * @param {goog.events.BrowserEvent} e A key event.
 * @return {boolean} Whether it's a text modifying key.
 */
goog.events.KeyCodes.isTextModifyingKeyEvent = function(e) {
  if (e.altKey && !e.ctrlKey ||
      e.metaKey ||
      // Function keys don't generate text
      e.keyCode >= goog.events.KeyCodes.F1 &&
      e.keyCode <= goog.events.KeyCodes.F12) {
    return false;
  }

  // The following keys are quite harmless, even in combination with
  // CTRL, ALT or SHIFT.
  switch (e.keyCode) {
    case goog.events.KeyCodes.ALT:
    case goog.events.KeyCodes.CAPS_LOCK:
    case goog.events.KeyCodes.CONTEXT_MENU:
    case goog.events.KeyCodes.CTRL:
    case goog.events.KeyCodes.DOWN:
    case goog.events.KeyCodes.END:
    case goog.events.KeyCodes.ESC:
    case goog.events.KeyCodes.HOME:
    case goog.events.KeyCodes.INSERT:
    case goog.events.KeyCodes.LEFT:
    case goog.events.KeyCodes.MAC_FF_META:
    case goog.events.KeyCodes.META:
    case goog.events.KeyCodes.NUMLOCK:
    case goog.events.KeyCodes.NUM_CENTER:
    case goog.events.KeyCodes.PAGE_DOWN:
    case goog.events.KeyCodes.PAGE_UP:
    case goog.events.KeyCodes.PAUSE:
    case goog.events.KeyCodes.PHANTOM:
    case goog.events.KeyCodes.PRINT_SCREEN:
    case goog.events.KeyCodes.RIGHT:
    case goog.events.KeyCodes.SCROLL_LOCK:
    case goog.events.KeyCodes.SHIFT:
    case goog.events.KeyCodes.UP:
    case goog.events.KeyCodes.WIN_KEY:
    case goog.events.KeyCodes.WIN_KEY_RIGHT:
      return false;
    default:
      return e.keyCode < goog.events.KeyCodes.FIRST_MEDIA_KEY ||
          e.keyCode > goog.events.KeyCodes.LAST_MEDIA_KEY;
  }
};

/**
 * Returns true if the key fires a keypress event in the current browser.
 *
 * Accoridng to MSDN [1] IE only fires keypress events for the following keys:
 * - Letters: A - Z (uppercase and lowercase)
 * - Numerals: 0 - 9
 * - Symbols: ! @ # $ % ^ & * ( ) _ - + = < [ ] { } , . / ? \ | ' ` " ~
 * - System: ESC, SPACEBAR, ENTER
 *
 * That's not entirely correct though, for instance there's no distinction
 * between upper and lower case letters.
 *
 * [1] http://msdn2.microsoft.com/en-us/library/ms536939(VS.85).aspx)
 *
 * Safari is similar to IE, but does not fire keypress for ESC.
 *
 * Additionally, IE6 does not fire keydown or keypress events for letters when
 * the control or alt keys are held down and the shift key is not. IE7 does
 * fire keydown in these cases, though, but not keypress.
 *
 * @param {number} keyCode A key code.
 * @param {number=} opt_heldKeyCode Key code of a currently-held key.
 * @param {boolean=} opt_shiftKey Whether the shift key is held down.
 * @param {boolean=} opt_ctrlKey Whether the control key is held down.
 * @param {boolean=} opt_altKey Whether the alt key is held down.
 * @return {boolean} Whether it's a key that fires a keypress event.
 */
goog.events.KeyCodes.firesKeyPressEvent = function(keyCode, opt_heldKeyCode,
    opt_shiftKey, opt_ctrlKey, opt_altKey) {
  if (!goog.userAgent.IE &&
      !(goog.userAgent.WEBKIT && goog.userAgent.isVersion('525'))) {
    return true;
  }

  if (goog.userAgent.MAC && opt_altKey) {
    return goog.events.KeyCodes.isCharacterKey(keyCode);
  }

  // Alt but not AltGr which is represented as Alt+Ctrl.
  if (opt_altKey && !opt_ctrlKey) {
    return false;
  }

  // Saves Ctrl or Alt + key for IE and WebKit 525+, which won't fire keypress.
  // Non-IE browsers and WebKit prior to 525 won't get this far so no need to
  // check the user agent.
  if (!opt_shiftKey &&
      (opt_heldKeyCode == goog.events.KeyCodes.CTRL ||
       opt_heldKeyCode == goog.events.KeyCodes.ALT)) {
    return false;
  }

  // When Ctrl+<somekey> is held in IE, it only fires a keypress once, but it
  // continues to fire keydown events as the event repeats.
  if (goog.userAgent.IE && opt_ctrlKey && opt_heldKeyCode == keyCode) {
    return false;
  }

  switch (keyCode) {
    case goog.events.KeyCodes.ENTER:
      return true;
    case goog.events.KeyCodes.ESC:
      return !goog.userAgent.WEBKIT;
  }

  return goog.events.KeyCodes.isCharacterKey(keyCode);
};

/**
 * Returns true if the key produces a character.
 * This does not cover characters on non-US keyboards (Russian, Hebrew, etc.).
 *
 * @param {number} keyCode A key code.
 * @return {boolean} Whether it's a character key.
 */
goog.events.KeyCodes.isCharacterKey = function(keyCode) {
  if (keyCode >= goog.events.KeyCodes.ZERO &&
      keyCode <= goog.events.KeyCodes.NINE) {
    return true;
  }

  if (keyCode >= goog.events.KeyCodes.NUM_ZERO &&
      keyCode <= goog.events.KeyCodes.NUM_MULTIPLY) {
    return true;
  }

  if (keyCode >= goog.events.KeyCodes.A &&
      keyCode <= goog.events.KeyCodes.Z) {
    return true;
  }

  // Safari sends zero key code for non-latin characters.
  if (goog.userAgent.WEBKIT && keyCode == 0) {
    return true;
  }

  switch (keyCode) {
    case goog.events.KeyCodes.SPACE:
    case goog.events.KeyCodes.QUESTION_MARK:
    case goog.events.KeyCodes.NUM_PLUS:
    case goog.events.KeyCodes.NUM_MINUS:
    case goog.events.KeyCodes.NUM_PERIOD:
    case goog.events.KeyCodes.NUM_DIVISION:
    case goog.events.KeyCodes.SEMICOLON:
    case goog.events.KeyCodes.DASH:
    case goog.events.KeyCodes.EQUALS:
    case goog.events.KeyCodes.COMMA:
    case goog.events.KeyCodes.PERIOD:
    case goog.events.KeyCodes.SLASH:
    case goog.events.KeyCodes.APOSTROPHE:
    case goog.events.KeyCodes.SINGLE_QUOTE:
    case goog.events.KeyCodes.OPEN_SQUARE_BRACKET:
    case goog.events.KeyCodes.BACKSLASH:
    case goog.events.KeyCodes.CLOSE_SQUARE_BRACKET:
      return true;
    default:
      return false;
  }
};
<commit_msg><commit_after>// Copyright 2006 The Closure Library Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/**
 * @fileoverview Constant declarations for common key codes.
 *
 * @see ../demos/keyhandler.html
 */

goog.provide('goog.events.KeyCodes');

goog.require('goog.userAgent');

/**
 * Key codes for common characters.
 *
 * This list is not localized and therefor some of the key codes are not correct
 * for non US keyboard layouts. See comments below.
 *
 * @enum {number}
 */
goog.events.KeyCodes = {
  MAC_ENTER: 3,
  BACKSPACE: 8,
  TAB: 9,
  NUM_CENTER: 12,  // NUMLOCK on FF/Safari Mac
  ENTER: 13,
  SHIFT: 16,
  CTRL: 17,
  ALT: 18,
  PAUSE: 19,
  CAPS_LOCK: 20,
  ESC: 27,
  SPACE: 32,
  PAGE_UP: 33,     // also NUM_NORTH_EAST
  PAGE_DOWN: 34,   // also NUM_SOUTH_EAST
  END: 35,         // also NUM_SOUTH_WEST
  HOME: 36,        // also NUM_NORTH_WEST
  LEFT: 37,        // also NUM_WEST
  UP: 38,          // also NUM_NORTH
  RIGHT: 39,       // also NUM_EAST
  DOWN: 40,        // also NUM_SOUTH
  PRINT_SCREEN: 44,
  INSERT: 45,      // also NUM_INSERT
  DELETE: 46,      // also NUM_DELETE
  ZERO: 48,
  ONE: 49,
  TWO: 50,
  THREE: 51,
  FOUR: 52,
  FIVE: 53,
  SIX: 54,
  SEVEN: 55,
  EIGHT: 56,
  NINE: 57,
  FF_SEMICOLON: 59, // Firefox (Gecko) fires this for semicolon instead of 186
  QUESTION_MARK: 63, // needs localization
  A: 65,
  B: 66,
  C: 67,
  D: 68,
  E: 69,
  F: 70,
  G: 71,
  H: 72,
  I: 73,
  J: 74,
  K: 75,
  L: 76,
  M: 77,
  N: 78,
  O: 79,
  P: 80,
  Q: 81,
  R: 82,
  S: 83,
  T: 84,
  U: 85,
  V: 86,
  W: 87,
  X: 88,
  Y: 89,
  Z: 90,
  META: 91, // WIN_KEY_LEFT
  WIN_KEY_RIGHT: 92,
  CONTEXT_MENU: 93,
  NUM_ZERO: 96,
  NUM_ONE: 97,
  NUM_TWO: 98,
  NUM_THREE: 99,
  NUM_FOUR: 100,
  NUM_FIVE: 101,
  NUM_SIX: 102,
  NUM_SEVEN: 103,
  NUM_EIGHT: 104,
  NUM_NINE: 105,
  NUM_MULTIPLY: 106,
  NUM_PLUS: 107,
  NUM_MINUS: 109,
  NUM_PERIOD: 110,
  NUM_DIVISION: 111,
  F1: 112,
  F2: 113,
  F3: 114,
  F4: 115,
  F5: 116,
  F6: 117,
  F7: 118,
  F8: 119,
  F9: 120,
  F10: 121,
  F11: 122,
  F12: 123,
  NUMLOCK: 144,
  SCROLL_LOCK: 145,

  // OS-specific media keys like volume controls and browser controls.
  FIRST_MEDIA_KEY: 166,
  LAST_MEDIA_KEY: 183,

  SEMICOLON: 186,            // needs localization
  DASH: 189,                 // needs localization
  EQUALS: 187,               // needs localization
  COMMA: 188,                // needs localization
  PERIOD: 190,               // needs localization
  SLASH: 191,                // needs localization
  APOSTROPHE: 192,           // needs localization
  TILDE: 192,                // needs localization
  SINGLE_QUOTE: 222,         // needs localization
  OPEN_SQUARE_BRACKET: 219,  // needs localization
  BACKSLASH: 220,            // needs localization
  CLOSE_SQUARE_BRACKET: 221, // needs localization
  WIN_KEY: 224,
  MAC_FF_META: 224, // Firefox (Gecko) fires this for the meta key instead of 91
  WIN_IME: 229,

  // We've seen users whose machines fire this keycode at regular one
  // second intervals. The common thread among these users is that
  // they're all using Dell Inspiron laptops, so we suspect that this
  // indicates a hardware/bios problem.
  // http://en.community.dell.com/support-forums/laptop/f/3518/p/19285957/19523128.aspx
  PHANTOM: 255
};

/**
 * Returns true if the event contains a text modifying key.
 * @param {goog.events.BrowserEvent} e A key event.
 * @return {boolean} Whether it's a text modifying key.
 */
goog.events.KeyCodes.isTextModifyingKeyEvent = function(e) {
  if (e.altKey && !e.ctrlKey ||
      e.metaKey ||
      // Function keys don't generate text
      e.keyCode >= goog.events.KeyCodes.F1 &&
      e.keyCode <= goog.events.KeyCodes.F12) {
    return false;
  }

  // The following keys are quite harmless, even in combination with
  // CTRL, ALT or SHIFT.
  switch (e.keyCode) {
    case goog.events.KeyCodes.ALT:
    case goog.events.KeyCodes.CAPS_LOCK:
    case goog.events.KeyCodes.CONTEXT_MENU:
    case goog.events.KeyCodes.CTRL:
    case goog.events.KeyCodes.DOWN:
    case goog.events.KeyCodes.END:
    case goog.events.KeyCodes.ESC:
    case goog.events.KeyCodes.HOME:
    case goog.events.KeyCodes.INSERT:
    case goog.events.KeyCodes.LEFT:
    case goog.events.KeyCodes.MAC_FF_META:
    case goog.events.KeyCodes.META:
    case goog.events.KeyCodes.NUMLOCK:
    case goog.events.KeyCodes.NUM_CENTER:
    case goog.events.KeyCodes.PAGE_DOWN:
    case goog.events.KeyCodes.PAGE_UP:
    case goog.events.KeyCodes.PAUSE:
    case goog.events.KeyCodes.PHANTOM:
    case goog.events.KeyCodes.PRINT_SCREEN:
    case goog.events.KeyCodes.RIGHT:
    case goog.events.KeyCodes.SCROLL_LOCK:
    case goog.events.KeyCodes.SHIFT:
    case goog.events.KeyCodes.UP:
    case goog.events.KeyCodes.WIN_KEY:
    case goog.events.KeyCodes.WIN_KEY_RIGHT:
      return false;
    default:
      return e.keyCode < goog.events.KeyCodes.FIRST_MEDIA_KEY ||
          e.keyCode > goog.events.KeyCodes.LAST_MEDIA_KEY;
  }
};

/**
 * Returns true if the key fires a keypress event in the current browser.
 *
 * Accoridng to MSDN [1] IE only fires keypress events for the following keys:
 * - Letters: A - Z (uppercase and lowercase)
 * - Numerals: 0 - 9
 * - Symbols: ! @ # $ % ^ & * ( ) _ - + = < [ ] { } , . / ? \ | ' ` " ~
 * - System: ESC, SPACEBAR, ENTER
 *
 * That's not entirely correct though, for instance there's no distinction
 * between upper and lower case letters.
 *
 * [1] http://msdn2.microsoft.com/en-us/library/ms536939(VS.85).aspx)
 *
 * Safari is similar to IE, but does not fire keypress for ESC.
 *
 * Additionally, IE6 does not fire keydown or keypress events for letters when
 * the control or alt keys are held down and the shift key is not. IE7 does
 * fire keydown in these cases, though, but not keypress.
 *
 * @param {number} keyCode A key code.
 * @param {number=} opt_heldKeyCode Key code of a currently-held key.
 * @param {boolean=} opt_shiftKey Whether the shift key is held down.
 * @param {boolean=} opt_ctrlKey Whether the control key is held down.
 * @param {boolean=} opt_altKey Whether the alt key is held down.
 * @return {boolean} Whether it's a key that fires a keypress event.
 */
goog.events.KeyCodes.firesKeyPressEvent = function(keyCode, opt_heldKeyCode,
    opt_shiftKey, opt_ctrlKey, opt_altKey) {
  if (!goog.userAgent.IE &&
      !(goog.userAgent.WEBKIT && goog.userAgent.isVersion('525'))) {
    return true;
  }

  if (goog.userAgent.MAC && opt_altKey) {
    return goog.events.KeyCodes.isCharacterKey(keyCode);
  }

  // Alt but not AltGr which is represented as Alt+Ctrl.
  if (opt_altKey && !opt_ctrlKey) {
    return false;
  }

  // Saves Ctrl or Alt + key for IE and WebKit 525+, which won't fire keypress.
  // Non-IE browsers and WebKit prior to 525 won't get this far so no need to
  // check the user agent.
  if (!opt_shiftKey &&
      (opt_heldKeyCode == goog.events.KeyCodes.CTRL ||
       opt_heldKeyCode == goog.events.KeyCodes.ALT)) {
    return false;
  }

  // When Ctrl+<somekey> is held in IE, it only fires a keypress once, but it
  // continues to fire keydown events as the event repeats.
  if (goog.userAgent.IE && opt_ctrlKey && opt_heldKeyCode == keyCode) {
    return false;
  }

  switch (keyCode) {
    case goog.events.KeyCodes.ENTER:
      return true;
    case goog.events.KeyCodes.ESC:
      return !goog.userAgent.WEBKIT;
  }

  return goog.events.KeyCodes.isCharacterKey(keyCode);
};

/**
 * Returns true if the key produces a character.
 * This does not cover characters on non-US keyboards (Russian, Hebrew, etc.).
 *
 * @param {number} keyCode A key code.
 * @return {boolean} Whether it's a character key.
 */
goog.events.KeyCodes.isCharacterKey = function(keyCode) {
  if (keyCode >= goog.events.KeyCodes.ZERO &&
      keyCode <= goog.events.KeyCodes.NINE) {
    return true;
  }

  if (keyCode >= goog.events.KeyCodes.NUM_ZERO &&
      keyCode <= goog.events.KeyCodes.NUM_MULTIPLY) {
    return true;
  }

  if (keyCode >= goog.events.KeyCodes.A &&
      keyCode <= goog.events.KeyCodes.Z) {
    return true;
  }

  // Safari sends zero key code for non-latin characters.
  if (goog.userAgent.WEBKIT && keyCode == 0) {
    return true;
  }

  switch (keyCode) {
    case goog.events.KeyCodes.SPACE:
    case goog.events.KeyCodes.QUESTION_MARK:
    case goog.events.KeyCodes.NUM_PLUS:
    case goog.events.KeyCodes.NUM_MINUS:
    case goog.events.KeyCodes.NUM_PERIOD:
    case goog.events.KeyCodes.NUM_DIVISION:
    case goog.events.KeyCodes.SEMICOLON:
    case goog.events.KeyCodes.FF_SEMICOLON:
    case goog.events.KeyCodes.DASH:
    case goog.events.KeyCodes.EQUALS:
    case goog.events.KeyCodes.COMMA:
    case goog.events.KeyCodes.PERIOD:
    case goog.events.KeyCodes.SLASH:
    case goog.events.KeyCodes.APOSTROPHE:
    case goog.events.KeyCodes.SINGLE_QUOTE:
    case goog.events.KeyCodes.OPEN_SQUARE_BRACKET:
    case goog.events.KeyCodes.BACKSLASH:
    case goog.events.KeyCodes.CLOSE_SQUARE_BRACKET:
      return true;
    default:
      return false;
  }
};
<|endoftext|>


<commit_before>/*
  webgame - three.js project gulp boilerplate
    MrPaws 2014

  TODO: 1) image processing boilerplate 2) always use minified bower deps (link)
*/
var gulp = require('gulp');

var del = require('del');
var uglify = require('gulp-uglify');
var concat = require('gulp-concat');
var jshint = require('gulp-jshint');
var rename = require('gulp-rename');
var merge = require('merge-stream');
var connect = require('gulp-connect');
var bower = require('main-bower-files');

var htmlSrc = '*.html';
var jsSrc = 'js/**/*.js';
var cssSrc = 'css/**/*.css';
var assetsSrc = 'assets/**';
var buildDir = 'dist';

gulp.task('clean', function(cb) {
  return del([buildDir], cb);
});

gulp.task('html',function () {
  return gulp.src(htmlSrc)
    .pipe(gulp.dest(buildDir))
    .pipe(connect.reload());
});

gulp.task('js', function () {
  return gulp.src(jsSrc)
    .pipe(concat('project.js'))
  	.pipe(uglify())
  	.pipe(rename('project.min.js'))
    .pipe(gulp.dest(buildDir + '/js'));
});

gulp.task('link', ['js'], function () {
  var jsFiles = bower();
  jsFiles.push(buildDir + '/js/project.min.js');
  return gulp.src(jsFiles)
  	.pipe(concat('all.js'))
  	.pipe(rename('all.min.js'))
    .pipe(gulp.dest(buildDir + '/js'))
    .pipe(connect.reload());
})

gulp.task('css', function () {
  return gulp.src(cssSrc)
  	.pipe(gulp.dest(buildDir + '/css'))
    .pipe(connect.reload());
});

gulp.task('assets', function () {
  return gulp.src(assetsSrc)
  	.pipe(gulp.dest(buildDir + '/assets'))
    .pipe(connect.reload());
});

gulp.task('connect', function() {
  connect.server({
    root: buildDir,
    livereload: true
  });
});

gulp.task('watch', function () {
  gulp.watch([htmlSrc], ['html']);
  gulp.watch([jsSrc], ['js','link']);
  gulp.watch([cssSrc], ['css']);
  gulp.watch([assetsSrc], ['assets']);
  gulp.watch(['bower.json'], ['link']);
});

gulp.task('default', ['clean','html','js','link','css','assets','connect','watch']);
<commit_msg>remove merge_stream from plugins<commit_after>/*
  webgame - three.js project gulp boilerplate
    MrPaws 2014

  TODO: 1) image processing boilerplate 2) always use minified bower deps (link)
*/
var gulp = require('gulp');

var del = require('del');
var uglify = require('gulp-uglify');
var concat = require('gulp-concat');
var jshint = require('gulp-jshint');
var rename = require('gulp-rename');
var connect = require('gulp-connect');
var bower = require('main-bower-files');

var htmlSrc = '*.html';
var jsSrc = 'js/**/*.js';
var cssSrc = 'css/**/*.css';
var assetsSrc = 'assets/**';
var buildDir = 'dist';

gulp.task('clean', function(cb) {
  return del([buildDir], cb);
});

gulp.task('html',function () {
  return gulp.src(htmlSrc)
    .pipe(gulp.dest(buildDir))
    .pipe(connect.reload());
});

gulp.task('js', function () {
  return gulp.src(jsSrc)
    .pipe(concat('project.js'))
  	.pipe(uglify())
  	.pipe(rename('project.min.js'))
    .pipe(gulp.dest(buildDir + '/js'));
});

gulp.task('link', ['js'], function () {
  var jsFiles = bower();
  jsFiles.push(buildDir + '/js/project.min.js');
  return gulp.src(jsFiles)
  	.pipe(concat('all.js'))
  	.pipe(rename('all.min.js'))
    .pipe(gulp.dest(buildDir + '/js'))
    .pipe(connect.reload());
})

gulp.task('css', function () {
  return gulp.src(cssSrc)
  	.pipe(gulp.dest(buildDir + '/css'))
    .pipe(connect.reload());
});

gulp.task('assets', function () {
  return gulp.src(assetsSrc)
  	.pipe(gulp.dest(buildDir + '/assets'))
    .pipe(connect.reload());
});

gulp.task('connect', function() {
  connect.server({
    root: buildDir,
    livereload: true
  });
});

gulp.task('watch', function () {
  gulp.watch([htmlSrc], ['html']);
  gulp.watch([jsSrc], ['js','link']);
  gulp.watch([cssSrc], ['css']);
  gulp.watch([assetsSrc], ['assets']);
  gulp.watch(['bower.json'], ['link']);
});

gulp.task('default', ['clean','html','js','link','css','assets','connect','watch']);
<|endoftext|>


<commit_before>//----------------------------------------------bits addMobiVeri--------------------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//----------------------------------------------updating addMobiVeri ---------------------------------------------------------------------------------
function addMobiVeri() {
    //----------------------------------------------append contact modal--------------------------------------------------------------------------------------
    $(".MobileModal").append('

Please enter your phone number so we can call you to confirm your delivery location
' +
        '
' +
        '
' +
        '  ' +
        '  <input id="inp-phone" type="number" class="validate" style="margin-left:0px;width:100%;">' +
        '  Phone number' +
        '
' +
        '
' +
        '
' +
        '    <button class="inp-phone btn cyan waves-effect waves-light" type="submit" name="action" disabled>ok</button>' +
        '
' +
        '
' +
        '
' +
        '
' +
        '
' +
        '  ' +
        ' <input id="inp-code" type="number" class="validate" style="margin-left:0px;width:100%;">' +
        '  confirmation code' +
        '
' +
        '
' +
        '
' +
        '    <button class="inp-code btn cyan waves-effect waves-light" type="submit" name="action" disabled>ok</button>' +
        '
' +
        '
' +
        '
' +

        '
' +
        '
' +
        ' Close' +
        '
');

    var forEach = function (array, callback, scope) {
        for (var i = 0; i < array.length; i++) {
            callback.call(scope, i, array[i]); // passes back stuff we need
        }
    };
    var myNodeList = document.querySelectorAll('input#inp-phone');
    forEach(myNodeList, function (index, value) {
        value.addEventListener("change", changedPhnNum);
    });
    var myNodeList = document.querySelectorAll('input#inp-code');
    forEach(myNodeList, function (index, value) {
        value.addEventListener("change", changedConfCode);
    });
}

function changedPhnNum(t) {
    console.log($(t.target).val());
    var val = $(t.target).val();

    doFetch({
        action: 'doMobiVeri',
        user: localStorage.getItem('bits-user-name'),
        val: val
    }).then(function (e) {
        if (e.status == 'ok') {
            $('#inp-phone').prop('disabled', true);
            $('#inp-code').prop('disabled', false);
            M.toast({
                html: 'confirmation code sent'
            });

        } else {

            $('#inp-phone').prop('disabled', false);
            $('#inp-code').prop('disabled', true);
            console.log(e);
        }
    });

}

function changedConfCode(t) {
    console.log($(t.target).val());
    var val = $(t.target).val();

    doFetch({
        action: 'doMobiVeriCode',
        user: localStorage.getItem('bits-user-name'),
        val: val
    }).then(function (e) {
        if (e.status == 'ok') {

            $('#inp-phone').prop('disabled', false);
            $('#inp-code').prop('disabled', true);
            M.toast({
                html: 'Phone Number added'
            });
            $("#MobileModal").modal("close")

        } else {
            console.log(e);
        }
    });

}
<commit_msg>mobile verification update<commit_after>//----------------------------------------------bits addMobiVeri--------------------------------------------------------------------------------------
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//----------------------------------------------updating addMobiVeri ---------------------------------------------------------------------------------
function addMobiVeri() {
    //----------------------------------------------append contact modal--------------------------------------------------------------------------------------
    $(".MobileModal").append('

Please enter your phone number so we can call you to confirm your delivery location
' +
        '
' +
        '
' +
        '  ' +
        '  <input id="inp-phone" type="number" class="validate" style="margin-left:0px;width:100%;">' +
        '  Phone number' +
        '
' +
        '
' +
        '
' +
        '    <button class="inp-phone btn waves-effect waves-light bits" type="submit" name="action">ok</button>' +
        '
' +
        '
' +
        '
' +
        '
' +
        '
' +
        '  ' +
        ' <input id="inp-code" type="number" class="validate" style="margin-left:0px;width:100%;">' +
        '  confirmation code' +
        '
' +
        '
' +
        '
' +
        '    <button class="inp-code btn waves-effect waves-light bits" type="submit" name="action">ok</button>' +
        '
' +
        '
' +
        '
' +

        '
' +
        '
' +
        ' Close' +
        '
');

    var forEach = function (array, callback, scope) {
        for (var i = 0; i < array.length; i++) {
            callback.call(scope, i, array[i]); // passes back stuff we need
        }
    };
    var myNodeList = document.querySelectorAll('input#inp-phone');
    forEach(myNodeList, function (index, value) {
        value.addEventListener("change", changedPhnNum);
    });
    var myNodeList = document.querySelectorAll('input#inp-code');
    forEach(myNodeList, function (index, value) {
        value.addEventListener("change", changedConfCode);
    });
}

function changedPhnNum(t) {
    console.log($(t.target).val());
    var val = $(t.target).val();

    if ($("#inp-phone").val().length < 10) {
        M.toast({
            html: 'Error! Confirm your number'
        });
    } else {
        doFetch({
            action: 'doMobiVeri',
            user: localStorage.getItem('bits-user-name'),
            val: val
        }).then(function (e) {
            if (e.status == 'ok') {
                $('#inp-phone').prop('disabled', true);
                $('#inp-code').prop('disabled', false);
                M.toast({
                    html: 'confirmation code sent'
                });

            } else {

                $('#inp-phone').prop('disabled', false);
                $('#inp-code').prop('disabled', true);
                console.log(e);
            }
        });
    }
}

function changedConfCode(t) {
    console.log($(t.target).val());
    var val = $(t.target).val();

    doFetch({
        action: 'doMobiVeriCode',
        user: localStorage.getItem('bits-user-name'),
        val: val
    }).then(function (e) {
        if (e.status == 'ok') {

            $('#inp-phone').prop('disabled', false);
            $('#inp-code').prop('disabled', true);
            M.toast({
                html: 'Phone Number added'
            });
            $("#MobileModal").modal("close")

        } else {
            console.log(e);
        }
    });

}
<|endoftext|>


<commit_before>// the eslint "no-unused-expressions" rule is triggered by the `expect`
// assertions in the tests. So, in order to avoid problems with eslint, I'm
// disabling that rule in this file
//
/* eslint-disable no-unused-expressions */

import React from 'react';
import { shallow, render, mount } from 'enzyme';
import chai from 'chai';
import sinon from 'sinon';

import Form from '../Form';

const expect = chai.expect;

/* eslint-disable no-unused-vars */
const debug = (component) => {
    console.info('------------------------------------------------------------');
    console.info(component.debug());
    console.info('------------------------------------------------------------');
};
/* eslint-enable no-unused-vars */

/* *****************************************************************************
a Form component containing a Dropdown
    should include a <Form.Dropdown> as a child
    should be a select.form-control
    should have the options specified in the `options` prop
    should have an empty set of options if options=[]
    should not include a label if none was specified
    should include a label if one was specified
    should select a specific value when value is set
    should select the first item when value is not set
    should select the first item when value is set to an invalid value

    should have a label.col-xs-3 when form is horizontal and labelColumns=3
    should have a div.col-xs-9 when form is horizontal and labelColumns=3

*/
describe('a Form component containing a Dropdown', () => {

    it('should include a <Form.Dropdown> as a child', () => {
        const options = [
            { value: '1', name: 'one' },
            { value: '2', name: 'two' },
        ];

        const component = shallow(
            <Form>
                <Form.Dropdown options={options} />
            </Form>
        );

        expect(component.find(Form.Dropdown)).to.have.length(1);
    });

    it('should be a select.form-control', () => {
        const options = [
            { value: '1', name: 'one' },
            { value: '2', name: 'two' },
        ];

        const component = render(
            <Form>
                <Form.Dropdown options={options} />
            </Form>
        );

        expect(component.find('select.form-control')).to.have.length(1);
    });

    it('should have the options specified in the `options` prop', () => {

        const options = [
            { value: '1', name: 'one' },
            { value: '2', name: 'two' },
        ];

        const component = render(
            <Form>
                <Form.Dropdown options={options} />
            </Form>
        );

        expect(component.find('option')).to.have.length(options.length, 'options count');

        options.forEach((opt) => {
            expect(component.find(`option[value="${opt.value}"]`))
                .to.have.length(1, `value=${opt.value}`);
            expect(component.find(`option[value="${opt.value}"]`).text())
                .to.equal(opt.name, `name=${opt.name}`);

        });
    });

    it('should have an empty set of options if options=[]', () => {

        const options = [];

        const component = render(
            <Form>
                <Form.Dropdown options={options} />
            </Form>
        );

        expect(component.find('option')).to.have.length(options.length, 'options count');
    });

    it('should not include a label if none was specified', () => {
        const options = [
            { value: '1', name: 'one' },
            { value: '2', name: 'two' },
        ];

        const component = render(
            <Form>
                <Form.Dropdown options={options} />
            </Form>
        );

        expect(component.find('label')).to.have.length(0);
    });

    it('should include a label if one was specified', () => {
        const options = [
            { value: '1', name: 'one' },
            { value: '2', name: 'two' },
        ];

        const label = 'some label';

        const component = render(
            <Form>
                <Form.Dropdown options={options} label={label} />
            </Form>
        );

        expect(component.find('label')).to.have.length(1);
        expect(component.find('label').text()).to.equal(label);
    });

    it('should select a specific value when value is set', () => {
        const options = [
            { value: '1', name: 'one' },
            { value: '2', name: 'two' },
            { value: '3', name: 'three' },
        ];

        const value = '2';

        const component = mount(
            <Form>
                <Form.Dropdown options={options} value={value} />
            </Form>
        );

        expect(component.find('select').props().value).to.equal(value);
    });

    it('should select the first item when value is not set', () => {
        const options = [
            { value: '1', name: 'one' },
            { value: '2', name: 'two' },
            { value: '3', name: 'three' },
        ];

        const component = mount(
            <Form>
                <Form.Dropdown options={options} />
            </Form>
        );

        expect(component.find('select').props().value).to.equal(options[0].value);
    });

    it('should select the first item when value is set to an invalid value', () => {
        const options = [
            { value: '1', name: 'one' },
            { value: '2', name: 'two' },
            { value: '3', name: 'three' },
        ];

        const value = '9';

        const component = mount(
            <Form>
                <Form.Dropdown options={options} value={value} />
            </Form>
        );

        expect(component.find('select').props().value).to.equal(options[0].value);
    });
});

/* *****************************************************************************
the Dropdown element
    should call onChange with the correct value on value change to a valid value
    should call onChange with the first option on value change to a invalid value
*/
describe('the Dropdown element', () => {

    it('should call onChange with the correct value on value change to a valid value', () => {

        const onChange = sinon.spy();

        const options = [
            { value: '1', name: 'one' },
            { value: '2', name: 'two' },
            { value: '3', name: 'three' },
        ];

        const initialValue = '2';

        const finalValue = '3';

        const component = mount(
            <Form>
                <Form.Dropdown options={options} value={initialValue} onChange={onChange} />
            </Form>
        );

        component.find('select').simulate('change', {
            target: { value: finalValue }
        });

        expect(onChange.callCount).to.equal(1);
        expect(onChange.calledWith(finalValue));
    });

    it('should call onChange with the first option on value change to a invalid value', () => {

        const onChange = sinon.spy();

        const options = [
            { value: '1', name: 'one' },
            { value: '2', name: 'two' },
            { value: '3', name: 'three' },
        ];

        const initialValue = '2';

        const finalValue = '9';

        const component = mount(
            <Form>
                <Form.Dropdown options={options} value={initialValue} onChange={onChange} />
            </Form>
        );

        component.find('select').simulate('change', {
            target: { value: finalValue }
        });

        expect(onChange.callCount).to.equal(1);
        expect(onChange.args[0][0]).to.equal(options[0].value);
    });

});
<commit_msg>added spec for label columns<commit_after>// the eslint "no-unused-expressions" rule is triggered by the `expect`
// assertions in the tests. So, in order to avoid problems with eslint, I'm
// disabling that rule in this file
//
/* eslint-disable no-unused-expressions */

import React from 'react';
import { shallow, render, mount } from 'enzyme';
import chai from 'chai';
import sinon from 'sinon';

import Form from '../Form';

const expect = chai.expect;

/* eslint-disable no-unused-vars */
const debug = (component) => {
    console.info('------------------------------------------------------------');
    console.info(component.debug());
    console.info('------------------------------------------------------------');
};
/* eslint-enable no-unused-vars */

/* *****************************************************************************
a Form component containing a Dropdown
    should include a <Form.Dropdown> as a child
    should be a select.form-control
    should have the options specified in the `options` prop
    should have an empty set of options if options=[]
    should not include a label if none was specified
    should include a label if one was specified
    should select a specific value when value is set
    should select the first item when value is not set
    should select the first item when value is set to an invalid value

    should have a label.col-xs-3 when form is horizontal and labelColumns=3
    should have a div.col-xs-9 when form is horizontal and labelColumns=3

*/
describe('a Form component containing a Dropdown', () => {

    it('should include a <Form.Dropdown> as a child', () => {
        const options = [
            { value: '1', name: 'one' },
            { value: '2', name: 'two' },
        ];

        const component = shallow(
            <Form>
                <Form.Dropdown options={options} />
            </Form>
        );

        expect(component.find(Form.Dropdown)).to.have.length(1);
    });

    it('should be a select.form-control', () => {
        const options = [
            { value: '1', name: 'one' },
            { value: '2', name: 'two' },
        ];

        const component = render(
            <Form>
                <Form.Dropdown options={options} />
            </Form>
        );

        expect(component.find('select.form-control')).to.have.length(1);
    });

    it('should have the options specified in the `options` prop', () => {

        const options = [
            { value: '1', name: 'one' },
            { value: '2', name: 'two' },
        ];

        const component = render(
            <Form>
                <Form.Dropdown options={options} />
            </Form>
        );

        expect(component.find('option')).to.have.length(options.length, 'options count');

        options.forEach((opt) => {
            expect(component.find(`option[value="${opt.value}"]`))
                .to.have.length(1, `value=${opt.value}`);
            expect(component.find(`option[value="${opt.value}"]`).text())
                .to.equal(opt.name, `name=${opt.name}`);

        });
    });

    it('should have an empty set of options if options=[]', () => {

        const options = [];

        const component = render(
            <Form>
                <Form.Dropdown options={options} />
            </Form>
        );

        expect(component.find('option')).to.have.length(options.length, 'options count');
    });

    it('should not include a label if none was specified', () => {
        const options = [
            { value: '1', name: 'one' },
            { value: '2', name: 'two' },
        ];

        const component = render(
            <Form>
                <Form.Dropdown options={options} />
            </Form>
        );

        expect(component.find('label')).to.have.length(0);
    });

    it('should include a label if one was specified', () => {
        const options = [
            { value: '1', name: 'one' },
            { value: '2', name: 'two' },
        ];

        const label = 'some label';

        const component = render(
            <Form>
                <Form.Dropdown options={options} label={label} />
            </Form>
        );

        expect(component.find('label')).to.have.length(1);
        expect(component.find('label').text()).to.equal(label);
    });

    it('should select a specific value when value is set', () => {
        const options = [
            { value: '1', name: 'one' },
            { value: '2', name: 'two' },
            { value: '3', name: 'three' },
        ];

        const value = '2';

        const component = mount(
            <Form>
                <Form.Dropdown options={options} value={value} />
            </Form>
        );

        expect(component.find('select').props().value).to.equal(value);
    });

    it('should select the first item when value is not set', () => {
        const options = [
            { value: '1', name: 'one' },
            { value: '2', name: 'two' },
            { value: '3', name: 'three' },
        ];

        const component = mount(
            <Form>
                <Form.Dropdown options={options} />
            </Form>
        );

        expect(component.find('select').props().value).to.equal(options[0].value);
    });

    it('should select the first item when value is set to an invalid value', () => {
        const options = [
            { value: '1', name: 'one' },
            { value: '2', name: 'two' },
            { value: '3', name: 'three' },
        ];

        const value = '9';

        const component = mount(
            <Form>
                <Form.Dropdown options={options} value={value} />
            </Form>
        );

        expect(component.find('select').props().value).to.equal(options[0].value);
    });

    it('should have a label.col-xs-3 when form is horizontal and labelColumns=3', () => {

        const options = [
            { value: '1', name: 'one' },
            { value: '2', name: 'two' },
            { value: '3', name: 'three' },
        ];

        const label = 'peter piper';
        const columns = 3;

        const value = 2;

        const component = mount(
            <Form horizontal labelColumns={columns}>
                <Form.Dropdown label={label} options={options} value={value} />
            </Form>
        );

        expect(component.find('div.form-horizontal')).to.have.length(1, 'form-horizontal');
        expect(component.find('label.control-label').props().className)
            .to.contain('col-xs-3', 'col-xs-3');
    });

});

/* *****************************************************************************
the Dropdown element
    should call onChange with the correct value on value change to a valid value
    should call onChange with the first option on value change to a invalid value
*/
describe('the Dropdown element', () => {

    it('should call onChange with the correct value on value change to a valid value', () => {

        const onChange = sinon.spy();

        const options = [
            { value: '1', name: 'one' },
            { value: '2', name: 'two' },
            { value: '3', name: 'three' },
        ];

        const initialValue = '2';

        const finalValue = '3';

        const component = mount(
            <Form>
                <Form.Dropdown options={options} value={initialValue} onChange={onChange} />
            </Form>
        );

        component.find('select').simulate('change', {
            target: { value: finalValue }
        });

        expect(onChange.callCount).to.equal(1);
        expect(onChange.calledWith(finalValue));
    });

    it('should call onChange with the first option on value change to a invalid value', () => {

        const onChange = sinon.spy();

        const options = [
            { value: '1', name: 'one' },
            { value: '2', name: 'two' },
            { value: '3', name: 'three' },
        ];

        const initialValue = '2';

        const finalValue = '9';

        const component = mount(
            <Form>
                <Form.Dropdown options={options} value={initialValue} onChange={onChange} />
            </Form>
        );

        component.find('select').simulate('change', {
            target: { value: finalValue }
        });

        expect(onChange.callCount).to.equal(1);
        expect(onChange.args[0][0]).to.equal(options[0].value);
    });

});
<|endoftext|>


<commit_before>const Discord = require('discord.js')
const client = new Discord.Client()
const Brain = require('./essentials/brain.js')

client.on('ready', () => {
  console.log(`Logged in as ${client.user.username}!`)
  client.helpResponse = '\n' + client.help.map(function (helpBlock) {
    return client.user.toString() + ' ' + helpBlock.expect + ' : ' + helpBlock.description
  }).join('\n')
})

client.brain = new Brain(client)
client.logger = console
client.help = []
client.respond = function (regex, callback, help) {
  client.on('message', function (msg) {
    if (msg.content.startsWith(client.user.toString())) {
      var match = msg.content.match(regex)
      if (match) {
        msg.match = match
        try {
          callback(msg)
        } catch(err) {
          client.logger.error(err)
        }
      }
    }
  })
  if (help) {
    client.help.push(help)
  }
}

client.respond(/help/i, function (msg) {
  msg.reply(client.helpResponse)
}, {expect: 'help', description: 'lists the available commands'})

var normalizedPath = require('path').join(__dirname, 'scripts')

require('fs').readdirSync(normalizedPath).forEach(function (file) {
  require('./scripts/' + file)(client)
})

client.login(process.env.HUBOT_DISCORD_TOKEN).catch(console.error)
<commit_msg>loading through async<commit_after>;(function () {
  const Discord = require('discord.js')
  const client = new Discord.Client()
  const Brain = require('./essentials/brain.js')

  client.on('ready', () => {
    console.log(`Logged in as ${client.user.username}!`)
    client.helpResponse = '\n' + client.help.map(function (helpBlock) {
      return client.user.toString() + ' ' + helpBlock.expect + ' : ' + helpBlock.description
    }).join('\n')
  })

  client.brain = new Brain(client)
  client.logger = console
  client.help = []
  client.respond = function (regex, callback, help) {
    client.on('message', function (msg) {
      if (msg.content.startsWith(client.user.toString())) {
        var match = msg.content.match(regex)
        if (match) {
          msg.match = match
          try {
            callback(msg)
          } catch(err) {
            client.logger.error(err)
          }
        }
      }
    })
    if (help) {
      client.help.push(help)
    }
  }

  client.respond(/help/i, function (msg) {
    msg.reply(client.helpResponse)
  }, {expect: 'help', description: 'lists the available commands'})

  var filesToLoad = 0
  var filesLoaded = 0
  function loadFiles (err, files) {
    filesToLoad += files.length
    files.forEach((file, index, files) => {
      require('./scripts/' + file)(client)
      filesLoaded++

      if (filesLoaded === filesToLoad) {
        login()
      }
    })
  }

  function loadDirectory (path) {
    require('fs').readdir(normalizedPath, loadFiles)
  }

  var normalizedPath = require('path').join(__dirname, 'scripts')
  loadDirectory(normalizedPath)

  function login () {
    client.login(process.env.HUBOT_DISCORD_TOKEN).catch(console.error)
  }
})()
<|endoftext|>


<commit_before>import Ember from 'ember';
import Model from 'ember-data/model';
import attr from 'ember-data/attr';
import {belongsTo, hasMany } from 'ember-data/relationships';
import {memberAction} from 'ember-api-actions';
const {computed} = Ember;

export default Model.extend({
  name: attr('string'),
  status: attr('session-status'),
  kind: attr('session-kind'),
  date: attr('date-range'),
  num_rounds: attr('number'),
  current: belongsTo('round', {async: true, inverse: 'current_session'}),
  primary: belongsTo('contest', {async: true, inverse: 'primary_contest'}),
  convention: belongsTo('convention', {async: true}),
  rounds: hasMany('round', {async: true}),
  performers: hasMany('performer', {async: true}),
  contests: hasMany('contest', {async: true}),
  judges: hasMany('judge', {async: true}),
  open: memberAction({path: 'open', type: 'post'}),
  close: memberAction({path: 'close', type: 'post'}),
  validate: memberAction({path: 'validate', type: 'post'}),
  start: memberAction({path: 'start', type: 'post'}),
  finish: memberAction({path: 'finish', type: 'post'}),
  draft: memberAction({path: 'draft', type: 'post'}),
  publish: memberAction({path: 'publish', type: 'post'}),
  cursor: belongsTo('performance', {async: true}),

  performerSortProperties: [
    'performer.totPoints:desc',
    'group.chap_name:asc',
  ],
  sortedPerformers: computed.sort(
    'performers',
    'performerSortProperties'
  ),

  publishedPerformers: computed.filterBy(
    'performers',
    'status',
    'Published'
  ),

  publishedSort: [
    'rank',
    'performer.group.name',
  ],
  sortedPublishedPerformers: computed.sort(
    'publishedPerformers',
    'publishedSort'
  ),

  primaryPerformers: computed.filterBy(
    'publishedPerformers',
    'rank'
  ),
  primarySort: [
    'rank',
    'sng_points:desc',
    'mus_points:desc',
    'prs_points:desc',
  ],
  sortedPrimaryPerformers: computed.sort(
    'primaryPerformers',
    'primarySort'
  ),

  secondaryPerformers: computed.filterBy(
    'publishedPerformers',
    'rank',
    null
  ),
  secondarySort: [
    'total_points:desc',
    'sng_points:desc',
    'mus_points:desc',
    'prs_points:desc',
  ],
  sortedSecondaryPerformers: computed.sort(
    'secondaryPerformers',
    'secondarySort'
  ),

  contestSort: [
    'is_qualifier:asc',
    'award.level:desc',
    'award.organization.name:asc',
    'award.is_primary:desc',
    'award.kind:asc',
    'award.is_improved:asc',
    'award.size:asc',
    'award.scope:asc',
  ],
  sortedContests: computed.sort(
    'contests',
    'contestSort'
  ),

  championshipContests: computed.filterBy(
    'contests',
    'is_qualifier',
    false
  ),

  sortedChampionshipContests: computed.sort(
    'championshipContests',
    'contestSort'
  ),

  qualificationContests: computed.filterBy(
    'contests',
    'is_qualifier',
    true
  ),

  sortedQualificiationContests: computed.sort(
    'qualificationContests',
    'contestSort'
  ),

  judgeSort: [
    'category',
    'kind',
    'slot',
  ],
  sortedJudges: computed.sort(
    'judges',
    'judgeSort'
  ),

  officialJudges: computed.filterBy(
    'judges',
    'kind',
    'Official'
  ),
  sortedOfficialJudges: computed.sort(
    'officialJudges',
    'judgeSort'
  ),

  roundsSort: [
    'num:desc',
  ],
  sortedRounds: computed.sort(
    'rounds',
    'roundsSort'
  ),

  currentPerformancesSort: [
    'num',
  ],
  currentPerformances: computed.sort(
    'current.performances',
    'currentPerformancesSort'
  ),
  ranks: Ember.computed('performers', function() {
      let lastScore = null;
      let rank = 0;
      return this.get('performers').sortBy('totPoints').reverse().map(performer => {
         let score = performer.get('totPoints');
         if (score !== lastScore) {rank++;}
         lastScore = score;
         return {
             performer: performer,
             rank: rank
         };
      });
  })
});
<commit_msg>Updated ranking computed property<commit_after>import Ember from 'ember';
import Model from 'ember-data/model';
import attr from 'ember-data/attr';
import {belongsTo, hasMany } from 'ember-data/relationships';
import {memberAction} from 'ember-api-actions';
const {computed} = Ember;

export default Model.extend({
  name: attr('string'),
  status: attr('session-status'),
  kind: attr('session-kind'),
  date: attr('date-range'),
  num_rounds: attr('number'),
  current: belongsTo('round', {async: true, inverse: 'current_session'}),
  primary: belongsTo('contest', {async: true, inverse: 'primary_contest'}),
  convention: belongsTo('convention', {async: true}),
  rounds: hasMany('round', {async: true}),
  performers: hasMany('performer', {async: true}),
  contests: hasMany('contest', {async: true}),
  judges: hasMany('judge', {async: true}),
  open: memberAction({path: 'open', type: 'post'}),
  close: memberAction({path: 'close', type: 'post'}),
  validate: memberAction({path: 'validate', type: 'post'}),
  start: memberAction({path: 'start', type: 'post'}),
  finish: memberAction({path: 'finish', type: 'post'}),
  draft: memberAction({path: 'draft', type: 'post'}),
  publish: memberAction({path: 'publish', type: 'post'}),
  cursor: belongsTo('performance', {async: true}),

  performerSortProperties: [
    'performer.totPoints:desc',
    'group.chap_name:asc',
  ],
  sortedPerformers: computed.sort(
    'performers',
    'performerSortProperties'
  ),

  publishedPerformers: computed.filterBy(
    'performers',
    'status',
    'Published'
  ),

  publishedSort: [
    'rank',
    'performer.group.name',
  ],
  sortedPublishedPerformers: computed.sort(
    'publishedPerformers',
    'publishedSort'
  ),

  primaryPerformers: computed.filterBy(
    'publishedPerformers',
    'rank'
  ),
  primarySort: [
    'rank',
    'sng_points:desc',
    'mus_points:desc',
    'prs_points:desc',
  ],
  sortedPrimaryPerformers: computed.sort(
    'primaryPerformers',
    'primarySort'
  ),

  secondaryPerformers: computed.filterBy(
    'publishedPerformers',
    'rank',
    null
  ),
  secondarySort: [
    'total_points:desc',
    'sng_points:desc',
    'mus_points:desc',
    'prs_points:desc',
  ],
  sortedSecondaryPerformers: computed.sort(
    'secondaryPerformers',
    'secondarySort'
  ),

  contestSort: [
    'is_qualifier:asc',
    'award.level:desc',
    'award.organization.name:asc',
    'award.is_primary:desc',
    'award.kind:asc',
    'award.is_improved:asc',
    'award.size:asc',
    'award.scope:asc',
  ],
  sortedContests: computed.sort(
    'contests',
    'contestSort'
  ),

  championshipContests: computed.filterBy(
    'contests',
    'is_qualifier',
    false
  ),

  sortedChampionshipContests: computed.sort(
    'championshipContests',
    'contestSort'
  ),

  qualificationContests: computed.filterBy(
    'contests',
    'is_qualifier',
    true
  ),

  sortedQualificiationContests: computed.sort(
    'qualificationContests',
    'contestSort'
  ),

  judgeSort: [
    'category',
    'kind',
    'slot',
  ],
  sortedJudges: computed.sort(
    'judges',
    'judgeSort'
  ),

  officialJudges: computed.filterBy(
    'judges',
    'kind',
    'Official'
  ),
  sortedOfficialJudges: computed.sort(
    'officialJudges',
    'judgeSort'
  ),

  roundsSort: [
    'num:desc',
  ],
  sortedRounds: computed.sort(
    'rounds',
    'roundsSort'
  ),

  currentPerformancesSort: [
    'num',
  ],
  currentPerformances: computed.sort(
    'current.performances',
    'currentPerformancesSort'
  ),
  ranks: Ember.computed('performers', function() {
    let lastScore = null;
    let lastRank = null;
    return this.get('performers').sortBy('totPoints').reverse().map((competitor, index) => {
       let score = competitor.get('totPoints');
       let rank = score === lastScore ? lastRank : index+1;
       lastScore = score;
       lastRank = rank;
       return {
           score: score,
           rank: rank
       };
    });
  })
});
<|endoftext|>


<commit_before>'use strict';

var Lib = require('../../lib');
var Axes = require('../../plots/cartesian/axes');
var boxHoverPoints = require('../box/hover');
var helpers = require('./helpers');

module.exports = function hoverPoints(pointData, xval, yval, hovermode, opts) {
    if(!opts) opts = {};
    var hoverLayer = opts.hoverLayer;

    var cd = pointData.cd;
    var trace = cd[0].trace;
    var hoveron = trace.hoveron;
    var hasHoveronViolins = hoveron.indexOf('violins') !== -1;
    var hasHoveronKDE = hoveron.indexOf('kde') !== -1;
    var closeData = [];
    var closePtData;
    var violinLineAttrs;

    if(hasHoveronViolins || hasHoveronKDE) {
        var closeBoxData = boxHoverPoints.hoverOnBoxes(pointData, xval, yval, hovermode);

        if(hasHoveronKDE && closeBoxData.length > 0) {
            var xa = pointData.xa;
            var ya = pointData.ya;
            var pLetter, vLetter, pAxis, vAxis, vVal;

            if(trace.orientation === 'h') {
                vVal = xval;
                pLetter = 'y';
                pAxis = ya;
                vLetter = 'x';
                vAxis = xa;
            } else {
                vVal = yval;
                pLetter = 'x';
                pAxis = xa;
                vLetter = 'y';
                vAxis = ya;
            }

            var di = cd[pointData.index];

            if(vVal >= di.span[0] && vVal <= di.span[1]) {
                var kdePointData = Lib.extendFlat({}, pointData);
                var vValPx = vAxis.c2p(vVal, true);
                var kdeVal = helpers.getKdeValue(di, trace, vVal);
                var pOnPath = helpers.getPositionOnKdePath(di, trace, vValPx);
                var paOffset = pAxis._offset;
                var paLength = pAxis._length;

                kdePointData[pLetter + '0'] = pOnPath[0];
                kdePointData[pLetter + '1'] = pOnPath[1];
                kdePointData[vLetter + '0'] = kdePointData[vLetter + '1'] = vValPx;
                kdePointData[vLetter + 'Label'] = vLetter + ': ' + Axes.hoverLabelText(vAxis, vVal, trace[vLetter + 'hoverformat']) + ', ' + cd[0].t.labels.kde + ' ' + kdeVal.toFixed(3);

                // move the spike to the KDE point
                var medId = 0;
                for(var k = 0; k < closeBoxData.length; k++) {
                    if(closeBoxData[k].attr === 'med') {
                        medId = k;
                        break;
                    }
                }

                kdePointData.spikeDistance = closeBoxData[medId].spikeDistance;
                var spikePosAttr = pLetter + 'Spike';
                kdePointData[spikePosAttr] = closeBoxData[medId][spikePosAttr];
                closeBoxData[medId].spikeDistance = undefined;
                closeBoxData[medId][spikePosAttr] = undefined;

                // no hovertemplate support yet
                kdePointData.hovertemplate = false;

                closeData.push(kdePointData);

                violinLineAttrs = {stroke: pointData.color};
                violinLineAttrs[pLetter + '1'] = Lib.constrain(paOffset + pOnPath[0], paOffset, paOffset + paLength);
                violinLineAttrs[pLetter + '2'] = Lib.constrain(paOffset + pOnPath[1], paOffset, paOffset + paLength);
                violinLineAttrs[vLetter + '1'] = violinLineAttrs[vLetter + '2'] = vAxis._offset + vValPx;
            }
        }

        if(hasHoveronViolins) {
            closeData = closeData.concat(closeBoxData);
        }
    }

    if(hoveron.indexOf('points') !== -1) {
        closePtData = boxHoverPoints.hoverOnPoints(pointData, xval, yval);
    }

    // update violin line (if any)
    var violinLine = hoverLayer.selectAll('.violinline-' + trace.uid)
        .data(violinLineAttrs ? [0] : []);
    violinLine.enter().append('line')
        .classed('violinline-' + trace.uid, true)
        .attr('stroke-width', 1.5);
    violinLine.exit().remove();
    violinLine.attr(violinLineAttrs);

    // same combine logic as box hoverPoints
    if(hovermode === 'closest') {
        if(closePtData) return [closePtData];
        return closeData;
    }
    if(closePtData) {
        closeData.push(closePtData);
        return closeData;
    }
    return closeData;
};
<commit_msg>handle transparent colors in violin<commit_after>'use strict';

var tinycolor = require('tinycolor2');

var Color = require('../../components/color');
var Lib = require('../../lib');
var Axes = require('../../plots/cartesian/axes');
var boxHoverPoints = require('../box/hover');
var helpers = require('./helpers');

module.exports = function hoverPoints(pointData, xval, yval, hovermode, opts) {
    if(!opts) opts = {};
    var hoverLayer = opts.hoverLayer;

    var cd = pointData.cd;
    var trace = cd[0].trace;
    var hoveron = trace.hoveron;
    var hasHoveronViolins = hoveron.indexOf('violins') !== -1;
    var hasHoveronKDE = hoveron.indexOf('kde') !== -1;
    var closeData = [];
    var closePtData;
    var violinLineAttrs;

    if(hasHoveronViolins || hasHoveronKDE) {
        var closeBoxData = boxHoverPoints.hoverOnBoxes(pointData, xval, yval, hovermode);

        if(hasHoveronKDE && closeBoxData.length > 0) {
            var xa = pointData.xa;
            var ya = pointData.ya;
            var pLetter, vLetter, pAxis, vAxis, vVal;

            if(trace.orientation === 'h') {
                vVal = xval;
                pLetter = 'y';
                pAxis = ya;
                vLetter = 'x';
                vAxis = xa;
            } else {
                vVal = yval;
                pLetter = 'x';
                pAxis = xa;
                vLetter = 'y';
                vAxis = ya;
            }

            var di = cd[pointData.index];

            if(vVal >= di.span[0] && vVal <= di.span[1]) {
                var kdePointData = Lib.extendFlat({}, pointData);
                var vValPx = vAxis.c2p(vVal, true);
                var kdeVal = helpers.getKdeValue(di, trace, vVal);
                var pOnPath = helpers.getPositionOnKdePath(di, trace, vValPx);
                var paOffset = pAxis._offset;
                var paLength = pAxis._length;

                kdePointData[pLetter + '0'] = pOnPath[0];
                kdePointData[pLetter + '1'] = pOnPath[1];
                kdePointData[vLetter + '0'] = kdePointData[vLetter + '1'] = vValPx;
                kdePointData[vLetter + 'Label'] = vLetter + ': ' + Axes.hoverLabelText(vAxis, vVal, trace[vLetter + 'hoverformat']) + ', ' + cd[0].t.labels.kde + ' ' + kdeVal.toFixed(3);

                // move the spike to the KDE point
                var medId = 0;
                for(var k = 0; k < closeBoxData.length; k++) {
                    if(closeBoxData[k].attr === 'med') {
                        medId = k;
                        break;
                    }
                }

                kdePointData.spikeDistance = closeBoxData[medId].spikeDistance;
                var spikePosAttr = pLetter + 'Spike';
                kdePointData[spikePosAttr] = closeBoxData[medId][spikePosAttr];
                closeBoxData[medId].spikeDistance = undefined;
                closeBoxData[medId][spikePosAttr] = undefined;

                // no hovertemplate support yet
                kdePointData.hovertemplate = false;

                closeData.push(kdePointData);

                var strokeC = pointData.color;
                var strokeColor = tinycolor(strokeC);
                var strokeAlpha = strokeColor.getAlpha();
                var strokeRGB = Color.tinyRGB(strokeColor);

                violinLineAttrs = {
                    stroke: strokeRGB,
                    'stroke-opacity': strokeAlpha
                };
                violinLineAttrs[pLetter + '1'] = Lib.constrain(paOffset + pOnPath[0], paOffset, paOffset + paLength);
                violinLineAttrs[pLetter + '2'] = Lib.constrain(paOffset + pOnPath[1], paOffset, paOffset + paLength);
                violinLineAttrs[vLetter + '1'] = violinLineAttrs[vLetter + '2'] = vAxis._offset + vValPx;
            }
        }

        if(hasHoveronViolins) {
            closeData = closeData.concat(closeBoxData);
        }
    }

    if(hoveron.indexOf('points') !== -1) {
        closePtData = boxHoverPoints.hoverOnPoints(pointData, xval, yval);
    }

    // update violin line (if any)
    var violinLine = hoverLayer.selectAll('.violinline-' + trace.uid)
        .data(violinLineAttrs ? [0] : []);
    violinLine.enter().append('line')
        .classed('violinline-' + trace.uid, true)
        .attr('stroke-width', 1.5);
    violinLine.exit().remove();
    violinLine.attr(violinLineAttrs);

    // same combine logic as box hoverPoints
    if(hovermode === 'closest') {
        if(closePtData) return [closePtData];
        return closeData;
    }
    if(closePtData) {
        closeData.push(closePtData);
        return closeData;
    }
    return closeData;
};
<|endoftext|>


<commit_before>'use strict';

//  ---------------------------------------------------------------------------

const Exchange = require ('./base/Exchange');
const { ExchangeError, AuthenticationError, ArgumentsRequired } = require ('./base/errors');

//  ---------------------------------------------------------------------------

module.exports = class ice3x extends Exchange {
    describe () {
        return this.deepExtend (super.describe (), {
            'id': 'ice3x',
            'name': 'ICE3X',
            'countries': [ 'ZA' ], // South Africa
            'rateLimit': 1000,
            'version': 'v1',
            'has': {
                'cancelOrder': true,
                'createOrder': true,
                'fetchBalance': true,
                'fetchCurrencies': true,
                'fetchDepositAddress': true,
                'fetchMarkets': true,
                'fetchMyTrades': true,
                'fetchOpenOrders': true,
                'fetchOrder': true,
                'fetchOrderBook': true,
                'fetchTicker': true,
                'fetchTickers': true,
                'fetchTrades': true,
            },
            'urls': {
                'logo': 'https://user-images.githubusercontent.com/51840849/87460809-1dd06c00-c616-11ea-98ad-7d5e1cb7fcdd.jpg',
                'api': 'https://ice3x.com/api',
                'www': 'https://ice3x.com', // 'https://ice3x.co.za',
                'doc': 'https://ice3x.co.za/ice-cubed-bitcoin-exchange-api-documentation-1-june-2017',
                'fees': [
                    'https://help.ice3.com/support/solutions/articles/11000033293-trading-fees',
                    'https://help.ice3.com/support/solutions/articles/11000033288-fees-explained',
                    'https://help.ice3.com/support/solutions/articles/11000008131-what-are-your-fiat-deposit-and-withdrawal-fees-',
                    'https://help.ice3.com/support/solutions/articles/11000033289-deposit-fees',
                ],
                'referral': 'https://ice3x.com?ref=14341802',
            },
            'api': {
                'public': {
                    'get': [
                        'currency/list',
                        'currency/info',
                        'pair/list',
                        'pair/info',
                        'stats/marketdepthfull',
                        'stats/marketdepthbtcav',
                        'stats/marketdepth',
                        'orderbook/info',
                        'trade/list',
                        'trade/info',
                    ],
                },
                'private': {
                    'post': [
                        'balance/list',
                        'balance/info',
                        'order/new',
                        'order/cancel',
                        'order/list',
                        'order/info',
                        'trade/list',
                        'trade/info',
                        'transaction/list',
                        'transaction/info',
                        'invoice/list',
                        'invoice/info',
                        'invoice/pdf',
                    ],
                },
            },
            'fees': {
                'trading': {
                    'maker': 0.005,
                    'taker': 0.005,
                },
            },
            'precision': {
                'amount': 8,
                'price': 8,
            },
        });
    }

    async fetchCurrencies (params = {}) {
        const response = await this.publicGetCurrencyList (params);
        const currencies = response['response']['entities'];
        const precision = this.precision['amount'];
        const result = {};
        for (let i = 0; i < currencies.length; i++) {
            const currency = currencies[i];
            const id = this.safeString (currency, 'currency_id');
            const currencyId = this.safeString (currency, 'iso');
            const code = this.safeCurrencyCode (currencyId);
            result[code] = {
                'id': id,
                'code': code,
                'name': currency['name'],
                'active': true,
                'precision': precision,
                'limits': {
                    'amount': {
                        'min': undefined,
                        'max': Math.pow (10, precision),
                    },
                    'price': {
                        'min': Math.pow (10, -precision),
                        'max': Math.pow (10, precision),
                    },
                    'cost': {
                        'min': undefined,
                        'max': undefined,
                    },
                },
                'info': currency,
                'fee': undefined,
            };
        }
        return result;
    }

    async fetchMarkets (params = {}) {
        if (this.currencies_by_id === undefined) {
            this.currencies = await this.fetchCurrencies ();
            this.currencies_by_id = this.indexBy (this.currencies, 'id');
        }
        const response = await this.publicGetPairList (params);
        const markets = this.safeValue (response['response'], 'entities');
        const result = [];
        for (let i = 0; i < markets.length; i++) {
            const market = markets[i];
            const id = this.safeString (market, 'pair_id');
            const baseId = this.safeString (market, 'currency_id_from');
            const quoteId = this.safeString (market, 'currency_id_to');
            const baseCurrency = this.currencies_by_id[baseId];
            const quoteCurrency = this.currencies_by_id[quoteId];
            const base = baseCurrency['code'];
            const quote = quoteCurrency['code'];
            const symbol = base + '/' + quote;
            result.push ({
                'id': id,
                'symbol': symbol,
                'base': base,
                'quote': quote,
                'baseId': baseId,
                'quoteId': quoteId,
                'active': undefined,
                'info': market,
                'precision': this.precision,
                'limits': this.limits,
            });
        }
        return result;
    }

    parseTicker (ticker, market = undefined) {
        const timestamp = this.milliseconds ();
        const symbol = market['symbol'];
        const last = this.safeFloat (ticker, 'last_price');
        return {
            'symbol': symbol,
            'timestamp': timestamp,
            'datetime': this.iso8601 (timestamp),
            'high': this.safeFloat (ticker, 'max'),
            'low': this.safeFloat (ticker, 'min'),
            'bid': this.safeFloat (ticker, 'max_bid'),
            'bidVolume': undefined,
            'ask': this.safeFloat (ticker, 'min_ask'),
            'askVolume': undefined,
            'vwap': undefined,
            'open': undefined,
            'close': last,
            'last': last,
            'previousClose': undefined,
            'change': undefined,
            'percentage': undefined,
            'average': this.safeFloat (ticker, 'avg'),
            'baseVolume': undefined,
            'quoteVolume': this.safeFloat (ticker, 'vol'),
            'info': ticker,
        };
    }

    async fetchTicker (symbol, params = {}) {
        await this.loadMarkets ();
        const market = this.market (symbol);
        const request = {
            'pair_id': market['id'],
        };
        const response = await this.publicGetStatsMarketdepthfull (this.extend (request, params));
        const ticker = this.safeValue (response['response'], 'entity');
        return this.parseTicker (ticker, market);
    }

    async fetchTickers (symbols = undefined, params = {}) {
        await this.loadMarkets ();
        const response = await this.publicGetStatsMarketdepthfull (params);
        const tickers = this.safeValue (response['response'], 'entities');
        const result = {};
        for (let i = 0; i < tickers.length; i++) {
            const ticker = tickers[i];
            const marketId = this.safeString (ticker, 'pair_id');
            const market = this.safeValue (this.marketsById, marketId);
            if (market !== undefined) {
                const symbol = market['symbol'];
                result[symbol] = this.parseTicker (ticker, market);
            }
        }
        return this.filterByArray (result, 'symbol', symbols);
    }

    async fetchOrderBook (symbol, limit = undefined, params = {}) {
        await this.loadMarkets ();
        const request = {
            'pair_id': this.marketId (symbol),
        };
        if (limit !== undefined) {
            const type = this.safeString (params, 'type');
            if ((type !== 'ask') && (type !== 'bid')) {
                // eslint-disable-next-line quotes
                throw new ArgumentsRequired (this.id + " fetchOrderBook() requires an exchange-specific extra 'type' param ('bid' or 'ask') when used with a limit");
            } else {
                request['items_per_page'] = limit;
            }
        }
        const response = await this.publicGetOrderbookInfo (this.extend (request, params));
        const orderbook = this.safeValue (response['response'], 'entities');
        return this.parseOrderBook (orderbook, undefined, 'bids', 'asks', 'price', 'amount');
    }

    parseTrade (trade, market = undefined) {
        const timestamp = this.safeTimestamp (trade, 'created');
        const price = this.safeFloat (trade, 'price');
        const amount = this.safeFloat (trade, 'volume');
        let cost = undefined;
        if (price !== undefined) {
            if (amount !== undefined) {
                cost = price * amount;
            }
        }
        let fee = undefined;
        const feeCost = this.safeFloat (trade, 'fee');
        if (feeCost !== undefined) {
            fee = {
                'cost': feeCost,
                'currency': market['quote'],
            };
        }
        const type = 'limit';
        const side = this.safeString (trade, 'type');
        const id = this.safeString (trade, 'trade_id');
        let symbol = undefined;
        if (market !== undefined) {
            symbol = market['symbol'];
        }
        return {
            'id': id,
            'info': trade,
            'timestamp': timestamp,
            'datetime': this.iso8601 (timestamp),
            'symbol': symbol,
            'order': undefined,
            'type': type,
            'side': side,
            'takerOrMaker': undefined,
            'price': price,
            'amount': amount,
            'cost': cost,
            'fee': fee,
        };
    }

    async fetchTrades (symbol, since = undefined, limit = undefined, params = {}) {
        await this.loadMarkets ();
        const market = this.market (symbol);
        const request = {
            'pair_id': market['id'],
        };
        const response = await this.publicGetTradeList (this.extend (request, params));
        const trades = this.safeValue (response['response'], 'entities');
        return this.parseTrades (trades, market, since, limit);
    }

    async fetchBalance (params = {}) {
        await this.loadMarkets ();
        const response = await this.privatePostBalanceList (params);
        const result = { 'info': response };
        const balances = this.safeValue (response['response'], 'entities', []);
        for (let i = 0; i < balances.length; i++) {
            const balance = balances[i];
            // currency ids are numeric strings
            const currencyId = this.safeString (balance, 'currency_id');
            const code = this.safeCurrencyCode (currencyId);
            const account = this.account ();
            account['total'] = this.safeFloat (balance, 'balance');
            result[code] = account;
        }
        return this.parseBalance (result);
    }

    parseOrder (order, market = undefined) {
        const pairId = this.safeInteger (order, 'pair_id');
        let symbol = undefined;
        if (pairId && !market && (pairId in this.marketsById)) {
            market = this.marketsById[pairId];
            symbol = market['symbol'];
        }
        const timestamp = this.safeTimestamp (order, 'created');
        const price = this.safeFloat (order, 'price');
        const amount = this.safeFloat (order, 'volume');
        let status = this.safeInteger (order, 'active');
        let remaining = this.safeFloat (order, 'remaining');
        let filled = undefined;
        if (status === 1) {
            status = 'open';
        } else {
            status = 'closed';
            remaining = 0;
            filled = amount;
        }
        let fee = undefined;
        const feeCost = this.safeFloat (order, 'fee');
        if (feeCost !== undefined) {
            fee = {
                'cost': feeCost,
            };
            if (market !== undefined) {
                fee['currency'] = market['quote'];
            }
        }
        return {
            'id': this.safeString (order, 'order_id'),
            'clientOrderId': undefined,
            'datetime': this.iso8601 (timestamp),
            'timestamp': timestamp,
            'lastTradeTimestamp': undefined,
            'status': status,
            'symbol': symbol,
            'type': 'limit',
            'timeInForce': undefined,
            'postOnly': undefined,
            'side': this.safeString (order, 'type'),
            'price': price,
            'stopPrice': undefined,
            'cost': undefined,
            'amount': amount,
            'filled': filled,
            'remaining': remaining,
            'trades': undefined,
            'fee': fee,
            'info': order,
            'average': undefined,
        };
    }

    async createOrder (symbol, type, side, amount, price = undefined, params = {}) {
        await this.loadMarkets ();
        const market = this.market (symbol);
        const request = {
            'pair_id': market['id'],
            'type': side,
            'amount': amount,
            'price': price,
        };
        const response = await this.privatePostOrderNew (this.extend (request, params));
        const order = this.parseOrder ({
            'order_id': response['response']['entity']['order_id'],
            'created': this.seconds (),
            'active': 1,
            'type': side,
            'price': price,
            'volume': amount,
            'remaining': amount,
            'info': response,
        }, market);
        return order;
    }

    async cancelOrder (id, symbol = undefined, params = {}) {
        const request = {
            'order_id': id,
        };
        return await this.privatePostOrderCancel (this.extend (request, params));
    }

    async fetchOrder (id, symbol = undefined, params = {}) {
        await this.loadMarkets ();
        const request = {
            'order _id': id,
        };
        const response = await this.privatePostOrderInfo (this.extend (request, params));
        const data = this.safeValue (response, 'response', {});
        const order = this.safeValue (data, 'entity');
        return this.parseOrder (order);
    }

    async fetchOpenOrders (symbol = undefined, since = undefined, limit = undefined, params = {}) {
        await this.loadMarkets ();
        const response = await this.privatePostOrderList (params);
        const data = this.safeValue (response, 'response', {});
        const orders = this.safeValue (data, 'entities', []);
        let market = undefined;
        if (symbol !== undefined) {
            market = this.market (symbol);
        }
        return this.parseOrders (orders, market, since, limit);
    }

    async fetchMyTrades (symbol = undefined, since = undefined, limit = undefined, params = {}) {
        await this.loadMarkets ();
        const market = this.market (symbol);
        const request = {
            'pair_id': market['id'],
        };
        if (limit !== undefined) {
            request['items_per_page'] = limit;
        }
        if (since !== undefined) {
            request['date_from'] = parseInt (since / 1000);
        }
        const response = await this.privatePostTradeList (this.extend (request, params));
        const data = this.safeValue (response, 'response', {});
        const trades = this.safeValue (data, 'entities', []);
        return this.parseTrades (trades, market, since, limit);
    }

    async fetchDepositAddress (code, params = {}) {
        await this.loadMarkets ();
        const currency = this.currency (code);
        const request = {
            'currency_id': currency['id'],
        };
        const response = await this.privatePostBalanceInfo (this.extend (request, params));
        const data = this.safeValue (response, 'response', {});
        const balance = this.safeValue (data, 'entity', {});
        const address = this.safeString (balance, 'address');
        const status = address ? 'ok' : 'none';
        return {
            'currency': code,
            'address': address,
            'tag': undefined,
            'status': status,
            'info': response,
        };
    }

    sign (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
        let url = this.urls['api'] + '/' + this.version + '/' + path;
        if (api === 'public') {
            if (Object.keys (params).length) {
                url += '?' + this.urlencode (params);
            }
        } else {
            this.checkRequiredCredentials ();
            body = this.urlencode (this.extend ({
                'nonce': this.nonce (),
            }, params));
            headers = {
                'Content-Type': 'application/x-www-form-urlencoded',
                'Key': this.apiKey,
                'Sign': this.hmac (this.encode (body), this.encode (this.secret), 'sha512'),
            };
        }
        return { 'url': url, 'method': method, 'body': body, 'headers': headers };
    }

    async request (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
        const response = await this.fetch2 (path, api, method, params, headers, body);
        const errors = this.safeValue (response, 'errors');
        const data = this.safeValue (response, 'response');
        if (errors || !data) {
            const authErrorKeys = [ 'Key', 'user_id', 'Sign' ];
            for (let i = 0; i < authErrorKeys.length; i++) {
                const errorKey = authErrorKeys[i];
                const errorMessage = this.safeString (errors, errorKey);
                if (!errorMessage) {
                    continue;
                }
                if (errorKey === 'user_id' && errorMessage.indexOf ('authorization') < 0) {
                    continue;
                }
                throw new AuthenticationError (errorMessage);
            }
            throw new ExchangeError (this.json (errors));
        }
        return response;
    }
};
<commit_msg>delist ice3x<commit_after><|endoftext|>


<commit_before>$(function() {
    console.log( "Ready!" );

    var style1 = {
    	  style: "montclair",
        colors: ['Hydra', 'Indigo']
    };

    var style2 = {
    	  style: "uptown",
        colors: ['Platinum', 'Sundown', 'Vanilla', 'Wasabi']
    };

    var data=style1;
    var ncolor=0;
    var pillow = $('#pillows .selected').attr('src').replace(/\.[^.$]+$/, '').split('/')[2];

    changeStyle(data);

    $('#styles img').click(function(){
      $('#styles img').removeClass('selected');
      $(this).addClass('selected');

      var style = $(this).attr('src').replace(/\.[^.$]+$/, '').split('/')[2];
      console.log(style);

      if(style=="uptown"){
        data = style2;
      }else if(style == "montclair"){
        data = style1;
      }

      changeStyle(data);
      changeColor(ncolor);

    });

    $('#colors img').click(function(){
      $('#colors img').removeClass('selected');
      $(this).addClass('selected');

      color = $(this).attr('src').replace(/\.[^.$]+$/, '').split('/')[2];
      console.log(color);

      ncolor = data.colors.indexOf(color);
      changeColor(ncolor);
    });

    function changeStyle(data){
      var template = $('#template').html();
      var rendered = Mustache.render(template, data);
      $('#dif-colors').html(rendered);
      $('#colors img')[0].setAttribute("class", "thumb selected");
      ncolor=0;
      setPreviewImage(data, ncolor, pillow);
    }

    function changeColor(ncolor){
      setPreviewImage(data, ncolor, pillow);
    }
    /**
     * Set the preview image
     * @param style [A string for unique styles]
     * @param color [A string for unique colors]
     */
    function setPreviewImage(data, ncolor, pillow){
    	var preview = $(".preview img");
    	var source = "images/previews/"+data.colors[0]+"_"+data.style+".jpeg";
    	preview.attr('src', source);
    }
});<commit_msg>delete index_.js<commit_after><|endoftext|>