<commit_before>import Ember from 'ember';
import GetText from 'i18n';

/**
 * This service translates through gettext.js.
 * There are two available methods to be used
 * for translations message ids from JS source:
 *
 * - t(msgid, hash);
 * - n(msgid, msgidPlural, count, hash);
 *
 * Furthermore, there's an auto initialization
 * feature (default: true), which detects user's
 * locale according to system preferences. If the
 * user's locale is supported in `availableLocales`,
 * the corresponding translations are loaded. If the
 * user's locale is not supported, the default locale
 * will be used instead (default: 'en'). Please use the
 * following method to change locales:
 *
 * - setLocale(locale);
 *
 * The following utility methods are also availalbe:
 *
 * - hasLocale(locale);
 * - detectLocale();
 *
 * To configure the path of the JSON files (depending on
 * the path configured via gettext.sh extractor) use the
 * `jsonPath` property (default: '/assets/locales').
 *
 * @namespace Service
 * @class L10N
 * @extends Ember.Service
 * @extends Ember.Evented
 * @public
 */
export default Ember.Service.extend(Ember.Evented, {
  // -------------------------------------------------------------------------
  // Dependencies

  ajax: Ember.inject.service('l10n-ajax'),

  // -------------------------------------------------------------------------
  // Properties

  /**
   * Current locale from user, defaults
   * to 'defaultLocale' if not retrievable
   * or currently available due to missing
   * translations.
   *
   * @property locale
   * @type {String}
   * @default null
   * @public
   */
  locale: null,

  /**
   * Use this property if you want to force
   * a specific locale and skip automatic
   * detection of user's system settings.
   * This is useful for signed in users,
   * but beware that unsupported locales
   * will fallback to the default locale!
   *
   * @property forceLocale
   * @type {String}
   * @default null
   * @public
   */
  forceLocale: null,

  /**
   * Fallback locale for unavailable locales.
   *
   * @property defaultLocale
   * @type {String}
   * @default 'en'
   * @public
   */
  defaultLocale: 'en',

  /**
   * Will invoke a language detection or loads
   * language from `forceLanguage` on service
   * instantiation. If disabling, make sure to
   * set locale manually with setLocale().
   *
   * @property autoInitialize
   * @type {String}
   * @default null
   * @public
   */
  autoInitialize: true,

  /**
   * Directory containing JSON files with all
   * translations for corresponding locale.
   *
   * @property jsonPath
   * @type {String}
   * @default 'assets/locales'
   * @public
   */
  jsonPath: '/assets/locales',

  /**
   * Currently available translations hash.
   *
   * @property availableLocales
   * @type {Object}
   * @public
   */
  availableLocales: Ember.computed(function() {
    return {
      'en': this.t('en')
    };
  }),

  /**
   * Cache persisting loaded JSON files to
   * avoid duplicated requests going out.
   *
   * @property _cache
   * @type {Object}
   * @default {}
   * @private
   */
  _cache: Ember.computed(function() {
    return {}; // complex type!
  }),

  /**
   * Reference to gettext library. This gets
   * lazily initialized within `init` method.
   *
   * @property _gettext
   * @type {String}
   * @default null
   * @private
   */
  _gettext: null,

  // -------------------------------------------------------------------------
  // Methods

  /**
   * Sets initial locale. If you want to to
   * skip language detection, please provide
   * `forceLocale` property with reopen().
   *
   * @method init
   * @return {Void}
   * @public
   */
  init() {
    this._super(...arguments);
    this.set('_gettext', new GetText());
    if (!this.get('autoInitialize')) {
      return;
    }

    this.setLocale(this.detectLocale());
  },

  /**
   * Provides current locale. If not set,
   * delivers default locale.
   *
   * @method setLocale
   * @param {String} locale
   * @return {String}
   * @public
   */
  getLocale() {
    let defaultLocale = this.get('defaultLocale');
    let locale = this.get('locale');
    if (Ember.isNone(locale)) {
      return defaultLocale;
    }

    return locale;
  },

  /**
   * Sets active locale if available. Returns a
   * RSPV Promise for asynchronous JSON request.
   *
   * @method setLocale
   * @param {String} locale
   * @return {RSVP.Promise}
   * @public
   */
  setLocale(locale) {
    if (!this.hasLocale(locale)) {
      return;
    }

    console.info(`l10n.js: Locale set to: "${locale}"`);
    this.set('locale', locale);
    this.get('_gettext').setLocale(locale);

    return this._loadJSON();
  },

  /**
   * Checks if locale is available.
   *
   * @method setLocale
   * @param {String} locale
   * @return {Boolean}
   * @public
   */
  hasLocale(locale) {
    let availableLocales = this.get('availableLocales');
    let hasLocale = !Ember.isNone(availableLocales[locale]);
    if (!hasLocale) {
      console.warn(`l10n.js: Locale "${locale}" is not available!`);
    }

    return hasLocale;
  },

  /**
   * Gets user's current client language and
   * provides extracted ISO-Code.
   *
   * @method detectLocale
   * @return {String}
   * @public
   */
  detectLocale() {
    let defaultLocale = this.get('defaultLocale');
    let forceLocale = this.get('forceLocale');
    let { navigator } = window;
    let locale;

    // auto detect locale if no force locale
    if (Ember.isNone(forceLocale)) {

      // special case: android user agents
      if (navigator && navigator.userAgent &&
        (locale = navigator.userAgent.match(
          /android.*\W(\w\w)-(\w\w)\W/i
        ))
      ) {
        locale = locale[1];
      }

      // for all other browsers
      if (Ember.isNone(locale) && navigator) {
        if (navigator.language) {
          locale = navigator.language;
        } else if (navigator.browserLanguage) {
          locale = navigator.browserLanguage;
        } else if (navigator.systemLanguage) {
          locale = navigator.systemLanguage;
        } else if (navigator.userLanguage) {
          locale = navigator.userLanguage;
        }
      }

      locale = locale.substr(0, 2);
    } else {
      locale = forceLocale;
    }

    // provide default locale if not available
    if (!this.hasLocale(locale)) {
      console.info(`l10n.js: Falling back to default language: "${defaultLocale}"!`);
      return defaultLocale;
    }

    // otherwise return detected locale
    if (Ember.isNone(forceLocale)) {
      console.info(`l10n.js: Automatically detected user language: "${locale}"`);
    } else {
      console.info(`l10n.js: Using forced locale: "${locale}"`);
    }

    return locale;
  },

  /**
   * Translates a singular form message id.
   *
   * @method t
   * @param {String} msgid
   * @param {Object} hash
   * @return {String}
   * @public
   */
  t(msgid, hash = {}) {
    if (Ember.typeOf(msgid) !== 'string') {
      try {
        msgid = msgid.toString();
      } catch (e) {
        console.log('l10n.js: "msgid" param for t() should be either a string or an object implementing toString() method!');
        return msgid;
      }
    }

    return this._strfmt(this.get('_gettext').gettext(msgid), hash);
  },

  /**
   * Translates a plural form message id.
   *
   * @method n
   * @param {String} msgid
   * @param {String} msgidPlural
   * @param {Number} count
   * @param {Object} hash
   * @return {String}
   * @public
   */
  n(msgid, msgidPlural, count = 1, hash = {}) {
    if (Ember.typeOf(msgid) !== 'string') {
      try {
        msgid = msgid.toString();
      } catch (e) {
        console.log('l10n.js: "msgid" param for n() should be either a string or an object implementing toString() method!');
        return msgid;
      }
    }

    if (Ember.typeOf(msgidPlural) !== 'string') {
      try {
        msgidPlural = msgidPlural.toString();
      } catch (e) {
        console.log('l10n.js: "msgid_plural" param for n() should be either a string or an object implementing toString() method!');
        return msgid;
      }
    }

    return this._strfmt(this.get('_gettext').ngettext(msgid, msgidPlural, count), hash);
  },

  /**
   * Replaces placeholders like {{placeholder}} from string.
   *
   * @method _strfmt
   * @param {String} string
   * @param {Object} hash
   * @return {String}
   * @private
   */
  _strfmt(string, hash) {
    // don't process empty hashes
    if (Ember.isNone(hash)) {
      return string;
    }

    // find and replace all {{placeholder}}
    let pattern = /{{\s*([\w]+)\s*}}/g;
    let replace = (idx, match) => {
      let value = hash[match];
      if (Ember.isNone(value)) {
        return `{{${match}}}`;
      }

      if (Ember.typeOf(value) === 'string') {
        value = this.get('_gettext').gettext(value);
      }

      return value;
    };

    return string.replace(pattern, replace);
  },

  /**
   * Loads current locale translation file.
   * Triggers `translation_loaded` event.
   *
   * @method _load
   * @return {Void}
   * @private
   */
  _loadJSON() {
    let ajax = this.get('ajax');
    let cache = this.get('_cache');
    let locale = this.get('locale');
    let url = `${this.get('jsonPath')}/${locale}.json`;

    let successCallback = (response) => {
      let cachedResponse = Ember.copy(response, true);
      this.notifyPropertyChange('availableLocales');
      this.get('_gettext').loadJSON(response);

      this.trigger('translation_loaded');
      cache[locale] = cachedResponse;
    };

    let failureCallback = (reason) => {
      console.error(`l10n.js: An error occured loading "${url}": ${reason}`);
    };

    // used cache translation if present
    if (cache.hasOwnProperty(locale)) {
      successCallback(cache[locale]);
      return;
    }

    // otherwise load json file from assets
    return ajax.request(url).then(
      successCallback,
      failureCallback
    );
  }

});
<commit_msg>Remove console.info output in setLocale<commit_after>import Ember from 'ember';
import GetText from 'i18n';

/**
 * This service translates through gettext.js.
 * There are two available methods to be used
 * for translations message ids from JS source:
 *
 * - t(msgid, hash);
 * - n(msgid, msgidPlural, count, hash);
 *
 * Furthermore, there's an auto initialization
 * feature (default: true), which detects user's
 * locale according to system preferences. If the
 * user's locale is supported in `availableLocales`,
 * the corresponding translations are loaded. If the
 * user's locale is not supported, the default locale
 * will be used instead (default: 'en'). Please use the
 * following method to change locales:
 *
 * - setLocale(locale);
 *
 * The following utility methods are also availalbe:
 *
 * - hasLocale(locale);
 * - detectLocale();
 *
 * To configure the path of the JSON files (depending on
 * the path configured via gettext.sh extractor) use the
 * `jsonPath` property (default: '/assets/locales').
 *
 * @namespace Service
 * @class L10N
 * @extends Ember.Service
 * @extends Ember.Evented
 * @public
 */
export default Ember.Service.extend(Ember.Evented, {
  // -------------------------------------------------------------------------
  // Dependencies

  ajax: Ember.inject.service('l10n-ajax'),

  // -------------------------------------------------------------------------
  // Properties

  /**
   * Current locale from user, defaults
   * to 'defaultLocale' if not retrievable
   * or currently available due to missing
   * translations.
   *
   * @property locale
   * @type {String}
   * @default null
   * @public
   */
  locale: null,

  /**
   * Use this property if you want to force
   * a specific locale and skip automatic
   * detection of user's system settings.
   * This is useful for signed in users,
   * but beware that unsupported locales
   * will fallback to the default locale!
   *
   * @property forceLocale
   * @type {String}
   * @default null
   * @public
   */
  forceLocale: null,

  /**
   * Fallback locale for unavailable locales.
   *
   * @property defaultLocale
   * @type {String}
   * @default 'en'
   * @public
   */
  defaultLocale: 'en',

  /**
   * Will invoke a language detection or loads
   * language from `forceLanguage` on service
   * instantiation. If disabling, make sure to
   * set locale manually with setLocale().
   *
   * @property autoInitialize
   * @type {String}
   * @default null
   * @public
   */
  autoInitialize: true,

  /**
   * Directory containing JSON files with all
   * translations for corresponding locale.
   *
   * @property jsonPath
   * @type {String}
   * @default 'assets/locales'
   * @public
   */
  jsonPath: '/assets/locales',

  /**
   * Currently available translations hash.
   *
   * @property availableLocales
   * @type {Object}
   * @public
   */
  availableLocales: Ember.computed(function() {
    return {
      'en': this.t('en')
    };
  }),

  /**
   * Cache persisting loaded JSON files to
   * avoid duplicated requests going out.
   *
   * @property _cache
   * @type {Object}
   * @default {}
   * @private
   */
  _cache: Ember.computed(function() {
    return {}; // complex type!
  }),

  /**
   * Reference to gettext library. This gets
   * lazily initialized within `init` method.
   *
   * @property _gettext
   * @type {String}
   * @default null
   * @private
   */
  _gettext: null,

  // -------------------------------------------------------------------------
  // Methods

  /**
   * Sets initial locale. If you want to to
   * skip language detection, please provide
   * `forceLocale` property with reopen().
   *
   * @method init
   * @return {Void}
   * @public
   */
  init() {
    this._super(...arguments);
    this.set('_gettext', new GetText());
    if (!this.get('autoInitialize')) {
      return;
    }

    this.setLocale(this.detectLocale());
  },

  /**
   * Provides current locale. If not set,
   * delivers default locale.
   *
   * @method setLocale
   * @param {String} locale
   * @return {String}
   * @public
   */
  getLocale() {
    let defaultLocale = this.get('defaultLocale');
    let locale = this.get('locale');
    if (Ember.isNone(locale)) {
      return defaultLocale;
    }

    return locale;
  },

  /**
   * Sets active locale if available. Returns a
   * RSPV Promise for asynchronous JSON request.
   *
   * @method setLocale
   * @param {String} locale
   * @return {RSVP.Promise}
   * @public
   */
  setLocale(locale) {
    if (!this.hasLocale(locale)) {
      return;
    }

    this.set('locale', locale);
    this.get('_gettext').setLocale(locale);

    return this._loadJSON();
  },

  /**
   * Checks if locale is available.
   *
   * @method setLocale
   * @param {String} locale
   * @return {Boolean}
   * @public
   */
  hasLocale(locale) {
    let availableLocales = this.get('availableLocales');
    let hasLocale = !Ember.isNone(availableLocales[locale]);
    if (!hasLocale) {
      console.warn(`l10n.js: Locale "${locale}" is not available!`);
    }

    return hasLocale;
  },

  /**
   * Gets user's current client language and
   * provides extracted ISO-Code.
   *
   * @method detectLocale
   * @return {String}
   * @public
   */
  detectLocale() {
    let defaultLocale = this.get('defaultLocale');
    let forceLocale = this.get('forceLocale');
    let { navigator } = window;
    let locale;

    // auto detect locale if no force locale
    if (Ember.isNone(forceLocale)) {

      // special case: android user agents
      if (navigator && navigator.userAgent &&
        (locale = navigator.userAgent.match(
          /android.*\W(\w\w)-(\w\w)\W/i
        ))
      ) {
        locale = locale[1];
      }

      // for all other browsers
      if (Ember.isNone(locale) && navigator) {
        if (navigator.language) {
          locale = navigator.language;
        } else if (navigator.browserLanguage) {
          locale = navigator.browserLanguage;
        } else if (navigator.systemLanguage) {
          locale = navigator.systemLanguage;
        } else if (navigator.userLanguage) {
          locale = navigator.userLanguage;
        }
      }

      locale = locale.substr(0, 2);
    } else {
      locale = forceLocale;
    }

    // provide default locale if not available
    if (!this.hasLocale(locale)) {
      console.info(`l10n.js: Falling back to default language: "${defaultLocale}"!`);
      return defaultLocale;
    }

    // otherwise return detected locale
    if (Ember.isNone(forceLocale)) {
      console.info(`l10n.js: Automatically detected user language: "${locale}"`);
    } else {
      console.info(`l10n.js: Using forced locale: "${locale}"`);
    }

    return locale;
  },

  /**
   * Translates a singular form message id.
   *
   * @method t
   * @param {String} msgid
   * @param {Object} hash
   * @return {String}
   * @public
   */
  t(msgid, hash = {}) {
    if (Ember.typeOf(msgid) !== 'string') {
      try {
        msgid = msgid.toString();
      } catch (e) {
        console.log('l10n.js: "msgid" param for t() should be either a string or an object implementing toString() method!');
        return msgid;
      }
    }

    return this._strfmt(this.get('_gettext').gettext(msgid), hash);
  },

  /**
   * Translates a plural form message id.
   *
   * @method n
   * @param {String} msgid
   * @param {String} msgidPlural
   * @param {Number} count
   * @param {Object} hash
   * @return {String}
   * @public
   */
  n(msgid, msgidPlural, count = 1, hash = {}) {
    if (Ember.typeOf(msgid) !== 'string') {
      try {
        msgid = msgid.toString();
      } catch (e) {
        console.log('l10n.js: "msgid" param for n() should be either a string or an object implementing toString() method!');
        return msgid;
      }
    }

    if (Ember.typeOf(msgidPlural) !== 'string') {
      try {
        msgidPlural = msgidPlural.toString();
      } catch (e) {
        console.log('l10n.js: "msgid_plural" param for n() should be either a string or an object implementing toString() method!');
        return msgid;
      }
    }

    return this._strfmt(this.get('_gettext').ngettext(msgid, msgidPlural, count), hash);
  },

  /**
   * Replaces placeholders like {{placeholder}} from string.
   *
   * @method _strfmt
   * @param {String} string
   * @param {Object} hash
   * @return {String}
   * @private
   */
  _strfmt(string, hash) {
    // don't process empty hashes
    if (Ember.isNone(hash)) {
      return string;
    }

    // find and replace all {{placeholder}}
    let pattern = /{{\s*([\w]+)\s*}}/g;
    let replace = (idx, match) => {
      let value = hash[match];
      if (Ember.isNone(value)) {
        return `{{${match}}}`;
      }

      if (Ember.typeOf(value) === 'string') {
        value = this.get('_gettext').gettext(value);
      }

      return value;
    };

    return string.replace(pattern, replace);
  },

  /**
   * Loads current locale translation file.
   * Triggers `translation_loaded` event.
   *
   * @method _load
   * @return {Void}
   * @private
   */
  _loadJSON() {
    let ajax = this.get('ajax');
    let cache = this.get('_cache');
    let locale = this.get('locale');
    let url = `${this.get('jsonPath')}/${locale}.json`;

    let successCallback = (response) => {
      let cachedResponse = Ember.copy(response, true);
      this.notifyPropertyChange('availableLocales');
      this.get('_gettext').loadJSON(response);

      this.trigger('translation_loaded');
      cache[locale] = cachedResponse;
    };

    let failureCallback = (reason) => {
      console.error(`l10n.js: An error occured loading "${url}": ${reason}`);
    };

    // used cache translation if present
    if (cache.hasOwnProperty(locale)) {
      successCallback(cache[locale]);
      return;
    }

    // otherwise load json file from assets
    return ajax.request(url).then(
      successCallback,
      failureCallback
    );
  }

});
<|endoftext|>


<commit_before>import { Controller } from 'stimulus'

export default class extends Controller {
  static targets = ['checking']

  connect() {
    this.timer = setInterval(() => {
      this.refresh()
    }, 2000)
  }

  refresh() {
    if (!this.checkingTargets.length) {
      this.stopRefresh()
      return
    }

    const compats = this.checkingTargets.slice(0, 10).map(el => [el.dataset.gemmy, el.dataset.railsRelease])
    const params  = new URLSearchParams({ compats: JSON.stringify(compats) })
    const url     = `${this.data.get('url')}?${params.toString()}`

    $.getScript(url)
  }

  stopRefresh() {
    if (this.timer) {
      clearInterval(this.timer)
    }
  }

  disconnect() {
    this.stopRefresh()
  }
}
<commit_msg>stop refreshing compat table when error occurs<commit_after>import { Controller } from 'stimulus'

export default class extends Controller {
  static targets = ['checking']

  connect() {
    this.timer = setInterval(() => {
      this.refresh()
    }, 2000)
  }

  refresh() {
    if (!this.checkingTargets.length) {
      this.stopRefresh()
      return
    }

    const compats = this.checkingTargets.slice(0, 10).map(el => [el.dataset.gemmy, el.dataset.railsRelease])
    const params  = new URLSearchParams({ compats: JSON.stringify(compats) })
    const url     = `${this.data.get('url')}?${params.toString()}`

    $.getScript(url)
      .fail((xhr, status, error) => {
        this.stopRefresh()
        if (Rollbar)
          Rollbar.error('Error during compat table refresh.', { xhr: xhr, status: status, error: error })
      })
  }

  stopRefresh() {
    if (this.timer) {
      clearInterval(this.timer)
    }
  }

  disconnect() {
    this.stopRefresh()
  }
}
<|endoftext|>


<commit_before>function getMovement(ncmazw,lb)
{
	var delta = clock.getDelta(); // seconds.
	var moveDistance = 70 * delta;
	var rotateAngle = Math.PI / 2 * delta;   // pi/2 radians (90 degrees) per second

	var oldX = MovingCube.position.x;
	var oldY = MovingCube.position.y;
	var oldZ = MovingCube.position.z;

	// local transformations
	// move forwards/backwards/left/right
	if ( keyboard.pressed("W") )
		MovingCube.translateZ( -moveDistance );
	if ( keyboard.pressed("S") )
		MovingCube.translateZ(  moveDistance );
	if ( keyboard.pressed("Q") )
		MovingCube.translateX( -moveDistance );
	if ( keyboard.pressed("E") )
		MovingCube.translateX(  moveDistance );
	if ( keyboard.pressed('space') )
		MovingCube.translateY( moveDistance );
	if ( keyboard.pressed("N") )
		MovingCube.translateY( -moveDistance);

	var xCurrentMapCoord = Math.floor(MovingCube.position.x / lb.xLen + ncmaze.xDim/2 + 0.5); // the +0.5 makes it so we're measuring from the top right corner of the square, not the center
	var zCurrentMapCoord = Math.floor(MovingCube.position.z / lb.zLen + ncmaze.yDim/2 + 0.5);

	if ( keyboard.pressed("P") ) // test
	{
		//console.log(camera.position);
		/*
		var paused = true;
		var teapotTexture = new THREE.ImageUtils.loadTexture( 'textures/goldGlitter.png' );
		teapotTexture.wrapS = teapotTexture.wrapT = THREE.RepeatWrapping;
		teapotTexture.repeat.set( 1, 1);
		var teapotMaterial = new THREE.MeshPhongMaterial( { map: teapotTexture } );
		console.log("Attempting to change material to:");
		console.log(teapotMaterial);
		lb.setWallTexture(teapotMaterial);
		minimap.changeMapMaterial(new THREE.MeshBasicMaterial( {color: 0xcc2222} ));

		console.log("Sun position:")
		console.log(skyAnimator.theSun.children[0])
		*/

		/*
		console.log("x:",xCurrentMapCoord);
		console.log("z:",zCurrentMapCoord);
		console.log("Map:",ncmaze.maze[zCurrentMapCoord][xCurrentMapCoord]);
		console.log("'S' !==",ncmaze.maze[zCurrentMapCoord][xCurrentMapCoord], "is", ncmaze.maze[zCurrentMapCoord][xCurrentMapCoord] !== 'S')
		*/
	}

	// the player tried to move into a wall. send back to current position
	if ((ncmaze.maze[zCurrentMapCoord][xCurrentMapCoord] !== '0' &&
		ncmaze.maze[zCurrentMapCoord][xCurrentMapCoord] !== 'S'  &&
		ncmaze.maze[zCurrentMapCoord][xCurrentMapCoord] !== 'F') &&
		lb.yLen > MovingCube.position.y)
	{
		//console.log(ncmaze.maze[zCurrentMapCoord][xCurrentMapCoord])
		MovingCube.position.x = oldX;
		MovingCube.position.y = oldY;
		MovingCube.position.z = oldZ;
	}

	// rotate left/right
	var rotation_matrix = new THREE.Matrix4().identity();
	if ( keyboard.pressed("A") )
	{
		MovingCube.rotateOnAxis( new THREE.Vector3(0,1,0), rotateAngle);
		camera.rotateOnAxis( new THREE.Vector3(0,1,0), rotateAngle);
	}
	if ( keyboard.pressed("D") )
	{
		MovingCube.rotateOnAxis( new THREE.Vector3(0,1,0), -rotateAngle);
		camera.rotateOnAxis( new THREE.Vector3(0,1,0), -rotateAngle);
	}

	// rotate up/down *TO DISABLE*
	if ( keyboard.pressed("R") )
	{
		MovingCube.rotateOnAxis( new THREE.Vector3(1,0,0), rotateAngle);
		camera.rotateOnAxis( new THREE.Vector3(1,0,0), rotateAngle);
	}
	if ( keyboard.pressed("F") )
	{
		MovingCube.rotateOnAxis( new THREE.Vector3(1,0,0), -rotateAngle);
		camera.rotateOnAxis( new THREE.Vector3(1,0,0), -rotateAngle);
	}

	// TODO: Menu toggle button
	if ( keyboard.pressed("Z") )
	{
		MovingCube.position.set(startX,25,startZ);
		MovingCube.rotation.set(0,0,0);
		camera.rotation.set(0,0,0);
	}
}<commit_msg>Disabled x camera rotation<commit_after>function getMovement(ncmazw,lb)
{
	var delta = clock.getDelta(); // seconds.
	var moveDistance = 70 * delta;
	var rotateAngle = Math.PI / 2 * delta;   // pi/2 radians (90 degrees) per second

	var oldX = MovingCube.position.x;
	var oldY = MovingCube.position.y;
	var oldZ = MovingCube.position.z;

	// local transformations
	// move forwards/backwards/left/right
	if ( keyboard.pressed("W") )
		MovingCube.translateZ( -moveDistance );
	if ( keyboard.pressed("S") )
		MovingCube.translateZ(  moveDistance );
	if ( keyboard.pressed("Q") )
		MovingCube.translateX( -moveDistance );
	if ( keyboard.pressed("E") )
		MovingCube.translateX(  moveDistance );
	if ( keyboard.pressed('space') )
		MovingCube.translateY( moveDistance );
	if ( keyboard.pressed("N") )
		MovingCube.translateY( -moveDistance);

	var xCurrentMapCoord = Math.floor(MovingCube.position.x / lb.xLen + ncmaze.xDim/2 + 0.5); // the +0.5 makes it so we're measuring from the top right corner of the square, not the center
	var zCurrentMapCoord = Math.floor(MovingCube.position.z / lb.zLen + ncmaze.yDim/2 + 0.5);

	if ( keyboard.pressed("P") ) // test
	{
		//console.log(camera.position);
		/*
		var paused = true;
		var teapotTexture = new THREE.ImageUtils.loadTexture( 'textures/goldGlitter.png' );
		teapotTexture.wrapS = teapotTexture.wrapT = THREE.RepeatWrapping;
		teapotTexture.repeat.set( 1, 1);
		var teapotMaterial = new THREE.MeshPhongMaterial( { map: teapotTexture } );
		console.log("Attempting to change material to:");
		console.log(teapotMaterial);
		lb.setWallTexture(teapotMaterial);
		minimap.changeMapMaterial(new THREE.MeshBasicMaterial( {color: 0xcc2222} ));

		console.log("Sun position:")
		console.log(skyAnimator.theSun.children[0])
		*/

		/*
		console.log("x:",xCurrentMapCoord);
		console.log("z:",zCurrentMapCoord);
		console.log("Map:",ncmaze.maze[zCurrentMapCoord][xCurrentMapCoord]);
		console.log("'S' !==",ncmaze.maze[zCurrentMapCoord][xCurrentMapCoord], "is", ncmaze.maze[zCurrentMapCoord][xCurrentMapCoord] !== 'S')
		*/
	}

	// the player tried to move into a wall. send back to current position
	if ((ncmaze.maze[zCurrentMapCoord][xCurrentMapCoord] !== '0' &&
		ncmaze.maze[zCurrentMapCoord][xCurrentMapCoord] !== 'S'  &&
		ncmaze.maze[zCurrentMapCoord][xCurrentMapCoord] !== 'F') &&
		lb.yLen > MovingCube.position.y)
	{
		//console.log(ncmaze.maze[zCurrentMapCoord][xCurrentMapCoord])
		MovingCube.position.x = oldX;
		MovingCube.position.y = oldY;
		MovingCube.position.z = oldZ;
	}

	// rotate left/right
	var rotation_matrix = new THREE.Matrix4().identity();
	if ( keyboard.pressed("A") )
	{
		MovingCube.rotateOnAxis( new THREE.Vector3(0,1,0), rotateAngle);
		camera.rotateOnAxis( new THREE.Vector3(0,1,0), rotateAngle);
	}
	if ( keyboard.pressed("D") )
	{
		MovingCube.rotateOnAxis( new THREE.Vector3(0,1,0), -rotateAngle);
		camera.rotateOnAxis( new THREE.Vector3(0,1,0), -rotateAngle);
	}

	// rotate up/down *TO DISABLE*
	/*
	if ( keyboard.pressed("R") )
	{
		MovingCube.rotateOnAxis( new THREE.Vector3(1,0,0), rotateAngle);
		camera.rotateOnAxis( new THREE.Vector3(1,0,0), rotateAngle);
	}
	if ( keyboard.pressed("F") )
	{
		MovingCube.rotateOnAxis( new THREE.Vector3(1,0,0), -rotateAngle);
		camera.rotateOnAxis( new THREE.Vector3(1,0,0), -rotateAngle);
	}
	*/

	// TODO: Menu toggle button
	if ( keyboard.pressed("Z") )
	{
		MovingCube.position.set(startX,25,startZ);
		MovingCube.rotation.set(0,0,0);
		camera.rotation.set(0,0,0);
	}
}<|endoftext|>


<commit_before>function choose(obj, def){
    if(obj === undefined){
        return def;
    }
    return obj;
}
var coercers = {
    identity: function(anything){
        return anything;
    },
    int: function(string){
        var int = parseInt(string);
        if(isNaN(int))throw new Error(string + " cannot be parsed as an int");
        return int
    },
    float: function(string){
        var float = parseFloat(string);
        if(isNaN(float))throw new Error(string + " cannot be parsed as a float");
        return float
    },
    date: function(string){
        var date = new Date(string);
        if(isNaN(date))throw new Error(string + " cannot be parsed as a date");
        return date
    },
    nonOption: function(string){
        if(string[0] === "-")throw new Error(string + "is read as an option");
        return string;
    },
    choice: function(/*choices*/){
        var choices = arguments;
        return function(string){
            for(var i = 0; i < choices.length; i++){
                if(choices[i] == string){// doubls equals equality, will transfer from string to int/bool/etc.
                    return choices[i];
                }
            }
        }
    },
},
options = {
    set: function(name, letter, doc){
        return {word: name, letter: letter, doc: doc?doc:"turn on "+name,
                func: function(array, object){
                    object[name] = true;
                }};
    },
    enum: function(tag, position, name, letter, doc){
        return {word: name, letter: letter, doc: doc?doc:"set "+tag+" to "+position,
                func: function(array, object){
                    object[tag] = position;
                }}
    },
    data: function(coerce, name, letter, doc){
        return {word: name, letter: letter,doc: doc?doc:"set "+name+"to argument",
        func: function(array, object){
                       object[name] = coerce(array[1]);
                       array.splice(1, 1);
                       console.log(array)
                   }
               }
    },
    string: function(name, letter, doc){
        return this.data(coercers.identity, name, letter, doc);
    },
},
filters = {
    position: function(name, coerce){
        var coerce = choose(coerce, function(n){return n});
        var func = function(array, object){
            if(!array.length)throw new Error("Not enough args for " + name);
            object[name] = coerce(array[0]);
            array.shift();
        }
        console.log(func);
        return func
    },
    flags: function(letters, words){
        return function(array, object){
            while(array.length){
                if(array[0].slice(0, 2) === "--" && words[array[0].slice(2)]){
                    words[array[0].slice(2)](array, object);
                    array.shift();
                }else if(array[0][0] === "-"){
                    var letter = array[0].slice(1);
                    for(var l = 0; l < letter.length; l++){
                        if(letters[letter[l]]){
                            letters[letter[l]](array, object);
                        }else{
                            throw new Error("Flag '" + letter[l] + "' in -" + letter + " is invalid");
                        }
                    }
                    array.shift();
                }else{
                    break;
                }
            }
        }
    },
    options: function(options){
        var letters = {},
            words = {},
            doc = "";
        for(var i = 0; i < options.length; i ++){
            var opt = options[i]
            letters[opt.letter] = opt.func;
            words[opt.word] = opt.func;
            doc += "\n    "+
                (opt.letter.length === 1 ? ("-" + opt.letter + ", "): "") +
                "--" + opt.word + ": " + opt.doc;
        }
        return [doc, this.flags(letters, words)];
    },
    optional: function(func){
        return function(array, object){
            try{
                func(array, object)
            }catch(e){}
        }
    },
},

Parser = function(string, values, def){
    this.filters = [];
    this.string = string;
    this.doc = "USAGE: " + string + "\n\n";
    this.def = choose(def, {}); //default is a keyword
    var choices = string.match(/[^\s\[\]]+|[\[\]]/g),
        option = false;
    for(var i = 1; i < choices.length; i++){
        if(choices[i] === "["){
            option = true;
            continue;
        }if(choices[i] === "]"){
            option = false;
            continue;
        }
        if(option){
            this.filters.push(filters.optional(values[choices[i]][1]));
        }else{
            this.filters.push(values[choices[i]][1]);
        }
        this.doc += choices[i] + ": " + values[choices[i]][0] + "\n";
    }
};
Parser.prototype = {
    parse: function(args){
        var array = args.slice(1),
            object = $.extend({}, this.def);
        for(var i = 0; i < this.filters.length; i++){
            this.filters[i](array, object);
        }
        if(array.length)throw new Error("Too many args: " + array)
        return object;
    }
}

window.optparse3 = {
    coercers: coercers,
    options: options,
    filters: filters,
    Parser: Parser,
}
<commit_msg>json as coercer<commit_after>function choose(obj, def){
    if(obj === undefined){
        return def;
    }
    return obj;
}
var coercers = {
    identity: function(anything){
        return anything;
    },
    int: function(string){
        var int = parseInt(string);
        if(isNaN(int))throw new Error(string + " cannot be parsed as an int");
        return int
    },
    float: function(string){
        var float = parseFloat(string);
        if(isNaN(float))throw new Error(string + " cannot be parsed as a float");
        return float
    },
    date: function(string){
        var date = new Date(string);
        if(isNaN(date))throw new Error(string + " cannot be parsed as a date");
        return date
    },
    nonOption: function(string){
        if(string[0] === "-")throw new Error(string + "is read as an option");
        return string;
    },
    choice: function(/*choices*/){
        var choices = arguments;
        return function(string){
            for(var i = 0; i < choices.length; i++){
                if(choices[i] == string){// doubls equals equality, will transfer from string to int/bool/etc.
                    return choices[i];
                }
            }
        }
    },
    json: function(string){
        return JSON.parse(string);
    },
},
options = {
    set: function(name, letter, doc){
        return {word: name, letter: letter, doc: doc?doc:"turn on "+name,
                func: function(array, object){
                    object[name] = true;
                }};
    },
    enum: function(tag, position, name, letter, doc){
        return {word: name, letter: letter, doc: doc?doc:"set "+tag+" to "+position,
                func: function(array, object){
                    object[tag] = position;
                }}
    },
    data: function(coerce, name, letter, doc){
        return {word: name, letter: letter,doc: doc?doc:"set "+name+"to argument",
        func: function(array, object){
                       object[name] = coerce(array[1]);
                       array.splice(1, 1);
                       console.log(array)
                   }
               }
    },
    string: function(name, letter, doc){
        return this.data(coercers.identity, name, letter, doc);
    },
},
filters = {
    position: function(name, coerce){
        var coerce = choose(coerce, function(n){return n});
        var func = function(array, object){
            if(!array.length)throw new Error("Not enough args for " + name);
            object[name] = coerce(array[0]);
            array.shift();
        }
        console.log(func);
        return func
    },
    flags: function(letters, words){
        return function(array, object){
            while(array.length){
                if(array[0].slice(0, 2) === "--" && words[array[0].slice(2)]){
                    words[array[0].slice(2)](array, object);
                    array.shift();
                }else if(array[0][0] === "-"){
                    var letter = array[0].slice(1);
                    for(var l = 0; l < letter.length; l++){
                        if(letters[letter[l]]){
                            letters[letter[l]](array, object);
                        }else{
                            throw new Error("Flag '" + letter[l] + "' in -" + letter + " is invalid");
                        }
                    }
                    array.shift();
                }else{
                    break;
                }
            }
        }
    },
    options: function(options){
        var letters = {},
            words = {},
            doc = "";
        for(var i = 0; i < options.length; i ++){
            var opt = options[i]
            letters[opt.letter] = opt.func;
            words[opt.word] = opt.func;
            doc += "\n    "+
                (opt.letter.length === 1 ? ("-" + opt.letter + ", "): "") +
                "--" + opt.word + ": " + opt.doc;
        }
        return [doc, this.flags(letters, words)];
    },
    optional: function(func){
        return function(array, object){
            try{
                func(array, object)
            }catch(e){}
        }
    },
},

Parser = function(string, values, def){
    this.filters = [];
    this.string = string;
    this.doc = "USAGE: " + string + "\n\n";
    this.def = choose(def, {}); //default is a keyword
    var choices = string.match(/[^\s\[\]]+|[\[\]]/g),
        option = false;
    for(var i = 1; i < choices.length; i++){
        if(choices[i] === "["){
            option = true;
            continue;
        }if(choices[i] === "]"){
            option = false;
            continue;
        }
        if(option){
            this.filters.push(filters.optional(values[choices[i]][1]));
        }else{
            this.filters.push(values[choices[i]][1]);
        }
        this.doc += choices[i] + ": " + values[choices[i]][0] + "\n";
    }
};
Parser.prototype = {
    parse: function(args){
        var array = args.slice(1),
            object = $.extend({}, this.def);
        for(var i = 0; i < this.filters.length; i++){
            this.filters[i](array, object);
        }
        if(array.length)throw new Error("Too many args: " + array)
        return object;
    }
}

window.optparse3 = {
    coercers: coercers,
    options: options,
    filters: filters,
    Parser: Parser,
}
<|endoftext|>


<commit_before>/**
 * UrlRouting
 *
 * The base controller for handling UrlRouting from the outside.
 * Prototypes only need to interface with this global object.
 */

/*
UrlRouting.draw(this, {
	"archive/$year/$month/$day": {
		handler: "archive",
		month: null,
		day: null,
		requirements: {
			year: /\d{4}/,
			month: /\d{2}/
			day: /\d{2}/
		}
	},

	"another/route": {
		...
	}
});

The syntax is pretty close to Rails.
In the path description (the string describing the route),
every path part that starts with a '$' sign is a variable.
For variables, further options are available:
In order to make the variables optional, assign them a null value,
as seen in the example above for month and day.
Please note that null values can only assigned from right to left.
In "requirements", regular expressions can be specified for checking of values.
So only if year in the example is actually a 4-char number,
the handler will be called.
Otherwise, the default error message will be displayed
(in case no other route will be responsible for the url).

In order to handle the defined routes,
you specify the getChildElement(name) function like this:

function getChildElement(name) {
	// first your normal getChildElement stuff, or the following,
	// if you didn't specify anything up to now.
	var obj = this.get(name);
	// in case obj is null, let's try the routes:
	if (!obj)
		obj = UrlRouting.handle(this, name);
	return obj;
}
*/

var UrlRouting = {

	/**
	 * Installs one or more routes for the prototype
	 * to be called from the prototype scope
	 */
	draw: function(prototype, routes) {
		if (!prototype.routes) {
			prototype.routes = {
				// mapped routes ar routes where the first
				// part of the path is a string that clearly specifies
				// the root of a route.
				mapped: {},
				// unmapped routes are route where the first
				// part of the path is a variable
				unmapped: []
			};
		}
		var protoRoutes = prototype.routes;
		for (var path in routes) {
			// create a route object for each passed path
			var route = new Route(path, routes[path]);
			if (route.parts.length > 0) {
				// see if it's a mapped or an unmapped route
				if (!route.parts[0].isParameter) {
					var name = route.parts[0].name;
					// there might be more than one mapped route with the same root.
					// so create a array of routes for each mapped name
					if (!protoRoutes.mapped[name])
						protoRoutes.mapped[name] = [];
					protoRoutes.mapped[name].push(route);
				} else {
					protoRoutes.unmapped.push(route);
				}
			}
		}
	},

	/**
	 * to be called from object.getChildElement(name)
	 */
	handle: function(object, name) {
		// handle mapped and unmapped routes differently
		var routes = object.__proto__.routes;
		if (routes) {
			var mapped = routes.mapped[name];
			if (mapped != null) {
				// mapped is an array containing one or more routes that share the same first path part
				return new RouteHandler(object, mapped, name);
			} else {
				// RouteHandler will have to handle all unmapped routes and find the fitting ones
				return new RouteHandler(object, routes.unmapped).getChildElement(name);
			}
		}
	}
};

/**
 * Route
 *
 * Prototype for storing one single route.
 */

/**
 * Creates the Route object. the passed path is parsed and split into single parts.
 * Each part might be a variable or a string part.
 * Vairable parts may have requirements specified as regular expressions.
 */
function Route(path, route) {
	var parts = path.split("/");
	var requirements = route.requirements;
	for (var i = 0; i < parts.length; i++) {
		var name = parts[i];
		var part = {
			isParameter: name.startsWith("$")
		};
		if (part.isParameter) {
			name = name.substring(1);

			if (requirements && requirements[name])
				part.requirement = requirements[name];

			part.nullAllowed = route[name] === null;
		}
		part.name = name;
		parts[i] = part;
	}
	this.path = path;
	this.parts = parts;
	this.action = route.action;
	this.handler = route.handler;
}

/**
 * Matches the given route level against a name.
 * Returns true if the route allows the name on that level, false otherwise.
 */
Route.prototype.match = function(level, name) {
	var part = this.parts[level];
	if (part != null) {
		if (part.isParameter) {
			if (part.requirement) return part.requirement.test(name);
			else return true;
		} else {
			return part.name == name;
		}
	}
}

/**
 * RouteHandler
 *
 * for each incoming request, a RouteHandler object is created. The same object is used for handling all
 * calls to getChildElement within one request. The object is keeping track of the path level and
 * the valid routes for the request.
 */

function RouteHandler(object, routes, firstLevel) {
	// clone the array as it's modified afterwards
	this.object = object;
	this.routes = routes.concat([]);
	// first level is set for mapped routes, which all share at least the first level
	if (firstLevel != null) {
		this.path = [firstLevel];
		this.level = 1;
	} else {
		this.path = [];
		this.level = 0;
	}
}

/**
 * getChildElement is called by Helma to determine the object on the next level. RoutHandler returns
 * either itself if there's at least one valid route, or null, which signifies that we can't go on
 * with that request and an error should be displayed.
 */
RouteHandler.prototype.getChildElement = function(name) {
	// on each level of the route, just find at least one matching route, remove the unmatching ones
	var routes = this.routes;
	for (var i = routes.length - 1; i >= 0; i--) {
		if (!routes[i].match(this.level, name))
			routes.splice(i, 1);
	}
	// if all routes are ruled out, return null, otherwise continue with the next level in the path
	if (routes.length > 0) {
		this.level++;
		this.path.push(name);
		return this;
	} else {
		return null;
	}
}

/**
 * The main_action is called if the request found it's target. It might be that still none
 * of the routes fit as they might require more parameters. This is validated and the
 * default notfound error is displayed in case it was not found.
 */
RouteHandler.prototype.main_action = function() {
	User.autoLogin(); // ADDED!
	var routes = this.routes;
	// see if all parts in the route do match (or are allowed to be null)
 	for (var i = routes.length - 1; i >= 0; i--) {
		var parts = routes[i].parts;
		for (var j = this.level; j < parts.length; j++) {
			if (!parts[j].nullAllowed) {
				routes.splice(i, 1);
				break;
			}
		}
	}
	var found = false;
	if (routes.length > 0) {
		// if there are still more than one, take the first and report
		// wrong routing setup to user through log:
		if (routes.length > 1) {
			res.push();
			res.writeln("UrlRouting Error: More than one route possible:");
			for (var i = 0; i < routes.length; i++) {
				res.writeln(routes[i].path);
			}
			app.log(res.pop());
		}

		var route = routes[0];
		var parts = route.parts;
		var path = this.path;

		if (route.action != null) {
			// a route may call an action, in which case the values are converted to req.data values
			var action = this.object[route.action + "_action"];
			if (action != null) {
				// set up the req.data values
				for (var i = 0; i < path.length; i++) {
					if (parts[i].isParameter) {
						req.data[parts[i].name] = path[i];
					}
				}
			 	action.apply(this.object);
				found = true;
			}
		} else if (route.handler != null) {
			// if it's calling a handler, a argument list is set up and passed when calling the handler function
			var handler = this.object[route.handler];
			if (handler != null) {
				// fill arguments list:
				var args = [];
				for (var i = 0; i < path.length; i++) {
					if (parts[i].isParameter) {
						args.push(path[i]);
					}
				}
				var obj = handler.apply(this.object, args);
				// handler can either handle the request itself or return an object to take care of this
				// call main action:
				if (obj) {
					if (obj.main_action)
						obj.main_action();
					found = true;
				} else if (obj === undefined) {
					// handler did not return anything -> it handled the request itself
					found = true;
				}
			}
		}
	}

	if (!found) {
		res.status = 404;
		// simulate error handling behavior in RequestEvaluator.java
		var action = root[getProperty("notfound", "notfound") + "_action"];
		if (action != null) {
			action.apply(root);
		} else {
			res.write("
Error in application ");
			res.write(app.name);
			res.write("
Object not found.");
		}
	}
}
<commit_msg>Cleaned up UrlRouting code.<commit_after>/**
 * UrlRouting
 *
 * The base controller for handling UrlRouting from the outside.
 * Prototypes only need to interface with this global object.
 */

/*
UrlRouting.draw(this, {
	'archive/$year/$month/$day': {
		handler: 'archive',
		month: null,
		day: null,
		requirements: {
			year: /\d{4}/,
			month: /\d{2}/
			day: /\d{2}/
		}
	},

	'another/route': {
		...
	}
});

The syntax is pretty close to Rails.
In the path description (the string describing the route),
every path part that starts with a '$' sign is a variable.
For variables, further options are available:
In order to make the variables optional, assign them a null value,
as seen in the example above for month and day.
Please note that null values can only assigned from right to left.
In 'requirements', regular expressions can be specified for checking of values.
So only if year in the example is actually a 4-char number,
the handler will be called.
Otherwise, the default error message will be displayed
(in case no other route will be responsible for the url).

In order to handle the defined routes,
you specify the getChildElement(name) function like this:

function getChildElement(name) {
	// first your normal getChildElement stuff, or the following,
	// if you didn't specify anything up to now.
	var obj = this.get(name);
	// in case obj is null, let's try the routes:
	if (!obj)
		obj = UrlRouting.handle(this, name);
	return obj;
}
*/

var UrlRouting = {
	/**
	 * Installs one or more routes for the prototype
	 * to be called from the prototype scope
	 */
	draw: function(prototype, routes) {
		if (!prototype.routes) {
			prototype.routes = {
				// mapped routes ar routes where the first
				// part of the path is a string that clearly specifies
				// the root of a route.
				mapped: {},
				// unmapped routes are route where the first
				// part of the path is a variable
				unmapped: []
			};
		}
		var protoRoutes = prototype.routes;
		for (var path in routes) {
			// create a route object for each passed path
			var route = new UrlRoute(path, routes[path]);
			if (route.parts.length > 0) {
				// see if it's a mapped or an unmapped route
				if (!route.parts[0].isParameter) {
					var name = route.parts[0].name;
					// There might be more than one mapped route with the same
					// root. So create a array of routes for each mapped name
					if (!protoRoutes.mapped[name])
						protoRoutes.mapped[name] = [];
					protoRoutes.mapped[name].push(route);
				} else {
					protoRoutes.unmapped.push(route);
				}
			}
		}
	},

	/**
	 * To be called from object.getChildElement(name)
	 */
	handle: function(object, name) {
		// Handle mapped and unmapped routes differently
		var routes = object.__proto__.routes;
		if (routes) {
			var mapped = routes.mapped[name];
			if (mapped) {
				// mapped is an array containing one or more routes that share
				// the same first path part
				return new UrlRouteHandler(object, mapped, name);
			} else {
				// UrlRouteHandler will have to handle all unmapped routes
				// and find the fitting ones
				return new UrlRouteHandler(object, routes.unmapped).getChildElement(name);
			}
		}
	}
};

/**
 * Route
 *
 * Prototype for storing one single route.
 */

/**
 * Creates the Route object. the passed path is parsed and split into single parts.
 * Each part might be a variable or a string part.
 * Vairable parts may have requirements specified as regular expressions.
 */
function UrlRoute(path, route) {
	var parts = path.split('/');
	var requirements = route.requirements;
	for (var i = 0; i < parts.length; i++) {
		var name = parts[i];
		var part = {
			isParameter: name.startsWith('$')
		};
		if (part.isParameter) {
			name = name.substring(1);

			if (requirements && requirements[name])
				part.requirement = requirements[name];

			part.nullAllowed = route[name] === null;
		}
		part.name = name;
		parts[i] = part;
	}
	this.path = path;
	this.parts = parts;
	this.action = route.action;
	this.handler = route.handler;
}

/**
 * Matches the given route level against a name.
 * Returns true if the route allows the name on that level, false otherwise.
 */
UrlRoute.prototype.match = function(level, name) {
	var part = this.parts[level];
	if (part) {
		if (part.isParameter) {
			if (part.requirement) return part.requirement.test(name);
			else return true;
		} else {
			return part.name == name;
		}
	}
}

/**
 * UrlRouteHandler
 *
 * For each incoming request, a UrlRouteHandler object is created.
 * The same object is used for handling all calls to getChildElement within one
 * request. The object is keeping track of the path level and the valid routes
 * for the request.
 */

function UrlRouteHandler(object, routes, firstLevel) {
	// Clone the array as it's modified afterwards
	this.object = object;
	this.routes = routes.concat([]);
	// First level is set for mapped routes, which all share at least the
	// first level
	if (firstLevel) {
		this.path = [firstLevel];
		this.level = 1;
	} else {
		this.path = [];
		this.level = 0;
	}
}

/**
 * getChildElement is called by Helma to determine the object on the next level.
 * RoutHandler returns either itself if there's at least one valid route,
 * or null, which signifies that we can't go on with that request and an error
 * should be displayed.
 */
UrlRouteHandler.prototype = {
	getChildElement: function(name) {
		// On each level of the route, just find at least one matching route,
		// remove the unmatching ones
		var routes = this.routes;
		for (var i = routes.length - 1; i >= 0; i--) {
			if (!routes[i].match(this.level, name))
				routes.splice(i, 1);
		}
		// If all routes are ruled out, return null, otherwise continue with
		// the next level in the path
		if (routes.length > 0) {
			this.level++;
			this.path.push(name);
			return this;
		} else {
			return null;
		}
	},

	/**
	 * The main_action is called if the request found it's target. It might be
	 * that still none of the routes fit as they might require more parameters.
	 * This is validated and the default notfound error is displayed in case it
	 * was not found.
	 */
	main_action: function() {
		User.autoLogin(); // ADDED!
		var routes = this.routes;
		// see if all parts in the route do match (or are allowed to be null)
	 	for (var i = routes.length - 1; i >= 0; i--) {
			var parts = routes[i].parts;
			for (var j = this.level; j < parts.length; j++) {
				if (!parts[j].nullAllowed) {
					routes.splice(i, 1);
					break;
				}
			}
		}
		var found = false;
		if (routes.length > 0) {
			// if there are still more than one, take the first and report
			// wrong routing setup to user through log:
			if (routes.length > 1) {
				res.push();
				res.writeln('UrlRouting Error: More than one route possible:');
				for (var i = 0; i < routes.length; i++) {
					res.writeln(routes[i].path);
				}
				app.log(res.pop());
			}

			var route = routes[0];
			var parts = route.parts;
			var path = this.path;

			if (route.action) {
				// A route may call an action, in which case the values are
				// converted to req.data values
				var action = this.object[route.action + '_action'];
				if (action) {
					// set up the req.data values
					for (var i = 0; i < path.length; i++) {
						if (parts[i].isParameter) {
							req.data[parts[i].name] = path[i];
						}
					}
				 	action.apply(this.object);
					found = true;
				}
			} else if (route.handler) {
				// If it's calling a handler, a argument list is set up and
				// passed when calling the handler function
				var handler = this.object[route.handler];
				if (handler) {
					// fill arguments list:
					var args = [];
					for (var i = 0; i < path.length; i++) {
						if (parts[i].isParameter) {
							args.push(path[i]);
						}
					}
					var obj = handler.apply(this.object, args);
					// Handler can either handle the request itself or return
					// an object to take care of this call main action:
					if (obj) {
						if (obj.main_action)
							obj.main_action();
						found = true;
					} else if (obj === undefined) {
						// Handler did not return anything
						// -> It handled the request itself
						found = true;
					}
				}
			}
		}
		if (!found) {
			res.status = 404;
			// simulate error handling behavior in RequestEvaluator.java
			var action = root[getProperty('notfound', 'notfound') + '_action'];
			if (action) {
				action.apply(root);
			} else {
				res.write('
Error in application ' + app.name + '
Object not found.');
			}
		}
	}
};<|endoftext|>


<commit_before>/* eslint-disable no-underscore-dangle */
/* eslint-disable react/forbid-prop-types */
import React from 'react';
import { Button, OverlayTrigger, Popover } from 'react-bootstrap';
import PropTypes from 'prop-types';
import uuid from 'uuid';
import MoleculesFetcher from '../fetchers/MoleculesFetcher';
import NotificationActions from '../actions/NotificationActions';
import LoadingActions from '../actions/LoadingActions';

const notify = (params) => {
  NotificationActions.add({
    title: params.title, message: params.msg, level: params.lvl, position: 'tc', dismissible: 'button', uid: uuid.v4()
  });
};

const buildRxn = (reaction) => {
  let rxn = '$RXN\n\n\n\n';
  const molBreak = '$MOL\n';
  let rl = 0;
  let xl = 0;
  let pl = 0;
  let molfiles = '';
  reaction._starting_materials.map((e) => {
    rl += 1;
    molfiles += molBreak + e.molfile.slice(0, e.molfile.lastIndexOf('$$$$'));
  });
  reaction._reactants.map((e) => {
    xl += 1;
    molfiles += molBreak + e.molfile.slice(0, e.molfile.lastIndexOf('$$$$'));
  });
  reaction._products.map((e) => {
    pl += 1;
    molfiles += molBreak + e.molfile.slice(0, e.molfile.lastIndexOf('$$$$'));
  });
  rxn += (`   ${(rl + xl).toString()}`).slice(-3);
  rxn += (`   ${pl.toString()}`).slice(-3);
  rxn += '\n';
  rxn += molfiles;
  return { rxn };
};

const ScifinderSearch = (props) => {
  const { el } = props;
  const search = (_type) => {
    const str = el.type === 'reaction' ? buildRxn(el).rxn : el.molfile;
    const params = { str, search: _type, ctype: 'x-mdl-rxnfile' };
    LoadingActions.start();
    MoleculesFetcher.fetchSciFinder(params)
      .then((result) => {
        if (result.errors.length === 0) {
          const url = `${result.host}${result.path}`;
          window.open(url, '_blank');
        } else {
          notify({ title: 'SciFinder-n Error', lvl: 'error', msg: result.errors[0] });
        }
      }).catch((errorMessage) => {
        console.log(errorMessage);
        notify({ title: 'SciFinder-n Error', lvl: 'error', msg: errorMessage });
      }).finally(() => LoadingActions.stop());
  };

  const renderButtons = () => {
    const BTNS = [
      { substances: 'icon-sample' }, { reactions: 'icon-reaction' }, { references: 'fa fa-book' }, { suppliers: 'fa fa-shopping-cart' }
    ];
    if (el.type === 'reaction') { [BTNS[0], BTNS[1]] = [BTNS[1], BTNS[0]]; }
    const btn = (name, icon) => (
      <Button key={`_sfn_btn_${name}`} onClick={() => search(name)}>

        {name}
      </Button>
    );
    return BTNS.map(b => Object.entries(b).map(([key, value]) => btn(key, value)));
  };

  const popoverSettings = (
    <Popover
      className="collection-overlay"
      id="popover-layout"
      style={{ maxWidth: 'none', width: 'auto' }}
    >

SciFinder-n Search for

          {renderButtons()}

    </Popover>
  );

  return (
    <OverlayTrigger trigger="click" placement="left" overlay={popoverSettings} rootClose>
      <Button className="button-right" style={{ padding: '0px' }}>

      </Button>
    </OverlayTrigger>
  );
};

ScifinderSearch.propTypes = { el: PropTypes.object.isRequired };
export default ScifinderSearch;
<commit_msg>replace logo with text (#859)<commit_after>/* eslint-disable no-underscore-dangle */
/* eslint-disable react/forbid-prop-types */
import React from 'react';
import { Button, OverlayTrigger, Popover } from 'react-bootstrap';
import PropTypes from 'prop-types';
import uuid from 'uuid';
import MoleculesFetcher from '../fetchers/MoleculesFetcher';
import NotificationActions from '../actions/NotificationActions';
import LoadingActions from '../actions/LoadingActions';

const notify = (params) => {
  NotificationActions.add({
    title: params.title, message: params.msg, level: params.lvl, position: 'tc', dismissible: 'button', uid: uuid.v4()
  });
};

const buildRxn = (reaction) => {
  let rxn = '$RXN\n\n\n\n';
  const molBreak = '$MOL\n';
  let rl = 0;
  let xl = 0;
  let pl = 0;
  let molfiles = '';
  reaction._starting_materials.map((e) => {
    rl += 1;
    molfiles += molBreak + e.molfile.slice(0, e.molfile.lastIndexOf('$$$$'));
  });
  reaction._reactants.map((e) => {
    xl += 1;
    molfiles += molBreak + e.molfile.slice(0, e.molfile.lastIndexOf('$$$$'));
  });
  reaction._products.map((e) => {
    pl += 1;
    molfiles += molBreak + e.molfile.slice(0, e.molfile.lastIndexOf('$$$$'));
  });
  rxn += (`   ${(rl + xl).toString()}`).slice(-3);
  rxn += (`   ${pl.toString()}`).slice(-3);
  rxn += '\n';
  rxn += molfiles;
  return { rxn };
};

const ScifinderSearch = (props) => {
  const { el } = props;
  const search = (_type) => {
    const str = el.type === 'reaction' ? buildRxn(el).rxn : el.molfile;
    const params = { str, search: _type, ctype: 'x-mdl-rxnfile' };
    LoadingActions.start();
    MoleculesFetcher.fetchSciFinder(params)
      .then((result) => {
        if (result.errors.length === 0) {
          const url = `${result.host}${result.path}`;
          window.open(url, '_blank');
        } else {
          notify({ title: 'SciFinder-n Error', lvl: 'error', msg: result.errors[0] });
        }
      }).catch((errorMessage) => {
        console.log(errorMessage);
        notify({ title: 'SciFinder-n Error', lvl: 'error', msg: errorMessage });
      }).finally(() => LoadingActions.stop());
  };

  const renderButtons = () => {
    const BTNS = [
      { substances: 'icon-sample' }, { reactions: 'icon-reaction' }, { references: 'fa fa-book' }, { suppliers: 'fa fa-shopping-cart' }
    ];
    if (el.type === 'reaction') { [BTNS[0], BTNS[1]] = [BTNS[1], BTNS[0]]; }
    const btn = (name, icon) => (
      <Button key={`_sfn_btn_${name}`} onClick={() => search(name)}>

        {name}
      </Button>
    );
    return BTNS.map(b => Object.entries(b).map(([key, value]) => btn(key, value)));
  };

  const popoverSettings = (
    <Popover
      className="collection-overlay"
      id="popover-layout"
      style={{ maxWidth: 'none', width: 'auto' }}
    >

SciFinder-n Search for

          {renderButtons()}

    </Popover>
  );

  return (
    <OverlayTrigger trigger="click" placement="left" overlay={popoverSettings} rootClose>
      <Button className="button-right" style={{ padding: '0px' }}>

 CAS content

      </Button>
    </OverlayTrigger>
  );
};

ScifinderSearch.propTypes = { el: PropTypes.object.isRequired };
export default ScifinderSearch;
<|endoftext|>


<commit_before>/* global angular */

import 'ionic-sdk/release/js/ionic.bundle';
import StellarSdk from 'stellar-sdk';
import horizon from '../../core/services/horizon.js';
import translate from '../../core/services/translate.service.js';

class CreatePersonalController {

	constructor($location, Modal, Reviewer, Wallet) {
		this.$location = $location;
		this.Modal = Modal;
		this.Reviewer = Reviewer;
		this.Wallet = Wallet;

		this.minBalance = horizon.getMinimumAccountBalance(Wallet.current.network);
		this.state = 1;

		this.account = {
			alias: getAccountName(),
			amount: this.minBalance
		};

		function getAccountName() {
			const accountNum = Wallet.accountList.filter(item => !item.isMultiSig()).length + 1;
			return translate.instant('account.defaultname', {number: accountNum});
		}
	}

	createAccount() {

		const network = this.account.network;

		if (this.hasValidFunder()) {

			const accounts = {};
			Object.keys(this.Wallet.accounts).forEach(key => {
				const account = this.Wallet.accounts[key];
				if (account.network === network) {
					accounts[account.alias] = account;
				}
			});

			const newAccount	= StellarSdk.Keypair.random();
			const funder		= accounts[this.account.funder];

			funder.horizon().loadAccount(funder.id)
			.then(account => {
				const tx = new StellarSdk.TransactionBuilder(account)
				.addOperation(StellarSdk.Operation.createAccount({
					destination: newAccount.publicKey(),
					startingBalance: this.account.amount.toString()
				}))
				.build();

				return {
					tx: tx,
					network: network
				};
			})
			.then(this.Reviewer.review)
			.then(() => {
				this.Wallet.importAccount(
					newAccount.publicKey(),
					newAccount.secret(),
					this.account.alias,
					network
				);
				this.$location.path('/');
			});
		}

		else {
			this.Wallet.createEmptyAccount(
				this.account.alias,
				network
			);
			this.$location.path('/');
		}
	}

	hasValidFunder() {
		const name = this.account.funder;
		const network = this.account.network;
		return this.Wallet.hasAccount(name, network);
	}

	next() {
		if (this.state === 1) {
			this.state = 2;
		}

		else if (this.state === 2) {
			this.createAccount();
		}
	}

	selectFunder() {
		const data = {
			network: this.account.network,
			minimum: this.minBalance
		};

		this.Modal.show('app/side-menu/modals/select-funder.html', data)
		.then(res => {
			this.account.funder = res;
		});
	}
}

angular.module('app.component.create-personal', [])
.component('createPersonal', {
	controller: CreatePersonalController,
	controllerAs: 'vm',
	templateUrl: 'app/side-menu/components/create-personal.html'
});
<commit_msg>Load fees after network selection<commit_after>/* global angular */

import 'ionic-sdk/release/js/ionic.bundle';
import StellarSdk from 'stellar-sdk';
import horizon from '../../core/services/horizon.js';
import translate from '../../core/services/translate.service.js';

class CreatePersonalController {

	constructor($location, Modal, Reviewer, Wallet) {
		this.$location = $location;
		this.Modal = Modal;
		this.Reviewer = Reviewer;
		this.Wallet = Wallet;

		this.state = 1;

		this.account = {
			alias: getAccountName()
		};

		function getAccountName() {
			const accountNum = Wallet.accountList.filter(item => !item.isMultiSig()).length + 1;
			return translate.instant('account.defaultname', {number: accountNum});
		}
	}

	createAccount() {

		const network = this.account.network;

		if (this.hasValidFunder()) {

			const accounts = {};
			Object.keys(this.Wallet.accounts).forEach(key => {
				const account = this.Wallet.accounts[key];
				if (account.network === network) {
					accounts[account.alias] = account;
				}
			});

			const newAccount	= StellarSdk.Keypair.random();
			const funder		= accounts[this.account.funder];

			funder.horizon().loadAccount(funder.id)
			.then(account => {
				const tx = new StellarSdk.TransactionBuilder(account)
				.addOperation(StellarSdk.Operation.createAccount({
					destination: newAccount.publicKey(),
					startingBalance: this.account.amount.toString()
				}))
				.build();

				return {
					tx: tx,
					network: network
				};
			})
			.then(this.Reviewer.review)
			.then(() => {
				this.Wallet.importAccount(
					newAccount.publicKey(),
					newAccount.secret(),
					this.account.alias,
					network
				);
				this.$location.path('/');
			});
		}

		else {
			this.Wallet.createEmptyAccount(
				this.account.alias,
				network
			);
			this.$location.path('/');
		}
	}

	hasValidFunder() {
		const name = this.account.funder;
		const network = this.account.network;
		return this.Wallet.hasAccount(name, network);
	}

	next() {
		if (this.state === 1) {
			this.minBalance = horizon.getMinimumAccountBalance(this.Wallet.current.network);
			this.state = 2;
		}

		else if (this.state === 2) {
			this.createAccount();
		}
	}

	selectFunder() {
		const data = {
			network: this.account.network,
			minimum: this.minBalance
		};

		this.Modal.show('app/side-menu/modals/select-funder.html', data)
		.then(res => {
			this.account.funder = res;
			this.account.amount = this.minBalance;
		});
	}
}

angular.module('app.component.create-personal', [])
.component('createPersonal', {
	controller: CreatePersonalController,
	controllerAs: 'vm',
	templateUrl: 'app/side-menu/components/create-personal.html'
});
<|endoftext|>


<commit_before>/********************************************************
 * Copyright (c) 2013 Azavea, Inc.
 * See LICENSE in the project root for copying permission
 * Requires: google-maps-api-v3; jquery; leaflet;
 ********************************************************/

'use strict';

define(['jquery', 'Leaflet', 'server-vars', 'common'], function($, L, serverVars) {
    // These nested require statements are kind of silly, but I need serverVars.gmapKey...
    var gmapRequire = "async!http://maps.googleapis.com/maps/api/js?v=3.2&key=" +
        serverVars.gmapKey + "&sensor=false";
    require([gmapRequire], function() {
        var schoolIcon = L.icon({
            iconUrl: '/static/img/leaflet-icons/marker-school.png',
            shadowUrl: '/static/img/leaflet-icons/marker-shadow.png',

            iconSize:     [35, 45], // size of the icon
            shadowSize:   [41, 41], // size of the shadow
            iconAnchor:   [10, 60], // point of the icon which will correspond to marker's location
            shadowAnchor: [4, 62],  // the same for the shadow
            popupAnchor:  [-3, -76] // point from which the popup should open relative to the iconAnchor
        });

        /* On page load, query api to get locations position, add marker to map
         * for location. Use google maps layer for leaflet.
         */
        $(document).ready(function() {
            $.getJSON(window.location.pathname + 'position', function(data) {
                var lat = data[0].lat,
                    lng = data[0].lng,
                    map = new L.Map('location-map', {center: new L.LatLng(lat, lng), zoom: 13}),
                    gmap = new L.Google('ROADMAP');

                map.addLayer(gmap);
                L.marker([lat, lng], {icon: schoolIcon}).addTo(map);
                map.panTo(new L.LatLng(lat, lng));
            });
        });
    });
});

<commit_msg>Load template for location single page view<commit_after>/********************************************************
 * Copyright (c) 2013 Azavea, Inc.
 * See LICENSE in the project root for copying permission
 * Requires: google-maps-api-v3; jquery; leaflet;
 ********************************************************/

'use strict';

define(['jquery', 'Leaflet', 'server-vars', 'text!templates/location.html', 'common'], function($, L, serverVars, html) {
    // These nested require statements are kind of silly, but I need serverVars.gmapKey...
    var gmapRequire = "async!http://maps.googleapis.com/maps/api/js?v=3.2&key=" +
        serverVars.gmapKey + "&sensor=false";
    require([gmapRequire], function() {
        var schoolIcon = L.icon({
            iconUrl: '/static/img/leaflet-icons/marker-school.png',
            shadowUrl: '/static/img/leaflet-icons/marker-shadow.png',

            iconSize:     [35, 45], // size of the icon
            shadowSize:   [41, 41], // size of the shadow
            iconAnchor:   [10, 60], // point of the icon which will correspond to marker's location
            shadowAnchor: [4, 62],  // the same for the shadow
            popupAnchor:  [-3, -76] // point from which the popup should open relative to the iconAnchor
        });

        /* On page load, query api to get locations position, add marker to map
         * for location. Use google maps layer for leaflet.
         */
        $(document).ready(function() {
            $.getJSON(window.location.pathname + 'position', function(data) {
                var lat = data[0].lat,
                    lng = data[0].lng,
                    map = new L.Map('location-map', {center: new L.LatLng(lat, lng), zoom: 13}),
                    gmap = new L.Google('ROADMAP');

                map.addLayer(gmap);
                L.marker([lat, lng], {icon: schoolIcon}).addTo(map);
                map.panTo(new L.LatLng(lat, lng));
            });
        });
    });
});

<|endoftext|>


<commit_before>import { audioContext } from '../webaudio';
import { capturingStart, capturingStop, layerAdd, playbackStart } from '../actions';
import MessageBus from '../utils/MessageBus';

const BUFFER_SIZE = 2048;
const FADE_SAMPLES = 400;
const MAX_RECORD_SECONDS = 4;

function createBuffer(dataL, dataR, length) {
  const buffer = audioContext.createBuffer(2, length, audioContext.sampleRate);

  const bufferL = buffer.getChannelData(0);
  const bufferR = buffer.getChannelData(1);

  for (let i = 0; i < length; i++) {
    bufferL[i] = dataL[i];
    bufferR[i] = dataR[i];
  }

  for (let i = 0; i < FADE_SAMPLES; i++) {
    const volume = i / FADE_SAMPLES;

    bufferL[i] *= volume;
    bufferR[i] *= volume;

    bufferL[length - i - 1] *= volume;
    bufferR[length - i - 1] *= volume;
  }

  return buffer;
}

class Recorder {
  constructor(recordBufferLength) {
    this.recordBufferL = new Float32Array(recordBufferLength);
    this.recordBufferR = new Float32Array(recordBufferLength);

    this.maxSample = 0;

    this.reset();
    this.setInputBuffer([], []);
  }

  reset() {
    this.isRecording = false;
    this.consecutiveSamplesUnderThreshold = 0;
    this.recordBufferIndex = 0;
  }

  setInputBuffer(inputBufferL, inputBufferR) {
    this.inputBufferL = inputBufferL;
    this.inputBufferR = inputBufferR;

    this.inputBufferIndex = 0;
  }

  update(isEnabled, recordingThreshold, recordingThresholdSamples) {
    while (this.inputBufferIndex < this.inputBufferL.length) {
      if (this.recordBufferIndex === this.recordBufferL.length) {
        return true;
      }

      if (this.isRecording && (this.consecutiveSamplesUnderThreshold >= recordingThresholdSamples)) {
        return true;
      }

      const sampleL = this.inputBufferL[this.inputBufferIndex];
      const sampleR = this.inputBufferR[this.inputBufferIndex];

      const absSampleL = Math.abs(sampleL);
      const absSampleR = Math.abs(sampleR);

      this.maxSample = Math.max(this.maxSample, absSampleL, absSampleR);

      if (isEnabled && ((absSampleL >= recordingThreshold) || (absSampleR >= recordingThreshold))) {
        this.consecutiveSamplesUnderThreshold = 0;
        this.isRecording = true;
      } else {
        this.consecutiveSamplesUnderThreshold++;
      }

      this.inputBufferIndex++;

      if (this.isRecording) {
        this.recordBufferL[this.recordBufferIndex] = sampleL;
        this.recordBufferR[this.recordBufferIndex] = sampleR;

        this.recordBufferIndex++;
      }
    }

    return false;
  }
}

export default function recorder(store) {
  const audioRecorder = audioContext.createScriptProcessor(BUFFER_SIZE, 2, 2);
  const maxSampleMessageBus = new MessageBus();
  const recordBufferLength = Math.floor(MAX_RECORD_SECONDS * audioContext.sampleRate);
  const recorder = new Recorder(recordBufferLength);

  let audioInput = null;

  const onAnimationFrame = function (time) {
    requestAnimationFrame(onAnimationFrame);

    maxSampleMessageBus.update(recorder.maxSample);

    recorder.maxSample = 0;
  };

  audioRecorder.onaudioprocess = function (event) {
    let state = store.getState();

    const inputBufferL = event.inputBuffer.getChannelData(0);
    const inputBufferR = event.inputBuffer.getChannelData(1);

    recorder.setInputBuffer(inputBufferL, inputBufferR);

    while (recorder.update(state.isRecording, state.recordingThreshold, state.recordingThresholdSamples)) {
      const buffer = createBuffer(recorder.recordBufferL, recorder.recordBufferR, recorder.recordBufferIndex);

      recorder.reset();

      if (state.layers.length < 5) {
        store.dispatch(layerAdd(state.nextLayerId, buffer));

        if (state.layers.length === 0) {
          store.dispatch(playbackStart());
        }
      }

      state = store.getState();
    }

    if (!state.isCapturing && recorder.isRecording) {
      store.dispatch(capturingStart());
    } else if (state.isCapturing && !recorder.isRecording) {
      store.dispatch(capturingStop());
    }
  };

  audioRecorder.connect(audioContext.destination);

  return function (next) {
    return function (action) {
      if (action.mediaStream) {
        audioInput = audioContext.createMediaStreamSource(action.mediaStream);

        audioInput.connect(audioRecorder);

        requestAnimationFrame(onAnimationFrame);
      }

      return next(action);
    };
  };
}
<commit_msg>cap maxSample value to 1<commit_after>import { audioContext } from '../webaudio';
import { capturingStart, capturingStop, layerAdd, playbackStart } from '../actions';
import MessageBus from '../utils/MessageBus';

const BUFFER_SIZE = 2048;
const FADE_SAMPLES = 400;
const MAX_RECORD_SECONDS = 4;

function createBuffer(dataL, dataR, length) {
  const buffer = audioContext.createBuffer(2, length, audioContext.sampleRate);

  const bufferL = buffer.getChannelData(0);
  const bufferR = buffer.getChannelData(1);

  for (let i = 0; i < length; i++) {
    bufferL[i] = dataL[i];
    bufferR[i] = dataR[i];
  }

  for (let i = 0; i < FADE_SAMPLES; i++) {
    const volume = i / FADE_SAMPLES;

    bufferL[i] *= volume;
    bufferR[i] *= volume;

    bufferL[length - i - 1] *= volume;
    bufferR[length - i - 1] *= volume;
  }

  return buffer;
}

class Recorder {
  constructor(recordBufferLength) {
    this.recordBufferL = new Float32Array(recordBufferLength);
    this.recordBufferR = new Float32Array(recordBufferLength);

    this.maxSample = 0;

    this.reset();
    this.setInputBuffer([], []);
  }

  reset() {
    this.isRecording = false;
    this.consecutiveSamplesUnderThreshold = 0;
    this.recordBufferIndex = 0;
  }

  setInputBuffer(inputBufferL, inputBufferR) {
    this.inputBufferL = inputBufferL;
    this.inputBufferR = inputBufferR;

    this.inputBufferIndex = 0;
  }

  update(isEnabled, recordingThreshold, recordingThresholdSamples) {
    while (this.inputBufferIndex < this.inputBufferL.length) {
      if (this.recordBufferIndex === this.recordBufferL.length) {
        return true;
      }

      if (this.isRecording && (this.consecutiveSamplesUnderThreshold >= recordingThresholdSamples)) {
        return true;
      }

      const sampleL = this.inputBufferL[this.inputBufferIndex];
      const sampleR = this.inputBufferR[this.inputBufferIndex];

      const absSampleL = Math.abs(sampleL);
      const absSampleR = Math.abs(sampleR);

      this.maxSample = Math.max(this.maxSample, absSampleL, absSampleR);

      if (isEnabled && ((absSampleL >= recordingThreshold) || (absSampleR >= recordingThreshold))) {
        this.consecutiveSamplesUnderThreshold = 0;
        this.isRecording = true;
      } else {
        this.consecutiveSamplesUnderThreshold++;
      }

      this.inputBufferIndex++;

      if (this.isRecording) {
        this.recordBufferL[this.recordBufferIndex] = sampleL;
        this.recordBufferR[this.recordBufferIndex] = sampleR;

        this.recordBufferIndex++;
      }
    }

    return false;
  }
}

export default function recorder(store) {
  const audioRecorder = audioContext.createScriptProcessor(BUFFER_SIZE, 2, 2);
  const maxSampleMessageBus = new MessageBus();
  const recordBufferLength = Math.floor(MAX_RECORD_SECONDS * audioContext.sampleRate);
  const recorder = new Recorder(recordBufferLength);

  let audioInput = null;

  const onAnimationFrame = function (time) {
    requestAnimationFrame(onAnimationFrame);

    const maxSample = Math.min(1, recorder.maxSample);

    recorder.maxSample = 0;

    maxSampleMessageBus.update(maxSample);
  };

  audioRecorder.onaudioprocess = function (event) {
    let state = store.getState();

    const inputBufferL = event.inputBuffer.getChannelData(0);
    const inputBufferR = event.inputBuffer.getChannelData(1);

    recorder.setInputBuffer(inputBufferL, inputBufferR);

    while (recorder.update(state.isRecording, state.recordingThreshold, state.recordingThresholdSamples)) {
      const buffer = createBuffer(recorder.recordBufferL, recorder.recordBufferR, recorder.recordBufferIndex);

      recorder.reset();

      if (state.layers.length < 5) {
        store.dispatch(layerAdd(state.nextLayerId, buffer));

        if (state.layers.length === 0) {
          store.dispatch(playbackStart());
        }
      }

      state = store.getState();
    }

    if (!state.isCapturing && recorder.isRecording) {
      store.dispatch(capturingStart());
    } else if (state.isCapturing && !recorder.isRecording) {
      store.dispatch(capturingStop());
    }
  };

  audioRecorder.connect(audioContext.destination);

  return function (next) {
    return function (action) {
      if (action.mediaStream) {
        audioInput = audioContext.createMediaStreamSource(action.mediaStream);

        audioInput.connect(audioRecorder);

        requestAnimationFrame(onAnimationFrame);
      }

      return next(action);
    };
  };
}
<|endoftext|>


<commit_before>/* @flow */

import findWithRegex from 'find-with-regex';
import _ from 'lodash';

export default (trigger: String) => (contentBlock: Object, callback: Function) => {
  findWithRegex(new RegExp(`(\\s|^)${_.escapeRegExp(trigger)}[\\w]*`, 'g'), contentBlock, callback);
};
<commit_msg>only import escapeRegExp instead of the whole lodash<commit_after>/* @flow */

import findWithRegex from 'find-with-regex';
import escapeRegExp from 'lodash/escapeRegExp';

export default (trigger: String) => (contentBlock: Object, callback: Function) => {
  findWithRegex(new RegExp(`(\\s|^)${escapeRegExp(trigger)}[\\w]*`, 'g'), contentBlock, callback);
};
<|endoftext|>


<commit_before>//import User from 'appkit/models/user';

import { test, moduleForModel } from 'appkit/tests/helpers/module_for';

var App;

moduleForModel('user', 'Integration - Model', {
    setup: function () {
        App = startApp();

    },
    teardown: function() {
        Ember.run(App, 'destroy');
    }
});

test('displayName', function() {
    var user = this.subject();

    var  store = this.store();

    Ember.run(function() {
        user = store.createRecord('user', {
            firstName: 'Tom',
            lastName: 'Dale'
        });

    });

    ok(user);
    equal(user.get('displayName'), 'Tom Dale');
});

test('gravatarURL', function() {
    var user = this.subject();

    var  store = this.store();

    Ember.run(function(){
        user = store.createRecord('user', {
            email: 'tom@example.com'
        });
    });

    equal(user.get('gravatarURL'),
    'http://www.gravatar.com/avatar/e4f7cd8905e896b04425b1d08411e9fb.jpg?s=80');
});

test('gravatarURL with blank email', function(){
    var user = this.subject();

    var  store = this.store();

    Ember.run(function() {
        user = store.createRecord('user', {
            email: ''
        });
    });

    equal(user.get('gravatarURL'),
        'http://www.gravatar.com/avatar/00000000000000000000000000000000.jpg?s=80');
});

test('gravatarURL with undefined email', function() {
    var user = this.subject();

    var  store = this.store();

    Ember.run(function() {
        user = store.createRecord('user');
    });

    equal(user.get('gravatarURL'),
    'http://www.gravatar.com/avatar/00000000000000000000000000000000.jpg?s=80');
});

<commit_msg>Remove gravatar related test from user_test.js<commit_after>//import User from 'appkit/models/user';

import { test, moduleForModel } from 'appkit/tests/helpers/module_for';

var App;

moduleForModel('user', 'Integration - Model', {
    setup: function () {
        App = startApp();
    },
    teardown: function() {
        Ember.run(App, 'destroy');
    }
});

test('displayName', function() {
    var user = this.subject();
    var  store = this.store();

    Ember.run(function() {
        user = store.createRecord('user', {
            firstName: 'Tom',
            lastName: 'Dale'
        });

    });

    ok(user);
    equal(user.get('displayName'), 'Tom Dale');
});

//These test can be removed because they are tested in the component
//test('gravatarURL', function() {
//    var user = this.subject();
//    var  store = this.store();
//
//    Ember.run(function(){
//        user = store.createRecord('user', {
//            email: 'tom@example.com'
//        });
//    });
//
//    equal(user.get('gravatarURL'),
//    'http://www.gravatar.com/avatar/e4f7cd8905e896b04425b1d08411e9fb.jpg?s=80');
//});
//
//test('gravatarURL with blank email', function(){
//    var user = this.subject();
//    var  store = this.store();
//
//    Ember.run(function() {
//        user = store.createRecord('user', {
//            email: ''
//        });
//    });
//
//    equal(user.get('gravatarURL'),
//        'http://www.gravatar.com/avatar/00000000000000000000000000000000.jpg?s=80');
//});
//
//test('gravatarURL with undefined email', function() {
//    var user = this.subject();
//
//    var  store = this.store();
//
//    Ember.run(function() {
//        user = store.createRecord('user');
//    });
//
//    equal(user.get('gravatarURL'),
//    'http://www.gravatar.com/avatar/00000000000000000000000000000000.jpg?s=80');
//});

<|endoftext|>