<commit_before>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

/**
 * @fileoverview
 * Functions related to controlling the modal UI state of the app. UI states
 * are expressed as HTML attributes with a dotted hierarchy. For example, the
 * string 'host.shared' will match any elements with an associated attribute
 * of 'host' or 'host.shared', showing those elements and hiding all others.
 * Elements with no associated attribute are ignored.
 */

'use strict';

/** @suppress {duplicate} */
var remoting = remoting || {};

/** @enum {string} */
// TODO(jamiewalch): Move 'in-session' to a separate web-page so that the
// 'home' state applies to all elements and can be removed.
remoting.AppMode = {
  HOME: 'home',
    UNAUTHENTICATED: 'home.auth',
    HOST: 'home.host',
      HOST_WAITING_FOR_CODE: 'home.host.waiting-for-code',
      HOST_WAITING_FOR_CONNECTION: 'home.host.waiting-for-connection',
      HOST_SHARED: 'home.host.shared',
      HOST_SHARE_FAILED: 'home.host.share-failed',
      HOST_SHARE_FINISHED: 'home.host.share-finished',
    CLIENT: 'home.client',
      CLIENT_UNCONNECTED: 'home.client.unconnected',
      CLIENT_PIN_PROMPT: 'home.client.pin-prompt',
      CLIENT_CONNECTING: 'home.client.connecting',
      CLIENT_CONNECT_FAILED_IT2ME: 'home.client.connect-failed.it2me',
      CLIENT_CONNECT_FAILED_ME2ME: 'home.client.connect-failed.me2me',
      CLIENT_SESSION_FINISHED_IT2ME: 'home.client.session-finished.it2me',
      CLIENT_SESSION_FINISHED_ME2ME: 'home.client.session-finished.me2me',
    HISTORY: 'home.history',
    CONFIRM_HOST_DELETE: 'home.confirm-host-delete',
    ASK_PIN: 'home.ask-pin',
  IN_SESSION: 'in-session'
};

/**
 * @param {Element} element The element to check.
 * @param {string} attr The attribute on the element to check.
 * @param {string} mode The mode to check for.
 * @return {boolean} True if |mode| is found within the element's |attr|.
 */
remoting.hasModeAttribute = function(element, attr, mode) {
  return element.getAttribute(attr).match(
      new RegExp('(\\s|^)' + mode + '(\\s|$)')) != null;
};

/**
 * Update the DOM by showing or hiding elements based on whether or not they
 * have an attribute matching the specified name.
 * @param {string} mode The value against which to match the attribute.
 * @param {string} attr The attribute name to match.
 * @return {void} Nothing.
 */
remoting.updateModalUi = function(mode, attr) {
  var modes = mode.split('.');
  for (var i = 1; i < modes.length; ++i)
    modes[i] = modes[i - 1] + '.' + modes[i];
  var elements = document.querySelectorAll('[' + attr + ']');
  for (var i = 0; i < elements.length; ++i) {
    var element = /** @type {Element} */ elements[i];
    var hidden = true;
    for (var m = 0; m < modes.length; ++m) {
      if (remoting.hasModeAttribute(element, attr, modes[m])) {
        hidden = false;
        break;
      }
    }
    element.hidden = hidden;
  }
};

/**
 * @type {remoting.AppMode} The current app mode
 */
remoting.currentMode = remoting.AppMode.HOME;

/**
 * Change the app's modal state to |mode|, determined by the data-ui-mode
 * attribute.
 *
 * @param {remoting.AppMode} mode The new modal state.
 */
remoting.setMode = function(mode) {
  remoting.updateModalUi(mode, 'data-ui-mode');
  console.log('App mode: ' + mode);
  remoting.currentMode = mode;
  if (mode == remoting.AppMode.IN_SESSION) {
    document.removeEventListener('keydown', remoting.ConnectionStats.onKeydown,
                                 false);
  } else {
    document.addEventListener('keydown', remoting.ConnectionStats.onKeydown,
                              false);
  }
  if (mode == remoting.AppMode.HOME) {
    var display = function() { remoting.hostList.display(); };
    remoting.hostList.refresh(display);
  }
};

/**
 * Get the major mode that the app is running in.
 * @return {string} The app's current major mode.
 */
remoting.getMajorMode = function() {
  return remoting.currentMode.split('.')[0];
};
<commit_msg>[Chromoting] Set the focus appropriately when asking the user for an access code.<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

/**
 * @fileoverview
 * Functions related to controlling the modal UI state of the app. UI states
 * are expressed as HTML attributes with a dotted hierarchy. For example, the
 * string 'host.shared' will match any elements with an associated attribute
 * of 'host' or 'host.shared', showing those elements and hiding all others.
 * Elements with no associated attribute are ignored.
 */

'use strict';

/** @suppress {duplicate} */
var remoting = remoting || {};

/** @enum {string} */
// TODO(jamiewalch): Move 'in-session' to a separate web-page so that the
// 'home' state applies to all elements and can be removed.
remoting.AppMode = {
  HOME: 'home',
    UNAUTHENTICATED: 'home.auth',
    HOST: 'home.host',
      HOST_WAITING_FOR_CODE: 'home.host.waiting-for-code',
      HOST_WAITING_FOR_CONNECTION: 'home.host.waiting-for-connection',
      HOST_SHARED: 'home.host.shared',
      HOST_SHARE_FAILED: 'home.host.share-failed',
      HOST_SHARE_FINISHED: 'home.host.share-finished',
    CLIENT: 'home.client',
      CLIENT_UNCONNECTED: 'home.client.unconnected',
      CLIENT_PIN_PROMPT: 'home.client.pin-prompt',
      CLIENT_CONNECTING: 'home.client.connecting',
      CLIENT_CONNECT_FAILED_IT2ME: 'home.client.connect-failed.it2me',
      CLIENT_CONNECT_FAILED_ME2ME: 'home.client.connect-failed.me2me',
      CLIENT_SESSION_FINISHED_IT2ME: 'home.client.session-finished.it2me',
      CLIENT_SESSION_FINISHED_ME2ME: 'home.client.session-finished.me2me',
    HISTORY: 'home.history',
    CONFIRM_HOST_DELETE: 'home.confirm-host-delete',
    ASK_PIN: 'home.ask-pin',
  IN_SESSION: 'in-session'
};

/**
 * @param {Element} element The element to check.
 * @param {string} attr The attribute on the element to check.
 * @param {string} mode The mode to check for.
 * @return {boolean} True if |mode| is found within the element's |attr|.
 */
remoting.hasModeAttribute = function(element, attr, mode) {
  return element.getAttribute(attr).match(
      new RegExp('(\\s|^)' + mode + '(\\s|$)')) != null;
};

/**
 * Update the DOM by showing or hiding elements based on whether or not they
 * have an attribute matching the specified name.
 * @param {string} mode The value against which to match the attribute.
 * @param {string} attr The attribute name to match.
 * @return {void} Nothing.
 */
remoting.updateModalUi = function(mode, attr) {
  var modes = mode.split('.');
  for (var i = 1; i < modes.length; ++i)
    modes[i] = modes[i - 1] + '.' + modes[i];
  var elements = document.querySelectorAll('[' + attr + ']');
  for (var i = 0; i < elements.length; ++i) {
    var element = /** @type {Element} */ elements[i];
    var hidden = true;
    for (var m = 0; m < modes.length; ++m) {
      if (remoting.hasModeAttribute(element, attr, modes[m])) {
        hidden = false;
        break;
      }
    }
    element.hidden = hidden;
    if (!hidden) {
      var autofocusNode = element.querySelector('[autofocus]');
      if (autofocusNode) {
        autofocusNode.focus();
      }
    }
  }
};

/**
 * @type {remoting.AppMode} The current app mode
 */
remoting.currentMode = remoting.AppMode.HOME;

/**
 * Change the app's modal state to |mode|, determined by the data-ui-mode
 * attribute.
 *
 * @param {remoting.AppMode} mode The new modal state.
 */
remoting.setMode = function(mode) {
  remoting.updateModalUi(mode, 'data-ui-mode');
  console.log('App mode: ' + mode);
  remoting.currentMode = mode;
  if (mode == remoting.AppMode.IN_SESSION) {
    document.removeEventListener('keydown', remoting.ConnectionStats.onKeydown,
                                 false);
  } else {
    document.addEventListener('keydown', remoting.ConnectionStats.onKeydown,
                              false);
  }
  if (mode == remoting.AppMode.HOME) {
    var display = function() { remoting.hostList.display(); };
    remoting.hostList.refresh(display);
  }
};

/**
 * Get the major mode that the app is running in.
 * @return {string} The app's current major mode.
 */
remoting.getMajorMode = function() {
  return remoting.currentMode.split('.')[0];
};
<|endoftext|>


<commit_before><commit_msg>Pseudo code for moves.<commit_after>pawn: [x + 1][y]
	initial move: if(pawn counter === 0){[x + 1 || x + 2][y]}
	promote: if(wpawn x === 7 || bpawn x === 0){choose piece to replace}

rook: [x + 1*n][y]
			[x - 1*n][y]
			[x][y + 1*n]
			[x][y - 1*n]

knight: [x + 2][y + 1]
				[x + 1][y + 2]
				[x - 2][y + 1]
				[x + 2][y - 1]

bishop: [x + 1*n][y + 1*n]
				[x - 1*n][y + 1*n]
				[x + 1*n][y - 1*n]
				[x - 1*n][y - 1*n]

queen: [x + 1*n][y]
			 [x - 1*n][y]
			 [x][y + 1*n]
			 [x][y - 1*n]
			 [x + 1*n][y + 1*n]
			 [x - 1*n][y + 1*n]
			 [x + 1*n][y - 1*n]
			 [x - 1*n][y - 1*n]

king: [x + 1][y]
			[x - 1][y]
			[x][y + 1]
			[x][y - 1]
			[x + 1][y + 1]
			[x - 1][y + 1]
			[x + 1][y - 1]
			[x - 1][y - 1]

castle-right: king: [x][y + 2]
							rook: [x][y - 2]
castle-left:  king: [x][y -2]
							rook:	[x][y + 3]<|endoftext|>


<commit_before>/**
 * Copyright 2015 IBM Corp. 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.
 */

'use strict';

$(document).ready(function() {

  var MIN_WORDS = 100;

  var widgetId = 'vizcontainer', // Must match the ID in index.jade
    widgetWidth = 700, widgetHeight = 700, // Default width and height
    personImageUrl = 'images/app.png', // Can be blank
    language = 'en'; // language selection

  // Jquery variables
  var $content = $('.content'),
    $loading   = $('.loading'),
    $error     = $('.error'),
    $errorMsg  = $('.errorMsg'),
    $traits    = $('.traits'),
    $results   = $('.results');

  /**
   * Clear the "textArea"
   */
  $('.clear-btn').click(function(){
    $('.clear-btn').blur();
    $content.val('');
    updateWordsCount();
  });

  /**
   * Update words count on change
   */
  $content.change(updateWordsCount);

  /**
   * Update words count on copy/past
   */
  $content.bind('paste', function() {
    setTimeout(updateWordsCount, 100);
  });

  /**
   * 1. Create the request
   * 2. Call the API
   * 3. Call the methods to display the results
   */
  $('.analysis-btn').click(function(){
    $('.analysis-btn').blur();

    $loading.show();
    $error.hide();
    $traits.hide();
    $results.hide();

    $.ajax({
      type: 'POST',
      data: {
        text: $content.val(),
        language: language
      },
      url: 'demo',
      dataType: 'json',
      success: function(response) {
        $loading.hide();

        if (response.error) {
          showError(response.error);
        } else {
          $results.show();
          showTraits(response);
          showTextSummary(response);
          showVizualization(response);
        }

      },
      error: function(xhr) {
        $loading.hide();

        var error;
        try {
          error = JSON.parse(xhr.responseText || {});
        } catch(e) {}
        showError(error.error || error);
      }
    });
  });

  /**
   * Display an error or a default message
   * @param  {String} error The error
   */
  function showError(error) {
    var defaultErrorMsg = 'Error processing the request, please try again later.';
    $error.show();
    $errorMsg.text(error || defaultErrorMsg);
  }

  /**
   * Displays the traits received from the
   * Personality Insights API in a table,
   * just trait names and values.
   */
  function showTraits(data) {
    console.log('showTraits()');
    $traits.show();

    var traitList = flatten(data.tree),
      table = $traits;

    table.empty();

    // Header
    $('#header-template').clone().appendTo(table);

    // For each trait
    for (var i = 0; i < traitList.length; i++) {
      var elem = traitList[i];

      var Klass = 'row';
      Klass += (elem.title) ? ' model_title' : ' model_trait';
      Klass += (elem.value === '') ? ' model_name' : '';

      if (elem.value !== '') { // Trait child name
        $('#trait-template').clone()
          .attr('class', Klass)
          .find('.tname')
          .find('span').html(elem.id).end()
          .end()
          .find('.tvalue')
            .find('span').html(elem.value === '' ?  '' : (elem.value + ' (± '+ elem.sampling_error+')'))
            .end()
          .end()
          .appendTo(table);
      } else {
        // Model name
        $('#model-template').clone()
          .attr('class', Klass)
          .find('.col-lg-12')
          .find('span').html(elem.id).end()
          .end()
          .appendTo(table);
      }
    }
  }

  /**
   * Construct a text representation for big5 traits crossing, facets and
   * values.
   */
  function showTextSummary(data) {
    console.log('showTextSummary()');
    var paragraphs = textSummary.assemble(data.tree);
    var div = $('.summary-div');
    $('.outputWordCountMessage').text(data.word_count_message ? '**' + data.word_count_message + '.' : '');
    div.empty();
    paragraphs.forEach(function(sentences) {
      $('

').text(sentences.join(' ')).appendTo(div);
    });
  }

/**
 * Renders the sunburst visualization. The parameter is the tree as returned
 * from the Personality Insights JSON API.
 * It uses the arguments widgetId, widgetWidth, widgetHeight and personImageUrl
 * declared on top of this script.
 */
function showVizualization(theProfile) {
  console.log('showVizualization()');

  $('#' + widgetId).empty();
  var d3vis = d3.select('#' + widgetId).append('svg:svg');
  var widget = {
    d3vis: d3vis,
    data: theProfile,
    loadingDiv: 'dummy',
    switchState: function() {
      console.log('[switchState]');
    },
    _layout: function() {
      console.log('[_layout]');
    },
    showTooltip: function() {
      console.log('[showTooltip]');
    },
    id: 'SystemUWidget',
    COLOR_PALLETTE: ['#1b6ba2', '#488436', '#d52829', '#F53B0C', '#972a6b', '#8c564b', '#dddddd'],
    expandAll: function() {
      this.vis.selectAll('g').each(function() {
        var g = d3.select(this);
        if (g.datum().parent && // Isn't the root g object.
          g.datum().parent.parent && // Isn't the feature trait.
          g.datum().parent.parent.parent) { // Isn't the feature dominant trait.
          g.attr('visibility', 'visible');
        }
      });
    },
    collapseAll: function() {
      this.vis.selectAll('g').each(function() {
        var g = d3.select(this);
        if (g.datum().parent !== null && // Isn't the root g object.
          g.datum().parent.parent !== null && // Isn't the feature trait.
          g.datum().parent.parent.parent !== null) { // Isn't the feature dominant trait.
          g.attr('visibility', 'hidden');
        }
      });
    },
    addPersonImage: function(url) {
      if (!this.vis || !url) {
        return;
      }
      var icon_defs = this.vis.append('defs');
      var width = this.dimW,
        height = this.dimH;

      // The flower had a radius of 640 / 1.9 = 336.84 in the original, now is 3.2.
      var radius = Math.min(width, height) / 16.58; // For 640 / 1.9 -> r = 65
      var scaled_w = radius * 2.46; // r = 65 -> w = 160

      var id = 'user_icon_' + this.id;
      icon_defs.append('pattern')
        .attr('id', id)
        .attr('height', 1)
        .attr('width', 1)
        .attr('patternUnits', 'objectBoundingBox')
        .append('image')
        .attr('width', scaled_w)
        .attr('height', scaled_w)
        .attr('x', radius - scaled_w / 2) // r = 65 -> x = -25
        .attr('y', radius - scaled_w / 2)
        .attr('xlink:href', url)
        .attr('opacity', 1.0)
        .on('dblclick.zoom', null);
      this.vis.append('circle')
        .attr('r', radius)
        .attr('stroke-width', 0)
        .attr('fill', 'url(#' + id + ')');
    }
  };

  widget.dimH = widgetHeight;
  widget.dimW = widgetWidth;
  widget.d3vis.attr('width', widget.dimW).attr('height', widget.dimH);
  widget.d3vis.attr('viewBox', '0 0 ' + widget.dimW + ', ' + widget.dimH);
  renderChart.call(widget);
  widget.expandAll.call(widget);
  if (personImageUrl)
    widget.addPersonImage.call(widget, personImageUrl);
}

  /**
   * Returns a 'flattened' version of the traits tree, to display it as a list
   * @return array of {id:string, title:boolean, value:string} objects
   */
  function flatten( /*object*/ tree) {
    var arr = [],
      f = function(t, level) {
        if (!t) return;
        if (level > 0 && (!t.children || level !== 2)) {
          arr.push({
            'id': t.name,
            'title': t.children ? true : false,
            'value': (typeof (t.percentage) !== 'undefined') ? Math.floor(t.percentage * 100) + '%' : '',
            'sampling_error': (typeof (t.sampling_error) !== 'undefined') ? Math.floor(t.sampling_error * 100) + '%' : ''
          });
        }
        if (t.children && t.id !== 'sbh') {
          for (var i = 0; i < t.children.length; i++) {
            f(t.children[i], level + 1);
          }
        }
      };
    f(tree, 0);
    return arr;
  }

  function updateWordsCount() {
    var text = $content.val();
    var wordsCount = text.match(/\S+/g) ? text.match(/\S+/g).length : 0;
    $('.inputFootnote').css('color',wordsCount < MIN_WORDS ? 'red' : 'gray');
    $('.wordsCount').text(wordsCount);
  }

  function onSampleTextChange() {
    var isEnglish = $('#english_radio').is(':checked');
    language = isEnglish ? 'en' : 'es';

    $.get('text/' + language + '.txt').done(function(text) {
      $content.val(text);
      updateWordsCount();
    });
  }

  onSampleTextChange();
  $content.keyup(updateWordsCount);
  $('.sample-radio').change(onSampleTextChange);
});
<commit_msg>desligado<commit_after>/**
 * Copyright 2015 IBM Corp. 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.
 */

'use strict';

$(document).ready(function() {

  var MIN_WORDS = 100;

  var widgetId = 'vizcontainer', // Must match the ID in index.jade
    widgetWidth = 700, widgetHeight = 700, // Default width and height
    personImageUrl = 'images/app.png', // Can be blank
    language = 'en'; // language selection

  // Jquery variables
  var $content = $('.content'),
    $loading   = $('.loading'),
    $error     = $('.error'),
    $errorMsg  = $('.errorMsg'),
    $traits    = $('.traits'),
    $results   = $('.results');

  /**
   * Clear the "textArea"
   */
  $('.clear-btn').click(function(){
    $('.clear-btn').blur();
    $content.val('');
    updateWordsCount();
  });

  /**
   * Update words count on change
   */
  $content.change(updateWordsCount);

  /**
   * Update words count on copy/past
   */
  $content.bind('paste', function() {
    setTimeout(updateWordsCount, 100);
  });

  /**
   * 1. Create the request
   * 2. Call the API
   * 3. Call the methods to display the results
   */
  $('.analysis-btn').click(function(){
    $('.analysis-btn').blur();

    $loading.show();
    $error.hide();
    $traits.hide();
    $results.hide();

    $.ajax({
      type: 'POST',
      data: {
        text: $content.val(),
        language: language
      },
      url: 'demo',
      dataType: 'json',
      success: function(response) {
        $loading.hide();

        if (response.error) {
          showError(response.error);
        } else {
          $results.show();
          showTraits(response);
          /*showTextSummary(response);
          showVizualization(response);*/
        }

      },
      error: function(xhr) {
        $loading.hide();

        var error;
        try {
          error = JSON.parse(xhr.responseText || {});
        } catch(e) {}
        showError(error.error || error);
      }
    });
  });

  /**
   * Display an error or a default message
   * @param  {String} error The error
   */
  function showError(error) {
    var defaultErrorMsg = 'Error processing the request, please try again later.';
    $error.show();
    $errorMsg.text(error || defaultErrorMsg);
  }

  /**
   * Displays the traits received from the
   * Personality Insights API in a table,
   * just trait names and values.
   */
  function showTraits(data) {
    console.log('showTraits()');
    $traits.show();

    var traitList = flatten(data.tree),
      table = $traits;

    table.empty();

    // Header
    $('#header-template').clone().appendTo(table);

    // For each trait
    for (var i = 0; i < traitList.length; i++) {
      var elem = traitList[i];

      var Klass = 'row';
      Klass += (elem.title) ? ' model_title' : ' model_trait';
      Klass += (elem.value === '') ? ' model_name' : '';

      if (elem.value !== '') { // Trait child name
        $('#trait-template').clone()
          .attr('class', Klass)
          .find('.tname')
          .find('span').html(elem.id).end()
          .end()
          .find('.tvalue')
            .find('span').html(elem.value === '' ?  '' : (elem.value + ' (± '+ elem.sampling_error+')'))
            .end()
          .end()
          .appendTo(table);
      } else {
        // Model name
        $('#model-template').clone()
          .attr('class', Klass)
          .find('.col-lg-12')
          .find('span').html(elem.id).end()
          .end()
          .appendTo(table);
      }
    }
  }

  /**
   * Construct a text representation for big5 traits crossing, facets and
   * values.
   */
  function showTextSummary(data) {
    console.log('showTextSummary()');
    var paragraphs = textSummary.assemble(data.tree);
    var div = $('.summary-div');
    $('.outputWordCountMessage').text(data.word_count_message ? '**' + data.word_count_message + '.' : '');
    div.empty();
    paragraphs.forEach(function(sentences) {
      $('

').text(sentences.join(' ')).appendTo(div);
    });
  }

/**
 * Renders the sunburst visualization. The parameter is the tree as returned
 * from the Personality Insights JSON API.
 * It uses the arguments widgetId, widgetWidth, widgetHeight and personImageUrl
 * declared on top of this script.
 */
function showVizualization(theProfile) {
  console.log('showVizualization()');

  $('#' + widgetId).empty();
  var d3vis = d3.select('#' + widgetId).append('svg:svg');
  var widget = {
    d3vis: d3vis,
    data: theProfile,
    loadingDiv: 'dummy',
    switchState: function() {
      console.log('[switchState]');
    },
    _layout: function() {
      console.log('[_layout]');
    },
    showTooltip: function() {
      console.log('[showTooltip]');
    },
    id: 'SystemUWidget',
    COLOR_PALLETTE: ['#1b6ba2', '#488436', '#d52829', '#F53B0C', '#972a6b', '#8c564b', '#dddddd'],
    expandAll: function() {
      this.vis.selectAll('g').each(function() {
        var g = d3.select(this);
        if (g.datum().parent && // Isn't the root g object.
          g.datum().parent.parent && // Isn't the feature trait.
          g.datum().parent.parent.parent) { // Isn't the feature dominant trait.
          g.attr('visibility', 'visible');
        }
      });
    },
    collapseAll: function() {
      this.vis.selectAll('g').each(function() {
        var g = d3.select(this);
        if (g.datum().parent !== null && // Isn't the root g object.
          g.datum().parent.parent !== null && // Isn't the feature trait.
          g.datum().parent.parent.parent !== null) { // Isn't the feature dominant trait.
          g.attr('visibility', 'hidden');
        }
      });
    },
    addPersonImage: function(url) {
      if (!this.vis || !url) {
        return;
      }
      var icon_defs = this.vis.append('defs');
      var width = this.dimW,
        height = this.dimH;

      // The flower had a radius of 640 / 1.9 = 336.84 in the original, now is 3.2.
      var radius = Math.min(width, height) / 16.58; // For 640 / 1.9 -> r = 65
      var scaled_w = radius * 2.46; // r = 65 -> w = 160

      var id = 'user_icon_' + this.id;
      icon_defs.append('pattern')
        .attr('id', id)
        .attr('height', 1)
        .attr('width', 1)
        .attr('patternUnits', 'objectBoundingBox')
        .append('image')
        .attr('width', scaled_w)
        .attr('height', scaled_w)
        .attr('x', radius - scaled_w / 2) // r = 65 -> x = -25
        .attr('y', radius - scaled_w / 2)
        .attr('xlink:href', url)
        .attr('opacity', 1.0)
        .on('dblclick.zoom', null);
      this.vis.append('circle')
        .attr('r', radius)
        .attr('stroke-width', 0)
        .attr('fill', 'url(#' + id + ')');
    }
  };

  widget.dimH = widgetHeight;
  widget.dimW = widgetWidth;
  widget.d3vis.attr('width', widget.dimW).attr('height', widget.dimH);
  widget.d3vis.attr('viewBox', '0 0 ' + widget.dimW + ', ' + widget.dimH);
  renderChart.call(widget);
  widget.expandAll.call(widget);
  if (personImageUrl)
    widget.addPersonImage.call(widget, personImageUrl);
}

  /**
   * Returns a 'flattened' version of the traits tree, to display it as a list
   * @return array of {id:string, title:boolean, value:string} objects
   */
  function flatten( /*object*/ tree) {
    var arr = [],
      f = function(t, level) {
        if (!t) return;
        if (level > 0 && (!t.children || level !== 2)) {
          arr.push({
            'id': t.name,
            'title': t.children ? true : false,
            'value': (typeof (t.percentage) !== 'undefined') ? Math.floor(t.percentage * 100) + '%' : '',
            'sampling_error': (typeof (t.sampling_error) !== 'undefined') ? Math.floor(t.sampling_error * 100) + '%' : ''
          });
        }
        if (t.children && t.id !== 'sbh') {
          for (var i = 0; i < t.children.length; i++) {
            f(t.children[i], level + 1);
          }
        }
      };
    f(tree, 0);
    return arr;
  }

  function updateWordsCount() {
    var text = $content.val();
    var wordsCount = text.match(/\S+/g) ? text.match(/\S+/g).length : 0;
    $('.inputFootnote').css('color',wordsCount < MIN_WORDS ? 'red' : 'gray');
    $('.wordsCount').text(wordsCount);
  }

  function onSampleTextChange() {
    var isEnglish = $('#english_radio').is(':checked');
    language = isEnglish ? 'en' : 'es';

    $.get('text/' + language + '.txt').done(function(text) {
      $content.val(text);
      updateWordsCount();
    });
  }

  onSampleTextChange();
  $content.keyup(updateWordsCount);
  $('.sample-radio').change(onSampleTextChange);
});
<|endoftext|>


<commit_before>// Copyright 2015-2019, University of Colorado Boulder

/**
 * Tandem is used to assign unique identifiers to PhetioObjects in PhET simulations and register/unregister them in a
 * registry. It is used to support PhET-iO.
 *
 * @author Sam Reid (PhET Interactive Simulations)
 */
define( function( require ) {
  'use strict';

  // modules
  var inherit = require( 'PHET_CORE/inherit' );
  var tandemNamespace = require( 'TANDEM/tandemNamespace' );
  var toCamelCase = require( 'PHET_CORE/toCamelCase' );

  // text
  var packageString = require( 'text!REPOSITORY/package.json' );

  // constants
  var packageJSON = JSON.parse( packageString ); // Tandem can't depend on joist, so requiring packageJSON doesn't work
  var PHET_IO_ENABLED = !!( window.phet && window.phet.phetio );

  // used to keep track of missing tandems, see phet.phetio.queryParameters.phetioPrintMissingTandems
  var missingTandems = {
    required: [],
    optional: [],
    uninstrumented: []
  };

  // Listeners that will be notified when items are registered/deregistered. See doc in addPhetioObjectListener
  var phetioObjectListeners = [];

  // variables
  // Before listeners are wired up, tandems are buffered.  When listeners are wired up, Tandem.launch() is called
  // and buffered tandems are flushed, then subsequent tandems are delivered to listeners directly
  var launched = false;
  var bufferedPhetioObjects = [];

  /**
   * Typically, sims will create tandems using `tandem.createTandem`.  This constructor is used internally or when
   * a tandem must be created from scratch.
   *
   * @param {string} phetioID - unique identifier as a string ('' for a root id)
   * @param {Object} [options]
   * @constructor
   */
  function Tandem( phetioID, options ) {

    assert && assert( phetioID.indexOf( ' ' ) === -1, 'phetioID cannot contain whitespace: ' + phetioID );

    // options (even subtype options) must be stored on the instance so they can be passed through to children
    // Note: Make sure that added options here are also added to options for inheritance and/or
    // for composition (createTandem/parentTandem) as they make sense.
    options = _.extend( {

      // if the tandem is not supplied and required, an error will be thrown.
      supplied: true,

      // required === false means it is an optional tandem
      required: true
    }, options );

    // @public (read-only)
    this.phetioID = ( phetioID !== undefined ) ? phetioID : '';

    // @private
    this.required = options.required;

    // @private
    this.supplied = options.supplied;
  }

  tandemNamespace.register( 'Tandem', Tandem );

  inherit( Object, Tandem, {

    /**
     * Adds a PhetioObject.  For example, it could be an axon Property, scenery Node or Sun button.  Each item should
     * only be added to the registry once, but that is not enforced here in Tandem.  For PhET-iO, phetioEngine.js
     * enforces one entry per ID in phetio.phetioObjectAdded
     *
     * This is used to register PhetioObjects with PhET-iO.
     * @param {PhetioObject} phetioObject
     * @public
     */
    addPhetioObject: function( phetioObject ) {
      assert && assert( arguments.length === 1, 'Tandem.addPhetioObject takes one argument' );

      // Cannot use typical require statement for PhetioObject because it creates a module loading loop
      assert && assert( phetioObject instanceof tandemNamespace.PhetioObject, 'argument should be of type PhetioObject' );

      if ( PHET_IO_ENABLED ) {

        // Throw an error if the tandem is required but not supplied
        if ( Tandem.validationEnabled() ) {
          assert && assert( !( this.required && !this.supplied ), 'Tandem was required but not supplied' );
        }

        // phetioPrintMissingTandems flag is present for a tandem that is required but not supplied.
        if ( phet.phetio.queryParameters.phetioPrintMissingTandems && ( this.required && !this.supplied ) ) {
          missingTandems.required.push( { phetioID: this.phetioID, stack: new Error().stack } );
        }

        // If tandem is optional, then don't add it
        if ( !this.required && !this.supplied ) {
          if ( phet.phetio.queryParameters.phetioPrintMissingTandems ) {
            var stackTrace = new Error().stack;

            // Generally Font is not desired because there are so many untandemized Fonts.
            if ( stackTrace.indexOf( 'PhetFont' ) === -1 ) {
              missingTandems.optional.push( { phetioID: this.phetioID, stack: stackTrace } );
            }
          }

          // For optionally instrumented types that are not provided tandems, the instance isn't really "added"
          // but likewise, it in not an error
          return;
        }

        if ( !launched ) {
          bufferedPhetioObjects.push( phetioObject );
        }
        else {
          for ( var i = 0; i < phetioObjectListeners.length; i++ ) {
            phetioObjectListeners[ i ].addPhetioObject( phetioObject );
          }
        }
      }
    },

    /**
     * Removes an instance from the registry
     * @param {PhetioObject} phetioObject - the instance to remove
     * @public
     */
    removeInstance: function( phetioObject ) {
      if ( !this.required && !this.supplied ) {
        return;
      }

      // Only active when running as phet-io
      if ( PHET_IO_ENABLED ) {
        for ( var i = 0; i < phetioObjectListeners.length; i++ ) {
          phetioObjectListeners[ i ].removePhetioObject( phetioObject );
        }
      }
    },

    /**
     * Create a new Tandem by appending the given id
     * @param {string} id
     * @param {Object} [options]
     * @returns {Tandem}
     * @public
     */
    createTandem: function( id, options ) {

      // Make sure the id was provided
      assert && assert( typeof id === 'string' && id.length > 0, 'id must be defined' );
      assert && assert( id.indexOf( '.' ) === -1, 'createTandem cannot accept dots: ' + id );
      assert && assert( id.indexOf( ' ' ) === -1, 'createTandem cannot accept whitespace: ' + id );
      assert && assert( id.indexOf( '-' ) === -1, 'createTandem cannot accept dash: ' + id );

      var string = ( this.phetioID.length > 0 ) ? phetio.PhetioIDUtils.append( this.phetioID, id ) : id;

      // Any child of something should be passed all inherited options. Make sure that this extend call includes all
      // that make sense from the constructor's extend call.
      options = _.extend( {
        supplied: this.supplied,
        required: this.required
      }, options );

      return new Tandem( string, options );
    },

    /**
     * Creates a group tandem for creating multiple indexed child tandems, such as:
     * sim.screen.model.electron_0
     * sim.screen.model.electron_1
     *
     * In this case, 'sim.screen.model.electron' is the string passed to createGroupTandem.
     *
     * Used for arrays, observable arrays, or when many elements of the same type are created and they do not otherwise
     * have unique identifiers.
     * @param {string} id
     * @param {string} [elementPrefix]
     * @returns {GroupTandem}
     * @public
     */
    createGroupTandem: function( id, elementPrefix ) {

      assert && assert( id.indexOf( '.' ) === -1, 'createTandem cannot accept dots: ' + id );
      assert && assert( id.indexOf( ' ' ) === -1, 'createTandem cannot accept whitespace: ' + id );

      // Unfortunately we must resort to globals here since loading through the namespace would create a cycle
      return new GroupTandem( phetio.PhetioIDUtils.append( this.phetioID, id ), elementPrefix );
    },

    /**
     * Get the last part of the tandem (after the last .), used in Joist for creating button names dynamically based
     * on screen names
     * @returns {string} the tail of the tandem
     * @public
     */
    get tail() { // TODO: rename to getComponentName()
      return phetio.PhetioIDUtils.getComponentName( this.phetioID );
    },

    /**
     * Returns a Tandem for everything except the tail.
     * @returns {Tandem}
     * @public
     */
    get parentTandem() {
      var headID = phetio.PhetioIDUtils.getParentID( this.phetioID );

      return new Tandem( headID, {
        required: this.required,
        supplied: this.supplied
      } );
    }
  }, {

    /**
     * Adds a listener that will be notified when items are registered/deregistered
     * Listeners have the form
     * {
     *   addPhetioObject(id,phetioObject),
     *   removePhetioObject(id,phetioObject)
     * }
     * where id is of type {string} and phetioObject is of type {PhetioObject}
     *
     * @param {Object} phetioObjectListener - described above
     * @public
     * @static
     */
    addPhetioObjectListener: function( phetioObjectListener ) {
      phetioObjectListeners.push( phetioObjectListener );
    },

    /**
     * When all listeners are listening, all buffered PhetioObjects are registered.
     * @public
     * @static
     */
    launch: function() {
      assert && assert( !launched, 'Tandem was launched twice' );
      launched = true;
      while ( bufferedPhetioObjects.length > 0 ) {
        var phetioObject = bufferedPhetioObjects.shift();
        phetioObject.register();
      }
    },

    /**
     * Catch cases where tandem is being supplied to a class that doesn't support tandem.
     * @param {Object} [options]
     * @public
     * @static
     */
    disallowTandem: function( options ) {

      if ( Tandem.validationEnabled() ) {
        assert && assert( !options.tandem, 'tandem is not allowed' );
      }
    },

    /**
     * When running in PhET-iO brand, some code (such as user interface components) must be instrumented for PhET-iO.
     * Uninstrumented files should call this function to indicate they still need to be instrumented, so they aren't
     * missed.  See https://github.com/phetsims/phet-io/issues/668
     * @public
     * @static
     */
    indicateUninstrumentedCode: function() {

      // Guard against undefined errors
      if ( PHET_IO_ENABLED ) {

        // Assert if validating tandems
        if ( this.validationEnabled() ) {
          assert && assert( false, 'Uninstrumented code detected' );
        }

        // Print stack trace if query parameter supplied
        if ( phet.phetio.queryParameters.phetioPrintMissingTandems ) {
          missingTandems.uninstrumented.push( { stack: new Error().stack } );
        }
      }
    },

    /**
     * Determine whether or not tandem validation is turned on for the sim.
     * @returns {Boolean} If tandems are being validated or not.
     * @public
     * @static
     */
    validationEnabled: function() {
      return PHET_IO_ENABLED &&
             phet.phetio.queryParameters.phetioValidateTandems &&

             // If we are printing the missing tandems, then validation must be disabled because the intention is to
             // run with partial tandem coverage and see which are missing.
             !phet.phetio.queryParameters.phetioPrintMissingTandems;
    }
  } );

  // The next few statics are created outside the static block because they instantiate Tandem instances.

  /**
   * The root tandem for a simulation
   * @public
   * @static
   * @type {Tandem}
   */
  Tandem.rootTandem = new Tandem( toCamelCase( packageJSON.name ) );

  /**
   * Many simulation elements are nested under "general".
   * @public
   * @static
   * @type {Tandem}
   */
  Tandem.generalTandem = Tandem.rootTandem.createTandem( 'general' );

  /**
   * Used to indicate a common code component that supports tandem, but doesn't not require it.
   * If a tandem is not passed through to this instance, then it will not be instrumented.
   * @public
   * @static
   * @type {Tandem}
   */
  Tandem.optional = Tandem.rootTandem.createTandem( 'optionalTandem', {
    required: false,
    supplied: false
  } );

  /**
   * Some common code (such as Checkbox or RadioButton) must always be instrumented and hence requires a tandem to be
   * passed in.
   * @public
   * @static
   * @type {Tandem}
   */
  Tandem.required = Tandem.rootTandem.createTandem( 'requiredTandem', {

    // let phetioPrintMissingTandems bypass this
    required: PHET_IO_ENABLED && ( phet.phetio.queryParameters.phetioValidateTandems || phet.phetio.queryParameters.phetioPrintMissingTandems ),
    supplied: false
  } );

  /**
   * Expose collected missing tandems only populated from specific query parameter, see phetioPrintMissingTandems for more
   * @public (phet-io internal)
   * @type {Object}
   */
  Tandem.missingTandems = missingTandems;

  /**
   * Group Tandem -- Declared in the same file to avoid circular reference errors in module loading.
   * @param {string} id - id as a string (or '' for a root id)
   * @constructor
   * @private create with Tandem.createGroupTandem
   */
  function GroupTandem( id, prefix ) {

    Tandem.call( this, id );

    // @private for generating indices from a pool
    this.groupElementIndex = 0;

    // @private
    this.prefix = prefix || 'element';
  }

  tandemNamespace.register( 'Tandem.GroupTandem', GroupTandem );

  inherit( Tandem, GroupTandem, {

    /**
     * Creates the next tandem in the group.
     * @returns {Tandem}
     * @public
     */
    createNextTandem: function() {
      return this.createTandem( this.prefix + '_' + ( this.groupElementIndex++ ) );
    },

    /**
     * Groups contain a prototype instance which demonstrates the PhET-iO API for that subtree.
     * This method creates the standard prototype Tandem name.
     * @returns {Tandem}
     * @public
     */
    createPrototypeTandem: function() {
      return this.createTandem( 'prototype' );
    }
  } );

  return Tandem;
} );<commit_msg>Comment out linked elements, see https://github.com/phetsims/sun/issues/420<commit_after>// Copyright 2015-2019, University of Colorado Boulder

/**
 * Tandem is used to assign unique identifiers to PhetioObjects in PhET simulations and register/unregister them in a
 * registry. It is used to support PhET-iO.
 *
 * @author Sam Reid (PhET Interactive Simulations)
 */
define( function( require ) {
  'use strict';

  // modules
  var inherit = require( 'PHET_CORE/inherit' );
  var tandemNamespace = require( 'TANDEM/tandemNamespace' );
  var toCamelCase = require( 'PHET_CORE/toCamelCase' );

  // text
  var packageString = require( 'text!REPOSITORY/package.json' );

  // constants
  var packageJSON = JSON.parse( packageString ); // Tandem can't depend on joist, so requiring packageJSON doesn't work
  var PHET_IO_ENABLED = !!( window.phet && window.phet.phetio );

  // used to keep track of missing tandems, see phet.phetio.queryParameters.phetioPrintMissingTandems
  var missingTandems = {
    required: [],
    optional: [],
    uninstrumented: []
  };

  // Listeners that will be notified when items are registered/deregistered. See doc in addPhetioObjectListener
  var phetioObjectListeners = [];

  // variables
  // Before listeners are wired up, tandems are buffered.  When listeners are wired up, Tandem.launch() is called
  // and buffered tandems are flushed, then subsequent tandems are delivered to listeners directly
  var launched = false;
  var bufferedPhetioObjects = [];

  /**
   * Typically, sims will create tandems using `tandem.createTandem`.  This constructor is used internally or when
   * a tandem must be created from scratch.
   *
   * @param {string} phetioID - unique identifier as a string ('' for a root id)
   * @param {Object} [options]
   * @constructor
   */
  function Tandem( phetioID, options ) {

    assert && assert( phetioID.indexOf( ' ' ) === -1, 'phetioID cannot contain whitespace: ' + phetioID );

    // options (even subtype options) must be stored on the instance so they can be passed through to children
    // Note: Make sure that added options here are also added to options for inheritance and/or
    // for composition (createTandem/parentTandem) as they make sense.
    options = _.extend( {

      // if the tandem is not supplied and required, an error will be thrown.
      supplied: true,

      // required === false means it is an optional tandem
      required: true
    }, options );

    // @public (read-only)
    this.phetioID = ( phetioID !== undefined ) ? phetioID : '';

    // @private
    this.required = options.required;

    // @public (read-only)
    this.supplied = options.supplied;
  }

  tandemNamespace.register( 'Tandem', Tandem );

  inherit( Object, Tandem, {

    /**
     * Adds a PhetioObject.  For example, it could be an axon Property, scenery Node or Sun button.  Each item should
     * only be added to the registry once, but that is not enforced here in Tandem.  For PhET-iO, phetioEngine.js
     * enforces one entry per ID in phetio.phetioObjectAdded
     *
     * This is used to register PhetioObjects with PhET-iO.
     * @param {PhetioObject} phetioObject
     * @public
     */
    addPhetioObject: function( phetioObject ) {
      assert && assert( arguments.length === 1, 'Tandem.addPhetioObject takes one argument' );

      // Cannot use typical require statement for PhetioObject because it creates a module loading loop
      assert && assert( phetioObject instanceof tandemNamespace.PhetioObject, 'argument should be of type PhetioObject' );

      if ( PHET_IO_ENABLED ) {

        // Throw an error if the tandem is required but not supplied
        if ( Tandem.validationEnabled() ) {
          assert && assert( !( this.required && !this.supplied ), 'Tandem was required but not supplied' );
        }

        // phetioPrintMissingTandems flag is present for a tandem that is required but not supplied.
        if ( phet.phetio.queryParameters.phetioPrintMissingTandems && ( this.required && !this.supplied ) ) {
          missingTandems.required.push( { phetioID: this.phetioID, stack: new Error().stack } );
        }

        // If tandem is optional, then don't add it
        if ( !this.required && !this.supplied ) {
          if ( phet.phetio.queryParameters.phetioPrintMissingTandems ) {
            var stackTrace = new Error().stack;

            // Generally Font is not desired because there are so many untandemized Fonts.
            if ( stackTrace.indexOf( 'PhetFont' ) === -1 ) {
              missingTandems.optional.push( { phetioID: this.phetioID, stack: stackTrace } );
            }
          }

          // For optionally instrumented types that are not provided tandems, the instance isn't really "added"
          // but likewise, it in not an error
          return;
        }

        if ( !launched ) {
          bufferedPhetioObjects.push( phetioObject );
        }
        else {
          for ( var i = 0; i < phetioObjectListeners.length; i++ ) {
            phetioObjectListeners[ i ].addPhetioObject( phetioObject );
          }
        }
      }
    },

    /**
     * Removes an instance from the registry
     * @param {PhetioObject} phetioObject - the instance to remove
     * @public
     */
    removeInstance: function( phetioObject ) {
      if ( !this.required && !this.supplied ) {
        return;
      }

      // Only active when running as phet-io
      if ( PHET_IO_ENABLED ) {
        for ( var i = 0; i < phetioObjectListeners.length; i++ ) {
          phetioObjectListeners[ i ].removePhetioObject( phetioObject );
        }
      }
    },

    /**
     * Create a new Tandem by appending the given id
     * @param {string} id
     * @param {Object} [options]
     * @returns {Tandem}
     * @public
     */
    createTandem: function( id, options ) {

      // Make sure the id was provided
      assert && assert( typeof id === 'string' && id.length > 0, 'id must be defined' );
      assert && assert( id.indexOf( '.' ) === -1, 'createTandem cannot accept dots: ' + id );
      assert && assert( id.indexOf( ' ' ) === -1, 'createTandem cannot accept whitespace: ' + id );
      assert && assert( id.indexOf( '-' ) === -1, 'createTandem cannot accept dash: ' + id );

      var string = ( this.phetioID.length > 0 ) ? phetio.PhetioIDUtils.append( this.phetioID, id ) : id;

      // Any child of something should be passed all inherited options. Make sure that this extend call includes all
      // that make sense from the constructor's extend call.
      options = _.extend( {
        supplied: this.supplied,
        required: this.required
      }, options );

      return new Tandem( string, options );
    },

    /**
     * Creates a group tandem for creating multiple indexed child tandems, such as:
     * sim.screen.model.electron_0
     * sim.screen.model.electron_1
     *
     * In this case, 'sim.screen.model.electron' is the string passed to createGroupTandem.
     *
     * Used for arrays, observable arrays, or when many elements of the same type are created and they do not otherwise
     * have unique identifiers.
     * @param {string} id
     * @param {string} [elementPrefix]
     * @returns {GroupTandem}
     * @public
     */
    createGroupTandem: function( id, elementPrefix ) {

      assert && assert( id.indexOf( '.' ) === -1, 'createTandem cannot accept dots: ' + id );
      assert && assert( id.indexOf( ' ' ) === -1, 'createTandem cannot accept whitespace: ' + id );

      // Unfortunately we must resort to globals here since loading through the namespace would create a cycle
      return new GroupTandem( phetio.PhetioIDUtils.append( this.phetioID, id ), elementPrefix );
    },

    /**
     * Get the last part of the tandem (after the last .), used in Joist for creating button names dynamically based
     * on screen names
     * @returns {string} the tail of the tandem
     * @public
     */
    get tail() { // TODO: rename to getComponentName()
      return phetio.PhetioIDUtils.getComponentName( this.phetioID );
    },

    /**
     * Returns a Tandem for everything except the tail.
     * @returns {Tandem}
     * @public
     */
    get parentTandem() {
      var headID = phetio.PhetioIDUtils.getParentID( this.phetioID );

      return new Tandem( headID, {
        required: this.required,
        supplied: this.supplied
      } );
    }
  }, {

    /**
     * Adds a listener that will be notified when items are registered/deregistered
     * Listeners have the form
     * {
     *   addPhetioObject(id,phetioObject),
     *   removePhetioObject(id,phetioObject)
     * }
     * where id is of type {string} and phetioObject is of type {PhetioObject}
     *
     * @param {Object} phetioObjectListener - described above
     * @public
     * @static
     */
    addPhetioObjectListener: function( phetioObjectListener ) {
      phetioObjectListeners.push( phetioObjectListener );
    },

    /**
     * When all listeners are listening, all buffered PhetioObjects are registered.
     * @public
     * @static
     */
    launch: function() {
      assert && assert( !launched, 'Tandem was launched twice' );
      launched = true;
      while ( bufferedPhetioObjects.length > 0 ) {
        var phetioObject = bufferedPhetioObjects.shift();
        phetioObject.register();
      }
    },

    /**
     * Catch cases where tandem is being supplied to a class that doesn't support tandem.
     * @param {Object} [options]
     * @public
     * @static
     */
    disallowTandem: function( options ) {

      if ( Tandem.validationEnabled() ) {
        assert && assert( !options.tandem, 'tandem is not allowed' );
      }
    },

    /**
     * When running in PhET-iO brand, some code (such as user interface components) must be instrumented for PhET-iO.
     * Uninstrumented files should call this function to indicate they still need to be instrumented, so they aren't
     * missed.  See https://github.com/phetsims/phet-io/issues/668
     * @public
     * @static
     */
    indicateUninstrumentedCode: function() {

      // Guard against undefined errors
      if ( PHET_IO_ENABLED ) {

        // Assert if validating tandems
        if ( this.validationEnabled() ) {
          assert && assert( false, 'Uninstrumented code detected' );
        }

        // Print stack trace if query parameter supplied
        if ( phet.phetio.queryParameters.phetioPrintMissingTandems ) {
          missingTandems.uninstrumented.push( { stack: new Error().stack } );
        }
      }
    },

    /**
     * Determine whether or not tandem validation is turned on for the sim.
     * @returns {Boolean} If tandems are being validated or not.
     * @public
     * @static
     */
    validationEnabled: function() {
      return PHET_IO_ENABLED &&
             phet.phetio.queryParameters.phetioValidateTandems &&

             // If we are printing the missing tandems, then validation must be disabled because the intention is to
             // run with partial tandem coverage and see which are missing.
             !phet.phetio.queryParameters.phetioPrintMissingTandems;
    }
  } );

  // The next few statics are created outside the static block because they instantiate Tandem instances.

  /**
   * The root tandem for a simulation
   * @public
   * @static
   * @type {Tandem}
   */
  Tandem.rootTandem = new Tandem( toCamelCase( packageJSON.name ) );

  /**
   * Many simulation elements are nested under "general".
   * @public
   * @static
   * @type {Tandem}
   */
  Tandem.generalTandem = Tandem.rootTandem.createTandem( 'general' );

  /**
   * Used to indicate a common code component that supports tandem, but doesn't not require it.
   * If a tandem is not passed through to this instance, then it will not be instrumented.
   * @public
   * @static
   * @type {Tandem}
   */
  Tandem.optional = Tandem.rootTandem.createTandem( 'optionalTandem', {
    required: false,
    supplied: false
  } );

  /**
   * Some common code (such as Checkbox or RadioButton) must always be instrumented and hence requires a tandem to be
   * passed in.
   * @public
   * @static
   * @type {Tandem}
   */
  Tandem.required = Tandem.rootTandem.createTandem( 'requiredTandem', {

    // let phetioPrintMissingTandems bypass this
    required: PHET_IO_ENABLED && ( phet.phetio.queryParameters.phetioValidateTandems || phet.phetio.queryParameters.phetioPrintMissingTandems ),
    supplied: false
  } );

  /**
   * Expose collected missing tandems only populated from specific query parameter, see phetioPrintMissingTandems for more
   * @public (phet-io internal)
   * @type {Object}
   */
  Tandem.missingTandems = missingTandems;

  /**
   * Group Tandem -- Declared in the same file to avoid circular reference errors in module loading.
   * @param {string} id - id as a string (or '' for a root id)
   * @constructor
   * @private create with Tandem.createGroupTandem
   */
  function GroupTandem( id, prefix ) {

    Tandem.call( this, id );

    // @private for generating indices from a pool
    this.groupElementIndex = 0;

    // @private
    this.prefix = prefix || 'element';
  }

  tandemNamespace.register( 'Tandem.GroupTandem', GroupTandem );

  inherit( Tandem, GroupTandem, {

    /**
     * Creates the next tandem in the group.
     * @returns {Tandem}
     * @public
     */
    createNextTandem: function() {
      return this.createTandem( this.prefix + '_' + ( this.groupElementIndex++ ) );
    },

    /**
     * Groups contain a prototype instance which demonstrates the PhET-iO API for that subtree.
     * This method creates the standard prototype Tandem name.
     * @returns {Tandem}
     * @public
     */
    createPrototypeTandem: function() {
      return this.createTandem( 'prototype' );
    }
  } );

  return Tandem;
} );<|endoftext|>


<commit_before>(function(window, document, undefined) {
    window.onload = init;
    function init() {
        //get the canvas
        var canvas = document.getElementById("mapcanvas");
        var c = canvas.getContext("2d");
        var cwidth = 960;
        var cheight = 540;
        var moves = {
            u: [0,-1],
            d: [0,1],
            l: [-1,0],
            r: [1,0]
        };
        document.getElementById("paintbtn").onclick = paint;

        function rgbToHex(R,G,B) {return toHex(R)+toHex(G)+toHex(B)}
        function toHex(n) {
            n = parseInt(n,10);
            if (isNaN(n)) return "00";
            n = Math.max(0,Math.min(n,255));
            return "0123456789ABCDEF".charAt((n-n%16)/16) + "0123456789ABCDEF".charAt(n%16);
        }

        function floodfill(node, targetcolor, replacementcolor, pathWidth, pathHeight){
            var nodeimgdata = c.getImageData(node.x,node.y,1,1).data;
            var nodecolor = "#" + rgbToHex(nodeimgdata[0],nodeimgdata[1],nodeimgdata[2]);

            if(nodecolor == replacementcolor){
                return;
            }
            if(targetcolor == replacementcolor){
                return;
            }

            if(nodecolor != targetcolor){
                return;
            }
            if(node.x < 0 || node.x >= pathWidth * 30 || node.y < 0 || node.y >= pathHeight*30){
                return;
            }

            c.fillStyle = replacementcolor;
            c.fillRect(node.x, node.y, 8, 8);
            var westnode = {
                x:0,
                y:0
            };
            westnode.x = node.x - 8;
            westnode.y = node.y;
            var eastnode = {
                x:0,
                y:0
            };
            eastnode.x = node.x + 8;
            eastnode.y = node.y
            var northnode = {
                x:0,
                y:0
            };
            northnode.x = node.x;
            northnode.y = node.y - 8;
            var southnode = {
                x:0,
                y:0
            };
            southnode.x = node.x;
            southnode.y = node.y + 8;
            floodfill(westnode, targetcolor, replacementcolor, pathWidth, pathHeight);
            floodfill(eastnode, targetcolor, replacementcolor, pathWidth, pathHeight);
            floodfill(northnode, targetcolor, replacementcolor, pathWidth, pathHeight);
            floodfill(southnode, targetcolor, replacementcolor, pathWidth, pathHeight);
            return;

        }

        function shuffle(array) {
          var currentIndex = array.length, temporaryValue, randomIndex ;

          // While there remain elements to shuffle...
          while (0 !== currentIndex) {

            // Pick a remaining element...
            randomIndex = Math.floor(Math.random() * currentIndex);
            currentIndex -= 1;

            // And swap it with the current element.
            temporaryValue = array[currentIndex];
            array[currentIndex] = array[randomIndex];
            array[randomIndex] = temporaryValue;
          }

          return array;
        }

        function reset(){
            c.clearRect ( 0 , 0 , canvas.width, canvas.height );
            c.beginPath();
        }

        function walk(start, stop, steps){
            var distX = stop.x - start.x;
            var distY = stop.y - start.y;

            var walkSteps = [];
            for(var i = 0; i< Math.abs(distX); i++){
                if(distX < 0){
                    walkSteps.push(moves.l);
                } else {
                    walkSteps.push(moves.r);
                }
            }
            for(var i = 0; i< Math.abs(distY); i++){
                if(distY < 0){
                    walkSteps.push(moves.u);
                } else {
                    walkSteps.push(moves.d);
                }
            }

            //add a number of random pairs based on how big our grid is
            for(var i = 0; i< steps; i++){
                var rand = Math.floor(Math.random() * 2);
                if(rand < 1){
                    walkSteps.push(moves.u);
                    walkSteps.push(moves.d);
                } else{
                    walkSteps.push(moves.l);
                    walkSteps.push(moves.r);
                }
            }

            return shuffle(walkSteps);
        }

        function createRoom(x, y, pw, ph){
            var randw = Math.floor((Math.random() * (pw/2) + 1) );
            var randh = Math.floor((Math.random() * (ph/2) + 1) );
            //alert(randw + ", " + randh);

            return [randw, randh];
        }

        function paint(){
            reset();

            var widthSelect = document.getElementById("width");
            var pathWidth = parseInt(widthSelect.options[widthSelect.selectedIndex].value);

            var heightSelect = document.getElementById("height");
            var pathHeight = parseInt(heightSelect.options[heightSelect.selectedIndex].value);
            //alert(pathWidth + ", " + pathHeight);

            //create a start and endpoint based on the grid size
            var startpoint = {
               x: -1,
               y: -1
            }
           var endpoint = {
               x: -1,
               y: -1
            }
            startpoint.x = 0;
            startpoint.y = pathHeight - 1;

            endpoint.x = pathWidth - 1;
            endpoint.y = 0;

            //paint the base grid
            for(var i = 0; i< pathWidth; i++){
                for(var j = 0; j< pathHeight; j++){

                    c.beginPath();
                    //c.lineWidth = 1;
                    c.fillStyle = "#000000";
                    c.fillRect(i*30, j*30, 30, 30);
                    c.stroke();
               }
           }

           var randsteps = 2* Math.floor((pathWidth/2) * (pathHeight/2));

           //create a random path that we will walk
           var walkArray = walk(startpoint, endpoint, randsteps);

           //create two moving points representing where we are and where we were
           var movingpoint = {
               x: -1,
               y: -1
           };
           var movingpointold = {
               x: -1,
               y: -1
           };
           movingpoint.x = startpoint.x;
           movingpoint.y = startpoint.y;
           movingpointold.x = startpoint.x;
           movingpointold.y = startpoint.y;

           var branch = 0;
           var branchpoint = {
               x: -1,
               y: -1
           };
           //follow the path and paint along the way
           for (var i = 0; i< walkArray.length; i++){
               movingpoint.x = movingpoint.x + walkArray[i][0];
               movingpoint.y = movingpoint.y + walkArray[i][1];
               var oppcurrMoveX = -1 * walkArray[i][0];
               var oppcurrMoveY = -1 * walkArray[i][1];
               var index = -1;
               for(var j = i; j< walkArray.length; j++){
                   if(walkArray[j][0] == oppcurrMoveX && walkArray[j][1] == oppcurrMoveY){
                       index = j;
                       break;
                   }
               }
               if(movingpoint.x > pathWidth -1){
                   movingpoint.x = movingpoint.x - 1;
                   if (index > -1) {
                       walkArray.splice(index, 1);
                   }

               }
               if(movingpoint.x < 0){
                   movingpoint.x = movingpoint.x + 1;
                   if (index > -1) {
                       walkArray.splice(index, 1);
                   }

               }
               if(movingpoint.y > pathHeight -1){
                   movingpoint.y = movingpoint.y - 1;
                   if (index > -1) {
                       walkArray.splice(index, 1);
                   }

               }
               if( movingpoint.y < 0){
                   movingpoint.y = movingpoint.y + 1;
                   if (index > -1) {
                       walkArray.splice(index, 1);
                   }

               }

               var movedirX = movingpoint.x - movingpointold.x;
               var movedirY = movingpoint.y - movingpointold.y;

               for(var l = 0; l< 30; l++){
                   c.fillStyle = "#FFFFFF";
                   c.fillRect(movingpointold.x*30 + movedirX*l + 8, movingpointold.y*30 + movedirY*l + 8, 6, 6);
               }

               c.fillStyle = "#FFFFFF";
               c.fillRect(movingpoint.x*30, movingpoint.y*30, 24, 24);

               if( i >= (pathWidth + pathHeight)/2 - 1 && branch < 1){
                   branchpoint.x = movingpoint.x;
                   branchpoint.y = movingpoint.y;

                   branch++;
               }

               movingpointold.x = movingpoint.x;
               movingpointold.y = movingpoint.y;
           }

            for(var i = 0; i< Math.floor(pathWidth/2)+1; i++){
                for(var j = 0; j< Math.floor(pathHeight/2)+1; j++){
                    var randRoom = Math.floor((Math.random() * 9));
                    if(randRoom < 1){
                        roomDim = createRoom(i,j,pathWidth,pathHeight);
                        c.beginPath();
                        //c.lineWidth = 3;
                        c.fillStyle = "#FFFFFF";
                        c.fillRect(i*30 , j*30, roomDim[0]*30 - 6, roomDim[1]*30 - 6);
                        c.stroke();
                    }
                }
            }

            //paint the start and end points.
            //c.fillStyle = "#33CC33";
            c.fillStyle = "#FFFFFF";
            c.fillRect(startpoint.x*30, startpoint.y*30, 24, 24);
            //c.fillStyle = "#CC0000";
            c.fillStyle = "#FFFFFF";
            c.fillRect(endpoint.x*30, endpoint.y*30, 24 ,24);

            c.fillStyle = "#CC66FF";
            c.fillRect(branchpoint.x*30, branchpoint.y*30, 24, 24);

            var startnode = {
                x:0,
                y:0
            };
            startnode.x = startpoint.x*30;
            startnode.y = startpoint.y*30;
            //floodfill(startnode,"#FFFFFF","#0099FF", pathWidth, pathHeight);
            var imgdata = c.getImageData(0,0,1,1).data;

            //paint the start and end points.
            c.fillStyle = "#33CC33";
            c.fillRect(startpoint.x*30, startpoint.y*30, 24, 24);
            c.fillStyle = "#CC0000";
            c.fillRect(endpoint.x*30, endpoint.y*30, 24 ,24);

        }
    }
})(window, document, undefined);
<commit_msg>Update script.js<commit_after>(function(window, document, undefined) {
    window.onload = init;
    function init() {
        //get the canvas
        var canvas = document.getElementById("mapcanvas");
        var c = canvas.getContext("2d");
        var cwidth = 960;
        var cheight = 540;
        var moves = {
            u: [0,-1],
            d: [0,1],
            l: [-1,0],
            r: [1,0]
        };
        document.getElementById("paintbtn").onclick = paint;

        function rgbToHex(R,G,B) {return toHex(R)+toHex(G)+toHex(B)}
        function toHex(n) {
            n = parseInt(n,10);
            if (isNaN(n)) return "00";
            n = Math.max(0,Math.min(n,255));
            return "0123456789ABCDEF".charAt((n-n%16)/16) + "0123456789ABCDEF".charAt(n%16);
        }

        function floodfill(node, targetcolor, replacementcolor, pathWidth, pathHeight){
            var nodeimgdata = c.getImageData(node.x,node.y,1,1).data;
            var nodecolor = "#" + rgbToHex(nodeimgdata[0],nodeimgdata[1],nodeimgdata[2]);

            if(nodecolor == replacementcolor){
                return;
            }
            if(targetcolor == replacementcolor){
                return;
            }

            if(nodecolor != targetcolor){
                return;
            }
            if(node.x < 0 || node.x >= pathWidth * 30 || node.y < 0 || node.y >= pathHeight*30){
                return;
            }

            c.fillStyle = replacementcolor;
            c.fillRect(node.x, node.y, 8, 8);
            var westnode = {
                x:0,
                y:0
            };
            westnode.x = node.x - 8;
            westnode.y = node.y;
            var eastnode = {
                x:0,
                y:0
            };
            eastnode.x = node.x + 8;
            eastnode.y = node.y
            var northnode = {
                x:0,
                y:0
            };
            northnode.x = node.x;
            northnode.y = node.y - 8;
            var southnode = {
                x:0,
                y:0
            };
            southnode.x = node.x;
            southnode.y = node.y + 8;
            floodfill(westnode, targetcolor, replacementcolor, pathWidth, pathHeight);
            floodfill(eastnode, targetcolor, replacementcolor, pathWidth, pathHeight);
            floodfill(northnode, targetcolor, replacementcolor, pathWidth, pathHeight);
            floodfill(southnode, targetcolor, replacementcolor, pathWidth, pathHeight);
            return;

        }

        function shuffle(array) {
          var currentIndex = array.length, temporaryValue, randomIndex ;

          // While there remain elements to shuffle...
          while (0 !== currentIndex) {

            // Pick a remaining element...
            randomIndex = Math.floor(Math.random() * currentIndex);
            currentIndex -= 1;

            // And swap it with the current element.
            temporaryValue = array[currentIndex];
            array[currentIndex] = array[randomIndex];
            array[randomIndex] = temporaryValue;
          }

          return array;
        }

        function reset(){
            c.clearRect ( 0 , 0 , canvas.width, canvas.height );
            c.beginPath();
        }

        function walk(start, stop, steps){
            var distX = stop.x - start.x;
            var distY = stop.y - start.y;

            var walkSteps = [];
            for(var i = 0; i< Math.abs(distX); i++){
                if(distX < 0){
                    walkSteps.push(moves.l);
                } else {
                    walkSteps.push(moves.r);
                }
            }
            for(var i = 0; i< Math.abs(distY); i++){
                if(distY < 0){
                    walkSteps.push(moves.u);
                } else {
                    walkSteps.push(moves.d);
                }
            }

            //add a number of random pairs based on how big our grid is
            for(var i = 0; i< steps; i++){
                var rand = Math.floor(Math.random() * 2);
                if(rand < 1){
                    walkSteps.push(moves.u);
                    walkSteps.push(moves.d);
                } else{
                    walkSteps.push(moves.l);
                    walkSteps.push(moves.r);
                }
            }

            return shuffle(walkSteps);
        }

        function createRoom(x, y, pw, ph){
            var randw = Math.floor((Math.random() * (pw/2) + 1) );
            var randh = Math.floor((Math.random() * (ph/2) + 1) );
            //alert(randw + ", " + randh);

            return [randw, randh];
        }

        function paint(){
            reset();

            var widthSelect = document.getElementById("width");
            var pathWidth = parseInt(widthSelect.options[widthSelect.selectedIndex].value);

            var heightSelect = document.getElementById("height");
            var pathHeight = parseInt(heightSelect.options[heightSelect.selectedIndex].value);
            //alert(pathWidth + ", " + pathHeight);

            //create a start and endpoint based on the grid size
            var startpoint = {
               x: -1,
               y: -1
            }
           var endpoint = {
               x: -1,
               y: -1
            }
            startpoint.x = 0;
            startpoint.y = pathHeight - 1;

            endpoint.x = pathWidth - 1;
            endpoint.y = 0;

            //paint the base grid
            for(var i = 0; i< pathWidth; i++){
                for(var j = 0; j< pathHeight; j++){

                    c.beginPath();
                    //c.lineWidth = 1;
                    c.fillStyle = "#000000";
                    c.fillRect(i*30, j*30, 30, 30);
                    c.stroke();
               }
           }

           var randsteps = 2* Math.floor((pathWidth/2) * (pathHeight/2));

           //create a random path that we will walk
           var walkArray = walk(startpoint, endpoint, randsteps);

           //create two moving points representing where we are and where we were
           var movingpoint = {
               x: -1,
               y: -1
           };
           var movingpointold = {
               x: -1,
               y: -1
           };
           movingpoint.x = startpoint.x;
           movingpoint.y = startpoint.y;
           movingpointold.x = startpoint.x;
           movingpointold.y = startpoint.y;

           var branch = 0;
           var branchpoint = {
               x: -1,
               y: -1
           };
           //follow the path and paint along the way
           for (var i = 0; i< walkArray.length; i++){
               movingpoint.x = movingpoint.x + walkArray[i][0];
               movingpoint.y = movingpoint.y + walkArray[i][1];
               var oppcurrMoveX = -1 * walkArray[i][0];
               var oppcurrMoveY = -1 * walkArray[i][1];
               var index = -1;
               for(var j = i; j< walkArray.length; j++){
                   if(walkArray[j][0] == oppcurrMoveX && walkArray[j][1] == oppcurrMoveY){
                       index = j;
                       break;
                   }
               }
               if(movingpoint.x > pathWidth -1){
                   movingpoint.x = movingpoint.x - 1;
                   if (index > -1) {
                       walkArray.splice(index, 1);
                   }

               }
               if(movingpoint.x < 0){
                   movingpoint.x = movingpoint.x + 1;
                   if (index > -1) {
                       walkArray.splice(index, 1);
                   }

               }
               if(movingpoint.y > pathHeight -1){
                   movingpoint.y = movingpoint.y - 1;
                   if (index > -1) {
                       walkArray.splice(index, 1);
                   }

               }
               if( movingpoint.y < 0){
                   movingpoint.y = movingpoint.y + 1;
                   if (index > -1) {
                       walkArray.splice(index, 1);
                   }

               }

               var movedirX = movingpoint.x - movingpointold.x;
               var movedirY = movingpoint.y - movingpointold.y;

               for(var l = 0; l< 30; l++){
                   c.fillStyle = "#FFFFFF";
                   c.fillRect(movingpointold.x*30 + movedirX*l + 8, movingpointold.y*30 + movedirY*l + 8, 6, 6);
               }

               c.fillStyle = "#FFFFFF";
               c.fillRect(movingpoint.x*30, movingpoint.y*30, 24, 24);

               if( i >= Math.floor(walkArray.lenght/2) && branch < 1){
                   branchpoint.x = movingpoint.x;
                   branchpoint.y = movingpoint.y;

                   branch++;
               }

               movingpointold.x = movingpoint.x;
               movingpointold.y = movingpoint.y;
           }

            for(var i = 0; i< Math.floor(pathWidth/2)+1; i++){
                for(var j = 0; j< Math.floor(pathHeight/2)+1; j++){
                    var randRoom = Math.floor((Math.random() * 9));
                    if(randRoom < 1){
                        roomDim = createRoom(i,j,pathWidth,pathHeight);
                        c.beginPath();
                        //c.lineWidth = 3;
                        c.fillStyle = "#FFFFFF";
                        c.fillRect(i*30 , j*30, roomDim[0]*30 - 6, roomDim[1]*30 - 6);
                        c.stroke();
                    }
                }
            }

            //paint the start and end points.
            //c.fillStyle = "#33CC33";
            c.fillStyle = "#FFFFFF";
            c.fillRect(startpoint.x*30, startpoint.y*30, 24, 24);
            //c.fillStyle = "#CC0000";
            c.fillStyle = "#FFFFFF";
            c.fillRect(endpoint.x*30, endpoint.y*30, 24 ,24);

            var startnode = {
                x:0,
                y:0
            };
            startnode.x = startpoint.x*30;
            startnode.y = startpoint.y*30;
            //floodfill(startnode,"#FFFFFF","#0099FF", pathWidth, pathHeight);
            var imgdata = c.getImageData(0,0,1,1).data;

            //paint the start and end points.
            c.fillStyle = "#33CC33";
            c.fillRect(startpoint.x*30, startpoint.y*30, 24, 24);
            c.fillStyle = "#CC0000";
            c.fillRect(endpoint.x*30, endpoint.y*30, 24 ,24);

            c.fillStyle = "#CC66FF";
            c.fillRect(branchpoint.x*30, branchpoint.y*30, 24, 24);

        }
    }
})(window, document, undefined);
<|endoftext|>


<commit_before>// least common multiple
Math.lcm = function() {
  var _factors = [];
  // arguments returns the arguments of js function
  for(var i in arguments) {
    if( arguments.hasOwnProperty(i) ){
      _factors.push(parseInt(arguments[i]));
    }
  }
  return _factors.gcd();
}

Array.prototype.lcm = function() {

}

// Considerar algumas propriedades para o algorítmo ficar mais rápido e não precisar fazer conta, exemplos:
// Para apenas dois números o Algorítmo de Euclides é mais rápido
// Se dois ou mais valores forem múltiplos entre si, então o MDC será o menor dentre eles;
// Seja n a quantidade de termos a ser calculado o MDC, se n <= 3, e se um dos termos for primo, então o MDC será 1
// Se dois termos forem primos, então o MDC também será 1, visto que dois números primos distintos nunca serão múltiplos
// MDC de valores iguais

// greatest common divisor
Math.gcd = function() {
  var _factors = [];
  // arguments returns the arguments of js function
  for(var i in arguments) {
    if( arguments.hasOwnProperty(i) ){
      _factors.push(parseInt(arguments[i]));
    }
  }
  return _factors.gcd();
}

Array.prototype.gcd = function() {
  var
    _factors = [],
    smallerFactorsHash = {},
    factor = 2,
    dividend = 1,
    count = 1,
    smallerCommonProduct = 1,
    _arr = this,
    powFactor = null
  ;

  _arr.map(function(item) {
    if(item < 0){
      item *= -1;
    }

    dividend = item;
    while ( dividend > 1 ) {

      factor = dividend.firstMultiple();
      dividend = dividend/dividend.firstMultiple();

      // guard sum of the same divisor
      if( dividend.firstMultiple() === factor ) {
        count++;
      } else {
        _factors.push(factor);

        // map smaller factors
        powFactor = Math.pow( factor, count );

        if( factor in smallerFactorsHash ) {
          if( powFactor < smallerFactorsHash[factor] ) {
            smallerFactorsHash[factor] = powFactor;
          }
        } else {
          smallerFactorsHash[factor] = powFactor;
        }

        count = 1;
      }

    }
  });

  // check common factors
  _factors = _factors.sort();
  _factors.map(function(n, i) {
    if( n === _factors[i+1] ) {
      count++;
    } else {
      if( count === _arr.length ) {
        smallerCommonProduct *= smallerFactorsHash[n];
      }
      count = 1;
   }

  });

  return smallerCommonProduct;
}
<commit_msg>Update math.js<commit_after>// least common multiple
Math.lcm = function() {
  var _factors = [];
  // arguments returns the argumegnts of js function
  for(var i in arguments) {
    if( arguments.hasOwnProperty(i) ){
      _factors.push(parseInt(arguments[i]));
    }
  }
  return _factors.lcm();
}

Array.prototype.lcm = function() {

}

// Considerar algumas propriedades para o algorítmo ficar mais rápido e não precisar fazer conta, exemplos:
// Para apenas dois números o Algorítmo de Euclides é mais rápido
// Se dois ou mais valores forem múltiplos entre si, então o MDC será o menor dentre eles;
// Seja n a quantidade de termos a ser calculado o MDC, se n <= 3, e se um dos termos for primo, então o MDC será 1
// Se dois termos forem primos, então o MDC também será 1, visto que dois números primos distintos nunca serão múltiplos
// MDC de valores iguais

// greatest common divisor
Math.gcd = function() {
  var _factors = [];
  // arguments returns the arguments of js function
  for(var i in arguments) {
    if( arguments.hasOwnProperty(i) ){
      _factors.push(parseInt(arguments[i]));
    }
  }
  return _factors.gcd();
}

Array.prototype.gcd = function() {
  var
    _factors = [],
    smallerFactorsHash = {},
    factor = 2,
    dividend = 1,
    count = 1,
    smallerCommonProduct = 1,
    _arr = this,
    powFactor = null
  ;

  _arr.map(function(item) {
    if(item < 0){
      item *= -1;
    }

    dividend = item;
    while ( dividend > 1 ) {

      factor = dividend.firstMultiple();
      dividend = dividend/dividend.firstMultiple();

      // guard sum of the same divisor
      if( dividend.firstMultiple() === factor ) {
        count++;
      } else {
        _factors.push(factor);

        // map smaller factors
        powFactor = Math.pow( factor, count );

        if( factor in smallerFactorsHash ) {
          if( powFactor < smallerFactorsHash[factor] ) {
            smallerFactorsHash[factor] = powFactor;
          }
        } else {
          smallerFactorsHash[factor] = powFactor;
        }

        count = 1;
      }

    }
  });

  // check common factors
  _factors = _factors.sort();
  _factors.map(function(n, i) {
    if( n === _factors[i+1] ) {
      count++;
    } else {
      if( count === _arr.length ) {
        smallerCommonProduct *= smallerFactorsHash[n];
      }
      count = 1;
   }

  });

  return smallerCommonProduct;
}
<|endoftext|>


<commit_before>
module.exports = function(grunt) {
  grunt.initConfig({
    sass: {
      dist: {
        files: [
          {
            expand: true,
            cwd: "<%= src_dir %>/css",
            src: ["*.scss"],
            dest: "<%= dest_dir %>/css",
            ext: ".css"
          }
        ]
      }
    },

    connect: {
      server: {
        options: {
          port: <%= port %>,
          hostname: "*",
          base: "<%= dest_dir %>"
        }
      }
    },

    watch: {
      sass: {
        files: ["<%= src_dir %>/css/*.sass"],
        tasks: ["sass:dist"]
      },

      livereload: {
        files: ["<%= dest_dir %>/css/*.css", "<%= dest_dir %>/css/**/*.css"],
        options: {
          livereload: true
        }
      }
    }
  });

  grunt.loadNpmTasks("grunt-contrib-connect");
  grunt.loadNpmTasks("grunt-contrib-watch");
  grunt.loadNpmTasks("grunt-contrib-sass");

  grunt.registerTask("livereload", ["connect:server", "watch"]);
  grunt.registerTask("default", []);
};
<commit_msg>fix ext<commit_after>
module.exports = function(grunt) {
  grunt.initConfig({
    sass: {
      dist: {
        files: [
          {
            expand: true,
            cwd: "<%= src_dir %>/css",
            src: ["*.scss"],
            dest: "<%= dest_dir %>/css",
            ext: ".css"
          }
        ]
      }
    },

    connect: {
      server: {
        options: {
          port: <%= port %>,
          hostname: "*",
          base: "<%= dest_dir %>"
        }
      }
    },

    watch: {
      sass: {
        files: ["<%= src_dir %>/css/*.scss"],
        tasks: ["sass:dist"]
      },

      livereload: {
        files: ["<%= dest_dir %>/css/*.css", "<%= dest_dir %>/css/**/*.css"],
        options: {
          livereload: true
        }
      }
    }
  });

  grunt.loadNpmTasks("grunt-contrib-connect");
  grunt.loadNpmTasks("grunt-contrib-watch");
  grunt.loadNpmTasks("grunt-contrib-sass");

  grunt.registerTask("livereload", ["connect:server", "watch"]);
  grunt.registerTask("default", []);
};
<|endoftext|>


<commit_before>import React from 'react'
import { Heading, Container, Flex, Box, Text, Subhead } from 'rebass'
import Icon from './Icon'
import { colors, mx, mm } from '../theme'

const Base = Container.extend.attrs({
  px: 3,
  my: 4,
  maxWidth: 72 * 16
})`text-align: center;`
const Feats = Flex.extend.attrs({ direction: ['column', 'row'] })``
const Feat = Container.extend.attrs({
  p: 3,
  m: [2, 3],
  w: [1, 1 / 3],
  maxWidth: 22 * 16
})`
  border-radius: .5rem;
  display: inline-block;
  text-align: left;
  p { line-height: 1.5; }
`
const Feature = ({ icon, alt, name, desc, ...props }) => (
  <Feat {...props}>
    <Icon name={icon} alt={alt} fill="white" size={48} mx="auto" />
    <Box mt={2}>
      <Subhead color="white" f={4} mb={1} children={name} />
      <Text f={3} color="white" children={desc} />
    </Box>
  </Feat>
)

export default ({ headline = true, ...props }) => (
  <Base id="features" {...props}>
    {headline && (
      <Heading
        color="primary"
        f={[5, 6]}
        mb={2}
        children="Students: start a club with all our resources."
      />
    )}
    <Feats>
      <Feature
        bg="success"
        icon="description"
        alt="Documentation icon"
        name="Starter materials"
        desc="Take off with curricula, guidelines, and leadership suggestions."
      />
      <Feature
        bg="accent"
        icon="question_answer"
        alt="Chat icon"
        name="A community that cares"
        desc="Meet like-minded students from around the world in our Slack."
      />
      <Feature
        bg="primary"
        icon="live_help"
        alt="Help icon"
        name="Coaching and assistance"
        desc="Get regular mentorship where it counts via office hours and calls."
      />
    </Feats>
  </Base>
)
<commit_msg>Add new about section to home page<commit_after>import React from 'react'
import { Heading, Container, Flex, Box, Image, Text, Subhead } from 'rebass'
import Icon from './Icon'
import { colors, cx, mx, mm, wk } from '../theme'

const Base = Container.extend.attrs({
  maxWidth: '100%',
  mt: 64 * -3,
  pt: 64 * 3,
  pw: 64,
  w: 1
})`
  position: relative;
  &:before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: ${64 * -1}px;
    z-index: -1;
    background: ${cx('gray.1')};
    ${wk('clip-path: polygon(0% 0%, 100% 0, 100% 75%, 0 100%)')}
    background-size: auto 100%;
    background-position-x: .5rem;
  }
`

const BannerImage = Image.extend.attrs({
  p: 16,
  w: 500,
  h: 350
})`
  display: inline-block;
  ${mx[3]} {
    transform: translate(0, 64px);
  }
`

const Section = Container.extend.attrs({
  maxWidth: 48 * 16
})`
  display: inline-block;
  text-align: left;
`

const CenteringContainer = Container.extend.attrs({
  mx: 'auto',
  maxWidth: 'none'
})`
  text-align: center;
`

const TextBlock = Text.extend.attrs({
  f: 4,
  my: 16
})``

const Bold = Text.extend.attrs({
  is: 'span',
  bold: true
})``

export default ({ headline = true, ...props }) => (
  <Base id="features" {...props}>
    <CenteringContainer>
      <Section id="section">
        <TextBlock>
          <Bold>What we do.</Bold> The Recurse Center is a self-directed,
          community-driven educational retreat for programmers in New York City.
        </TextBlock>
        <TextBlock>
          <Bold>Our philosophy.</Bold> We believe people learn best when they take
          control of their own education and are free to explore what they’re
          interested in. RC is heavily influenced by unschooling.
        </TextBlock>
        <TextBlock>
          <Bold>Never graduate.</Bold> RC doesn’t end after you leave. We have a
          diverse, active, and engaged alumni community of over 1,100 smart,
          enthusiastic, helpful programmers all over the world.
        </TextBlock>
        <TextBlock>
          <Bold>Build a career.</Bold> We’re here to support you at every stage of
          your career, whether you’re looking for a new job or not, and whether you
          just finished RC or attended many years ago.
        </TextBlock>
      </Section>
      <BannerImage src="/hacking.png" />
    </CenteringContainer>
  </Base>
)
<|endoftext|>


<commit_before>(function () {
  "use strict";

  angular.module('mnWizardStep3Service', [
    'mnWizardStep1Service',
    'mnWizardStep2Service',
    'mnFilters'
  ]).factory('mnWizardStep3Service', mnWizardStep3ServiceFactory);

  function mnWizardStep3ServiceFactory($http, mnWizardStep2Service, mnWizardStep1Service, mnBytesToMBFilter, bucketsFormConfiguration) {

    var mnWizardStep3Service = {
      getWizardBucketConf: getWizardBucketConf,
      postBuckets: postBuckets
    };

    return mnWizardStep3Service;

    function getWizardBucketConf() {
      return $http({
        method: 'GET',
        url: '/pools/default/buckets/default'
      }).then(function (resp) {
        var data = resp.data;
        var bucketConf = _.pick(data, _.keys( _.clone(bucketsFormConfiguration)));
        bucketConf.replicaIndex = bucketConf.replicaIndex ? 1 : 0;
        bucketConf.flushEnabled = (data.controllers !== undefined && data.controllers.flush !== undefined) ? 1 : 0;
        bucketConf.ramQuotaMB = mnBytesToMBFilter(resp.data.quota.rawRAM);
        bucketConf.uri = '/pools/default/buckets/default';
        return bucketConf;
      }, function () {
        var bucketConf = _.clone(bucketsFormConfiguration);
        bucketConf.ignoreWarnings = true;
        bucketConf.name = 'default';
        bucketConf.isNew = true;
        bucketConf.ramQuotaMB =  mnWizardStep1Service.getDynamicRamQuota() - mnBytesToMBFilter(mnWizardStep2Service.getSampleBucketsRAMQuota())
        return bucketConf
      }).then(function (bucketConf) {
        bucketConf.otherBucketsRamQuotaMB = mnBytesToMBFilter(mnWizardStep2Service.getSampleBucketsRAMQuota());
        bucketConf.isWizard = true;
        return bucketConf;
      })
    }

    function postBuckets(data, url) {
      return $http({
        data: data,
        method: 'POST',
        url: url
      });
    }
  }
})();
<commit_msg>spock-ui: skipMap during bucket configuration via setup wizard<commit_after>(function () {
  "use strict";

  angular.module('mnWizardStep3Service', [
    'mnWizardStep1Service',
    'mnWizardStep2Service',
    'mnFilters'
  ]).factory('mnWizardStep3Service', mnWizardStep3ServiceFactory);

  function mnWizardStep3ServiceFactory($http, mnWizardStep2Service, mnWizardStep1Service, mnBytesToMBFilter, bucketsFormConfiguration) {

    var mnWizardStep3Service = {
      getWizardBucketConf: getWizardBucketConf,
      postBuckets: postBuckets
    };

    return mnWizardStep3Service;

    function getWizardBucketConf() {
      return $http({
        method: 'GET',
        url: '/pools/default/buckets/default?basic_stats=true&skipMap=true'
      }).then(function (resp) {
        var data = resp.data;
        var bucketConf = _.pick(data, _.keys( _.clone(bucketsFormConfiguration)));
        bucketConf.replicaIndex = bucketConf.replicaIndex ? 1 : 0;
        bucketConf.flushEnabled = (data.controllers !== undefined && data.controllers.flush !== undefined) ? 1 : 0;
        bucketConf.ramQuotaMB = mnBytesToMBFilter(resp.data.quota.rawRAM);
        bucketConf.uri = '/pools/default/buckets/default?basic_stats=true&skipMap=true';
        return bucketConf;
      }, function () {
        var bucketConf = _.clone(bucketsFormConfiguration);
        bucketConf.ignoreWarnings = true;
        bucketConf.name = 'default';
        bucketConf.isNew = true;
        bucketConf.ramQuotaMB =  mnWizardStep1Service.getDynamicRamQuota() - mnBytesToMBFilter(mnWizardStep2Service.getSampleBucketsRAMQuota())
        return bucketConf
      }).then(function (bucketConf) {
        bucketConf.otherBucketsRamQuotaMB = mnBytesToMBFilter(mnWizardStep2Service.getSampleBucketsRAMQuota());
        bucketConf.isWizard = true;
        return bucketConf;
      })
    }

    function postBuckets(data, url) {
      return $http({
        data: data,
        method: 'POST',
        url: url
      });
    }
  }
})();
<|endoftext|>


<commit_before>'use strict'

const AudioContext=require('./audio-context')
const Loader=require('./loader')
const AudioGraph=require('./audio-graph')
const Canvas=require('./canvas')

const Lines=require('crnx-base/lines')
const JsLines=require('crnx-base/js-lines')
const InterleaveLines=require('crnx-base/interleave-lines')
const NoseWrapLines=require('crnx-base/nose-wrap-lines')
const BaseWebCode=require('crnx-base/web-code')

class Code extends BaseWebCode {
	constructor(options,i18n) {
		super()
		this.i18n=i18n
		this.featureContext={}
		this.features=[
			new AudioContext(options.api),
			new Loader(options.loader),
			new AudioGraph(options.graph),
			new Canvas(options.canvas),
		]
		// possible feature context flags:
		//	alignedInputs = all input labels have to be the same width; requested by equalizer
		//	audioContext =
		//		AudioContext has to assign the audio context to var ctx
		//		AudioGraph has to output the js
		//		media elements of AudioGraph have to have crossorigin enabled
		//	canvas = Canvas has to output <canvas> element and create var canvas and var canvasContext
		//	canvasVolumeGradient = Canvas has to create var canvasVolumeGradient
		//	loader = Loader has to provide loadSample() function
		//	loaderOnError = loadSample() caller has to pass the error handler
		//	maxLogFftSize = max log(fft size) of all analysers
		//	maxLogFftSizeNodeJsName = name of analyser node with max log(fft size); if set, Canvas has to allocate analyserData array
		// visualization functions, either undefined or set to VisFunction object:
		//	visualizeWaveformFn
		//	visualizeFrequencyBarsFn
		//	visualizeFrequencyOutlineFn
		//	visualizeVolumeFn
		// counters:
		//	canvasVolumeMeterCounter = number of volume meters, for communication between volume vis fns
		// helpers:
		//	getConnectAssignJsLines = set by AudioContext
		for (const feature of this.features) {
			feature.requestFeatureContext(this.featureContext)
		}
		this.isInteresting=!!this.featureContext.audioContext
	}
	get basename() {
		return 'webaudio'
	}
	get lang() {
		return this.i18n.lang
	}
	get title() {
		return this.i18n('code.title')
	}
	get styleLines() {
		const a=Lines.b()
		if (this.featureContext.alignedInputs) {
			a(
				"label {",
				"	display: inline-block;",
				"	width: 10em;",
				"	text-align: right;",
				"	line-height: 0.8em;",
				"}",
				".min {",
				"	display: inline-block;",
				"	width: 5em;",
				"	text-align: right;",
				"}",
				".max {",
				"	display: inline-block;",
				"	width: 5em;",
				"	text-align: left;",
				"}"
			)
		}
		if (this.featureContext.canvas) {
			a(
				"canvas {",
				"	border: 1px solid;",
				"}"
			)
		}
		return a.e()
	}
	get bodyLines() {
		return Lines.bae(
			...this.features.map(feature=>feature.getHtmlLines(this.featureContext,this.i18n))
		)
	}
	get scriptLines() {
		return InterleaveLines.bae(
			...this.features.map(feature=>feature.getInitJsLines(this.featureContext,this.i18n)),
			NoseWrapLines.b(
				JsLines.bae(
					"function visualize() {"
				),
				JsLines.bae(
					"	requestAnimationFrame(visualize);",
					"}",
					"requestAnimationFrame(visualize);"
				)
			).ae(
				...this.features.map(feature=>feature.getPreVisJsLines(this.featureContext,this.i18n)),
				...this.features.map(feature=>feature.getVisJsLines(this.featureContext,this.i18n))
			)
		)
	}
}

module.exports=Code
<commit_msg>set width only for first-child labels<commit_after>'use strict'

const AudioContext=require('./audio-context')
const Loader=require('./loader')
const AudioGraph=require('./audio-graph')
const Canvas=require('./canvas')

const Lines=require('crnx-base/lines')
const JsLines=require('crnx-base/js-lines')
const InterleaveLines=require('crnx-base/interleave-lines')
const NoseWrapLines=require('crnx-base/nose-wrap-lines')
const BaseWebCode=require('crnx-base/web-code')

class Code extends BaseWebCode {
	constructor(options,i18n) {
		super()
		this.i18n=i18n
		this.featureContext={}
		this.features=[
			new AudioContext(options.api),
			new Loader(options.loader),
			new AudioGraph(options.graph),
			new Canvas(options.canvas),
		]
		// possible feature context flags:
		//	alignedInputs = all input labels have to be the same width; requested by equalizer
		//	audioContext =
		//		AudioContext has to assign the audio context to var ctx
		//		AudioGraph has to output the js
		//		media elements of AudioGraph have to have crossorigin enabled
		//	canvas = Canvas has to output <canvas> element and create var canvas and var canvasContext
		//	canvasVolumeGradient = Canvas has to create var canvasVolumeGradient
		//	loader = Loader has to provide loadSample() function
		//	loaderOnError = loadSample() caller has to pass the error handler
		//	maxLogFftSize = max log(fft size) of all analysers
		//	maxLogFftSizeNodeJsName = name of analyser node with max log(fft size); if set, Canvas has to allocate analyserData array
		// visualization functions, either undefined or set to VisFunction object:
		//	visualizeWaveformFn
		//	visualizeFrequencyBarsFn
		//	visualizeFrequencyOutlineFn
		//	visualizeVolumeFn
		// counters:
		//	canvasVolumeMeterCounter = number of volume meters, for communication between volume vis fns
		// helpers:
		//	getConnectAssignJsLines = set by AudioContext
		for (const feature of this.features) {
			feature.requestFeatureContext(this.featureContext)
		}
		this.isInteresting=!!this.featureContext.audioContext
	}
	get basename() {
		return 'webaudio'
	}
	get lang() {
		return this.i18n.lang
	}
	get title() {
		return this.i18n('code.title')
	}
	get styleLines() {
		const a=Lines.b()
		if (this.featureContext.alignedInputs) {
			a(
				"label:first-child {",
				"	display: inline-block;",
				"	width: 10em;",
				"	text-align: right;",
				"	line-height: 0.8em;",
				"}",
				".min {",
				"	display: inline-block;",
				"	width: 5em;",
				"	text-align: right;",
				"}",
				".max {",
				"	display: inline-block;",
				"	width: 5em;",
				"	text-align: left;",
				"}"
			)
		}
		if (this.featureContext.canvas) {
			a(
				"canvas {",
				"	border: 1px solid;",
				"}"
			)
		}
		return a.e()
	}
	get bodyLines() {
		return Lines.bae(
			...this.features.map(feature=>feature.getHtmlLines(this.featureContext,this.i18n))
		)
	}
	get scriptLines() {
		return InterleaveLines.bae(
			...this.features.map(feature=>feature.getInitJsLines(this.featureContext,this.i18n)),
			NoseWrapLines.b(
				JsLines.bae(
					"function visualize() {"
				),
				JsLines.bae(
					"	requestAnimationFrame(visualize);",
					"}",
					"requestAnimationFrame(visualize);"
				)
			).ae(
				...this.features.map(feature=>feature.getPreVisJsLines(this.featureContext,this.i18n)),
				...this.features.map(feature=>feature.getVisJsLines(this.featureContext,this.i18n))
			)
		)
	}
}

module.exports=Code
<|endoftext|>